Bug 1171966 - Update SMIL animation styles only when there are pending changes; r=dholbert

Bug 960465 (specifically part 6, changeset 7d16f2fd8329) changed the way we
process animation-only style changes. This caused us to update SMIL animations
more often than is needed.

This patch adjusts this behavior to update the style from SMIL animations less
frequently by tracking when animated values have been composited without adding
the corresponding changes to a restyle tracker.
This commit is contained in:
Brian Birtles 2015-07-31 13:14:46 +09:00
parent aefe552c95
commit 0dd0ecdc09
3 changed files with 26 additions and 17 deletions

View File

@ -32,6 +32,7 @@ nsSMILAnimationController::nsSMILAnimationController(nsIDocument* aDoc)
mDeferredStartSampling(false),
mRunningSample(false),
mRegisteredWithRefreshDriver(false),
mMightHavePendingStyleUpdates(false),
mDocument(aDoc)
{
MOZ_ASSERT(aDoc, "need a non-null document");
@ -439,6 +440,7 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
// Update last compositor table
mLastCompositorTable = currentCompositorTable.forget();
mMightHavePendingStyleUpdates = true;
NS_ASSERTION(!mResampleNeeded, "Resample dirty flag set during sample!");
}
@ -704,6 +706,9 @@ nsSMILAnimationController::GetTargetIdentifierForAnimation(
void
nsSMILAnimationController::AddStyleUpdatesTo(RestyleTracker& aTracker)
{
MOZ_ASSERT(mMightHavePendingStyleUpdates,
"Should only add style updates when we think we might have some");
for (auto iter = mAnimationElementTable.Iter(); !iter.Done(); iter.Next()) {
SVGAnimationElement* animElement = iter.Get()->GetKey();
@ -721,6 +726,8 @@ nsSMILAnimationController::AddStyleUpdatesTo(RestyleTracker& aTracker)
: eRestyle_SVGAttrAnimations;
aTracker.AddPendingRestyle(key.mElement, rshint, nsChangeHint(0));
}
mMightHavePendingStyleUpdates = false;
}
//----------------------------------------------------------------------

View File

@ -74,10 +74,8 @@ public:
void SetResampleNeeded()
{
if (!mRunningSample) {
if (!mResampleNeeded) {
FlagDocumentNeedsFlush();
}
if (!mRunningSample && !mResampleNeeded) {
FlagDocumentNeedsFlush();
mResampleNeeded = true;
}
}
@ -104,10 +102,16 @@ public:
void NotifyRefreshDriverDestroying(nsRefreshDriver* aRefreshDriver);
// Helper to check if we have any animation elements at all
bool HasRegisteredAnimations()
{ return mAnimationElementTable.Count() != 0; }
bool HasRegisteredAnimations() const
{
return mAnimationElementTable.Count() != 0;
}
void AddStyleUpdatesTo(mozilla::RestyleTracker& aTracker);
bool MightHavePendingStyleUpdates() const
{
return mMightHavePendingStyleUpdates;
}
protected:
~nsSMILAnimationController();
@ -186,6 +190,9 @@ protected:
// Are we registered with our document's refresh driver?
bool mRegisteredWithRefreshDriver;
// Have we updated animated values without adding them to the restyle tracker?
bool mMightHavePendingStyleUpdates;
// Store raw ptr to mDocument. It owns the controller, so controller
// shouldn't outlive it
nsIDocument* mDocument;

View File

@ -1774,18 +1774,13 @@ RestyleManager::UpdateOnlyAnimationStyles()
bool doCSS = mLastUpdateForThrottledAnimations != now;
mLastUpdateForThrottledAnimations = now;
bool doSMIL = false;
nsIDocument* document = mPresContext->Document();
nsSMILAnimationController* animationController = nullptr;
if (document->HasAnimationController()) {
animationController = document->GetAnimationController();
// FIXME: Ideally, we only want to do this if animation timelines
// have advanced. However, different SMIL animations could be
// getting their time from different outermost SVG elements, so
// finding all of them might be a pain. So this could be optimized
// to set doSMIL to true in fewer cases.
doSMIL = true;
}
nsSMILAnimationController* animationController =
document->HasAnimationController() ?
document->GetAnimationController() :
nullptr;
bool doSMIL = animationController &&
animationController->MightHavePendingStyleUpdates();
if (!doCSS && !doSMIL) {
return;