Bug 1656419 - Check whether the given animation and the animation stored in mPartialPrerenderedAnimations are in the same EffectSet instead of just comparing the animation instances. r=boris
Differential Revision: https://phabricator.services.mozilla.com/D85535
This commit is contained in:
@@ -124,6 +124,16 @@ EffectSet* EffectSet::GetEffectSetForStyleFrame(const nsIFrame* aStyleFrame) {
|
|||||||
return GetEffectSet(target->mElement, target->mPseudoType);
|
return GetEffectSet(target->mElement, target->mPseudoType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
EffectSet* EffectSet::GetEffectSetForEffect(const KeyframeEffect* aEffect) {
|
||||||
|
NonOwningAnimationTarget target = aEffect->GetAnimationTarget();
|
||||||
|
if (!target) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EffectSet::GetEffectSet(target.mElement, target.mPseudoType);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
void EffectSet::DestroyEffectSet(dom::Element* aElement,
|
void EffectSet::DestroyEffectSet(dom::Element* aElement,
|
||||||
PseudoStyleType aPseudoType) {
|
PseudoStyleType aPseudoType) {
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ class EffectSet {
|
|||||||
// to use this.
|
// to use this.
|
||||||
static EffectSet* GetEffectSetForStyleFrame(const nsIFrame* aStyleFrame);
|
static EffectSet* GetEffectSetForStyleFrame(const nsIFrame* aStyleFrame);
|
||||||
|
|
||||||
|
static EffectSet* GetEffectSetForEffect(const dom::KeyframeEffect* aEffect);
|
||||||
|
|
||||||
static void DestroyEffectSet(dom::Element* aElement,
|
static void DestroyEffectSet(dom::Element* aElement,
|
||||||
PseudoStyleType aPseudoType);
|
PseudoStyleType aPseudoType);
|
||||||
|
|
||||||
|
|||||||
@@ -904,8 +904,12 @@ void KeyframeEffect::UpdateTarget(Element* aElement,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mTarget) {
|
if (mTarget) {
|
||||||
UnregisterTarget();
|
// Call ResetIsRunningOnCompositor() prior to UnregisterTarget() since
|
||||||
|
// ResetIsRunningOnCompositor() might try to get the EffectSet associated
|
||||||
|
// with this keyframe effect to remove partial pre-render animation from
|
||||||
|
// the layer manager.
|
||||||
ResetIsRunningOnCompositor();
|
ResetIsRunningOnCompositor();
|
||||||
|
UnregisterTarget();
|
||||||
|
|
||||||
RequestRestyle(EffectCompositor::RestyleType::Layer);
|
RequestRestyle(EffectCompositor::RestyleType::Layer);
|
||||||
|
|
||||||
|
|||||||
23
dom/animation/test/crashtests/1656419.html
Normal file
23
dom/animation/test/crashtests/1656419.html
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<style>
|
||||||
|
#target {
|
||||||
|
width: 200vw;
|
||||||
|
height: 200vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="target"></div>
|
||||||
|
<script>
|
||||||
|
const animA = target.animate(
|
||||||
|
{ transform: 'translateX(100px)' },
|
||||||
|
{ duration: 50 }
|
||||||
|
);
|
||||||
|
const animB = target.animate(
|
||||||
|
{ transform: 'translateX(100px)', composite: 'add' },
|
||||||
|
{ duration: 100 }
|
||||||
|
);
|
||||||
|
animB.finished.then(() => {
|
||||||
|
document.documentElement.classList.remove("reftest-wait");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
@@ -53,3 +53,4 @@ pref(dom.animations-api.core.enabled,true) load 1612891-2.html
|
|||||||
pref(dom.animations-api.core.enabled,true) load 1612891-3.html
|
pref(dom.animations-api.core.enabled,true) load 1612891-3.html
|
||||||
pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.getAnimations.enabled,true) load 1633442.html
|
pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.getAnimations.enabled,true) load 1633442.html
|
||||||
pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.implicit-keyframes.enabled,true) load 1633486.html
|
pref(dom.animations-api.core.enabled,true) pref(dom.animations-api.implicit-keyframes.enabled,true) load 1633486.html
|
||||||
|
pref(layout.animation.prerender.partial,true) load 1656419.html
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#include "mozilla/Telemetry.h" // for Accumulate
|
#include "mozilla/Telemetry.h" // for Accumulate
|
||||||
#include "mozilla/ToString.h"
|
#include "mozilla/ToString.h"
|
||||||
#include "mozilla/dom/Animation.h" // for dom::Animation
|
#include "mozilla/dom/Animation.h" // for dom::Animation
|
||||||
|
#include "mozilla/dom/KeyframeEffect.h" // for dom::Animation
|
||||||
|
#include "mozilla/EffectSet.h" // for dom::Animation
|
||||||
#include "mozilla/gfx/2D.h" // for DrawTarget
|
#include "mozilla/gfx/2D.h" // for DrawTarget
|
||||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||||
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
||||||
@@ -180,8 +182,15 @@ void LayerManager::RemovePartialPrerenderedAnimation(
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
RefPtr<dom::Animation> animation;
|
RefPtr<dom::Animation> animation;
|
||||||
if (mPartialPrerenderedAnimations.Remove(aCompositorAnimationId,
|
if (mPartialPrerenderedAnimations.Remove(aCompositorAnimationId,
|
||||||
getter_AddRefs(animation))) {
|
getter_AddRefs(animation)) &&
|
||||||
MOZ_ASSERT(aAnimation == animation.get());
|
// It may be possible that either animation's effect has already been
|
||||||
|
// nulled out via Animation::SetEffect() so ignore such cases.
|
||||||
|
aAnimation->GetEffect() && aAnimation->GetEffect()->AsKeyframeEffect() &&
|
||||||
|
animation->GetEffect() && animation->GetEffect()->AsKeyframeEffect()) {
|
||||||
|
MOZ_ASSERT(EffectSet::GetEffectSetForEffect(
|
||||||
|
aAnimation->GetEffect()->AsKeyframeEffect()) ==
|
||||||
|
EffectSet::GetEffectSetForEffect(
|
||||||
|
animation->GetEffect()->AsKeyframeEffect()));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
mPartialPrerenderedAnimations.Remove(aCompositorAnimationId);
|
mPartialPrerenderedAnimations.Remove(aCompositorAnimationId);
|
||||||
|
|||||||
Reference in New Issue
Block a user