|
1 /* |
|
2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implementation of CHuiEnv, a common working environment for the Toolkit. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include <eikenv.h> |
|
21 #include <bautils.h> |
|
22 #include <coemain.h> |
|
23 #include <w32std.h> |
|
24 #include <gdi.h> |
|
25 #include <e32math.h> |
|
26 |
|
27 #include "uiacceltk/HuiEnv.h" // Class definition |
|
28 #include <ecom/implementationinformation.h> |
|
29 #include "HuiRenderPlugin.h" |
|
30 #include "uiacceltk/HuiStatic.h" |
|
31 #include "alf/alfconstants.h" |
|
32 #include "HuiRenderSurface.h" |
|
33 #include "uiacceltk/HuiDisplay.h" |
|
34 #include "HuiRosterImpl.h" |
|
35 #include "uiacceltk/HuiScheduler.h" |
|
36 #include "uiacceltk/HuiTextureManager.h" |
|
37 #include "uiacceltk/HuiControlGroup.h" |
|
38 #include "HuiVisualFactory.h" |
|
39 #include "uiacceltk/HuiS60Skin.h" |
|
40 #include "uiacceltk/HuiEvent.h" |
|
41 #include "uiacceltk/HuiRoster.h" |
|
42 #include "uiacceltk/HuiUtil.h" |
|
43 #include "uiacceltk/HuiPanic.h" |
|
44 #include "uiacceltk/huitextstylemanager.h" |
|
45 #include "huistatictlsdata.h" |
|
46 #include "uiacceltk/HuiThemeManager.h" |
|
47 #include "huicanvastexturecache.h" |
|
48 #include "HuiFxEngine.h" |
|
49 |
|
50 #define HUI_HIRES_TIMER |
|
51 |
|
52 |
|
53 /* Constants */ |
|
54 |
|
55 // Until we get refresh interval issues solved (implement hi-res timer), this define keeps fps at respectable enough level |
|
56 #ifdef SYMBIAN_BUILD_GCE |
|
57 #define HUI_NGA_MIN_REFRESH_INTERVAL |
|
58 #endif |
|
59 |
|
60 // This is for testing, can be used to force forced refresh |
|
61 #ifdef SYMBIAN_BUILD_GCE |
|
62 //#define HUI_NGA_FORCED_REFRESH |
|
63 #endif |
|
64 |
|
65 // This is for testing, prints performance information |
|
66 //#define HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
67 |
|
68 #ifdef SYMBIAN_BUILD_GCE |
|
69 #ifdef __WINSCW__ |
|
70 const TInt KHuiEnvDefaultNormalRefreshIntervalMs = 40; |
|
71 const TInt KHuiEnvDefaultBusyRefreshIntervalMs = 40; |
|
72 #else |
|
73 const TInt KHuiEnvDefaultNormalRefreshIntervalMs = 15; |
|
74 const TInt KHuiEnvDefaultBusyRefreshIntervalMs = 15; |
|
75 #endif |
|
76 #else |
|
77 const TInt KHuiEnvDefaultNormalRefreshIntervalMs = 20; |
|
78 const TInt KHuiEnvDefaultBusyRefreshIntervalMs = 2 * KHuiEnvDefaultNormalRefreshIntervalMs; |
|
79 #endif |
|
80 |
|
81 |
|
82 #ifndef SYMBIAN_BUILD_GCE |
|
83 const TUint KHuiEnvMaxCpuTime = 100; |
|
84 #endif |
|
85 const TUint KRndTexMemCalcFlag = 0x800; |
|
86 |
|
87 /* If there is idle between frames, this is how much we can use as overdrive max cpu utilisation */ |
|
88 const TUint KHuiEnvMaxCpuTimeOverdriveMaxValue = 100; |
|
89 |
|
90 /* If max cpu usage has been set below this value, overdrive is not used because there is probaply a good reson |
|
91 for a low max cpu usage value */ |
|
92 const TUint KHuiEnvMaxCpuTimeOverdriveLowerThreshold = 50; |
|
93 |
|
94 |
|
95 /** Threshold number for refreshes that don't have any effect. When exceeded, |
|
96 refresh is paused. */ |
|
97 const TInt KIdleRefreshCountThreshold = 3; |
|
98 |
|
99 const THuiRefreshMode KHuiDefaultRefreshMode = EHuiRefreshModeAutomatic; |
|
100 class CHighResTimer : public CTimer |
|
101 { |
|
102 public: |
|
103 static CHighResTimer* NewL(TCallBack aCallBack, TInt aPriority) |
|
104 { |
|
105 CHighResTimer* self = new(ELeave) CHighResTimer(aCallBack, aPriority); |
|
106 CleanupStack::PushL(self); |
|
107 self->ConstructL(); |
|
108 CleanupStack::Pop(self); |
|
109 return self; |
|
110 } |
|
111 |
|
112 ~CHighResTimer() |
|
113 { |
|
114 Cancel(); |
|
115 } |
|
116 |
|
117 void CallBack(const TInt aWaitInMilliSecs) |
|
118 { |
|
119 TInt wait = 1000*aWaitInMilliSecs; |
|
120 if (wait < 0) |
|
121 { |
|
122 wait = 15000; |
|
123 } |
|
124 else if (wait > 60000) |
|
125 { |
|
126 wait = 60000; |
|
127 } |
|
128 |
|
129 HighRes( TTimeIntervalMicroSeconds32( wait ) ); |
|
130 } |
|
131 |
|
132 private: |
|
133 CHighResTimer(TCallBack aCallBack, TInt aPriority) |
|
134 : CTimer(aPriority), iCallBack(aCallBack) |
|
135 { |
|
136 CActiveScheduler::Add(this); |
|
137 } |
|
138 |
|
139 void RunL() |
|
140 { |
|
141 iCallBack.CallBack(); |
|
142 } |
|
143 |
|
144 TCallBack iCallBack; |
|
145 }; |
|
146 |
|
147 EXPORT_C CHuiEnv* CHuiEnv::NewL(THuiRenderer aRenderer, MHuiEnvObserver* aObserver) |
|
148 { |
|
149 CHuiEnv* self = CHuiEnv::NewLC(aRenderer, aObserver); |
|
150 CleanupStack::Pop(self); |
|
151 return self; |
|
152 } |
|
153 |
|
154 |
|
155 EXPORT_C CHuiEnv* CHuiEnv::NewLC(THuiRenderer aRenderer, MHuiEnvObserver* aObserver) |
|
156 { |
|
157 CHuiEnv* self = new (ELeave) CHuiEnv(aObserver); |
|
158 CleanupStack::PushL(self); |
|
159 self->ConstructL(aRenderer); |
|
160 |
|
161 return self; |
|
162 } |
|
163 |
|
164 |
|
165 CHuiEnv::CHuiEnv(MHuiEnvObserver* aObserver) |
|
166 : iState(ENormal), |
|
167 iRefreshMode(KHuiDefaultRefreshMode), |
|
168 iRefreshInterval(KHuiEnvDefaultNormalRefreshIntervalMs), |
|
169 iRefreshIntervalTarget(KHuiEnvDefaultNormalRefreshIntervalMs), |
|
170 iEnvObserver(aObserver), |
|
171 iIdleThreshold(10), |
|
172 iMaxCPUUtilization(0), // disable adaptive scheduling by default |
|
173 iRefreshLoopPriority(CActive::EPriorityStandard), |
|
174 iRefreshLoopActive(EFalse) |
|
175 { |
|
176 iIdleCPUValueMonitored = CPUTimeSupported() && OpenHandleToIdleCPUValueThread(); |
|
177 } |
|
178 |
|
179 // to get around nasty ownership problem with texture manager interface |
|
180 void NullTextureManagerPtr(TAny* aPtrToPtr) |
|
181 { |
|
182 if (aPtrToPtr) |
|
183 { |
|
184 CHuiTextureManager** ptr = (CHuiTextureManager**)aPtrToPtr; |
|
185 *ptr = 0; |
|
186 } |
|
187 } |
|
188 |
|
189 void CHuiEnv::ConstructL(THuiRenderer aRenderer) |
|
190 { |
|
191 HUI_DEBUG(_L("CHuiEnv::ConstructL() - Constructing Hitchcock User Interface Toolkit (HUITK) working environment") ); |
|
192 HUI_DEBUG1(_L("CHuiEnv::ConstructL() - Free memory in beginning: %i"), HuiUtil::FreeMemory()); |
|
193 |
|
194 // Static data area. |
|
195 iStatic = CHuiStatic::NewL(this); |
|
196 HUI_DEBUG1(_L("CHuiEnv::ConstructL() - Free memory after static created: %i"), HuiUtil::FreeMemory()); |
|
197 |
|
198 // Instantiate the right type of renderer plugin. |
|
199 |
|
200 |
|
201 // The Ecom plugin framework requires the identifier to be a descriptor. |
|
202 // Convert the identifier to descriptor, which the ecom uses to determine |
|
203 // the correct renderer. |
|
204 |
|
205 // -----------RnD------------------------------------------------------------- |
|
206 // Disable renderer selection for now !! |
|
207 // -----------RnD------------------------------------------------------------- |
|
208 |
|
209 // can't currently switch on fly and alf_config has its issues.. |
|
210 aRenderer = EHuiRendererVg10; |
|
211 |
|
212 |
|
213 TBuf<10> renderer; |
|
214 renderer.Num(aRenderer); |
|
215 |
|
216 // The aRenderer holds the renderer information which is usually gotten from |
|
217 // central repository key. It might not be defined though, and in that case, |
|
218 // we'll try to load from the |
|
219 switch(aRenderer) |
|
220 { |
|
221 case EHuiRendererDefault: |
|
222 { |
|
223 const THuiRenderer rendererTable[] = |
|
224 { |
|
225 EHuiRendererVg10, |
|
226 EHuiRendererBitgdi, |
|
227 EHuiRendererGles20, |
|
228 EHuiRendererGles11, |
|
229 EHuiRendererGles10, |
|
230 }; |
|
231 const TInt KRendererCount = 5; |
|
232 for (TInt index = 0; index < KRendererCount ; index++) |
|
233 { |
|
234 renderer.Num(rendererTable[index]); |
|
235 TRAPD(error, iRenderer = reinterpret_cast<CHuiRenderPlugin*>(CHuiRenderPluginBase::NewL( renderer ))); |
|
236 if (error) |
|
237 { |
|
238 HUI_DEBUG1(_L("CHuiEnv::ConstructL() - Renderer construction failed, error code: %i, trying next one...."),error ); |
|
239 if (index == KRendererCount-1) |
|
240 { |
|
241 // the last renderer in the table failed to load |
|
242 HUI_DEBUG(_L("CHuiEnv::ConstructL() - ERROR! Failed to create any renderer.. bailing out") ); |
|
243 User::Leave(error); |
|
244 } |
|
245 continue; |
|
246 } |
|
247 // got a renderer, use that... |
|
248 iRendererIdentifier = rendererTable[index]; |
|
249 break; |
|
250 } |
|
251 break; |
|
252 } |
|
253 |
|
254 |
|
255 default: |
|
256 { |
|
257 // Load the renderer plugin with the given identifier. The Ecom framework |
|
258 // will take care searching for matching renderer. If not found, will leave with KErrNotFound |
|
259 iRenderer = reinterpret_cast<CHuiRenderPlugin*>(CHuiRenderPluginBase::NewL( renderer )); |
|
260 iRendererIdentifier = aRenderer; |
|
261 |
|
262 // @TODO Should we panic, if renderer wasn't found, or is the Leave |
|
263 // with KErrNotFound enough? |
|
264 //THuiPanic::Panic(THuiPanic::EStaticInvalidRenderer); |
|
265 break; |
|
266 } |
|
267 } |
|
268 |
|
269 iStatic->SetRenderer(*iRenderer); |
|
270 |
|
271 CHuiStatic::Tic(1); |
|
272 |
|
273 // Create the scheduler. |
|
274 iScheduler = new (ELeave) CHuiScheduler(*this); |
|
275 |
|
276 // Create a texture manager. |
|
277 |
|
278 CleanupStack::PushL(TCleanupItem(NullTextureManagerPtr,&iTextureManager)); |
|
279 iTextureManager = iRenderer->CreateTextureManagerL(*this); |
|
280 // Register as a state change and texture loaded event observer |
|
281 CleanupStack::Pop(); |
|
282 iTextureManager->iStateObservers.AppendL(*this); |
|
283 iTextureManager->iLoadObservers.AppendL(*this); |
|
284 |
|
285 // Create a font manager. |
|
286 iFontManager = iRenderer->CreateFontManagerL(); |
|
287 |
|
288 // Create a text style manager. |
|
289 iTextStyleManager = CHuiTextStyleManager::NewL(); |
|
290 iTextStyleManager->ConstructBuiltInStylesL(); |
|
291 |
|
292 // Create a visual factory. |
|
293 iVisualFactory = new (ELeave) CHuiVisualFactory(*this); |
|
294 |
|
295 // Create an effects engine |
|
296 iEffectsEngine = iRenderer->CreateEffectsEngineL(); |
|
297 |
|
298 // Cache the last input time. |
|
299 iLastInputTime = CHuiStatic::Time(); |
|
300 |
|
301 // Create a shared roster. This is used by all overlaid displays. |
|
302 iSharedRoster = new (ELeave) CHuiRosterImpl(NULL); |
|
303 |
|
304 /** @todo Create a skin here. This must be done in a better way. |
|
305 The skin can only be created when there is a EGL context because |
|
306 the skin will attempt to create textures and load fonts. */ |
|
307 |
|
308 if(!iSkin) |
|
309 { |
|
310 if(iEnvObserver) |
|
311 { |
|
312 iSkin = iEnvObserver->CreateSkinL(*this); |
|
313 } |
|
314 if(!iSkin) |
|
315 { |
|
316 // Create an instance of the default skin. The S60 skin uses data |
|
317 // and bitmaps from the current S60 skin. |
|
318 iSkin = new (ELeave) CHuiS60Skin(*this); |
|
319 (static_cast<CHuiS60Skin*>(iSkin))->ConstructL(); |
|
320 } |
|
321 } |
|
322 |
|
323 // DEPRECATED: JUST A DUMMY CONSTRUCTION TO PREVENT BREAKS |
|
324 //iThemeManager = CHuiThemeManager::NewL(); |
|
325 |
|
326 iCanvasTextureCache = CHuiCanvasTextureCache::NewL(); |
|
327 |
|
328 #ifndef SYMBIAN_BUILD_GCE |
|
329 #ifndef __WINSCW__ |
|
330 // for now, display fps information automatically if errrd installed |
|
331 if (eikenv) |
|
332 { |
|
333 _LIT(KRDSupport, "c:\\resource\\errrd" ); |
|
334 if (eikenv->FsSession().Handle() && BaflUtils::FileExists( eikenv->FsSession(), KRDSupport )) |
|
335 { |
|
336 SetFPSCounterThreshold(700); |
|
337 } |
|
338 } |
|
339 #endif |
|
340 #endif //SYMBIAN_BUILD_GCE |
|
341 HUI_DEBUG(_L("CHuiEnv::ConstructL - Working environment ready.")); |
|
342 } |
|
343 |
|
344 |
|
345 CHuiEnv::~CHuiEnv() |
|
346 { |
|
347 iActionObservers.Close(); |
|
348 |
|
349 // Destroy groups in reverse order so that references will be removed |
|
350 // in natural order. |
|
351 TInt i = 0; |
|
352 for(i = iLoadedGroups.Count() - 1; i >= 0; --i) |
|
353 { |
|
354 CHuiControlGroup* g = iLoadedGroups[i]; |
|
355 iLoadedGroups.Remove(i); |
|
356 delete g; |
|
357 } |
|
358 iLoadedGroups.Reset(); |
|
359 |
|
360 for(i = iDisplays.Count() - 1; i >= 0; --i) |
|
361 { |
|
362 // Deleting a display causes it to be automatically removed from the |
|
363 // displays array. |
|
364 delete iDisplays[i]; |
|
365 } |
|
366 |
|
367 iDisplays.Reset(); |
|
368 iOverlaidDisplays.Reset(); |
|
369 |
|
370 delete iCanvasTextureCache; |
|
371 |
|
372 delete iSharedRoster; |
|
373 delete iSkin; |
|
374 delete iVisualFactory; |
|
375 delete iTextureManager; |
|
376 delete iEffectsEngine; |
|
377 |
|
378 // DEPRECATED: JUST A DUMMY DESTRUCTION |
|
379 //delete iThemeManager; //Theme support |
|
380 |
|
381 delete iFontManager; |
|
382 delete iTextStyleManager; |
|
383 delete iPeriodic; |
|
384 delete iScheduler; |
|
385 iScheduler = NULL; |
|
386 delete iRenderer; |
|
387 delete iStatic; |
|
388 iEnvObserver = NULL; |
|
389 |
|
390 if (iIdleCPUValueMonitored) |
|
391 { |
|
392 CloseHandleToIdleCPUValueThread(); |
|
393 } |
|
394 |
|
395 iLowMemoryObservers.Close(); |
|
396 iMemoryLevelObservers.Close(); |
|
397 } |
|
398 |
|
399 |
|
400 void CHuiEnv::SetTextureManager(CHuiTextureManager& aManager) |
|
401 { |
|
402 iTextureManager = &aManager; |
|
403 } |
|
404 |
|
405 |
|
406 EXPORT_C THuiRenderer CHuiEnv::Renderer() const |
|
407 { |
|
408 return iRendererIdentifier; |
|
409 } |
|
410 |
|
411 |
|
412 EXPORT_C void CHuiEnv::SetRefreshMode(THuiRefreshMode aMode) |
|
413 { |
|
414 switch (aMode) |
|
415 { |
|
416 case EHuiRefreshModeManual: |
|
417 //HUI_DEBUG(_L("CHuiEnv::SetRefreshMode() - Setting manual refresh mode.")); |
|
418 break; |
|
419 case EHuiRefreshModeAutomatic: |
|
420 //HUI_DEBUG(_L("CHuiEnv::SetRefreshMode() - Setting automatic refresh mode.")); |
|
421 break; |
|
422 case EHuiRefreshModeForced: |
|
423 //HUI_DEBUG(_L("CHuiEnv::SetRefreshMode() - Setting forced refresh mode.")); |
|
424 break; |
|
425 default: |
|
426 //HUI_DEBUG(_L("CHuiEnv::SetRefreshMode() - ERROR! Tried to set unknown refresh mode! Ignoring..")); |
|
427 return; |
|
428 } |
|
429 |
|
430 |
|
431 #ifdef HUI_NGA_FORCED_REFRESH |
|
432 iRefreshMode = EHuiRefreshModeForced; |
|
433 #else |
|
434 iRefreshMode = aMode; |
|
435 #endif |
|
436 |
|
437 if(aMode == EHuiRefreshModeManual) |
|
438 { |
|
439 StopRefresh(); |
|
440 } |
|
441 else |
|
442 { |
|
443 StartRefresh(iRefreshIntervalTarget); |
|
444 } |
|
445 } |
|
446 |
|
447 |
|
448 EXPORT_C THuiRefreshMode CHuiEnv::RefreshMode() const |
|
449 { |
|
450 return iRefreshMode; |
|
451 } |
|
452 |
|
453 |
|
454 EXPORT_C void CHuiEnv::SetMaxFrameRate(TReal32 aFrameRate) __SOFTFP |
|
455 { |
|
456 #ifdef HUI_NGA_MIN_REFRESH_INTERVAL |
|
457 if (aFrameRate < (1000/KHuiEnvDefaultNormalRefreshIntervalMs)) |
|
458 aFrameRate = 1000/KHuiEnvDefaultNormalRefreshIntervalMs; |
|
459 #endif |
|
460 |
|
461 TInt oldIRefreshIntervalTarget = iRefreshIntervalTarget; |
|
462 if(aFrameRate != 0.0) |
|
463 { |
|
464 iRefreshIntervalTarget = TInt(1000 / aFrameRate); |
|
465 } |
|
466 else |
|
467 { |
|
468 iRefreshIntervalTarget = KHuiEnvDefaultNormalRefreshIntervalMs; |
|
469 } |
|
470 |
|
471 if(iRefreshIntervalTarget < 1) |
|
472 { |
|
473 iRefreshIntervalTarget = 1; |
|
474 } |
|
475 |
|
476 // If the refresh timer is running, update it. |
|
477 if(!iMaxCPUUtilization && /* Adaptive scheduling not enabled */ |
|
478 iPeriodic && (iPeriodic->IsActive() || iRefreshLoopActive ) && /* and heart beat already active */ |
|
479 oldIRefreshIntervalTarget != iRefreshIntervalTarget ) |
|
480 { |
|
481 StartRefresh(iRefreshIntervalTarget); |
|
482 } |
|
483 } |
|
484 |
|
485 |
|
486 EXPORT_C void CHuiEnv::StartRefresh(TInt aMilliSeconds) |
|
487 { |
|
488 StartRefresh(aMilliSeconds, aMilliSeconds); |
|
489 } |
|
490 |
|
491 void CHuiEnv::StartRefresh(TInt aIntervalInMilliSeconds, TInt aDelayInMilliseconds) |
|
492 { |
|
493 // Cancel the previous timer. |
|
494 StopRefresh(); |
|
495 |
|
496 if(iState == EReleased) |
|
497 { |
|
498 // When environment is released no refresh is done. |
|
499 return; |
|
500 } |
|
501 |
|
502 if ( aIntervalInMilliSeconds < 1 ) |
|
503 { |
|
504 HUI_DEBUG1(_L("CHuiEnv::StartRefresh() - Requested %i ms - too low!."), aIntervalInMilliSeconds); |
|
505 aIntervalInMilliSeconds = 1; |
|
506 } |
|
507 |
|
508 if (aIntervalInMilliSeconds > 1000) |
|
509 { |
|
510 HUI_DEBUG1(_L("CHuiEnv::StartRefresh() - Requested %i ms - too high!."), aIntervalInMilliSeconds); |
|
511 aIntervalInMilliSeconds = 1000; |
|
512 } |
|
513 |
|
514 if ( aDelayInMilliseconds < 1 ) |
|
515 { |
|
516 HUI_DEBUG1(_L("CHuiEnv::StartRefresh() - Requested %i aDelayInMilliseconds ms - too low!."), aDelayInMilliseconds); |
|
517 aDelayInMilliseconds = 1; |
|
518 } |
|
519 |
|
520 if (aDelayInMilliseconds > 1000) |
|
521 { |
|
522 HUI_DEBUG1(_L("CHuiEnv::StartRefresh() - Requested %i aDelayInMilliseconds ms - too high!."), aDelayInMilliseconds); |
|
523 aDelayInMilliseconds = 1000; |
|
524 } |
|
525 |
|
526 |
|
527 //HUI_DEBUG1(_L("CHuiEnv::StartRefresh() - Starting at %i ms interval."), aMilliSeconds); |
|
528 |
|
529 // Create a new refresh timer. |
|
530 |
|
531 TInt err(0); |
|
532 if (!iPeriodic) |
|
533 { |
|
534 #ifdef HUI_HIRES_TIMER |
|
535 TRAP(err, iPeriodic = CHighResTimer::NewL(TCallBack(CHuiEnv::RefreshCallBack, this), iRefreshLoopPriority)); |
|
536 #else |
|
537 TRAP( err, iPeriodic = CPeriodic::NewL(iRefreshLoopPriority) ); |
|
538 #endif |
|
539 } |
|
540 |
|
541 if (!err) |
|
542 { |
|
543 #ifdef HUI_HIRES_TIMER |
|
544 iPeriodic->CallBack( aIntervalInMilliSeconds ); |
|
545 #else |
|
546 iPeriodic->Start(TTimeIntervalMicroSeconds32(1000 * aDelayInMilliseconds), |
|
547 TTimeIntervalMicroSeconds32(1000 * aIntervalInMilliSeconds), |
|
548 TCallBack(CHuiEnv::RefreshCallBack, this)); |
|
549 #endif |
|
550 iRefreshLoopActive = ETrue; |
|
551 |
|
552 // Store current refresh interval |
|
553 iRefreshInterval = aIntervalInMilliSeconds; |
|
554 } |
|
555 } |
|
556 |
|
557 void CHuiEnv::StopRefresh() |
|
558 { |
|
559 //HUI_DEBUG(_L("CHuiEnv::StopRefresh()")); |
|
560 if(iPeriodic) |
|
561 { |
|
562 iPeriodic->Cancel(); |
|
563 iRefreshLoopActive = EFalse; |
|
564 } |
|
565 } |
|
566 |
|
567 |
|
568 EXPORT_C void CHuiEnv::ContinueRefresh() |
|
569 { |
|
570 ContinueRefresh(EFalse); |
|
571 } |
|
572 |
|
573 void CHuiEnv::ContinueRefresh(TBool aFastFirstRefresh) |
|
574 { |
|
575 if((iRefreshMode == EHuiRefreshModeManual) || |
|
576 (iState == EReleased)) |
|
577 { |
|
578 // When running in manual refresh mode, this has no effect. Refreshes |
|
579 // must be manually requested. |
|
580 // When environment is released no refresh is done. |
|
581 return; |
|
582 } |
|
583 |
|
584 if(!iPeriodic || ( !iPeriodic->IsActive() && !iRefreshLoopActive ) ) |
|
585 { |
|
586 HUI_DEBUG1(_L("CHuiEnv::ContinueRefresh() - Continuing normal refresh with %i ms intervals."), |
|
587 iRefreshInterval); |
|
588 |
|
589 TInt refreshDelay = aFastFirstRefresh ? 1 : iRefreshIntervalTarget; |
|
590 StartRefresh(iRefreshIntervalTarget, refreshDelay); |
|
591 |
|
592 // When refresh is paused, the frame rate is virtually infinite |
|
593 // since nothing needs to be done on each refresh. This means that |
|
594 // when refresh continues, the first elapsed step should be zero. |
|
595 // A call to UpdateTime() updates the internal absolute clock with |
|
596 // the latest time. |
|
597 CHuiStatic::UpdateTime(); |
|
598 } |
|
599 } |
|
600 |
|
601 EXPORT_C void CHuiEnv::PauseRefresh() |
|
602 { |
|
603 HUI_DEBUG(_L("CHuiEnv::PauseRefresh() - Refresh paused due to inactivity.")); |
|
604 HUI_DEBUG1(_L("CHuiEnv::PauseRefresh() - Free memory left: %i"), HuiUtil::FreeMemory()); |
|
605 StopRefresh(); |
|
606 } |
|
607 |
|
608 |
|
609 EXPORT_C CHuiDisplay& |
|
610 CHuiEnv::NewDisplayL(const TRect& aRect, CCoeControl* aNativeControl, TInt aFlags, |
|
611 CHuiDisplay* aDisplayToShareRoster, TInt aDisplayType ) |
|
612 { |
|
613 return NewDisplayL(aRect, aNativeControl, aFlags, aDisplayToShareRoster, aDisplayType, KHuiUidBackBufferScreen0); |
|
614 } |
|
615 |
|
616 |
|
617 EXPORT_C CHuiDisplay& |
|
618 CHuiEnv::NewDisplayL(const TRect& aRect, CCoeControl* aNativeControl, TInt aFlags, |
|
619 CHuiDisplay* aDisplayToShareRoster, TInt aDisplayType, TUid aBackBufferUid) |
|
620 { |
|
621 TBool isDisplayTypeTvOut = |
|
622 ((aDisplayType == CHuiDisplay::EDisplayTvOut) || |
|
623 (aDisplayType == CHuiDisplay::EDisplayTvOutWide) || |
|
624 ((aDisplayType == CHuiDisplay::EDisplayNormal) && |
|
625 ((aBackBufferUid == KHuiUidBackBufferTvOutNormal) || |
|
626 (aBackBufferUid == KHuiUidBackBufferTvOutWide)))); |
|
627 |
|
628 if ((iRendererIdentifier != EHuiRendererBitgdi) && |
|
629 (isDisplayTypeTvOut || (aDisplayType == CHuiDisplay::EDisplayOffScreenBuffer))) |
|
630 { |
|
631 User::Leave(KErrNotSupported); |
|
632 } |
|
633 |
|
634 CHuiRoster* roster = NULL; |
|
635 if (aDisplayToShareRoster) |
|
636 { |
|
637 roster = &aDisplayToShareRoster->Roster(); |
|
638 } |
|
639 if(aFlags & ENewDisplayOverlaid) |
|
640 { |
|
641 roster = iSharedRoster; |
|
642 } |
|
643 |
|
644 CHuiDisplay* display = new (ELeave) CHuiDisplay(*this, aNativeControl, aDisplayType, aBackBufferUid); |
|
645 CleanupStack::PushL(display); |
|
646 display->ConstructL(aRect, roster); |
|
647 User::LeaveIfError(iDisplays.Append(display)); |
|
648 CleanupStack::Pop(display); |
|
649 |
|
650 // Notify the current renderer of the changed number of displays |
|
651 iRenderer->NotifyDisplayCountL(iDisplays.Count()); |
|
652 |
|
653 HUI_DEBUG2(_L("HuiEnv::NewDisplay %x added to array, with flags %x"), display, aFlags); |
|
654 |
|
655 // Notify observers about new TvOut display |
|
656 if(isDisplayTypeTvOut) |
|
657 { |
|
658 ReportAction(THuiActionCommand(KHuiActionNewTVOutDisplayUid.iUid)); |
|
659 } |
|
660 |
|
661 return *display; |
|
662 } |
|
663 |
|
664 EXPORT_C CHuiDisplay& CHuiEnv::NewDisplayL(RWindow* aNativeWindow, |
|
665 TInt aFlags, |
|
666 CHuiDisplay* aDisplayToShareRoster, |
|
667 TInt aDisplayType, |
|
668 TUid aBackBufferUid) |
|
669 { |
|
670 CHuiRoster* roster = NULL; |
|
671 if (aDisplayToShareRoster) |
|
672 { |
|
673 roster = &aDisplayToShareRoster->Roster(); |
|
674 } |
|
675 if(aFlags & ENewDisplayOverlaid) |
|
676 { |
|
677 roster = iSharedRoster; |
|
678 } |
|
679 |
|
680 CHuiDisplay* display = new (ELeave) CHuiDisplay(*this, aNativeWindow, aDisplayType, aBackBufferUid); |
|
681 CleanupStack::PushL(display); |
|
682 display->ConstructL(TRect(TPoint(0,0),aNativeWindow->Size()), roster); |
|
683 User::LeaveIfError(iDisplays.Append(display)); |
|
684 CleanupStack::Pop(display); |
|
685 |
|
686 // Notify the current renderer of the changed number of displays |
|
687 iRenderer->NotifyDisplayCountL(iDisplays.Count()); |
|
688 |
|
689 HUI_DEBUG2(_L("HuiEnv::NewDisplay %x added to array, with flags %x"), display, aFlags); |
|
690 |
|
691 return *display; |
|
692 } |
|
693 |
|
694 |
|
695 EXPORT_C TInt CHuiEnv::DisplayCount() const |
|
696 { |
|
697 return iDisplays.Count(); |
|
698 } |
|
699 |
|
700 |
|
701 void CHuiEnv::RemoveDisplay(CHuiDisplay& aDisplay) |
|
702 { |
|
703 // Actually this is "DestroyDisplay" |
|
704 |
|
705 /** @todo Make a proper observer. */ |
|
706 TInt index = iDisplays.Find(&aDisplay); |
|
707 if(index >= 0) |
|
708 { |
|
709 iDisplays.Remove(index); |
|
710 } |
|
711 else |
|
712 { |
|
713 HUI_DEBUG1(_L("HuiEnv::DestroyContext: display %x not in array"), &aDisplay); |
|
714 } |
|
715 index = iOverlaidDisplays.Find(&aDisplay); |
|
716 if(index >= 0) |
|
717 { |
|
718 iOverlaidDisplays.Remove(index); |
|
719 } |
|
720 |
|
721 // Notify the current renderer of the changed number of displays |
|
722 TRAP_IGNORE(iRenderer->NotifyDisplayCountL(iDisplays.Count())) |
|
723 |
|
724 #ifdef _DEBUG |
|
725 HUI_DEBUG(_L(" Contents of iDisplays:")); |
|
726 for(TInt i = 0; i < iDisplays.Count(); ++i) |
|
727 { |
|
728 HUI_DEBUG2(_L(" %i: %x"), i, iDisplays[i]); |
|
729 } |
|
730 #endif |
|
731 } |
|
732 |
|
733 |
|
734 EXPORT_C TInt CHuiEnv::RefreshCallBack(TAny* aInstance) |
|
735 { |
|
736 ASSERT( aInstance ); |
|
737 CHuiEnv* self = static_cast<CHuiEnv*>( aInstance ); |
|
738 |
|
739 TReal32 elapsedTime = 0; |
|
740 |
|
741 // Investigate whether the environment is released |
|
742 if(self->iState == EReleased) |
|
743 { |
|
744 HUI_DEBUG(_L("CHuiEnv::RefreshCallBack() - Warning: Refresh callback called while environment is released.")); |
|
745 return KErrNone; |
|
746 } |
|
747 |
|
748 self->SetTimeFromLastUpdate(CHuiStatic::MilliSecondsSinceUpdateTime()); |
|
749 // Compute the elapsed time (in sec.) between the current and the |
|
750 // previous refresh call. |
|
751 CHuiStatic::UpdateTime(); |
|
752 elapsedTime = CHuiStatic::ElapsedSeconds(); |
|
753 |
|
754 // Time advancements should not happen in too large increments. |
|
755 /** @todo The time advancement should be done in steps if the |
|
756 elapsed time is too long. The static time in CHuiStatic |
|
757 should also be updated using the same steps. This will |
|
758 allow scheduled commands to be executed and timed |
|
759 correctly (start times of timed transitions). */ |
|
760 |
|
761 HUI_DEBUGF1(_L("CHuiEnv::RefreshCallBack() - Elapsed time: %f"), elapsedTime); |
|
762 |
|
763 if (elapsedTime < 0) |
|
764 { |
|
765 elapsedTime = 1; |
|
766 } |
|
767 |
|
768 self->AdvanceTime(elapsedTime); |
|
769 |
|
770 // Report the current frame rate at certain intervals. |
|
771 TReal32 nowTime = CHuiStatic::SecondsSinceStart(); |
|
772 if(nowTime - self->iPreviousFpsTime > 3) |
|
773 { |
|
774 HUI_DEBUG1(_L("CHuiEnv::RefreshCallBack() - FPS: %f"), CHuiStatic::FrameRate()); |
|
775 self->iPreviousFpsTime = nowTime; |
|
776 } |
|
777 |
|
778 return KErrNone; |
|
779 } |
|
780 |
|
781 |
|
782 void CHuiEnv::AdvanceTime(TReal32 aElapsedTime) |
|
783 { |
|
784 HUI_DEBUGF( _L("CHuiEnv::AdvanceTime() - Started") ); |
|
785 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
786 TTime startTime; |
|
787 TTime endTime; |
|
788 #endif |
|
789 |
|
790 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
791 RDebug::Print(_L("CHuiEnv::AdvanceTime starting measuring 0.")); |
|
792 startTime.UniversalTime(); |
|
793 #endif |
|
794 |
|
795 |
|
796 TUint usedMaxCPUUtilization = iMaxCPUUtilization; |
|
797 |
|
798 // Calculate cpu values based on null thread cpu usage between frames. |
|
799 // Values will be updated at the end of the frame. |
|
800 if (iIdleCPUValueMonitored && usedMaxCPUUtilization) |
|
801 { |
|
802 TTime currentTime; |
|
803 currentTime.HomeTime(); |
|
804 |
|
805 TTimeIntervalMicroSeconds cputime; |
|
806 iIdleCPUValueThread.GetCpuTime(cputime); |
|
807 |
|
808 TInt64 cpudelta = cputime.Int64() - iIdleCPUValue; |
|
809 TInt64 timedelta = currentTime.Int64() - iIdleCPUValuePreviousTime; |
|
810 |
|
811 // If null thread was runnign between frames, we could use more cpu if needed. |
|
812 if (cpudelta && timedelta) |
|
813 { |
|
814 // Calculate how much we want ! |
|
815 if (iMaxCPUUtilization > KHuiEnvMaxCpuTimeOverdriveLowerThreshold && |
|
816 iMaxCPUUtilization < KHuiEnvMaxCpuTimeOverdriveMaxValue ) |
|
817 { |
|
818 usedMaxCPUUtilization += (KHuiEnvMaxCpuTimeOverdriveMaxValue - iMaxCPUUtilization) * cpudelta/timedelta; |
|
819 |
|
820 // Sanity check just in case cpu/time measurements are not accurate |
|
821 if (usedMaxCPUUtilization > KHuiEnvMaxCpuTimeOverdriveMaxValue) |
|
822 { |
|
823 usedMaxCPUUtilization = KHuiEnvMaxCpuTimeOverdriveMaxValue; |
|
824 } |
|
825 |
|
826 if (usedMaxCPUUtilization < iMaxCPUUtilization) |
|
827 { |
|
828 usedMaxCPUUtilization = iMaxCPUUtilization; |
|
829 } |
|
830 } |
|
831 } |
|
832 } |
|
833 |
|
834 if(aElapsedTime > 0) |
|
835 { |
|
836 // Let the scheduler know that time has passed. It will possible animate |
|
837 // visuals and perform actions, causing dirty regions in the display. |
|
838 iScheduler->AdvanceTime(aElapsedTime); |
|
839 |
|
840 // Scheduled command might have released the environment. |
|
841 if(iState == EReleased) |
|
842 { |
|
843 HUI_DEBUG(_L("CHuiEnv::AdvanceTime() - Environment released when executing scheduled commands. AdvanceTime cancelled.")); |
|
844 return; |
|
845 } |
|
846 |
|
847 // Let the texture manager know that time has passed. It will update any |
|
848 // animated textures. |
|
849 iTextureManager->AdvanceTime(aElapsedTime); |
|
850 // Notify the effects engine to update animated effects |
|
851 if (iEffectsEngine) |
|
852 { |
|
853 iEffectsEngine->AdvanceTime(aElapsedTime); |
|
854 |
|
855 // Notify the effects end observers |
|
856 iEffectsEngine->NotifyEffectEndObservers(); |
|
857 } |
|
858 } |
|
859 |
|
860 // Check for no input for long time. |
|
861 TTime now = CHuiStatic::Time(); |
|
862 TTimeIntervalSeconds seconds = 0; |
|
863 now.SecondsFrom(iLastInputTime, seconds); |
|
864 if(seconds.Int() >= iIdleThreshold && !iInputIdleIsActive) |
|
865 { |
|
866 HUI_DEBUG1(_L("CHuiEnv::AdvanceTime() - No input received within %i seconds. Going to idle."), iIdleThreshold); |
|
867 iInputIdleIsActive = ETrue; |
|
868 |
|
869 // Idle state begins. |
|
870 TRAPD(err, SendIdleL(ETrue)); |
|
871 if(err != KErrNone) |
|
872 { |
|
873 // @todo Log error? |
|
874 } |
|
875 |
|
876 // Switching to idle state might have released the environment. |
|
877 if(iState == EReleased) |
|
878 { |
|
879 HUI_DEBUG(_L("CHuiEnv::AdvanceTime() - Environment released when switching to idle state. AdvanceTime cancelled.")); |
|
880 return; |
|
881 } |
|
882 } |
|
883 |
|
884 TBool somethingUpdated = EFalse; |
|
885 |
|
886 // Refresh all displays. |
|
887 TInt i; |
|
888 const TInt displayCount = iDisplays.Count(); |
|
889 RArray<TBool> displayRefreshed( displayCount ? displayCount : 1 ); |
|
890 for(i = 0; i < iDisplays.Count(); ++i) |
|
891 { |
|
892 displayRefreshed.Append(EFalse); |
|
893 if(iRefreshMode == EHuiRefreshModeForced || iDisplays[i]->IsDirty()) |
|
894 { |
|
895 MakeCurrent(*iDisplays[i]); |
|
896 |
|
897 HUI_DEBUGF1( _L("CHuiEnv::AdvanceTime() - Refreshing display %i"), i ); |
|
898 TBool updated = iDisplays[i]->Refresh(); |
|
899 displayRefreshed[i] = updated; |
|
900 if(updated) |
|
901 { |
|
902 somethingUpdated = ETrue; |
|
903 } |
|
904 } |
|
905 } |
|
906 |
|
907 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
908 endTime.UniversalTime(); |
|
909 TInt timeInMs = endTime.MicroSecondsFrom( startTime ).Int64()/1000; |
|
910 RDebug::Print(_L("CHuiEnv::AdvanceTime first part %i ms"), timeInMs); |
|
911 #endif |
|
912 |
|
913 TBool continueRefresh = ETrue; |
|
914 |
|
915 if(somethingUpdated) |
|
916 { |
|
917 |
|
918 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
919 RDebug::Print(_L("CHuiEnv::AdvanceTime starting measuring 2.")); |
|
920 startTime.UniversalTime(); |
|
921 #endif |
|
922 |
|
923 iIdleRefreshCount = 0; |
|
924 // Clear change flags now that the frames are complete. |
|
925 for(i = 0; i < iDisplays.Count(); ++i) |
|
926 { |
|
927 // Clear changed for an off screen display only if the buffer has new content. |
|
928 // Index is ok becacause displayRefreshed array was defined using size of iDisplays array |
|
929 if (displayRefreshed[i]) |
|
930 { |
|
931 iDisplays[i]->ClearChanged(); |
|
932 } |
|
933 } |
|
934 } |
|
935 else if(iScheduler->PendingCount() == 0) |
|
936 { |
|
937 // But if there are scheduled commands, let's make sure they'll get |
|
938 // executed at the right time. They might get badly delayed if the |
|
939 // refresh wasn't occuring. |
|
940 |
|
941 /** @todo Use a separate timer for the scheduler? */ |
|
942 |
|
943 // Nothing happened during the display refreshing. |
|
944 iIdleRefreshCount++; |
|
945 |
|
946 // If this occurs too often, pause refresh automatically. |
|
947 if(iIdleRefreshCount > KIdleRefreshCountThreshold) |
|
948 { |
|
949 if (iFpsCounterThreshold && iMillisecondFromFPSUpdate && iFrames) |
|
950 { |
|
951 TBuf<16> numBuf; |
|
952 TReal fps = 1000*(TReal)iFrames/iMillisecondFromFPSUpdate; |
|
953 numBuf.AppendNum(fps, TRealFormat(5,2)); |
|
954 User::InfoPrint(numBuf); |
|
955 iFrames = 0; |
|
956 iMillisecondFromFPSUpdate = 0; |
|
957 } |
|
958 |
|
959 PauseRefresh(); |
|
960 continueRefresh = EFalse; |
|
961 } |
|
962 } |
|
963 else |
|
964 { |
|
965 // for PC lint |
|
966 } |
|
967 |
|
968 if(somethingUpdated) |
|
969 { |
|
970 HUI_DEBUGF( _L("CHuiEnv::AdvanceTime() - Swap buffers") ); |
|
971 |
|
972 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
973 RDebug::Print(_L("CHuiEnv::AdvanceTime starting measuring 1.")); |
|
974 startTime.UniversalTime(); |
|
975 #endif |
|
976 |
|
977 SwapBuffers(displayRefreshed); |
|
978 |
|
979 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
980 endTime.UniversalTime(); |
|
981 TInt timeInMs = endTime.MicroSecondsFrom( startTime ).Int64()/1000; |
|
982 RDebug::Print(_L("CHuiEnv::AdvanceTime swapbuffers took %i ms"), timeInMs); |
|
983 #endif |
|
984 } |
|
985 |
|
986 displayRefreshed.Close(); // Not needed any more |
|
987 |
|
988 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
989 endTime.UniversalTime(); |
|
990 timeInMs = endTime.MicroSecondsFrom( startTime ).Int64()/1000; |
|
991 RDebug::Print(_L("CHuiEnv::AdvanceTime iDisplays[i]->ClearChanged() took %i ms"), timeInMs); |
|
992 #endif |
|
993 |
|
994 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
995 RDebug::Print(_L("CHuiEnv::AdvanceTime starting measuring 3.")); |
|
996 startTime.UniversalTime(); |
|
997 #endif |
|
998 |
|
999 |
|
1000 // Clear change flags of all control groups now that the refresh has |
|
1001 // been completed for all displays. |
|
1002 // |
|
1003 // DEPRECATE: |
|
1004 // This should be removed when control opacities are deprecated! |
|
1005 // Controls shouldn't need change flags because change flags are |
|
1006 // only for the refresh. |
|
1007 // |
|
1008 for(i = 0; i < iLoadedGroups.Count(); ++i) |
|
1009 { |
|
1010 iLoadedGroups[i]->ClearChanged(); |
|
1011 } |
|
1012 |
|
1013 iTextureManager->ClearChangedTextures(); |
|
1014 iCanvasTextureCache->AdvanceTime(); |
|
1015 |
|
1016 #ifdef HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL |
|
1017 endTime.UniversalTime(); |
|
1018 timeInMs = endTime.MicroSecondsFrom( startTime ).Int64()/1000; |
|
1019 RDebug::Print(_L("CHuiEnv::AdvanceTime textures ClearChanged() and other stuff took %i ms"), timeInMs); |
|
1020 #endif |
|
1021 |
|
1022 if (continueRefresh) |
|
1023 { |
|
1024 TUint refreshTime = CHuiStatic::MilliSecondsSinceUpdateTime(); |
|
1025 // Refresh rate adjustment |
|
1026 if (usedMaxCPUUtilization) |
|
1027 { |
|
1028 // Estimated frame, when sleep time is included. |
|
1029 TUint estimatedTotalRefreshTime = (refreshTime * 100) / usedMaxCPUUtilization; |
|
1030 |
|
1031 if (estimatedTotalRefreshTime >= iRefreshIntervalTarget) |
|
1032 { |
|
1033 // Rendering slower that fps limit set by user. |
|
1034 // Start refresh after the sleep period as the frame has already been rendered. |
|
1035 StartRefresh(estimatedTotalRefreshTime - refreshTime); |
|
1036 } |
|
1037 #ifndef HUI_HIRES_TIMER |
|
1038 else if (iRefreshIntervalTarget != iRefreshInterval) |
|
1039 { |
|
1040 StartRefresh(iRefreshIntervalTarget); |
|
1041 } |
|
1042 #endif |
|
1043 else |
|
1044 { |
|
1045 // Rendering faster than the fps limit set by user. Limit fps to target fps. |
|
1046 // The sleep time is the full frame time less by the render time. |
|
1047 #ifdef HUI_HIRES_TIMER |
|
1048 StartRefresh( iRefreshIntervalTarget - refreshTime ); |
|
1049 #endif |
|
1050 } |
|
1051 } |
|
1052 else |
|
1053 { |
|
1054 // No CPU utilisation. |
|
1055 // The sleep time is the full frame time less by the render time. |
|
1056 #ifdef HUI_HIRES_TIMER |
|
1057 StartRefresh( iRefreshIntervalTarget - refreshTime ); |
|
1058 #endif |
|
1059 } |
|
1060 |
|
1061 if (iFpsCounterThreshold && iMillisecondFromFPSUpdate > iFpsCounterThreshold) |
|
1062 { |
|
1063 TBuf<16> numBuf; |
|
1064 TReal fps = 1000*(TReal)iFrames/iMillisecondFromFPSUpdate; |
|
1065 numBuf.AppendNum(fps, TRealFormat(5,2)); |
|
1066 User::InfoPrint(numBuf); |
|
1067 iFrames = 0; |
|
1068 iMillisecondFromFPSUpdate = 0; |
|
1069 } |
|
1070 } |
|
1071 |
|
1072 iCurrentDisplay = NULL; // informs the egosystem that the drawing is done. |
|
1073 CHuiStatic::ReportNewFrame(); |
|
1074 |
|
1075 // Store cpu value conters of null thread. Values will be used at the start of the next frame. |
|
1076 if (iIdleCPUValueMonitored) |
|
1077 { |
|
1078 TTime currentTime; |
|
1079 currentTime.HomeTime(); |
|
1080 |
|
1081 TTimeIntervalMicroSeconds cputime; |
|
1082 iIdleCPUValueThread.GetCpuTime(cputime); |
|
1083 |
|
1084 // Store as previous values |
|
1085 iIdleCPUValue = cputime.Int64(); |
|
1086 iIdleCPUValuePreviousTime = currentTime.Int64(); |
|
1087 } |
|
1088 |
|
1089 HUI_DEBUGF( _L("CHuiEnv::AdvanceTime() - Exited") ); |
|
1090 } |
|
1091 |
|
1092 |
|
1093 EXPORT_C TBool CHuiEnv::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType, |
|
1094 CHuiDisplay* aAssocDisplay) |
|
1095 { |
|
1096 if(aAssocDisplay) |
|
1097 { |
|
1098 THuiEvent event(aAssocDisplay, aKeyEvent, aType); |
|
1099 |
|
1100 // Notify the environment itself. |
|
1101 NotifyInputReceivedL(event); |
|
1102 |
|
1103 if(aAssocDisplay->Roster().HandleEventL(event)) |
|
1104 { |
|
1105 return EKeyWasConsumed; |
|
1106 } |
|
1107 return EKeyWasNotConsumed; |
|
1108 } |
|
1109 |
|
1110 return EKeyWasNotConsumed; |
|
1111 } |
|
1112 |
|
1113 |
|
1114 void CHuiEnv::NotifyInputReceivedL(const THuiEvent& aEvent) |
|
1115 { |
|
1116 ContinueRefresh(); |
|
1117 |
|
1118 if(aEvent.IsKeyEvent() || aEvent.IsPointerEvent()) |
|
1119 { |
|
1120 if(iInputIdleIsActive) |
|
1121 { |
|
1122 HUI_DEBUG(_L("CHuiEnv::NotifyInputReceivedL() - Got key/pointer input! Idle state ends!")); |
|
1123 // Idle state ends. |
|
1124 SendIdleL(EFalse); |
|
1125 } |
|
1126 |
|
1127 iLastInputTime = CHuiStatic::Time(); |
|
1128 iInputIdleIsActive = EFalse; |
|
1129 } |
|
1130 } |
|
1131 |
|
1132 |
|
1133 void CHuiEnv::SendIdleL(TBool aIdleBegins) |
|
1134 { |
|
1135 CHuiDisplay* display = NULL; |
|
1136 |
|
1137 if(iDisplays.Count() != 0) |
|
1138 { |
|
1139 // If we have any displays, pass the first one. |
|
1140 display = iDisplays[0]; |
|
1141 } |
|
1142 |
|
1143 THuiEvent idleEvent(display, |
|
1144 aIdleBegins ? THuiEvent::ETypeIdleBegin : |
|
1145 THuiEvent::ETypeIdleEnd); |
|
1146 BroadcastEventL(idleEvent); |
|
1147 } |
|
1148 |
|
1149 |
|
1150 EXPORT_C void CHuiEnv::SetIdleThreshold(TInt aMilliSeconds) |
|
1151 { |
|
1152 iIdleThreshold = aMilliSeconds/1000; |
|
1153 } |
|
1154 |
|
1155 |
|
1156 EXPORT_C void CHuiEnv::BroadcastEventL(const THuiEvent& aEvent) |
|
1157 { |
|
1158 for(TInt i = 0; i < iDisplays.Count(); ++i) |
|
1159 { |
|
1160 THuiEvent event = aEvent; |
|
1161 event.iDisplay = iDisplays[i]; |
|
1162 /** @todo Musn't access the roster directly. */ |
|
1163 iDisplays[i]->Roster().HandleEventL(event); |
|
1164 } |
|
1165 } |
|
1166 |
|
1167 |
|
1168 void CHuiEnv::MakeCurrent(const CHuiDisplay& aDisplay) const |
|
1169 { |
|
1170 aDisplay.RenderSurface().MakeCurrent(); |
|
1171 iCurrentDisplay = const_cast<CHuiDisplay*>(&aDisplay); |
|
1172 } |
|
1173 |
|
1174 |
|
1175 void CHuiEnv::SwapBuffers(const RArray<TBool>& aDisplayRefreshed) |
|
1176 { |
|
1177 /** @todo This may not work as expected when multiple displays are |
|
1178 being used. */ |
|
1179 |
|
1180 if (iFpsCounterThreshold) |
|
1181 { |
|
1182 iFrames++; |
|
1183 iMillisecondFromFPSUpdate += iRefreshIntervalReal; |
|
1184 } |
|
1185 |
|
1186 /** @todo Only swap the visible displays. */ |
|
1187 |
|
1188 for(TInt i = 0; i < iDisplays.Count(); ++i) |
|
1189 { |
|
1190 // Index should ok becacause displayRefreshed array was defined using size of iDisplays array |
|
1191 // This function should only be called from inside CHuiEnv even if it is public. |
|
1192 // At least it is not exported. |
|
1193 if (aDisplayRefreshed[i] |
|
1194 && (iDisplays[i]->DisplayType() != CHuiDisplay::EDisplayOffScreenBuffer) |
|
1195 && (iDisplays[i]->ScreenBufferObserver() == NULL)) |
|
1196 { |
|
1197 MakeCurrent(*iDisplays[i]); |
|
1198 if (iSwapObserver) |
|
1199 iSwapObserver->PrepareSwap(); |
|
1200 iDisplays[i]->RenderSurface().SwapBuffers(); |
|
1201 if (iSwapObserver) |
|
1202 iSwapObserver->SwapComplete(); |
|
1203 |
|
1204 } |
|
1205 } |
|
1206 } |
|
1207 |
|
1208 |
|
1209 void CHuiEnv::CreateResourceReaderLC(TResourceReader& aReader, TInt aResourceId) const |
|
1210 { |
|
1211 CCoeEnv* coe = CCoeEnv::Static(); |
|
1212 if (!coe) |
|
1213 { |
|
1214 User::Leave(KErrNotSupported); |
|
1215 } |
|
1216 coe->CreateResourceReaderLC(aReader, aResourceId); |
|
1217 } |
|
1218 |
|
1219 |
|
1220 EXPORT_C CHuiControlGroup& CHuiEnv::NewControlGroupL(TInt aId) |
|
1221 { |
|
1222 CHuiControlGroup* group = new (ELeave) CHuiControlGroup(aId, *this); |
|
1223 CleanupStack::PushL(group); |
|
1224 User::LeaveIfError(iLoadedGroups.Append(group)); |
|
1225 CleanupStack::Pop(group); |
|
1226 return *group; |
|
1227 } |
|
1228 |
|
1229 |
|
1230 EXPORT_C TInt CHuiEnv::DeleteControlGroup(TInt aId) |
|
1231 { |
|
1232 TInt i; |
|
1233 |
|
1234 for(i = 0; i < iLoadedGroups.Count(); ++i) |
|
1235 { |
|
1236 if(iLoadedGroups[i]->ResourceId() == aId) |
|
1237 { |
|
1238 // This is control group to delete. |
|
1239 CHuiControlGroup* group = iLoadedGroups[i]; |
|
1240 CancelCommands(group); |
|
1241 |
|
1242 for (TInt ii = iDisplays.Count()-1; ii>=0; ii--) |
|
1243 { |
|
1244 TInt index = iDisplays[ii]->Roster().Find(group); |
|
1245 if (index != KErrNotFound) |
|
1246 { |
|
1247 iDisplays[ii]->Roster().Hide(iDisplays[ii]->Roster().ControlGroup(index)); |
|
1248 } |
|
1249 } |
|
1250 |
|
1251 iLoadedGroups.Remove(i); |
|
1252 delete group; |
|
1253 return KErrNone; |
|
1254 } |
|
1255 } |
|
1256 |
|
1257 return KErrNotFound; |
|
1258 } |
|
1259 |
|
1260 |
|
1261 EXPORT_C CHuiControlGroup& CHuiEnv::LoadControlGroupL(TInt aResourceId) |
|
1262 { |
|
1263 CHuiControlGroup* group = new (ELeave) CHuiControlGroup(aResourceId, *this); |
|
1264 CleanupStack::PushL(group); |
|
1265 |
|
1266 // Create a resource reader and construct the group and its controls. |
|
1267 TResourceReader reader; |
|
1268 CreateResourceReaderLC(reader, aResourceId); |
|
1269 group->ConstructFromResourceL(reader); |
|
1270 CleanupStack::PopAndDestroy(); // reader |
|
1271 |
|
1272 // Add the control group to the list of all existing groups. |
|
1273 // The environment will retain ownership of the group. |
|
1274 User::LeaveIfError( iLoadedGroups.Append(group) ); |
|
1275 |
|
1276 CleanupStack::Pop(group); |
|
1277 return *group; |
|
1278 } |
|
1279 |
|
1280 |
|
1281 EXPORT_C void CHuiEnv::LoadBitmapsL(TInt aResourceId) |
|
1282 { |
|
1283 TResourceReader reader; |
|
1284 CreateResourceReaderLC(reader, aResourceId); |
|
1285 |
|
1286 TInt count = reader.ReadInt16(); |
|
1287 HUI_DEBUG2(_L("CHuiEnv::LoadBitmapsL() - Registering %i bitmaps from resource id %i to the texture manager."), count, aResourceId); |
|
1288 |
|
1289 TInt i = 0; |
|
1290 CHuiTextureManager & manager = TextureManager(); |
|
1291 for(i = 0; i < count; ++i) |
|
1292 { |
|
1293 TInt id = reader.ReadInt32(); |
|
1294 TPtrC fileName = reader.ReadTPtrC(); |
|
1295 HUI_DEBUG2(_L("CHuiEnv::LoadBitmapsL() - Bitmap id %i: \"%S\""), id, &fileName); |
|
1296 manager.DefineFileNameL(id, fileName); |
|
1297 } |
|
1298 |
|
1299 CleanupStack::PopAndDestroy(); // reader |
|
1300 } |
|
1301 |
|
1302 |
|
1303 EXPORT_C CHuiControlGroup& CHuiEnv::ControlGroup(TInt aResourceId) |
|
1304 { |
|
1305 for(TInt i = 0; i < iLoadedGroups.Count(); ++i) |
|
1306 { |
|
1307 if(iLoadedGroups[i]->ResourceId() == aResourceId) |
|
1308 { |
|
1309 return *iLoadedGroups[i]; |
|
1310 } |
|
1311 } |
|
1312 |
|
1313 // Group hasn't been loaded yet |
|
1314 /** @todo load automatically? */ |
|
1315 THuiPanic::Panic(THuiPanic::EInternal); |
|
1316 return *iLoadedGroups[0]; |
|
1317 } |
|
1318 |
|
1319 |
|
1320 EXPORT_C CHuiControl* CHuiEnv::FindControl(TInt aId) const |
|
1321 { |
|
1322 for(TInt i = 0; i < iLoadedGroups.Count(); ++i) |
|
1323 { |
|
1324 CHuiControl* control = iLoadedGroups[i]->FindControl(aId); |
|
1325 if(control) |
|
1326 { |
|
1327 return control; |
|
1328 } |
|
1329 } |
|
1330 // The control does not exist. |
|
1331 return NULL; |
|
1332 } |
|
1333 |
|
1334 |
|
1335 EXPORT_C CHuiVisualFactory& CHuiEnv::VisualFactory() const |
|
1336 { |
|
1337 return *iVisualFactory; |
|
1338 } |
|
1339 |
|
1340 |
|
1341 EXPORT_C CHuiTextureManager& CHuiEnv::TextureManager() const |
|
1342 { |
|
1343 return *iTextureManager; |
|
1344 } |
|
1345 |
|
1346 |
|
1347 EXPORT_C THuiFontManager& CHuiEnv::FontManager() const |
|
1348 { |
|
1349 return *iFontManager; |
|
1350 } |
|
1351 |
|
1352 |
|
1353 EXPORT_C CHuiTextStyleManager& CHuiEnv::TextStyleManager() const |
|
1354 { |
|
1355 return *iTextStyleManager; |
|
1356 } |
|
1357 |
|
1358 |
|
1359 EXPORT_C CHuiSkin& CHuiEnv::Skin() const |
|
1360 { |
|
1361 return *iSkin; |
|
1362 } |
|
1363 |
|
1364 |
|
1365 EXPORT_C void CHuiEnv::NotifySkinChangedL() |
|
1366 { |
|
1367 ReportAction(THuiActionCommand(KAknsMessageSkinChange)); |
|
1368 for(TInt i = 0; i < iDisplays.Count(); ++i) |
|
1369 { |
|
1370 iDisplays[i]->RosterImpl().NotifySkinChangedL(); |
|
1371 } |
|
1372 iTextureManager->NotifySkinChangedL(); |
|
1373 } |
|
1374 |
|
1375 |
|
1376 EXPORT_C TInt CHuiEnv::Send(const THuiCommand& aCommand, TInt aDelayMilliSeconds) |
|
1377 { |
|
1378 TRAPD(err, SendL(aCommand, aDelayMilliSeconds)); |
|
1379 if(err != KErrNone) |
|
1380 { |
|
1381 HUI_DEBUG1(_L("CHuiEnv::Send() - Leave %i while posting command."), err); |
|
1382 } |
|
1383 return err; |
|
1384 } |
|
1385 |
|
1386 |
|
1387 EXPORT_C void CHuiEnv::SendL(const THuiCommand& aCommand, TInt aDelayMilliSeconds) |
|
1388 { |
|
1389 ContinueRefresh(); |
|
1390 iScheduler->PostCommandL(aCommand, aDelayMilliSeconds); |
|
1391 } |
|
1392 |
|
1393 |
|
1394 EXPORT_C void CHuiEnv::CancelCommands(TAny* aObject) |
|
1395 { |
|
1396 if (iScheduler) |
|
1397 { |
|
1398 iScheduler->CancelCommands(aObject); |
|
1399 } |
|
1400 } |
|
1401 |
|
1402 |
|
1403 EXPORT_C void CHuiEnv::CancelCommands(MHuiEventHandler* aObject) |
|
1404 { |
|
1405 if (iScheduler) |
|
1406 { |
|
1407 iScheduler->CancelCommands(aObject); |
|
1408 } |
|
1409 } |
|
1410 |
|
1411 |
|
1412 EXPORT_C void CHuiEnv::CancelCommands(TAny* aObject, |
|
1413 THuiOp aCommandOperation) |
|
1414 { |
|
1415 if (iScheduler) |
|
1416 { |
|
1417 iScheduler->CancelCommands(aObject, aCommandOperation); |
|
1418 } |
|
1419 } |
|
1420 |
|
1421 |
|
1422 EXPORT_C void CHuiEnv::CancelCommands(TAny* aObject, |
|
1423 THuiCommandType aCommandType, |
|
1424 TInt aParam) |
|
1425 { |
|
1426 if (iScheduler) |
|
1427 { |
|
1428 iScheduler->CancelCommands(aObject, aCommandType, aParam); |
|
1429 } |
|
1430 } |
|
1431 |
|
1432 |
|
1433 EXPORT_C TInt CHuiEnv::TimeUntilCommand(TAny* aObject, |
|
1434 THuiCommandType aCommandType) |
|
1435 { |
|
1436 return iScheduler->TimeUntilCommand(aObject, aCommandType); |
|
1437 } |
|
1438 |
|
1439 |
|
1440 void CHuiEnv::TextureLoadingCompleted(CHuiTexture& /*aTexture*/, |
|
1441 TInt /*aTextureId*/, |
|
1442 TInt /*aErrorCode*/) |
|
1443 { |
|
1444 // Texture changed flag has been set, visuals should redraw |
|
1445 // changed textures automatically. |
|
1446 } |
|
1447 |
|
1448 |
|
1449 void CHuiEnv::TextureManagerStateChanged(const CHuiTextureManager& aManager) |
|
1450 { |
|
1451 if(aManager.State() == CHuiTextureManager::EIdle) |
|
1452 { |
|
1453 StartRefresh(iRefreshIntervalTarget); |
|
1454 } |
|
1455 else if (!iMaxCPUUtilization) |
|
1456 { // only use busy refresh interwall if adaptive scheduling is not enabled |
|
1457 StartRefresh(KHuiEnvDefaultBusyRefreshIntervalMs); |
|
1458 } |
|
1459 else |
|
1460 { |
|
1461 // for PC lint |
|
1462 } |
|
1463 } |
|
1464 |
|
1465 |
|
1466 EXPORT_C CHuiDisplay& CHuiEnv::PrimaryDisplay() const |
|
1467 { |
|
1468 return *iDisplays[0]; |
|
1469 } |
|
1470 |
|
1471 |
|
1472 EXPORT_C CHuiDisplay& CHuiEnv::Display(TInt aIndex) const |
|
1473 { |
|
1474 return *iDisplays[aIndex]; |
|
1475 } |
|
1476 |
|
1477 |
|
1478 EXPORT_C void CHuiEnv::Release() |
|
1479 { |
|
1480 if(iState == ENormal) |
|
1481 { |
|
1482 HUI_DEBUG(_L("CHuiEnv::Release() - Switching to background!")); |
|
1483 |
|
1484 ReportAction(THuiActionCommand(KHuiEnvReleasedActionId)); |
|
1485 |
|
1486 // Pause refresh. |
|
1487 PauseRefresh(); |
|
1488 |
|
1489 // Release the displays. |
|
1490 for(TInt i = 0; i < iDisplays.Count(); ++i) |
|
1491 { |
|
1492 iDisplays[i]->Release(); |
|
1493 } |
|
1494 |
|
1495 // Release the texture manager. |
|
1496 TBool allTexturesReleased = iTextureManager->Release(); |
|
1497 |
|
1498 // Release the rendering plugin only if all the textures are released. |
|
1499 if ( allTexturesReleased ) |
|
1500 { |
|
1501 HUI_DEBUG(_L("CHuiEnv::Release() - All textures released - releasing renderer")); |
|
1502 iRenderer->Release(); |
|
1503 } |
|
1504 if (iEffectsEngine) |
|
1505 { |
|
1506 iEffectsEngine->Release(); |
|
1507 } |
|
1508 |
|
1509 // Finally set the new state. |
|
1510 iState = EReleased; |
|
1511 } |
|
1512 } |
|
1513 |
|
1514 |
|
1515 EXPORT_C void CHuiEnv::RestoreL() |
|
1516 { |
|
1517 if(iState == EReleased) |
|
1518 { |
|
1519 HUI_DEBUG(_L("CHuiEnv::RestoreL() - Coming back to foreground!")); |
|
1520 |
|
1521 // Restore the renderer plugin. |
|
1522 iRenderer->RestoreL(); |
|
1523 |
|
1524 // Restore the texture manager. |
|
1525 iTextureManager->RestoreL(); |
|
1526 if (iEffectsEngine) |
|
1527 { |
|
1528 iEffectsEngine->RestoreL(); |
|
1529 } |
|
1530 |
|
1531 HUI_DEBUG(_L("CHuiEnv::RestoreL() - Restoring displays..")); |
|
1532 |
|
1533 // Restore the displays. |
|
1534 for(TInt i = 0; i < iDisplays.Count(); ++i) |
|
1535 { |
|
1536 iDisplays[i]->RestoreL(); |
|
1537 } |
|
1538 |
|
1539 // Set the state to normal |
|
1540 iState = ENormal; |
|
1541 |
|
1542 ReportAction(THuiActionCommand(KHuiEnvRestoredActionId)); |
|
1543 |
|
1544 // Continue refresh. |
|
1545 ContinueRefresh(); |
|
1546 |
|
1547 HUI_DEBUG(_L("CHuiEnv::RestoreL() - Environment restored!")); |
|
1548 } |
|
1549 } |
|
1550 |
|
1551 EXPORT_C void CHuiEnv::SetMaxCpuTime(TUint aPercent) |
|
1552 { |
|
1553 aPercent = aPercent; // to avoid warnings |
|
1554 #ifndef SYMBIAN_BUILD_GCE |
|
1555 iMaxCPUUtilization = (aPercent < KHuiEnvMaxCpuTime?aPercent:KHuiEnvMaxCpuTime); // Min does not work |
|
1556 #endif |
|
1557 } |
|
1558 |
|
1559 // Forward the respective RnD feature flag to respective components, here to TextureManager |
|
1560 EXPORT_C void CHuiEnv::EnableDebugFlag( TUint aRndFlag ) |
|
1561 { |
|
1562 iTextureManager->EnableTexMemoryCalculation( aRndFlag&KRndTexMemCalcFlag ); |
|
1563 } |
|
1564 |
|
1565 CHuiScheduler& CHuiEnv::Scheduler() |
|
1566 { |
|
1567 return *iScheduler; |
|
1568 } |
|
1569 |
|
1570 |
|
1571 TInt CHuiEnv::ReportAction(const THuiActionCommand& aCommand) |
|
1572 { |
|
1573 TInt resultError = KErrNone; |
|
1574 |
|
1575 for(TInt i = 0; i < iActionObservers.Count(); ++i) |
|
1576 { |
|
1577 TRAPD(err, iActionObservers[i].HandleActionL(aCommand)); |
|
1578 if(err != KErrNone && resultError == KErrNone) |
|
1579 { |
|
1580 // The first error code is returned. |
|
1581 resultError = err; |
|
1582 } |
|
1583 } |
|
1584 return resultError; |
|
1585 } |
|
1586 |
|
1587 |
|
1588 RPointerArray<CHuiDisplay> CHuiEnv::Displays() const |
|
1589 { |
|
1590 return iDisplays; |
|
1591 } |
|
1592 |
|
1593 |
|
1594 EXPORT_C TInt& CHuiEnv::GlesRefCounter() |
|
1595 { |
|
1596 return iGlesRefCounter; |
|
1597 } |
|
1598 |
|
1599 EXPORT_C CHuiEnv* CHuiEnv::Static() |
|
1600 { |
|
1601 return &(CHuiStatic::Env()); |
|
1602 } |
|
1603 |
|
1604 EXPORT_C CHuiThemeManager& CHuiEnv::ThemeManager() const |
|
1605 { |
|
1606 return *iThemeManager; |
|
1607 } |
|
1608 |
|
1609 EXPORT_C void CHuiEnv::SetFPSCounterThreshold(TUint aMilliseconds) |
|
1610 { |
|
1611 if (aMilliseconds > 0) |
|
1612 { |
|
1613 iFpsCounterThreshold = aMilliseconds; |
|
1614 } |
|
1615 else |
|
1616 { |
|
1617 iFpsCounterThreshold = 0; |
|
1618 } |
|
1619 |
|
1620 iFrames = 0; |
|
1621 iMillisecondFromFPSUpdate = 0; |
|
1622 } |
|
1623 |
|
1624 void CHuiEnv::SetTimeFromLastUpdate(TUint aTimeFromLastUpdate) |
|
1625 { |
|
1626 iRefreshIntervalReal = aTimeFromLastUpdate; |
|
1627 } |
|
1628 |
|
1629 |
|
1630 CHuiDisplay* CHuiEnv::CurrentDisplay() const |
|
1631 { |
|
1632 return iCurrentDisplay; |
|
1633 } |
|
1634 |
|
1635 EXPORT_C void CHuiEnv::ChangeRefreshLoopPriority(CActive::TPriority aPriority) |
|
1636 { |
|
1637 iRefreshLoopPriority = aPriority; |
|
1638 if (iPeriodic) |
|
1639 { |
|
1640 TBool wasActive = (iPeriodic->IsActive() || iRefreshLoopActive); |
|
1641 StopRefresh(); |
|
1642 delete iPeriodic; |
|
1643 iPeriodic = 0; |
|
1644 iRefreshLoopActive = EFalse; |
|
1645 if (wasActive) |
|
1646 { |
|
1647 StartRefresh(iRefreshIntervalTarget); |
|
1648 } |
|
1649 } |
|
1650 } |
|
1651 |
|
1652 TBool CHuiEnv::CPUTimeSupported() |
|
1653 { |
|
1654 TTimeIntervalMicroSeconds time; |
|
1655 TInt err = RThread().GetCpuTime(time); |
|
1656 |
|
1657 if (err == KErrNone && time.Int64() > 0) |
|
1658 { |
|
1659 return ETrue; |
|
1660 } |
|
1661 else |
|
1662 { |
|
1663 return EFalse; |
|
1664 } |
|
1665 } |
|
1666 |
|
1667 TBool CHuiEnv::OpenHandleToIdleCPUValueThread() |
|
1668 { |
|
1669 // find the kernel process and then the null thread |
|
1670 TFindProcess fp(_L("ekern.exe*")); |
|
1671 |
|
1672 TFullName kernelName; |
|
1673 if (fp.Next(kernelName) == KErrNone) |
|
1674 { |
|
1675 // process found, append null thread identifier |
|
1676 kernelName.Append(_L("::Null")); |
|
1677 |
|
1678 // find the thread |
|
1679 TFindThread ft(kernelName); |
|
1680 |
|
1681 TFullName threadName; |
|
1682 if (ft.Next(threadName) == KErrNone) |
|
1683 { |
|
1684 // open instance to the thread |
|
1685 if (iIdleCPUValueThread.Open(threadName) != KErrNone) |
|
1686 { |
|
1687 return EFalse; |
|
1688 } |
|
1689 } |
|
1690 } |
|
1691 else |
|
1692 { |
|
1693 // process not found |
|
1694 return EFalse; |
|
1695 } |
|
1696 |
|
1697 // success! |
|
1698 return ETrue; |
|
1699 } |
|
1700 |
|
1701 void CHuiEnv::CloseHandleToIdleCPUValueThread() |
|
1702 { |
|
1703 iIdleCPUValueThread.Close(); |
|
1704 } |
|
1705 |
|
1706 CHuiCanvasTextureCache& CHuiEnv::CanvasTextureCache() const |
|
1707 { |
|
1708 return *iCanvasTextureCache; |
|
1709 } |
|
1710 |
|
1711 EXPORT_C CHuiFxEngine* CHuiEnv::EffectsEngine() const |
|
1712 { |
|
1713 return iEffectsEngine; |
|
1714 } |
|
1715 |
|
1716 EXPORT_C void CHuiEnv::AddLowMemoryObserver(MHuiLowMemoryObserver * aObserver) |
|
1717 { |
|
1718 iLowMemoryObservers.Append(aObserver); |
|
1719 } |
|
1720 |
|
1721 EXPORT_C void CHuiEnv::RemoveLowMemoryObserver(MHuiLowMemoryObserver * aObserver) |
|
1722 { |
|
1723 TInt index = iLowMemoryObservers.Find(aObserver); |
|
1724 if(index != KErrNotFound) |
|
1725 { |
|
1726 iLowMemoryObservers.Remove(index); |
|
1727 } |
|
1728 } |
|
1729 |
|
1730 EXPORT_C void CHuiEnv::NotifyLowMemory(TBool /*aEnable*/) |
|
1731 { |
|
1732 //deprecated |
|
1733 } |
|
1734 |
|
1735 |
|
1736 EXPORT_C void CHuiEnv::AddMemoryLevelObserver(MHuiMemoryLevelObserver * aObserver) |
|
1737 { |
|
1738 iMemoryLevelObservers.Append(aObserver); |
|
1739 } |
|
1740 |
|
1741 EXPORT_C void CHuiEnv::RemoveMemoryLevelObserver(MHuiMemoryLevelObserver * aObserver) |
|
1742 { |
|
1743 TInt index = iMemoryLevelObservers.Find(aObserver); |
|
1744 if(index != KErrNotFound) |
|
1745 { |
|
1746 iMemoryLevelObservers.Remove(index); |
|
1747 } |
|
1748 } |
|
1749 |
|
1750 EXPORT_C void CHuiEnv::NotifyMemoryLevel(THuiMemoryLevel aMemoryLevel) |
|
1751 { |
|
1752 iMemoryLevel = aMemoryLevel; |
|
1753 |
|
1754 // notify all observers |
|
1755 for(TInt i=0; i<iMemoryLevelObservers.Count(); i++) |
|
1756 { |
|
1757 iMemoryLevelObservers[i]->SetMemoryLevel(aMemoryLevel); |
|
1758 } |
|
1759 } |
|
1760 |
|
1761 EXPORT_C THuiMemoryLevel CHuiEnv::MemoryLevel() |
|
1762 { |
|
1763 return iMemoryLevel; |
|
1764 } |