|
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 } |