uiacceltk/hitchcock/coretoolkit/src/HuiEnv.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
child 13 8f67d927ea57
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     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     }