Skip to content

Commit

Permalink
Bug 1209405 - Part 3: Save updating style. r=birtles
Browse files Browse the repository at this point in the history
MozReview-Commit-ID: FAWfIeXrLki
  • Loading branch information
dadaa committed May 23, 2016
1 parent e5a0ffd commit b3aa2dc
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 12 deletions.
23 changes: 16 additions & 7 deletions dom/smil/nsSMILAnimationController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,12 +319,13 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
return;
}

bool isStyleFlushNeeded = mResampleNeeded;
mResampleNeeded = false;
// Set running sample flag -- do this before flushing styles so that when we
// flush styles we don't end up requesting extra samples
AutoRestore<bool> autoRestoreRunningSample(mRunningSample);
mRunningSample = true;

// STEP 1: Bring model up to date
// (i) Rewind elements where necessary
// (ii) Run milestone samples
Expand Down Expand Up @@ -378,7 +379,9 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
for (auto iter = mAnimationElementTable.Iter(); !iter.Done(); iter.Next()) {
SVGAnimationElement* animElem = iter.Get()->GetKey();
SampleTimedElement(animElem, &activeContainers);
AddAnimationToCompositorTable(animElem, currentCompositorTable);
AddAnimationToCompositorTable(animElem,
currentCompositorTable,
isStyleFlushNeeded);
}
activeContainers.Clear();

Expand Down Expand Up @@ -422,9 +425,11 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
}

nsCOMPtr<nsIDocument> kungFuDeathGrip(mDocument); // keeps 'this' alive too
mDocument->FlushPendingNotifications(Flush_Style);
if (isStyleFlushNeeded) {
mDocument->FlushPendingNotifications(Flush_Style);
}

// WARNING:
// WARNING:
// WARNING: the above flush may have destroyed the pres shell and/or
// WARNING: frames and other layout related objects.
// WARNING:
Expand All @@ -434,13 +439,14 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
// random order. For animation from/to 'inherit' values to work correctly
// when the inherited value is *also* being animated, we really should be
// traversing our animated nodes in an ancestors-first order (bug 501183)
bool mightHavePendingStyleUpdates = false;
for (auto iter = currentCompositorTable->Iter(); !iter.Done(); iter.Next()) {
iter.Get()->ComposeAttribute();
iter.Get()->ComposeAttribute(mightHavePendingStyleUpdates);
}

// Update last compositor table
mLastCompositorTable = currentCompositorTable.forget();
mMightHavePendingStyleUpdates = true;
mMightHavePendingStyleUpdates = mightHavePendingStyleUpdates;

NS_ASSERTION(!mResampleNeeded, "Resample dirty flag set during sample!");
}
Expand Down Expand Up @@ -596,7 +602,9 @@ nsSMILAnimationController::SampleTimedElement(

/*static*/ void
nsSMILAnimationController::AddAnimationToCompositorTable(
SVGAnimationElement* aElement, nsSMILCompositorTable* aCompositorTable)
SVGAnimationElement* aElement,
nsSMILCompositorTable* aCompositorTable,
bool& aStyleFlushNeeded)
{
// Add a compositor to the hash table if there's not already one there
nsSMILTargetIdentifier key;
Expand Down Expand Up @@ -629,6 +637,7 @@ nsSMILAnimationController::AddAnimationToCompositorTable(
// trigger this same clause in future samples (until it changes again).
func.ClearHasChanged();
}
aStyleFlushNeeded |= func.ValueNeedsReparsingEverySample();
}

static inline bool
Expand Down
6 changes: 5 additions & 1 deletion dom/smil/nsSMILAnimationController.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,12 @@ class nsSMILAnimationController final : public nsSMILTimeContainer,

static void SampleTimedElement(mozilla::dom::SVGAnimationElement* aElement,
TimeContainerHashtable* aActiveContainers);

static void AddAnimationToCompositorTable(
mozilla::dom::SVGAnimationElement* aElement, nsSMILCompositorTable* aCompositorTable);
mozilla::dom::SVGAnimationElement* aElement,
nsSMILCompositorTable* aCompositorTable,
bool& aStyleFlushNeeded);

static bool GetTargetIdentifierForAnimation(
mozilla::dom::SVGAnimationElement* aAnimElem, nsSMILTargetIdentifier& aResult);

Expand Down
8 changes: 8 additions & 0 deletions dom/smil/nsSMILAnimationFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ class nsSMILAnimationFunction
mWasSkippedInPrevSample = true;
}

/**
* Returns true if we need to recalculate the animation value on every sample.
* (e.g. because it depends on context like the font-size)
*/
bool ValueNeedsReparsingEverySample() const {
return mValueNeedsReparsingEverySample;
}

// Comparator utility class, used for sorting nsSMILAnimationFunctions
class Comparator {
public:
Expand Down
5 changes: 4 additions & 1 deletion dom/smil/nsSMILCompositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ nsSMILCompositor::AddAnimationFunction(nsSMILAnimationFunction* aFunc)
}

void
nsSMILCompositor::ComposeAttribute()
nsSMILCompositor::ComposeAttribute(bool& aMightHavePendingStyleUpdates)
{
if (!mKey.mElement)
return;
Expand All @@ -65,6 +65,8 @@ nsSMILCompositor::ComposeAttribute()
// No active animation functions. (We can still have a nsSMILCompositor in
// that case if an animation function has *just* become inactive)
smilAttr->ClearAnimValue();
// Removing the animation effect may require a style update.
aMightHavePendingStyleUpdates = true;
return;
}

Expand All @@ -88,6 +90,7 @@ nsSMILCompositor::ComposeAttribute()
}

// FIFTH: Compose animation functions
aMightHavePendingStyleUpdates = true;
uint32_t length = mAnimationFunctions.Length();
for (uint32_t i = firstFuncToCompose; i < length; ++i) {
mAnimationFunctions[i]->ComposeResult(*smilAttr, sandwichResultValue);
Expand Down
7 changes: 4 additions & 3 deletions dom/smil/nsSMILCompositor.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ class nsSMILCompositor : public PLDHashEntryHdr

// Composes the attribute's current value with the list of animation
// functions, and assigns the resulting value to this compositor's target
// attribute
void ComposeAttribute();
// attribute. If a change is made that might produce style updates,
// aMightHavePendingStyleUpdates is set to true. Otherwise it is not modified.
void ComposeAttribute(bool& aMightHavePendingStyleUpdates);

// Clears animation effects on my target attribute
void ClearAnimationEffects();
Expand All @@ -74,7 +75,7 @@ class nsSMILCompositor : public PLDHashEntryHdr
// Create a nsISMILAttr for my target, on the heap. Caller is responsible
// for deallocating the returned object.
nsISMILAttr* CreateSMILAttr();

// Finds the index of the first function that will affect our animation
// sandwich. Also toggles the 'mForceCompositing' flag if it finds that any
// (used) functions have changed.
Expand Down

0 comments on commit b3aa2dc

Please sign in to comment.