windowing/windowserverplugins/openwfc/src/openwfcwrapper.cpp
changeset 0 5d03bc08d59c
child 18 5e30ef2e26cb
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description: Owns, hides, and provides an interface to the OpenWFC compositor for use by the final (display) render stage.
       
    14 
       
    15 #include "openwfcwrapper.h"
       
    16 #include "panic.h"
       
    17 #include "utils.h"
       
    18 
       
    19 #include <WF/wfc.h>
       
    20 #include "elementwrapper.h"
       
    21 #include <graphics/compositionsurfaceupdate.h>
       
    22 #include <graphics/symbianstream.h>
       
    23 #include "openwfcpanics.h"
       
    24 #include "openwfcjobmanager.h"
       
    25 
       
    26 #include <graphics/eglsynchelper.h>
       
    27 
       
    28 #define KRgbaBlack       0x000000FF
       
    29 
       
    30 void Panic(TOpenWfcPanic aPanic)
       
    31     {
       
    32     _LIT(KPanic, "OpenWFC");
       
    33     User::Panic(KPanic, aPanic);
       
    34     }
       
    35 
       
    36 class COpenWfcWrapper::OffScreenComposeGuard
       
    37     {
       
    38     public:
       
    39         OffScreenComposeGuard(TRequestStatus*& aRequestStatus);
       
    40         void SetOffScreenNativeStream(WFCNativeStreamType aNativeStream);
       
    41         void SetTargetNativeStream(WFCNativeStreamType aNativeStream);
       
    42         void SetSync(EGLSyncKHR aSync, EGLDisplay aDpy);
       
    43         void SetDeviceAndContext(WFCDevice aDevice, WFCContext aContext);
       
    44         void Close();
       
    45         void LogRequestStatusError(TInt aRequestStatusError);
       
    46     private:
       
    47         TRequestStatus*& iRequestStatus;
       
    48         EGLSyncKHR iSync;
       
    49         EGLDisplay iEGLDisplay;
       
    50         WFCDevice iDevice;
       
    51         WFCContext iContext;
       
    52         TInt    iRequestStatusError;
       
    53     };
       
    54 
       
    55 COpenWfcWrapper::OffScreenComposeGuard::OffScreenComposeGuard(TRequestStatus*& aRequestStatus):
       
    56 iRequestStatus(aRequestStatus),
       
    57 iSync(EGL_NO_SYNC_KHR),
       
    58 iDevice(WFC_INVALID_HANDLE),
       
    59 iContext(WFC_INVALID_HANDLE),
       
    60 iRequestStatusError(KErrNone)
       
    61     {}
       
    62 
       
    63 
       
    64 void COpenWfcWrapper::OffScreenComposeGuard::SetSync(EGLSyncKHR aSync, EGLDisplay aDpy)
       
    65     {
       
    66     iSync = aSync;
       
    67     iEGLDisplay = aDpy;
       
    68     }
       
    69 
       
    70 void COpenWfcWrapper::OffScreenComposeGuard::SetDeviceAndContext(WFCDevice aDevice, WFCContext aContext)
       
    71     {
       
    72     iContext = aContext; 
       
    73     iDevice = aDevice;
       
    74     }
       
    75 
       
    76 void COpenWfcWrapper::OffScreenComposeGuard::LogRequestStatusError(TInt aRequestStatusError)
       
    77     {
       
    78     iRequestStatusError=aRequestStatusError;
       
    79     }
       
    80 
       
    81 void COpenWfcWrapper::OffScreenComposeGuard::Close()
       
    82     {
       
    83     if (iContext != WFC_INVALID_HANDLE)
       
    84         {
       
    85         DestroyAllContextElements(iDevice, iContext);
       
    86         wfcDestroyContext(iDevice, iContext);
       
    87         }
       
    88   
       
    89     if (iSync != EGL_NO_SYNC_KHR)
       
    90         {
       
    91         eglDestroySyncKHR(iEGLDisplay, iSync);
       
    92         }
       
    93 
       
    94     if (iRequestStatus)
       
    95         {
       
    96         User::RequestComplete(iRequestStatus, iRequestStatusError);
       
    97         }
       
    98     }
       
    99 
       
   100 TEMPLATE_SPECIALIZATION class RHashTableBase::Defaults<TSurfaceId, RHashTableBase::EDefaultSpecifier_Normal>
       
   101     {
       
   102 public:
       
   103     inline static TGeneralHashFunction32 Hash();
       
   104     inline static TGeneralIdentityRelation Id();
       
   105     };
       
   106 
       
   107 inline TGeneralHashFunction32 RHashTableBase::Defaults<TSurfaceId, RHashTableBase::EDefaultSpecifier_Normal>::Hash()
       
   108     {return (TGeneralHashFunction32)&DefaultHash::Integer;}
       
   109 
       
   110 inline TGeneralIdentityRelation RHashTableBase::Defaults<TSurfaceId, RHashTableBase::EDefaultSpecifier_Normal>::Id()
       
   111     {return (TGeneralIdentityRelation)&DefaultIdentity::Integer;}
       
   112 
       
   113 TUint32 COpenWfcWrapper::HashFunction(const TSurfaceId& aHashKey)
       
   114     {
       
   115     TPckgC<TSurfaceId> pckg(aHashKey);
       
   116     return DefaultHash::Des8(pckg);
       
   117     }
       
   118 COpenWfcWrapper* COpenWfcWrapper::NewL(TInt aScreenNo, CDisplayPolicy* aDisplayPolicy)
       
   119 	{
       
   120 	COpenWfcWrapper* wrapper = new (ELeave) COpenWfcWrapper(aDisplayPolicy);
       
   121 	CleanupStack::PushL(wrapper);
       
   122 	wrapper->ConstructL(aScreenNo);
       
   123 	CleanupStack::Pop(wrapper);
       
   124 	return wrapper;
       
   125 	}
       
   126 
       
   127 COpenWfcWrapper::COpenWfcWrapper(CDisplayPolicy* aDisplayPolicy)
       
   128 	: iUiSurface(TSurfaceId::CreateNullId()), iDisplayPolicy(aDisplayPolicy),
       
   129 	iSourceMap(THashFunction32<TSurfaceId>(COpenWfcWrapper::HashFunction), TIdentityRelation<TSurfaceId>()),
       
   130 	iDevice(WFC_INVALID_HANDLE),
       
   131 	iOnScreenContext(WFC_INVALID_HANDLE),
       
   132 	iScreenNumber(-1),
       
   133 	iJobManager(NULL),
       
   134 	iRotation(MWsScene::ESceneAntiClockwise0),
       
   135 	iAutonomousCompositionInitiated(EFalse)
       
   136 	{
       
   137 	}
       
   138 
       
   139 void COpenWfcWrapper::ConstructL(TInt aScreenId)
       
   140 	{
       
   141     _LIT(KOpenWfcLog, "+ COpenWfcWrapper::ConstructL");
       
   142     RDebug::Print(KOpenWfcLog);
       
   143 
       
   144     iScreenNumber = aScreenId;
       
   145     WFCint filterList[] = { WFC_DEVICE_FILTER_SCREEN_NUMBER, iScreenNumber, WFC_NONE};
       
   146 
       
   147     iEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
       
   148     eglInitialize(iEGLDisplay, NULL, NULL);
       
   149         
       
   150     WFCint dev = 0;
       
   151     if ((wfcEnumerateDevices(&dev, 1, filterList) == 1) &&
       
   152         (dev != WFC_INVALID_HANDLE))
       
   153         {
       
   154         // clean previous errors
       
   155         wfcGetError(iDevice);
       
   156     
       
   157         // Let's get the device handle, opening in the same time the device
       
   158         iDevice = wfcCreateDevice(dev, NULL);
       
   159         if (iDevice==NULL)
       
   160             {
       
   161             //Not enough information to deduce why the device could not be created. Report as memory failure
       
   162             User::Leave(KErrNoMemory);
       
   163             }
       
   164         //Can't clean previous errors until we have a device, and the errors should be none if it created successfully.
       
   165         OPENWFC_ASSERT_DEBUG(!wfcGetError(iDevice),EPanicWfcStartupErrorUnexpected);
       
   166         
       
   167         iOnScreenContext = wfcCreateOnScreenContext(iDevice, iScreenNumber, NULL);
       
   168         if (iOnScreenContext==NULL)
       
   169             {
       
   170             TInt err = wfcGetError(iDevice);
       
   171             OPENWFC_ASSERT_DEBUG(err==WFC_ERROR_OUT_OF_MEMORY,EPanicWfcContextNotCreated);
       
   172             User::Leave((err==WFC_ERROR_OUT_OF_MEMORY)?KErrNoMemory:KErrUnknown);
       
   173             }
       
   174 
       
   175         wfcSetContextAttribi(iDevice, iOnScreenContext, WFC_CONTEXT_ROTATION, WFC_ROTATION_0);
       
   176         wfcSetContextAttribi(iDevice, iOnScreenContext, WFC_CONTEXT_BG_COLOR, KRgbaBlack);
       
   177         
       
   178         iContextDisplayControl = NULL;
       
   179         
       
   180         User::LeaveIfNull(iJobManager = COpenWfcJobManger::NewL(*this, iDevice, iOnScreenContext, iScreenNumber));
       
   181         }
       
   182     else
       
   183         {
       
   184         // we cannot continue because we cannot find a device for the given screenId
       
   185         // Not enough information to get detailed error! Report as parameter not accepted.
       
   186         User::Leave(KErrArgument);
       
   187         }
       
   188     iSurfaceManager.Open();
       
   189 
       
   190     iSourceMap.Reserve(iInitialSourceMapSize);
       
   191     }
       
   192 
       
   193 COpenWfcWrapper::~COpenWfcWrapper()
       
   194 	{
       
   195 	iUiElement1 = NULL;
       
   196 	iUiElement2 = NULL;
       
   197     if(!iUiSurface.IsNull())
       
   198         UnregisterSurface(iUiSurface);
       
   199     
       
   200     if (iJobManager)
       
   201         {
       
   202         PauseComposition();
       
   203         delete iJobManager;
       
   204         }
       
   205     
       
   206     //destroy all the elements, which should remove all the element references.
       
   207     while (iCleanupElementList)
       
   208         {
       
   209         CElementWrapper* cleanupElement = iCleanupElementList;
       
   210         delete cleanupElement;
       
   211         OPENWFC_ASSERT_DEBUG(cleanupElement != iCleanupElementList,EPanicWfcElementNotRemovedOnShutdown);
       
   212         if (cleanupElement == iCleanupElementList)
       
   213             {
       
   214             break;  //can't keep cleaning up the same front item
       
   215             }
       
   216         }
       
   217     THashMapIter<TSurfaceId, SourceAndRef> iter(iSourceMap);
       
   218     const TSurfaceId* nextKey = iter.NextKey();
       
   219     while (nextKey)
       
   220         {
       
   221         const SourceAndRef* pSource = NULL;
       
   222         //destroy any remaining registered surfaces
       
   223         pSource = iter.CurrentValue();
       
   224         OPENWFC_ASSERT_DEBUG(pSource && pSource->elementRef == 0,EPanicWfcElementNotRemovedOnShutdown);
       
   225         wfcDestroySource(iDevice,pSource->source);
       
   226         nextKey = iter.NextKey();
       
   227         }
       
   228 
       
   229     iSourceMap.Close();
       
   230     iSurfaceManager.Close();
       
   231     eglTerminate(iEGLDisplay);
       
   232 
       
   233     // Destroying the context should take care of any sources or masks
       
   234     wfcDestroyContext(iDevice, iOnScreenContext);
       
   235     wfcDestroyDevice(iDevice);
       
   236 	}
       
   237 
       
   238 class CBaseExtension: public CBase
       
   239     {
       
   240     public:
       
   241         virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
       
   242             {   return CBase::Extension_(aExtensionId,a0,a1);   }
       
   243     };
       
   244 TInt COpenWfcWrapper::Extension_(TUint aExtensionId, TAny*& aRetPtr, TAny* aExtra)
       
   245     {
       
   246 #ifndef _DEBUG
       
   247     (void) aExtra;
       
   248 #endif
       
   249     
       
   250     switch (aExtensionId)
       
   251         {
       
   252 #ifdef _DEBUG
       
   253         case EExtensionDebugBackendGuid:
       
   254             return KErrNotSupported;
       
   255         case EExtensionDebugContextGuid:
       
   256             aRetPtr=(TAny*)OnScreenContext();
       
   257             return KErrNone;
       
   258         case EExtensionDebugDeviceGuid:
       
   259             aRetPtr=(TAny*)Device();
       
   260             return KErrNone;
       
   261         case EExtensionDebugElementGuid:
       
   262             if (aExtra)
       
   263                 {
       
   264                 CElementWrapper* newElement=static_cast<CElementWrapper*>(aExtra);
       
   265                 aRetPtr=(TAny*)newElement->Element();
       
   266                 return KErrNone;
       
   267                 }
       
   268             else
       
   269                 {
       
   270                 return KErrBadHandle;
       
   271                 }
       
   272         case EExtensionDebugSourceGuid:
       
   273             if (aExtra)
       
   274                 {
       
   275                 TSurfaceId* surfId=static_cast<TSurfaceId*>(aExtra);
       
   276                 SourceAndRef* foundSourceAndRef=iSourceMap.Find(*surfId);
       
   277                 if (foundSourceAndRef)
       
   278                     {
       
   279                     aRetPtr=(TAny*)foundSourceAndRef->source;
       
   280                     return KErrNone;
       
   281                     }
       
   282                 else
       
   283                     {
       
   284                     return KErrNotFound;
       
   285                     }
       
   286                 }
       
   287             else
       
   288                 {
       
   289                 return KErrBadHandle;
       
   290                 }
       
   291 #endif
       
   292         case MCompositionSurfaceUpdate::ETypeId:
       
   293              {
       
   294              CBaseExtension* basePtr = NULL;
       
   295              SymbianStreamHasRegisteredScreenNotifications(iScreenNumber,reinterpret_cast<void**>(&basePtr));
       
   296              if (basePtr)
       
   297                  {
       
   298                  return basePtr->Extension_(MCompositionSurfaceUpdate::KUidCompositionSurfaceUpdate,aRetPtr,aExtra);
       
   299                  }
       
   300              else
       
   301                  {
       
   302                  return KErrNotSupported;
       
   303                  }
       
   304              }
       
   305         case MWsDisplayControl::ETypeId:
       
   306             if (iContextDisplayControl)
       
   307                 {
       
   308                 aRetPtr= static_cast<MWsDisplayControl*>(this);
       
   309                 return KErrNone;
       
   310                 }
       
   311             else
       
   312                 {
       
   313                 return KErrNotSupported;
       
   314                 }
       
   315         case MDisplayControlBase::ETypeId:
       
   316             if (iContextDisplayControl)
       
   317                 {
       
   318                 aRetPtr= static_cast<MDisplayControlBase*>(this);
       
   319                 return KErrNone;
       
   320                 }
       
   321             else
       
   322                 {
       
   323                 return KErrNotSupported;
       
   324                 }
       
   325         default:
       
   326             return KErrNotSupported;
       
   327         }
       
   328     }
       
   329 MWsElement* COpenWfcWrapper::CreateElementL()
       
   330 	{
       
   331 	CElementWrapper* element = CElementWrapper::NewL(*this,iCleanupElementList);
       
   332 	return element;
       
   333 	}
       
   334 
       
   335 void COpenWfcWrapper::DestroyElement(MWsElement* aElement)
       
   336 	{		
       
   337 	if(aElement)
       
   338 	    {	    
       
   339 	    CElementWrapper* element=static_cast<CElementWrapper*>(aElement);
       
   340 	    RemoveElementFromSceneList(element);
       
   341 	    if (!(element->UpdateFlags()&CElementWrapper::EUpdate_SceneCommited))
       
   342 	          {
       
   343 	             delete element;
       
   344 	          }
       
   345 	    }
       
   346 	}
       
   347 
       
   348 void COpenWfcWrapper::Compose(TRequestStatus* aCompleted)
       
   349 	{
       
   350 	STD_ASSERT_DEBUG(CompositionDue(), EPluginPanicCompositionSequenceError);
       
   351 
       
   352 	OPENWFC_ASSERT_DEBUG(iJobManager, EPanicWfcThreadManagerNotInitialised);
       
   353     if (!iAutonomousCompositionInitiated)
       
   354         {
       
   355         ResumeComposition();
       
   356         }
       
   357     iJobManager->ComposeRequest(aCompleted);
       
   358     
       
   359 	iCompositionModified = EFalse;
       
   360 	ResumeCompositorIfPaused();
       
   361 	}
       
   362 
       
   363 TSize COpenWfcWrapper::ScreenSize() const
       
   364 	{
       
   365     // clean previous errors
       
   366     #ifdef _DEBUG
       
   367     (void)wfcGetError(iDevice);
       
   368     #endif
       
   369     
       
   370     TInt height = wfcGetContextAttribi(iDevice, iOnScreenContext, WFC_CONTEXT_TARGET_HEIGHT);
       
   371     OPENWFC_ASSERT_DEBUG(TranslateOpenWfcError(wfcGetError(iDevice)) == KErrNone, EPanicWfcBadAttribute);
       
   372 
       
   373     TInt width = wfcGetContextAttribi(iDevice, iOnScreenContext, WFC_CONTEXT_TARGET_WIDTH);
       
   374     OPENWFC_ASSERT_DEBUG(TranslateOpenWfcError(wfcGetError(iDevice)) == KErrNone, EPanicWfcBadAttribute);
       
   375     
       
   376     WFCint rotation = wfcGetContextAttribi(iDevice, iOnScreenContext, WFC_CONTEXT_ROTATION);
       
   377     OPENWFC_ASSERT_DEBUG(TranslateOpenWfcError(wfcGetError(iDevice)) == KErrNone, EPanicWfcBadAttribute);
       
   378     
       
   379     return rotation == WFC_ROTATION_0 || rotation == WFC_ROTATION_180 ? TSize(width, height) : TSize(height, width);
       
   380 	}
       
   381 
       
   382 TInt COpenWfcWrapper::RegisterSurface (const TSurfaceId& aSurface)
       
   383     {
       
   384     // clean previous errors
       
   385     wfcGetError(iDevice);
       
   386     //check surface id not null
       
   387     if (aSurface.IsNull())
       
   388         {
       
   389         return KErrArgument;
       
   390         }
       
   391     
       
   392     if (!IsValidSurface(aSurface))
       
   393         {
       
   394         return KErrBadHandle;
       
   395         } 
       
   396     
       
   397     //look for surface being registered
       
   398     SourceAndRef* sourceAndRef = iSourceMap.Find(aSurface);
       
   399     if (sourceAndRef)
       
   400         {
       
   401         //if registered increase ref count and return
       
   402         sourceAndRef->sourceRef++;
       
   403         return KErrNone;
       
   404         }
       
   405 
       
   406     // Surface not currently registered so do so now.
       
   407     // Initialise struct. Could be handled via. constructor.
       
   408     SourceAndRef newSourceAndRef;
       
   409     newSourceAndRef.source = NULL;
       
   410     newSourceAndRef.sourceRef = 1;    //Surface reference count
       
   411     newSourceAndRef.elementRef = 0;   //Element reference count
       
   412 
       
   413     //No need to acquire stream as public NativeStream handle is TSurfaceId
       
   414     WFCNativeStreamType stream = reinterpret_cast<WFCNativeStreamType>(&aSurface);
       
   415 
       
   416     //create source
       
   417     newSourceAndRef.source = wfcCreateSourceFromStream(iDevice,iOnScreenContext,stream,NULL);
       
   418     //check for valid surface size should be performed by compositor in CreateSource.
       
   419     if (newSourceAndRef.source == WFC_INVALID_HANDLE)
       
   420         {
       
   421         return TranslateOpenWfcError(wfcGetError(iDevice));
       
   422         }
       
   423     //add to list
       
   424     TInt err = iSourceMap.Insert(aSurface,newSourceAndRef);
       
   425     if (err != KErrNone)
       
   426         {
       
   427         wfcDestroySource(iDevice,newSourceAndRef.source);
       
   428         return KErrNoMemory;
       
   429         }
       
   430 
       
   431     return KErrNone;
       
   432     }
       
   433 
       
   434 TInt COpenWfcWrapper::UnregisterSurface (const TSurfaceId& aSurface)
       
   435     {
       
   436     //check surface id not null
       
   437     if (aSurface.IsNull())
       
   438         {
       
   439         return KErrArgument;
       
   440         }
       
   441 
       
   442     if (!IsValidSurface(aSurface))
       
   443         {
       
   444         return KErrArgument;
       
   445         }   
       
   446     
       
   447     SourceAndRef* sourceAndRef = iSourceMap.Find(aSurface);
       
   448 
       
   449     if (sourceAndRef && sourceAndRef->sourceRef == 0)
       
   450         {
       
   451         sourceAndRef = NULL;
       
   452         }
       
   453     if (sourceAndRef)
       
   454         {
       
   455         if (sourceAndRef->sourceRef <= 1)
       
   456             {
       
   457             sourceAndRef->sourceRef = 0;
       
   458 
       
   459             if (sourceAndRef->elementRef > 0)
       
   460                 {
       
   461                 //if elements are currently in use
       
   462                 return KErrInUse;
       
   463                 }
       
   464             wfcDestroySource(iDevice,sourceAndRef->source); //removing source reference on the stream
       
   465 
       
   466             //destroy entry
       
   467             iSourceMap.Remove(aSurface);
       
   468             return KErrNone;
       
   469             }
       
   470         sourceAndRef->sourceRef--;
       
   471         return KErrNone;
       
   472         }
       
   473     return KErrBadHandle;
       
   474     }
       
   475 
       
   476 TBool COpenWfcWrapper::IsValidSurface(const TSurfaceId& aSurface)
       
   477     {
       
   478     if (aSurface.Type() != TSurfaceId::EScreenSurface)
       
   479         {
       
   480         RSurfaceManager::TInfoBuf buff;
       
   481         TInt err = SurfaceManager().SurfaceInfo(aSurface, buff);
       
   482     
       
   483         if (err == KErrArgument)
       
   484             {
       
   485             return EFalse;
       
   486             }     
       
   487         } 
       
   488     return ETrue;
       
   489     }
       
   490 
       
   491 /** 
       
   492  * Finds the source for a registered surface ID and increments its "element" reference count
       
   493  * @return registered source handle or WFC_INVALID_HANDLE if not registered
       
   494  **/
       
   495 WFCSource COpenWfcWrapper::IncEltRefRegSource(const TSurfaceId& aHashKey)
       
   496     {
       
   497     SourceAndRef* foundSourceAndRef=iSourceMap.Find(aHashKey);
       
   498     if (foundSourceAndRef && foundSourceAndRef->sourceRef)
       
   499         {   //still registered
       
   500         foundSourceAndRef->elementRef++;
       
   501         return foundSourceAndRef->source;
       
   502         }
       
   503     return WFC_INVALID_HANDLE;
       
   504     }
       
   505 
       
   506 
       
   507 /** 
       
   508  * Finds the source for a registered surface ID and decrements the "element" reference count.
       
   509  * If all counts are zero then the source is unregistered and the mapping removed   
       
   510  * @return positive if not destroyed, 0 if destroyed
       
   511  *         or KErrBadHandle if bad surface id or surface has no element reference count
       
   512  **/
       
   513 TInt COpenWfcWrapper::DecEltRefRegSource(const TSurfaceId& aHashKey)
       
   514     {
       
   515     SourceAndRef* foundSourceAndRef=iSourceMap.Find(aHashKey);
       
   516     if (foundSourceAndRef && foundSourceAndRef->elementRef>0)
       
   517         {
       
   518         TInt retRefs=((--foundSourceAndRef->elementRef)+foundSourceAndRef->sourceRef);
       
   519         if (retRefs==0)
       
   520             {
       
   521             wfcDestroySource(iDevice,foundSourceAndRef->source);
       
   522             iSourceMap.Remove(aHashKey);
       
   523             }
       
   524         return retRefs;
       
   525         }
       
   526     return KErrBadHandle;
       
   527     }
       
   528 
       
   529 void COpenWfcWrapper::RemoveElement(MWsElement* aElement)
       
   530 	{
       
   531     if (!aElement)
       
   532         {
       
   533         return;
       
   534         }
       
   535 	
       
   536 	CElementWrapper* removeElement = static_cast<CElementWrapper*>(aElement);
       
   537 	
       
   538 	//the UI element is a special case since we set and maintain the surface
       
   539 	TUint32 renderStageFlags;
       
   540 	removeElement->GetRenderStageFlags(renderStageFlags);
       
   541 	if (renderStageFlags & MWsElement::EElementIsIndirectlyRenderedUserInterface || 
       
   542 	    renderStageFlags & MWsElement::EElementIsDirectlyRenderedUserInterface)
       
   543 		{
       
   544 		if(removeElement == iUiElement1)
       
   545 		    iUiElement1 = NULL;
       
   546 		else if(removeElement == iUiElement2)
       
   547 		    iUiElement2 = NULL;
       
   548 		else
       
   549 			STD_ASSERT_DEBUG(EFalse, EPluginPanicNonMatchingRemovalOfUiElement);
       
   550 		}
       
   551 
       
   552 	RemoveElementFromSceneList(removeElement);
       
   553 	removeElement->InsertAfter(iRemoveElementList,NULL,CElementWrapper::EUpdate_Remove);  //insert into remove element list!!!
       
   554 	SetCompositionModified();
       
   555 	}
       
   556 
       
   557 void COpenWfcWrapper::RemoveElementFromSceneList(CElementWrapper* aElement)
       
   558     {
       
   559     CElementWrapper** refFromElementBelow=NULL;
       
   560     if (iSceneElementList==aElement)
       
   561         {
       
   562         refFromElementBelow=&iSceneElementList;  //remove from bottom of scene
       
   563         }
       
   564     else if (iRemoveElementList==aElement)
       
   565         {
       
   566         refFromElementBelow=&iRemoveElementList;
       
   567         }
       
   568     else
       
   569         {
       
   570         refFromElementBelow=aElement->RefsMyElementBelow();   //remove from current mid-list position
       
   571         }
       
   572     
       
   573     aElement->RemoveAfter(refFromElementBelow);
       
   574     }
       
   575 
       
   576 TInt COpenWfcWrapper::SetUiSurface(const TSurfaceId& aNewUiSurface)
       
   577 	{
       
   578 	TInt err = RegisterSurface(aNewUiSurface);
       
   579 	if (!err)
       
   580 		{
       
   581 		if(iUiElement1)
       
   582 			{
       
   583 			err = iUiElement1->ConnectSurface(aNewUiSurface);
       
   584 			STD_ASSERT_DEBUG(!err, EPluginPanicNewUiSurfaceUnsettable);
       
   585 			}
       
   586 		if(iUiElement2)
       
   587 			{
       
   588 			err = iUiElement2->ConnectSurface(aNewUiSurface);
       
   589 			STD_ASSERT_DEBUG(!err, EPluginPanicNewUiSurfaceUnsettable);
       
   590 			}
       
   591 		}
       
   592 
       
   593 	if(!err)
       
   594 		{
       
   595 		if(!iUiSurface.IsNull())
       
   596 			{
       
   597 			// This should not fail as the surface will no longer be used by any element
       
   598 			err = UnregisterSurface(iUiSurface);
       
   599 
       
   600       if (err == KErrInUse)	// This is not needed once openwf implementation is corrected:
       
   601 									          // It should not return KErrInUse if it is only the backend holding onto it.
       
   602 			    {
       
   603 			    err = KErrNone;
       
   604 			    }
       
   605 
       
   606 			STD_ASSERT_DEBUG(!err, EPluginPanicPreviousUiSurfaceUnregisterable);
       
   607 			}
       
   608 
       
   609 		iUiSurface = aNewUiSurface;
       
   610 		}
       
   611 	return err;
       
   612 	}
       
   613 
       
   614 TInt COpenWfcWrapper::AddElement(MWsElement* aElement, MWsElement* aAbove)
       
   615     {
       
   616     TInt err = KErrNone;
       
   617     CElementWrapper* addedElement = static_cast<CElementWrapper*>(aElement);
       
   618     CElementWrapper* insertAboveThisElement = static_cast<CElementWrapper*>(aAbove);
       
   619 
       
   620     if (aElement == aAbove)
       
   621         {
       
   622         return KErrArgument;
       
   623         }
       
   624     
       
   625     if (addedElement == NULL || &addedElement->Owner()!=this || 
       
   626         (insertAboveThisElement && &insertAboveThisElement->Owner()!=this) || 
       
   627         (addedElement->UpdateFlags() & CElementWrapper::EUpdate_Destroy))
       
   628         {
       
   629         return KErrArgument;
       
   630         }
       
   631     
       
   632     if (insertAboveThisElement && 
       
   633         ((!insertAboveThisElement->RefsMyElementBelow() && iSceneElementList != insertAboveThisElement) || 
       
   634         (insertAboveThisElement->UpdateFlags() & (CElementWrapper::EUpdate_Remove | CElementWrapper::EUpdate_Destroy))))
       
   635         {
       
   636         return KErrArgument;
       
   637         }
       
   638     
       
   639     //the UI element is a special case since we set and maintain the surface
       
   640     TUint32 renderStageFlags;
       
   641     addedElement->GetRenderStageFlags(renderStageFlags);
       
   642     if (renderStageFlags & MWsElement::EElementIsIndirectlyRenderedUserInterface || 
       
   643         renderStageFlags & MWsElement::EElementIsDirectlyRenderedUserInterface)
       
   644         {
       
   645         err = AttachSurfaceToUiElement(addedElement);
       
   646         }
       
   647     
       
   648     if(!err)
       
   649         {
       
   650         //figure out which element to add the element above           
       
   651         const TSurfaceId& newSurf = addedElement->ConnectedSurface();
       
   652         if (!addedElement->ConnectedSurface().IsNull())
       
   653             {
       
   654             //is surface registered
       
   655             WFCSource newSource = IncEltRefRegSource(newSurf);
       
   656             if (newSource == WFC_INVALID_HANDLE)
       
   657                 { //suggests the surface was not registered
       
   658                 return KErrArgument;
       
   659                 }
       
   660             DecEltRefRegSource(newSurf);    //only need to decrement if it found a source
       
   661             }
       
   662         
       
   663         RemoveElementFromSceneList(addedElement);
       
   664        
       
   665         // figure out which element to add it below
       
   666         CElementWrapper** insertBelowThisElement = NULL;
       
   667         if (insertAboveThisElement)
       
   668             {
       
   669             insertBelowThisElement=&insertAboveThisElement->MyElementAbove();
       
   670             }
       
   671         else
       
   672             {
       
   673             insertBelowThisElement=&iSceneElementList;
       
   674             }
       
   675         
       
   676         addedElement->InsertAfter(*insertBelowThisElement,insertAboveThisElement,CElementWrapper::EUpdate_Insert);
       
   677         
       
   678         SetCompositionModified();
       
   679         }
       
   680     
       
   681     return err;
       
   682     }
       
   683 
       
   684 void COpenWfcWrapper::Compose(const TSurfaceId& aOffScreenTarget, TRequestStatus* aCompleted)
       
   685 	{
       
   686     if (aOffScreenTarget.IsNull())
       
   687         {
       
   688         if (aCompleted)
       
   689             {
       
   690             User::RequestComplete(aCompleted, KErrNone);
       
   691             return;
       
   692             }
       
   693         }
       
   694     ComposeInternal(aOffScreenTarget,TPoint(0,0),iSceneElementList,NULL,aCompleted);
       
   695 	}
       
   696 
       
   697 void COpenWfcWrapper::Compose(const TSurfaceId& aOffScreenTarget, const TPoint& aOrigin,
       
   698 	         MWsElement* aStart, MWsElement* aEnd, TRequestStatus* aCompleted)
       
   699 	{
       
   700     if (aOffScreenTarget.IsNull())
       
   701         {
       
   702         if (aCompleted)
       
   703             {
       
   704             User::RequestComplete(aCompleted, KErrNone);
       
   705             return;
       
   706             }
       
   707         }
       
   708     
       
   709     CElementWrapper* startElement=static_cast<CElementWrapper*>(aStart);
       
   710     CElementWrapper* endElement=static_cast<CElementWrapper*>(aEnd);
       
   711     
       
   712     if (startElement)
       
   713         {
       
   714         if (    &startElement->Owner()!=this
       
   715             ||  (startElement!=iSceneElementList && !startElement->ElementBelow())
       
   716             ||  (startElement->UpdateFlags() & (startElement->EUpdate_Remove|startElement->EUpdate_Destroy))
       
   717             )
       
   718             {
       
   719             if (aCompleted)
       
   720                 {
       
   721                 RThread().RequestComplete(aCompleted, KErrArgument);
       
   722                 }
       
   723             return;
       
   724             }
       
   725         if (endElement)
       
   726             {   //If endElement is NULL then draw to end else draw including the specified endElement
       
   727             TBool fail=EFalse;
       
   728             if (    &endElement->Owner()!=this
       
   729                 ||  (endElement->UpdateFlags() & (endElement->EUpdate_Remove|endElement->EUpdate_Destroy))
       
   730                 )
       
   731                 {
       
   732                 fail=ETrue;
       
   733                 }
       
   734             else
       
   735                 {
       
   736                 for (CElementWrapper* sceneElement=startElement;sceneElement!=endElement;sceneElement=sceneElement->MyElementAbove())
       
   737                     {
       
   738                     if (sceneElement==NULL)
       
   739                         {
       
   740                         fail=ETrue;
       
   741                         break;
       
   742                         }
       
   743                     }
       
   744                 }
       
   745             if (fail)
       
   746                 {
       
   747                 if (aCompleted)
       
   748                     {
       
   749                     RThread().RequestComplete(aCompleted, KErrArgument);
       
   750                     }
       
   751                 return;
       
   752                 }
       
   753             aEnd=aEnd->ElementAbove();   //now scene does NOT include endElement. May now be NULL!
       
   754             }
       
   755         }
       
   756     else
       
   757         {
       
   758         aEnd=NULL;
       
   759         }
       
   760     ComposeInternal(aOffScreenTarget,aOrigin,aStart,aEnd,aCompleted);
       
   761 	}
       
   762 
       
   763 /** Internal compose does not check some errors. 
       
   764  *  They should have already been checked by the public API caller.
       
   765  *  NOTE element aEnd is NOT composed by this internal method!
       
   766  *  Any elements pending removal will not be displayed (including aStart and aEnd.
       
   767  * 
       
   768  * @param   aOffScreenTarget    A valid surface for offscreen composition.
       
   769  * @param   aOrigin             The origin sets where the top-left corner of the
       
   770  *                              surface is within the element coordinate system.
       
   771  * @param   aStart              The starting element of the elements to be composed.
       
   772  * @param   aEnd                The element above the last element to be composed (or NULL).
       
   773  * @param   aCompleted          NULL or request status that will be set to KErrNone when
       
   774  *                              the composition finishes.
       
   775  **/
       
   776 void COpenWfcWrapper::ComposeInternal (const TSurfaceId&   aOffScreenTarget,
       
   777                         const TPoint&       aOrigin,
       
   778                         MWsElement*       aStart,
       
   779                         MWsElement*       aEnd,
       
   780                         TRequestStatus*     aCompleted)
       
   781     {
       
   782     // Initial approach reuses the device but it may be more safer to create, and destroy, its own device
       
   783     CElementWrapper* startElement=static_cast<CElementWrapper*>(aStart);
       
   784     CElementWrapper* endElement=static_cast<CElementWrapper*>(aEnd);
       
   785     
       
   786     TInt err = KErrNone;
       
   787 #ifdef _DEBUG
       
   788     // clean previous errors
       
   789     wfcGetError(iDevice);
       
   790 #endif    
       
   791     
       
   792     if (aCompleted)
       
   793         {
       
   794         *aCompleted = KRequestPending;
       
   795         }
       
   796     
       
   797     OffScreenComposeGuard composeGuard(aCompleted);
       
   798     
       
   799     WFCNativeStreamType stream=reinterpret_cast<WFCNativeStreamType>(&aOffScreenTarget);
       
   800     
       
   801     RSurfaceManager::TInfoBuf buff;
       
   802     err=SurfaceManager().SurfaceInfo(aOffScreenTarget,buff);
       
   803     OPENWFC_ASSERT_DEBUG(err==KErrNone,TOpenWfcPanic(__LINE__));
       
   804     if (err!=KErrNone || buff().iSize.iWidth ==0 || buff().iSize.iHeight == 0)
       
   805         {
       
   806         composeGuard.LogRequestStatusError(KErrArgument);
       
   807         composeGuard.Close();
       
   808         return;
       
   809         }
       
   810     
       
   811     // Create the native stream target
       
   812     TSurfaceId targetSurfaceId = TSurfaceId::CreateNullId();
       
   813     WFCNativeStreamType targetStream = WFC_INVALID_HANDLE;
       
   814     OPENWFC_ASSERT_DEBUG(wfcGetError(iDevice)==WFC_ERROR_NONE,(TOpenWfcPanic)__LINE__);
       
   815 
       
   816     targetSurfaceId = aOffScreenTarget;
       
   817     targetStream = stream;
       
   818      
       
   819     EGLint attrib_list[1] = {EGL_NONE };
       
   820     
       
   821     EGLSyncKHR sync = eglCreateSyncKHR(iEGLDisplay,
       
   822                                                 EGL_SYNC_REUSABLE_KHR,
       
   823                                                 attrib_list);
       
   824     
       
   825     if (sync == EGL_NO_SYNC_KHR)
       
   826         {
       
   827         composeGuard.LogRequestStatusError(KErrNoMemory);
       
   828         composeGuard.Close();
       
   829         return;
       
   830         }
       
   831     composeGuard.SetSync(sync, iEGLDisplay);
       
   832     
       
   833     // Now, that we have the target surface stream we can create the temporary context
       
   834     WFCContext offScreenContext = wfcCreateOffScreenContext(iDevice, targetStream, NULL);
       
   835 
       
   836     if (offScreenContext == WFC_INVALID_HANDLE)
       
   837         {
       
   838         composeGuard.LogRequestStatusError(TranslateOpenWfcError(wfcGetError(iDevice)));
       
   839         composeGuard.Close();
       
   840         return;
       
   841         }
       
   842 
       
   843     composeGuard.SetDeviceAndContext(iDevice, offScreenContext);
       
   844 
       
   845     TInt contextBackGroundColour = wfcGetContextAttribi(iDevice, iOnScreenContext, WFC_CONTEXT_BG_COLOR);
       
   846     wfcSetContextAttribi(iDevice, offScreenContext, WFC_CONTEXT_BG_COLOR, contextBackGroundColour);
       
   847     OPENWFC_ASSERT_DEBUG(TranslateOpenWfcError(wfcGetError(iDevice)) == KErrNone, EPanicWfcBadAttribute);
       
   848     
       
   849     TPoint elementOffset(-aOrigin.iX,-aOrigin.iY);
       
   850     // let's replicate the scene to the offscreen context
       
   851     WFCElement previousTargetElement = WFC_INVALID_HANDLE;
       
   852     for (CElementWrapper* elementScene = startElement; elementScene !=endElement; elementScene = elementScene->MyElementAbove())
       
   853         {
       
   854         if (!(elementScene->UpdateFlags()&(elementScene->EUpdate_Destroy|elementScene->EUpdate_Remove)))
       
   855             {
       
   856             // we do our best to replicate the elements
       
   857             TInt err=elementScene->ReplicateElements(offScreenContext, previousTargetElement,elementOffset);
       
   858             if (err)
       
   859                 {
       
   860                 composeGuard.LogRequestStatusError(err);
       
   861                 composeGuard.Close();
       
   862                 return;
       
   863                 }
       
   864             }
       
   865         }
       
   866 
       
   867     // let's compose
       
   868     wfcCommit(iDevice, offScreenContext, WFC_TRUE);
       
   869     wfcCompose(iDevice, offScreenContext, WFC_TRUE);
       
   870     wfcFence(iDevice, offScreenContext, iEGLDisplay, sync);
       
   871     EGLTimeKHR timeout = (EGLTimeKHR) EGL_FOREVER_KHR;
       
   872     OPENWFC_ASSERT_DEBUG(TranslateOpenWfcError(wfcGetError(iDevice)) == KErrNone, EPanicWfcBadAttribute);
       
   873     eglClientWaitSyncKHR(iEGLDisplay, sync, 0, timeout);
       
   874     
       
   875     composeGuard.Close();
       
   876     }
       
   877 
       
   878 void COpenWfcWrapper::PauseComposition (void)
       
   879     {
       
   880     
       
   881     OPENWFC_ASSERT_DEBUG(iJobManager, EPanicWfcThreadManagerNotInitialised);
       
   882     iAutonomousCompositionInitiated = ETrue;
       
   883     iJobManager->CompositionPauseRequest();
       
   884     }
       
   885 
       
   886 void COpenWfcWrapper::ResumeComposition (void)
       
   887     {
       
   888     OPENWFC_ASSERT_DEBUG(iJobManager, EPanicWfcThreadManagerNotInitialised);
       
   889     iAutonomousCompositionInitiated = ETrue;
       
   890     iJobManager->CompositionResumeRequest();
       
   891     }
       
   892 
       
   893 TBitFlags32 COpenWfcWrapper::SupportedScreenRotations() const
       
   894     {
       
   895     TBitFlags32 result;
       
   896     // we DO support, by default, all these rotations
       
   897     result.Set(MWsScene::ESceneAntiClockwise0);
       
   898     result.Set(MWsScene::ESceneAntiClockwise90);
       
   899     result.Set(MWsScene::ESceneAntiClockwise180);
       
   900     result.Set(MWsScene::ESceneAntiClockwise270);
       
   901     return result;
       
   902     }
       
   903 
       
   904 void COpenWfcWrapper::SetScreenRotation(MWsScene::TSceneRotation aRotation)
       
   905 	{
       
   906 #ifdef _DEBUG
       
   907     // clean previous errors
       
   908     (void)wfcGetError(iDevice);
       
   909 #endif
       
   910 
       
   911     if (aRotation != iRotation)
       
   912         {
       
   913         WFCRotation wfcRotation = WFC_ROTATION_0;
       
   914         switch (aRotation)
       
   915             {
       
   916             case MWsScene::ESceneAntiClockwise90:
       
   917                 wfcRotation = WFC_ROTATION_90;
       
   918                 break;
       
   919             case MWsScene::ESceneAntiClockwise180:
       
   920                 wfcRotation = WFC_ROTATION_180;
       
   921                 break;
       
   922             case MWsScene::ESceneAntiClockwise270:
       
   923                 wfcRotation = WFC_ROTATION_270;
       
   924                 break;
       
   925             default:
       
   926                 wfcRotation = WFC_ROTATION_0;
       
   927                 break;
       
   928             }
       
   929         iRotation = aRotation;
       
   930         wfcSetContextAttribi(iDevice, iOnScreenContext, WFC_CONTEXT_ROTATION, wfcRotation);
       
   931         OPENWFC_ASSERT_DEBUG(TranslateOpenWfcError(wfcGetError(iDevice)) == KErrNone, EPanicWfcBadAttribute);
       
   932         }
       
   933 	
       
   934 	SetCompositionModified();
       
   935 	}
       
   936 
       
   937 TInt COpenWfcWrapper::SetConfiguration(const TDisplayConfiguration& aConfig)
       
   938     {
       
   939     return iContextDisplayControl->SetConfiguration (aConfig);
       
   940     }
       
   941 
       
   942 MWsScene::TSceneRotation COpenWfcWrapper::ScreenRotation() const
       
   943 	{
       
   944 #ifdef _DEBUG
       
   945     // clean previous errors
       
   946     (void)wfcGetError(iDevice);
       
   947 #endif
       
   948     WFCint result = wfcGetContextAttribi(iDevice, iOnScreenContext, WFC_CONTEXT_ROTATION);
       
   949     OPENWFC_ASSERT_DEBUG(TranslateOpenWfcError(wfcGetError(iDevice)) == KErrNone, EPanicWfcBadAttribute);
       
   950     MWsScene::TSceneRotation rotation = MWsScene::ESceneAntiClockwise0;
       
   951     switch (result)
       
   952         {
       
   953         case WFC_ROTATION_90:
       
   954             rotation = MWsScene::ESceneAntiClockwise90;
       
   955             break;
       
   956         case WFC_ROTATION_180:
       
   957             rotation = MWsScene::ESceneAntiClockwise180;
       
   958             break;
       
   959         case WFC_ROTATION_270:
       
   960             rotation = MWsScene::ESceneAntiClockwise270;
       
   961             break;
       
   962         case WFC_ROTATION_0:
       
   963         default:
       
   964             OPENWFC_ASSERT_DEBUG(result==WFC_ROTATION_0,(TOpenWfcPanic)__LINE__);
       
   965             rotation = MWsScene::ESceneAntiClockwise0;
       
   966             break;
       
   967         }
       
   968     
       
   969 	return rotation;
       
   970 	}
       
   971 
       
   972 TInt COpenWfcWrapper::NumberOfResolutions()const
       
   973     {
       
   974     if (iContextDisplayControl)
       
   975         {
       
   976         return iContextDisplayControl->NumberOfResolutions();
       
   977         }
       
   978     return KErrNotSupported;
       
   979     }
       
   980 
       
   981 TInt COpenWfcWrapper::GetResolutions(RArray<TResolution>& aResolutions)const
       
   982     {
       
   983     if (iContextDisplayControl)
       
   984         {
       
   985         return iContextDisplayControl->GetResolutions(aResolutions);
       
   986         }
       
   987     return KErrNotSupported;
       
   988     }
       
   989 
       
   990 void COpenWfcWrapper::GetConfiguration(TDisplayConfiguration& aConfig)const
       
   991     {
       
   992     if (iContextDisplayControl)
       
   993         {
       
   994         iContextDisplayControl->GetConfiguration (aConfig);
       
   995         }
       
   996     }
       
   997 
       
   998 TInt COpenWfcWrapper::PreferredDisplayVersion() const
       
   999     {
       
  1000     if (iContextDisplayControl)
       
  1001         {
       
  1002         return iContextDisplayControl->PreferredDisplayVersion();
       
  1003         }
       
  1004     return KErrNotSupported;
       
  1005     }
       
  1006 
       
  1007 void COpenWfcWrapper::NotifyOnDisplayChange(TRequestStatus& aStatus)
       
  1008     {
       
  1009     // Stub for future implementation. 
       
  1010     TRequestStatus *status = &aStatus;
       
  1011     RThread().RequestComplete(status, KErrNotSupported);
       
  1012     }
       
  1013 
       
  1014 void COpenWfcWrapper::NotifyOnDisplayChangeCancel()
       
  1015     {
       
  1016     // Stub for future implementation. 
       
  1017     }
       
  1018 
       
  1019 void COpenWfcWrapper::NotifyOnConfigChange(TRequestStatus& aStatus)
       
  1020     {
       
  1021     // Stub for future implementation. 
       
  1022     TRequestStatus *status = &aStatus;
       
  1023     RThread().RequestComplete(status, KErrNotSupported);
       
  1024     }
       
  1025 
       
  1026 void COpenWfcWrapper::NotifyOnConfigChangeCancel()
       
  1027     {
       
  1028     // Stub for future implementation. 
       
  1029     }
       
  1030 
       
  1031 
       
  1032 void COpenWfcWrapper::FlushSceneElementChanges()
       
  1033     {
       
  1034     while (CElementWrapper* curr = iRemoveElementList)
       
  1035         {
       
  1036         curr->FlushSceneChanges();
       
  1037         RemoveElementFromSceneList(curr);
       
  1038         if (curr->UpdateFlags() & CElementWrapper::EUpdate_Destroy)
       
  1039             {
       
  1040             delete curr;
       
  1041             }
       
  1042         }
       
  1043     iRemoveElementList=NULL;
       
  1044     if (CElementWrapper* curr=iSceneElementList)
       
  1045         {
       
  1046         for (CElementWrapper*next=curr->MyElementAbove(); curr;   curr=next,next=curr?curr->MyElementAbove():NULL)
       
  1047             {
       
  1048             curr->FlushSceneChanges();
       
  1049             }
       
  1050         }
       
  1051     }
       
  1052 
       
  1053 TInt COpenWfcWrapper::TranslateOpenWfcError(WFCErrorCode error)
       
  1054     {
       
  1055     switch (error)
       
  1056         {
       
  1057         case WFC_ERROR_NONE:
       
  1058             return KErrNone;
       
  1059         case WFC_ERROR_OUT_OF_MEMORY:
       
  1060             return KErrNoMemory;
       
  1061         case WFC_ERROR_ILLEGAL_ARGUMENT:
       
  1062             return KErrArgument;
       
  1063         case WFC_ERROR_BAD_ATTRIBUTE:
       
  1064             return KErrArgument;
       
  1065         case WFC_ERROR_BAD_DEVICE:
       
  1066             return KErrArgument;
       
  1067         case WFC_ERROR_UNSUPPORTED:
       
  1068             return KErrNotSupported;
       
  1069         case WFC_ERROR_IN_USE:
       
  1070             return KErrInUse;
       
  1071         case WFC_ERROR_BUSY:
       
  1072             return KErrServerBusy;
       
  1073         case WFC_ERROR_BAD_HANDLE:
       
  1074             return KErrBadHandle;
       
  1075         case WFC_ERROR_INCONSISTENCY:
       
  1076             return KErrGeneral;
       
  1077         case WFC_ERROR_FORCE_32BIT:
       
  1078             // intentional fall through
       
  1079         default:
       
  1080             return KErrUnknown;
       
  1081         }
       
  1082     }
       
  1083 
       
  1084 void COpenWfcWrapper::DestroyAllContextElements(WFCDevice dev, WFCContext ctx)
       
  1085     {
       
  1086     // we try our best to destroy all elements of the specified context
       
  1087     if (dev != WFC_INVALID_HANDLE && ctx != WFC_INVALID_HANDLE)
       
  1088         {
       
  1089         WFCElement element = wfcGetContextAttribi(dev, ctx, WFC_CONTEXT_LOWEST_ELEMENT);
       
  1090         if (element != WFC_INVALID_HANDLE)
       
  1091             {
       
  1092             wfcDestroyElement(dev, element);
       
  1093             }
       
  1094         }
       
  1095     }
       
  1096 
       
  1097 void COpenWfcWrapper::PauseCompositorIfNeeded()
       
  1098 	{
       
  1099 	if (!iPaused && iAllowCompositorPause && iWithinBeginEnd)
       
  1100 		{
       
  1101 		PauseComposition();
       
  1102 		iPaused = ETrue;
       
  1103 		}
       
  1104 	}
       
  1105 
       
  1106 /**
       
  1107 Sets the system state for modified scene composition.
       
  1108 	- Pause OpenWF composition if the standard render stage is within a begin/end block.
       
  1109 	- If not within a pause/end block then set a flag to indicate that the scene composition 
       
  1110 		has been modified. On entering the begin/end block composition will be paused appropriatly.
       
  1111 */
       
  1112 void COpenWfcWrapper::SetCompositionModified()
       
  1113 	{
       
  1114 	PauseCompositorIfNeeded();
       
  1115 	iCompositionModified = ETrue;
       
  1116 	}
       
  1117 
       
  1118 void COpenWfcWrapper::ResumeCompositorIfPaused()
       
  1119 	{
       
  1120 	if (iPaused)
       
  1121 		ResumeComposition();
       
  1122 	iPaused = EFalse;
       
  1123 	}
       
  1124 
       
  1125 void COpenWfcWrapper::Begin(const TRegion* aRegion)
       
  1126 	{
       
  1127 	iWithinBeginEnd = ETrue;
       
  1128 	iAllowCompositorPause = (aRegion && !aRegion->IsEmpty());
       
  1129 	
       
  1130 	if (iCompositionModified)
       
  1131 		PauseCompositorIfNeeded();
       
  1132 	}
       
  1133 
       
  1134 TBool COpenWfcWrapper::CompositionDue()
       
  1135 	{
       
  1136 	return (iWithinBeginEnd && iCompositionModified);
       
  1137 	}
       
  1138 
       
  1139 void COpenWfcWrapper::End()
       
  1140 	{
       
  1141 	iWithinBeginEnd = EFalse;
       
  1142 	}
       
  1143 
       
  1144 TInt COpenWfcWrapper::FlushedSetConfiguration(const TDisplayConfiguration& /*aConfig*/)
       
  1145 	{
       
  1146 	OPENWFC_ASSERT_DEBUG(0, EPanicMethodNotImplemented);
       
  1147 	TInt retval=KErrNone;
       
  1148 	if (retval<=KErrNone)
       
  1149 		{
       
  1150 		SetCompositionModified();
       
  1151 		}
       
  1152 	return retval;
       
  1153 	}
       
  1154 
       
  1155 CDisplayPolicy* COpenWfcWrapper::DisplayPolicy()
       
  1156 	{
       
  1157 	return iDisplayPolicy;
       
  1158 	}
       
  1159 
       
  1160 TInt COpenWfcWrapper::AttachSurfaceToUiElement(CElementWrapper* aNewUiElement)
       
  1161 	{
       
  1162 	STD_ASSERT_DEBUG(!iUiSurface.IsNull(), EPluginPanicUiSurfaceIsNull);
       
  1163 	if(iUiElement1 == NULL || iUiElement1 == aNewUiElement)
       
  1164 	    iUiElement1 = aNewUiElement;
       
  1165 	else if(iUiElement2 == NULL || iUiElement2 == aNewUiElement)
       
  1166 	    iUiElement2 = aNewUiElement;
       
  1167 	else
       
  1168 		STD_ASSERT_DEBUG(EFalse, EPluginPanicDuplicateUiElement);
       
  1169 
       
  1170 	return aNewUiElement->ConnectSurface(iUiSurface);
       
  1171 	}