[WebView] Add unique visual state request ids.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob8dab1af16ef499518470c915e0f77f2f0026ec2c
1 // Copyright 2011 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.
5 #include "cc/trees/layer_tree_host.h"
7 #include <algorithm>
9 #include "base/auto_reset.h"
10 #include "base/synchronization/lock.h"
11 #include "cc/animation/timing_function.h"
12 #include "cc/base/swap_promise.h"
13 #include "cc/debug/frame_rate_counter.h"
14 #include "cc/layers/content_layer.h"
15 #include "cc/layers/content_layer_client.h"
16 #include "cc/layers/io_surface_layer.h"
17 #include "cc/layers/layer_impl.h"
18 #include "cc/layers/painted_scrollbar_layer.h"
19 #include "cc/layers/picture_layer.h"
20 #include "cc/layers/solid_color_layer.h"
21 #include "cc/layers/video_layer.h"
22 #include "cc/output/begin_frame_args.h"
23 #include "cc/output/compositor_frame_ack.h"
24 #include "cc/output/copy_output_request.h"
25 #include "cc/output/copy_output_result.h"
26 #include "cc/output/output_surface.h"
27 #include "cc/quads/draw_quad.h"
28 #include "cc/quads/io_surface_draw_quad.h"
29 #include "cc/quads/tile_draw_quad.h"
30 #include "cc/resources/prioritized_resource.h"
31 #include "cc/resources/prioritized_resource_manager.h"
32 #include "cc/resources/resource_update_queue.h"
33 #include "cc/test/fake_content_layer.h"
34 #include "cc/test/fake_content_layer_client.h"
35 #include "cc/test/fake_content_layer_impl.h"
36 #include "cc/test/fake_layer_tree_host_client.h"
37 #include "cc/test/fake_output_surface.h"
38 #include "cc/test/fake_painted_scrollbar_layer.h"
39 #include "cc/test/fake_picture_layer.h"
40 #include "cc/test/fake_picture_layer_impl.h"
41 #include "cc/test/fake_picture_pile.h"
42 #include "cc/test/fake_proxy.h"
43 #include "cc/test/fake_scoped_ui_resource.h"
44 #include "cc/test/fake_video_frame_provider.h"
45 #include "cc/test/geometry_test_utils.h"
46 #include "cc/test/impl_side_painting_settings.h"
47 #include "cc/test/layer_tree_test.h"
48 #include "cc/test/test_shared_bitmap_manager.h"
49 #include "cc/test/test_web_graphics_context_3d.h"
50 #include "cc/trees/layer_tree_host_impl.h"
51 #include "cc/trees/layer_tree_impl.h"
52 #include "cc/trees/single_thread_proxy.h"
53 #include "cc/trees/thread_proxy.h"
54 #include "gpu/GLES2/gl2extchromium.h"
55 #include "skia/ext/refptr.h"
56 #include "testing/gmock/include/gmock/gmock.h"
57 #include "third_party/khronos/GLES2/gl2.h"
58 #include "third_party/khronos/GLES2/gl2ext.h"
59 #include "third_party/skia/include/core/SkPicture.h"
60 #include "ui/gfx/frame_time.h"
61 #include "ui/gfx/geometry/point_conversions.h"
62 #include "ui/gfx/geometry/size_conversions.h"
63 #include "ui/gfx/geometry/vector2d_conversions.h"
65 using testing::_;
66 using testing::AnyNumber;
67 using testing::AtLeast;
68 using testing::Mock;
70 namespace cc {
71 namespace {
73 class LayerTreeHostTest : public LayerTreeTest {};
75 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
76 // when no raster tasks get scheduled.
77 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
78 public:
79 LayerTreeHostTestReadyToActivateEmpty()
80 : did_notify_ready_to_activate_(false),
81 all_tiles_required_for_activation_are_ready_to_draw_(false),
82 required_for_activation_count_(0) {}
84 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
86 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
87 const std::vector<PictureLayerImpl*>& layers = impl->GetPictureLayers();
88 required_for_activation_count_ = 0;
89 for (const auto& layer : layers) {
90 FakePictureLayerImpl* fake_layer =
91 static_cast<FakePictureLayerImpl*>(layer);
92 required_for_activation_count_ +=
93 fake_layer->CountTilesRequiredForActivation();
97 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
98 did_notify_ready_to_activate_ = true;
99 all_tiles_required_for_activation_are_ready_to_draw_ =
100 impl->tile_manager()->IsReadyToActivate();
101 EndTest();
104 void AfterTest() override {
105 EXPECT_TRUE(did_notify_ready_to_activate_);
106 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
107 EXPECT_EQ(size_t(0), required_for_activation_count_);
110 protected:
111 bool did_notify_ready_to_activate_;
112 bool all_tiles_required_for_activation_are_ready_to_draw_;
113 size_t required_for_activation_count_;
116 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
118 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
119 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
120 class LayerTreeHostTestReadyToActivateNonEmpty
121 : public LayerTreeHostTestReadyToActivateEmpty {
122 public:
123 void SetupTree() override {
124 client_.set_fill_with_nonsolid_color(true);
125 scoped_refptr<FakePictureLayer> root_layer =
126 FakePictureLayer::Create(&client_);
127 root_layer->SetBounds(gfx::Size(1024, 1024));
128 root_layer->SetIsDrawable(true);
130 layer_tree_host()->SetRootLayer(root_layer);
131 LayerTreeHostTest::SetupTree();
134 void AfterTest() override {
135 EXPECT_TRUE(did_notify_ready_to_activate_);
136 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
137 EXPECT_LE(size_t(1), required_for_activation_count_);
140 private:
141 FakeContentLayerClient client_;
144 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
146 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
147 // no raster tasks get scheduled.
148 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
149 public:
150 LayerTreeHostTestReadyToDrawEmpty()
151 : did_notify_ready_to_draw_(false),
152 all_tiles_required_for_draw_are_ready_to_draw_(false),
153 required_for_draw_count_(0) {}
155 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
157 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
158 did_notify_ready_to_draw_ = true;
159 const std::vector<PictureLayerImpl*>& layers = impl->GetPictureLayers();
160 all_tiles_required_for_draw_are_ready_to_draw_ =
161 impl->tile_manager()->IsReadyToDraw();
162 for (const auto& layer : layers) {
163 FakePictureLayerImpl* fake_layer =
164 static_cast<FakePictureLayerImpl*>(layer);
165 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw();
168 EndTest();
171 void AfterTest() override {
172 EXPECT_TRUE(did_notify_ready_to_draw_);
173 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
174 EXPECT_EQ(size_t(0), required_for_draw_count_);
177 protected:
178 bool did_notify_ready_to_draw_;
179 bool all_tiles_required_for_draw_are_ready_to_draw_;
180 size_t required_for_draw_count_;
183 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
185 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
186 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
187 class LayerTreeHostTestReadyToDrawNonEmpty
188 : public LayerTreeHostTestReadyToDrawEmpty {
189 public:
190 void SetupTree() override {
191 client_.set_fill_with_nonsolid_color(true);
192 scoped_refptr<FakePictureLayer> root_layer =
193 FakePictureLayer::Create(&client_);
194 root_layer->SetBounds(gfx::Size(1024, 1024));
195 root_layer->SetIsDrawable(true);
197 layer_tree_host()->SetRootLayer(root_layer);
198 LayerTreeHostTest::SetupTree();
201 void AfterTest() override {
202 EXPECT_TRUE(did_notify_ready_to_draw_);
203 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
204 EXPECT_LE(size_t(1), required_for_draw_count_);
207 private:
208 FakeContentLayerClient client_;
211 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
212 // single threaded mode.
213 SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
215 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
216 // draw with frame 0.
217 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
218 public:
219 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
221 void BeginTest() override {
222 PostSetNeedsCommitToMainThread();
223 PostSetNeedsCommitToMainThread();
226 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
227 num_draws_++;
228 if (!impl->active_tree()->source_frame_number())
229 EndTest();
232 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
233 num_commits_++;
236 void AfterTest() override {
237 EXPECT_LE(1, num_commits_);
238 EXPECT_LE(1, num_draws_);
241 private:
242 int num_commits_;
243 int num_draws_;
246 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
248 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
249 // first committed frame draws should lead to another commit.
250 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
251 public:
252 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
254 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
256 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
258 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
259 ++num_commits_;
260 switch (num_commits_) {
261 case 1:
262 PostSetNeedsCommitToMainThread();
263 break;
264 case 2:
265 EndTest();
266 break;
267 default:
268 NOTREACHED();
272 void AfterTest() override {
273 EXPECT_EQ(2, num_commits_);
274 EXPECT_LE(1, num_draws_);
277 private:
278 int num_commits_;
279 int num_draws_;
282 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
284 // Verify that we pass property values in PushPropertiesTo.
285 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
286 protected:
287 void SetupTree() override {
288 scoped_refptr<Layer> root = Layer::Create();
289 root->CreateRenderSurface();
290 root->SetBounds(gfx::Size(10, 10));
291 layer_tree_host()->SetRootLayer(root);
292 LayerTreeHostTest::SetupTree();
295 enum Properties {
296 STARTUP,
297 BOUNDS,
298 HIDE_LAYER_AND_SUBTREE,
299 DRAWS_CONTENT,
300 DONE,
303 void BeginTest() override {
304 index_ = STARTUP;
305 PostSetNeedsCommitToMainThread();
308 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
309 VerifyAfterValues(impl->active_tree()->root_layer());
312 void DidCommitAndDrawFrame() override {
313 SetBeforeValues(layer_tree_host()->root_layer());
314 VerifyBeforeValues(layer_tree_host()->root_layer());
316 ++index_;
317 if (index_ == DONE) {
318 EndTest();
319 return;
322 SetAfterValues(layer_tree_host()->root_layer());
325 void AfterTest() override {}
327 void VerifyBeforeValues(Layer* layer) {
328 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
329 EXPECT_FALSE(layer->hide_layer_and_subtree());
330 EXPECT_FALSE(layer->DrawsContent());
333 void SetBeforeValues(Layer* layer) {
334 layer->SetBounds(gfx::Size(10, 10));
335 layer->SetHideLayerAndSubtree(false);
336 layer->SetIsDrawable(false);
339 void VerifyAfterValues(LayerImpl* layer) {
340 switch (static_cast<Properties>(index_)) {
341 case STARTUP:
342 case DONE:
343 break;
344 case BOUNDS:
345 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
346 break;
347 case HIDE_LAYER_AND_SUBTREE:
348 EXPECT_TRUE(layer->hide_layer_and_subtree());
349 break;
350 case DRAWS_CONTENT:
351 EXPECT_TRUE(layer->DrawsContent());
352 break;
356 void SetAfterValues(Layer* layer) {
357 switch (static_cast<Properties>(index_)) {
358 case STARTUP:
359 case DONE:
360 break;
361 case BOUNDS:
362 layer->SetBounds(gfx::Size(20, 20));
363 break;
364 case HIDE_LAYER_AND_SUBTREE:
365 layer->SetHideLayerAndSubtree(true);
366 break;
367 case DRAWS_CONTENT:
368 layer->SetIsDrawable(true);
369 break;
373 int index_;
376 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
378 // 1 setNeedsRedraw after the first commit has completed should lead to 1
379 // additional draw.
380 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
381 public:
382 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
384 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
386 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
387 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
388 if (!num_draws_) {
389 // Redraw again to verify that the second redraw doesn't commit.
390 PostSetNeedsRedrawToMainThread();
391 } else {
392 EndTest();
394 num_draws_++;
397 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
398 EXPECT_EQ(0, num_draws_);
399 num_commits_++;
402 void AfterTest() override {
403 EXPECT_GE(2, num_draws_);
404 EXPECT_EQ(1, num_commits_);
407 private:
408 int num_commits_;
409 int num_draws_;
412 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
414 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
415 // must contain invalid_rect.
416 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
417 public:
418 LayerTreeHostTestSetNeedsRedrawRect()
419 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
421 void BeginTest() override {
422 if (layer_tree_host()->settings().impl_side_painting)
423 root_layer_ = FakePictureLayer::Create(&client_);
424 else
425 root_layer_ = ContentLayer::Create(&client_);
426 root_layer_->SetIsDrawable(true);
427 root_layer_->SetBounds(bounds_);
428 layer_tree_host()->SetRootLayer(root_layer_);
429 layer_tree_host()->SetViewportSize(bounds_);
430 PostSetNeedsCommitToMainThread();
433 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
434 LayerTreeHostImpl::FrameData* frame_data,
435 DrawResult draw_result) override {
436 EXPECT_EQ(DRAW_SUCCESS, draw_result);
438 gfx::RectF root_damage_rect;
439 if (!frame_data->render_passes.empty())
440 root_damage_rect = frame_data->render_passes.back()->damage_rect;
442 if (!num_draws_) {
443 // If this is the first frame, expect full frame damage.
444 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_));
445 } else {
446 // Check that invalid_rect_ is indeed repainted.
447 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
450 return draw_result;
453 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
454 if (!num_draws_) {
455 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
456 } else {
457 EndTest();
459 num_draws_++;
462 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
464 private:
465 int num_draws_;
466 const gfx::Size bounds_;
467 const gfx::Rect invalid_rect_;
468 FakeContentLayerClient client_;
469 scoped_refptr<Layer> root_layer_;
472 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
474 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
475 public:
476 void InitializeSettings(LayerTreeSettings* settings) override {
477 settings->layer_transforms_should_scale_layer_contents = true;
480 void SetupTree() override {
481 root_layer_ = Layer::Create();
482 root_layer_->SetBounds(gfx::Size(10, 20));
483 root_layer_->CreateRenderSurface();
485 if (layer_tree_host()->settings().impl_side_painting)
486 scaled_layer_ = FakePictureLayer::Create(&client_);
487 else
488 scaled_layer_ = FakeContentLayer::Create(&client_);
489 scaled_layer_->SetBounds(gfx::Size(1, 1));
490 root_layer_->AddChild(scaled_layer_);
492 layer_tree_host()->SetRootLayer(root_layer_);
493 LayerTreeHostTest::SetupTree();
496 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
498 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
499 if (host_impl->active_tree()->source_frame_number() == 1)
500 EndTest();
503 void DidCommit() override {
504 switch (layer_tree_host()->source_frame_number()) {
505 case 1:
506 // SetBounds grows the layer and exposes new content.
507 if (layer_tree_host()->settings().impl_side_painting) {
508 scaled_layer_->SetBounds(gfx::Size(4, 4));
509 } else {
510 // Changing the device scale factor causes a commit. It also changes
511 // the content bounds of |scaled_layer_|, which should not generate
512 // a second commit as a result.
513 layer_tree_host()->SetDeviceScaleFactor(4.f);
515 break;
516 default:
517 // No extra commits.
518 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
522 void AfterTest() override {
523 EXPECT_EQ(gfx::Size(4, 4).ToString(),
524 scaled_layer_->content_bounds().ToString());
527 private:
528 FakeContentLayerClient client_;
529 scoped_refptr<Layer> root_layer_;
530 scoped_refptr<Layer> scaled_layer_;
533 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
535 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
536 : public LayerTreeHostTest {
537 public:
538 void InitializeSettings(LayerTreeSettings* settings) override {
539 settings->layer_transforms_should_scale_layer_contents = true;
542 void SetupTree() override {
543 root_layer_ = Layer::Create();
544 root_layer_->SetBounds(gfx::Size(10, 20));
545 root_layer_->CreateRenderSurface();
547 bool paint_scrollbar = true;
548 bool has_thumb = false;
549 scrollbar_ = FakePaintedScrollbarLayer::Create(
550 paint_scrollbar, has_thumb, root_layer_->id());
551 scrollbar_->SetPosition(gfx::Point(0, 10));
552 scrollbar_->SetBounds(gfx::Size(10, 10));
554 root_layer_->AddChild(scrollbar_);
556 layer_tree_host()->SetRootLayer(root_layer_);
557 LayerTreeHostTest::SetupTree();
560 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
562 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
563 if (host_impl->active_tree()->source_frame_number() == 1)
564 EndTest();
567 void DidCommit() override {
568 switch (layer_tree_host()->source_frame_number()) {
569 case 1:
570 // Changing the device scale factor causes a commit. It also changes
571 // the content bounds of |scrollbar_|, which should not generate
572 // a second commit as a result.
573 layer_tree_host()->SetDeviceScaleFactor(4.f);
574 break;
575 default:
576 // No extra commits.
577 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
581 void AfterTest() override {
582 EXPECT_EQ(gfx::Size(40, 40).ToString(),
583 scrollbar_->content_bounds().ToString());
586 private:
587 FakeContentLayerClient client_;
588 scoped_refptr<Layer> root_layer_;
589 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
592 SINGLE_AND_MULTI_THREAD_TEST_F(
593 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
595 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
596 public:
597 LayerTreeHostTestSetNextCommitForcesRedraw()
598 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
600 void BeginTest() override {
601 if (layer_tree_host()->settings().impl_side_painting)
602 root_layer_ = FakePictureLayer::Create(&client_);
603 else
604 root_layer_ = ContentLayer::Create(&client_);
605 root_layer_->SetIsDrawable(true);
606 root_layer_->SetBounds(bounds_);
607 layer_tree_host()->SetRootLayer(root_layer_);
608 layer_tree_host()->SetViewportSize(bounds_);
609 PostSetNeedsCommitToMainThread();
612 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
613 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
614 host_impl->SetNeedsRedrawRect(invalid_rect_);
617 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
618 LayerTreeHostImpl::FrameData* frame_data,
619 DrawResult draw_result) override {
620 EXPECT_EQ(DRAW_SUCCESS, draw_result);
622 gfx::RectF root_damage_rect;
623 if (!frame_data->render_passes.empty())
624 root_damage_rect = frame_data->render_passes.back()->damage_rect;
626 switch (num_draws_) {
627 case 0:
628 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
629 break;
630 case 1:
631 case 2:
632 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
633 break;
634 case 3:
635 EXPECT_EQ(invalid_rect_, root_damage_rect);
636 break;
637 case 4:
638 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
639 break;
640 default:
641 NOTREACHED();
644 return draw_result;
647 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
648 switch (num_draws_) {
649 case 0:
650 case 1:
651 // Cycle through a couple of empty commits to ensure we're observing the
652 // right behavior
653 PostSetNeedsCommitToMainThread();
654 break;
655 case 2:
656 // Should force full frame damage on the next commit
657 PostSetNextCommitForcesRedrawToMainThread();
658 PostSetNeedsCommitToMainThread();
659 if (host_impl->settings().impl_side_painting)
660 host_impl->BlockNotifyReadyToActivateForTesting(true);
661 else
662 num_draws_++;
663 break;
664 case 3:
665 host_impl->BlockNotifyReadyToActivateForTesting(false);
666 break;
667 default:
668 EndTest();
669 break;
671 num_draws_++;
674 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
676 private:
677 int num_draws_;
678 const gfx::Size bounds_;
679 const gfx::Rect invalid_rect_;
680 FakeContentLayerClient client_;
681 scoped_refptr<Layer> root_layer_;
684 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
685 LayerTreeHostTestSetNextCommitForcesRedraw);
687 // Tests that if a layer is not drawn because of some reason in the parent then
688 // its damage is preserved until the next time it is drawn.
689 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
690 public:
691 LayerTreeHostTestUndrawnLayersDamageLater() {}
693 void SetupTree() override {
694 if (layer_tree_host()->settings().impl_side_painting)
695 root_layer_ = FakePictureLayer::Create(&client_);
696 else
697 root_layer_ = ContentLayer::Create(&client_);
698 root_layer_->SetIsDrawable(true);
699 root_layer_->SetBounds(gfx::Size(50, 50));
700 layer_tree_host()->SetRootLayer(root_layer_);
702 // The initially transparent layer has a larger child layer, which is
703 // not initially drawn because of the this (parent) layer.
704 if (layer_tree_host()->settings().impl_side_painting)
705 parent_layer_ = FakePictureLayer::Create(&client_);
706 else
707 parent_layer_ = FakeContentLayer::Create(&client_);
708 parent_layer_->SetBounds(gfx::Size(15, 15));
709 parent_layer_->SetOpacity(0.0f);
710 root_layer_->AddChild(parent_layer_);
712 if (layer_tree_host()->settings().impl_side_painting)
713 child_layer_ = FakePictureLayer::Create(&client_);
714 else
715 child_layer_ = FakeContentLayer::Create(&client_);
716 child_layer_->SetBounds(gfx::Size(25, 25));
717 parent_layer_->AddChild(child_layer_);
719 LayerTreeHostTest::SetupTree();
722 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
724 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
725 LayerTreeHostImpl::FrameData* frame_data,
726 DrawResult draw_result) override {
727 EXPECT_EQ(DRAW_SUCCESS, draw_result);
729 gfx::RectF root_damage_rect;
730 if (!frame_data->render_passes.empty())
731 root_damage_rect = frame_data->render_passes.back()->damage_rect;
733 // The first time, the whole view needs be drawn.
734 // Afterwards, just the opacity of surface_layer1 is changed a few times,
735 // and each damage should be the bounding box of it and its child. If this
736 // was working improperly, the damage might not include its childs bounding
737 // box.
738 switch (host_impl->active_tree()->source_frame_number()) {
739 case 0:
740 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
741 break;
742 case 1:
743 case 2:
744 case 3:
745 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
746 break;
747 default:
748 NOTREACHED();
751 return draw_result;
754 void DidCommitAndDrawFrame() override {
755 switch (layer_tree_host()->source_frame_number()) {
756 case 1:
757 // Test not owning the surface.
758 parent_layer_->SetOpacity(1.0f);
759 break;
760 case 2:
761 parent_layer_->SetOpacity(0.0f);
762 break;
763 case 3:
764 // Test owning the surface.
765 parent_layer_->SetOpacity(0.5f);
766 parent_layer_->SetForceRenderSurface(true);
767 break;
768 case 4:
769 EndTest();
770 break;
771 default:
772 NOTREACHED();
776 void AfterTest() override {}
778 private:
779 FakeContentLayerClient client_;
780 scoped_refptr<Layer> root_layer_;
781 scoped_refptr<Layer> parent_layer_;
782 scoped_refptr<Layer> child_layer_;
785 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
787 // Tests that if a layer is not drawn because of some reason in the parent,
788 // causing its content bounds to not be computed, then when it is later drawn,
789 // its content bounds get pushed.
790 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
791 : public LayerTreeHostTest {
792 public:
793 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
794 : root_layer_(Layer::Create()) {}
796 void SetupTree() override {
797 root_layer_->CreateRenderSurface();
798 root_layer_->SetIsDrawable(true);
799 root_layer_->SetBounds(gfx::Size(20, 20));
800 layer_tree_host()->SetRootLayer(root_layer_);
802 parent_layer_ = Layer::Create();
803 parent_layer_->SetBounds(gfx::Size(20, 20));
804 parent_layer_->SetOpacity(0.0f);
805 root_layer_->AddChild(parent_layer_);
807 child_layer_ = Layer::Create();
808 child_layer_->SetBounds(gfx::Size(15, 15));
809 parent_layer_->AddChild(child_layer_);
811 LayerTreeHostTest::SetupTree();
814 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
816 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
817 LayerImpl* root = host_impl->active_tree()->root_layer();
818 LayerImpl* parent = root->children()[0];
819 LayerImpl* child = parent->children()[0];
821 switch (host_impl->active_tree()->source_frame_number()) {
822 case 0:
823 EXPECT_EQ(0.f, parent->opacity());
824 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
825 break;
826 case 1:
827 EXPECT_EQ(1.f, parent->opacity());
828 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
829 EndTest();
830 break;
831 default:
832 NOTREACHED();
836 void DidCommit() override {
837 switch (layer_tree_host()->source_frame_number()) {
838 case 1:
839 parent_layer_->SetOpacity(1.0f);
840 break;
841 case 2:
842 break;
843 default:
844 NOTREACHED();
848 void AfterTest() override {}
850 private:
851 scoped_refptr<Layer> root_layer_;
852 scoped_refptr<Layer> parent_layer_;
853 scoped_refptr<Layer> child_layer_;
856 SINGLE_AND_MULTI_THREAD_TEST_F(
857 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
859 // This test verifies that properties on the layer tree host are commited
860 // to the impl side.
861 class LayerTreeHostTestCommit : public LayerTreeHostTest {
862 public:
863 LayerTreeHostTestCommit() {}
865 void BeginTest() override {
866 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
867 layer_tree_host()->set_background_color(SK_ColorGRAY);
869 PostSetNeedsCommitToMainThread();
872 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
873 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
874 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
876 EndTest();
879 void AfterTest() override {}
882 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
884 // This test verifies that LayerTreeHostImpl's current frame time gets
885 // updated in consecutive frames when it doesn't draw due to tree
886 // activation failure.
887 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
888 : public LayerTreeHostTest {
889 public:
890 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
891 : frame_count_with_pending_tree_(0) {}
893 void BeginTest() override {
894 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
895 layer_tree_host()->set_background_color(SK_ColorGRAY);
897 PostSetNeedsCommitToMainThread();
900 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
901 EXPECT_EQ(frame_count_with_pending_tree_, 0);
902 if (impl->settings().impl_side_painting)
903 impl->BlockNotifyReadyToActivateForTesting(true);
906 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
907 const BeginFrameArgs& args) override {
908 if (impl->pending_tree())
909 frame_count_with_pending_tree_++;
911 if (frame_count_with_pending_tree_ == 1) {
912 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
913 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
914 } else if (frame_count_with_pending_tree_ == 2 &&
915 impl->settings().impl_side_painting) {
916 impl->BlockNotifyReadyToActivateForTesting(false);
920 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
921 if (frame_count_with_pending_tree_ > 1) {
922 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
923 EXPECT_NE(first_frame_time_.ToInternalValue(),
924 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
925 EndTest();
926 return;
929 EXPECT_FALSE(impl->settings().impl_side_painting);
930 EndTest();
932 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
933 if (impl->settings().impl_side_painting)
934 EXPECT_NE(frame_count_with_pending_tree_, 1);
937 void AfterTest() override {}
939 private:
940 int frame_count_with_pending_tree_;
941 base::TimeTicks first_frame_time_;
944 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
945 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
947 // This test verifies that LayerTreeHostImpl's current frame time gets
948 // updated in consecutive frames when it draws in each frame.
949 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
950 public:
951 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
953 void BeginTest() override {
954 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
955 layer_tree_host()->set_background_color(SK_ColorGRAY);
957 PostSetNeedsCommitToMainThread();
960 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
961 frame_++;
962 if (frame_ == 1) {
963 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
964 impl->SetNeedsRedraw();
966 // Since we might use a low-resolution clock on Windows, we need to
967 // make sure that the clock has incremented past first_frame_time_.
968 while (first_frame_time_ == gfx::FrameTime::Now()) {
971 return;
974 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
975 EndTest();
978 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
979 // Ensure there isn't a commit between the two draws, to ensure that a
980 // commit isn't required for updating the current frame time. We can
981 // only check for this in the multi-threaded case, since in the single-
982 // threaded case there will always be a commit between consecutive draws.
983 if (HasImplThread())
984 EXPECT_EQ(0, frame_);
987 void AfterTest() override {}
989 private:
990 int frame_;
991 base::TimeTicks first_frame_time_;
994 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
996 // Verifies that StartPageScaleAnimation events propagate correctly
997 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
998 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
999 public:
1000 LayerTreeHostTestStartPageScaleAnimation() {}
1002 void SetupTree() override {
1003 LayerTreeHostTest::SetupTree();
1005 if (layer_tree_host()->settings().impl_side_painting) {
1006 scoped_refptr<FakePictureLayer> layer =
1007 FakePictureLayer::Create(&client_);
1008 layer->set_always_update_resources(true);
1009 scroll_layer_ = layer;
1010 } else {
1011 scroll_layer_ = FakeContentLayer::Create(&client_);
1014 Layer* root_layer = layer_tree_host()->root_layer();
1015 scroll_layer_->SetScrollClipLayerId(root_layer->id());
1016 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
1017 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
1018 2 * root_layer->bounds().height()));
1019 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
1020 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1021 // This test requires the page_scale and inner viewport layers to be
1022 // identified.
1023 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
1024 scroll_layer_.get(), NULL);
1025 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1028 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1030 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
1031 float scale,
1032 float) override {
1033 gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
1034 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset,
1035 scroll_delta));
1036 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1039 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1040 // We get one commit before the first draw, and the animation doesn't happen
1041 // until the second draw.
1042 switch (impl->active_tree()->source_frame_number()) {
1043 case 0:
1044 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1045 // We'll start an animation when we get back to the main thread.
1046 break;
1047 case 1:
1048 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1049 break;
1050 case 2:
1051 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
1052 EndTest();
1053 break;
1054 default:
1055 NOTREACHED();
1059 void DidCommitAndDrawFrame() override {
1060 switch (layer_tree_host()->source_frame_number()) {
1061 case 1:
1062 layer_tree_host()->StartPageScaleAnimation(
1063 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1064 break;
1068 void AfterTest() override {}
1070 FakeContentLayerClient client_;
1071 scoped_refptr<Layer> scroll_layer_;
1074 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1076 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1077 public:
1078 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1080 void BeginTest() override {
1081 PostSetNeedsCommitToMainThread();
1082 PostSetVisibleToMainThread(false);
1083 // This is suppressed while we're invisible.
1084 PostSetNeedsRedrawToMainThread();
1085 // Triggers the redraw.
1086 PostSetVisibleToMainThread(true);
1089 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1090 EXPECT_TRUE(impl->visible());
1091 ++num_draws_;
1092 EndTest();
1095 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
1097 private:
1098 int num_draws_;
1101 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1103 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1104 public:
1105 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1107 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1109 void PaintContents(SkCanvas* canvas,
1110 const gfx::Rect& clip,
1111 PaintingControlSetting picture_control) override {
1112 // Set layer opacity to 0.
1113 if (test_layer_)
1114 test_layer_->SetOpacity(0.f);
1116 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
1117 const gfx::Rect& clip,
1118 PaintingControlSetting picture_control) override {
1119 NOTIMPLEMENTED();
1120 return DisplayItemList::Create();
1122 bool FillsBoundsCompletely() const override { return false; }
1124 private:
1125 Layer* test_layer_;
1128 class ContentLayerWithUpdateTracking : public ContentLayer {
1129 public:
1130 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1131 ContentLayerClient* client) {
1132 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1135 int PaintContentsCount() { return paint_contents_count_; }
1136 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1138 bool Update(ResourceUpdateQueue* queue,
1139 const OcclusionTracker<Layer>* occlusion) override {
1140 bool updated = ContentLayer::Update(queue, occlusion);
1141 paint_contents_count_++;
1142 return updated;
1145 private:
1146 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1147 : ContentLayer(client), paint_contents_count_(0) {
1148 SetBounds(gfx::Size(10, 10));
1149 SetIsDrawable(true);
1151 ~ContentLayerWithUpdateTracking() override {}
1153 int paint_contents_count_;
1156 // Layer opacity change during paint should not prevent compositor resources
1157 // from being updated during commit.
1158 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1159 public:
1160 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {}
1162 void BeginTest() override {
1163 if (layer_tree_host()->settings().impl_side_painting) {
1164 update_check_picture_layer_ =
1165 FakePictureLayer::Create(&test_opacity_change_delegate_);
1166 test_opacity_change_delegate_.SetTestLayer(
1167 update_check_picture_layer_.get());
1168 is_impl_paint_ = true;
1169 } else {
1170 update_check_content_layer_ = ContentLayerWithUpdateTracking::Create(
1171 &test_opacity_change_delegate_);
1172 test_opacity_change_delegate_.SetTestLayer(
1173 update_check_content_layer_.get());
1174 is_impl_paint_ = false;
1176 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1177 if (layer_tree_host()->settings().impl_side_painting)
1178 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
1179 else
1180 layer_tree_host()->root_layer()->AddChild(update_check_content_layer_);
1182 PostSetNeedsCommitToMainThread();
1185 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
1187 void AfterTest() override {
1188 // Update() should have been called once.
1189 if (is_impl_paint_)
1190 EXPECT_EQ(1u, update_check_picture_layer_->update_count());
1191 else
1192 EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount());
1195 private:
1196 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1197 scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_;
1198 scoped_refptr<FakePictureLayer> update_check_picture_layer_;
1199 bool is_impl_paint_;
1202 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1204 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1205 : public LayerTreeHostTest {
1206 public:
1207 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {}
1209 void InitializeSettings(LayerTreeSettings* settings) override {
1210 // PictureLayer can only be used with impl side painting enabled.
1211 settings->impl_side_painting = true;
1214 void BeginTest() override {
1215 client_.set_fill_with_nonsolid_color(true);
1216 root_layer_ = FakePictureLayer::Create(&client_);
1217 child_layer_ = FakePictureLayer::Create(&client_);
1219 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1220 layer_tree_host()->SetDeviceScaleFactor(1.5);
1221 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1223 root_layer_->AddChild(child_layer_);
1225 root_layer_->SetIsDrawable(true);
1226 root_layer_->SetBounds(gfx::Size(30, 30));
1228 child_layer_->SetIsDrawable(true);
1229 child_layer_->SetPosition(gfx::Point(2, 2));
1230 child_layer_->SetBounds(gfx::Size(10, 10));
1232 layer_tree_host()->SetRootLayer(root_layer_);
1234 PostSetNeedsCommitToMainThread();
1237 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1238 // Should only do one commit.
1239 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1240 // Device scale factor should come over to impl.
1241 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1243 // Both layers are on impl.
1244 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1246 // Device viewport is scaled.
1247 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1249 FakePictureLayerImpl* root =
1250 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
1251 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
1252 impl->active_tree()->root_layer()->children()[0]);
1254 // Positions remain in layout pixels.
1255 EXPECT_EQ(gfx::Point(0, 0), root->position());
1256 EXPECT_EQ(gfx::Point(2, 2), child->position());
1258 // Compute all the layer transforms for the frame.
1259 LayerTreeHostImpl::FrameData frame_data;
1260 impl->PrepareToDraw(&frame_data);
1261 impl->DidDrawAllLayers(frame_data);
1263 const LayerImplList& render_surface_layer_list =
1264 *frame_data.render_surface_layer_list;
1266 // Both layers should be drawing into the root render surface.
1267 ASSERT_EQ(1u, render_surface_layer_list.size());
1268 ASSERT_EQ(root->render_surface(),
1269 render_surface_layer_list[0]->render_surface());
1270 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1272 // The root render surface is the size of the viewport.
1273 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect());
1275 // The max tiling scale of the child should be scaled.
1276 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale());
1278 gfx::Transform scale_transform;
1279 scale_transform.Scale(impl->device_scale_factor(),
1280 impl->device_scale_factor());
1282 // The root layer is scaled by 2x.
1283 gfx::Transform root_screen_space_transform = scale_transform;
1284 gfx::Transform root_draw_transform = scale_transform;
1286 EXPECT_EQ(root_draw_transform, root->draw_transform());
1287 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1289 // The child is at position 2,2, which is transformed to 3,3 after the scale
1290 gfx::Transform child_transform;
1291 child_transform.Translate(3.f, 3.f);
1292 child_transform.Scale(child->MaximumTilingContentsScale(),
1293 child->MaximumTilingContentsScale());
1295 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform());
1296 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform,
1297 child->screen_space_transform());
1299 EndTest();
1302 void AfterTest() override {}
1304 private:
1305 FakeContentLayerClient client_;
1306 scoped_refptr<FakePictureLayer> root_layer_;
1307 scoped_refptr<FakePictureLayer> child_layer_;
1310 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1312 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1313 // Verify atomicity of commits and reuse of textures.
1314 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1315 public:
1316 void InitializeSettings(LayerTreeSettings* settings) override {
1317 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1318 // Make sure partial texture updates are turned off.
1319 settings->max_partial_texture_updates = 0;
1320 // Linear fade animator prevents scrollbars from drawing immediately.
1321 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1324 void SetupTree() override {
1325 layer_ = FakeContentLayer::Create(&client_);
1326 layer_->SetBounds(gfx::Size(10, 20));
1328 bool paint_scrollbar = true;
1329 bool has_thumb = false;
1330 scrollbar_ = FakePaintedScrollbarLayer::Create(
1331 paint_scrollbar, has_thumb, layer_->id());
1332 scrollbar_->SetPosition(gfx::Point(0, 10));
1333 scrollbar_->SetBounds(gfx::Size(10, 10));
1335 layer_->AddChild(scrollbar_);
1337 layer_tree_host()->SetRootLayer(layer_);
1338 LayerTreeHostTest::SetupTree();
1341 void BeginTest() override {
1342 drew_frame_ = -1;
1343 PostSetNeedsCommitToMainThread();
1346 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1347 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1349 TestWebGraphicsContext3D* context = TestContext();
1351 switch (impl->active_tree()->source_frame_number()) {
1352 case 0:
1353 // Number of textures should be one for each layer
1354 ASSERT_EQ(2u, context->NumTextures());
1355 // Number of textures used for commit should be one for each layer.
1356 EXPECT_EQ(2u, context->NumUsedTextures());
1357 // Verify that used texture is correct.
1358 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1359 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1361 context->ResetUsedTextures();
1362 break;
1363 case 1:
1364 // Number of textures should be one for scrollbar layer since it was
1365 // requested and deleted on the impl-thread, and double for the content
1366 // layer since its first texture is used by impl thread and cannot by
1367 // used for update.
1368 ASSERT_EQ(3u, context->NumTextures());
1369 // Number of textures used for commit should be one for each layer.
1370 EXPECT_EQ(2u, context->NumUsedTextures());
1371 // First textures should not have been used.
1372 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1373 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1374 // New textures should have been used.
1375 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1376 context->ResetUsedTextures();
1377 break;
1378 case 2:
1379 EndTest();
1380 break;
1381 default:
1382 NOTREACHED();
1383 break;
1387 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1388 TestWebGraphicsContext3D* context = TestContext();
1390 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1391 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1392 return;
1394 drew_frame_ = impl->active_tree()->source_frame_number();
1396 // We draw/ship one texture each frame for each layer.
1397 EXPECT_EQ(2u, context->NumUsedTextures());
1398 context->ResetUsedTextures();
1400 if (!TestEnded())
1401 PostSetNeedsCommitToMainThread();
1404 void Layout() override {
1405 layer_->SetNeedsDisplay();
1406 scrollbar_->SetNeedsDisplay();
1409 void AfterTest() override {}
1411 protected:
1412 FakeContentLayerClient client_;
1413 scoped_refptr<FakeContentLayer> layer_;
1414 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1415 int drew_frame_;
1418 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1419 LayerTreeHostTestDirectRendererAtomicCommit);
1421 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1422 class LayerTreeHostTestDelegatingRendererAtomicCommit
1423 : public LayerTreeHostTestDirectRendererAtomicCommit {
1424 public:
1425 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1426 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1428 TestWebGraphicsContext3D* context = TestContext();
1430 switch (impl->active_tree()->source_frame_number()) {
1431 case 0:
1432 // Number of textures should be one for each layer
1433 ASSERT_EQ(2u, context->NumTextures());
1434 // Number of textures used for commit should be one for each layer.
1435 EXPECT_EQ(2u, context->NumUsedTextures());
1436 // Verify that used texture is correct.
1437 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1438 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1439 context->ResetUsedTextures();
1440 break;
1441 case 1:
1442 // Number of textures should be doubled as the first context layer
1443 // texture is being used by the impl-thread and cannot be used for
1444 // update. The scrollbar behavior is different direct renderer because
1445 // UI resource deletion with delegating renderer occurs after tree
1446 // activation.
1447 ASSERT_EQ(4u, context->NumTextures());
1448 // Number of textures used for commit should still be
1449 // one for each layer.
1450 EXPECT_EQ(2u, context->NumUsedTextures());
1451 // First textures should not have been used.
1452 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1453 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1454 // New textures should have been used.
1455 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1456 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1457 context->ResetUsedTextures();
1458 break;
1459 case 2:
1460 EndTest();
1461 break;
1462 default:
1463 NOTREACHED();
1464 break;
1469 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1470 LayerTreeHostTestDelegatingRendererAtomicCommit);
1472 static void SetLayerPropertiesForTesting(Layer* layer,
1473 Layer* parent,
1474 const gfx::Transform& transform,
1475 const gfx::Point3F& transform_origin,
1476 const gfx::PointF& position,
1477 const gfx::Size& bounds,
1478 bool opaque) {
1479 layer->RemoveAllChildren();
1480 if (parent)
1481 parent->AddChild(layer);
1482 layer->SetTransform(transform);
1483 layer->SetTransformOrigin(transform_origin);
1484 layer->SetPosition(position);
1485 layer->SetBounds(bounds);
1486 layer->SetContentsOpaque(opaque);
1489 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1490 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1491 : public LayerTreeHostTest {
1492 public:
1493 void InitializeSettings(LayerTreeSettings* settings) override {
1494 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1495 // Allow one partial texture update.
1496 settings->max_partial_texture_updates = 1;
1497 // No partial updates when impl side painting is enabled.
1498 settings->impl_side_painting = false;
1501 void SetupTree() override {
1502 parent_ = FakeContentLayer::Create(&client_);
1503 parent_->SetBounds(gfx::Size(10, 20));
1505 child_ = FakeContentLayer::Create(&client_);
1506 child_->SetPosition(gfx::Point(0, 10));
1507 child_->SetBounds(gfx::Size(3, 10));
1509 parent_->AddChild(child_);
1511 layer_tree_host()->SetRootLayer(parent_);
1512 LayerTreeHostTest::SetupTree();
1515 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1517 void DidCommitAndDrawFrame() override {
1518 switch (layer_tree_host()->source_frame_number()) {
1519 case 1:
1520 parent_->SetNeedsDisplay();
1521 child_->SetNeedsDisplay();
1522 break;
1523 case 2:
1524 // Damage part of layers.
1525 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1526 child_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1527 break;
1528 case 3:
1529 child_->SetNeedsDisplay();
1530 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1531 break;
1532 case 4:
1533 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1534 break;
1535 case 5:
1536 EndTest();
1537 break;
1538 default:
1539 NOTREACHED() << layer_tree_host()->source_frame_number();
1540 break;
1544 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1545 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1547 TestWebGraphicsContext3D* context = TestContext();
1549 switch (impl->active_tree()->source_frame_number()) {
1550 case 0:
1551 // Number of textures should be one for each layer.
1552 ASSERT_EQ(2u, context->NumTextures());
1553 // Number of textures used for commit should be one for each layer.
1554 EXPECT_EQ(2u, context->NumUsedTextures());
1555 // Verify that used textures are correct.
1556 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1557 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1558 context->ResetUsedTextures();
1559 break;
1560 case 1:
1561 if (HasImplThread()) {
1562 // Number of textures should be two for each content layer.
1563 ASSERT_EQ(4u, context->NumTextures());
1564 } else {
1565 // In single thread we can always do partial updates, so the limit has
1566 // no effect.
1567 ASSERT_EQ(2u, context->NumTextures());
1569 // Number of textures used for commit should be one for each content
1570 // layer.
1571 EXPECT_EQ(2u, context->NumUsedTextures());
1573 if (HasImplThread()) {
1574 // First content textures should not have been used.
1575 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1576 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1577 // New textures should have been used.
1578 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1579 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1580 } else {
1581 // In single thread we can always do partial updates, so the limit has
1582 // no effect.
1583 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1584 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1587 context->ResetUsedTextures();
1588 break;
1589 case 2:
1590 if (HasImplThread()) {
1591 // Number of textures should be two for each content layer.
1592 ASSERT_EQ(4u, context->NumTextures());
1593 } else {
1594 // In single thread we can always do partial updates, so the limit has
1595 // no effect.
1596 ASSERT_EQ(2u, context->NumTextures());
1598 // Number of textures used for commit should be one for each content
1599 // layer.
1600 EXPECT_EQ(2u, context->NumUsedTextures());
1602 if (HasImplThread()) {
1603 // One content layer does a partial update also.
1604 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1605 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1606 } else {
1607 // In single thread we can always do partial updates, so the limit has
1608 // no effect.
1609 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1610 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1613 context->ResetUsedTextures();
1614 break;
1615 case 3:
1616 // No textures should be used for commit.
1617 EXPECT_EQ(0u, context->NumUsedTextures());
1619 context->ResetUsedTextures();
1620 break;
1621 case 4:
1622 // Number of textures used for commit should be one, for the
1623 // content layer.
1624 EXPECT_EQ(1u, context->NumUsedTextures());
1626 context->ResetUsedTextures();
1627 break;
1628 default:
1629 NOTREACHED();
1630 break;
1634 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1635 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1637 TestWebGraphicsContext3D* context = TestContext();
1639 // Number of textures used for drawing should one per layer except for
1640 // frame 3 where the viewport only contains one layer.
1641 if (impl->active_tree()->source_frame_number() == 3) {
1642 EXPECT_EQ(1u, context->NumUsedTextures());
1643 } else {
1644 EXPECT_EQ(2u, context->NumUsedTextures())
1645 << "For frame " << impl->active_tree()->source_frame_number();
1648 context->ResetUsedTextures();
1651 void AfterTest() override {}
1653 private:
1654 FakeContentLayerClient client_;
1655 scoped_refptr<FakeContentLayer> parent_;
1656 scoped_refptr<FakeContentLayer> child_;
1659 // Partial updates are not possible with a delegating renderer.
1660 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1661 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1663 // TODO(sohanjg) : Make it work with impl-side painting.
1664 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1665 : public LayerTreeHostTest {
1666 protected:
1667 void SetupTree() override {
1668 root_layer_ = FakeContentLayer::Create(&client_);
1669 root_layer_->SetBounds(gfx::Size(100, 100));
1671 surface_layer1_ = FakeContentLayer::Create(&client_);
1672 surface_layer1_->SetBounds(gfx::Size(100, 100));
1673 surface_layer1_->SetForceRenderSurface(true);
1674 surface_layer1_->SetOpacity(0.5f);
1675 root_layer_->AddChild(surface_layer1_);
1677 surface_layer2_ = FakeContentLayer::Create(&client_);
1678 surface_layer2_->SetBounds(gfx::Size(100, 100));
1679 surface_layer2_->SetForceRenderSurface(true);
1680 surface_layer2_->SetOpacity(0.5f);
1681 surface_layer1_->AddChild(surface_layer2_);
1683 replica_layer1_ = FakeContentLayer::Create(&client_);
1684 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1686 replica_layer2_ = FakeContentLayer::Create(&client_);
1687 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1689 layer_tree_host()->SetRootLayer(root_layer_);
1690 LayerTreeHostTest::SetupTree();
1693 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1695 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1696 Renderer* renderer = host_impl->renderer();
1697 RenderPassId surface1_render_pass_id = host_impl->active_tree()
1698 ->root_layer()
1699 ->children()[0]
1700 ->render_surface()
1701 ->GetRenderPassId();
1702 RenderPassId surface2_render_pass_id = host_impl->active_tree()
1703 ->root_layer()
1704 ->children()[0]
1705 ->children()[0]
1706 ->render_surface()
1707 ->GetRenderPassId();
1709 switch (host_impl->active_tree()->source_frame_number()) {
1710 case 0:
1711 EXPECT_TRUE(
1712 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1713 EXPECT_TRUE(
1714 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1716 // Reduce the memory limit to only fit the root layer and one render
1717 // surface. This prevents any contents drawing into surfaces
1718 // from being allocated.
1719 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1720 break;
1721 case 1:
1722 EXPECT_FALSE(
1723 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1724 EXPECT_FALSE(
1725 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1727 EndTest();
1728 break;
1732 void DidCommitAndDrawFrame() override {
1733 if (layer_tree_host()->source_frame_number() < 2)
1734 root_layer_->SetNeedsDisplay();
1737 void AfterTest() override {
1738 EXPECT_LE(2u, root_layer_->update_count());
1739 EXPECT_LE(2u, surface_layer1_->update_count());
1740 EXPECT_LE(2u, surface_layer2_->update_count());
1743 FakeContentLayerClient client_;
1744 scoped_refptr<FakeContentLayer> root_layer_;
1745 scoped_refptr<FakeContentLayer> surface_layer1_;
1746 scoped_refptr<FakeContentLayer> replica_layer1_;
1747 scoped_refptr<FakeContentLayer> surface_layer2_;
1748 scoped_refptr<FakeContentLayer> replica_layer2_;
1751 // Surfaces don't exist with a delegated renderer.
1752 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1753 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1755 class EvictionTestLayer : public Layer {
1756 public:
1757 static scoped_refptr<EvictionTestLayer> Create() {
1758 return make_scoped_refptr(new EvictionTestLayer());
1761 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override;
1762 bool DrawsContent() const override { return true; }
1764 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
1765 void PushPropertiesTo(LayerImpl* impl) override;
1766 void SetTexturePriorities(const PriorityCalculator&) override;
1768 bool HaveBackingTexture() const {
1769 return texture_.get() ? texture_->have_backing_texture() : false;
1772 private:
1773 EvictionTestLayer() : Layer() {}
1774 ~EvictionTestLayer() override {}
1776 void CreateTextureIfNeeded() {
1777 if (texture_)
1778 return;
1779 texture_ = PrioritizedResource::Create(
1780 layer_tree_host()->contents_texture_manager());
1781 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1782 bitmap_.allocN32Pixels(10, 10);
1785 scoped_ptr<PrioritizedResource> texture_;
1786 SkBitmap bitmap_;
1789 class EvictionTestLayerImpl : public LayerImpl {
1790 public:
1791 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1792 int id) {
1793 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1795 ~EvictionTestLayerImpl() override {}
1797 void AppendQuads(RenderPass* render_pass,
1798 const Occlusion& occlusion_in_content_space,
1799 AppendQuadsData* append_quads_data) override {
1800 ASSERT_TRUE(has_texture_);
1801 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1804 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1806 private:
1807 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1808 : LayerImpl(tree_impl, id), has_texture_(false) {}
1810 bool has_texture_;
1813 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1814 CreateTextureIfNeeded();
1815 if (!texture_)
1816 return;
1817 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1820 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1821 const OcclusionTracker<Layer>* occlusion) {
1822 CreateTextureIfNeeded();
1823 if (!texture_)
1824 return false;
1826 gfx::Rect full_rect(0, 0, 10, 10);
1827 ResourceUpdate upload = ResourceUpdate::Create(
1828 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1829 queue->AppendFullUpload(upload);
1830 return true;
1833 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1834 LayerTreeImpl* tree_impl) {
1835 return EvictionTestLayerImpl::Create(tree_impl, layer_id_);
1838 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1839 Layer::PushPropertiesTo(layer_impl);
1841 EvictionTestLayerImpl* test_layer_impl =
1842 static_cast<EvictionTestLayerImpl*>(layer_impl);
1843 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1846 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1847 public:
1848 LayerTreeHostTestEvictTextures()
1849 : layer_(EvictionTestLayer::Create()),
1850 impl_for_evict_textures_(0),
1851 num_commits_(0) {}
1853 void BeginTest() override {
1854 layer_tree_host()->SetRootLayer(layer_);
1855 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1857 gfx::Transform identity_matrix;
1858 SetLayerPropertiesForTesting(layer_.get(),
1860 identity_matrix,
1861 gfx::Point3F(0.f, 0.f, 0.f),
1862 gfx::PointF(0.f, 0.f),
1863 gfx::Size(10, 20),
1864 true);
1866 PostSetNeedsCommitToMainThread();
1869 void PostEvictTextures() {
1870 ImplThreadTaskRunner()->PostTask(
1871 FROM_HERE,
1872 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1873 base::Unretained(this)));
1876 void EvictTexturesOnImplThread() {
1877 DCHECK(impl_for_evict_textures_);
1878 impl_for_evict_textures_->EvictTexturesForTesting();
1881 // Commit 1: Just commit and draw normally, then post an eviction at the end
1882 // that will trigger a commit.
1883 // Commit 2: Triggered by the eviction, let it go through and then set
1884 // needsCommit.
1885 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1886 // task, which will be handled before the commit. Don't set needsCommit, it
1887 // should have been posted. A frame should not be drawn (note,
1888 // didCommitAndDrawFrame may be called anyway).
1889 // Commit 4: Triggered by the eviction, let it go through and then set
1890 // needsCommit.
1891 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1892 // Layout(), a frame should not be drawn but a commit will be posted.
1893 // Commit 6: Triggered by the eviction, post an eviction task in
1894 // Layout(), which will be a noop, letting the commit (which recreates the
1895 // textures) go through and draw a frame, then end the test.
1897 // Commits 1+2 test the eviction recovery path where eviction happens outside
1898 // of the beginFrame/commit pair.
1899 // Commits 3+4 test the eviction recovery path where eviction happens inside
1900 // the beginFrame/commit pair.
1901 // Commits 5+6 test the path where an eviction happens during the eviction
1902 // recovery path.
1903 void DidCommit() override {
1904 switch (num_commits_) {
1905 case 1:
1906 EXPECT_TRUE(layer_->HaveBackingTexture());
1907 PostEvictTextures();
1908 break;
1909 case 2:
1910 EXPECT_TRUE(layer_->HaveBackingTexture());
1911 layer_tree_host()->SetNeedsCommit();
1912 break;
1913 case 3:
1914 break;
1915 case 4:
1916 EXPECT_TRUE(layer_->HaveBackingTexture());
1917 layer_tree_host()->SetNeedsCommit();
1918 break;
1919 case 5:
1920 break;
1921 case 6:
1922 EXPECT_TRUE(layer_->HaveBackingTexture());
1923 EndTest();
1924 break;
1925 default:
1926 NOTREACHED();
1927 break;
1931 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1932 impl_for_evict_textures_ = impl;
1935 void Layout() override {
1936 ++num_commits_;
1937 switch (num_commits_) {
1938 case 1:
1939 case 2:
1940 break;
1941 case 3:
1942 PostEvictTextures();
1943 break;
1944 case 4:
1945 // We couldn't check in didCommitAndDrawFrame on commit 3,
1946 // so check here.
1947 EXPECT_FALSE(layer_->HaveBackingTexture());
1948 break;
1949 case 5:
1950 PostEvictTextures();
1951 break;
1952 case 6:
1953 // We couldn't check in didCommitAndDrawFrame on commit 5,
1954 // so check here.
1955 EXPECT_FALSE(layer_->HaveBackingTexture());
1956 PostEvictTextures();
1957 break;
1958 default:
1959 NOTREACHED();
1960 break;
1964 void AfterTest() override {}
1966 private:
1967 FakeContentLayerClient client_;
1968 scoped_refptr<EvictionTestLayer> layer_;
1969 LayerTreeHostImpl* impl_for_evict_textures_;
1970 int num_commits_;
1973 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
1975 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1976 public:
1977 LayerTreeHostTestContinuousInvalidate()
1978 : num_commit_complete_(0), num_draw_layers_(0) {}
1980 void BeginTest() override {
1981 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1982 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1984 if (layer_tree_host()->settings().impl_side_painting)
1985 layer_ = FakePictureLayer::Create(&client_);
1986 else
1987 layer_ = FakeContentLayer::Create(&client_);
1989 layer_->SetBounds(gfx::Size(10, 10));
1990 layer_->SetPosition(gfx::PointF(0.f, 0.f));
1991 layer_->SetIsDrawable(true);
1992 layer_tree_host()->root_layer()->AddChild(layer_);
1994 PostSetNeedsCommitToMainThread();
1997 void DidCommitAndDrawFrame() override {
1998 if (num_draw_layers_ == 2)
1999 return;
2000 layer_->SetNeedsDisplay();
2003 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2004 if (num_draw_layers_ == 1)
2005 num_commit_complete_++;
2008 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2009 num_draw_layers_++;
2010 if (num_draw_layers_ == 2)
2011 EndTest();
2014 void AfterTest() override {
2015 // Check that we didn't commit twice between first and second draw.
2016 EXPECT_EQ(1, num_commit_complete_);
2019 private:
2020 FakeContentLayerClient client_;
2021 scoped_refptr<Layer> layer_;
2022 int num_commit_complete_;
2023 int num_draw_layers_;
2026 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
2028 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2029 public:
2030 LayerTreeHostTestDeferCommits()
2031 : num_will_begin_impl_frame_(0),
2032 num_send_begin_main_frame_(0) {}
2034 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2036 void WillBeginImplFrame(const BeginFrameArgs& args) override {
2037 num_will_begin_impl_frame_++;
2038 switch (num_will_begin_impl_frame_) {
2039 case 1:
2040 break;
2041 case 2:
2042 PostSetNeedsCommitToMainThread();
2043 break;
2044 case 3:
2045 PostSetDeferCommitsToMainThread(false);
2046 break;
2047 default:
2048 // Sometimes |num_will_begin_impl_frame_| will be greater than 3 if the
2049 // main thread is slow to respond.
2050 break;
2054 void ScheduledActionSendBeginMainFrame() override {
2055 num_send_begin_main_frame_++;
2056 switch (num_send_begin_main_frame_) {
2057 case 1:
2058 PostSetDeferCommitsToMainThread(true);
2059 break;
2060 case 2:
2061 EndTest();
2062 break;
2063 default:
2064 NOTREACHED();
2065 break;
2069 void AfterTest() override {
2070 EXPECT_GE(num_will_begin_impl_frame_, 3);
2071 EXPECT_EQ(2, num_send_begin_main_frame_);
2074 private:
2075 int num_will_begin_impl_frame_;
2076 int num_send_begin_main_frame_;
2079 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2081 class LayerTreeHostWithProxy : public LayerTreeHost {
2082 public:
2083 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2084 const LayerTreeSettings& settings,
2085 scoped_ptr<FakeProxy> proxy)
2086 : LayerTreeHost(client, NULL, NULL, settings) {
2087 proxy->SetLayerTreeHost(this);
2088 client->SetLayerTreeHost(this);
2089 InitializeForTesting(proxy.Pass());
2093 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2094 // When partial updates are not allowed, max updates should be 0.
2096 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2098 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2099 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2100 proxy->SetMaxPartialTextureUpdates(5);
2102 LayerTreeSettings settings;
2103 settings.max_partial_texture_updates = 10;
2105 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2107 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2110 // When partial updates are allowed,
2111 // max updates should be limited by the proxy.
2113 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2115 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2116 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2117 proxy->SetMaxPartialTextureUpdates(5);
2119 LayerTreeSettings settings;
2120 settings.max_partial_texture_updates = 10;
2122 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2124 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2127 // When partial updates are allowed,
2128 // max updates should also be limited by the settings.
2130 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2132 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2133 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2134 proxy->SetMaxPartialTextureUpdates(20);
2136 LayerTreeSettings settings;
2137 settings.max_partial_texture_updates = 10;
2139 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2141 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2145 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2146 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2148 LayerTreeSettings settings;
2149 settings.max_partial_texture_updates = 4;
2150 settings.single_thread_proxy_scheduler = false;
2152 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2153 new TestSharedBitmapManager());
2154 scoped_ptr<LayerTreeHost> host =
2155 LayerTreeHost::CreateSingleThreaded(&client,
2156 &client,
2157 shared_bitmap_manager.get(),
2158 NULL,
2159 settings,
2160 base::MessageLoopProxy::current(),
2161 nullptr);
2162 client.SetLayerTreeHost(host.get());
2163 host->Composite(base::TimeTicks::Now());
2165 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2168 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2169 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2171 LayerTreeSettings settings;
2172 settings.max_partial_texture_updates = 4;
2173 settings.single_thread_proxy_scheduler = false;
2175 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2176 new TestSharedBitmapManager());
2177 scoped_ptr<LayerTreeHost> host =
2178 LayerTreeHost::CreateSingleThreaded(&client,
2179 &client,
2180 shared_bitmap_manager.get(),
2181 NULL,
2182 settings,
2183 base::MessageLoopProxy::current(),
2184 nullptr);
2185 client.SetLayerTreeHost(host.get());
2186 host->Composite(base::TimeTicks::Now());
2188 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2191 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2192 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2194 LayerTreeSettings settings;
2195 settings.max_partial_texture_updates = 4;
2196 settings.single_thread_proxy_scheduler = false;
2198 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2199 new TestSharedBitmapManager());
2200 scoped_ptr<LayerTreeHost> host =
2201 LayerTreeHost::CreateSingleThreaded(&client,
2202 &client,
2203 shared_bitmap_manager.get(),
2204 NULL,
2205 settings,
2206 base::MessageLoopProxy::current(),
2207 nullptr);
2208 client.SetLayerTreeHost(host.get());
2209 host->Composite(base::TimeTicks::Now());
2211 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2214 TEST(LayerTreeHostTest,
2215 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2216 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2218 LayerTreeSettings settings;
2219 settings.max_partial_texture_updates = 4;
2220 settings.single_thread_proxy_scheduler = false;
2222 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2223 new TestSharedBitmapManager());
2224 scoped_ptr<LayerTreeHost> host =
2225 LayerTreeHost::CreateSingleThreaded(&client,
2226 &client,
2227 shared_bitmap_manager.get(),
2228 NULL,
2229 settings,
2230 base::MessageLoopProxy::current(),
2231 nullptr);
2232 client.SetLayerTreeHost(host.get());
2233 host->Composite(base::TimeTicks::Now());
2235 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2238 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
2239 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2240 : public LayerTreeHostTest {
2241 public:
2242 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2243 : root_layer_(FakeContentLayer::Create(&client_)),
2244 child_layer1_(FakeContentLayer::Create(&client_)),
2245 child_layer2_(FakeContentLayer::Create(&client_)),
2246 num_commits_(0) {}
2248 void BeginTest() override {
2249 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2250 root_layer_->SetBounds(gfx::Size(100, 100));
2251 child_layer1_->SetBounds(gfx::Size(100, 100));
2252 child_layer2_->SetBounds(gfx::Size(100, 100));
2253 root_layer_->AddChild(child_layer1_);
2254 root_layer_->AddChild(child_layer2_);
2255 layer_tree_host()->SetRootLayer(root_layer_);
2256 PostSetNeedsCommitToMainThread();
2259 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2260 bool visible) override {
2261 if (visible) {
2262 // One backing should remain unevicted.
2263 EXPECT_EQ(
2264 100u * 100u * 4u * 1u,
2265 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2266 } else {
2267 EXPECT_EQ(
2268 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2271 // Make sure that contents textures are marked as having been
2272 // purged.
2273 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2274 // End the test in this state.
2275 EndTest();
2278 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2279 ++num_commits_;
2280 switch (num_commits_) {
2281 case 1:
2282 // All three backings should have memory.
2283 EXPECT_EQ(
2284 100u * 100u * 4u * 3u,
2285 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2286 // Set a new policy that will kick out 1 of the 3 resources.
2287 // Because a resource was evicted, a commit will be kicked off.
2288 host_impl->SetMemoryPolicy(
2289 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2290 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2291 1000));
2292 break;
2293 case 2:
2294 // Only two backings should have memory.
2295 EXPECT_EQ(
2296 100u * 100u * 4u * 2u,
2297 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2298 // Become backgrounded, which will cause 1 more resource to be
2299 // evicted.
2300 PostSetVisibleToMainThread(false);
2301 break;
2302 default:
2303 // No further commits should happen because this is not visible
2304 // anymore.
2305 NOTREACHED();
2306 break;
2310 void AfterTest() override {}
2312 private:
2313 FakeContentLayerClient client_;
2314 scoped_refptr<FakeContentLayer> root_layer_;
2315 scoped_refptr<FakeContentLayer> child_layer1_;
2316 scoped_refptr<FakeContentLayer> child_layer2_;
2317 int num_commits_;
2320 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2321 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2323 class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
2324 public:
2325 class PaintClient : public FakeContentLayerClient {
2326 public:
2327 PaintClient() : paint_count_(0) {}
2329 int paint_count() const { return paint_count_; }
2331 void PaintContents(SkCanvas* canvas,
2332 const gfx::Rect& clip,
2333 PaintingControlSetting picture_control) override {
2334 FakeContentLayerClient::PaintContents(canvas, clip, picture_control);
2335 ++paint_count_;
2338 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
2339 const gfx::Rect& clip,
2340 PaintingControlSetting picture_control) override {
2341 NOTIMPLEMENTED();
2342 return DisplayItemList::Create();
2345 bool FillsBoundsCompletely() const override { return false; }
2347 private:
2348 int paint_count_;
2351 void SetupTree() override {
2352 num_tiles_rastered_ = 0;
2354 scoped_refptr<Layer> root_layer;
2355 if (layer_tree_host()->settings().impl_side_painting)
2356 root_layer = PictureLayer::Create(&client_);
2357 else
2358 root_layer = ContentLayer::Create(&client_);
2359 client_.set_fill_with_nonsolid_color(true);
2360 root_layer->SetIsDrawable(true);
2361 root_layer->SetBounds(gfx::Size(10, 10));
2362 root_layer->SetContentsOpaque(true);
2364 layer_tree_host()->SetRootLayer(root_layer);
2366 // The expecations are based on the assumption that the default
2367 // LCD settings are:
2368 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2369 EXPECT_FALSE(root_layer->can_use_lcd_text());
2371 LayerTreeHostTest::SetupTree();
2374 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2376 void DidCommitAndDrawFrame() override {
2377 switch (layer_tree_host()->source_frame_number()) {
2378 case 1:
2379 // The first update consists of a paint of the whole layer.
2380 EXPECT_EQ(1, client_.paint_count());
2381 // LCD text must have been enabled on the layer.
2382 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2383 PostSetNeedsCommitToMainThread();
2384 break;
2385 case 2:
2386 // Since nothing changed on layer, there should be no paint.
2387 EXPECT_EQ(1, client_.paint_count());
2388 // LCD text must not have changed.
2389 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2390 // Change layer opacity that should trigger lcd change.
2391 layer_tree_host()->root_layer()->SetOpacity(.5f);
2392 break;
2393 case 3:
2394 // LCD text doesn't require re-recording, so no painting should occur.
2395 EXPECT_EQ(1, client_.paint_count());
2396 // LCD text must have been disabled on the layer due to opacity.
2397 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2398 // Change layer opacity that should not trigger lcd change.
2399 layer_tree_host()->root_layer()->SetOpacity(1.f);
2400 break;
2401 case 4:
2402 // LCD text doesn't require re-recording, so no painting should occur.
2403 EXPECT_EQ(1, client_.paint_count());
2404 // Even though LCD text could be allowed.
2405 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2406 EndTest();
2407 break;
2411 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
2412 const Tile* tile) override {
2413 ++num_tiles_rastered_;
2416 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2417 switch (host_impl->active_tree()->source_frame_number()) {
2418 case 0:
2419 // The first draw.
2420 EXPECT_EQ(1, num_tiles_rastered_);
2421 break;
2422 case 1:
2423 // Nothing changed on the layer.
2424 EXPECT_EQ(1, num_tiles_rastered_);
2425 break;
2426 case 2:
2427 // LCD text was disabled, it should be re-rastered with LCD text off.
2428 EXPECT_EQ(2, num_tiles_rastered_);
2429 break;
2430 case 3:
2431 // LCD text was enabled but it's sticky and stays off.
2432 EXPECT_EQ(2, num_tiles_rastered_);
2433 break;
2437 void AfterTest() override {}
2439 private:
2440 PaintClient client_;
2441 int num_tiles_rastered_;
2444 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
2446 // Verify that the BeginFrame notification is used to initiate rendering.
2447 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2448 public:
2449 void InitializeSettings(LayerTreeSettings* settings) override {
2450 settings->use_external_begin_frame_source = true;
2453 void BeginTest() override {
2454 // This will trigger a SetNeedsBeginFrame which will trigger a
2455 // BeginFrame.
2456 PostSetNeedsCommitToMainThread();
2459 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2460 LayerTreeHostImpl::FrameData* frame,
2461 DrawResult draw_result) override {
2462 EndTest();
2463 return DRAW_SUCCESS;
2466 void AfterTest() override {}
2468 private:
2469 base::TimeTicks frame_time_;
2472 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2474 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2475 : public LayerTreeHostTest {
2476 public:
2477 void InitializeSettings(LayerTreeSettings* settings) override {
2478 settings->use_external_begin_frame_source = true;
2479 settings->using_synchronous_renderer_compositor = true;
2482 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2484 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2485 // The BeginFrame notification is turned off now but will get enabled
2486 // once we return. End test while it's enabled.
2487 ImplThreadTaskRunner()->PostTask(
2488 FROM_HERE,
2489 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2490 base::Unretained(this)));
2493 void AfterTest() override {}
2496 MULTI_THREAD_TEST_F(
2497 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2499 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2500 protected:
2501 LayerTreeHostTestAbortedCommitDoesntStall()
2502 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2504 void InitializeSettings(LayerTreeSettings* settings) override {
2505 settings->use_external_begin_frame_source = true;
2508 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2510 void DidCommit() override {
2511 commit_count_++;
2512 if (commit_count_ == 4) {
2513 // After two aborted commits, request a real commit now to make sure a
2514 // real commit following an aborted commit will still complete and
2515 // end the test even when the Impl thread is idle.
2516 layer_tree_host()->SetNeedsCommit();
2520 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2521 CommitEarlyOutReason reason) override {
2522 commit_abort_count_++;
2523 // Initiate another abortable commit.
2524 host_impl->SetNeedsCommit();
2527 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2528 commit_complete_count_++;
2529 if (commit_complete_count_ == 1) {
2530 // Initiate an abortable commit after the first commit.
2531 host_impl->SetNeedsCommit();
2532 } else {
2533 EndTest();
2537 void AfterTest() override {
2538 EXPECT_EQ(commit_count_, 5);
2539 EXPECT_EQ(commit_abort_count_, 3);
2540 EXPECT_EQ(commit_complete_count_, 2);
2543 int commit_count_;
2544 int commit_abort_count_;
2545 int commit_complete_count_;
2548 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2549 : public LayerTreeHostTestAbortedCommitDoesntStall {
2550 void InitializeSettings(LayerTreeSettings* settings) override {
2551 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2552 settings->using_synchronous_renderer_compositor = true;
2556 MULTI_THREAD_TEST_F(
2557 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2559 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2560 : public LayerTreeHostTestAbortedCommitDoesntStall {
2561 void InitializeSettings(LayerTreeSettings* settings) override {
2562 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2563 settings->throttle_frame_production = false;
2567 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2569 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2570 : public LayerTreeHostTest {
2571 protected:
2572 void InitializeSettings(LayerTreeSettings* settings) override {
2573 settings->impl_side_painting = true;
2576 void SetupTree() override {
2577 LayerTreeHostTest::SetupTree();
2579 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2580 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2581 layer->SetBounds(gfx::Size(10, 10));
2582 layer_tree_host()->root_layer()->AddChild(layer);
2585 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2587 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2588 EndTest();
2591 void AfterTest() override {}
2593 FakeContentLayerClient client_;
2596 MULTI_THREAD_TEST_F(
2597 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2599 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2600 : public LayerTreeHostTest {
2601 public:
2602 class SetBoundsClient : public ContentLayerClient {
2603 public:
2604 SetBoundsClient() : layer_(0) {}
2606 void set_layer(Layer* layer) { layer_ = layer; }
2608 void PaintContents(SkCanvas* canvas,
2609 const gfx::Rect& clip,
2610 PaintingControlSetting picture_control) override {
2611 layer_->SetBounds(gfx::Size(2, 2));
2614 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
2615 const gfx::Rect& clip,
2616 PaintingControlSetting picture_control) override {
2617 NOTIMPLEMENTED();
2618 return DisplayItemList::Create();
2621 bool FillsBoundsCompletely() const override { return false; }
2623 private:
2624 Layer* layer_;
2627 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2629 void SetupTree() override {
2630 if (layer_tree_host()->settings().impl_side_painting) {
2631 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_);
2632 layer_tree_host()->SetRootLayer(root_layer);
2633 } else {
2634 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2635 layer_tree_host()->SetRootLayer(root_layer);
2637 Layer* root_layer = layer_tree_host()->root_layer();
2638 root_layer->SetIsDrawable(true);
2639 root_layer->SetBounds(gfx::Size(1, 1));
2641 client_.set_layer(root_layer);
2643 LayerTreeHostTest::SetupTree();
2646 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2647 void AfterTest() override {}
2649 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2650 num_commits_++;
2651 if (num_commits_ == 1) {
2652 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2653 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds());
2654 } else {
2655 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2656 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds());
2657 EndTest();
2661 private:
2662 SetBoundsClient client_;
2663 int num_commits_;
2666 SINGLE_AND_MULTI_THREAD_TEST_F(
2667 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2669 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2670 public:
2671 MockIOSurfaceWebGraphicsContext3D() {
2672 test_capabilities_.gpu.iosurface = true;
2673 test_capabilities_.gpu.texture_rectangle = true;
2676 GLuint createTexture() override { return 1; }
2677 MOCK_METHOD1(activeTexture, void(GLenum texture));
2678 MOCK_METHOD2(bindTexture, void(GLenum target,
2679 GLuint texture_id));
2680 MOCK_METHOD3(texParameteri, void(GLenum target,
2681 GLenum pname,
2682 GLint param));
2683 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2684 GLint width,
2685 GLint height,
2686 GLuint ioSurfaceId,
2687 GLuint plane));
2688 MOCK_METHOD4(drawElements, void(GLenum mode,
2689 GLsizei count,
2690 GLenum type,
2691 GLintptr offset));
2692 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2693 MOCK_METHOD2(produceTextureCHROMIUM,
2694 void(GLenum target, const GLbyte* mailbox));
2697 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2698 protected:
2699 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2700 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2701 new MockIOSurfaceWebGraphicsContext3D);
2702 mock_context_ = mock_context_owned.get();
2704 if (delegating_renderer())
2705 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
2706 else
2707 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
2710 void SetupTree() override {
2711 LayerTreeHostTest::SetupTree();
2713 layer_tree_host()->root_layer()->SetIsDrawable(false);
2715 io_surface_id_ = 9;
2716 io_surface_size_ = gfx::Size(6, 7);
2718 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2719 io_surface_layer->SetBounds(gfx::Size(10, 10));
2720 io_surface_layer->SetIsDrawable(true);
2721 io_surface_layer->SetContentsOpaque(true);
2722 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2723 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2726 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2728 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2729 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2730 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2732 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2733 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2734 .Times(AtLeast(1));
2735 EXPECT_CALL(*mock_context_,
2736 texParameteri(
2737 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2738 .Times(1);
2739 EXPECT_CALL(*mock_context_,
2740 texParameteri(
2741 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2742 .Times(1);
2743 EXPECT_CALL(*mock_context_,
2744 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2745 GL_TEXTURE_POOL_CHROMIUM,
2746 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2747 EXPECT_CALL(*mock_context_,
2748 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2749 GL_TEXTURE_WRAP_S,
2750 GL_CLAMP_TO_EDGE)).Times(1);
2751 EXPECT_CALL(*mock_context_,
2752 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2753 GL_TEXTURE_WRAP_T,
2754 GL_CLAMP_TO_EDGE)).Times(1);
2756 EXPECT_CALL(*mock_context_,
2757 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2758 io_surface_size_.width(),
2759 io_surface_size_.height(),
2760 io_surface_id_,
2761 0)).Times(1);
2763 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2766 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2767 LayerTreeHostImpl::FrameData* frame,
2768 DrawResult draw_result) override {
2769 Mock::VerifyAndClearExpectations(&mock_context_);
2770 ResourceProvider* resource_provider = host_impl->resource_provider();
2771 EXPECT_EQ(1u, resource_provider->num_resources());
2772 CHECK_EQ(1u, frame->render_passes.size());
2773 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2774 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
2775 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2776 const IOSurfaceDrawQuad* io_surface_draw_quad =
2777 IOSurfaceDrawQuad::MaterialCast(quad);
2778 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2779 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
2780 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2781 resource_provider->TargetForTesting(
2782 io_surface_draw_quad->io_surface_resource_id));
2784 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2785 .Times(1);
2786 if (delegating_renderer()) {
2787 // The io surface layer's resource should be sent to the parent.
2788 EXPECT_CALL(*mock_context_,
2789 produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2790 } else {
2791 // The io surface layer's texture is drawn.
2792 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2793 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2794 .Times(AtLeast(1));
2797 return draw_result;
2800 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2801 Mock::VerifyAndClearExpectations(&mock_context_);
2803 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2804 EndTest();
2807 void AfterTest() override {}
2809 int io_surface_id_;
2810 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2811 gfx::Size io_surface_size_;
2814 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2816 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2817 public:
2818 void BeginTest() override {
2819 frame_ = 0;
2820 PostSetNeedsCommitToMainThread();
2823 // Round 1: commit + draw
2824 // Round 2: commit only (no draw/swap)
2825 // Round 3: draw only (no commit)
2827 void DidCommit() override {
2828 int commit = layer_tree_host()->source_frame_number();
2829 switch (commit) {
2830 case 2:
2831 // Round 2 done.
2832 EXPECT_EQ(1, frame_);
2833 layer_tree_host()->SetNeedsRedraw();
2834 break;
2838 void DidCompleteSwapBuffers() override {
2839 int commit = layer_tree_host()->source_frame_number();
2840 ++frame_;
2841 switch (frame_) {
2842 case 1:
2843 // Round 1 done.
2844 EXPECT_EQ(1, commit);
2845 layer_tree_host()->SetNeedsCommit();
2846 break;
2847 case 2:
2848 // Round 3 done.
2849 EXPECT_EQ(2, commit);
2850 EndTest();
2851 break;
2855 void AfterTest() override {}
2857 protected:
2858 int frame_;
2861 // Flaky on all platforms: http://crbug.com/327498
2862 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
2863 RunTest(true, true, true);
2866 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
2867 RunTest(true, false, true);
2870 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
2871 public:
2872 void InitializeSettings(LayerTreeSettings* settings) override {
2873 // PictureLayer can only be used with impl side painting enabled.
2874 settings->impl_side_painting = true;
2877 void SetupTree() override {
2878 layer_ = FakePictureLayer::Create(&client_);
2879 // Force commits to not be aborted so new frames get drawn, otherwise
2880 // the renderer gets deferred initialized but nothing new needs drawing.
2881 layer_->set_always_update_resources(true);
2882 layer_tree_host()->SetRootLayer(layer_);
2883 LayerTreeHostTest::SetupTree();
2886 void BeginTest() override {
2887 did_initialize_gl_ = false;
2888 did_release_gl_ = false;
2889 last_source_frame_number_drawn_ = -1; // Never drawn.
2890 PostSetNeedsCommitToMainThread();
2893 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2894 scoped_ptr<TestWebGraphicsContext3D> context3d(
2895 TestWebGraphicsContext3D::Create());
2897 return FakeOutputSurface::CreateDeferredGL(
2898 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
2899 delegating_renderer());
2902 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2903 ASSERT_TRUE(host_impl->RootLayer());
2904 FakePictureLayerImpl* layer_impl =
2905 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
2907 // The same frame can be draw multiple times if new visible tiles are
2908 // rasterized. But we want to make sure we only post DeferredInitialize
2909 // and ReleaseGL once, so early out if the same frame is drawn again.
2910 if (last_source_frame_number_drawn_ ==
2911 host_impl->active_tree()->source_frame_number())
2912 return;
2914 last_source_frame_number_drawn_ =
2915 host_impl->active_tree()->source_frame_number();
2917 if (!did_initialize_gl_) {
2918 EXPECT_LE(1u, layer_impl->append_quads_count());
2919 ImplThreadTaskRunner()->PostTask(
2920 FROM_HERE,
2921 base::Bind(
2922 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
2923 base::Unretained(this),
2924 base::Unretained(host_impl)));
2925 } else if (did_initialize_gl_ && !did_release_gl_) {
2926 EXPECT_LE(2u, layer_impl->append_quads_count());
2927 ImplThreadTaskRunner()->PostTask(
2928 FROM_HERE,
2929 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
2930 base::Unretained(this),
2931 base::Unretained(host_impl)));
2932 } else if (did_initialize_gl_ && did_release_gl_) {
2933 EXPECT_LE(3u, layer_impl->append_quads_count());
2934 EndTest();
2938 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
2939 EXPECT_FALSE(did_initialize_gl_);
2940 // SetAndInitializeContext3D calls SetNeedsCommit.
2941 FakeOutputSurface* fake_output_surface =
2942 static_cast<FakeOutputSurface*>(host_impl->output_surface());
2943 scoped_refptr<TestContextProvider> context_provider =
2944 TestContextProvider::Create(); // Not bound to thread.
2945 EXPECT_TRUE(
2946 fake_output_surface->InitializeAndSetContext3d(context_provider));
2947 did_initialize_gl_ = true;
2950 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
2951 EXPECT_TRUE(did_initialize_gl_);
2952 EXPECT_FALSE(did_release_gl_);
2953 // ReleaseGL calls SetNeedsCommit.
2954 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
2955 did_release_gl_ = true;
2958 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2959 ASSERT_TRUE(result);
2960 DelegatedFrameData* delegated_frame_data =
2961 output_surface()->last_sent_frame().delegated_frame_data.get();
2962 if (!delegated_frame_data)
2963 return;
2965 // Return all resources immediately.
2966 TransferableResourceArray resources_to_return =
2967 output_surface()->resources_held_by_parent();
2969 CompositorFrameAck ack;
2970 for (size_t i = 0; i < resources_to_return.size(); ++i)
2971 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
2972 host_impl->ReclaimResources(&ack);
2975 void AfterTest() override {
2976 EXPECT_TRUE(did_initialize_gl_);
2977 EXPECT_TRUE(did_release_gl_);
2980 private:
2981 FakeContentLayerClient client_;
2982 scoped_refptr<FakePictureLayer> layer_;
2983 bool did_initialize_gl_;
2984 bool did_release_gl_;
2985 int last_source_frame_number_drawn_;
2988 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
2990 class LayerTreeHostTestDeferredInitializeWithGpuRasterization
2991 : public LayerTreeHostTestDeferredInitialize {
2992 void InitializeSettings(LayerTreeSettings* settings) override {
2993 // PictureLayer can only be used with impl side painting enabled.
2994 settings->impl_side_painting = true;
2995 settings->gpu_rasterization_enabled = true;
2996 settings->gpu_rasterization_forced = true;
3000 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization);
3002 // Test for UI Resource management.
3003 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3004 public:
3005 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
3007 void InitializeSettings(LayerTreeSettings* settings) override {
3008 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
3011 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3013 void DidCommit() override {
3014 int frame = layer_tree_host()->source_frame_number();
3015 switch (frame) {
3016 case 1:
3017 CreateResource();
3018 CreateResource();
3019 PostSetNeedsCommitToMainThread();
3020 break;
3021 case 2:
3022 // Usually ScopedUIResource are deleted from the manager in their
3023 // destructor. Here we just want to test that a direct call to
3024 // DeleteUIResource works.
3025 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3026 PostSetNeedsCommitToMainThread();
3027 break;
3028 case 3:
3029 // DeleteUIResource can be called with an invalid id.
3030 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3031 PostSetNeedsCommitToMainThread();
3032 break;
3033 case 4:
3034 CreateResource();
3035 CreateResource();
3036 PostSetNeedsCommitToMainThread();
3037 break;
3038 case 5:
3039 ClearResources();
3040 EndTest();
3041 break;
3045 void PerformTest(LayerTreeHostImpl* impl) {
3046 TestWebGraphicsContext3D* context = TestContext();
3048 int frame = impl->active_tree()->source_frame_number();
3049 switch (frame) {
3050 case 0:
3051 ASSERT_EQ(0u, context->NumTextures());
3052 break;
3053 case 1:
3054 // Created two textures.
3055 ASSERT_EQ(2u, context->NumTextures());
3056 break;
3057 case 2:
3058 // One texture left after one deletion.
3059 ASSERT_EQ(1u, context->NumTextures());
3060 break;
3061 case 3:
3062 // Resource manager state should not change when delete is called on an
3063 // invalid id.
3064 ASSERT_EQ(1u, context->NumTextures());
3065 break;
3066 case 4:
3067 // Creation after deletion: two more creates should total up to
3068 // three textures.
3069 ASSERT_EQ(3u, context->NumTextures());
3070 break;
3074 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3075 if (!layer_tree_host()->settings().impl_side_painting)
3076 PerformTest(impl);
3079 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3080 if (layer_tree_host()->settings().impl_side_painting)
3081 PerformTest(impl);
3084 void AfterTest() override {}
3086 private:
3087 // Must clear all resources before exiting.
3088 void ClearResources() {
3089 for (int i = 0; i < num_ui_resources_; i++)
3090 ui_resources_[i] = nullptr;
3093 void CreateResource() {
3094 ui_resources_[num_ui_resources_++] =
3095 FakeScopedUIResource::Create(layer_tree_host());
3098 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3099 int num_ui_resources_;
3102 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3104 class PushPropertiesCountingLayerImpl : public LayerImpl {
3105 public:
3106 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
3107 LayerTreeImpl* tree_impl, int id) {
3108 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
3111 ~PushPropertiesCountingLayerImpl() override {}
3113 void PushPropertiesTo(LayerImpl* layer) override {
3114 LayerImpl::PushPropertiesTo(layer);
3115 push_properties_count_++;
3116 // Push state to the active tree because we can only access it from there.
3117 static_cast<PushPropertiesCountingLayerImpl*>(
3118 layer)->push_properties_count_ = push_properties_count_;
3121 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3122 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3125 size_t push_properties_count() const { return push_properties_count_; }
3126 void reset_push_properties_count() { push_properties_count_ = 0; }
3128 private:
3129 size_t push_properties_count_;
3131 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
3132 : LayerImpl(tree_impl, id),
3133 push_properties_count_(0) {
3134 SetBounds(gfx::Size(1, 1));
3138 class PushPropertiesCountingLayer : public Layer {
3139 public:
3140 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3141 return new PushPropertiesCountingLayer();
3144 void PushPropertiesTo(LayerImpl* layer) override {
3145 Layer::PushPropertiesTo(layer);
3146 push_properties_count_++;
3147 if (persist_needs_push_properties_)
3148 needs_push_properties_ = true;
3151 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3152 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3155 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
3157 size_t push_properties_count() const { return push_properties_count_; }
3158 void reset_push_properties_count() { push_properties_count_ = 0; }
3160 void set_persist_needs_push_properties(bool persist) {
3161 persist_needs_push_properties_ = persist;
3164 private:
3165 PushPropertiesCountingLayer()
3166 : push_properties_count_(0), persist_needs_push_properties_(false) {
3167 SetBounds(gfx::Size(1, 1));
3169 ~PushPropertiesCountingLayer() override {}
3171 size_t push_properties_count_;
3172 bool persist_needs_push_properties_;
3175 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3176 protected:
3177 void BeginTest() override {
3178 num_commits_ = 0;
3179 expected_push_properties_root_ = 0;
3180 expected_push_properties_child_ = 0;
3181 expected_push_properties_grandchild_ = 0;
3182 expected_push_properties_child2_ = 0;
3183 expected_push_properties_other_root_ = 0;
3184 expected_push_properties_leaf_layer_ = 0;
3185 PostSetNeedsCommitToMainThread();
3188 void SetupTree() override {
3189 root_ = PushPropertiesCountingLayer::Create();
3190 root_->CreateRenderSurface();
3191 child_ = PushPropertiesCountingLayer::Create();
3192 child2_ = PushPropertiesCountingLayer::Create();
3193 grandchild_ = PushPropertiesCountingLayer::Create();
3194 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3195 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3197 root_->AddChild(child_);
3198 root_->AddChild(child2_);
3199 child_->AddChild(grandchild_);
3200 child2_->AddChild(leaf_always_pushing_layer_);
3202 other_root_ = PushPropertiesCountingLayer::Create();
3203 other_root_->CreateRenderSurface();
3205 // Don't set the root layer here.
3206 LayerTreeHostTest::SetupTree();
3209 void DidCommitAndDrawFrame() override {
3210 ++num_commits_;
3212 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3213 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3214 EXPECT_EQ(expected_push_properties_grandchild_,
3215 grandchild_->push_properties_count());
3216 EXPECT_EQ(expected_push_properties_child2_,
3217 child2_->push_properties_count());
3218 EXPECT_EQ(expected_push_properties_other_root_,
3219 other_root_->push_properties_count());
3220 EXPECT_EQ(expected_push_properties_leaf_layer_,
3221 leaf_always_pushing_layer_->push_properties_count());
3223 // The scrollbar layer always needs to be pushed.
3224 if (root_->layer_tree_host()) {
3225 EXPECT_TRUE(root_->descendant_needs_push_properties());
3226 EXPECT_FALSE(root_->needs_push_properties());
3228 if (child2_->layer_tree_host()) {
3229 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3230 EXPECT_FALSE(child2_->needs_push_properties());
3232 if (leaf_always_pushing_layer_->layer_tree_host()) {
3233 EXPECT_FALSE(
3234 leaf_always_pushing_layer_->descendant_needs_push_properties());
3235 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3238 // child_ and grandchild_ don't persist their need to push properties.
3239 if (child_->layer_tree_host()) {
3240 EXPECT_FALSE(child_->descendant_needs_push_properties());
3241 EXPECT_FALSE(child_->needs_push_properties());
3243 if (grandchild_->layer_tree_host()) {
3244 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3245 EXPECT_FALSE(grandchild_->needs_push_properties());
3248 if (other_root_->layer_tree_host()) {
3249 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3250 EXPECT_FALSE(other_root_->needs_push_properties());
3253 switch (num_commits_) {
3254 case 1:
3255 layer_tree_host()->SetRootLayer(root_);
3256 // Layers added to the tree get committed.
3257 ++expected_push_properties_root_;
3258 ++expected_push_properties_child_;
3259 ++expected_push_properties_grandchild_;
3260 ++expected_push_properties_child2_;
3261 break;
3262 case 2:
3263 layer_tree_host()->SetNeedsCommit();
3264 // No layers need commit.
3265 break;
3266 case 3:
3267 layer_tree_host()->SetRootLayer(other_root_);
3268 // Layers added to the tree get committed.
3269 ++expected_push_properties_other_root_;
3270 break;
3271 case 4:
3272 layer_tree_host()->SetRootLayer(root_);
3273 // Layers added to the tree get committed.
3274 ++expected_push_properties_root_;
3275 ++expected_push_properties_child_;
3276 ++expected_push_properties_grandchild_;
3277 ++expected_push_properties_child2_;
3278 break;
3279 case 5:
3280 layer_tree_host()->SetNeedsCommit();
3281 // No layers need commit.
3282 break;
3283 case 6:
3284 child_->RemoveFromParent();
3285 // No layers need commit.
3286 break;
3287 case 7:
3288 root_->AddChild(child_);
3289 // Layers added to the tree get committed.
3290 ++expected_push_properties_child_;
3291 ++expected_push_properties_grandchild_;
3292 break;
3293 case 8:
3294 grandchild_->RemoveFromParent();
3295 // No layers need commit.
3296 break;
3297 case 9:
3298 child_->AddChild(grandchild_);
3299 // Layers added to the tree get committed.
3300 ++expected_push_properties_grandchild_;
3301 break;
3302 case 10:
3303 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3304 // No layers need commit.
3305 break;
3306 case 11:
3307 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3308 // No layers need commit.
3309 break;
3310 case 12:
3311 child_->SetPosition(gfx::Point(1, 1));
3312 // The modified layer needs commit
3313 ++expected_push_properties_child_;
3314 break;
3315 case 13:
3316 child2_->SetPosition(gfx::Point(1, 1));
3317 // The modified layer needs commit
3318 ++expected_push_properties_child2_;
3319 break;
3320 case 14:
3321 child_->RemoveFromParent();
3322 root_->AddChild(child_);
3323 // Layers added to the tree get committed.
3324 ++expected_push_properties_child_;
3325 ++expected_push_properties_grandchild_;
3326 break;
3327 case 15:
3328 grandchild_->SetPosition(gfx::Point(1, 1));
3329 // The modified layer needs commit
3330 ++expected_push_properties_grandchild_;
3331 break;
3332 case 16:
3333 // SetNeedsDisplay does not always set needs commit (so call it
3334 // explicitly), but is a property change.
3335 child_->SetNeedsDisplay();
3336 ++expected_push_properties_child_;
3337 layer_tree_host()->SetNeedsCommit();
3338 break;
3339 case 17:
3340 EndTest();
3341 break;
3344 // The leaf layer always pushes.
3345 if (leaf_always_pushing_layer_->layer_tree_host())
3346 ++expected_push_properties_leaf_layer_;
3349 void AfterTest() override {}
3351 int num_commits_;
3352 FakeContentLayerClient client_;
3353 scoped_refptr<PushPropertiesCountingLayer> root_;
3354 scoped_refptr<PushPropertiesCountingLayer> child_;
3355 scoped_refptr<PushPropertiesCountingLayer> child2_;
3356 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3357 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3358 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3359 size_t expected_push_properties_root_;
3360 size_t expected_push_properties_child_;
3361 size_t expected_push_properties_child2_;
3362 size_t expected_push_properties_grandchild_;
3363 size_t expected_push_properties_other_root_;
3364 size_t expected_push_properties_leaf_layer_;
3367 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3369 class LayerTreeHostTestImplLayersPushProperties
3370 : public LayerTreeHostTestLayersPushProperties {
3371 protected:
3372 void BeginTest() override {
3373 expected_push_properties_root_impl_ = 0;
3374 expected_push_properties_child_impl_ = 0;
3375 expected_push_properties_grandchild_impl_ = 0;
3376 expected_push_properties_child2_impl_ = 0;
3377 expected_push_properties_grandchild2_impl_ = 0;
3378 LayerTreeHostTestLayersPushProperties::BeginTest();
3381 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3382 // These commits are in response to the changes made in
3383 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3384 switch (num_commits_) {
3385 case 0:
3386 // Tree hasn't been setup yet don't bother to check anything.
3387 return;
3388 case 1:
3389 // Root gets set up, Everyone is initialized.
3390 ++expected_push_properties_root_impl_;
3391 ++expected_push_properties_child_impl_;
3392 ++expected_push_properties_grandchild_impl_;
3393 ++expected_push_properties_child2_impl_;
3394 ++expected_push_properties_grandchild2_impl_;
3395 break;
3396 case 2:
3397 // Tree doesn't change but the one leaf that always pushes is pushed.
3398 ++expected_push_properties_grandchild2_impl_;
3399 break;
3400 case 3:
3401 // Root is swapped here.
3402 // Clear the expected push properties the tree will be rebuilt.
3403 expected_push_properties_root_impl_ = 0;
3404 expected_push_properties_child_impl_ = 0;
3405 expected_push_properties_grandchild_impl_ = 0;
3406 expected_push_properties_child2_impl_ = 0;
3407 expected_push_properties_grandchild2_impl_ = 0;
3409 // Make sure the new root is pushed.
3410 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3411 host_impl->RootLayer())->push_properties_count());
3412 return;
3413 case 4:
3414 // Root is swapped back all of the layers in the tree get pushed.
3415 ++expected_push_properties_root_impl_;
3416 ++expected_push_properties_child_impl_;
3417 ++expected_push_properties_grandchild_impl_;
3418 ++expected_push_properties_child2_impl_;
3419 ++expected_push_properties_grandchild2_impl_;
3420 break;
3421 case 5:
3422 // Tree doesn't change but the one leaf that always pushes is pushed.
3423 ++expected_push_properties_grandchild2_impl_;
3424 break;
3425 case 6:
3426 // First child is removed. Structure of the tree changes here so swap
3427 // some of the values. child_impl becomes child2_impl.
3428 expected_push_properties_child_impl_ =
3429 expected_push_properties_child2_impl_;
3430 expected_push_properties_child2_impl_ = 0;
3431 // grandchild_impl becomes grandchild2_impl.
3432 expected_push_properties_grandchild_impl_ =
3433 expected_push_properties_grandchild2_impl_;
3434 expected_push_properties_grandchild2_impl_ = 0;
3436 // grandchild_impl is now the leaf that always pushes. It is pushed.
3437 ++expected_push_properties_grandchild_impl_;
3438 break;
3439 case 7:
3440 // The leaf that always pushes is pushed.
3441 ++expected_push_properties_grandchild_impl_;
3443 // Child is added back. New layers are initialized.
3444 ++expected_push_properties_grandchild2_impl_;
3445 ++expected_push_properties_child2_impl_;
3446 break;
3447 case 8:
3448 // Leaf is removed.
3449 expected_push_properties_grandchild2_impl_ = 0;
3451 // Always pushing.
3452 ++expected_push_properties_grandchild_impl_;
3453 break;
3454 case 9:
3455 // Leaf is added back
3456 ++expected_push_properties_grandchild2_impl_;
3458 // The leaf that always pushes is pushed.
3459 ++expected_push_properties_grandchild_impl_;
3460 break;
3461 case 10:
3462 // The leaf that always pushes is pushed.
3463 ++expected_push_properties_grandchild_impl_;
3464 break;
3465 case 11:
3466 // The leaf that always pushes is pushed.
3467 ++expected_push_properties_grandchild_impl_;
3468 break;
3469 case 12:
3470 // The leaf that always pushes is pushed.
3471 ++expected_push_properties_grandchild_impl_;
3473 // This child position was changed.
3474 ++expected_push_properties_child2_impl_;
3475 break;
3476 case 13:
3477 // The position of this child was changed.
3478 ++expected_push_properties_child_impl_;
3480 // The leaf that always pushes is pushed.
3481 ++expected_push_properties_grandchild_impl_;
3482 break;
3483 case 14:
3484 // Second child is removed from tree. Don't discard counts because
3485 // they are added back before commit.
3487 // The leaf that always pushes is pushed.
3488 ++expected_push_properties_grandchild_impl_;
3490 // Second child added back.
3491 ++expected_push_properties_child2_impl_;
3492 ++expected_push_properties_grandchild2_impl_;
3494 break;
3495 case 15:
3496 // The position of this child was changed.
3497 ++expected_push_properties_grandchild2_impl_;
3499 // The leaf that always pushes is pushed.
3500 ++expected_push_properties_grandchild_impl_;
3501 break;
3502 case 16:
3503 // Second child is invalidated with SetNeedsDisplay
3504 ++expected_push_properties_child2_impl_;
3506 // The leaf that always pushed is pushed.
3507 ++expected_push_properties_grandchild_impl_;
3508 break;
3511 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3512 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3513 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3514 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3515 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3517 // Pull the layers that we need from the tree assuming the same structure
3518 // as LayerTreeHostTestLayersPushProperties
3519 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3520 host_impl->RootLayer());
3522 if (root_impl_ && root_impl_->children().size() > 0) {
3523 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3524 root_impl_->children()[0]);
3526 if (child_impl_ && child_impl_->children().size() > 0)
3527 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3528 child_impl_->children()[0]);
3531 if (root_impl_ && root_impl_->children().size() > 1) {
3532 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3533 root_impl_->children()[1]);
3535 if (child2_impl_ && child2_impl_->children().size() > 0)
3536 leaf_always_pushing_layer_impl_ =
3537 static_cast<PushPropertiesCountingLayerImpl*>(
3538 child2_impl_->children()[0]);
3541 if (root_impl_)
3542 EXPECT_EQ(expected_push_properties_root_impl_,
3543 root_impl_->push_properties_count());
3544 if (child_impl_)
3545 EXPECT_EQ(expected_push_properties_child_impl_,
3546 child_impl_->push_properties_count());
3547 if (grandchild_impl_)
3548 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3549 grandchild_impl_->push_properties_count());
3550 if (child2_impl_)
3551 EXPECT_EQ(expected_push_properties_child2_impl_,
3552 child2_impl_->push_properties_count());
3553 if (leaf_always_pushing_layer_impl_)
3554 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3555 leaf_always_pushing_layer_impl_->push_properties_count());
3558 size_t expected_push_properties_root_impl_;
3559 size_t expected_push_properties_child_impl_;
3560 size_t expected_push_properties_child2_impl_;
3561 size_t expected_push_properties_grandchild_impl_;
3562 size_t expected_push_properties_grandchild2_impl_;
3565 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3566 RunTestWithImplSidePainting();
3569 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3570 : public LayerTreeHostTest {
3571 protected:
3572 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3574 void SetupTree() override {
3575 root_ = Layer::Create();
3576 root_->CreateRenderSurface();
3577 root_->SetBounds(gfx::Size(1, 1));
3579 bool paint_scrollbar = true;
3580 bool has_thumb = false;
3581 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3582 paint_scrollbar, has_thumb, root_->id());
3584 root_->AddChild(scrollbar_layer_);
3586 layer_tree_host()->SetRootLayer(root_);
3587 LayerTreeHostTest::SetupTree();
3590 void DidCommitAndDrawFrame() override {
3591 switch (layer_tree_host()->source_frame_number()) {
3592 case 0:
3593 break;
3594 case 1: {
3595 // During update, the ignore_set_needs_commit_ bit is set to true to
3596 // avoid causing a second commit to be scheduled. If a property change
3597 // is made during this, however, it needs to be pushed in the upcoming
3598 // commit.
3599 scoped_ptr<base::AutoReset<bool>> ignore =
3600 scrollbar_layer_->IgnoreSetNeedsCommit();
3602 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3604 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3605 EXPECT_TRUE(root_->descendant_needs_push_properties());
3606 layer_tree_host()->SetNeedsCommit();
3608 scrollbar_layer_->reset_push_properties_count();
3609 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3610 break;
3612 case 2:
3613 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3614 EndTest();
3615 break;
3619 void AfterTest() override {}
3621 scoped_refptr<Layer> root_;
3622 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3625 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3627 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3628 protected:
3629 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3631 void SetupTree() override {
3632 root_ = PushPropertiesCountingLayer::Create();
3633 root_->CreateRenderSurface();
3634 child_ = PushPropertiesCountingLayer::Create();
3635 root_->AddChild(child_);
3637 layer_tree_host()->SetRootLayer(root_);
3638 LayerTreeHostTest::SetupTree();
3641 void DidCommitAndDrawFrame() override {
3642 switch (layer_tree_host()->source_frame_number()) {
3643 case 0:
3644 break;
3645 case 1: {
3646 // During update, the ignore_set_needs_commit_ bit is set to true to
3647 // avoid causing a second commit to be scheduled. If a property change
3648 // is made during this, however, it needs to be pushed in the upcoming
3649 // commit.
3650 EXPECT_FALSE(root_->needs_push_properties());
3651 EXPECT_FALSE(child_->needs_push_properties());
3652 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3653 root_->reset_push_properties_count();
3654 child_->reset_push_properties_count();
3655 child_->SetDrawsContent(true);
3656 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3657 EXPECT_EQ(0u, root_->push_properties_count());
3658 EXPECT_EQ(0u, child_->push_properties_count());
3659 EXPECT_TRUE(root_->needs_push_properties());
3660 EXPECT_TRUE(child_->needs_push_properties());
3661 break;
3663 case 2:
3664 EXPECT_EQ(1u, root_->push_properties_count());
3665 EXPECT_EQ(1u, child_->push_properties_count());
3666 EXPECT_FALSE(root_->needs_push_properties());
3667 EXPECT_FALSE(child_->needs_push_properties());
3668 EndTest();
3669 break;
3673 void AfterTest() override {}
3675 scoped_refptr<PushPropertiesCountingLayer> root_;
3676 scoped_refptr<PushPropertiesCountingLayer> child_;
3679 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3681 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3682 : public LayerTreeHostTest {
3683 protected:
3684 void BeginTest() override {
3685 expected_push_properties_root_ = 0;
3686 expected_push_properties_child_ = 0;
3687 expected_push_properties_grandchild1_ = 0;
3688 expected_push_properties_grandchild2_ = 0;
3689 expected_push_properties_grandchild3_ = 0;
3690 PostSetNeedsCommitToMainThread();
3693 void SetupTree() override {
3694 root_ = PushPropertiesCountingLayer::Create();
3695 root_->CreateRenderSurface();
3696 child_ = PushPropertiesCountingLayer::Create();
3697 grandchild1_ = PushPropertiesCountingLayer::Create();
3698 grandchild2_ = PushPropertiesCountingLayer::Create();
3699 grandchild3_ = PushPropertiesCountingLayer::Create();
3701 root_->AddChild(child_);
3702 child_->AddChild(grandchild1_);
3703 child_->AddChild(grandchild2_);
3704 child_->AddChild(grandchild3_);
3706 // Don't set the root layer here.
3707 LayerTreeHostTest::SetupTree();
3710 void AfterTest() override {}
3712 FakeContentLayerClient client_;
3713 scoped_refptr<PushPropertiesCountingLayer> root_;
3714 scoped_refptr<PushPropertiesCountingLayer> child_;
3715 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3716 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3717 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3718 size_t expected_push_properties_root_;
3719 size_t expected_push_properties_child_;
3720 size_t expected_push_properties_grandchild1_;
3721 size_t expected_push_properties_grandchild2_;
3722 size_t expected_push_properties_grandchild3_;
3725 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3726 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3727 protected:
3728 void DidCommitAndDrawFrame() override {
3729 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3730 switch (last_source_frame_number) {
3731 case 0:
3732 EXPECT_FALSE(root_->needs_push_properties());
3733 EXPECT_FALSE(root_->descendant_needs_push_properties());
3734 EXPECT_FALSE(child_->needs_push_properties());
3735 EXPECT_FALSE(child_->descendant_needs_push_properties());
3736 EXPECT_FALSE(grandchild1_->needs_push_properties());
3737 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3738 EXPECT_FALSE(grandchild2_->needs_push_properties());
3739 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3740 EXPECT_FALSE(grandchild3_->needs_push_properties());
3741 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3743 layer_tree_host()->SetRootLayer(root_);
3745 EXPECT_TRUE(root_->needs_push_properties());
3746 EXPECT_TRUE(root_->descendant_needs_push_properties());
3747 EXPECT_TRUE(child_->needs_push_properties());
3748 EXPECT_TRUE(child_->descendant_needs_push_properties());
3749 EXPECT_TRUE(grandchild1_->needs_push_properties());
3750 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3751 EXPECT_TRUE(grandchild2_->needs_push_properties());
3752 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3753 EXPECT_TRUE(grandchild3_->needs_push_properties());
3754 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3755 break;
3756 case 1:
3757 EndTest();
3758 break;
3763 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3765 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3766 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3767 protected:
3768 void DidCommitAndDrawFrame() override {
3769 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3770 switch (last_source_frame_number) {
3771 case 0:
3772 layer_tree_host()->SetRootLayer(root_);
3773 break;
3774 case 1:
3775 EXPECT_FALSE(root_->needs_push_properties());
3776 EXPECT_FALSE(root_->descendant_needs_push_properties());
3777 EXPECT_FALSE(child_->needs_push_properties());
3778 EXPECT_FALSE(child_->descendant_needs_push_properties());
3779 EXPECT_FALSE(grandchild1_->needs_push_properties());
3780 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3781 EXPECT_FALSE(grandchild2_->needs_push_properties());
3782 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3783 EXPECT_FALSE(grandchild3_->needs_push_properties());
3784 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3786 grandchild1_->RemoveFromParent();
3787 grandchild1_->SetPosition(gfx::Point(1, 1));
3789 EXPECT_FALSE(root_->needs_push_properties());
3790 EXPECT_FALSE(root_->descendant_needs_push_properties());
3791 EXPECT_FALSE(child_->needs_push_properties());
3792 EXPECT_FALSE(child_->descendant_needs_push_properties());
3793 EXPECT_FALSE(grandchild2_->needs_push_properties());
3794 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3795 EXPECT_FALSE(grandchild3_->needs_push_properties());
3796 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3798 child_->AddChild(grandchild1_);
3800 EXPECT_FALSE(root_->needs_push_properties());
3801 EXPECT_TRUE(root_->descendant_needs_push_properties());
3802 EXPECT_FALSE(child_->needs_push_properties());
3803 EXPECT_TRUE(child_->descendant_needs_push_properties());
3804 EXPECT_TRUE(grandchild1_->needs_push_properties());
3805 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3806 EXPECT_FALSE(grandchild2_->needs_push_properties());
3807 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3808 EXPECT_FALSE(grandchild3_->needs_push_properties());
3809 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3811 grandchild2_->SetPosition(gfx::Point(1, 1));
3813 EXPECT_FALSE(root_->needs_push_properties());
3814 EXPECT_TRUE(root_->descendant_needs_push_properties());
3815 EXPECT_FALSE(child_->needs_push_properties());
3816 EXPECT_TRUE(child_->descendant_needs_push_properties());
3817 EXPECT_TRUE(grandchild1_->needs_push_properties());
3818 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3819 EXPECT_TRUE(grandchild2_->needs_push_properties());
3820 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3821 EXPECT_FALSE(grandchild3_->needs_push_properties());
3822 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3824 // grandchild2_ will still need a push properties.
3825 grandchild1_->RemoveFromParent();
3827 EXPECT_FALSE(root_->needs_push_properties());
3828 EXPECT_TRUE(root_->descendant_needs_push_properties());
3829 EXPECT_FALSE(child_->needs_push_properties());
3830 EXPECT_TRUE(child_->descendant_needs_push_properties());
3832 // grandchild3_ does not need a push properties, so recursing should
3833 // no longer be needed.
3834 grandchild2_->RemoveFromParent();
3836 EXPECT_FALSE(root_->needs_push_properties());
3837 EXPECT_FALSE(root_->descendant_needs_push_properties());
3838 EXPECT_FALSE(child_->needs_push_properties());
3839 EXPECT_FALSE(child_->descendant_needs_push_properties());
3840 EndTest();
3841 break;
3846 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3848 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3849 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3850 protected:
3851 void DidCommitAndDrawFrame() override {
3852 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3853 switch (last_source_frame_number) {
3854 case 0:
3855 layer_tree_host()->SetRootLayer(root_);
3856 grandchild1_->set_persist_needs_push_properties(true);
3857 grandchild2_->set_persist_needs_push_properties(true);
3858 break;
3859 case 1:
3860 EXPECT_FALSE(root_->needs_push_properties());
3861 EXPECT_TRUE(root_->descendant_needs_push_properties());
3862 EXPECT_FALSE(child_->needs_push_properties());
3863 EXPECT_TRUE(child_->descendant_needs_push_properties());
3864 EXPECT_TRUE(grandchild1_->needs_push_properties());
3865 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3866 EXPECT_TRUE(grandchild2_->needs_push_properties());
3867 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3868 EXPECT_FALSE(grandchild3_->needs_push_properties());
3869 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3871 // grandchild2_ will still need a push properties.
3872 grandchild1_->RemoveFromParent();
3874 EXPECT_FALSE(root_->needs_push_properties());
3875 EXPECT_TRUE(root_->descendant_needs_push_properties());
3876 EXPECT_FALSE(child_->needs_push_properties());
3877 EXPECT_TRUE(child_->descendant_needs_push_properties());
3879 // grandchild3_ does not need a push properties, so recursing should
3880 // no longer be needed.
3881 grandchild2_->RemoveFromParent();
3883 EXPECT_FALSE(root_->needs_push_properties());
3884 EXPECT_FALSE(root_->descendant_needs_push_properties());
3885 EXPECT_FALSE(child_->needs_push_properties());
3886 EXPECT_FALSE(child_->descendant_needs_push_properties());
3887 EndTest();
3888 break;
3893 MULTI_THREAD_TEST_F(
3894 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3896 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3897 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3898 protected:
3899 void DidCommitAndDrawFrame() override {
3900 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3901 switch (last_source_frame_number) {
3902 case 0:
3903 layer_tree_host()->SetRootLayer(root_);
3904 break;
3905 case 1:
3906 EXPECT_FALSE(root_->needs_push_properties());
3907 EXPECT_FALSE(root_->descendant_needs_push_properties());
3908 EXPECT_FALSE(child_->needs_push_properties());
3909 EXPECT_FALSE(child_->descendant_needs_push_properties());
3910 EXPECT_FALSE(grandchild1_->needs_push_properties());
3911 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3912 EXPECT_FALSE(grandchild2_->needs_push_properties());
3913 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3914 EXPECT_FALSE(grandchild3_->needs_push_properties());
3915 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3917 // Change grandchildren while their parent is not in the tree.
3918 child_->RemoveFromParent();
3919 grandchild1_->SetPosition(gfx::Point(1, 1));
3920 grandchild2_->SetPosition(gfx::Point(1, 1));
3921 root_->AddChild(child_);
3923 EXPECT_FALSE(root_->needs_push_properties());
3924 EXPECT_TRUE(root_->descendant_needs_push_properties());
3925 EXPECT_TRUE(child_->needs_push_properties());
3926 EXPECT_TRUE(child_->descendant_needs_push_properties());
3927 EXPECT_TRUE(grandchild1_->needs_push_properties());
3928 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3929 EXPECT_TRUE(grandchild2_->needs_push_properties());
3930 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3931 EXPECT_TRUE(grandchild3_->needs_push_properties());
3932 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3934 grandchild1_->RemoveFromParent();
3936 EXPECT_FALSE(root_->needs_push_properties());
3937 EXPECT_TRUE(root_->descendant_needs_push_properties());
3938 EXPECT_TRUE(child_->needs_push_properties());
3939 EXPECT_TRUE(child_->descendant_needs_push_properties());
3941 grandchild2_->RemoveFromParent();
3943 EXPECT_FALSE(root_->needs_push_properties());
3944 EXPECT_TRUE(root_->descendant_needs_push_properties());
3945 EXPECT_TRUE(child_->needs_push_properties());
3946 EXPECT_TRUE(child_->descendant_needs_push_properties());
3948 grandchild3_->RemoveFromParent();
3950 EXPECT_FALSE(root_->needs_push_properties());
3951 EXPECT_TRUE(root_->descendant_needs_push_properties());
3952 EXPECT_TRUE(child_->needs_push_properties());
3953 EXPECT_FALSE(child_->descendant_needs_push_properties());
3955 EndTest();
3956 break;
3961 MULTI_THREAD_TEST_F(
3962 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3964 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3965 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3966 protected:
3967 void DidCommitAndDrawFrame() override {
3968 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3969 switch (last_source_frame_number) {
3970 case 0:
3971 layer_tree_host()->SetRootLayer(root_);
3972 break;
3973 case 1:
3974 EXPECT_FALSE(root_->needs_push_properties());
3975 EXPECT_FALSE(root_->descendant_needs_push_properties());
3976 EXPECT_FALSE(child_->needs_push_properties());
3977 EXPECT_FALSE(child_->descendant_needs_push_properties());
3978 EXPECT_FALSE(grandchild1_->needs_push_properties());
3979 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3980 EXPECT_FALSE(grandchild2_->needs_push_properties());
3981 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3982 EXPECT_FALSE(grandchild3_->needs_push_properties());
3983 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3985 child_->SetPosition(gfx::Point(1, 1));
3986 grandchild1_->SetPosition(gfx::Point(1, 1));
3987 grandchild2_->SetPosition(gfx::Point(1, 1));
3989 EXPECT_FALSE(root_->needs_push_properties());
3990 EXPECT_TRUE(root_->descendant_needs_push_properties());
3991 EXPECT_TRUE(child_->needs_push_properties());
3992 EXPECT_TRUE(child_->descendant_needs_push_properties());
3993 EXPECT_TRUE(grandchild1_->needs_push_properties());
3994 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3995 EXPECT_TRUE(grandchild2_->needs_push_properties());
3996 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3997 EXPECT_FALSE(grandchild3_->needs_push_properties());
3998 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4000 grandchild1_->RemoveFromParent();
4002 EXPECT_FALSE(root_->needs_push_properties());
4003 EXPECT_TRUE(root_->descendant_needs_push_properties());
4004 EXPECT_TRUE(child_->needs_push_properties());
4005 EXPECT_TRUE(child_->descendant_needs_push_properties());
4007 grandchild2_->RemoveFromParent();
4009 EXPECT_FALSE(root_->needs_push_properties());
4010 EXPECT_TRUE(root_->descendant_needs_push_properties());
4011 EXPECT_TRUE(child_->needs_push_properties());
4012 EXPECT_FALSE(child_->descendant_needs_push_properties());
4014 child_->RemoveFromParent();
4016 EXPECT_FALSE(root_->needs_push_properties());
4017 EXPECT_FALSE(root_->descendant_needs_push_properties());
4019 EndTest();
4020 break;
4025 MULTI_THREAD_TEST_F(
4026 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4028 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4029 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4030 protected:
4031 void DidCommitAndDrawFrame() override {
4032 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4033 switch (last_source_frame_number) {
4034 case 0:
4035 layer_tree_host()->SetRootLayer(root_);
4036 break;
4037 case 1:
4038 EXPECT_FALSE(root_->needs_push_properties());
4039 EXPECT_FALSE(root_->descendant_needs_push_properties());
4040 EXPECT_FALSE(child_->needs_push_properties());
4041 EXPECT_FALSE(child_->descendant_needs_push_properties());
4042 EXPECT_FALSE(grandchild1_->needs_push_properties());
4043 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4044 EXPECT_FALSE(grandchild2_->needs_push_properties());
4045 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4046 EXPECT_FALSE(grandchild3_->needs_push_properties());
4047 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4049 grandchild1_->SetPosition(gfx::Point(1, 1));
4050 grandchild2_->SetPosition(gfx::Point(1, 1));
4051 child_->SetPosition(gfx::Point(1, 1));
4053 EXPECT_FALSE(root_->needs_push_properties());
4054 EXPECT_TRUE(root_->descendant_needs_push_properties());
4055 EXPECT_TRUE(child_->needs_push_properties());
4056 EXPECT_TRUE(child_->descendant_needs_push_properties());
4057 EXPECT_TRUE(grandchild1_->needs_push_properties());
4058 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4059 EXPECT_TRUE(grandchild2_->needs_push_properties());
4060 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4061 EXPECT_FALSE(grandchild3_->needs_push_properties());
4062 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4064 grandchild1_->RemoveFromParent();
4066 EXPECT_FALSE(root_->needs_push_properties());
4067 EXPECT_TRUE(root_->descendant_needs_push_properties());
4068 EXPECT_TRUE(child_->needs_push_properties());
4069 EXPECT_TRUE(child_->descendant_needs_push_properties());
4071 grandchild2_->RemoveFromParent();
4073 EXPECT_FALSE(root_->needs_push_properties());
4074 EXPECT_TRUE(root_->descendant_needs_push_properties());
4075 EXPECT_TRUE(child_->needs_push_properties());
4076 EXPECT_FALSE(child_->descendant_needs_push_properties());
4078 child_->RemoveFromParent();
4080 EXPECT_FALSE(root_->needs_push_properties());
4081 EXPECT_FALSE(root_->descendant_needs_push_properties());
4083 EndTest();
4084 break;
4089 MULTI_THREAD_TEST_F(
4090 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4092 // This test verifies that the tree activation callback is invoked correctly.
4093 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4094 public:
4095 LayerTreeHostTestTreeActivationCallback()
4096 : num_commits_(0), callback_count_(0) {}
4098 void BeginTest() override {
4099 EXPECT_TRUE(HasImplThread());
4100 PostSetNeedsCommitToMainThread();
4103 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4104 LayerTreeHostImpl::FrameData* frame_data,
4105 DrawResult draw_result) override {
4106 ++num_commits_;
4107 switch (num_commits_) {
4108 case 1:
4109 EXPECT_EQ(0, callback_count_);
4110 callback_count_ = 0;
4111 SetCallback(true);
4112 PostSetNeedsCommitToMainThread();
4113 break;
4114 case 2:
4115 EXPECT_EQ(1, callback_count_);
4116 callback_count_ = 0;
4117 SetCallback(false);
4118 PostSetNeedsCommitToMainThread();
4119 break;
4120 case 3:
4121 EXPECT_EQ(0, callback_count_);
4122 callback_count_ = 0;
4123 EndTest();
4124 break;
4125 default:
4126 ADD_FAILURE() << num_commits_;
4127 EndTest();
4128 break;
4130 return LayerTreeHostTest::PrepareToDrawOnThread(
4131 host_impl, frame_data, draw_result);
4134 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
4136 void SetCallback(bool enable) {
4137 output_surface()->SetTreeActivationCallback(
4138 enable
4139 ? base::Bind(
4140 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4141 base::Unretained(this))
4142 : base::Closure());
4145 void ActivationCallback() { ++callback_count_; }
4147 int num_commits_;
4148 int callback_count_;
4151 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4152 RunTest(true, false, true);
4155 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4156 RunTest(true, true, true);
4159 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4160 public:
4161 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4163 void BeginTest() override {
4164 ASSERT_TRUE(!!invalidate_layer_.get())
4165 << "Derived tests must set this in SetupTree";
4167 // One initial commit.
4168 PostSetNeedsCommitToMainThread();
4171 void DidCommitAndDrawFrame() override {
4172 // After commit, invalidate the layer. This should cause a commit.
4173 if (layer_tree_host()->source_frame_number() == 1)
4174 invalidate_layer_->SetNeedsDisplay();
4177 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4178 num_draws_++;
4179 if (impl->active_tree()->source_frame_number() == 1)
4180 EndTest();
4183 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4184 num_commits_++;
4187 void AfterTest() override {
4188 EXPECT_GE(2, num_commits_);
4189 EXPECT_GE(2, num_draws_);
4192 protected:
4193 scoped_refptr<Layer> invalidate_layer_;
4195 private:
4196 int num_commits_;
4197 int num_draws_;
4200 // VideoLayer must support being invalidated and then passing that along
4201 // to the compositor thread, even though no resources are updated in
4202 // response to that invalidation.
4203 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4204 public:
4205 void SetupTree() override {
4206 LayerTreeHostTest::SetupTree();
4207 scoped_refptr<VideoLayer> video_layer =
4208 VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
4209 video_layer->SetBounds(gfx::Size(10, 10));
4210 video_layer->SetIsDrawable(true);
4211 layer_tree_host()->root_layer()->AddChild(video_layer);
4213 invalidate_layer_ = video_layer;
4216 private:
4217 FakeVideoFrameProvider provider_;
4220 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4222 // IOSurfaceLayer must support being invalidated and then passing that along
4223 // to the compositor thread, even though no resources are updated in
4224 // response to that invalidation.
4225 class LayerTreeHostTestIOSurfaceLayerInvalidate
4226 : public LayerInvalidateCausesDraw {
4227 public:
4228 void SetupTree() override {
4229 LayerTreeHostTest::SetupTree();
4230 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4231 layer->SetBounds(gfx::Size(10, 10));
4232 uint32_t fake_io_surface_id = 7;
4233 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4234 layer->SetIsDrawable(true);
4235 layer_tree_host()->root_layer()->AddChild(layer);
4237 invalidate_layer_ = layer;
4241 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4242 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4243 LayerTreeHostTestIOSurfaceLayerInvalidate);
4245 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4246 protected:
4247 void SetupTree() override {
4248 root_layer_ = Layer::Create();
4249 root_layer_->CreateRenderSurface();
4250 root_layer_->SetPosition(gfx::Point());
4251 root_layer_->SetBounds(gfx::Size(10, 10));
4253 parent_layer_ = SolidColorLayer::Create();
4254 parent_layer_->SetPosition(gfx::Point());
4255 parent_layer_->SetBounds(gfx::Size(10, 10));
4256 parent_layer_->SetIsDrawable(true);
4257 root_layer_->AddChild(parent_layer_);
4259 child_layer_ = SolidColorLayer::Create();
4260 child_layer_->SetPosition(gfx::Point());
4261 child_layer_->SetBounds(gfx::Size(10, 10));
4262 child_layer_->SetIsDrawable(true);
4263 parent_layer_->AddChild(child_layer_);
4265 layer_tree_host()->SetRootLayer(root_layer_);
4266 LayerTreeHostTest::SetupTree();
4269 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4271 void DidCommitAndDrawFrame() override {
4272 switch (layer_tree_host()->source_frame_number()) {
4273 case 1:
4274 // The layer type used does not need to push properties every frame.
4275 EXPECT_FALSE(child_layer_->needs_push_properties());
4277 // Change the bounds of the child layer, but make it skipped
4278 // by CalculateDrawProperties.
4279 parent_layer_->SetOpacity(0.f);
4280 child_layer_->SetBounds(gfx::Size(5, 5));
4281 break;
4282 case 2:
4283 // The bounds of the child layer were pushed to the impl side.
4284 EXPECT_FALSE(child_layer_->needs_push_properties());
4286 EndTest();
4287 break;
4291 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4292 LayerImpl* root = impl->active_tree()->root_layer();
4293 LayerImpl* parent = root->children()[0];
4294 LayerImpl* child = parent->children()[0];
4296 switch (impl->active_tree()->source_frame_number()) {
4297 case 1:
4298 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4299 break;
4303 void AfterTest() override {}
4305 scoped_refptr<Layer> root_layer_;
4306 scoped_refptr<SolidColorLayer> parent_layer_;
4307 scoped_refptr<SolidColorLayer> child_layer_;
4310 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4312 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4313 protected:
4314 void InitializeSettings(LayerTreeSettings* settings) override {
4315 settings->impl_side_painting = true;
4318 void SetupTree() override {
4319 root_layer_ = FakePictureLayer::Create(&client_);
4320 root_layer_->SetBounds(gfx::Size(10, 10));
4322 layer_tree_host()->SetRootLayer(root_layer_);
4323 LayerTreeHostTest::SetupTree();
4326 void BeginTest() override {
4327 // The viewport is empty, but we still need to update layers on the main
4328 // thread.
4329 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4330 PostSetNeedsCommitToMainThread();
4333 void DidCommit() override {
4334 // The layer should be updated even though the viewport is empty, so we
4335 // are capable of drawing it on the impl tree.
4336 EXPECT_GT(root_layer_->update_count(), 0u);
4337 EndTest();
4340 void AfterTest() override {}
4342 FakeContentLayerClient client_;
4343 scoped_refptr<FakePictureLayer> root_layer_;
4346 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4348 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4349 public:
4350 LayerTreeHostTestAbortEvictedTextures()
4351 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4353 protected:
4354 void SetupTree() override {
4355 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4356 root_layer->SetBounds(gfx::Size(200, 200));
4357 root_layer->SetIsDrawable(true);
4358 root_layer->CreateRenderSurface();
4360 layer_tree_host()->SetRootLayer(root_layer);
4361 LayerTreeHostTest::SetupTree();
4364 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4366 void WillBeginMainFrame() override {
4367 num_will_begin_main_frames_++;
4368 switch (num_will_begin_main_frames_) {
4369 case 2:
4370 // Send a redraw to the compositor thread. This will (wrongly) be
4371 // ignored unless aborting resets the texture state.
4372 layer_tree_host()->SetNeedsRedraw();
4373 break;
4377 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
4378 num_impl_commits_++;
4381 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4382 switch (impl->SourceAnimationFrameNumber()) {
4383 case 1:
4384 // Prevent draws until commit.
4385 impl->active_tree()->SetContentsTexturesPurged();
4386 EXPECT_FALSE(impl->CanDraw());
4387 // Trigger an abortable commit.
4388 impl->SetNeedsCommit();
4389 break;
4390 case 2:
4391 EndTest();
4392 break;
4396 void AfterTest() override {
4397 // Ensure that the commit was truly aborted.
4398 EXPECT_EQ(2, num_will_begin_main_frames_);
4399 EXPECT_EQ(1, num_impl_commits_);
4402 private:
4403 int num_will_begin_main_frames_;
4404 int num_impl_commits_;
4407 // Commits can only be aborted when using the thread proxy.
4408 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4410 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4411 protected:
4412 void InitializeSettings(LayerTreeSettings* settings) override {
4413 settings->impl_side_painting = true;
4414 settings->use_zero_copy = false;
4415 settings->use_one_copy = false;
4418 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4419 scoped_refptr<TestContextProvider> context_provider =
4420 TestContextProvider::Create();
4421 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
4422 if (delegating_renderer())
4423 return FakeOutputSurface::CreateDelegating3d(context_provider);
4424 else
4425 return FakeOutputSurface::Create3d(context_provider);
4428 void SetupTree() override {
4429 client_.set_fill_with_nonsolid_color(true);
4430 scoped_refptr<FakePictureLayer> root_layer =
4431 FakePictureLayer::Create(&client_);
4432 root_layer->SetBounds(gfx::Size(1024, 1024));
4433 root_layer->SetIsDrawable(true);
4435 layer_tree_host()->SetRootLayer(root_layer);
4436 LayerTreeHostTest::SetupTree();
4439 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4441 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4442 TestWebGraphicsContext3D* context = TestContext();
4444 // Expect that the transfer buffer memory used is equal to the
4445 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4446 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
4447 EndTest();
4450 void AfterTest() override {}
4452 private:
4453 FakeContentLayerClient client_;
4456 // Impl-side painting is a multi-threaded compositor feature.
4457 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4459 // Test ensuring that memory limits are sent to the prioritized resource
4460 // manager.
4461 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4462 public:
4463 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4465 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4467 void WillCommit() override {
4468 // Some commits are aborted, so increment number of attempted commits here.
4469 num_commits_++;
4472 void DidCommit() override {
4473 switch (num_commits_) {
4474 case 1:
4475 // Verify default values.
4476 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4477 layer_tree_host()
4478 ->contents_texture_manager()
4479 ->MaxMemoryLimitBytes());
4480 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4481 layer_tree_host()
4482 ->contents_texture_manager()
4483 ->ExternalPriorityCutoff());
4484 PostSetNeedsCommitToMainThread();
4485 break;
4486 case 2:
4487 // The values should remain the same until the commit after the policy
4488 // is changed.
4489 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4490 layer_tree_host()
4491 ->contents_texture_manager()
4492 ->MaxMemoryLimitBytes());
4493 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4494 layer_tree_host()
4495 ->contents_texture_manager()
4496 ->ExternalPriorityCutoff());
4497 break;
4498 case 3:
4499 // Verify values were correctly passed.
4500 EXPECT_EQ(16u * 1024u * 1024u,
4501 layer_tree_host()
4502 ->contents_texture_manager()
4503 ->MaxMemoryLimitBytes());
4504 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4505 layer_tree_host()
4506 ->contents_texture_manager()
4507 ->ExternalPriorityCutoff());
4508 EndTest();
4509 break;
4510 case 4:
4511 // Make sure no extra commits happen.
4512 NOTREACHED();
4513 break;
4517 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4518 switch (num_commits_) {
4519 case 1:
4520 break;
4521 case 2:
4522 // This will trigger a commit because the priority cutoff has changed.
4523 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4524 16u * 1024u * 1024u,
4525 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4526 1000));
4527 break;
4528 case 3:
4529 // This will not trigger a commit because the priority cutoff has not
4530 // changed, and there is already enough memory for all allocations.
4531 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4532 32u * 1024u * 1024u,
4533 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4534 1000));
4535 break;
4536 case 4:
4537 NOTREACHED();
4538 break;
4542 void AfterTest() override {}
4544 private:
4545 int num_commits_;
4548 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4550 } // namespace
4552 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4553 : public LayerTreeHostTest {
4554 protected:
4555 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4556 : first_output_surface_memory_limit_(4321234),
4557 second_output_surface_memory_limit_(1234321) {}
4559 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4560 if (!first_context_provider_.get()) {
4561 first_context_provider_ = TestContextProvider::Create();
4562 } else {
4563 EXPECT_FALSE(second_context_provider_.get());
4564 second_context_provider_ = TestContextProvider::Create();
4567 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4568 ? second_context_provider_
4569 : first_context_provider_);
4570 scoped_ptr<FakeOutputSurface> output_surface;
4571 if (delegating_renderer())
4572 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4573 else
4574 output_surface = FakeOutputSurface::Create3d(provider);
4575 output_surface->SetMemoryPolicyToSetAtBind(
4576 make_scoped_ptr(new ManagedMemoryPolicy(
4577 second_context_provider_.get() ? second_output_surface_memory_limit_
4578 : first_output_surface_memory_limit_,
4579 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4580 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4581 return output_surface.Pass();
4584 void SetupTree() override {
4585 if (layer_tree_host()->settings().impl_side_painting)
4586 root_ = FakePictureLayer::Create(&client_);
4587 else
4588 root_ = FakeContentLayer::Create(&client_);
4589 root_->SetBounds(gfx::Size(20, 20));
4590 layer_tree_host()->SetRootLayer(root_);
4591 LayerTreeHostTest::SetupTree();
4594 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4596 void DidCommitAndDrawFrame() override {
4597 // Lost context sometimes takes two frames to recreate. The third frame
4598 // is sometimes aborted, so wait until the fourth frame to verify that
4599 // the memory has been set, and the fifth frame to end the test.
4600 if (layer_tree_host()->source_frame_number() < 5) {
4601 layer_tree_host()->SetNeedsCommit();
4602 } else if (layer_tree_host()->source_frame_number() == 5) {
4603 EndTest();
4607 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
4608 switch (impl->active_tree()->source_frame_number()) {
4609 case 1:
4610 EXPECT_EQ(first_output_surface_memory_limit_,
4611 impl->memory_allocation_limit_bytes());
4612 // Lose the output surface.
4613 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4614 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4615 break;
4616 case 4:
4617 EXPECT_EQ(second_output_surface_memory_limit_,
4618 impl->memory_allocation_limit_bytes());
4619 break;
4623 void AfterTest() override {}
4625 scoped_refptr<TestContextProvider> first_context_provider_;
4626 scoped_refptr<TestContextProvider> second_context_provider_;
4627 size_t first_output_surface_memory_limit_;
4628 size_t second_output_surface_memory_limit_;
4629 FakeContentLayerClient client_;
4630 scoped_refptr<Layer> root_;
4633 SINGLE_AND_MULTI_THREAD_TEST_F(
4634 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4636 struct TestSwapPromiseResult {
4637 TestSwapPromiseResult()
4638 : did_swap_called(false),
4639 did_not_swap_called(false),
4640 dtor_called(false),
4641 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4643 bool did_swap_called;
4644 bool did_not_swap_called;
4645 bool dtor_called;
4646 SwapPromise::DidNotSwapReason reason;
4647 base::Lock lock;
4650 class TestSwapPromise : public SwapPromise {
4651 public:
4652 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4654 ~TestSwapPromise() override {
4655 base::AutoLock lock(result_->lock);
4656 result_->dtor_called = true;
4659 void DidSwap(CompositorFrameMetadata* metadata) override {
4660 base::AutoLock lock(result_->lock);
4661 EXPECT_FALSE(result_->did_swap_called);
4662 EXPECT_FALSE(result_->did_not_swap_called);
4663 result_->did_swap_called = true;
4666 void DidNotSwap(DidNotSwapReason reason) override {
4667 base::AutoLock lock(result_->lock);
4668 EXPECT_FALSE(result_->did_swap_called);
4669 EXPECT_FALSE(result_->did_not_swap_called);
4670 result_->did_not_swap_called = true;
4671 result_->reason = reason;
4674 int64 TraceId() const override { return 0; }
4676 private:
4677 // Not owned.
4678 TestSwapPromiseResult* result_;
4681 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4682 protected:
4683 LayerTreeHostTestBreakSwapPromise()
4684 : commit_count_(0), commit_complete_count_(0) {}
4686 void WillBeginMainFrame() override {
4687 ASSERT_LE(commit_count_, 2);
4688 scoped_ptr<SwapPromise> swap_promise(
4689 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4690 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4693 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4695 void DidCommit() override {
4696 commit_count_++;
4697 if (commit_count_ == 2) {
4698 // This commit will finish.
4699 layer_tree_host()->SetNeedsCommit();
4703 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4704 commit_complete_count_++;
4705 if (commit_complete_count_ == 1) {
4706 // This commit will be aborted because no actual update.
4707 PostSetNeedsUpdateLayersToMainThread();
4708 } else {
4709 EndTest();
4713 void AfterTest() override {
4714 // 3 commits are scheduled. 2 completes. 1 is aborted.
4715 EXPECT_EQ(commit_count_, 3);
4716 EXPECT_EQ(commit_complete_count_, 2);
4719 // The first commit completes and causes swap buffer which finishes
4720 // the promise.
4721 base::AutoLock lock(swap_promise_result_[0].lock);
4722 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4723 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4724 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4728 // The second commit is aborted since it contains no updates.
4729 base::AutoLock lock(swap_promise_result_[1].lock);
4730 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4731 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4732 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
4733 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4737 // The last commit completes but it does not cause swap buffer because
4738 // there is no damage in the frame data.
4739 base::AutoLock lock(swap_promise_result_[2].lock);
4740 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4741 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4742 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4743 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4747 int commit_count_;
4748 int commit_complete_count_;
4749 TestSwapPromiseResult swap_promise_result_[3];
4752 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4754 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
4755 public:
4756 LayerTreeHostTestKeepSwapPromise() {}
4758 void BeginTest() override {
4759 layer_ = SolidColorLayer::Create();
4760 layer_->SetIsDrawable(true);
4761 layer_->SetBounds(gfx::Size(10, 10));
4762 layer_tree_host()->SetRootLayer(layer_);
4763 gfx::Size bounds(100, 100);
4764 layer_tree_host()->SetViewportSize(bounds);
4765 PostSetNeedsCommitToMainThread();
4768 void DidCommit() override {
4769 MainThreadTaskRunner()->PostTask(
4770 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
4771 base::Unretained(this)));
4774 void ChangeFrame() {
4775 switch (layer_tree_host()->source_frame_number()) {
4776 case 1:
4777 layer_->SetBounds(gfx::Size(10, 11));
4778 layer_tree_host()->QueueSwapPromise(
4779 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
4780 break;
4781 case 2:
4782 break;
4783 default:
4784 NOTREACHED();
4785 break;
4789 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
4790 EXPECT_TRUE(result);
4791 if (host_impl->active_tree()->source_frame_number() >= 1) {
4792 // The commit changes layers so it should cause a swap.
4793 base::AutoLock lock(swap_promise_result_.lock);
4794 EXPECT_TRUE(swap_promise_result_.did_swap_called);
4795 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
4796 EXPECT_TRUE(swap_promise_result_.dtor_called);
4797 EndTest();
4801 void AfterTest() override {}
4803 private:
4804 scoped_refptr<Layer> layer_;
4805 TestSwapPromiseResult swap_promise_result_;
4808 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
4810 class LayerTreeHostTestBreakSwapPromiseForVisibility
4811 : public LayerTreeHostTest {
4812 protected:
4813 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4815 void SetVisibleFalseAndQueueSwapPromise() {
4816 layer_tree_host()->SetVisible(false);
4817 scoped_ptr<SwapPromise> swap_promise(
4818 new TestSwapPromise(&swap_promise_result_));
4819 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4822 void ScheduledActionWillSendBeginMainFrame() override {
4823 MainThreadTaskRunner()->PostTask(
4824 FROM_HERE,
4825 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility
4826 ::SetVisibleFalseAndQueueSwapPromise,
4827 base::Unretained(this)));
4830 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4831 CommitEarlyOutReason reason) override {
4832 EndTest();
4835 void AfterTest() override {
4837 base::AutoLock lock(swap_promise_result_.lock);
4838 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4839 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4840 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4841 EXPECT_TRUE(swap_promise_result_.dtor_called);
4845 TestSwapPromiseResult swap_promise_result_;
4848 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
4850 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest {
4851 protected:
4852 LayerTreeHostTestBreakSwapPromiseForContext()
4853 : output_surface_lost_triggered_(false) {
4856 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4858 void LoseOutputSurfaceAndQueueSwapPromise() {
4859 layer_tree_host()->DidLoseOutputSurface();
4860 scoped_ptr<SwapPromise> swap_promise(
4861 new TestSwapPromise(&swap_promise_result_));
4862 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4865 void ScheduledActionWillSendBeginMainFrame() override {
4866 if (output_surface_lost_triggered_)
4867 return;
4868 output_surface_lost_triggered_ = true;
4870 MainThreadTaskRunner()->PostTask(
4871 FROM_HERE,
4872 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext
4873 ::LoseOutputSurfaceAndQueueSwapPromise,
4874 base::Unretained(this)));
4877 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4878 CommitEarlyOutReason reason) override {
4879 // This is needed so that the impl-thread state matches main-thread state.
4880 host_impl->DidLoseOutputSurface();
4881 EndTest();
4884 void AfterTest() override {
4886 base::AutoLock lock(swap_promise_result_.lock);
4887 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4888 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4889 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4890 EXPECT_TRUE(swap_promise_result_.dtor_called);
4894 bool output_surface_lost_triggered_;
4895 TestSwapPromiseResult swap_promise_result_;
4898 SINGLE_AND_MULTI_THREAD_TEST_F(
4899 LayerTreeHostTestBreakSwapPromiseForContext);
4901 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
4902 public:
4903 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
4904 LayerTreeHostImpl* layer_tree_host_impl,
4905 int* set_needs_commit_count,
4906 int* set_needs_redraw_count)
4907 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
4908 set_needs_commit_count_(set_needs_commit_count) {}
4910 ~SimpleSwapPromiseMonitor() override {}
4912 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
4914 void OnSetNeedsRedrawOnImpl() override {
4915 ADD_FAILURE() << "Should not get called on main thread.";
4918 void OnForwardScrollUpdateToMainThreadOnImpl() override {
4919 ADD_FAILURE() << "Should not get called on main thread.";
4922 private:
4923 int* set_needs_commit_count_;
4926 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
4927 public:
4928 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4930 void WillBeginMainFrame() override {
4931 if (TestEnded())
4932 return;
4934 int set_needs_commit_count = 0;
4935 int set_needs_redraw_count = 0;
4938 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4939 new SimpleSwapPromiseMonitor(layer_tree_host(),
4940 NULL,
4941 &set_needs_commit_count,
4942 &set_needs_redraw_count));
4943 layer_tree_host()->SetNeedsCommit();
4944 EXPECT_EQ(1, set_needs_commit_count);
4945 EXPECT_EQ(0, set_needs_redraw_count);
4948 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
4949 // monitored.
4950 layer_tree_host()->SetNeedsCommit();
4951 EXPECT_EQ(1, set_needs_commit_count);
4952 EXPECT_EQ(0, set_needs_redraw_count);
4955 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4956 new SimpleSwapPromiseMonitor(layer_tree_host(),
4957 NULL,
4958 &set_needs_commit_count,
4959 &set_needs_redraw_count));
4960 layer_tree_host()->SetNeedsUpdateLayers();
4961 EXPECT_EQ(2, set_needs_commit_count);
4962 EXPECT_EQ(0, set_needs_redraw_count);
4966 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4967 new SimpleSwapPromiseMonitor(layer_tree_host(),
4968 NULL,
4969 &set_needs_commit_count,
4970 &set_needs_redraw_count));
4971 layer_tree_host()->SetNeedsAnimate();
4972 EXPECT_EQ(3, set_needs_commit_count);
4973 EXPECT_EQ(0, set_needs_redraw_count);
4976 EndTest();
4979 void AfterTest() override {}
4982 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
4984 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
4985 : public LayerTreeHostTest {
4986 protected:
4987 void InitializeSettings(LayerTreeSettings* settings) override {
4988 settings->impl_side_painting = true;
4991 void SetupTree() override {
4992 LayerTreeHostTest::SetupTree();
4993 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
4996 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4998 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4999 host_impl->EvictAllUIResources();
5000 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
5001 // mode. Active tree should require high-res to draw after entering this
5002 // mode to ensure that high-res tiles are also required for a pending tree
5003 // to be activated.
5004 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5007 void DidCommit() override {
5008 int frame = layer_tree_host()->source_frame_number();
5009 switch (frame) {
5010 case 1:
5011 PostSetNeedsCommitToMainThread();
5012 break;
5013 case 2:
5014 ui_resource_ = nullptr;
5015 EndTest();
5016 break;
5020 void AfterTest() override {}
5022 FakeContentLayerClient client_;
5023 scoped_ptr<FakeScopedUIResource> ui_resource_;
5026 // This test is flaky, see http://crbug.com/386199
5027 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
5029 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
5030 protected:
5031 void InitializeSettings(LayerTreeSettings* settings) override {
5032 settings->impl_side_painting = true;
5034 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5035 EXPECT_FALSE(settings->gpu_rasterization_forced);
5038 void SetupTree() override {
5039 LayerTreeHostTest::SetupTree();
5041 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5042 layer->SetBounds(gfx::Size(10, 10));
5043 layer->SetIsDrawable(true);
5044 layer_tree_host()->root_layer()->AddChild(layer);
5047 void BeginTest() override {
5048 Layer* root = layer_tree_host()->root_layer();
5049 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5050 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5052 // Verify default values.
5053 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5054 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5055 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5056 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5057 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5059 // Setting gpu rasterization trigger does not enable gpu rasterization.
5060 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5061 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5062 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5064 PostSetNeedsCommitToMainThread();
5067 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5068 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5069 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5072 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5073 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5074 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5075 EndTest();
5078 void AfterTest() override {}
5080 FakeContentLayerClient layer_client_;
5083 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
5085 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
5086 protected:
5087 void InitializeSettings(LayerTreeSettings* settings) override {
5088 settings->impl_side_painting = true;
5090 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5091 settings->gpu_rasterization_enabled = true;
5094 void SetupTree() override {
5095 LayerTreeHostTest::SetupTree();
5097 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5098 layer->SetBounds(gfx::Size(10, 10));
5099 layer->SetIsDrawable(true);
5100 layer_tree_host()->root_layer()->AddChild(layer);
5103 void BeginTest() override {
5104 Layer* root = layer_tree_host()->root_layer();
5105 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5106 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5108 // Verify default values.
5109 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5110 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5111 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5112 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5113 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5115 // Gpu rasterization trigger is relevant.
5116 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5117 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5118 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5120 // Content-based veto is relevant as well.
5121 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5122 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5123 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5124 // Veto will take effect when layers are updated.
5125 // The results will be verified after commit is completed below.
5126 // Since we are manually marking picture pile as unsuitable,
5127 // make sure that the layer gets a chance to update.
5128 layer->SetNeedsDisplay();
5129 PostSetNeedsCommitToMainThread();
5132 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5133 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5134 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5137 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5138 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5139 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5140 EndTest();
5143 void AfterTest() override {}
5145 FakeContentLayerClient layer_client_;
5148 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
5150 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
5151 protected:
5152 void InitializeSettings(LayerTreeSettings* settings) override {
5153 ASSERT_TRUE(settings->impl_side_painting);
5155 EXPECT_FALSE(settings->gpu_rasterization_forced);
5156 settings->gpu_rasterization_forced = true;
5159 void SetupTree() override {
5160 LayerTreeHostTest::SetupTree();
5162 scoped_refptr<FakePictureLayer> layer =
5163 FakePictureLayer::Create(&layer_client_);
5164 layer->SetBounds(gfx::Size(10, 10));
5165 layer->SetIsDrawable(true);
5166 layer_tree_host()->root_layer()->AddChild(layer);
5169 void BeginTest() override {
5170 Layer* root = layer_tree_host()->root_layer();
5171 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5172 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5174 // Verify default values.
5175 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5176 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5177 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5178 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5180 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
5181 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5182 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5183 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5184 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5186 // Content-based veto is irrelevant as well.
5187 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5188 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5189 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5190 // Veto will take effect when layers are updated.
5191 // The results will be verified after commit is completed below.
5192 // Since we are manually marking picture pile as unsuitable,
5193 // make sure that the layer gets a chance to update.
5194 layer->SetNeedsDisplay();
5195 PostSetNeedsCommitToMainThread();
5198 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5199 EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
5200 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5203 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5204 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
5205 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5206 EndTest();
5209 void AfterTest() override {}
5211 FakeContentLayerClient layer_client_;
5214 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
5216 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
5217 public:
5218 LayerTreeHostTestContinuousPainting()
5219 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
5221 protected:
5222 enum { kExpectedNumCommits = 10 };
5224 void SetupTree() override {
5225 scoped_refptr<Layer> root_layer = Layer::Create();
5226 root_layer->SetBounds(bounds_);
5227 root_layer->CreateRenderSurface();
5229 if (layer_tree_host()->settings().impl_side_painting) {
5230 picture_layer_ = FakePictureLayer::Create(&client_);
5231 child_layer_ = picture_layer_.get();
5232 } else {
5233 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
5234 child_layer_ = content_layer_.get();
5236 child_layer_->SetBounds(bounds_);
5237 child_layer_->SetIsDrawable(true);
5238 root_layer->AddChild(child_layer_);
5240 layer_tree_host()->SetRootLayer(root_layer);
5241 layer_tree_host()->SetViewportSize(bounds_);
5242 LayerTreeHostTest::SetupTree();
5245 void BeginTest() override {
5246 MainThreadTaskRunner()->PostTask(
5247 FROM_HERE,
5248 base::Bind(
5249 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
5250 base::Unretained(this)));
5251 // Wait 50x longer than expected.
5252 double milliseconds_per_frame =
5253 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
5254 MainThreadTaskRunner()->PostDelayedTask(
5255 FROM_HERE,
5256 base::Bind(
5257 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
5258 base::Unretained(this)),
5259 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
5260 milliseconds_per_frame));
5263 void BeginMainFrame(const BeginFrameArgs& args) override {
5264 child_layer_->SetNeedsDisplay();
5267 void AfterTest() override {
5268 EXPECT_LE(kExpectedNumCommits, num_commits_);
5269 EXPECT_LE(kExpectedNumCommits, num_draws_);
5270 int update_count = content_layer_.get()
5271 ? content_layer_->PaintContentsCount()
5272 : picture_layer_->update_count();
5273 EXPECT_LE(kExpectedNumCommits, update_count);
5276 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5277 if (++num_draws_ == kExpectedNumCommits)
5278 EndTest();
5281 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5282 ++num_commits_;
5285 private:
5286 void EnableContinuousPainting() {
5287 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5288 debug_state.continuous_painting = true;
5289 layer_tree_host()->SetDebugState(debug_state);
5292 void DisableContinuousPainting() {
5293 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5294 debug_state.continuous_painting = false;
5295 layer_tree_host()->SetDebugState(debug_state);
5296 EndTest();
5299 int num_commits_;
5300 int num_draws_;
5301 const gfx::Size bounds_;
5302 FakeContentLayerClient client_;
5303 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5304 scoped_refptr<FakePictureLayer> picture_layer_;
5305 Layer* child_layer_;
5308 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5310 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
5311 public:
5312 LayerTreeHostTestSendBeginFramesToChildren()
5313 : begin_frame_sent_to_children_(false) {
5316 void InitializeSettings(LayerTreeSettings* settings) override {
5317 settings->forward_begin_frames_to_children = true;
5320 void BeginTest() override {
5321 // Kick off the test with a commit.
5322 PostSetNeedsCommitToMainThread();
5325 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5326 begin_frame_sent_to_children_ = true;
5327 EndTest();
5330 void DidBeginMainFrame() override {
5331 // Children requested BeginFrames.
5332 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5335 void AfterTest() override {
5336 // Ensure that BeginFrame message is sent to children during parent
5337 // scheduler handles its BeginFrame.
5338 EXPECT_TRUE(begin_frame_sent_to_children_);
5341 private:
5342 bool begin_frame_sent_to_children_;
5345 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
5347 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
5348 : public LayerTreeHostTest {
5349 public:
5350 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
5351 : begin_frame_sent_to_children_(false) {
5354 void InitializeSettings(LayerTreeSettings* settings) override {
5355 settings->use_external_begin_frame_source = true;
5356 settings->forward_begin_frames_to_children = true;
5359 void BeginTest() override {
5360 // Kick off the test with a commit.
5361 PostSetNeedsCommitToMainThread();
5364 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5365 begin_frame_sent_to_children_ = true;
5366 EndTest();
5369 void DidBeginMainFrame() override {
5370 // Children requested BeginFrames.
5371 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5374 void AfterTest() override {
5375 // Ensure that BeginFrame message is sent to children during parent
5376 // scheduler handles its BeginFrame.
5377 EXPECT_TRUE(begin_frame_sent_to_children_);
5380 private:
5381 bool begin_frame_sent_to_children_;
5384 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
5386 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5387 public:
5388 LayerTreeHostTestActivateOnInvisible()
5389 : activation_count_(0), visible_(true) {}
5391 void InitializeSettings(LayerTreeSettings* settings) override {
5392 settings->impl_side_painting = true;
5395 void BeginTest() override {
5396 // Kick off the test with a commit.
5397 PostSetNeedsCommitToMainThread();
5400 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5401 // Make sure we don't activate using the notify signal from tile manager.
5402 host_impl->BlockNotifyReadyToActivateForTesting(true);
5405 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5407 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5408 bool visible) override {
5409 visible_ = visible;
5411 // Once invisible, we can go visible again.
5412 if (!visible) {
5413 PostSetVisibleToMainThread(true);
5414 } else {
5415 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5416 EndTest();
5420 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5421 ++activation_count_;
5422 EXPECT_FALSE(visible_);
5425 void AfterTest() override {
5426 // Ensure we activated even though the signal was blocked.
5427 EXPECT_EQ(1, activation_count_);
5428 EXPECT_TRUE(visible_);
5431 private:
5432 int activation_count_;
5433 bool visible_;
5435 FakeContentLayerClient client_;
5436 scoped_refptr<FakePictureLayer> picture_layer_;
5439 // TODO(vmpstr): Enable with single thread impl-side painting.
5440 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5442 // Do a synchronous composite and assert that the swap promise succeeds.
5443 class LayerTreeHostTestSynchronousCompositeSwapPromise
5444 : public LayerTreeHostTest {
5445 public:
5446 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5448 void InitializeSettings(LayerTreeSettings* settings) override {
5449 settings->single_thread_proxy_scheduler = false;
5452 void BeginTest() override {
5453 // Successful composite.
5454 scoped_ptr<SwapPromise> swap_promise0(
5455 new TestSwapPromise(&swap_promise_result_[0]));
5456 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5457 layer_tree_host()->Composite(gfx::FrameTime::Now());
5459 // Fail to swap (no damage).
5460 scoped_ptr<SwapPromise> swap_promise1(
5461 new TestSwapPromise(&swap_promise_result_[1]));
5462 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5463 layer_tree_host()->SetNeedsCommit();
5464 layer_tree_host()->Composite(gfx::FrameTime::Now());
5466 // Fail to draw (not visible).
5467 scoped_ptr<SwapPromise> swap_promise2(
5468 new TestSwapPromise(&swap_promise_result_[2]));
5469 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5470 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5471 layer_tree_host()->SetVisible(false);
5472 layer_tree_host()->Composite(gfx::FrameTime::Now());
5474 EndTest();
5477 void DidCommit() override {
5478 commit_count_++;
5479 ASSERT_LE(commit_count_, 3);
5482 void AfterTest() override {
5483 EXPECT_EQ(3, commit_count_);
5485 // Initial swap promise should have succeded.
5487 base::AutoLock lock(swap_promise_result_[0].lock);
5488 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5489 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5490 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5493 // Second swap promise fails to swap.
5495 base::AutoLock lock(swap_promise_result_[1].lock);
5496 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5497 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5498 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5499 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5502 // Third swap promises also fails to swap (and draw).
5504 base::AutoLock lock(swap_promise_result_[2].lock);
5505 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5506 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5507 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5508 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5512 int commit_count_;
5513 TestSwapPromiseResult swap_promise_result_[3];
5516 // Impl-side painting is not supported for synchronous compositing.
5517 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
5519 // Make sure page scale and top control deltas are applied to the client even
5520 // when the LayerTreeHost doesn't have a root layer.
5521 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
5522 : public LayerTreeHostTest {
5523 public:
5524 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
5525 : deltas_sent_to_client_(false) {}
5527 void BeginTest() override {
5528 layer_tree_host()->SetRootLayer(nullptr);
5529 info_.page_scale_delta = 3.14f;
5530 info_.top_controls_delta = 2.73f;
5532 PostSetNeedsCommitToMainThread();
5535 void BeginMainFrame(const BeginFrameArgs& args) override {
5536 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
5538 layer_tree_host()->ApplyScrollAndScale(&info_);
5539 EndTest();
5542 void ApplyViewportDeltas(const gfx::Vector2dF& inner,
5543 const gfx::Vector2dF& outer,
5544 const gfx::Vector2dF& elastic_overscroll_delta,
5545 float scale_delta,
5546 float top_controls_delta) override {
5547 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5548 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5549 deltas_sent_to_client_ = true;
5552 void ApplyViewportDeltas(
5553 const gfx::Vector2d& scroll,
5554 float scale_delta,
5555 float top_controls_delta) override {
5556 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5557 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5558 deltas_sent_to_client_ = true;
5561 void AfterTest() override {
5562 EXPECT_TRUE(deltas_sent_to_client_);
5565 ScrollAndScaleSet info_;
5566 bool deltas_sent_to_client_;
5569 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5571 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
5572 protected:
5573 LayerTreeHostTestCrispUpAfterPinchEnds()
5574 : playback_allowed_event_(true, true) {}
5576 void SetupTree() override {
5577 frame_ = 1;
5578 posted_ = false;
5579 client_.set_fill_with_nonsolid_color(true);
5581 scoped_refptr<Layer> root = Layer::Create();
5582 root->SetBounds(gfx::Size(500, 500));
5584 scoped_refptr<Layer> pinch = Layer::Create();
5585 pinch->SetBounds(gfx::Size(500, 500));
5586 pinch->SetScrollClipLayerId(root->id());
5587 pinch->SetIsContainerForFixedPositionLayers(true);
5588 root->AddChild(pinch);
5590 scoped_ptr<FakePicturePile> pile(
5591 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5592 ImplSidePaintingSettings().default_tile_grid_size));
5593 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5594 scoped_refptr<FakePictureLayer> layer =
5595 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5596 layer->SetBounds(gfx::Size(500, 500));
5597 layer->SetContentsOpaque(true);
5598 // Avoid LCD text on the layer so we don't cause extra commits when we
5599 // pinch.
5600 layer->disable_lcd_text();
5601 pinch->AddChild(layer);
5603 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5604 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5605 layer_tree_host()->SetRootLayer(root);
5606 LayerTreeHostTest::SetupTree();
5609 // Returns the delta scale of all quads in the frame's root pass from their
5610 // ideal, or 0 if they are not all the same.
5611 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5612 if (frame_data->has_no_damage)
5613 return 0.f;
5614 float frame_scale = 0.f;
5615 RenderPass* root_pass = frame_data->render_passes.back();
5616 for (const auto& draw_quad : root_pass->quad_list) {
5617 // Checkerboards mean an incomplete frame.
5618 if (draw_quad->material != DrawQuad::TILED_CONTENT)
5619 return 0.f;
5620 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5621 float quad_scale =
5622 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5623 float transform_scale =
5624 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5625 float scale = quad_scale / transform_scale;
5626 if (frame_scale != 0.f && frame_scale != scale)
5627 return 0.f;
5628 frame_scale = scale;
5630 return frame_scale;
5633 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5635 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5636 LayerTreeHostImpl::FrameData* frame_data,
5637 DrawResult draw_result) override {
5638 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5639 switch (frame_) {
5640 case 1:
5641 // Drew at page scale 1 before any pinching.
5642 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5643 EXPECT_EQ(1.f, quad_scale_delta);
5644 PostNextAfterDraw(host_impl);
5645 break;
5646 case 2:
5647 if (quad_scale_delta != 1.f)
5648 break;
5649 // Drew at page scale 1.5 after pinching in.
5650 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5651 EXPECT_EQ(1.f, quad_scale_delta);
5652 PostNextAfterDraw(host_impl);
5653 break;
5654 case 3:
5655 // By pinching out, we will create a new tiling and raster it. This may
5656 // cause some additional draws, though we should still be drawing with
5657 // the old 1.5 tiling.
5658 if (frame_data->has_no_damage)
5659 break;
5660 // Drew at page scale 1 with the 1.5 tiling while pinching out.
5661 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5662 EXPECT_EQ(1.5f, quad_scale_delta);
5663 // We don't PostNextAfterDraw here, instead we wait for the new tiling
5664 // to finish rastering so we don't get any noise in further steps.
5665 break;
5666 case 4:
5667 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
5668 // while waiting for texture uploads to complete.
5669 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5670 // This frame will not have any damage, since it's actually the same as
5671 // the last frame, and should contain no incomplete tiles. We just want
5672 // to make sure we drew here at least once after the pinch ended to be
5673 // sure that drawing after pinch doesn't leave us at the wrong scale
5674 EXPECT_TRUE(frame_data->has_no_damage);
5675 PostNextAfterDraw(host_impl);
5676 break;
5677 case 5:
5678 if (quad_scale_delta != 1.f)
5679 break;
5680 // Drew at scale 1 after texture uploads are done.
5681 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5682 EXPECT_EQ(1.f, quad_scale_delta);
5683 EndTest();
5684 break;
5686 return draw_result;
5689 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
5690 if (posted_)
5691 return;
5692 posted_ = true;
5693 ImplThreadTaskRunner()->PostDelayedTask(
5694 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
5695 base::Unretained(this), host_impl),
5696 // Use a delay to allow raster/upload to happen in between frames. This
5697 // should cause flakiness if we fail to block raster/upload when
5698 // desired.
5699 base::TimeDelta::FromMilliseconds(16 * 4));
5702 void Next(LayerTreeHostImpl* host_impl) {
5703 ++frame_;
5704 posted_ = false;
5705 switch (frame_) {
5706 case 2:
5707 // Pinch zoom in.
5708 host_impl->PinchGestureBegin();
5709 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
5710 host_impl->PinchGestureEnd();
5711 break;
5712 case 3:
5713 // Pinch zoom back to 1.f but don't end it.
5714 host_impl->PinchGestureBegin();
5715 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
5716 break;
5717 case 4:
5718 // End the pinch, but delay tile production.
5719 playback_allowed_event_.Reset();
5720 host_impl->PinchGestureEnd();
5721 break;
5722 case 5:
5723 // Let tiles complete.
5724 playback_allowed_event_.Signal();
5725 break;
5729 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5730 const Tile* tile) override {
5731 if (frame_ == 3) {
5732 // On frame 3, we will have a lower res tile complete for the pinch-out
5733 // gesture even though it's not displayed. We wait for it here to prevent
5734 // flakiness.
5735 EXPECT_EQ(0.75f, tile->contents_scale());
5736 PostNextAfterDraw(host_impl);
5738 // On frame_ == 4, we are preventing texture uploads from completing,
5739 // so this verifies they are not completing before frame_ == 5.
5740 // Flaky failures here indicate we're failing to prevent uploads from
5741 // completing.
5742 EXPECT_NE(4, frame_) << tile->contents_scale();
5745 void AfterTest() override {}
5747 FakeContentLayerClient client_;
5748 int frame_;
5749 bool posted_;
5750 base::WaitableEvent playback_allowed_event_;
5753 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
5755 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
5756 : public LayerTreeHostTestCrispUpAfterPinchEnds {
5757 protected:
5758 void InitializeSettings(LayerTreeSettings* settings) override {
5759 settings->use_one_copy = true;
5762 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
5763 scoped_ptr<TestWebGraphicsContext3D> context3d =
5764 TestWebGraphicsContext3D::Create();
5765 context3d->set_support_image(true);
5766 context3d->set_support_sync_query(true);
5767 #if defined(OS_MACOSX)
5768 context3d->set_support_texture_rectangle(true);
5769 #endif
5771 if (delegating_renderer())
5772 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
5773 else
5774 return FakeOutputSurface::Create3d(context3d.Pass());
5778 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
5780 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
5781 protected:
5782 RasterizeWithGpuRasterizationCreatesResources() {}
5784 void InitializeSettings(LayerTreeSettings* settings) override {
5785 settings->impl_side_painting = true;
5786 settings->gpu_rasterization_forced = true;
5789 void SetupTree() override {
5790 client_.set_fill_with_nonsolid_color(true);
5792 scoped_refptr<Layer> root = Layer::Create();
5793 root->SetBounds(gfx::Size(500, 500));
5795 scoped_ptr<FakePicturePile> pile(
5796 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5797 ImplSidePaintingSettings().default_tile_grid_size));
5798 scoped_refptr<FakePictureLayer> layer =
5799 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5800 layer->SetBounds(gfx::Size(500, 500));
5801 layer->SetContentsOpaque(true);
5802 root->AddChild(layer);
5804 layer_tree_host()->SetRootLayer(root);
5805 LayerTreeHostTest::SetupTree();
5808 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5810 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5811 LayerTreeHostImpl::FrameData* frame_data,
5812 DrawResult draw_result) override {
5813 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
5814 EndTest();
5815 return draw_result;
5817 void AfterTest() override {}
5819 FakeContentLayerClient client_;
5822 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
5824 class GpuRasterizationRasterizesVisibleOnly : public LayerTreeHostTest {
5825 protected:
5826 GpuRasterizationRasterizesVisibleOnly() : viewport_size_(1024, 2048) {}
5828 void InitializeSettings(LayerTreeSettings* settings) override {
5829 settings->impl_side_painting = true;
5830 settings->gpu_rasterization_enabled = true;
5831 settings->gpu_rasterization_forced = true;
5834 void SetupTree() override {
5835 client_.set_fill_with_nonsolid_color(true);
5837 scoped_ptr<FakePicturePile> pile(
5838 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5839 ImplSidePaintingSettings().default_tile_grid_size));
5840 scoped_refptr<FakePictureLayer> root =
5841 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5842 root->SetBounds(gfx::Size(viewport_size_.width(), 10000));
5843 root->SetContentsOpaque(true);
5845 layer_tree_host()->SetRootLayer(root);
5846 LayerTreeHostTest::SetupTree();
5847 layer_tree_host()->SetViewportSize(viewport_size_);
5850 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5852 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5853 LayerTreeHostImpl::FrameData* frame_data,
5854 DrawResult draw_result) override {
5855 EXPECT_EQ(4u, host_impl->resource_provider()->num_resources());
5857 // Verify which tiles got resources using an eviction iterator, which has to
5858 // return all tiles that have resources.
5859 scoped_ptr<EvictionTilePriorityQueue> eviction_queue(
5860 host_impl->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES));
5861 int tile_count = 0;
5862 for (; !eviction_queue->IsEmpty(); eviction_queue->Pop()) {
5863 Tile* tile = eviction_queue->Top();
5864 // Ensure this tile is within the viewport.
5865 EXPECT_TRUE(tile->content_rect().Intersects(gfx::Rect(viewport_size_)));
5866 // Ensure that the tile is 1/4 of the viewport tall (plus padding).
5867 EXPECT_EQ(tile->content_rect().height(),
5868 (viewport_size_.height() / 4) + 2);
5869 ++tile_count;
5871 EXPECT_EQ(4, tile_count);
5872 EndTest();
5873 return draw_result;
5876 void AfterTest() override {}
5878 private:
5879 FakeContentLayerClient client_;
5880 gfx::Size viewport_size_;
5883 MULTI_THREAD_IMPL_TEST_F(GpuRasterizationRasterizesVisibleOnly);
5885 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
5886 : public LayerTreeHostTest {
5887 protected:
5888 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
5889 : playback_allowed_event_(true, true) {}
5891 void InitializeSettings(LayerTreeSettings* settings) override {
5892 settings->impl_side_painting = true;
5895 void SetupTree() override {
5896 step_ = 1;
5897 continuous_draws_ = 0;
5898 client_.set_fill_with_nonsolid_color(true);
5900 scoped_refptr<Layer> root = Layer::Create();
5901 root->SetBounds(gfx::Size(500, 500));
5903 scoped_refptr<Layer> pinch = Layer::Create();
5904 pinch->SetBounds(gfx::Size(500, 500));
5905 pinch->SetScrollClipLayerId(root->id());
5906 pinch->SetIsContainerForFixedPositionLayers(true);
5907 root->AddChild(pinch);
5909 scoped_ptr<FakePicturePile> pile(
5910 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5911 ImplSidePaintingSettings().default_tile_grid_size));
5912 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5913 scoped_refptr<FakePictureLayer> layer =
5914 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5915 layer->SetBounds(gfx::Size(500, 500));
5916 layer->SetContentsOpaque(true);
5917 // Avoid LCD text on the layer so we don't cause extra commits when we
5918 // pinch.
5919 layer->disable_lcd_text();
5920 pinch->AddChild(layer);
5922 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5923 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5924 layer_tree_host()->SetRootLayer(root);
5925 LayerTreeHostTest::SetupTree();
5928 // Returns the delta scale of all quads in the frame's root pass from their
5929 // ideal, or 0 if they are not all the same.
5930 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5931 if (frame_data->has_no_damage)
5932 return 0.f;
5933 float frame_scale = 0.f;
5934 RenderPass* root_pass = frame_data->render_passes.back();
5935 for (const auto& draw_quad : root_pass->quad_list) {
5936 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5937 float quad_scale =
5938 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5939 float transform_scale =
5940 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5941 float scale = quad_scale / transform_scale;
5942 if (frame_scale != 0.f && frame_scale != scale)
5943 return 0.f;
5944 frame_scale = scale;
5946 return frame_scale;
5949 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5951 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5952 LayerTreeHostImpl::FrameData* frame_data,
5953 DrawResult draw_result) override {
5954 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5955 switch (step_) {
5956 case 1:
5957 // Drew at scale 1 before any pinching.
5958 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5959 EXPECT_EQ(1.f, quad_scale_delta);
5960 break;
5961 case 2:
5962 if (quad_scale_delta != 1.f / 1.5f)
5963 break;
5964 // Drew at scale 1 still though the ideal is 1.5.
5965 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5966 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
5967 break;
5968 case 3:
5969 // Continuous draws are attempted.
5970 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5971 if (!frame_data->has_no_damage)
5972 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
5973 break;
5974 case 4:
5975 if (quad_scale_delta != 1.f)
5976 break;
5977 // Drew at scale 1.5 when all the tiles completed.
5978 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5979 EXPECT_EQ(1.f, quad_scale_delta);
5980 break;
5981 case 5:
5982 // TODO(danakj): We get more draws before the NotifyReadyToDraw
5983 // because it is asynchronous from the previous draw and happens late.
5984 break;
5985 case 6:
5986 // NotifyReadyToDraw happened. If we were already inside a frame, we may
5987 // try to draw once more.
5988 break;
5989 case 7:
5990 NOTREACHED() << "No draws should happen once we have a complete frame.";
5991 break;
5993 return draw_result;
5996 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
5997 switch (step_) {
5998 case 1:
5999 // Delay tile production.
6000 playback_allowed_event_.Reset();
6001 // Pinch zoom in to cause new tiles to be required.
6002 host_impl->PinchGestureBegin();
6003 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6004 host_impl->PinchGestureEnd();
6005 ++step_;
6006 break;
6007 case 2:
6008 ++step_;
6009 break;
6010 case 3:
6011 // We should continue to try draw while there are incomplete visible
6012 // tiles.
6013 if (++continuous_draws_ > 5) {
6014 // Allow the tiles to complete.
6015 playback_allowed_event_.Signal();
6016 ++step_;
6018 break;
6019 case 4:
6020 ++step_;
6021 break;
6022 case 5:
6023 // Waiting for NotifyReadyToDraw.
6024 break;
6025 case 6:
6026 // NotifyReadyToDraw happened.
6027 ++step_;
6028 break;
6032 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
6033 if (step_ == 5) {
6034 ++step_;
6035 // NotifyReadyToDraw has happened, we may draw once more, but should not
6036 // get any more draws after that. End the test after a timeout to watch
6037 // for any extraneous draws.
6038 // TODO(brianderson): We could remove this delay and instead wait until
6039 // the BeginFrameSource decides it doesn't need to send frames anymore,
6040 // or test that it already doesn't here.
6041 EndTestAfterDelayMs(16 * 4);
6045 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6046 const Tile* tile) override {
6047 // On step_ == 2, we are preventing texture uploads from completing,
6048 // so this verifies they are not completing before step_ == 3.
6049 // Flaky failures here indicate we're failing to prevent uploads from
6050 // completing.
6051 EXPECT_NE(2, step_);
6054 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
6056 FakeContentLayerClient client_;
6057 int step_;
6058 int continuous_draws_;
6059 base::WaitableEvent playback_allowed_event_;
6062 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
6064 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
6065 public:
6066 LayerTreeHostTestOneActivatePerPrepareTiles()
6067 : notify_ready_to_activate_count_(0u),
6068 scheduled_prepare_tiles_count_(0) {}
6070 void SetupTree() override {
6071 client_.set_fill_with_nonsolid_color(true);
6072 scoped_refptr<FakePictureLayer> root_layer =
6073 FakePictureLayer::Create(&client_);
6074 root_layer->SetBounds(gfx::Size(1500, 1500));
6075 root_layer->SetIsDrawable(true);
6077 layer_tree_host()->SetRootLayer(root_layer);
6078 LayerTreeHostTest::SetupTree();
6081 void BeginTest() override {
6082 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
6083 PostSetNeedsCommitToMainThread();
6086 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
6087 bool success) override {
6088 ASSERT_TRUE(success);
6089 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
6092 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6093 ++notify_ready_to_activate_count_;
6094 EndTestAfterDelayMs(100);
6097 void ScheduledActionPrepareTiles() override {
6098 ++scheduled_prepare_tiles_count_;
6101 void AfterTest() override {
6102 // Expect at most a notification for each scheduled prepare tiles, plus one
6103 // for the initial commit (which doesn't go through scheduled actions).
6104 // The reason this is not an equality is because depending on timing, we
6105 // might get a prepare tiles but not yet get a notification that we're
6106 // ready to activate. The intent of a test is to ensure that we don't
6107 // get more than one notification per prepare tiles, so this is OK.
6108 EXPECT_LE(notify_ready_to_activate_count_,
6109 1u + scheduled_prepare_tiles_count_);
6112 protected:
6113 FakeContentLayerClient client_;
6114 size_t notify_ready_to_activate_count_;
6115 size_t scheduled_prepare_tiles_count_;
6118 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
6120 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
6121 : public LayerTreeHostTest {
6122 public:
6123 LayerTreeHostTestFrameTimingRequestsSaveTimestamps()
6124 : check_results_on_commit_(false) {}
6126 void SetupTree() override {
6127 scoped_refptr<FakePictureLayer> root_layer =
6128 FakePictureLayer::Create(&client_);
6129 root_layer->SetBounds(gfx::Size(200, 200));
6130 root_layer->SetIsDrawable(true);
6132 scoped_refptr<FakePictureLayer> child_layer =
6133 FakePictureLayer::Create(&client_);
6134 child_layer->SetBounds(gfx::Size(1500, 1500));
6135 child_layer->SetIsDrawable(true);
6137 std::vector<FrameTimingRequest> requests;
6138 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100)));
6139 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100)));
6140 child_layer->SetFrameTimingRequests(requests);
6142 root_layer->AddChild(child_layer);
6143 layer_tree_host()->SetRootLayer(root_layer);
6144 LayerTreeHostTest::SetupTree();
6147 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6149 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
6150 if (!check_results_on_commit_)
6151 return;
6153 // Since in reality, the events will be read by LayerTreeHost during commit,
6154 // we check the requests here to ensure that they are correct at the next
6155 // commit time (as opposed to checking in DrawLayers for instance).
6156 // TODO(vmpstr): Change this to read things from the main thread when this
6157 // information is propagated to the main thread (not yet implemented).
6158 FrameTimingTracker* tracker = host_impl->frame_timing_tracker();
6159 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set =
6160 tracker->GroupCountsByRectId();
6161 EXPECT_EQ(1u, timing_set->size());
6162 auto rect_1_it = timing_set->find(1);
6163 EXPECT_TRUE(rect_1_it != timing_set->end());
6164 const auto& timing_events = rect_1_it->second;
6165 EXPECT_EQ(1u, timing_events.size());
6166 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6167 timing_events[0].frame_id);
6168 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6170 EndTest();
6173 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6174 check_results_on_commit_ = true;
6175 PostSetNeedsCommitToMainThread();
6178 void AfterTest() override {}
6180 private:
6181 FakeContentLayerClient client_;
6182 bool check_results_on_commit_;
6185 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
6187 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
6188 public:
6189 LayerTreeHostTestActivationCausesPrepareTiles()
6190 : scheduled_prepare_tiles_count_(0) {}
6192 void SetupTree() override {
6193 client_.set_fill_with_nonsolid_color(true);
6194 scoped_refptr<FakePictureLayer> root_layer =
6195 FakePictureLayer::Create(&client_);
6196 root_layer->SetBounds(gfx::Size(150, 150));
6197 root_layer->SetIsDrawable(true);
6199 layer_tree_host()->SetRootLayer(root_layer);
6200 LayerTreeHostTest::SetupTree();
6203 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6205 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6206 // Ensure we've already activated.
6207 EXPECT_FALSE(impl->pending_tree());
6209 // After activating, we either need to prepare tiles, or we've already
6210 // called a scheduled prepare tiles. This is done because activation might
6211 // cause us to have to memory available (old active tree is gone), so we
6212 // need to ensure we will get a PrepareTiles call.
6213 if (!impl->prepare_tiles_needed())
6214 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
6215 EndTest();
6218 void ScheduledActionPrepareTiles() override {
6219 ++scheduled_prepare_tiles_count_;
6222 void AfterTest() override {}
6224 protected:
6225 FakeContentLayerClient client_;
6226 int scheduled_prepare_tiles_count_;
6229 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
6231 // This tests an assertion that DidCommit and WillCommit happen in the same
6232 // stack frame with no tasks that run between them. Various embedders of
6233 // cc depend on this logic. ui::Compositor holds a compositor lock between
6234 // these events and the inspector timeline wants begin/end CompositeLayers
6235 // to be properly nested with other begin/end events.
6236 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
6237 : public LayerTreeHostTest {
6238 public:
6239 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
6241 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6243 void WillCommit() override {
6244 MainThreadTaskRunner()->PostTask(
6245 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
6246 EndTestShouldRunAfterDidCommit,
6247 base::Unretained(this)));
6250 void EndTestShouldRunAfterDidCommit() {
6251 EXPECT_TRUE(did_commit_);
6252 EndTest();
6255 void DidCommit() override {
6256 EXPECT_FALSE(did_commit_);
6257 did_commit_ = true;
6260 void AfterTest() override { EXPECT_TRUE(did_commit_); }
6262 private:
6263 bool did_commit_;
6266 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
6268 } // namespace cc