Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit 1e63f43

Browse files
REGRESSION (r268483): Map jumps around while zooming on windy.com, strava.com
https://bugs.webkit.org/show_bug.cgi?id=217987 <rdar://problem/70418548> Reviewed by Simon Fraser. Source/WebCore: When several animations targetting the same property and the same layer are overlapping, we used to always override the previous animations. With r268483 we started maintaining all active animations and let them run, potentially with additivity if the animation could be broken into several animations each targeting a given transform operation. On top of that, with r268615 and the support for accelerated animation of individual CSS transform properties (translate, scale and rotate), all transform-related animations were made additive. This meant that we would always run active animations targeting "transform" in a way where they would be additive rather than being replaced. Any animation targeting "transform" will yield one or several accelerated animations, and the first of this animation set will always have a 0 index. So now, when we compile a list of transform animations in GraphicsLayerCA::updateAnimations(), we reset that list any time we encounted an animation with a 0 index, ensuring only the top-most transform animation is applied. We also fix an issue where we didn't account for the possibility that a single KeyframeEffect could yield several transform animations with the same name in pauseAnimation() and removeAnimation(). We now pause or remove all animations with the provided name. Test: webanimations/accelerated-overlapping-transform-animations.html * platform/graphics/ca/GraphicsLayerCA.cpp: (WebCore::GraphicsLayerCA::pauseAnimation): (WebCore::GraphicsLayerCA::removeAnimation): (WebCore::GraphicsLayerCA::updateAnimations): LayoutTests: Add a new test that checks that only the last of two overlapping "transform" animations is applied. * platform/mac-wk1/TestExpectations: * webanimations/accelerated-overlapping-transform-animations-expected.html: Added. * webanimations/accelerated-overlapping-transform-animations.html: Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@268771 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 5e080aa commit 1e63f43

File tree

6 files changed

+133
-21
lines changed

6 files changed

+133
-21
lines changed

LayoutTests/ChangeLog

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2020-10-20 Antoine Quint <[email protected]>
2+
3+
REGRESSION (r268483): Map jumps around while zooming on windy.com, strava.com
4+
https://bugs.webkit.org/show_bug.cgi?id=217987
5+
<rdar://problem/70418548>
6+
7+
Reviewed by Simon Fraser.
8+
9+
Add a new test that checks that only the last of two overlapping "transform" animations is applied.
10+
11+
* platform/mac-wk1/TestExpectations:
12+
* webanimations/accelerated-overlapping-transform-animations-expected.html: Added.
13+
* webanimations/accelerated-overlapping-transform-animations.html: Added.
14+
115
2020-10-20 Truitt Savell <[email protected]>
216

317
imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-output-channel-count.https.html is a flaky failure

LayoutTests/platform/mac-wk1/TestExpectations

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,3 +1199,4 @@ webkit.org/b/217761 [ Mojave+ Debug ] webgl/2.0.0/conformance/extensions/webgl-c
11991199

12001200
webkit.org/b/217934 inspector/debugger/breakpoint-resolve-when-script-added.html [ Skip ]
12011201

1202+
webkit.org/b/217997 webanimations/accelerated-overlapping-transform-animations.html [ Pass Failure ]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<style>
2+
3+
#target {
4+
position: absolute;
5+
top: 0;
6+
left: 0;
7+
width: 100px;
8+
height: 100px;
9+
background-color: black;
10+
transform: translateX(200px);
11+
}
12+
13+
</style>
14+
<div id="target"></div>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<style>
2+
3+
#target {
4+
position: absolute;
5+
top: 0;
6+
left: 0;
7+
width: 100px;
8+
height: 100px;
9+
background-color: black;
10+
}
11+
12+
</style>
13+
<div id="target"></div>
14+
<script src="../resources/ui-helper.js"></script>
15+
<script>
16+
17+
(async () => {
18+
if (window.testRunner)
19+
testRunner.waitUntilDone();
20+
21+
const target = document.getElementById("target");
22+
23+
// Make the animations last a whole minute so they don't end while the test is running.
24+
const duration = 60 * 1000;
25+
26+
// Start a first stationary "transform" animation.
27+
const firstAnimation = target.animate({ transform: ["translateX(100px)", "translateX(100px)"] }, duration);
28+
29+
// Wait until this first animation has been applied.
30+
await firstAnimation.ready;
31+
await UIHelper.ensureStablePresentationUpdate();
32+
33+
// Now start a second stationary "transform" animation, which should replace the previous animation.
34+
const secondAnimation = target.animate({ transform: ["translateX(200px)", "translateX(200px)"] }, duration);
35+
36+
// Wait until this second animation has been applied.
37+
await secondAnimation.ready;
38+
await UIHelper.ensureStablePresentationUpdate();
39+
40+
if (window.testRunner)
41+
testRunner.notifyDone();
42+
})();
43+
44+
</script>

Source/WebCore/ChangeLog

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
1+
2020-10-20 Antoine Quint <[email protected]>
2+
3+
REGRESSION (r268483): Map jumps around while zooming on windy.com, strava.com
4+
https://bugs.webkit.org/show_bug.cgi?id=217987
5+
<rdar://problem/70418548>
6+
7+
Reviewed by Simon Fraser.
8+
9+
When several animations targetting the same property and the same layer are overlapping, we used to
10+
always override the previous animations. With r268483 we started maintaining all active animations
11+
and let them run, potentially with additivity if the animation could be broken into several animations
12+
each targeting a given transform operation.
13+
14+
On top of that, with r268615 and the support for accelerated animation of individual CSS transform
15+
properties (translate, scale and rotate), all transform-related animations were made additive.
16+
17+
This meant that we would always run active animations targeting "transform" in a way where they would be
18+
additive rather than being replaced.
19+
20+
Any animation targeting "transform" will yield one or several accelerated animations, and the first of this
21+
animation set will always have a 0 index. So now, when we compile a list of transform animations in
22+
GraphicsLayerCA::updateAnimations(), we reset that list any time we encounted an animation with a 0 index,
23+
ensuring only the top-most transform animation is applied.
24+
25+
We also fix an issue where we didn't account for the possibility that a single KeyframeEffect could yield
26+
several transform animations with the same name in pauseAnimation() and removeAnimation(). We now pause or
27+
remove all animations with the provided name.
28+
29+
Test: webanimations/accelerated-overlapping-transform-animations.html
30+
31+
* platform/graphics/ca/GraphicsLayerCA.cpp:
32+
(WebCore::GraphicsLayerCA::pauseAnimation):
33+
(WebCore::GraphicsLayerCA::removeAnimation):
34+
(WebCore::GraphicsLayerCA::updateAnimations):
35+
136
2020-10-20 Jer Noble <[email protected]>
237

338
[media-session] Basic support for MediaSession.setPositionState() and MediaSession.setActionHandler()

Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,34 +1079,30 @@ void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOff
10791079
{
10801080
LOG_WITH_STREAM(Animations, stream << "GraphicsLayerCA " << this << " id " << primaryLayerID() << " pauseAnimation " << animationName << " (is running " << animationIsRunning(animationName) << ")");
10811081

1082-
auto index = m_animations.findMatching([&](LayerPropertyAnimation animation) {
1083-
return animation.m_name == animationName && !animation.m_pendingRemoval;
1084-
});
1085-
1086-
if (index == notFound)
1087-
return;
1088-
1089-
auto& animation = m_animations[index];
1090-
animation.m_playState = PlayState::PausePending;
1091-
animation.m_timeOffset = Seconds { timeOffset };
1082+
for (auto& animation : m_animations) {
1083+
// There may be several animations with the same name in the case of transform animations
1084+
// animating multiple components as individual animations.
1085+
if (animation.m_name == animationName && !animation.m_pendingRemoval) {
1086+
animation.m_playState = PlayState::PausePending;
1087+
animation.m_timeOffset = Seconds { timeOffset };
10921088

1093-
noteLayerPropertyChanged(AnimationChanged);
1089+
noteLayerPropertyChanged(AnimationChanged);
1090+
}
1091+
}
10941092
}
10951093

10961094
void GraphicsLayerCA::removeAnimation(const String& animationName)
10971095
{
10981096
LOG_WITH_STREAM(Animations, stream << "GraphicsLayerCA " << this << " id " << primaryLayerID() << " removeAnimation " << animationName << " (is running " << animationIsRunning(animationName) << ")");
10991097

1100-
auto index = m_animations.findMatching([&](LayerPropertyAnimation animation) {
1101-
return animation.m_name == animationName && !animation.m_pendingRemoval;
1102-
});
1103-
1104-
if (index == notFound)
1105-
return;
1106-
1107-
m_animations[index].m_pendingRemoval = true;
1108-
1109-
noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);
1098+
for (auto& animation : m_animations) {
1099+
// There may be several animations with the same name in the case of transform animations
1100+
// animating multiple components as individual animations.
1101+
if (animation.m_name == animationName && !animation.m_pendingRemoval) {
1102+
animation.m_pendingRemoval = true;
1103+
noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);
1104+
}
1105+
}
11101106
}
11111107

11121108
void GraphicsLayerCA::platformCALayerAnimationStarted(const String& animationKey, MonotonicTime startTime)
@@ -2960,6 +2956,14 @@ void GraphicsLayerCA::updateAnimations()
29602956
rotateAnimation = &animation;
29612957
break;
29622958
case AnimatedPropertyTransform:
2959+
// In the case of animations targeting the "transform" CSS property, there may be several
2960+
// animations created for a single KeyframeEffect, one for each transform component. In that
2961+
// case the animation index starts at 0 and increases for each component. If we encounter an
2962+
// index of 0 this means this animation establishes a new group of animation belonging to a
2963+
// single KeyframeEffect. As such, since the top-most KeyframeEffect replaces the previous
2964+
// ones, we can remove all the previously-added "transform" animations.
2965+
if (!animation.m_index)
2966+
transformAnimations.clear();
29632967
transformAnimations.append(&animation);
29642968
break;
29652969
case AnimatedPropertyOpacity:

0 commit comments

Comments
 (0)