os/mm/mmplugins/mmfwplugins/src/Plugin/subtitle/subtitlegraphicdrawer/mmfsubtitlegraphicdrawer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
/**
sl@0
    17
 @file
sl@0
    18
 @internalComponent
sl@0
    19
*/
sl@0
    20
sl@0
    21
#include <graphics/wsgraphicscontext.h>
sl@0
    22
#include "mmfsubtitlegraphicdrawer.h"
sl@0
    23
sl@0
    24
// Compensation value in microseconds to account for differences in the requested callback time and the actual
sl@0
    25
// time the callback is delivered
sl@0
    26
static const TInt KClockDrift=100000;
sl@0
    27
sl@0
    28
CMMFSubtitleGraphicDrawer* CMMFSubtitleGraphicDrawer::NewL()
sl@0
    29
    {
sl@0
    30
    CMMFSubtitleGraphicDrawer* self = new(ELeave) CMMFSubtitleGraphicDrawer();  
sl@0
    31
    return self;
sl@0
    32
    }
sl@0
    33
    
sl@0
    34
CMMFSubtitleGraphicDrawer::~CMMFSubtitleGraphicDrawer()
sl@0
    35
    {
sl@0
    36
    delete iBitmap1;
sl@0
    37
    delete iBitmap2;
sl@0
    38
    delete iTempBitmap;
sl@0
    39
    }
sl@0
    40
sl@0
    41
void CMMFSubtitleGraphicDrawer::ConstructL(MWsGraphicDrawerEnvironment& aEnv, const TGraphicDrawerId& aId, MWsClient& aOwner, const TDesC8& /*aData*/)
sl@0
    42
    {
sl@0
    43
    // Note this method is called by the baseclass not CMMFSubtitleGraphicDrawer
sl@0
    44
    BaseConstructL(aEnv, aId, aOwner);
sl@0
    45
    
sl@0
    46
    // Construct bitmap objects.  Do this here as we can leave usefully with
sl@0
    47
    // any construction errors
sl@0
    48
	iBitmap1 = new (ELeave) CFbsBitmap();
sl@0
    49
	iBitmap2 = new (ELeave) CFbsBitmap();
sl@0
    50
	iTempBitmap = new (ELeave) CFbsBitmap();
sl@0
    51
    }
sl@0
    52
sl@0
    53
sl@0
    54
// From CwsGraphicDrawer
sl@0
    55
void CMMFSubtitleGraphicDrawer::HandleMessage(const TDesC8& aData)
sl@0
    56
    {   
sl@0
    57
    // Retreive message type from buffer
sl@0
    58
    TInt8 msgType = aData[0];
sl@0
    59
    
sl@0
    60
    switch (msgType)
sl@0
    61
    	{    	
sl@0
    62
	case ESubtitleCrpMessageInit:
sl@0
    63
		{
sl@0
    64
		iCaptureRegion = ETrue;
sl@0
    65
		TPckgBuf<TSubtitleCrpMsgInit> message;
sl@0
    66
		message.Copy(aData);
sl@0
    67
		ProcessMessageInit(message());
sl@0
    68
		}
sl@0
    69
		break;
sl@0
    70
		
sl@0
    71
	case ESubtitleCrpMessageInitSimple:
sl@0
    72
		iCaptureRegion = ETrue;
sl@0
    73
		iBitmap1Valid=EFalse;
sl@0
    74
    	iBitmap2Valid=EFalse;
sl@0
    75
    	iTempBitmapValid=ETrue;
sl@0
    76
		break;
sl@0
    77
		
sl@0
    78
	case ESubtitleCrpMessageDrawFrame:
sl@0
    79
		{
sl@0
    80
		iState = ESubtitleGraphicStateDrawFrame;
sl@0
    81
		TPckgBuf<TSubtitleCrpMsgDrawFrame> message;
sl@0
    82
		message.Copy(aData);
sl@0
    83
		ProcessMessageDrawFrame(message());
sl@0
    84
		}
sl@0
    85
		break;
sl@0
    86
		
sl@0
    87
	case ESubtitleCrpMessageSwapFrame:
sl@0
    88
		{
sl@0
    89
		iState = ESubtitleGraphicStateSwapFrame;
sl@0
    90
		TPckgBuf<TSubtitleCrpMsgRenderSwapFrame> message;
sl@0
    91
		message.Copy(aData);
sl@0
    92
        ProcessMessageSwapFrame(message());
sl@0
    93
		}
sl@0
    94
        break;
sl@0
    95
    	
sl@0
    96
    case ESubtitleCrpMessageClear:
sl@0
    97
    	iDisplayClearDue.UniversalTime();
sl@0
    98
    	iState = ESubtitleGraphicStateClear;
sl@0
    99
    	break;
sl@0
   100
		
sl@0
   101
	default:
sl@0
   102
		// Silently ignore unrecognised messages
sl@0
   103
		// Clear messages for example require no further processing
sl@0
   104
		// Set the state to waiting so DoDraw will do nothing.
sl@0
   105
		iState = ESubtitleGraphicStateWaiting;
sl@0
   106
	break;
sl@0
   107
    	}
sl@0
   108
    
sl@0
   109
    // Note clear messages require no further processing we just need to invalidate the display
sl@0
   110
sl@0
   111
	// Ask WSERV to redraw the CRP
sl@0
   112
    Invalidate();
sl@0
   113
    }
sl@0
   114
sl@0
   115
void CMMFSubtitleGraphicDrawer::DoDraw(MWsGc& aGc, const TRect& aRect, const TDesC8& /*aData*/) const
sl@0
   116
	{	
sl@0
   117
	// For some crp rendering states we need to ensure that this DoDraw has been called
sl@0
   118
	// in response to Invalidate() and not generated in response to a portion of the CRP
sl@0
   119
	// becoming invald for some reason (menus, dialogs etc)
sl@0
   120
	
sl@0
   121
	// Store the invalid region as our subtitle region to complete initialization.
sl@0
   122
	if (iCaptureRegion)
sl@0
   123
		{
sl@0
   124
		iSubtitleRegion = aRect;
sl@0
   125
		iCaptureRegion = EFalse;
sl@0
   126
		}
sl@0
   127
	
sl@0
   128
	// If the current state is waiting we do dont need to do anything
sl@0
   129
	if ((iSubtitleRegion.IsEmpty())||(iState==ESubtitleGraphicStateWaiting))
sl@0
   130
		{
sl@0
   131
		return;
sl@0
   132
		}
sl@0
   133
	
sl@0
   134
	switch(iState)
sl@0
   135
	    {   	
sl@0
   136
	case ESubtitleGraphicStateDrawFrame:
sl@0
   137
	case ESubtitleGraphicStateSwapFrame:	
sl@0
   138
		// Blt new content
sl@0
   139
		DoBitBlt(aGc, iDirtyRegion);
sl@0
   140
		
sl@0
   141
		if ( iDisplayDuration.Int64() > 0 )
sl@0
   142
			{
sl@0
   143
			// Schedule a clear frame to remove this subtitle after the requested time
sl@0
   144
		    // Note clear messages require no further processing we just need to schedule a redraw
sl@0
   145
			aGc.ScheduleAnimation(iSubtitleRegion, iDisplayDuration.Int64());
sl@0
   146
			iDisplayClearDue.UniversalTime();
sl@0
   147
			iDisplayClearDue=iDisplayDuration.Int64()+iDisplayClearDue.Int64()-KClockDrift;
sl@0
   148
			iState = ESubtitleGraphicStateClear;
sl@0
   149
			}
sl@0
   150
		else
sl@0
   151
			{
sl@0
   152
			// Redraw this frames content until instructed to stop
sl@0
   153
			iState = ESubtitleGraphicStateRefreshContent;
sl@0
   154
			}
sl@0
   155
	    break;
sl@0
   156
	
sl@0
   157
	case ESubtitleGraphicStateRefreshContent:
sl@0
   158
		// Refresh current frame content
sl@0
   159
		DoBitBlt(aGc, iDirtyRegion);
sl@0
   160
		break;
sl@0
   161
		
sl@0
   162
	case ESubtitleGraphicStateClear:
sl@0
   163
		{
sl@0
   164
		// Clear is due, check to see if the clear is due now
sl@0
   165
		TTime timeNow;
sl@0
   166
		timeNow.UniversalTime();
sl@0
   167
		TInt diff=iDisplayClearDue.Int64()-timeNow.Int64();
sl@0
   168
		
sl@0
   169
		if ( diff > 0 )
sl@0
   170
			{
sl@0
   171
			// Clear is not due do a standard bitblt		
sl@0
   172
			DoBitBlt(aGc, iDirtyRegion);
sl@0
   173
			}
sl@0
   174
		else
sl@0
   175
			{
sl@0
   176
			// No further processing required as WSERV clears the region for us
sl@0
   177
			iState = ESubtitleGraphicStateWaiting;
sl@0
   178
			}
sl@0
   179
		}
sl@0
   180
		break;
sl@0
   181
		
sl@0
   182
	default:
sl@0
   183
		// Should never happen
sl@0
   184
#ifdef _DEBUG
sl@0
   185
		RDebug::Printf("CMMFSubtitleGraphicDrawer::DoDraw() - Invalid State in Drawer should never happen");
sl@0
   186
		User::Invariant();
sl@0
   187
#endif
sl@0
   188
	    break;
sl@0
   189
	    }
sl@0
   190
	}
sl@0
   191
sl@0
   192
/**
sl@0
   193
Renders the current bitmap frame
sl@0
   194
*/
sl@0
   195
void CMMFSubtitleGraphicDrawer::DoBitBlt(MWsGc& aGc, const TRect& aRect) const
sl@0
   196
	{
sl@0
   197
	MWsGraphicsContext* context = aGc.ObjectInterface<MWsGraphicsContext>();
sl@0
   198
	if(!context)
sl@0
   199
		{
sl@0
   200
		RDebug::Printf("CMMFSubtitleGraphicDrawer::DoBitBlt can not get MWsGraphicsContext");
sl@0
   201
		return;
sl@0
   202
		}
sl@0
   203
	context->Push();
sl@0
   204
	
sl@0
   205
	switch (iCurrentFrame)
sl@0
   206
		{
sl@0
   207
		case ESubtitleGraphicFrame1:
sl@0
   208
			if (iBitmap1Valid)
sl@0
   209
				{
sl@0
   210
				context->BitBlt(iSubtitleRegion.iTl + aRect.iTl, *iBitmap1, aRect);
sl@0
   211
				}
sl@0
   212
			break;
sl@0
   213
		
sl@0
   214
		case ESubtitleGraphicFrame2:
sl@0
   215
			if (iBitmap2Valid)
sl@0
   216
				{
sl@0
   217
				context->BitBlt(iSubtitleRegion.iTl + aRect.iTl, *iBitmap2, aRect);
sl@0
   218
				}
sl@0
   219
			break;
sl@0
   220
		
sl@0
   221
		case ESubtitleGraphicFrame3:
sl@0
   222
			if (iTempBitmapValid)
sl@0
   223
				{
sl@0
   224
				context->BitBlt(iSubtitleRegion.iTl + aRect.iTl, *iTempBitmap, aRect);
sl@0
   225
				}
sl@0
   226
			break;
sl@0
   227
		
sl@0
   228
		default:
sl@0
   229
			break;
sl@0
   230
		}
sl@0
   231
sl@0
   232
	context->Pop();	
sl@0
   233
	}
sl@0
   234
sl@0
   235
/**
sl@0
   236
Process initialization message from client.  Readies the CRP for drawing
sl@0
   237
@param aMessage Message data received from client
sl@0
   238
*/
sl@0
   239
void CMMFSubtitleGraphicDrawer::ProcessMessageInit(TSubtitleCrpMsgInit& aMessage)
sl@0
   240
	{
sl@0
   241
	// Duplicate client bitmap handles
sl@0
   242
	// These are verified by the client before they are sent
sl@0
   243
	iBitmap1->Reset();
sl@0
   244
	TInt err = iBitmap1->Duplicate(aMessage.iBitmapHandle1);
sl@0
   245
	
sl@0
   246
	// This should never be a problem but check in debug modes just in case
sl@0
   247
	// We dont do this in release mode as it panics the window server...
sl@0
   248
	__ASSERT_DEBUG(KErrNone==err, User::Invariant());
sl@0
   249
	
sl@0
   250
	iBitmap2->Reset();
sl@0
   251
	err = iBitmap2->Duplicate(aMessage.iBitmapHandle2);
sl@0
   252
	// This should never be a problem but check in debug modes just in case
sl@0
   253
	// We dont do this in release mode as it panics the window server...
sl@0
   254
	__ASSERT_DEBUG(KErrNone==err, User::Invariant());
sl@0
   255
	
sl@0
   256
	iCurrentFrame=ESubtitleGraphicFrame1;
sl@0
   257
	iBitmap1Valid=ETrue;
sl@0
   258
	iBitmap2Valid=ETrue;
sl@0
   259
	iTempBitmapValid=EFalse;
sl@0
   260
	}
sl@0
   261
sl@0
   262
/**
sl@0
   263
Process draw frame message from client.  Draw the bitmap provided.
sl@0
   264
@param aMessage Message data received from client
sl@0
   265
*/
sl@0
   266
void CMMFSubtitleGraphicDrawer::ProcessMessageDrawFrame(TSubtitleCrpMsgDrawFrame& aMessage)
sl@0
   267
	{
sl@0
   268
	// Duplicate client bitmap handle
sl@0
   269
	iTempBitmap->Reset();
sl@0
   270
	iTempBitmap->Duplicate(aMessage.iBitmapHandle);
sl@0
   271
	
sl@0
   272
    iOldDirtyRegion=iDirtyRegion;
sl@0
   273
	iDirtyRegion=aMessage.iDirtyRegion;
sl@0
   274
		
sl@0
   275
    iDisplayDuration=aMessage.iDisplayDuration;
sl@0
   276
    iCurrentFrame=ESubtitleGraphicFrame3;
sl@0
   277
	}
sl@0
   278
sl@0
   279
/**
sl@0
   280
Process swap frame message from client.  Draws the current backbuffer provided.
sl@0
   281
@param aMessage Message data received from client
sl@0
   282
*/
sl@0
   283
void CMMFSubtitleGraphicDrawer::ProcessMessageSwapFrame(TSubtitleCrpMsgRenderSwapFrame& aMessage)
sl@0
   284
	{
sl@0
   285
	__ASSERT_DEBUG((aMessage.iExpectedFrame==ESubtitleGraphicFrame1)||(aMessage.iExpectedFrame==ESubtitleGraphicFrame2), User::Invariant());
sl@0
   286
	
sl@0
   287
	iDisplayDuration = aMessage.iDisplayDuration;
sl@0
   288
	iOldDirtyRegion=iDirtyRegion;
sl@0
   289
	iDirtyRegion = aMessage.iDirtyRegion;
sl@0
   290
	
sl@0
   291
	// Swap the frame pointer
sl@0
   292
	iCurrentFrame = static_cast<TSubtitleGraphicFrame>(aMessage.iExpectedFrame);
sl@0
   293
	}