1 /*
2  * Copyright (c) 2013, Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "third_party/blink/renderer/core/animation/animation.h"
32 
33 #include <memory>
34 
35 #include "base/bits.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
39 #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
40 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
41 #include "third_party/blink/renderer/core/animation/animation_clock.h"
42 #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h"
43 #include "third_party/blink/renderer/core/animation/css_number_interpolation_type.h"
44 #include "third_party/blink/renderer/core/animation/document_timeline.h"
45 #include "third_party/blink/renderer/core/animation/element_animations.h"
46 #include "third_party/blink/renderer/core/animation/keyframe_effect.h"
47 #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
48 #include "third_party/blink/renderer/core/animation/pending_animations.h"
49 #include "third_party/blink/renderer/core/animation/scroll_timeline.h"
50 #include "third_party/blink/renderer/core/animation/timing.h"
51 #include "third_party/blink/renderer/core/dom/document.h"
52 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
53 #include "third_party/blink/renderer/core/dom/events/event.h"
54 #include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
55 #include "third_party/blink/renderer/core/dom/qualified_name.h"
56 #include "third_party/blink/renderer/core/paint/paint_layer.h"
57 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
58 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
59 #include "third_party/blink/renderer/platform/animation/compositor_animation.h"
60 #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h"
61 #include "third_party/blink/renderer/platform/animation/compositor_target_property.h"
62 #include "third_party/blink/renderer/platform/bindings/microtask.h"
63 #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
64 #include "third_party/blink/renderer/platform/heap/heap.h"
65 #include "third_party/blink/renderer/platform/testing/histogram_tester.h"
66 #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
67 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
68 
69 namespace blink {
70 
71 namespace {
72 
MillisecondsToSeconds(double milliseconds)73 double MillisecondsToSeconds(double milliseconds) {
74   return milliseconds / 1000;
75 }
76 
77 }  // namespace
78 
ExpectRelativeErrorWithinEpsilon(double expected,double observed)79 void ExpectRelativeErrorWithinEpsilon(double expected, double observed) {
80   EXPECT_NEAR(1.0, observed / expected, std::numeric_limits<double>::epsilon());
81 }
82 
83 class AnimationAnimationTestNoCompositing : public RenderingTest {
84  public:
AnimationAnimationTestNoCompositing()85   AnimationAnimationTestNoCompositing()
86       : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
87 
SetUp()88   void SetUp() override {
89     last_frame_time = 0;
90     RenderingTest::SetUp();
91     SetUpWithoutStartingTimeline();
92     StartTimeline();
93   }
94 
SetUpWithoutStartingTimeline()95   void SetUpWithoutStartingTimeline() {
96     GetDocument().GetAnimationClock().ResetTimeForTesting();
97     timeline = GetDocument().Timeline();
98     timeline->ResetForTesting();
99     animation = timeline->Play(nullptr);
100     animation->setStartTime(0);
101     animation->setEffect(MakeAnimation());
102   }
103 
StartTimeline()104   void StartTimeline() { SimulateFrame(0); }
105 
MakeSimpleEffectModel()106   KeyframeEffectModelBase* MakeSimpleEffectModel() {
107     PropertyHandle PropertyHandleOpacity(GetCSSPropertyOpacity());
108     TransitionKeyframe* start_keyframe =
109         MakeGarbageCollected<TransitionKeyframe>(PropertyHandleOpacity);
110     start_keyframe->SetValue(std::make_unique<TypedInterpolationValue>(
111         CSSNumberInterpolationType(PropertyHandleOpacity),
112         std::make_unique<InterpolableNumber>(1.0)));
113     start_keyframe->SetOffset(0.0);
114     // Egregious hack: Sideload the compositor value.
115     // This is usually set in a part of the rendering process SimulateFrame
116     // doesn't call.
117     start_keyframe->SetCompositorValue(
118         MakeGarbageCollected<CompositorKeyframeDouble>(1.0));
119     TransitionKeyframe* end_keyframe =
120         MakeGarbageCollected<TransitionKeyframe>(PropertyHandleOpacity);
121     end_keyframe->SetValue(std::make_unique<TypedInterpolationValue>(
122         CSSNumberInterpolationType(PropertyHandleOpacity),
123         std::make_unique<InterpolableNumber>(0.0)));
124     end_keyframe->SetOffset(1.0);
125     // Egregious hack: Sideload the compositor value.
126     end_keyframe->SetCompositorValue(
127         MakeGarbageCollected<CompositorKeyframeDouble>(0.0));
128 
129     TransitionKeyframeVector keyframes;
130     keyframes.push_back(start_keyframe);
131     keyframes.push_back(end_keyframe);
132 
133     return MakeGarbageCollected<TransitionKeyframeEffectModel>(keyframes);
134   }
135 
ResetWithCompositedAnimation()136   void ResetWithCompositedAnimation() {
137     // Get rid of the default animation.
138     animation->cancel();
139 
140     RunDocumentLifecycle();
141 
142     SetBodyInnerHTML("<div id='target'></div>");
143 
144     MakeCompositedAnimation();
145   }
146 
MakeCompositedAnimation()147   void MakeCompositedAnimation() {
148     // Create a compositable animation; in this case opacity from 1 to 0.
149     Timing timing;
150     timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
151 
152     Persistent<StringKeyframe> start_keyframe =
153         MakeGarbageCollected<StringKeyframe>();
154     start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
155                                         SecureContextMode::kInsecureContext,
156                                         nullptr);
157     Persistent<StringKeyframe> end_keyframe =
158         MakeGarbageCollected<StringKeyframe>();
159     end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
160                                       SecureContextMode::kInsecureContext,
161                                       nullptr);
162 
163     StringKeyframeVector keyframes;
164     keyframes.push_back(start_keyframe);
165     keyframes.push_back(end_keyframe);
166 
167     Element* element = GetElementById("target");
168     auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
169     animation = timeline->Play(
170         MakeGarbageCollected<KeyframeEffect>(element, model, timing));
171 
172     // After creating the animation we need to clean the lifecycle so that the
173     // animation can be pushed to the compositor.
174     UpdateAllLifecyclePhasesForTest();
175 
176     GetDocument().GetAnimationClock().UpdateTime(base::TimeTicks());
177     GetDocument().GetPendingAnimations().Update(nullptr, true);
178   }
179 
MakeEmptyEffectModel()180   KeyframeEffectModelBase* MakeEmptyEffectModel() {
181     return MakeGarbageCollected<StringKeyframeEffectModel>(
182         StringKeyframeVector());
183   }
184 
MakeAnimation(double duration=30,Timing::FillMode fill_mode=Timing::FillMode::AUTO)185   KeyframeEffect* MakeAnimation(
186       double duration = 30,
187       Timing::FillMode fill_mode = Timing::FillMode::AUTO) {
188     Timing timing;
189     timing.iteration_duration = AnimationTimeDelta::FromSecondsD(duration);
190     timing.fill_mode = fill_mode;
191     return MakeGarbageCollected<KeyframeEffect>(nullptr, MakeEmptyEffectModel(),
192                                                 timing);
193   }
194 
SimulateFrame(double time_ms)195   bool SimulateFrame(double time_ms) {
196     if (animation->pending())
197       animation->NotifyReady(MillisecondsToSeconds(last_frame_time));
198     SimulateMicrotask();
199 
200     last_frame_time = time_ms;
201     const auto* paint_artifact_compositor =
202         GetDocument().GetFrame()->View()->GetPaintArtifactCompositor();
203     GetDocument().GetAnimationClock().UpdateTime(
204         base::TimeTicks() + base::TimeDelta::FromMillisecondsD(time_ms));
205     GetDocument().GetPendingAnimations().Update(paint_artifact_compositor,
206                                                 false);
207     // The timeline does not know about our animation, so we have to explicitly
208     // call update().
209     return animation->Update(kTimingUpdateForAnimationFrame);
210   }
211 
SimulateAwaitReady()212   void SimulateAwaitReady() { SimulateFrame(last_frame_time); }
213 
SimulateMicrotask()214   void SimulateMicrotask() {
215     Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate());
216   }
217 
SimulateFrameForScrollAnimations()218   void SimulateFrameForScrollAnimations() {
219     // Advance time by 100 ms.
220     auto new_time = GetAnimationClock().CurrentTime() +
221                     base::TimeDelta::FromMilliseconds(100);
222     GetPage().Animator().ServiceScriptedAnimations(new_time);
223   }
224 
225   Persistent<DocumentTimeline> timeline;
226   Persistent<Animation> animation;
227 
228  private:
229   double last_frame_time;
230 };
231 
232 class AnimationAnimationTestCompositing
233     : public AnimationAnimationTestNoCompositing {
SetUp()234   void SetUp() override {
235     EnableCompositing();
236     AnimationAnimationTestNoCompositing::SetUp();
237   }
238 };
239 
240 class AnimationAnimationTestCompositeAfterPaint
241     : public AnimationAnimationTestNoCompositing {
SetUp()242   void SetUp() override {
243     EnableCompositing();
244     AnimationAnimationTestNoCompositing::SetUp();
245   }
246 
247   ScopedCompositeAfterPaintForTest enable_cap{true};
248 };
249 
TEST_F(AnimationAnimationTestNoCompositing,InitialState)250 TEST_F(AnimationAnimationTestNoCompositing, InitialState) {
251   SetUpWithoutStartingTimeline();
252   animation = timeline->Play(nullptr);
253   EXPECT_EQ(0, animation->currentTime());
254   EXPECT_TRUE(animation->pending());
255   EXPECT_FALSE(animation->Paused());
256   EXPECT_EQ(1, animation->playbackRate());
257   EXPECT_FALSE(animation->startTime().has_value());
258 
259   StartTimeline();
260   EXPECT_EQ("finished", animation->playState());
261   EXPECT_EQ(0, timeline->CurrentTimeMilliseconds());
262   EXPECT_EQ(0, animation->currentTime());
263   EXPECT_FALSE(animation->Paused());
264   EXPECT_FALSE(animation->pending());
265   EXPECT_EQ(1, animation->playbackRate());
266   EXPECT_EQ(0, animation->startTime());
267 }
268 
TEST_F(AnimationAnimationTestNoCompositing,CurrentTimeDoesNotSetOutdated)269 TEST_F(AnimationAnimationTestNoCompositing, CurrentTimeDoesNotSetOutdated) {
270   EXPECT_FALSE(animation->Outdated());
271   EXPECT_EQ(0, animation->currentTime());
272   EXPECT_FALSE(animation->Outdated());
273   // FIXME: We should split simulateFrame into a version that doesn't update
274   // the animation and one that does, as most of the tests don't require
275   // update() to be called.
276   GetDocument().GetAnimationClock().UpdateTime(
277       base::TimeTicks() + base::TimeDelta::FromMilliseconds(10000));
278   EXPECT_EQ(10000, animation->currentTime());
279   EXPECT_FALSE(animation->Outdated());
280 }
281 
TEST_F(AnimationAnimationTestNoCompositing,SetCurrentTime)282 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTime) {
283   EXPECT_EQ("running", animation->playState());
284   animation->setCurrentTime(10000);
285   EXPECT_EQ("running", animation->playState());
286   EXPECT_EQ(10000, animation->currentTime());
287 
288   SimulateFrame(10000);
289   EXPECT_EQ("running", animation->playState());
290   EXPECT_EQ(20000, animation->currentTime());
291 }
292 
TEST_F(AnimationAnimationTestNoCompositing,SetCurrentTimeNegative)293 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeNegative) {
294   animation->setCurrentTime(-10000);
295   EXPECT_EQ("running", animation->playState());
296   EXPECT_EQ(-10000, animation->currentTime());
297 
298   SimulateFrame(20000);
299   EXPECT_EQ(10000, animation->currentTime());
300   animation->setPlaybackRate(-2);
301   animation->setCurrentTime(-10000);
302   EXPECT_EQ("finished", animation->playState());
303   // A seek can set current time outside the range [0, EffectEnd()].
304   EXPECT_EQ(-10000, animation->currentTime());
305 
306   SimulateFrame(40000);
307   // Hold current time even though outside normal range for the animation.
308   EXPECT_FALSE(animation->pending());
309   EXPECT_EQ("finished", animation->playState());
310   EXPECT_EQ(-10000, animation->currentTime());
311 }
312 
TEST_F(AnimationAnimationTestNoCompositing,SetCurrentTimeNegativeWithoutSimultaneousPlaybackRateChange)313 TEST_F(AnimationAnimationTestNoCompositing,
314        SetCurrentTimeNegativeWithoutSimultaneousPlaybackRateChange) {
315   SimulateFrame(20000);
316   EXPECT_EQ(20000, animation->currentTime());
317   EXPECT_EQ("running", animation->playState());
318 
319   // Reversing the direction preserves current time.
320   animation->setPlaybackRate(-1);
321   EXPECT_EQ("running", animation->playState());
322   EXPECT_EQ(20000, animation->currentTime());
323   SimulateAwaitReady();
324 
325   SimulateFrame(30000);
326   EXPECT_EQ(10000, animation->currentTime());
327   EXPECT_EQ("running", animation->playState());
328 
329   animation->setCurrentTime(-10000);
330   EXPECT_EQ("finished", animation->playState());
331 }
332 
TEST_F(AnimationAnimationTestNoCompositing,SetCurrentTimePastContentEnd)333 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) {
334   animation->setCurrentTime(50000);
335   EXPECT_EQ("finished", animation->playState());
336   EXPECT_EQ(50000, animation->currentTime());
337 
338   SimulateFrame(20000);
339   EXPECT_EQ("finished", animation->playState());
340   EXPECT_EQ(50000, animation->currentTime());
341   // Reversing the play direction changes the play state from finished to
342   // running.
343   animation->setPlaybackRate(-2);
344   animation->setCurrentTime(50000);
345   EXPECT_EQ("running", animation->playState());
346   EXPECT_EQ(50000, animation->currentTime());
347   SimulateAwaitReady();
348 
349   SimulateFrame(40000);
350   EXPECT_EQ("running", animation->playState());
351   EXPECT_EQ(10000, animation->currentTime());
352 }
353 
TEST_F(AnimationAnimationTestNoCompositing,SetCurrentTimeMax)354 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeMax) {
355   double limit = std::numeric_limits<double>::max();
356   animation->setCurrentTime(limit);
357   ExpectRelativeErrorWithinEpsilon(limit, animation->currentTime().value());
358 
359   SimulateFrame(100000);
360   ExpectRelativeErrorWithinEpsilon(limit, animation->currentTime().value());
361 }
362 
TEST_F(AnimationAnimationTestNoCompositing,SetCurrentTimeSetsStartTime)363 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeSetsStartTime) {
364   EXPECT_EQ(0, animation->startTime());
365   animation->setCurrentTime(1000);
366   EXPECT_EQ(-1000, animation->startTime());
367 
368   SimulateFrame(1000);
369   EXPECT_EQ(-1000, animation->startTime());
370   EXPECT_EQ(2000, animation->currentTime());
371 }
372 
TEST_F(AnimationAnimationTestNoCompositing,SetStartTime)373 TEST_F(AnimationAnimationTestNoCompositing, SetStartTime) {
374   SimulateFrame(20000);
375   EXPECT_EQ("running", animation->playState());
376   EXPECT_EQ(0, animation->startTime());
377   EXPECT_EQ(20000, animation->currentTime());
378   animation->setStartTime(10000);
379   EXPECT_EQ("running", animation->playState());
380   EXPECT_EQ(10000, animation->startTime());
381   EXPECT_EQ(10000, animation->currentTime());
382 
383   SimulateFrame(30000);
384   EXPECT_EQ(10000, animation->startTime());
385   EXPECT_EQ(20000, animation->currentTime());
386   animation->setStartTime(-20000);
387   EXPECT_EQ("finished", animation->playState());
388 }
389 
TEST_F(AnimationAnimationTestNoCompositing,SetStartTimeLimitsAnimation)390 TEST_F(AnimationAnimationTestNoCompositing, SetStartTimeLimitsAnimation) {
391   // Setting the start time is a seek operation, which is not constrained by the
392   // normal limits on the animation.
393   animation->setStartTime(-50000);
394   EXPECT_EQ("finished", animation->playState());
395   EXPECT_TRUE(animation->Limited());
396   EXPECT_EQ(50000, animation->currentTime());
397   animation->setPlaybackRate(-1);
398   EXPECT_EQ("running", animation->playState());
399   animation->setStartTime(-100000);
400   EXPECT_EQ("finished", animation->playState());
401   EXPECT_EQ(-100000, animation->currentTime());
402   EXPECT_TRUE(animation->Limited());
403 }
404 
TEST_F(AnimationAnimationTestNoCompositing,SetStartTimeOnLimitedAnimation)405 TEST_F(AnimationAnimationTestNoCompositing, SetStartTimeOnLimitedAnimation) {
406   // The setStartTime method is a seek and thus not constrained by the normal
407   // limits on the animation.
408   SimulateFrame(30000);
409   animation->setStartTime(-10000);
410   EXPECT_EQ("finished", animation->playState());
411   EXPECT_EQ(40000, animation->currentTime());
412   EXPECT_TRUE(animation->Limited());
413 
414   animation->setCurrentTime(50000);
415   EXPECT_EQ(50000, animation->currentTime());
416   animation->setStartTime(-40000);
417   EXPECT_EQ(70000, animation->currentTime());
418   EXPECT_EQ("finished", animation->playState());
419   EXPECT_TRUE(animation->Limited());
420 }
421 
TEST_F(AnimationAnimationTestNoCompositing,StartTimePauseFinish)422 TEST_F(AnimationAnimationTestNoCompositing, StartTimePauseFinish) {
423   NonThrowableExceptionState exception_state;
424   animation->pause();
425   EXPECT_EQ("paused", animation->playState());
426   EXPECT_TRUE(animation->pending());
427   SimulateAwaitReady();
428   EXPECT_FALSE(animation->pending());
429   EXPECT_FALSE(animation->startTime().has_value());
430   animation->finish(exception_state);
431   EXPECT_EQ("finished", animation->playState());
432   EXPECT_FALSE(animation->pending());
433   EXPECT_EQ(-30000, animation->startTime());
434 }
435 
TEST_F(AnimationAnimationTestNoCompositing,FinishWhenPaused)436 TEST_F(AnimationAnimationTestNoCompositing, FinishWhenPaused) {
437   NonThrowableExceptionState exception_state;
438   animation->pause();
439   EXPECT_EQ("paused", animation->playState());
440   EXPECT_TRUE(animation->pending());
441 
442   SimulateFrame(10000);
443   EXPECT_EQ("paused", animation->playState());
444   EXPECT_FALSE(animation->pending());
445   animation->finish(exception_state);
446   EXPECT_EQ("finished", animation->playState());
447 }
448 
TEST_F(AnimationAnimationTestNoCompositing,StartTimeFinishPause)449 TEST_F(AnimationAnimationTestNoCompositing, StartTimeFinishPause) {
450   NonThrowableExceptionState exception_state;
451   animation->finish(exception_state);
452   EXPECT_EQ(-30000, animation->startTime());
453   animation->pause();
454   EXPECT_EQ("paused", animation->playState());
455   EXPECT_TRUE(animation->pending());
456   SimulateAwaitReady();
457   EXPECT_FALSE(animation->pending());
458   EXPECT_FALSE(animation->startTime().has_value());
459 }
460 
TEST_F(AnimationAnimationTestNoCompositing,StartTimeWithZeroPlaybackRate)461 TEST_F(AnimationAnimationTestNoCompositing, StartTimeWithZeroPlaybackRate) {
462   animation->setPlaybackRate(0);
463   EXPECT_EQ("running", animation->playState());
464   SimulateAwaitReady();
465   EXPECT_TRUE(animation->startTime().has_value());
466 
467   SimulateFrame(10000);
468   EXPECT_EQ("running", animation->playState());
469   EXPECT_EQ(0, animation->currentTime());
470 }
471 
TEST_F(AnimationAnimationTestNoCompositing,PausePlay)472 TEST_F(AnimationAnimationTestNoCompositing, PausePlay) {
473   // Pause the animation at the 10s mark.
474   SimulateFrame(10000);
475   animation->pause();
476   EXPECT_EQ("paused", animation->playState());
477   EXPECT_TRUE(animation->pending());
478   EXPECT_EQ(10000, animation->currentTime());
479 
480   // Resume playing the animation at the 20s mark.
481   SimulateFrame(20000);
482   EXPECT_EQ("paused", animation->playState());
483   EXPECT_FALSE(animation->pending());
484   EXPECT_EQ(10000, animation->currentTime());
485   animation->play();
486   EXPECT_EQ("running", animation->playState());
487   EXPECT_TRUE(animation->pending());
488   SimulateAwaitReady();
489   EXPECT_FALSE(animation->pending());
490 
491   // Advance another 10s.
492   SimulateFrame(30000);
493   EXPECT_EQ(20000, animation->currentTime());
494 }
495 
TEST_F(AnimationAnimationTestNoCompositing,PlayRewindsToStart)496 TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToStart) {
497   // Auto-replay when starting from limit.
498   animation->setCurrentTime(30000);
499   animation->play();
500   EXPECT_EQ(0, animation->currentTime());
501 
502   // Auto-replay when starting past the upper bound.
503   animation->setCurrentTime(40000);
504   animation->play();
505   EXPECT_EQ(0, animation->currentTime());
506   EXPECT_EQ("running", animation->playState());
507   EXPECT_TRUE(animation->pending());
508 
509   // Snap to start of the animation if playing in forward direction starting
510   // from a negative value of current time.
511   SimulateFrame(10000);
512   EXPECT_FALSE(animation->pending());
513   animation->setCurrentTime(-10000);
514   EXPECT_EQ("running", animation->playState());
515   EXPECT_FALSE(animation->pending());
516   animation->play();
517   EXPECT_EQ(0, animation->currentTime());
518   EXPECT_EQ("running", animation->playState());
519   EXPECT_TRUE(animation->pending());
520   SimulateAwaitReady();
521   EXPECT_EQ("running", animation->playState());
522   EXPECT_FALSE(animation->pending());
523 }
524 
TEST_F(AnimationAnimationTestNoCompositing,PlayRewindsToEnd)525 TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToEnd) {
526   // Snap to end when playing a reversed animation from the start.
527   animation->setPlaybackRate(-1);
528   animation->play();
529   EXPECT_EQ(30000, animation->currentTime());
530 
531   // Snap to end if playing a reversed animation starting past the upper limit.
532   animation->setCurrentTime(40000);
533   EXPECT_EQ("running", animation->playState());
534   EXPECT_TRUE(animation->pending());
535   animation->play();
536   EXPECT_EQ(30000, animation->currentTime());
537   EXPECT_TRUE(animation->pending());
538 
539   SimulateFrame(10000);
540   EXPECT_EQ("running", animation->playState());
541   EXPECT_FALSE(animation->pending());
542 
543   // Snap to the end if playing a reversed animation starting with a negative
544   // value for current time.
545   animation->setCurrentTime(-10000);
546   animation->play();
547   EXPECT_EQ(30000, animation->currentTime());
548   EXPECT_EQ("running", animation->playState());
549   EXPECT_TRUE(animation->pending());
550 
551   SimulateFrame(20000);
552   EXPECT_EQ("running", animation->playState());
553   EXPECT_FALSE(animation->pending());
554 }
555 
TEST_F(AnimationAnimationTestNoCompositing,PlayWithPlaybackRateZeroDoesNotSeek)556 TEST_F(AnimationAnimationTestNoCompositing,
557        PlayWithPlaybackRateZeroDoesNotSeek) {
558   // When playback rate is zero, any value set for the current time effectively
559   // becomes the hold time.
560   animation->setPlaybackRate(0);
561   animation->play();
562   EXPECT_EQ(0, animation->currentTime());
563 
564   animation->setCurrentTime(40000);
565   animation->play();
566   EXPECT_EQ(40000, animation->currentTime());
567 
568   animation->setCurrentTime(-10000);
569   animation->play();
570   EXPECT_EQ(-10000, animation->currentTime());
571 }
572 
TEST_F(AnimationAnimationTestNoCompositing,PlayAfterPauseWithPlaybackRateZeroUpdatesPlayState)573 TEST_F(AnimationAnimationTestNoCompositing,
574        PlayAfterPauseWithPlaybackRateZeroUpdatesPlayState) {
575   animation->pause();
576   animation->setPlaybackRate(0);
577 
578   SimulateFrame(1000);
579   EXPECT_EQ("paused", animation->playState());
580   animation->play();
581   EXPECT_EQ("running", animation->playState());
582   EXPECT_TRUE(animation->pending());
583 }
584 
TEST_F(AnimationAnimationTestNoCompositing,Reverse)585 TEST_F(AnimationAnimationTestNoCompositing, Reverse) {
586   animation->setCurrentTime(10000);
587   animation->pause();
588   animation->reverse();
589   EXPECT_EQ("running", animation->playState());
590   EXPECT_TRUE(animation->pending());
591   // Effective playback rate does not kick in until the animation is ready.
592   EXPECT_EQ(1, animation->playbackRate());
593   EXPECT_EQ(10000, animation->currentTime());
594   SimulateAwaitReady();
595   EXPECT_FALSE(animation->pending());
596   EXPECT_EQ(-1, animation->playbackRate());
597   // Updating the playback rate does not change current time.
598   EXPECT_EQ(10000, animation->currentTime());
599 }
600 
TEST_F(AnimationAnimationTestNoCompositing,ReverseHoldsCurrentTimeWithPlaybackRateZero)601 TEST_F(AnimationAnimationTestNoCompositing,
602        ReverseHoldsCurrentTimeWithPlaybackRateZero) {
603   animation->setCurrentTime(10000);
604   animation->setPlaybackRate(0);
605   animation->pause();
606   animation->reverse();
607   SimulateAwaitReady();
608   EXPECT_EQ("running", animation->playState());
609   EXPECT_EQ(0, animation->playbackRate());
610   EXPECT_EQ(10000, animation->currentTime());
611 
612   SimulateFrame(20000);
613   EXPECT_EQ(10000, animation->currentTime());
614 }
615 
TEST_F(AnimationAnimationTestNoCompositing,ReverseSeeksToStart)616 TEST_F(AnimationAnimationTestNoCompositing, ReverseSeeksToStart) {
617   animation->setCurrentTime(-10000);
618   animation->setPlaybackRate(-1);
619   animation->reverse();
620   EXPECT_EQ(0, animation->currentTime());
621 }
622 
TEST_F(AnimationAnimationTestNoCompositing,ReverseSeeksToEnd)623 TEST_F(AnimationAnimationTestNoCompositing, ReverseSeeksToEnd) {
624   animation->setCurrentTime(40000);
625   animation->reverse();
626   EXPECT_EQ(30000, animation->currentTime());
627 }
628 
TEST_F(AnimationAnimationTestNoCompositing,ReverseBeyondLimit)629 TEST_F(AnimationAnimationTestNoCompositing, ReverseBeyondLimit) {
630   animation->setCurrentTime(40000);
631   animation->setPlaybackRate(-1);
632   animation->reverse();
633   EXPECT_EQ("running", animation->playState());
634   EXPECT_TRUE(animation->pending());
635   EXPECT_EQ(0, animation->currentTime());
636 
637   animation->setCurrentTime(-10000);
638   animation->reverse();
639   EXPECT_EQ("running", animation->playState());
640   EXPECT_TRUE(animation->pending());
641   EXPECT_EQ(30000, animation->currentTime());
642 }
643 
TEST_F(AnimationAnimationTestNoCompositing,Finish)644 TEST_F(AnimationAnimationTestNoCompositing, Finish) {
645   NonThrowableExceptionState exception_state;
646   animation->finish(exception_state);
647   // Finished snaps to the end of the animation.
648   EXPECT_EQ(30000, animation->currentTime());
649   EXPECT_EQ("finished", animation->playState());
650   // Finished is a synchronous operation.
651   EXPECT_FALSE(animation->pending());
652 
653   animation->setPlaybackRate(-1);
654   animation->finish(exception_state);
655   EXPECT_EQ(0, animation->currentTime());
656   EXPECT_EQ("finished", animation->playState());
657   EXPECT_FALSE(animation->pending());
658 }
659 
TEST_F(AnimationAnimationTestNoCompositing,FinishAfterEffectEnd)660 TEST_F(AnimationAnimationTestNoCompositing, FinishAfterEffectEnd) {
661   NonThrowableExceptionState exception_state;
662   // OK to set current time out of bounds.
663   animation->setCurrentTime(40000);
664   animation->finish(exception_state);
665   // The finish method triggers a snap to the upper boundary.
666   EXPECT_EQ(30000, animation->currentTime());
667 }
668 
TEST_F(AnimationAnimationTestNoCompositing,FinishBeforeStart)669 TEST_F(AnimationAnimationTestNoCompositing, FinishBeforeStart) {
670   NonThrowableExceptionState exception_state;
671   animation->setCurrentTime(-10000);
672   animation->setPlaybackRate(-1);
673   animation->finish(exception_state);
674   EXPECT_EQ(0, animation->currentTime());
675 }
676 
TEST_F(AnimationAnimationTestNoCompositing,FinishDoesNothingWithPlaybackRateZero)677 TEST_F(AnimationAnimationTestNoCompositing,
678        FinishDoesNothingWithPlaybackRateZero) {
679   // Cannot finish an animation that has a playback rate of zero.
680   DummyExceptionStateForTesting exception_state;
681   animation->setCurrentTime(10000);
682   animation->setPlaybackRate(0);
683   animation->finish(exception_state);
684   EXPECT_EQ(10000, animation->currentTime());
685   EXPECT_TRUE(exception_state.HadException());
686 }
687 
TEST_F(AnimationAnimationTestNoCompositing,FinishRaisesException)688 TEST_F(AnimationAnimationTestNoCompositing, FinishRaisesException) {
689   // Cannot finish an animation that has an infinite iteration-count and a
690   // non-zero iteration-duration.
691   Timing timing;
692   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(1);
693   timing.iteration_count = std::numeric_limits<double>::infinity();
694   animation->setEffect(MakeGarbageCollected<KeyframeEffect>(
695       nullptr, MakeEmptyEffectModel(), timing));
696   animation->setCurrentTime(10000);
697 
698   DummyExceptionStateForTesting exception_state;
699   animation->finish(exception_state);
700   EXPECT_EQ(10000, animation->currentTime());
701   EXPECT_TRUE(exception_state.HadException());
702   EXPECT_EQ(DOMExceptionCode::kInvalidStateError,
703             exception_state.CodeAs<DOMExceptionCode>());
704 }
705 
TEST_F(AnimationAnimationTestNoCompositing,LimitingAtEffectEnd)706 TEST_F(AnimationAnimationTestNoCompositing, LimitingAtEffectEnd) {
707   SimulateFrame(30000);
708   EXPECT_EQ(30000, animation->currentTime());
709   EXPECT_TRUE(animation->Limited());
710 
711   // Cannot run past the end of the animation without a seek.
712   SimulateFrame(40000);
713   EXPECT_EQ(30000, animation->currentTime());
714   EXPECT_FALSE(animation->Paused());
715 }
716 
TEST_F(AnimationAnimationTestNoCompositing,LimitingAtStart)717 TEST_F(AnimationAnimationTestNoCompositing, LimitingAtStart) {
718   SimulateFrame(30000);
719   animation->setPlaybackRate(-2);
720   SimulateAwaitReady();
721 
722   SimulateFrame(45000);
723   EXPECT_EQ(0, animation->currentTime());
724   EXPECT_TRUE(animation->Limited());
725 
726   SimulateFrame(60000);
727   EXPECT_EQ(0, animation->currentTime());
728   EXPECT_FALSE(animation->Paused());
729 }
730 
TEST_F(AnimationAnimationTestNoCompositing,LimitingWithNoEffect)731 TEST_F(AnimationAnimationTestNoCompositing, LimitingWithNoEffect) {
732   animation->setEffect(nullptr);
733   EXPECT_TRUE(animation->Limited());
734   SimulateFrame(30000);
735   EXPECT_EQ(0, animation->currentTime());
736 }
737 
TEST_F(AnimationAnimationTestNoCompositing,SetPlaybackRate)738 TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRate) {
739   animation->setPlaybackRate(2);
740   SimulateAwaitReady();
741   EXPECT_EQ(2, animation->playbackRate());
742   EXPECT_EQ(0, animation->currentTime());
743 
744   SimulateFrame(10000);
745   EXPECT_EQ(20000, animation->currentTime());
746 }
747 
TEST_F(AnimationAnimationTestNoCompositing,SetPlaybackRateWhilePaused)748 TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateWhilePaused) {
749   SimulateFrame(10000);
750   animation->pause();
751   EXPECT_EQ(10000, animation->currentTime());
752   animation->setPlaybackRate(2);
753   EXPECT_EQ(10000, animation->currentTime());
754   SimulateAwaitReady();
755 
756   SimulateFrame(20000);
757   animation->play();
758   // Change to playback rate does not alter current time.
759   EXPECT_EQ(10000, animation->currentTime());
760   SimulateAwaitReady();
761 
762   SimulateFrame(25000);
763   EXPECT_EQ(20000, animation->currentTime());
764 }
765 
TEST_F(AnimationAnimationTestNoCompositing,SetPlaybackRateWhileLimited)766 TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateWhileLimited) {
767   // Animation plays until it hits the upper bound.
768   SimulateFrame(40000);
769   EXPECT_EQ(30000, animation->currentTime());
770   EXPECT_TRUE(animation->Limited());
771   animation->setPlaybackRate(2);
772   SimulateAwaitReady();
773 
774   // Already at the end of the animation.
775   SimulateFrame(50000);
776   EXPECT_EQ(30000, animation->currentTime());
777   animation->setPlaybackRate(-2);
778   SimulateAwaitReady();
779 
780   SimulateFrame(60000);
781   EXPECT_FALSE(animation->Limited());
782   EXPECT_EQ(10000, animation->currentTime());
783 }
784 
TEST_F(AnimationAnimationTestNoCompositing,SetPlaybackRateZero)785 TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateZero) {
786   SimulateFrame(10000);
787   animation->setPlaybackRate(0);
788   EXPECT_EQ(10000, animation->currentTime());
789 
790   SimulateFrame(20000);
791   EXPECT_EQ(10000, animation->currentTime());
792   animation->setCurrentTime(20000);
793   EXPECT_EQ(20000, animation->currentTime());
794 }
795 
TEST_F(AnimationAnimationTestNoCompositing,SetPlaybackRateMax)796 TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateMax) {
797   animation->setPlaybackRate(std::numeric_limits<double>::max());
798   EXPECT_EQ(std::numeric_limits<double>::max(), animation->playbackRate());
799   EXPECT_EQ(0, animation->currentTime());
800   SimulateAwaitReady();
801 
802   SimulateFrame(1);
803   EXPECT_EQ(30000, animation->currentTime());
804 }
805 
TEST_F(AnimationAnimationTestNoCompositing,UpdatePlaybackRate)806 TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRate) {
807   animation->updatePlaybackRate(2);
808   EXPECT_EQ(1, animation->playbackRate());
809   SimulateAwaitReady();
810   EXPECT_EQ(2, animation->playbackRate());
811   EXPECT_EQ(0, animation->currentTime());
812 
813   SimulateFrame(10000);
814   EXPECT_EQ(20000, animation->currentTime());
815 }
816 
TEST_F(AnimationAnimationTestNoCompositing,UpdatePlaybackRateWhilePaused)817 TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhilePaused) {
818   animation->pause();
819 
820   // Pending playback rate on pending-paused animation is picked up after async
821   // tick.
822   EXPECT_EQ("paused", animation->playState());
823   EXPECT_TRUE(animation->pending());
824   animation->updatePlaybackRate(2);
825   EXPECT_EQ(1, animation->playbackRate());
826   SimulateAwaitReady();
827   EXPECT_EQ(2, animation->playbackRate());
828   EXPECT_FALSE(animation->pending());
829 
830   // Pending playback rate on a paused animation is resolved immediately.
831   animation->updatePlaybackRate(3);
832   EXPECT_FALSE(animation->pending());
833   EXPECT_EQ(3, animation->playbackRate());
834 }
835 
TEST_F(AnimationAnimationTestNoCompositing,UpdatePlaybackRateWhileLimited)836 TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileLimited) {
837   NonThrowableExceptionState exception_state;
838   animation->finish(exception_state);
839   EXPECT_EQ(30000, animation->currentTime());
840 
841   // Updating playback rate does not affect current time.
842   animation->updatePlaybackRate(2);
843   EXPECT_EQ(30000, animation->currentTime());
844 
845   // Updating payback rate is resolved immediately for an animation in the
846   // finished state.
847   EXPECT_EQ(2, animation->playbackRate());
848 }
849 
TEST_F(AnimationAnimationTestNoCompositing,UpdatePlaybackRateWhileRunning)850 TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileRunning) {
851   animation->play();
852   SimulateFrame(1000);
853   animation->updatePlaybackRate(2);
854 
855   // Updating playback rate triggers pending state for the play state.
856   // Pending playback rate is not resolved until next async tick.
857   EXPECT_TRUE(animation->pending());
858   EXPECT_EQ(1, animation->playbackRate());
859   SimulateAwaitReady();
860   EXPECT_FALSE(animation->pending());
861   EXPECT_EQ(2, animation->playbackRate());
862 }
863 
TEST_F(AnimationAnimationTestNoCompositing,SetEffect)864 TEST_F(AnimationAnimationTestNoCompositing, SetEffect) {
865   animation = timeline->Play(nullptr);
866   animation->setStartTime(0);
867   AnimationEffect* effect1 = MakeAnimation();
868   AnimationEffect* effect2 = MakeAnimation();
869   animation->setEffect(effect1);
870   EXPECT_EQ(effect1, animation->effect());
871   EXPECT_EQ(0, animation->currentTime());
872   animation->setCurrentTime(15000);
873   animation->setEffect(effect2);
874   EXPECT_EQ(15000, animation->currentTime());
875   EXPECT_EQ(nullptr, effect1->GetAnimationForTesting());
876   EXPECT_EQ(animation, effect2->GetAnimationForTesting());
877   EXPECT_EQ(effect2, animation->effect());
878 }
879 
TEST_F(AnimationAnimationTestNoCompositing,SetEffectLimitsAnimation)880 TEST_F(AnimationAnimationTestNoCompositing, SetEffectLimitsAnimation) {
881   animation->setCurrentTime(20000);
882   animation->setEffect(MakeAnimation(10));
883   EXPECT_EQ(20000, animation->currentTime());
884   EXPECT_TRUE(animation->Limited());
885   SimulateFrame(10000);
886   EXPECT_EQ(20000, animation->currentTime());
887 }
888 
TEST_F(AnimationAnimationTestNoCompositing,SetEffectUnlimitsAnimation)889 TEST_F(AnimationAnimationTestNoCompositing, SetEffectUnlimitsAnimation) {
890   animation->setCurrentTime(40000);
891   animation->setEffect(MakeAnimation(60));
892   EXPECT_FALSE(animation->Limited());
893   EXPECT_EQ(40000, animation->currentTime());
894   SimulateFrame(10000);
895   EXPECT_EQ(50000, animation->currentTime());
896 }
897 
TEST_F(AnimationAnimationTestNoCompositing,EmptyAnimationsDontUpdateEffects)898 TEST_F(AnimationAnimationTestNoCompositing, EmptyAnimationsDontUpdateEffects) {
899   animation = timeline->Play(nullptr);
900   animation->Update(kTimingUpdateOnDemand);
901   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
902 
903   SimulateFrame(1234);
904   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
905 }
906 
TEST_F(AnimationAnimationTestNoCompositing,AnimationsDisassociateFromEffect)907 TEST_F(AnimationAnimationTestNoCompositing, AnimationsDisassociateFromEffect) {
908   AnimationEffect* animation_node = animation->effect();
909   Animation* animation2 = timeline->Play(animation_node);
910   EXPECT_EQ(nullptr, animation->effect());
911   animation->setEffect(animation_node);
912   EXPECT_EQ(nullptr, animation2->effect());
913 }
914 
TEST_F(AnimationAnimationTestNoCompositing,AnimationsReturnTimeToNextEffect)915 TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) {
916   Timing timing;
917   timing.start_delay = 1;
918   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(1);
919   timing.end_delay = 1;
920   auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>(
921       nullptr, MakeEmptyEffectModel(), timing);
922   animation = timeline->Play(keyframe_effect);
923   animation->setStartTime(0);
924 
925   // Next effect change at end of start delay.
926   SimulateFrame(0);
927   EXPECT_EQ(AnimationTimeDelta::FromSecondsD(1),
928             animation->TimeToEffectChange());
929 
930   // Next effect change at end of start delay.
931   SimulateFrame(500);
932   EXPECT_EQ(AnimationTimeDelta::FromSecondsD(0.5),
933             animation->TimeToEffectChange());
934 
935   // Start of active phase.
936   SimulateFrame(1000);
937   EXPECT_EQ(AnimationTimeDelta(), animation->TimeToEffectChange());
938 
939   // Still in active phase.
940   SimulateFrame(1500);
941   EXPECT_EQ(AnimationTimeDelta(), animation->TimeToEffectChange());
942 
943   // Start of the after phase. Next effect change at end of after phase.
944   SimulateFrame(2000);
945   EXPECT_EQ(AnimationTimeDelta::FromSecondsD(1),
946             animation->TimeToEffectChange());
947 
948   // Still in effect if fillmode = forward|both.
949   SimulateFrame(3000);
950   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
951 
952   // Reset to start of animation. Next effect at the end of the start delay.
953   animation->setCurrentTime(0);
954   SimulateFrame(3000);
955   EXPECT_EQ(AnimationTimeDelta::FromSecondsD(1),
956             animation->TimeToEffectChange());
957 
958   // Start delay is scaled by playback rate.
959   animation->setPlaybackRate(2);
960   SimulateFrame(3000);
961   EXPECT_EQ(AnimationTimeDelta::FromSecondsD(0.5),
962             animation->TimeToEffectChange());
963 
964   // Effectively a paused animation.
965   animation->setPlaybackRate(0);
966   animation->Update(kTimingUpdateOnDemand);
967   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
968 
969   // Reversed animation from end time. Next effect after end delay.
970   animation->setCurrentTime(3000);
971   animation->setPlaybackRate(-1);
972   animation->Update(kTimingUpdateOnDemand);
973   SimulateFrame(3000);
974   EXPECT_EQ(AnimationTimeDelta::FromSecondsD(1),
975             animation->TimeToEffectChange());
976 
977   // End delay is scaled by playback rate.
978   animation->setPlaybackRate(-2);
979   animation->Update(kTimingUpdateOnDemand);
980   SimulateFrame(3000);
981   EXPECT_EQ(AnimationTimeDelta::FromSecondsD(0.5),
982             animation->TimeToEffectChange());
983 }
984 
TEST_F(AnimationAnimationTestNoCompositing,TimeToNextEffectWhenPaused)985 TEST_F(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenPaused) {
986   EXPECT_EQ(AnimationTimeDelta(), animation->TimeToEffectChange());
987   animation->pause();
988   EXPECT_TRUE(animation->pending());
989   EXPECT_EQ("paused", animation->playState());
990   SimulateAwaitReady();
991   EXPECT_FALSE(animation->pending());
992   animation->Update(kTimingUpdateOnDemand);
993   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
994 }
995 
TEST_F(AnimationAnimationTestNoCompositing,TimeToNextEffectWhenCancelledBeforeStart)996 TEST_F(AnimationAnimationTestNoCompositing,
997        TimeToNextEffectWhenCancelledBeforeStart) {
998   EXPECT_EQ(AnimationTimeDelta(), animation->TimeToEffectChange());
999   animation->setCurrentTime(-8000);
1000   animation->setPlaybackRate(2);
1001   EXPECT_EQ("running", animation->playState());
1002   animation->cancel();
1003   EXPECT_EQ("idle", animation->playState());
1004   EXPECT_FALSE(animation->pending());
1005   animation->Update(kTimingUpdateOnDemand);
1006   // This frame will fire the finish event event though no start time has been
1007   // received from the compositor yet, as cancel() nukes start times.
1008   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
1009 }
1010 
TEST_F(AnimationAnimationTestNoCompositing,TimeToNextEffectWhenCancelledBeforeStartReverse)1011 TEST_F(AnimationAnimationTestNoCompositing,
1012        TimeToNextEffectWhenCancelledBeforeStartReverse) {
1013   EXPECT_EQ(AnimationTimeDelta(), animation->TimeToEffectChange());
1014   animation->setCurrentTime(9000);
1015   animation->setPlaybackRate(-3);
1016   EXPECT_EQ("running", animation->playState());
1017   animation->cancel();
1018   EXPECT_EQ("idle", animation->playState());
1019   EXPECT_FALSE(animation->pending());
1020   animation->Update(kTimingUpdateOnDemand);
1021   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
1022 }
1023 
TEST_F(AnimationAnimationTestNoCompositing,TimeToNextEffectSimpleCancelledBeforeStart)1024 TEST_F(AnimationAnimationTestNoCompositing,
1025        TimeToNextEffectSimpleCancelledBeforeStart) {
1026   EXPECT_EQ(AnimationTimeDelta(), animation->TimeToEffectChange());
1027   EXPECT_EQ("running", animation->playState());
1028   animation->cancel();
1029   EXPECT_EQ("idle", animation->playState());
1030   EXPECT_FALSE(animation->pending());
1031   animation->Update(kTimingUpdateOnDemand);
1032   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
1033 }
1034 
TEST_F(AnimationAnimationTestNoCompositing,AttachedAnimations)1035 TEST_F(AnimationAnimationTestNoCompositing, AttachedAnimations) {
1036   Persistent<Element> element = GetDocument().CreateElementForBinding("foo");
1037 
1038   Timing timing;
1039   auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>(
1040       element.Get(), MakeEmptyEffectModel(), timing);
1041   Animation* animation = timeline->Play(keyframe_effect);
1042   SimulateFrame(0);
1043   timeline->ServiceAnimations(kTimingUpdateForAnimationFrame);
1044   EXPECT_EQ(
1045       1U, element->GetElementAnimations()->Animations().find(animation)->value);
1046 
1047   ThreadState::Current()->CollectAllGarbageForTesting();
1048   EXPECT_TRUE(element->GetElementAnimations()->Animations().IsEmpty());
1049 }
1050 
TEST_F(AnimationAnimationTestNoCompositing,HasLowerCompositeOrdering)1051 TEST_F(AnimationAnimationTestNoCompositing, HasLowerCompositeOrdering) {
1052   Animation* animation1 = timeline->Play(nullptr);
1053   Animation* animation2 = timeline->Play(nullptr);
1054   EXPECT_TRUE(Animation::HasLowerCompositeOrdering(
1055       animation1, animation2,
1056       Animation::CompareAnimationsOrdering::kPointerOrder));
1057 }
1058 
TEST_F(AnimationAnimationTestNoCompositing,PlayAfterCancel)1059 TEST_F(AnimationAnimationTestNoCompositing, PlayAfterCancel) {
1060   animation->cancel();
1061   EXPECT_EQ("idle", animation->playState());
1062   EXPECT_FALSE(animation->currentTime().has_value());
1063   EXPECT_FALSE(animation->startTime().has_value());
1064   animation->play();
1065   EXPECT_EQ("running", animation->playState());
1066   EXPECT_TRUE(animation->pending());
1067   EXPECT_EQ(0, animation->currentTime());
1068   EXPECT_FALSE(animation->startTime().has_value());
1069   SimulateAwaitReady();
1070   EXPECT_FALSE(animation->pending());
1071   EXPECT_EQ(0, animation->currentTime());
1072   EXPECT_EQ(0, animation->startTime());
1073 
1074   SimulateFrame(10000);
1075   EXPECT_EQ("running", animation->playState());
1076   EXPECT_EQ(10000, animation->currentTime());
1077   EXPECT_EQ(0, animation->startTime());
1078 }
1079 
TEST_F(AnimationAnimationTestNoCompositing,PlayBackwardsAfterCancel)1080 TEST_F(AnimationAnimationTestNoCompositing, PlayBackwardsAfterCancel) {
1081   animation->setPlaybackRate(-1);
1082   animation->setCurrentTime(15000);
1083   animation->cancel();
1084   EXPECT_EQ("idle", animation->playState());
1085   EXPECT_FALSE(animation->pending());
1086   EXPECT_FALSE(animation->currentTime().has_value());
1087   EXPECT_FALSE(animation->startTime().has_value());
1088 
1089   // Snap to the end of the animation.
1090   animation->play();
1091   EXPECT_EQ("running", animation->playState());
1092   EXPECT_TRUE(animation->pending());
1093   EXPECT_EQ(30000, animation->currentTime());
1094   EXPECT_FALSE(animation->startTime().has_value());
1095   SimulateAwaitReady();
1096   EXPECT_FALSE(animation->pending());
1097   EXPECT_EQ(30000, animation->startTime());
1098 
1099   SimulateFrame(10000);
1100   EXPECT_EQ("running", animation->playState());
1101   EXPECT_EQ(20000, animation->currentTime());
1102   EXPECT_EQ(30000, animation->startTime());
1103 }
1104 
TEST_F(AnimationAnimationTestNoCompositing,ReverseAfterCancel)1105 TEST_F(AnimationAnimationTestNoCompositing, ReverseAfterCancel) {
1106   animation->cancel();
1107   EXPECT_EQ("idle", animation->playState());
1108   EXPECT_FALSE(animation->pending());
1109   EXPECT_FALSE(animation->currentTime().has_value());
1110   EXPECT_FALSE(animation->startTime().has_value());
1111 
1112   // Reverse snaps to the end of the animation.
1113   animation->reverse();
1114   EXPECT_EQ("running", animation->playState());
1115   EXPECT_TRUE(animation->pending());
1116   EXPECT_EQ(30000, animation->currentTime());
1117   EXPECT_FALSE(animation->startTime().has_value());
1118   SimulateAwaitReady();
1119   EXPECT_FALSE(animation->pending());
1120   EXPECT_EQ(30000, animation->startTime());
1121 
1122   SimulateFrame(10000);
1123   EXPECT_EQ("running", animation->playState());
1124   EXPECT_EQ(20000, animation->currentTime());
1125   EXPECT_EQ(30000, animation->startTime());
1126 }
1127 
TEST_F(AnimationAnimationTestNoCompositing,FinishAfterCancel)1128 TEST_F(AnimationAnimationTestNoCompositing, FinishAfterCancel) {
1129   NonThrowableExceptionState exception_state;
1130   animation->cancel();
1131   EXPECT_EQ("idle", animation->playState());
1132   EXPECT_FALSE(animation->currentTime().has_value());
1133   EXPECT_FALSE(animation->startTime().has_value());
1134 
1135   animation->finish(exception_state);
1136   EXPECT_EQ("finished", animation->playState());
1137   EXPECT_EQ(30000, animation->currentTime());
1138   EXPECT_EQ(-30000, animation->startTime());
1139 }
1140 
TEST_F(AnimationAnimationTestNoCompositing,PauseAfterCancel)1141 TEST_F(AnimationAnimationTestNoCompositing, PauseAfterCancel) {
1142   animation->cancel();
1143   EXPECT_EQ("idle", animation->playState());
1144   EXPECT_FALSE(animation->currentTime().has_value());
1145   EXPECT_FALSE(animation->startTime().has_value());
1146   animation->pause();
1147   EXPECT_EQ("paused", animation->playState());
1148   EXPECT_TRUE(animation->pending());
1149   EXPECT_EQ(0, animation->currentTime());
1150   EXPECT_FALSE(animation->startTime().has_value());
1151   SimulateAwaitReady();
1152   EXPECT_FALSE(animation->pending());
1153   EXPECT_EQ(0, animation->currentTime());
1154   EXPECT_FALSE(animation->startTime().has_value());
1155 }
1156 
1157 // crbug.com/1052217
TEST_F(AnimationAnimationTestNoCompositing,SetPlaybackRateAfterFinish)1158 TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateAfterFinish) {
1159   animation->setEffect(MakeAnimation(30, Timing::FillMode::FORWARDS));
1160   animation->finish();
1161   animation->Update(kTimingUpdateOnDemand);
1162   EXPECT_EQ("finished", animation->playState());
1163   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
1164 
1165   // Reversing a finished animation marks the animation as outdated. Required
1166   // to recompute the time to next interval.
1167   animation->setPlaybackRate(-1);
1168   EXPECT_EQ("running", animation->playState());
1169   EXPECT_EQ(animation->playbackRate(), -1);
1170   EXPECT_TRUE(animation->Outdated());
1171   animation->Update(kTimingUpdateOnDemand);
1172   EXPECT_EQ(0, animation->TimeToEffectChange()->InSecondsF());
1173   EXPECT_FALSE(animation->Outdated());
1174 }
1175 
TEST_F(AnimationAnimationTestNoCompositing,UpdatePlaybackRateAfterFinish)1176 TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateAfterFinish) {
1177   animation->setEffect(MakeAnimation(30, Timing::FillMode::FORWARDS));
1178   animation->finish();
1179   animation->Update(kTimingUpdateOnDemand);
1180   EXPECT_EQ("finished", animation->playState());
1181   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
1182 
1183   // Reversing a finished animation marks the animation as outdated. Required
1184   // to recompute the time to next interval. The pending playback rate is
1185   // immediately applied when updatePlaybackRate is called on a non-running
1186   // animation.
1187   animation->updatePlaybackRate(-1);
1188   EXPECT_EQ("running", animation->playState());
1189   EXPECT_EQ(animation->playbackRate(), -1);
1190   EXPECT_TRUE(animation->Outdated());
1191   animation->Update(kTimingUpdateOnDemand);
1192   EXPECT_EQ(0, animation->TimeToEffectChange()->InSecondsF());
1193   EXPECT_FALSE(animation->Outdated());
1194 }
1195 
TEST_F(AnimationAnimationTestCompositeAfterPaint,NoCompositeWithoutCompositedElementId)1196 TEST_F(AnimationAnimationTestCompositeAfterPaint,
1197        NoCompositeWithoutCompositedElementId) {
1198   SetBodyInnerHTML(
1199       "<div id='foo' style='position: relative; will-change: "
1200       "opacity;'>composited</div>"
1201       "<div id='bar' style='position: relative'>not composited</div>");
1202 
1203   LayoutObject* object_composited = GetLayoutObjectByElementId("foo");
1204   LayoutObject* object_not_composited = GetLayoutObjectByElementId("bar");
1205 
1206   Timing timing;
1207   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
1208   auto* keyframe_effect_composited = MakeGarbageCollected<KeyframeEffect>(
1209       To<Element>(object_composited->GetNode()), MakeSimpleEffectModel(),
1210       timing);
1211   Animation* animation_composited = timeline->Play(keyframe_effect_composited);
1212   auto* keyframe_effect_not_composited = MakeGarbageCollected<KeyframeEffect>(
1213       To<Element>(object_not_composited->GetNode()), MakeSimpleEffectModel(),
1214       timing);
1215   Animation* animation_not_composited =
1216       timeline->Play(keyframe_effect_not_composited);
1217 
1218   SimulateFrame(0);
1219   EXPECT_EQ(animation_composited->CheckCanStartAnimationOnCompositorInternal(),
1220             CompositorAnimations::kNoFailure);
1221   const PaintArtifactCompositor* paint_artifact_compositor =
1222       GetDocument().View()->GetPaintArtifactCompositor();
1223   ASSERT_TRUE(paint_artifact_compositor);
1224   EXPECT_EQ(animation_composited->CheckCanStartAnimationOnCompositor(
1225                 paint_artifact_compositor),
1226             CompositorAnimations::kNoFailure);
1227   EXPECT_NE(animation_not_composited->CheckCanStartAnimationOnCompositor(
1228                 paint_artifact_compositor),
1229             CompositorAnimations::kNoFailure);
1230 }
1231 
1232 // Regression test for http://crbug.com/819591 . If a compositable animation is
1233 // played and then paused before any start time is set (either blink or
1234 // compositor side), the pausing must still set compositor pending or the pause
1235 // won't be synced.
TEST_F(AnimationAnimationTestCompositing,SetCompositorPendingWithUnresolvedStartTimes)1236 TEST_F(AnimationAnimationTestCompositing,
1237        SetCompositorPendingWithUnresolvedStartTimes) {
1238   ResetWithCompositedAnimation();
1239 
1240   // At this point, the animation exists on both the compositor and blink side,
1241   // but no start time has arrived on either side. The compositor is currently
1242   // synced, no update is pending.
1243   EXPECT_FALSE(animation->CompositorPendingForTesting());
1244 
1245   // However, if we pause the animation then the compositor should still be
1246   // marked pending. This is required because otherwise the compositor will go
1247   // ahead and start playing the animation once it receives a start time (e.g.
1248   // on the next compositor frame).
1249   animation->pause();
1250 
1251   EXPECT_TRUE(animation->CompositorPendingForTesting());
1252 }
1253 
TEST_F(AnimationAnimationTestCompositing,PreCommitWithUnresolvedStartTimes)1254 TEST_F(AnimationAnimationTestCompositing, PreCommitWithUnresolvedStartTimes) {
1255   ResetWithCompositedAnimation();
1256 
1257   // At this point, the animation exists on both the compositor and blink side,
1258   // but no start time has arrived on either side. The compositor is currently
1259   // synced, no update is pending.
1260   EXPECT_FALSE(animation->CompositorPendingForTesting());
1261 
1262   // At this point, a call to PreCommit should bail out and tell us to wait for
1263   // next commit because there are no resolved start times.
1264   EXPECT_FALSE(animation->PreCommit(0, nullptr, true));
1265 }
1266 
1267 namespace {
GenerateHistogramValue(CompositorAnimations::FailureReason reason)1268 int GenerateHistogramValue(CompositorAnimations::FailureReason reason) {
1269   // The enum values in CompositorAnimations::FailureReasons are stored as 2^i
1270   // as they are a bitmask, but are recorded into the histogram as (i+1) to give
1271   // sequential histogram values. The exception is kNoFailure, which is stored
1272   // as 0 and recorded as 0.
1273   if (reason == CompositorAnimations::kNoFailure)
1274     return CompositorAnimations::kNoFailure;
1275   return base::bits::CountTrailingZeroBits(static_cast<uint32_t>(reason)) + 1;
1276 }
1277 }  // namespace
1278 
TEST_F(AnimationAnimationTestCompositing,PreCommitRecordsHistograms)1279 TEST_F(AnimationAnimationTestCompositing, PreCommitRecordsHistograms) {
1280   const std::string histogram_name =
1281       "Blink.Animation.CompositedAnimationFailureReason";
1282 
1283   // Initially the animation in this test has no target, so it is invalid.
1284   {
1285     HistogramTester histogram;
1286     ASSERT_TRUE(animation->PreCommit(0, nullptr, true));
1287     histogram.ExpectBucketCount(
1288         histogram_name,
1289         GenerateHistogramValue(CompositorAnimations::kInvalidAnimationOrEffect),
1290         1);
1291   }
1292 
1293   // Restart the animation with a target and compositing state.
1294   {
1295     HistogramTester histogram;
1296     ResetWithCompositedAnimation();
1297     histogram.ExpectBucketCount(
1298         histogram_name,
1299         GenerateHistogramValue(CompositorAnimations::kNoFailure), 1);
1300   }
1301 
1302   // Now make the playback rate 0. This trips both the invalid animation and
1303   // unsupported timing parameter reasons.
1304   animation->setPlaybackRate(0);
1305   animation->NotifyReady(100);
1306   {
1307     HistogramTester histogram;
1308     ASSERT_TRUE(animation->PreCommit(0, nullptr, true));
1309     histogram.ExpectBucketCount(
1310         histogram_name,
1311         GenerateHistogramValue(CompositorAnimations::kInvalidAnimationOrEffect),
1312         1);
1313     histogram.ExpectBucketCount(
1314         histogram_name,
1315         GenerateHistogramValue(
1316             CompositorAnimations::kEffectHasUnsupportedTimingParameters),
1317         1);
1318   }
1319   animation->setPlaybackRate(1);
1320 
1321   // Finally, change the keyframes to something unsupported by the compositor.
1322   Persistent<StringKeyframe> start_keyframe =
1323       MakeGarbageCollected<StringKeyframe>();
1324   start_keyframe->SetCSSPropertyValue(
1325       CSSPropertyID::kLeft, "0", SecureContextMode::kInsecureContext, nullptr);
1326   Persistent<StringKeyframe> end_keyframe =
1327       MakeGarbageCollected<StringKeyframe>();
1328   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kLeft, "100px",
1329                                     SecureContextMode::kInsecureContext,
1330                                     nullptr);
1331 
1332   To<KeyframeEffect>(animation->effect())
1333       ->SetKeyframes({start_keyframe, end_keyframe});
1334   UpdateAllLifecyclePhasesForTest();
1335   {
1336     HistogramTester histogram;
1337     ASSERT_TRUE(animation->PreCommit(0, nullptr, true));
1338     histogram.ExpectBucketCount(
1339         histogram_name,
1340         GenerateHistogramValue(CompositorAnimations::kUnsupportedCSSProperty),
1341         1);
1342   }
1343 }
1344 
1345 // crbug.com/990000.
TEST_F(AnimationAnimationTestCompositing,ReplaceCompositedAnimation)1346 TEST_F(AnimationAnimationTestCompositing, ReplaceCompositedAnimation) {
1347   const std::string histogram_name =
1348       "Blink.Animation.CompositedAnimationFailureReason";
1349 
1350   // Start with a composited animation.
1351   ResetWithCompositedAnimation();
1352   ASSERT_TRUE(animation->HasActiveAnimationsOnCompositor());
1353 
1354   // Replace the animation. The new animation should not be incompatible and
1355   // therefore able to run on the compositor.
1356   animation->cancel();
1357   MakeCompositedAnimation();
1358   ASSERT_TRUE(animation->HasActiveAnimationsOnCompositor());
1359 }
1360 
TEST_F(AnimationAnimationTestCompositing,SetKeyframesCausesCompositorPending)1361 TEST_F(AnimationAnimationTestCompositing, SetKeyframesCausesCompositorPending) {
1362   ResetWithCompositedAnimation();
1363 
1364   // At this point, the animation exists on both the compositor and blink side,
1365   // but no start time has arrived on either side. The compositor is currently
1366   // synced, no update is pending.
1367   EXPECT_FALSE(animation->CompositorPendingForTesting());
1368 
1369   // Now change the keyframes; this should mark the animation as compositor
1370   // pending as we need to sync the compositor side.
1371   Persistent<StringKeyframe> start_keyframe =
1372       MakeGarbageCollected<StringKeyframe>();
1373   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
1374                                       SecureContextMode::kInsecureContext,
1375                                       nullptr);
1376   Persistent<StringKeyframe> end_keyframe =
1377       MakeGarbageCollected<StringKeyframe>();
1378   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
1379                                     SecureContextMode::kInsecureContext,
1380                                     nullptr);
1381 
1382   StringKeyframeVector keyframes;
1383   keyframes.push_back(start_keyframe);
1384   keyframes.push_back(end_keyframe);
1385 
1386   To<KeyframeEffect>(animation->effect())->SetKeyframes(keyframes);
1387 
1388   EXPECT_TRUE(animation->CompositorPendingForTesting());
1389 }
1390 
1391 // crbug.com/1057076
1392 // Infinite duration animations should not run on the compositor.
TEST_F(AnimationAnimationTestCompositing,InfiniteDurationAnimation)1393 TEST_F(AnimationAnimationTestCompositing, InfiniteDurationAnimation) {
1394   ResetWithCompositedAnimation();
1395   EXPECT_EQ(CompositorAnimations::kNoFailure,
1396             animation->CheckCanStartAnimationOnCompositor(nullptr));
1397 
1398   OptionalEffectTiming* effect_timing = OptionalEffectTiming::Create();
1399   effect_timing->setDuration(UnrestrictedDoubleOrString::FromUnrestrictedDouble(
1400       std::numeric_limits<double>::infinity()));
1401   animation->effect()->updateTiming(effect_timing);
1402   EXPECT_EQ(CompositorAnimations::kEffectHasUnsupportedTimingParameters,
1403             animation->CheckCanStartAnimationOnCompositor(nullptr));
1404 }
1405 
TEST_F(AnimationAnimationTestCompositing,ScrollLinkedAnimationCanBeComposited)1406 TEST_F(AnimationAnimationTestCompositing,
1407        ScrollLinkedAnimationCanBeComposited) {
1408   ResetWithCompositedAnimation();
1409   SetBodyInnerHTML(R"HTML(
1410     <style>
1411       #scroller { will-change: transform; overflow: scroll; width: 100px; height: 100px; }
1412       #target { width: 100px; height: 200px; will-change: opacity;}
1413       #spacer { width: 200px; height: 2000px; }
1414     </style>
1415     <div id ='scroller'>
1416       <div id ='target'></div>
1417       <div id ='spacer'></div>
1418     </div>
1419   )HTML");
1420 
1421   // Create ScrollTimeline
1422   auto* scroller =
1423       To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller"));
1424   PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
1425   scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
1426                                    mojom::blink::ScrollType::kProgrammatic);
1427   ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
1428   DoubleOrScrollTimelineAutoKeyword time_range =
1429       DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
1430   options->setTimeRange(time_range);
1431   options->setScrollSource(GetElementById("scroller"));
1432   ScrollTimeline* scroll_timeline =
1433       ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
1434 
1435   // Create KeyframeEffect
1436   Timing timing;
1437   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
1438 
1439   Persistent<StringKeyframe> start_keyframe =
1440       MakeGarbageCollected<StringKeyframe>();
1441   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
1442                                       SecureContextMode::kInsecureContext,
1443                                       nullptr);
1444   Persistent<StringKeyframe> end_keyframe =
1445       MakeGarbageCollected<StringKeyframe>();
1446   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
1447                                     SecureContextMode::kInsecureContext,
1448                                     nullptr);
1449 
1450   StringKeyframeVector keyframes;
1451   keyframes.push_back(start_keyframe);
1452   keyframes.push_back(end_keyframe);
1453 
1454   Element* element = GetElementById("target");
1455   auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
1456 
1457   // Create scroll-linked animation
1458   NonThrowableExceptionState exception_state;
1459   Animation* scroll_animation = Animation::Create(
1460       MakeGarbageCollected<KeyframeEffect>(element, model, timing),
1461       scroll_timeline, exception_state);
1462 
1463   model->SnapshotAllCompositorKeyframesIfNecessary(
1464       *element, *ComputedStyle::Create(), nullptr);
1465 
1466   UpdateAllLifecyclePhasesForTest();
1467   scroll_animation->play();
1468   EXPECT_EQ(scroll_animation->CheckCanStartAnimationOnCompositor(nullptr),
1469             CompositorAnimations::kNoFailure);
1470 }
1471 
TEST_F(AnimationAnimationTestCompositing,StartScrollLinkedAnimationWithStartTimeIfApplicable)1472 TEST_F(AnimationAnimationTestCompositing,
1473        StartScrollLinkedAnimationWithStartTimeIfApplicable) {
1474   ResetWithCompositedAnimation();
1475   SetBodyInnerHTML(R"HTML(
1476     <style>
1477       #scroller { will-change: transform; overflow: scroll; width: 100px; height: 100px; }
1478       #target { width: 100px; height: 200px; will-change: opacity;}
1479       #spacer { width: 200px; height: 700px; }
1480     </style>
1481     <div id ='scroller'>
1482       <div id ='target'></div>
1483       <div id ='spacer'></div>
1484     </div>
1485   )HTML");
1486 
1487   // Create ScrollTimeline
1488   auto* scroller =
1489       To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller"));
1490   PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
1491   scrollable_area->SetScrollOffset(ScrollOffset(0, 100),
1492                                    mojom::blink::ScrollType::kProgrammatic);
1493   ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
1494   DoubleOrScrollTimelineAutoKeyword time_range =
1495       DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
1496   options->setTimeRange(time_range);
1497   options->setScrollSource(GetElementById("scroller"));
1498   ScrollTimeline* scroll_timeline =
1499       ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
1500 
1501   // Create KeyframeEffect
1502   Timing timing;
1503   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
1504 
1505   Persistent<StringKeyframe> start_keyframe =
1506       MakeGarbageCollected<StringKeyframe>();
1507   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
1508                                       SecureContextMode::kInsecureContext,
1509                                       nullptr);
1510   Persistent<StringKeyframe> end_keyframe =
1511       MakeGarbageCollected<StringKeyframe>();
1512   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
1513                                     SecureContextMode::kInsecureContext,
1514                                     nullptr);
1515 
1516   StringKeyframeVector keyframes;
1517   keyframes.push_back(start_keyframe);
1518   keyframes.push_back(end_keyframe);
1519 
1520   Element* element = GetElementById("target");
1521   auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
1522 
1523   KeyframeEffect* keyframe_effect =
1524       MakeGarbageCollected<KeyframeEffect>(element, model, timing);
1525 
1526   // Create scroll-linked animation
1527   NonThrowableExceptionState exception_state;
1528   Animation* scroll_animation =
1529       Animation::Create(keyframe_effect, scroll_timeline, exception_state);
1530 
1531   model->SnapshotAllCompositorKeyframesIfNecessary(
1532       *element, *ComputedStyle::Create(), nullptr);
1533 
1534   UpdateAllLifecyclePhasesForTest();
1535   const double TEST_START_TIME = 10;
1536   scroll_animation->setStartTime(TEST_START_TIME);
1537   scroll_animation->play();
1538   EXPECT_EQ(scroll_animation->CheckCanStartAnimationOnCompositor(nullptr),
1539             CompositorAnimations::kNoFailure);
1540   // Start the animation on compositor. The time offset of the compositor
1541   // keyframe should be unset if we start the animation with its start time.
1542   scroll_animation->PreCommit(1, nullptr, true);
1543   cc::KeyframeModel* keyframe_model =
1544       keyframe_effect->GetAnimationForTesting()
1545           ->GetCompositorAnimation()
1546           ->CcAnimation()
1547           ->GetKeyframeModel(compositor_target_property::OPACITY);
1548   EXPECT_EQ(keyframe_model->start_time() - base::TimeTicks(),
1549             base::TimeDelta::FromMilliseconds(TEST_START_TIME));
1550   EXPECT_EQ(keyframe_model->time_offset(), base::TimeDelta());
1551 }
1552 
1553 // Verifies correctness of scroll linked animation current and start times in
1554 // various animation states.
TEST_F(AnimationAnimationTestNoCompositing,ScrollLinkedAnimationCreation)1555 TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) {
1556   SetBodyInnerHTML(R"HTML(
1557     <style>
1558       #scroller { overflow: scroll; width: 100px; height: 100px; }
1559       #spacer { width: 200px; height: 200px; }
1560     </style>
1561     <div id='scroller'>
1562       <div id ='spacer'></div>
1563     </div>
1564   )HTML");
1565 
1566   auto* scroller =
1567       To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller"));
1568   PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
1569   scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
1570                                    mojom::blink::ScrollType::kProgrammatic);
1571   ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
1572   DoubleOrScrollTimelineAutoKeyword time_range =
1573       DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
1574   options->setTimeRange(time_range);
1575   options->setScrollSource(GetElementById("scroller"));
1576   ScrollTimeline* scroll_timeline =
1577       ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
1578 
1579   NonThrowableExceptionState exception_state;
1580   Animation* scroll_animation =
1581       Animation::Create(MakeAnimation(), scroll_timeline, exception_state);
1582 
1583   // Verify start and current times in Idle state.
1584   EXPECT_FALSE(scroll_animation->startTime().has_value());
1585   EXPECT_FALSE(scroll_animation->currentTime().has_value());
1586 
1587   scroll_animation->play();
1588 
1589   // Verify start and current times in Pending state.
1590   EXPECT_EQ(0, scroll_animation->startTime());
1591   EXPECT_EQ(20, scroll_animation->currentTime());
1592 
1593   UpdateAllLifecyclePhasesForTest();
1594   // Verify start and current times in Playing state.
1595   EXPECT_EQ(0, scroll_animation->startTime());
1596   EXPECT_EQ(20, scroll_animation->currentTime());
1597 
1598   // Verify current time after scroll.
1599   scrollable_area->SetScrollOffset(ScrollOffset(0, 40),
1600                                    mojom::blink::ScrollType::kProgrammatic);
1601   SimulateFrameForScrollAnimations();
1602   EXPECT_EQ(40, scroll_animation->currentTime());
1603 }
1604 
1605 // Verifies that finished composited scroll-linked animations restart on
1606 // compositor upon reverse scrolling.
TEST_F(AnimationAnimationTestCompositing,FinishedScrollLinkedAnimationRestartsOnReverseScrolling)1607 TEST_F(AnimationAnimationTestCompositing,
1608        FinishedScrollLinkedAnimationRestartsOnReverseScrolling) {
1609   ResetWithCompositedAnimation();
1610   SetBodyInnerHTML(R"HTML(
1611     <style>
1612       #scroller { will-change: transform; overflow: scroll; width: 100px; height: 100px; }
1613       #target { width: 100px; height: 200px; will-change: opacity;}
1614       #spacer { width: 200px; height: 700px; }
1615     </style>
1616     <div id ='scroller'>
1617       <div id ='target'></div>
1618       <div id ='spacer'></div>
1619     </div>
1620   )HTML");
1621 
1622   auto* scroller =
1623       To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller"));
1624   ASSERT_TRUE(scroller->UsesCompositedScrolling());
1625 
1626   // Create ScrollTimeline
1627   ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
1628   DoubleOrScrollTimelineAutoKeyword time_range =
1629       DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
1630   options->setTimeRange(time_range);
1631   options->setScrollSource(GetElementById("scroller"));
1632   ScrollTimeline* scroll_timeline =
1633       ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
1634 
1635   // Create KeyframeEffect
1636   Timing timing;
1637   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
1638   Persistent<StringKeyframe> start_keyframe =
1639       MakeGarbageCollected<StringKeyframe>();
1640   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
1641                                       SecureContextMode::kInsecureContext,
1642                                       nullptr);
1643   Persistent<StringKeyframe> end_keyframe =
1644       MakeGarbageCollected<StringKeyframe>();
1645   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
1646                                     SecureContextMode::kInsecureContext,
1647                                     nullptr);
1648 
1649   StringKeyframeVector keyframes;
1650   keyframes.push_back(start_keyframe);
1651   keyframes.push_back(end_keyframe);
1652 
1653   Element* element = GetElementById("target");
1654   auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
1655 
1656   KeyframeEffect* keyframe_effect =
1657       MakeGarbageCollected<KeyframeEffect>(element, model, timing);
1658 
1659   // Create scroll-linked animation
1660   NonThrowableExceptionState exception_state;
1661   Animation* scroll_animation =
1662       Animation::Create(keyframe_effect, scroll_timeline, exception_state);
1663   model->SnapshotAllCompositorKeyframesIfNecessary(
1664       *element, *ComputedStyle::Create(), nullptr);
1665   UpdateAllLifecyclePhasesForTest();
1666 
1667   scroll_animation->play();
1668   EXPECT_EQ(scroll_animation->playState(), "running");
1669   GetDocument().GetPendingAnimations().Update(nullptr, true);
1670   EXPECT_TRUE(scroll_animation->HasActiveAnimationsOnCompositor());
1671 
1672   // Advances the animation to "finished" state. The composited animation will
1673   // be destroyed accordingly.
1674   scroll_animation->setCurrentTime(50000);
1675   EXPECT_EQ(scroll_animation->playState(), "finished");
1676   scroll_animation->Update(kTimingUpdateForAnimationFrame);
1677   GetDocument().GetPendingAnimations().Update(nullptr, true);
1678   EXPECT_FALSE(scroll_animation->HasActiveAnimationsOnCompositor());
1679 
1680   // Restarting the animation should create a new compositor animation.
1681   scroll_animation->setCurrentTime(100);
1682   UpdateAllLifecyclePhasesForTest();
1683   EXPECT_EQ(scroll_animation->playState(), "running");
1684   scroll_animation->Update(kTimingUpdateForAnimationFrame);
1685   GetDocument().GetPendingAnimations().Update(nullptr, true);
1686   EXPECT_TRUE(scroll_animation->HasActiveAnimationsOnCompositor());
1687 }
1688 
TEST_F(AnimationAnimationTestNoCompositing,RemoveCanceledAnimationFromActiveSet)1689 TEST_F(AnimationAnimationTestNoCompositing,
1690        RemoveCanceledAnimationFromActiveSet) {
1691   EXPECT_EQ("running", animation->playState());
1692   EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame));
1693   SimulateFrame(1000);
1694   EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame));
1695   animation->cancel();
1696   EXPECT_EQ("idle", animation->playState());
1697   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
1698 }
1699 
TEST_F(AnimationAnimationTestNoCompositing,RemoveFinishedAnimationFromActiveSet)1700 TEST_F(AnimationAnimationTestNoCompositing,
1701        RemoveFinishedAnimationFromActiveSet) {
1702   EXPECT_EQ("running", animation->playState());
1703   EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame));
1704   SimulateFrame(1000);
1705   EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame));
1706 
1707   // Synchronous completion.
1708   animation->finish();
1709   EXPECT_EQ("finished", animation->playState());
1710   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
1711 
1712   // Play creates a new pending finished promise.
1713   animation->play();
1714   EXPECT_EQ("running", animation->playState());
1715   EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame));
1716 
1717   // Asynchronous completion.
1718   animation->setCurrentTime(50000);
1719   EXPECT_EQ("finished", animation->playState());
1720   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
1721 }
1722 
TEST_F(AnimationAnimationTestNoCompositing,PendingActivityWithFinishedPromise)1723 TEST_F(AnimationAnimationTestNoCompositing,
1724        PendingActivityWithFinishedPromise) {
1725   // No pending activity even when running if there is no finished promise
1726   // or event listener.
1727   EXPECT_EQ("running", animation->playState());
1728   SimulateFrame(1000);
1729   EXPECT_FALSE(animation->HasPendingActivity());
1730 
1731   // An unresolved finished promise indicates pending activity.
1732   ScriptState* script_state =
1733       ToScriptStateForMainWorld(GetDocument().GetFrame());
1734   animation->finished(script_state);
1735   EXPECT_TRUE(animation->HasPendingActivity());
1736 
1737   // Resolving the finished promise clears the pending activity.
1738   animation->setCurrentTime(50000);
1739   EXPECT_EQ("finished", animation->playState());
1740   SimulateMicrotask();
1741   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
1742   EXPECT_FALSE(animation->HasPendingActivity());
1743 
1744   // Playing an already finished animation creates a new pending finished
1745   // promise.
1746   animation->play();
1747   EXPECT_EQ("running", animation->playState());
1748   SimulateFrame(2000);
1749   EXPECT_TRUE(animation->HasPendingActivity());
1750   // Cancel rejects the finished promise and creates a new pending finished
1751   // promise.
1752   // TODO(crbug.com/960944): Investigate if this should return false to prevent
1753   // holding onto the animation indefinitely.
1754   animation->cancel();
1755   EXPECT_TRUE(animation->HasPendingActivity());
1756 }
1757 
1758 class MockEventListener final : public NativeEventListener {
1759  public:
1760   MOCK_METHOD2(Invoke, void(ExecutionContext*, Event*));
1761 };
1762 
TEST_F(AnimationAnimationTestNoCompositing,PendingActivityWithFinishedEventListener)1763 TEST_F(AnimationAnimationTestNoCompositing,
1764        PendingActivityWithFinishedEventListener) {
1765   EXPECT_EQ("running", animation->playState());
1766   EXPECT_FALSE(animation->HasPendingActivity());
1767 
1768   // Attaching a listener for the finished event indicates pending activity.
1769   Persistent<MockEventListener> event_listener =
1770       MakeGarbageCollected<MockEventListener>();
1771   animation->addEventListener(event_type_names::kFinish, event_listener);
1772   EXPECT_TRUE(animation->HasPendingActivity());
1773 
1774   // Synchronous finish clears pending activity.
1775   animation->finish();
1776   EXPECT_EQ("finished", animation->playState());
1777   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
1778   EXPECT_TRUE(animation->HasPendingActivity());
1779   animation->pending_finished_event_ = nullptr;
1780   EXPECT_FALSE(animation->HasPendingActivity());
1781 
1782   // Playing an already finished animation resets the finished state.
1783   animation->play();
1784   EXPECT_EQ("running", animation->playState());
1785   SimulateFrame(2000);
1786   EXPECT_TRUE(animation->HasPendingActivity());
1787 
1788   // Finishing the animation asynchronously clears the pending activity.
1789   animation->setCurrentTime(50000);
1790   EXPECT_EQ("finished", animation->playState());
1791   SimulateMicrotask();
1792   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
1793   EXPECT_TRUE(animation->HasPendingActivity());
1794   animation->pending_finished_event_ = nullptr;
1795   EXPECT_FALSE(animation->HasPendingActivity());
1796 
1797   // Canceling an animation clears the pending activity.
1798   animation->play();
1799   EXPECT_EQ("running", animation->playState());
1800   SimulateFrame(2000);
1801   animation->cancel();
1802   EXPECT_EQ("idle", animation->playState());
1803   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
1804   EXPECT_FALSE(animation->HasPendingActivity());
1805 }
1806 
1807 class AnimationPendingAnimationsTest : public RenderingTest {
1808  public:
AnimationPendingAnimationsTest()1809   AnimationPendingAnimationsTest()
1810       : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
1811 
1812   enum CompositingMode { kComposited, kNonComposited };
1813 
SetUp()1814   void SetUp() override {
1815     EnableCompositing();
1816     RenderingTest::SetUp();
1817     GetDocument().GetAnimationClock().ResetTimeForTesting();
1818     timeline = GetDocument().Timeline();
1819     timeline->ResetForTesting();
1820   }
1821 
MakeAnimation(const char * target,CompositingMode mode)1822   Animation* MakeAnimation(const char* target, CompositingMode mode) {
1823     Timing timing;
1824     timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
1825     Persistent<StringKeyframe> start_keyframe =
1826         MakeGarbageCollected<StringKeyframe>();
1827     start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
1828                                         SecureContextMode::kInsecureContext,
1829                                         nullptr);
1830     Persistent<StringKeyframe> end_keyframe =
1831         MakeGarbageCollected<StringKeyframe>();
1832     end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
1833                                       SecureContextMode::kInsecureContext,
1834                                       nullptr);
1835 
1836     StringKeyframeVector keyframes;
1837     keyframes.push_back(start_keyframe);
1838     keyframes.push_back(end_keyframe);
1839 
1840     Element* element = GetElementById(target);
1841     auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
1842 
1843     Animation* animation = timeline->Play(
1844         MakeGarbageCollected<KeyframeEffect>(element, model, timing));
1845 
1846     if (mode == kNonComposited) {
1847       // Having a playback rate of zero is one of several ways to force an
1848       // animation to be non-composited.
1849       animation->updatePlaybackRate(0);
1850     }
1851 
1852     return animation;
1853   }
1854 
Update()1855   bool Update() {
1856     UpdateAllLifecyclePhasesForTest();
1857     GetDocument().GetAnimationClock().UpdateTime(base::TimeTicks());
1858     return GetDocument().GetPendingAnimations().Update(nullptr, true);
1859   }
1860 
NotifyAnimationStarted(Animation * animation)1861   void NotifyAnimationStarted(Animation* animation) {
1862     animation->GetDocument()
1863         ->GetPendingAnimations()
1864         .NotifyCompositorAnimationStarted(0, animation->CompositorGroup());
1865   }
1866 
restartAnimation(Animation * animation)1867   void restartAnimation(Animation* animation) {
1868     animation->cancel();
1869     animation->play();
1870   }
1871 
1872   Persistent<DocumentTimeline> timeline;
1873 };
1874 
TEST_F(AnimationPendingAnimationsTest,PendingAnimationStartSynchronization)1875 TEST_F(AnimationPendingAnimationsTest, PendingAnimationStartSynchronization) {
1876   RunDocumentLifecycle();
1877   SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>");
1878 
1879   Persistent<Animation> animA = MakeAnimation("foo", kComposited);
1880   Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
1881 
1882   // B's start time synchronized with A's start time.
1883   EXPECT_TRUE(Update());
1884   EXPECT_TRUE(animA->pending());
1885   EXPECT_TRUE(animB->pending());
1886   EXPECT_TRUE(animA->HasActiveAnimationsOnCompositor());
1887   EXPECT_FALSE(animB->HasActiveAnimationsOnCompositor());
1888   NotifyAnimationStarted(animA);
1889   EXPECT_FALSE(animA->pending());
1890   EXPECT_FALSE(animB->pending());
1891 }
1892 
TEST_F(AnimationPendingAnimationsTest,PendingAnimationCancelUnblocksSynchronizedStart)1893 TEST_F(AnimationPendingAnimationsTest,
1894        PendingAnimationCancelUnblocksSynchronizedStart) {
1895   RunDocumentLifecycle();
1896   SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>");
1897 
1898   Persistent<Animation> animA = MakeAnimation("foo", kComposited);
1899   Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
1900 
1901   EXPECT_TRUE(Update());
1902   EXPECT_TRUE(animA->pending());
1903   EXPECT_TRUE(animB->pending());
1904   animA->cancel();
1905 
1906   // Animation A no longer blocks B from starting.
1907   EXPECT_FALSE(Update());
1908   EXPECT_FALSE(animB->pending());
1909 }
1910 
TEST_F(AnimationPendingAnimationsTest,PendingAnimationOnlySynchronizeStartsOfNewlyPendingAnimations)1911 TEST_F(AnimationPendingAnimationsTest,
1912        PendingAnimationOnlySynchronizeStartsOfNewlyPendingAnimations) {
1913   RunDocumentLifecycle();
1914   SetBodyInnerHTML(
1915       "<div id='foo'></div><div id='bar'></div><div id='baz'></div>");
1916 
1917   Persistent<Animation> animA = MakeAnimation("foo", kComposited);
1918   Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
1919 
1920   // This test simulates the conditions in crbug.com/666710. The start of a
1921   // non-composited animation is deferred in order to synchronize with a
1922   // composited animation, which is canceled before it starts. Subsequent frames
1923   // produce new composited animations which prevented the non-composited
1924   // animation from ever starting. Non-composited animations should not be
1925   // synchronize with new composited animations if queued up in a prior call to
1926   // PendingAnimations::Update.
1927   EXPECT_TRUE(Update());
1928   EXPECT_TRUE(animA->pending());
1929   EXPECT_TRUE(animB->pending());
1930   animA->cancel();
1931 
1932   Persistent<Animation> animC = MakeAnimation("baz", kComposited);
1933   Persistent<Animation> animD = MakeAnimation("bar", kNonComposited);
1934 
1935   EXPECT_TRUE(Update());
1936   // B's is unblocked despite newly created composited animation.
1937   EXPECT_FALSE(animB->pending());
1938   EXPECT_TRUE(animC->pending());
1939   // D's start time is synchronized with C's start.
1940   EXPECT_TRUE(animD->pending());
1941   NotifyAnimationStarted(animC);
1942   EXPECT_FALSE(animC->pending());
1943   EXPECT_FALSE(animD->pending());
1944 }
1945 
TEST_F(AnimationAnimationTestCompositing,ScrollLinkedAnimationNotCompositedIfScrollSourceIsNotComposited)1946 TEST_F(AnimationAnimationTestCompositing,
1947        ScrollLinkedAnimationNotCompositedIfScrollSourceIsNotComposited) {
1948   GetDocument().GetSettings()->SetPreferCompositingToLCDTextEnabled(false);
1949   SetBodyInnerHTML(R"HTML(
1950     <style>
1951       #scroller { overflow: scroll; width: 100px; height: 100px; }
1952       /* to prevent the mock overlay scrollbar from affecting compositing. */
1953       #scroller::-webkit-scrollbar { display: none; }
1954       #target { width: 100px; height: 200px; will-change: transform; }
1955       #spacer { width: 200px; height: 2000px; }
1956     </style>
1957     <div id ='scroller'>
1958       <div id ='target'></div>
1959       <div id ='spacer'></div>
1960     </div>
1961   )HTML");
1962 
1963   // Create ScrollTimeline
1964   auto* scroller =
1965       To<LayoutBoxModelObject>(GetLayoutObjectByElementId("scroller"));
1966   PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
1967   ASSERT_FALSE(scroller->UsesCompositedScrolling());
1968   scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
1969                                    mojom::blink::ScrollType::kProgrammatic);
1970   ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
1971   DoubleOrScrollTimelineAutoKeyword time_range =
1972       DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
1973   options->setTimeRange(time_range);
1974   options->setScrollSource(GetElementById("scroller"));
1975   ScrollTimeline* scroll_timeline =
1976       ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
1977 
1978   // Create KeyframeEffect
1979   Timing timing;
1980   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
1981 
1982   Persistent<StringKeyframe> start_keyframe =
1983       MakeGarbageCollected<StringKeyframe>();
1984   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
1985                                       SecureContextMode::kInsecureContext,
1986                                       nullptr);
1987   Persistent<StringKeyframe> end_keyframe =
1988       MakeGarbageCollected<StringKeyframe>();
1989   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
1990                                     SecureContextMode::kInsecureContext,
1991                                     nullptr);
1992 
1993   StringKeyframeVector keyframes;
1994   keyframes.push_back(start_keyframe);
1995   keyframes.push_back(end_keyframe);
1996 
1997   Element* element = GetElementById("target");
1998   auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
1999 
2000   // Create scroll-linked animation
2001   NonThrowableExceptionState exception_state;
2002   Animation* scroll_animation = Animation::Create(
2003       MakeGarbageCollected<KeyframeEffect>(element, model, timing),
2004       scroll_timeline, exception_state);
2005 
2006   model->SnapshotAllCompositorKeyframesIfNecessary(
2007       *element, *ComputedStyle::Create(), nullptr);
2008 
2009   UpdateAllLifecyclePhasesForTest();
2010   scroll_animation->play();
2011   EXPECT_EQ(scroll_animation->CheckCanStartAnimationOnCompositor(nullptr),
2012             CompositorAnimations::kTimelineSourceHasInvalidCompositingState);
2013 }
2014 
2015 }  // namespace blink
2016