--- a/uiacceltk/hitchcock/coretoolkit/src/HuiFxEngine.cpp Mon Mar 15 12:43:37 2010 +0200
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiFxEngine.cpp Wed Mar 31 23:03:58 2010 +0300
@@ -66,6 +66,7 @@
#endif
#endif
CHuiStatic::Env().AddMemoryLevelObserver(this);
+ iActiveEffectGroups.Reserve(2);
}
EXPORT_C TBool CHuiFxEngine::FxmlUsesInput1(const TDesC &aFileName)
@@ -302,6 +303,7 @@
// the effect will be removed, and will no longer be part of iActiveEffects set.
// We must check if the effect is still in our list, but the indices change
// if something is removed from the middle of the list
+ TInt skipGroup = KErrNotFound;
for ( i = iActiveEffects.Count() - 1; i >= 0; i-- )
{
CHuiFxEffect* effect = iActiveEffects[i];
@@ -309,10 +311,24 @@
{
refreshRequired = ETrue;
}
- if ( i < iActiveEffects.Count() && effect == iActiveEffects[i] && !(effect->EffectFlags() & KHuiFxWaitGroupSyncronization))
+ TInt flags = effect->EffectFlags();
+ if ( !(flags & KHuiFxWaitGroupSyncronization)
+ && (skipGroup == KErrNotFound || skipGroup != effect->GroupId()))
{
// The effect is still in its place, it did not go away yet
+ TBool waitingGroupBefore = flags & KHuiFxWaitGroupToStartSyncronized;
effect->AdvanceTime(aElapsedTime);
+
+ if (waitingGroupBefore)
+ {
+ flags = effect->EffectFlags();
+ if (!(flags & KHuiFxReadyAndWaitingGroupToStartSyncronized) && !(flags & KHuiFxWaitGroupToStartSyncronized))
+ {
+ // effects in this group are all ready to start drawing. Skip this group in AdvanceTime,
+ // that they can start syncronized on the next round
+ skipGroup = effect->GroupId();
+ }
+ }
}
}
@@ -626,48 +642,123 @@
ASSERT(iBuffersInCache == 0);
}
-
+
+TInt CHuiFxEngine::FindEffectGroup(TInt aGroup)
+ {
+ for (TInt i=0 ; i < iActiveEffectGroups.Count();i++)
+ {
+ if (iActiveEffectGroups[i].iGroup == aGroup)
+ {
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
EXPORT_C void CHuiFxEngine::BeginGroupEffect(TInt aGroup)
{
- TInt index = iActiveEffectGroups.Find(aGroup);
+ // Multiple grouped effects at the same time are not supported.
+ // Same visual might participate different groups, which will mess up the effect
+ if (iActiveEffectGroups.Count()>0)
+ {
+ // delete previous groups
+ while(iActiveEffectGroups.Count())
+ {
+ TInt groupId = iActiveEffectGroups[0].iGroup;
+ for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
+ {
+ if (iActiveEffects[i]->GroupId() == groupId)
+ {
+ iActiveEffects[i]->ClearEffectFlag(KHuiFxReadyAndWaitingGroupToStartSyncronized);
+ iActiveEffects[i]->ClearEffectFlag(KHuiFxWaitGroupToStartSyncronized);
+ iActiveEffects[i]->ClearEffectFlag(KHuiFxWaitGroupSyncronization);
+ }
+
+ }
+ iActiveEffectGroups.Remove(0);
+ }
+ }
+
+ TInt index = FindEffectGroup(aGroup);
+
if (index == KErrNotFound)
{
- iActiveEffectGroups.Append(aGroup);
- }
- else
- {
- // group already exists
+ const TEffectGroupStruct item(aGroup);
+ iActiveEffectGroups.Append(item);
}
}
+// This will add effect to this group. Do not call this function more than once for single effect
EXPORT_C TInt CHuiFxEngine::ActiveGroupEffect()
{
- if (iActiveEffectGroups.Count() > 0)
- {
- return iActiveEffectGroups[iActiveEffectGroups.Count()-1];
- }
- else
- {
- return KErrNotFound;
- }
+ TInt index = iActiveEffectGroups.Count();
+ if (index == 0)
+ {
+ return KErrNotFound;
+ }
+ while(--index >= 0)
+ {
+ // group is alive until all its effects have been drawn once. .iEndCalled is to prevent
+ // another effect entering into this group
+ const TEffectGroupStruct& item = iActiveEffectGroups[index];
+ if (!item.iEndCalled)
+ {
+ return iActiveEffectGroups[index].iGroup;
+ }
+ }
+ return KErrNotFound;
}
+EXPORT_C TBool CHuiFxEngine::AddEffectToGroup(TInt aGroup)
+ {
+ TInt index = FindEffectGroup(aGroup);
+ if (index != KErrNotFound)
+ {
+ // keep count of effects in this group. All must draw atleast once, before
+ // syncronized group effect may start
+ iActiveEffectGroups[index].iWaiting++;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
EXPORT_C void CHuiFxEngine::StartGroupEffect(TInt aGroup)
{
- TInt index = iActiveEffectGroups.Find(aGroup);
+ TInt index = FindEffectGroup(aGroup);
if (index != KErrNotFound)
{
- iActiveEffectGroups.Remove(index);
-
+ iActiveEffectGroups[index].iEndCalled = ETrue; // this group will not take any more participants
for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
{
CHuiFxEffect* effect = iActiveEffects[i];
TInt flags = effect->EffectFlags();
if ((flags & KHuiFxWaitGroupSyncronization) && (effect->GroupId() == aGroup))
{
- flags &= ~KHuiFxWaitGroupSyncronization;
- effect->SetEffectFlags(flags);
+ effect->ClearEffectFlag(KHuiFxWaitGroupSyncronization);
+ effect->SetEffectFlag(KHuiFxWaitGroupToStartSyncronized);
}
}
}
}
+
+void CHuiFxEngine::NotifyEffectReady(TInt aGroupId)
+ {
+ TInt index = FindEffectGroup(aGroupId);
+ if (index != KErrNotFound)
+ {
+ if (--iActiveEffectGroups[iActiveEffectGroups.Count()-1].iWaiting == 0)
+ {
+ // set in motion all effects in this group
+ iActiveEffectGroups.Remove(index);
+ for ( TInt i = iActiveEffects.Count() - 1; i >= 0; i-- )
+ {
+ CHuiFxEffect* effect = iActiveEffects[i];
+ TInt flags = effect->EffectFlags();
+ if ((flags & KHuiFxReadyAndWaitingGroupToStartSyncronized) && (effect->GroupId() == aGroupId))
+ {
+ effect->ClearEffectFlag(KHuiFxReadyAndWaitingGroupToStartSyncronized);
+ }
+ }
+ }
+ }
+ }