Bug 1229280 - Move animation generation from AnimationCollection to EffectSet; r=dbaron

--HG--
extra : rebase_source : 26a942c8c6058e629e7d7ed549eb1fcdf7f6d399
This commit is contained in:
Brian Birtles 2016-01-06 11:04:05 +09:00
parent bf9f389bda
commit bf0b758990
11 changed files with 68 additions and 48 deletions

View File

@ -6,7 +6,9 @@
#include "EffectSet.h"
#include "mozilla/dom/Element.h" // For Element
#include "RestyleManager.h"
#include "nsCycleCollectionNoteChild.h" // For CycleCollectionNoteChild
#include "nsPresContext.h"
namespace mozilla {
@ -106,6 +108,13 @@ EffectSet::GetOrCreateEffectSet(dom::Element* aElement,
return effectSet;
}
void
EffectSet::UpdateAnimationGeneration(nsPresContext* aPresContext)
{
mAnimationGeneration =
aPresContext->RestyleManager()->GetAnimationGeneration();
}
/* static */ nsIAtom**
EffectSet::GetEffectSetPropertyAtoms()
{

View File

@ -11,6 +11,8 @@
#include "nsHashKeys.h" // For nsPtrHashKey
#include "nsTHashtable.h" // For nsTHashtable
class nsPresContext;
namespace mozilla {
namespace dom {
@ -25,6 +27,7 @@ class EffectSet
public:
EffectSet()
: mCascadeNeedsUpdate(false)
, mAnimationGeneration(0)
#ifdef DEBUG
, mCalledPropertyDtor(false)
#endif
@ -125,6 +128,9 @@ public:
void MarkCascadeNeedsUpdate() { mCascadeNeedsUpdate = true; }
void MarkCascadeUpdated() { mCascadeNeedsUpdate = false; }
void UpdateAnimationGeneration(nsPresContext* aPresContext);
uint64_t GetAnimationGeneration() const { return mAnimationGeneration; }
static nsIAtom** GetEffectSetPropertyAtoms();
private:
@ -140,6 +146,14 @@ private:
// one the effects goes in or out of the "in effect" state.
bool mCascadeNeedsUpdate;
// RestyleManager keeps track of the number of animation restyles.
// 'mini-flushes' (see nsTransitionManager::UpdateAllThrottledStyles()).
// mAnimationGeneration is the sequence number of the last flush where a
// transition/animation changed. We keep a similar count on the
// corresponding layer so we can check that the layer is up to date with
// the animation manager.
uint64_t mAnimationGeneration;
#ifdef DEBUG
bool mCalledPropertyDtor;
#endif

View File

@ -1839,14 +1839,15 @@ KeyframeEffectReadOnly::CanThrottle() const
continue;
}
AnimationCollection* collection = GetCollection();
MOZ_ASSERT(collection,
"CanThrottle should be called on an effect associated with an animation");
EffectSet* effectSet = EffectSet::GetEffectSet(mTarget, mPseudoType);
MOZ_ASSERT(effectSet, "CanThrottle should be called on an effect "
"associated with a target element");
layers::Layer* layer =
FrameLayerBuilder::GetDedicatedLayer(frame, record.mLayerType);
// Unthrottle if the layer needs to be brought up to date with the animation.
// Unthrottle if the layer needs to be brought up to date
if (!layer ||
collection->mAnimationGeneration > layer->GetAnimationGeneration()) {
effectSet->GetAnimationGeneration() !=
layer->GetAnimationGeneration()) {
return false;
}

View File

@ -39,6 +39,7 @@ UNIFIED_SOURCES += [
LOCAL_INCLUDES += [
'/dom/base',
'/layout/base',
'/layout/style',
]

View File

@ -1337,15 +1337,10 @@ RestyleManager::AttributeChanged(Element* aElement,
}
/* static */ uint64_t
RestyleManager::GetMaxAnimationGenerationForFrame(nsIFrame* aFrame)
RestyleManager::GetAnimationGenerationForFrame(nsIFrame* aFrame)
{
AnimationCollection* transitions =
aFrame->PresContext()->TransitionManager()->GetAnimationCollection(aFrame);
AnimationCollection* animations =
aFrame->PresContext()->AnimationManager()->GetAnimationCollection(aFrame);
return std::max(transitions ? transitions->mAnimationGeneration : 0,
animations ? animations->mAnimationGeneration : 0);
EffectSet* effectSet = EffectSet::GetEffectSet(aFrame);
return effectSet ? effectSet->GetAnimationGeneration() : 0;
}
void
@ -2708,7 +2703,7 @@ ElementRestyler::AddLayerChangesForAnimation()
// on layers for transitions and animations and use != comparison below
// rather than a > comparison.
uint64_t frameGeneration =
RestyleManager::GetMaxAnimationGenerationForFrame(mFrame);
RestyleManager::GetAnimationGenerationForFrame(mFrame);
nsChangeHint hint = nsChangeHint(0);
for (const LayerAnimationInfo::Record& layerInfo :

View File

@ -100,10 +100,7 @@ public:
// track whether off-main-thread animations are up-to-date.
uint64_t GetAnimationGeneration() const { return mAnimationGeneration; }
// A workaround until bug 847286 lands that gets the maximum of the animation
// generation counters stored on the set of animations and transitions
// respectively for |aFrame|.
static uint64_t GetMaxAnimationGenerationForFrame(nsIFrame* aFrame);
static uint64_t GetAnimationGenerationForFrame(nsIFrame* aFrame);
// Update the animation generation count to mark that animation state
// has changed.

View File

@ -522,7 +522,7 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
// Otherwise, in RestyleManager we'll notice the discrepancy between the
// animation generation numbers and update the layer indefinitely.
uint64_t animationGeneration =
RestyleManager::GetMaxAnimationGenerationForFrame(aFrame);
RestyleManager::GetAnimationGenerationForFrame(aFrame);
aLayer->SetAnimationGeneration(animationGeneration);
nsPresContext* presContext = aFrame->PresContext();

View File

@ -542,7 +542,11 @@ AnimationCollection::RequestRestyle(RestyleType aRestyleType)
// Prompt layers to re-sync their animations.
presContext->ClearLastStyleUpdateForAllAnimations();
presContext->RestyleManager()->IncrementAnimationGeneration();
UpdateAnimationGeneration(presContext);
EffectSet* effectSet =
EffectSet::GetEffectSet(mElement, PseudoElementType());
if (effectSet) {
effectSet->UpdateAnimationGeneration(presContext);
}
}
// Steps for RestyleType::Standard and above:
@ -564,13 +568,6 @@ AnimationCollection::RequestRestyle(RestyleType aRestyleType)
presContext->Document()->SetNeedStyleFlush();
}
void
AnimationCollection::UpdateAnimationGeneration(nsPresContext* aPresContext)
{
mAnimationGeneration =
aPresContext->RestyleManager()->GetAnimationGeneration();
}
void
AnimationCollection::UpdateCheckGeneration(
nsPresContext* aPresContext)

View File

@ -201,7 +201,6 @@ struct AnimationCollection : public LinkedListElement<AnimationCollection>
: mElement(aElement)
, mElementProperty(aElementProperty)
, mManager(aManager)
, mAnimationGeneration(0)
, mCheckGeneration(0)
, mStyleChanging(true)
, mHasPendingAnimationRestyle(false)
@ -337,24 +336,13 @@ public:
// null, but mStyleRuleRefreshTime will still be valid.
RefPtr<AnimValuesStyleRule> mStyleRule;
// RestyleManager keeps track of the number of animation
// 'mini-flushes' (see nsTransitionManager::UpdateAllThrottledStyles()).
// mAnimationGeneration is the sequence number of the last flush where a
// transition/animation changed. We keep a similar count on the
// corresponding layer so we can check that the layer is up to date with
// the animation manager.
uint64_t mAnimationGeneration;
// Update mAnimationGeneration to nsCSSFrameConstructor's count
void UpdateAnimationGeneration(nsPresContext* aPresContext);
// For CSS transitions only, we also record the most recent generation
// For CSS transitions only, we record the most recent generation
// for which we've done the transition update, so that we avoid doing
// it more than once per style change. This should be greater than or
// equal to mAnimationGeneration, except when the generation counter
// cycles, or when animations are updated through the DOM Animation
// interfaces.
// it more than once per style change.
// (Note that we also store an animation generation on each EffectSet in
// order to track when we need to update animations on layers.)
uint64_t mCheckGeneration;
// Update mAnimationGeneration to nsCSSFrameConstructor's count
// Update mCheckGeneration to RestyleManager's count
void UpdateCheckGeneration(nsPresContext* aPresContext);
// The refresh time associated with mStyleRule.

View File

@ -8,6 +8,7 @@
#include "mozilla/dom/CSSAnimationBinding.h"
#include "mozilla/EffectCompositor.h"
#include "mozilla/EffectSet.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/dom/DocumentTimeline.h"
@ -416,7 +417,11 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
if (collection) {
collection->mStyleRule = nullptr;
collection->mStyleRuleRefreshTime = TimeStamp();
collection->UpdateAnimationGeneration(mPresContext);
EffectSet* effectSet =
EffectSet::GetEffectSet(aElement, aStyleContext->GetPseudoType());
if (effectSet) {
effectSet->UpdateAnimationGeneration(mPresContext);
}
// Copy over the start times and (if still paused) pause starts
// for each animation (matching on name only) that was also in the

View File

@ -19,6 +19,7 @@
#include "nsRuleWalker.h"
#include "nsCSSPropertySet.h"
#include "mozilla/EffectCompositor.h"
#include "mozilla/EffectSet.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/dom/DocumentTimeline.h"
@ -464,7 +465,10 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
currentValue != segment.mToValue) {
// stop the transition
if (anim->HasCurrentEffect()) {
collection->UpdateAnimationGeneration(mPresContext);
EffectSet* effectSet = EffectSet::GetEffectSet(aElement, pseudoType);
if (effectSet) {
effectSet->UpdateAnimationGeneration(mPresContext);
}
}
anim->CancelFromStyle();
animations.RemoveElementAt(i);
@ -604,7 +608,11 @@ nsTransitionManager::ConsiderStartingTransition(
animations[currentIndex]->CancelFromStyle();
oldPT = nullptr; // Clear pointer so it doesn't dangle
animations.RemoveElementAt(currentIndex);
aElementTransitions->UpdateAnimationGeneration(mPresContext);
EffectSet* effectSet =
EffectSet::GetEffectSet(aElement, aNewStyleContext->GetPseudoType());
if (effectSet) {
effectSet->UpdateAnimationGeneration(mPresContext);
}
if (animations.IsEmpty()) {
aElementTransitions->Destroy();
@ -735,7 +743,12 @@ nsTransitionManager::ConsiderStartingTransition(
return;
}
}
aElementTransitions->UpdateAnimationGeneration(mPresContext);
EffectSet* effectSet =
EffectSet::GetEffectSet(aElement, aNewStyleContext->GetPseudoType());
if (effectSet) {
effectSet->UpdateAnimationGeneration(mPresContext);
}
*aStartedAny = true;
aWhichStarted->AddProperty(aProperty);