зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322291 - Part 2: Make sure that the base style is set even if additive or accumulates animations are in the delay phase. r=birtles
Before this patch we skipped KeyframeEffectReadOnly::ComposeStyle() for animations that are not in effect. After this patch we call KeyframeEffectReadOnly::ComposeStyle() even if the animation is not in-effect state in order to prepare the base style for properties that can be run on the compositor because the in-effect animation will be sent to the compositor and might be composed onto the base style on the compositor after the animation gets out of its delay phase. MozReview-Commit-ID: FuAZv4jqVMJ --HG-- extra : rebase_source : 9ef2f078e5ee18735fb8cd3086f20774fe8b1fd0
This commit is contained in:
Родитель
bb044df0ec
Коммит
603fea3c36
|
@ -923,10 +923,6 @@ Animation::ComposeStyle(RefPtr<AnimValuesStyleRule>& aStyleRule,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!IsInEffect()) {
|
||||
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
|
||||
// GetCurrentTime. These are:
|
||||
|
|
|
@ -387,6 +387,49 @@ KeyframeEffectReadOnly::CompositeValue(
|
|||
aCompositeOperation);
|
||||
}
|
||||
|
||||
void
|
||||
KeyframeEffectReadOnly::EnsureBaseStylesForCompositor(
|
||||
const nsCSSPropertyIDSet& aPropertiesToSkip)
|
||||
{
|
||||
if (!mTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<nsStyleContext> styleContext;
|
||||
|
||||
for (const AnimationProperty& property : mProperties) {
|
||||
if (!nsCSSProps::PropHasFlags(property.mProperty,
|
||||
CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aPropertiesToSkip.HasProperty(property.mProperty)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const AnimationPropertySegment& segment : property.mSegments) {
|
||||
if (segment.mFromComposite == dom::CompositeOperation::Replace &&
|
||||
segment.mToComposite == dom::CompositeOperation::Replace) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!styleContext) {
|
||||
styleContext = GetTargetStyleContext();
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(styleContext);
|
||||
|
||||
Unused << EffectCompositor::GetBaseStyle(property.mProperty,
|
||||
styleContext,
|
||||
*mTarget->mElement,
|
||||
mTarget->mPseudoType);
|
||||
// Make this property as needing a base style so that we send the (now
|
||||
// cached) base style to the compositor.
|
||||
SetNeedsBaseStyle(property.mProperty);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
KeyframeEffectReadOnly::ComposeStyle(
|
||||
RefPtr<AnimValuesStyleRule>& aStyleRule,
|
||||
|
@ -406,6 +449,19 @@ KeyframeEffectReadOnly::ComposeStyle(
|
|||
// If the progress is null, we don't have fill data for the current
|
||||
// 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).
|
||||
// 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);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -427,6 +427,11 @@ protected:
|
|||
// compositor.
|
||||
void SetNeedsBaseStyle(nsCSSPropertyID aProperty);
|
||||
|
||||
// Ensure the base styles is available for any properties that can be run on
|
||||
// the compositor and which are not includes in |aPropertiesToSkip|.
|
||||
void EnsureBaseStylesForCompositor(
|
||||
const nsCSSPropertyIDSet& aPropertiesToSkip);
|
||||
|
||||
Maybe<OwningAnimationTarget> mTarget;
|
||||
|
||||
KeyframeEffectParams mEffectOptions;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", boom);
|
||||
function boom(){
|
||||
let o1 = (function(){
|
||||
let e=document.createElement("frameset");
|
||||
document.documentElement.appendChild(e);
|
||||
return e;
|
||||
})();
|
||||
let a1 = o1.animate({ "transform": "rotate3d(22,73,26,374grad)" },
|
||||
{ duration: 10, delay: 100 });
|
||||
|
||||
// We need to wait the end of the delay to ensure that the animation is
|
||||
// composited on the compositor, but there is no event for script animation
|
||||
// that fires after the delay phase finished. So we wait for finished promise
|
||||
// instead.
|
||||
a1.finished.then(function() {
|
||||
document.documentElement.className = "";
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -13,5 +13,6 @@ pref(dom.animations-api.core.enabled,true) load 1277272-1.html
|
|||
pref(dom.animations-api.core.enabled,true) load 1290535-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1304886-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1322382-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1322291-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1323114-1.html
|
||||
pref(dom.animations-api.core.enabled,true) load 1323114-2.html
|
||||
|
|
|
@ -471,6 +471,25 @@ promise_test(t => {
|
|||
'composed onto a underlying animation with fill:forwards during positive ' +
|
||||
'endDelay');
|
||||
|
||||
promise_test(t => {
|
||||
useTestRefreshMode(t);
|
||||
|
||||
var div = addDiv(t, { style: 'transform: translateX(100px)' });
|
||||
div.animate({ transform: 'translateX(200px)' },
|
||||
{ duration: 100 * MS_PER_SEC, delay: 50 * MS_PER_SEC });
|
||||
|
||||
return waitForPaintsFlushed().then(() => {
|
||||
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(100 * MS_PER_SEC);
|
||||
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_matrix_equals(transform, 'matrix(1, 0, 0, 1, 150, 0)',
|
||||
'Transform value for animation with positive delay should be composed ' +
|
||||
'onto the base style');
|
||||
});
|
||||
}, 'Transform value for animation with no keyframe at offset 0 and with ' +
|
||||
'positive delay');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
|
|
Загрузка…
Ссылка в новой задаче