Commit dec72e86 authored by Majid Valipour's avatar Majid Valipour Committed by Commit Bot

[animation-worklet] Transfrom related worklet animations should respond to zoom

Worklet animation compositing state should be updated when a zoom or viewport
resize changes css pixel to dip ratio.

The fix is to simply match what we already do for regular animations for worklet
animations.

TEST=virtual/threaded/fast/animationworklet/worklet-animation-responsive-to-zoom.html

Bug: 879107
Change-Id: I0b74bd8297e83b18afd087247f09339aedcc618b
Reviewed-on: https://chromium-review.googlesource.com/1237133Reviewed-by: default avatarStephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarMajid Valipour <majidvp@chromium.org>
Commit-Queue: Majid Valipour <majidvp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593171}
parent e117baf4
<!DOCTYPE html>
<style>
.box {
width: 100px;
height: 100px;
background-color: #00ff00;
transform: translateX(100px);
}
</style>
<div id="target" class="box"></div>
<script>
internals.setZoomFactor(2);
</script>
<!DOCTYPE html>
<style>
.box {
width: 100px;
height: 100px;
background-color: #00ff00;
}
</style>
<div id="target" class="box"></div>
<script id="visual_update" type="text/worklet">
registerAnimator("simple_animator", class {
animate(currentTime, effect) {
effect.localTime = 500;
}
});
</script>
<script src="resources/animation-worklet-tests.js"></script>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
runInAnimationWorklet(
document.getElementById('visual_update').textContent
).then(()=>{
const effect = new KeyframeEffect(
document.getElementById('target'),
[{ transform: 'translateX(0)' }, { transform: 'translateX(200px)'}],
{duration: 1000});
const animation = new WorkletAnimation('simple_animator', effect);
animation.play();
if (window.testRunner) {
waitTwoAnimationFrames(_ => {
internals.setZoomFactor(2);
waitTwoAnimationFrames(_ => {
testRunner.notifyDone();
});
});
}
});
</script>
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h" #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
#include "third_party/blink/renderer/core/animation/transition_interpolation.h" #include "third_party/blink/renderer/core/animation/transition_interpolation.h"
#include "third_party/blink/renderer/core/animation/worklet_animation_base.h"
#include "third_party/blink/renderer/core/css/css_keyframe_rule.h" #include "third_party/blink/renderer/core/css/css_keyframe_rule.h"
#include "third_party/blink/renderer/core/css/css_property_equality.h" #include "third_party/blink/renderer/core/css/css_property_equality.h"
#include "third_party/blink/renderer/core/css/css_value_list.h" #include "third_party/blink/renderer/core/css/css_value_list.h"
...@@ -273,31 +274,40 @@ void CSSAnimations::CalculateCompositorAnimationUpdate( ...@@ -273,31 +274,40 @@ void CSSAnimations::CalculateCompositorAnimationUpdate(
bool transform_zoom_changed = bool transform_zoom_changed =
old_style->HasCurrentTransformAnimation() && old_style->HasCurrentTransformAnimation() &&
old_style->EffectiveZoom() != style.EffectiveZoom(); old_style->EffectiveZoom() != style.EffectiveZoom();
for (auto& entry : element_animations->Animations()) {
Animation& animation = *entry.key; const auto& snapshot = [&](AnimationEffect* effect) {
const KeyframeEffectModelBase* keyframe_effect = const KeyframeEffectModelBase* keyframe_effect =
GetKeyframeEffectModelBase(animation.effect()); GetKeyframeEffectModelBase(effect);
if (!keyframe_effect) if (!keyframe_effect)
continue; return false;
if ((transform_zoom_changed || was_viewport_resized) && if ((transform_zoom_changed || was_viewport_resized) &&
(keyframe_effect->Affects(PropertyHandle(GetCSSPropertyTransform())) || (keyframe_effect->Affects(PropertyHandle(GetCSSPropertyTransform())) ||
keyframe_effect->Affects(PropertyHandle(GetCSSPropertyTranslate())))) keyframe_effect->Affects(PropertyHandle(GetCSSPropertyTranslate()))))
keyframe_effect->InvalidateCompositorKeyframesSnapshot(); keyframe_effect->InvalidateCompositorKeyframesSnapshot();
bool update_compositor_keyframes = false;
if (keyframe_effect->SnapshotAllCompositorKeyframesIfNecessary( if (keyframe_effect->SnapshotAllCompositorKeyframesIfNecessary(
element, style, parent_style)) { element, style, parent_style)) {
update_compositor_keyframes = true; return true;
} else if (keyframe_effect->HasSyntheticKeyframes() && } else if (keyframe_effect->HasSyntheticKeyframes() &&
keyframe_effect->SnapshotNeutralCompositorKeyframes( keyframe_effect->SnapshotNeutralCompositorKeyframes(
element, *old_style, style, parent_style)) { element, *old_style, style, parent_style)) {
update_compositor_keyframes = true; return true;
} }
return false;
};
if (update_compositor_keyframes) for (auto& entry : element_animations->Animations()) {
Animation& animation = *entry.key;
if (snapshot(animation.effect()))
update.UpdateCompositorKeyframes(&animation); update.UpdateCompositorKeyframes(&animation);
} }
for (auto& entry : element_animations->GetWorkletAnimations()) {
WorkletAnimationBase& animation = *entry;
if (snapshot(animation.GetEffect()))
animation.InvalidateCompositingState();
}
} }
void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
......
...@@ -26,6 +26,7 @@ class CORE_EXPORT WorkletAnimationBase : public ScriptWrappable { ...@@ -26,6 +26,7 @@ class CORE_EXPORT WorkletAnimationBase : public ScriptWrappable {
// Updates the animation on the compositor side to reflect the main thread // Updates the animation on the compositor side to reflect the main thread
// state. // state.
virtual void UpdateCompositingState() = 0; virtual void UpdateCompositingState() = 0;
virtual void InvalidateCompositingState() = 0;
virtual Document* GetDocument() const = 0; virtual Document* GetDocument() const = 0;
virtual KeyframeEffect* GetEffect() const = 0; virtual KeyframeEffect* GetEffect() const = 0;
......
...@@ -380,8 +380,7 @@ void WorkletAnimation::UpdateIfNecessary() { ...@@ -380,8 +380,7 @@ void WorkletAnimation::UpdateIfNecessary() {
} }
void WorkletAnimation::EffectInvalidated() { void WorkletAnimation::EffectInvalidated() {
effect_needs_restart_ = true; InvalidateCompositingState();
document_->GetWorkletAnimationController().InvalidateAnimation(*this);
} }
void WorkletAnimation::Update(TimingUpdateReason reason) { void WorkletAnimation::Update(TimingUpdateReason reason) {
...@@ -442,6 +441,11 @@ void WorkletAnimation::UpdateCompositingState() { ...@@ -442,6 +441,11 @@ void WorkletAnimation::UpdateCompositingState() {
} }
} }
void WorkletAnimation::InvalidateCompositingState() {
effect_needs_restart_ = true;
document_->GetWorkletAnimationController().InvalidateAnimation(*this);
}
void WorkletAnimation::StartOnMain() { void WorkletAnimation::StartOnMain() {
running_on_main_thread_ = true; running_on_main_thread_ = true;
SetStartTimeToNow(); SetStartTimeToNow();
......
...@@ -88,6 +88,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase, ...@@ -88,6 +88,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
// WorkletAnimationBase implementation. // WorkletAnimationBase implementation.
void Update(TimingUpdateReason) override; void Update(TimingUpdateReason) override;
void UpdateCompositingState() override; void UpdateCompositingState() override;
void InvalidateCompositingState() override;
// CompositorAnimationClient implementation. // CompositorAnimationClient implementation.
CompositorAnimation* GetCompositorAnimation() const override { CompositorAnimation* GetCompositorAnimation() const override {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment