Add Apps.AppListSearchQueryLength UMA histogram.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob51ea3d91a69aba3cdad2746c61acb6849d9c2e2f
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_swap_called(false),
4931 did_not_swap_called(false),
4932 dtor_called(false),
4933 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4935 bool did_swap_called;
4936 bool did_not_swap_called;
4937 bool dtor_called;
4938 SwapPromise::DidNotSwapReason reason;
4939 base::Lock lock;
4942 class TestSwapPromise : public SwapPromise {
4943 public:
4944 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4946 ~TestSwapPromise() override {
4947 base::AutoLock lock(result_->lock);
4948 result_->dtor_called = true;
4951 void DidSwap(CompositorFrameMetadata* metadata) override {
4952 base::AutoLock lock(result_->lock);
4953 EXPECT_FALSE(result_->did_swap_called);
4954 EXPECT_FALSE(result_->did_not_swap_called);
4955 result_->did_swap_called = true;
4958 void DidNotSwap(DidNotSwapReason reason) override {
4959 base::AutoLock lock(result_->lock);
4960 EXPECT_FALSE(result_->did_swap_called);
4961 EXPECT_FALSE(result_->did_not_swap_called);
4962 result_->did_not_swap_called = true;
4963 result_->reason = reason;
4966 int64 TraceId() const override { return 0; }
4968 private:
4969 // Not owned.
4970 TestSwapPromiseResult* result_;
4973 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4974 protected:
4975 LayerTreeHostTestBreakSwapPromise()
4976 : commit_count_(0), commit_complete_count_(0) {}
4978 void WillBeginMainFrame() override {
4979 ASSERT_LE(commit_count_, 2);
4980 scoped_ptr<SwapPromise> swap_promise(
4981 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4982 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4985 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4987 void DidCommit() override {
4988 commit_count_++;
4989 if (commit_count_ == 2) {
4990 // This commit will finish.
4991 layer_tree_host()->SetNeedsCommit();
4995 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4996 commit_complete_count_++;
4997 if (commit_complete_count_ == 1) {
4998 // This commit will be aborted because no actual update.
4999 PostSetNeedsUpdateLayersToMainThread();
5000 } else {
5001 EndTest();
5005 void AfterTest() override {
5006 // 3 commits are scheduled. 2 completes. 1 is aborted.
5007 EXPECT_EQ(commit_count_, 3);
5008 EXPECT_EQ(commit_complete_count_, 2);
5011 // The first commit completes and causes swap buffer which finishes
5012 // the promise.
5013 base::AutoLock lock(swap_promise_result_[0].lock);
5014 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5015 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5016 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5020 // The second commit is aborted since it contains no updates.
5021 base::AutoLock lock(swap_promise_result_[1].lock);
5022 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5023 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5024 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
5025 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5029 // The last commit completes but it does not cause swap buffer because
5030 // there is no damage in the frame data.
5031 base::AutoLock lock(swap_promise_result_[2].lock);
5032 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5033 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5034 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5035 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5039 int commit_count_;
5040 int commit_complete_count_;
5041 TestSwapPromiseResult swap_promise_result_[3];
5044 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
5046 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
5047 public:
5048 LayerTreeHostTestKeepSwapPromise() {}
5050 void BeginTest() override {
5051 layer_ = SolidColorLayer::Create();
5052 layer_->SetIsDrawable(true);
5053 layer_->SetBounds(gfx::Size(10, 10));
5054 layer_tree_host()->SetRootLayer(layer_);
5055 gfx::Size bounds(100, 100);
5056 layer_tree_host()->SetViewportSize(bounds);
5057 PostSetNeedsCommitToMainThread();
5060 void DidCommit() override {
5061 MainThreadTaskRunner()->PostTask(
5062 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
5063 base::Unretained(this)));
5066 void ChangeFrame() {
5067 switch (layer_tree_host()->source_frame_number()) {
5068 case 1:
5069 layer_->SetBounds(gfx::Size(10, 11));
5070 layer_tree_host()->QueueSwapPromise(
5071 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
5072 break;
5073 case 2:
5074 break;
5075 default:
5076 NOTREACHED();
5077 break;
5081 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
5082 EXPECT_TRUE(result);
5083 if (host_impl->active_tree()->source_frame_number() >= 1) {
5084 // The commit changes layers so it should cause a swap.
5085 base::AutoLock lock(swap_promise_result_.lock);
5086 EXPECT_TRUE(swap_promise_result_.did_swap_called);
5087 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5088 EXPECT_TRUE(swap_promise_result_.dtor_called);
5089 EndTest();
5093 void AfterTest() override {}
5095 private:
5096 scoped_refptr<Layer> layer_;
5097 TestSwapPromiseResult swap_promise_result_;
5100 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
5102 class LayerTreeHostTestBreakSwapPromiseForVisibility
5103 : public LayerTreeHostTest {
5104 protected:
5105 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5107 void SetVisibleFalseAndQueueSwapPromise() {
5108 layer_tree_host()->SetVisible(false);
5109 scoped_ptr<SwapPromise> swap_promise(
5110 new TestSwapPromise(&swap_promise_result_));
5111 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5114 void ScheduledActionWillSendBeginMainFrame() override {
5115 MainThreadTaskRunner()->PostTask(
5116 FROM_HERE,
5117 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility
5118 ::SetVisibleFalseAndQueueSwapPromise,
5119 base::Unretained(this)));
5122 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5123 CommitEarlyOutReason reason) override {
5124 EndTest();
5127 void AfterTest() override {
5129 base::AutoLock lock(swap_promise_result_.lock);
5130 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5131 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5132 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5133 EXPECT_TRUE(swap_promise_result_.dtor_called);
5137 TestSwapPromiseResult swap_promise_result_;
5140 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
5142 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest {
5143 protected:
5144 LayerTreeHostTestBreakSwapPromiseForContext()
5145 : output_surface_lost_triggered_(false) {
5148 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5150 void LoseOutputSurfaceAndQueueSwapPromise() {
5151 layer_tree_host()->DidLoseOutputSurface();
5152 scoped_ptr<SwapPromise> swap_promise(
5153 new TestSwapPromise(&swap_promise_result_));
5154 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5157 void ScheduledActionWillSendBeginMainFrame() override {
5158 if (output_surface_lost_triggered_)
5159 return;
5160 output_surface_lost_triggered_ = true;
5162 MainThreadTaskRunner()->PostTask(
5163 FROM_HERE,
5164 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext
5165 ::LoseOutputSurfaceAndQueueSwapPromise,
5166 base::Unretained(this)));
5169 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5170 CommitEarlyOutReason reason) override {
5171 // This is needed so that the impl-thread state matches main-thread state.
5172 host_impl->DidLoseOutputSurface();
5173 EndTest();
5176 void AfterTest() override {
5178 base::AutoLock lock(swap_promise_result_.lock);
5179 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5180 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5181 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5182 EXPECT_TRUE(swap_promise_result_.dtor_called);
5186 bool output_surface_lost_triggered_;
5187 TestSwapPromiseResult swap_promise_result_;
5190 SINGLE_AND_MULTI_THREAD_TEST_F(
5191 LayerTreeHostTestBreakSwapPromiseForContext);
5193 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
5194 public:
5195 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
5196 LayerTreeHostImpl* layer_tree_host_impl,
5197 int* set_needs_commit_count,
5198 int* set_needs_redraw_count)
5199 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
5200 set_needs_commit_count_(set_needs_commit_count) {}
5202 ~SimpleSwapPromiseMonitor() override {}
5204 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
5206 void OnSetNeedsRedrawOnImpl() override {
5207 ADD_FAILURE() << "Should not get called on main thread.";
5210 void OnForwardScrollUpdateToMainThreadOnImpl() override {
5211 ADD_FAILURE() << "Should not get called on main thread.";
5214 private:
5215 int* set_needs_commit_count_;
5218 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
5219 public:
5220 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5222 void WillBeginMainFrame() override {
5223 if (TestEnded())
5224 return;
5226 int set_needs_commit_count = 0;
5227 int set_needs_redraw_count = 0;
5230 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5231 new SimpleSwapPromiseMonitor(layer_tree_host(),
5232 NULL,
5233 &set_needs_commit_count,
5234 &set_needs_redraw_count));
5235 layer_tree_host()->SetNeedsCommit();
5236 EXPECT_EQ(1, set_needs_commit_count);
5237 EXPECT_EQ(0, set_needs_redraw_count);
5240 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
5241 // monitored.
5242 layer_tree_host()->SetNeedsCommit();
5243 EXPECT_EQ(1, set_needs_commit_count);
5244 EXPECT_EQ(0, set_needs_redraw_count);
5247 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5248 new SimpleSwapPromiseMonitor(layer_tree_host(),
5249 NULL,
5250 &set_needs_commit_count,
5251 &set_needs_redraw_count));
5252 layer_tree_host()->SetNeedsUpdateLayers();
5253 EXPECT_EQ(2, set_needs_commit_count);
5254 EXPECT_EQ(0, set_needs_redraw_count);
5258 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5259 new SimpleSwapPromiseMonitor(layer_tree_host(),
5260 NULL,
5261 &set_needs_commit_count,
5262 &set_needs_redraw_count));
5263 layer_tree_host()->SetNeedsAnimate();
5264 EXPECT_EQ(3, set_needs_commit_count);
5265 EXPECT_EQ(0, set_needs_redraw_count);
5268 EndTest();
5271 void AfterTest() override {}
5274 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
5276 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
5277 : public LayerTreeHostTest {
5278 protected:
5279 void InitializeSettings(LayerTreeSettings* settings) override {
5280 settings->impl_side_painting = true;
5283 void SetupTree() override {
5284 LayerTreeHostTest::SetupTree();
5285 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
5288 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5290 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5291 host_impl->EvictAllUIResources();
5292 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
5293 // mode. Active tree should require high-res to draw after entering this
5294 // mode to ensure that high-res tiles are also required for a pending tree
5295 // to be activated.
5296 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5299 void DidCommit() override {
5300 int frame = layer_tree_host()->source_frame_number();
5301 switch (frame) {
5302 case 1:
5303 PostSetNeedsCommitToMainThread();
5304 break;
5305 case 2:
5306 ui_resource_ = nullptr;
5307 EndTest();
5308 break;
5312 void AfterTest() override {}
5314 FakeContentLayerClient client_;
5315 scoped_ptr<FakeScopedUIResource> ui_resource_;
5318 // This test is flaky, see http://crbug.com/386199
5319 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
5321 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
5322 protected:
5323 void InitializeSettings(LayerTreeSettings* settings) override {
5324 settings->impl_side_painting = true;
5326 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5327 EXPECT_FALSE(settings->gpu_rasterization_forced);
5330 void SetupTree() override {
5331 LayerTreeHostTest::SetupTree();
5333 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5334 layer->SetBounds(gfx::Size(10, 10));
5335 layer->SetIsDrawable(true);
5336 layer_tree_host()->root_layer()->AddChild(layer);
5339 void BeginTest() override {
5340 Layer* root = layer_tree_host()->root_layer();
5341 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5342 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5344 // Verify default values.
5345 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5346 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5347 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5348 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5350 // Setting gpu rasterization trigger does not enable gpu rasterization.
5351 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5352 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5354 PostSetNeedsCommitToMainThread();
5357 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5358 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5359 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5362 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5363 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5364 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5365 EndTest();
5368 void AfterTest() override {}
5370 FakeContentLayerClient layer_client_;
5373 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
5375 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
5376 protected:
5377 void InitializeSettings(LayerTreeSettings* settings) override {
5378 settings->impl_side_painting = true;
5380 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5381 settings->gpu_rasterization_enabled = true;
5384 void SetupTree() override {
5385 LayerTreeHostTest::SetupTree();
5387 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5388 layer->SetBounds(gfx::Size(10, 10));
5389 layer->SetIsDrawable(true);
5390 layer_tree_host()->root_layer()->AddChild(layer);
5393 void BeginTest() override {
5394 Layer* root = layer_tree_host()->root_layer();
5395 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5396 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5398 // Verify default values.
5399 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5400 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5401 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5402 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5404 // Gpu rasterization trigger is relevant.
5405 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5406 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5408 // Content-based veto is relevant as well.
5409 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5410 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5411 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5412 // Veto will take effect when layers are updated.
5413 // The results will be verified after commit is completed below.
5414 // Since we are manually marking picture pile as unsuitable,
5415 // make sure that the layer gets a chance to update.
5416 layer->SetNeedsDisplay();
5417 PostSetNeedsCommitToMainThread();
5420 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5421 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5422 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5425 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5426 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5427 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5428 EndTest();
5431 void AfterTest() override {}
5433 FakeContentLayerClient layer_client_;
5436 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
5438 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
5439 protected:
5440 void InitializeSettings(LayerTreeSettings* settings) override {
5441 ASSERT_TRUE(settings->impl_side_painting);
5443 EXPECT_FALSE(settings->gpu_rasterization_forced);
5444 settings->gpu_rasterization_forced = true;
5447 void SetupTree() override {
5448 LayerTreeHostTest::SetupTree();
5450 scoped_refptr<FakePictureLayer> layer =
5451 FakePictureLayer::Create(&layer_client_);
5452 layer->SetBounds(gfx::Size(10, 10));
5453 layer->SetIsDrawable(true);
5454 layer_tree_host()->root_layer()->AddChild(layer);
5457 void BeginTest() override {
5458 Layer* root = layer_tree_host()->root_layer();
5459 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5460 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5462 // Verify default values.
5463 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5464 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5465 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5466 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5468 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
5469 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5470 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5472 // Content-based veto is irrelevant as well.
5473 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5474 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5475 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5476 // Veto will take effect when layers are updated.
5477 // The results will be verified after commit is completed below.
5478 // Since we are manually marking picture pile as unsuitable,
5479 // make sure that the layer gets a chance to update.
5480 layer->SetNeedsDisplay();
5481 PostSetNeedsCommitToMainThread();
5484 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5485 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
5486 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5489 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5490 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
5491 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5492 EndTest();
5495 void AfterTest() override {}
5497 FakeContentLayerClient layer_client_;
5500 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
5502 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
5503 public:
5504 LayerTreeHostTestContinuousPainting()
5505 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
5507 protected:
5508 enum { kExpectedNumCommits = 10 };
5510 void SetupTree() override {
5511 scoped_refptr<Layer> root_layer = Layer::Create();
5512 root_layer->SetBounds(bounds_);
5513 root_layer->CreateRenderSurface();
5515 if (layer_tree_host()->settings().impl_side_painting) {
5516 picture_layer_ = FakePictureLayer::Create(&client_);
5517 child_layer_ = picture_layer_.get();
5518 } else {
5519 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
5520 child_layer_ = content_layer_.get();
5522 child_layer_->SetBounds(bounds_);
5523 child_layer_->SetIsDrawable(true);
5524 root_layer->AddChild(child_layer_);
5526 layer_tree_host()->SetRootLayer(root_layer);
5527 layer_tree_host()->SetViewportSize(bounds_);
5528 LayerTreeHostTest::SetupTree();
5531 void BeginTest() override {
5532 MainThreadTaskRunner()->PostTask(
5533 FROM_HERE,
5534 base::Bind(
5535 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
5536 base::Unretained(this)));
5537 // Wait 50x longer than expected.
5538 double milliseconds_per_frame =
5539 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
5540 MainThreadTaskRunner()->PostDelayedTask(
5541 FROM_HERE,
5542 base::Bind(
5543 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
5544 base::Unretained(this)),
5545 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
5546 milliseconds_per_frame));
5549 void BeginMainFrame(const BeginFrameArgs& args) override {
5550 child_layer_->SetNeedsDisplay();
5553 void AfterTest() override {
5554 EXPECT_LE(kExpectedNumCommits, num_commits_);
5555 EXPECT_LE(kExpectedNumCommits, num_draws_);
5556 int update_count = content_layer_.get()
5557 ? content_layer_->PaintContentsCount()
5558 : picture_layer_->update_count();
5559 EXPECT_LE(kExpectedNumCommits, update_count);
5562 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5563 if (++num_draws_ == kExpectedNumCommits)
5564 EndTest();
5567 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5568 ++num_commits_;
5571 private:
5572 void EnableContinuousPainting() {
5573 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5574 debug_state.continuous_painting = true;
5575 layer_tree_host()->SetDebugState(debug_state);
5578 void DisableContinuousPainting() {
5579 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5580 debug_state.continuous_painting = false;
5581 layer_tree_host()->SetDebugState(debug_state);
5582 EndTest();
5585 int num_commits_;
5586 int num_draws_;
5587 const gfx::Size bounds_;
5588 FakeContentLayerClient client_;
5589 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5590 scoped_refptr<FakePictureLayer> picture_layer_;
5591 Layer* child_layer_;
5594 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5596 class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
5597 : public LayerTreeHostTest {
5598 public:
5599 enum { kExpectedNumImplFrames = 10 };
5601 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame()
5602 : will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {}
5604 void BeginTest() override {
5605 // Kick off the test with a commit.
5606 PostSetNeedsCommitToMainThread();
5609 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
5610 const BeginFrameArgs& args) override {
5611 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5612 EXPECT_FALSE(TestEnded());
5613 will_begin_impl_frame_count_++;
5616 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
5617 did_finish_impl_frame_count_++;
5618 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5620 // Request a number of commits to cause multiple impl frames. We expect to
5621 // get one more impl frames than the number of commits requested because
5622 // after a commit it takes one frame to become idle.
5623 if (did_finish_impl_frame_count_ < kExpectedNumImplFrames - 1)
5624 PostSetNeedsCommitToMainThread();
5627 void SendBeginMainFrameNotExpectedSoon() override { EndTest(); }
5629 void AfterTest() override {
5630 EXPECT_GT(will_begin_impl_frame_count_, 0);
5631 EXPECT_GT(did_finish_impl_frame_count_, 0);
5632 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5634 // TODO(mithro): Figure out why the multithread version of this test
5635 // sometimes has one more frame then expected. Possibly related to
5636 // http://crbug.com/443185
5637 if (!HasImplThread()) {
5638 EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
5639 EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
5643 private:
5644 int will_begin_impl_frame_count_;
5645 int did_finish_impl_frame_count_;
5648 SINGLE_AND_MULTI_THREAD_TEST_F(
5649 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame);
5651 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
5652 public:
5653 LayerTreeHostTestSendBeginFramesToChildren()
5654 : begin_frame_sent_to_children_(false) {
5657 void BeginTest() override {
5658 // Kick off the test with a commit.
5659 PostSetNeedsCommitToMainThread();
5662 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5663 begin_frame_sent_to_children_ = true;
5664 EndTest();
5667 void DidBeginMainFrame() override {
5668 // Children requested BeginFrames.
5669 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5672 void AfterTest() override {
5673 // Ensure that BeginFrame message is sent to children during parent
5674 // scheduler handles its BeginFrame.
5675 EXPECT_TRUE(begin_frame_sent_to_children_);
5678 private:
5679 bool begin_frame_sent_to_children_;
5682 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
5684 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
5685 : public LayerTreeHostTest {
5686 public:
5687 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
5688 : begin_frame_sent_to_children_(false) {
5691 void InitializeSettings(LayerTreeSettings* settings) override {
5692 settings->use_external_begin_frame_source = true;
5695 void BeginTest() override {
5696 // Kick off the test with a commit.
5697 PostSetNeedsCommitToMainThread();
5700 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5701 begin_frame_sent_to_children_ = true;
5702 EndTest();
5705 void DidBeginMainFrame() override {
5706 // Children requested BeginFrames.
5707 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5710 void AfterTest() override {
5711 // Ensure that BeginFrame message is sent to children during parent
5712 // scheduler handles its BeginFrame.
5713 EXPECT_TRUE(begin_frame_sent_to_children_);
5716 private:
5717 bool begin_frame_sent_to_children_;
5720 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
5722 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5723 public:
5724 LayerTreeHostTestActivateOnInvisible()
5725 : activation_count_(0), visible_(true) {}
5727 void InitializeSettings(LayerTreeSettings* settings) override {
5728 settings->impl_side_painting = true;
5731 void BeginTest() override {
5732 // Kick off the test with a commit.
5733 PostSetNeedsCommitToMainThread();
5736 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5737 // Make sure we don't activate using the notify signal from tile manager.
5738 host_impl->BlockNotifyReadyToActivateForTesting(true);
5741 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5743 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5744 bool visible) override {
5745 visible_ = visible;
5747 // Once invisible, we can go visible again.
5748 if (!visible) {
5749 PostSetVisibleToMainThread(true);
5750 } else {
5751 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5752 EndTest();
5756 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5757 ++activation_count_;
5758 EXPECT_FALSE(visible_);
5761 void AfterTest() override {
5762 // Ensure we activated even though the signal was blocked.
5763 EXPECT_EQ(1, activation_count_);
5764 EXPECT_TRUE(visible_);
5767 private:
5768 int activation_count_;
5769 bool visible_;
5771 FakeContentLayerClient client_;
5772 scoped_refptr<FakePictureLayer> picture_layer_;
5775 // TODO(vmpstr): Enable with single thread impl-side painting.
5776 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5778 // Do a synchronous composite and assert that the swap promise succeeds.
5779 class LayerTreeHostTestSynchronousCompositeSwapPromise
5780 : public LayerTreeHostTest {
5781 public:
5782 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5784 void InitializeSettings(LayerTreeSettings* settings) override {
5785 settings->single_thread_proxy_scheduler = false;
5788 void BeginTest() override {
5789 // Successful composite.
5790 scoped_ptr<SwapPromise> swap_promise0(
5791 new TestSwapPromise(&swap_promise_result_[0]));
5792 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5793 layer_tree_host()->Composite(gfx::FrameTime::Now());
5795 // Fail to swap (no damage).
5796 scoped_ptr<SwapPromise> swap_promise1(
5797 new TestSwapPromise(&swap_promise_result_[1]));
5798 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5799 layer_tree_host()->SetNeedsCommit();
5800 layer_tree_host()->Composite(gfx::FrameTime::Now());
5802 // Fail to draw (not visible).
5803 scoped_ptr<SwapPromise> swap_promise2(
5804 new TestSwapPromise(&swap_promise_result_[2]));
5805 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5806 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5807 layer_tree_host()->SetVisible(false);
5808 layer_tree_host()->Composite(gfx::FrameTime::Now());
5810 EndTest();
5813 void DidCommit() override {
5814 commit_count_++;
5815 ASSERT_LE(commit_count_, 3);
5818 void AfterTest() override {
5819 EXPECT_EQ(3, commit_count_);
5821 // Initial swap promise should have succeded.
5823 base::AutoLock lock(swap_promise_result_[0].lock);
5824 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5825 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5826 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5829 // Second swap promise fails to swap.
5831 base::AutoLock lock(swap_promise_result_[1].lock);
5832 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5833 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5834 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5835 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5838 // Third swap promises also fails to swap (and draw).
5840 base::AutoLock lock(swap_promise_result_[2].lock);
5841 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5842 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5843 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5844 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5848 int commit_count_;
5849 TestSwapPromiseResult swap_promise_result_[3];
5852 // Impl-side painting is not supported for synchronous compositing.
5853 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
5855 // Make sure page scale and top control deltas are applied to the client even
5856 // when the LayerTreeHost doesn't have a root layer.
5857 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
5858 : public LayerTreeHostTest {
5859 public:
5860 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
5861 : deltas_sent_to_client_(false) {}
5863 void BeginTest() override {
5864 layer_tree_host()->SetRootLayer(nullptr);
5865 info_.page_scale_delta = 3.14f;
5866 info_.top_controls_delta = 2.73f;
5868 PostSetNeedsCommitToMainThread();
5871 void BeginMainFrame(const BeginFrameArgs& args) override {
5872 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
5874 layer_tree_host()->ApplyScrollAndScale(&info_);
5875 EndTest();
5878 void ApplyViewportDeltas(const gfx::Vector2dF& inner,
5879 const gfx::Vector2dF& outer,
5880 const gfx::Vector2dF& elastic_overscroll_delta,
5881 float scale_delta,
5882 float top_controls_delta) override {
5883 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5884 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5885 deltas_sent_to_client_ = true;
5888 void ApplyViewportDeltas(
5889 const gfx::Vector2d& scroll,
5890 float scale_delta,
5891 float top_controls_delta) override {
5892 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5893 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5894 deltas_sent_to_client_ = true;
5897 void AfterTest() override {
5898 EXPECT_TRUE(deltas_sent_to_client_);
5901 ScrollAndScaleSet info_;
5902 bool deltas_sent_to_client_;
5905 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5907 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
5908 protected:
5909 LayerTreeHostTestCrispUpAfterPinchEnds()
5910 : playback_allowed_event_(true, true) {}
5912 void SetupTree() override {
5913 frame_ = 1;
5914 posted_ = false;
5915 client_.set_fill_with_nonsolid_color(true);
5917 scoped_refptr<Layer> root = Layer::Create();
5918 root->SetBounds(gfx::Size(500, 500));
5920 scoped_refptr<Layer> pinch = Layer::Create();
5921 pinch->SetBounds(gfx::Size(500, 500));
5922 pinch->SetScrollClipLayerId(root->id());
5923 pinch->SetIsContainerForFixedPositionLayers(true);
5924 root->AddChild(pinch);
5926 scoped_ptr<FakePicturePile> pile(
5927 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5928 ImplSidePaintingSettings().default_tile_grid_size));
5929 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5930 scoped_refptr<FakePictureLayer> layer =
5931 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5932 layer->SetBounds(gfx::Size(500, 500));
5933 layer->SetContentsOpaque(true);
5934 // Avoid LCD text on the layer so we don't cause extra commits when we
5935 // pinch.
5936 layer->disable_lcd_text();
5937 pinch->AddChild(layer);
5939 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5940 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5941 layer_tree_host()->SetRootLayer(root);
5942 LayerTreeHostTest::SetupTree();
5945 // Returns the delta scale of all quads in the frame's root pass from their
5946 // ideal, or 0 if they are not all the same.
5947 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5948 if (frame_data->has_no_damage)
5949 return 0.f;
5950 float frame_scale = 0.f;
5951 RenderPass* root_pass = frame_data->render_passes.back();
5952 for (const auto& draw_quad : root_pass->quad_list) {
5953 // Checkerboards mean an incomplete frame.
5954 if (draw_quad->material != DrawQuad::TILED_CONTENT)
5955 return 0.f;
5956 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5957 float quad_scale =
5958 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5959 float transform_scale =
5960 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5961 float scale = quad_scale / transform_scale;
5962 if (frame_scale != 0.f && frame_scale != scale)
5963 return 0.f;
5964 frame_scale = scale;
5966 return frame_scale;
5969 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5971 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5972 LayerTreeHostImpl::FrameData* frame_data,
5973 DrawResult draw_result) override {
5974 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5975 switch (frame_) {
5976 case 1:
5977 // Drew at page scale 1 before any pinching.
5978 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5979 EXPECT_EQ(1.f, quad_scale_delta);
5980 PostNextAfterDraw(host_impl);
5981 break;
5982 case 2:
5983 if (quad_scale_delta != 1.f)
5984 break;
5985 // Drew at page scale 1.5 after pinching in.
5986 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5987 EXPECT_EQ(1.f, quad_scale_delta);
5988 PostNextAfterDraw(host_impl);
5989 break;
5990 case 3:
5991 // By pinching out, we will create a new tiling and raster it. This may
5992 // cause some additional draws, though we should still be drawing with
5993 // the old 1.5 tiling.
5994 if (frame_data->has_no_damage)
5995 break;
5996 // Drew at page scale 1 with the 1.5 tiling while pinching out.
5997 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5998 EXPECT_EQ(1.5f, quad_scale_delta);
5999 // We don't PostNextAfterDraw here, instead we wait for the new tiling
6000 // to finish rastering so we don't get any noise in further steps.
6001 break;
6002 case 4:
6003 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
6004 // while waiting for texture uploads to complete.
6005 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6006 // This frame will not have any damage, since it's actually the same as
6007 // the last frame, and should contain no incomplete tiles. We just want
6008 // to make sure we drew here at least once after the pinch ended to be
6009 // sure that drawing after pinch doesn't leave us at the wrong scale
6010 EXPECT_TRUE(frame_data->has_no_damage);
6011 PostNextAfterDraw(host_impl);
6012 break;
6013 case 5:
6014 if (quad_scale_delta != 1.f)
6015 break;
6016 // Drew at scale 1 after texture uploads are done.
6017 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6018 EXPECT_EQ(1.f, quad_scale_delta);
6019 EndTest();
6020 break;
6022 return draw_result;
6025 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
6026 if (posted_)
6027 return;
6028 posted_ = true;
6029 ImplThreadTaskRunner()->PostDelayedTask(
6030 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
6031 base::Unretained(this), host_impl),
6032 // Use a delay to allow raster/upload to happen in between frames. This
6033 // should cause flakiness if we fail to block raster/upload when
6034 // desired.
6035 base::TimeDelta::FromMilliseconds(16 * 4));
6038 void Next(LayerTreeHostImpl* host_impl) {
6039 ++frame_;
6040 posted_ = false;
6041 switch (frame_) {
6042 case 2:
6043 // Pinch zoom in.
6044 host_impl->PinchGestureBegin();
6045 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6046 host_impl->PinchGestureEnd();
6047 break;
6048 case 3:
6049 // Pinch zoom back to 1.f but don't end it.
6050 host_impl->PinchGestureBegin();
6051 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
6052 break;
6053 case 4:
6054 // End the pinch, but delay tile production.
6055 playback_allowed_event_.Reset();
6056 host_impl->PinchGestureEnd();
6057 break;
6058 case 5:
6059 // Let tiles complete.
6060 playback_allowed_event_.Signal();
6061 break;
6065 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6066 const Tile* tile) override {
6067 if (frame_ == 3) {
6068 // On frame 3, we will have a lower res tile complete for the pinch-out
6069 // gesture even though it's not displayed. We wait for it here to prevent
6070 // flakiness.
6071 EXPECT_EQ(0.75f, tile->contents_scale());
6072 PostNextAfterDraw(host_impl);
6074 // On frame_ == 4, we are preventing texture uploads from completing,
6075 // so this verifies they are not completing before frame_ == 5.
6076 // Flaky failures here indicate we're failing to prevent uploads from
6077 // completing.
6078 EXPECT_NE(4, frame_) << tile->contents_scale();
6081 void AfterTest() override {}
6083 FakeContentLayerClient client_;
6084 int frame_;
6085 bool posted_;
6086 base::WaitableEvent playback_allowed_event_;
6089 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
6091 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
6092 : public LayerTreeHostTestCrispUpAfterPinchEnds {
6093 protected:
6094 void InitializeSettings(LayerTreeSettings* settings) override {
6095 settings->use_one_copy = true;
6098 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
6099 scoped_ptr<TestWebGraphicsContext3D> context3d =
6100 TestWebGraphicsContext3D::Create();
6101 context3d->set_support_image(true);
6102 context3d->set_support_sync_query(true);
6103 #if defined(OS_MACOSX)
6104 context3d->set_support_texture_rectangle(true);
6105 #endif
6107 if (delegating_renderer())
6108 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
6109 else
6110 return FakeOutputSurface::Create3d(context3d.Pass());
6114 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
6116 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
6117 protected:
6118 RasterizeWithGpuRasterizationCreatesResources() {}
6120 void InitializeSettings(LayerTreeSettings* settings) override {
6121 settings->impl_side_painting = true;
6122 settings->gpu_rasterization_forced = true;
6125 void SetupTree() override {
6126 client_.set_fill_with_nonsolid_color(true);
6128 scoped_refptr<Layer> root = Layer::Create();
6129 root->SetBounds(gfx::Size(500, 500));
6131 scoped_ptr<FakePicturePile> pile(
6132 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6133 ImplSidePaintingSettings().default_tile_grid_size));
6134 scoped_refptr<FakePictureLayer> layer =
6135 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6136 layer->SetBounds(gfx::Size(500, 500));
6137 layer->SetContentsOpaque(true);
6138 root->AddChild(layer);
6140 layer_tree_host()->SetRootLayer(root);
6141 LayerTreeHostTest::SetupTree();
6144 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6146 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6147 LayerTreeHostImpl::FrameData* frame_data,
6148 DrawResult draw_result) override {
6149 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
6150 EndTest();
6151 return draw_result;
6153 void AfterTest() override {}
6155 FakeContentLayerClient client_;
6158 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
6160 class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
6161 protected:
6162 GpuRasterizationRasterizesBorderTiles() : viewport_size_(1024, 2048) {}
6164 void InitializeSettings(LayerTreeSettings* settings) override {
6165 settings->impl_side_painting = true;
6166 settings->gpu_rasterization_enabled = true;
6167 settings->gpu_rasterization_forced = true;
6170 void SetupTree() override {
6171 client_.set_fill_with_nonsolid_color(true);
6173 scoped_ptr<FakePicturePile> pile(
6174 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6175 ImplSidePaintingSettings().default_tile_grid_size));
6176 scoped_refptr<FakePictureLayer> root =
6177 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6178 root->SetBounds(gfx::Size(10000, 10000));
6179 root->SetContentsOpaque(true);
6181 layer_tree_host()->SetRootLayer(root);
6182 LayerTreeHostTest::SetupTree();
6183 layer_tree_host()->SetViewportSize(viewport_size_);
6186 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6188 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6189 LayerTreeHostImpl::FrameData* frame_data,
6190 DrawResult draw_result) override {
6191 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources());
6192 EndTest();
6193 return draw_result;
6196 void AfterTest() override {}
6198 private:
6199 FakeContentLayerClient client_;
6200 gfx::Size viewport_size_;
6203 MULTI_THREAD_IMPL_TEST_F(GpuRasterizationRasterizesBorderTiles);
6205 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
6206 : public LayerTreeHostTest {
6207 protected:
6208 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
6209 : playback_allowed_event_(true, true) {}
6211 void InitializeSettings(LayerTreeSettings* settings) override {
6212 settings->impl_side_painting = true;
6215 void SetupTree() override {
6216 step_ = 1;
6217 continuous_draws_ = 0;
6218 client_.set_fill_with_nonsolid_color(true);
6220 scoped_refptr<Layer> root = Layer::Create();
6221 root->SetBounds(gfx::Size(500, 500));
6223 scoped_refptr<Layer> pinch = Layer::Create();
6224 pinch->SetBounds(gfx::Size(500, 500));
6225 pinch->SetScrollClipLayerId(root->id());
6226 pinch->SetIsContainerForFixedPositionLayers(true);
6227 root->AddChild(pinch);
6229 scoped_ptr<FakePicturePile> pile(
6230 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6231 ImplSidePaintingSettings().default_tile_grid_size));
6232 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
6233 scoped_refptr<FakePictureLayer> layer =
6234 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6235 layer->SetBounds(gfx::Size(500, 500));
6236 layer->SetContentsOpaque(true);
6237 // Avoid LCD text on the layer so we don't cause extra commits when we
6238 // pinch.
6239 layer->disable_lcd_text();
6240 pinch->AddChild(layer);
6242 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
6243 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6244 layer_tree_host()->SetRootLayer(root);
6245 LayerTreeHostTest::SetupTree();
6248 // Returns the delta scale of all quads in the frame's root pass from their
6249 // ideal, or 0 if they are not all the same.
6250 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6251 if (frame_data->has_no_damage)
6252 return 0.f;
6253 float frame_scale = 0.f;
6254 RenderPass* root_pass = frame_data->render_passes.back();
6255 for (const auto& draw_quad : root_pass->quad_list) {
6256 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
6257 float quad_scale =
6258 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6259 float transform_scale =
6260 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
6261 float scale = quad_scale / transform_scale;
6262 if (frame_scale != 0.f && frame_scale != scale)
6263 return 0.f;
6264 frame_scale = scale;
6266 return frame_scale;
6269 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6271 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6272 LayerTreeHostImpl::FrameData* frame_data,
6273 DrawResult draw_result) override {
6274 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6275 switch (step_) {
6276 case 1:
6277 // Drew at scale 1 before any pinching.
6278 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6279 EXPECT_EQ(1.f, quad_scale_delta);
6280 break;
6281 case 2:
6282 if (quad_scale_delta != 1.f / 1.5f)
6283 break;
6284 // Drew at scale 1 still though the ideal is 1.5.
6285 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6286 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6287 break;
6288 case 3:
6289 // Continuous draws are attempted.
6290 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6291 if (!frame_data->has_no_damage)
6292 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6293 break;
6294 case 4:
6295 if (quad_scale_delta != 1.f)
6296 break;
6297 // Drew at scale 1.5 when all the tiles completed.
6298 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6299 EXPECT_EQ(1.f, quad_scale_delta);
6300 break;
6301 case 5:
6302 // TODO(danakj): We get more draws before the NotifyReadyToDraw
6303 // because it is asynchronous from the previous draw and happens late.
6304 break;
6305 case 6:
6306 // NotifyReadyToDraw happened. If we were already inside a frame, we may
6307 // try to draw once more.
6308 break;
6309 case 7:
6310 NOTREACHED() << "No draws should happen once we have a complete frame.";
6311 break;
6313 return draw_result;
6316 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6317 switch (step_) {
6318 case 1:
6319 // Delay tile production.
6320 playback_allowed_event_.Reset();
6321 // Pinch zoom in to cause new tiles to be required.
6322 host_impl->PinchGestureBegin();
6323 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6324 host_impl->PinchGestureEnd();
6325 ++step_;
6326 break;
6327 case 2:
6328 ++step_;
6329 break;
6330 case 3:
6331 // We should continue to try draw while there are incomplete visible
6332 // tiles.
6333 if (++continuous_draws_ > 5) {
6334 // Allow the tiles to complete.
6335 playback_allowed_event_.Signal();
6336 ++step_;
6338 break;
6339 case 4:
6340 ++step_;
6341 break;
6342 case 5:
6343 // Waiting for NotifyReadyToDraw.
6344 break;
6345 case 6:
6346 // NotifyReadyToDraw happened.
6347 ++step_;
6348 break;
6352 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
6353 if (step_ == 5) {
6354 ++step_;
6355 // NotifyReadyToDraw has happened, we may draw once more, but should not
6356 // get any more draws after that. End the test after a timeout to watch
6357 // for any extraneous draws.
6358 // TODO(brianderson): We could remove this delay and instead wait until
6359 // the BeginFrameSource decides it doesn't need to send frames anymore,
6360 // or test that it already doesn't here.
6361 EndTestAfterDelayMs(16 * 4);
6365 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6366 const Tile* tile) override {
6367 // On step_ == 2, we are preventing texture uploads from completing,
6368 // so this verifies they are not completing before step_ == 3.
6369 // Flaky failures here indicate we're failing to prevent uploads from
6370 // completing.
6371 EXPECT_NE(2, step_);
6374 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
6376 FakeContentLayerClient client_;
6377 int step_;
6378 int continuous_draws_;
6379 base::WaitableEvent playback_allowed_event_;
6382 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
6384 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
6385 public:
6386 LayerTreeHostTestOneActivatePerPrepareTiles()
6387 : notify_ready_to_activate_count_(0u),
6388 scheduled_prepare_tiles_count_(0) {}
6390 void SetupTree() override {
6391 client_.set_fill_with_nonsolid_color(true);
6392 scoped_refptr<FakePictureLayer> root_layer =
6393 FakePictureLayer::Create(&client_);
6394 root_layer->SetBounds(gfx::Size(1500, 1500));
6395 root_layer->SetIsDrawable(true);
6397 layer_tree_host()->SetRootLayer(root_layer);
6398 LayerTreeHostTest::SetupTree();
6401 void BeginTest() override {
6402 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
6403 PostSetNeedsCommitToMainThread();
6406 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
6407 bool success) override {
6408 ASSERT_TRUE(success);
6409 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
6412 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6413 ++notify_ready_to_activate_count_;
6414 EndTestAfterDelayMs(100);
6417 void ScheduledActionPrepareTiles() override {
6418 ++scheduled_prepare_tiles_count_;
6421 void AfterTest() override {
6422 // Expect at most a notification for each scheduled prepare tiles, plus one
6423 // for the initial commit (which doesn't go through scheduled actions).
6424 // The reason this is not an equality is because depending on timing, we
6425 // might get a prepare tiles but not yet get a notification that we're
6426 // ready to activate. The intent of a test is to ensure that we don't
6427 // get more than one notification per prepare tiles, so this is OK.
6428 EXPECT_LE(notify_ready_to_activate_count_,
6429 1u + scheduled_prepare_tiles_count_);
6432 protected:
6433 FakeContentLayerClient client_;
6434 size_t notify_ready_to_activate_count_;
6435 size_t scheduled_prepare_tiles_count_;
6438 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
6440 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
6441 : public LayerTreeHostTest {
6442 public:
6443 LayerTreeHostTestFrameTimingRequestsSaveTimestamps()
6444 : check_results_on_commit_(false) {}
6446 void SetupTree() override {
6447 scoped_refptr<FakePictureLayer> root_layer =
6448 FakePictureLayer::Create(&client_);
6449 root_layer->SetBounds(gfx::Size(200, 200));
6450 root_layer->SetIsDrawable(true);
6452 scoped_refptr<FakePictureLayer> child_layer =
6453 FakePictureLayer::Create(&client_);
6454 child_layer->SetBounds(gfx::Size(1500, 1500));
6455 child_layer->SetIsDrawable(true);
6457 std::vector<FrameTimingRequest> requests;
6458 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100)));
6459 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100)));
6460 child_layer->SetFrameTimingRequests(requests);
6462 root_layer->AddChild(child_layer);
6463 layer_tree_host()->SetRootLayer(root_layer);
6464 LayerTreeHostTest::SetupTree();
6467 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6469 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
6470 if (!check_results_on_commit_)
6471 return;
6473 // Since in reality, the events will be read by LayerTreeHost during commit,
6474 // we check the requests here to ensure that they are correct at the next
6475 // commit time (as opposed to checking in DrawLayers for instance).
6476 // TODO(vmpstr): Change this to read things from the main thread when this
6477 // information is propagated to the main thread (not yet implemented).
6478 FrameTimingTracker* tracker = host_impl->frame_timing_tracker();
6480 // Check composite events.
6482 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set =
6483 tracker->GroupCompositeCountsByRectId();
6484 EXPECT_EQ(1u, timing_set->size());
6485 auto rect_1_it = timing_set->find(1);
6486 EXPECT_TRUE(rect_1_it != timing_set->end());
6487 const auto& timing_events = rect_1_it->second;
6488 EXPECT_EQ(1u, timing_events.size());
6489 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6490 timing_events[0].frame_id);
6491 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6494 // Check main frame events.
6496 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> timing_set =
6497 tracker->GroupMainFrameCountsByRectId();
6498 EXPECT_EQ(2u, timing_set->size());
6499 auto rect_1_it = timing_set->find(1);
6500 EXPECT_TRUE(rect_1_it != timing_set->end());
6501 const auto& timing_events = rect_1_it->second;
6502 EXPECT_EQ(1u, timing_events.size());
6503 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6504 timing_events[0].frame_id);
6505 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6506 EXPECT_GT(timing_events[0].end_time, timing_events[0].timestamp);
6509 EndTest();
6512 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6513 check_results_on_commit_ = true;
6514 PostSetNeedsCommitToMainThread();
6517 void AfterTest() override {}
6519 private:
6520 FakeContentLayerClient client_;
6521 bool check_results_on_commit_;
6524 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
6526 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
6527 public:
6528 LayerTreeHostTestActivationCausesPrepareTiles()
6529 : scheduled_prepare_tiles_count_(0) {}
6531 void SetupTree() override {
6532 client_.set_fill_with_nonsolid_color(true);
6533 scoped_refptr<FakePictureLayer> root_layer =
6534 FakePictureLayer::Create(&client_);
6535 root_layer->SetBounds(gfx::Size(150, 150));
6536 root_layer->SetIsDrawable(true);
6538 layer_tree_host()->SetRootLayer(root_layer);
6539 LayerTreeHostTest::SetupTree();
6542 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6544 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6545 // Ensure we've already activated.
6546 EXPECT_FALSE(impl->pending_tree());
6548 // After activating, we either need to prepare tiles, or we've already
6549 // called a scheduled prepare tiles. This is done because activation might
6550 // cause us to have to memory available (old active tree is gone), so we
6551 // need to ensure we will get a PrepareTiles call.
6552 if (!impl->prepare_tiles_needed())
6553 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
6554 EndTest();
6557 void ScheduledActionPrepareTiles() override {
6558 ++scheduled_prepare_tiles_count_;
6561 void AfterTest() override {}
6563 protected:
6564 FakeContentLayerClient client_;
6565 int scheduled_prepare_tiles_count_;
6568 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
6570 // This tests an assertion that DidCommit and WillCommit happen in the same
6571 // stack frame with no tasks that run between them. Various embedders of
6572 // cc depend on this logic. ui::Compositor holds a compositor lock between
6573 // these events and the inspector timeline wants begin/end CompositeLayers
6574 // to be properly nested with other begin/end events.
6575 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
6576 : public LayerTreeHostTest {
6577 public:
6578 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
6580 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6582 void WillCommit() override {
6583 MainThreadTaskRunner()->PostTask(
6584 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
6585 EndTestShouldRunAfterDidCommit,
6586 base::Unretained(this)));
6589 void EndTestShouldRunAfterDidCommit() {
6590 EXPECT_TRUE(did_commit_);
6591 EndTest();
6594 void DidCommit() override {
6595 EXPECT_FALSE(did_commit_);
6596 did_commit_ = true;
6599 void AfterTest() override { EXPECT_TRUE(did_commit_); }
6601 private:
6602 bool did_commit_;
6605 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
6607 // Verify that if a LayerImpl holds onto a copy request for multiple
6608 // frames that it will continue to have a render surface through
6609 // multiple commits, even though the Layer itself has no reason
6610 // to have a render surface.
6611 class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest {
6612 protected:
6613 void SetupTree() override {
6614 scoped_refptr<Layer> root = Layer::Create();
6615 root->CreateRenderSurface();
6616 root->SetBounds(gfx::Size(10, 10));
6617 child_ = Layer::Create();
6618 child_->SetBounds(gfx::Size(20, 20));
6619 root->AddChild(child_);
6621 layer_tree_host()->SetRootLayer(root);
6622 LayerTreeHostTest::SetupTree();
6625 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6627 void BeginTest() override {
6628 child_->RequestCopyOfOutput(
6629 CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback)));
6630 EXPECT_TRUE(child_->HasCopyRequest());
6631 PostSetNeedsCommitToMainThread();
6634 void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); }
6636 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6637 LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id());
6639 switch (host_impl->sync_tree()->source_frame_number()) {
6640 case 0:
6641 EXPECT_TRUE(child_impl->HasCopyRequest());
6642 EXPECT_TRUE(child_impl->render_surface());
6643 break;
6644 case 1:
6645 if (host_impl->proxy()->CommitToActiveTree()) {
6646 EXPECT_TRUE(child_impl->HasCopyRequest());
6647 EXPECT_TRUE(child_impl->render_surface());
6648 } else {
6649 EXPECT_FALSE(child_impl->HasCopyRequest());
6650 EXPECT_FALSE(child_impl->render_surface());
6652 break;
6653 default:
6654 NOTREACHED();
6655 break;
6659 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6660 LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id());
6661 EXPECT_TRUE(child_impl->HasCopyRequest());
6662 EXPECT_TRUE(child_impl->render_surface());
6664 switch (host_impl->active_tree()->source_frame_number()) {
6665 case 0:
6666 // Lose output surface to prevent drawing and cause another commit.
6667 host_impl->DidLoseOutputSurface();
6668 break;
6669 case 1:
6670 EndTest();
6671 break;
6672 default:
6673 NOTREACHED();
6674 break;
6678 void AfterTest() override {}
6680 private:
6681 scoped_refptr<Layer> child_;
6684 SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests);
6686 class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
6687 protected:
6688 void SetupTree() override {
6689 root = Layer::Create();
6690 child = Layer::Create();
6691 root->AddChild(child);
6692 layer_tree_host()->SetRootLayer(root);
6693 LayerTreeHostTest::SetupTree();
6696 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6698 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6700 void DidCommit() override {
6701 switch (layer_tree_host()->source_frame_number()) {
6702 case 1:
6703 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
6704 base::Bind(CopyOutputCallback)));
6705 EXPECT_TRUE(
6706 root->draw_properties().layer_or_descendant_has_copy_request);
6707 break;
6708 case 2:
6709 EXPECT_FALSE(
6710 root->draw_properties().layer_or_descendant_has_copy_request);
6711 EndTest();
6712 break;
6716 void AfterTest() override {}
6718 private:
6719 scoped_refptr<Layer> root;
6720 scoped_refptr<Layer> child;
6723 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
6725 class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
6726 protected:
6727 void SetupTree() override {
6728 // The masked layer has bounds 50x50, but it has a child that causes
6729 // the surface bounds to be larger. It also has a parent that clips the
6730 // masked layer and its surface.
6732 scoped_refptr<Layer> root = Layer::Create();
6734 scoped_refptr<Layer> clipping_layer = Layer::Create();
6735 root->AddChild(clipping_layer);
6737 scoped_refptr<FakePictureLayer> content_layer =
6738 FakePictureLayer::Create(&client_);
6739 clipping_layer->AddChild(content_layer);
6741 scoped_refptr<FakePictureLayer> content_child_layer =
6742 FakePictureLayer::Create(&client_);
6743 content_layer->AddChild(content_child_layer);
6745 scoped_refptr<FakePictureLayer> mask_layer =
6746 FakePictureLayer::Create(&client_);
6747 content_layer->SetMaskLayer(mask_layer.get());
6749 gfx::Size root_size(100, 100);
6750 root->SetBounds(root_size);
6752 gfx::Rect clipping_rect(20, 10, 10, 20);
6753 clipping_layer->SetBounds(clipping_rect.size());
6754 clipping_layer->SetPosition(clipping_rect.origin());
6755 clipping_layer->SetMasksToBounds(true);
6757 gfx::Size layer_size(50, 50);
6758 content_layer->SetBounds(layer_size);
6759 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin());
6761 gfx::Size child_size(50, 50);
6762 content_child_layer->SetBounds(child_size);
6763 content_child_layer->SetPosition(gfx::Point(20, 0));
6765 gfx::Size mask_size(100, 100);
6766 mask_layer->SetBounds(mask_size);
6767 mask_layer->SetIsMask(true);
6769 layer_tree_host()->SetRootLayer(root);
6770 LayerTreeTest::SetupTree();
6773 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6775 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6776 LayerTreeHostImpl::FrameData* frame_data,
6777 DrawResult draw_result) override {
6778 EXPECT_EQ(2u, frame_data->render_passes.size());
6779 RenderPass* root_pass = frame_data->render_passes.back();
6780 EXPECT_EQ(2u, root_pass->quad_list.size());
6782 // There's a solid color quad under everything.
6783 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
6785 // The surface is clipped to 10x20.
6786 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
6787 const RenderPassDrawQuad* render_pass_quad =
6788 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
6789 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
6790 render_pass_quad->rect.ToString());
6791 // The masked layer is 50x50, but the surface size is 10x20. So the texture
6792 // coords in the mask are scaled by 10/50 and 20/50.
6793 // The surface is clipped to (20,10) so the mask texture coords are offset
6794 // by 20/50 and 10/50
6795 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
6796 .ToString(),
6797 render_pass_quad->MaskUVRect().ToString());
6798 EXPECT_EQ(gfx::Vector2dF(10.f / 50.f, 20.f / 50.f).ToString(),
6799 render_pass_quad->mask_uv_scale.ToString());
6800 EndTest();
6801 return draw_result;
6804 void AfterTest() override {}
6806 FakeContentLayerClient client_;
6809 SINGLE_AND_MULTI_THREAD_TEST_F(
6810 LayerTreeTestMaskLayerForSurfaceWithClippedLayer);
6812 class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
6813 protected:
6814 void InitializeSettings(LayerTreeSettings* settings) override {
6815 settings->layer_transforms_should_scale_layer_contents = true;
6818 void SetupTree() override {
6819 // Root
6820 // |
6821 // +-- Scaling Layer (adds a 2x scale)
6822 // |
6823 // +-- Content Layer
6824 // +--Mask
6826 scoped_refptr<Layer> root = Layer::Create();
6828 scoped_refptr<Layer> scaling_layer = Layer::Create();
6829 root->AddChild(scaling_layer);
6831 scoped_refptr<FakePictureLayer> content_layer =
6832 FakePictureLayer::Create(&client_);
6833 scaling_layer->AddChild(content_layer);
6835 scoped_refptr<FakePictureLayer> mask_layer =
6836 FakePictureLayer::Create(&client_);
6837 content_layer->SetMaskLayer(mask_layer.get());
6839 gfx::Size root_size(100, 100);
6840 root->SetBounds(root_size);
6842 gfx::Size scaling_layer_size(50, 50);
6843 scaling_layer->SetBounds(scaling_layer_size);
6844 gfx::Transform scale;
6845 scale.Scale(2.f, 2.f);
6846 scaling_layer->SetTransform(scale);
6848 content_layer->SetBounds(scaling_layer_size);
6850 mask_layer->SetBounds(scaling_layer_size);
6851 mask_layer->SetIsMask(true);
6853 layer_tree_host()->SetRootLayer(root);
6854 LayerTreeTest::SetupTree();
6857 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6859 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6860 LayerTreeHostImpl::FrameData* frame_data,
6861 DrawResult draw_result) override {
6862 EXPECT_EQ(2u, frame_data->render_passes.size());
6863 RenderPass* root_pass = frame_data->render_passes.back();
6864 EXPECT_EQ(2u, root_pass->quad_list.size());
6866 // There's a solid color quad under everything.
6867 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
6869 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
6870 const RenderPassDrawQuad* render_pass_quad =
6871 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
6872 switch (host_impl->active_tree()->source_frame_number()) {
6873 case 0:
6874 // Check that the tree scaling is correctly taken into account for the
6875 // mask, that should fully map onto the quad.
6876 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
6877 render_pass_quad->rect.ToString());
6878 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
6879 render_pass_quad->MaskUVRect().ToString());
6880 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
6881 render_pass_quad->mask_uv_scale.ToString());
6882 break;
6883 case 1:
6884 // Applying a DSF should change the render surface size, but won't
6885 // affect which part of the mask is used.
6886 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
6887 render_pass_quad->rect.ToString());
6888 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
6889 render_pass_quad->MaskUVRect().ToString());
6890 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
6891 render_pass_quad->mask_uv_scale.ToString());
6892 EndTest();
6893 break;
6895 return draw_result;
6898 void DidCommit() override {
6899 switch (layer_tree_host()->source_frame_number()) {
6900 case 1:
6901 gfx::Size double_root_size(200, 200);
6902 layer_tree_host()->SetViewportSize(double_root_size);
6903 layer_tree_host()->SetDeviceScaleFactor(2.f);
6904 break;
6908 void AfterTest() override {}
6910 FakeContentLayerClient client_;
6913 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling);
6915 class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest {
6916 protected:
6917 void SetupTree() override {
6918 // The mask layer has bounds 100x100 but is attached to a layer with bounds
6919 // 50x50.
6921 scoped_refptr<Layer> root = Layer::Create();
6923 scoped_refptr<FakePictureLayer> content_layer =
6924 FakePictureLayer::Create(&client_);
6925 root->AddChild(content_layer);
6927 scoped_refptr<FakePictureLayer> mask_layer =
6928 FakePictureLayer::Create(&client_);
6929 content_layer->SetMaskLayer(mask_layer.get());
6931 gfx::Size root_size(100, 100);
6932 root->SetBounds(root_size);
6934 gfx::Size layer_size(50, 50);
6935 content_layer->SetBounds(layer_size);
6937 gfx::Size mask_size(100, 100);
6938 mask_layer->SetBounds(mask_size);
6939 mask_layer->SetIsMask(true);
6941 layer_tree_host()->SetRootLayer(root);
6942 LayerTreeTest::SetupTree();
6945 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6947 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6948 LayerTreeHostImpl::FrameData* frame_data,
6949 DrawResult draw_result) override {
6950 EXPECT_EQ(2u, frame_data->render_passes.size());
6951 RenderPass* root_pass = frame_data->render_passes.back();
6952 EXPECT_EQ(2u, root_pass->quad_list.size());
6954 // There's a solid color quad under everything.
6955 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
6957 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
6958 const RenderPassDrawQuad* render_pass_quad =
6959 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
6960 switch (host_impl->active_tree()->source_frame_number()) {
6961 case 0:
6962 // Check that the mask fills the surface.
6963 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
6964 render_pass_quad->rect.ToString());
6965 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
6966 render_pass_quad->MaskUVRect().ToString());
6967 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
6968 render_pass_quad->mask_uv_scale.ToString());
6969 break;
6970 case 1:
6971 // Applying a DSF should change the render surface size, but won't
6972 // affect which part of the mask is used.
6973 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
6974 render_pass_quad->rect.ToString());
6975 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
6976 render_pass_quad->MaskUVRect().ToString());
6977 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
6978 render_pass_quad->mask_uv_scale.ToString());
6979 EndTest();
6980 break;
6982 return draw_result;
6985 void DidCommit() override {
6986 switch (layer_tree_host()->source_frame_number()) {
6987 case 1:
6988 gfx::Size double_root_size(200, 200);
6989 layer_tree_host()->SetViewportSize(double_root_size);
6990 layer_tree_host()->SetDeviceScaleFactor(2.f);
6991 break;
6995 void AfterTest() override {}
6997 FakeContentLayerClient client_;
7000 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithDifferentBounds);
7002 class LayerTreeTestReflectionMaskLayerWithDifferentBounds
7003 : public LayerTreeTest {
7004 protected:
7005 void SetupTree() override {
7006 // The replica's mask layer has bounds 100x100 but the replica is of a
7007 // layer with bounds 50x50.
7009 scoped_refptr<Layer> root = Layer::Create();
7011 scoped_refptr<FakePictureLayer> content_layer =
7012 FakePictureLayer::Create(&client_);
7013 root->AddChild(content_layer);
7015 scoped_refptr<Layer> replica_layer = Layer::Create();
7016 content_layer->SetReplicaLayer(replica_layer.get());
7018 scoped_refptr<FakePictureLayer> mask_layer =
7019 FakePictureLayer::Create(&client_);
7020 replica_layer->SetMaskLayer(mask_layer.get());
7022 gfx::Size root_size(100, 100);
7023 root->SetBounds(root_size);
7025 gfx::Size layer_size(50, 50);
7026 content_layer->SetBounds(layer_size);
7028 gfx::Size mask_size(100, 100);
7029 mask_layer->SetBounds(mask_size);
7030 mask_layer->SetIsMask(true);
7032 layer_tree_host()->SetRootLayer(root);
7033 LayerTreeTest::SetupTree();
7036 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7038 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7039 LayerTreeHostImpl::FrameData* frame_data,
7040 DrawResult draw_result) override {
7041 EXPECT_EQ(2u, frame_data->render_passes.size());
7042 RenderPass* root_pass = frame_data->render_passes.back();
7043 EXPECT_EQ(3u, root_pass->quad_list.size());
7045 // There's a solid color quad under everything.
7046 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7048 EXPECT_EQ(DrawQuad::RENDER_PASS,
7049 root_pass->quad_list.ElementAt(1)->material);
7050 const RenderPassDrawQuad* render_pass_quad =
7051 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.ElementAt(1));
7052 switch (host_impl->active_tree()->source_frame_number()) {
7053 case 0:
7054 // Check that the mask fills the surface.
7055 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
7056 render_pass_quad->rect.ToString());
7057 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7058 render_pass_quad->MaskUVRect().ToString());
7059 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7060 render_pass_quad->mask_uv_scale.ToString());
7061 break;
7062 case 1:
7063 // Applying a DSF should change the render surface size, but won't
7064 // affect which part of the mask is used.
7065 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
7066 render_pass_quad->rect.ToString());
7067 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7068 render_pass_quad->MaskUVRect().ToString());
7069 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7070 render_pass_quad->mask_uv_scale.ToString());
7071 EndTest();
7072 break;
7074 return draw_result;
7077 void DidCommit() override {
7078 switch (layer_tree_host()->source_frame_number()) {
7079 case 1:
7080 gfx::Size double_root_size(200, 200);
7081 layer_tree_host()->SetViewportSize(double_root_size);
7082 layer_tree_host()->SetDeviceScaleFactor(2.f);
7083 break;
7087 void AfterTest() override {}
7089 FakeContentLayerClient client_;
7092 SINGLE_AND_MULTI_THREAD_TEST_F(
7093 LayerTreeTestReflectionMaskLayerWithDifferentBounds);
7095 class LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild
7096 : public LayerTreeTest {
7097 protected:
7098 void SetupTree() override {
7099 // The replica is of a layer with bounds 50x50, but it has a child that
7100 // causes the surface bounds to be larger.
7102 scoped_refptr<Layer> root = Layer::Create();
7104 scoped_refptr<FakePictureLayer> content_layer =
7105 FakePictureLayer::Create(&client_);
7106 root->AddChild(content_layer);
7108 content_child_layer_ = FakePictureLayer::Create(&client_);
7109 content_layer->AddChild(content_child_layer_);
7111 scoped_refptr<Layer> replica_layer = Layer::Create();
7112 content_layer->SetReplicaLayer(replica_layer.get());
7114 scoped_refptr<FakePictureLayer> mask_layer =
7115 FakePictureLayer::Create(&client_);
7116 replica_layer->SetMaskLayer(mask_layer.get());
7118 gfx::Size root_size(100, 100);
7119 root->SetBounds(root_size);
7121 gfx::Size layer_size(50, 50);
7122 content_layer->SetBounds(layer_size);
7123 content_child_layer_->SetBounds(layer_size);
7124 content_child_layer_->SetPosition(gfx::PointF(50.f, 0.f));
7126 gfx::Size mask_size(100, 100);
7127 mask_layer->SetBounds(mask_size);
7128 mask_layer->SetIsMask(true);
7130 layer_tree_host()->SetRootLayer(root);
7131 LayerTreeTest::SetupTree();
7134 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7136 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7137 LayerTreeHostImpl::FrameData* frame_data,
7138 DrawResult draw_result) override {
7139 EXPECT_EQ(2u, frame_data->render_passes.size());
7140 RenderPass* root_pass = frame_data->render_passes.back();
7141 EXPECT_EQ(3u, root_pass->quad_list.size());
7143 // There's a solid color quad under everything.
7144 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7146 EXPECT_EQ(DrawQuad::RENDER_PASS,
7147 root_pass->quad_list.ElementAt(1)->material);
7148 const RenderPassDrawQuad* replica_quad =
7149 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.ElementAt(1));
7150 switch (host_impl->active_tree()->source_frame_number()) {
7151 case 0:
7152 // The surface is 100x50.
7153 // The mask covers the owning layer only.
7154 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
7155 replica_quad->rect.ToString());
7156 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
7157 replica_quad->MaskUVRect().ToString());
7158 EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
7159 replica_quad->mask_uv_scale.ToString());
7160 break;
7161 case 1:
7162 // The surface is 100x50 with its origin at (-50, 0).
7163 // The mask covers the owning layer only.
7164 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
7165 replica_quad->rect.ToString());
7166 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
7167 replica_quad->MaskUVRect().ToString());
7168 EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
7169 replica_quad->mask_uv_scale.ToString());
7170 EndTest();
7171 break;
7173 return draw_result;
7176 void DidCommit() override {
7177 switch (layer_tree_host()->source_frame_number()) {
7178 case 1:
7179 // Move the child to (-50, 0) instead. Now the mask should be moved to
7180 // still cover the layer being replicated.
7181 content_child_layer_->SetPosition(gfx::PointF(-50.f, 0.f));
7182 break;
7186 void AfterTest() override {}
7188 scoped_refptr<FakePictureLayer> content_child_layer_;
7189 FakeContentLayerClient client_;
7192 SINGLE_AND_MULTI_THREAD_TEST_F(
7193 LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild);
7195 } // namespace cc