diff --git a/dom/animation/KeyframeEffectReadOnly.cpp b/dom/animation/KeyframeEffectReadOnly.cpp index 9dc4d735b9fc..d413438d6ed2 100644 --- a/dom/animation/KeyframeEffectReadOnly.cpp +++ b/dom/animation/KeyframeEffectReadOnly.cpp @@ -430,6 +430,12 @@ KeyframeEffectReadOnly::EnsureBaseStylesForCompositor( continue; } + // We only call SetNeedsBaseStyle after calling GetBaseStyle so if + // NeedsBaseStyle is true, the base style should be already filled-in. + if (NeedsBaseStyle(property.mProperty)) { + continue; + } + for (const AnimationPropertySegment& segment : property.mSegments) { if (segment.mFromComposite == dom::CompositeOperation::Replace && segment.mToComposite == dom::CompositeOperation::Replace) { @@ -473,18 +479,15 @@ KeyframeEffectReadOnly::ComposeStyle( // time so we shouldn't animate. if (computedTiming.mProgress.IsNull()) { // If we are not in-effect, this effect might still be sent to the - // compositor and later become in-effect (e.g. if it is in the delay phase). + // compositor and later become in-effect (e.g. if it is in the delay phase, + // or, if it is in the end delay phase but with a negative playback rate). // In that case, we might need the base style in order to perform // additive/accumulative animation on the compositor. - // In case of properties that can be run on the compositor, we need the base - // styles for such properties because those animation will be sent to - // compositor while they are in delay phase so that we can composite this - // animation on the compositor once the animation is out of the delay phase - // on the compositor. - if (computedTiming.mPhase == ComputedTiming::AnimationPhase::Before) { - EnsureBaseStylesForCompositor(aPropertiesToSkip); - } + // Note, however, that we don't actually send animations with a negative + // playback rate in their end delay phase to the compositor at this stage + // (bug 1330498). + EnsureBaseStylesForCompositor(aPropertiesToSkip); return; } @@ -591,6 +594,14 @@ KeyframeEffectReadOnly::ComposeStyle( aStyleRule->AddValue(prop.mProperty, Move(toValue)); } } + + // For properties that can be run on the compositor, we may need to prepare + // base styles to send to the compositor even if the current processing + // segment for properties does not have either an additive or accumulative + // composite mode, and even if the animation is not in-effect. That's because + // the animation may later progress to a segment which has an additive or + // accumulative composite on the compositor mode. + EnsureBaseStylesForCompositor(aPropertiesToSkip); } bool