diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/plugins/openwfcrs/src/displayrenderstage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/plugins/openwfcrs/src/displayrenderstage.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,1207 @@ +// Copyright (c) 2007-2009 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 "displayrenderstage.h" +#include +#include +#include "openwfcwrapper.h" +#include "panic.h" +#include "utils.h" +#include "rsdisplaychangeao.h" +#include +#include +#include +#include "screencaptureutil.h" +#include "elementwrapper.h" +#include "alfdecoderserverclient.h" +#include "huiwscanvascommands.h" + +#include "alflogger.h" + +CDisplayRenderStage* CDisplayRenderStage::NewL(MWsGraphicDrawerEnvironment* aEnv,MWsScreen* aScreen, TInt aScreenNumber) + { + CDisplayRenderStage* stage = new(ELeave) CDisplayRenderStage(aScreenNumber); + CleanupStack::PushL(stage); + stage->ConstructL(aEnv, aScreen, aScreenNumber); + CleanupStack::Pop(stage); + return stage; + } + +CDisplayRenderStage::CDisplayRenderStage(TInt aScreenNumber) + : iScreenNumber(aScreenNumber) + { + } + +CDisplayRenderStage::~CDisplayRenderStage() + { + iSurfaceUpdateSession.Close(); + iUpdateRegion = NULL; + delete iDispNotifier; + delete iConfigNotifier; + delete iDisplayPolicy; + delete iOpenWfcWrapper; + delete iScreenCaptureUtil; + } + +void CDisplayRenderStage::ConstructL(MWsGraphicDrawerEnvironment* aEnv, MWsScreen* aScreen, TInt aScreenNumber) + { + BaseConstructL(); + + MWsIniFile* iniFile = aEnv->ObjectInterface(); + STD_ASSERT_ALWAYS(iniFile, EPluginPanicIniFileMissing); + + //Initialise display policy and strategy segments + iDisplayPolicy = CDisplayPolicy::NewL(aEnv,aScreen, aScreenNumber); + iDisplayPolicyEnabled = iDisplayPolicy->PolicyEnabled(); + // initialize compositor + iOpenWfcWrapper = COpenWfcWrapper::NewL(aScreenNumber, iDisplayPolicy); + iOpenWfcWrapperDisplayControl = iOpenWfcWrapper->GetInterface(); + if(iOpenWfcWrapperDisplayControl) + { + iDispNotifier = CRsDisplayChangeNotifier::NewL(iOpenWfcWrapperDisplayControl, iDisplayPolicy); + iDispNotifier->IssueNotificationRequest(); + iConfigNotifier = CRsConfigChangeNotifier::NewL(iOpenWfcWrapperDisplayControl); + iConfigNotifier->IssueNotificationRequest(); + + //calculate min UI buffer size depending on physical resolutions + TInt ret = iOpenWfcWrapperDisplayControl->NumberOfResolutions(); + RArray resolutions; + CleanupClosePushL(resolutions); + if(ret > 0) + { + User::LeaveIfError(resolutions.Reserve(ret)); + User::LeaveIfError(iOpenWfcWrapperDisplayControl->GetResolutions(resolutions)); + } + iDisplayPolicy->CalculateMinBufferSize(resolutions, ret); + CleanupStack::PopAndDestroy(&resolutions); + } + + TSize screenSize = iOpenWfcWrapper->ScreenSize(); + iDisplayPolicy->AdjustStageBufferSize(TSize(0,0), screenSize); + + User::LeaveIfError(iSurfaceUpdateSession.Connect()); + + TDisplayConfiguration displayConfig; + if(iOpenWfcWrapperDisplayControl) + { + iOpenWfcWrapper->GetConfiguration(displayConfig); + } + else + { + displayConfig.SetResolution(SizeInPixels()); // Both getters eventually reach RDisplayChannel + displayConfig.SetResolutionTwips(SizeInTwips());// as iOpenWfcWrapper->GetConfiguration does + const MWsScene::TSceneRotation rotation = iOpenWfcWrapper->ScreenRotation(); + displayConfig.SetRotation(static_cast(rotation)); + } + iDisplayPolicy->SetCompositionInfo(displayConfig,displayConfig); //1 to 1 mapping + } + +TAny* CDisplayRenderStage::ResolveObjectInterface(TUint aTypeId) + { + switch(aTypeId) + { + case MWsScreenDevice::EWsObjectInterfaceId: + return static_cast(this); + case MWsScene::EWsObjectInterfaceId: + return static_cast(this); + case MWsDisplayControl::EWsObjectInterfaceId: +//#ifndef FAKE_DISPLAY_CONFIGURATION_FOR_SINGLE_DISPLAY +// if (iOpenWfcWrapperDisplayControl) +//#endif +// { //only support the interface if the compositor does + //otherwise we need to fake single-element support. + return static_cast(this); +// } +// break; + case MWsDisplayMapping::EWsObjectInterfaceId: + return static_cast(this); + case MWsWindowTreeObserver::EWsObjectInterfaceId: + return static_cast(this); + case KAlfCompositionControllerIfUid: + return static_cast(this); + case MWsDisplayPolicy::EWsObjectInterfaceId: + { + if (iDisplayPolicyEnabled) + { + return static_cast(this); + } + else + { + return NULL; + } + } + } + + return CWsRenderStage::ResolveObjectInterface(aTypeId); + } + +void CDisplayRenderStage::Begin(const TRegion* aRegion) + { + STD_ASSERT_DEBUG(!aRegion || !aRegion->CheckError(), EPluginPanicRegionError); + iUpdateRegion = aRegion; + iOpenWfcWrapper->Begin(aRegion); + } + +void CDisplayRenderStage::End(TRequestStatus* aFinished) + { + if (!iOpenWfcWrapper->CompositionDue() && aFinished) + { + // No re-composition required and the update region is empty. + // Signal that we are ready for more updates. + *aFinished = KRequestPending; + User::RequestComplete(aFinished, KErrNone); + } + else + { + iOpenWfcWrapper->Compose(aFinished); + } + + iOpenWfcWrapper->End(); + iUpdateRegion = NULL; + } + +TInt CDisplayRenderStage::ScreenNumber() const + { + return iScreenNumber; + } + +TDisplayMode CDisplayRenderStage::DisplayMode() const + { + return EColor16MAP;//iRenderTarget->DisplayMode(); + } + +TSize CDisplayRenderStage::SizeInPixels() const + { + TSize size(0, 0); + if (iOpenWfcWrapperDisplayControl) + { + size=iDisplayPolicy->GetUiResolution(); + } + return size; + } + +TSize CDisplayRenderStage::SizeInTwips() const + { + if (iOpenWfcWrapperDisplayControl) + { + TSize size(0, 0); + size = iDisplayPolicy->GetUiResolutionAsTwips(); + if (size.iWidth) + { + return size; + } + } + const TSize size = SizeInPixels(); + const MWsScene::TSceneRotation screenRotation = iOpenWfcWrapper->ScreenRotation(); + const TBool rotated = (screenRotation == ESceneAntiClockwise90 || screenRotation == ESceneAntiClockwise270); + + TInt twips = 0; + TInt res = HAL::Get(iScreenNumber, rotated ? HALData::EDisplayYTwips : HALData::EDisplayXTwips,twips); + __ASSERT_DEBUG(res==KErrNone && twips!=0, Panic(EPluginPanicSizeInTwipsFailed)); + const TInt horzTwipsPerThousandPixels = twips * 1000 / size.iWidth; + const TInt horzSizeInTwips = (horzTwipsPerThousandPixels * size.iWidth + 500) / 1000; + + twips = 0; + res = HAL::Get(iScreenNumber, rotated ? HALData::EDisplayXTwips : HALData::EDisplayYTwips,twips); + __ASSERT_DEBUG(res==KErrNone && twips!=0, Panic(EPluginPanicSizeInTwipsFailed)); + const TInt vertTwipsPerThousandPixels = twips * 1000 / size.iHeight; + const TInt vertSizeInTwips = (vertTwipsPerThousandPixels * size.iHeight + 500) / 1000; + + return TSize (horzSizeInTwips, vertSizeInTwips); + } + +TRect CDisplayRenderStage::PointerRect() const + { + if (iScreenNumber != 0) + { + return TRect(); // Only screen 0 supports a digitizer + } + + TMachineInfoV1Buf macInfo; + UserHal::MachineInfo(macInfo); + return TRect(-macInfo().iOffsetToDisplayInPixels, macInfo().iXYInputSizeInPixels); + } + +void CDisplayRenderStage::GetPixel(TRgb& /*aColor*/, const TPoint& /*aPixel*/) const + { + //iRenderTarget->GetPixel(aColor, aPixel); + } + +void CDisplayRenderStage::GetScanLine(TDes8& /*aScanLine*/, const TPoint& /*aStartPixel*/, TInt /*aPixelLength*/, TDisplayMode /*aDispMode*/) const + { + //iRenderTarget->GetScanLine(aScanLine, aStartPixel, aPixelLength, aDispMode); + } + +TBool CDisplayRenderStage::RectCompare(const TRect& /*aRect1*/, const TRect& /*aRect2*/) const + { + return EFalse;//iRenderTarget->RectCompare(aRect1, aRect2); + } + +void doDynamicCaptureL(CDisplayRenderStage* aThis, CFbsBitmap* aBitmap) + { + if (!aThis->iScreenCaptureUtil) + { + aThis->iScreenCaptureUtil = CScreenCaptureUtil::NewL(aThis); + } + aThis->iScreenCaptureUtil->ComposeScreenL(aBitmap->Handle()); + } + +void CDisplayRenderStage::CopyScreenToBitmapL(CFbsBitmap* aBitmap, const TRect& /*aRect*/) const + { + if (iRunningOnLowMem) + { + User::Leave(KErrNoMemory); + } + + if ( aBitmap->ExtendedBitmapType() != KNullUid ) + { + User::Leave(KErrArgument); + } + + doDynamicCaptureL((CDisplayRenderStage*)this, aBitmap); + } + +MWsElement* CDisplayRenderStage::CreateSceneElementL() + { + return iOpenWfcWrapper->CreateElementL(); + } + +void CDisplayRenderStage::DestroySceneElement(MWsElement* aElement) + { + iOpenWfcWrapper->DestroyElement(aElement); + } + +TInt CDisplayRenderStage::InsertSceneElement(MWsElement* aInsertElement, MWsElement* aSubordinateElement) + { + if (aInsertElement) + { +#ifdef USE_UI_SURFACE_FOR_ALF + TUint32 flags(0); + aInsertElement->GetRenderStageFlags(flags); + if ( flags & MWsElement::EElementIsIndirectlyRenderedUserInterface) + { + iUiElement = aInsertElement; + if (!iAlfElement) + { + __ALFLOGSTRING("CDisplayRenderStage: Skipping UI element for now"); + return KErrNone; + } + } + } +#endif + return iOpenWfcWrapper->AddElement(aInsertElement, aSubordinateElement); + } + +TInt CDisplayRenderStage::RemoveSceneElement(MWsElement* aRemoveElement) + { + iOpenWfcWrapper->RemoveElement(aRemoveElement); + return KErrNone; + } + +void CDisplayRenderStage::ComposePendingScene(TSurfaceId& aOffScreenTarget, TRequestStatus* aCompleted) + { + /* + * If the supplied off-screen target is NULL and If the optionally provided TRequestStatus + * is present, signal immediately and return. + */ + if (aOffScreenTarget.IsNull()) + { + if (aCompleted) + { + User::RequestComplete(aCompleted, KErrArgument); + return; + } + } + + iOpenWfcWrapper->RegisterSurface(aOffScreenTarget); + iOpenWfcWrapper->Compose(aOffScreenTarget, aCompleted); + iOpenWfcWrapper->UnregisterSurface(aOffScreenTarget); + } + +TInt CDisplayRenderStage::SetSceneRotation(const MWsScene::TSceneRotation aSceneRotation) + { + const TSceneRotation oldRotation = iOpenWfcWrapper->ScreenRotation(); + + //rotate in compositor + iOpenWfcWrapper->SetScreenRotation(aSceneRotation); + +/* switch (aSceneRotation) + { + case ESceneAntiClockwise0: + case ESceneAntiClockwise180: + iRenderTarget->SetAspectRatio(CRenderTarget::ENormalAspectRatio); + break; + default: + iRenderTarget->SetAspectRatio(CRenderTarget::EInvertedAspectRatio); + } +*/ + TDisplayConfiguration rotate; + rotate.SetRotation((TDisplayConfiguration::TRotation)aSceneRotation); + iDisplayPolicy->SetCompositionInfo(rotate,rotate); + //update ui element + //const TSurfaceId& uiSurface = iRenderTarget->SurfaceId(); + //return iOpenWfcWrapper->SetUiSurface(uiSurface); + return KErrNone; + } + +MWsScene::TSceneRotation CDisplayRenderStage::SceneRotation() const + { + return iOpenWfcWrapper->ScreenRotation(); + } + +void CDisplayRenderStage::ClearDisplay(TRgb /*aBackColor*/) + { + } +// +// +// Implementation of MWsDisplayConfiguration/MDisplayConfiguration interface +// +// + + +void CDisplayRenderStage::NotifyOnDisplayChange(TRequestStatus& aStatus) + { + aStatus = KRequestPending; + if(iDispNotifier) + { + iDispNotifier->RegisterActiveStatus(aStatus); + } + else + { + TRequestStatus* reqPtr=&aStatus; //indirection is required + User::RequestComplete(reqPtr, KErrNotSupported); + } + } + +void CDisplayRenderStage::NotifyOnDisplayChangeCancel() + { + if(iDispNotifier) + { + iDispNotifier->CancelNotificationRequest(); + } + } + +void CDisplayRenderStage::NotifyOnConfigChange(TRequestStatus& aStatus) + { + aStatus = KRequestPending; + if(iConfigNotifier) + { + iConfigNotifier->RegisterActiveStatus(aStatus); + } + else + { + TRequestStatus* reqPtr=&aStatus; //indirection is required + User::RequestComplete(reqPtr, KErrNotSupported); + } + } + +void CDisplayRenderStage::NotifyOnConfigChangeCancel() + { + if(iConfigNotifier) + { + iConfigNotifier->CancelNotificationRequest(); + } + } + +/** Determine the display configuration and application rendering + offset to use for a given screen size mode. + + The Window Server uses this function when a request to change to a + new screen size mode or new display configuration is made by a + client. The display configuration passed in may be partially filled, + and the combination of the defined entries in it and the requested + screen size mode values shall be used to define the rest of the + configuration and new application offset to be used. + + Only undefined entries in the configuration may be set by this + function. Entries already defined must retain the same values. If + the combination of defined entries and size mode values is not + acceptable to the implementer, the function shall return EFalse. + + If the function returns ETrue, the Window Server shall set the + returned display configuration, notify render stages of the new + application offset and change to use the screen size mode. If + either this function returns EFalse or the call to set the display + configuration fails for any reason (such as KErrNoMemory, for + example), then no further changes are made. + + @see MWsScreenConfigList + + @param aScreenSizeMode The requested screen size mode. If static, + the size in pixels, size in twips, and the rotation must be + respected. If dynamic, only the rotation must be respected. + @param aConfig The requested display configuration on input, the + required configuration on return. Only undefined entries may be set. + + @param aSizeModePosition The screen size mode offset and size to be filled in + + @return KErrNone if no error, otherwise a system wide error code +*/ +TInt CDisplayRenderStage::GetSizeModeConfiguration(TInt aScreenSizeMode, TDisplayConfiguration& aConfig, TRect& aSizeModePosition) const + { + TInt reply; + RArray resolutions; + reply = iOpenWfcWrapperDisplayControl->GetResolutions(resolutions); + if (reply < KErrNone && + reply != KErrDisconnected) + { + resolutions.Close(); + return reply; + } + TBool isDisconnected=EFalse; + if (reply == KErrDisconnected || resolutions.Count() == 0) + { + isDisconnected=ETrue; + } + else if (resolutions.Count() == 1 && resolutions[0].iPixelSize==TSize(0,0)) + { + isDisconnected=ETrue; + } + + if (isDisconnected) + {//in this case aScreenSizeMode should be the smallest app mode + reply = iDisplayPolicy->GetSizeModeConfiguration(aScreenSizeMode, aConfig, aSizeModePosition); + } + else + { + reply = iDisplayPolicy->GetSizeModeConfiguration(resolutions,aScreenSizeMode,aConfig,aSizeModePosition); + } + + resolutions.Close(); + return reply; + } + +void CDisplayRenderStage::SetSizeModeExtent(TRect& aExtent, TBitFlags32 aContext) + { + if (aContext.iFlags&KOffMap) + { + iDisplayPolicy->SetSizeModeExtent(aExtent,aContext); + aContext.iFlags&=~KOffMap; + } +/* if (aContext.iFlags&KOffGc) + { + iRenderTarget->SetDrawDeviceOffset(aExtent.iTl); + aContext.iFlags&=~KOffGc; + }*/ + //Could chain through again if required? + } + +TInt CDisplayRenderStage::NumberOfResolutions() const + { + if(iOpenWfcWrapperDisplayControl) + { + TInt returnValue = iOpenWfcWrapperDisplayControl->NumberOfResolutions(); + iDisplayPolicy->AddVirtualResolutionCount(returnValue); + return returnValue; + } +#ifdef FAKE_DISPLAY_CONFIGURATION_FOR_SINGLE_DISPLAY + return 1; +#else + return KErrNotSupported; +#endif + } + +TInt CDisplayRenderStage::GetResolutions(RArray& aResolutions) const + { + if(iOpenWfcWrapperDisplayControl) + { + TInt returnValue = iOpenWfcWrapperDisplayControl->GetResolutions(aResolutions); + if (returnValue >= KErrNone) + { + //add virtual resolutions + returnValue = iDisplayPolicy->AddVirtualResolutions(aResolutions); + } + return returnValue; + } + return KErrNotSupported; + } + + +void CDisplayRenderStage::GetConfiguration(TDisplayConfiguration& aConfig) const + { + aConfig.ClearAll(); + if(iOpenWfcWrapperDisplayControl) + { + iOpenWfcWrapperDisplayControl->GetConfiguration(aConfig); + if (aConfig.IsDefined(aConfig.EResolution)) + { + TSize uiRes=iDisplayPolicy->GetUiResolution(); + TDisplayConfiguration::TRotation rotation; + if(aConfig.GetRotation(rotation)) + { + if(rotation&TDisplayConfiguration::ERotation90CW) + { + TInt height = uiRes.iHeight; + uiRes.iHeight = uiRes.iWidth; + uiRes.iWidth = height; + } + } + if (uiRes.iWidth) + { + aConfig.SetResolution(uiRes); + } + } + } + } + +TInt CDisplayRenderStage::SetConfigurationAndBuffer(const TDisplayConfiguration& /*aConfig*/,const TSize* /*aUiSize*/) + { +/* //May need to resize the FB buffer + TInt result = KErrNone; + TSize reqUiSize; + TBool reallocBuffer=EFalse; + TSize newFbSize; + + RWsOffScreenImageTarget newTarget; + if (aUiSize) + { + newFbSize=*aUiSize; + + iDisplayPolicy->AdjustStageBufferSize(iRenderTarget->SizeInPixels(),newFbSize); + + //if realloc needed + //if (!(newFbSize == iRenderTarget->SizeInPixels())) + // { + // reallocBuffer = ETrue; + // result = iRenderTarget->AllocNewTarget(newTarget,newFbSize); //newFbSize should not be zero here. + // if (result < KErrNone) + // { + // newTarget.Close(); + // return result; + // } + // } + } + TDisplayConfiguration displayCopy; + iOpenWfcWrapper->GetConfiguration(displayCopy); + if (aConfig.IsDefined(aConfig.EResolution)||aConfig.IsDefined(aConfig.ERotation)) + { + result=iOpenWfcWrapper->FlushedSetConfiguration(aConfig); + } + if (resultFlushedSetConfiguration(displayCopy); + STD_ASSERT_DEBUG((tempResult==KErrNone)||(tempResult==KErrDisconnected),EPluginPanicTemp); + if (reallocBuffer) + { + newTarget.Close(); + } + } + else + { + if (reallocBuffer) + { + const TSurfaceId& uiSurface = newTarget.iImageCollections + [iRenderTarget->AspectRatio()].SurfaceId(); + result = iOpenWfcWrapper->SetUiSurface(uiSurface); + if (result == KErrNone) + { + iRenderTarget->SwitchTarget(newTarget); //now newTarget shouldn't be closed + } + else + { + TInt tempResult = iOpenWfcWrapper->FlushedSetConfiguration(displayCopy); + STD_ASSERT_DEBUG((tempResult==KErrNone)||(result==KErrDisconnected),EPluginPanicTemp); + newTarget.Close(); + } + } + } + return result; +*/ + return KErrNone; + } + +TInt CDisplayRenderStage::SetConfiguration(const TDisplayConfiguration& aConfig) + { + if(iOpenWfcWrapperDisplayControl) + { + + TInt returnValue = iOpenWfcWrapperDisplayControl->NumberOfResolutions(); + TBool success=EFalse; + //Both "no resolution" and KErrDisconnected are treated as disconnected + if(returnValue == KErrDisconnected || returnValue == 0) + { + //Ui Res is set to same as smallest appmode + //compsotion res is set to zero + + TSize uiSize; + TDisplayConfiguration emptyConvertedConfig; + emptyConvertedConfig.SetResolution(TSize(0,0)); + aConfig.GetResolution(uiSize); + returnValue=SetConfigurationAndBuffer(emptyConvertedConfig,&uiSize); + iDisplayPolicy->SetCompositionInfo(emptyConvertedConfig,aConfig); + return returnValue; + } + + TDisplayConfiguration convertedConfig(aConfig); + RArray resolutions; + returnValue = resolutions.Reserve(returnValue); + + if (returnValue < KErrNone) + { + resolutions.Close(); + return returnValue; + } + returnValue = iOpenWfcWrapperDisplayControl->GetResolutions(resolutions); + + if (returnValue < KErrNone) + { + resolutions.Close(); + return returnValue; + } + success = iDisplayPolicy->SettingConfiguration(resolutions,convertedConfig); //if virtual, converts to real + resolutions.Close(); + + TSize uiSize; + TBool isUiSize = aConfig.GetResolution(uiSize); + if (success) + { + TInt reply; + if (isUiSize) + { + reply=SetConfigurationAndBuffer(convertedConfig,&uiSize); + } + else + { + reply=SetConfigurationAndBuffer(convertedConfig,NULL); + } + if (reply>=KErrNone) + { + iDisplayPolicy->SetCompositionInfo(convertedConfig,aConfig); +// iBitGcWrapper->BitGc().Activate(iScreenDevice); + } + return reply; + } + else + { + TSize tempSize; + + if (!convertedConfig.GetResolution(tempSize)) + { //signals the config is totally invalid and should not be used + return KErrArgument; + } + TInt reply; + if (isUiSize) + { + reply=SetConfigurationAndBuffer(convertedConfig,&uiSize); + } + else + { + reply=SetConfigurationAndBuffer(convertedConfig,NULL); + } + if (reply>=KErrNone) + { + iDisplayPolicy->SetCompositionInfo(aConfig,aConfig); +// iBitGcWrapper->BitGc().Activate(iScreenDevice); + } + return reply; + } + } + else + { //This will never work when faked + return KErrNotSupported; + } + } + +TInt CDisplayRenderStage::PreferredDisplayVersion() const + { + if(iOpenWfcWrapperDisplayControl) + { + return iOpenWfcWrapperDisplayControl->PreferredDisplayVersion(); + } + else + { +#ifdef FAKE_DISPLAY_CONFIGURATION_FOR_SINGLE_DISPLAY + return TDisplayConfiguration().Version(); +#else + return KErrNotSupported; +#endif + } + } +TInt CDisplayRenderStage::MapCoordinates(TCoordinateSpace aSourceSpace, const TRect& aSource, TCoordinateSpace aTargetSpace, TRect& aTarget) const + { + return iDisplayPolicy->MapCoordinates(aSourceSpace, aSource, aTargetSpace, aTarget); + } + +void CDisplayRenderStage::NewAppModesAvailable() + { + iDisplayPolicy->NewAppModesAvailable(); + } + +TInt CDisplayRenderStage::SuitableAppMode(TDisplayStatus aSituation) + { + return iDisplayPolicy->SuitableAppMode(aSituation); + } + +void CDisplayRenderStage::SetLastAppMode(TInt aMode) + { + iDisplayPolicy->SetLastAppMode(aMode); + } + +TInt CDisplayRenderStage::RegisterSurface(const TSurfaceId& aSurface) + { + return iOpenWfcWrapper->RegisterSurface(aSurface); + } + +TInt CDisplayRenderStage::UnregisterSurface(const TSurfaceId& aSurface) + { + return iOpenWfcWrapper->UnregisterSurface(aSurface); + } + +// --------------------------------------------------------------------------- +// EnableAlpha +// --------------------------------------------------------------------------- +// +TInt CDisplayRenderStage::EnableAlpha(TBool aEnable) + { + __ALFLOGSTRING2("CDisplayRenderStage::EnableAlpha - iTargetElement: %d, aEnable: %d", iTargetElement, aEnable); + if ( iTargetElement ) + { + TUint32 flags = 0; + iTargetElement->GetTargetRendererFlags(flags); + if ( aEnable ) + { + flags |= MWsElement::EElementTransparencySource; + } + else + { + flags ^= MWsElement::EElementTransparencySource; + } + iTargetElement->SetTargetRendererFlags(flags); + TRAP_IGNORE(ElementUseAlphaFlagChangedL(*iTargetElement, aEnable)); + } + return KErrNone; + } + + +void CDisplayRenderStage::ElementUseAlphaFlagChangedL(MWsElement& aElement, TBool aEnabled) + { + TElementData elementData(&aElement, TSurfaceId::CreateNullId(), 0, 0, 0); + TInt index = iElementArray.Find(elementData); + if ( index != KErrNotFound && iElementArray[index].iWindowTreeNodeId!=0 ) + { + TInt array[] = { + iElementArray[index].iWindowTreeNodeId, + aEnabled }; + iAlfBridge->WriteIntsL( + EAlfNodeLayerUsesAlphaFlagChanged, + 2, + array + ); + iAlfBridge->CommitL(); + __ALFLOGSTRING1("CDisplayRenderStage::ElementUseAlphaFlagChanged - aEnabled %d", aEnabled); + } + } + + +// --------------------------------------------------------------------------- +// SetOpacity +// --------------------------------------------------------------------------- +// +TInt CDisplayRenderStage::SetOpacity(TReal32 aOpacity) __SOFTFP + { + TInt error = KErrNone; + TInt opacity = 255*aOpacity; + __ALFLOGSTRING3("CDisplayRenderStage::SetOpacity - iTargetElement: %d, aOpacity %f, opacity %d", iTargetElement, aOpacity, opacity ); + if (iTargetElement) + { + TUint32 flags = 0; + iTargetElement->GetTargetRendererFlags(flags); + flags |= MWsElement::EElementTransparencyGlobalAlpha; + iTargetElement->SetTargetRendererFlags(MWsElement::EElementTransparencyGlobalAlpha); + iTargetElement->SetGlobalAlpha(opacity); + } + // Todo: Could do some real magic based for 0.. + return error; + } + +// --------------------------------------------------------------------------- +// SetRotation, Not in degrees !!! +// --------------------------------------------------------------------------- +// +TInt CDisplayRenderStage::SetRotation(TInt aRotation) + { + __ALFLOGSTRING2("CDisplayRenderStage::SetRotation - iTargetElement: %d, aRotation: %d ", iTargetElement, aRotation); + + MWsElement::TElementRotation rotation = + static_cast (aRotation); + + if (iTargetElement) + { + iTargetElement->SetSourceRotation(rotation); + } + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// SetExtent +// --------------------------------------------------------------------------- +// +TInt CDisplayRenderStage::SetExtent( + const TRect& aRect, +#ifdef _ALF_LOGGING + TInt aScreen) +#else + TInt) +#endif + { + __ALFLOGSTRING2("CDisplayRenderStage::SetExtent - %d %d ",aRect.iTl.iX,aRect.iTl.iY ); + __ALFLOGSTRING2("CDisplayRenderStage::SetExtent - %d %d ",aRect.iBr.iX,aRect.iBr.iY ); +#ifdef _ALF_LOGGING + __ALFLOGSTRING2("CDisplayRenderStage::SetExtent - iTargetElement: %d, aScreen: %d ", iTargetElement, aScreen ); +#endif + __ALFLOGSTRING1("CDisplayRenderStage::SetExtent - iScreenNumber %d ", iScreenNumber); + + TInt error = KErrNone; + TBool composeNeeded = EFalse; + if (iTargetElement) + { + iTargetElement->SetDestinationRectangle(aRect); + iTargetElement->SetDestinationClippingRect(aRect); + iExtentSurfaceId.CreateNullId(); // was not used -> reset + } + // window is not found from this screen, handle as extent without window if extent surface is set + // Todo. + return error; + } + +// --------------------------------------------------------------------------- +// SetIsBackgroundAnim +// --------------------------------------------------------------------------- +// +void CDisplayRenderStage::SetIsBackgroundAnim(TBool aValue ) + { + if( iTargetElement ) + { + iTargetElement->SetIsBackgroundAnim(aValue); + } + } + + +TInt CDisplayRenderStage::SetSourceRect(const TRect& aRect) + { + if( iTargetElement ) + { + iTargetElement->SetSourceRectangle(aRect); + } + return KErrNone; + } +// --------------------------------------------------------------------------- +// CreateTargetL +// --------------------------------------------------------------------------- +// +TInt CDisplayRenderStage::CreateTargetL(TInt aTarget, TInt aWsHandle, TInt aGroupHandle) + { + __ALFLOGSTRING2("CDisplayRenderStage::CreateTargetL - : %d, %d", aWsHandle, aGroupHandle ); + TInt result(KErrNotFound); + // find the element for this window + CElementWrapper* element = NULL; + + for (TInt i = 0; i < iElementArray.Count(); i++) + { + RDebug::Print(_L("CDisplayRenderStage::CreateTargetL - %d - %d - %d"), iElementArray[i].iWindowHandle, iElementArray[i].iWindowGrpId, iElementArray[i].iWindowTreeNodeId ); + + if (iElementArray[i].iWindowHandle == aWsHandle + && iElementArray[i].iWindowGrpId == aGroupHandle) + { + element = dynamic_cast(iElementArray[i].iElement); + break; + } + } + + if (element) + { + SElementTarget elementtarget; + elementtarget.iTarget = aTarget; + elementtarget.iElement = element; + result = iElementTargets.Append(elementtarget); + + // todo: is there need to lock target so that wserv does not accidentally overwrite the state from client + + __ALFLOGSTRING1("CDisplayRenderStage::CreateTargetL - client composition element count %d ", iElementTargets.Count() ); + } + return KErrNone; + } + +// --------------------------------------------------------------------------- +// SetTargetL +// --------------------------------------------------------------------------- +// +void CDisplayRenderStage::SetTargetL(TInt aTarget) + { + __ALFLOGSTRING1("CDisplayRenderStage::SetTargetL - %d ", aTarget ); + CElementWrapper* tmp = FindElementTarget(aTarget); + if (tmp) + { + __ALFLOGSTRING1("CDisplayRenderStage::SetTargetL - Found target ", aTarget ); + iTargetElement = tmp; + } + else + { + if (iTargetElement) + { // flush changes to composition when target is released + iTargetElement->FlushSceneChanges(); + } + iTargetElement = NULL; + __ALFLOGSTRING1("CDisplayRenderStage::SetTargetL - Target was not found!", aTarget ); + } + } + +void CDisplayRenderStage::SetTarget(MWsElement* aElement) + { + if (iTargetElement && !aElement) + { // flush changes when target is "freed" + iTargetElement->FlushSceneChanges(); + } + + //__ASSERT_DEBUG(!iTargetElement, USER_INVARIANT()) + iTargetElement = dynamic_cast(aElement); + } + +// --------------------------------------------------------------------------- +// SetExtentSurfaceId +// --------------------------------------------------------------------------- +// +void CDisplayRenderStage::SetExtentSurfaceId(const TSurfaceId& aSurfaceId) + { + iExtentSurfaceId = aSurfaceId; + } +// --------------------------------------------------------------------------- +// SetOrder +// --------------------------------------------------------------------------- +// +TInt CDisplayRenderStage::SetOrder(TInt /*aTarget*/, TInt /*aTop*/, TBool /*aAbove*/, TBool /*aCombineTargets*/) + { + TInt newKey = KErrNone; + // ToDo + return newKey; + } + +// --------------------------------------------------------------------------- +// DeleteTarget +// --------------------------------------------------------------------------- +// +void CDisplayRenderStage::DeleteTarget(TInt aTarget) + { + __ALFLOGSTRING1("CDisplayRenderStage::DeleteTarget - %d ", aTarget ); + // try to remove from the element targets + MWsElement* element = FindElementTarget(aTarget); + if(element) + { + // Todo: Should we restore some flags / state? + } + + for( TInt x = 0; x < iElementTargets.Count() ; x++) + { + if( iElementTargets[x].iTarget == aTarget ) + { + iElementTargets.Remove(x); + break; + } + } + + __ALFLOGSTRING1("CDisplayRenderStage::DeleteTarget - client composition element count %d ", iElementTargets.Count() ); + } + +void CDisplayRenderStage::LowOnGraphicsMemory() + { + __ALFLOGSTRING("void CDisplayRenderStage::LowOnGraphicsMemory()"); + iRunningOnLowMem = ETrue; + delete iScreenCaptureUtil; + iScreenCaptureUtil = 0; + } + +void CDisplayRenderStage::GraphicsMemoryGood() + { + __ALFLOGSTRING("void CDisplayRenderStage::GraphicsMemoryGood()"); + iRunningOnLowMem = EFalse; + } + +void CDisplayRenderStage::AlfBridgeCallback(TInt aEvent, TAny* aData) + { + switch(aEvent) + { + case MAlfBridge::EAlfBridgeCreated: + iAlfBridge = (MAlfBridge*) aData; + return; + case MAlfBridge::EAlfNativeWindowCreated: + AlfWindowListenerCallback((TAlfNativeWindowData*)aData); + return; + case MAlfBridge::ESetWindowTreeObserver: + iWindowTreeObserver = (MAlfCompositionAgnosticWindowTreeObserver*)aData; + return; + default: + break; + } + } +// --------------------------------------------------------------------------- +// AlfWindowListenerCallBack +// --------------------------------------------------------------------------- +// +#ifdef USE_UI_SURFACE_FOR_ALF +void CDisplayRenderStage::AlfWindowListenerCallback(TAlfNativeWindowData*) + { +#else +void CDisplayRenderStage::AlfWindowListenerCallback(TAlfNativeWindowData* aData) + { + // Got window and group id from Alf. + iAlfElement = FindElement(aData->iAlfWindowGrpId, aData->iAlfWindowHandle); + if (iAlfElement) + { + if (!(iAlfElement->ConnectedSurface().IsNull())) + { + // Found Alf Egl surface. Enable alpha on it to be able to create transparent holes. + SetTarget(iAlfElement); + EnableAlpha(); + SetOpacity(1.0f); + SetTarget(0); + iOpenWfcWrapper->SetUiSurface(iAlfElement->ConnectedSurface()) + } + } +#endif + } + +MWsElement* CDisplayRenderStage::FindElement(TInt aWindowGrpId, TInt aWindowHandle) + { + for(TInt index = 0; index < iElementArray.Count(); ++index) + { + if( (iElementArray[index].iWindowGrpId == aWindowGrpId) + && (iElementArray[index].iWindowHandle == aWindowHandle)) + { + return iElementArray[index].iElement; + } + } + return NULL; + } + +void CDisplayRenderStage::ElementAdded(const MWsWindowTreeNode& aWindowTreeNode, const MWsElement& aElement) + { + __ALFLOGSTRING1("CDisplayRenderStage::ElementAdded. iScreenNumber=%d", iScreenNumber); + + const MWsWindow* window = aWindowTreeNode.Window(); + TUint32 windowId = window->Handle(); + TInt windowGroupId = 0; + const MWsWindowTreeNode* parentWindowGroup = aWindowTreeNode.ParentNode(); + while (parentWindowGroup) + { + if (parentWindowGroup->NodeType() == MWsWindowTreeNode::EWinTreeNodeGroup) + { + windowGroupId = parentWindowGroup->WindowGroup()->Identifier(); +#ifdef USE_UI_SURFACE_FOR_ALF + if (iUiElement->ConnectedSurface() == TSurfaceId::CreateNullId() && + parentWindowGroup->WindowGroup()->Client() && + parentWindowGroup->WindowGroup()->Client()->SecureId() == RProcess().SecureId()) // ALF + { + iAlfElement = (MWsElement*) &aElement; + if (!(iAlfElement->ConnectedSurface().IsNull())) + { + // Found Alf Egl surface. Enable alpha on it to be able to create transparent holes. + SetTarget(iAlfElement); + EnableAlpha(); + SetOpacity(1.0f); + SetTarget(0); + iOpenWfcWrapper->SetUiSurface(iAlfElement->ConnectedSurface()); + if (iUiElement) + { + iUiElement->ConnectSurface(iAlfElement->ConnectedSurface()); + RemoveSceneElement(iAlfElement); + InsertSceneElement(iUiElement,0); + iAlfElement = iUiElement; + // Todo: do we need to compose manually to make change happen immediately + return; + } + } + } +#endif // #ifdef USE_UI_SURFACE_FOR_ALF + + break; + } + parentWindowGroup = parentWindowGroup->ParentNode(); + } + + // Store window handle and surface Id in an array + TInt index = KErrNotFound; + TUint32 nodeId = (TUint32)&aWindowTreeNode; + for(TInt i = 0; i < iElementArray.Count(); ++i) + { + if(iElementArray[i].iSurfaceId == aElement.ConnectedSurface()) + { + iElementArray[i].iWindowGrpId = windowGroupId; + iElementArray[i].iWindowHandle = windowId; + iElementArray[i].iWindowTreeNodeId = nodeId; + index = i; + break; + } + } + + __ALFLOGSTRING1("DisplayRenderStage::ElementAdded. index=%d", index); + if (index == KErrNotFound) + { + ASSERT(EFalse); + return; // error + } + + + //SetTarget(iElementArray[index].iElement); // Usefull for debugging + //SetOpacity(0.5f); + //SetTarget(0); + + __ALFLOGSTRING1("--aElement: %x", iElementArray[index].iElement); + __ALFLOGSTRING1("--iSurfaceId: %d", iElementArray[index].iSurfaceId); + __ALFLOGSTRING1("--iWindowHandle: %d", iElementArray[index].iWindowHandle); + __ALFLOGSTRING1("--iWindowTreeNodeId: %d", iElementArray[index].iWindowTreeNodeId); + + // Send EAlfNodeLayerAdded command that will set the surface extent to the visual + // Note : it is not necessary to send EAlfNodeLayerAdded command in Alf EGL surface Element case + // but it should not do any harm either. + TRect extent; + aElement.GetDestinationRectangle( extent ); + TInt array[] = { + nodeId, + extent.iTl.iX, + extent.iTl.iY, + extent.iBr.iX, + extent.iBr.iY + }; + iAlfBridge->WriteIntsL( + EAlfNodeLayerAdded, + 5, + array ); + iAlfBridge->CommitL(); + + // Do compose. This is required to get newly created surface in composition right away. + // Otherwise, if the surface would not be updated to the composition scene here all surface updates would fail + // until next normal compose call. + //(void)CAlfComposeObject::CreateAndStartL(*iGceWrapper); + + __ALFLOGSTRING("CDisplayRenderStage::ElementAdded - End"); + } + +CElementWrapper* CDisplayRenderStage::FindElementTarget( TInt aTarget ) + { + TInt i = 0; + for( ; i < iElementTargets.Count() ; i++ ) + { + if( iElementTargets[i].iTarget == aTarget ) + { + break; + } + } + if( i < iElementTargets.Count()) + { + return iElementTargets[i].iElement; + } + return NULL; + }