uiacceltk/hitchcock/coretoolkit/src/HuiEnv_stubs.cpp
changeset 0 15bf7259bb7c
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2009 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: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include <eikenv.h>
       
    19 #include <bautils.h>
       
    20 #include <coemain.h>
       
    21 #include <w32std.h>
       
    22 #include <gdi.h>
       
    23 #include <e32math.h>
       
    24 
       
    25 #include "uiacceltk/huiEnv.h"  // Class definition
       
    26 #include <ecom/implementationinformation.h>
       
    27 #include "huirenderplugin.h"
       
    28 #include "uiacceltk/huiStatic.h"
       
    29 #include "alf/alfconstants.h"
       
    30 #include "huirendersurface.h"
       
    31 #include "uiacceltk/huiDisplay.h"
       
    32 #include "huirosterimpl.h"
       
    33 #include "uiacceltk/huiScheduler.h"
       
    34 #include "uiacceltk/huiTextureManager.h"
       
    35 #include "uiacceltk/huiControlGroup.h"
       
    36 #include "huivisualfactory.h"
       
    37 #include "uiacceltk/huiS60Skin.h"
       
    38 #include "uiacceltk/huiEvent.h"
       
    39 #include "uiacceltk/huiRoster.h"
       
    40 #include "uiacceltk/huiUtil.h"
       
    41 #include "uiacceltk/huipanic.h"
       
    42 #include "uiacceltk/huiTextStyleManager.h"
       
    43 #include "huistatictlsdata.h"
       
    44 #include "uiacceltk/HuiThemeManager.h"
       
    45 
       
    46 
       
    47 /* Constants */
       
    48 const TInt KHuiEnvDefaultNormalRefreshIntervalMs = 40;
       
    49 
       
    50 /* If there is idle between frames, this is how much we can use as overdrive max cpu utilisation */
       
    51 const TUint KHuiEnvMaxCpuTimeOverdriveMaxValue = 100;
       
    52 
       
    53 /* If max cpu usage has been set below this value, overdrive is not used because there is probaply a good reson 
       
    54 for a low max cpu usage value */
       
    55 const TUint KHuiEnvMaxCpuTimeOverdriveLowerThreshold = 50;
       
    56 
       
    57 // @todo: this should be obsolete once scheduling can adapt to CPU load
       
    58 const TInt KHuiEnvDefaultBusyRefreshIntervalMs = 2 * KHuiEnvDefaultNormalRefreshIntervalMs;
       
    59 
       
    60 /** Threshold number for refreshes that don't have any effect. When exceeded,
       
    61     refresh is paused. */
       
    62 const TInt KIdleRefreshCountThreshold = 3;
       
    63 
       
    64 
       
    65 // to get around nasty ownership problem with texture manager interface
       
    66 void NullTextureManagerPtr(TAny* aPtrToPtr)
       
    67     {
       
    68     if (aPtrToPtr)
       
    69         {
       
    70         CHuiTextureManager** ptr = (CHuiTextureManager**)aPtrToPtr;
       
    71         *ptr = 0;
       
    72         }
       
    73     }
       
    74 
       
    75 
       
    76 void CHuiEnv::SetTextureManager(CHuiTextureManager& aManager)
       
    77     {
       
    78     iTextureManager = &aManager;
       
    79     }
       
    80 
       
    81 
       
    82 
       
    83 void CHuiEnv::StopRefresh()
       
    84     {
       
    85     HUI_DEBUG(_L("CHuiEnv::StopRefresh()"));
       
    86     if(iPeriodic)
       
    87         {
       
    88         iPeriodic->Cancel();
       
    89         }
       
    90     }
       
    91 
       
    92 void CHuiEnv::RemoveDisplay(CHuiDisplay& aDisplay)
       
    93     {
       
    94     // Actually this is "DestroyDisplay"
       
    95 
       
    96     /** @todo  Make a proper observer. */
       
    97     TInt index = iDisplays.Find(&aDisplay);
       
    98     if(index >= 0)
       
    99         {
       
   100         iDisplays.Remove(index);
       
   101         }
       
   102     else
       
   103         {
       
   104         HUI_DEBUG1(_L("HuiEnv::DestroyContext: display %x not in array"), &aDisplay);
       
   105         }
       
   106     index = iOverlaidDisplays.Find(&aDisplay);
       
   107     if(index >= 0)
       
   108         {
       
   109         iOverlaidDisplays.Remove(index);
       
   110         }
       
   111 
       
   112     // Notify the current renderer of the changed number of displays
       
   113     TRAP_IGNORE(iRenderer->NotifyDisplayCountL(iDisplays.Count()))
       
   114 
       
   115 #ifdef _DEBUG
       
   116     HUI_DEBUG(_L("  Contents of iDisplays:"));
       
   117     for(TInt i = 0; i < iDisplays.Count(); ++i)
       
   118         {
       
   119         HUI_DEBUG2(_L("  %i: %x"), i, iDisplays[i]);
       
   120         }
       
   121 #endif
       
   122     }
       
   123 
       
   124 
       
   125 void CHuiEnv::AdvanceTime(TReal32 aElapsedTime)
       
   126     {
       
   127     HUI_DEBUGF( _L("CHuiEnv::AdvanceTime() - Started") )
       
   128 
       
   129     TUint usedMaxCPUUtilization = iMaxCPUUtilization;
       
   130 
       
   131     // Calculate cpu values based on null thread cpu usage between frames. 
       
   132     // Values will be updated at the end of the frame.
       
   133     if (iIdleCPUValueMonitored)
       
   134         {
       
   135         TTime currentTime;
       
   136         currentTime.HomeTime();
       
   137 
       
   138         TTimeIntervalMicroSeconds cputime;
       
   139         iIdleCPUValueThread.GetCpuTime(cputime);
       
   140 
       
   141         TInt64 cpudelta = cputime.Int64() - iIdleCPUValue;
       
   142         TInt64 timedelta = currentTime.Int64() - iIdleCPUValuePreviousTime;
       
   143 
       
   144         // If null thread was runnign between frames, we could use more cpu if needed.
       
   145         if (cpudelta && timedelta)
       
   146             {
       
   147             // Calculate how much we want !
       
   148             if (iMaxCPUUtilization > KHuiEnvMaxCpuTimeOverdriveLowerThreshold &&
       
   149                 iMaxCPUUtilization < KHuiEnvMaxCpuTimeOverdriveMaxValue )
       
   150                 {
       
   151                 usedMaxCPUUtilization += (KHuiEnvMaxCpuTimeOverdriveMaxValue - iMaxCPUUtilization) * cpudelta/timedelta;
       
   152                 
       
   153                 // Sanity check just in case cpu/time measurements are not accurate
       
   154                 if (usedMaxCPUUtilization > KHuiEnvMaxCpuTimeOverdriveMaxValue)
       
   155                     {
       
   156                     usedMaxCPUUtilization = KHuiEnvMaxCpuTimeOverdriveMaxValue;   
       
   157                     }                
       
   158                 }
       
   159             }
       
   160         }
       
   161 
       
   162     if(aElapsedTime > 0)
       
   163         {
       
   164         // Let the scheduler know that time has passed. It will possible animate
       
   165         // visuals and perform actions, causing dirty regions in the display.
       
   166         iScheduler->AdvanceTime(aElapsedTime);
       
   167 
       
   168         // Scheduled command might have released the environment.
       
   169         if(iState == EReleased)
       
   170             {
       
   171             HUI_DEBUG(_L("CHuiEnv::AdvanceTime() - Environment released when executing scheduled commands. AdvanceTime cancelled."));
       
   172             return;
       
   173             }
       
   174 
       
   175         // Let the texture manager know that time has passed. It will update any
       
   176         // animated textures.
       
   177         iTextureManager->AdvanceTime(aElapsedTime);                
       
   178         }
       
   179 
       
   180     // Check for no input for long time.
       
   181     TTime now = CHuiStatic::Time();
       
   182     TTimeIntervalSeconds seconds = 0;
       
   183     now.SecondsFrom(iLastInputTime, seconds);
       
   184     if(seconds.Int() >= iIdleThreshold && !iInputIdleIsActive)
       
   185         {
       
   186         HUI_DEBUG1(_L("CHuiEnv::AdvanceTime() - No input received within %i seconds. Going to idle."), iIdleThreshold);
       
   187         iInputIdleIsActive = ETrue;
       
   188         
       
   189         // Idle state begins.
       
   190         TRAPD(err, SendIdleL(ETrue));
       
   191         if(err != KErrNone)
       
   192             {
       
   193             // @todo  Log error?
       
   194             }
       
   195             
       
   196         // Switching to idle state might have released the environment.
       
   197         if(iState == EReleased)
       
   198             {
       
   199             HUI_DEBUG(_L("CHuiEnv::AdvanceTime() - Environment released when switching to idle state. AdvanceTime cancelled."));
       
   200             return;
       
   201             }            
       
   202         }
       
   203 
       
   204     TBool somethingUpdated = EFalse;
       
   205 
       
   206     // Refresh all displays.
       
   207     TInt i;
       
   208     const TInt displayCount = iDisplays.Count();
       
   209     RArray<TBool> displayRefreshed( displayCount ? displayCount : 1 );
       
   210     for(i = 0; i < iDisplays.Count(); ++i)
       
   211         {
       
   212         displayRefreshed.Append(EFalse);
       
   213         if(iRefreshMode == EHuiRefreshModeForced || iDisplays[i]->IsDirty())
       
   214             {
       
   215             MakeCurrent(*iDisplays[i]);
       
   216 
       
   217             HUI_DEBUGF1( _L("CHuiEnv::AdvanceTime() - Refreshing display %i"), i )
       
   218             TBool updated = iDisplays[i]->Refresh();
       
   219             displayRefreshed[i] = updated;
       
   220             if(updated)
       
   221                 {
       
   222                 somethingUpdated = ETrue;
       
   223                 }
       
   224             }
       
   225         }
       
   226     
       
   227     TBool continueRefresh = ETrue;
       
   228 
       
   229     if(somethingUpdated)
       
   230         {
       
   231         HUI_DEBUGF( _L("CHuiEnv::AdvanceTime() - Swap buffers") )
       
   232 
       
   233         SwapBuffers(displayRefreshed);
       
   234         iIdleRefreshCount = 0;
       
   235         // Clear change flags now that the frames are complete.
       
   236         for(i = 0; i < iDisplays.Count(); ++i)
       
   237             {
       
   238             // Clear changed for an off screen display only if the buffer has new content.
       
   239             // Index is ok becacause displayRefreshed array was defined using size of iDisplays array
       
   240             if (displayRefreshed[i])
       
   241             	{
       
   242             	iDisplays[i]->ClearChanged();
       
   243             	}
       
   244             }
       
   245         }
       
   246     else if(iScheduler->PendingCount() == 0)
       
   247         {
       
   248         // But if there are scheduled commands, let's make sure they'll get
       
   249         // executed at the right time. They might get badly delayed if the
       
   250         // refresh wasn't occuring.
       
   251 
       
   252         /** @todo  Use a separate timer for the scheduler? */
       
   253 
       
   254         // Nothing happened during the display refreshing.
       
   255         iIdleRefreshCount++;
       
   256 
       
   257         // If this occurs too often, pause refresh automatically.
       
   258         if(iIdleRefreshCount > KIdleRefreshCountThreshold)
       
   259             {
       
   260             if (iFpsCounterThreshold && iMillisecondFromFPSUpdate && iFrames)
       
   261                 {
       
   262                 TBuf<16> numBuf;
       
   263                 TReal fps = 1000*(TReal)iFrames/iMillisecondFromFPSUpdate;
       
   264                 numBuf.AppendNum(fps, TRealFormat(5,2));
       
   265                 User::InfoPrint(numBuf);
       
   266                 iFrames = 0;
       
   267                 iMillisecondFromFPSUpdate = 0;
       
   268                 }
       
   269 
       
   270             PauseRefresh();
       
   271             continueRefresh = EFalse;
       
   272             }
       
   273         }
       
   274     else
       
   275         {
       
   276         // for PC lint
       
   277         }
       
   278 
       
   279 	displayRefreshed.Close(); // Not needed any more
       
   280 
       
   281     // Clear change flags of all control groups now that the refresh has
       
   282     // been completed for all displays.
       
   283     //
       
   284     // DEPRECATE:
       
   285     // This should be removed when control opacities are deprecated! 
       
   286     // Controls shouldn't need change flags because change flags are 
       
   287     // only for the refresh.
       
   288     //
       
   289     for(i = 0; i < iLoadedGroups.Count(); ++i)
       
   290         {
       
   291         iLoadedGroups[i]->ClearChanged();
       
   292         }
       
   293 
       
   294     iTextureManager->ClearChangedTextures();
       
   295 
       
   296     if (continueRefresh)
       
   297         {
       
   298         // Refresh rate adjustment
       
   299         if (usedMaxCPUUtilization)
       
   300             {
       
   301             TUint millisecondsUsedInRefresh = CHuiStatic::MilliSecondsSinceUpdateTime();
       
   302 
       
   303             TUint totalLoopTime = (millisecondsUsedInRefresh * 100) / usedMaxCPUUtilization;
       
   304     
       
   305             if (totalLoopTime >= iRefreshIntervalTarget)
       
   306                 {
       
   307                 iRefreshInterval = (millisecondsUsedInRefresh*(100-usedMaxCPUUtilization))/usedMaxCPUUtilization;
       
   308                 StartRefresh(iRefreshInterval);        
       
   309                 }
       
   310             else if (iRefreshIntervalTarget != iRefreshInterval)
       
   311                 {
       
   312                 iRefreshInterval = iRefreshIntervalTarget; 
       
   313                 StartRefresh(iRefreshInterval);
       
   314                 }
       
   315             else
       
   316                 {
       
   317                 // otherwise just let the periodic run as it already has good interval set
       
   318                 }
       
   319             }
       
   320 
       
   321         if (iFpsCounterThreshold && iMillisecondFromFPSUpdate > iFpsCounterThreshold)
       
   322             {
       
   323             TBuf<16> numBuf;
       
   324             TReal fps = 1000*(TReal)iFrames/iMillisecondFromFPSUpdate;
       
   325             numBuf.AppendNum(fps, TRealFormat(5,2));
       
   326             User::InfoPrint(numBuf);
       
   327             iFrames = 0;
       
   328             iMillisecondFromFPSUpdate = 0;
       
   329             }
       
   330         }
       
   331 
       
   332     iCurrentDisplay = NULL; // informs the egosystem that the drawing is done.
       
   333     CHuiStatic::ReportNewFrame();
       
   334     
       
   335     // Store cpu value conters of null thread. Values will be used at the start of the next frame.
       
   336     if (iIdleCPUValueMonitored)
       
   337         {
       
   338         TTime currentTime;
       
   339         currentTime.HomeTime();
       
   340 
       
   341         TTimeIntervalMicroSeconds cputime;
       
   342         iIdleCPUValueThread.GetCpuTime(cputime);
       
   343 
       
   344         // Store as previous values
       
   345         iIdleCPUValue = cputime.Int64();
       
   346         iIdleCPUValuePreviousTime = currentTime.Int64();                           
       
   347         }
       
   348             
       
   349     HUI_DEBUGF( _L("CHuiEnv::AdvanceTime() - Exited") );
       
   350     }
       
   351 
       
   352 void CHuiEnv::NotifyInputReceivedL(const THuiEvent& aEvent)
       
   353     {
       
   354     ContinueRefresh();
       
   355 
       
   356     if(aEvent.IsKeyEvent() || aEvent.IsPointerEvent())
       
   357         {
       
   358         if(iInputIdleIsActive)
       
   359             {
       
   360             HUI_DEBUG(_L("CHuiEnv::NotifyInputReceivedL() - Got key/pointer input! Idle state ends!"));
       
   361             // Idle state ends.
       
   362             SendIdleL(EFalse);
       
   363             }
       
   364 
       
   365         iLastInputTime = CHuiStatic::Time();
       
   366         iInputIdleIsActive = EFalse;
       
   367         }
       
   368     }
       
   369 
       
   370 
       
   371 void CHuiEnv::SendIdleL(TBool aIdleBegins)
       
   372     {
       
   373     CHuiDisplay* display = NULL;
       
   374     
       
   375     if(iDisplays.Count() != 0)
       
   376         {
       
   377         // If we have any displays, pass the first one.
       
   378         display = iDisplays[0];
       
   379         }
       
   380     
       
   381     THuiEvent idleEvent(display,
       
   382         aIdleBegins ? THuiEvent::ETypeIdleBegin :
       
   383                       THuiEvent::ETypeIdleEnd);
       
   384     BroadcastEventL(idleEvent);
       
   385     }
       
   386 
       
   387 
       
   388 
       
   389 void CHuiEnv::MakeCurrent(const CHuiDisplay& aDisplay) const
       
   390     {
       
   391     aDisplay.RenderSurface().MakeCurrent();
       
   392     iCurrentDisplay = const_cast<CHuiDisplay*>(&aDisplay);
       
   393     }
       
   394 
       
   395 
       
   396 void CHuiEnv::SwapBuffers(const RArray<TBool>& aDisplayRefreshed)
       
   397     {
       
   398     /** @todo This may not work as expected when multiple displays are
       
   399         being used. */
       
   400 
       
   401     if (iFpsCounterThreshold)
       
   402         {
       
   403         iFrames++;
       
   404         iMillisecondFromFPSUpdate += iRefreshIntervalReal;
       
   405         }    
       
   406 
       
   407     /** @todo  Only swap the visible displays. */
       
   408 
       
   409     for(TInt i = 0; i < iDisplays.Count(); ++i)
       
   410         {          
       
   411         // Index should ok becacause displayRefreshed array was defined using size of iDisplays array
       
   412         // This function should only be called from inside CHuiEnv even if it is public.
       
   413         // At least it is not exported.
       
   414         if (aDisplayRefreshed[i] 
       
   415             && (iDisplays[i]->DisplayType() != CHuiDisplay::EDisplayOffScreenBuffer)
       
   416             && (iDisplays[i]->ScreenBufferObserver() == NULL))
       
   417         	{
       
   418      		iDisplays[i]->RenderSurface().SwapBuffers();
       
   419         	}
       
   420         }
       
   421     }
       
   422 
       
   423 
       
   424 void CHuiEnv::CreateResourceReaderLC(TResourceReader& aReader, TInt aResourceId) const
       
   425     {
       
   426     CCoeEnv* coe = CCoeEnv::Static();
       
   427     if (!coe)
       
   428     		{
       
   429     		User::Leave(KErrNotSupported);
       
   430     	  }
       
   431     coe->CreateResourceReaderLC(aReader, aResourceId);
       
   432     }
       
   433 
       
   434 void CHuiEnv::TextureLoadingCompleted(CHuiTexture& /*aTexture*/,
       
   435                                     TInt /*aTextureId*/,
       
   436                                     TInt /*aErrorCode*/)
       
   437     {
       
   438     // Texture changed flag has been set, visuals should redraw
       
   439     // changed textures automatically.
       
   440     }
       
   441 
       
   442 
       
   443 void CHuiEnv::TextureManagerStateChanged(const CHuiTextureManager& aManager)
       
   444     {
       
   445     if(aManager.State() == CHuiTextureManager::EIdle)
       
   446         {
       
   447         StartRefresh(iRefreshIntervalTarget);
       
   448         }
       
   449     else if (!iMaxCPUUtilization)  
       
   450         { // only use busy refresh interwall if adaptive scheduling is not enabled
       
   451         StartRefresh(KHuiEnvDefaultBusyRefreshIntervalMs);
       
   452         }
       
   453     else
       
   454         {
       
   455         // for PC lint
       
   456         }
       
   457     }
       
   458 
       
   459 CHuiScheduler& CHuiEnv::Scheduler()
       
   460     {
       
   461     return *iScheduler;
       
   462     }
       
   463 
       
   464 
       
   465 TInt CHuiEnv::ReportAction(const THuiActionCommand& aCommand)
       
   466     {
       
   467     TInt resultError = KErrNone;
       
   468 
       
   469     for(TInt i = 0; i < iActionObservers.Count(); ++i)
       
   470         {
       
   471         TRAPD(err, iActionObservers[i].HandleActionL(aCommand));
       
   472         if(err != KErrNone && resultError == KErrNone)
       
   473             {
       
   474             // The first error code is returned.
       
   475             resultError = err;
       
   476             }
       
   477         }
       
   478     return resultError;
       
   479     }
       
   480     
       
   481 
       
   482 RPointerArray<CHuiDisplay> CHuiEnv::Displays() const
       
   483     {
       
   484     return iDisplays;
       
   485     }
       
   486 
       
   487 
       
   488 
       
   489 void CHuiEnv::SetTimeFromLastUpdate(TUint aTimeFromLastUpdate)
       
   490     {
       
   491     iRefreshIntervalReal = aTimeFromLastUpdate;
       
   492     }
       
   493 
       
   494 
       
   495 CHuiDisplay* CHuiEnv::CurrentDisplay() const
       
   496     {
       
   497     return iCurrentDisplay;    
       
   498     }
       
   499 
       
   500 TBool CHuiEnv::CPUTimeSupported()
       
   501     {
       
   502     TTimeIntervalMicroSeconds time;
       
   503     TInt err = RThread().GetCpuTime(time);
       
   504     
       
   505     if (err == KErrNone && time.Int64() > 0)
       
   506         {
       
   507         return ETrue;    
       
   508         }        
       
   509     else
       
   510         {
       
   511         return EFalse;    
       
   512         }        
       
   513     }
       
   514     
       
   515 TBool CHuiEnv::OpenHandleToIdleCPUValueThread()
       
   516     {
       
   517     // find the kernel process and then the null thread
       
   518     TFindProcess fp(_L("ekern.exe*"));
       
   519     
       
   520     TFullName kernelName;
       
   521     if (fp.Next(kernelName) == KErrNone)
       
   522         {
       
   523         // process found, append null thread identifier
       
   524         kernelName.Append(_L("::Null"));
       
   525         
       
   526         // find the thread
       
   527         TFindThread ft(kernelName);
       
   528 
       
   529         TFullName threadName;
       
   530         if (ft.Next(threadName) == KErrNone)
       
   531             {
       
   532             // open instance to the thread
       
   533             if (iIdleCPUValueThread.Open(threadName) != KErrNone)
       
   534                 {
       
   535                 return EFalse;                    
       
   536                 }                
       
   537             }
       
   538         }        
       
   539     else
       
   540         {
       
   541         // process not found
       
   542         return EFalse;    
       
   543         }        
       
   544     
       
   545     // success!
       
   546     return ETrue;        
       
   547     }
       
   548 
       
   549 void CHuiEnv::CloseHandleToIdleCPUValueThread()
       
   550     {
       
   551     iIdleCPUValueThread.Close();
       
   552     }
       
   553 
       
   554 CHuiCanvasTextureCache& CHuiEnv::CanvasTextureCache() const
       
   555     {
       
   556     return *iCanvasTextureCache;    
       
   557     }