OLD | NEW |
| (Empty) |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "cc/trees/layer_tree_host.h" | |
6 | |
7 #include "cc/animation/animation_curve.h" | |
8 #include "cc/animation/layer_animation_controller.h" | |
9 #include "cc/animation/scroll_offset_animation_curve.h" | |
10 #include "cc/animation/timing_function.h" | |
11 #include "cc/base/time_util.h" | |
12 #include "cc/layers/layer.h" | |
13 #include "cc/layers/layer_impl.h" | |
14 #include "cc/test/animation_test_common.h" | |
15 #include "cc/test/fake_content_layer.h" | |
16 #include "cc/test/fake_content_layer_client.h" | |
17 #include "cc/test/layer_tree_test.h" | |
18 #include "cc/trees/layer_tree_impl.h" | |
19 | |
20 namespace cc { | |
21 namespace { | |
22 | |
23 class LayerTreeHostAnimationTest : public LayerTreeTest { | |
24 public: | |
25 void SetupTree() override { | |
26 LayerTreeTest::SetupTree(); | |
27 layer_tree_host()->root_layer()->set_layer_animation_delegate(this); | |
28 } | |
29 }; | |
30 | |
31 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to | |
32 // be set. | |
33 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested | |
34 : public LayerTreeHostAnimationTest { | |
35 public: | |
36 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested() | |
37 : num_commits_(0) {} | |
38 | |
39 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
40 | |
41 void BeginMainFrame(const BeginFrameArgs& args) override { | |
42 // We skip the first commit because its the commit that populates the | |
43 // impl thread with a tree. After the second commit, the test is done. | |
44 if (num_commits_ != 1) | |
45 return; | |
46 | |
47 layer_tree_host()->SetNeedsAnimate(); | |
48 // Right now, CommitRequested is going to be true, because during | |
49 // BeginFrame, we force CommitRequested to true to prevent requests from | |
50 // hitting the impl thread. But, when the next DidCommit happens, we should | |
51 // verify that CommitRequested has gone back to false. | |
52 } | |
53 | |
54 void DidCommit() override { | |
55 if (!num_commits_) { | |
56 EXPECT_FALSE(layer_tree_host()->CommitRequested()); | |
57 layer_tree_host()->SetNeedsAnimate(); | |
58 EXPECT_FALSE(layer_tree_host()->CommitRequested()); | |
59 } | |
60 | |
61 // Verifies that the SetNeedsAnimate we made in ::Animate did not | |
62 // trigger CommitRequested. | |
63 EXPECT_FALSE(layer_tree_host()->CommitRequested()); | |
64 EndTest(); | |
65 num_commits_++; | |
66 } | |
67 | |
68 void AfterTest() override {} | |
69 | |
70 private: | |
71 int num_commits_; | |
72 }; | |
73 | |
74 MULTI_THREAD_TEST_F( | |
75 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested); | |
76 | |
77 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate | |
78 // callback, request another frame using SetNeedsAnimate. End the test when | |
79 // animate gets called yet-again, indicating that the proxy is correctly | |
80 // handling the case where SetNeedsAnimate() is called inside the BeginFrame | |
81 // flow. | |
82 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback | |
83 : public LayerTreeHostAnimationTest { | |
84 public: | |
85 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback() | |
86 : num_begin_frames_(0) {} | |
87 | |
88 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
89 | |
90 void BeginMainFrame(const BeginFrameArgs& args) override { | |
91 if (!num_begin_frames_) { | |
92 layer_tree_host()->SetNeedsAnimate(); | |
93 num_begin_frames_++; | |
94 return; | |
95 } | |
96 EndTest(); | |
97 } | |
98 | |
99 void AfterTest() override {} | |
100 | |
101 private: | |
102 int num_begin_frames_; | |
103 }; | |
104 | |
105 MULTI_THREAD_TEST_F( | |
106 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback); | |
107 | |
108 // Add a layer animation and confirm that | |
109 // LayerTreeHostImpl::UpdateAnimationState does get called. | |
110 class LayerTreeHostAnimationTestAddAnimation | |
111 : public LayerTreeHostAnimationTest { | |
112 public: | |
113 LayerTreeHostAnimationTestAddAnimation() | |
114 : update_animation_state_was_called_(false) {} | |
115 | |
116 void BeginTest() override { | |
117 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); | |
118 } | |
119 | |
120 void UpdateAnimationState(LayerTreeHostImpl* host_impl, | |
121 bool has_unfinished_animation) override { | |
122 EXPECT_FALSE(has_unfinished_animation); | |
123 update_animation_state_was_called_ = true; | |
124 } | |
125 | |
126 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
127 Animation::TargetProperty target_property, | |
128 int group) override { | |
129 EXPECT_LT(base::TimeTicks(), monotonic_time); | |
130 | |
131 LayerAnimationController* controller = | |
132 layer_tree_host()->root_layer()->layer_animation_controller(); | |
133 Animation* animation = controller->GetAnimation(Animation::OPACITY); | |
134 if (animation) | |
135 controller->RemoveAnimation(animation->id()); | |
136 | |
137 EndTest(); | |
138 } | |
139 | |
140 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); } | |
141 | |
142 private: | |
143 bool update_animation_state_was_called_; | |
144 }; | |
145 | |
146 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation); | |
147 | |
148 // Add a layer animation to a layer, but continually fail to draw. Confirm that | |
149 // after a while, we do eventually force a draw. | |
150 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws | |
151 : public LayerTreeHostAnimationTest { | |
152 public: | |
153 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws() | |
154 : started_animating_(false) {} | |
155 | |
156 void BeginTest() override { | |
157 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); | |
158 } | |
159 | |
160 void AnimateLayers(LayerTreeHostImpl* host_impl, | |
161 base::TimeTicks monotonic_time) override { | |
162 started_animating_ = true; | |
163 } | |
164 | |
165 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
166 if (started_animating_) | |
167 EndTest(); | |
168 } | |
169 | |
170 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
171 LayerTreeHostImpl::FrameData* frame, | |
172 DrawResult draw_result) override { | |
173 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; | |
174 } | |
175 | |
176 void AfterTest() override {} | |
177 | |
178 private: | |
179 bool started_animating_; | |
180 }; | |
181 | |
182 // Starvation can only be an issue with the MT compositor. | |
183 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws); | |
184 | |
185 // Ensures that animations eventually get deleted. | |
186 class LayerTreeHostAnimationTestAnimationsGetDeleted | |
187 : public LayerTreeHostAnimationTest { | |
188 public: | |
189 LayerTreeHostAnimationTestAnimationsGetDeleted() | |
190 : started_animating_(false) {} | |
191 | |
192 void BeginTest() override { | |
193 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); | |
194 } | |
195 | |
196 void AnimateLayers(LayerTreeHostImpl* host_impl, | |
197 base::TimeTicks monotonic_time) override { | |
198 bool have_animations = !host_impl->animation_registrar() | |
199 ->active_animation_controllers_for_testing() | |
200 .empty(); | |
201 if (!started_animating_ && have_animations) { | |
202 started_animating_ = true; | |
203 return; | |
204 } | |
205 | |
206 if (started_animating_ && !have_animations) | |
207 EndTest(); | |
208 } | |
209 | |
210 void NotifyAnimationFinished(base::TimeTicks monotonic_time, | |
211 Animation::TargetProperty target_property, | |
212 int group) override { | |
213 // Animations on the impl-side controller only get deleted during a commit, | |
214 // so we need to schedule a commit. | |
215 layer_tree_host()->SetNeedsCommit(); | |
216 } | |
217 | |
218 void AfterTest() override {} | |
219 | |
220 private: | |
221 bool started_animating_; | |
222 }; | |
223 | |
224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); | |
225 | |
226 // Ensures that animations continue to be ticked when we are backgrounded. | |
227 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded | |
228 : public LayerTreeHostAnimationTest { | |
229 public: | |
230 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded() | |
231 : num_begin_frames_(0) {} | |
232 | |
233 void BeginTest() override { | |
234 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer()); | |
235 } | |
236 | |
237 // Use WillAnimateLayers to set visible false before the animation runs and | |
238 // causes a commit, so we block the second visible animate in single-thread | |
239 // mode. | |
240 void WillAnimateLayers(LayerTreeHostImpl* host_impl, | |
241 base::TimeTicks monotonic_time) override { | |
242 // Verify that the host can draw, it's just not visible. | |
243 EXPECT_TRUE(host_impl->CanDraw()); | |
244 if (num_begin_frames_ < 2) { | |
245 if (!num_begin_frames_) { | |
246 // We have a long animation running. It should continue to tick even | |
247 // if we are not visible. | |
248 PostSetVisibleToMainThread(false); | |
249 } | |
250 num_begin_frames_++; | |
251 return; | |
252 } | |
253 EndTest(); | |
254 } | |
255 | |
256 void AfterTest() override {} | |
257 | |
258 private: | |
259 int num_begin_frames_; | |
260 }; | |
261 | |
262 SINGLE_AND_MULTI_THREAD_TEST_F( | |
263 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded); | |
264 | |
265 // Ensures that animation time remains monotonic when we switch from foreground | |
266 // to background ticking and back, even if we're skipping draws due to | |
267 // checkerboarding when in the foreground. | |
268 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic | |
269 : public LayerTreeHostAnimationTest { | |
270 public: | |
271 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic() | |
272 : has_background_ticked_(false), num_foreground_animates_(0) {} | |
273 | |
274 void InitializeSettings(LayerTreeSettings* settings) override { | |
275 // Make sure that drawing many times doesn't cause a checkerboarded | |
276 // animation to start so we avoid flake in this test. | |
277 settings->timeout_and_draw_when_animation_checkerboards = false; | |
278 } | |
279 | |
280 void BeginTest() override { | |
281 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer()); | |
282 } | |
283 | |
284 void AnimateLayers(LayerTreeHostImpl* host_impl, | |
285 base::TimeTicks monotonic_time) override { | |
286 EXPECT_GE(monotonic_time, last_tick_time_); | |
287 last_tick_time_ = monotonic_time; | |
288 if (host_impl->visible()) { | |
289 num_foreground_animates_++; | |
290 if (num_foreground_animates_ > 1 && !has_background_ticked_) | |
291 PostSetVisibleToMainThread(false); | |
292 else if (has_background_ticked_) | |
293 EndTest(); | |
294 } else { | |
295 has_background_ticked_ = true; | |
296 PostSetVisibleToMainThread(true); | |
297 } | |
298 } | |
299 | |
300 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
301 LayerTreeHostImpl::FrameData* frame, | |
302 DrawResult draw_result) override { | |
303 if (TestEnded()) | |
304 return draw_result; | |
305 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; | |
306 } | |
307 | |
308 void AfterTest() override {} | |
309 | |
310 private: | |
311 bool has_background_ticked_; | |
312 int num_foreground_animates_; | |
313 base::TimeTicks last_tick_time_; | |
314 }; | |
315 | |
316 SINGLE_AND_MULTI_THREAD_TEST_F( | |
317 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic); | |
318 | |
319 // Ensures that animations do not tick when we are backgrounded and | |
320 // and we have an empty active tree. | |
321 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree | |
322 : public LayerTreeHostAnimationTest { | |
323 protected: | |
324 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree() | |
325 : active_tree_was_animated_(false) {} | |
326 | |
327 base::TimeDelta BackgroundAnimationInterval(LayerTreeHostImpl* host_impl) { | |
328 return base::TimeDelta::FromSecondsD( | |
329 1.0 / host_impl->settings().background_animation_rate); | |
330 } | |
331 | |
332 void BeginTest() override { | |
333 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); | |
334 } | |
335 | |
336 void NotifyAnimationFinished(base::TimeTicks monotonic_time, | |
337 Animation::TargetProperty target_property, | |
338 int group) override { | |
339 // Replace animated commits with an empty tree. | |
340 layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL)); | |
341 } | |
342 | |
343 void DidCommit() override { | |
344 // This alternates setting an empty tree and a non-empty tree with an | |
345 // animation. | |
346 switch (layer_tree_host()->source_frame_number()) { | |
347 case 1: | |
348 // Wait for NotifyAnimationFinished to commit an empty tree. | |
349 break; | |
350 case 2: | |
351 SetupTree(); | |
352 AddOpacityTransitionToLayer( | |
353 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true); | |
354 break; | |
355 case 3: | |
356 // Wait for NotifyAnimationFinished to commit an empty tree. | |
357 break; | |
358 case 4: | |
359 EndTest(); | |
360 break; | |
361 } | |
362 } | |
363 | |
364 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
365 // At the start of every commit, block activations and make sure | |
366 // we are backgrounded. | |
367 if (host_impl->settings().impl_side_painting) | |
368 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
369 PostSetVisibleToMainThread(false); | |
370 } | |
371 | |
372 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
373 if (!host_impl->settings().impl_side_painting) { | |
374 // There are no activations to block if we're not impl-side-painting, | |
375 // so just advance the test immediately. | |
376 if (host_impl->active_tree()->source_frame_number() < 3) | |
377 UnblockActivations(host_impl); | |
378 return; | |
379 } | |
380 | |
381 // We block activation for several ticks to make sure that, even though | |
382 // there is a pending tree with animations, we still do not background | |
383 // tick if the active tree is empty. | |
384 if (host_impl->pending_tree()->source_frame_number() < 3) { | |
385 base::MessageLoopProxy::current()->PostDelayedTask( | |
386 FROM_HERE, | |
387 base::Bind( | |
388 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree:: | |
389 UnblockActivations, | |
390 base::Unretained(this), host_impl), | |
391 4 * BackgroundAnimationInterval(host_impl)); | |
392 } | |
393 } | |
394 | |
395 virtual void UnblockActivations(LayerTreeHostImpl* host_impl) { | |
396 if (host_impl->settings().impl_side_painting) | |
397 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
398 } | |
399 | |
400 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
401 active_tree_was_animated_ = false; | |
402 | |
403 // Verify that commits are actually alternating with empty / non-empty | |
404 // trees. | |
405 int frame_number = host_impl->active_tree()->source_frame_number(); | |
406 switch (frame_number) { | |
407 case 0: | |
408 case 2: | |
409 EXPECT_TRUE(host_impl->active_tree()->root_layer()) | |
410 << "frame: " << frame_number; | |
411 break; | |
412 case 1: | |
413 case 3: | |
414 EXPECT_FALSE(host_impl->active_tree()->root_layer()) | |
415 << "frame: " << frame_number; | |
416 break; | |
417 } | |
418 | |
419 if (host_impl->active_tree()->source_frame_number() < 3) { | |
420 // Initiate the next commit after a delay to give us a chance to | |
421 // background tick if the active tree isn't empty. | |
422 base::MessageLoopProxy::current()->PostDelayedTask( | |
423 FROM_HERE, | |
424 base::Bind( | |
425 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree:: | |
426 InitiateNextCommit, | |
427 base::Unretained(this), host_impl), | |
428 4 * BackgroundAnimationInterval(host_impl)); | |
429 } | |
430 } | |
431 | |
432 void WillAnimateLayers(LayerTreeHostImpl* host_impl, | |
433 base::TimeTicks monotonic_time) override { | |
434 EXPECT_TRUE(host_impl->active_tree()->root_layer()); | |
435 active_tree_was_animated_ = true; | |
436 } | |
437 | |
438 void InitiateNextCommit(LayerTreeHostImpl* host_impl) { | |
439 // Verify that we actually animated when we should have. | |
440 bool has_active_tree = host_impl->active_tree()->root_layer(); | |
441 EXPECT_EQ(has_active_tree, active_tree_was_animated_); | |
442 | |
443 // The next commit is blocked until we become visible again. | |
444 PostSetVisibleToMainThread(true); | |
445 } | |
446 | |
447 void AfterTest() override {} | |
448 | |
449 bool active_tree_was_animated_; | |
450 }; | |
451 | |
452 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( | |
453 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree); | |
454 | |
455 // Ensure that an animation's timing function is respected. | |
456 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction | |
457 : public LayerTreeHostAnimationTest { | |
458 public: | |
459 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} | |
460 | |
461 void SetupTree() override { | |
462 LayerTreeHostAnimationTest::SetupTree(); | |
463 content_ = FakeContentLayer::Create(&client_); | |
464 content_->SetBounds(gfx::Size(4, 4)); | |
465 layer_tree_host()->root_layer()->AddChild(content_); | |
466 } | |
467 | |
468 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); } | |
469 | |
470 void AnimateLayers(LayerTreeHostImpl* host_impl, | |
471 base::TimeTicks monotonic_time) override { | |
472 LayerAnimationController* controller_impl = | |
473 host_impl->active_tree()->root_layer()->children()[0]-> | |
474 layer_animation_controller(); | |
475 Animation* animation = controller_impl->GetAnimation(Animation::OPACITY); | |
476 if (!animation) | |
477 return; | |
478 | |
479 const FloatAnimationCurve* curve = | |
480 animation->curve()->ToFloatAnimationCurve(); | |
481 float start_opacity = curve->GetValue(base::TimeDelta()); | |
482 float end_opacity = curve->GetValue(curve->Duration()); | |
483 float linearly_interpolated_opacity = | |
484 0.25f * end_opacity + 0.75f * start_opacity; | |
485 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f); | |
486 // If the linear timing function associated with this animation was not | |
487 // picked up, then the linearly interpolated opacity would be different | |
488 // because of the default ease timing function. | |
489 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time)); | |
490 | |
491 EndTest(); | |
492 } | |
493 | |
494 void AfterTest() override {} | |
495 | |
496 FakeContentLayerClient client_; | |
497 scoped_refptr<FakeContentLayer> content_; | |
498 }; | |
499 | |
500 SINGLE_AND_MULTI_THREAD_TEST_F( | |
501 LayerTreeHostAnimationTestAddAnimationWithTimingFunction); | |
502 | |
503 // Ensures that main thread animations have their start times synchronized with | |
504 // impl thread animations. | |
505 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes | |
506 : public LayerTreeHostAnimationTest { | |
507 public: | |
508 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {} | |
509 | |
510 void SetupTree() override { | |
511 LayerTreeHostAnimationTest::SetupTree(); | |
512 content_ = FakeContentLayer::Create(&client_); | |
513 content_->SetBounds(gfx::Size(4, 4)); | |
514 content_->set_layer_animation_delegate(this); | |
515 layer_tree_host()->root_layer()->AddChild(content_); | |
516 } | |
517 | |
518 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); } | |
519 | |
520 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
521 Animation::TargetProperty target_property, | |
522 int group) override { | |
523 LayerAnimationController* controller = | |
524 layer_tree_host()->root_layer()->children()[0]-> | |
525 layer_animation_controller(); | |
526 Animation* animation = controller->GetAnimation(Animation::OPACITY); | |
527 main_start_time_ = animation->start_time(); | |
528 controller->RemoveAnimation(animation->id()); | |
529 EndTest(); | |
530 } | |
531 | |
532 void UpdateAnimationState(LayerTreeHostImpl* impl_host, | |
533 bool has_unfinished_animation) override { | |
534 LayerAnimationController* controller = | |
535 impl_host->active_tree()->root_layer()->children()[0]-> | |
536 layer_animation_controller(); | |
537 Animation* animation = controller->GetAnimation(Animation::OPACITY); | |
538 if (!animation) | |
539 return; | |
540 | |
541 impl_start_time_ = animation->start_time(); | |
542 } | |
543 | |
544 void AfterTest() override { | |
545 EXPECT_EQ(impl_start_time_, main_start_time_); | |
546 EXPECT_LT(base::TimeTicks(), impl_start_time_); | |
547 } | |
548 | |
549 private: | |
550 base::TimeTicks main_start_time_; | |
551 base::TimeTicks impl_start_time_; | |
552 FakeContentLayerClient client_; | |
553 scoped_refptr<FakeContentLayer> content_; | |
554 }; | |
555 | |
556 SINGLE_AND_MULTI_THREAD_TEST_F( | |
557 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes); | |
558 | |
559 // Ensures that notify animation finished is called. | |
560 class LayerTreeHostAnimationTestAnimationFinishedEvents | |
561 : public LayerTreeHostAnimationTest { | |
562 public: | |
563 LayerTreeHostAnimationTestAnimationFinishedEvents() {} | |
564 | |
565 void BeginTest() override { | |
566 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); | |
567 } | |
568 | |
569 void NotifyAnimationFinished(base::TimeTicks monotonic_time, | |
570 Animation::TargetProperty target_property, | |
571 int group) override { | |
572 LayerAnimationController* controller = | |
573 layer_tree_host()->root_layer()->layer_animation_controller(); | |
574 Animation* animation = controller->GetAnimation(Animation::OPACITY); | |
575 if (animation) | |
576 controller->RemoveAnimation(animation->id()); | |
577 EndTest(); | |
578 } | |
579 | |
580 void AfterTest() override {} | |
581 }; | |
582 | |
583 SINGLE_AND_MULTI_THREAD_TEST_F( | |
584 LayerTreeHostAnimationTestAnimationFinishedEvents); | |
585 | |
586 // Ensures that when opacity is being animated, this value does not cause the | |
587 // subtree to be skipped. | |
588 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity | |
589 : public LayerTreeHostAnimationTest { | |
590 public: | |
591 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity() | |
592 : update_check_layer_(FakeContentLayer::Create(&client_)) { | |
593 } | |
594 | |
595 void SetupTree() override { | |
596 update_check_layer_->SetOpacity(0.f); | |
597 layer_tree_host()->SetRootLayer(update_check_layer_); | |
598 LayerTreeHostAnimationTest::SetupTree(); | |
599 } | |
600 | |
601 void BeginTest() override { | |
602 PostAddAnimationToMainThread(update_check_layer_.get()); | |
603 } | |
604 | |
605 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
606 LayerAnimationController* controller_impl = | |
607 host_impl->active_tree()->root_layer()->layer_animation_controller(); | |
608 Animation* animation_impl = | |
609 controller_impl->GetAnimation(Animation::OPACITY); | |
610 controller_impl->RemoveAnimation(animation_impl->id()); | |
611 EndTest(); | |
612 } | |
613 | |
614 void AfterTest() override { | |
615 // Update() should have been called once, proving that the layer was not | |
616 // skipped. | |
617 EXPECT_EQ(1u, update_check_layer_->update_count()); | |
618 | |
619 // clear update_check_layer_ so LayerTreeHost dies. | |
620 update_check_layer_ = NULL; | |
621 } | |
622 | |
623 private: | |
624 FakeContentLayerClient client_; | |
625 scoped_refptr<FakeContentLayer> update_check_layer_; | |
626 }; | |
627 | |
628 SINGLE_AND_MULTI_THREAD_TEST_F( | |
629 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity); | |
630 | |
631 // Layers added to tree with existing active animations should have the | |
632 // animation correctly recognized. | |
633 class LayerTreeHostAnimationTestLayerAddedWithAnimation | |
634 : public LayerTreeHostAnimationTest { | |
635 public: | |
636 LayerTreeHostAnimationTestLayerAddedWithAnimation() {} | |
637 | |
638 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
639 | |
640 void DidCommit() override { | |
641 if (layer_tree_host()->source_frame_number() == 1) { | |
642 scoped_refptr<Layer> layer = Layer::Create(); | |
643 layer->set_layer_animation_delegate(this); | |
644 | |
645 // Any valid AnimationCurve will do here. | |
646 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve()); | |
647 scoped_ptr<Animation> animation( | |
648 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY)); | |
649 layer->layer_animation_controller()->AddAnimation(animation.Pass()); | |
650 | |
651 // We add the animation *before* attaching the layer to the tree. | |
652 layer_tree_host()->root_layer()->AddChild(layer); | |
653 } | |
654 } | |
655 | |
656 void AnimateLayers(LayerTreeHostImpl* impl_host, | |
657 base::TimeTicks monotonic_time) override { | |
658 EndTest(); | |
659 } | |
660 | |
661 void AfterTest() override {} | |
662 }; | |
663 | |
664 SINGLE_AND_MULTI_THREAD_TEST_F( | |
665 LayerTreeHostAnimationTestLayerAddedWithAnimation); | |
666 | |
667 class LayerTreeHostAnimationTestCancelAnimateCommit | |
668 : public LayerTreeHostAnimationTest { | |
669 public: | |
670 LayerTreeHostAnimationTestCancelAnimateCommit() | |
671 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {} | |
672 | |
673 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
674 | |
675 void BeginMainFrame(const BeginFrameArgs& args) override { | |
676 num_begin_frames_++; | |
677 // No-op animate will cancel the commit. | |
678 if (layer_tree_host()->source_frame_number() == 1) { | |
679 EndTest(); | |
680 return; | |
681 } | |
682 layer_tree_host()->SetNeedsAnimate(); | |
683 } | |
684 | |
685 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
686 num_commit_calls_++; | |
687 if (impl->active_tree()->source_frame_number() > 1) | |
688 FAIL() << "Commit should have been canceled."; | |
689 } | |
690 | |
691 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
692 num_draw_calls_++; | |
693 if (impl->active_tree()->source_frame_number() > 1) | |
694 FAIL() << "Draw should have been canceled."; | |
695 } | |
696 | |
697 void AfterTest() override { | |
698 EXPECT_EQ(2, num_begin_frames_); | |
699 EXPECT_EQ(1, num_commit_calls_); | |
700 EXPECT_EQ(1, num_draw_calls_); | |
701 } | |
702 | |
703 private: | |
704 int num_begin_frames_; | |
705 int num_commit_calls_; | |
706 int num_draw_calls_; | |
707 FakeContentLayerClient client_; | |
708 scoped_refptr<FakeContentLayer> content_; | |
709 }; | |
710 | |
711 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit); | |
712 | |
713 class LayerTreeHostAnimationTestForceRedraw | |
714 : public LayerTreeHostAnimationTest { | |
715 public: | |
716 LayerTreeHostAnimationTestForceRedraw() | |
717 : num_animate_(0), num_draw_layers_(0) {} | |
718 | |
719 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
720 | |
721 void BeginMainFrame(const BeginFrameArgs& args) override { | |
722 if (++num_animate_ < 2) | |
723 layer_tree_host()->SetNeedsAnimate(); | |
724 } | |
725 | |
726 void Layout() override { layer_tree_host()->SetNextCommitForcesRedraw(); } | |
727 | |
728 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
729 if (++num_draw_layers_ == 2) | |
730 EndTest(); | |
731 } | |
732 | |
733 void AfterTest() override { | |
734 // The first commit will always draw; make sure the second draw triggered | |
735 // by the animation was not cancelled. | |
736 EXPECT_EQ(2, num_draw_layers_); | |
737 EXPECT_EQ(2, num_animate_); | |
738 } | |
739 | |
740 private: | |
741 int num_animate_; | |
742 int num_draw_layers_; | |
743 }; | |
744 | |
745 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw); | |
746 | |
747 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit | |
748 : public LayerTreeHostAnimationTest { | |
749 public: | |
750 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit() | |
751 : num_animate_(0), num_draw_layers_(0) {} | |
752 | |
753 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
754 | |
755 void BeginMainFrame(const BeginFrameArgs& args) override { | |
756 if (++num_animate_ <= 2) { | |
757 layer_tree_host()->SetNeedsCommit(); | |
758 layer_tree_host()->SetNeedsAnimate(); | |
759 } | |
760 } | |
761 | |
762 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
763 if (++num_draw_layers_ == 2) | |
764 EndTest(); | |
765 } | |
766 | |
767 void AfterTest() override { | |
768 // The first commit will always draw; make sure the second draw triggered | |
769 // by the SetNeedsCommit was not cancelled. | |
770 EXPECT_EQ(2, num_draw_layers_); | |
771 EXPECT_GE(num_animate_, 2); | |
772 } | |
773 | |
774 private: | |
775 int num_animate_; | |
776 int num_draw_layers_; | |
777 }; | |
778 | |
779 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit); | |
780 | |
781 // Make sure the main thread can still execute animations when CanDraw() is not | |
782 // true. | |
783 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw | |
784 : public LayerTreeHostAnimationTest { | |
785 public: | |
786 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {} | |
787 | |
788 void SetupTree() override { | |
789 LayerTreeHostAnimationTest::SetupTree(); | |
790 content_ = FakeContentLayer::Create(&client_); | |
791 content_->SetBounds(gfx::Size(4, 4)); | |
792 content_->set_layer_animation_delegate(this); | |
793 layer_tree_host()->root_layer()->AddChild(content_); | |
794 } | |
795 | |
796 void BeginTest() override { | |
797 layer_tree_host()->SetViewportSize(gfx::Size()); | |
798 PostAddAnimationToMainThread(content_.get()); | |
799 } | |
800 | |
801 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
802 Animation::TargetProperty target_property, | |
803 int group) override { | |
804 started_times_++; | |
805 } | |
806 | |
807 void NotifyAnimationFinished(base::TimeTicks monotonic_time, | |
808 Animation::TargetProperty target_property, | |
809 int group) override { | |
810 EndTest(); | |
811 } | |
812 | |
813 void AfterTest() override { EXPECT_EQ(1, started_times_); } | |
814 | |
815 private: | |
816 int started_times_; | |
817 FakeContentLayerClient client_; | |
818 scoped_refptr<FakeContentLayer> content_; | |
819 }; | |
820 | |
821 SINGLE_AND_MULTI_THREAD_TEST_F( | |
822 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw); | |
823 | |
824 // Make sure the main thread can still execute animations when the renderer is | |
825 // backgrounded. | |
826 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible | |
827 : public LayerTreeHostAnimationTest { | |
828 public: | |
829 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {} | |
830 | |
831 void SetupTree() override { | |
832 LayerTreeHostAnimationTest::SetupTree(); | |
833 content_ = FakeContentLayer::Create(&client_); | |
834 content_->SetBounds(gfx::Size(4, 4)); | |
835 content_->set_layer_animation_delegate(this); | |
836 layer_tree_host()->root_layer()->AddChild(content_); | |
837 } | |
838 | |
839 void BeginTest() override { | |
840 visible_ = true; | |
841 PostAddAnimationToMainThread(content_.get()); | |
842 } | |
843 | |
844 void DidCommit() override { | |
845 visible_ = false; | |
846 layer_tree_host()->SetVisible(false); | |
847 } | |
848 | |
849 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
850 Animation::TargetProperty target_property, | |
851 int group) override { | |
852 EXPECT_FALSE(visible_); | |
853 started_times_++; | |
854 } | |
855 | |
856 void NotifyAnimationFinished(base::TimeTicks monotonic_time, | |
857 Animation::TargetProperty target_property, | |
858 int group) override { | |
859 EXPECT_FALSE(visible_); | |
860 EXPECT_EQ(1, started_times_); | |
861 EndTest(); | |
862 } | |
863 | |
864 void AfterTest() override {} | |
865 | |
866 private: | |
867 bool visible_; | |
868 int started_times_; | |
869 FakeContentLayerClient client_; | |
870 scoped_refptr<FakeContentLayer> content_; | |
871 }; | |
872 | |
873 SINGLE_AND_MULTI_THREAD_TEST_F( | |
874 LayerTreeHostAnimationTestRunAnimationWhenNotVisible); | |
875 | |
876 // Animations should not be started when frames are being skipped due to | |
877 // checkerboard. | |
878 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations | |
879 : public LayerTreeHostAnimationTest { | |
880 void SetupTree() override { | |
881 LayerTreeHostAnimationTest::SetupTree(); | |
882 content_ = FakeContentLayer::Create(&client_); | |
883 content_->SetBounds(gfx::Size(4, 4)); | |
884 content_->set_layer_animation_delegate(this); | |
885 layer_tree_host()->root_layer()->AddChild(content_); | |
886 } | |
887 | |
888 void InitializeSettings(LayerTreeSettings* settings) override { | |
889 // Make sure that drawing many times doesn't cause a checkerboarded | |
890 // animation to start so we avoid flake in this test. | |
891 settings->timeout_and_draw_when_animation_checkerboards = false; | |
892 } | |
893 | |
894 void BeginTest() override { | |
895 prevented_draw_ = 0; | |
896 added_animations_ = 0; | |
897 started_times_ = 0; | |
898 | |
899 PostSetNeedsCommitToMainThread(); | |
900 } | |
901 | |
902 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
903 LayerTreeHostImpl::FrameData* frame_data, | |
904 DrawResult draw_result) override { | |
905 if (added_animations_ < 2) | |
906 return draw_result; | |
907 if (TestEnded()) | |
908 return draw_result; | |
909 // Act like there is checkerboard when the second animation wants to draw. | |
910 ++prevented_draw_; | |
911 if (prevented_draw_ > 2) | |
912 EndTest(); | |
913 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; | |
914 } | |
915 | |
916 void DidCommitAndDrawFrame() override { | |
917 switch (layer_tree_host()->source_frame_number()) { | |
918 case 1: | |
919 // The animation is longer than 1 BeginFrame interval. | |
920 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false); | |
921 added_animations_++; | |
922 break; | |
923 case 2: | |
924 // This second animation will not be drawn so it should not start. | |
925 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5); | |
926 added_animations_++; | |
927 break; | |
928 } | |
929 } | |
930 | |
931 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
932 Animation::TargetProperty target_property, | |
933 int group) override { | |
934 if (TestEnded()) | |
935 return; | |
936 started_times_++; | |
937 } | |
938 | |
939 void AfterTest() override { | |
940 // Make sure we tried to draw the second animation but failed. | |
941 EXPECT_LT(0, prevented_draw_); | |
942 // The first animation should be started, but the second should not because | |
943 // of checkerboard. | |
944 EXPECT_EQ(1, started_times_); | |
945 } | |
946 | |
947 int prevented_draw_; | |
948 int added_animations_; | |
949 int started_times_; | |
950 FakeContentLayerClient client_; | |
951 scoped_refptr<FakeContentLayer> content_; | |
952 }; | |
953 | |
954 MULTI_THREAD_TEST_F( | |
955 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations); | |
956 | |
957 // Verifies that scroll offset animations are only accepted when impl-scrolling | |
958 // is supported, and that when scroll offset animations are accepted, | |
959 // scroll offset updates are sent back to the main thread. | |
960 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated | |
961 : public LayerTreeHostAnimationTest { | |
962 public: | |
963 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {} | |
964 | |
965 void SetupTree() override { | |
966 LayerTreeHostAnimationTest::SetupTree(); | |
967 | |
968 scroll_layer_ = FakeContentLayer::Create(&client_); | |
969 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); | |
970 scroll_layer_->SetBounds(gfx::Size(1000, 1000)); | |
971 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); | |
972 layer_tree_host()->root_layer()->AddChild(scroll_layer_); | |
973 } | |
974 | |
975 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
976 | |
977 void DidCommit() override { | |
978 switch (layer_tree_host()->source_frame_number()) { | |
979 case 1: { | |
980 scoped_ptr<ScrollOffsetAnimationCurve> curve( | |
981 ScrollOffsetAnimationCurve::Create( | |
982 gfx::ScrollOffset(500.f, 550.f), | |
983 EaseInOutTimingFunction::Create())); | |
984 scoped_ptr<Animation> animation( | |
985 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET)); | |
986 animation->set_needs_synchronized_start_time(true); | |
987 bool animation_added = scroll_layer_->AddAnimation(animation.Pass()); | |
988 bool impl_scrolling_supported = | |
989 layer_tree_host()->proxy()->SupportsImplScrolling(); | |
990 EXPECT_EQ(impl_scrolling_supported, animation_added); | |
991 if (!impl_scrolling_supported) | |
992 EndTest(); | |
993 break; | |
994 } | |
995 default: | |
996 if (scroll_layer_->scroll_offset().x() > 10 && | |
997 scroll_layer_->scroll_offset().y() > 20) | |
998 EndTest(); | |
999 } | |
1000 } | |
1001 | |
1002 void AfterTest() override {} | |
1003 | |
1004 private: | |
1005 FakeContentLayerClient client_; | |
1006 scoped_refptr<FakeContentLayer> scroll_layer_; | |
1007 }; | |
1008 | |
1009 SINGLE_AND_MULTI_THREAD_TEST_F( | |
1010 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated); | |
1011 | |
1012 // Verifies that when the main thread removes a scroll animation and sets a new | |
1013 // scroll position, the active tree takes on exactly this new scroll position | |
1014 // after activation, and the main thread doesn't receive a spurious scroll | |
1015 // delta. | |
1016 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval | |
1017 : public LayerTreeHostAnimationTest { | |
1018 public: | |
1019 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval() | |
1020 : final_postion_(50.0, 100.0) {} | |
1021 | |
1022 void SetupTree() override { | |
1023 LayerTreeHostAnimationTest::SetupTree(); | |
1024 | |
1025 scroll_layer_ = FakeContentLayer::Create(&client_); | |
1026 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); | |
1027 scroll_layer_->SetBounds(gfx::Size(10000, 10000)); | |
1028 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0)); | |
1029 layer_tree_host()->root_layer()->AddChild(scroll_layer_); | |
1030 | |
1031 scoped_ptr<ScrollOffsetAnimationCurve> curve( | |
1032 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f), | |
1033 EaseInOutTimingFunction::Create())); | |
1034 scoped_ptr<Animation> animation( | |
1035 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET)); | |
1036 animation->set_needs_synchronized_start_time(true); | |
1037 scroll_layer_->AddAnimation(animation.Pass()); | |
1038 } | |
1039 | |
1040 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1041 | |
1042 void BeginMainFrame(const BeginFrameArgs& args) override { | |
1043 switch (layer_tree_host()->source_frame_number()) { | |
1044 case 0: | |
1045 break; | |
1046 case 1: { | |
1047 Animation* animation = | |
1048 scroll_layer_->layer_animation_controller()->GetAnimation( | |
1049 Animation::SCROLL_OFFSET); | |
1050 scroll_layer_->layer_animation_controller()->RemoveAnimation( | |
1051 animation->id()); | |
1052 scroll_layer_->SetScrollOffset(final_postion_); | |
1053 break; | |
1054 } | |
1055 default: | |
1056 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset()); | |
1057 } | |
1058 } | |
1059 | |
1060 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
1061 if (host_impl->settings().impl_side_painting) | |
1062 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
1063 } | |
1064 | |
1065 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, | |
1066 const BeginFrameArgs& args) override { | |
1067 if (!host_impl->pending_tree()) | |
1068 return; | |
1069 | |
1070 if (!host_impl->active_tree()->root_layer()) { | |
1071 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
1072 return; | |
1073 } | |
1074 | |
1075 LayerImpl* scroll_layer_impl = | |
1076 host_impl->active_tree()->root_layer()->children()[0]; | |
1077 Animation* animation = | |
1078 scroll_layer_impl->layer_animation_controller()->GetAnimation( | |
1079 Animation::SCROLL_OFFSET); | |
1080 | |
1081 if (!animation || animation->run_state() != Animation::RUNNING) { | |
1082 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
1083 return; | |
1084 } | |
1085 | |
1086 // Block activation until the running animation has a chance to produce a | |
1087 // scroll delta. | |
1088 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta(); | |
1089 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f) | |
1090 return; | |
1091 | |
1092 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
1093 } | |
1094 | |
1095 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
1096 if (!host_impl->settings().impl_side_painting) | |
1097 return; | |
1098 if (host_impl->pending_tree()->source_frame_number() != 1) | |
1099 return; | |
1100 LayerImpl* scroll_layer_impl = | |
1101 host_impl->pending_tree()->root_layer()->children()[0]; | |
1102 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset()); | |
1103 } | |
1104 | |
1105 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
1106 if (host_impl->active_tree()->source_frame_number() != 1) | |
1107 return; | |
1108 LayerImpl* scroll_layer_impl = | |
1109 host_impl->active_tree()->root_layer()->children()[0]; | |
1110 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset()); | |
1111 EndTest(); | |
1112 } | |
1113 | |
1114 void AfterTest() override { | |
1115 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset()); | |
1116 } | |
1117 | |
1118 private: | |
1119 FakeContentLayerClient client_; | |
1120 scoped_refptr<FakeContentLayer> scroll_layer_; | |
1121 const gfx::ScrollOffset final_postion_; | |
1122 }; | |
1123 | |
1124 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval); | |
1125 | |
1126 // When animations are simultaneously added to an existing layer and to a new | |
1127 // layer, they should start at the same time, even when there's already a | |
1128 // running animation on the existing layer. | |
1129 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers | |
1130 : public LayerTreeHostAnimationTest { | |
1131 public: | |
1132 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers() | |
1133 : frame_count_with_pending_tree_(0) {} | |
1134 | |
1135 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1136 | |
1137 void DidCommit() override { | |
1138 if (layer_tree_host()->source_frame_number() == 1) { | |
1139 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1); | |
1140 } else if (layer_tree_host()->source_frame_number() == 2) { | |
1141 AddOpacityTransitionToLayer( | |
1142 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true); | |
1143 | |
1144 scoped_refptr<Layer> layer = Layer::Create(); | |
1145 layer_tree_host()->root_layer()->AddChild(layer); | |
1146 layer->set_layer_animation_delegate(this); | |
1147 layer->SetBounds(gfx::Size(4, 4)); | |
1148 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true); | |
1149 } | |
1150 } | |
1151 | |
1152 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
1153 if (host_impl->settings().impl_side_painting) | |
1154 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
1155 } | |
1156 | |
1157 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
1158 // For the commit that added animations to new and existing layers, keep | |
1159 // blocking activation. We want to verify that even with activation blocked, | |
1160 // the animation on the layer that's already in the active tree won't get a | |
1161 // head start. | |
1162 if (host_impl->settings().impl_side_painting && | |
1163 host_impl->pending_tree()->source_frame_number() != 2) { | |
1164 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
1165 } | |
1166 } | |
1167 | |
1168 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, | |
1169 const BeginFrameArgs& args) override { | |
1170 if (!host_impl->pending_tree() || | |
1171 host_impl->pending_tree()->source_frame_number() != 2) | |
1172 return; | |
1173 | |
1174 frame_count_with_pending_tree_++; | |
1175 if (frame_count_with_pending_tree_ == 2 && | |
1176 host_impl->settings().impl_side_painting) { | |
1177 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
1178 } | |
1179 } | |
1180 | |
1181 void UpdateAnimationState(LayerTreeHostImpl* host_impl, | |
1182 bool has_unfinished_animation) override { | |
1183 LayerAnimationController* root_controller_impl = | |
1184 host_impl->active_tree()->root_layer()->layer_animation_controller(); | |
1185 Animation* root_animation = | |
1186 root_controller_impl->GetAnimation(Animation::OPACITY); | |
1187 if (!root_animation || root_animation->run_state() != Animation::RUNNING) | |
1188 return; | |
1189 | |
1190 LayerAnimationController* child_controller_impl = | |
1191 host_impl->active_tree()->root_layer()->children() | |
1192 [0]->layer_animation_controller(); | |
1193 Animation* child_animation = | |
1194 child_controller_impl->GetAnimation(Animation::OPACITY); | |
1195 EXPECT_EQ(Animation::RUNNING, child_animation->run_state()); | |
1196 EXPECT_EQ(root_animation->start_time(), child_animation->start_time()); | |
1197 root_controller_impl->AbortAnimations(Animation::OPACITY); | |
1198 root_controller_impl->AbortAnimations(Animation::TRANSFORM); | |
1199 child_controller_impl->AbortAnimations(Animation::OPACITY); | |
1200 EndTest(); | |
1201 } | |
1202 | |
1203 void AfterTest() override {} | |
1204 | |
1205 private: | |
1206 int frame_count_with_pending_tree_; | |
1207 }; | |
1208 | |
1209 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( | |
1210 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers); | |
1211 | |
1212 class LayerTreeHostAnimationTestAddAnimationAfterAnimating | |
1213 : public LayerTreeHostAnimationTest { | |
1214 public: | |
1215 LayerTreeHostAnimationTestAddAnimationAfterAnimating() | |
1216 : num_swap_buffers_(0) {} | |
1217 | |
1218 void SetupTree() override { | |
1219 LayerTreeHostAnimationTest::SetupTree(); | |
1220 content_ = Layer::Create(); | |
1221 content_->SetBounds(gfx::Size(4, 4)); | |
1222 layer_tree_host()->root_layer()->AddChild(content_); | |
1223 } | |
1224 | |
1225 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1226 | |
1227 void DidCommit() override { | |
1228 switch (layer_tree_host()->source_frame_number()) { | |
1229 case 1: | |
1230 // First frame: add an animation to the root layer. | |
1231 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5); | |
1232 break; | |
1233 case 2: | |
1234 // Second frame: add an animation to the content layer. The root layer | |
1235 // animation has caused us to animate already during this frame. | |
1236 AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false); | |
1237 break; | |
1238 } | |
1239 } | |
1240 | |
1241 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
1242 // After both animations have started, verify that they have valid | |
1243 // start times. | |
1244 num_swap_buffers_++; | |
1245 AnimationRegistrar::AnimationControllerMap controllers_copy = | |
1246 host_impl->animation_registrar() | |
1247 ->active_animation_controllers_for_testing(); | |
1248 if (controllers_copy.size() == 2u) { | |
1249 EndTest(); | |
1250 EXPECT_GE(num_swap_buffers_, 3); | |
1251 for (auto& it : controllers_copy) { | |
1252 int id = it.first; | |
1253 if (id == host_impl->RootLayer()->id()) { | |
1254 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM); | |
1255 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0); | |
1256 } else if (id == host_impl->RootLayer()->children()[0]->id()) { | |
1257 Animation* anim = it.second->GetAnimation(Animation::OPACITY); | |
1258 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0); | |
1259 } | |
1260 } | |
1261 } | |
1262 } | |
1263 | |
1264 void AfterTest() override {} | |
1265 | |
1266 private: | |
1267 scoped_refptr<Layer> content_; | |
1268 int num_swap_buffers_; | |
1269 }; | |
1270 | |
1271 SINGLE_AND_MULTI_THREAD_TEST_F( | |
1272 LayerTreeHostAnimationTestAddAnimationAfterAnimating); | |
1273 | |
1274 } // namespace | |
1275 } // namespace cc | |
OLD | NEW |