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 @@
#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/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_property_equality.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
......@@ -273,31 +274,40 @@ void CSSAnimations::CalculateCompositorAnimationUpdate(
bool transform_zoom_changed =
old_style->HasCurrentTransformAnimation() &&
old_style->EffectiveZoom() != style.EffectiveZoom();
for (auto& entry : element_animations->Animations()) {
Animation& animation = *entry.key;
const auto& snapshot = [&](AnimationEffect* effect) {
const KeyframeEffectModelBase* keyframe_effect =
GetKeyframeEffectModelBase(animation.effect());
GetKeyframeEffectModelBase(effect);
if (!keyframe_effect)
continue;
return false;
if ((transform_zoom_changed || was_viewport_resized) &&
(keyframe_effect->Affects(PropertyHandle(GetCSSPropertyTransform())) ||
keyframe_effect->Affects(PropertyHandle(GetCSSPropertyTranslate()))))
keyframe_effect->InvalidateCompositorKeyframesSnapshot();
bool update_compositor_keyframes = false;
if (keyframe_effect->SnapshotAllCompositorKeyframesIfNecessary(
element, style, parent_style)) {
update_compositor_keyframes = true;
return true;
} else if (keyframe_effect->HasSyntheticKeyframes() &&
keyframe_effect->SnapshotNeutralCompositorKeyframes(
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);
}
for (auto& entry : element_animations->GetWorkletAnimations()) {
WorkletAnimationBase& animation = *entry;
if (snapshot(animation.GetEffect()))
animation.InvalidateCompositingState();
}
}
void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
......
......@@ -26,6 +26,7 @@ class CORE_EXPORT WorkletAnimationBase : public ScriptWrappable {
// Updates the animation on the compositor side to reflect the main thread
// state.
virtual void UpdateCompositingState() = 0;
virtual void InvalidateCompositingState() = 0;
virtual Document* GetDocument() const = 0;
virtual KeyframeEffect* GetEffect() const = 0;
......
......@@ -380,8 +380,7 @@ void WorkletAnimation::UpdateIfNecessary() {
}
void WorkletAnimation::EffectInvalidated() {
effect_needs_restart_ = true;
document_->GetWorkletAnimationController().InvalidateAnimation(*this);
InvalidateCompositingState();
}
void WorkletAnimation::Update(TimingUpdateReason reason) {
......@@ -442,6 +441,11 @@ void WorkletAnimation::UpdateCompositingState() {
}
}
void WorkletAnimation::InvalidateCompositingState() {
effect_needs_restart_ = true;
document_->GetWorkletAnimationController().InvalidateAnimation(*this);
}
void WorkletAnimation::StartOnMain() {
running_on_main_thread_ = true;
SetStartTimeToNow();
......
......@@ -88,6 +88,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
// WorkletAnimationBase implementation.
void Update(TimingUpdateReason) override;
void UpdateCompositingState() override;
void InvalidateCompositingState() override;
// CompositorAnimationClient implementation.
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