uiacceltk/hitchcock/coretoolkit/src/HuiFxEngine.cpp
changeset 19 f5bac0badc7e
parent 13 8f67d927ea57
child 21 6ce30188c5bf
equal deleted inserted replaced
14:83d2d132aa58 19:f5bac0badc7e
    14 * Description:   
    14 * Description:   
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 
    18 
    19 
       
    20 #include "HuiFxEngine.h"
    19 #include "HuiFxEngine.h"
    21 #include "HuiFxEffectParser.h"
    20 #include "HuiFxEffectParser.h"
    22 #include "HuiFxEffect.h"
    21 #include "HuiFxEffect.h"
    23 #include "HuiFxEffectCache.h"
    22 #include "HuiFxEffectCache.h"
    24 #include <uiacceltk/HuiEnv.h>
    23 #include <uiacceltk/HuiEnv.h>
    64         //delete effect; // no need for this effect.
    63         //delete effect; // no need for this effect.
    65         }
    64         }
    66 #endif
    65 #endif
    67 #endif
    66 #endif
    68     CHuiStatic::Env().AddMemoryLevelObserver(this);
    67     CHuiStatic::Env().AddMemoryLevelObserver(this);
       
    68     iActiveEffectGroups.Reserve(2);
    69     }
    69     }
    70 
    70 
    71 EXPORT_C TBool CHuiFxEngine::FxmlUsesInput1(const TDesC &aFileName)
    71 EXPORT_C TBool CHuiFxEngine::FxmlUsesInput1(const TDesC &aFileName)
    72     {
    72     {
    73 #ifdef HUIFX_EFFECTCACHE_ENABLED
    73 #ifdef HUIFX_EFFECTCACHE_ENABLED
    74     return iCache->FxmlUsesInput1(aFileName);
    74     return iCache->FxmlUsesInput1(aFileName);
    75 #endif
    75 #endif
    76 #ifndef HUIFX_EFFECTCACHE_ENABLED
    76 #ifndef HUIFX_EFFECTCACHE_ENABLED
    77     return EFalse;
    77     return EFalse;
    78 #endif
    78 #endif
       
    79     }
       
    80 EXPORT_C TBool CHuiFxEngine::FxmlUsesOpaqueHint(const TDesC &aFileName)
       
    81     {
       
    82 #ifdef HUIFX_EFFECTCACHE_ENABLED
       
    83     return iCache->FxmlUsesOpaqueHint(aFileName);
       
    84 #endif
       
    85 #ifndef HUIFX_EFFECTCACHE_ENABLED
       
    86     return EFalse;
       
    87 #endif    
    79     }
    88     }
    80 
    89 
    81 TBool CHuiFxEngine::FxmlUsesInput1(CHuiFxEffect& aEffect)
    90 TBool CHuiFxEngine::FxmlUsesInput1(CHuiFxEffect& aEffect)
    82     {
    91     {
    83     RArray<THuiFxVisualSrcType> array;
    92     RArray<THuiFxVisualSrcType> array;
   280 void CHuiFxEngine::NotifyEffectEndObservers()
   289 void CHuiFxEngine::NotifyEffectEndObservers()
   281     {
   290     {
   282     for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
   291     for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
   283         {
   292         {
   284         CHuiFxEffect* effect = iActiveEffects[i];
   293         CHuiFxEffect* effect = iActiveEffects[i];
   285         if (!effect->Changed())
   294         if (!(effect->EffectFlags() & KHuiFadeEffectFlag) && !effect->Changed())
   286             {
   295             {
       
   296 #ifdef HUIFX_TRACE
       
   297             RDebug::Printf("void CHuiFxEngine::NotifyEffectEndObservers() calling NotifyEffectEndObserver");
       
   298 #endif
   287             effect->NotifyEffectEndObserver();
   299             effect->NotifyEffectEndObserver();
   288             }
   300             }
   289         }    
   301         }    
   290     }
   302     }
   291 
   303 
   293     {
   305     {
   294     // TODO: Can we do anything about all this polling?
   306     // TODO: Can we do anything about all this polling?
   295     TInt i;
   307     TInt i;
   296     TBool refreshRequired = EFalse;
   308     TBool refreshRequired = EFalse;
   297 #ifdef HUIFX_TRACE    
   309 #ifdef HUIFX_TRACE    
   298     RDebug::Print(_L("CHuiFxEngine::AdvanceTime - 0x%x "), this);   
   310     RDebug::Print(_L("CHuiFxEngine::AdvanceTime - 0x%x, effect count: %d"), this, iActiveEffects.Count());   
   299 #endif
   311 #endif
   300     // Go through the list in reverse order.
   312     // Go through the list in reverse order.
   301 // If the effect has ended, and has the callback set,
   313 // If the effect has ended, and has the callback set,
   302 // the effect will be removed, and will no longer be part of iActiveEffects set.
   314 // the effect will be removed, and will no longer be part of iActiveEffects set.
   303 // We must check if the effect is still in our list, but the indices change
   315 // We must check if the effect is still in our list, but the indices change
   304 // if something is removed from the middle of the list
   316 // if something is removed from the middle of the list
       
   317     TInt skipGroup = KErrNotFound;
   305     for ( i = iActiveEffects.Count() - 1; i >= 0; i-- )
   318     for ( i = iActiveEffects.Count() - 1; i >= 0; i-- )
   306         {
   319         {
   307         CHuiFxEffect* effect = iActiveEffects[i];
   320         CHuiFxEffect* effect = iActiveEffects[i];
   308         if (effect->Changed())
   321         if (effect->Changed())
   309             {
   322             {
   310             refreshRequired = ETrue;
   323             refreshRequired = ETrue;
   311             }
   324             }
   312         if ( i < iActiveEffects.Count() && effect == iActiveEffects[i] && !(effect->EffectFlags() & KHuiFxWaitGroupSyncronization))
   325         TInt flags = effect->EffectFlags();
       
   326         if ( !(flags & KHuiFxWaitGroupSyncronization)
       
   327                 && !(flags & KHuiFadeEffectFlag) // fade is not animated. Note, if animated effect would be used, remove this!
       
   328                 && (skipGroup == KErrNotFound || skipGroup != effect->GroupId())
       
   329                )
   313             {
   330             {
   314             // The effect is still in its place, it did not go away yet
   331             // The effect is still in its place, it did not go away yet
       
   332             TBool waitingGroupBefore = flags & KHuiFxWaitGroupToStartSyncronized;
   315             effect->AdvanceTime(aElapsedTime);
   333             effect->AdvanceTime(aElapsedTime);
       
   334             
       
   335             if (waitingGroupBefore)
       
   336                 {
       
   337                 flags = effect->EffectFlags();
       
   338                 if (!(flags & KHuiFxReadyAndWaitingGroupToStartSyncronized) && !(flags & KHuiFxWaitGroupToStartSyncronized))
       
   339                     {
       
   340                     // effects in this group are all ready to start drawing. Skip this group in AdvanceTime, 
       
   341 					// that they can start syncronized on the next round
       
   342                     skipGroup = effect->GroupId();
       
   343                     }
       
   344                 }
   316             }
   345             }
   317         }
   346         }
   318     
   347     
   319     if (refreshRequired)
   348     if (refreshRequired)
   320         {
   349         {
   330 #ifdef HUIFX_TRACE        
   359 #ifdef HUIFX_TRACE        
   331     RDebug::Print(_L("CHuiFxEngine::AddEffectL - 0x%x "), aEffect);
   360     RDebug::Print(_L("CHuiFxEngine::AddEffectL - 0x%x "), aEffect);
   332 #endif // #ifdef HUIFX_TRACE    
   361 #endif // #ifdef HUIFX_TRACE    
   333 
   362 
   334     iActiveEffects.AppendL(aEffect);
   363     iActiveEffects.AppendL(aEffect);
       
   364     if (iEffectObserver)
       
   365         {
       
   366         iEffectObserver->EffectAdded(aEffect);    
       
   367         }
   335     }
   368     }
   336 
   369 
   337 EXPORT_C void CHuiFxEngine::RemoveEffect(CHuiFxEffect* aEffect)
   370 EXPORT_C void CHuiFxEngine::RemoveEffect(CHuiFxEffect* aEffect)
   338     {
   371     {
   339 #ifdef HUIFX_TRACE    
   372 #ifdef HUIFX_TRACE    
   341 #endif    
   374 #endif    
   342     TInt i = iActiveEffects.Find(aEffect);
   375     TInt i = iActiveEffects.Find(aEffect);
   343     if (i >= 0)
   376     if (i >= 0)
   344         {
   377         {
   345         iActiveEffects.Remove(i);
   378         iActiveEffects.Remove(i);
       
   379         if (iEffectObserver)
       
   380             {
       
   381             iEffectObserver->EffectComplete(aEffect);
       
   382             }
   346         }
   383         }
   347     }
   384     }
   348 
   385 
   349 EXPORT_C TReal32 CHuiFxEngine::GetReferenceValue(THuiFxReferencePoint aPoint)
   386 EXPORT_C TReal32 CHuiFxEngine::GetReferenceValue(THuiFxReferencePoint aPoint)
   350     {
   387     {
   487     RDebug::Print(_L("CHuiFxEngine::ReleaseRenderbuffer - buffer: 0x%x "), aBuffer);
   524     RDebug::Print(_L("CHuiFxEngine::ReleaseRenderbuffer - buffer: 0x%x "), aBuffer);
   488 #endif
   525 #endif
   489     ASSERT((aBuffer) && (iBuffersInUse > 0));
   526     ASSERT((aBuffer) && (iBuffersInUse > 0));
   490 
   527 
   491 #ifdef HUIFX_RBCACHE_ENABLED
   528 #ifdef HUIFX_RBCACHE_ENABLED
   492     if(iLowGraphicsMemoryMode || IsCacheFull())
   529     if(iLowGraphicsMemoryMode < EHuiMemoryLevelReduced || IsCacheFull())
   493         {
   530         {
   494 #ifdef HUIFX_TRACE            
   531 #ifdef HUIFX_TRACE            
   495         RDebug::Print(_L("CHuiFxEngine::ReleaseRenderbuffer() --- Renderbuffer cache full! Suspectible for memory fragmentation! Cache size is %d entries."), CACHE_SIZE);
   532         RDebug::Print(_L("CHuiFxEngine::ReleaseRenderbuffer() --- Renderbuffer cache full! Suspectible for memory fragmentation! Cache size is %d entries."), CACHE_SIZE);
   496 #endif
   533 #endif
   497 #endif        
   534 #endif        
   570     }
   607     }
   571     
   608     
   572 EXPORT_C void  CHuiFxEngine::SetMemoryLevel(THuiMemoryLevel aLevel)
   609 EXPORT_C void  CHuiFxEngine::SetMemoryLevel(THuiMemoryLevel aLevel)
   573     {
   610     {
   574     iLowGraphicsMemoryMode = aLevel;
   611     iLowGraphicsMemoryMode = aLevel;
   575     if(iLowGraphicsMemoryMode) // != Normal
   612     if(iLowGraphicsMemoryMode < EHuiMemoryLevelReduced)
   576         {
   613         {
   577         ClearCache();
   614         ClearCache();
   578         }
   615         }
   579     }
   616     }
   580 
   617 
   583     // Default implementation does nothing
   620     // Default implementation does nothing
   584     }
   621     }
   585 
   622 
   586 TInt CHuiFxEngine::LowMemoryState()
   623 TInt CHuiFxEngine::LowMemoryState()
   587     {
   624     {
   588     return iLowGraphicsMemoryMode;
   625     return iLowGraphicsMemoryMode < EHuiMemoryLevelReduced;
   589     }
   626     }
   590 
   627 
   591 TBool CHuiFxEngine::HasActiveEffects() const
   628 TBool CHuiFxEngine::HasActiveEffects() const
   592     {
   629     {
   593 	// Don't report active effects if in SW-rendering mode
   630 	// Don't report active effects if in SW-rendering mode
   594     if(iLowGraphicsMemoryMode) // != Normal
   631     if(iLowGraphicsMemoryMode < EHuiMemoryLevelReduced) 
   595         {
   632         {
   596         return EFalse;
   633         return EFalse;
   597         }
   634         }
   598     return iActiveEffects.Count() > 0;
   635     return iActiveEffects.Count() > 0;
       
   636     }
       
   637 
       
   638 TBool CHuiFxEngine::HasActiveFadeEffect() const
       
   639     {
       
   640     // Don't report active effects if in SW-rendering mode
       
   641     if(iLowGraphicsMemoryMode < EHuiMemoryLevelReduced) 
       
   642         {
       
   643         return EFalse;
       
   644         }
       
   645     TInt effectCount = iActiveEffects.Count();
       
   646     for (TInt count  = 0; count < effectCount; count++)
       
   647         {
       
   648         if (iActiveEffects[count]->EffectFlags() & KHuiFadeEffectFlag)
       
   649             {
       
   650             return ETrue;
       
   651             }
       
   652         }
       
   653     return EFalse;
   599     }
   654     }
   600 
   655 
   601 void CHuiFxEngine::ClearCache()
   656 void CHuiFxEngine::ClearCache()
   602     {
   657     {
   603     // Release cached render targets from effects
   658     // Release cached render targets from effects
   624                 }
   679                 }
   625         }
   680         }
   626     
   681     
   627     ASSERT(iBuffersInCache == 0);    
   682     ASSERT(iBuffersInCache == 0);    
   628     }
   683     }
   629 	
   684 
       
   685 TInt CHuiFxEngine::FindEffectGroup(TInt aGroup)
       
   686     {
       
   687     for (TInt i=0 ; i < iActiveEffectGroups.Count();i++)
       
   688         {
       
   689         if (iActiveEffectGroups[i].iGroup == aGroup)
       
   690             {
       
   691             return i; 
       
   692             }
       
   693         }
       
   694     return KErrNotFound;
       
   695     }
       
   696 
   630 EXPORT_C void CHuiFxEngine::BeginGroupEffect(TInt aGroup)
   697 EXPORT_C void CHuiFxEngine::BeginGroupEffect(TInt aGroup)
   631 	{
   698 	{
   632 	TInt index = iActiveEffectGroups.Find(aGroup);
   699 #ifdef HUIFX_TRACE   
       
   700 	RDebug::Printf("CHuiFxEngine::BeginGroupEffect(TInt aGroup %d) >>", aGroup);
       
   701 #endif
       
   702 	// Multiple grouped effects at the same time are not supported. 
       
   703     // Same visual might participate different groups, which will mess up the effect
       
   704     if (iActiveEffectGroups.Count()>0)
       
   705         {
       
   706         // delete previous groups
       
   707         while(iActiveEffectGroups.Count())
       
   708             {
       
   709             TInt groupId = iActiveEffectGroups[0].iGroup;
       
   710             for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
       
   711                 {
       
   712                 if (iActiveEffects[i]->GroupId() == groupId)
       
   713                     {
       
   714                     iActiveEffects[i]->ClearEffectFlag(KHuiFxReadyAndWaitingGroupToStartSyncronized);
       
   715                     iActiveEffects[i]->ClearEffectFlag(KHuiFxWaitGroupToStartSyncronized);
       
   716                     iActiveEffects[i]->ClearEffectFlag(KHuiFxWaitGroupSyncronization);
       
   717                     }
       
   718                 
       
   719                 }
       
   720             iActiveEffectGroups.Remove(0);
       
   721             }
       
   722         }
       
   723 	
       
   724 	TInt index = FindEffectGroup(aGroup);
       
   725 	
   633 	if (index == KErrNotFound)
   726 	if (index == KErrNotFound)
   634 		{
   727 		{
   635 		iActiveEffectGroups.Append(aGroup);
   728         const TEffectGroupStruct item(aGroup);
   636 		}
   729 		iActiveEffectGroups.Append(item);
   637 	else
       
   638 		{
       
   639 		// group already exists
       
   640 		}
   730 		}
   641 	}
   731 	}
   642 
   732 
       
   733 // This will add effect to this group. Do not call this function more than once for single effect 
   643 EXPORT_C TInt CHuiFxEngine::ActiveGroupEffect()
   734 EXPORT_C TInt CHuiFxEngine::ActiveGroupEffect()
   644 	{
   735 	{
   645 	if (iActiveEffectGroups.Count() > 0)
   736 	TInt index = iActiveEffectGroups.Count();
   646 		{
   737 	if (index == 0)
   647 		return iActiveEffectGroups[iActiveEffectGroups.Count()-1];
   738 	    {
   648 		}
   739         return KErrNotFound;
   649 	else
   740 	    }
   650 		{
   741 	while(--index >= 0)
   651 		return KErrNotFound;
   742         {
   652 		}
   743 		// group is alive until all its effects have been drawn once. .iEndCalled is to prevent
       
   744 		// another effect entering into this group
       
   745         const TEffectGroupStruct& item = iActiveEffectGroups[index];
       
   746         if (!item.iEndCalled) 
       
   747             { 
       
   748 			return iActiveEffectGroups[index].iGroup;
       
   749             }
       
   750         }
       
   751     return KErrNotFound;
   653 	}
   752 	}
       
   753 
       
   754 EXPORT_C TBool CHuiFxEngine::AddEffectToGroup(TInt aGroup)
       
   755     {
       
   756     TInt index = FindEffectGroup(aGroup);
       
   757     if (index != KErrNotFound)
       
   758         {
       
   759         // keep count of effects in this group. All must draw atleast once, before
       
   760         // syncronized group effect may start
       
   761         iActiveEffectGroups[index].iWaiting++;
       
   762 #ifdef HUIFX_TRACE
       
   763         RDebug::Printf("CHuiFxEngine::AddEffectToGroup - %d, waiting in group: %d", aGroup, iActiveEffectGroups[index].iWaiting);
       
   764 #endif
       
   765         return ETrue;
       
   766         }
       
   767     return EFalse;
       
   768     }
   654 
   769 
   655 EXPORT_C void CHuiFxEngine::StartGroupEffect(TInt aGroup)
   770 EXPORT_C void CHuiFxEngine::StartGroupEffect(TInt aGroup)
   656 	{
   771 	{
   657 	TInt index = iActiveEffectGroups.Find(aGroup);
   772 #ifdef HUIFX_TRACE
       
   773     RDebug::Printf("CHuiFxEngine::StartGroupEffect(TInt aGroup %d) >>", aGroup);
       
   774 #endif	    
       
   775 	TInt index = FindEffectGroup(aGroup);
   658 	if (index != KErrNotFound)
   776 	if (index != KErrNotFound)
   659 		{
   777 		{
   660 		iActiveEffectGroups.Remove(index);
   778 		iActiveEffectGroups[index].iEndCalled = ETrue; // this group will not take any more participants
   661 	
       
   662 		for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
   779 		for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
   663 			{
   780 			{
   664 			CHuiFxEffect* effect = iActiveEffects[i];
   781 			CHuiFxEffect* effect = iActiveEffects[i];
   665 			TInt flags = effect->EffectFlags();
   782 			TInt flags = effect->EffectFlags();
   666 			if ((flags & KHuiFxWaitGroupSyncronization) && (effect->GroupId() == aGroup))
   783 			if ((flags & KHuiFxWaitGroupSyncronization) && (effect->GroupId() == aGroup))
   667 				{
   784 				{
   668 				flags &= ~KHuiFxWaitGroupSyncronization;
   785                 effect->ClearEffectFlag(KHuiFxWaitGroupSyncronization);
   669 				effect->SetEffectFlags(flags);
   786                 effect->SetEffectFlag(KHuiFxWaitGroupToStartSyncronized);
   670 				}
   787 				}
   671 			}
   788 			}
   672 		}
   789 		}
   673 	}
   790 	}
       
   791 
       
   792 void CHuiFxEngine::NotifyEffectReady(TInt aGroupId)
       
   793     {
       
   794 #ifdef HUIFX_TRACE    
       
   795     RDebug::Print(_L("CHuiFxEngine::NotifyEffectReady - %d"), aGroupId);
       
   796 #endif
       
   797     TInt index = FindEffectGroup(aGroupId);
       
   798     if (index != KErrNotFound)
       
   799         {
       
   800         iActiveEffectGroups[index].iWaiting--;    
       
   801 #ifdef HUIFX_TRACE
       
   802         RDebug::Print(_L("CHuiFxEngine::NotifyEffectReady - waiting %d in group %d"), iActiveEffectGroups[index].iWaiting , aGroupId);
       
   803 #endif        
       
   804         if (iActiveEffectGroups[index].iWaiting == 0)
       
   805             {
       
   806             // set in motion all effects in this group
       
   807 	        iActiveEffectGroups.Remove(index);
       
   808             for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
       
   809                 {
       
   810                 CHuiFxEffect* effect = iActiveEffects[i];
       
   811                 TInt flags = effect->EffectFlags();
       
   812 #ifdef HUIFX_TRACE
       
   813                 RDebug::Print(_L("CHuiFxEngine::NotifyEffectReady - effect 0x%x, group: %d, flags 0x%x"), effect, effect->GroupId(), effect->EffectFlags());
       
   814 #endif                
       
   815                 if ((flags & KHuiFxReadyAndWaitingGroupToStartSyncronized) && (effect->GroupId() == aGroupId))
       
   816                     {
       
   817                     effect->ClearEffectFlag(KHuiFxReadyAndWaitingGroupToStartSyncronized);
       
   818                     }
       
   819                 }
       
   820             }
       
   821         }
       
   822     }