Disable flaky AnimatedContentSamplerParameterizedTest.FrameTimestampsConvergeTowardsE...
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob98ac5a11d6efbd35f41f8c9a17d9403d535f2ad6
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/location.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/synchronization/lock.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "cc/animation/timing_function.h"
15 #include "cc/debug/frame_rate_counter.h"
16 #include "cc/layers/content_layer.h"
17 #include "cc/layers/content_layer_client.h"
18 #include "cc/layers/io_surface_layer.h"
19 #include "cc/layers/layer_impl.h"
20 #include "cc/layers/painted_scrollbar_layer.h"
21 #include "cc/layers/picture_layer.h"
22 #include "cc/layers/solid_color_layer.h"
23 #include "cc/layers/video_layer.h"
24 #include "cc/output/begin_frame_args.h"
25 #include "cc/output/compositor_frame_ack.h"
26 #include "cc/output/copy_output_request.h"
27 #include "cc/output/copy_output_result.h"
28 #include "cc/output/output_surface.h"
29 #include "cc/output/swap_promise.h"
30 #include "cc/quads/draw_quad.h"
31 #include "cc/quads/io_surface_draw_quad.h"
32 #include "cc/quads/render_pass_draw_quad.h"
33 #include "cc/quads/tile_draw_quad.h"
34 #include "cc/resources/prioritized_resource.h"
35 #include "cc/resources/prioritized_resource_manager.h"
36 #include "cc/resources/resource_update_queue.h"
37 #include "cc/test/fake_content_layer.h"
38 #include "cc/test/fake_content_layer_client.h"
39 #include "cc/test/fake_content_layer_impl.h"
40 #include "cc/test/fake_layer_tree_host_client.h"
41 #include "cc/test/fake_output_surface.h"
42 #include "cc/test/fake_painted_scrollbar_layer.h"
43 #include "cc/test/fake_picture_layer.h"
44 #include "cc/test/fake_picture_layer_impl.h"
45 #include "cc/test/fake_picture_pile.h"
46 #include "cc/test/fake_proxy.h"
47 #include "cc/test/fake_scoped_ui_resource.h"
48 #include "cc/test/fake_video_frame_provider.h"
49 #include "cc/test/geometry_test_utils.h"
50 #include "cc/test/impl_side_painting_settings.h"
51 #include "cc/test/layer_tree_test.h"
52 #include "cc/test/test_shared_bitmap_manager.h"
53 #include "cc/test/test_web_graphics_context_3d.h"
54 #include "cc/trees/layer_tree_host_impl.h"
55 #include "cc/trees/layer_tree_impl.h"
56 #include "cc/trees/single_thread_proxy.h"
57 #include "cc/trees/thread_proxy.h"
58 #include "gpu/GLES2/gl2extchromium.h"
59 #include "skia/ext/refptr.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "third_party/khronos/GLES2/gl2.h"
62 #include "third_party/khronos/GLES2/gl2ext.h"
63 #include "third_party/skia/include/core/SkPicture.h"
64 #include "ui/gfx/frame_time.h"
65 #include "ui/gfx/geometry/point_conversions.h"
66 #include "ui/gfx/geometry/size_conversions.h"
67 #include "ui/gfx/geometry/vector2d_conversions.h"
69 using testing::_;
70 using testing::AnyNumber;
71 using testing::AtLeast;
72 using testing::Mock;
74 namespace cc {
75 namespace {
77 class LayerTreeHostTest : public LayerTreeTest {
78 public:
79 LayerTreeHostTest() : contents_texture_manager_(nullptr) {}
81 void DidInitializeOutputSurface() override {
82 contents_texture_manager_ = layer_tree_host()->contents_texture_manager();
85 protected:
86 PrioritizedResourceManager* contents_texture_manager_;
89 class LayerTreeHostTestHasImplThreadTest : public LayerTreeHostTest {
90 public:
91 LayerTreeHostTestHasImplThreadTest() : threaded_(false) {}
93 void RunTest(bool threaded,
94 bool delegating_renderer,
95 bool impl_side_painting) override {
96 threaded_ = threaded;
97 LayerTreeHostTest::RunTest(threaded, delegating_renderer,
98 impl_side_painting);
101 void BeginTest() override {
102 EXPECT_EQ(threaded_, HasImplThread());
103 EndTest();
106 void AfterTest() override { EXPECT_EQ(threaded_, HasImplThread()); }
108 private:
109 bool threaded_;
112 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestHasImplThreadTest);
114 class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest {
115 protected:
116 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
118 void Layout() override {
119 // This shouldn't cause a second commit to happen.
120 layer_tree_host()->SetNeedsCommit();
123 void DidCommit() override {
124 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
125 EndTest();
128 void AfterTest() override {}
131 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
132 LayerTreeHostTestSetNeedsCommitInsideLayout);
134 class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest {
135 protected:
136 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
138 void Layout() override {
139 // This shouldn't cause a second commit to happen.
140 layer_tree_host()->SetNeedsUpdateLayers();
143 void DidCommit() override {
144 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
145 EndTest();
148 void AfterTest() override {}
151 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
152 LayerTreeHostTestSetNeedsUpdateInsideLayout);
154 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
155 // when no raster tasks get scheduled.
156 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
157 public:
158 LayerTreeHostTestReadyToActivateEmpty()
159 : did_notify_ready_to_activate_(false),
160 all_tiles_required_for_activation_are_ready_to_draw_(false),
161 required_for_activation_count_(0) {}
163 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
165 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
166 const std::vector<PictureLayerImpl*>& layers =
167 impl->sync_tree()->picture_layers();
168 required_for_activation_count_ = 0;
169 for (const auto& layer : layers) {
170 FakePictureLayerImpl* fake_layer =
171 static_cast<FakePictureLayerImpl*>(layer);
172 required_for_activation_count_ +=
173 fake_layer->CountTilesRequiredForActivation();
177 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
178 did_notify_ready_to_activate_ = true;
179 all_tiles_required_for_activation_are_ready_to_draw_ =
180 impl->tile_manager()->IsReadyToActivate();
181 EndTest();
184 void AfterTest() override {
185 EXPECT_TRUE(did_notify_ready_to_activate_);
186 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
187 EXPECT_EQ(size_t(0), required_for_activation_count_);
190 protected:
191 bool did_notify_ready_to_activate_;
192 bool all_tiles_required_for_activation_are_ready_to_draw_;
193 size_t required_for_activation_count_;
196 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
198 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
199 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
200 class LayerTreeHostTestReadyToActivateNonEmpty
201 : public LayerTreeHostTestReadyToActivateEmpty {
202 public:
203 void SetupTree() override {
204 client_.set_fill_with_nonsolid_color(true);
205 scoped_refptr<FakePictureLayer> root_layer =
206 FakePictureLayer::Create(&client_);
207 root_layer->SetBounds(gfx::Size(1024, 1024));
208 root_layer->SetIsDrawable(true);
210 layer_tree_host()->SetRootLayer(root_layer);
211 LayerTreeHostTest::SetupTree();
214 void AfterTest() override {
215 EXPECT_TRUE(did_notify_ready_to_activate_);
216 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
217 EXPECT_LE(size_t(1), required_for_activation_count_);
220 private:
221 FakeContentLayerClient client_;
224 // Multi-thread only because in single thread the commit goes directly to the
225 // active tree, so notify ready to activate is skipped.
226 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
228 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
229 // no raster tasks get scheduled.
230 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
231 public:
232 LayerTreeHostTestReadyToDrawEmpty()
233 : did_notify_ready_to_draw_(false),
234 all_tiles_required_for_draw_are_ready_to_draw_(false),
235 required_for_draw_count_(0) {}
237 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
239 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
240 did_notify_ready_to_draw_ = true;
241 const std::vector<PictureLayerImpl*>& layers =
242 impl->active_tree()->picture_layers();
243 all_tiles_required_for_draw_are_ready_to_draw_ =
244 impl->tile_manager()->IsReadyToDraw();
245 for (const auto& layer : layers) {
246 FakePictureLayerImpl* fake_layer =
247 static_cast<FakePictureLayerImpl*>(layer);
248 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw();
251 EndTest();
254 void AfterTest() override {
255 EXPECT_TRUE(did_notify_ready_to_draw_);
256 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
257 EXPECT_EQ(size_t(0), required_for_draw_count_);
260 protected:
261 bool did_notify_ready_to_draw_;
262 bool all_tiles_required_for_draw_are_ready_to_draw_;
263 size_t required_for_draw_count_;
266 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
268 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
269 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
270 class LayerTreeHostTestReadyToDrawNonEmpty
271 : public LayerTreeHostTestReadyToDrawEmpty {
272 public:
273 void SetupTree() override {
274 client_.set_fill_with_nonsolid_color(true);
275 scoped_refptr<FakePictureLayer> root_layer =
276 FakePictureLayer::Create(&client_);
277 root_layer->SetBounds(gfx::Size(1024, 1024));
278 root_layer->SetIsDrawable(true);
280 layer_tree_host()->SetRootLayer(root_layer);
281 LayerTreeHostTest::SetupTree();
284 void AfterTest() override {
285 EXPECT_TRUE(did_notify_ready_to_draw_);
286 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
287 EXPECT_LE(size_t(1), required_for_draw_count_);
290 private:
291 FakeContentLayerClient client_;
294 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
295 // single threaded mode.
296 SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
298 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
299 // draw with frame 0.
300 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
301 public:
302 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
304 void BeginTest() override {
305 PostSetNeedsCommitToMainThread();
306 PostSetNeedsCommitToMainThread();
309 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
310 num_draws_++;
311 if (!impl->active_tree()->source_frame_number())
312 EndTest();
315 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
316 num_commits_++;
319 void AfterTest() override {
320 EXPECT_LE(1, num_commits_);
321 EXPECT_LE(1, num_draws_);
324 private:
325 int num_commits_;
326 int num_draws_;
329 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
331 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
332 // first committed frame draws should lead to another commit.
333 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
334 public:
335 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
337 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
339 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
341 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
342 ++num_commits_;
343 switch (num_commits_) {
344 case 1:
345 PostSetNeedsCommitToMainThread();
346 break;
347 case 2:
348 EndTest();
349 break;
350 default:
351 NOTREACHED();
355 void AfterTest() override {
356 EXPECT_EQ(2, num_commits_);
357 EXPECT_LE(1, num_draws_);
360 private:
361 int num_commits_;
362 int num_draws_;
365 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
367 // Verify that we pass property values in PushPropertiesTo.
368 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
369 protected:
370 void SetupTree() override {
371 scoped_refptr<Layer> root = Layer::Create();
372 root->CreateRenderSurface();
373 root->SetBounds(gfx::Size(10, 10));
374 layer_tree_host()->SetRootLayer(root);
375 LayerTreeHostTest::SetupTree();
378 enum Properties {
379 STARTUP,
380 BOUNDS,
381 HIDE_LAYER_AND_SUBTREE,
382 DRAWS_CONTENT,
383 DONE,
386 void BeginTest() override {
387 index_ = STARTUP;
388 PostSetNeedsCommitToMainThread();
391 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
392 VerifyAfterValues(impl->active_tree()->root_layer());
395 void DidCommitAndDrawFrame() override {
396 SetBeforeValues(layer_tree_host()->root_layer());
397 VerifyBeforeValues(layer_tree_host()->root_layer());
399 ++index_;
400 if (index_ == DONE) {
401 EndTest();
402 return;
405 SetAfterValues(layer_tree_host()->root_layer());
408 void AfterTest() override {}
410 void VerifyBeforeValues(Layer* layer) {
411 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
412 EXPECT_FALSE(layer->hide_layer_and_subtree());
413 EXPECT_FALSE(layer->DrawsContent());
416 void SetBeforeValues(Layer* layer) {
417 layer->SetBounds(gfx::Size(10, 10));
418 layer->SetHideLayerAndSubtree(false);
419 layer->SetIsDrawable(false);
422 void VerifyAfterValues(LayerImpl* layer) {
423 switch (static_cast<Properties>(index_)) {
424 case STARTUP:
425 case DONE:
426 break;
427 case BOUNDS:
428 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
429 break;
430 case HIDE_LAYER_AND_SUBTREE:
431 EXPECT_TRUE(layer->hide_layer_and_subtree());
432 break;
433 case DRAWS_CONTENT:
434 EXPECT_TRUE(layer->DrawsContent());
435 break;
439 void SetAfterValues(Layer* layer) {
440 switch (static_cast<Properties>(index_)) {
441 case STARTUP:
442 case DONE:
443 break;
444 case BOUNDS:
445 layer->SetBounds(gfx::Size(20, 20));
446 break;
447 case HIDE_LAYER_AND_SUBTREE:
448 layer->SetHideLayerAndSubtree(true);
449 break;
450 case DRAWS_CONTENT:
451 layer->SetIsDrawable(true);
452 break;
456 int index_;
459 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
461 // 1 setNeedsRedraw after the first commit has completed should lead to 1
462 // additional draw.
463 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
464 public:
465 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
467 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
469 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
470 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
471 if (!num_draws_) {
472 // Redraw again to verify that the second redraw doesn't commit.
473 PostSetNeedsRedrawToMainThread();
474 } else {
475 EndTest();
477 num_draws_++;
480 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
481 EXPECT_EQ(0, num_draws_);
482 num_commits_++;
485 void AfterTest() override {
486 EXPECT_GE(2, num_draws_);
487 EXPECT_EQ(1, num_commits_);
490 private:
491 int num_commits_;
492 int num_draws_;
495 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
497 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
498 // must contain invalid_rect.
499 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
500 public:
501 LayerTreeHostTestSetNeedsRedrawRect()
502 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
504 void BeginTest() override {
505 if (layer_tree_host()->settings().impl_side_painting)
506 root_layer_ = FakePictureLayer::Create(&client_);
507 else
508 root_layer_ = ContentLayer::Create(&client_);
509 root_layer_->SetIsDrawable(true);
510 root_layer_->SetBounds(bounds_);
511 layer_tree_host()->SetRootLayer(root_layer_);
512 layer_tree_host()->SetViewportSize(bounds_);
513 PostSetNeedsCommitToMainThread();
516 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
517 LayerTreeHostImpl::FrameData* frame_data,
518 DrawResult draw_result) override {
519 EXPECT_EQ(DRAW_SUCCESS, draw_result);
521 gfx::RectF root_damage_rect;
522 if (!frame_data->render_passes.empty())
523 root_damage_rect = frame_data->render_passes.back()->damage_rect;
525 if (!num_draws_) {
526 // If this is the first frame, expect full frame damage.
527 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_));
528 } else {
529 // Check that invalid_rect_ is indeed repainted.
530 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
533 return draw_result;
536 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
537 if (!num_draws_) {
538 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
539 } else {
540 EndTest();
542 num_draws_++;
545 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
547 private:
548 int num_draws_;
549 const gfx::Size bounds_;
550 const gfx::Rect invalid_rect_;
551 FakeContentLayerClient client_;
552 scoped_refptr<Layer> root_layer_;
555 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
557 // Ensure the texture size of the pending and active trees are identical when a
558 // layer is not in the viewport and a resize happens on the viewport
559 class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
560 public:
561 LayerTreeHostTestGpuRasterDeviceSizeChanged()
562 : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {}
564 void BeginTest() override {
565 client_.set_fill_with_nonsolid_color(true);
566 root_layer_ = FakePictureLayer::Create(&client_);
567 root_layer_->SetIsDrawable(true);
568 gfx::Transform transform;
569 // Translate the layer out of the viewport to force it to not update its
570 // tile size via PushProperties.
571 transform.Translate(10000.0, 10000.0);
572 root_layer_->SetTransform(transform);
573 root_layer_->SetBounds(bounds_);
574 layer_tree_host()->SetRootLayer(root_layer_);
575 layer_tree_host()->SetViewportSize(bounds_);
577 PostSetNeedsCommitToMainThread();
580 void InitializeSettings(LayerTreeSettings* settings) override {
581 settings->gpu_rasterization_enabled = true;
582 settings->gpu_rasterization_forced = true;
585 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
586 // Perform 2 commits.
587 if (!num_draws_) {
588 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
589 } else {
590 EndTest();
592 num_draws_++;
595 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
596 if (num_draws_ == 2) {
597 auto pending_tree = host_impl->pending_tree();
598 auto pending_layer_impl =
599 static_cast<FakePictureLayerImpl*>(pending_tree->root_layer());
600 EXPECT_NE(pending_layer_impl, nullptr);
602 auto active_tree = host_impl->pending_tree();
603 auto active_layer_impl =
604 static_cast<FakePictureLayerImpl*>(active_tree->root_layer());
605 EXPECT_NE(pending_layer_impl, nullptr);
607 auto active_tiling_set = active_layer_impl->picture_layer_tiling_set();
608 auto active_tiling = active_tiling_set->tiling_at(0);
609 auto pending_tiling_set = pending_layer_impl->picture_layer_tiling_set();
610 auto pending_tiling = pending_tiling_set->tiling_at(0);
611 EXPECT_EQ(
612 pending_tiling->TilingDataForTesting().max_texture_size().width(),
613 active_tiling->TilingDataForTesting().max_texture_size().width());
617 void DidCommitAndDrawFrame() override {
618 // On the second commit, resize the viewport.
619 if (num_draws_ == 1) {
620 layer_tree_host()->SetViewportSize(gfx::Size(400, 64));
624 void AfterTest() override {}
626 private:
627 int num_draws_;
628 const gfx::Size bounds_;
629 const gfx::Rect invalid_rect_;
630 FakeContentLayerClient client_;
631 scoped_refptr<FakePictureLayer> root_layer_;
634 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
635 LayerTreeHostTestGpuRasterDeviceSizeChanged);
637 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
638 public:
639 void InitializeSettings(LayerTreeSettings* settings) override {
640 settings->layer_transforms_should_scale_layer_contents = true;
643 void SetupTree() override {
644 root_layer_ = Layer::Create();
645 root_layer_->SetBounds(gfx::Size(10, 20));
646 root_layer_->CreateRenderSurface();
648 if (layer_tree_host()->settings().impl_side_painting)
649 scaled_layer_ = FakePictureLayer::Create(&client_);
650 else
651 scaled_layer_ = FakeContentLayer::Create(&client_);
652 scaled_layer_->SetBounds(gfx::Size(1, 1));
653 root_layer_->AddChild(scaled_layer_);
655 layer_tree_host()->SetRootLayer(root_layer_);
656 LayerTreeHostTest::SetupTree();
659 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
661 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
662 if (host_impl->active_tree()->source_frame_number() == 1)
663 EndTest();
666 void DidCommit() override {
667 switch (layer_tree_host()->source_frame_number()) {
668 case 1:
669 // SetBounds grows the layer and exposes new content.
670 scaled_layer_->SetBounds(gfx::Size(4, 4));
671 break;
672 default:
673 // No extra commits.
674 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
678 void AfterTest() override {
679 EXPECT_EQ(gfx::Size(4, 4).ToString(), scaled_layer_->bounds().ToString());
682 private:
683 FakeContentLayerClient client_;
684 scoped_refptr<Layer> root_layer_;
685 scoped_refptr<Layer> scaled_layer_;
688 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
690 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
691 : public LayerTreeHostTest {
692 public:
693 void InitializeSettings(LayerTreeSettings* settings) override {
694 settings->layer_transforms_should_scale_layer_contents = true;
697 void SetupTree() override {
698 root_layer_ = Layer::Create();
699 root_layer_->SetBounds(gfx::Size(10, 20));
700 root_layer_->CreateRenderSurface();
702 bool paint_scrollbar = true;
703 bool has_thumb = false;
704 scrollbar_ = FakePaintedScrollbarLayer::Create(
705 paint_scrollbar, has_thumb, root_layer_->id());
706 scrollbar_->SetPosition(gfx::Point(0, 10));
707 scrollbar_->SetBounds(gfx::Size(10, 10));
709 root_layer_->AddChild(scrollbar_);
711 layer_tree_host()->SetRootLayer(root_layer_);
712 LayerTreeHostTest::SetupTree();
715 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
717 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
718 if (host_impl->active_tree()->source_frame_number() == 1)
719 EndTest();
722 void DidCommit() override {
723 switch (layer_tree_host()->source_frame_number()) {
724 case 1:
725 // Changing the device scale factor causes a commit. It also changes
726 // the content bounds of |scrollbar_|, which should not generate
727 // a second commit as a result.
728 layer_tree_host()->SetDeviceScaleFactor(4.f);
729 break;
730 default:
731 // No extra commits.
732 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
733 break;
737 void AfterTest() override {
740 private:
741 FakeContentLayerClient client_;
742 scoped_refptr<Layer> root_layer_;
743 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
746 SINGLE_AND_MULTI_THREAD_TEST_F(
747 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
749 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
750 public:
751 LayerTreeHostTestSetNextCommitForcesRedraw()
752 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
754 void BeginTest() override {
755 if (layer_tree_host()->settings().impl_side_painting)
756 root_layer_ = FakePictureLayer::Create(&client_);
757 else
758 root_layer_ = ContentLayer::Create(&client_);
759 root_layer_->SetIsDrawable(true);
760 root_layer_->SetBounds(bounds_);
761 layer_tree_host()->SetRootLayer(root_layer_);
762 layer_tree_host()->SetViewportSize(bounds_);
763 PostSetNeedsCommitToMainThread();
766 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
767 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
768 host_impl->SetNeedsRedrawRect(invalid_rect_);
771 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
772 LayerTreeHostImpl::FrameData* frame_data,
773 DrawResult draw_result) override {
774 EXPECT_EQ(DRAW_SUCCESS, draw_result);
776 gfx::RectF root_damage_rect;
777 if (!frame_data->render_passes.empty())
778 root_damage_rect = frame_data->render_passes.back()->damage_rect;
780 switch (num_draws_) {
781 case 0:
782 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
783 break;
784 case 1:
785 case 2:
786 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
787 break;
788 case 3:
789 EXPECT_EQ(invalid_rect_, root_damage_rect);
790 break;
791 case 4:
792 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
793 break;
794 default:
795 NOTREACHED();
798 return draw_result;
801 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
802 switch (num_draws_) {
803 case 0:
804 case 1:
805 // Cycle through a couple of empty commits to ensure we're observing the
806 // right behavior
807 PostSetNeedsCommitToMainThread();
808 break;
809 case 2:
810 // Should force full frame damage on the next commit
811 PostSetNextCommitForcesRedrawToMainThread();
812 PostSetNeedsCommitToMainThread();
813 if (host_impl->settings().impl_side_painting)
814 host_impl->BlockNotifyReadyToActivateForTesting(true);
815 else
816 num_draws_++;
817 break;
818 case 3:
819 host_impl->BlockNotifyReadyToActivateForTesting(false);
820 break;
821 default:
822 EndTest();
823 break;
825 num_draws_++;
828 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
830 private:
831 int num_draws_;
832 const gfx::Size bounds_;
833 const gfx::Rect invalid_rect_;
834 FakeContentLayerClient client_;
835 scoped_refptr<Layer> root_layer_;
838 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
839 LayerTreeHostTestSetNextCommitForcesRedraw);
841 // Tests that if a layer is not drawn because of some reason in the parent then
842 // its damage is preserved until the next time it is drawn.
843 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
844 public:
845 LayerTreeHostTestUndrawnLayersDamageLater() {}
847 void InitializeSettings(LayerTreeSettings* settings) override {
848 // If we don't set the minimum contents scale, it's harder to verify whether
849 // the damage we get is correct. For other scale amounts, please see
850 // LayerTreeHostTestDamageWithScale.
851 settings->minimum_contents_scale = 1.f;
854 void SetupTree() override {
855 if (layer_tree_host()->settings().impl_side_painting)
856 root_layer_ = FakePictureLayer::Create(&client_);
857 else
858 root_layer_ = ContentLayer::Create(&client_);
859 root_layer_->SetIsDrawable(true);
860 root_layer_->SetBounds(gfx::Size(50, 50));
861 layer_tree_host()->SetRootLayer(root_layer_);
863 // The initially transparent layer has a larger child layer, which is
864 // not initially drawn because of the this (parent) layer.
865 if (layer_tree_host()->settings().impl_side_painting)
866 parent_layer_ = FakePictureLayer::Create(&client_);
867 else
868 parent_layer_ = FakeContentLayer::Create(&client_);
869 parent_layer_->SetBounds(gfx::Size(15, 15));
870 parent_layer_->SetOpacity(0.0f);
871 root_layer_->AddChild(parent_layer_);
873 if (layer_tree_host()->settings().impl_side_painting)
874 child_layer_ = FakePictureLayer::Create(&client_);
875 else
876 child_layer_ = FakeContentLayer::Create(&client_);
877 child_layer_->SetBounds(gfx::Size(25, 25));
878 parent_layer_->AddChild(child_layer_);
880 LayerTreeHostTest::SetupTree();
883 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
885 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
886 LayerTreeHostImpl::FrameData* frame_data,
887 DrawResult draw_result) override {
888 EXPECT_EQ(DRAW_SUCCESS, draw_result);
890 gfx::RectF root_damage_rect;
891 if (!frame_data->render_passes.empty())
892 root_damage_rect = frame_data->render_passes.back()->damage_rect;
894 // The first time, the whole view needs be drawn.
895 // Afterwards, just the opacity of surface_layer1 is changed a few times,
896 // and each damage should be the bounding box of it and its child. If this
897 // was working improperly, the damage might not include its childs bounding
898 // box.
899 switch (host_impl->active_tree()->source_frame_number()) {
900 case 0:
901 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
902 break;
903 case 1:
904 case 2:
905 case 3:
906 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
907 break;
908 default:
909 NOTREACHED();
912 return draw_result;
915 void DidCommitAndDrawFrame() override {
916 switch (layer_tree_host()->source_frame_number()) {
917 case 1:
918 // Test not owning the surface.
919 parent_layer_->SetOpacity(1.0f);
920 break;
921 case 2:
922 parent_layer_->SetOpacity(0.0f);
923 break;
924 case 3:
925 // Test owning the surface.
926 parent_layer_->SetOpacity(0.5f);
927 parent_layer_->SetForceRenderSurface(true);
928 break;
929 case 4:
930 EndTest();
931 break;
932 default:
933 NOTREACHED();
937 void AfterTest() override {}
939 private:
940 FakeContentLayerClient client_;
941 scoped_refptr<Layer> root_layer_;
942 scoped_refptr<Layer> parent_layer_;
943 scoped_refptr<Layer> child_layer_;
946 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
948 // Tests that if a layer is not drawn because of some reason in the parent then
949 // its damage is preserved until the next time it is drawn.
950 class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest {
951 public:
952 LayerTreeHostTestDamageWithScale() {}
954 void SetupTree() override {
955 client_.set_fill_with_nonsolid_color(true);
957 scoped_ptr<FakePicturePile> pile(
958 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
959 ImplSidePaintingSettings().default_tile_grid_size));
960 root_layer_ =
961 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
962 root_layer_->SetBounds(gfx::Size(50, 50));
964 pile.reset(
965 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
966 ImplSidePaintingSettings().default_tile_grid_size));
967 child_layer_ =
968 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
969 child_layer_->SetBounds(gfx::Size(25, 25));
970 child_layer_->SetIsDrawable(true);
971 child_layer_->SetContentsOpaque(true);
972 root_layer_->AddChild(child_layer_);
974 layer_tree_host()->SetRootLayer(root_layer_);
975 LayerTreeHostTest::SetupTree();
978 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
979 // Force the layer to have a tiling at 1.3f scale. Note that if we simply
980 // add tiling, it will be gone by the time we draw because of aggressive
981 // cleanup. AddTilingUntilNextDraw ensures that it remains there during
982 // damage calculation.
983 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
984 host_impl->active_tree()->LayerById(child_layer_->id()));
985 child_layer_impl->AddTilingUntilNextDraw(1.3f);
988 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
990 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
991 LayerTreeHostImpl::FrameData* frame_data,
992 DrawResult draw_result) override {
993 EXPECT_EQ(DRAW_SUCCESS, draw_result);
995 gfx::RectF root_damage_rect;
996 if (!frame_data->render_passes.empty())
997 root_damage_rect = frame_data->render_passes.back()->damage_rect;
999 // The first time, the whole view needs be drawn.
1000 // Afterwards, just the opacity of surface_layer1 is changed a few times,
1001 // and each damage should be the bounding box of it and its child. If this
1002 // was working improperly, the damage might not include its childs bounding
1003 // box.
1004 switch (host_impl->active_tree()->source_frame_number()) {
1005 case 0:
1006 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
1007 break;
1008 case 1: {
1009 FakePictureLayerImpl* child_layer_impl =
1010 static_cast<FakePictureLayerImpl*>(
1011 host_impl->active_tree()->LayerById(child_layer_->id()));
1012 // We remove tilings pretty aggressively if they are not ideal. Add this
1013 // back in so that we can compare
1014 // child_layer_impl->GetEnclosingRectInTargetSpace to the damage.
1015 child_layer_impl->AddTilingUntilNextDraw(1.3f);
1017 EXPECT_EQ(gfx::Rect(26, 26), root_damage_rect);
1018 EXPECT_EQ(child_layer_impl->GetEnclosingRectInTargetSpace(),
1019 root_damage_rect);
1020 EXPECT_TRUE(child_layer_impl->GetEnclosingRectInTargetSpace().Contains(
1021 gfx::Rect(child_layer_->bounds())));
1022 break;
1024 default:
1025 NOTREACHED();
1028 return draw_result;
1031 void DidCommitAndDrawFrame() override {
1032 switch (layer_tree_host()->source_frame_number()) {
1033 case 1: {
1034 // Test not owning the surface.
1035 child_layer_->SetOpacity(0.5f);
1036 break;
1038 case 2:
1039 EndTest();
1040 break;
1041 default:
1042 NOTREACHED();
1046 void AfterTest() override {}
1048 private:
1049 FakeContentLayerClient client_;
1050 scoped_refptr<Layer> root_layer_;
1051 scoped_refptr<Layer> child_layer_;
1054 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestDamageWithScale);
1056 // Tests that if a layer is not drawn because of some reason in the parent,
1057 // causing its content bounds to not be computed, then when it is later drawn,
1058 // its content bounds get pushed.
1059 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
1060 : public LayerTreeHostTest {
1061 public:
1062 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
1063 : root_layer_(Layer::Create()) {}
1065 void SetupTree() override {
1066 root_layer_->CreateRenderSurface();
1067 root_layer_->SetIsDrawable(true);
1068 root_layer_->SetBounds(gfx::Size(20, 20));
1069 layer_tree_host()->SetRootLayer(root_layer_);
1071 parent_layer_ = Layer::Create();
1072 parent_layer_->SetBounds(gfx::Size(20, 20));
1073 parent_layer_->SetOpacity(0.0f);
1074 root_layer_->AddChild(parent_layer_);
1076 child_layer_ = Layer::Create();
1077 child_layer_->SetBounds(gfx::Size(15, 15));
1078 parent_layer_->AddChild(child_layer_);
1080 LayerTreeHostTest::SetupTree();
1083 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1085 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1086 LayerImpl* root = host_impl->active_tree()->root_layer();
1087 LayerImpl* parent = root->children()[0];
1088 LayerImpl* child = parent->children()[0];
1090 switch (host_impl->active_tree()->source_frame_number()) {
1091 case 0:
1092 EXPECT_EQ(0.f, parent->opacity());
1093 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
1094 break;
1095 case 1:
1096 EXPECT_EQ(1.f, parent->opacity());
1097 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
1098 EndTest();
1099 break;
1100 default:
1101 NOTREACHED();
1105 void DidCommit() override {
1106 switch (layer_tree_host()->source_frame_number()) {
1107 case 1:
1108 parent_layer_->SetOpacity(1.0f);
1109 break;
1110 case 2:
1111 break;
1112 default:
1113 NOTREACHED();
1117 void AfterTest() override {}
1119 private:
1120 scoped_refptr<Layer> root_layer_;
1121 scoped_refptr<Layer> parent_layer_;
1122 scoped_refptr<Layer> child_layer_;
1125 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
1126 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
1128 // This test verifies that properties on the layer tree host are commited
1129 // to the impl side.
1130 class LayerTreeHostTestCommit : public LayerTreeHostTest {
1131 public:
1132 LayerTreeHostTestCommit() {}
1134 void BeginTest() override {
1135 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1136 layer_tree_host()->set_background_color(SK_ColorGRAY);
1138 PostSetNeedsCommitToMainThread();
1141 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1142 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
1143 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
1145 EndTest();
1148 void AfterTest() override {}
1151 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
1153 // This test verifies that LayerTreeHostImpl's current frame time gets
1154 // updated in consecutive frames when it doesn't draw due to tree
1155 // activation failure.
1156 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
1157 : public LayerTreeHostTest {
1158 public:
1159 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
1160 : frame_count_with_pending_tree_(0) {}
1162 void BeginTest() override {
1163 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1164 layer_tree_host()->set_background_color(SK_ColorGRAY);
1166 PostSetNeedsCommitToMainThread();
1169 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
1170 EXPECT_EQ(frame_count_with_pending_tree_, 0);
1171 if (impl->settings().impl_side_painting)
1172 impl->BlockNotifyReadyToActivateForTesting(true);
1175 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1176 const BeginFrameArgs& args) override {
1177 if (impl->pending_tree())
1178 frame_count_with_pending_tree_++;
1180 if (frame_count_with_pending_tree_ == 1) {
1181 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
1182 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1183 } else if (frame_count_with_pending_tree_ == 2 &&
1184 impl->settings().impl_side_painting) {
1185 impl->BlockNotifyReadyToActivateForTesting(false);
1189 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1190 if (frame_count_with_pending_tree_ > 1) {
1191 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
1192 EXPECT_NE(first_frame_time_.ToInternalValue(),
1193 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
1194 EndTest();
1195 return;
1198 EXPECT_FALSE(impl->settings().impl_side_painting);
1199 EndTest();
1201 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1202 if (impl->settings().impl_side_painting)
1203 EXPECT_NE(frame_count_with_pending_tree_, 1);
1206 void AfterTest() override {}
1208 private:
1209 int frame_count_with_pending_tree_;
1210 base::TimeTicks first_frame_time_;
1213 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1214 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
1216 // This test verifies that LayerTreeHostImpl's current frame time gets
1217 // updated in consecutive frames when it draws in each frame.
1218 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
1219 public:
1220 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
1222 void BeginTest() override {
1223 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1224 layer_tree_host()->set_background_color(SK_ColorGRAY);
1226 PostSetNeedsCommitToMainThread();
1229 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1230 frame_++;
1231 if (frame_ == 1) {
1232 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1233 impl->SetNeedsRedraw();
1235 // Since we might use a low-resolution clock on Windows, we need to
1236 // make sure that the clock has incremented past first_frame_time_.
1237 while (first_frame_time_ == gfx::FrameTime::Now()) {
1240 return;
1243 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
1244 EndTest();
1247 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1248 // Ensure there isn't a commit between the two draws, to ensure that a
1249 // commit isn't required for updating the current frame time. We can
1250 // only check for this in the multi-threaded case, since in the single-
1251 // threaded case there will always be a commit between consecutive draws.
1252 if (HasImplThread())
1253 EXPECT_EQ(0, frame_);
1256 void AfterTest() override {}
1258 private:
1259 int frame_;
1260 base::TimeTicks first_frame_time_;
1263 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1265 // Verifies that StartPageScaleAnimation events propagate correctly
1266 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1267 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
1268 public:
1269 LayerTreeHostTestStartPageScaleAnimation() {}
1271 void SetupTree() override {
1272 LayerTreeHostTest::SetupTree();
1274 scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client_);
1275 layer->set_always_update_resources(true);
1276 scroll_layer_ = layer;
1278 Layer* root_layer = layer_tree_host()->root_layer();
1279 scroll_layer_->SetScrollClipLayerId(root_layer->id());
1280 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
1281 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
1282 2 * root_layer->bounds().height()));
1283 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
1284 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1285 // This test requires the page_scale and inner viewport layers to be
1286 // identified.
1287 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
1288 scroll_layer_.get(), NULL);
1289 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1292 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1294 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
1295 float scale,
1296 float) override {
1297 gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
1298 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset,
1299 scroll_delta));
1300 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1303 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1304 // We get one commit before the first draw, and the animation doesn't happen
1305 // until the second draw.
1306 switch (impl->active_tree()->source_frame_number()) {
1307 case 0:
1308 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1309 // We'll start an animation when we get back to the main thread.
1310 break;
1311 case 1:
1312 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1313 break;
1314 case 2:
1315 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
1316 EndTest();
1317 break;
1318 default:
1319 NOTREACHED();
1323 void DidCommitAndDrawFrame() override {
1324 switch (layer_tree_host()->source_frame_number()) {
1325 case 1:
1326 layer_tree_host()->StartPageScaleAnimation(
1327 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1328 break;
1332 void AfterTest() override {}
1334 FakeContentLayerClient client_;
1335 scoped_refptr<Layer> scroll_layer_;
1338 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1340 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1341 public:
1342 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1344 void BeginTest() override {
1345 PostSetNeedsCommitToMainThread();
1346 PostSetVisibleToMainThread(false);
1347 // This is suppressed while we're invisible.
1348 PostSetNeedsRedrawToMainThread();
1349 // Triggers the redraw.
1350 PostSetVisibleToMainThread(true);
1353 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1354 EXPECT_TRUE(impl->visible());
1355 ++num_draws_;
1356 EndTest();
1359 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
1361 private:
1362 int num_draws_;
1365 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1367 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1368 public:
1369 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1371 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1373 void PaintContents(SkCanvas* canvas,
1374 const gfx::Rect& clip,
1375 PaintingControlSetting picture_control) override {
1376 // Set layer opacity to 0.
1377 if (test_layer_)
1378 test_layer_->SetOpacity(0.f);
1380 void PaintContentsToDisplayList(
1381 DisplayItemList* display_list,
1382 const gfx::Rect& clip,
1383 PaintingControlSetting picture_control) override {
1384 NOTIMPLEMENTED();
1386 bool FillsBoundsCompletely() const override { return false; }
1388 private:
1389 Layer* test_layer_;
1392 class ContentLayerWithUpdateTracking : public ContentLayer {
1393 public:
1394 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1395 ContentLayerClient* client) {
1396 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1399 int PaintContentsCount() { return paint_contents_count_; }
1400 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1402 bool Update(ResourceUpdateQueue* queue,
1403 const OcclusionTracker<Layer>* occlusion) override {
1404 bool updated = ContentLayer::Update(queue, occlusion);
1405 paint_contents_count_++;
1406 return updated;
1409 private:
1410 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1411 : ContentLayer(client), paint_contents_count_(0) {
1412 SetBounds(gfx::Size(10, 10));
1413 SetIsDrawable(true);
1415 ~ContentLayerWithUpdateTracking() override {}
1417 int paint_contents_count_;
1420 // Layer opacity change during paint should not prevent compositor resources
1421 // from being updated during commit.
1422 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1423 public:
1424 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {}
1426 void BeginTest() override {
1427 if (layer_tree_host()->settings().impl_side_painting) {
1428 update_check_picture_layer_ =
1429 FakePictureLayer::Create(&test_opacity_change_delegate_);
1430 test_opacity_change_delegate_.SetTestLayer(
1431 update_check_picture_layer_.get());
1432 is_impl_paint_ = true;
1433 } else {
1434 update_check_content_layer_ = ContentLayerWithUpdateTracking::Create(
1435 &test_opacity_change_delegate_);
1436 test_opacity_change_delegate_.SetTestLayer(
1437 update_check_content_layer_.get());
1438 is_impl_paint_ = false;
1440 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1441 if (layer_tree_host()->settings().impl_side_painting)
1442 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
1443 else
1444 layer_tree_host()->root_layer()->AddChild(update_check_content_layer_);
1446 PostSetNeedsCommitToMainThread();
1449 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
1451 void AfterTest() override {
1452 // Update() should have been called once.
1453 if (is_impl_paint_)
1454 EXPECT_EQ(1u, update_check_picture_layer_->update_count());
1455 else
1456 EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount());
1459 private:
1460 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1461 scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_;
1462 scoped_refptr<FakePictureLayer> update_check_picture_layer_;
1463 bool is_impl_paint_;
1466 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1468 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1469 : public LayerTreeHostTest {
1470 public:
1471 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {}
1473 void InitializeSettings(LayerTreeSettings* settings) override {
1474 // PictureLayer can only be used with impl side painting enabled.
1475 settings->impl_side_painting = true;
1478 void BeginTest() override {
1479 client_.set_fill_with_nonsolid_color(true);
1480 root_layer_ = FakePictureLayer::Create(&client_);
1481 child_layer_ = FakePictureLayer::Create(&client_);
1483 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1484 layer_tree_host()->SetDeviceScaleFactor(1.5);
1485 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1487 root_layer_->AddChild(child_layer_);
1489 root_layer_->SetIsDrawable(true);
1490 root_layer_->SetBounds(gfx::Size(30, 30));
1492 child_layer_->SetIsDrawable(true);
1493 child_layer_->SetPosition(gfx::Point(2, 2));
1494 child_layer_->SetBounds(gfx::Size(10, 10));
1496 layer_tree_host()->SetRootLayer(root_layer_);
1498 PostSetNeedsCommitToMainThread();
1501 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1502 // Should only do one commit.
1503 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1504 // Device scale factor should come over to impl.
1505 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1507 // Both layers are on impl.
1508 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1510 // Device viewport is scaled.
1511 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1513 FakePictureLayerImpl* root =
1514 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
1515 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
1516 impl->active_tree()->root_layer()->children()[0]);
1518 // Positions remain in layout pixels.
1519 EXPECT_EQ(gfx::Point(0, 0), root->position());
1520 EXPECT_EQ(gfx::Point(2, 2), child->position());
1522 // Compute all the layer transforms for the frame.
1523 LayerTreeHostImpl::FrameData frame_data;
1524 impl->PrepareToDraw(&frame_data);
1525 impl->DidDrawAllLayers(frame_data);
1527 const LayerImplList& render_surface_layer_list =
1528 *frame_data.render_surface_layer_list;
1530 // Both layers should be drawing into the root render surface.
1531 ASSERT_EQ(1u, render_surface_layer_list.size());
1532 ASSERT_EQ(root->render_surface(),
1533 render_surface_layer_list[0]->render_surface());
1534 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1536 // The root render surface is the size of the viewport.
1537 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect());
1539 // The max tiling scale of the child should be scaled.
1540 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale());
1542 gfx::Transform scale_transform;
1543 scale_transform.Scale(impl->device_scale_factor(),
1544 impl->device_scale_factor());
1546 // The root layer is scaled by 2x.
1547 gfx::Transform root_screen_space_transform = scale_transform;
1548 gfx::Transform root_draw_transform = scale_transform;
1550 EXPECT_EQ(root_draw_transform, root->draw_transform());
1551 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1553 // The child is at position 2,2, which is transformed to 3,3 after the scale
1554 gfx::Transform child_transform;
1555 child_transform.Translate(3.f, 3.f);
1556 child_transform.Scale(child->MaximumTilingContentsScale(),
1557 child->MaximumTilingContentsScale());
1559 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform());
1560 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform,
1561 child->screen_space_transform());
1563 EndTest();
1566 void AfterTest() override {}
1568 private:
1569 FakeContentLayerClient client_;
1570 scoped_refptr<FakePictureLayer> root_layer_;
1571 scoped_refptr<FakePictureLayer> child_layer_;
1574 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1576 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1577 // Verify atomicity of commits and reuse of textures.
1578 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1579 public:
1580 void InitializeSettings(LayerTreeSettings* settings) override {
1581 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1582 // Make sure partial texture updates are turned off.
1583 settings->max_partial_texture_updates = 0;
1584 // Linear fade animator prevents scrollbars from drawing immediately.
1585 settings->scrollbar_animator = LayerTreeSettings::NO_ANIMATOR;
1588 void SetupTree() override {
1589 layer_ = FakeContentLayer::Create(&client_);
1590 layer_->SetBounds(gfx::Size(10, 20));
1592 bool paint_scrollbar = true;
1593 bool has_thumb = false;
1594 scrollbar_ = FakePaintedScrollbarLayer::Create(
1595 paint_scrollbar, has_thumb, layer_->id());
1596 scrollbar_->SetPosition(gfx::Point(0, 10));
1597 scrollbar_->SetBounds(gfx::Size(10, 10));
1599 layer_->AddChild(scrollbar_);
1601 layer_tree_host()->SetRootLayer(layer_);
1602 LayerTreeHostTest::SetupTree();
1605 void BeginTest() override {
1606 drew_frame_ = -1;
1607 PostSetNeedsCommitToMainThread();
1610 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1611 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
1613 TestWebGraphicsContext3D* context = TestContext();
1615 switch (impl->active_tree()->source_frame_number()) {
1616 case 0:
1617 // Number of textures should be one for each layer
1618 ASSERT_EQ(2u, context->NumTextures());
1619 // Number of textures used for commit should be one for each layer.
1620 EXPECT_EQ(2u, context->NumUsedTextures());
1621 // Verify that used texture is correct.
1622 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1623 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1625 context->ResetUsedTextures();
1626 break;
1627 case 1:
1628 // Number of textures should be one for scrollbar layer since it was
1629 // requested and deleted on the impl-thread, and double for the content
1630 // layer since its first texture is used by impl thread and cannot by
1631 // used for update.
1632 ASSERT_EQ(3u, context->NumTextures());
1633 // Number of textures used for commit should be one for each layer.
1634 EXPECT_EQ(2u, context->NumUsedTextures());
1635 // First textures should not have been used.
1636 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1637 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1638 // New textures should have been used.
1639 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1640 context->ResetUsedTextures();
1641 break;
1642 case 2:
1643 EndTest();
1644 break;
1645 default:
1646 NOTREACHED();
1647 break;
1651 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1652 TestWebGraphicsContext3D* context = TestContext();
1654 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1655 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1656 return;
1658 drew_frame_ = impl->active_tree()->source_frame_number();
1660 // We draw/ship one texture each frame for each layer.
1661 EXPECT_EQ(2u, context->NumUsedTextures());
1662 context->ResetUsedTextures();
1664 if (!TestEnded())
1665 PostSetNeedsCommitToMainThread();
1668 void Layout() override {
1669 layer_->SetNeedsDisplay();
1670 scrollbar_->SetNeedsDisplay();
1673 void AfterTest() override {}
1675 protected:
1676 FakeContentLayerClient client_;
1677 scoped_refptr<FakeContentLayer> layer_;
1678 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1679 int drew_frame_;
1682 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1683 LayerTreeHostTestDirectRendererAtomicCommit);
1685 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1686 class LayerTreeHostTestDelegatingRendererAtomicCommit
1687 : public LayerTreeHostTestDirectRendererAtomicCommit {
1688 public:
1689 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1690 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
1692 TestWebGraphicsContext3D* context = TestContext();
1694 switch (impl->active_tree()->source_frame_number()) {
1695 case 0:
1696 // Number of textures should be one for each layer
1697 ASSERT_EQ(2u, context->NumTextures());
1698 // Number of textures used for commit should be one for each layer.
1699 EXPECT_EQ(2u, context->NumUsedTextures());
1700 // Verify that used texture is correct.
1701 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1702 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1703 break;
1704 case 1:
1705 // Number of textures should be doubled as the first context layer
1706 // texture is being used by the impl-thread and cannot be used for
1707 // update. The scrollbar behavior is different direct renderer because
1708 // UI resource deletion with delegating renderer occurs after tree
1709 // activation.
1710 ASSERT_EQ(4u, context->NumTextures());
1711 // Number of textures used for commit should still be
1712 // one for each layer.
1713 EXPECT_EQ(2u, context->NumUsedTextures());
1714 // First textures should not have been used.
1715 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1716 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1717 // New textures should have been used.
1718 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1719 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1720 break;
1721 case 2:
1722 EndTest();
1723 break;
1724 default:
1725 NOTREACHED();
1726 break;
1731 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1732 LayerTreeHostTestDelegatingRendererAtomicCommit);
1734 static void SetLayerPropertiesForTesting(Layer* layer,
1735 Layer* parent,
1736 const gfx::Transform& transform,
1737 const gfx::Point3F& transform_origin,
1738 const gfx::PointF& position,
1739 const gfx::Size& bounds,
1740 bool opaque) {
1741 layer->RemoveAllChildren();
1742 if (parent)
1743 parent->AddChild(layer);
1744 layer->SetTransform(transform);
1745 layer->SetTransformOrigin(transform_origin);
1746 layer->SetPosition(position);
1747 layer->SetBounds(bounds);
1748 layer->SetContentsOpaque(opaque);
1751 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1752 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1753 : public LayerTreeHostTest {
1754 public:
1755 void InitializeSettings(LayerTreeSettings* settings) override {
1756 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1757 // Allow one partial texture update.
1758 settings->max_partial_texture_updates = 1;
1759 // No partial updates when impl side painting is enabled.
1760 settings->impl_side_painting = false;
1763 void SetupTree() override {
1764 parent_ = FakeContentLayer::Create(&client_);
1765 parent_->SetBounds(gfx::Size(10, 20));
1767 child_ = FakeContentLayer::Create(&client_);
1768 child_->SetPosition(gfx::Point(0, 10));
1769 child_->SetBounds(gfx::Size(3, 10));
1771 parent_->AddChild(child_);
1773 layer_tree_host()->SetRootLayer(parent_);
1774 LayerTreeHostTest::SetupTree();
1777 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1779 void DidCommitAndDrawFrame() override {
1780 switch (layer_tree_host()->source_frame_number()) {
1781 case 1:
1782 parent_->SetNeedsDisplay();
1783 child_->SetNeedsDisplay();
1784 break;
1785 case 2:
1786 // Damage part of layers.
1787 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1788 child_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1789 break;
1790 case 3:
1791 child_->SetNeedsDisplay();
1792 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1793 break;
1794 case 4:
1795 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1796 break;
1797 case 5:
1798 EndTest();
1799 break;
1800 default:
1801 NOTREACHED() << layer_tree_host()->source_frame_number();
1802 break;
1806 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1807 ASSERT_EQ(1u, impl->settings().max_partial_texture_updates);
1809 TestWebGraphicsContext3D* context = TestContext();
1811 switch (impl->active_tree()->source_frame_number()) {
1812 case 0:
1813 // Number of textures should be one for each layer.
1814 ASSERT_EQ(2u, context->NumTextures());
1815 // Number of textures used for commit should be one for each layer.
1816 EXPECT_EQ(2u, context->NumUsedTextures());
1817 // Verify that used textures are correct.
1818 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1819 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1820 context->ResetUsedTextures();
1821 break;
1822 case 1:
1823 if (HasImplThread()) {
1824 // Number of textures should be two for each content layer.
1825 ASSERT_EQ(4u, context->NumTextures());
1826 } else {
1827 // In single thread we can always do partial updates, so the limit has
1828 // no effect.
1829 ASSERT_EQ(2u, context->NumTextures());
1831 // Number of textures used for commit should be one for each content
1832 // layer.
1833 EXPECT_EQ(2u, context->NumUsedTextures());
1835 if (HasImplThread()) {
1836 // First content textures should not have been used.
1837 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1838 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1839 // New textures should have been used.
1840 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1841 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1842 } else {
1843 // In single thread we can always do partial updates, so the limit has
1844 // no effect.
1845 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1846 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1849 context->ResetUsedTextures();
1850 break;
1851 case 2:
1852 if (HasImplThread()) {
1853 // Number of textures should be two for each content layer.
1854 ASSERT_EQ(4u, context->NumTextures());
1855 } else {
1856 // In single thread we can always do partial updates, so the limit has
1857 // no effect.
1858 ASSERT_EQ(2u, context->NumTextures());
1860 // Number of textures used for commit should be one for each content
1861 // layer.
1862 EXPECT_EQ(2u, context->NumUsedTextures());
1864 if (HasImplThread()) {
1865 // One content layer does a partial update also.
1866 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1867 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1868 } else {
1869 // In single thread we can always do partial updates, so the limit has
1870 // no effect.
1871 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1872 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1875 context->ResetUsedTextures();
1876 break;
1877 case 3:
1878 // No textures should be used for commit.
1879 EXPECT_EQ(0u, context->NumUsedTextures());
1881 context->ResetUsedTextures();
1882 break;
1883 case 4:
1884 // Number of textures used for commit should be one, for the
1885 // content layer.
1886 EXPECT_EQ(1u, context->NumUsedTextures());
1888 context->ResetUsedTextures();
1889 break;
1890 default:
1891 NOTREACHED();
1892 break;
1896 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1897 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1899 TestWebGraphicsContext3D* context = TestContext();
1901 // Number of textures used for drawing should one per layer except for
1902 // frame 3 where the viewport only contains one layer.
1903 if (impl->active_tree()->source_frame_number() == 3) {
1904 EXPECT_EQ(1u, context->NumUsedTextures());
1905 } else {
1906 EXPECT_EQ(2u, context->NumUsedTextures())
1907 << "For frame " << impl->active_tree()->source_frame_number();
1910 context->ResetUsedTextures();
1913 void AfterTest() override {}
1915 private:
1916 FakeContentLayerClient client_;
1917 scoped_refptr<FakeContentLayer> parent_;
1918 scoped_refptr<FakeContentLayer> child_;
1921 // Partial updates are not possible with a delegating renderer.
1922 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1923 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1925 // TODO(sohanjg) : Make it work with impl-side painting.
1926 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1927 : public LayerTreeHostTest {
1928 protected:
1929 void SetupTree() override {
1930 root_layer_ = FakeContentLayer::Create(&client_);
1931 root_layer_->SetBounds(gfx::Size(100, 100));
1933 surface_layer1_ = FakeContentLayer::Create(&client_);
1934 surface_layer1_->SetBounds(gfx::Size(100, 100));
1935 surface_layer1_->SetForceRenderSurface(true);
1936 surface_layer1_->SetOpacity(0.5f);
1937 root_layer_->AddChild(surface_layer1_);
1939 surface_layer2_ = FakeContentLayer::Create(&client_);
1940 surface_layer2_->SetBounds(gfx::Size(100, 100));
1941 surface_layer2_->SetForceRenderSurface(true);
1942 surface_layer2_->SetOpacity(0.5f);
1943 surface_layer1_->AddChild(surface_layer2_);
1945 replica_layer1_ = FakeContentLayer::Create(&client_);
1946 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1948 replica_layer2_ = FakeContentLayer::Create(&client_);
1949 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1951 layer_tree_host()->SetRootLayer(root_layer_);
1952 LayerTreeHostTest::SetupTree();
1955 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1957 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1958 Renderer* renderer = host_impl->renderer();
1959 RenderPassId surface1_render_pass_id = host_impl->active_tree()
1960 ->root_layer()
1961 ->children()[0]
1962 ->render_surface()
1963 ->GetRenderPassId();
1964 RenderPassId surface2_render_pass_id = host_impl->active_tree()
1965 ->root_layer()
1966 ->children()[0]
1967 ->children()[0]
1968 ->render_surface()
1969 ->GetRenderPassId();
1971 switch (host_impl->active_tree()->source_frame_number()) {
1972 case 0:
1973 EXPECT_TRUE(
1974 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1975 EXPECT_TRUE(
1976 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1978 // Reduce the memory limit to only fit the root layer and one render
1979 // surface. This prevents any contents drawing into surfaces
1980 // from being allocated.
1981 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1982 break;
1983 case 1:
1984 EXPECT_FALSE(
1985 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1986 EXPECT_FALSE(
1987 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1989 EndTest();
1990 break;
1994 void DidCommitAndDrawFrame() override {
1995 if (layer_tree_host()->source_frame_number() < 2)
1996 root_layer_->SetNeedsDisplay();
1999 void AfterTest() override {
2000 EXPECT_LE(2u, root_layer_->update_count());
2001 EXPECT_LE(2u, surface_layer1_->update_count());
2002 EXPECT_LE(2u, surface_layer2_->update_count());
2005 FakeContentLayerClient client_;
2006 scoped_refptr<FakeContentLayer> root_layer_;
2007 scoped_refptr<FakeContentLayer> surface_layer1_;
2008 scoped_refptr<FakeContentLayer> replica_layer1_;
2009 scoped_refptr<FakeContentLayer> surface_layer2_;
2010 scoped_refptr<FakeContentLayer> replica_layer2_;
2013 // Surfaces don't exist with a delegated renderer.
2014 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
2015 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
2017 class EvictionTestLayer : public Layer {
2018 public:
2019 static scoped_refptr<EvictionTestLayer> Create() {
2020 return make_scoped_refptr(new EvictionTestLayer());
2023 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override;
2024 bool DrawsContent() const override { return true; }
2026 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
2027 void PushPropertiesTo(LayerImpl* impl) override;
2028 void SetTexturePriorities(const PriorityCalculator&) override;
2030 bool HaveBackingTexture() const {
2031 return texture_.get() ? texture_->have_backing_texture() : false;
2034 private:
2035 EvictionTestLayer() : Layer() {}
2036 ~EvictionTestLayer() override {}
2038 void CreateTextureIfNeeded() {
2039 if (texture_)
2040 return;
2041 texture_ = PrioritizedResource::Create(
2042 layer_tree_host()->contents_texture_manager());
2043 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
2044 bitmap_.allocN32Pixels(10, 10);
2047 scoped_ptr<PrioritizedResource> texture_;
2048 SkBitmap bitmap_;
2051 class EvictionTestLayerImpl : public LayerImpl {
2052 public:
2053 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
2054 int id) {
2055 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
2057 ~EvictionTestLayerImpl() override {}
2059 void AppendQuads(RenderPass* render_pass,
2060 AppendQuadsData* append_quads_data) override {
2061 ASSERT_TRUE(has_texture_);
2062 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
2065 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
2067 private:
2068 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
2069 : LayerImpl(tree_impl, id), has_texture_(false) {}
2071 bool has_texture_;
2074 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
2075 CreateTextureIfNeeded();
2076 if (!texture_)
2077 return;
2078 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
2081 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
2082 const OcclusionTracker<Layer>* occlusion) {
2083 CreateTextureIfNeeded();
2084 if (!texture_)
2085 return false;
2087 gfx::Rect full_rect(0, 0, 10, 10);
2088 ResourceUpdate upload = ResourceUpdate::Create(
2089 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
2090 queue->AppendFullUpload(upload);
2091 return true;
2094 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
2095 LayerTreeImpl* tree_impl) {
2096 return EvictionTestLayerImpl::Create(tree_impl, layer_id_);
2099 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
2100 Layer::PushPropertiesTo(layer_impl);
2102 EvictionTestLayerImpl* test_layer_impl =
2103 static_cast<EvictionTestLayerImpl*>(layer_impl);
2104 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
2107 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
2108 public:
2109 LayerTreeHostTestEvictTextures()
2110 : layer_(EvictionTestLayer::Create()),
2111 impl_for_evict_textures_(0),
2112 num_commits_(0) {}
2114 void BeginTest() override {
2115 layer_tree_host()->SetRootLayer(layer_);
2116 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
2118 gfx::Transform identity_matrix;
2119 SetLayerPropertiesForTesting(layer_.get(),
2121 identity_matrix,
2122 gfx::Point3F(0.f, 0.f, 0.f),
2123 gfx::PointF(0.f, 0.f),
2124 gfx::Size(10, 20),
2125 true);
2127 PostSetNeedsCommitToMainThread();
2130 void PostEvictTextures() {
2131 ImplThreadTaskRunner()->PostTask(
2132 FROM_HERE,
2133 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
2134 base::Unretained(this)));
2137 void EvictTexturesOnImplThread() {
2138 DCHECK(impl_for_evict_textures_);
2139 impl_for_evict_textures_->EvictTexturesForTesting();
2142 // Commit 1: Just commit and draw normally, then post an eviction at the end
2143 // that will trigger a commit.
2144 // Commit 2: Triggered by the eviction, let it go through and then set
2145 // needsCommit.
2146 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
2147 // task, which will be handled before the commit. Don't set needsCommit, it
2148 // should have been posted. A frame should not be drawn (note,
2149 // didCommitAndDrawFrame may be called anyway).
2150 // Commit 4: Triggered by the eviction, let it go through and then set
2151 // needsCommit.
2152 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
2153 // Layout(), a frame should not be drawn but a commit will be posted.
2154 // Commit 6: Triggered by the eviction, post an eviction task in
2155 // Layout(), which will be a noop, letting the commit (which recreates the
2156 // textures) go through and draw a frame, then end the test.
2158 // Commits 1+2 test the eviction recovery path where eviction happens outside
2159 // of the beginFrame/commit pair.
2160 // Commits 3+4 test the eviction recovery path where eviction happens inside
2161 // the beginFrame/commit pair.
2162 // Commits 5+6 test the path where an eviction happens during the eviction
2163 // recovery path.
2164 void DidCommit() override {
2165 switch (num_commits_) {
2166 case 1:
2167 EXPECT_TRUE(layer_->HaveBackingTexture());
2168 PostEvictTextures();
2169 break;
2170 case 2:
2171 EXPECT_TRUE(layer_->HaveBackingTexture());
2172 layer_tree_host()->SetNeedsCommit();
2173 break;
2174 case 3:
2175 break;
2176 case 4:
2177 EXPECT_TRUE(layer_->HaveBackingTexture());
2178 layer_tree_host()->SetNeedsCommit();
2179 break;
2180 case 5:
2181 break;
2182 case 6:
2183 EXPECT_TRUE(layer_->HaveBackingTexture());
2184 EndTest();
2185 break;
2186 default:
2187 NOTREACHED();
2188 break;
2192 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2193 impl_for_evict_textures_ = impl;
2196 void Layout() override {
2197 ++num_commits_;
2198 switch (num_commits_) {
2199 case 1:
2200 case 2:
2201 break;
2202 case 3:
2203 PostEvictTextures();
2204 break;
2205 case 4:
2206 // We couldn't check in didCommitAndDrawFrame on commit 3,
2207 // so check here.
2208 EXPECT_FALSE(layer_->HaveBackingTexture());
2209 break;
2210 case 5:
2211 PostEvictTextures();
2212 break;
2213 case 6:
2214 // We couldn't check in didCommitAndDrawFrame on commit 5,
2215 // so check here.
2216 EXPECT_FALSE(layer_->HaveBackingTexture());
2217 PostEvictTextures();
2218 break;
2219 default:
2220 NOTREACHED();
2221 break;
2225 void AfterTest() override {}
2227 private:
2228 FakeContentLayerClient client_;
2229 scoped_refptr<EvictionTestLayer> layer_;
2230 LayerTreeHostImpl* impl_for_evict_textures_;
2231 int num_commits_;
2234 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
2236 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
2237 public:
2238 LayerTreeHostTestContinuousInvalidate()
2239 : num_commit_complete_(0), num_draw_layers_(0) {}
2241 void BeginTest() override {
2242 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2243 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2245 if (layer_tree_host()->settings().impl_side_painting)
2246 layer_ = FakePictureLayer::Create(&client_);
2247 else
2248 layer_ = FakeContentLayer::Create(&client_);
2250 layer_->SetBounds(gfx::Size(10, 10));
2251 layer_->SetPosition(gfx::PointF(0.f, 0.f));
2252 layer_->SetIsDrawable(true);
2253 layer_tree_host()->root_layer()->AddChild(layer_);
2255 PostSetNeedsCommitToMainThread();
2258 void DidCommitAndDrawFrame() override {
2259 if (num_draw_layers_ == 2)
2260 return;
2261 layer_->SetNeedsDisplay();
2264 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2265 if (num_draw_layers_ == 1)
2266 num_commit_complete_++;
2269 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2270 num_draw_layers_++;
2271 if (num_draw_layers_ == 2)
2272 EndTest();
2275 void AfterTest() override {
2276 // Check that we didn't commit twice between first and second draw.
2277 EXPECT_EQ(1, num_commit_complete_);
2280 private:
2281 FakeContentLayerClient client_;
2282 scoped_refptr<Layer> layer_;
2283 int num_commit_complete_;
2284 int num_draw_layers_;
2287 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
2289 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2290 public:
2291 LayerTreeHostTestDeferCommits()
2292 : num_will_begin_impl_frame_(0),
2293 num_send_begin_main_frame_(0) {}
2295 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2297 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
2298 const BeginFrameArgs& args) override {
2299 num_will_begin_impl_frame_++;
2300 switch (num_will_begin_impl_frame_) {
2301 case 1:
2302 break;
2303 case 2:
2304 case 3:
2305 case 4:
2306 // Post a number of frames to increase the chance that, if there exist
2307 // bugs, an unexpected BeginMainFrame will be issued.
2308 PostSetNeedsCommitToMainThread();
2309 PostSetNeedsRedrawToMainThread();
2310 break;
2311 case 5:
2312 PostSetDeferCommitsToMainThread(false);
2313 break;
2314 default:
2315 // Sometimes |num_will_begin_impl_frame_| will be greater than 5 if the
2316 // main thread is slow to respond.
2317 break;
2321 void ScheduledActionSendBeginMainFrame() override {
2322 num_send_begin_main_frame_++;
2323 switch (num_send_begin_main_frame_) {
2324 case 1:
2325 PostSetDeferCommitsToMainThread(true);
2326 break;
2327 case 2:
2328 EndTest();
2329 break;
2330 default:
2331 NOTREACHED();
2332 break;
2336 void AfterTest() override {
2337 EXPECT_GE(num_will_begin_impl_frame_, 5);
2338 EXPECT_EQ(2, num_send_begin_main_frame_);
2341 private:
2342 int num_will_begin_impl_frame_;
2343 int num_send_begin_main_frame_;
2346 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2348 class LayerTreeHostTestCompositeImmediatelyStateTransitions
2349 : public LayerTreeHostTest {
2350 public:
2351 enum {
2352 kInvalid,
2353 kStartedTest,
2354 kStartedImplFrame,
2355 kStartedMainFrame,
2356 kStartedCommit,
2357 kCompletedCommit,
2358 kCompletedMainFrame,
2359 kCompletedImplFrame,
2362 LayerTreeHostTestCompositeImmediatelyStateTransitions()
2363 : current_state_(kInvalid), current_begin_frame_args_() {}
2365 void InitializeSettings(LayerTreeSettings* settings) override {
2366 settings->single_thread_proxy_scheduler = false;
2369 void BeginTest() override {
2370 current_state_ = kStartedTest;
2371 PostCompositeImmediatelyToMainThread();
2374 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
2375 const BeginFrameArgs& args) override {
2376 EXPECT_EQ(current_state_, kStartedTest);
2377 current_state_ = kStartedImplFrame;
2379 EXPECT_FALSE(current_begin_frame_args_.IsValid());
2380 EXPECT_TRUE(args.IsValid());
2381 current_begin_frame_args_ = args;
2383 void WillBeginMainFrame() override {
2384 EXPECT_EQ(current_state_, kStartedImplFrame);
2385 current_state_ = kStartedMainFrame;
2387 void BeginMainFrame(const BeginFrameArgs& args) override {
2388 EXPECT_EQ(current_state_, kStartedMainFrame);
2389 EXPECT_EQ(args.frame_time, current_begin_frame_args_.frame_time);
2391 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
2392 EXPECT_EQ(current_state_, kStartedMainFrame);
2393 current_state_ = kStartedCommit;
2395 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2396 EXPECT_EQ(current_state_, kStartedCommit);
2397 current_state_ = kCompletedCommit;
2399 void DidBeginMainFrame() override {
2400 EXPECT_EQ(current_state_, kCompletedCommit);
2401 current_state_ = kCompletedMainFrame;
2403 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
2404 EXPECT_EQ(current_state_, kCompletedMainFrame);
2405 current_state_ = kCompletedImplFrame;
2406 EndTest();
2408 void AfterTest() override { EXPECT_EQ(current_state_, kCompletedImplFrame); }
2410 private:
2411 int current_state_;
2412 BeginFrameArgs current_begin_frame_args_;
2415 SINGLE_THREAD_TEST_F(LayerTreeHostTestCompositeImmediatelyStateTransitions);
2417 class LayerTreeHostWithProxy : public LayerTreeHost {
2418 public:
2419 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2420 scoped_ptr<FakeProxy> proxy,
2421 LayerTreeHost::InitParams* params)
2422 : LayerTreeHost(params) {
2423 proxy->SetLayerTreeHost(this);
2424 client->SetLayerTreeHost(this);
2425 InitializeForTesting(proxy.Pass());
2429 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2430 // When partial updates are not allowed, max updates should be 0.
2432 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2434 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2435 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2436 proxy->SetMaxPartialTextureUpdates(5);
2438 LayerTreeSettings settings;
2439 settings.impl_side_painting = false;
2440 settings.max_partial_texture_updates = 10;
2442 LayerTreeHost::InitParams params;
2443 params.client = &client;
2444 params.settings = &settings;
2445 LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
2447 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2450 // When partial updates are allowed,
2451 // max updates should be limited by the proxy.
2453 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2455 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2456 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2457 proxy->SetMaxPartialTextureUpdates(5);
2459 LayerTreeSettings settings;
2460 settings.impl_side_painting = false;
2461 settings.max_partial_texture_updates = 10;
2463 LayerTreeHost::InitParams params;
2464 params.client = &client;
2465 params.settings = &settings;
2466 LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
2468 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2471 // When partial updates are allowed,
2472 // max updates should also be limited by the settings.
2474 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2476 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2477 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2478 proxy->SetMaxPartialTextureUpdates(20);
2480 LayerTreeSettings settings;
2481 settings.impl_side_painting = false;
2482 settings.max_partial_texture_updates = 10;
2484 LayerTreeHost::InitParams params;
2485 params.client = &client;
2486 params.settings = &settings;
2487 LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
2489 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2493 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2494 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2496 LayerTreeSettings settings;
2497 settings.max_partial_texture_updates = 4;
2498 settings.single_thread_proxy_scheduler = false;
2499 settings.impl_side_painting = false;
2501 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2502 new TestSharedBitmapManager());
2503 LayerTreeHost::InitParams params;
2504 params.client = &client;
2505 params.shared_bitmap_manager = shared_bitmap_manager.get();
2506 params.settings = &settings;
2507 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
2508 scoped_ptr<LayerTreeHost> host =
2509 LayerTreeHost::CreateSingleThreaded(&client, &params);
2510 client.SetLayerTreeHost(host.get());
2511 host->Composite(base::TimeTicks::Now());
2513 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2516 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2517 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2519 LayerTreeSettings settings;
2520 settings.max_partial_texture_updates = 4;
2521 settings.single_thread_proxy_scheduler = false;
2522 settings.impl_side_painting = false;
2524 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2525 new TestSharedBitmapManager());
2526 LayerTreeHost::InitParams params;
2527 params.client = &client;
2528 params.shared_bitmap_manager = shared_bitmap_manager.get();
2529 params.settings = &settings;
2530 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
2531 scoped_ptr<LayerTreeHost> host =
2532 LayerTreeHost::CreateSingleThreaded(&client, &params);
2533 client.SetLayerTreeHost(host.get());
2534 host->Composite(base::TimeTicks::Now());
2536 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2539 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2540 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2542 LayerTreeSettings settings;
2543 settings.max_partial_texture_updates = 4;
2544 settings.single_thread_proxy_scheduler = false;
2545 settings.impl_side_painting = false;
2547 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2548 new TestSharedBitmapManager());
2549 LayerTreeHost::InitParams params;
2550 params.client = &client;
2551 params.shared_bitmap_manager = shared_bitmap_manager.get();
2552 params.settings = &settings;
2553 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
2554 scoped_ptr<LayerTreeHost> host =
2555 LayerTreeHost::CreateSingleThreaded(&client, &params);
2556 client.SetLayerTreeHost(host.get());
2557 host->Composite(base::TimeTicks::Now());
2559 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2562 TEST(LayerTreeHostTest,
2563 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2564 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2566 LayerTreeSettings settings;
2567 settings.max_partial_texture_updates = 4;
2568 settings.single_thread_proxy_scheduler = false;
2569 settings.impl_side_painting = false;
2571 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2572 new TestSharedBitmapManager());
2573 LayerTreeHost::InitParams params;
2574 params.client = &client;
2575 params.shared_bitmap_manager = shared_bitmap_manager.get();
2576 params.settings = &settings;
2577 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
2578 scoped_ptr<LayerTreeHost> host =
2579 LayerTreeHost::CreateSingleThreaded(&client, &params);
2580 client.SetLayerTreeHost(host.get());
2581 host->Composite(base::TimeTicks::Now());
2583 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2586 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
2587 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2588 : public LayerTreeHostTest {
2589 public:
2590 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2591 : root_layer_(FakeContentLayer::Create(&client_)),
2592 child_layer1_(FakeContentLayer::Create(&client_)),
2593 child_layer2_(FakeContentLayer::Create(&client_)),
2594 num_commits_(0) {}
2596 void BeginTest() override {
2597 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2598 root_layer_->SetBounds(gfx::Size(100, 100));
2599 child_layer1_->SetBounds(gfx::Size(100, 100));
2600 child_layer2_->SetBounds(gfx::Size(100, 100));
2601 root_layer_->AddChild(child_layer1_);
2602 root_layer_->AddChild(child_layer2_);
2603 layer_tree_host()->SetRootLayer(root_layer_);
2604 PostSetNeedsCommitToMainThread();
2607 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2608 bool visible) override {
2609 if (visible) {
2610 // One backing should remain unevicted.
2611 EXPECT_EQ(100u * 100u * 4u * 1u,
2612 contents_texture_manager_->MemoryUseBytes());
2613 } else {
2614 EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes());
2617 // Make sure that contents textures are marked as having been
2618 // purged.
2619 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2620 // End the test in this state.
2621 EndTest();
2624 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2625 ++num_commits_;
2626 switch (num_commits_) {
2627 case 1:
2628 // All three backings should have memory.
2629 EXPECT_EQ(100u * 100u * 4u * 3u,
2630 contents_texture_manager_->MemoryUseBytes());
2632 // Set a new policy that will kick out 1 of the 3 resources.
2633 // Because a resource was evicted, a commit will be kicked off.
2634 host_impl->SetMemoryPolicy(
2635 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2636 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2637 1000));
2638 break;
2639 case 2:
2640 // Only two backings should have memory.
2641 EXPECT_EQ(100u * 100u * 4u * 2u,
2642 contents_texture_manager_->MemoryUseBytes());
2643 // Become backgrounded, which will cause 1 more resource to be
2644 // evicted.
2645 PostSetVisibleToMainThread(false);
2646 break;
2647 default:
2648 // No further commits should happen because this is not visible
2649 // anymore.
2650 NOTREACHED();
2651 break;
2655 void AfterTest() override {}
2657 private:
2658 FakeContentLayerClient client_;
2659 scoped_refptr<FakeContentLayer> root_layer_;
2660 scoped_refptr<FakeContentLayer> child_layer1_;
2661 scoped_refptr<FakeContentLayer> child_layer2_;
2662 int num_commits_;
2665 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2666 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2668 class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
2669 public:
2670 void SetupTree() override {
2671 num_tiles_rastered_ = 0;
2673 scoped_refptr<Layer> root_layer = PictureLayer::Create(&client_);
2674 client_.set_fill_with_nonsolid_color(true);
2675 root_layer->SetIsDrawable(true);
2676 root_layer->SetBounds(gfx::Size(10, 10));
2677 root_layer->SetContentsOpaque(true);
2679 layer_tree_host()->SetRootLayer(root_layer);
2681 // The expectations are based on the assumption that the default
2682 // LCD settings are:
2683 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2685 LayerTreeHostTest::SetupTree();
2688 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2690 void DidCommitAndDrawFrame() override {
2691 switch (layer_tree_host()->source_frame_number()) {
2692 case 1:
2693 PostSetNeedsCommitToMainThread();
2694 break;
2695 case 2:
2696 // Change layer opacity that should trigger lcd change.
2697 layer_tree_host()->root_layer()->SetOpacity(.5f);
2698 break;
2699 case 3:
2700 // Change layer opacity that should not trigger lcd change.
2701 layer_tree_host()->root_layer()->SetOpacity(1.f);
2702 break;
2703 case 4:
2704 EndTest();
2705 break;
2709 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
2710 const Tile* tile) override {
2711 ++num_tiles_rastered_;
2714 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2715 PictureLayerImpl* root_layer =
2716 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer());
2717 bool can_use_lcd_text =
2718 host_impl->active_tree()->root_layer()->can_use_lcd_text();
2719 switch (host_impl->active_tree()->source_frame_number()) {
2720 case 0:
2721 // The first draw.
2722 EXPECT_EQ(1, num_tiles_rastered_);
2723 EXPECT_TRUE(can_use_lcd_text);
2724 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2725 break;
2726 case 1:
2727 // Nothing changed on the layer.
2728 EXPECT_EQ(1, num_tiles_rastered_);
2729 EXPECT_TRUE(can_use_lcd_text);
2730 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2731 break;
2732 case 2:
2733 // LCD text was disabled; it should be re-rastered with LCD text off.
2734 EXPECT_EQ(2, num_tiles_rastered_);
2735 EXPECT_FALSE(can_use_lcd_text);
2736 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2737 break;
2738 case 3:
2739 // LCD text was enabled, but it's sticky and stays off.
2740 EXPECT_EQ(2, num_tiles_rastered_);
2741 EXPECT_TRUE(can_use_lcd_text);
2742 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2743 break;
2747 void AfterTest() override {}
2749 private:
2750 FakeContentLayerClient client_;
2751 int num_tiles_rastered_;
2754 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
2756 // Verify that the BeginFrame notification is used to initiate rendering.
2757 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2758 public:
2759 void InitializeSettings(LayerTreeSettings* settings) override {
2760 settings->use_external_begin_frame_source = true;
2763 void BeginTest() override {
2764 // This will trigger a SetNeedsBeginFrame which will trigger a
2765 // BeginFrame.
2766 PostSetNeedsCommitToMainThread();
2769 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2770 LayerTreeHostImpl::FrameData* frame,
2771 DrawResult draw_result) override {
2772 EndTest();
2773 return DRAW_SUCCESS;
2776 void AfterTest() override {}
2778 private:
2779 base::TimeTicks frame_time_;
2782 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2784 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2785 : public LayerTreeHostTest {
2786 public:
2787 void InitializeSettings(LayerTreeSettings* settings) override {
2788 settings->use_external_begin_frame_source = true;
2789 settings->using_synchronous_renderer_compositor = true;
2792 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2794 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2795 // The BeginFrame notification is turned off now but will get enabled
2796 // once we return. End test while it's enabled.
2797 ImplThreadTaskRunner()->PostTask(
2798 FROM_HERE,
2799 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2800 base::Unretained(this)));
2803 void AfterTest() override {}
2806 MULTI_THREAD_TEST_F(
2807 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2809 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2810 protected:
2811 LayerTreeHostTestAbortedCommitDoesntStall()
2812 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2814 void InitializeSettings(LayerTreeSettings* settings) override {
2815 settings->use_external_begin_frame_source = true;
2818 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2820 void DidCommit() override {
2821 commit_count_++;
2822 if (commit_count_ == 4) {
2823 // After two aborted commits, request a real commit now to make sure a
2824 // real commit following an aborted commit will still complete and
2825 // end the test even when the Impl thread is idle.
2826 layer_tree_host()->SetNeedsCommit();
2830 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2831 CommitEarlyOutReason reason) override {
2832 commit_abort_count_++;
2833 // Initiate another abortable commit.
2834 host_impl->SetNeedsCommit();
2837 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2838 commit_complete_count_++;
2839 if (commit_complete_count_ == 1) {
2840 // Initiate an abortable commit after the first commit.
2841 host_impl->SetNeedsCommit();
2842 } else {
2843 EndTest();
2847 void AfterTest() override {
2848 EXPECT_EQ(commit_count_, 5);
2849 EXPECT_EQ(commit_abort_count_, 3);
2850 EXPECT_EQ(commit_complete_count_, 2);
2853 int commit_count_;
2854 int commit_abort_count_;
2855 int commit_complete_count_;
2858 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2859 : public LayerTreeHostTestAbortedCommitDoesntStall {
2860 protected:
2861 void InitializeSettings(LayerTreeSettings* settings) override {
2862 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2863 settings->using_synchronous_renderer_compositor = true;
2866 void ScheduledActionInvalidateOutputSurface() override {
2867 ImplThreadTaskRunner()->PostTask(
2868 FROM_HERE,
2869 base::Bind(
2870 &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor::
2871 CallOnDraw,
2872 base::Unretained(this)));
2875 void CallOnDraw() {
2876 // Synchronous compositor does not draw unless told to do so by the output
2877 // surface.
2878 output_surface()->client()->OnDraw();
2882 MULTI_THREAD_TEST_F(
2883 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2885 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2886 : public LayerTreeHostTestAbortedCommitDoesntStall {
2887 void InitializeSettings(LayerTreeSettings* settings) override {
2888 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2889 settings->throttle_frame_production = false;
2893 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2895 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2896 : public LayerTreeHostTest {
2897 protected:
2898 void InitializeSettings(LayerTreeSettings* settings) override {
2899 settings->impl_side_painting = true;
2902 void SetupTree() override {
2903 LayerTreeHostTest::SetupTree();
2905 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2906 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2907 layer->SetBounds(gfx::Size(10, 10));
2908 layer_tree_host()->root_layer()->AddChild(layer);
2911 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2913 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2914 EndTest();
2917 void AfterTest() override {}
2919 FakeContentLayerClient client_;
2922 MULTI_THREAD_TEST_F(
2923 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2925 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2926 : public LayerTreeHostTest {
2927 public:
2928 class SetBoundsClient : public ContentLayerClient {
2929 public:
2930 SetBoundsClient() : layer_(0) {}
2932 void set_layer(Layer* layer) { layer_ = layer; }
2934 void PaintContents(SkCanvas* canvas,
2935 const gfx::Rect& clip,
2936 PaintingControlSetting picture_control) override {
2937 layer_->SetBounds(gfx::Size(2, 2));
2940 void PaintContentsToDisplayList(
2941 DisplayItemList* display_list,
2942 const gfx::Rect& clip,
2943 PaintingControlSetting picture_control) override {
2944 NOTIMPLEMENTED();
2947 bool FillsBoundsCompletely() const override { return false; }
2949 private:
2950 Layer* layer_;
2953 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2955 void SetupTree() override {
2956 if (layer_tree_host()->settings().impl_side_painting) {
2957 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_);
2958 layer_tree_host()->SetRootLayer(root_layer);
2959 } else {
2960 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2961 layer_tree_host()->SetRootLayer(root_layer);
2963 Layer* root_layer = layer_tree_host()->root_layer();
2964 root_layer->SetIsDrawable(true);
2965 root_layer->SetBounds(gfx::Size(1, 1));
2967 client_.set_layer(root_layer);
2969 LayerTreeHostTest::SetupTree();
2972 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2973 void AfterTest() override {}
2975 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2976 num_commits_++;
2977 if (num_commits_ == 1) {
2978 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2979 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds());
2980 } else {
2981 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2982 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds());
2983 EndTest();
2987 private:
2988 SetBoundsClient client_;
2989 int num_commits_;
2992 SINGLE_AND_MULTI_THREAD_TEST_F(
2993 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2995 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2996 public:
2997 MockIOSurfaceWebGraphicsContext3D() {
2998 test_capabilities_.gpu.iosurface = true;
2999 test_capabilities_.gpu.texture_rectangle = true;
3002 GLuint createTexture() override { return 1; }
3003 MOCK_METHOD1(activeTexture, void(GLenum texture));
3004 MOCK_METHOD2(bindTexture, void(GLenum target,
3005 GLuint texture_id));
3006 MOCK_METHOD3(texParameteri, void(GLenum target,
3007 GLenum pname,
3008 GLint param));
3009 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
3010 GLint width,
3011 GLint height,
3012 GLuint ioSurfaceId,
3013 GLuint plane));
3014 MOCK_METHOD4(drawElements, void(GLenum mode,
3015 GLsizei count,
3016 GLenum type,
3017 GLintptr offset));
3018 MOCK_METHOD1(deleteTexture, void(GLenum texture));
3019 MOCK_METHOD3(produceTextureDirectCHROMIUM,
3020 void(GLuint texture, GLenum target, const GLbyte* mailbox));
3023 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
3024 protected:
3025 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3026 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
3027 new MockIOSurfaceWebGraphicsContext3D);
3028 mock_context_ = mock_context_owned.get();
3030 if (delegating_renderer())
3031 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
3032 else
3033 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
3036 void SetupTree() override {
3037 LayerTreeHostTest::SetupTree();
3039 layer_tree_host()->root_layer()->SetIsDrawable(false);
3041 io_surface_id_ = 9;
3042 io_surface_size_ = gfx::Size(6, 7);
3044 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
3045 io_surface_layer->SetBounds(gfx::Size(10, 10));
3046 io_surface_layer->SetIsDrawable(true);
3047 io_surface_layer->SetContentsOpaque(true);
3048 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
3049 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
3052 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3054 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3055 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
3056 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
3058 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
3059 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
3060 .Times(AtLeast(1));
3061 EXPECT_CALL(*mock_context_,
3062 texParameteri(
3063 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
3064 .Times(1);
3065 EXPECT_CALL(*mock_context_,
3066 texParameteri(
3067 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
3068 .Times(1);
3069 EXPECT_CALL(*mock_context_,
3070 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
3071 GL_TEXTURE_POOL_CHROMIUM,
3072 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
3073 EXPECT_CALL(*mock_context_,
3074 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
3075 GL_TEXTURE_WRAP_S,
3076 GL_CLAMP_TO_EDGE)).Times(1);
3077 EXPECT_CALL(*mock_context_,
3078 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
3079 GL_TEXTURE_WRAP_T,
3080 GL_CLAMP_TO_EDGE)).Times(1);
3082 EXPECT_CALL(*mock_context_,
3083 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
3084 io_surface_size_.width(),
3085 io_surface_size_.height(),
3086 io_surface_id_,
3087 0)).Times(1);
3089 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
3092 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3093 LayerTreeHostImpl::FrameData* frame,
3094 DrawResult draw_result) override {
3095 Mock::VerifyAndClearExpectations(&mock_context_);
3096 ResourceProvider* resource_provider = host_impl->resource_provider();
3097 EXPECT_EQ(1u, resource_provider->num_resources());
3098 CHECK_EQ(1u, frame->render_passes.size());
3099 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
3100 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
3101 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
3102 const IOSurfaceDrawQuad* io_surface_draw_quad =
3103 IOSurfaceDrawQuad::MaterialCast(quad);
3104 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
3105 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
3106 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
3107 resource_provider->TargetForTesting(
3108 io_surface_draw_quad->io_surface_resource_id));
3110 if (delegating_renderer()) {
3111 // The io surface layer's resource should be sent to the parent.
3112 EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM(
3113 _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
3114 } else {
3115 // The io surface layer's texture is drawn.
3116 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
3117 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
3118 .Times(AtLeast(1));
3121 return draw_result;
3124 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
3125 Mock::VerifyAndClearExpectations(&mock_context_);
3127 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
3128 EndTest();
3131 void AfterTest() override {}
3133 int io_surface_id_;
3134 MockIOSurfaceWebGraphicsContext3D* mock_context_;
3135 gfx::Size io_surface_size_;
3138 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
3140 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
3141 public:
3142 void BeginTest() override {
3143 frame_ = 0;
3144 PostSetNeedsCommitToMainThread();
3147 // Round 1: commit + draw
3148 // Round 2: commit only (no draw/swap)
3149 // Round 3: draw only (no commit)
3151 void DidCommit() override {
3152 int commit = layer_tree_host()->source_frame_number();
3153 switch (commit) {
3154 case 2:
3155 // Round 2 done.
3156 EXPECT_EQ(1, frame_);
3157 layer_tree_host()->SetNeedsRedraw();
3158 break;
3162 void DidCompleteSwapBuffers() override {
3163 int commit = layer_tree_host()->source_frame_number();
3164 ++frame_;
3165 switch (frame_) {
3166 case 1:
3167 // Round 1 done.
3168 EXPECT_EQ(1, commit);
3169 layer_tree_host()->SetNeedsCommit();
3170 break;
3171 case 2:
3172 // Round 3 done.
3173 EXPECT_EQ(2, commit);
3174 EndTest();
3175 break;
3179 void AfterTest() override {}
3181 protected:
3182 int frame_;
3185 // Flaky on all platforms: http://crbug.com/327498
3186 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
3187 RunTest(true, true, true);
3190 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
3191 RunTest(true, false, true);
3194 class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest {
3195 public:
3196 void SetupTree() override {
3197 root_layer_ = FakePictureLayer::Create(&client_);
3198 root_layer_->SetIsDrawable(true);
3199 root_layer_->SetBounds(gfx::Size(50, 50));
3201 parent_layer_ = FakePictureLayer::Create(&client_);
3202 parent_layer_->SetIsDrawable(true);
3203 parent_layer_->SetBounds(gfx::Size(50, 50));
3204 parent_layer_->SetForceRenderSurface(true);
3206 child_layer_ = FakePictureLayer::Create(&client_);
3207 child_layer_->SetIsDrawable(true);
3208 child_layer_->SetBounds(gfx::Size(50, 50));
3210 root_layer_->AddChild(parent_layer_);
3211 parent_layer_->AddChild(child_layer_);
3212 layer_tree_host()->SetRootLayer(root_layer_);
3214 LayerTreeHostTest::SetupTree();
3217 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3218 if (delegating_renderer()) {
3219 return FakeOutputSurface::CreateDelegatingSoftware(
3220 make_scoped_ptr(new SoftwareOutputDevice));
3221 } else {
3222 return FakeOutputSurface::CreateSoftware(
3223 make_scoped_ptr(new SoftwareOutputDevice));
3227 void BeginTest() override {
3228 PostSetNeedsCommitToMainThread();
3229 swap_count_ = 0;
3232 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3233 LayerTreeHostImpl::FrameData* frame_data,
3234 DrawResult draw_result) override {
3235 if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
3236 EXPECT_EQ(1u, frame_data->render_passes.size());
3237 // Has at least 3 quads for each layer.
3238 RenderPass* render_pass = frame_data->render_passes[0];
3239 EXPECT_GE(render_pass->quad_list.size(), 3u);
3240 } else {
3241 EXPECT_EQ(2u, frame_data->render_passes.size());
3243 // At least root layer quad in root render pass.
3244 EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u);
3245 // At least parent and child layer quads in parent render pass.
3246 EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u);
3248 return draw_result;
3251 void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3252 swap_count_++;
3253 switch (swap_count_) {
3254 case 1: {
3255 gfx::Transform identity;
3256 gfx::Rect empty_rect;
3257 bool resourceless_software_draw = true;
3258 host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect,
3259 empty_rect, identity,
3260 resourceless_software_draw);
3261 host_impl->SetFullRootLayerDamage();
3262 host_impl->SetNeedsRedraw();
3263 break;
3265 case 2:
3266 EndTest();
3267 break;
3268 default:
3269 NOTREACHED();
3273 void AfterTest() override {}
3275 private:
3276 FakeContentLayerClient client_;
3277 scoped_refptr<Layer> root_layer_;
3278 scoped_refptr<Layer> parent_layer_;
3279 scoped_refptr<Layer> child_layer_;
3280 int swap_count_;
3283 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw);
3285 // Test for UI Resource management.
3286 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3287 public:
3288 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
3290 void InitializeSettings(LayerTreeSettings* settings) override {
3291 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
3294 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3296 void DidCommit() override {
3297 int frame = layer_tree_host()->source_frame_number();
3298 switch (frame) {
3299 case 1:
3300 CreateResource();
3301 CreateResource();
3302 PostSetNeedsCommitToMainThread();
3303 break;
3304 case 2:
3305 // Usually ScopedUIResource are deleted from the manager in their
3306 // destructor. Here we just want to test that a direct call to
3307 // DeleteUIResource works.
3308 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3309 PostSetNeedsCommitToMainThread();
3310 break;
3311 case 3:
3312 // DeleteUIResource can be called with an invalid id.
3313 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3314 PostSetNeedsCommitToMainThread();
3315 break;
3316 case 4:
3317 CreateResource();
3318 CreateResource();
3319 PostSetNeedsCommitToMainThread();
3320 break;
3321 case 5:
3322 ClearResources();
3323 EndTest();
3324 break;
3328 void PerformTest(LayerTreeHostImpl* impl) {
3329 TestWebGraphicsContext3D* context = TestContext();
3331 int frame = impl->active_tree()->source_frame_number();
3332 switch (frame) {
3333 case 0:
3334 ASSERT_EQ(0u, context->NumTextures());
3335 break;
3336 case 1:
3337 // Created two textures.
3338 ASSERT_EQ(2u, context->NumTextures());
3339 break;
3340 case 2:
3341 // One texture left after one deletion.
3342 ASSERT_EQ(1u, context->NumTextures());
3343 break;
3344 case 3:
3345 // Resource manager state should not change when delete is called on an
3346 // invalid id.
3347 ASSERT_EQ(1u, context->NumTextures());
3348 break;
3349 case 4:
3350 // Creation after deletion: two more creates should total up to
3351 // three textures.
3352 ASSERT_EQ(3u, context->NumTextures());
3353 break;
3357 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3358 if (!impl->settings().impl_side_painting)
3359 PerformTest(impl);
3362 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3363 if (impl->settings().impl_side_painting)
3364 PerformTest(impl);
3367 void AfterTest() override {}
3369 private:
3370 // Must clear all resources before exiting.
3371 void ClearResources() {
3372 for (int i = 0; i < num_ui_resources_; i++)
3373 ui_resources_[i] = nullptr;
3376 void CreateResource() {
3377 ui_resources_[num_ui_resources_++] =
3378 FakeScopedUIResource::Create(layer_tree_host());
3381 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3382 int num_ui_resources_;
3385 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3387 class PushPropertiesCountingLayerImpl : public LayerImpl {
3388 public:
3389 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
3390 LayerTreeImpl* tree_impl, int id) {
3391 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
3394 ~PushPropertiesCountingLayerImpl() override {}
3396 void PushPropertiesTo(LayerImpl* layer) override {
3397 LayerImpl::PushPropertiesTo(layer);
3398 push_properties_count_++;
3399 // Push state to the active tree because we can only access it from there.
3400 static_cast<PushPropertiesCountingLayerImpl*>(
3401 layer)->push_properties_count_ = push_properties_count_;
3404 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3405 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3408 size_t push_properties_count() const { return push_properties_count_; }
3409 void reset_push_properties_count() { push_properties_count_ = 0; }
3411 private:
3412 size_t push_properties_count_;
3414 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
3415 : LayerImpl(tree_impl, id),
3416 push_properties_count_(0) {
3417 SetBounds(gfx::Size(1, 1));
3421 class PushPropertiesCountingLayer : public Layer {
3422 public:
3423 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3424 return new PushPropertiesCountingLayer();
3427 void PushPropertiesTo(LayerImpl* layer) override {
3428 Layer::PushPropertiesTo(layer);
3429 push_properties_count_++;
3430 if (persist_needs_push_properties_)
3431 needs_push_properties_ = true;
3434 // Something to make this layer push properties, but no other layer.
3435 void MakePushProperties() { SetContentsOpaque(!contents_opaque()); }
3437 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3438 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3441 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
3443 size_t push_properties_count() const { return push_properties_count_; }
3444 void reset_push_properties_count() { push_properties_count_ = 0; }
3446 void set_persist_needs_push_properties(bool persist) {
3447 persist_needs_push_properties_ = persist;
3450 private:
3451 PushPropertiesCountingLayer()
3452 : push_properties_count_(0), persist_needs_push_properties_(false) {
3453 SetBounds(gfx::Size(1, 1));
3455 ~PushPropertiesCountingLayer() override {}
3457 size_t push_properties_count_;
3458 bool persist_needs_push_properties_;
3461 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3462 protected:
3463 void BeginTest() override {
3464 num_commits_ = 0;
3465 expected_push_properties_root_ = 0;
3466 expected_push_properties_child_ = 0;
3467 expected_push_properties_grandchild_ = 0;
3468 expected_push_properties_child2_ = 0;
3469 expected_push_properties_other_root_ = 0;
3470 expected_push_properties_leaf_layer_ = 0;
3471 PostSetNeedsCommitToMainThread();
3474 void SetupTree() override {
3475 root_ = PushPropertiesCountingLayer::Create();
3476 root_->CreateRenderSurface();
3477 child_ = PushPropertiesCountingLayer::Create();
3478 child2_ = PushPropertiesCountingLayer::Create();
3479 grandchild_ = PushPropertiesCountingLayer::Create();
3480 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3481 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3483 root_->AddChild(child_);
3484 root_->AddChild(child2_);
3485 child_->AddChild(grandchild_);
3486 child2_->AddChild(leaf_always_pushing_layer_);
3488 other_root_ = PushPropertiesCountingLayer::Create();
3489 other_root_->CreateRenderSurface();
3491 // Don't set the root layer here.
3492 LayerTreeHostTest::SetupTree();
3495 void DidCommitAndDrawFrame() override {
3496 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count())
3497 << "num_commits: " << num_commits_;
3498 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count())
3499 << "num_commits: " << num_commits_;
3500 EXPECT_EQ(expected_push_properties_grandchild_,
3501 grandchild_->push_properties_count())
3502 << "num_commits: " << num_commits_;
3503 EXPECT_EQ(expected_push_properties_child2_,
3504 child2_->push_properties_count())
3505 << "num_commits: " << num_commits_;
3506 EXPECT_EQ(expected_push_properties_other_root_,
3507 other_root_->push_properties_count())
3508 << "num_commits: " << num_commits_;
3509 EXPECT_EQ(expected_push_properties_leaf_layer_,
3510 leaf_always_pushing_layer_->push_properties_count())
3511 << "num_commits: " << num_commits_;
3513 ++num_commits_;
3515 // The scrollbar layer always needs to be pushed.
3516 if (root_->layer_tree_host()) {
3517 EXPECT_TRUE(root_->descendant_needs_push_properties());
3518 EXPECT_FALSE(root_->needs_push_properties());
3520 if (child2_->layer_tree_host()) {
3521 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3522 EXPECT_FALSE(child2_->needs_push_properties());
3524 if (leaf_always_pushing_layer_->layer_tree_host()) {
3525 EXPECT_FALSE(
3526 leaf_always_pushing_layer_->descendant_needs_push_properties());
3527 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3530 // child_ and grandchild_ don't persist their need to push properties.
3531 if (child_->layer_tree_host()) {
3532 EXPECT_FALSE(child_->descendant_needs_push_properties());
3533 EXPECT_FALSE(child_->needs_push_properties());
3535 if (grandchild_->layer_tree_host()) {
3536 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3537 EXPECT_FALSE(grandchild_->needs_push_properties());
3540 if (other_root_->layer_tree_host()) {
3541 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3542 EXPECT_FALSE(other_root_->needs_push_properties());
3545 switch (num_commits_) {
3546 case 1:
3547 layer_tree_host()->SetRootLayer(root_);
3548 // Layers added to the tree get committed.
3549 ++expected_push_properties_root_;
3550 ++expected_push_properties_child_;
3551 ++expected_push_properties_grandchild_;
3552 ++expected_push_properties_child2_;
3553 break;
3554 case 2:
3555 layer_tree_host()->SetNeedsCommit();
3556 // No layers need commit.
3557 break;
3558 case 3:
3559 layer_tree_host()->SetRootLayer(other_root_);
3560 // Layers added to the tree get committed.
3561 ++expected_push_properties_other_root_;
3562 break;
3563 case 4:
3564 layer_tree_host()->SetRootLayer(root_);
3565 // Layers added to the tree get committed.
3566 ++expected_push_properties_root_;
3567 ++expected_push_properties_child_;
3568 ++expected_push_properties_grandchild_;
3569 ++expected_push_properties_child2_;
3570 break;
3571 case 5:
3572 layer_tree_host()->SetNeedsCommit();
3573 // No layers need commit.
3574 break;
3575 case 6:
3576 child_->RemoveFromParent();
3577 // No layers need commit.
3578 break;
3579 case 7:
3580 root_->AddChild(child_);
3581 // Layers added to the tree get committed.
3582 ++expected_push_properties_child_;
3583 ++expected_push_properties_grandchild_;
3584 break;
3585 case 8:
3586 grandchild_->RemoveFromParent();
3587 // No layers need commit.
3588 break;
3589 case 9:
3590 child_->AddChild(grandchild_);
3591 // Layers added to the tree get committed.
3592 ++expected_push_properties_grandchild_;
3593 break;
3594 case 10:
3595 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3596 // No layers need commit.
3597 break;
3598 case 11:
3599 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3600 // No layers need commit.
3601 break;
3602 case 12:
3603 child_->MakePushProperties();
3604 // The modified layer needs commit
3605 ++expected_push_properties_child_;
3606 break;
3607 case 13:
3608 child2_->MakePushProperties();
3609 // The modified layer needs commit
3610 ++expected_push_properties_child2_;
3611 break;
3612 case 14:
3613 child_->RemoveFromParent();
3614 root_->AddChild(child_);
3615 // Layers added to the tree get committed.
3616 ++expected_push_properties_child_;
3617 ++expected_push_properties_grandchild_;
3618 break;
3619 case 15:
3620 grandchild_->MakePushProperties();
3621 // The modified layer needs commit
3622 ++expected_push_properties_grandchild_;
3623 break;
3624 case 16:
3625 // SetNeedsDisplay does not always set needs commit (so call it
3626 // explicitly), but is a property change.
3627 child_->SetNeedsDisplay();
3628 ++expected_push_properties_child_;
3629 layer_tree_host()->SetNeedsCommit();
3630 break;
3631 case 17:
3632 EndTest();
3633 break;
3636 // The leaf layer always pushes.
3637 if (leaf_always_pushing_layer_->layer_tree_host())
3638 ++expected_push_properties_leaf_layer_;
3641 void AfterTest() override {}
3643 int num_commits_;
3644 FakeContentLayerClient client_;
3645 scoped_refptr<PushPropertiesCountingLayer> root_;
3646 scoped_refptr<PushPropertiesCountingLayer> child_;
3647 scoped_refptr<PushPropertiesCountingLayer> child2_;
3648 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3649 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3650 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3651 size_t expected_push_properties_root_;
3652 size_t expected_push_properties_child_;
3653 size_t expected_push_properties_child2_;
3654 size_t expected_push_properties_grandchild_;
3655 size_t expected_push_properties_other_root_;
3656 size_t expected_push_properties_leaf_layer_;
3659 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3661 class LayerTreeHostTestImplLayersPushProperties
3662 : public LayerTreeHostTestLayersPushProperties {
3663 protected:
3664 void BeginTest() override {
3665 expected_push_properties_root_impl_ = 0;
3666 expected_push_properties_child_impl_ = 0;
3667 expected_push_properties_grandchild_impl_ = 0;
3668 expected_push_properties_child2_impl_ = 0;
3669 expected_push_properties_grandchild2_impl_ = 0;
3670 LayerTreeHostTestLayersPushProperties::BeginTest();
3673 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3674 // These commits are in response to the changes made in
3675 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3676 switch (num_commits_) {
3677 case 0:
3678 // Tree hasn't been setup yet don't bother to check anything.
3679 return;
3680 case 1:
3681 // Root gets set up, Everyone is initialized.
3682 ++expected_push_properties_root_impl_;
3683 ++expected_push_properties_child_impl_;
3684 ++expected_push_properties_grandchild_impl_;
3685 ++expected_push_properties_child2_impl_;
3686 ++expected_push_properties_grandchild2_impl_;
3687 break;
3688 case 2:
3689 // Tree doesn't change but the one leaf that always pushes is pushed.
3690 ++expected_push_properties_grandchild2_impl_;
3691 break;
3692 case 3:
3693 // Root is swapped here.
3694 // Clear the expected push properties the tree will be rebuilt.
3695 expected_push_properties_root_impl_ = 0;
3696 expected_push_properties_child_impl_ = 0;
3697 expected_push_properties_grandchild_impl_ = 0;
3698 expected_push_properties_child2_impl_ = 0;
3699 expected_push_properties_grandchild2_impl_ = 0;
3701 // Make sure the new root is pushed.
3702 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3703 host_impl->RootLayer())->push_properties_count());
3704 return;
3705 case 4:
3706 // Root is swapped back all of the layers in the tree get pushed.
3707 ++expected_push_properties_root_impl_;
3708 ++expected_push_properties_child_impl_;
3709 ++expected_push_properties_grandchild_impl_;
3710 ++expected_push_properties_child2_impl_;
3711 ++expected_push_properties_grandchild2_impl_;
3712 break;
3713 case 5:
3714 // Tree doesn't change but the one leaf that always pushes is pushed.
3715 ++expected_push_properties_grandchild2_impl_;
3716 break;
3717 case 6:
3718 // First child is removed. Structure of the tree changes here so swap
3719 // some of the values. child_impl becomes child2_impl.
3720 expected_push_properties_child_impl_ =
3721 expected_push_properties_child2_impl_;
3722 expected_push_properties_child2_impl_ = 0;
3723 // grandchild_impl becomes grandchild2_impl.
3724 expected_push_properties_grandchild_impl_ =
3725 expected_push_properties_grandchild2_impl_;
3726 expected_push_properties_grandchild2_impl_ = 0;
3728 // grandchild_impl is now the leaf that always pushes. It is pushed.
3729 ++expected_push_properties_grandchild_impl_;
3730 break;
3731 case 7:
3732 // The leaf that always pushes is pushed.
3733 ++expected_push_properties_grandchild_impl_;
3735 // Child is added back. New layers are initialized.
3736 ++expected_push_properties_grandchild2_impl_;
3737 ++expected_push_properties_child2_impl_;
3738 break;
3739 case 8:
3740 // Leaf is removed.
3741 expected_push_properties_grandchild2_impl_ = 0;
3743 // Always pushing.
3744 ++expected_push_properties_grandchild_impl_;
3745 break;
3746 case 9:
3747 // Leaf is added back
3748 ++expected_push_properties_grandchild2_impl_;
3750 // The leaf that always pushes is pushed.
3751 ++expected_push_properties_grandchild_impl_;
3752 break;
3753 case 10:
3754 // The leaf that always pushes is pushed.
3755 ++expected_push_properties_grandchild_impl_;
3756 break;
3757 case 11:
3758 // The leaf that always pushes is pushed.
3759 ++expected_push_properties_grandchild_impl_;
3760 break;
3761 case 12:
3762 // The leaf that always pushes is pushed.
3763 ++expected_push_properties_grandchild_impl_;
3765 // This child position was changed.
3766 ++expected_push_properties_child2_impl_;
3767 break;
3768 case 13:
3769 // The position of this child was changed.
3770 ++expected_push_properties_child_impl_;
3772 // The leaf that always pushes is pushed.
3773 ++expected_push_properties_grandchild_impl_;
3774 break;
3775 case 14:
3776 // Second child is removed from tree. Don't discard counts because
3777 // they are added back before commit.
3779 // The leaf that always pushes is pushed.
3780 ++expected_push_properties_grandchild_impl_;
3782 // Second child added back.
3783 ++expected_push_properties_child2_impl_;
3784 ++expected_push_properties_grandchild2_impl_;
3786 break;
3787 case 15:
3788 // The position of this child was changed.
3789 ++expected_push_properties_grandchild2_impl_;
3791 // The leaf that always pushes is pushed.
3792 ++expected_push_properties_grandchild_impl_;
3793 break;
3794 case 16:
3795 // Second child is invalidated with SetNeedsDisplay
3796 ++expected_push_properties_child2_impl_;
3798 // The leaf that always pushed is pushed.
3799 ++expected_push_properties_grandchild_impl_;
3800 break;
3803 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3804 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3805 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3806 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3807 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3809 // Pull the layers that we need from the tree assuming the same structure
3810 // as LayerTreeHostTestLayersPushProperties
3811 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3812 host_impl->RootLayer());
3814 if (root_impl_ && root_impl_->children().size() > 0) {
3815 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3816 root_impl_->children()[0]);
3818 if (child_impl_ && child_impl_->children().size() > 0)
3819 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3820 child_impl_->children()[0]);
3823 if (root_impl_ && root_impl_->children().size() > 1) {
3824 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3825 root_impl_->children()[1]);
3827 if (child2_impl_ && child2_impl_->children().size() > 0)
3828 leaf_always_pushing_layer_impl_ =
3829 static_cast<PushPropertiesCountingLayerImpl*>(
3830 child2_impl_->children()[0]);
3833 if (root_impl_)
3834 EXPECT_EQ(expected_push_properties_root_impl_,
3835 root_impl_->push_properties_count());
3836 if (child_impl_)
3837 EXPECT_EQ(expected_push_properties_child_impl_,
3838 child_impl_->push_properties_count());
3839 if (grandchild_impl_)
3840 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3841 grandchild_impl_->push_properties_count());
3842 if (child2_impl_)
3843 EXPECT_EQ(expected_push_properties_child2_impl_,
3844 child2_impl_->push_properties_count());
3845 if (leaf_always_pushing_layer_impl_)
3846 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3847 leaf_always_pushing_layer_impl_->push_properties_count());
3850 size_t expected_push_properties_root_impl_;
3851 size_t expected_push_properties_child_impl_;
3852 size_t expected_push_properties_child2_impl_;
3853 size_t expected_push_properties_grandchild_impl_;
3854 size_t expected_push_properties_grandchild2_impl_;
3857 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3858 RunTestWithImplSidePainting();
3861 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3862 : public LayerTreeHostTest {
3863 protected:
3864 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3866 void SetupTree() override {
3867 root_ = Layer::Create();
3868 root_->CreateRenderSurface();
3869 root_->SetBounds(gfx::Size(1, 1));
3871 bool paint_scrollbar = true;
3872 bool has_thumb = false;
3873 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3874 paint_scrollbar, has_thumb, root_->id());
3876 root_->AddChild(scrollbar_layer_);
3878 layer_tree_host()->SetRootLayer(root_);
3879 LayerTreeHostTest::SetupTree();
3882 void DidCommitAndDrawFrame() override {
3883 switch (layer_tree_host()->source_frame_number()) {
3884 case 0:
3885 break;
3886 case 1: {
3887 // During update, the ignore_set_needs_commit_ bit is set to true to
3888 // avoid causing a second commit to be scheduled. If a property change
3889 // is made during this, however, it needs to be pushed in the upcoming
3890 // commit.
3891 scoped_ptr<base::AutoReset<bool>> ignore =
3892 scrollbar_layer_->IgnoreSetNeedsCommit();
3894 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3896 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3897 EXPECT_TRUE(root_->descendant_needs_push_properties());
3898 layer_tree_host()->SetNeedsCommit();
3900 scrollbar_layer_->reset_push_properties_count();
3901 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3902 break;
3904 case 2:
3905 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3906 EndTest();
3907 break;
3911 void AfterTest() override {}
3913 scoped_refptr<Layer> root_;
3914 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3917 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3919 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3920 protected:
3921 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3923 void SetupTree() override {
3924 root_ = PushPropertiesCountingLayer::Create();
3925 root_->CreateRenderSurface();
3926 child_ = PushPropertiesCountingLayer::Create();
3927 root_->AddChild(child_);
3929 layer_tree_host()->SetRootLayer(root_);
3930 LayerTreeHostTest::SetupTree();
3933 void DidCommitAndDrawFrame() override {
3934 switch (layer_tree_host()->source_frame_number()) {
3935 case 0:
3936 break;
3937 case 1: {
3938 // During update, the ignore_set_needs_commit_ bit is set to true to
3939 // avoid causing a second commit to be scheduled. If a property change
3940 // is made during this, however, it needs to be pushed in the upcoming
3941 // commit.
3942 EXPECT_FALSE(root_->needs_push_properties());
3943 EXPECT_FALSE(child_->needs_push_properties());
3944 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3945 root_->reset_push_properties_count();
3946 child_->reset_push_properties_count();
3947 child_->SetDrawsContent(true);
3948 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3949 EXPECT_EQ(0u, root_->push_properties_count());
3950 EXPECT_EQ(0u, child_->push_properties_count());
3951 EXPECT_TRUE(root_->needs_push_properties());
3952 EXPECT_TRUE(child_->needs_push_properties());
3953 break;
3955 case 2:
3956 EXPECT_EQ(1u, root_->push_properties_count());
3957 EXPECT_EQ(1u, child_->push_properties_count());
3958 EXPECT_FALSE(root_->needs_push_properties());
3959 EXPECT_FALSE(child_->needs_push_properties());
3960 EndTest();
3961 break;
3965 void AfterTest() override {}
3967 scoped_refptr<PushPropertiesCountingLayer> root_;
3968 scoped_refptr<PushPropertiesCountingLayer> child_;
3971 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3973 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3974 : public LayerTreeHostTest {
3975 protected:
3976 void BeginTest() override {
3977 expected_push_properties_root_ = 0;
3978 expected_push_properties_child_ = 0;
3979 expected_push_properties_grandchild1_ = 0;
3980 expected_push_properties_grandchild2_ = 0;
3981 expected_push_properties_grandchild3_ = 0;
3982 PostSetNeedsCommitToMainThread();
3985 void SetupTree() override {
3986 root_ = PushPropertiesCountingLayer::Create();
3987 root_->CreateRenderSurface();
3988 child_ = PushPropertiesCountingLayer::Create();
3989 grandchild1_ = PushPropertiesCountingLayer::Create();
3990 grandchild2_ = PushPropertiesCountingLayer::Create();
3991 grandchild3_ = PushPropertiesCountingLayer::Create();
3993 root_->AddChild(child_);
3994 child_->AddChild(grandchild1_);
3995 child_->AddChild(grandchild2_);
3996 child_->AddChild(grandchild3_);
3998 // Don't set the root layer here.
3999 LayerTreeHostTest::SetupTree();
4002 void AfterTest() override {}
4004 FakeContentLayerClient client_;
4005 scoped_refptr<PushPropertiesCountingLayer> root_;
4006 scoped_refptr<PushPropertiesCountingLayer> child_;
4007 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
4008 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
4009 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
4010 size_t expected_push_properties_root_;
4011 size_t expected_push_properties_child_;
4012 size_t expected_push_properties_grandchild1_;
4013 size_t expected_push_properties_grandchild2_;
4014 size_t expected_push_properties_grandchild3_;
4017 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
4018 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4019 protected:
4020 void DidCommitAndDrawFrame() override {
4021 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4022 switch (last_source_frame_number) {
4023 case 0:
4024 EXPECT_FALSE(root_->needs_push_properties());
4025 EXPECT_FALSE(root_->descendant_needs_push_properties());
4026 EXPECT_FALSE(child_->needs_push_properties());
4027 EXPECT_FALSE(child_->descendant_needs_push_properties());
4028 EXPECT_FALSE(grandchild1_->needs_push_properties());
4029 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4030 EXPECT_FALSE(grandchild2_->needs_push_properties());
4031 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4032 EXPECT_FALSE(grandchild3_->needs_push_properties());
4033 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4035 layer_tree_host()->SetRootLayer(root_);
4037 EXPECT_TRUE(root_->needs_push_properties());
4038 EXPECT_TRUE(root_->descendant_needs_push_properties());
4039 EXPECT_TRUE(child_->needs_push_properties());
4040 EXPECT_TRUE(child_->descendant_needs_push_properties());
4041 EXPECT_TRUE(grandchild1_->needs_push_properties());
4042 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4043 EXPECT_TRUE(grandchild2_->needs_push_properties());
4044 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4045 EXPECT_TRUE(grandchild3_->needs_push_properties());
4046 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4047 break;
4048 case 1:
4049 EndTest();
4050 break;
4055 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
4057 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
4058 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4059 protected:
4060 void DidCommitAndDrawFrame() override {
4061 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4062 switch (last_source_frame_number) {
4063 case 0:
4064 layer_tree_host()->SetRootLayer(root_);
4065 break;
4066 case 1:
4067 EXPECT_FALSE(root_->needs_push_properties());
4068 EXPECT_FALSE(root_->descendant_needs_push_properties());
4069 EXPECT_FALSE(child_->needs_push_properties());
4070 EXPECT_FALSE(child_->descendant_needs_push_properties());
4071 EXPECT_FALSE(grandchild1_->needs_push_properties());
4072 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4073 EXPECT_FALSE(grandchild2_->needs_push_properties());
4074 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4075 EXPECT_FALSE(grandchild3_->needs_push_properties());
4076 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4078 grandchild1_->RemoveFromParent();
4079 grandchild1_->SetPosition(gfx::Point(1, 1));
4081 EXPECT_FALSE(root_->needs_push_properties());
4082 EXPECT_FALSE(root_->descendant_needs_push_properties());
4083 EXPECT_FALSE(child_->needs_push_properties());
4084 EXPECT_FALSE(child_->descendant_needs_push_properties());
4085 EXPECT_FALSE(grandchild2_->needs_push_properties());
4086 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4087 EXPECT_FALSE(grandchild3_->needs_push_properties());
4088 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4090 child_->AddChild(grandchild1_);
4092 EXPECT_FALSE(root_->needs_push_properties());
4093 EXPECT_TRUE(root_->descendant_needs_push_properties());
4094 EXPECT_FALSE(child_->needs_push_properties());
4095 EXPECT_TRUE(child_->descendant_needs_push_properties());
4096 EXPECT_TRUE(grandchild1_->needs_push_properties());
4097 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4098 EXPECT_FALSE(grandchild2_->needs_push_properties());
4099 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4100 EXPECT_FALSE(grandchild3_->needs_push_properties());
4101 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4103 grandchild2_->SetPosition(gfx::Point(1, 1));
4105 EXPECT_FALSE(root_->needs_push_properties());
4106 EXPECT_TRUE(root_->descendant_needs_push_properties());
4107 EXPECT_FALSE(child_->needs_push_properties());
4108 EXPECT_TRUE(child_->descendant_needs_push_properties());
4109 EXPECT_TRUE(grandchild1_->needs_push_properties());
4110 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4111 EXPECT_TRUE(grandchild2_->needs_push_properties());
4112 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4113 EXPECT_FALSE(grandchild3_->needs_push_properties());
4114 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4116 // grandchild2_ will still need a push properties.
4117 grandchild1_->RemoveFromParent();
4119 EXPECT_FALSE(root_->needs_push_properties());
4120 EXPECT_TRUE(root_->descendant_needs_push_properties());
4121 EXPECT_FALSE(child_->needs_push_properties());
4122 EXPECT_TRUE(child_->descendant_needs_push_properties());
4124 // grandchild3_ does not need a push properties, so recursing should
4125 // no longer be needed.
4126 grandchild2_->RemoveFromParent();
4128 EXPECT_FALSE(root_->needs_push_properties());
4129 EXPECT_FALSE(root_->descendant_needs_push_properties());
4130 EXPECT_FALSE(child_->needs_push_properties());
4131 EXPECT_FALSE(child_->descendant_needs_push_properties());
4132 EndTest();
4133 break;
4138 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
4140 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
4141 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4142 protected:
4143 void DidCommitAndDrawFrame() override {
4144 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4145 switch (last_source_frame_number) {
4146 case 0:
4147 layer_tree_host()->SetRootLayer(root_);
4148 grandchild1_->set_persist_needs_push_properties(true);
4149 grandchild2_->set_persist_needs_push_properties(true);
4150 break;
4151 case 1:
4152 EXPECT_FALSE(root_->needs_push_properties());
4153 EXPECT_TRUE(root_->descendant_needs_push_properties());
4154 EXPECT_FALSE(child_->needs_push_properties());
4155 EXPECT_TRUE(child_->descendant_needs_push_properties());
4156 EXPECT_TRUE(grandchild1_->needs_push_properties());
4157 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4158 EXPECT_TRUE(grandchild2_->needs_push_properties());
4159 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4160 EXPECT_FALSE(grandchild3_->needs_push_properties());
4161 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4163 // grandchild2_ will still need a push properties.
4164 grandchild1_->RemoveFromParent();
4166 EXPECT_FALSE(root_->needs_push_properties());
4167 EXPECT_TRUE(root_->descendant_needs_push_properties());
4168 EXPECT_FALSE(child_->needs_push_properties());
4169 EXPECT_TRUE(child_->descendant_needs_push_properties());
4171 // grandchild3_ does not need a push properties, so recursing should
4172 // no longer be needed.
4173 grandchild2_->RemoveFromParent();
4175 EXPECT_FALSE(root_->needs_push_properties());
4176 EXPECT_FALSE(root_->descendant_needs_push_properties());
4177 EXPECT_FALSE(child_->needs_push_properties());
4178 EXPECT_FALSE(child_->descendant_needs_push_properties());
4179 EndTest();
4180 break;
4185 MULTI_THREAD_TEST_F(
4186 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
4188 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
4189 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4190 protected:
4191 void DidCommitAndDrawFrame() override {
4192 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4193 switch (last_source_frame_number) {
4194 case 0:
4195 layer_tree_host()->SetRootLayer(root_);
4196 break;
4197 case 1:
4198 EXPECT_FALSE(root_->needs_push_properties());
4199 EXPECT_FALSE(root_->descendant_needs_push_properties());
4200 EXPECT_FALSE(child_->needs_push_properties());
4201 EXPECT_FALSE(child_->descendant_needs_push_properties());
4202 EXPECT_FALSE(grandchild1_->needs_push_properties());
4203 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4204 EXPECT_FALSE(grandchild2_->needs_push_properties());
4205 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4206 EXPECT_FALSE(grandchild3_->needs_push_properties());
4207 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4209 // Change grandchildren while their parent is not in the tree.
4210 child_->RemoveFromParent();
4211 grandchild1_->SetPosition(gfx::Point(1, 1));
4212 grandchild2_->SetPosition(gfx::Point(1, 1));
4213 root_->AddChild(child_);
4215 EXPECT_FALSE(root_->needs_push_properties());
4216 EXPECT_TRUE(root_->descendant_needs_push_properties());
4217 EXPECT_TRUE(child_->needs_push_properties());
4218 EXPECT_TRUE(child_->descendant_needs_push_properties());
4219 EXPECT_TRUE(grandchild1_->needs_push_properties());
4220 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4221 EXPECT_TRUE(grandchild2_->needs_push_properties());
4222 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4223 EXPECT_TRUE(grandchild3_->needs_push_properties());
4224 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4226 grandchild1_->RemoveFromParent();
4228 EXPECT_FALSE(root_->needs_push_properties());
4229 EXPECT_TRUE(root_->descendant_needs_push_properties());
4230 EXPECT_TRUE(child_->needs_push_properties());
4231 EXPECT_TRUE(child_->descendant_needs_push_properties());
4233 grandchild2_->RemoveFromParent();
4235 EXPECT_FALSE(root_->needs_push_properties());
4236 EXPECT_TRUE(root_->descendant_needs_push_properties());
4237 EXPECT_TRUE(child_->needs_push_properties());
4238 EXPECT_TRUE(child_->descendant_needs_push_properties());
4240 grandchild3_->RemoveFromParent();
4242 EXPECT_FALSE(root_->needs_push_properties());
4243 EXPECT_TRUE(root_->descendant_needs_push_properties());
4244 EXPECT_TRUE(child_->needs_push_properties());
4245 EXPECT_FALSE(child_->descendant_needs_push_properties());
4247 EndTest();
4248 break;
4253 MULTI_THREAD_TEST_F(
4254 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4256 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4257 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4258 protected:
4259 void DidCommitAndDrawFrame() override {
4260 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4261 switch (last_source_frame_number) {
4262 case 0:
4263 layer_tree_host()->SetRootLayer(root_);
4264 break;
4265 case 1:
4266 EXPECT_FALSE(root_->needs_push_properties());
4267 EXPECT_FALSE(root_->descendant_needs_push_properties());
4268 EXPECT_FALSE(child_->needs_push_properties());
4269 EXPECT_FALSE(child_->descendant_needs_push_properties());
4270 EXPECT_FALSE(grandchild1_->needs_push_properties());
4271 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4272 EXPECT_FALSE(grandchild2_->needs_push_properties());
4273 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4274 EXPECT_FALSE(grandchild3_->needs_push_properties());
4275 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4277 child_->SetPosition(gfx::Point(1, 1));
4278 grandchild1_->SetPosition(gfx::Point(1, 1));
4279 grandchild2_->SetPosition(gfx::Point(1, 1));
4281 EXPECT_FALSE(root_->needs_push_properties());
4282 EXPECT_TRUE(root_->descendant_needs_push_properties());
4283 EXPECT_TRUE(child_->needs_push_properties());
4284 EXPECT_TRUE(child_->descendant_needs_push_properties());
4285 EXPECT_TRUE(grandchild1_->needs_push_properties());
4286 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4287 EXPECT_TRUE(grandchild2_->needs_push_properties());
4288 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4289 EXPECT_FALSE(grandchild3_->needs_push_properties());
4290 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4292 grandchild1_->RemoveFromParent();
4294 EXPECT_FALSE(root_->needs_push_properties());
4295 EXPECT_TRUE(root_->descendant_needs_push_properties());
4296 EXPECT_TRUE(child_->needs_push_properties());
4297 EXPECT_TRUE(child_->descendant_needs_push_properties());
4299 grandchild2_->RemoveFromParent();
4301 EXPECT_FALSE(root_->needs_push_properties());
4302 EXPECT_TRUE(root_->descendant_needs_push_properties());
4303 EXPECT_TRUE(child_->needs_push_properties());
4304 EXPECT_FALSE(child_->descendant_needs_push_properties());
4306 child_->RemoveFromParent();
4308 EXPECT_FALSE(root_->needs_push_properties());
4309 EXPECT_FALSE(root_->descendant_needs_push_properties());
4311 EndTest();
4312 break;
4317 MULTI_THREAD_TEST_F(
4318 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4320 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4321 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4322 protected:
4323 void DidCommitAndDrawFrame() override {
4324 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4325 switch (last_source_frame_number) {
4326 case 0:
4327 layer_tree_host()->SetRootLayer(root_);
4328 break;
4329 case 1:
4330 EXPECT_FALSE(root_->needs_push_properties());
4331 EXPECT_FALSE(root_->descendant_needs_push_properties());
4332 EXPECT_FALSE(child_->needs_push_properties());
4333 EXPECT_FALSE(child_->descendant_needs_push_properties());
4334 EXPECT_FALSE(grandchild1_->needs_push_properties());
4335 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4336 EXPECT_FALSE(grandchild2_->needs_push_properties());
4337 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4338 EXPECT_FALSE(grandchild3_->needs_push_properties());
4339 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4341 grandchild1_->SetPosition(gfx::Point(1, 1));
4342 grandchild2_->SetPosition(gfx::Point(1, 1));
4343 child_->SetPosition(gfx::Point(1, 1));
4345 EXPECT_FALSE(root_->needs_push_properties());
4346 EXPECT_TRUE(root_->descendant_needs_push_properties());
4347 EXPECT_TRUE(child_->needs_push_properties());
4348 EXPECT_TRUE(child_->descendant_needs_push_properties());
4349 EXPECT_TRUE(grandchild1_->needs_push_properties());
4350 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4351 EXPECT_TRUE(grandchild2_->needs_push_properties());
4352 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4353 EXPECT_FALSE(grandchild3_->needs_push_properties());
4354 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4356 grandchild1_->RemoveFromParent();
4358 EXPECT_FALSE(root_->needs_push_properties());
4359 EXPECT_TRUE(root_->descendant_needs_push_properties());
4360 EXPECT_TRUE(child_->needs_push_properties());
4361 EXPECT_TRUE(child_->descendant_needs_push_properties());
4363 grandchild2_->RemoveFromParent();
4365 EXPECT_FALSE(root_->needs_push_properties());
4366 EXPECT_TRUE(root_->descendant_needs_push_properties());
4367 EXPECT_TRUE(child_->needs_push_properties());
4368 EXPECT_FALSE(child_->descendant_needs_push_properties());
4370 child_->RemoveFromParent();
4372 EXPECT_FALSE(root_->needs_push_properties());
4373 EXPECT_FALSE(root_->descendant_needs_push_properties());
4375 EndTest();
4376 break;
4381 MULTI_THREAD_TEST_F(
4382 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4384 // This test verifies that the tree activation callback is invoked correctly.
4385 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4386 public:
4387 LayerTreeHostTestTreeActivationCallback()
4388 : num_commits_(0), callback_count_(0) {}
4390 void BeginTest() override {
4391 EXPECT_TRUE(HasImplThread());
4392 PostSetNeedsCommitToMainThread();
4395 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4396 LayerTreeHostImpl::FrameData* frame_data,
4397 DrawResult draw_result) override {
4398 ++num_commits_;
4399 switch (num_commits_) {
4400 case 1:
4401 EXPECT_EQ(0, callback_count_);
4402 callback_count_ = 0;
4403 SetCallback(true);
4404 PostSetNeedsCommitToMainThread();
4405 break;
4406 case 2:
4407 EXPECT_EQ(1, callback_count_);
4408 callback_count_ = 0;
4409 SetCallback(false);
4410 PostSetNeedsCommitToMainThread();
4411 break;
4412 case 3:
4413 EXPECT_EQ(0, callback_count_);
4414 callback_count_ = 0;
4415 EndTest();
4416 break;
4417 default:
4418 ADD_FAILURE() << num_commits_;
4419 EndTest();
4420 break;
4422 return LayerTreeHostTest::PrepareToDrawOnThread(
4423 host_impl, frame_data, draw_result);
4426 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
4428 void SetCallback(bool enable) {
4429 output_surface()->SetTreeActivationCallback(
4430 enable
4431 ? base::Bind(
4432 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4433 base::Unretained(this))
4434 : base::Closure());
4437 void ActivationCallback() { ++callback_count_; }
4439 int num_commits_;
4440 int callback_count_;
4443 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4444 RunTest(true, false, true);
4447 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4448 RunTest(true, true, true);
4451 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4452 public:
4453 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4455 void BeginTest() override {
4456 ASSERT_TRUE(invalidate_layer_)
4457 << "Derived tests must set this in SetupTree";
4459 // One initial commit.
4460 PostSetNeedsCommitToMainThread();
4463 void DidCommitAndDrawFrame() override {
4464 // After commit, invalidate the layer. This should cause a commit.
4465 if (layer_tree_host()->source_frame_number() == 1)
4466 invalidate_layer_->SetNeedsDisplay();
4469 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4470 num_draws_++;
4471 if (impl->active_tree()->source_frame_number() == 1)
4472 EndTest();
4475 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4476 num_commits_++;
4479 void AfterTest() override {
4480 EXPECT_GE(2, num_commits_);
4481 EXPECT_GE(2, num_draws_);
4484 protected:
4485 scoped_refptr<Layer> invalidate_layer_;
4487 private:
4488 int num_commits_;
4489 int num_draws_;
4492 // VideoLayer must support being invalidated and then passing that along
4493 // to the compositor thread, even though no resources are updated in
4494 // response to that invalidation.
4495 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4496 public:
4497 void SetupTree() override {
4498 LayerTreeHostTest::SetupTree();
4499 scoped_refptr<VideoLayer> video_layer =
4500 VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
4501 video_layer->SetBounds(gfx::Size(10, 10));
4502 video_layer->SetIsDrawable(true);
4503 layer_tree_host()->root_layer()->AddChild(video_layer);
4505 invalidate_layer_ = video_layer;
4508 private:
4509 FakeVideoFrameProvider provider_;
4512 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4514 // IOSurfaceLayer must support being invalidated and then passing that along
4515 // to the compositor thread, even though no resources are updated in
4516 // response to that invalidation.
4517 class LayerTreeHostTestIOSurfaceLayerInvalidate
4518 : public LayerInvalidateCausesDraw {
4519 public:
4520 void SetupTree() override {
4521 LayerTreeHostTest::SetupTree();
4522 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4523 layer->SetBounds(gfx::Size(10, 10));
4524 uint32_t fake_io_surface_id = 7;
4525 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4526 layer->SetIsDrawable(true);
4527 layer_tree_host()->root_layer()->AddChild(layer);
4529 invalidate_layer_ = layer;
4533 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4534 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4535 LayerTreeHostTestIOSurfaceLayerInvalidate);
4537 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4538 protected:
4539 void SetupTree() override {
4540 root_layer_ = Layer::Create();
4541 root_layer_->CreateRenderSurface();
4542 root_layer_->SetPosition(gfx::Point());
4543 root_layer_->SetBounds(gfx::Size(10, 10));
4545 parent_layer_ = SolidColorLayer::Create();
4546 parent_layer_->SetPosition(gfx::Point());
4547 parent_layer_->SetBounds(gfx::Size(10, 10));
4548 parent_layer_->SetIsDrawable(true);
4549 root_layer_->AddChild(parent_layer_);
4551 child_layer_ = SolidColorLayer::Create();
4552 child_layer_->SetPosition(gfx::Point());
4553 child_layer_->SetBounds(gfx::Size(10, 10));
4554 child_layer_->SetIsDrawable(true);
4555 parent_layer_->AddChild(child_layer_);
4557 layer_tree_host()->SetRootLayer(root_layer_);
4558 LayerTreeHostTest::SetupTree();
4561 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4563 void DidCommitAndDrawFrame() override {
4564 switch (layer_tree_host()->source_frame_number()) {
4565 case 1:
4566 // The layer type used does not need to push properties every frame.
4567 EXPECT_FALSE(child_layer_->needs_push_properties());
4569 // Change the bounds of the child layer, but make it skipped
4570 // by CalculateDrawProperties.
4571 parent_layer_->SetOpacity(0.f);
4572 child_layer_->SetBounds(gfx::Size(5, 5));
4573 break;
4574 case 2:
4575 // The bounds of the child layer were pushed to the impl side.
4576 EXPECT_FALSE(child_layer_->needs_push_properties());
4578 EndTest();
4579 break;
4583 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4584 LayerImpl* root = impl->active_tree()->root_layer();
4585 LayerImpl* parent = root->children()[0];
4586 LayerImpl* child = parent->children()[0];
4588 switch (impl->active_tree()->source_frame_number()) {
4589 case 1:
4590 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4591 break;
4595 void AfterTest() override {}
4597 scoped_refptr<Layer> root_layer_;
4598 scoped_refptr<SolidColorLayer> parent_layer_;
4599 scoped_refptr<SolidColorLayer> child_layer_;
4602 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4604 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4605 protected:
4606 void InitializeSettings(LayerTreeSettings* settings) override {
4607 settings->impl_side_painting = true;
4610 void SetupTree() override {
4611 root_layer_ = FakePictureLayer::Create(&client_);
4612 root_layer_->SetBounds(gfx::Size(10, 10));
4614 layer_tree_host()->SetRootLayer(root_layer_);
4615 LayerTreeHostTest::SetupTree();
4618 void BeginTest() override {
4619 // The viewport is empty, but we still need to update layers on the main
4620 // thread.
4621 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4622 PostSetNeedsCommitToMainThread();
4625 void DidCommit() override {
4626 // The layer should be updated even though the viewport is empty, so we
4627 // are capable of drawing it on the impl tree.
4628 EXPECT_GT(root_layer_->update_count(), 0u);
4629 EndTest();
4632 void AfterTest() override {}
4634 FakeContentLayerClient client_;
4635 scoped_refptr<FakePictureLayer> root_layer_;
4638 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4640 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4641 public:
4642 LayerTreeHostTestAbortEvictedTextures()
4643 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4645 protected:
4646 void SetupTree() override {
4647 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4648 root_layer->SetBounds(gfx::Size(200, 200));
4649 root_layer->SetIsDrawable(true);
4650 root_layer->CreateRenderSurface();
4652 layer_tree_host()->SetRootLayer(root_layer);
4653 LayerTreeHostTest::SetupTree();
4656 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4658 void WillBeginMainFrame() override {
4659 num_will_begin_main_frames_++;
4660 switch (num_will_begin_main_frames_) {
4661 case 2:
4662 // Send a redraw to the compositor thread. This will (wrongly) be
4663 // ignored unless aborting resets the texture state.
4664 layer_tree_host()->SetNeedsRedraw();
4665 break;
4669 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
4670 num_impl_commits_++;
4673 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4674 switch (impl->SourceAnimationFrameNumber()) {
4675 case 1:
4676 // Prevent draws until commit.
4677 impl->active_tree()->SetContentsTexturesPurged();
4678 EXPECT_FALSE(impl->CanDraw());
4679 // Trigger an abortable commit.
4680 impl->SetNeedsCommit();
4681 break;
4682 case 2:
4683 EndTest();
4684 break;
4688 void AfterTest() override {
4689 // Ensure that the commit was truly aborted.
4690 EXPECT_EQ(2, num_will_begin_main_frames_);
4691 EXPECT_EQ(1, num_impl_commits_);
4694 private:
4695 int num_will_begin_main_frames_;
4696 int num_impl_commits_;
4699 // Commits can only be aborted when using the thread proxy.
4700 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4702 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4703 protected:
4704 void InitializeSettings(LayerTreeSettings* settings) override {
4705 settings->impl_side_painting = true;
4706 settings->use_zero_copy = false;
4707 settings->use_one_copy = false;
4710 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4711 scoped_refptr<TestContextProvider> context_provider =
4712 TestContextProvider::Create();
4713 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
4714 if (delegating_renderer())
4715 return FakeOutputSurface::CreateDelegating3d(context_provider);
4716 else
4717 return FakeOutputSurface::Create3d(context_provider);
4720 void SetupTree() override {
4721 client_.set_fill_with_nonsolid_color(true);
4722 scoped_refptr<FakePictureLayer> root_layer =
4723 FakePictureLayer::Create(&client_);
4724 root_layer->SetBounds(gfx::Size(1024, 1024));
4725 root_layer->SetIsDrawable(true);
4727 layer_tree_host()->SetRootLayer(root_layer);
4728 LayerTreeHostTest::SetupTree();
4731 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4733 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4734 TestWebGraphicsContext3D* context = TestContext();
4736 // Expect that the transfer buffer memory used is equal to the
4737 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4738 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
4739 EndTest();
4742 void AfterTest() override {}
4744 private:
4745 FakeContentLayerClient client_;
4748 // Impl-side painting is a multi-threaded compositor feature.
4749 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4751 // Test ensuring that memory limits are sent to the prioritized resource
4752 // manager.
4753 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4754 public:
4755 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4757 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4759 void WillCommit() override {
4760 // Some commits are aborted, so increment number of attempted commits here.
4761 num_commits_++;
4764 void DidCommit() override {
4765 switch (num_commits_) {
4766 case 1:
4767 // Verify default values.
4768 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4769 layer_tree_host()
4770 ->contents_texture_manager()
4771 ->MaxMemoryLimitBytes());
4772 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4773 layer_tree_host()
4774 ->contents_texture_manager()
4775 ->ExternalPriorityCutoff());
4776 PostSetNeedsCommitToMainThread();
4777 break;
4778 case 2:
4779 // The values should remain the same until the commit after the policy
4780 // is changed.
4781 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4782 layer_tree_host()
4783 ->contents_texture_manager()
4784 ->MaxMemoryLimitBytes());
4785 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4786 layer_tree_host()
4787 ->contents_texture_manager()
4788 ->ExternalPriorityCutoff());
4789 break;
4790 case 3:
4791 // Verify values were correctly passed.
4792 EXPECT_EQ(16u * 1024u * 1024u,
4793 layer_tree_host()
4794 ->contents_texture_manager()
4795 ->MaxMemoryLimitBytes());
4796 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4797 layer_tree_host()
4798 ->contents_texture_manager()
4799 ->ExternalPriorityCutoff());
4800 EndTest();
4801 break;
4802 case 4:
4803 // Make sure no extra commits happen.
4804 NOTREACHED();
4805 break;
4809 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4810 switch (num_commits_) {
4811 case 1:
4812 break;
4813 case 2:
4814 // This will trigger a commit because the priority cutoff has changed.
4815 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4816 16u * 1024u * 1024u,
4817 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4818 1000));
4819 break;
4820 case 3:
4821 // This will not trigger a commit because the priority cutoff has not
4822 // changed, and there is already enough memory for all allocations.
4823 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4824 32u * 1024u * 1024u,
4825 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4826 1000));
4827 break;
4828 case 4:
4829 NOTREACHED();
4830 break;
4834 void AfterTest() override {}
4836 private:
4837 int num_commits_;
4840 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4842 } // namespace
4844 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4845 : public LayerTreeHostTest {
4846 protected:
4847 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4848 : first_output_surface_memory_limit_(4321234),
4849 second_output_surface_memory_limit_(1234321) {}
4851 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4852 if (!first_context_provider_.get()) {
4853 first_context_provider_ = TestContextProvider::Create();
4854 } else {
4855 EXPECT_FALSE(second_context_provider_.get());
4856 second_context_provider_ = TestContextProvider::Create();
4859 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4860 ? second_context_provider_
4861 : first_context_provider_);
4862 scoped_ptr<FakeOutputSurface> output_surface;
4863 if (delegating_renderer())
4864 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4865 else
4866 output_surface = FakeOutputSurface::Create3d(provider);
4867 output_surface->SetMemoryPolicyToSetAtBind(
4868 make_scoped_ptr(new ManagedMemoryPolicy(
4869 second_context_provider_.get() ? second_output_surface_memory_limit_
4870 : first_output_surface_memory_limit_,
4871 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4872 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4873 return output_surface.Pass();
4876 void SetupTree() override {
4877 if (layer_tree_host()->settings().impl_side_painting)
4878 root_ = FakePictureLayer::Create(&client_);
4879 else
4880 root_ = FakeContentLayer::Create(&client_);
4881 root_->SetBounds(gfx::Size(20, 20));
4882 layer_tree_host()->SetRootLayer(root_);
4883 LayerTreeHostTest::SetupTree();
4886 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4888 void DidCommitAndDrawFrame() override {
4889 // Lost context sometimes takes two frames to recreate. The third frame
4890 // is sometimes aborted, so wait until the fourth frame to verify that
4891 // the memory has been set, and the fifth frame to end the test.
4892 if (layer_tree_host()->source_frame_number() < 5) {
4893 layer_tree_host()->SetNeedsCommit();
4894 } else if (layer_tree_host()->source_frame_number() == 5) {
4895 EndTest();
4899 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
4900 switch (impl->active_tree()->source_frame_number()) {
4901 case 1:
4902 EXPECT_EQ(first_output_surface_memory_limit_,
4903 impl->memory_allocation_limit_bytes());
4904 // Lose the output surface.
4905 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4906 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4907 break;
4908 case 4:
4909 EXPECT_EQ(second_output_surface_memory_limit_,
4910 impl->memory_allocation_limit_bytes());
4911 break;
4915 void AfterTest() override {}
4917 scoped_refptr<TestContextProvider> first_context_provider_;
4918 scoped_refptr<TestContextProvider> second_context_provider_;
4919 size_t first_output_surface_memory_limit_;
4920 size_t second_output_surface_memory_limit_;
4921 FakeContentLayerClient client_;
4922 scoped_refptr<Layer> root_;
4925 SINGLE_AND_MULTI_THREAD_TEST_F(
4926 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4928 struct TestSwapPromiseResult {
4929 TestSwapPromiseResult()
4930 : did_activate_called(false),
4931 did_swap_called(false),
4932 did_not_swap_called(false),
4933 dtor_called(false),
4934 reason(SwapPromise::COMMIT_FAILS) {}
4936 bool did_activate_called;
4937 bool did_swap_called;
4938 bool did_not_swap_called;
4939 bool dtor_called;
4940 SwapPromise::DidNotSwapReason reason;
4941 base::Lock lock;
4944 class TestSwapPromise : public SwapPromise {
4945 public:
4946 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4948 ~TestSwapPromise() override {
4949 base::AutoLock lock(result_->lock);
4950 result_->dtor_called = true;
4953 void DidActivate() override {
4954 base::AutoLock lock(result_->lock);
4955 EXPECT_FALSE(result_->did_activate_called);
4956 EXPECT_FALSE(result_->did_swap_called);
4957 EXPECT_FALSE(result_->did_not_swap_called);
4958 result_->did_activate_called = true;
4961 void DidSwap(CompositorFrameMetadata* metadata) override {
4962 base::AutoLock lock(result_->lock);
4963 EXPECT_TRUE(result_->did_activate_called);
4964 EXPECT_FALSE(result_->did_swap_called);
4965 EXPECT_FALSE(result_->did_not_swap_called);
4966 result_->did_swap_called = true;
4969 void DidNotSwap(DidNotSwapReason reason) override {
4970 base::AutoLock lock(result_->lock);
4971 EXPECT_FALSE(result_->did_swap_called);
4972 EXPECT_FALSE(result_->did_not_swap_called);
4973 EXPECT_FALSE(result_->did_activate_called &&
4974 reason != DidNotSwapReason::SWAP_FAILS);
4975 result_->did_not_swap_called = true;
4976 result_->reason = reason;
4979 int64 TraceId() const override { return 0; }
4981 private:
4982 // Not owned.
4983 TestSwapPromiseResult* result_;
4986 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4987 protected:
4988 LayerTreeHostTestBreakSwapPromise()
4989 : commit_count_(0), commit_complete_count_(0) {}
4991 void WillBeginMainFrame() override {
4992 ASSERT_LE(commit_count_, 2);
4993 scoped_ptr<SwapPromise> swap_promise(
4994 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4995 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4998 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5000 void DidCommit() override {
5001 commit_count_++;
5002 if (commit_count_ == 2) {
5003 // This commit will finish.
5004 layer_tree_host()->SetNeedsCommit();
5008 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5009 if (host_impl->pending_tree()) {
5010 int frame = host_impl->pending_tree()->source_frame_number();
5011 base::AutoLock lock(swap_promise_result_[frame].lock);
5012 EXPECT_FALSE(swap_promise_result_[frame].did_activate_called);
5013 EXPECT_FALSE(swap_promise_result_[frame].did_swap_called);
5017 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5018 int frame = host_impl->active_tree()->source_frame_number();
5019 base::AutoLock lock(swap_promise_result_[frame].lock);
5020 EXPECT_TRUE(swap_promise_result_[frame].did_activate_called);
5021 EXPECT_FALSE(swap_promise_result_[frame].did_swap_called);
5024 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5025 commit_complete_count_++;
5026 if (commit_complete_count_ == 1) {
5027 // This commit will be aborted because no actual update.
5028 PostSetNeedsUpdateLayersToMainThread();
5029 } else {
5030 EndTest();
5034 void AfterTest() override {
5035 // 3 commits are scheduled. 2 completes. 1 is aborted.
5036 EXPECT_EQ(commit_count_, 3);
5037 EXPECT_EQ(commit_complete_count_, 2);
5040 // The first commit completes and causes swap buffer which finishes
5041 // the promise.
5042 base::AutoLock lock(swap_promise_result_[0].lock);
5043 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5044 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5045 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5049 // The second commit is aborted since it contains no updates.
5050 base::AutoLock lock(swap_promise_result_[1].lock);
5051 EXPECT_FALSE(swap_promise_result_[1].did_activate_called);
5052 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5053 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5054 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
5055 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5059 // The last commit completes but it does not cause swap buffer because
5060 // there is no damage in the frame data.
5061 base::AutoLock lock(swap_promise_result_[2].lock);
5062 EXPECT_TRUE(swap_promise_result_[2].did_activate_called);
5063 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5064 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5065 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5066 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5070 int commit_count_;
5071 int commit_complete_count_;
5072 TestSwapPromiseResult swap_promise_result_[3];
5075 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
5077 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
5078 public:
5079 LayerTreeHostTestKeepSwapPromise() {}
5081 void BeginTest() override {
5082 layer_ = SolidColorLayer::Create();
5083 layer_->SetIsDrawable(true);
5084 layer_->SetBounds(gfx::Size(10, 10));
5085 layer_tree_host()->SetRootLayer(layer_);
5086 gfx::Size bounds(100, 100);
5087 layer_tree_host()->SetViewportSize(bounds);
5088 PostSetNeedsCommitToMainThread();
5091 void DidCommit() override {
5092 MainThreadTaskRunner()->PostTask(
5093 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
5094 base::Unretained(this)));
5097 void ChangeFrame() {
5098 switch (layer_tree_host()->source_frame_number()) {
5099 case 1:
5100 layer_->SetBounds(gfx::Size(10, 11));
5101 layer_tree_host()->QueueSwapPromise(
5102 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
5103 break;
5104 case 2:
5105 break;
5106 default:
5107 NOTREACHED();
5108 break;
5112 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5113 if (host_impl->pending_tree()) {
5114 if (host_impl->pending_tree()->source_frame_number() == 1) {
5115 base::AutoLock lock(swap_promise_result_.lock);
5116 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5117 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5118 SetCallback(true);
5119 } else {
5120 SetCallback(false);
5125 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5126 if (host_impl->active_tree()->source_frame_number() == 1) {
5127 base::AutoLock lock(swap_promise_result_.lock);
5128 EXPECT_TRUE(swap_promise_result_.did_activate_called);
5129 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5133 void ActivationCallback() {
5134 // DidActivate needs to happen before the tree activation callback.
5135 base::AutoLock lock(swap_promise_result_.lock);
5136 EXPECT_TRUE(swap_promise_result_.did_activate_called);
5139 void SetCallback(bool enable) {
5140 output_surface()->SetTreeActivationCallback(
5141 enable
5142 ? base::Bind(&LayerTreeHostTestKeepSwapPromise::ActivationCallback,
5143 base::Unretained(this))
5144 : base::Closure());
5147 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
5148 EXPECT_TRUE(result);
5149 if (host_impl->active_tree()->source_frame_number() >= 1) {
5150 // The commit changes layers so it should cause a swap.
5151 base::AutoLock lock(swap_promise_result_.lock);
5152 EXPECT_TRUE(swap_promise_result_.did_swap_called);
5153 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5154 EXPECT_TRUE(swap_promise_result_.dtor_called);
5155 EndTest();
5159 void AfterTest() override {}
5161 private:
5162 scoped_refptr<Layer> layer_;
5163 TestSwapPromiseResult swap_promise_result_;
5166 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
5168 class LayerTreeHostTestBreakSwapPromiseForVisibility
5169 : public LayerTreeHostTest {
5170 protected:
5171 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5173 void SetVisibleFalseAndQueueSwapPromise() {
5174 layer_tree_host()->SetVisible(false);
5175 scoped_ptr<SwapPromise> swap_promise(
5176 new TestSwapPromise(&swap_promise_result_));
5177 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5180 void ScheduledActionWillSendBeginMainFrame() override {
5181 MainThreadTaskRunner()->PostTask(
5182 FROM_HERE,
5183 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility
5184 ::SetVisibleFalseAndQueueSwapPromise,
5185 base::Unretained(this)));
5188 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5189 CommitEarlyOutReason reason) override {
5190 EndTest();
5193 void AfterTest() override {
5195 base::AutoLock lock(swap_promise_result_.lock);
5196 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5197 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5198 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5199 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5200 EXPECT_TRUE(swap_promise_result_.dtor_called);
5204 TestSwapPromiseResult swap_promise_result_;
5207 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
5209 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest {
5210 protected:
5211 LayerTreeHostTestBreakSwapPromiseForContext()
5212 : output_surface_lost_triggered_(false) {
5215 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5217 void LoseOutputSurfaceAndQueueSwapPromise() {
5218 layer_tree_host()->DidLoseOutputSurface();
5219 scoped_ptr<SwapPromise> swap_promise(
5220 new TestSwapPromise(&swap_promise_result_));
5221 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5224 void ScheduledActionWillSendBeginMainFrame() override {
5225 if (output_surface_lost_triggered_)
5226 return;
5227 output_surface_lost_triggered_ = true;
5229 MainThreadTaskRunner()->PostTask(
5230 FROM_HERE,
5231 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext
5232 ::LoseOutputSurfaceAndQueueSwapPromise,
5233 base::Unretained(this)));
5236 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5237 CommitEarlyOutReason reason) override {
5238 // This is needed so that the impl-thread state matches main-thread state.
5239 host_impl->DidLoseOutputSurface();
5240 EndTest();
5243 void AfterTest() override {
5245 base::AutoLock lock(swap_promise_result_.lock);
5246 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5247 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5248 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5249 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5250 EXPECT_TRUE(swap_promise_result_.dtor_called);
5254 bool output_surface_lost_triggered_;
5255 TestSwapPromiseResult swap_promise_result_;
5258 SINGLE_AND_MULTI_THREAD_TEST_F(
5259 LayerTreeHostTestBreakSwapPromiseForContext);
5261 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
5262 public:
5263 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
5264 LayerTreeHostImpl* layer_tree_host_impl,
5265 int* set_needs_commit_count,
5266 int* set_needs_redraw_count)
5267 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
5268 set_needs_commit_count_(set_needs_commit_count) {}
5270 ~SimpleSwapPromiseMonitor() override {}
5272 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
5274 void OnSetNeedsRedrawOnImpl() override {
5275 ADD_FAILURE() << "Should not get called on main thread.";
5278 void OnForwardScrollUpdateToMainThreadOnImpl() override {
5279 ADD_FAILURE() << "Should not get called on main thread.";
5282 private:
5283 int* set_needs_commit_count_;
5286 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
5287 public:
5288 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5290 void WillBeginMainFrame() override {
5291 if (TestEnded())
5292 return;
5294 int set_needs_commit_count = 0;
5295 int set_needs_redraw_count = 0;
5298 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5299 new SimpleSwapPromiseMonitor(layer_tree_host(),
5300 NULL,
5301 &set_needs_commit_count,
5302 &set_needs_redraw_count));
5303 layer_tree_host()->SetNeedsCommit();
5304 EXPECT_EQ(1, set_needs_commit_count);
5305 EXPECT_EQ(0, set_needs_redraw_count);
5308 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
5309 // monitored.
5310 layer_tree_host()->SetNeedsCommit();
5311 EXPECT_EQ(1, set_needs_commit_count);
5312 EXPECT_EQ(0, set_needs_redraw_count);
5315 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5316 new SimpleSwapPromiseMonitor(layer_tree_host(),
5317 NULL,
5318 &set_needs_commit_count,
5319 &set_needs_redraw_count));
5320 layer_tree_host()->SetNeedsUpdateLayers();
5321 EXPECT_EQ(2, set_needs_commit_count);
5322 EXPECT_EQ(0, set_needs_redraw_count);
5326 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5327 new SimpleSwapPromiseMonitor(layer_tree_host(),
5328 NULL,
5329 &set_needs_commit_count,
5330 &set_needs_redraw_count));
5331 layer_tree_host()->SetNeedsAnimate();
5332 EXPECT_EQ(3, set_needs_commit_count);
5333 EXPECT_EQ(0, set_needs_redraw_count);
5336 EndTest();
5339 void AfterTest() override {}
5342 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
5344 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
5345 : public LayerTreeHostTest {
5346 protected:
5347 void InitializeSettings(LayerTreeSettings* settings) override {
5348 settings->impl_side_painting = true;
5351 void SetupTree() override {
5352 LayerTreeHostTest::SetupTree();
5353 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
5356 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5358 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5359 host_impl->EvictAllUIResources();
5360 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
5361 // mode. Active tree should require high-res to draw after entering this
5362 // mode to ensure that high-res tiles are also required for a pending tree
5363 // to be activated.
5364 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5367 void DidCommit() override {
5368 int frame = layer_tree_host()->source_frame_number();
5369 switch (frame) {
5370 case 1:
5371 PostSetNeedsCommitToMainThread();
5372 break;
5373 case 2:
5374 ui_resource_ = nullptr;
5375 EndTest();
5376 break;
5380 void AfterTest() override {}
5382 FakeContentLayerClient client_;
5383 scoped_ptr<FakeScopedUIResource> ui_resource_;
5386 // This test is flaky, see http://crbug.com/386199
5387 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
5389 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
5390 protected:
5391 void InitializeSettings(LayerTreeSettings* settings) override {
5392 settings->impl_side_painting = true;
5394 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5395 EXPECT_FALSE(settings->gpu_rasterization_forced);
5398 void SetupTree() override {
5399 LayerTreeHostTest::SetupTree();
5401 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5402 layer->SetBounds(gfx::Size(10, 10));
5403 layer->SetIsDrawable(true);
5404 layer_tree_host()->root_layer()->AddChild(layer);
5407 void BeginTest() override {
5408 Layer* root = layer_tree_host()->root_layer();
5409 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5410 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5412 // Verify default values.
5413 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5414 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5415 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5416 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5418 // Setting gpu rasterization trigger does not enable gpu rasterization.
5419 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5420 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5422 PostSetNeedsCommitToMainThread();
5425 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5426 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5427 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5430 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5431 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5432 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5433 EndTest();
5436 void AfterTest() override {}
5438 FakeContentLayerClient layer_client_;
5441 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
5443 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
5444 protected:
5445 void InitializeSettings(LayerTreeSettings* settings) override {
5446 settings->impl_side_painting = true;
5448 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5449 settings->gpu_rasterization_enabled = true;
5452 void SetupTree() override {
5453 LayerTreeHostTest::SetupTree();
5455 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5456 layer->SetBounds(gfx::Size(10, 10));
5457 layer->SetIsDrawable(true);
5458 layer_tree_host()->root_layer()->AddChild(layer);
5461 void BeginTest() override {
5462 Layer* root = layer_tree_host()->root_layer();
5463 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5464 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5466 // Verify default values.
5467 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5468 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5469 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5470 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5472 // Gpu rasterization trigger is relevant.
5473 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5474 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5476 // Content-based veto is relevant as well.
5477 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5478 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5479 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5480 // Veto will take effect when layers are updated.
5481 // The results will be verified after commit is completed below.
5482 // Since we are manually marking picture pile as unsuitable,
5483 // make sure that the layer gets a chance to update.
5484 layer->SetNeedsDisplay();
5485 PostSetNeedsCommitToMainThread();
5488 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5489 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5490 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5493 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5494 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5495 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5496 EndTest();
5499 void AfterTest() override {}
5501 FakeContentLayerClient layer_client_;
5504 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
5506 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
5507 protected:
5508 void InitializeSettings(LayerTreeSettings* settings) override {
5509 ASSERT_TRUE(settings->impl_side_painting);
5511 EXPECT_FALSE(settings->gpu_rasterization_forced);
5512 settings->gpu_rasterization_forced = true;
5515 void SetupTree() override {
5516 LayerTreeHostTest::SetupTree();
5518 scoped_refptr<FakePictureLayer> layer =
5519 FakePictureLayer::Create(&layer_client_);
5520 layer->SetBounds(gfx::Size(10, 10));
5521 layer->SetIsDrawable(true);
5522 layer_tree_host()->root_layer()->AddChild(layer);
5525 void BeginTest() override {
5526 Layer* root = layer_tree_host()->root_layer();
5527 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5528 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5530 // Verify default values.
5531 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5532 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5533 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5534 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5536 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
5537 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5538 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5540 // Content-based veto is irrelevant as well.
5541 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5542 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5543 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5544 // Veto will take effect when layers are updated.
5545 // The results will be verified after commit is completed below.
5546 // Since we are manually marking picture pile as unsuitable,
5547 // make sure that the layer gets a chance to update.
5548 layer->SetNeedsDisplay();
5549 PostSetNeedsCommitToMainThread();
5552 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5553 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
5554 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5557 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5558 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
5559 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5560 EndTest();
5563 void AfterTest() override {}
5565 FakeContentLayerClient layer_client_;
5568 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
5570 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
5571 public:
5572 LayerTreeHostTestContinuousPainting()
5573 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
5575 protected:
5576 enum { kExpectedNumCommits = 10 };
5578 void SetupTree() override {
5579 scoped_refptr<Layer> root_layer = Layer::Create();
5580 root_layer->SetBounds(bounds_);
5581 root_layer->CreateRenderSurface();
5583 if (layer_tree_host()->settings().impl_side_painting) {
5584 picture_layer_ = FakePictureLayer::Create(&client_);
5585 child_layer_ = picture_layer_.get();
5586 } else {
5587 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
5588 child_layer_ = content_layer_.get();
5590 child_layer_->SetBounds(bounds_);
5591 child_layer_->SetIsDrawable(true);
5592 root_layer->AddChild(child_layer_);
5594 layer_tree_host()->SetRootLayer(root_layer);
5595 layer_tree_host()->SetViewportSize(bounds_);
5596 LayerTreeHostTest::SetupTree();
5599 void BeginTest() override {
5600 MainThreadTaskRunner()->PostTask(
5601 FROM_HERE,
5602 base::Bind(
5603 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
5604 base::Unretained(this)));
5605 // Wait 50x longer than expected.
5606 double milliseconds_per_frame =
5607 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
5608 MainThreadTaskRunner()->PostDelayedTask(
5609 FROM_HERE,
5610 base::Bind(
5611 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
5612 base::Unretained(this)),
5613 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
5614 milliseconds_per_frame));
5617 void BeginMainFrame(const BeginFrameArgs& args) override {
5618 child_layer_->SetNeedsDisplay();
5621 void AfterTest() override {
5622 EXPECT_LE(kExpectedNumCommits, num_commits_);
5623 EXPECT_LE(kExpectedNumCommits, num_draws_);
5624 int update_count = content_layer_.get()
5625 ? content_layer_->PaintContentsCount()
5626 : picture_layer_->update_count();
5627 EXPECT_LE(kExpectedNumCommits, update_count);
5630 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5631 if (++num_draws_ == kExpectedNumCommits)
5632 EndTest();
5635 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5636 ++num_commits_;
5639 private:
5640 void EnableContinuousPainting() {
5641 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5642 debug_state.continuous_painting = true;
5643 layer_tree_host()->SetDebugState(debug_state);
5646 void DisableContinuousPainting() {
5647 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5648 debug_state.continuous_painting = false;
5649 layer_tree_host()->SetDebugState(debug_state);
5650 EndTest();
5653 int num_commits_;
5654 int num_draws_;
5655 const gfx::Size bounds_;
5656 FakeContentLayerClient client_;
5657 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5658 scoped_refptr<FakePictureLayer> picture_layer_;
5659 Layer* child_layer_;
5662 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5664 class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
5665 : public LayerTreeHostTest {
5666 public:
5667 enum { kExpectedNumImplFrames = 10 };
5669 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame()
5670 : will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {}
5672 void BeginTest() override {
5673 // Kick off the test with a commit.
5674 PostSetNeedsCommitToMainThread();
5677 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
5678 const BeginFrameArgs& args) override {
5679 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5680 EXPECT_FALSE(TestEnded());
5681 will_begin_impl_frame_count_++;
5684 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
5685 did_finish_impl_frame_count_++;
5686 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5688 // Request a number of commits to cause multiple impl frames. We expect to
5689 // get one more impl frames than the number of commits requested because
5690 // after a commit it takes one frame to become idle.
5691 if (did_finish_impl_frame_count_ < kExpectedNumImplFrames - 1)
5692 PostSetNeedsCommitToMainThread();
5695 void SendBeginMainFrameNotExpectedSoon() override { EndTest(); }
5697 void AfterTest() override {
5698 EXPECT_GT(will_begin_impl_frame_count_, 0);
5699 EXPECT_GT(did_finish_impl_frame_count_, 0);
5700 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5702 // TODO(mithro): Figure out why the multithread version of this test
5703 // sometimes has one more frame then expected. Possibly related to
5704 // http://crbug.com/443185
5705 if (!HasImplThread()) {
5706 EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
5707 EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
5711 private:
5712 int will_begin_impl_frame_count_;
5713 int did_finish_impl_frame_count_;
5716 SINGLE_AND_MULTI_THREAD_TEST_F(
5717 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame);
5719 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
5720 public:
5721 LayerTreeHostTestSendBeginFramesToChildren()
5722 : begin_frame_sent_to_children_(false) {
5725 void BeginTest() override {
5726 // Kick off the test with a commit.
5727 PostSetNeedsCommitToMainThread();
5730 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5731 begin_frame_sent_to_children_ = true;
5732 EndTest();
5735 void DidBeginMainFrame() override {
5736 // Children requested BeginFrames.
5737 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5740 void AfterTest() override {
5741 // Ensure that BeginFrame message is sent to children during parent
5742 // scheduler handles its BeginFrame.
5743 EXPECT_TRUE(begin_frame_sent_to_children_);
5746 private:
5747 bool begin_frame_sent_to_children_;
5750 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
5752 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
5753 : public LayerTreeHostTest {
5754 public:
5755 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
5756 : begin_frame_sent_to_children_(false) {
5759 void InitializeSettings(LayerTreeSettings* settings) override {
5760 settings->use_external_begin_frame_source = true;
5763 void BeginTest() override {
5764 // Kick off the test with a commit.
5765 PostSetNeedsCommitToMainThread();
5768 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5769 begin_frame_sent_to_children_ = true;
5770 EndTest();
5773 void DidBeginMainFrame() override {
5774 // Children requested BeginFrames.
5775 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5778 void AfterTest() override {
5779 // Ensure that BeginFrame message is sent to children during parent
5780 // scheduler handles its BeginFrame.
5781 EXPECT_TRUE(begin_frame_sent_to_children_);
5784 private:
5785 bool begin_frame_sent_to_children_;
5788 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
5790 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5791 public:
5792 LayerTreeHostTestActivateOnInvisible()
5793 : activation_count_(0), visible_(true) {}
5795 void InitializeSettings(LayerTreeSettings* settings) override {
5796 settings->impl_side_painting = true;
5799 void BeginTest() override {
5800 // Kick off the test with a commit.
5801 PostSetNeedsCommitToMainThread();
5804 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5805 // Make sure we don't activate using the notify signal from tile manager.
5806 host_impl->BlockNotifyReadyToActivateForTesting(true);
5809 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5811 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5812 bool visible) override {
5813 visible_ = visible;
5815 // Once invisible, we can go visible again.
5816 if (!visible) {
5817 PostSetVisibleToMainThread(true);
5818 } else {
5819 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5820 EndTest();
5824 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5825 ++activation_count_;
5826 EXPECT_FALSE(visible_);
5829 void AfterTest() override {
5830 // Ensure we activated even though the signal was blocked.
5831 EXPECT_EQ(1, activation_count_);
5832 EXPECT_TRUE(visible_);
5835 private:
5836 int activation_count_;
5837 bool visible_;
5839 FakeContentLayerClient client_;
5840 scoped_refptr<FakePictureLayer> picture_layer_;
5843 // TODO(vmpstr): Enable with single thread impl-side painting.
5844 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5846 // Do a synchronous composite and assert that the swap promise succeeds.
5847 class LayerTreeHostTestSynchronousCompositeSwapPromise
5848 : public LayerTreeHostTest {
5849 public:
5850 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5852 void InitializeSettings(LayerTreeSettings* settings) override {
5853 settings->single_thread_proxy_scheduler = false;
5856 void BeginTest() override {
5857 // Successful composite.
5858 scoped_ptr<SwapPromise> swap_promise0(
5859 new TestSwapPromise(&swap_promise_result_[0]));
5860 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5861 layer_tree_host()->Composite(gfx::FrameTime::Now());
5863 // Fail to swap (no damage).
5864 scoped_ptr<SwapPromise> swap_promise1(
5865 new TestSwapPromise(&swap_promise_result_[1]));
5866 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5867 layer_tree_host()->SetNeedsCommit();
5868 layer_tree_host()->Composite(gfx::FrameTime::Now());
5870 // Fail to draw (not visible).
5871 scoped_ptr<SwapPromise> swap_promise2(
5872 new TestSwapPromise(&swap_promise_result_[2]));
5873 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5874 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5875 layer_tree_host()->SetVisible(false);
5876 layer_tree_host()->Composite(gfx::FrameTime::Now());
5878 EndTest();
5881 void DidCommit() override {
5882 commit_count_++;
5883 ASSERT_LE(commit_count_, 3);
5886 void AfterTest() override {
5887 EXPECT_EQ(3, commit_count_);
5889 // Initial swap promise should have succeded.
5891 base::AutoLock lock(swap_promise_result_[0].lock);
5892 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5893 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5894 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5897 // Second swap promise fails to swap.
5899 base::AutoLock lock(swap_promise_result_[1].lock);
5900 EXPECT_TRUE(swap_promise_result_[1].did_activate_called);
5901 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5902 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5903 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5904 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5907 // Third swap promises also fails to swap (and draw).
5909 base::AutoLock lock(swap_promise_result_[2].lock);
5910 EXPECT_TRUE(swap_promise_result_[2].did_activate_called);
5911 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5912 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5913 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5914 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5918 int commit_count_;
5919 TestSwapPromiseResult swap_promise_result_[3];
5922 // Impl-side painting is not supported for synchronous compositing.
5923 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
5925 // Make sure page scale and top control deltas are applied to the client even
5926 // when the LayerTreeHost doesn't have a root layer.
5927 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
5928 : public LayerTreeHostTest {
5929 public:
5930 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
5931 : deltas_sent_to_client_(false) {}
5933 void BeginTest() override {
5934 layer_tree_host()->SetRootLayer(nullptr);
5935 info_.page_scale_delta = 3.14f;
5936 info_.top_controls_delta = 2.73f;
5938 PostSetNeedsCommitToMainThread();
5941 void BeginMainFrame(const BeginFrameArgs& args) override {
5942 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
5944 layer_tree_host()->ApplyScrollAndScale(&info_);
5945 EndTest();
5948 void ApplyViewportDeltas(const gfx::Vector2dF& inner,
5949 const gfx::Vector2dF& outer,
5950 const gfx::Vector2dF& elastic_overscroll_delta,
5951 float scale_delta,
5952 float top_controls_delta) override {
5953 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5954 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5955 deltas_sent_to_client_ = true;
5958 void ApplyViewportDeltas(
5959 const gfx::Vector2d& scroll,
5960 float scale_delta,
5961 float top_controls_delta) override {
5962 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5963 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5964 deltas_sent_to_client_ = true;
5967 void AfterTest() override {
5968 EXPECT_TRUE(deltas_sent_to_client_);
5971 ScrollAndScaleSet info_;
5972 bool deltas_sent_to_client_;
5975 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5977 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
5978 protected:
5979 LayerTreeHostTestCrispUpAfterPinchEnds()
5980 : playback_allowed_event_(true, true) {}
5982 void SetupTree() override {
5983 frame_ = 1;
5984 posted_ = false;
5985 client_.set_fill_with_nonsolid_color(true);
5987 scoped_refptr<Layer> root = Layer::Create();
5988 root->SetBounds(gfx::Size(500, 500));
5990 scoped_refptr<Layer> pinch = Layer::Create();
5991 pinch->SetBounds(gfx::Size(500, 500));
5992 pinch->SetScrollClipLayerId(root->id());
5993 pinch->SetIsContainerForFixedPositionLayers(true);
5994 root->AddChild(pinch);
5996 scoped_ptr<FakePicturePile> pile(
5997 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5998 ImplSidePaintingSettings().default_tile_grid_size));
5999 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
6000 scoped_refptr<FakePictureLayer> layer =
6001 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6002 layer->SetBounds(gfx::Size(500, 500));
6003 layer->SetContentsOpaque(true);
6004 // Avoid LCD text on the layer so we don't cause extra commits when we
6005 // pinch.
6006 layer->disable_lcd_text();
6007 pinch->AddChild(layer);
6009 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
6010 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6011 layer_tree_host()->SetRootLayer(root);
6012 LayerTreeHostTest::SetupTree();
6015 // Returns the delta scale of all quads in the frame's root pass from their
6016 // ideal, or 0 if they are not all the same.
6017 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6018 if (frame_data->has_no_damage)
6019 return 0.f;
6020 float frame_scale = 0.f;
6021 RenderPass* root_pass = frame_data->render_passes.back();
6022 for (const auto& draw_quad : root_pass->quad_list) {
6023 // Checkerboards mean an incomplete frame.
6024 if (draw_quad->material != DrawQuad::TILED_CONTENT)
6025 return 0.f;
6026 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
6027 float quad_scale =
6028 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6029 float transform_scale =
6030 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
6031 float scale = quad_scale / transform_scale;
6032 if (frame_scale != 0.f && frame_scale != scale)
6033 return 0.f;
6034 frame_scale = scale;
6036 return frame_scale;
6039 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6041 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6042 LayerTreeHostImpl::FrameData* frame_data,
6043 DrawResult draw_result) override {
6044 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6045 switch (frame_) {
6046 case 1:
6047 // Drew at page scale 1 before any pinching.
6048 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6049 EXPECT_EQ(1.f, quad_scale_delta);
6050 PostNextAfterDraw(host_impl);
6051 break;
6052 case 2:
6053 if (quad_scale_delta != 1.f)
6054 break;
6055 // Drew at page scale 1.5 after pinching in.
6056 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6057 EXPECT_EQ(1.f, quad_scale_delta);
6058 PostNextAfterDraw(host_impl);
6059 break;
6060 case 3:
6061 // By pinching out, we will create a new tiling and raster it. This may
6062 // cause some additional draws, though we should still be drawing with
6063 // the old 1.5 tiling.
6064 if (frame_data->has_no_damage)
6065 break;
6066 // Drew at page scale 1 with the 1.5 tiling while pinching out.
6067 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6068 EXPECT_EQ(1.5f, quad_scale_delta);
6069 // We don't PostNextAfterDraw here, instead we wait for the new tiling
6070 // to finish rastering so we don't get any noise in further steps.
6071 break;
6072 case 4:
6073 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
6074 // while waiting for texture uploads to complete.
6075 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6076 // This frame will not have any damage, since it's actually the same as
6077 // the last frame, and should contain no incomplete tiles. We just want
6078 // to make sure we drew here at least once after the pinch ended to be
6079 // sure that drawing after pinch doesn't leave us at the wrong scale
6080 EXPECT_TRUE(frame_data->has_no_damage);
6081 PostNextAfterDraw(host_impl);
6082 break;
6083 case 5:
6084 if (quad_scale_delta != 1.f)
6085 break;
6086 // Drew at scale 1 after texture uploads are done.
6087 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6088 EXPECT_EQ(1.f, quad_scale_delta);
6089 EndTest();
6090 break;
6092 return draw_result;
6095 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
6096 if (posted_)
6097 return;
6098 posted_ = true;
6099 ImplThreadTaskRunner()->PostDelayedTask(
6100 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
6101 base::Unretained(this), host_impl),
6102 // Use a delay to allow raster/upload to happen in between frames. This
6103 // should cause flakiness if we fail to block raster/upload when
6104 // desired.
6105 base::TimeDelta::FromMilliseconds(16 * 4));
6108 void Next(LayerTreeHostImpl* host_impl) {
6109 ++frame_;
6110 posted_ = false;
6111 switch (frame_) {
6112 case 2:
6113 // Pinch zoom in.
6114 host_impl->PinchGestureBegin();
6115 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6116 host_impl->PinchGestureEnd();
6117 break;
6118 case 3:
6119 // Pinch zoom back to 1.f but don't end it.
6120 host_impl->PinchGestureBegin();
6121 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
6122 break;
6123 case 4:
6124 // End the pinch, but delay tile production.
6125 playback_allowed_event_.Reset();
6126 host_impl->PinchGestureEnd();
6127 break;
6128 case 5:
6129 // Let tiles complete.
6130 playback_allowed_event_.Signal();
6131 break;
6135 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6136 const Tile* tile) override {
6137 if (frame_ == 3) {
6138 // On frame 3, we will have a lower res tile complete for the pinch-out
6139 // gesture even though it's not displayed. We wait for it here to prevent
6140 // flakiness.
6141 EXPECT_EQ(0.75f, tile->contents_scale());
6142 PostNextAfterDraw(host_impl);
6144 // On frame_ == 4, we are preventing texture uploads from completing,
6145 // so this verifies they are not completing before frame_ == 5.
6146 // Flaky failures here indicate we're failing to prevent uploads from
6147 // completing.
6148 EXPECT_NE(4, frame_) << tile->contents_scale();
6151 void AfterTest() override {}
6153 FakeContentLayerClient client_;
6154 int frame_;
6155 bool posted_;
6156 base::WaitableEvent playback_allowed_event_;
6159 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
6161 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
6162 : public LayerTreeHostTestCrispUpAfterPinchEnds {
6163 protected:
6164 void InitializeSettings(LayerTreeSettings* settings) override {
6165 settings->use_one_copy = true;
6168 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
6169 scoped_ptr<TestWebGraphicsContext3D> context3d =
6170 TestWebGraphicsContext3D::Create();
6171 context3d->set_support_image(true);
6172 context3d->set_support_sync_query(true);
6173 #if defined(OS_MACOSX)
6174 context3d->set_support_texture_rectangle(true);
6175 #endif
6177 if (delegating_renderer())
6178 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
6179 else
6180 return FakeOutputSurface::Create3d(context3d.Pass());
6184 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
6186 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
6187 protected:
6188 RasterizeWithGpuRasterizationCreatesResources() {}
6190 void InitializeSettings(LayerTreeSettings* settings) override {
6191 settings->impl_side_painting = true;
6192 settings->gpu_rasterization_forced = true;
6195 void SetupTree() override {
6196 client_.set_fill_with_nonsolid_color(true);
6198 scoped_refptr<Layer> root = Layer::Create();
6199 root->SetBounds(gfx::Size(500, 500));
6201 scoped_ptr<FakePicturePile> pile(
6202 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6203 ImplSidePaintingSettings().default_tile_grid_size));
6204 scoped_refptr<FakePictureLayer> layer =
6205 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6206 layer->SetBounds(gfx::Size(500, 500));
6207 layer->SetContentsOpaque(true);
6208 root->AddChild(layer);
6210 layer_tree_host()->SetRootLayer(root);
6211 LayerTreeHostTest::SetupTree();
6214 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6216 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6217 LayerTreeHostImpl::FrameData* frame_data,
6218 DrawResult draw_result) override {
6219 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
6220 EndTest();
6221 return draw_result;
6223 void AfterTest() override {}
6225 FakeContentLayerClient client_;
6228 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
6230 class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
6231 protected:
6232 GpuRasterizationRasterizesBorderTiles() : viewport_size_(1024, 2048) {}
6234 void InitializeSettings(LayerTreeSettings* settings) override {
6235 settings->impl_side_painting = true;
6236 settings->gpu_rasterization_enabled = true;
6237 settings->gpu_rasterization_forced = true;
6240 void SetupTree() override {
6241 client_.set_fill_with_nonsolid_color(true);
6243 scoped_ptr<FakePicturePile> pile(
6244 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6245 ImplSidePaintingSettings().default_tile_grid_size));
6246 scoped_refptr<FakePictureLayer> root =
6247 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6248 root->SetBounds(gfx::Size(10000, 10000));
6249 root->SetContentsOpaque(true);
6251 layer_tree_host()->SetRootLayer(root);
6252 LayerTreeHostTest::SetupTree();
6253 layer_tree_host()->SetViewportSize(viewport_size_);
6256 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6258 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6259 LayerTreeHostImpl::FrameData* frame_data,
6260 DrawResult draw_result) override {
6261 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources());
6262 EndTest();
6263 return draw_result;
6266 void AfterTest() override {}
6268 private:
6269 FakeContentLayerClient client_;
6270 gfx::Size viewport_size_;
6273 MULTI_THREAD_IMPL_TEST_F(GpuRasterizationRasterizesBorderTiles);
6275 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
6276 : public LayerTreeHostTest {
6277 protected:
6278 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
6279 : playback_allowed_event_(true, true) {}
6281 void InitializeSettings(LayerTreeSettings* settings) override {
6282 settings->impl_side_painting = true;
6285 void SetupTree() override {
6286 step_ = 1;
6287 continuous_draws_ = 0;
6288 client_.set_fill_with_nonsolid_color(true);
6290 scoped_refptr<Layer> root = Layer::Create();
6291 root->SetBounds(gfx::Size(500, 500));
6293 scoped_refptr<Layer> pinch = Layer::Create();
6294 pinch->SetBounds(gfx::Size(500, 500));
6295 pinch->SetScrollClipLayerId(root->id());
6296 pinch->SetIsContainerForFixedPositionLayers(true);
6297 root->AddChild(pinch);
6299 scoped_ptr<FakePicturePile> pile(
6300 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6301 ImplSidePaintingSettings().default_tile_grid_size));
6302 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
6303 scoped_refptr<FakePictureLayer> layer =
6304 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6305 layer->SetBounds(gfx::Size(500, 500));
6306 layer->SetContentsOpaque(true);
6307 // Avoid LCD text on the layer so we don't cause extra commits when we
6308 // pinch.
6309 layer->disable_lcd_text();
6310 pinch->AddChild(layer);
6312 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
6313 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6314 layer_tree_host()->SetRootLayer(root);
6315 LayerTreeHostTest::SetupTree();
6318 // Returns the delta scale of all quads in the frame's root pass from their
6319 // ideal, or 0 if they are not all the same.
6320 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6321 if (frame_data->has_no_damage)
6322 return 0.f;
6323 float frame_scale = 0.f;
6324 RenderPass* root_pass = frame_data->render_passes.back();
6325 for (const auto& draw_quad : root_pass->quad_list) {
6326 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
6327 float quad_scale =
6328 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6329 float transform_scale =
6330 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
6331 float scale = quad_scale / transform_scale;
6332 if (frame_scale != 0.f && frame_scale != scale)
6333 return 0.f;
6334 frame_scale = scale;
6336 return frame_scale;
6339 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6341 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6342 LayerTreeHostImpl::FrameData* frame_data,
6343 DrawResult draw_result) override {
6344 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6345 switch (step_) {
6346 case 1:
6347 // Drew at scale 1 before any pinching.
6348 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6349 EXPECT_EQ(1.f, quad_scale_delta);
6350 break;
6351 case 2:
6352 if (quad_scale_delta != 1.f / 1.5f)
6353 break;
6354 // Drew at scale 1 still though the ideal is 1.5.
6355 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6356 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6357 break;
6358 case 3:
6359 // Continuous draws are attempted.
6360 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6361 if (!frame_data->has_no_damage)
6362 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6363 break;
6364 case 4:
6365 if (quad_scale_delta != 1.f)
6366 break;
6367 // Drew at scale 1.5 when all the tiles completed.
6368 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6369 EXPECT_EQ(1.f, quad_scale_delta);
6370 break;
6371 case 5:
6372 // TODO(danakj): We get more draws before the NotifyReadyToDraw
6373 // because it is asynchronous from the previous draw and happens late.
6374 break;
6375 case 6:
6376 // NotifyReadyToDraw happened. If we were already inside a frame, we may
6377 // try to draw once more.
6378 break;
6379 case 7:
6380 NOTREACHED() << "No draws should happen once we have a complete frame.";
6381 break;
6383 return draw_result;
6386 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6387 switch (step_) {
6388 case 1:
6389 // Delay tile production.
6390 playback_allowed_event_.Reset();
6391 // Pinch zoom in to cause new tiles to be required.
6392 host_impl->PinchGestureBegin();
6393 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6394 host_impl->PinchGestureEnd();
6395 ++step_;
6396 break;
6397 case 2:
6398 ++step_;
6399 break;
6400 case 3:
6401 // We should continue to try draw while there are incomplete visible
6402 // tiles.
6403 if (++continuous_draws_ > 5) {
6404 // Allow the tiles to complete.
6405 playback_allowed_event_.Signal();
6406 ++step_;
6408 break;
6409 case 4:
6410 ++step_;
6411 break;
6412 case 5:
6413 // Waiting for NotifyReadyToDraw.
6414 break;
6415 case 6:
6416 // NotifyReadyToDraw happened.
6417 ++step_;
6418 break;
6422 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
6423 if (step_ == 5) {
6424 ++step_;
6425 // NotifyReadyToDraw has happened, we may draw once more, but should not
6426 // get any more draws after that. End the test after a timeout to watch
6427 // for any extraneous draws.
6428 // TODO(brianderson): We could remove this delay and instead wait until
6429 // the BeginFrameSource decides it doesn't need to send frames anymore,
6430 // or test that it already doesn't here.
6431 EndTestAfterDelayMs(16 * 4);
6435 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6436 const Tile* tile) override {
6437 // On step_ == 2, we are preventing texture uploads from completing,
6438 // so this verifies they are not completing before step_ == 3.
6439 // Flaky failures here indicate we're failing to prevent uploads from
6440 // completing.
6441 EXPECT_NE(2, step_);
6444 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
6446 FakeContentLayerClient client_;
6447 int step_;
6448 int continuous_draws_;
6449 base::WaitableEvent playback_allowed_event_;
6452 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
6454 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
6455 public:
6456 LayerTreeHostTestOneActivatePerPrepareTiles()
6457 : notify_ready_to_activate_count_(0u),
6458 scheduled_prepare_tiles_count_(0) {}
6460 void SetupTree() override {
6461 client_.set_fill_with_nonsolid_color(true);
6462 scoped_refptr<FakePictureLayer> root_layer =
6463 FakePictureLayer::Create(&client_);
6464 root_layer->SetBounds(gfx::Size(1500, 1500));
6465 root_layer->SetIsDrawable(true);
6467 layer_tree_host()->SetRootLayer(root_layer);
6468 LayerTreeHostTest::SetupTree();
6471 void BeginTest() override {
6472 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
6473 PostSetNeedsCommitToMainThread();
6476 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
6477 bool success) override {
6478 ASSERT_TRUE(success);
6479 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
6482 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6483 ++notify_ready_to_activate_count_;
6484 EndTestAfterDelayMs(100);
6487 void ScheduledActionPrepareTiles() override {
6488 ++scheduled_prepare_tiles_count_;
6491 void AfterTest() override {
6492 // Expect at most a notification for each scheduled prepare tiles, plus one
6493 // for the initial commit (which doesn't go through scheduled actions).
6494 // The reason this is not an equality is because depending on timing, we
6495 // might get a prepare tiles but not yet get a notification that we're
6496 // ready to activate. The intent of a test is to ensure that we don't
6497 // get more than one notification per prepare tiles, so this is OK.
6498 EXPECT_LE(notify_ready_to_activate_count_,
6499 1u + scheduled_prepare_tiles_count_);
6502 protected:
6503 FakeContentLayerClient client_;
6504 size_t notify_ready_to_activate_count_;
6505 size_t scheduled_prepare_tiles_count_;
6508 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
6510 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
6511 : public LayerTreeHostTest {
6512 public:
6513 LayerTreeHostTestFrameTimingRequestsSaveTimestamps()
6514 : check_results_on_commit_(false) {}
6516 void SetupTree() override {
6517 scoped_refptr<FakePictureLayer> root_layer =
6518 FakePictureLayer::Create(&client_);
6519 root_layer->SetBounds(gfx::Size(200, 200));
6520 root_layer->SetIsDrawable(true);
6522 scoped_refptr<FakePictureLayer> child_layer =
6523 FakePictureLayer::Create(&client_);
6524 child_layer->SetBounds(gfx::Size(1500, 1500));
6525 child_layer->SetIsDrawable(true);
6527 std::vector<FrameTimingRequest> requests;
6528 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100)));
6529 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100)));
6530 child_layer->SetFrameTimingRequests(requests);
6532 root_layer->AddChild(child_layer);
6533 layer_tree_host()->SetRootLayer(root_layer);
6534 LayerTreeHostTest::SetupTree();
6537 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6539 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
6540 if (!check_results_on_commit_)
6541 return;
6543 // Since in reality, the events will be read by LayerTreeHost during commit,
6544 // we check the requests here to ensure that they are correct at the next
6545 // commit time (as opposed to checking in DrawLayers for instance).
6546 // TODO(vmpstr): Change this to read things from the main thread when this
6547 // information is propagated to the main thread (not yet implemented).
6548 FrameTimingTracker* tracker = host_impl->frame_timing_tracker();
6550 // Check composite events.
6552 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set =
6553 tracker->GroupCompositeCountsByRectId();
6554 EXPECT_EQ(1u, timing_set->size());
6555 auto rect_1_it = timing_set->find(1);
6556 EXPECT_TRUE(rect_1_it != timing_set->end());
6557 const auto& timing_events = rect_1_it->second;
6558 EXPECT_EQ(1u, timing_events.size());
6559 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6560 timing_events[0].frame_id);
6561 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6564 // Check main frame events.
6566 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> timing_set =
6567 tracker->GroupMainFrameCountsByRectId();
6568 EXPECT_EQ(2u, timing_set->size());
6569 auto rect_1_it = timing_set->find(1);
6570 EXPECT_TRUE(rect_1_it != timing_set->end());
6571 const auto& timing_events = rect_1_it->second;
6572 EXPECT_EQ(1u, timing_events.size());
6573 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6574 timing_events[0].frame_id);
6575 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6576 EXPECT_GT(timing_events[0].end_time, timing_events[0].timestamp);
6579 EndTest();
6582 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6583 check_results_on_commit_ = true;
6584 PostSetNeedsCommitToMainThread();
6587 void AfterTest() override {}
6589 private:
6590 FakeContentLayerClient client_;
6591 bool check_results_on_commit_;
6594 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
6596 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
6597 public:
6598 LayerTreeHostTestActivationCausesPrepareTiles()
6599 : scheduled_prepare_tiles_count_(0) {}
6601 void SetupTree() override {
6602 client_.set_fill_with_nonsolid_color(true);
6603 scoped_refptr<FakePictureLayer> root_layer =
6604 FakePictureLayer::Create(&client_);
6605 root_layer->SetBounds(gfx::Size(150, 150));
6606 root_layer->SetIsDrawable(true);
6608 layer_tree_host()->SetRootLayer(root_layer);
6609 LayerTreeHostTest::SetupTree();
6612 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6614 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6615 // Ensure we've already activated.
6616 EXPECT_FALSE(impl->pending_tree());
6618 // After activating, we either need to prepare tiles, or we've already
6619 // called a scheduled prepare tiles. This is done because activation might
6620 // cause us to have to memory available (old active tree is gone), so we
6621 // need to ensure we will get a PrepareTiles call.
6622 if (!impl->prepare_tiles_needed())
6623 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
6624 EndTest();
6627 void ScheduledActionPrepareTiles() override {
6628 ++scheduled_prepare_tiles_count_;
6631 void AfterTest() override {}
6633 protected:
6634 FakeContentLayerClient client_;
6635 int scheduled_prepare_tiles_count_;
6638 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
6640 // This tests an assertion that DidCommit and WillCommit happen in the same
6641 // stack frame with no tasks that run between them. Various embedders of
6642 // cc depend on this logic. ui::Compositor holds a compositor lock between
6643 // these events and the inspector timeline wants begin/end CompositeLayers
6644 // to be properly nested with other begin/end events.
6645 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
6646 : public LayerTreeHostTest {
6647 public:
6648 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
6650 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6652 void WillCommit() override {
6653 MainThreadTaskRunner()->PostTask(
6654 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
6655 EndTestShouldRunAfterDidCommit,
6656 base::Unretained(this)));
6659 void EndTestShouldRunAfterDidCommit() {
6660 EXPECT_TRUE(did_commit_);
6661 EndTest();
6664 void DidCommit() override {
6665 EXPECT_FALSE(did_commit_);
6666 did_commit_ = true;
6669 void AfterTest() override { EXPECT_TRUE(did_commit_); }
6671 private:
6672 bool did_commit_;
6675 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
6677 // Verify that if a LayerImpl holds onto a copy request for multiple
6678 // frames that it will continue to have a render surface through
6679 // multiple commits, even though the Layer itself has no reason
6680 // to have a render surface.
6681 class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest {
6682 protected:
6683 void SetupTree() override {
6684 scoped_refptr<Layer> root = Layer::Create();
6685 root->CreateRenderSurface();
6686 root->SetBounds(gfx::Size(10, 10));
6687 child_ = Layer::Create();
6688 child_->SetBounds(gfx::Size(20, 20));
6689 root->AddChild(child_);
6691 layer_tree_host()->SetRootLayer(root);
6692 LayerTreeHostTest::SetupTree();
6695 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6697 void BeginTest() override {
6698 child_->RequestCopyOfOutput(
6699 CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback)));
6700 EXPECT_TRUE(child_->HasCopyRequest());
6701 PostSetNeedsCommitToMainThread();
6704 void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); }
6706 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6707 LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id());
6709 switch (host_impl->sync_tree()->source_frame_number()) {
6710 case 0:
6711 EXPECT_TRUE(child_impl->HasCopyRequest());
6712 EXPECT_TRUE(child_impl->render_surface());
6713 break;
6714 case 1:
6715 if (host_impl->proxy()->CommitToActiveTree()) {
6716 EXPECT_TRUE(child_impl->HasCopyRequest());
6717 EXPECT_TRUE(child_impl->render_surface());
6718 } else {
6719 EXPECT_FALSE(child_impl->HasCopyRequest());
6720 EXPECT_FALSE(child_impl->render_surface());
6722 break;
6723 default:
6724 NOTREACHED();
6725 break;
6729 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6730 LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id());
6731 EXPECT_TRUE(child_impl->HasCopyRequest());
6732 EXPECT_TRUE(child_impl->render_surface());
6734 switch (host_impl->active_tree()->source_frame_number()) {
6735 case 0:
6736 // Lose output surface to prevent drawing and cause another commit.
6737 host_impl->DidLoseOutputSurface();
6738 break;
6739 case 1:
6740 EndTest();
6741 break;
6742 default:
6743 NOTREACHED();
6744 break;
6748 void AfterTest() override {}
6750 private:
6751 scoped_refptr<Layer> child_;
6754 SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests);
6756 class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
6757 protected:
6758 void SetupTree() override {
6759 root = Layer::Create();
6760 child = Layer::Create();
6761 root->AddChild(child);
6762 layer_tree_host()->SetRootLayer(root);
6763 LayerTreeHostTest::SetupTree();
6766 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6768 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6770 void DidCommit() override {
6771 switch (layer_tree_host()->source_frame_number()) {
6772 case 1:
6773 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
6774 base::Bind(CopyOutputCallback)));
6775 EXPECT_TRUE(
6776 root->draw_properties().layer_or_descendant_has_copy_request);
6777 break;
6778 case 2:
6779 EXPECT_FALSE(
6780 root->draw_properties().layer_or_descendant_has_copy_request);
6781 EndTest();
6782 break;
6786 void AfterTest() override {}
6788 private:
6789 scoped_refptr<Layer> root;
6790 scoped_refptr<Layer> child;
6793 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
6795 class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
6796 protected:
6797 void SetupTree() override {
6798 // The masked layer has bounds 50x50, but it has a child that causes
6799 // the surface bounds to be larger. It also has a parent that clips the
6800 // masked layer and its surface.
6802 scoped_refptr<Layer> root = Layer::Create();
6804 scoped_refptr<Layer> clipping_layer = Layer::Create();
6805 root->AddChild(clipping_layer);
6807 scoped_refptr<FakePictureLayer> content_layer =
6808 FakePictureLayer::Create(&client_);
6809 clipping_layer->AddChild(content_layer);
6811 scoped_refptr<FakePictureLayer> content_child_layer =
6812 FakePictureLayer::Create(&client_);
6813 content_layer->AddChild(content_child_layer);
6815 scoped_refptr<FakePictureLayer> mask_layer =
6816 FakePictureLayer::Create(&client_);
6817 content_layer->SetMaskLayer(mask_layer.get());
6819 gfx::Size root_size(100, 100);
6820 root->SetBounds(root_size);
6822 gfx::Rect clipping_rect(20, 10, 10, 20);
6823 clipping_layer->SetBounds(clipping_rect.size());
6824 clipping_layer->SetPosition(clipping_rect.origin());
6825 clipping_layer->SetMasksToBounds(true);
6827 gfx::Size layer_size(50, 50);
6828 content_layer->SetBounds(layer_size);
6829 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin());
6831 gfx::Size child_size(50, 50);
6832 content_child_layer->SetBounds(child_size);
6833 content_child_layer->SetPosition(gfx::Point(20, 0));
6835 gfx::Size mask_size(100, 100);
6836 mask_layer->SetBounds(mask_size);
6837 mask_layer->SetIsMask(true);
6839 layer_tree_host()->SetRootLayer(root);
6840 LayerTreeTest::SetupTree();
6843 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6845 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6846 LayerTreeHostImpl::FrameData* frame_data,
6847 DrawResult draw_result) override {
6848 EXPECT_EQ(2u, frame_data->render_passes.size());
6849 RenderPass* root_pass = frame_data->render_passes.back();
6850 EXPECT_EQ(2u, root_pass->quad_list.size());
6852 // There's a solid color quad under everything.
6853 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
6855 // The surface is clipped to 10x20.
6856 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
6857 const RenderPassDrawQuad* render_pass_quad =
6858 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
6859 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
6860 render_pass_quad->rect.ToString());
6861 // The masked layer is 50x50, but the surface size is 10x20. So the texture
6862 // coords in the mask are scaled by 10/50 and 20/50.
6863 // The surface is clipped to (20,10) so the mask texture coords are offset
6864 // by 20/50 and 10/50
6865 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
6866 .ToString(),
6867 render_pass_quad->MaskUVRect().ToString());
6868 EXPECT_EQ(gfx::Vector2dF(10.f / 50.f, 20.f / 50.f).ToString(),
6869 render_pass_quad->mask_uv_scale.ToString());
6870 EndTest();
6871 return draw_result;
6874 void AfterTest() override {}
6876 FakeContentLayerClient client_;
6879 SINGLE_AND_MULTI_THREAD_TEST_F(
6880 LayerTreeTestMaskLayerForSurfaceWithClippedLayer);
6882 class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
6883 protected:
6884 void InitializeSettings(LayerTreeSettings* settings) override {
6885 settings->layer_transforms_should_scale_layer_contents = true;
6888 void SetupTree() override {
6889 // Root
6890 // |
6891 // +-- Scaling Layer (adds a 2x scale)
6892 // |
6893 // +-- Content Layer
6894 // +--Mask
6896 scoped_refptr<Layer> root = Layer::Create();
6898 scoped_refptr<Layer> scaling_layer = Layer::Create();
6899 root->AddChild(scaling_layer);
6901 scoped_refptr<FakePictureLayer> content_layer =
6902 FakePictureLayer::Create(&client_);
6903 scaling_layer->AddChild(content_layer);
6905 scoped_refptr<FakePictureLayer> mask_layer =
6906 FakePictureLayer::Create(&client_);
6907 content_layer->SetMaskLayer(mask_layer.get());
6909 gfx::Size root_size(100, 100);
6910 root->SetBounds(root_size);
6912 gfx::Size scaling_layer_size(50, 50);
6913 scaling_layer->SetBounds(scaling_layer_size);
6914 gfx::Transform scale;
6915 scale.Scale(2.f, 2.f);
6916 scaling_layer->SetTransform(scale);
6918 content_layer->SetBounds(scaling_layer_size);
6920 mask_layer->SetBounds(scaling_layer_size);
6921 mask_layer->SetIsMask(true);
6923 layer_tree_host()->SetRootLayer(root);
6924 LayerTreeTest::SetupTree();
6927 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6929 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6930 LayerTreeHostImpl::FrameData* frame_data,
6931 DrawResult draw_result) override {
6932 EXPECT_EQ(2u, frame_data->render_passes.size());
6933 RenderPass* root_pass = frame_data->render_passes.back();
6934 EXPECT_EQ(2u, root_pass->quad_list.size());
6936 // There's a solid color quad under everything.
6937 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
6939 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
6940 const RenderPassDrawQuad* render_pass_quad =
6941 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
6942 switch (host_impl->active_tree()->source_frame_number()) {
6943 case 0:
6944 // Check that the tree scaling is correctly taken into account for the
6945 // mask, that should fully map onto the quad.
6946 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
6947 render_pass_quad->rect.ToString());
6948 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
6949 render_pass_quad->MaskUVRect().ToString());
6950 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
6951 render_pass_quad->mask_uv_scale.ToString());
6952 break;
6953 case 1:
6954 // Applying a DSF should change the render surface size, but won't
6955 // affect which part of the mask is used.
6956 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
6957 render_pass_quad->rect.ToString());
6958 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
6959 render_pass_quad->MaskUVRect().ToString());
6960 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
6961 render_pass_quad->mask_uv_scale.ToString());
6962 EndTest();
6963 break;
6965 return draw_result;
6968 void DidCommit() override {
6969 switch (layer_tree_host()->source_frame_number()) {
6970 case 1:
6971 gfx::Size double_root_size(200, 200);
6972 layer_tree_host()->SetViewportSize(double_root_size);
6973 layer_tree_host()->SetDeviceScaleFactor(2.f);
6974 break;
6978 void AfterTest() override {}
6980 FakeContentLayerClient client_;
6983 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling);
6985 class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest {
6986 protected:
6987 void SetupTree() override {
6988 // The mask layer has bounds 100x100 but is attached to a layer with bounds
6989 // 50x50.
6991 scoped_refptr<Layer> root = Layer::Create();
6993 scoped_refptr<FakePictureLayer> content_layer =
6994 FakePictureLayer::Create(&client_);
6995 root->AddChild(content_layer);
6997 scoped_refptr<FakePictureLayer> mask_layer =
6998 FakePictureLayer::Create(&client_);
6999 content_layer->SetMaskLayer(mask_layer.get());
7001 gfx::Size root_size(100, 100);
7002 root->SetBounds(root_size);
7004 gfx::Size layer_size(50, 50);
7005 content_layer->SetBounds(layer_size);
7007 gfx::Size mask_size(100, 100);
7008 mask_layer->SetBounds(mask_size);
7009 mask_layer->SetIsMask(true);
7011 layer_tree_host()->SetRootLayer(root);
7012 LayerTreeTest::SetupTree();
7015 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7017 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7018 LayerTreeHostImpl::FrameData* frame_data,
7019 DrawResult draw_result) override {
7020 EXPECT_EQ(2u, frame_data->render_passes.size());
7021 RenderPass* root_pass = frame_data->render_passes.back();
7022 EXPECT_EQ(2u, root_pass->quad_list.size());
7024 // There's a solid color quad under everything.
7025 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7027 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
7028 const RenderPassDrawQuad* render_pass_quad =
7029 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
7030 switch (host_impl->active_tree()->source_frame_number()) {
7031 case 0:
7032 // Check that the mask fills the surface.
7033 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
7034 render_pass_quad->rect.ToString());
7035 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7036 render_pass_quad->MaskUVRect().ToString());
7037 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7038 render_pass_quad->mask_uv_scale.ToString());
7039 break;
7040 case 1:
7041 // Applying a DSF should change the render surface size, but won't
7042 // affect which part of the mask is used.
7043 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
7044 render_pass_quad->rect.ToString());
7045 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7046 render_pass_quad->MaskUVRect().ToString());
7047 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7048 render_pass_quad->mask_uv_scale.ToString());
7049 EndTest();
7050 break;
7052 return draw_result;
7055 void DidCommit() override {
7056 switch (layer_tree_host()->source_frame_number()) {
7057 case 1:
7058 gfx::Size double_root_size(200, 200);
7059 layer_tree_host()->SetViewportSize(double_root_size);
7060 layer_tree_host()->SetDeviceScaleFactor(2.f);
7061 break;
7065 void AfterTest() override {}
7067 FakeContentLayerClient client_;
7070 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithDifferentBounds);
7072 class LayerTreeTestReflectionMaskLayerWithDifferentBounds
7073 : public LayerTreeTest {
7074 protected:
7075 void SetupTree() override {
7076 // The replica's mask layer has bounds 100x100 but the replica is of a
7077 // layer with bounds 50x50.
7079 scoped_refptr<Layer> root = Layer::Create();
7081 scoped_refptr<FakePictureLayer> content_layer =
7082 FakePictureLayer::Create(&client_);
7083 root->AddChild(content_layer);
7085 scoped_refptr<Layer> replica_layer = Layer::Create();
7086 content_layer->SetReplicaLayer(replica_layer.get());
7088 scoped_refptr<FakePictureLayer> mask_layer =
7089 FakePictureLayer::Create(&client_);
7090 replica_layer->SetMaskLayer(mask_layer.get());
7092 gfx::Size root_size(100, 100);
7093 root->SetBounds(root_size);
7095 gfx::Size layer_size(50, 50);
7096 content_layer->SetBounds(layer_size);
7098 gfx::Size mask_size(100, 100);
7099 mask_layer->SetBounds(mask_size);
7100 mask_layer->SetIsMask(true);
7102 layer_tree_host()->SetRootLayer(root);
7103 LayerTreeTest::SetupTree();
7106 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7108 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7109 LayerTreeHostImpl::FrameData* frame_data,
7110 DrawResult draw_result) override {
7111 EXPECT_EQ(2u, frame_data->render_passes.size());
7112 RenderPass* root_pass = frame_data->render_passes.back();
7113 EXPECT_EQ(3u, root_pass->quad_list.size());
7115 // There's a solid color quad under everything.
7116 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7118 EXPECT_EQ(DrawQuad::RENDER_PASS,
7119 root_pass->quad_list.ElementAt(1)->material);
7120 const RenderPassDrawQuad* render_pass_quad =
7121 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.ElementAt(1));
7122 switch (host_impl->active_tree()->source_frame_number()) {
7123 case 0:
7124 // Check that the mask fills the surface.
7125 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
7126 render_pass_quad->rect.ToString());
7127 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7128 render_pass_quad->MaskUVRect().ToString());
7129 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7130 render_pass_quad->mask_uv_scale.ToString());
7131 break;
7132 case 1:
7133 // Applying a DSF should change the render surface size, but won't
7134 // affect which part of the mask is used.
7135 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
7136 render_pass_quad->rect.ToString());
7137 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7138 render_pass_quad->MaskUVRect().ToString());
7139 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7140 render_pass_quad->mask_uv_scale.ToString());
7141 EndTest();
7142 break;
7144 return draw_result;
7147 void DidCommit() override {
7148 switch (layer_tree_host()->source_frame_number()) {
7149 case 1:
7150 gfx::Size double_root_size(200, 200);
7151 layer_tree_host()->SetViewportSize(double_root_size);
7152 layer_tree_host()->SetDeviceScaleFactor(2.f);
7153 break;
7157 void AfterTest() override {}
7159 FakeContentLayerClient client_;
7162 SINGLE_AND_MULTI_THREAD_TEST_F(
7163 LayerTreeTestReflectionMaskLayerWithDifferentBounds);
7165 class LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild
7166 : public LayerTreeTest {
7167 protected:
7168 void SetupTree() override {
7169 // The replica is of a layer with bounds 50x50, but it has a child that
7170 // causes the surface bounds to be larger.
7172 scoped_refptr<Layer> root = Layer::Create();
7174 scoped_refptr<FakePictureLayer> content_layer =
7175 FakePictureLayer::Create(&client_);
7176 root->AddChild(content_layer);
7178 content_child_layer_ = FakePictureLayer::Create(&client_);
7179 content_layer->AddChild(content_child_layer_);
7181 scoped_refptr<Layer> replica_layer = Layer::Create();
7182 content_layer->SetReplicaLayer(replica_layer.get());
7184 scoped_refptr<FakePictureLayer> mask_layer =
7185 FakePictureLayer::Create(&client_);
7186 replica_layer->SetMaskLayer(mask_layer.get());
7188 gfx::Size root_size(100, 100);
7189 root->SetBounds(root_size);
7191 gfx::Size layer_size(50, 50);
7192 content_layer->SetBounds(layer_size);
7193 content_child_layer_->SetBounds(layer_size);
7194 content_child_layer_->SetPosition(gfx::PointF(50.f, 0.f));
7196 gfx::Size mask_size(100, 100);
7197 mask_layer->SetBounds(mask_size);
7198 mask_layer->SetIsMask(true);
7200 layer_tree_host()->SetRootLayer(root);
7201 LayerTreeTest::SetupTree();
7204 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7206 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7207 LayerTreeHostImpl::FrameData* frame_data,
7208 DrawResult draw_result) override {
7209 EXPECT_EQ(2u, frame_data->render_passes.size());
7210 RenderPass* root_pass = frame_data->render_passes.back();
7211 EXPECT_EQ(3u, root_pass->quad_list.size());
7213 // There's a solid color quad under everything.
7214 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7216 EXPECT_EQ(DrawQuad::RENDER_PASS,
7217 root_pass->quad_list.ElementAt(1)->material);
7218 const RenderPassDrawQuad* replica_quad =
7219 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.ElementAt(1));
7220 switch (host_impl->active_tree()->source_frame_number()) {
7221 case 0:
7222 // The surface is 100x50.
7223 // The mask covers the owning layer only.
7224 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
7225 replica_quad->rect.ToString());
7226 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
7227 replica_quad->MaskUVRect().ToString());
7228 EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
7229 replica_quad->mask_uv_scale.ToString());
7230 break;
7231 case 1:
7232 // The surface is 100x50 with its origin at (-50, 0).
7233 // The mask covers the owning layer only.
7234 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
7235 replica_quad->rect.ToString());
7236 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
7237 replica_quad->MaskUVRect().ToString());
7238 EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
7239 replica_quad->mask_uv_scale.ToString());
7240 EndTest();
7241 break;
7243 return draw_result;
7246 void DidCommit() override {
7247 switch (layer_tree_host()->source_frame_number()) {
7248 case 1:
7249 // Move the child to (-50, 0) instead. Now the mask should be moved to
7250 // still cover the layer being replicated.
7251 content_child_layer_->SetPosition(gfx::PointF(-50.f, 0.f));
7252 break;
7256 void AfterTest() override {}
7258 scoped_refptr<FakePictureLayer> content_child_layer_;
7259 FakeContentLayerClient client_;
7262 SINGLE_AND_MULTI_THREAD_TEST_F(
7263 LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild);
7265 } // namespace cc