cc: Make scheduling be driven by vsync for android webview.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob00f4f9aa68dd1d46012a5698aeda07456d3ae923
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include <algorithm>
9 #include "base/auto_reset.h"
10 #include "base/synchronization/lock.h"
11 #include "cc/animation/timing_function.h"
12 #include "cc/debug/frame_rate_counter.h"
13 #include "cc/layers/content_layer.h"
14 #include "cc/layers/content_layer_client.h"
15 #include "cc/layers/io_surface_layer.h"
16 #include "cc/layers/layer_impl.h"
17 #include "cc/layers/painted_scrollbar_layer.h"
18 #include "cc/layers/picture_layer.h"
19 #include "cc/layers/solid_color_layer.h"
20 #include "cc/layers/video_layer.h"
21 #include "cc/output/begin_frame_args.h"
22 #include "cc/output/compositor_frame_ack.h"
23 #include "cc/output/copy_output_request.h"
24 #include "cc/output/copy_output_result.h"
25 #include "cc/output/output_surface.h"
26 #include "cc/output/swap_promise.h"
27 #include "cc/quads/draw_quad.h"
28 #include "cc/quads/io_surface_draw_quad.h"
29 #include "cc/quads/tile_draw_quad.h"
30 #include "cc/resources/prioritized_resource.h"
31 #include "cc/resources/prioritized_resource_manager.h"
32 #include "cc/resources/resource_update_queue.h"
33 #include "cc/test/fake_content_layer.h"
34 #include "cc/test/fake_content_layer_client.h"
35 #include "cc/test/fake_content_layer_impl.h"
36 #include "cc/test/fake_layer_tree_host_client.h"
37 #include "cc/test/fake_output_surface.h"
38 #include "cc/test/fake_painted_scrollbar_layer.h"
39 #include "cc/test/fake_picture_layer.h"
40 #include "cc/test/fake_picture_layer_impl.h"
41 #include "cc/test/fake_picture_pile.h"
42 #include "cc/test/fake_proxy.h"
43 #include "cc/test/fake_scoped_ui_resource.h"
44 #include "cc/test/fake_video_frame_provider.h"
45 #include "cc/test/geometry_test_utils.h"
46 #include "cc/test/impl_side_painting_settings.h"
47 #include "cc/test/layer_tree_test.h"
48 #include "cc/test/test_shared_bitmap_manager.h"
49 #include "cc/test/test_web_graphics_context_3d.h"
50 #include "cc/trees/layer_tree_host_impl.h"
51 #include "cc/trees/layer_tree_impl.h"
52 #include "cc/trees/single_thread_proxy.h"
53 #include "cc/trees/thread_proxy.h"
54 #include "gpu/GLES2/gl2extchromium.h"
55 #include "skia/ext/refptr.h"
56 #include "testing/gmock/include/gmock/gmock.h"
57 #include "third_party/khronos/GLES2/gl2.h"
58 #include "third_party/khronos/GLES2/gl2ext.h"
59 #include "third_party/skia/include/core/SkPicture.h"
60 #include "ui/gfx/frame_time.h"
61 #include "ui/gfx/geometry/point_conversions.h"
62 #include "ui/gfx/geometry/size_conversions.h"
63 #include "ui/gfx/geometry/vector2d_conversions.h"
65 using testing::_;
66 using testing::AnyNumber;
67 using testing::AtLeast;
68 using testing::Mock;
70 namespace cc {
71 namespace {
73 class LayerTreeHostTest : public LayerTreeTest {
74 public:
75 LayerTreeHostTest() : contents_texture_manager_(nullptr) {}
77 void DidInitializeOutputSurface() override {
78 contents_texture_manager_ = layer_tree_host()->contents_texture_manager();
81 protected:
82 PrioritizedResourceManager* contents_texture_manager_;
85 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
86 // when no raster tasks get scheduled.
87 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
88 public:
89 LayerTreeHostTestReadyToActivateEmpty()
90 : did_notify_ready_to_activate_(false),
91 all_tiles_required_for_activation_are_ready_to_draw_(false),
92 required_for_activation_count_(0) {}
94 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
96 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
97 const std::vector<PictureLayerImpl*>& layers =
98 impl->sync_tree()->picture_layers();
99 required_for_activation_count_ = 0;
100 for (const auto& layer : layers) {
101 FakePictureLayerImpl* fake_layer =
102 static_cast<FakePictureLayerImpl*>(layer);
103 required_for_activation_count_ +=
104 fake_layer->CountTilesRequiredForActivation();
108 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
109 did_notify_ready_to_activate_ = true;
110 all_tiles_required_for_activation_are_ready_to_draw_ =
111 impl->tile_manager()->IsReadyToActivate();
112 EndTest();
115 void AfterTest() override {
116 EXPECT_TRUE(did_notify_ready_to_activate_);
117 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
118 EXPECT_EQ(size_t(0), required_for_activation_count_);
121 protected:
122 bool did_notify_ready_to_activate_;
123 bool all_tiles_required_for_activation_are_ready_to_draw_;
124 size_t required_for_activation_count_;
127 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
129 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
130 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
131 class LayerTreeHostTestReadyToActivateNonEmpty
132 : public LayerTreeHostTestReadyToActivateEmpty {
133 public:
134 void SetupTree() override {
135 client_.set_fill_with_nonsolid_color(true);
136 scoped_refptr<FakePictureLayer> root_layer =
137 FakePictureLayer::Create(&client_);
138 root_layer->SetBounds(gfx::Size(1024, 1024));
139 root_layer->SetIsDrawable(true);
141 layer_tree_host()->SetRootLayer(root_layer);
142 LayerTreeHostTest::SetupTree();
145 void AfterTest() override {
146 EXPECT_TRUE(did_notify_ready_to_activate_);
147 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
148 EXPECT_LE(size_t(1), required_for_activation_count_);
151 private:
152 FakeContentLayerClient client_;
155 // Multi-thread only because in single thread the commit goes directly to the
156 // active tree, so notify ready to activate is skipped.
157 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
159 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
160 // no raster tasks get scheduled.
161 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
162 public:
163 LayerTreeHostTestReadyToDrawEmpty()
164 : did_notify_ready_to_draw_(false),
165 all_tiles_required_for_draw_are_ready_to_draw_(false),
166 required_for_draw_count_(0) {}
168 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
170 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
171 did_notify_ready_to_draw_ = true;
172 const std::vector<PictureLayerImpl*>& layers =
173 impl->active_tree()->picture_layers();
174 all_tiles_required_for_draw_are_ready_to_draw_ =
175 impl->tile_manager()->IsReadyToDraw();
176 for (const auto& layer : layers) {
177 FakePictureLayerImpl* fake_layer =
178 static_cast<FakePictureLayerImpl*>(layer);
179 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw();
182 EndTest();
185 void AfterTest() override {
186 EXPECT_TRUE(did_notify_ready_to_draw_);
187 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
188 EXPECT_EQ(size_t(0), required_for_draw_count_);
191 protected:
192 bool did_notify_ready_to_draw_;
193 bool all_tiles_required_for_draw_are_ready_to_draw_;
194 size_t required_for_draw_count_;
197 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
199 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
200 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
201 class LayerTreeHostTestReadyToDrawNonEmpty
202 : public LayerTreeHostTestReadyToDrawEmpty {
203 public:
204 void SetupTree() override {
205 client_.set_fill_with_nonsolid_color(true);
206 scoped_refptr<FakePictureLayer> root_layer =
207 FakePictureLayer::Create(&client_);
208 root_layer->SetBounds(gfx::Size(1024, 1024));
209 root_layer->SetIsDrawable(true);
211 layer_tree_host()->SetRootLayer(root_layer);
212 LayerTreeHostTest::SetupTree();
215 void AfterTest() override {
216 EXPECT_TRUE(did_notify_ready_to_draw_);
217 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
218 EXPECT_LE(size_t(1), required_for_draw_count_);
221 private:
222 FakeContentLayerClient client_;
225 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
226 // single threaded mode.
227 SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
229 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
230 // draw with frame 0.
231 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
232 public:
233 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
235 void BeginTest() override {
236 PostSetNeedsCommitToMainThread();
237 PostSetNeedsCommitToMainThread();
240 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
241 num_draws_++;
242 if (!impl->active_tree()->source_frame_number())
243 EndTest();
246 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
247 num_commits_++;
250 void AfterTest() override {
251 EXPECT_LE(1, num_commits_);
252 EXPECT_LE(1, num_draws_);
255 private:
256 int num_commits_;
257 int num_draws_;
260 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
262 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
263 // first committed frame draws should lead to another commit.
264 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
265 public:
266 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
268 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
270 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
272 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
273 ++num_commits_;
274 switch (num_commits_) {
275 case 1:
276 PostSetNeedsCommitToMainThread();
277 break;
278 case 2:
279 EndTest();
280 break;
281 default:
282 NOTREACHED();
286 void AfterTest() override {
287 EXPECT_EQ(2, num_commits_);
288 EXPECT_LE(1, num_draws_);
291 private:
292 int num_commits_;
293 int num_draws_;
296 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
298 // Verify that we pass property values in PushPropertiesTo.
299 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
300 protected:
301 void SetupTree() override {
302 scoped_refptr<Layer> root = Layer::Create();
303 root->CreateRenderSurface();
304 root->SetBounds(gfx::Size(10, 10));
305 layer_tree_host()->SetRootLayer(root);
306 LayerTreeHostTest::SetupTree();
309 enum Properties {
310 STARTUP,
311 BOUNDS,
312 HIDE_LAYER_AND_SUBTREE,
313 DRAWS_CONTENT,
314 DONE,
317 void BeginTest() override {
318 index_ = STARTUP;
319 PostSetNeedsCommitToMainThread();
322 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
323 VerifyAfterValues(impl->active_tree()->root_layer());
326 void DidCommitAndDrawFrame() override {
327 SetBeforeValues(layer_tree_host()->root_layer());
328 VerifyBeforeValues(layer_tree_host()->root_layer());
330 ++index_;
331 if (index_ == DONE) {
332 EndTest();
333 return;
336 SetAfterValues(layer_tree_host()->root_layer());
339 void AfterTest() override {}
341 void VerifyBeforeValues(Layer* layer) {
342 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
343 EXPECT_FALSE(layer->hide_layer_and_subtree());
344 EXPECT_FALSE(layer->DrawsContent());
347 void SetBeforeValues(Layer* layer) {
348 layer->SetBounds(gfx::Size(10, 10));
349 layer->SetHideLayerAndSubtree(false);
350 layer->SetIsDrawable(false);
353 void VerifyAfterValues(LayerImpl* layer) {
354 switch (static_cast<Properties>(index_)) {
355 case STARTUP:
356 case DONE:
357 break;
358 case BOUNDS:
359 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
360 break;
361 case HIDE_LAYER_AND_SUBTREE:
362 EXPECT_TRUE(layer->hide_layer_and_subtree());
363 break;
364 case DRAWS_CONTENT:
365 EXPECT_TRUE(layer->DrawsContent());
366 break;
370 void SetAfterValues(Layer* layer) {
371 switch (static_cast<Properties>(index_)) {
372 case STARTUP:
373 case DONE:
374 break;
375 case BOUNDS:
376 layer->SetBounds(gfx::Size(20, 20));
377 break;
378 case HIDE_LAYER_AND_SUBTREE:
379 layer->SetHideLayerAndSubtree(true);
380 break;
381 case DRAWS_CONTENT:
382 layer->SetIsDrawable(true);
383 break;
387 int index_;
390 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
392 // 1 setNeedsRedraw after the first commit has completed should lead to 1
393 // additional draw.
394 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
395 public:
396 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
398 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
400 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
401 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
402 if (!num_draws_) {
403 // Redraw again to verify that the second redraw doesn't commit.
404 PostSetNeedsRedrawToMainThread();
405 } else {
406 EndTest();
408 num_draws_++;
411 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
412 EXPECT_EQ(0, num_draws_);
413 num_commits_++;
416 void AfterTest() override {
417 EXPECT_GE(2, num_draws_);
418 EXPECT_EQ(1, num_commits_);
421 private:
422 int num_commits_;
423 int num_draws_;
426 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
428 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
429 // must contain invalid_rect.
430 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
431 public:
432 LayerTreeHostTestSetNeedsRedrawRect()
433 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
435 void BeginTest() override {
436 if (layer_tree_host()->settings().impl_side_painting)
437 root_layer_ = FakePictureLayer::Create(&client_);
438 else
439 root_layer_ = ContentLayer::Create(&client_);
440 root_layer_->SetIsDrawable(true);
441 root_layer_->SetBounds(bounds_);
442 layer_tree_host()->SetRootLayer(root_layer_);
443 layer_tree_host()->SetViewportSize(bounds_);
444 PostSetNeedsCommitToMainThread();
447 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
448 LayerTreeHostImpl::FrameData* frame_data,
449 DrawResult draw_result) override {
450 EXPECT_EQ(DRAW_SUCCESS, draw_result);
452 gfx::RectF root_damage_rect;
453 if (!frame_data->render_passes.empty())
454 root_damage_rect = frame_data->render_passes.back()->damage_rect;
456 if (!num_draws_) {
457 // If this is the first frame, expect full frame damage.
458 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_));
459 } else {
460 // Check that invalid_rect_ is indeed repainted.
461 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
464 return draw_result;
467 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
468 if (!num_draws_) {
469 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
470 } else {
471 EndTest();
473 num_draws_++;
476 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
478 private:
479 int num_draws_;
480 const gfx::Size bounds_;
481 const gfx::Rect invalid_rect_;
482 FakeContentLayerClient client_;
483 scoped_refptr<Layer> root_layer_;
486 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
488 // Ensure the texture size of the pending and active trees are identical when a
489 // layer is not in the viewport and a resize happens on the viewport
490 class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
491 public:
492 LayerTreeHostTestGpuRasterDeviceSizeChanged()
493 : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {}
495 void BeginTest() override {
496 client_.set_fill_with_nonsolid_color(true);
497 root_layer_ = FakePictureLayer::Create(&client_);
498 root_layer_->SetIsDrawable(true);
499 gfx::Transform transform;
500 // Translate the layer out of the viewport to force it to not update its
501 // tile size via PushProperties.
502 transform.Translate(10000.0, 10000.0);
503 root_layer_->SetTransform(transform);
504 root_layer_->SetBounds(bounds_);
505 layer_tree_host()->SetRootLayer(root_layer_);
506 layer_tree_host()->SetViewportSize(bounds_);
508 PostSetNeedsCommitToMainThread();
511 void InitializeSettings(LayerTreeSettings* settings) override {
512 settings->gpu_rasterization_enabled = true;
513 settings->gpu_rasterization_forced = true;
516 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
517 // Perform 2 commits.
518 if (!num_draws_) {
519 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
520 } else {
521 EndTest();
523 num_draws_++;
526 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
527 if (num_draws_ == 2) {
528 auto pending_tree = host_impl->pending_tree();
529 auto pending_layer_impl =
530 static_cast<FakePictureLayerImpl*>(pending_tree->root_layer());
531 EXPECT_NE(pending_layer_impl, nullptr);
533 auto active_tree = host_impl->pending_tree();
534 auto active_layer_impl =
535 static_cast<FakePictureLayerImpl*>(active_tree->root_layer());
536 EXPECT_NE(pending_layer_impl, nullptr);
538 auto active_tiling_set = active_layer_impl->picture_layer_tiling_set();
539 auto active_tiling = active_tiling_set->tiling_at(0);
540 auto pending_tiling_set = pending_layer_impl->picture_layer_tiling_set();
541 auto pending_tiling = pending_tiling_set->tiling_at(0);
542 EXPECT_EQ(
543 pending_tiling->TilingDataForTesting().max_texture_size().width(),
544 active_tiling->TilingDataForTesting().max_texture_size().width());
548 void DidCommitAndDrawFrame() override {
549 // On the second commit, resize the viewport.
550 if (num_draws_ == 1) {
551 layer_tree_host()->SetViewportSize(gfx::Size(400, 64));
555 void AfterTest() override {}
557 private:
558 int num_draws_;
559 const gfx::Size bounds_;
560 const gfx::Rect invalid_rect_;
561 FakeContentLayerClient client_;
562 scoped_refptr<FakePictureLayer> root_layer_;
565 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
566 LayerTreeHostTestGpuRasterDeviceSizeChanged);
568 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
569 public:
570 void InitializeSettings(LayerTreeSettings* settings) override {
571 settings->layer_transforms_should_scale_layer_contents = true;
574 void SetupTree() override {
575 root_layer_ = Layer::Create();
576 root_layer_->SetBounds(gfx::Size(10, 20));
577 root_layer_->CreateRenderSurface();
579 if (layer_tree_host()->settings().impl_side_painting)
580 scaled_layer_ = FakePictureLayer::Create(&client_);
581 else
582 scaled_layer_ = FakeContentLayer::Create(&client_);
583 scaled_layer_->SetBounds(gfx::Size(1, 1));
584 root_layer_->AddChild(scaled_layer_);
586 layer_tree_host()->SetRootLayer(root_layer_);
587 LayerTreeHostTest::SetupTree();
590 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
592 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
593 if (host_impl->active_tree()->source_frame_number() == 1)
594 EndTest();
597 void DidCommit() override {
598 switch (layer_tree_host()->source_frame_number()) {
599 case 1:
600 // SetBounds grows the layer and exposes new content.
601 if (layer_tree_host()->settings().impl_side_painting) {
602 scaled_layer_->SetBounds(gfx::Size(4, 4));
603 } else {
604 // Changing the device scale factor causes a commit. It also changes
605 // the content bounds of |scaled_layer_|, which should not generate
606 // a second commit as a result.
607 layer_tree_host()->SetDeviceScaleFactor(4.f);
609 break;
610 default:
611 // No extra commits.
612 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
616 void AfterTest() override {
617 EXPECT_EQ(gfx::Size(4, 4).ToString(),
618 scaled_layer_->content_bounds().ToString());
621 private:
622 FakeContentLayerClient client_;
623 scoped_refptr<Layer> root_layer_;
624 scoped_refptr<Layer> scaled_layer_;
627 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
629 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
630 : public LayerTreeHostTest {
631 public:
632 void InitializeSettings(LayerTreeSettings* settings) override {
633 settings->layer_transforms_should_scale_layer_contents = true;
636 void SetupTree() override {
637 root_layer_ = Layer::Create();
638 root_layer_->SetBounds(gfx::Size(10, 20));
639 root_layer_->CreateRenderSurface();
641 bool paint_scrollbar = true;
642 bool has_thumb = false;
643 scrollbar_ = FakePaintedScrollbarLayer::Create(
644 paint_scrollbar, has_thumb, root_layer_->id());
645 scrollbar_->SetPosition(gfx::Point(0, 10));
646 scrollbar_->SetBounds(gfx::Size(10, 10));
648 root_layer_->AddChild(scrollbar_);
650 layer_tree_host()->SetRootLayer(root_layer_);
651 LayerTreeHostTest::SetupTree();
654 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
656 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
657 if (host_impl->active_tree()->source_frame_number() == 1)
658 EndTest();
661 void DidCommit() override {
662 switch (layer_tree_host()->source_frame_number()) {
663 case 1:
664 // Changing the device scale factor causes a commit. It also changes
665 // the content bounds of |scrollbar_|, which should not generate
666 // a second commit as a result.
667 layer_tree_host()->SetDeviceScaleFactor(4.f);
668 break;
669 default:
670 // No extra commits.
671 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
675 void AfterTest() override {
676 EXPECT_EQ(gfx::Size(40, 40).ToString(),
677 scrollbar_->internal_content_bounds().ToString());
680 private:
681 FakeContentLayerClient client_;
682 scoped_refptr<Layer> root_layer_;
683 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
686 SINGLE_AND_MULTI_THREAD_TEST_F(
687 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
689 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
690 public:
691 LayerTreeHostTestSetNextCommitForcesRedraw()
692 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
694 void BeginTest() override {
695 if (layer_tree_host()->settings().impl_side_painting)
696 root_layer_ = FakePictureLayer::Create(&client_);
697 else
698 root_layer_ = ContentLayer::Create(&client_);
699 root_layer_->SetIsDrawable(true);
700 root_layer_->SetBounds(bounds_);
701 layer_tree_host()->SetRootLayer(root_layer_);
702 layer_tree_host()->SetViewportSize(bounds_);
703 PostSetNeedsCommitToMainThread();
706 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
707 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
708 host_impl->SetNeedsRedrawRect(invalid_rect_);
711 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
712 LayerTreeHostImpl::FrameData* frame_data,
713 DrawResult draw_result) override {
714 EXPECT_EQ(DRAW_SUCCESS, draw_result);
716 gfx::RectF root_damage_rect;
717 if (!frame_data->render_passes.empty())
718 root_damage_rect = frame_data->render_passes.back()->damage_rect;
720 switch (num_draws_) {
721 case 0:
722 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
723 break;
724 case 1:
725 case 2:
726 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
727 break;
728 case 3:
729 EXPECT_EQ(invalid_rect_, root_damage_rect);
730 break;
731 case 4:
732 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
733 break;
734 default:
735 NOTREACHED();
738 return draw_result;
741 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
742 switch (num_draws_) {
743 case 0:
744 case 1:
745 // Cycle through a couple of empty commits to ensure we're observing the
746 // right behavior
747 PostSetNeedsCommitToMainThread();
748 break;
749 case 2:
750 // Should force full frame damage on the next commit
751 PostSetNextCommitForcesRedrawToMainThread();
752 PostSetNeedsCommitToMainThread();
753 if (host_impl->settings().impl_side_painting)
754 host_impl->BlockNotifyReadyToActivateForTesting(true);
755 else
756 num_draws_++;
757 break;
758 case 3:
759 host_impl->BlockNotifyReadyToActivateForTesting(false);
760 break;
761 default:
762 EndTest();
763 break;
765 num_draws_++;
768 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
770 private:
771 int num_draws_;
772 const gfx::Size bounds_;
773 const gfx::Rect invalid_rect_;
774 FakeContentLayerClient client_;
775 scoped_refptr<Layer> root_layer_;
778 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
779 LayerTreeHostTestSetNextCommitForcesRedraw);
781 // Tests that if a layer is not drawn because of some reason in the parent then
782 // its damage is preserved until the next time it is drawn.
783 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
784 public:
785 LayerTreeHostTestUndrawnLayersDamageLater() {}
787 void InitializeSettings(LayerTreeSettings* settings) override {
788 // If we don't set the minimum contents scale, it's harder to verify whether
789 // the damage we get is correct. For other scale amounts, please see
790 // LayerTreeHostTestDamageWithScale.
791 settings->minimum_contents_scale = 1.f;
794 void SetupTree() override {
795 if (layer_tree_host()->settings().impl_side_painting)
796 root_layer_ = FakePictureLayer::Create(&client_);
797 else
798 root_layer_ = ContentLayer::Create(&client_);
799 root_layer_->SetIsDrawable(true);
800 root_layer_->SetBounds(gfx::Size(50, 50));
801 layer_tree_host()->SetRootLayer(root_layer_);
803 // The initially transparent layer has a larger child layer, which is
804 // not initially drawn because of the this (parent) layer.
805 if (layer_tree_host()->settings().impl_side_painting)
806 parent_layer_ = FakePictureLayer::Create(&client_);
807 else
808 parent_layer_ = FakeContentLayer::Create(&client_);
809 parent_layer_->SetBounds(gfx::Size(15, 15));
810 parent_layer_->SetOpacity(0.0f);
811 root_layer_->AddChild(parent_layer_);
813 if (layer_tree_host()->settings().impl_side_painting)
814 child_layer_ = FakePictureLayer::Create(&client_);
815 else
816 child_layer_ = FakeContentLayer::Create(&client_);
817 child_layer_->SetBounds(gfx::Size(25, 25));
818 parent_layer_->AddChild(child_layer_);
820 LayerTreeHostTest::SetupTree();
823 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
825 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
826 LayerTreeHostImpl::FrameData* frame_data,
827 DrawResult draw_result) override {
828 EXPECT_EQ(DRAW_SUCCESS, draw_result);
830 gfx::RectF root_damage_rect;
831 if (!frame_data->render_passes.empty())
832 root_damage_rect = frame_data->render_passes.back()->damage_rect;
834 // The first time, the whole view needs be drawn.
835 // Afterwards, just the opacity of surface_layer1 is changed a few times,
836 // and each damage should be the bounding box of it and its child. If this
837 // was working improperly, the damage might not include its childs bounding
838 // box.
839 switch (host_impl->active_tree()->source_frame_number()) {
840 case 0:
841 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
842 break;
843 case 1:
844 case 2:
845 case 3:
846 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
847 break;
848 default:
849 NOTREACHED();
852 return draw_result;
855 void DidCommitAndDrawFrame() override {
856 switch (layer_tree_host()->source_frame_number()) {
857 case 1:
858 // Test not owning the surface.
859 parent_layer_->SetOpacity(1.0f);
860 break;
861 case 2:
862 parent_layer_->SetOpacity(0.0f);
863 break;
864 case 3:
865 // Test owning the surface.
866 parent_layer_->SetOpacity(0.5f);
867 parent_layer_->SetForceRenderSurface(true);
868 break;
869 case 4:
870 EndTest();
871 break;
872 default:
873 NOTREACHED();
877 void AfterTest() override {}
879 private:
880 FakeContentLayerClient client_;
881 scoped_refptr<Layer> root_layer_;
882 scoped_refptr<Layer> parent_layer_;
883 scoped_refptr<Layer> child_layer_;
886 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
888 // Tests that if a layer is not drawn because of some reason in the parent then
889 // its damage is preserved until the next time it is drawn.
890 class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest {
891 public:
892 LayerTreeHostTestDamageWithScale() {}
894 void SetupTree() override {
895 client_.set_fill_with_nonsolid_color(true);
897 scoped_ptr<FakePicturePile> pile(
898 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
899 ImplSidePaintingSettings().default_tile_grid_size));
900 root_layer_ =
901 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
902 root_layer_->SetBounds(gfx::Size(50, 50));
904 pile.reset(
905 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
906 ImplSidePaintingSettings().default_tile_grid_size));
907 child_layer_ =
908 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
909 child_layer_->SetBounds(gfx::Size(25, 25));
910 child_layer_->SetIsDrawable(true);
911 child_layer_->SetContentsOpaque(true);
912 root_layer_->AddChild(child_layer_);
914 layer_tree_host()->SetRootLayer(root_layer_);
915 LayerTreeHostTest::SetupTree();
918 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
919 // Force the layer to have a tiling at 1.3f scale. Note that if we simply
920 // add tiling, it will be gone by the time we draw because of aggressive
921 // cleanup. AddTilingUntilNextDraw ensures that it remains there during
922 // damage calculation.
923 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
924 host_impl->active_tree()->LayerById(child_layer_->id()));
925 child_layer_impl->AddTilingUntilNextDraw(1.3f);
928 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
930 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
931 LayerTreeHostImpl::FrameData* frame_data,
932 DrawResult draw_result) override {
933 EXPECT_EQ(DRAW_SUCCESS, draw_result);
935 gfx::RectF root_damage_rect;
936 if (!frame_data->render_passes.empty())
937 root_damage_rect = frame_data->render_passes.back()->damage_rect;
939 // The first time, the whole view needs be drawn.
940 // Afterwards, just the opacity of surface_layer1 is changed a few times,
941 // and each damage should be the bounding box of it and its child. If this
942 // was working improperly, the damage might not include its childs bounding
943 // box.
944 switch (host_impl->active_tree()->source_frame_number()) {
945 case 0:
946 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
947 break;
948 case 1: {
949 FakePictureLayerImpl* child_layer_impl =
950 static_cast<FakePictureLayerImpl*>(
951 host_impl->active_tree()->LayerById(child_layer_->id()));
952 // We remove tilings pretty aggressively if they are not ideal. Add this
953 // back in so that we can compare
954 // child_layer_impl->GetEnclosingRectInTargetSpace to the damage.
955 child_layer_impl->AddTilingUntilNextDraw(1.3f);
957 EXPECT_EQ(gfx::Rect(26, 26), root_damage_rect);
958 EXPECT_EQ(child_layer_impl->GetEnclosingRectInTargetSpace(),
959 root_damage_rect);
960 EXPECT_TRUE(child_layer_impl->GetEnclosingRectInTargetSpace().Contains(
961 gfx::Rect(child_layer_->bounds())));
962 break;
964 default:
965 NOTREACHED();
968 return draw_result;
971 void DidCommitAndDrawFrame() override {
972 switch (layer_tree_host()->source_frame_number()) {
973 case 1: {
974 // Test not owning the surface.
975 child_layer_->SetOpacity(0.5f);
976 break;
978 case 2:
979 EndTest();
980 break;
981 default:
982 NOTREACHED();
986 void AfterTest() override {}
988 private:
989 FakeContentLayerClient client_;
990 scoped_refptr<Layer> root_layer_;
991 scoped_refptr<Layer> child_layer_;
994 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestDamageWithScale);
996 // Tests that if a layer is not drawn because of some reason in the parent,
997 // causing its content bounds to not be computed, then when it is later drawn,
998 // its content bounds get pushed.
999 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
1000 : public LayerTreeHostTest {
1001 public:
1002 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
1003 : root_layer_(Layer::Create()) {}
1005 void SetupTree() override {
1006 root_layer_->CreateRenderSurface();
1007 root_layer_->SetIsDrawable(true);
1008 root_layer_->SetBounds(gfx::Size(20, 20));
1009 layer_tree_host()->SetRootLayer(root_layer_);
1011 parent_layer_ = Layer::Create();
1012 parent_layer_->SetBounds(gfx::Size(20, 20));
1013 parent_layer_->SetOpacity(0.0f);
1014 root_layer_->AddChild(parent_layer_);
1016 child_layer_ = Layer::Create();
1017 child_layer_->SetBounds(gfx::Size(15, 15));
1018 parent_layer_->AddChild(child_layer_);
1020 LayerTreeHostTest::SetupTree();
1023 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1025 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1026 LayerImpl* root = host_impl->active_tree()->root_layer();
1027 LayerImpl* parent = root->children()[0];
1028 LayerImpl* child = parent->children()[0];
1030 switch (host_impl->active_tree()->source_frame_number()) {
1031 case 0:
1032 EXPECT_EQ(0.f, parent->opacity());
1033 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
1034 break;
1035 case 1:
1036 EXPECT_EQ(1.f, parent->opacity());
1037 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
1038 EndTest();
1039 break;
1040 default:
1041 NOTREACHED();
1045 void DidCommit() override {
1046 switch (layer_tree_host()->source_frame_number()) {
1047 case 1:
1048 parent_layer_->SetOpacity(1.0f);
1049 break;
1050 case 2:
1051 break;
1052 default:
1053 NOTREACHED();
1057 void AfterTest() override {}
1059 private:
1060 scoped_refptr<Layer> root_layer_;
1061 scoped_refptr<Layer> parent_layer_;
1062 scoped_refptr<Layer> child_layer_;
1065 SINGLE_AND_MULTI_THREAD_TEST_F(
1066 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
1068 // This test verifies that properties on the layer tree host are commited
1069 // to the impl side.
1070 class LayerTreeHostTestCommit : public LayerTreeHostTest {
1071 public:
1072 LayerTreeHostTestCommit() {}
1074 void BeginTest() override {
1075 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1076 layer_tree_host()->set_background_color(SK_ColorGRAY);
1078 PostSetNeedsCommitToMainThread();
1081 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1082 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
1083 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
1085 EndTest();
1088 void AfterTest() override {}
1091 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
1093 // This test verifies that LayerTreeHostImpl's current frame time gets
1094 // updated in consecutive frames when it doesn't draw due to tree
1095 // activation failure.
1096 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
1097 : public LayerTreeHostTest {
1098 public:
1099 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
1100 : frame_count_with_pending_tree_(0) {}
1102 void BeginTest() override {
1103 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1104 layer_tree_host()->set_background_color(SK_ColorGRAY);
1106 PostSetNeedsCommitToMainThread();
1109 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
1110 EXPECT_EQ(frame_count_with_pending_tree_, 0);
1111 if (impl->settings().impl_side_painting)
1112 impl->BlockNotifyReadyToActivateForTesting(true);
1115 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1116 const BeginFrameArgs& args) override {
1117 if (impl->pending_tree())
1118 frame_count_with_pending_tree_++;
1120 if (frame_count_with_pending_tree_ == 1) {
1121 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
1122 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1123 } else if (frame_count_with_pending_tree_ == 2 &&
1124 impl->settings().impl_side_painting) {
1125 impl->BlockNotifyReadyToActivateForTesting(false);
1129 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1130 if (frame_count_with_pending_tree_ > 1) {
1131 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
1132 EXPECT_NE(first_frame_time_.ToInternalValue(),
1133 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
1134 EndTest();
1135 return;
1138 EXPECT_FALSE(impl->settings().impl_side_painting);
1139 EndTest();
1141 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1142 if (impl->settings().impl_side_painting)
1143 EXPECT_NE(frame_count_with_pending_tree_, 1);
1146 void AfterTest() override {}
1148 private:
1149 int frame_count_with_pending_tree_;
1150 base::TimeTicks first_frame_time_;
1153 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1154 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
1156 // This test verifies that LayerTreeHostImpl's current frame time gets
1157 // updated in consecutive frames when it draws in each frame.
1158 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
1159 public:
1160 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(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 DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1170 frame_++;
1171 if (frame_ == 1) {
1172 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1173 impl->SetNeedsRedraw();
1175 // Since we might use a low-resolution clock on Windows, we need to
1176 // make sure that the clock has incremented past first_frame_time_.
1177 while (first_frame_time_ == gfx::FrameTime::Now()) {
1180 return;
1183 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
1184 EndTest();
1187 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1188 // Ensure there isn't a commit between the two draws, to ensure that a
1189 // commit isn't required for updating the current frame time. We can
1190 // only check for this in the multi-threaded case, since in the single-
1191 // threaded case there will always be a commit between consecutive draws.
1192 if (HasImplThread())
1193 EXPECT_EQ(0, frame_);
1196 void AfterTest() override {}
1198 private:
1199 int frame_;
1200 base::TimeTicks first_frame_time_;
1203 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1205 // Verifies that StartPageScaleAnimation events propagate correctly
1206 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1207 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
1208 public:
1209 LayerTreeHostTestStartPageScaleAnimation() {}
1211 void SetupTree() override {
1212 LayerTreeHostTest::SetupTree();
1214 if (layer_tree_host()->settings().impl_side_painting) {
1215 scoped_refptr<FakePictureLayer> layer =
1216 FakePictureLayer::Create(&client_);
1217 layer->set_always_update_resources(true);
1218 scroll_layer_ = layer;
1219 } else {
1220 scroll_layer_ = FakeContentLayer::Create(&client_);
1223 Layer* root_layer = layer_tree_host()->root_layer();
1224 scroll_layer_->SetScrollClipLayerId(root_layer->id());
1225 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
1226 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
1227 2 * root_layer->bounds().height()));
1228 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
1229 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1230 // This test requires the page_scale and inner viewport layers to be
1231 // identified.
1232 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
1233 scroll_layer_.get(), NULL);
1234 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1237 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1239 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
1240 float scale,
1241 float) override {
1242 gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
1243 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset,
1244 scroll_delta));
1245 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1248 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1249 // We get one commit before the first draw, and the animation doesn't happen
1250 // until the second draw.
1251 switch (impl->active_tree()->source_frame_number()) {
1252 case 0:
1253 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1254 // We'll start an animation when we get back to the main thread.
1255 break;
1256 case 1:
1257 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1258 break;
1259 case 2:
1260 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
1261 EndTest();
1262 break;
1263 default:
1264 NOTREACHED();
1268 void DidCommitAndDrawFrame() override {
1269 switch (layer_tree_host()->source_frame_number()) {
1270 case 1:
1271 layer_tree_host()->StartPageScaleAnimation(
1272 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1273 break;
1277 void AfterTest() override {}
1279 FakeContentLayerClient client_;
1280 scoped_refptr<Layer> scroll_layer_;
1283 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1285 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1286 public:
1287 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1289 void BeginTest() override {
1290 PostSetNeedsCommitToMainThread();
1291 PostSetVisibleToMainThread(false);
1292 // This is suppressed while we're invisible.
1293 PostSetNeedsRedrawToMainThread();
1294 // Triggers the redraw.
1295 PostSetVisibleToMainThread(true);
1298 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1299 EXPECT_TRUE(impl->visible());
1300 ++num_draws_;
1301 EndTest();
1304 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
1306 private:
1307 int num_draws_;
1310 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1312 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1313 public:
1314 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1316 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1318 void PaintContents(SkCanvas* canvas,
1319 const gfx::Rect& clip,
1320 PaintingControlSetting picture_control) override {
1321 // Set layer opacity to 0.
1322 if (test_layer_)
1323 test_layer_->SetOpacity(0.f);
1325 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
1326 const gfx::Rect& clip,
1327 PaintingControlSetting picture_control) override {
1328 NOTIMPLEMENTED();
1329 return DisplayItemList::Create();
1331 bool FillsBoundsCompletely() const override { return false; }
1333 private:
1334 Layer* test_layer_;
1337 class ContentLayerWithUpdateTracking : public ContentLayer {
1338 public:
1339 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1340 ContentLayerClient* client) {
1341 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1344 int PaintContentsCount() { return paint_contents_count_; }
1345 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1347 bool Update(ResourceUpdateQueue* queue,
1348 const OcclusionTracker<Layer>* occlusion) override {
1349 bool updated = ContentLayer::Update(queue, occlusion);
1350 paint_contents_count_++;
1351 return updated;
1354 private:
1355 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1356 : ContentLayer(client), paint_contents_count_(0) {
1357 SetBounds(gfx::Size(10, 10));
1358 SetIsDrawable(true);
1360 ~ContentLayerWithUpdateTracking() override {}
1362 int paint_contents_count_;
1365 // Layer opacity change during paint should not prevent compositor resources
1366 // from being updated during commit.
1367 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1368 public:
1369 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {}
1371 void BeginTest() override {
1372 if (layer_tree_host()->settings().impl_side_painting) {
1373 update_check_picture_layer_ =
1374 FakePictureLayer::Create(&test_opacity_change_delegate_);
1375 test_opacity_change_delegate_.SetTestLayer(
1376 update_check_picture_layer_.get());
1377 is_impl_paint_ = true;
1378 } else {
1379 update_check_content_layer_ = ContentLayerWithUpdateTracking::Create(
1380 &test_opacity_change_delegate_);
1381 test_opacity_change_delegate_.SetTestLayer(
1382 update_check_content_layer_.get());
1383 is_impl_paint_ = false;
1385 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1386 if (layer_tree_host()->settings().impl_side_painting)
1387 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
1388 else
1389 layer_tree_host()->root_layer()->AddChild(update_check_content_layer_);
1391 PostSetNeedsCommitToMainThread();
1394 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
1396 void AfterTest() override {
1397 // Update() should have been called once.
1398 if (is_impl_paint_)
1399 EXPECT_EQ(1u, update_check_picture_layer_->update_count());
1400 else
1401 EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount());
1404 private:
1405 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1406 scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_;
1407 scoped_refptr<FakePictureLayer> update_check_picture_layer_;
1408 bool is_impl_paint_;
1411 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1413 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1414 : public LayerTreeHostTest {
1415 public:
1416 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {}
1418 void InitializeSettings(LayerTreeSettings* settings) override {
1419 // PictureLayer can only be used with impl side painting enabled.
1420 settings->impl_side_painting = true;
1423 void BeginTest() override {
1424 client_.set_fill_with_nonsolid_color(true);
1425 root_layer_ = FakePictureLayer::Create(&client_);
1426 child_layer_ = FakePictureLayer::Create(&client_);
1428 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1429 layer_tree_host()->SetDeviceScaleFactor(1.5);
1430 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1432 root_layer_->AddChild(child_layer_);
1434 root_layer_->SetIsDrawable(true);
1435 root_layer_->SetBounds(gfx::Size(30, 30));
1437 child_layer_->SetIsDrawable(true);
1438 child_layer_->SetPosition(gfx::Point(2, 2));
1439 child_layer_->SetBounds(gfx::Size(10, 10));
1441 layer_tree_host()->SetRootLayer(root_layer_);
1443 PostSetNeedsCommitToMainThread();
1446 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1447 // Should only do one commit.
1448 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1449 // Device scale factor should come over to impl.
1450 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1452 // Both layers are on impl.
1453 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1455 // Device viewport is scaled.
1456 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1458 FakePictureLayerImpl* root =
1459 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
1460 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
1461 impl->active_tree()->root_layer()->children()[0]);
1463 // Positions remain in layout pixels.
1464 EXPECT_EQ(gfx::Point(0, 0), root->position());
1465 EXPECT_EQ(gfx::Point(2, 2), child->position());
1467 // Compute all the layer transforms for the frame.
1468 LayerTreeHostImpl::FrameData frame_data;
1469 impl->PrepareToDraw(&frame_data);
1470 impl->DidDrawAllLayers(frame_data);
1472 const LayerImplList& render_surface_layer_list =
1473 *frame_data.render_surface_layer_list;
1475 // Both layers should be drawing into the root render surface.
1476 ASSERT_EQ(1u, render_surface_layer_list.size());
1477 ASSERT_EQ(root->render_surface(),
1478 render_surface_layer_list[0]->render_surface());
1479 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1481 // The root render surface is the size of the viewport.
1482 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect());
1484 // The max tiling scale of the child should be scaled.
1485 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale());
1487 gfx::Transform scale_transform;
1488 scale_transform.Scale(impl->device_scale_factor(),
1489 impl->device_scale_factor());
1491 // The root layer is scaled by 2x.
1492 gfx::Transform root_screen_space_transform = scale_transform;
1493 gfx::Transform root_draw_transform = scale_transform;
1495 EXPECT_EQ(root_draw_transform, root->draw_transform());
1496 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1498 // The child is at position 2,2, which is transformed to 3,3 after the scale
1499 gfx::Transform child_transform;
1500 child_transform.Translate(3.f, 3.f);
1501 child_transform.Scale(child->MaximumTilingContentsScale(),
1502 child->MaximumTilingContentsScale());
1504 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform());
1505 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform,
1506 child->screen_space_transform());
1508 EndTest();
1511 void AfterTest() override {}
1513 private:
1514 FakeContentLayerClient client_;
1515 scoped_refptr<FakePictureLayer> root_layer_;
1516 scoped_refptr<FakePictureLayer> child_layer_;
1519 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1521 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1522 // Verify atomicity of commits and reuse of textures.
1523 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1524 public:
1525 void InitializeSettings(LayerTreeSettings* settings) override {
1526 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1527 // Make sure partial texture updates are turned off.
1528 settings->max_partial_texture_updates = 0;
1529 // Linear fade animator prevents scrollbars from drawing immediately.
1530 settings->scrollbar_animator = LayerTreeSettings::NO_ANIMATOR;
1533 void SetupTree() override {
1534 layer_ = FakeContentLayer::Create(&client_);
1535 layer_->SetBounds(gfx::Size(10, 20));
1537 bool paint_scrollbar = true;
1538 bool has_thumb = false;
1539 scrollbar_ = FakePaintedScrollbarLayer::Create(
1540 paint_scrollbar, has_thumb, layer_->id());
1541 scrollbar_->SetPosition(gfx::Point(0, 10));
1542 scrollbar_->SetBounds(gfx::Size(10, 10));
1544 layer_->AddChild(scrollbar_);
1546 layer_tree_host()->SetRootLayer(layer_);
1547 LayerTreeHostTest::SetupTree();
1550 void BeginTest() override {
1551 drew_frame_ = -1;
1552 PostSetNeedsCommitToMainThread();
1555 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1556 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
1558 TestWebGraphicsContext3D* context = TestContext();
1560 switch (impl->active_tree()->source_frame_number()) {
1561 case 0:
1562 // Number of textures should be one for each layer
1563 ASSERT_EQ(2u, context->NumTextures());
1564 // Number of textures used for commit should be one for each layer.
1565 EXPECT_EQ(2u, context->NumUsedTextures());
1566 // Verify that used texture is correct.
1567 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1568 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1570 context->ResetUsedTextures();
1571 break;
1572 case 1:
1573 // Number of textures should be one for scrollbar layer since it was
1574 // requested and deleted on the impl-thread, and double for the content
1575 // layer since its first texture is used by impl thread and cannot by
1576 // used for update.
1577 ASSERT_EQ(3u, context->NumTextures());
1578 // Number of textures used for commit should be one for each layer.
1579 EXPECT_EQ(2u, context->NumUsedTextures());
1580 // First textures should not have been used.
1581 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1582 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1583 // New textures should have been used.
1584 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1585 context->ResetUsedTextures();
1586 break;
1587 case 2:
1588 EndTest();
1589 break;
1590 default:
1591 NOTREACHED();
1592 break;
1596 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1597 TestWebGraphicsContext3D* context = TestContext();
1599 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1600 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1601 return;
1603 drew_frame_ = impl->active_tree()->source_frame_number();
1605 // We draw/ship one texture each frame for each layer.
1606 EXPECT_EQ(2u, context->NumUsedTextures());
1607 context->ResetUsedTextures();
1609 if (!TestEnded())
1610 PostSetNeedsCommitToMainThread();
1613 void Layout() override {
1614 layer_->SetNeedsDisplay();
1615 scrollbar_->SetNeedsDisplay();
1618 void AfterTest() override {}
1620 protected:
1621 FakeContentLayerClient client_;
1622 scoped_refptr<FakeContentLayer> layer_;
1623 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1624 int drew_frame_;
1627 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1628 LayerTreeHostTestDirectRendererAtomicCommit);
1630 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1631 class LayerTreeHostTestDelegatingRendererAtomicCommit
1632 : public LayerTreeHostTestDirectRendererAtomicCommit {
1633 public:
1634 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1635 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
1637 TestWebGraphicsContext3D* context = TestContext();
1639 switch (impl->active_tree()->source_frame_number()) {
1640 case 0:
1641 // Number of textures should be one for each layer
1642 ASSERT_EQ(2u, context->NumTextures());
1643 // Number of textures used for commit should be one for each layer.
1644 EXPECT_EQ(2u, context->NumUsedTextures());
1645 // Verify that used texture is correct.
1646 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1647 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1648 break;
1649 case 1:
1650 // Number of textures should be doubled as the first context layer
1651 // texture is being used by the impl-thread and cannot be used for
1652 // update. The scrollbar behavior is different direct renderer because
1653 // UI resource deletion with delegating renderer occurs after tree
1654 // activation.
1655 ASSERT_EQ(4u, context->NumTextures());
1656 // Number of textures used for commit should still be
1657 // one for each layer.
1658 EXPECT_EQ(2u, context->NumUsedTextures());
1659 // First textures should not have been used.
1660 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1661 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1662 // New textures should have been used.
1663 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1664 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1665 break;
1666 case 2:
1667 EndTest();
1668 break;
1669 default:
1670 NOTREACHED();
1671 break;
1676 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1677 LayerTreeHostTestDelegatingRendererAtomicCommit);
1679 static void SetLayerPropertiesForTesting(Layer* layer,
1680 Layer* parent,
1681 const gfx::Transform& transform,
1682 const gfx::Point3F& transform_origin,
1683 const gfx::PointF& position,
1684 const gfx::Size& bounds,
1685 bool opaque) {
1686 layer->RemoveAllChildren();
1687 if (parent)
1688 parent->AddChild(layer);
1689 layer->SetTransform(transform);
1690 layer->SetTransformOrigin(transform_origin);
1691 layer->SetPosition(position);
1692 layer->SetBounds(bounds);
1693 layer->SetContentsOpaque(opaque);
1696 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1697 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1698 : public LayerTreeHostTest {
1699 public:
1700 void InitializeSettings(LayerTreeSettings* settings) override {
1701 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1702 // Allow one partial texture update.
1703 settings->max_partial_texture_updates = 1;
1704 // No partial updates when impl side painting is enabled.
1705 settings->impl_side_painting = false;
1708 void SetupTree() override {
1709 parent_ = FakeContentLayer::Create(&client_);
1710 parent_->SetBounds(gfx::Size(10, 20));
1712 child_ = FakeContentLayer::Create(&client_);
1713 child_->SetPosition(gfx::Point(0, 10));
1714 child_->SetBounds(gfx::Size(3, 10));
1716 parent_->AddChild(child_);
1718 layer_tree_host()->SetRootLayer(parent_);
1719 LayerTreeHostTest::SetupTree();
1722 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1724 void DidCommitAndDrawFrame() override {
1725 switch (layer_tree_host()->source_frame_number()) {
1726 case 1:
1727 parent_->SetNeedsDisplay();
1728 child_->SetNeedsDisplay();
1729 break;
1730 case 2:
1731 // Damage part of layers.
1732 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1733 child_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1734 break;
1735 case 3:
1736 child_->SetNeedsDisplay();
1737 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1738 break;
1739 case 4:
1740 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1741 break;
1742 case 5:
1743 EndTest();
1744 break;
1745 default:
1746 NOTREACHED() << layer_tree_host()->source_frame_number();
1747 break;
1751 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1752 ASSERT_EQ(1u, impl->settings().max_partial_texture_updates);
1754 TestWebGraphicsContext3D* context = TestContext();
1756 switch (impl->active_tree()->source_frame_number()) {
1757 case 0:
1758 // Number of textures should be one for each layer.
1759 ASSERT_EQ(2u, context->NumTextures());
1760 // Number of textures used for commit should be one for each layer.
1761 EXPECT_EQ(2u, context->NumUsedTextures());
1762 // Verify that used textures are correct.
1763 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1764 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1765 context->ResetUsedTextures();
1766 break;
1767 case 1:
1768 if (HasImplThread()) {
1769 // Number of textures should be two for each content layer.
1770 ASSERT_EQ(4u, context->NumTextures());
1771 } else {
1772 // In single thread we can always do partial updates, so the limit has
1773 // no effect.
1774 ASSERT_EQ(2u, context->NumTextures());
1776 // Number of textures used for commit should be one for each content
1777 // layer.
1778 EXPECT_EQ(2u, context->NumUsedTextures());
1780 if (HasImplThread()) {
1781 // First content textures should not have been used.
1782 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1783 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1784 // New textures should have been used.
1785 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1786 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1787 } else {
1788 // In single thread we can always do partial updates, so the limit has
1789 // no effect.
1790 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1791 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1794 context->ResetUsedTextures();
1795 break;
1796 case 2:
1797 if (HasImplThread()) {
1798 // Number of textures should be two for each content layer.
1799 ASSERT_EQ(4u, context->NumTextures());
1800 } else {
1801 // In single thread we can always do partial updates, so the limit has
1802 // no effect.
1803 ASSERT_EQ(2u, context->NumTextures());
1805 // Number of textures used for commit should be one for each content
1806 // layer.
1807 EXPECT_EQ(2u, context->NumUsedTextures());
1809 if (HasImplThread()) {
1810 // One content layer does a partial update also.
1811 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1812 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1813 } else {
1814 // In single thread we can always do partial updates, so the limit has
1815 // no effect.
1816 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1817 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1820 context->ResetUsedTextures();
1821 break;
1822 case 3:
1823 // No textures should be used for commit.
1824 EXPECT_EQ(0u, context->NumUsedTextures());
1826 context->ResetUsedTextures();
1827 break;
1828 case 4:
1829 // Number of textures used for commit should be one, for the
1830 // content layer.
1831 EXPECT_EQ(1u, context->NumUsedTextures());
1833 context->ResetUsedTextures();
1834 break;
1835 default:
1836 NOTREACHED();
1837 break;
1841 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1842 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1844 TestWebGraphicsContext3D* context = TestContext();
1846 // Number of textures used for drawing should one per layer except for
1847 // frame 3 where the viewport only contains one layer.
1848 if (impl->active_tree()->source_frame_number() == 3) {
1849 EXPECT_EQ(1u, context->NumUsedTextures());
1850 } else {
1851 EXPECT_EQ(2u, context->NumUsedTextures())
1852 << "For frame " << impl->active_tree()->source_frame_number();
1855 context->ResetUsedTextures();
1858 void AfterTest() override {}
1860 private:
1861 FakeContentLayerClient client_;
1862 scoped_refptr<FakeContentLayer> parent_;
1863 scoped_refptr<FakeContentLayer> child_;
1866 // Partial updates are not possible with a delegating renderer.
1867 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1868 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1870 // TODO(sohanjg) : Make it work with impl-side painting.
1871 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1872 : public LayerTreeHostTest {
1873 protected:
1874 void SetupTree() override {
1875 root_layer_ = FakeContentLayer::Create(&client_);
1876 root_layer_->SetBounds(gfx::Size(100, 100));
1878 surface_layer1_ = FakeContentLayer::Create(&client_);
1879 surface_layer1_->SetBounds(gfx::Size(100, 100));
1880 surface_layer1_->SetForceRenderSurface(true);
1881 surface_layer1_->SetOpacity(0.5f);
1882 root_layer_->AddChild(surface_layer1_);
1884 surface_layer2_ = FakeContentLayer::Create(&client_);
1885 surface_layer2_->SetBounds(gfx::Size(100, 100));
1886 surface_layer2_->SetForceRenderSurface(true);
1887 surface_layer2_->SetOpacity(0.5f);
1888 surface_layer1_->AddChild(surface_layer2_);
1890 replica_layer1_ = FakeContentLayer::Create(&client_);
1891 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1893 replica_layer2_ = FakeContentLayer::Create(&client_);
1894 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1896 layer_tree_host()->SetRootLayer(root_layer_);
1897 LayerTreeHostTest::SetupTree();
1900 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1902 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1903 Renderer* renderer = host_impl->renderer();
1904 RenderPassId surface1_render_pass_id = host_impl->active_tree()
1905 ->root_layer()
1906 ->children()[0]
1907 ->render_surface()
1908 ->GetRenderPassId();
1909 RenderPassId surface2_render_pass_id = host_impl->active_tree()
1910 ->root_layer()
1911 ->children()[0]
1912 ->children()[0]
1913 ->render_surface()
1914 ->GetRenderPassId();
1916 switch (host_impl->active_tree()->source_frame_number()) {
1917 case 0:
1918 EXPECT_TRUE(
1919 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1920 EXPECT_TRUE(
1921 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1923 // Reduce the memory limit to only fit the root layer and one render
1924 // surface. This prevents any contents drawing into surfaces
1925 // from being allocated.
1926 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1927 break;
1928 case 1:
1929 EXPECT_FALSE(
1930 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1931 EXPECT_FALSE(
1932 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1934 EndTest();
1935 break;
1939 void DidCommitAndDrawFrame() override {
1940 if (layer_tree_host()->source_frame_number() < 2)
1941 root_layer_->SetNeedsDisplay();
1944 void AfterTest() override {
1945 EXPECT_LE(2u, root_layer_->update_count());
1946 EXPECT_LE(2u, surface_layer1_->update_count());
1947 EXPECT_LE(2u, surface_layer2_->update_count());
1950 FakeContentLayerClient client_;
1951 scoped_refptr<FakeContentLayer> root_layer_;
1952 scoped_refptr<FakeContentLayer> surface_layer1_;
1953 scoped_refptr<FakeContentLayer> replica_layer1_;
1954 scoped_refptr<FakeContentLayer> surface_layer2_;
1955 scoped_refptr<FakeContentLayer> replica_layer2_;
1958 // Surfaces don't exist with a delegated renderer.
1959 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1960 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1962 class EvictionTestLayer : public Layer {
1963 public:
1964 static scoped_refptr<EvictionTestLayer> Create() {
1965 return make_scoped_refptr(new EvictionTestLayer());
1968 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override;
1969 bool DrawsContent() const override { return true; }
1971 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
1972 void PushPropertiesTo(LayerImpl* impl) override;
1973 void SetTexturePriorities(const PriorityCalculator&) override;
1975 bool HaveBackingTexture() const {
1976 return texture_.get() ? texture_->have_backing_texture() : false;
1979 private:
1980 EvictionTestLayer() : Layer() {}
1981 ~EvictionTestLayer() override {}
1983 void CreateTextureIfNeeded() {
1984 if (texture_)
1985 return;
1986 texture_ = PrioritizedResource::Create(
1987 layer_tree_host()->contents_texture_manager());
1988 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1989 bitmap_.allocN32Pixels(10, 10);
1992 scoped_ptr<PrioritizedResource> texture_;
1993 SkBitmap bitmap_;
1996 class EvictionTestLayerImpl : public LayerImpl {
1997 public:
1998 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1999 int id) {
2000 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
2002 ~EvictionTestLayerImpl() override {}
2004 void AppendQuads(RenderPass* render_pass,
2005 AppendQuadsData* append_quads_data) override {
2006 ASSERT_TRUE(has_texture_);
2007 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
2010 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
2012 private:
2013 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
2014 : LayerImpl(tree_impl, id), has_texture_(false) {}
2016 bool has_texture_;
2019 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
2020 CreateTextureIfNeeded();
2021 if (!texture_)
2022 return;
2023 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
2026 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
2027 const OcclusionTracker<Layer>* occlusion) {
2028 CreateTextureIfNeeded();
2029 if (!texture_)
2030 return false;
2032 gfx::Rect full_rect(0, 0, 10, 10);
2033 ResourceUpdate upload = ResourceUpdate::Create(
2034 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
2035 queue->AppendFullUpload(upload);
2036 return true;
2039 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
2040 LayerTreeImpl* tree_impl) {
2041 return EvictionTestLayerImpl::Create(tree_impl, layer_id_);
2044 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
2045 Layer::PushPropertiesTo(layer_impl);
2047 EvictionTestLayerImpl* test_layer_impl =
2048 static_cast<EvictionTestLayerImpl*>(layer_impl);
2049 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
2052 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
2053 public:
2054 LayerTreeHostTestEvictTextures()
2055 : layer_(EvictionTestLayer::Create()),
2056 impl_for_evict_textures_(0),
2057 num_commits_(0) {}
2059 void BeginTest() override {
2060 layer_tree_host()->SetRootLayer(layer_);
2061 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
2063 gfx::Transform identity_matrix;
2064 SetLayerPropertiesForTesting(layer_.get(),
2066 identity_matrix,
2067 gfx::Point3F(0.f, 0.f, 0.f),
2068 gfx::PointF(0.f, 0.f),
2069 gfx::Size(10, 20),
2070 true);
2072 PostSetNeedsCommitToMainThread();
2075 void PostEvictTextures() {
2076 ImplThreadTaskRunner()->PostTask(
2077 FROM_HERE,
2078 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
2079 base::Unretained(this)));
2082 void EvictTexturesOnImplThread() {
2083 DCHECK(impl_for_evict_textures_);
2084 impl_for_evict_textures_->EvictTexturesForTesting();
2087 // Commit 1: Just commit and draw normally, then post an eviction at the end
2088 // that will trigger a commit.
2089 // Commit 2: Triggered by the eviction, let it go through and then set
2090 // needsCommit.
2091 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
2092 // task, which will be handled before the commit. Don't set needsCommit, it
2093 // should have been posted. A frame should not be drawn (note,
2094 // didCommitAndDrawFrame may be called anyway).
2095 // Commit 4: Triggered by the eviction, let it go through and then set
2096 // needsCommit.
2097 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
2098 // Layout(), a frame should not be drawn but a commit will be posted.
2099 // Commit 6: Triggered by the eviction, post an eviction task in
2100 // Layout(), which will be a noop, letting the commit (which recreates the
2101 // textures) go through and draw a frame, then end the test.
2103 // Commits 1+2 test the eviction recovery path where eviction happens outside
2104 // of the beginFrame/commit pair.
2105 // Commits 3+4 test the eviction recovery path where eviction happens inside
2106 // the beginFrame/commit pair.
2107 // Commits 5+6 test the path where an eviction happens during the eviction
2108 // recovery path.
2109 void DidCommit() override {
2110 switch (num_commits_) {
2111 case 1:
2112 EXPECT_TRUE(layer_->HaveBackingTexture());
2113 PostEvictTextures();
2114 break;
2115 case 2:
2116 EXPECT_TRUE(layer_->HaveBackingTexture());
2117 layer_tree_host()->SetNeedsCommit();
2118 break;
2119 case 3:
2120 break;
2121 case 4:
2122 EXPECT_TRUE(layer_->HaveBackingTexture());
2123 layer_tree_host()->SetNeedsCommit();
2124 break;
2125 case 5:
2126 break;
2127 case 6:
2128 EXPECT_TRUE(layer_->HaveBackingTexture());
2129 EndTest();
2130 break;
2131 default:
2132 NOTREACHED();
2133 break;
2137 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2138 impl_for_evict_textures_ = impl;
2141 void Layout() override {
2142 ++num_commits_;
2143 switch (num_commits_) {
2144 case 1:
2145 case 2:
2146 break;
2147 case 3:
2148 PostEvictTextures();
2149 break;
2150 case 4:
2151 // We couldn't check in didCommitAndDrawFrame on commit 3,
2152 // so check here.
2153 EXPECT_FALSE(layer_->HaveBackingTexture());
2154 break;
2155 case 5:
2156 PostEvictTextures();
2157 break;
2158 case 6:
2159 // We couldn't check in didCommitAndDrawFrame on commit 5,
2160 // so check here.
2161 EXPECT_FALSE(layer_->HaveBackingTexture());
2162 PostEvictTextures();
2163 break;
2164 default:
2165 NOTREACHED();
2166 break;
2170 void AfterTest() override {}
2172 private:
2173 FakeContentLayerClient client_;
2174 scoped_refptr<EvictionTestLayer> layer_;
2175 LayerTreeHostImpl* impl_for_evict_textures_;
2176 int num_commits_;
2179 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
2181 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
2182 public:
2183 LayerTreeHostTestContinuousInvalidate()
2184 : num_commit_complete_(0), num_draw_layers_(0) {}
2186 void BeginTest() override {
2187 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2188 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2190 if (layer_tree_host()->settings().impl_side_painting)
2191 layer_ = FakePictureLayer::Create(&client_);
2192 else
2193 layer_ = FakeContentLayer::Create(&client_);
2195 layer_->SetBounds(gfx::Size(10, 10));
2196 layer_->SetPosition(gfx::PointF(0.f, 0.f));
2197 layer_->SetIsDrawable(true);
2198 layer_tree_host()->root_layer()->AddChild(layer_);
2200 PostSetNeedsCommitToMainThread();
2203 void DidCommitAndDrawFrame() override {
2204 if (num_draw_layers_ == 2)
2205 return;
2206 layer_->SetNeedsDisplay();
2209 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2210 if (num_draw_layers_ == 1)
2211 num_commit_complete_++;
2214 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2215 num_draw_layers_++;
2216 if (num_draw_layers_ == 2)
2217 EndTest();
2220 void AfterTest() override {
2221 // Check that we didn't commit twice between first and second draw.
2222 EXPECT_EQ(1, num_commit_complete_);
2225 private:
2226 FakeContentLayerClient client_;
2227 scoped_refptr<Layer> layer_;
2228 int num_commit_complete_;
2229 int num_draw_layers_;
2232 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
2234 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2235 public:
2236 LayerTreeHostTestDeferCommits()
2237 : num_will_begin_impl_frame_(0),
2238 num_send_begin_main_frame_(0) {}
2240 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2242 void WillBeginImplFrame(const BeginFrameArgs& args) override {
2243 num_will_begin_impl_frame_++;
2244 switch (num_will_begin_impl_frame_) {
2245 case 1:
2246 break;
2247 case 2:
2248 case 3:
2249 case 4:
2250 // Post a number of frames to increase the chance that, if there exist
2251 // bugs, an unexpected BeginMainFrame will be issued.
2252 PostSetNeedsCommitToMainThread();
2253 PostSetNeedsRedrawToMainThread();
2254 break;
2255 case 5:
2256 PostSetDeferCommitsToMainThread(false);
2257 break;
2258 default:
2259 // Sometimes |num_will_begin_impl_frame_| will be greater than 5 if the
2260 // main thread is slow to respond.
2261 break;
2265 void ScheduledActionSendBeginMainFrame() override {
2266 num_send_begin_main_frame_++;
2267 switch (num_send_begin_main_frame_) {
2268 case 1:
2269 PostSetDeferCommitsToMainThread(true);
2270 break;
2271 case 2:
2272 EndTest();
2273 break;
2274 default:
2275 NOTREACHED();
2276 break;
2280 void AfterTest() override {
2281 EXPECT_GE(num_will_begin_impl_frame_, 5);
2282 EXPECT_EQ(2, num_send_begin_main_frame_);
2285 private:
2286 int num_will_begin_impl_frame_;
2287 int num_send_begin_main_frame_;
2290 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2292 class LayerTreeHostWithProxy : public LayerTreeHost {
2293 public:
2294 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2295 const LayerTreeSettings& settings,
2296 scoped_ptr<FakeProxy> proxy)
2297 : LayerTreeHost(client, NULL, NULL, NULL, settings) {
2298 proxy->SetLayerTreeHost(this);
2299 client->SetLayerTreeHost(this);
2300 InitializeForTesting(proxy.Pass());
2304 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2305 // When partial updates are not allowed, max updates should be 0.
2307 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2309 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2310 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2311 proxy->SetMaxPartialTextureUpdates(5);
2313 LayerTreeSettings settings;
2314 settings.impl_side_painting = false;
2315 settings.max_partial_texture_updates = 10;
2317 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2319 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2322 // When partial updates are allowed,
2323 // max updates should be limited by the proxy.
2325 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2327 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2328 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2329 proxy->SetMaxPartialTextureUpdates(5);
2331 LayerTreeSettings settings;
2332 settings.impl_side_painting = false;
2333 settings.max_partial_texture_updates = 10;
2335 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2337 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2340 // When partial updates are allowed,
2341 // max updates should also be limited by the settings.
2343 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2345 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2346 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2347 proxy->SetMaxPartialTextureUpdates(20);
2349 LayerTreeSettings settings;
2350 settings.impl_side_painting = false;
2351 settings.max_partial_texture_updates = 10;
2353 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2355 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2359 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2360 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2362 LayerTreeSettings settings;
2363 settings.max_partial_texture_updates = 4;
2364 settings.single_thread_proxy_scheduler = false;
2365 settings.impl_side_painting = false;
2367 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2368 new TestSharedBitmapManager());
2369 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2370 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2371 base::MessageLoopProxy::current(), nullptr);
2372 client.SetLayerTreeHost(host.get());
2373 host->Composite(base::TimeTicks::Now());
2375 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2378 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2379 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2381 LayerTreeSettings settings;
2382 settings.max_partial_texture_updates = 4;
2383 settings.single_thread_proxy_scheduler = false;
2384 settings.impl_side_painting = false;
2386 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2387 new TestSharedBitmapManager());
2388 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2389 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2390 base::MessageLoopProxy::current(), nullptr);
2391 client.SetLayerTreeHost(host.get());
2392 host->Composite(base::TimeTicks::Now());
2394 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2397 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2398 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2400 LayerTreeSettings settings;
2401 settings.max_partial_texture_updates = 4;
2402 settings.single_thread_proxy_scheduler = false;
2403 settings.impl_side_painting = false;
2405 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2406 new TestSharedBitmapManager());
2407 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2408 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2409 base::MessageLoopProxy::current(), nullptr);
2410 client.SetLayerTreeHost(host.get());
2411 host->Composite(base::TimeTicks::Now());
2413 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2416 TEST(LayerTreeHostTest,
2417 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2418 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2420 LayerTreeSettings settings;
2421 settings.max_partial_texture_updates = 4;
2422 settings.single_thread_proxy_scheduler = false;
2423 settings.impl_side_painting = false;
2425 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2426 new TestSharedBitmapManager());
2427 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2428 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2429 base::MessageLoopProxy::current(), nullptr);
2430 client.SetLayerTreeHost(host.get());
2431 host->Composite(base::TimeTicks::Now());
2433 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2436 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
2437 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2438 : public LayerTreeHostTest {
2439 public:
2440 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2441 : root_layer_(FakeContentLayer::Create(&client_)),
2442 child_layer1_(FakeContentLayer::Create(&client_)),
2443 child_layer2_(FakeContentLayer::Create(&client_)),
2444 num_commits_(0) {}
2446 void BeginTest() override {
2447 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2448 root_layer_->SetBounds(gfx::Size(100, 100));
2449 child_layer1_->SetBounds(gfx::Size(100, 100));
2450 child_layer2_->SetBounds(gfx::Size(100, 100));
2451 root_layer_->AddChild(child_layer1_);
2452 root_layer_->AddChild(child_layer2_);
2453 layer_tree_host()->SetRootLayer(root_layer_);
2454 PostSetNeedsCommitToMainThread();
2457 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2458 bool visible) override {
2459 if (visible) {
2460 // One backing should remain unevicted.
2461 EXPECT_EQ(100u * 100u * 4u * 1u,
2462 contents_texture_manager_->MemoryUseBytes());
2463 } else {
2464 EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes());
2467 // Make sure that contents textures are marked as having been
2468 // purged.
2469 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2470 // End the test in this state.
2471 EndTest();
2474 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2475 ++num_commits_;
2476 switch (num_commits_) {
2477 case 1:
2478 // All three backings should have memory.
2479 EXPECT_EQ(100u * 100u * 4u * 3u,
2480 contents_texture_manager_->MemoryUseBytes());
2482 // Set a new policy that will kick out 1 of the 3 resources.
2483 // Because a resource was evicted, a commit will be kicked off.
2484 host_impl->SetMemoryPolicy(
2485 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2486 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2487 1000));
2488 break;
2489 case 2:
2490 // Only two backings should have memory.
2491 EXPECT_EQ(100u * 100u * 4u * 2u,
2492 contents_texture_manager_->MemoryUseBytes());
2493 // Become backgrounded, which will cause 1 more resource to be
2494 // evicted.
2495 PostSetVisibleToMainThread(false);
2496 break;
2497 default:
2498 // No further commits should happen because this is not visible
2499 // anymore.
2500 NOTREACHED();
2501 break;
2505 void AfterTest() override {}
2507 private:
2508 FakeContentLayerClient client_;
2509 scoped_refptr<FakeContentLayer> root_layer_;
2510 scoped_refptr<FakeContentLayer> child_layer1_;
2511 scoped_refptr<FakeContentLayer> child_layer2_;
2512 int num_commits_;
2515 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2516 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2518 class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
2519 public:
2520 void SetupTree() override {
2521 num_tiles_rastered_ = 0;
2523 scoped_refptr<Layer> root_layer = PictureLayer::Create(&client_);
2524 client_.set_fill_with_nonsolid_color(true);
2525 root_layer->SetIsDrawable(true);
2526 root_layer->SetBounds(gfx::Size(10, 10));
2527 root_layer->SetContentsOpaque(true);
2529 layer_tree_host()->SetRootLayer(root_layer);
2531 // The expectations are based on the assumption that the default
2532 // LCD settings are:
2533 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2535 LayerTreeHostTest::SetupTree();
2538 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2540 void DidCommitAndDrawFrame() override {
2541 switch (layer_tree_host()->source_frame_number()) {
2542 case 1:
2543 PostSetNeedsCommitToMainThread();
2544 break;
2545 case 2:
2546 // Change layer opacity that should trigger lcd change.
2547 layer_tree_host()->root_layer()->SetOpacity(.5f);
2548 break;
2549 case 3:
2550 // Change layer opacity that should not trigger lcd change.
2551 layer_tree_host()->root_layer()->SetOpacity(1.f);
2552 break;
2553 case 4:
2554 EndTest();
2555 break;
2559 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
2560 const Tile* tile) override {
2561 ++num_tiles_rastered_;
2564 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2565 PictureLayerImpl* root_layer =
2566 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer());
2567 bool can_use_lcd_text =
2568 host_impl->active_tree()->root_layer()->can_use_lcd_text();
2569 switch (host_impl->active_tree()->source_frame_number()) {
2570 case 0:
2571 // The first draw.
2572 EXPECT_EQ(1, num_tiles_rastered_);
2573 EXPECT_TRUE(can_use_lcd_text);
2574 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2575 break;
2576 case 1:
2577 // Nothing changed on the layer.
2578 EXPECT_EQ(1, num_tiles_rastered_);
2579 EXPECT_TRUE(can_use_lcd_text);
2580 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2581 break;
2582 case 2:
2583 // LCD text was disabled; it should be re-rastered with LCD text off.
2584 EXPECT_EQ(2, num_tiles_rastered_);
2585 EXPECT_FALSE(can_use_lcd_text);
2586 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2587 break;
2588 case 3:
2589 // LCD text was enabled, but it's sticky and stays off.
2590 EXPECT_EQ(2, num_tiles_rastered_);
2591 EXPECT_TRUE(can_use_lcd_text);
2592 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2593 break;
2597 void AfterTest() override {}
2599 private:
2600 FakeContentLayerClient client_;
2601 int num_tiles_rastered_;
2604 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
2606 // Verify that the BeginFrame notification is used to initiate rendering.
2607 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2608 public:
2609 void InitializeSettings(LayerTreeSettings* settings) override {
2610 settings->use_external_begin_frame_source = true;
2613 void BeginTest() override {
2614 // This will trigger a SetNeedsBeginFrame which will trigger a
2615 // BeginFrame.
2616 PostSetNeedsCommitToMainThread();
2619 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2620 LayerTreeHostImpl::FrameData* frame,
2621 DrawResult draw_result) override {
2622 EndTest();
2623 return DRAW_SUCCESS;
2626 void AfterTest() override {}
2628 private:
2629 base::TimeTicks frame_time_;
2632 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2634 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2635 : public LayerTreeHostTest {
2636 public:
2637 void InitializeSettings(LayerTreeSettings* settings) override {
2638 settings->use_external_begin_frame_source = true;
2639 settings->using_synchronous_renderer_compositor = true;
2642 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2644 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2645 // The BeginFrame notification is turned off now but will get enabled
2646 // once we return. End test while it's enabled.
2647 ImplThreadTaskRunner()->PostTask(
2648 FROM_HERE,
2649 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2650 base::Unretained(this)));
2653 void AfterTest() override {}
2656 MULTI_THREAD_TEST_F(
2657 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2659 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2660 protected:
2661 LayerTreeHostTestAbortedCommitDoesntStall()
2662 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2664 void InitializeSettings(LayerTreeSettings* settings) override {
2665 settings->use_external_begin_frame_source = true;
2668 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2670 void DidCommit() override {
2671 commit_count_++;
2672 if (commit_count_ == 4) {
2673 // After two aborted commits, request a real commit now to make sure a
2674 // real commit following an aborted commit will still complete and
2675 // end the test even when the Impl thread is idle.
2676 layer_tree_host()->SetNeedsCommit();
2680 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2681 CommitEarlyOutReason reason) override {
2682 commit_abort_count_++;
2683 // Initiate another abortable commit.
2684 host_impl->SetNeedsCommit();
2687 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2688 commit_complete_count_++;
2689 if (commit_complete_count_ == 1) {
2690 // Initiate an abortable commit after the first commit.
2691 host_impl->SetNeedsCommit();
2692 } else {
2693 EndTest();
2697 void AfterTest() override {
2698 EXPECT_EQ(commit_count_, 5);
2699 EXPECT_EQ(commit_abort_count_, 3);
2700 EXPECT_EQ(commit_complete_count_, 2);
2703 int commit_count_;
2704 int commit_abort_count_;
2705 int commit_complete_count_;
2708 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2709 : public LayerTreeHostTestAbortedCommitDoesntStall {
2710 protected:
2711 void InitializeSettings(LayerTreeSettings* settings) override {
2712 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2713 settings->using_synchronous_renderer_compositor = true;
2716 void ScheduledActionInvalidateOutputSurface() override {
2717 ImplThreadTaskRunner()->PostTask(
2718 FROM_HERE,
2719 base::Bind(
2720 &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor::
2721 CallOnDraw,
2722 base::Unretained(this)));
2725 void CallOnDraw() {
2726 // Synchronous compositor does not draw unless told to do so by the output
2727 // surface.
2728 output_surface()->client()->OnDraw();
2732 MULTI_THREAD_TEST_F(
2733 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2735 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2736 : public LayerTreeHostTestAbortedCommitDoesntStall {
2737 void InitializeSettings(LayerTreeSettings* settings) override {
2738 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2739 settings->throttle_frame_production = false;
2743 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2745 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2746 : public LayerTreeHostTest {
2747 protected:
2748 void InitializeSettings(LayerTreeSettings* settings) override {
2749 settings->impl_side_painting = true;
2752 void SetupTree() override {
2753 LayerTreeHostTest::SetupTree();
2755 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2756 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2757 layer->SetBounds(gfx::Size(10, 10));
2758 layer_tree_host()->root_layer()->AddChild(layer);
2761 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2763 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2764 EndTest();
2767 void AfterTest() override {}
2769 FakeContentLayerClient client_;
2772 MULTI_THREAD_TEST_F(
2773 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2775 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2776 : public LayerTreeHostTest {
2777 public:
2778 class SetBoundsClient : public ContentLayerClient {
2779 public:
2780 SetBoundsClient() : layer_(0) {}
2782 void set_layer(Layer* layer) { layer_ = layer; }
2784 void PaintContents(SkCanvas* canvas,
2785 const gfx::Rect& clip,
2786 PaintingControlSetting picture_control) override {
2787 layer_->SetBounds(gfx::Size(2, 2));
2790 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
2791 const gfx::Rect& clip,
2792 PaintingControlSetting picture_control) override {
2793 NOTIMPLEMENTED();
2794 return DisplayItemList::Create();
2797 bool FillsBoundsCompletely() const override { return false; }
2799 private:
2800 Layer* layer_;
2803 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2805 void SetupTree() override {
2806 if (layer_tree_host()->settings().impl_side_painting) {
2807 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_);
2808 layer_tree_host()->SetRootLayer(root_layer);
2809 } else {
2810 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2811 layer_tree_host()->SetRootLayer(root_layer);
2813 Layer* root_layer = layer_tree_host()->root_layer();
2814 root_layer->SetIsDrawable(true);
2815 root_layer->SetBounds(gfx::Size(1, 1));
2817 client_.set_layer(root_layer);
2819 LayerTreeHostTest::SetupTree();
2822 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2823 void AfterTest() override {}
2825 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2826 num_commits_++;
2827 if (num_commits_ == 1) {
2828 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2829 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds());
2830 } else {
2831 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2832 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds());
2833 EndTest();
2837 private:
2838 SetBoundsClient client_;
2839 int num_commits_;
2842 SINGLE_AND_MULTI_THREAD_TEST_F(
2843 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2845 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2846 public:
2847 MockIOSurfaceWebGraphicsContext3D() {
2848 test_capabilities_.gpu.iosurface = true;
2849 test_capabilities_.gpu.texture_rectangle = true;
2852 GLuint createTexture() override { return 1; }
2853 MOCK_METHOD1(activeTexture, void(GLenum texture));
2854 MOCK_METHOD2(bindTexture, void(GLenum target,
2855 GLuint texture_id));
2856 MOCK_METHOD3(texParameteri, void(GLenum target,
2857 GLenum pname,
2858 GLint param));
2859 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2860 GLint width,
2861 GLint height,
2862 GLuint ioSurfaceId,
2863 GLuint plane));
2864 MOCK_METHOD4(drawElements, void(GLenum mode,
2865 GLsizei count,
2866 GLenum type,
2867 GLintptr offset));
2868 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2869 MOCK_METHOD3(produceTextureDirectCHROMIUM,
2870 void(GLuint texture, GLenum target, const GLbyte* mailbox));
2873 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2874 protected:
2875 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2876 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2877 new MockIOSurfaceWebGraphicsContext3D);
2878 mock_context_ = mock_context_owned.get();
2880 if (delegating_renderer())
2881 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
2882 else
2883 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
2886 void SetupTree() override {
2887 LayerTreeHostTest::SetupTree();
2889 layer_tree_host()->root_layer()->SetIsDrawable(false);
2891 io_surface_id_ = 9;
2892 io_surface_size_ = gfx::Size(6, 7);
2894 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2895 io_surface_layer->SetBounds(gfx::Size(10, 10));
2896 io_surface_layer->SetIsDrawable(true);
2897 io_surface_layer->SetContentsOpaque(true);
2898 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2899 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2902 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2904 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2905 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2906 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2908 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2909 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2910 .Times(AtLeast(1));
2911 EXPECT_CALL(*mock_context_,
2912 texParameteri(
2913 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2914 .Times(1);
2915 EXPECT_CALL(*mock_context_,
2916 texParameteri(
2917 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2918 .Times(1);
2919 EXPECT_CALL(*mock_context_,
2920 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2921 GL_TEXTURE_POOL_CHROMIUM,
2922 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2923 EXPECT_CALL(*mock_context_,
2924 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2925 GL_TEXTURE_WRAP_S,
2926 GL_CLAMP_TO_EDGE)).Times(1);
2927 EXPECT_CALL(*mock_context_,
2928 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2929 GL_TEXTURE_WRAP_T,
2930 GL_CLAMP_TO_EDGE)).Times(1);
2932 EXPECT_CALL(*mock_context_,
2933 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2934 io_surface_size_.width(),
2935 io_surface_size_.height(),
2936 io_surface_id_,
2937 0)).Times(1);
2939 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2942 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2943 LayerTreeHostImpl::FrameData* frame,
2944 DrawResult draw_result) override {
2945 Mock::VerifyAndClearExpectations(&mock_context_);
2946 ResourceProvider* resource_provider = host_impl->resource_provider();
2947 EXPECT_EQ(1u, resource_provider->num_resources());
2948 CHECK_EQ(1u, frame->render_passes.size());
2949 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2950 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
2951 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2952 const IOSurfaceDrawQuad* io_surface_draw_quad =
2953 IOSurfaceDrawQuad::MaterialCast(quad);
2954 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2955 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
2956 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2957 resource_provider->TargetForTesting(
2958 io_surface_draw_quad->io_surface_resource_id));
2960 if (delegating_renderer()) {
2961 // The io surface layer's resource should be sent to the parent.
2962 EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM(
2963 _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2964 } else {
2965 // The io surface layer's texture is drawn.
2966 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2967 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2968 .Times(AtLeast(1));
2971 return draw_result;
2974 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2975 Mock::VerifyAndClearExpectations(&mock_context_);
2977 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2978 EndTest();
2981 void AfterTest() override {}
2983 int io_surface_id_;
2984 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2985 gfx::Size io_surface_size_;
2988 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2990 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2991 public:
2992 void BeginTest() override {
2993 frame_ = 0;
2994 PostSetNeedsCommitToMainThread();
2997 // Round 1: commit + draw
2998 // Round 2: commit only (no draw/swap)
2999 // Round 3: draw only (no commit)
3001 void DidCommit() override {
3002 int commit = layer_tree_host()->source_frame_number();
3003 switch (commit) {
3004 case 2:
3005 // Round 2 done.
3006 EXPECT_EQ(1, frame_);
3007 layer_tree_host()->SetNeedsRedraw();
3008 break;
3012 void DidCompleteSwapBuffers() override {
3013 int commit = layer_tree_host()->source_frame_number();
3014 ++frame_;
3015 switch (frame_) {
3016 case 1:
3017 // Round 1 done.
3018 EXPECT_EQ(1, commit);
3019 layer_tree_host()->SetNeedsCommit();
3020 break;
3021 case 2:
3022 // Round 3 done.
3023 EXPECT_EQ(2, commit);
3024 EndTest();
3025 break;
3029 void AfterTest() override {}
3031 protected:
3032 int frame_;
3035 // Flaky on all platforms: http://crbug.com/327498
3036 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
3037 RunTest(true, true, true);
3040 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
3041 RunTest(true, false, true);
3044 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
3045 public:
3046 void InitializeSettings(LayerTreeSettings* settings) override {
3047 // PictureLayer can only be used with impl side painting enabled.
3048 settings->impl_side_painting = true;
3051 void SetupTree() override {
3052 layer_ = FakePictureLayer::Create(&client_);
3053 // Force commits to not be aborted so new frames get drawn, otherwise
3054 // the renderer gets deferred initialized but nothing new needs drawing.
3055 layer_->set_always_update_resources(true);
3056 layer_tree_host()->SetRootLayer(layer_);
3057 LayerTreeHostTest::SetupTree();
3060 void BeginTest() override {
3061 did_initialize_gl_ = false;
3062 did_release_gl_ = false;
3063 last_source_frame_number_drawn_ = -1; // Never drawn.
3064 PostSetNeedsCommitToMainThread();
3067 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3068 scoped_ptr<TestWebGraphicsContext3D> context3d(
3069 TestWebGraphicsContext3D::Create());
3071 return FakeOutputSurface::CreateDeferredGL(
3072 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
3073 delegating_renderer());
3076 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
3077 ASSERT_TRUE(host_impl->RootLayer());
3078 FakePictureLayerImpl* layer_impl =
3079 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
3081 // The same frame can be draw multiple times if new visible tiles are
3082 // rasterized. But we want to make sure we only post DeferredInitialize
3083 // and ReleaseGL once, so early out if the same frame is drawn again.
3084 if (last_source_frame_number_drawn_ ==
3085 host_impl->active_tree()->source_frame_number())
3086 return;
3088 last_source_frame_number_drawn_ =
3089 host_impl->active_tree()->source_frame_number();
3091 if (!did_initialize_gl_) {
3092 EXPECT_LE(1u, layer_impl->append_quads_count());
3093 ImplThreadTaskRunner()->PostTask(
3094 FROM_HERE,
3095 base::Bind(
3096 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3097 base::Unretained(this),
3098 base::Unretained(host_impl)));
3099 } else if (did_initialize_gl_ && !did_release_gl_) {
3100 EXPECT_LE(2u, layer_impl->append_quads_count());
3101 ImplThreadTaskRunner()->PostTask(
3102 FROM_HERE,
3103 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3104 base::Unretained(this),
3105 base::Unretained(host_impl)));
3106 } else if (did_initialize_gl_ && did_release_gl_) {
3107 EXPECT_LE(3u, layer_impl->append_quads_count());
3108 EndTest();
3112 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
3113 EXPECT_FALSE(did_initialize_gl_);
3114 // SetAndInitializeContext3D calls SetNeedsCommit.
3115 FakeOutputSurface* fake_output_surface =
3116 static_cast<FakeOutputSurface*>(host_impl->output_surface());
3117 scoped_refptr<TestContextProvider> context_provider =
3118 TestContextProvider::Create(); // Not bound to thread.
3119 scoped_refptr<TestContextProvider> worker_context_provider =
3120 TestContextProvider::Create(); // Not bound to thread.
3121 EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d(
3122 context_provider, worker_context_provider));
3123 did_initialize_gl_ = true;
3126 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3127 EXPECT_TRUE(did_initialize_gl_);
3128 EXPECT_FALSE(did_release_gl_);
3129 // ReleaseGL calls SetNeedsCommit.
3130 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3131 did_release_gl_ = true;
3134 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
3135 ASSERT_TRUE(result);
3136 DelegatedFrameData* delegated_frame_data =
3137 output_surface()->last_sent_frame().delegated_frame_data.get();
3138 if (!delegated_frame_data)
3139 return;
3141 // Return all resources immediately.
3142 TransferableResourceArray resources_to_return =
3143 output_surface()->resources_held_by_parent();
3145 CompositorFrameAck ack;
3146 for (size_t i = 0; i < resources_to_return.size(); ++i)
3147 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
3148 host_impl->ReclaimResources(&ack);
3151 void AfterTest() override {
3152 EXPECT_TRUE(did_initialize_gl_);
3153 EXPECT_TRUE(did_release_gl_);
3156 private:
3157 FakeContentLayerClient client_;
3158 scoped_refptr<FakePictureLayer> layer_;
3159 bool did_initialize_gl_;
3160 bool did_release_gl_;
3161 int last_source_frame_number_drawn_;
3164 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3166 class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest {
3167 public:
3168 void SetupTree() override {
3169 root_layer_ = FakePictureLayer::Create(&client_);
3170 root_layer_->SetIsDrawable(true);
3171 root_layer_->SetBounds(gfx::Size(50, 50));
3173 parent_layer_ = FakePictureLayer::Create(&client_);
3174 parent_layer_->SetIsDrawable(true);
3175 parent_layer_->SetBounds(gfx::Size(50, 50));
3176 parent_layer_->SetForceRenderSurface(true);
3178 child_layer_ = FakePictureLayer::Create(&client_);
3179 child_layer_->SetIsDrawable(true);
3180 child_layer_->SetBounds(gfx::Size(50, 50));
3182 root_layer_->AddChild(parent_layer_);
3183 parent_layer_->AddChild(child_layer_);
3184 layer_tree_host()->SetRootLayer(root_layer_);
3186 LayerTreeHostTest::SetupTree();
3189 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3190 return FakeOutputSurface::CreateDeferredGL(
3191 make_scoped_ptr(new SoftwareOutputDevice), delegating_renderer());
3194 void BeginTest() override {
3195 PostSetNeedsCommitToMainThread();
3196 swap_count_ = 0;
3199 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3200 LayerTreeHostImpl::FrameData* frame_data,
3201 DrawResult draw_result) override {
3202 if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
3203 EXPECT_EQ(1u, frame_data->render_passes.size());
3204 // Has at least 3 quads for each layer.
3205 RenderPass* render_pass = frame_data->render_passes[0];
3206 EXPECT_GE(render_pass->quad_list.size(), 3u);
3207 } else {
3208 EXPECT_EQ(2u, frame_data->render_passes.size());
3210 // At least root layer quad in root render pass.
3211 EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u);
3212 // At least parent and child layer quads in parent render pass.
3213 EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u);
3215 return draw_result;
3218 void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3219 swap_count_++;
3220 switch (swap_count_) {
3221 case 1: {
3222 gfx::Transform identity;
3223 gfx::Rect empty_rect;
3224 bool resourceless_software_draw = true;
3225 host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect,
3226 empty_rect, identity,
3227 resourceless_software_draw);
3228 host_impl->SetFullRootLayerDamage();
3229 host_impl->SetNeedsRedraw();
3230 break;
3232 case 2:
3233 EndTest();
3234 break;
3235 default:
3236 NOTREACHED();
3240 void AfterTest() override {}
3242 private:
3243 FakeContentLayerClient client_;
3244 scoped_refptr<Layer> root_layer_;
3245 scoped_refptr<Layer> parent_layer_;
3246 scoped_refptr<Layer> child_layer_;
3247 int swap_count_;
3250 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw);
3252 class LayerTreeHostTestDeferredInitializeWithGpuRasterization
3253 : public LayerTreeHostTestDeferredInitialize {
3254 void InitializeSettings(LayerTreeSettings* settings) override {
3255 // PictureLayer can only be used with impl side painting enabled.
3256 settings->impl_side_painting = true;
3257 settings->gpu_rasterization_enabled = true;
3258 settings->gpu_rasterization_forced = true;
3262 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization);
3264 // Test for UI Resource management.
3265 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3266 public:
3267 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
3269 void InitializeSettings(LayerTreeSettings* settings) override {
3270 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
3273 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3275 void DidCommit() override {
3276 int frame = layer_tree_host()->source_frame_number();
3277 switch (frame) {
3278 case 1:
3279 CreateResource();
3280 CreateResource();
3281 PostSetNeedsCommitToMainThread();
3282 break;
3283 case 2:
3284 // Usually ScopedUIResource are deleted from the manager in their
3285 // destructor. Here we just want to test that a direct call to
3286 // DeleteUIResource works.
3287 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3288 PostSetNeedsCommitToMainThread();
3289 break;
3290 case 3:
3291 // DeleteUIResource can be called with an invalid id.
3292 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3293 PostSetNeedsCommitToMainThread();
3294 break;
3295 case 4:
3296 CreateResource();
3297 CreateResource();
3298 PostSetNeedsCommitToMainThread();
3299 break;
3300 case 5:
3301 ClearResources();
3302 EndTest();
3303 break;
3307 void PerformTest(LayerTreeHostImpl* impl) {
3308 TestWebGraphicsContext3D* context = TestContext();
3310 int frame = impl->active_tree()->source_frame_number();
3311 switch (frame) {
3312 case 0:
3313 ASSERT_EQ(0u, context->NumTextures());
3314 break;
3315 case 1:
3316 // Created two textures.
3317 ASSERT_EQ(2u, context->NumTextures());
3318 break;
3319 case 2:
3320 // One texture left after one deletion.
3321 ASSERT_EQ(1u, context->NumTextures());
3322 break;
3323 case 3:
3324 // Resource manager state should not change when delete is called on an
3325 // invalid id.
3326 ASSERT_EQ(1u, context->NumTextures());
3327 break;
3328 case 4:
3329 // Creation after deletion: two more creates should total up to
3330 // three textures.
3331 ASSERT_EQ(3u, context->NumTextures());
3332 break;
3336 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3337 if (!impl->settings().impl_side_painting)
3338 PerformTest(impl);
3341 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3342 if (impl->settings().impl_side_painting)
3343 PerformTest(impl);
3346 void AfterTest() override {}
3348 private:
3349 // Must clear all resources before exiting.
3350 void ClearResources() {
3351 for (int i = 0; i < num_ui_resources_; i++)
3352 ui_resources_[i] = nullptr;
3355 void CreateResource() {
3356 ui_resources_[num_ui_resources_++] =
3357 FakeScopedUIResource::Create(layer_tree_host());
3360 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3361 int num_ui_resources_;
3364 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3366 class PushPropertiesCountingLayerImpl : public LayerImpl {
3367 public:
3368 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
3369 LayerTreeImpl* tree_impl, int id) {
3370 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
3373 ~PushPropertiesCountingLayerImpl() override {}
3375 void PushPropertiesTo(LayerImpl* layer) override {
3376 LayerImpl::PushPropertiesTo(layer);
3377 push_properties_count_++;
3378 // Push state to the active tree because we can only access it from there.
3379 static_cast<PushPropertiesCountingLayerImpl*>(
3380 layer)->push_properties_count_ = push_properties_count_;
3383 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3384 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3387 size_t push_properties_count() const { return push_properties_count_; }
3388 void reset_push_properties_count() { push_properties_count_ = 0; }
3390 private:
3391 size_t push_properties_count_;
3393 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
3394 : LayerImpl(tree_impl, id),
3395 push_properties_count_(0) {
3396 SetBounds(gfx::Size(1, 1));
3400 class PushPropertiesCountingLayer : public Layer {
3401 public:
3402 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3403 return new PushPropertiesCountingLayer();
3406 void PushPropertiesTo(LayerImpl* layer) override {
3407 Layer::PushPropertiesTo(layer);
3408 push_properties_count_++;
3409 if (persist_needs_push_properties_)
3410 needs_push_properties_ = true;
3413 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3414 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3417 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
3419 size_t push_properties_count() const { return push_properties_count_; }
3420 void reset_push_properties_count() { push_properties_count_ = 0; }
3422 void set_persist_needs_push_properties(bool persist) {
3423 persist_needs_push_properties_ = persist;
3426 private:
3427 PushPropertiesCountingLayer()
3428 : push_properties_count_(0), persist_needs_push_properties_(false) {
3429 SetBounds(gfx::Size(1, 1));
3431 ~PushPropertiesCountingLayer() override {}
3433 size_t push_properties_count_;
3434 bool persist_needs_push_properties_;
3437 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3438 protected:
3439 void BeginTest() override {
3440 num_commits_ = 0;
3441 expected_push_properties_root_ = 0;
3442 expected_push_properties_child_ = 0;
3443 expected_push_properties_grandchild_ = 0;
3444 expected_push_properties_child2_ = 0;
3445 expected_push_properties_other_root_ = 0;
3446 expected_push_properties_leaf_layer_ = 0;
3447 PostSetNeedsCommitToMainThread();
3450 void SetupTree() override {
3451 root_ = PushPropertiesCountingLayer::Create();
3452 root_->CreateRenderSurface();
3453 child_ = PushPropertiesCountingLayer::Create();
3454 child2_ = PushPropertiesCountingLayer::Create();
3455 grandchild_ = PushPropertiesCountingLayer::Create();
3456 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3457 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3459 root_->AddChild(child_);
3460 root_->AddChild(child2_);
3461 child_->AddChild(grandchild_);
3462 child2_->AddChild(leaf_always_pushing_layer_);
3464 other_root_ = PushPropertiesCountingLayer::Create();
3465 other_root_->CreateRenderSurface();
3467 // Don't set the root layer here.
3468 LayerTreeHostTest::SetupTree();
3471 void DidCommitAndDrawFrame() override {
3472 ++num_commits_;
3474 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3475 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3476 EXPECT_EQ(expected_push_properties_grandchild_,
3477 grandchild_->push_properties_count());
3478 EXPECT_EQ(expected_push_properties_child2_,
3479 child2_->push_properties_count());
3480 EXPECT_EQ(expected_push_properties_other_root_,
3481 other_root_->push_properties_count());
3482 EXPECT_EQ(expected_push_properties_leaf_layer_,
3483 leaf_always_pushing_layer_->push_properties_count());
3485 // The scrollbar layer always needs to be pushed.
3486 if (root_->layer_tree_host()) {
3487 EXPECT_TRUE(root_->descendant_needs_push_properties());
3488 EXPECT_FALSE(root_->needs_push_properties());
3490 if (child2_->layer_tree_host()) {
3491 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3492 EXPECT_FALSE(child2_->needs_push_properties());
3494 if (leaf_always_pushing_layer_->layer_tree_host()) {
3495 EXPECT_FALSE(
3496 leaf_always_pushing_layer_->descendant_needs_push_properties());
3497 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3500 // child_ and grandchild_ don't persist their need to push properties.
3501 if (child_->layer_tree_host()) {
3502 EXPECT_FALSE(child_->descendant_needs_push_properties());
3503 EXPECT_FALSE(child_->needs_push_properties());
3505 if (grandchild_->layer_tree_host()) {
3506 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3507 EXPECT_FALSE(grandchild_->needs_push_properties());
3510 if (other_root_->layer_tree_host()) {
3511 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3512 EXPECT_FALSE(other_root_->needs_push_properties());
3515 switch (num_commits_) {
3516 case 1:
3517 layer_tree_host()->SetRootLayer(root_);
3518 // Layers added to the tree get committed.
3519 ++expected_push_properties_root_;
3520 ++expected_push_properties_child_;
3521 ++expected_push_properties_grandchild_;
3522 ++expected_push_properties_child2_;
3523 break;
3524 case 2:
3525 layer_tree_host()->SetNeedsCommit();
3526 // No layers need commit.
3527 break;
3528 case 3:
3529 layer_tree_host()->SetRootLayer(other_root_);
3530 // Layers added to the tree get committed.
3531 ++expected_push_properties_other_root_;
3532 break;
3533 case 4:
3534 layer_tree_host()->SetRootLayer(root_);
3535 // Layers added to the tree get committed.
3536 ++expected_push_properties_root_;
3537 ++expected_push_properties_child_;
3538 ++expected_push_properties_grandchild_;
3539 ++expected_push_properties_child2_;
3540 break;
3541 case 5:
3542 layer_tree_host()->SetNeedsCommit();
3543 // No layers need commit.
3544 break;
3545 case 6:
3546 child_->RemoveFromParent();
3547 // No layers need commit.
3548 break;
3549 case 7:
3550 root_->AddChild(child_);
3551 // Layers added to the tree get committed.
3552 ++expected_push_properties_child_;
3553 ++expected_push_properties_grandchild_;
3554 break;
3555 case 8:
3556 grandchild_->RemoveFromParent();
3557 // No layers need commit.
3558 break;
3559 case 9:
3560 child_->AddChild(grandchild_);
3561 // Layers added to the tree get committed.
3562 ++expected_push_properties_grandchild_;
3563 break;
3564 case 10:
3565 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3566 // No layers need commit.
3567 break;
3568 case 11:
3569 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3570 // No layers need commit.
3571 break;
3572 case 12:
3573 child_->SetPosition(gfx::Point(1, 1));
3574 // The modified layer needs commit
3575 ++expected_push_properties_child_;
3576 break;
3577 case 13:
3578 child2_->SetPosition(gfx::Point(1, 1));
3579 // The modified layer needs commit
3580 ++expected_push_properties_child2_;
3581 break;
3582 case 14:
3583 child_->RemoveFromParent();
3584 root_->AddChild(child_);
3585 // Layers added to the tree get committed.
3586 ++expected_push_properties_child_;
3587 ++expected_push_properties_grandchild_;
3588 break;
3589 case 15:
3590 grandchild_->SetPosition(gfx::Point(1, 1));
3591 // The modified layer needs commit
3592 ++expected_push_properties_grandchild_;
3593 break;
3594 case 16:
3595 // SetNeedsDisplay does not always set needs commit (so call it
3596 // explicitly), but is a property change.
3597 child_->SetNeedsDisplay();
3598 ++expected_push_properties_child_;
3599 layer_tree_host()->SetNeedsCommit();
3600 break;
3601 case 17:
3602 EndTest();
3603 break;
3606 // The leaf layer always pushes.
3607 if (leaf_always_pushing_layer_->layer_tree_host())
3608 ++expected_push_properties_leaf_layer_;
3611 void AfterTest() override {}
3613 int num_commits_;
3614 FakeContentLayerClient client_;
3615 scoped_refptr<PushPropertiesCountingLayer> root_;
3616 scoped_refptr<PushPropertiesCountingLayer> child_;
3617 scoped_refptr<PushPropertiesCountingLayer> child2_;
3618 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3619 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3620 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3621 size_t expected_push_properties_root_;
3622 size_t expected_push_properties_child_;
3623 size_t expected_push_properties_child2_;
3624 size_t expected_push_properties_grandchild_;
3625 size_t expected_push_properties_other_root_;
3626 size_t expected_push_properties_leaf_layer_;
3629 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3631 class LayerTreeHostTestImplLayersPushProperties
3632 : public LayerTreeHostTestLayersPushProperties {
3633 protected:
3634 void BeginTest() override {
3635 expected_push_properties_root_impl_ = 0;
3636 expected_push_properties_child_impl_ = 0;
3637 expected_push_properties_grandchild_impl_ = 0;
3638 expected_push_properties_child2_impl_ = 0;
3639 expected_push_properties_grandchild2_impl_ = 0;
3640 LayerTreeHostTestLayersPushProperties::BeginTest();
3643 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3644 // These commits are in response to the changes made in
3645 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3646 switch (num_commits_) {
3647 case 0:
3648 // Tree hasn't been setup yet don't bother to check anything.
3649 return;
3650 case 1:
3651 // Root gets set up, Everyone is initialized.
3652 ++expected_push_properties_root_impl_;
3653 ++expected_push_properties_child_impl_;
3654 ++expected_push_properties_grandchild_impl_;
3655 ++expected_push_properties_child2_impl_;
3656 ++expected_push_properties_grandchild2_impl_;
3657 break;
3658 case 2:
3659 // Tree doesn't change but the one leaf that always pushes is pushed.
3660 ++expected_push_properties_grandchild2_impl_;
3661 break;
3662 case 3:
3663 // Root is swapped here.
3664 // Clear the expected push properties the tree will be rebuilt.
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;
3671 // Make sure the new root is pushed.
3672 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3673 host_impl->RootLayer())->push_properties_count());
3674 return;
3675 case 4:
3676 // Root is swapped back all of the layers in the tree get pushed.
3677 ++expected_push_properties_root_impl_;
3678 ++expected_push_properties_child_impl_;
3679 ++expected_push_properties_grandchild_impl_;
3680 ++expected_push_properties_child2_impl_;
3681 ++expected_push_properties_grandchild2_impl_;
3682 break;
3683 case 5:
3684 // Tree doesn't change but the one leaf that always pushes is pushed.
3685 ++expected_push_properties_grandchild2_impl_;
3686 break;
3687 case 6:
3688 // First child is removed. Structure of the tree changes here so swap
3689 // some of the values. child_impl becomes child2_impl.
3690 expected_push_properties_child_impl_ =
3691 expected_push_properties_child2_impl_;
3692 expected_push_properties_child2_impl_ = 0;
3693 // grandchild_impl becomes grandchild2_impl.
3694 expected_push_properties_grandchild_impl_ =
3695 expected_push_properties_grandchild2_impl_;
3696 expected_push_properties_grandchild2_impl_ = 0;
3698 // grandchild_impl is now the leaf that always pushes. It is pushed.
3699 ++expected_push_properties_grandchild_impl_;
3700 break;
3701 case 7:
3702 // The leaf that always pushes is pushed.
3703 ++expected_push_properties_grandchild_impl_;
3705 // Child is added back. New layers are initialized.
3706 ++expected_push_properties_grandchild2_impl_;
3707 ++expected_push_properties_child2_impl_;
3708 break;
3709 case 8:
3710 // Leaf is removed.
3711 expected_push_properties_grandchild2_impl_ = 0;
3713 // Always pushing.
3714 ++expected_push_properties_grandchild_impl_;
3715 break;
3716 case 9:
3717 // Leaf is added back
3718 ++expected_push_properties_grandchild2_impl_;
3720 // The leaf that always pushes is pushed.
3721 ++expected_push_properties_grandchild_impl_;
3722 break;
3723 case 10:
3724 // The leaf that always pushes is pushed.
3725 ++expected_push_properties_grandchild_impl_;
3726 break;
3727 case 11:
3728 // The leaf that always pushes is pushed.
3729 ++expected_push_properties_grandchild_impl_;
3730 break;
3731 case 12:
3732 // The leaf that always pushes is pushed.
3733 ++expected_push_properties_grandchild_impl_;
3735 // This child position was changed.
3736 ++expected_push_properties_child2_impl_;
3737 break;
3738 case 13:
3739 // The position of this child was changed.
3740 ++expected_push_properties_child_impl_;
3742 // The leaf that always pushes is pushed.
3743 ++expected_push_properties_grandchild_impl_;
3744 break;
3745 case 14:
3746 // Second child is removed from tree. Don't discard counts because
3747 // they are added back before commit.
3749 // The leaf that always pushes is pushed.
3750 ++expected_push_properties_grandchild_impl_;
3752 // Second child added back.
3753 ++expected_push_properties_child2_impl_;
3754 ++expected_push_properties_grandchild2_impl_;
3756 break;
3757 case 15:
3758 // The position of this child was changed.
3759 ++expected_push_properties_grandchild2_impl_;
3761 // The leaf that always pushes is pushed.
3762 ++expected_push_properties_grandchild_impl_;
3763 break;
3764 case 16:
3765 // Second child is invalidated with SetNeedsDisplay
3766 ++expected_push_properties_child2_impl_;
3768 // The leaf that always pushed is pushed.
3769 ++expected_push_properties_grandchild_impl_;
3770 break;
3773 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3774 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3775 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3776 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3777 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3779 // Pull the layers that we need from the tree assuming the same structure
3780 // as LayerTreeHostTestLayersPushProperties
3781 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3782 host_impl->RootLayer());
3784 if (root_impl_ && root_impl_->children().size() > 0) {
3785 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3786 root_impl_->children()[0]);
3788 if (child_impl_ && child_impl_->children().size() > 0)
3789 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3790 child_impl_->children()[0]);
3793 if (root_impl_ && root_impl_->children().size() > 1) {
3794 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3795 root_impl_->children()[1]);
3797 if (child2_impl_ && child2_impl_->children().size() > 0)
3798 leaf_always_pushing_layer_impl_ =
3799 static_cast<PushPropertiesCountingLayerImpl*>(
3800 child2_impl_->children()[0]);
3803 if (root_impl_)
3804 EXPECT_EQ(expected_push_properties_root_impl_,
3805 root_impl_->push_properties_count());
3806 if (child_impl_)
3807 EXPECT_EQ(expected_push_properties_child_impl_,
3808 child_impl_->push_properties_count());
3809 if (grandchild_impl_)
3810 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3811 grandchild_impl_->push_properties_count());
3812 if (child2_impl_)
3813 EXPECT_EQ(expected_push_properties_child2_impl_,
3814 child2_impl_->push_properties_count());
3815 if (leaf_always_pushing_layer_impl_)
3816 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3817 leaf_always_pushing_layer_impl_->push_properties_count());
3820 size_t expected_push_properties_root_impl_;
3821 size_t expected_push_properties_child_impl_;
3822 size_t expected_push_properties_child2_impl_;
3823 size_t expected_push_properties_grandchild_impl_;
3824 size_t expected_push_properties_grandchild2_impl_;
3827 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3828 RunTestWithImplSidePainting();
3831 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3832 : public LayerTreeHostTest {
3833 protected:
3834 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3836 void SetupTree() override {
3837 root_ = Layer::Create();
3838 root_->CreateRenderSurface();
3839 root_->SetBounds(gfx::Size(1, 1));
3841 bool paint_scrollbar = true;
3842 bool has_thumb = false;
3843 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3844 paint_scrollbar, has_thumb, root_->id());
3846 root_->AddChild(scrollbar_layer_);
3848 layer_tree_host()->SetRootLayer(root_);
3849 LayerTreeHostTest::SetupTree();
3852 void DidCommitAndDrawFrame() override {
3853 switch (layer_tree_host()->source_frame_number()) {
3854 case 0:
3855 break;
3856 case 1: {
3857 // During update, the ignore_set_needs_commit_ bit is set to true to
3858 // avoid causing a second commit to be scheduled. If a property change
3859 // is made during this, however, it needs to be pushed in the upcoming
3860 // commit.
3861 scoped_ptr<base::AutoReset<bool>> ignore =
3862 scrollbar_layer_->IgnoreSetNeedsCommit();
3864 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3866 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3867 EXPECT_TRUE(root_->descendant_needs_push_properties());
3868 layer_tree_host()->SetNeedsCommit();
3870 scrollbar_layer_->reset_push_properties_count();
3871 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3872 break;
3874 case 2:
3875 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3876 EndTest();
3877 break;
3881 void AfterTest() override {}
3883 scoped_refptr<Layer> root_;
3884 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3887 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3889 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3890 protected:
3891 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3893 void SetupTree() override {
3894 root_ = PushPropertiesCountingLayer::Create();
3895 root_->CreateRenderSurface();
3896 child_ = PushPropertiesCountingLayer::Create();
3897 root_->AddChild(child_);
3899 layer_tree_host()->SetRootLayer(root_);
3900 LayerTreeHostTest::SetupTree();
3903 void DidCommitAndDrawFrame() override {
3904 switch (layer_tree_host()->source_frame_number()) {
3905 case 0:
3906 break;
3907 case 1: {
3908 // During update, the ignore_set_needs_commit_ bit is set to true to
3909 // avoid causing a second commit to be scheduled. If a property change
3910 // is made during this, however, it needs to be pushed in the upcoming
3911 // commit.
3912 EXPECT_FALSE(root_->needs_push_properties());
3913 EXPECT_FALSE(child_->needs_push_properties());
3914 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3915 root_->reset_push_properties_count();
3916 child_->reset_push_properties_count();
3917 child_->SetDrawsContent(true);
3918 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3919 EXPECT_EQ(0u, root_->push_properties_count());
3920 EXPECT_EQ(0u, child_->push_properties_count());
3921 EXPECT_TRUE(root_->needs_push_properties());
3922 EXPECT_TRUE(child_->needs_push_properties());
3923 break;
3925 case 2:
3926 EXPECT_EQ(1u, root_->push_properties_count());
3927 EXPECT_EQ(1u, child_->push_properties_count());
3928 EXPECT_FALSE(root_->needs_push_properties());
3929 EXPECT_FALSE(child_->needs_push_properties());
3930 EndTest();
3931 break;
3935 void AfterTest() override {}
3937 scoped_refptr<PushPropertiesCountingLayer> root_;
3938 scoped_refptr<PushPropertiesCountingLayer> child_;
3941 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3943 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3944 : public LayerTreeHostTest {
3945 protected:
3946 void BeginTest() override {
3947 expected_push_properties_root_ = 0;
3948 expected_push_properties_child_ = 0;
3949 expected_push_properties_grandchild1_ = 0;
3950 expected_push_properties_grandchild2_ = 0;
3951 expected_push_properties_grandchild3_ = 0;
3952 PostSetNeedsCommitToMainThread();
3955 void SetupTree() override {
3956 root_ = PushPropertiesCountingLayer::Create();
3957 root_->CreateRenderSurface();
3958 child_ = PushPropertiesCountingLayer::Create();
3959 grandchild1_ = PushPropertiesCountingLayer::Create();
3960 grandchild2_ = PushPropertiesCountingLayer::Create();
3961 grandchild3_ = PushPropertiesCountingLayer::Create();
3963 root_->AddChild(child_);
3964 child_->AddChild(grandchild1_);
3965 child_->AddChild(grandchild2_);
3966 child_->AddChild(grandchild3_);
3968 // Don't set the root layer here.
3969 LayerTreeHostTest::SetupTree();
3972 void AfterTest() override {}
3974 FakeContentLayerClient client_;
3975 scoped_refptr<PushPropertiesCountingLayer> root_;
3976 scoped_refptr<PushPropertiesCountingLayer> child_;
3977 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3978 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3979 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3980 size_t expected_push_properties_root_;
3981 size_t expected_push_properties_child_;
3982 size_t expected_push_properties_grandchild1_;
3983 size_t expected_push_properties_grandchild2_;
3984 size_t expected_push_properties_grandchild3_;
3987 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3988 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3989 protected:
3990 void DidCommitAndDrawFrame() override {
3991 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3992 switch (last_source_frame_number) {
3993 case 0:
3994 EXPECT_FALSE(root_->needs_push_properties());
3995 EXPECT_FALSE(root_->descendant_needs_push_properties());
3996 EXPECT_FALSE(child_->needs_push_properties());
3997 EXPECT_FALSE(child_->descendant_needs_push_properties());
3998 EXPECT_FALSE(grandchild1_->needs_push_properties());
3999 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4000 EXPECT_FALSE(grandchild2_->needs_push_properties());
4001 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4002 EXPECT_FALSE(grandchild3_->needs_push_properties());
4003 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4005 layer_tree_host()->SetRootLayer(root_);
4007 EXPECT_TRUE(root_->needs_push_properties());
4008 EXPECT_TRUE(root_->descendant_needs_push_properties());
4009 EXPECT_TRUE(child_->needs_push_properties());
4010 EXPECT_TRUE(child_->descendant_needs_push_properties());
4011 EXPECT_TRUE(grandchild1_->needs_push_properties());
4012 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4013 EXPECT_TRUE(grandchild2_->needs_push_properties());
4014 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4015 EXPECT_TRUE(grandchild3_->needs_push_properties());
4016 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4017 break;
4018 case 1:
4019 EndTest();
4020 break;
4025 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
4027 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
4028 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4029 protected:
4030 void DidCommitAndDrawFrame() override {
4031 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4032 switch (last_source_frame_number) {
4033 case 0:
4034 layer_tree_host()->SetRootLayer(root_);
4035 break;
4036 case 1:
4037 EXPECT_FALSE(root_->needs_push_properties());
4038 EXPECT_FALSE(root_->descendant_needs_push_properties());
4039 EXPECT_FALSE(child_->needs_push_properties());
4040 EXPECT_FALSE(child_->descendant_needs_push_properties());
4041 EXPECT_FALSE(grandchild1_->needs_push_properties());
4042 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4043 EXPECT_FALSE(grandchild2_->needs_push_properties());
4044 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4045 EXPECT_FALSE(grandchild3_->needs_push_properties());
4046 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4048 grandchild1_->RemoveFromParent();
4049 grandchild1_->SetPosition(gfx::Point(1, 1));
4051 EXPECT_FALSE(root_->needs_push_properties());
4052 EXPECT_FALSE(root_->descendant_needs_push_properties());
4053 EXPECT_FALSE(child_->needs_push_properties());
4054 EXPECT_FALSE(child_->descendant_needs_push_properties());
4055 EXPECT_FALSE(grandchild2_->needs_push_properties());
4056 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4057 EXPECT_FALSE(grandchild3_->needs_push_properties());
4058 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4060 child_->AddChild(grandchild1_);
4062 EXPECT_FALSE(root_->needs_push_properties());
4063 EXPECT_TRUE(root_->descendant_needs_push_properties());
4064 EXPECT_FALSE(child_->needs_push_properties());
4065 EXPECT_TRUE(child_->descendant_needs_push_properties());
4066 EXPECT_TRUE(grandchild1_->needs_push_properties());
4067 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4068 EXPECT_FALSE(grandchild2_->needs_push_properties());
4069 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4070 EXPECT_FALSE(grandchild3_->needs_push_properties());
4071 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4073 grandchild2_->SetPosition(gfx::Point(1, 1));
4075 EXPECT_FALSE(root_->needs_push_properties());
4076 EXPECT_TRUE(root_->descendant_needs_push_properties());
4077 EXPECT_FALSE(child_->needs_push_properties());
4078 EXPECT_TRUE(child_->descendant_needs_push_properties());
4079 EXPECT_TRUE(grandchild1_->needs_push_properties());
4080 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4081 EXPECT_TRUE(grandchild2_->needs_push_properties());
4082 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4083 EXPECT_FALSE(grandchild3_->needs_push_properties());
4084 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4086 // grandchild2_ will still need a push properties.
4087 grandchild1_->RemoveFromParent();
4089 EXPECT_FALSE(root_->needs_push_properties());
4090 EXPECT_TRUE(root_->descendant_needs_push_properties());
4091 EXPECT_FALSE(child_->needs_push_properties());
4092 EXPECT_TRUE(child_->descendant_needs_push_properties());
4094 // grandchild3_ does not need a push properties, so recursing should
4095 // no longer be needed.
4096 grandchild2_->RemoveFromParent();
4098 EXPECT_FALSE(root_->needs_push_properties());
4099 EXPECT_FALSE(root_->descendant_needs_push_properties());
4100 EXPECT_FALSE(child_->needs_push_properties());
4101 EXPECT_FALSE(child_->descendant_needs_push_properties());
4102 EndTest();
4103 break;
4108 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
4110 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
4111 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4112 protected:
4113 void DidCommitAndDrawFrame() override {
4114 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4115 switch (last_source_frame_number) {
4116 case 0:
4117 layer_tree_host()->SetRootLayer(root_);
4118 grandchild1_->set_persist_needs_push_properties(true);
4119 grandchild2_->set_persist_needs_push_properties(true);
4120 break;
4121 case 1:
4122 EXPECT_FALSE(root_->needs_push_properties());
4123 EXPECT_TRUE(root_->descendant_needs_push_properties());
4124 EXPECT_FALSE(child_->needs_push_properties());
4125 EXPECT_TRUE(child_->descendant_needs_push_properties());
4126 EXPECT_TRUE(grandchild1_->needs_push_properties());
4127 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4128 EXPECT_TRUE(grandchild2_->needs_push_properties());
4129 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4130 EXPECT_FALSE(grandchild3_->needs_push_properties());
4131 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4133 // grandchild2_ will still need a push properties.
4134 grandchild1_->RemoveFromParent();
4136 EXPECT_FALSE(root_->needs_push_properties());
4137 EXPECT_TRUE(root_->descendant_needs_push_properties());
4138 EXPECT_FALSE(child_->needs_push_properties());
4139 EXPECT_TRUE(child_->descendant_needs_push_properties());
4141 // grandchild3_ does not need a push properties, so recursing should
4142 // no longer be needed.
4143 grandchild2_->RemoveFromParent();
4145 EXPECT_FALSE(root_->needs_push_properties());
4146 EXPECT_FALSE(root_->descendant_needs_push_properties());
4147 EXPECT_FALSE(child_->needs_push_properties());
4148 EXPECT_FALSE(child_->descendant_needs_push_properties());
4149 EndTest();
4150 break;
4155 MULTI_THREAD_TEST_F(
4156 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
4158 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
4159 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4160 protected:
4161 void DidCommitAndDrawFrame() override {
4162 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4163 switch (last_source_frame_number) {
4164 case 0:
4165 layer_tree_host()->SetRootLayer(root_);
4166 break;
4167 case 1:
4168 EXPECT_FALSE(root_->needs_push_properties());
4169 EXPECT_FALSE(root_->descendant_needs_push_properties());
4170 EXPECT_FALSE(child_->needs_push_properties());
4171 EXPECT_FALSE(child_->descendant_needs_push_properties());
4172 EXPECT_FALSE(grandchild1_->needs_push_properties());
4173 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4174 EXPECT_FALSE(grandchild2_->needs_push_properties());
4175 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4176 EXPECT_FALSE(grandchild3_->needs_push_properties());
4177 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4179 // Change grandchildren while their parent is not in the tree.
4180 child_->RemoveFromParent();
4181 grandchild1_->SetPosition(gfx::Point(1, 1));
4182 grandchild2_->SetPosition(gfx::Point(1, 1));
4183 root_->AddChild(child_);
4185 EXPECT_FALSE(root_->needs_push_properties());
4186 EXPECT_TRUE(root_->descendant_needs_push_properties());
4187 EXPECT_TRUE(child_->needs_push_properties());
4188 EXPECT_TRUE(child_->descendant_needs_push_properties());
4189 EXPECT_TRUE(grandchild1_->needs_push_properties());
4190 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4191 EXPECT_TRUE(grandchild2_->needs_push_properties());
4192 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4193 EXPECT_TRUE(grandchild3_->needs_push_properties());
4194 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4196 grandchild1_->RemoveFromParent();
4198 EXPECT_FALSE(root_->needs_push_properties());
4199 EXPECT_TRUE(root_->descendant_needs_push_properties());
4200 EXPECT_TRUE(child_->needs_push_properties());
4201 EXPECT_TRUE(child_->descendant_needs_push_properties());
4203 grandchild2_->RemoveFromParent();
4205 EXPECT_FALSE(root_->needs_push_properties());
4206 EXPECT_TRUE(root_->descendant_needs_push_properties());
4207 EXPECT_TRUE(child_->needs_push_properties());
4208 EXPECT_TRUE(child_->descendant_needs_push_properties());
4210 grandchild3_->RemoveFromParent();
4212 EXPECT_FALSE(root_->needs_push_properties());
4213 EXPECT_TRUE(root_->descendant_needs_push_properties());
4214 EXPECT_TRUE(child_->needs_push_properties());
4215 EXPECT_FALSE(child_->descendant_needs_push_properties());
4217 EndTest();
4218 break;
4223 MULTI_THREAD_TEST_F(
4224 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4226 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4227 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4228 protected:
4229 void DidCommitAndDrawFrame() override {
4230 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4231 switch (last_source_frame_number) {
4232 case 0:
4233 layer_tree_host()->SetRootLayer(root_);
4234 break;
4235 case 1:
4236 EXPECT_FALSE(root_->needs_push_properties());
4237 EXPECT_FALSE(root_->descendant_needs_push_properties());
4238 EXPECT_FALSE(child_->needs_push_properties());
4239 EXPECT_FALSE(child_->descendant_needs_push_properties());
4240 EXPECT_FALSE(grandchild1_->needs_push_properties());
4241 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4242 EXPECT_FALSE(grandchild2_->needs_push_properties());
4243 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4244 EXPECT_FALSE(grandchild3_->needs_push_properties());
4245 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4247 child_->SetPosition(gfx::Point(1, 1));
4248 grandchild1_->SetPosition(gfx::Point(1, 1));
4249 grandchild2_->SetPosition(gfx::Point(1, 1));
4251 EXPECT_FALSE(root_->needs_push_properties());
4252 EXPECT_TRUE(root_->descendant_needs_push_properties());
4253 EXPECT_TRUE(child_->needs_push_properties());
4254 EXPECT_TRUE(child_->descendant_needs_push_properties());
4255 EXPECT_TRUE(grandchild1_->needs_push_properties());
4256 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4257 EXPECT_TRUE(grandchild2_->needs_push_properties());
4258 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4259 EXPECT_FALSE(grandchild3_->needs_push_properties());
4260 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4262 grandchild1_->RemoveFromParent();
4264 EXPECT_FALSE(root_->needs_push_properties());
4265 EXPECT_TRUE(root_->descendant_needs_push_properties());
4266 EXPECT_TRUE(child_->needs_push_properties());
4267 EXPECT_TRUE(child_->descendant_needs_push_properties());
4269 grandchild2_->RemoveFromParent();
4271 EXPECT_FALSE(root_->needs_push_properties());
4272 EXPECT_TRUE(root_->descendant_needs_push_properties());
4273 EXPECT_TRUE(child_->needs_push_properties());
4274 EXPECT_FALSE(child_->descendant_needs_push_properties());
4276 child_->RemoveFromParent();
4278 EXPECT_FALSE(root_->needs_push_properties());
4279 EXPECT_FALSE(root_->descendant_needs_push_properties());
4281 EndTest();
4282 break;
4287 MULTI_THREAD_TEST_F(
4288 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4290 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4291 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4292 protected:
4293 void DidCommitAndDrawFrame() override {
4294 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4295 switch (last_source_frame_number) {
4296 case 0:
4297 layer_tree_host()->SetRootLayer(root_);
4298 break;
4299 case 1:
4300 EXPECT_FALSE(root_->needs_push_properties());
4301 EXPECT_FALSE(root_->descendant_needs_push_properties());
4302 EXPECT_FALSE(child_->needs_push_properties());
4303 EXPECT_FALSE(child_->descendant_needs_push_properties());
4304 EXPECT_FALSE(grandchild1_->needs_push_properties());
4305 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4306 EXPECT_FALSE(grandchild2_->needs_push_properties());
4307 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4308 EXPECT_FALSE(grandchild3_->needs_push_properties());
4309 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4311 grandchild1_->SetPosition(gfx::Point(1, 1));
4312 grandchild2_->SetPosition(gfx::Point(1, 1));
4313 child_->SetPosition(gfx::Point(1, 1));
4315 EXPECT_FALSE(root_->needs_push_properties());
4316 EXPECT_TRUE(root_->descendant_needs_push_properties());
4317 EXPECT_TRUE(child_->needs_push_properties());
4318 EXPECT_TRUE(child_->descendant_needs_push_properties());
4319 EXPECT_TRUE(grandchild1_->needs_push_properties());
4320 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4321 EXPECT_TRUE(grandchild2_->needs_push_properties());
4322 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4323 EXPECT_FALSE(grandchild3_->needs_push_properties());
4324 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4326 grandchild1_->RemoveFromParent();
4328 EXPECT_FALSE(root_->needs_push_properties());
4329 EXPECT_TRUE(root_->descendant_needs_push_properties());
4330 EXPECT_TRUE(child_->needs_push_properties());
4331 EXPECT_TRUE(child_->descendant_needs_push_properties());
4333 grandchild2_->RemoveFromParent();
4335 EXPECT_FALSE(root_->needs_push_properties());
4336 EXPECT_TRUE(root_->descendant_needs_push_properties());
4337 EXPECT_TRUE(child_->needs_push_properties());
4338 EXPECT_FALSE(child_->descendant_needs_push_properties());
4340 child_->RemoveFromParent();
4342 EXPECT_FALSE(root_->needs_push_properties());
4343 EXPECT_FALSE(root_->descendant_needs_push_properties());
4345 EndTest();
4346 break;
4351 MULTI_THREAD_TEST_F(
4352 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4354 // This test verifies that the tree activation callback is invoked correctly.
4355 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4356 public:
4357 LayerTreeHostTestTreeActivationCallback()
4358 : num_commits_(0), callback_count_(0) {}
4360 void BeginTest() override {
4361 EXPECT_TRUE(HasImplThread());
4362 PostSetNeedsCommitToMainThread();
4365 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4366 LayerTreeHostImpl::FrameData* frame_data,
4367 DrawResult draw_result) override {
4368 ++num_commits_;
4369 switch (num_commits_) {
4370 case 1:
4371 EXPECT_EQ(0, callback_count_);
4372 callback_count_ = 0;
4373 SetCallback(true);
4374 PostSetNeedsCommitToMainThread();
4375 break;
4376 case 2:
4377 EXPECT_EQ(1, callback_count_);
4378 callback_count_ = 0;
4379 SetCallback(false);
4380 PostSetNeedsCommitToMainThread();
4381 break;
4382 case 3:
4383 EXPECT_EQ(0, callback_count_);
4384 callback_count_ = 0;
4385 EndTest();
4386 break;
4387 default:
4388 ADD_FAILURE() << num_commits_;
4389 EndTest();
4390 break;
4392 return LayerTreeHostTest::PrepareToDrawOnThread(
4393 host_impl, frame_data, draw_result);
4396 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
4398 void SetCallback(bool enable) {
4399 output_surface()->SetTreeActivationCallback(
4400 enable
4401 ? base::Bind(
4402 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4403 base::Unretained(this))
4404 : base::Closure());
4407 void ActivationCallback() { ++callback_count_; }
4409 int num_commits_;
4410 int callback_count_;
4413 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4414 RunTest(true, false, true);
4417 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4418 RunTest(true, true, true);
4421 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4422 public:
4423 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4425 void BeginTest() override {
4426 ASSERT_TRUE(!!invalidate_layer_.get())
4427 << "Derived tests must set this in SetupTree";
4429 // One initial commit.
4430 PostSetNeedsCommitToMainThread();
4433 void DidCommitAndDrawFrame() override {
4434 // After commit, invalidate the layer. This should cause a commit.
4435 if (layer_tree_host()->source_frame_number() == 1)
4436 invalidate_layer_->SetNeedsDisplay();
4439 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4440 num_draws_++;
4441 if (impl->active_tree()->source_frame_number() == 1)
4442 EndTest();
4445 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4446 num_commits_++;
4449 void AfterTest() override {
4450 EXPECT_GE(2, num_commits_);
4451 EXPECT_GE(2, num_draws_);
4454 protected:
4455 scoped_refptr<Layer> invalidate_layer_;
4457 private:
4458 int num_commits_;
4459 int num_draws_;
4462 // VideoLayer must support being invalidated and then passing that along
4463 // to the compositor thread, even though no resources are updated in
4464 // response to that invalidation.
4465 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4466 public:
4467 void SetupTree() override {
4468 LayerTreeHostTest::SetupTree();
4469 scoped_refptr<VideoLayer> video_layer =
4470 VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
4471 video_layer->SetBounds(gfx::Size(10, 10));
4472 video_layer->SetIsDrawable(true);
4473 layer_tree_host()->root_layer()->AddChild(video_layer);
4475 invalidate_layer_ = video_layer;
4478 private:
4479 FakeVideoFrameProvider provider_;
4482 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4484 // IOSurfaceLayer must support being invalidated and then passing that along
4485 // to the compositor thread, even though no resources are updated in
4486 // response to that invalidation.
4487 class LayerTreeHostTestIOSurfaceLayerInvalidate
4488 : public LayerInvalidateCausesDraw {
4489 public:
4490 void SetupTree() override {
4491 LayerTreeHostTest::SetupTree();
4492 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4493 layer->SetBounds(gfx::Size(10, 10));
4494 uint32_t fake_io_surface_id = 7;
4495 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4496 layer->SetIsDrawable(true);
4497 layer_tree_host()->root_layer()->AddChild(layer);
4499 invalidate_layer_ = layer;
4503 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4504 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4505 LayerTreeHostTestIOSurfaceLayerInvalidate);
4507 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4508 protected:
4509 void SetupTree() override {
4510 root_layer_ = Layer::Create();
4511 root_layer_->CreateRenderSurface();
4512 root_layer_->SetPosition(gfx::Point());
4513 root_layer_->SetBounds(gfx::Size(10, 10));
4515 parent_layer_ = SolidColorLayer::Create();
4516 parent_layer_->SetPosition(gfx::Point());
4517 parent_layer_->SetBounds(gfx::Size(10, 10));
4518 parent_layer_->SetIsDrawable(true);
4519 root_layer_->AddChild(parent_layer_);
4521 child_layer_ = SolidColorLayer::Create();
4522 child_layer_->SetPosition(gfx::Point());
4523 child_layer_->SetBounds(gfx::Size(10, 10));
4524 child_layer_->SetIsDrawable(true);
4525 parent_layer_->AddChild(child_layer_);
4527 layer_tree_host()->SetRootLayer(root_layer_);
4528 LayerTreeHostTest::SetupTree();
4531 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4533 void DidCommitAndDrawFrame() override {
4534 switch (layer_tree_host()->source_frame_number()) {
4535 case 1:
4536 // The layer type used does not need to push properties every frame.
4537 EXPECT_FALSE(child_layer_->needs_push_properties());
4539 // Change the bounds of the child layer, but make it skipped
4540 // by CalculateDrawProperties.
4541 parent_layer_->SetOpacity(0.f);
4542 child_layer_->SetBounds(gfx::Size(5, 5));
4543 break;
4544 case 2:
4545 // The bounds of the child layer were pushed to the impl side.
4546 EXPECT_FALSE(child_layer_->needs_push_properties());
4548 EndTest();
4549 break;
4553 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4554 LayerImpl* root = impl->active_tree()->root_layer();
4555 LayerImpl* parent = root->children()[0];
4556 LayerImpl* child = parent->children()[0];
4558 switch (impl->active_tree()->source_frame_number()) {
4559 case 1:
4560 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4561 break;
4565 void AfterTest() override {}
4567 scoped_refptr<Layer> root_layer_;
4568 scoped_refptr<SolidColorLayer> parent_layer_;
4569 scoped_refptr<SolidColorLayer> child_layer_;
4572 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4574 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4575 protected:
4576 void InitializeSettings(LayerTreeSettings* settings) override {
4577 settings->impl_side_painting = true;
4580 void SetupTree() override {
4581 root_layer_ = FakePictureLayer::Create(&client_);
4582 root_layer_->SetBounds(gfx::Size(10, 10));
4584 layer_tree_host()->SetRootLayer(root_layer_);
4585 LayerTreeHostTest::SetupTree();
4588 void BeginTest() override {
4589 // The viewport is empty, but we still need to update layers on the main
4590 // thread.
4591 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4592 PostSetNeedsCommitToMainThread();
4595 void DidCommit() override {
4596 // The layer should be updated even though the viewport is empty, so we
4597 // are capable of drawing it on the impl tree.
4598 EXPECT_GT(root_layer_->update_count(), 0u);
4599 EndTest();
4602 void AfterTest() override {}
4604 FakeContentLayerClient client_;
4605 scoped_refptr<FakePictureLayer> root_layer_;
4608 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4610 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4611 public:
4612 LayerTreeHostTestAbortEvictedTextures()
4613 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4615 protected:
4616 void SetupTree() override {
4617 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4618 root_layer->SetBounds(gfx::Size(200, 200));
4619 root_layer->SetIsDrawable(true);
4620 root_layer->CreateRenderSurface();
4622 layer_tree_host()->SetRootLayer(root_layer);
4623 LayerTreeHostTest::SetupTree();
4626 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4628 void WillBeginMainFrame() override {
4629 num_will_begin_main_frames_++;
4630 switch (num_will_begin_main_frames_) {
4631 case 2:
4632 // Send a redraw to the compositor thread. This will (wrongly) be
4633 // ignored unless aborting resets the texture state.
4634 layer_tree_host()->SetNeedsRedraw();
4635 break;
4639 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
4640 num_impl_commits_++;
4643 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4644 switch (impl->SourceAnimationFrameNumber()) {
4645 case 1:
4646 // Prevent draws until commit.
4647 impl->active_tree()->SetContentsTexturesPurged();
4648 EXPECT_FALSE(impl->CanDraw());
4649 // Trigger an abortable commit.
4650 impl->SetNeedsCommit();
4651 break;
4652 case 2:
4653 EndTest();
4654 break;
4658 void AfterTest() override {
4659 // Ensure that the commit was truly aborted.
4660 EXPECT_EQ(2, num_will_begin_main_frames_);
4661 EXPECT_EQ(1, num_impl_commits_);
4664 private:
4665 int num_will_begin_main_frames_;
4666 int num_impl_commits_;
4669 // Commits can only be aborted when using the thread proxy.
4670 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4672 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4673 protected:
4674 void InitializeSettings(LayerTreeSettings* settings) override {
4675 settings->impl_side_painting = true;
4676 settings->use_zero_copy = false;
4677 settings->use_one_copy = false;
4680 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4681 scoped_refptr<TestContextProvider> context_provider =
4682 TestContextProvider::Create();
4683 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
4684 if (delegating_renderer())
4685 return FakeOutputSurface::CreateDelegating3d(context_provider);
4686 else
4687 return FakeOutputSurface::Create3d(context_provider);
4690 void SetupTree() override {
4691 client_.set_fill_with_nonsolid_color(true);
4692 scoped_refptr<FakePictureLayer> root_layer =
4693 FakePictureLayer::Create(&client_);
4694 root_layer->SetBounds(gfx::Size(1024, 1024));
4695 root_layer->SetIsDrawable(true);
4697 layer_tree_host()->SetRootLayer(root_layer);
4698 LayerTreeHostTest::SetupTree();
4701 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4703 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4704 TestWebGraphicsContext3D* context = TestContext();
4706 // Expect that the transfer buffer memory used is equal to the
4707 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4708 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
4709 EndTest();
4712 void AfterTest() override {}
4714 private:
4715 FakeContentLayerClient client_;
4718 // Impl-side painting is a multi-threaded compositor feature.
4719 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4721 // Test ensuring that memory limits are sent to the prioritized resource
4722 // manager.
4723 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4724 public:
4725 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4727 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4729 void WillCommit() override {
4730 // Some commits are aborted, so increment number of attempted commits here.
4731 num_commits_++;
4734 void DidCommit() override {
4735 switch (num_commits_) {
4736 case 1:
4737 // Verify default values.
4738 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4739 layer_tree_host()
4740 ->contents_texture_manager()
4741 ->MaxMemoryLimitBytes());
4742 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4743 layer_tree_host()
4744 ->contents_texture_manager()
4745 ->ExternalPriorityCutoff());
4746 PostSetNeedsCommitToMainThread();
4747 break;
4748 case 2:
4749 // The values should remain the same until the commit after the policy
4750 // is changed.
4751 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4752 layer_tree_host()
4753 ->contents_texture_manager()
4754 ->MaxMemoryLimitBytes());
4755 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4756 layer_tree_host()
4757 ->contents_texture_manager()
4758 ->ExternalPriorityCutoff());
4759 break;
4760 case 3:
4761 // Verify values were correctly passed.
4762 EXPECT_EQ(16u * 1024u * 1024u,
4763 layer_tree_host()
4764 ->contents_texture_manager()
4765 ->MaxMemoryLimitBytes());
4766 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4767 layer_tree_host()
4768 ->contents_texture_manager()
4769 ->ExternalPriorityCutoff());
4770 EndTest();
4771 break;
4772 case 4:
4773 // Make sure no extra commits happen.
4774 NOTREACHED();
4775 break;
4779 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4780 switch (num_commits_) {
4781 case 1:
4782 break;
4783 case 2:
4784 // This will trigger a commit because the priority cutoff has changed.
4785 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4786 16u * 1024u * 1024u,
4787 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4788 1000));
4789 break;
4790 case 3:
4791 // This will not trigger a commit because the priority cutoff has not
4792 // changed, and there is already enough memory for all allocations.
4793 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4794 32u * 1024u * 1024u,
4795 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4796 1000));
4797 break;
4798 case 4:
4799 NOTREACHED();
4800 break;
4804 void AfterTest() override {}
4806 private:
4807 int num_commits_;
4810 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4812 } // namespace
4814 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4815 : public LayerTreeHostTest {
4816 protected:
4817 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4818 : first_output_surface_memory_limit_(4321234),
4819 second_output_surface_memory_limit_(1234321) {}
4821 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4822 if (!first_context_provider_.get()) {
4823 first_context_provider_ = TestContextProvider::Create();
4824 } else {
4825 EXPECT_FALSE(second_context_provider_.get());
4826 second_context_provider_ = TestContextProvider::Create();
4829 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4830 ? second_context_provider_
4831 : first_context_provider_);
4832 scoped_ptr<FakeOutputSurface> output_surface;
4833 if (delegating_renderer())
4834 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4835 else
4836 output_surface = FakeOutputSurface::Create3d(provider);
4837 output_surface->SetMemoryPolicyToSetAtBind(
4838 make_scoped_ptr(new ManagedMemoryPolicy(
4839 second_context_provider_.get() ? second_output_surface_memory_limit_
4840 : first_output_surface_memory_limit_,
4841 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4842 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4843 return output_surface.Pass();
4846 void SetupTree() override {
4847 if (layer_tree_host()->settings().impl_side_painting)
4848 root_ = FakePictureLayer::Create(&client_);
4849 else
4850 root_ = FakeContentLayer::Create(&client_);
4851 root_->SetBounds(gfx::Size(20, 20));
4852 layer_tree_host()->SetRootLayer(root_);
4853 LayerTreeHostTest::SetupTree();
4856 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4858 void DidCommitAndDrawFrame() override {
4859 // Lost context sometimes takes two frames to recreate. The third frame
4860 // is sometimes aborted, so wait until the fourth frame to verify that
4861 // the memory has been set, and the fifth frame to end the test.
4862 if (layer_tree_host()->source_frame_number() < 5) {
4863 layer_tree_host()->SetNeedsCommit();
4864 } else if (layer_tree_host()->source_frame_number() == 5) {
4865 EndTest();
4869 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
4870 switch (impl->active_tree()->source_frame_number()) {
4871 case 1:
4872 EXPECT_EQ(first_output_surface_memory_limit_,
4873 impl->memory_allocation_limit_bytes());
4874 // Lose the output surface.
4875 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4876 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4877 break;
4878 case 4:
4879 EXPECT_EQ(second_output_surface_memory_limit_,
4880 impl->memory_allocation_limit_bytes());
4881 break;
4885 void AfterTest() override {}
4887 scoped_refptr<TestContextProvider> first_context_provider_;
4888 scoped_refptr<TestContextProvider> second_context_provider_;
4889 size_t first_output_surface_memory_limit_;
4890 size_t second_output_surface_memory_limit_;
4891 FakeContentLayerClient client_;
4892 scoped_refptr<Layer> root_;
4895 SINGLE_AND_MULTI_THREAD_TEST_F(
4896 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4898 struct TestSwapPromiseResult {
4899 TestSwapPromiseResult()
4900 : did_swap_called(false),
4901 did_not_swap_called(false),
4902 dtor_called(false),
4903 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4905 bool did_swap_called;
4906 bool did_not_swap_called;
4907 bool dtor_called;
4908 SwapPromise::DidNotSwapReason reason;
4909 base::Lock lock;
4912 class TestSwapPromise : public SwapPromise {
4913 public:
4914 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4916 ~TestSwapPromise() override {
4917 base::AutoLock lock(result_->lock);
4918 result_->dtor_called = true;
4921 void DidSwap(CompositorFrameMetadata* metadata) override {
4922 base::AutoLock lock(result_->lock);
4923 EXPECT_FALSE(result_->did_swap_called);
4924 EXPECT_FALSE(result_->did_not_swap_called);
4925 result_->did_swap_called = true;
4928 void DidNotSwap(DidNotSwapReason reason) override {
4929 base::AutoLock lock(result_->lock);
4930 EXPECT_FALSE(result_->did_swap_called);
4931 EXPECT_FALSE(result_->did_not_swap_called);
4932 result_->did_not_swap_called = true;
4933 result_->reason = reason;
4936 int64 TraceId() const override { return 0; }
4938 private:
4939 // Not owned.
4940 TestSwapPromiseResult* result_;
4943 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4944 protected:
4945 LayerTreeHostTestBreakSwapPromise()
4946 : commit_count_(0), commit_complete_count_(0) {}
4948 void WillBeginMainFrame() override {
4949 ASSERT_LE(commit_count_, 2);
4950 scoped_ptr<SwapPromise> swap_promise(
4951 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4952 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4955 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4957 void DidCommit() override {
4958 commit_count_++;
4959 if (commit_count_ == 2) {
4960 // This commit will finish.
4961 layer_tree_host()->SetNeedsCommit();
4965 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4966 commit_complete_count_++;
4967 if (commit_complete_count_ == 1) {
4968 // This commit will be aborted because no actual update.
4969 PostSetNeedsUpdateLayersToMainThread();
4970 } else {
4971 EndTest();
4975 void AfterTest() override {
4976 // 3 commits are scheduled. 2 completes. 1 is aborted.
4977 EXPECT_EQ(commit_count_, 3);
4978 EXPECT_EQ(commit_complete_count_, 2);
4981 // The first commit completes and causes swap buffer which finishes
4982 // the promise.
4983 base::AutoLock lock(swap_promise_result_[0].lock);
4984 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4985 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4986 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4990 // The second commit is aborted since it contains no updates.
4991 base::AutoLock lock(swap_promise_result_[1].lock);
4992 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4993 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4994 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
4995 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4999 // The last commit completes but it does not cause swap buffer because
5000 // there is no damage in the frame data.
5001 base::AutoLock lock(swap_promise_result_[2].lock);
5002 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5003 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5004 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5005 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5009 int commit_count_;
5010 int commit_complete_count_;
5011 TestSwapPromiseResult swap_promise_result_[3];
5014 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
5016 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
5017 public:
5018 LayerTreeHostTestKeepSwapPromise() {}
5020 void BeginTest() override {
5021 layer_ = SolidColorLayer::Create();
5022 layer_->SetIsDrawable(true);
5023 layer_->SetBounds(gfx::Size(10, 10));
5024 layer_tree_host()->SetRootLayer(layer_);
5025 gfx::Size bounds(100, 100);
5026 layer_tree_host()->SetViewportSize(bounds);
5027 PostSetNeedsCommitToMainThread();
5030 void DidCommit() override {
5031 MainThreadTaskRunner()->PostTask(
5032 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
5033 base::Unretained(this)));
5036 void ChangeFrame() {
5037 switch (layer_tree_host()->source_frame_number()) {
5038 case 1:
5039 layer_->SetBounds(gfx::Size(10, 11));
5040 layer_tree_host()->QueueSwapPromise(
5041 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
5042 break;
5043 case 2:
5044 break;
5045 default:
5046 NOTREACHED();
5047 break;
5051 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
5052 EXPECT_TRUE(result);
5053 if (host_impl->active_tree()->source_frame_number() >= 1) {
5054 // The commit changes layers so it should cause a swap.
5055 base::AutoLock lock(swap_promise_result_.lock);
5056 EXPECT_TRUE(swap_promise_result_.did_swap_called);
5057 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5058 EXPECT_TRUE(swap_promise_result_.dtor_called);
5059 EndTest();
5063 void AfterTest() override {}
5065 private:
5066 scoped_refptr<Layer> layer_;
5067 TestSwapPromiseResult swap_promise_result_;
5070 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
5072 class LayerTreeHostTestBreakSwapPromiseForVisibility
5073 : public LayerTreeHostTest {
5074 protected:
5075 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5077 void SetVisibleFalseAndQueueSwapPromise() {
5078 layer_tree_host()->SetVisible(false);
5079 scoped_ptr<SwapPromise> swap_promise(
5080 new TestSwapPromise(&swap_promise_result_));
5081 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5084 void ScheduledActionWillSendBeginMainFrame() override {
5085 MainThreadTaskRunner()->PostTask(
5086 FROM_HERE,
5087 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility
5088 ::SetVisibleFalseAndQueueSwapPromise,
5089 base::Unretained(this)));
5092 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5093 CommitEarlyOutReason reason) override {
5094 EndTest();
5097 void AfterTest() override {
5099 base::AutoLock lock(swap_promise_result_.lock);
5100 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5101 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5102 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5103 EXPECT_TRUE(swap_promise_result_.dtor_called);
5107 TestSwapPromiseResult swap_promise_result_;
5110 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
5112 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest {
5113 protected:
5114 LayerTreeHostTestBreakSwapPromiseForContext()
5115 : output_surface_lost_triggered_(false) {
5118 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5120 void LoseOutputSurfaceAndQueueSwapPromise() {
5121 layer_tree_host()->DidLoseOutputSurface();
5122 scoped_ptr<SwapPromise> swap_promise(
5123 new TestSwapPromise(&swap_promise_result_));
5124 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5127 void ScheduledActionWillSendBeginMainFrame() override {
5128 if (output_surface_lost_triggered_)
5129 return;
5130 output_surface_lost_triggered_ = true;
5132 MainThreadTaskRunner()->PostTask(
5133 FROM_HERE,
5134 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext
5135 ::LoseOutputSurfaceAndQueueSwapPromise,
5136 base::Unretained(this)));
5139 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5140 CommitEarlyOutReason reason) override {
5141 // This is needed so that the impl-thread state matches main-thread state.
5142 host_impl->DidLoseOutputSurface();
5143 EndTest();
5146 void AfterTest() override {
5148 base::AutoLock lock(swap_promise_result_.lock);
5149 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5150 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5151 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5152 EXPECT_TRUE(swap_promise_result_.dtor_called);
5156 bool output_surface_lost_triggered_;
5157 TestSwapPromiseResult swap_promise_result_;
5160 SINGLE_AND_MULTI_THREAD_TEST_F(
5161 LayerTreeHostTestBreakSwapPromiseForContext);
5163 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
5164 public:
5165 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
5166 LayerTreeHostImpl* layer_tree_host_impl,
5167 int* set_needs_commit_count,
5168 int* set_needs_redraw_count)
5169 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
5170 set_needs_commit_count_(set_needs_commit_count) {}
5172 ~SimpleSwapPromiseMonitor() override {}
5174 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
5176 void OnSetNeedsRedrawOnImpl() override {
5177 ADD_FAILURE() << "Should not get called on main thread.";
5180 void OnForwardScrollUpdateToMainThreadOnImpl() override {
5181 ADD_FAILURE() << "Should not get called on main thread.";
5184 private:
5185 int* set_needs_commit_count_;
5188 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
5189 public:
5190 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5192 void WillBeginMainFrame() override {
5193 if (TestEnded())
5194 return;
5196 int set_needs_commit_count = 0;
5197 int set_needs_redraw_count = 0;
5200 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5201 new SimpleSwapPromiseMonitor(layer_tree_host(),
5202 NULL,
5203 &set_needs_commit_count,
5204 &set_needs_redraw_count));
5205 layer_tree_host()->SetNeedsCommit();
5206 EXPECT_EQ(1, set_needs_commit_count);
5207 EXPECT_EQ(0, set_needs_redraw_count);
5210 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
5211 // monitored.
5212 layer_tree_host()->SetNeedsCommit();
5213 EXPECT_EQ(1, set_needs_commit_count);
5214 EXPECT_EQ(0, set_needs_redraw_count);
5217 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5218 new SimpleSwapPromiseMonitor(layer_tree_host(),
5219 NULL,
5220 &set_needs_commit_count,
5221 &set_needs_redraw_count));
5222 layer_tree_host()->SetNeedsUpdateLayers();
5223 EXPECT_EQ(2, set_needs_commit_count);
5224 EXPECT_EQ(0, set_needs_redraw_count);
5228 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5229 new SimpleSwapPromiseMonitor(layer_tree_host(),
5230 NULL,
5231 &set_needs_commit_count,
5232 &set_needs_redraw_count));
5233 layer_tree_host()->SetNeedsAnimate();
5234 EXPECT_EQ(3, set_needs_commit_count);
5235 EXPECT_EQ(0, set_needs_redraw_count);
5238 EndTest();
5241 void AfterTest() override {}
5244 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
5246 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
5247 : public LayerTreeHostTest {
5248 protected:
5249 void InitializeSettings(LayerTreeSettings* settings) override {
5250 settings->impl_side_painting = true;
5253 void SetupTree() override {
5254 LayerTreeHostTest::SetupTree();
5255 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
5258 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5260 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5261 host_impl->EvictAllUIResources();
5262 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
5263 // mode. Active tree should require high-res to draw after entering this
5264 // mode to ensure that high-res tiles are also required for a pending tree
5265 // to be activated.
5266 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5269 void DidCommit() override {
5270 int frame = layer_tree_host()->source_frame_number();
5271 switch (frame) {
5272 case 1:
5273 PostSetNeedsCommitToMainThread();
5274 break;
5275 case 2:
5276 ui_resource_ = nullptr;
5277 EndTest();
5278 break;
5282 void AfterTest() override {}
5284 FakeContentLayerClient client_;
5285 scoped_ptr<FakeScopedUIResource> ui_resource_;
5288 // This test is flaky, see http://crbug.com/386199
5289 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
5291 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
5292 protected:
5293 void InitializeSettings(LayerTreeSettings* settings) override {
5294 settings->impl_side_painting = true;
5296 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5297 EXPECT_FALSE(settings->gpu_rasterization_forced);
5300 void SetupTree() override {
5301 LayerTreeHostTest::SetupTree();
5303 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5304 layer->SetBounds(gfx::Size(10, 10));
5305 layer->SetIsDrawable(true);
5306 layer_tree_host()->root_layer()->AddChild(layer);
5309 void BeginTest() override {
5310 Layer* root = layer_tree_host()->root_layer();
5311 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5312 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5314 // Verify default values.
5315 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5316 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5317 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5318 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5319 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5321 // Setting gpu rasterization trigger does not enable gpu rasterization.
5322 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5323 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5324 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5326 PostSetNeedsCommitToMainThread();
5329 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5330 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5331 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5334 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5335 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5336 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5337 EndTest();
5340 void AfterTest() override {}
5342 FakeContentLayerClient layer_client_;
5345 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
5347 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
5348 protected:
5349 void InitializeSettings(LayerTreeSettings* settings) override {
5350 settings->impl_side_painting = true;
5352 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5353 settings->gpu_rasterization_enabled = true;
5356 void SetupTree() override {
5357 LayerTreeHostTest::SetupTree();
5359 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5360 layer->SetBounds(gfx::Size(10, 10));
5361 layer->SetIsDrawable(true);
5362 layer_tree_host()->root_layer()->AddChild(layer);
5365 void BeginTest() override {
5366 Layer* root = layer_tree_host()->root_layer();
5367 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5368 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5370 // Verify default values.
5371 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5372 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5373 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5374 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5375 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5377 // Gpu rasterization trigger is relevant.
5378 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5379 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5380 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5382 // Content-based veto is relevant as well.
5383 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5384 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5385 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5386 // Veto will take effect when layers are updated.
5387 // The results will be verified after commit is completed below.
5388 // Since we are manually marking picture pile as unsuitable,
5389 // make sure that the layer gets a chance to update.
5390 layer->SetNeedsDisplay();
5391 PostSetNeedsCommitToMainThread();
5394 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5395 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5396 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5399 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5400 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5401 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5402 EndTest();
5405 void AfterTest() override {}
5407 FakeContentLayerClient layer_client_;
5410 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
5412 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
5413 protected:
5414 void InitializeSettings(LayerTreeSettings* settings) override {
5415 ASSERT_TRUE(settings->impl_side_painting);
5417 EXPECT_FALSE(settings->gpu_rasterization_forced);
5418 settings->gpu_rasterization_forced = true;
5421 void SetupTree() override {
5422 LayerTreeHostTest::SetupTree();
5424 scoped_refptr<FakePictureLayer> layer =
5425 FakePictureLayer::Create(&layer_client_);
5426 layer->SetBounds(gfx::Size(10, 10));
5427 layer->SetIsDrawable(true);
5428 layer_tree_host()->root_layer()->AddChild(layer);
5431 void BeginTest() override {
5432 Layer* root = layer_tree_host()->root_layer();
5433 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5434 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5436 // Verify default values.
5437 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5438 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5439 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5440 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5442 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
5443 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5444 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5445 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5446 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5448 // Content-based veto is irrelevant as well.
5449 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5450 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5451 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5452 // Veto will take effect when layers are updated.
5453 // The results will be verified after commit is completed below.
5454 // Since we are manually marking picture pile as unsuitable,
5455 // make sure that the layer gets a chance to update.
5456 layer->SetNeedsDisplay();
5457 PostSetNeedsCommitToMainThread();
5460 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5461 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
5462 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5465 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5466 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
5467 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5468 EndTest();
5471 void AfterTest() override {}
5473 FakeContentLayerClient layer_client_;
5476 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
5478 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
5479 public:
5480 LayerTreeHostTestContinuousPainting()
5481 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
5483 protected:
5484 enum { kExpectedNumCommits = 10 };
5486 void SetupTree() override {
5487 scoped_refptr<Layer> root_layer = Layer::Create();
5488 root_layer->SetBounds(bounds_);
5489 root_layer->CreateRenderSurface();
5491 if (layer_tree_host()->settings().impl_side_painting) {
5492 picture_layer_ = FakePictureLayer::Create(&client_);
5493 child_layer_ = picture_layer_.get();
5494 } else {
5495 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
5496 child_layer_ = content_layer_.get();
5498 child_layer_->SetBounds(bounds_);
5499 child_layer_->SetIsDrawable(true);
5500 root_layer->AddChild(child_layer_);
5502 layer_tree_host()->SetRootLayer(root_layer);
5503 layer_tree_host()->SetViewportSize(bounds_);
5504 LayerTreeHostTest::SetupTree();
5507 void BeginTest() override {
5508 MainThreadTaskRunner()->PostTask(
5509 FROM_HERE,
5510 base::Bind(
5511 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
5512 base::Unretained(this)));
5513 // Wait 50x longer than expected.
5514 double milliseconds_per_frame =
5515 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
5516 MainThreadTaskRunner()->PostDelayedTask(
5517 FROM_HERE,
5518 base::Bind(
5519 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
5520 base::Unretained(this)),
5521 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
5522 milliseconds_per_frame));
5525 void BeginMainFrame(const BeginFrameArgs& args) override {
5526 child_layer_->SetNeedsDisplay();
5529 void AfterTest() override {
5530 EXPECT_LE(kExpectedNumCommits, num_commits_);
5531 EXPECT_LE(kExpectedNumCommits, num_draws_);
5532 int update_count = content_layer_.get()
5533 ? content_layer_->PaintContentsCount()
5534 : picture_layer_->update_count();
5535 EXPECT_LE(kExpectedNumCommits, update_count);
5538 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5539 if (++num_draws_ == kExpectedNumCommits)
5540 EndTest();
5543 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5544 ++num_commits_;
5547 private:
5548 void EnableContinuousPainting() {
5549 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5550 debug_state.continuous_painting = true;
5551 layer_tree_host()->SetDebugState(debug_state);
5554 void DisableContinuousPainting() {
5555 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5556 debug_state.continuous_painting = false;
5557 layer_tree_host()->SetDebugState(debug_state);
5558 EndTest();
5561 int num_commits_;
5562 int num_draws_;
5563 const gfx::Size bounds_;
5564 FakeContentLayerClient client_;
5565 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5566 scoped_refptr<FakePictureLayer> picture_layer_;
5567 Layer* child_layer_;
5570 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5572 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
5573 public:
5574 LayerTreeHostTestSendBeginFramesToChildren()
5575 : begin_frame_sent_to_children_(false) {
5578 void BeginTest() override {
5579 // Kick off the test with a commit.
5580 PostSetNeedsCommitToMainThread();
5583 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5584 begin_frame_sent_to_children_ = true;
5585 EndTest();
5588 void DidBeginMainFrame() override {
5589 // Children requested BeginFrames.
5590 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5593 void AfterTest() override {
5594 // Ensure that BeginFrame message is sent to children during parent
5595 // scheduler handles its BeginFrame.
5596 EXPECT_TRUE(begin_frame_sent_to_children_);
5599 private:
5600 bool begin_frame_sent_to_children_;
5603 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
5605 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
5606 : public LayerTreeHostTest {
5607 public:
5608 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
5609 : begin_frame_sent_to_children_(false) {
5612 void InitializeSettings(LayerTreeSettings* settings) override {
5613 settings->use_external_begin_frame_source = true;
5616 void BeginTest() override {
5617 // Kick off the test with a commit.
5618 PostSetNeedsCommitToMainThread();
5621 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5622 begin_frame_sent_to_children_ = true;
5623 EndTest();
5626 void DidBeginMainFrame() override {
5627 // Children requested BeginFrames.
5628 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5631 void AfterTest() override {
5632 // Ensure that BeginFrame message is sent to children during parent
5633 // scheduler handles its BeginFrame.
5634 EXPECT_TRUE(begin_frame_sent_to_children_);
5637 private:
5638 bool begin_frame_sent_to_children_;
5641 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
5643 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5644 public:
5645 LayerTreeHostTestActivateOnInvisible()
5646 : activation_count_(0), visible_(true) {}
5648 void InitializeSettings(LayerTreeSettings* settings) override {
5649 settings->impl_side_painting = true;
5652 void BeginTest() override {
5653 // Kick off the test with a commit.
5654 PostSetNeedsCommitToMainThread();
5657 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5658 // Make sure we don't activate using the notify signal from tile manager.
5659 host_impl->BlockNotifyReadyToActivateForTesting(true);
5662 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5664 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5665 bool visible) override {
5666 visible_ = visible;
5668 // Once invisible, we can go visible again.
5669 if (!visible) {
5670 PostSetVisibleToMainThread(true);
5671 } else {
5672 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5673 EndTest();
5677 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5678 ++activation_count_;
5679 EXPECT_FALSE(visible_);
5682 void AfterTest() override {
5683 // Ensure we activated even though the signal was blocked.
5684 EXPECT_EQ(1, activation_count_);
5685 EXPECT_TRUE(visible_);
5688 private:
5689 int activation_count_;
5690 bool visible_;
5692 FakeContentLayerClient client_;
5693 scoped_refptr<FakePictureLayer> picture_layer_;
5696 // TODO(vmpstr): Enable with single thread impl-side painting.
5697 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5699 // Do a synchronous composite and assert that the swap promise succeeds.
5700 class LayerTreeHostTestSynchronousCompositeSwapPromise
5701 : public LayerTreeHostTest {
5702 public:
5703 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5705 void InitializeSettings(LayerTreeSettings* settings) override {
5706 settings->single_thread_proxy_scheduler = false;
5709 void BeginTest() override {
5710 // Successful composite.
5711 scoped_ptr<SwapPromise> swap_promise0(
5712 new TestSwapPromise(&swap_promise_result_[0]));
5713 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5714 layer_tree_host()->Composite(gfx::FrameTime::Now());
5716 // Fail to swap (no damage).
5717 scoped_ptr<SwapPromise> swap_promise1(
5718 new TestSwapPromise(&swap_promise_result_[1]));
5719 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5720 layer_tree_host()->SetNeedsCommit();
5721 layer_tree_host()->Composite(gfx::FrameTime::Now());
5723 // Fail to draw (not visible).
5724 scoped_ptr<SwapPromise> swap_promise2(
5725 new TestSwapPromise(&swap_promise_result_[2]));
5726 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5727 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5728 layer_tree_host()->SetVisible(false);
5729 layer_tree_host()->Composite(gfx::FrameTime::Now());
5731 EndTest();
5734 void DidCommit() override {
5735 commit_count_++;
5736 ASSERT_LE(commit_count_, 3);
5739 void AfterTest() override {
5740 EXPECT_EQ(3, commit_count_);
5742 // Initial swap promise should have succeded.
5744 base::AutoLock lock(swap_promise_result_[0].lock);
5745 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5746 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5747 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5750 // Second swap promise fails to swap.
5752 base::AutoLock lock(swap_promise_result_[1].lock);
5753 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5754 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5755 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5756 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5759 // Third swap promises also fails to swap (and draw).
5761 base::AutoLock lock(swap_promise_result_[2].lock);
5762 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5763 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5764 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5765 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5769 int commit_count_;
5770 TestSwapPromiseResult swap_promise_result_[3];
5773 // Impl-side painting is not supported for synchronous compositing.
5774 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
5776 // Make sure page scale and top control deltas are applied to the client even
5777 // when the LayerTreeHost doesn't have a root layer.
5778 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
5779 : public LayerTreeHostTest {
5780 public:
5781 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
5782 : deltas_sent_to_client_(false) {}
5784 void BeginTest() override {
5785 layer_tree_host()->SetRootLayer(nullptr);
5786 info_.page_scale_delta = 3.14f;
5787 info_.top_controls_delta = 2.73f;
5789 PostSetNeedsCommitToMainThread();
5792 void BeginMainFrame(const BeginFrameArgs& args) override {
5793 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
5795 layer_tree_host()->ApplyScrollAndScale(&info_);
5796 EndTest();
5799 void ApplyViewportDeltas(const gfx::Vector2dF& inner,
5800 const gfx::Vector2dF& outer,
5801 const gfx::Vector2dF& elastic_overscroll_delta,
5802 float scale_delta,
5803 float top_controls_delta) override {
5804 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5805 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5806 deltas_sent_to_client_ = true;
5809 void ApplyViewportDeltas(
5810 const gfx::Vector2d& scroll,
5811 float scale_delta,
5812 float top_controls_delta) override {
5813 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5814 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5815 deltas_sent_to_client_ = true;
5818 void AfterTest() override {
5819 EXPECT_TRUE(deltas_sent_to_client_);
5822 ScrollAndScaleSet info_;
5823 bool deltas_sent_to_client_;
5826 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5828 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
5829 protected:
5830 LayerTreeHostTestCrispUpAfterPinchEnds()
5831 : playback_allowed_event_(true, true) {}
5833 void SetupTree() override {
5834 frame_ = 1;
5835 posted_ = false;
5836 client_.set_fill_with_nonsolid_color(true);
5838 scoped_refptr<Layer> root = Layer::Create();
5839 root->SetBounds(gfx::Size(500, 500));
5841 scoped_refptr<Layer> pinch = Layer::Create();
5842 pinch->SetBounds(gfx::Size(500, 500));
5843 pinch->SetScrollClipLayerId(root->id());
5844 pinch->SetIsContainerForFixedPositionLayers(true);
5845 root->AddChild(pinch);
5847 scoped_ptr<FakePicturePile> pile(
5848 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5849 ImplSidePaintingSettings().default_tile_grid_size));
5850 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5851 scoped_refptr<FakePictureLayer> layer =
5852 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5853 layer->SetBounds(gfx::Size(500, 500));
5854 layer->SetContentsOpaque(true);
5855 // Avoid LCD text on the layer so we don't cause extra commits when we
5856 // pinch.
5857 layer->disable_lcd_text();
5858 pinch->AddChild(layer);
5860 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5861 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5862 layer_tree_host()->SetRootLayer(root);
5863 LayerTreeHostTest::SetupTree();
5866 // Returns the delta scale of all quads in the frame's root pass from their
5867 // ideal, or 0 if they are not all the same.
5868 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5869 if (frame_data->has_no_damage)
5870 return 0.f;
5871 float frame_scale = 0.f;
5872 RenderPass* root_pass = frame_data->render_passes.back();
5873 for (const auto& draw_quad : root_pass->quad_list) {
5874 // Checkerboards mean an incomplete frame.
5875 if (draw_quad->material != DrawQuad::TILED_CONTENT)
5876 return 0.f;
5877 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5878 float quad_scale =
5879 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5880 float transform_scale =
5881 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5882 float scale = quad_scale / transform_scale;
5883 if (frame_scale != 0.f && frame_scale != scale)
5884 return 0.f;
5885 frame_scale = scale;
5887 return frame_scale;
5890 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5892 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5893 LayerTreeHostImpl::FrameData* frame_data,
5894 DrawResult draw_result) override {
5895 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5896 switch (frame_) {
5897 case 1:
5898 // Drew at page scale 1 before any pinching.
5899 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5900 EXPECT_EQ(1.f, quad_scale_delta);
5901 PostNextAfterDraw(host_impl);
5902 break;
5903 case 2:
5904 if (quad_scale_delta != 1.f)
5905 break;
5906 // Drew at page scale 1.5 after pinching in.
5907 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5908 EXPECT_EQ(1.f, quad_scale_delta);
5909 PostNextAfterDraw(host_impl);
5910 break;
5911 case 3:
5912 // By pinching out, we will create a new tiling and raster it. This may
5913 // cause some additional draws, though we should still be drawing with
5914 // the old 1.5 tiling.
5915 if (frame_data->has_no_damage)
5916 break;
5917 // Drew at page scale 1 with the 1.5 tiling while pinching out.
5918 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5919 EXPECT_EQ(1.5f, quad_scale_delta);
5920 // We don't PostNextAfterDraw here, instead we wait for the new tiling
5921 // to finish rastering so we don't get any noise in further steps.
5922 break;
5923 case 4:
5924 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
5925 // while waiting for texture uploads to complete.
5926 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5927 // This frame will not have any damage, since it's actually the same as
5928 // the last frame, and should contain no incomplete tiles. We just want
5929 // to make sure we drew here at least once after the pinch ended to be
5930 // sure that drawing after pinch doesn't leave us at the wrong scale
5931 EXPECT_TRUE(frame_data->has_no_damage);
5932 PostNextAfterDraw(host_impl);
5933 break;
5934 case 5:
5935 if (quad_scale_delta != 1.f)
5936 break;
5937 // Drew at scale 1 after texture uploads are done.
5938 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5939 EXPECT_EQ(1.f, quad_scale_delta);
5940 EndTest();
5941 break;
5943 return draw_result;
5946 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
5947 if (posted_)
5948 return;
5949 posted_ = true;
5950 ImplThreadTaskRunner()->PostDelayedTask(
5951 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
5952 base::Unretained(this), host_impl),
5953 // Use a delay to allow raster/upload to happen in between frames. This
5954 // should cause flakiness if we fail to block raster/upload when
5955 // desired.
5956 base::TimeDelta::FromMilliseconds(16 * 4));
5959 void Next(LayerTreeHostImpl* host_impl) {
5960 ++frame_;
5961 posted_ = false;
5962 switch (frame_) {
5963 case 2:
5964 // Pinch zoom in.
5965 host_impl->PinchGestureBegin();
5966 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
5967 host_impl->PinchGestureEnd();
5968 break;
5969 case 3:
5970 // Pinch zoom back to 1.f but don't end it.
5971 host_impl->PinchGestureBegin();
5972 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
5973 break;
5974 case 4:
5975 // End the pinch, but delay tile production.
5976 playback_allowed_event_.Reset();
5977 host_impl->PinchGestureEnd();
5978 break;
5979 case 5:
5980 // Let tiles complete.
5981 playback_allowed_event_.Signal();
5982 break;
5986 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5987 const Tile* tile) override {
5988 if (frame_ == 3) {
5989 // On frame 3, we will have a lower res tile complete for the pinch-out
5990 // gesture even though it's not displayed. We wait for it here to prevent
5991 // flakiness.
5992 EXPECT_EQ(0.75f, tile->contents_scale());
5993 PostNextAfterDraw(host_impl);
5995 // On frame_ == 4, we are preventing texture uploads from completing,
5996 // so this verifies they are not completing before frame_ == 5.
5997 // Flaky failures here indicate we're failing to prevent uploads from
5998 // completing.
5999 EXPECT_NE(4, frame_) << tile->contents_scale();
6002 void AfterTest() override {}
6004 FakeContentLayerClient client_;
6005 int frame_;
6006 bool posted_;
6007 base::WaitableEvent playback_allowed_event_;
6010 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
6012 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
6013 : public LayerTreeHostTestCrispUpAfterPinchEnds {
6014 protected:
6015 void InitializeSettings(LayerTreeSettings* settings) override {
6016 settings->use_one_copy = true;
6019 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
6020 scoped_ptr<TestWebGraphicsContext3D> context3d =
6021 TestWebGraphicsContext3D::Create();
6022 context3d->set_support_image(true);
6023 context3d->set_support_sync_query(true);
6024 #if defined(OS_MACOSX)
6025 context3d->set_support_texture_rectangle(true);
6026 #endif
6028 if (delegating_renderer())
6029 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
6030 else
6031 return FakeOutputSurface::Create3d(context3d.Pass());
6035 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
6037 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
6038 protected:
6039 RasterizeWithGpuRasterizationCreatesResources() {}
6041 void InitializeSettings(LayerTreeSettings* settings) override {
6042 settings->impl_side_painting = true;
6043 settings->gpu_rasterization_forced = true;
6046 void SetupTree() override {
6047 client_.set_fill_with_nonsolid_color(true);
6049 scoped_refptr<Layer> root = Layer::Create();
6050 root->SetBounds(gfx::Size(500, 500));
6052 scoped_ptr<FakePicturePile> pile(
6053 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6054 ImplSidePaintingSettings().default_tile_grid_size));
6055 scoped_refptr<FakePictureLayer> layer =
6056 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6057 layer->SetBounds(gfx::Size(500, 500));
6058 layer->SetContentsOpaque(true);
6059 root->AddChild(layer);
6061 layer_tree_host()->SetRootLayer(root);
6062 LayerTreeHostTest::SetupTree();
6065 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6067 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6068 LayerTreeHostImpl::FrameData* frame_data,
6069 DrawResult draw_result) override {
6070 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
6071 EndTest();
6072 return draw_result;
6074 void AfterTest() override {}
6076 FakeContentLayerClient client_;
6079 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
6081 class SynchronousGpuRasterizationRasterizesVisibleOnly
6082 : public LayerTreeHostTest {
6083 protected:
6084 SynchronousGpuRasterizationRasterizesVisibleOnly()
6085 : viewport_size_(1024, 2048) {}
6087 void InitializeSettings(LayerTreeSettings* settings) override {
6088 settings->impl_side_painting = true;
6089 settings->gpu_rasterization_enabled = true;
6090 settings->gpu_rasterization_forced = true;
6091 settings->threaded_gpu_rasterization_enabled = false;
6094 void SetupTree() override {
6095 client_.set_fill_with_nonsolid_color(true);
6097 scoped_ptr<FakePicturePile> pile(
6098 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6099 ImplSidePaintingSettings().default_tile_grid_size));
6100 scoped_refptr<FakePictureLayer> root =
6101 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6102 root->SetBounds(gfx::Size(viewport_size_.width(), 10000));
6103 root->SetContentsOpaque(true);
6105 layer_tree_host()->SetRootLayer(root);
6106 LayerTreeHostTest::SetupTree();
6107 layer_tree_host()->SetViewportSize(viewport_size_);
6110 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6112 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6113 LayerTreeHostImpl::FrameData* frame_data,
6114 DrawResult draw_result) override {
6115 EXPECT_EQ(4u, host_impl->resource_provider()->num_resources());
6117 // Verify which tiles got resources using an eviction iterator, which has to
6118 // return all tiles that have resources.
6119 scoped_ptr<EvictionTilePriorityQueue> eviction_queue(
6120 host_impl->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES));
6121 int tile_count = 0;
6122 for (; !eviction_queue->IsEmpty(); eviction_queue->Pop()) {
6123 Tile* tile = eviction_queue->Top();
6124 // Ensure this tile is within the viewport.
6125 EXPECT_TRUE(tile->content_rect().Intersects(gfx::Rect(viewport_size_)));
6126 // Ensure that the tile is 1/4 of the viewport tall (plus padding).
6127 EXPECT_EQ(tile->content_rect().height(),
6128 (viewport_size_.height() / 4) + 2);
6129 ++tile_count;
6131 EXPECT_EQ(4, tile_count);
6132 EndTest();
6133 return draw_result;
6136 void AfterTest() override {}
6138 private:
6139 FakeContentLayerClient client_;
6140 gfx::Size viewport_size_;
6143 MULTI_THREAD_IMPL_TEST_F(SynchronousGpuRasterizationRasterizesVisibleOnly);
6145 class ThreadedGpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
6146 protected:
6147 ThreadedGpuRasterizationRasterizesBorderTiles()
6148 : viewport_size_(1024, 2048) {}
6150 void InitializeSettings(LayerTreeSettings* settings) override {
6151 settings->impl_side_painting = true;
6152 settings->gpu_rasterization_enabled = true;
6153 settings->gpu_rasterization_forced = true;
6154 settings->threaded_gpu_rasterization_enabled = true;
6157 void SetupTree() override {
6158 client_.set_fill_with_nonsolid_color(true);
6160 scoped_ptr<FakePicturePile> pile(
6161 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6162 ImplSidePaintingSettings().default_tile_grid_size));
6163 scoped_refptr<FakePictureLayer> root =
6164 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6165 root->SetBounds(gfx::Size(10000, 10000));
6166 root->SetContentsOpaque(true);
6168 layer_tree_host()->SetRootLayer(root);
6169 LayerTreeHostTest::SetupTree();
6170 layer_tree_host()->SetViewportSize(viewport_size_);
6173 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6175 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6176 LayerTreeHostImpl::FrameData* frame_data,
6177 DrawResult draw_result) override {
6178 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources());
6179 EndTest();
6180 return draw_result;
6183 void AfterTest() override {}
6185 private:
6186 FakeContentLayerClient client_;
6187 gfx::Size viewport_size_;
6190 MULTI_THREAD_IMPL_TEST_F(ThreadedGpuRasterizationRasterizesBorderTiles);
6192 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
6193 : public LayerTreeHostTest {
6194 protected:
6195 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
6196 : playback_allowed_event_(true, true) {}
6198 void InitializeSettings(LayerTreeSettings* settings) override {
6199 settings->impl_side_painting = true;
6202 void SetupTree() override {
6203 step_ = 1;
6204 continuous_draws_ = 0;
6205 client_.set_fill_with_nonsolid_color(true);
6207 scoped_refptr<Layer> root = Layer::Create();
6208 root->SetBounds(gfx::Size(500, 500));
6210 scoped_refptr<Layer> pinch = Layer::Create();
6211 pinch->SetBounds(gfx::Size(500, 500));
6212 pinch->SetScrollClipLayerId(root->id());
6213 pinch->SetIsContainerForFixedPositionLayers(true);
6214 root->AddChild(pinch);
6216 scoped_ptr<FakePicturePile> pile(
6217 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6218 ImplSidePaintingSettings().default_tile_grid_size));
6219 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
6220 scoped_refptr<FakePictureLayer> layer =
6221 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6222 layer->SetBounds(gfx::Size(500, 500));
6223 layer->SetContentsOpaque(true);
6224 // Avoid LCD text on the layer so we don't cause extra commits when we
6225 // pinch.
6226 layer->disable_lcd_text();
6227 pinch->AddChild(layer);
6229 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
6230 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6231 layer_tree_host()->SetRootLayer(root);
6232 LayerTreeHostTest::SetupTree();
6235 // Returns the delta scale of all quads in the frame's root pass from their
6236 // ideal, or 0 if they are not all the same.
6237 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6238 if (frame_data->has_no_damage)
6239 return 0.f;
6240 float frame_scale = 0.f;
6241 RenderPass* root_pass = frame_data->render_passes.back();
6242 for (const auto& draw_quad : root_pass->quad_list) {
6243 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
6244 float quad_scale =
6245 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6246 float transform_scale =
6247 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
6248 float scale = quad_scale / transform_scale;
6249 if (frame_scale != 0.f && frame_scale != scale)
6250 return 0.f;
6251 frame_scale = scale;
6253 return frame_scale;
6256 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6258 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6259 LayerTreeHostImpl::FrameData* frame_data,
6260 DrawResult draw_result) override {
6261 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6262 switch (step_) {
6263 case 1:
6264 // Drew at scale 1 before any pinching.
6265 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6266 EXPECT_EQ(1.f, quad_scale_delta);
6267 break;
6268 case 2:
6269 if (quad_scale_delta != 1.f / 1.5f)
6270 break;
6271 // Drew at scale 1 still though the ideal is 1.5.
6272 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6273 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6274 break;
6275 case 3:
6276 // Continuous draws are attempted.
6277 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6278 if (!frame_data->has_no_damage)
6279 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6280 break;
6281 case 4:
6282 if (quad_scale_delta != 1.f)
6283 break;
6284 // Drew at scale 1.5 when all the tiles completed.
6285 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6286 EXPECT_EQ(1.f, quad_scale_delta);
6287 break;
6288 case 5:
6289 // TODO(danakj): We get more draws before the NotifyReadyToDraw
6290 // because it is asynchronous from the previous draw and happens late.
6291 break;
6292 case 6:
6293 // NotifyReadyToDraw happened. If we were already inside a frame, we may
6294 // try to draw once more.
6295 break;
6296 case 7:
6297 NOTREACHED() << "No draws should happen once we have a complete frame.";
6298 break;
6300 return draw_result;
6303 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6304 switch (step_) {
6305 case 1:
6306 // Delay tile production.
6307 playback_allowed_event_.Reset();
6308 // Pinch zoom in to cause new tiles to be required.
6309 host_impl->PinchGestureBegin();
6310 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6311 host_impl->PinchGestureEnd();
6312 ++step_;
6313 break;
6314 case 2:
6315 ++step_;
6316 break;
6317 case 3:
6318 // We should continue to try draw while there are incomplete visible
6319 // tiles.
6320 if (++continuous_draws_ > 5) {
6321 // Allow the tiles to complete.
6322 playback_allowed_event_.Signal();
6323 ++step_;
6325 break;
6326 case 4:
6327 ++step_;
6328 break;
6329 case 5:
6330 // Waiting for NotifyReadyToDraw.
6331 break;
6332 case 6:
6333 // NotifyReadyToDraw happened.
6334 ++step_;
6335 break;
6339 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
6340 if (step_ == 5) {
6341 ++step_;
6342 // NotifyReadyToDraw has happened, we may draw once more, but should not
6343 // get any more draws after that. End the test after a timeout to watch
6344 // for any extraneous draws.
6345 // TODO(brianderson): We could remove this delay and instead wait until
6346 // the BeginFrameSource decides it doesn't need to send frames anymore,
6347 // or test that it already doesn't here.
6348 EndTestAfterDelayMs(16 * 4);
6352 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6353 const Tile* tile) override {
6354 // On step_ == 2, we are preventing texture uploads from completing,
6355 // so this verifies they are not completing before step_ == 3.
6356 // Flaky failures here indicate we're failing to prevent uploads from
6357 // completing.
6358 EXPECT_NE(2, step_);
6361 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
6363 FakeContentLayerClient client_;
6364 int step_;
6365 int continuous_draws_;
6366 base::WaitableEvent playback_allowed_event_;
6369 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
6371 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
6372 public:
6373 LayerTreeHostTestOneActivatePerPrepareTiles()
6374 : notify_ready_to_activate_count_(0u),
6375 scheduled_prepare_tiles_count_(0) {}
6377 void SetupTree() override {
6378 client_.set_fill_with_nonsolid_color(true);
6379 scoped_refptr<FakePictureLayer> root_layer =
6380 FakePictureLayer::Create(&client_);
6381 root_layer->SetBounds(gfx::Size(1500, 1500));
6382 root_layer->SetIsDrawable(true);
6384 layer_tree_host()->SetRootLayer(root_layer);
6385 LayerTreeHostTest::SetupTree();
6388 void BeginTest() override {
6389 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
6390 PostSetNeedsCommitToMainThread();
6393 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
6394 bool success) override {
6395 ASSERT_TRUE(success);
6396 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
6399 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6400 ++notify_ready_to_activate_count_;
6401 EndTestAfterDelayMs(100);
6404 void ScheduledActionPrepareTiles() override {
6405 ++scheduled_prepare_tiles_count_;
6408 void AfterTest() override {
6409 // Expect at most a notification for each scheduled prepare tiles, plus one
6410 // for the initial commit (which doesn't go through scheduled actions).
6411 // The reason this is not an equality is because depending on timing, we
6412 // might get a prepare tiles but not yet get a notification that we're
6413 // ready to activate. The intent of a test is to ensure that we don't
6414 // get more than one notification per prepare tiles, so this is OK.
6415 EXPECT_LE(notify_ready_to_activate_count_,
6416 1u + scheduled_prepare_tiles_count_);
6419 protected:
6420 FakeContentLayerClient client_;
6421 size_t notify_ready_to_activate_count_;
6422 size_t scheduled_prepare_tiles_count_;
6425 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
6427 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
6428 : public LayerTreeHostTest {
6429 public:
6430 LayerTreeHostTestFrameTimingRequestsSaveTimestamps()
6431 : check_results_on_commit_(false) {}
6433 void SetupTree() override {
6434 scoped_refptr<FakePictureLayer> root_layer =
6435 FakePictureLayer::Create(&client_);
6436 root_layer->SetBounds(gfx::Size(200, 200));
6437 root_layer->SetIsDrawable(true);
6439 scoped_refptr<FakePictureLayer> child_layer =
6440 FakePictureLayer::Create(&client_);
6441 child_layer->SetBounds(gfx::Size(1500, 1500));
6442 child_layer->SetIsDrawable(true);
6444 std::vector<FrameTimingRequest> requests;
6445 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100)));
6446 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100)));
6447 child_layer->SetFrameTimingRequests(requests);
6449 root_layer->AddChild(child_layer);
6450 layer_tree_host()->SetRootLayer(root_layer);
6451 LayerTreeHostTest::SetupTree();
6454 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6456 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
6457 if (!check_results_on_commit_)
6458 return;
6460 // Since in reality, the events will be read by LayerTreeHost during commit,
6461 // we check the requests here to ensure that they are correct at the next
6462 // commit time (as opposed to checking in DrawLayers for instance).
6463 // TODO(vmpstr): Change this to read things from the main thread when this
6464 // information is propagated to the main thread (not yet implemented).
6465 FrameTimingTracker* tracker = host_impl->frame_timing_tracker();
6466 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set =
6467 tracker->GroupCountsByRectId();
6468 EXPECT_EQ(1u, timing_set->size());
6469 auto rect_1_it = timing_set->find(1);
6470 EXPECT_TRUE(rect_1_it != timing_set->end());
6471 const auto& timing_events = rect_1_it->second;
6472 EXPECT_EQ(1u, timing_events.size());
6473 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6474 timing_events[0].frame_id);
6475 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6477 EndTest();
6480 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6481 check_results_on_commit_ = true;
6482 PostSetNeedsCommitToMainThread();
6485 void AfterTest() override {}
6487 private:
6488 FakeContentLayerClient client_;
6489 bool check_results_on_commit_;
6492 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
6494 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
6495 public:
6496 LayerTreeHostTestActivationCausesPrepareTiles()
6497 : scheduled_prepare_tiles_count_(0) {}
6499 void SetupTree() override {
6500 client_.set_fill_with_nonsolid_color(true);
6501 scoped_refptr<FakePictureLayer> root_layer =
6502 FakePictureLayer::Create(&client_);
6503 root_layer->SetBounds(gfx::Size(150, 150));
6504 root_layer->SetIsDrawable(true);
6506 layer_tree_host()->SetRootLayer(root_layer);
6507 LayerTreeHostTest::SetupTree();
6510 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6512 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6513 // Ensure we've already activated.
6514 EXPECT_FALSE(impl->pending_tree());
6516 // After activating, we either need to prepare tiles, or we've already
6517 // called a scheduled prepare tiles. This is done because activation might
6518 // cause us to have to memory available (old active tree is gone), so we
6519 // need to ensure we will get a PrepareTiles call.
6520 if (!impl->prepare_tiles_needed())
6521 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
6522 EndTest();
6525 void ScheduledActionPrepareTiles() override {
6526 ++scheduled_prepare_tiles_count_;
6529 void AfterTest() override {}
6531 protected:
6532 FakeContentLayerClient client_;
6533 int scheduled_prepare_tiles_count_;
6536 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
6538 // This tests an assertion that DidCommit and WillCommit happen in the same
6539 // stack frame with no tasks that run between them. Various embedders of
6540 // cc depend on this logic. ui::Compositor holds a compositor lock between
6541 // these events and the inspector timeline wants begin/end CompositeLayers
6542 // to be properly nested with other begin/end events.
6543 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
6544 : public LayerTreeHostTest {
6545 public:
6546 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
6548 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6550 void WillCommit() override {
6551 MainThreadTaskRunner()->PostTask(
6552 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
6553 EndTestShouldRunAfterDidCommit,
6554 base::Unretained(this)));
6557 void EndTestShouldRunAfterDidCommit() {
6558 EXPECT_TRUE(did_commit_);
6559 EndTest();
6562 void DidCommit() override {
6563 EXPECT_FALSE(did_commit_);
6564 did_commit_ = true;
6567 void AfterTest() override { EXPECT_TRUE(did_commit_); }
6569 private:
6570 bool did_commit_;
6573 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
6575 // Verify that if a LayerImpl holds onto a copy request for multiple
6576 // frames that it will continue to have a render surface through
6577 // multiple commits, even though the Layer itself has no reason
6578 // to have a render surface.
6579 class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest {
6580 protected:
6581 void SetupTree() override {
6582 scoped_refptr<Layer> root = Layer::Create();
6583 root->CreateRenderSurface();
6584 root->SetBounds(gfx::Size(10, 10));
6585 child_ = Layer::Create();
6586 child_->SetBounds(gfx::Size(20, 20));
6587 root->AddChild(child_);
6589 layer_tree_host()->SetRootLayer(root);
6590 LayerTreeHostTest::SetupTree();
6593 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6595 void BeginTest() override {
6596 child_->RequestCopyOfOutput(
6597 CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback)));
6598 EXPECT_TRUE(child_->HasCopyRequest());
6599 PostSetNeedsCommitToMainThread();
6602 void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); }
6604 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6605 LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id());
6607 switch (host_impl->sync_tree()->source_frame_number()) {
6608 case 0:
6609 EXPECT_TRUE(child_impl->HasCopyRequest());
6610 EXPECT_TRUE(child_impl->render_surface());
6611 break;
6612 case 1:
6613 if (host_impl->proxy()->CommitToActiveTree()) {
6614 EXPECT_TRUE(child_impl->HasCopyRequest());
6615 EXPECT_TRUE(child_impl->render_surface());
6616 } else {
6617 EXPECT_FALSE(child_impl->HasCopyRequest());
6618 EXPECT_FALSE(child_impl->render_surface());
6620 break;
6621 default:
6622 NOTREACHED();
6623 break;
6627 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6628 LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id());
6629 EXPECT_TRUE(child_impl->HasCopyRequest());
6630 EXPECT_TRUE(child_impl->render_surface());
6632 switch (host_impl->active_tree()->source_frame_number()) {
6633 case 0:
6634 // Lose output surface to prevent drawing and cause another commit.
6635 host_impl->DidLoseOutputSurface();
6636 break;
6637 case 1:
6638 EndTest();
6639 break;
6640 default:
6641 NOTREACHED();
6642 break;
6646 void AfterTest() override {}
6648 private:
6649 scoped_refptr<Layer> child_;
6652 SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests);
6654 } // namespace cc