Bug 1340958 - Templatize ComposeStyle. r?birtles
Later in this patch series we will replace ServoAnimationRule with a hashmap.
At that point, we would like to pass the hashmap to ComposeStyle. In order
to achieve that, this patch templatizes the 'animation rule' parameter of
ComposeStyle in both Animation and KeyframeEffectReadOnly so that it can
represent a hashmap instead.
MozReview-Commit-ID: H5bMxjN3W8n
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -9,16 +9,17 @@
#include "mozilla/dom/AnimationBinding.h"
#include "mozilla/dom/AnimationPlaybackEvent.h"
#include "mozilla/dom/DocumentTimeline.h"
#include "mozilla/AnimationTarget.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/AsyncEventDispatcher.h" // For AsyncEventDispatcher
#include "mozilla/Maybe.h" // For Maybe
#include "mozilla/AnimationRule.h" // For AnimationRule
+#include "mozilla/TypeTraits.h" // For Forward<>
#include "nsAnimationManager.h" // For CSSAnimation
#include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
#include "nsIDocument.h" // For nsIDocument
#include "nsIPresShell.h" // For nsIPresShell
#include "nsThreadUtils.h" // For nsRunnableMethod and nsRevocableEventPtr
#include "nsTransitionManager.h" // For CSSTransition
#include "PendingAnimationTracker.h" // For PendingAnimationTracker
@@ -937,18 +938,19 @@ Animation::WillComposeStyle()
MOZ_ASSERT(mEffect);
KeyframeEffectReadOnly* keyframeEffect = mEffect->AsKeyframeEffect();
if (keyframeEffect) {
keyframeEffect->WillComposeStyle();
}
}
+template<typename ComposeAnimationResult>
void
-Animation::ComposeStyle(AnimationRule& aStyleRule,
+Animation::ComposeStyle(ComposeAnimationResult&& aComposeResult,
const nsCSSPropertyIDSet& aPropertiesToSkip)
{
if (!mEffect) {
return;
}
// In order to prevent flicker, there are a few cases where we want to use
// a different time for rendering that would otherwise be returned by
@@ -1000,17 +1002,18 @@ Animation::ComposeStyle(AnimationRule& a
if (!timeToUse.IsNull()) {
mHoldTime.SetValue((timeToUse.Value() - mStartTime.Value())
.MultDouble(mPlaybackRate));
}
}
KeyframeEffectReadOnly* keyframeEffect = mEffect->AsKeyframeEffect();
if (keyframeEffect) {
- keyframeEffect->ComposeStyle(aStyleRule, aPropertiesToSkip);
+ keyframeEffect->ComposeStyle(Forward<ComposeAnimationResult>(aComposeResult),
+ aPropertiesToSkip);
}
}
MOZ_ASSERT(playState == PlayState(),
"Play state should not change during the course of compositing");
}
void
@@ -1501,10 +1504,22 @@ Animation::DispatchPlaybackEvent(const n
bool
Animation::IsRunningOnCompositor() const
{
return mEffect &&
mEffect->AsKeyframeEffect() &&
mEffect->AsKeyframeEffect()->IsRunningOnCompositor();
}
+template
+void
+Animation::ComposeStyle<RefPtr<AnimValuesStyleRule>&>(
+ RefPtr<AnimValuesStyleRule>& aAnimationRule,
+ const nsCSSPropertyIDSet& aPropertiesToSkip);
+
+template
+void
+Animation::ComposeStyle<RefPtr<ServoAnimationRule>&>(
+ RefPtr<ServoAnimationRule>& aAnimationRule,
+ const nsCSSPropertyIDSet& aPropertiesToSkip);
+
} // namespace dom
} // namespace mozilla
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -316,22 +316,23 @@ public:
/**
* Updates various bits of state that we need to update as the result of
* running ComposeStyle().
* See the comment of KeyframeEffectReadOnly::WillComposeStyle for more detail.
*/
void WillComposeStyle();
/**
- * Updates |aStyleRule| with the animation values of this animation's effect,
- * if any.
+ * Updates |aComposeResult| with the animation values of this animation's
+ * effect, if any.
* Any properties contained in |aPropertiesToSkip| will not be added or
- * updated in |aStyleRule|.
+ * updated in |aComposeResult|.
*/
- void ComposeStyle(AnimationRule& aStyleRule,
+ template<typename ComposeAnimationResult>
+ void ComposeStyle(ComposeAnimationResult&& aComposeResult,
const nsCSSPropertyIDSet& aPropertiesToSkip);
void NotifyEffectTimingUpdated();
void NotifyGeometricAnimationsStartingThisFrame();
/**
* Used by subclasses to synchronously queue a cancel event in situations
* where the Animation may have been cancelled.
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -503,17 +503,17 @@ EffectCompositor::GetServoAnimationRule(
// If multiple animations affect the same property, animations with higher
// composite order (priority) override or add or animations with lower
// priority.
const nsCSSPropertyIDSet propertiesToSkip =
aCascadeLevel == CascadeLevel::Animations
? effectSet->PropertiesForAnimationsLevel().Inverse()
: effectSet->PropertiesForAnimationsLevel();
for (KeyframeEffectReadOnly* effect : sortedEffectList) {
- effect->GetAnimation()->ComposeStyle(animRule, propertiesToSkip);
+ effect->GetAnimation()->ComposeStyle(animRule.mServo, propertiesToSkip);
}
MOZ_ASSERT(effectSet == EffectSet::GetEffectSet(aElement, aPseudoType),
"EffectSet should not change while composing style");
return animRule.mServo;
}
@@ -778,17 +778,17 @@ EffectCompositor::ComposeAnimationRule(d
// composite order (priority) override or add or animations with lower
// priority except properties in propertiesToSkip.
const nsCSSPropertyIDSet& propertiesToSkip =
aCascadeLevel == CascadeLevel::Animations
? effects->PropertiesForAnimationsLevel().Inverse()
: effects->PropertiesForAnimationsLevel();
for (KeyframeEffectReadOnly* effect : sortedEffectList) {
effect->GetAnimation()->WillComposeStyle();
- effect->GetAnimation()->ComposeStyle(animRule, propertiesToSkip);
+ effect->GetAnimation()->ComposeStyle(animRule.mGecko, propertiesToSkip);
}
MOZ_ASSERT(effects == EffectSet::GetEffectSet(aElement, aPseudoType),
"EffectSet should not change while composing style");
}
/* static */ void
EffectCompositor::GetOverriddenProperties(nsStyleContext* aStyleContext,
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -644,19 +644,20 @@ KeyframeEffectReadOnly::ComposeStyleRule
aAnimationRule->AddValue(aProperty.mProperty, interpolated);
} else if (valuePosition < 0.5) {
aAnimationRule->AddValue(aProperty.mProperty, servoFromValue);
} else {
aAnimationRule->AddValue(aProperty.mProperty, servoToValue);
}
}
+template<typename ComposeAnimationResult>
void
KeyframeEffectReadOnly::ComposeStyle(
- AnimationRule& aStyleRule,
+ ComposeAnimationResult&& aComposeResult,
const nsCSSPropertyIDSet& aPropertiesToSkip)
{
MOZ_DIAGNOSTIC_ASSERT(!mIsComposingStyle,
"Should not be called recursively");
if (mIsComposingStyle) {
return;
}
@@ -666,18 +667,16 @@ KeyframeEffectReadOnly::ComposeStyle(
ComputedTiming computedTiming = GetComputedTiming();
// If the progress is null, we don't have fill data for the current
// time so we shouldn't animate.
if (computedTiming.mProgress.IsNull()) {
return;
}
- bool isServoBackend = mDocument->IsStyledByServo();
-
for (size_t propIdx = 0, propEnd = mProperties.Length();
propIdx != propEnd; ++propIdx)
{
const AnimationProperty& prop = mProperties[propIdx];
MOZ_ASSERT(prop.mSegments[0].mFromKey == 0.0, "incorrect first from key");
MOZ_ASSERT(prop.mSegments[prop.mSegments.Length() - 1].mToKey == 1.0,
"incorrect last to key");
@@ -701,27 +700,20 @@ KeyframeEffectReadOnly::ComposeStyle(
MOZ_ASSERT(segment->mFromKey == (segment-1)->mToKey, "incorrect keys");
}
MOZ_ASSERT(segment->mFromKey <= segment->mToKey, "incorrect keys");
MOZ_ASSERT(segment >= prop.mSegments.Elements() &&
size_t(segment - prop.mSegments.Elements()) <
prop.mSegments.Length(),
"out of array bounds");
- if (isServoBackend) {
- ComposeStyleRule(aStyleRule.mServo,
- prop,
- *segment,
- computedTiming);
- } else {
- ComposeStyleRule(aStyleRule.mGecko,
- prop,
- *segment,
- computedTiming);
- }
+ ComposeStyleRule(Forward<ComposeAnimationResult>(aComposeResult),
+ prop,
+ *segment,
+ computedTiming);
}
}
bool
KeyframeEffectReadOnly::IsRunningOnCompositor() const
{
// We consider animation is running on compositor if there is at least
// one property running on compositor.
@@ -1816,10 +1808,22 @@ KeyframeEffectReadOnly::ContainsAnimated
}
}
}
}
return false;
}
+template
+void
+KeyframeEffectReadOnly::ComposeStyle<RefPtr<AnimValuesStyleRule>&>(
+ RefPtr<AnimValuesStyleRule>& aAnimationRule,
+ const nsCSSPropertyIDSet& aPropertiesToSkip);
+
+template
+void
+KeyframeEffectReadOnly::ComposeStyle<RefPtr<ServoAnimationRule>&>(
+ RefPtr<ServoAnimationRule>& aAnimationRule,
+ const nsCSSPropertyIDSet& aPropertiesToSkip);
+
} // namespace dom
} // namespace mozilla
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -250,20 +250,21 @@ public:
void UpdateProperties(const ServoComputedStyleValues& aServoValues);
// Update various bits of state related to running ComposeStyle().
// We need to update this outside ComposeStyle() because we should avoid
// mutating any state in ComposeStyle() since it might be called during
// parallel traversal.
void WillComposeStyle();
- // Updates |aStyleRule| with the animation values produced by this
+ // Updates |aComposeResult| with the animation values produced by this
// AnimationEffect for the current time except any properties contained
// in |aPropertiesToSkip|.
- void ComposeStyle(AnimationRule& aStyleRule,
+ template<typename ComposeAnimationResult>
+ void ComposeStyle(ComposeAnimationResult&& aRestultContainer,
const nsCSSPropertyIDSet& aPropertiesToSkip);
// Composite |aValueToComposite| on |aUnderlyingValue| with
// |aCompositeOperation|.
// Returns |aValueToComposite| if |aCompositeOperation| is Replace.
static StyleAnimationValue CompositeValue(
nsCSSPropertyID aProperty,
const StyleAnimationValue& aValueToComposite,