--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/AlfDecoderServerClient/src/alfcompositionclient.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,1141 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <alfdecoderserverclient.h>
+#include <alfstreamerconsts.h>
+
+#include <uiacceltk/HuiUtil.h>
+#include <coemain.h>
+#include <alf/alfcompositionclient.h>
+#include "graphics/surfacemanager.h"
+#include "graphics/surface.h"
+#include "graphics/surfaceupdateclient.h"
+#include "graphics/suerror.h" // KAllScreens
+
+#include "graphics/surfaceconfiguration.h" // TSurfaceConfiguration
+
+#include "alflogger.h"
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionClientBaseData::NewL
+// ---------------------------------------------------------------------------
+//
+CAlfCompositionClientBase::CAlfCompositionClientBaseData*
+ CAlfCompositionClientBase::CAlfCompositionClientBaseData::NewL(
+ TInt aBufferSize,
+ RAlfBridgerClient* aClient)
+ {
+ CAlfCompositionClientBaseData* me = new (ELeave) CAlfCompositionClientBaseData();
+ CleanupStack::PushL(me);
+ me->ConstructL(aBufferSize, aClient);
+ CleanupStack::Pop();
+ return me;
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionClientBaseData::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionClientBase::CAlfCompositionClientBaseData::ConstructL(TInt /*aBufferSize*/, RAlfBridgerClient* aClient)
+ {
+ if (!aClient)
+ {
+ iClient = new (ELeave) RAlfBridgerClient();
+ iOwnsClient = ETrue;
+ User::LeaveIfError(iClient->Connect());
+ }
+ else
+ {
+ iClient = aClient;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ~CAlfCompositionClientBaseData
+// ---------------------------------------------------------------------------
+//
+CAlfCompositionClientBase::CAlfCompositionClientBaseData::~CAlfCompositionClientBaseData()
+ {
+ if (iOwnsClient && iClient)
+ {
+ iClient->Close();
+ delete iClient;
+ }
+ if (iDeleted)
+ {
+ *iDeleted = ETrue;
+ }
+ }
+// ---------------------------------------------------------------------------
+// RequestEventL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionClientBase::RequestEventL(TInt aBufferSize, RAlfBridgerClient* aClient)
+ {
+ if (!IsActive())
+ {
+ if (!iData)
+ {
+ iData = CAlfCompositionClientBaseData::NewL(aBufferSize, aClient);
+ }
+ SetActive();
+ iData->iClient->SendAsynchronous(KAlfCompOpRequestEvent,TIpcArgs(&iData->iBuffer), iStatus);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SendEvent
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionClientBase::SendEvent(TInt aOp, const TAny* aEventData, TInt aEventSize)
+ {
+ // Todo, should support batching / asynch
+ if (!iData)
+ {
+ TRAPD(err, iData = CAlfCompositionClientBaseData::NewL(aEventSize, 0)) // basically zero buffer would do
+ if (err)
+ {
+ return err;
+ }
+ }
+
+ TPtrC8 ptr(reinterpret_cast<const TUint8*>(aEventData), aEventSize);
+
+ return iData->iClient->SendSynch(aOp, ptr);
+ }
+
+// ---------------------------------------------------------------------------
+// HandleEventL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionClientBase::HandleEventL(TInt /*aEventType*/, TAny* /*aEventData*/)
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// NullBoolPtr
+// ---------------------------------------------------------------------------
+//
+void NullBoolPtr(TAny* ptr)
+ {
+ TBool** boolptr = static_cast<TBool**>(ptr);
+ *boolptr = 0;
+ }
+
+// ---------------------------------------------------------------------------
+// RunL
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionClientBase::RunL()
+ {
+ TInt status = iStatus.Int();
+ User::LeaveIfError(status);
+ TBool deleted = EFalse;
+ iData->iDeleted = &deleted;
+ CleanupStack::PushL(TCleanupItem(NullBoolPtr, &iData->iDeleted));
+ HandleEventL(status, (void*)iData->iBuffer.Ptr());
+ CleanupStack::PopAndDestroy();
+ if (!deleted) // just small precaution if client deletes itself on callback
+ {
+ RequestEventL(sizeof(TInt));
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// DoCancel
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionClientBase::DoCancel()
+ {
+ if (iData)
+ {
+ iData->iClient->SendSynch(KAlfCompOpCancelEventRequest, TIpcArgs(Handle()) );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// RunError
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionClientBase::RunError(TInt aError)
+ {
+ RDebug::Print(_L("CAlfCompositionClientBase::RunError( %d )"),aError);
+ if ( aError == KErrServerTerminated )
+ {
+ RDebug::Print(_L("CAlfCompositionClientBase::RunError - ALF server has died. Everything is lost. Halting."));
+ USER_INVARIANT();
+ }
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// ~CAlfCompositionClientBase
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfCompositionClientBase::~CAlfCompositionClientBase()
+ {
+ Cancel();
+ delete iData;
+ iData = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// SetHandleL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionClientBase::SetHandleL(TInt aHandle)
+ {
+ User::LeaveIfError(aHandle);
+ if (!iData)
+ {
+ iData = CAlfCompositionClientBaseData::NewL(sizeof(TInt),0);// basically zero buffer would do
+ }
+ iData->iHandle = aHandle;
+ }
+
+// ---------------------------------------------------------------------------
+// Handle
+// ---------------------------------------------------------------------------
+//
+TInt CAlfCompositionClientBase::Handle() const
+ {
+ return iData?iData->iHandle:0;
+ }
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfCompositionCntrlClient* CAlfCompositionCntrlClient::NewL(RAlfBridgerClient* aClient, MAlfCompositionController* aController)
+ {
+ CAlfCompositionCntrlClient* me = new (ELeave) CAlfCompositionCntrlClient(aController);
+ me->RequestEventL(60, aClient); // magic, extent with options
+ me->SendEvent(KAlfCompositionWServReady,0,0);
+ return me;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfCompositionCntrlClient::~CAlfCompositionCntrlClient()
+ {
+ iHostBindingsHash.Close();
+ iHostPermittedOpsHash.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// HandleEventL
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionCntrlClient::HandleEventL(TInt aEventType, TAny* aEventData)
+ {
+ __ASSERT_DEBUG(iController, USER_INVARIANT());
+
+ if (aEventType == KAlfCompositionLowOnGraphicsMemory && iController)
+ {
+ iController->LowOnGraphicsMemory();
+ return;
+ }
+
+ if (aEventType == KAlfCompositionGoodOnGraphicsMemory && iController)
+ {
+ iController->GraphicsMemoryGood();
+ return;
+ }
+
+ TInt* ptr = static_cast<TInt*>(aEventData);
+ TInt target;
+
+ // find out if target is a host (is binded to some other target)
+ TInt bindedTarget = 0;
+ TInt* tempbind = iHostBindingsHash.Find(*ptr);
+ if(tempbind)
+ bindedTarget = *tempbind;
+ TInt32 permittedOps = 0;
+ if(bindedTarget)
+ {
+ target = bindedTarget;
+ TInt32* tempOps = iHostPermittedOpsHash.Find(*ptr);
+ if(tempOps)
+ permittedOps = *tempOps;
+ }
+ else
+ {
+ target = *ptr;
+ }
+
+ // SetTargetL is always sent before the actual command.
+ iController->SetTargetL(target); // When this is composition
+
+ switch (aEventType)
+ {
+ case KAlfCompOpCreateToken:
+ {
+ break;
+ }
+ case KAlfCompOpBindSourceToToken:
+ {
+ RDebug::Print(_L("ptr0: %d, Target %d, Flags %d, combinedtarget"), ptr[0], ptr[1], ptr[2]);
+ if( ptr[1] != 0) // add binding information for new host to given target with permitted operations
+ {
+ iHostBindingsHash.Insert(*ptr, ptr[1]);
+ iHostPermittedOpsHash.Insert(*ptr, ptr[2]);
+ }
+ else // remove old host bindings when the host is being deleted.
+ {
+ iHostBindingsHash.Remove(*ptr);
+ iHostPermittedOpsHash.Remove(*ptr);
+ }
+ break;
+ }
+ case KAlfCompOpCreateSource:
+ {
+ iController->CreateTargetL(target, ptr[2], ptr[3]);
+ break;
+ }
+ case KAlfCompOpEnableAlpha:
+ {
+ if ( !bindedTarget || permittedOps & CAlfCompositionHost::EAlfAllowChangeAlpha)
+ {
+ iController->EnableAlpha(ptr[1]);
+ }
+ break;
+ }
+ case KAlfCompOpSetOpacity:
+ {
+ if ( !bindedTarget || permittedOps & CAlfCompositionHost::EAlfAllowChangeOpacity)
+ {
+ TReal32* opacity = /*static_cast<*/(TReal32*)(++ptr);
+ iController->SetOpacity(*opacity);
+ }
+ break;
+ }
+ case KAlfCompOpSetRotation:
+ {
+ if ( !bindedTarget || permittedOps & CAlfCompositionHost::EAlfAllowChangeRotation)
+ {
+ iController->SetRotation(ptr[1]);
+ }
+ break;
+ }
+ case KAlfCompOpSetZOrder:
+ {
+ TInt newToken = 0;
+ if( ptr[3] != KErrNotFound)
+ {
+ newToken = iController->SetOrder(target,ptr[1],ptr[2],ETrue); // top, below, combineTargets
+ }
+ else
+ {
+ newToken = iController->SetOrder(target,ptr[1],ptr[2],EFalse); // top, below, combineTargets
+ }
+ TInt array[] = {ptr[0], newToken, ptr[3]}; // caller session, newToken, secretKey
+ SendEvent(KAlfCompositionTargetCreated, array, sizeof(array));
+ break;
+ }
+
+ case KAlfCompOpSetExtent:
+ {
+ if ( !bindedTarget || permittedOps & CAlfCompositionHost::EAlfAllowChangeExtent)
+ {
+ TRect rect(ptr[1],ptr[2],ptr[3],ptr[4]);
+ TSurfaceId surfaceId;
+ surfaceId.iInternal[0] = ptr[6];
+ surfaceId.iInternal[1] = ptr[7];
+ surfaceId.iInternal[2] = ptr[8];
+ surfaceId.iInternal[3] = ptr[9];
+ iController->SetExtentSurfaceId(surfaceId);
+ iController->SetExtent(rect, ptr[5]); // rect, screen
+ }
+ break;
+ }
+ case KAlfCompOpSetSRect:
+ {
+ if ( !bindedTarget || permittedOps & CAlfCompositionHost::EAlfAllowChangeExtent)
+ {
+ TRect rect(ptr[1],ptr[2],ptr[3],ptr[4]);
+ iController->SetSourceRect(rect);
+ }
+ break;
+ }
+ case KAlfComOpSetBackgroundAnim:
+ {
+ if ( !bindedTarget || permittedOps & CAlfCompositionHost::EAlfAllowChangeBackgroundAnim)
+ {
+ iController->SetIsBackgroundAnim(ptr[1]);
+ }
+ break;
+ }
+ case KAlfCompOpSessionClosed:
+ {
+ iController->DeleteTarget(target);
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// RunError
+// ---------------------------------------------------------------------------
+//
+TInt CAlfCompositionCntrlClient::RunError(TInt aError)
+ {
+ CAlfCompositionClientBase::RunError(aError);
+ // reactivate
+ TRAPD(err, RequestEventL(60)); // magic, extent with options
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+NONSHARABLE_CLASS(CAlfCompositionSource::CAlfCompositionSourceData):public CBase
+ {
+ public:
+ static CAlfCompositionSourceData* NewL()
+ {
+ CAlfCompositionSourceData* me = new (ELeave) CAlfCompositionSourceData();
+ CleanupStack::PushL(me);
+ // jada
+ CleanupStack::Pop();
+ return me;
+ }
+
+ ~CAlfCompositionSourceData()
+ {
+ if (iDeleted)
+ {
+ *iDeleted = ETrue;
+ }
+ iObservers.Reset();
+ }
+
+ TBool* iDeleted;
+ TSurfaceId iSurfaceId;
+ RPointerArray<MAlfCompositionObserver> iObservers;
+ };
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfCompositionSource* CAlfCompositionSource::NewL(RWindow& aClientWindow)
+ {
+ CAlfCompositionSource* me = new (ELeave) CAlfCompositionSource();
+ CleanupStack::PushL(me);
+ me->ConstructL(aClientWindow);
+ CleanupStack::Pop(me);
+ return me;
+ }
+
+// ---------------------------------------------------------------------------
+// ~CAlfCompositionSource
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfCompositionSource::~CAlfCompositionSource()
+ {
+ delete iData;
+ iData = NULL;
+ }
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionSource::ConstructL(TInt aWsHandle, TInt aGroupHandle, TInt aScreenNumber)
+ {
+ iData = CAlfCompositionSourceData::NewL();
+ RDebug::Print(_L("CAlfCompositionClientBase::ConstructL - %d"), iData );
+
+ User::LeaveIfError( SendEvent(KAlfCompositionSourceScreenNumber, &aScreenNumber, sizeof(TInt)));
+
+ TInt array[] = { 0, aWsHandle, aGroupHandle};
+ TInt handle = SendEvent(KAlfCompOpCreateSource, array, sizeof(array));
+ SetHandleL(handle);
+ }
+
+void CAlfCompositionSource::ConstructL(RWindow& aClientWindow)
+ {
+ ConstructL(aClientWindow.ClientHandle(), aClientWindow.WindowGroupId(), aClientWindow.ScreenNumber());
+ TSurfaceConfiguration surfaceConfigs;
+ User::LeaveIfError(aClientWindow.GetBackgroundSurface(surfaceConfigs));
+ surfaceConfigs.GetSurfaceId(iData->iSurfaceId);
+ if(iData->iSurfaceId.IsNull())
+ {
+ __ALFLOGSTRING( "CAlfCompositionSource::NewL - Window does not have background surface set - Leaving");
+ User::Leave(KErrNotFound);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CreatePermissionToken
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionSource::CreatePermissionToken(TInt aKey, TInt aPermissionFlags)
+ {
+ TInt array[] = {aKey, aPermissionFlags};
+ return SendEvent(KAlfCompOpCreateToken, array, sizeof(array));
+ }
+
+// ---------------------------------------------------------------------------
+// EnableAlpha
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionSource::EnableAlpha(TBool aEnable)
+ {
+ return SendEvent(KAlfCompOpEnableAlpha, &aEnable, sizeof(TInt));
+ }
+
+// ---------------------------------------------------------------------------
+// SetOpacity
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionSource::SetOpacity(TReal32 aOpacity) __SOFTFP
+ {
+ return SendEvent(KAlfCompOpSetOpacity, &aOpacity, sizeof(TReal32));
+ }
+
+// ---------------------------------------------------------------------------
+// SetRotation
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionSource::SetRotation(TInt aRotationInDegrees)
+ {
+ return SendEvent(KAlfCompOpSetRotation, &aRotationInDegrees, sizeof(TInt));
+ }
+
+// ---------------------------------------------------------------------------
+// SetZOrder
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionSource::SetZOrder(const CAlfCompositionClientBase& aNode, TBool aAbove, TInt aKey)
+ {
+ TInt array[] = {aNode.Handle(), aAbove, aKey};
+ return SendEvent(KAlfCompOpSetZOrder, array, sizeof(array));
+ }
+
+// ---------------------------------------------------------------------------
+// SetExtent
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionSource::SetExtent(const TRect& aRect, TInt aScreen)
+ {
+ TInt array[] = {aRect.iTl.iX,aRect.iTl.iY,aRect.iBr.iX,aRect.iBr.iY, aScreen,
+ iData->iSurfaceId.iInternal[0], iData->iSurfaceId.iInternal[1], iData->iSurfaceId.iInternal[2],
+ iData->iSurfaceId.iInternal[3]};
+ return SendEvent(KAlfCompOpSetExtent, array, sizeof(array));
+ }
+
+// ---------------------------------------------------------------------------
+// SetSourceRect
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionSource::SetSourceRect(const TRect& aRect)
+ {
+ TInt array[] = {aRect.iTl.iX,aRect.iTl.iY,aRect.iBr.iX,aRect.iBr.iY};
+ return SendEvent(KAlfCompOpSetSRect, array, sizeof(array));
+ }
+
+// ---------------------------------------------------------------------------
+// AddCompositionObserverL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionSource::AddCompositionObserverL(MAlfCompositionObserver& aObserver, TInt aScreenNumber)
+ {
+ if (iData->iObservers.Count() == 1 || aScreenNumber != 0)
+ { // TODO: support only single observer for now
+ // because we can't currently handle deletion of an observer
+ // during handle event properly (if there were more than one observers present)
+ User::Leave(KErrNotSupported);
+ }
+
+ TInt index = iData->iObservers.Find(&aObserver);
+ if (index == KErrNotFound)
+ {
+ iData->iObservers.AppendL(&aObserver);
+ }
+ RequestEventL(sizeof(TInt)); // enable notifications if not active yet
+ }
+
+// ---------------------------------------------------------------------------
+// RemoveObserver
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionSource::RemoveObserver(MAlfCompositionObserver& aObserver)
+ {
+ TInt index = iData->iObservers.Find(&aObserver);
+ if (index != KErrNotFound)
+ {
+ iData->iObservers.Remove(index);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SetIsBackgroundAnim
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionSource::SetIsBackgroundAnim(TBool aIsBg)
+ {
+ SendEvent(KAlfComOpSetBackgroundAnim, &aIsBg, sizeof(TBool));
+ }
+
+// ---------------------------------------------------------------------------
+// EnableKeyboard
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionSource::EnableKeyboard(TBool aEnable, TInt aScreen)
+ {
+ TInt array[] = {aEnable, aScreen};
+ SendEvent(KAlfCompOpEnableKb, array, sizeof(array));
+ }
+
+// ---------------------------------------------------------------------------
+// HandleEventL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionSource::HandleEventL(TInt aEventType, TAny* aEventData)
+ {
+ switch (aEventType)
+ {
+ case KAlfCompositionFrameReady:
+ {
+ for (TInt i = 0; i < iData->iObservers.Count(); i++)
+ {
+ iData->iObservers[i]->FrameReady(*static_cast<TInt*>(aEventData)); // todo multiple screens
+ }
+ break;
+ }
+ case KAlfCompositionLowOnGraphicsMemory:
+ {
+ for (TInt i = 0; i < iData->iObservers.Count(); i++)
+ {
+ iData->iObservers[i]->RunningLowOnGraphicsMemory(); // todo multiple screens
+ }
+ break;
+ }
+ case KAlfCompositionTargetHidden:
+ {
+ for (TInt i = 0; i < iData->iObservers.Count(); i++)
+ {
+ iData->iObservers[i]->CompositionTargetHidden(); // todo multiple screens
+ }
+ break;
+ }
+ case KAlfCompositionGoodOnGraphicsMemory:
+ {
+ TInt count = iData->iObservers.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ iData->iObservers[i]->GraphicsMemoryGood();
+ }
+ break;
+ }
+ case KAlfCompositionTargetVisible:
+ {
+ for (TInt i = 0; i < iData->iObservers.Count(); i++)
+ {
+ iData->iObservers[i]->CompositionTargetVisible(); // todo multiple screens
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionHost::NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfCompositionHost* CAlfCompositionHost::NewL(TInt aToken, TInt aKey)
+ {
+ CAlfCompositionHost* me = new (ELeave) CAlfCompositionHost();
+ CleanupStack::PushL(me);
+ me->ConstructL(aToken, aKey);
+ CleanupStack::Pop();
+ return me;
+ }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionHost::ConstructL(TInt aToken, TInt aKey)
+ {
+ iData = CAlfCompositionSourceData::NewL();
+ RDebug::Print(_L("CAlfCompositionClientBase::ConstructL - %d"), iData );
+
+ TInt array[] = { 0, aToken, aKey };
+ TInt result = SendEvent(KAlfCompOpBindSourceToToken, array, sizeof(array));
+ User::LeaveIfError(result);
+ SetHandleL(result);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+NONSHARABLE_CLASS( CSurfaceUpdateCallback ) : public CActive
+ {
+ public:
+
+ public:
+ CSurfaceUpdateCallback( CAlfCompositionPixelSource& aPixelSource, TInt aBufferNumber,
+ TInt aPriority): CActive(aPriority), iPixelSource(aPixelSource),
+ iBufferNumber(aBufferNumber) { CActiveScheduler::Add(this); };
+ ~CSurfaceUpdateCallback() { Cancel(); };
+ public:
+
+ void SetActive() {iStatus = KRequestPending; CActive::SetActive();};
+
+ void RunL()
+ {
+ if( iStatus == KErrNone )
+ {
+ SetActive();
+ if( !iPixelSource.DrawFrameL(iStatus, iBufferNumber) )
+ {
+ __ALFLOGSTRING( "CSurfaceUpdateCallBack::RunL - DrawFrameL returned EFalse -> Pause");
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ Cancel();
+ }
+ }
+ else
+ {
+ __ALFLOGSTRING1("CSurfaceUpdateCallBack::RunL %d", iStatus.Int());
+ iPixelSource.Suspend();
+ }
+
+
+ };
+ void DoCancel() { };
+
+ private: // Data
+ CAlfCompositionPixelSource& iPixelSource;
+ TInt iBufferNumber;
+ };
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+NONSHARABLE_CLASS(CAlfCompositionPixelSource::CAlfCompositionPixelSourceData):public CBase
+ {
+ public:
+
+ enum TPixelSourceStatus
+ {
+ EActive = 0, // drawing loop running
+ EPaused = 1, // drawing paused but resources are still reserved
+ ESuspended = 2 // drawing suspended and surface related resources freed until activated again
+ };
+
+ static CAlfCompositionPixelSourceData* NewL(MAlfBufferProvider& aProvider)
+ {
+ CAlfCompositionPixelSourceData* me = new (ELeave) CAlfCompositionPixelSourceData(aProvider);
+ return me;
+ }
+
+
+ CAlfCompositionPixelSourceData(MAlfBufferProvider& aProvider) :
+ iProvider( aProvider), iSourceStatus(ESuspended) {iSurfaceId.CreateNullId();}
+
+ ~CAlfCompositionPixelSourceData()
+ {
+ if(iWindow && iSourceStatus != ESuspended)
+ {
+ iWindow->RemoveBackgroundSurface(ETrue);
+ }
+
+ if(iSourceStatus != ESuspended)
+ {
+ iSurfaceUpdateSession.CancelAllUpdateNotifications();
+ }
+
+ iSurfaceUpdateSession.Close();
+
+ if(iSurfaceManager)
+ {
+ iSurfaceManager->CloseSurface(iSurfaceId);
+ iSurfaceManager->Close();
+ delete iSurfaceManager;
+ }
+
+ if(iSurfaceChunk)
+ {
+ iSurfaceChunk->Close();
+ delete iSurfaceChunk;
+ }
+
+ if(iSurfaceUpdateWaiter && iSurfaceUpdateWaiter->IsActive())
+ {
+ iSurfaceUpdateWaiter->Cancel();
+ }
+ delete iSurfaceUpdateWaiter;
+
+ }
+ MAlfBufferProvider& iProvider;
+
+ TPixelSourceStatus iSourceStatus;
+
+ RSurfaceUpdateSession iSurfaceUpdateSession;
+ TSurfaceId iSurfaceId;
+ RSurfaceManager* iSurfaceManager;
+ RChunk* iSurfaceChunk;
+
+ // Not owned
+ RWindow* iWindow;
+
+ TUint8* iSurfaceBuffer;
+
+ CSurfaceUpdateCallback* iSurfaceUpdateWaiter;
+
+ TInt iCurrentBuffer;
+
+ TRect iSurfaceRect;
+ };
+
+
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfCompositionPixelSource* CAlfCompositionPixelSource::NewL(MAlfBufferProvider& aProvider, RWindow* aWindow)
+ {
+ CAlfCompositionPixelSource* me = new (ELeave) CAlfCompositionPixelSource();
+ CleanupStack::PushL(me);
+ me->ConstructL(aProvider, aWindow);
+ CleanupStack::Pop(me);
+ return me;
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::ActivateL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionPixelSource::ActivateL()
+ {
+ if( !iData->iWindow && iData->iSurfaceId.IsNull() )
+ {
+ User::Leave(KErrNotReady);
+ }
+
+ if( iData->iSourceStatus == CAlfCompositionPixelSourceData::ESuspended )
+ {
+ MAlfBufferProvider::TBufferCreationAttributes& creationAttribs = iData->iProvider.BufferAttributes();
+
+ iData->iSurfaceRect = TRect(TPoint(0,0), TSize(creationAttribs.iWidth, creationAttribs.iHeight));
+
+ ConstructSurfaceL(creationAttribs);
+
+ iData->iWindow->SetBackgroundSurface(iData->iSurfaceId);
+
+ TInt array[] = { 0, iData->iWindow->ClientHandle(), iData->iWindow->WindowGroupId() };
+ TInt handle = SendEvent(KAlfCompOpCreateSource, array, sizeof(array));
+ CAlfCompositionClientBase::SetHandleL( handle );
+
+ User::LeaveIfError( iData->iSurfaceUpdateSession.Connect() );
+ }
+
+ if( iData->iSourceStatus != CAlfCompositionPixelSourceData::EActive )
+ {
+ if( !iData->iSurfaceUpdateWaiter )
+ {
+ iData->iSurfaceUpdateWaiter = new (ELeave) CSurfaceUpdateCallback( *this, 0, CActive::EPriorityIdle );
+ }
+
+ iData->iSurfaceUpdateWaiter->SetActive();
+ TRequestStatus* status = &iData->iSurfaceUpdateWaiter->iStatus;
+ User::RequestComplete(status, KErrNone);
+
+ iData->iProvider.OnActivation();
+ iData->iSourceStatus = CAlfCompositionPixelSourceData::EActive;
+ }
+
+ // do nothing if content was already active
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::Suspend
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfCompositionPixelSource::Suspend()
+ {
+ if(iData->iSourceStatus != CAlfCompositionPixelSourceData::ESuspended)
+ {
+ iData->iProvider.ContextAboutToSuspend();
+
+ TInt error = SendEvent(KAlfCompOpSessionClosed,0,0);
+
+ // todo: what if error != KErrNone
+
+ FreeSurface();
+
+ if(iData->iSurfaceUpdateWaiter && iData->iSurfaceUpdateWaiter->IsActive())
+ {
+ iData->iSurfaceUpdateWaiter->Cancel();
+ }
+
+
+ iData->iSourceStatus = CAlfCompositionPixelSourceData::ESuspended;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::CAlfCompositionPixelSource
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfCompositionPixelSource::~CAlfCompositionPixelSource()
+ {
+ Suspend();
+ delete iData;
+ iData = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::SetExtent
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfCompositionPixelSource::SetExtent(const TRect& aRect, TInt aScreen)
+ {
+ TInt error = KErrNone;
+ if(iData->iSurfaceId.IsNull() && !iData->iWindow)
+ {
+ //create surface as client did not supply window
+ MAlfBufferProvider::TBufferCreationAttributes& creationAttribs = iData->iProvider.BufferAttributes();
+
+ iData->iSurfaceRect = TRect(TPoint(0,0), TSize(creationAttribs.iWidth, creationAttribs.iHeight));
+
+ TRAP(error, ConstructSurfaceL(creationAttribs) );
+
+ if( error == KErrNone )
+ {
+ error = iData->iSurfaceUpdateSession.Connect();
+ iData->iSourceStatus = CAlfCompositionPixelSourceData::EPaused;
+ }
+ }
+
+ if( error == KErrNone )
+ {
+ TInt array[] = {aRect.iTl.iX,aRect.iTl.iY,aRect.iBr.iX,aRect.iBr.iY, aScreen,
+ iData->iSurfaceId.iInternal[0], iData->iSurfaceId.iInternal[1], iData->iSurfaceId.iInternal[2],
+ iData->iSurfaceId.iInternal[3]};
+ error = SendEvent(KAlfCompOpSetExtent, array, sizeof(array));
+ }
+ return error;
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionPixelSource::ConstructL(MAlfBufferProvider& aProvider, RWindow* aWindow)
+ {
+ iData = CAlfCompositionPixelSourceData::NewL( aProvider );
+ TInt screenNumber = KErrNotFound;
+ if( aWindow )
+ {
+ iData->iWindow = aWindow;
+ screenNumber = aWindow->ScreenNumber();
+ }
+ else // let's just initialize baseclass and wait for client to call SetExtent
+ {
+ iData->iWindow = NULL;
+ }
+ // construct the base class
+ CAlfCompositionSource::ConstructL(0, 0, screenNumber);
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::ConstructSurfaceL
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionPixelSource::ConstructSurfaceL(MAlfBufferProvider::TBufferCreationAttributes& aCreationAttributes)
+ {
+ TSize size(aCreationAttributes.iWidth, aCreationAttributes.iHeight);
+
+ TUidPixelFormat surfaceFormat = EUidPixelFormatUnknown;
+ switch (aCreationAttributes.iFormat)
+ {
+ case MAlfBufferProvider::ESourceFormatRGB_565:
+ surfaceFormat = EUidPixelFormatRGB_565;
+ break;
+ case MAlfBufferProvider::ESourceFormatXRGB_8888:
+ surfaceFormat = EUidPixelFormatXRGB_8888;
+ break;
+ case MAlfBufferProvider::ESourceFormatARGB_8888:
+ surfaceFormat = EUidPixelFormatARGB_8888;
+ break;
+ case MAlfBufferProvider::ESourceFormatARGB_8888_PRE:
+ surfaceFormat = EUidPixelFormatARGB_8888_PRE;
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ break;
+ }
+
+ TInt err = KErrNone;
+ if(!iData->iSurfaceManager)
+ {
+ iData->iSurfaceManager = new RSurfaceManager();
+ User::LeaveIfNull(iData->iSurfaceManager);
+
+ err = iData->iSurfaceManager->Open();
+ User::LeaveIfError(err);
+
+ RSurfaceManager::TSurfaceCreationAttributesBuf attributes;
+ attributes().iPixelFormat = surfaceFormat;
+ attributes().iSize = size;
+ attributes().iBuffers = 1;
+ attributes().iStride = aCreationAttributes.iStride;
+ attributes().iAlignment = aCreationAttributes.iAlignment;
+ attributes().iContiguous = ETrue;
+ attributes().iMappable = ETrue;
+
+ // Create surface
+ err = iData->iSurfaceManager->CreateSurface(attributes, iData->iSurfaceId);
+ User::LeaveIfError(err);
+ }
+
+ if(!iData->iSurfaceChunk)
+ {
+ // Map to chunk
+ iData->iSurfaceChunk = new RChunk();
+ User::LeaveIfNull(iData->iSurfaceChunk);
+ err = iData->iSurfaceManager->MapSurface(iData->iSurfaceId, *iData->iSurfaceChunk);
+ User::LeaveIfError(err);
+ }
+
+ // Get the info from the surfaceManager
+ RSurfaceManager::TInfoBuf info;
+ err = iData->iSurfaceManager->SurfaceInfo(iData->iSurfaceId, info);
+ User::LeaveIfError(err);
+ RSurfaceManager::TSurfaceInfoV01 surfaceInfo = info();
+ aCreationAttributes.iStride = surfaceInfo.iStride;
+
+ TInt offset = 0;
+ iData->iSurfaceManager->GetBufferOffset(iData->iSurfaceId, 0, offset);
+
+ // Store pointer to the pixel data
+ iData->iSurfaceBuffer = iData->iSurfaceChunk->Base() + offset;
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::FreeSurface
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionPixelSource::FreeSurface()
+ {
+ if(iData->iWindow && iData->iSourceStatus != CAlfCompositionPixelSourceData::ESuspended)
+ {
+ iData->iWindow->RemoveBackgroundSurface(ETrue);
+ iData->iWindow->Session()->Flush();
+ }
+
+ if(iData->iSourceStatus != CAlfCompositionPixelSourceData::ESuspended)
+ {
+ iData->iSurfaceUpdateSession.CancelAllUpdateNotifications();
+ }
+ iData->iSurfaceUpdateSession.Close();
+
+ if(iData->iSurfaceManager)
+ {
+ iData->iSurfaceManager->CloseSurface(iData->iSurfaceId);
+ iData->iSurfaceManager->Close();
+ delete iData->iSurfaceManager;
+ iData->iSurfaceManager = NULL;
+ }
+
+ iData->iSurfaceId = TSurfaceId::CreateNullId();
+
+ if(iData->iSurfaceChunk)
+ {
+ iData->iSurfaceChunk->Close();
+ delete iData->iSurfaceChunk;
+ iData->iSurfaceChunk = NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::Buffer
+// ---------------------------------------------------------------------------
+//
+TUint8* CAlfCompositionPixelSource::Buffer(TInt /*aBufferNumber*/)
+ {
+ return iData->iSurfaceBuffer;
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::DrawFrameL
+// ---------------------------------------------------------------------------
+//
+TBool CAlfCompositionPixelSource::DrawFrameL(TRequestStatus& aStatus, TInt aBufferNumber)
+ {
+ // Region indicates the currently visible region of the surface. The information is not yet available.
+ RRegion region;
+ region.AddRect(iData->iSurfaceRect);
+ TUint8* buffer = Buffer(aBufferNumber);
+ TBool draw = iData->iProvider.ProduceNewFrameL(region, buffer);
+ if(draw)
+ {
+ iData->iSurfaceUpdateSession.NotifyWhenAvailable(aStatus);
+
+ iData->iSurfaceUpdateSession.SubmitUpdate(KAllScreens, iData->iSurfaceId, aBufferNumber);
+ }
+ else
+ {
+ iData->iSourceStatus = CAlfCompositionPixelSourceData::EPaused;
+ }
+ region.Close();
+ return draw;
+ }
+
+// ---------------------------------------------------------------------------
+// CAlfCompositionPixelSource::HandleEventL
+// ---------------------------------------------------------------------------
+//
+void CAlfCompositionPixelSource::HandleEventL(TInt aEventType, TAny* aEventData)
+ {
+ switch (aEventType)
+ {
+ case KAlfCompositionFrameReady:
+ {
+ // do nothing for now
+ }
+ break;
+ case KAlfCompositionLowOnGraphicsMemory:
+ case KAlfCompositionTargetHidden:
+ {
+ // suspend drawing
+ Suspend();
+ }
+ break;
+ default:
+ break;
+ }
+ // call base class
+ CAlfCompositionSource::HandleEventL( aEventType, aEventData );
+ }
+
+//end of file