Bug 1232577 part 4 - Add and remove (pseudo-)elements needing an animation style rule update to the EffectCompositor; r=heycam

This patch uses the presence/absence of (pseudo-)elements in the "needs
animation rule update" hashmap on EffectCompositor to detect if a style update
is required. The various flags in AnimationCollection that do a similar job
still remain so that we can remove them one-by-one in subsequent patches in
this series.
This commit is contained in:
Brian Birtles 2016-01-13 07:54:53 +09:00
Родитель 03057136c3
Коммит 815e0c4b64
4 изменённых файлов: 104 добавлений и 16 удалений

Просмотреть файл

@ -129,6 +129,42 @@ FindAnimationsForCompositor(const nsIFrame* aFrame,
return foundSome;
}
void
EffectCompositor::RequestRestyle(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
RestyleType aRestyleType,
CascadeLevel aCascadeLevel)
{
auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
PseudoElementHashKey key = { aElement, aPseudoType };
if (aRestyleType == RestyleType::Throttled &&
!elementsToRestyle.Contains(key)) {
elementsToRestyle.Put(key, false);
} else {
elementsToRestyle.Put(key, true);
}
}
void
EffectCompositor::MaybeUpdateAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type
aPseudoType,
CascadeLevel aCascadeLevel,
bool& aStyleChanging)
{
auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
PseudoElementHashKey key = { aElement, aPseudoType };
if (!elementsToRestyle.Contains(key)) {
return;
}
ComposeAnimationRule(aElement, aPseudoType, aCascadeLevel, aStyleChanging);
elementsToRestyle.Remove(key);
}
/* static */ bool
EffectCompositor::HasAnimationsForCompositor(const nsIFrame* aFrame,
nsCSSProperty aProperty)

Просмотреть файл

@ -72,13 +72,31 @@ public:
// Animation style has changed and needs to be updated on the main thread
// as well as forcing animations on layers to be updated.
// This is needed in cases such as when an animation becomes paused or has
// its playback rate changed. In such a case, although the computed style
// its playback rate changed. In such cases, although the computed style
// and refresh driver time might not change, we still need to ensure the
// corresponding animations on layers are updated to reflect the new
// configuration of the animation.
Layer
};
// Notifies the compositor that the animation rule for the specified
// (pseudo-)element at the specified cascade level needs to be updated.
// The specified steps taken to update the animation rule depend on
// |aRestyleType| whose values are described above.
void RequestRestyle(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
RestyleType aRestyleType,
CascadeLevel aCascadeLevel);
// Updates the animation rule stored on the EffectSet for the
// specified (pseudo-)element for cascade level |aLevel|.
// If the animation rule is not marked as needing an update,
// no work is done.
void MaybeUpdateAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CascadeLevel aCascadeLevel,
bool& aStyleChanging);
static bool HasAnimationsForCompositor(const nsIFrame* aFrame,
nsCSSProperty aProperty);
@ -122,6 +140,9 @@ public:
static Maybe<Pair<dom::Element*, nsCSSPseudoElements::Type>>
GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame);
private:
~EffectCompositor() = default;
// Rebuilds the animation rule corresponding to |aCascadeLevel| on the
// EffectSet associated with the specified (pseudo-)element.
static void ComposeAnimationRule(dom::Element* aElement,
@ -129,9 +150,6 @@ public:
CascadeLevel aCascadeLevel,
bool& aStyleChanging);
private:
~EffectCompositor() = default;
// Get the properties in |aEffectSet| that we are able to animate on the
// compositor but which are also specified at a higher level in the cascade
// than the animations level in |aStyleContext|.

Просмотреть файл

@ -165,7 +165,6 @@ KeyframeEffectReadOnly::NotifyAnimationTimingUpdated()
// Request restyle if necessary.
ComputedTiming computedTiming = GetComputedTiming();
AnimationCollection* collection = GetCollection();
// Bug 1235002: We should skip requesting a restyle when mProperties is empty.
// However, currently we don't properly encapsulate mProperties so we can't
// detect when it changes. As a result, if we skip requesting restyles when
@ -174,13 +173,33 @@ KeyframeEffectReadOnly::NotifyAnimationTimingUpdated()
// request a restyle at all. Since animations without properties are rare, we
// currently just request the restyle regardless of whether mProperties is
// empty or not.
if (collection &&
// Bug 1216843: When we implement iteration composite modes, we need to
// also detect if the current iteration has changed.
computedTiming.mProgress != mProgressOnLastCompose) {
collection->RequestRestyle(CanThrottle() ?
EffectCompositor::RestyleType::Throttled :
EffectCompositor::RestyleType::Standard);
//
// Bug 1216843: When we implement iteration composite modes, we need to
// also detect if the current iteration has changed.
if (computedTiming.mProgress != mProgressOnLastCompose) {
EffectCompositor::RestyleType restyleType =
CanThrottle() ?
EffectCompositor::RestyleType::Throttled :
EffectCompositor::RestyleType::Standard;
// FIXME: This arrangement of calling RequestRestyle on *either* the
// collection or the compositor is temporary while we move this method
// to the compositor.
//
// In the case where we don't have a collection (as is often the case
// when we create animations but haven't yet added them to a collection
// yet) we still need to make sure that the effect ends up in the
// "needs restyle" map in the compositor.
AnimationCollection* collection = GetCollection();
if (collection) {
collection->RequestRestyle(restyleType);
} else if (mAnimation) {
nsPresContext* presContext = GetPresContext();
if (presContext) {
presContext->EffectCompositor()->
RequestRestyle(mTarget, mPseudoType, restyleType,
mAnimation->CascadeLevel());
}
}
}
}

Просмотреть файл

@ -416,6 +416,12 @@ AnimationCollection::EnsureStyleRuleFor(TimeStamp aRefreshTime)
{
mHasPendingAnimationRestyle = false;
nsPresContext* presContext = mManager->PresContext();
if (!presContext) {
// Pres context will be null after the manager is disconnected.
return;
}
if (!mStyleChanging) {
mStyleRuleRefreshTime = aRefreshTime;
return;
@ -450,10 +456,10 @@ AnimationCollection::EnsureStyleRuleFor(TimeStamp aRefreshTime)
IsForAnimations() ?
EffectCompositor::CascadeLevel::Animations :
EffectCompositor::CascadeLevel::Transitions;
EffectCompositor::ComposeAnimationRule(mElement,
PseudoElementType(),
cascadeLevel,
mStyleChanging);
presContext->EffectCompositor()->MaybeUpdateAnimationRule(mElement,
PseudoElementType(),
cascadeLevel,
mStyleChanging);
}
void
@ -468,6 +474,15 @@ AnimationCollection::RequestRestyle(EffectCompositor::RestyleType aRestyleType)
return;
}
EffectCompositor::CascadeLevel cascadeLevel =
IsForAnimations() ?
EffectCompositor::CascadeLevel::Animations :
EffectCompositor::CascadeLevel::Transitions;
presContext->EffectCompositor()->RequestRestyle(mElement,
PseudoElementType(),
aRestyleType,
cascadeLevel);
// Steps for RestyleType::Layer:
if (aRestyleType == EffectCompositor::RestyleType::Layer) {