Roll WPR. (Remove old WPR code. Make WPR cert file name unique.)
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blobef3e36269050fcdccc143e6f9192d50570a0ae58
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 PostSetNeedsCommitToMainThread();
2249 break;
2250 case 3:
2251 PostSetDeferCommitsToMainThread(false);
2252 break;
2253 default:
2254 // Sometimes |num_will_begin_impl_frame_| will be greater than 3 if the
2255 // main thread is slow to respond.
2256 break;
2260 void ScheduledActionSendBeginMainFrame() override {
2261 num_send_begin_main_frame_++;
2262 switch (num_send_begin_main_frame_) {
2263 case 1:
2264 PostSetDeferCommitsToMainThread(true);
2265 break;
2266 case 2:
2267 EndTest();
2268 break;
2269 default:
2270 NOTREACHED();
2271 break;
2275 void AfterTest() override {
2276 EXPECT_GE(num_will_begin_impl_frame_, 3);
2277 EXPECT_EQ(2, num_send_begin_main_frame_);
2280 private:
2281 int num_will_begin_impl_frame_;
2282 int num_send_begin_main_frame_;
2285 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2287 class LayerTreeHostWithProxy : public LayerTreeHost {
2288 public:
2289 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2290 const LayerTreeSettings& settings,
2291 scoped_ptr<FakeProxy> proxy)
2292 : LayerTreeHost(client, NULL, NULL, NULL, settings) {
2293 proxy->SetLayerTreeHost(this);
2294 client->SetLayerTreeHost(this);
2295 InitializeForTesting(proxy.Pass());
2299 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2300 // When partial updates are not allowed, max updates should be 0.
2302 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2304 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2305 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2306 proxy->SetMaxPartialTextureUpdates(5);
2308 LayerTreeSettings settings;
2309 settings.impl_side_painting = false;
2310 settings.max_partial_texture_updates = 10;
2312 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2314 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2317 // When partial updates are allowed,
2318 // max updates should be limited by the proxy.
2320 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2322 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2323 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2324 proxy->SetMaxPartialTextureUpdates(5);
2326 LayerTreeSettings settings;
2327 settings.impl_side_painting = false;
2328 settings.max_partial_texture_updates = 10;
2330 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2332 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2335 // When partial updates are allowed,
2336 // max updates should also be limited by the settings.
2338 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2340 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2341 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2342 proxy->SetMaxPartialTextureUpdates(20);
2344 LayerTreeSettings settings;
2345 settings.impl_side_painting = false;
2346 settings.max_partial_texture_updates = 10;
2348 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2350 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2354 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2355 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2357 LayerTreeSettings settings;
2358 settings.max_partial_texture_updates = 4;
2359 settings.single_thread_proxy_scheduler = false;
2360 settings.impl_side_painting = false;
2362 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2363 new TestSharedBitmapManager());
2364 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2365 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2366 base::MessageLoopProxy::current(), nullptr);
2367 client.SetLayerTreeHost(host.get());
2368 host->Composite(base::TimeTicks::Now());
2370 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2373 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2374 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2376 LayerTreeSettings settings;
2377 settings.max_partial_texture_updates = 4;
2378 settings.single_thread_proxy_scheduler = false;
2379 settings.impl_side_painting = false;
2381 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2382 new TestSharedBitmapManager());
2383 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2384 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2385 base::MessageLoopProxy::current(), nullptr);
2386 client.SetLayerTreeHost(host.get());
2387 host->Composite(base::TimeTicks::Now());
2389 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2392 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2393 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2395 LayerTreeSettings settings;
2396 settings.max_partial_texture_updates = 4;
2397 settings.single_thread_proxy_scheduler = false;
2398 settings.impl_side_painting = false;
2400 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2401 new TestSharedBitmapManager());
2402 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2403 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2404 base::MessageLoopProxy::current(), nullptr);
2405 client.SetLayerTreeHost(host.get());
2406 host->Composite(base::TimeTicks::Now());
2408 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2411 TEST(LayerTreeHostTest,
2412 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2413 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2415 LayerTreeSettings settings;
2416 settings.max_partial_texture_updates = 4;
2417 settings.single_thread_proxy_scheduler = false;
2418 settings.impl_side_painting = false;
2420 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2421 new TestSharedBitmapManager());
2422 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2423 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2424 base::MessageLoopProxy::current(), nullptr);
2425 client.SetLayerTreeHost(host.get());
2426 host->Composite(base::TimeTicks::Now());
2428 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2431 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
2432 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2433 : public LayerTreeHostTest {
2434 public:
2435 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2436 : root_layer_(FakeContentLayer::Create(&client_)),
2437 child_layer1_(FakeContentLayer::Create(&client_)),
2438 child_layer2_(FakeContentLayer::Create(&client_)),
2439 num_commits_(0) {}
2441 void BeginTest() override {
2442 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2443 root_layer_->SetBounds(gfx::Size(100, 100));
2444 child_layer1_->SetBounds(gfx::Size(100, 100));
2445 child_layer2_->SetBounds(gfx::Size(100, 100));
2446 root_layer_->AddChild(child_layer1_);
2447 root_layer_->AddChild(child_layer2_);
2448 layer_tree_host()->SetRootLayer(root_layer_);
2449 PostSetNeedsCommitToMainThread();
2452 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2453 bool visible) override {
2454 if (visible) {
2455 // One backing should remain unevicted.
2456 EXPECT_EQ(100u * 100u * 4u * 1u,
2457 contents_texture_manager_->MemoryUseBytes());
2458 } else {
2459 EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes());
2462 // Make sure that contents textures are marked as having been
2463 // purged.
2464 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2465 // End the test in this state.
2466 EndTest();
2469 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2470 ++num_commits_;
2471 switch (num_commits_) {
2472 case 1:
2473 // All three backings should have memory.
2474 EXPECT_EQ(100u * 100u * 4u * 3u,
2475 contents_texture_manager_->MemoryUseBytes());
2477 // Set a new policy that will kick out 1 of the 3 resources.
2478 // Because a resource was evicted, a commit will be kicked off.
2479 host_impl->SetMemoryPolicy(
2480 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2481 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2482 1000));
2483 break;
2484 case 2:
2485 // Only two backings should have memory.
2486 EXPECT_EQ(100u * 100u * 4u * 2u,
2487 contents_texture_manager_->MemoryUseBytes());
2488 // Become backgrounded, which will cause 1 more resource to be
2489 // evicted.
2490 PostSetVisibleToMainThread(false);
2491 break;
2492 default:
2493 // No further commits should happen because this is not visible
2494 // anymore.
2495 NOTREACHED();
2496 break;
2500 void AfterTest() override {}
2502 private:
2503 FakeContentLayerClient client_;
2504 scoped_refptr<FakeContentLayer> root_layer_;
2505 scoped_refptr<FakeContentLayer> child_layer1_;
2506 scoped_refptr<FakeContentLayer> child_layer2_;
2507 int num_commits_;
2510 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2511 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2513 class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
2514 public:
2515 void SetupTree() override {
2516 num_tiles_rastered_ = 0;
2518 scoped_refptr<Layer> root_layer = PictureLayer::Create(&client_);
2519 client_.set_fill_with_nonsolid_color(true);
2520 root_layer->SetIsDrawable(true);
2521 root_layer->SetBounds(gfx::Size(10, 10));
2522 root_layer->SetContentsOpaque(true);
2524 layer_tree_host()->SetRootLayer(root_layer);
2526 // The expectations are based on the assumption that the default
2527 // LCD settings are:
2528 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2530 LayerTreeHostTest::SetupTree();
2533 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2535 void DidCommitAndDrawFrame() override {
2536 switch (layer_tree_host()->source_frame_number()) {
2537 case 1:
2538 PostSetNeedsCommitToMainThread();
2539 break;
2540 case 2:
2541 // Change layer opacity that should trigger lcd change.
2542 layer_tree_host()->root_layer()->SetOpacity(.5f);
2543 break;
2544 case 3:
2545 // Change layer opacity that should not trigger lcd change.
2546 layer_tree_host()->root_layer()->SetOpacity(1.f);
2547 break;
2548 case 4:
2549 EndTest();
2550 break;
2554 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
2555 const Tile* tile) override {
2556 ++num_tiles_rastered_;
2559 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2560 PictureLayerImpl* root_layer =
2561 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer());
2562 bool can_use_lcd_text =
2563 host_impl->active_tree()->root_layer()->can_use_lcd_text();
2564 switch (host_impl->active_tree()->source_frame_number()) {
2565 case 0:
2566 // The first draw.
2567 EXPECT_EQ(1, num_tiles_rastered_);
2568 EXPECT_TRUE(can_use_lcd_text);
2569 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2570 break;
2571 case 1:
2572 // Nothing changed on the layer.
2573 EXPECT_EQ(1, num_tiles_rastered_);
2574 EXPECT_TRUE(can_use_lcd_text);
2575 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2576 break;
2577 case 2:
2578 // LCD text was disabled; it should be re-rastered with LCD text off.
2579 EXPECT_EQ(2, num_tiles_rastered_);
2580 EXPECT_FALSE(can_use_lcd_text);
2581 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2582 break;
2583 case 3:
2584 // LCD text was enabled, but it's sticky and stays off.
2585 EXPECT_EQ(2, num_tiles_rastered_);
2586 EXPECT_TRUE(can_use_lcd_text);
2587 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2588 break;
2592 void AfterTest() override {}
2594 private:
2595 FakeContentLayerClient client_;
2596 int num_tiles_rastered_;
2599 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
2601 // Verify that the BeginFrame notification is used to initiate rendering.
2602 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2603 public:
2604 void InitializeSettings(LayerTreeSettings* settings) override {
2605 settings->use_external_begin_frame_source = true;
2608 void BeginTest() override {
2609 // This will trigger a SetNeedsBeginFrame which will trigger a
2610 // BeginFrame.
2611 PostSetNeedsCommitToMainThread();
2614 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2615 LayerTreeHostImpl::FrameData* frame,
2616 DrawResult draw_result) override {
2617 EndTest();
2618 return DRAW_SUCCESS;
2621 void AfterTest() override {}
2623 private:
2624 base::TimeTicks frame_time_;
2627 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2629 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2630 : public LayerTreeHostTest {
2631 public:
2632 void InitializeSettings(LayerTreeSettings* settings) override {
2633 settings->use_external_begin_frame_source = true;
2634 settings->using_synchronous_renderer_compositor = true;
2637 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2639 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2640 // The BeginFrame notification is turned off now but will get enabled
2641 // once we return. End test while it's enabled.
2642 ImplThreadTaskRunner()->PostTask(
2643 FROM_HERE,
2644 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2645 base::Unretained(this)));
2648 void AfterTest() override {}
2651 MULTI_THREAD_TEST_F(
2652 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2654 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2655 protected:
2656 LayerTreeHostTestAbortedCommitDoesntStall()
2657 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2659 void InitializeSettings(LayerTreeSettings* settings) override {
2660 settings->use_external_begin_frame_source = true;
2663 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2665 void DidCommit() override {
2666 commit_count_++;
2667 if (commit_count_ == 4) {
2668 // After two aborted commits, request a real commit now to make sure a
2669 // real commit following an aborted commit will still complete and
2670 // end the test even when the Impl thread is idle.
2671 layer_tree_host()->SetNeedsCommit();
2675 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2676 CommitEarlyOutReason reason) override {
2677 commit_abort_count_++;
2678 // Initiate another abortable commit.
2679 host_impl->SetNeedsCommit();
2682 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2683 commit_complete_count_++;
2684 if (commit_complete_count_ == 1) {
2685 // Initiate an abortable commit after the first commit.
2686 host_impl->SetNeedsCommit();
2687 } else {
2688 EndTest();
2692 void AfterTest() override {
2693 EXPECT_EQ(commit_count_, 5);
2694 EXPECT_EQ(commit_abort_count_, 3);
2695 EXPECT_EQ(commit_complete_count_, 2);
2698 int commit_count_;
2699 int commit_abort_count_;
2700 int commit_complete_count_;
2703 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2704 : public LayerTreeHostTestAbortedCommitDoesntStall {
2705 void InitializeSettings(LayerTreeSettings* settings) override {
2706 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2707 settings->using_synchronous_renderer_compositor = true;
2711 MULTI_THREAD_TEST_F(
2712 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2714 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2715 : public LayerTreeHostTestAbortedCommitDoesntStall {
2716 void InitializeSettings(LayerTreeSettings* settings) override {
2717 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2718 settings->throttle_frame_production = false;
2722 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2724 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2725 : public LayerTreeHostTest {
2726 protected:
2727 void InitializeSettings(LayerTreeSettings* settings) override {
2728 settings->impl_side_painting = true;
2731 void SetupTree() override {
2732 LayerTreeHostTest::SetupTree();
2734 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2735 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2736 layer->SetBounds(gfx::Size(10, 10));
2737 layer_tree_host()->root_layer()->AddChild(layer);
2740 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2742 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2743 EndTest();
2746 void AfterTest() override {}
2748 FakeContentLayerClient client_;
2751 MULTI_THREAD_TEST_F(
2752 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2754 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2755 : public LayerTreeHostTest {
2756 public:
2757 class SetBoundsClient : public ContentLayerClient {
2758 public:
2759 SetBoundsClient() : layer_(0) {}
2761 void set_layer(Layer* layer) { layer_ = layer; }
2763 void PaintContents(SkCanvas* canvas,
2764 const gfx::Rect& clip,
2765 PaintingControlSetting picture_control) override {
2766 layer_->SetBounds(gfx::Size(2, 2));
2769 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
2770 const gfx::Rect& clip,
2771 PaintingControlSetting picture_control) override {
2772 NOTIMPLEMENTED();
2773 return DisplayItemList::Create();
2776 bool FillsBoundsCompletely() const override { return false; }
2778 private:
2779 Layer* layer_;
2782 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2784 void SetupTree() override {
2785 if (layer_tree_host()->settings().impl_side_painting) {
2786 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_);
2787 layer_tree_host()->SetRootLayer(root_layer);
2788 } else {
2789 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2790 layer_tree_host()->SetRootLayer(root_layer);
2792 Layer* root_layer = layer_tree_host()->root_layer();
2793 root_layer->SetIsDrawable(true);
2794 root_layer->SetBounds(gfx::Size(1, 1));
2796 client_.set_layer(root_layer);
2798 LayerTreeHostTest::SetupTree();
2801 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2802 void AfterTest() override {}
2804 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2805 num_commits_++;
2806 if (num_commits_ == 1) {
2807 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2808 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds());
2809 } else {
2810 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2811 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds());
2812 EndTest();
2816 private:
2817 SetBoundsClient client_;
2818 int num_commits_;
2821 SINGLE_AND_MULTI_THREAD_TEST_F(
2822 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2824 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2825 public:
2826 MockIOSurfaceWebGraphicsContext3D() {
2827 test_capabilities_.gpu.iosurface = true;
2828 test_capabilities_.gpu.texture_rectangle = true;
2831 GLuint createTexture() override { return 1; }
2832 MOCK_METHOD1(activeTexture, void(GLenum texture));
2833 MOCK_METHOD2(bindTexture, void(GLenum target,
2834 GLuint texture_id));
2835 MOCK_METHOD3(texParameteri, void(GLenum target,
2836 GLenum pname,
2837 GLint param));
2838 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2839 GLint width,
2840 GLint height,
2841 GLuint ioSurfaceId,
2842 GLuint plane));
2843 MOCK_METHOD4(drawElements, void(GLenum mode,
2844 GLsizei count,
2845 GLenum type,
2846 GLintptr offset));
2847 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2848 MOCK_METHOD3(produceTextureDirectCHROMIUM,
2849 void(GLuint texture, GLenum target, const GLbyte* mailbox));
2852 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2853 protected:
2854 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2855 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2856 new MockIOSurfaceWebGraphicsContext3D);
2857 mock_context_ = mock_context_owned.get();
2859 if (delegating_renderer())
2860 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
2861 else
2862 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
2865 void SetupTree() override {
2866 LayerTreeHostTest::SetupTree();
2868 layer_tree_host()->root_layer()->SetIsDrawable(false);
2870 io_surface_id_ = 9;
2871 io_surface_size_ = gfx::Size(6, 7);
2873 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2874 io_surface_layer->SetBounds(gfx::Size(10, 10));
2875 io_surface_layer->SetIsDrawable(true);
2876 io_surface_layer->SetContentsOpaque(true);
2877 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2878 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2881 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2883 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2884 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2885 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2887 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2888 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2889 .Times(AtLeast(1));
2890 EXPECT_CALL(*mock_context_,
2891 texParameteri(
2892 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2893 .Times(1);
2894 EXPECT_CALL(*mock_context_,
2895 texParameteri(
2896 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2897 .Times(1);
2898 EXPECT_CALL(*mock_context_,
2899 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2900 GL_TEXTURE_POOL_CHROMIUM,
2901 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2902 EXPECT_CALL(*mock_context_,
2903 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2904 GL_TEXTURE_WRAP_S,
2905 GL_CLAMP_TO_EDGE)).Times(1);
2906 EXPECT_CALL(*mock_context_,
2907 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2908 GL_TEXTURE_WRAP_T,
2909 GL_CLAMP_TO_EDGE)).Times(1);
2911 EXPECT_CALL(*mock_context_,
2912 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2913 io_surface_size_.width(),
2914 io_surface_size_.height(),
2915 io_surface_id_,
2916 0)).Times(1);
2918 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2921 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2922 LayerTreeHostImpl::FrameData* frame,
2923 DrawResult draw_result) override {
2924 Mock::VerifyAndClearExpectations(&mock_context_);
2925 ResourceProvider* resource_provider = host_impl->resource_provider();
2926 EXPECT_EQ(1u, resource_provider->num_resources());
2927 CHECK_EQ(1u, frame->render_passes.size());
2928 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2929 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
2930 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2931 const IOSurfaceDrawQuad* io_surface_draw_quad =
2932 IOSurfaceDrawQuad::MaterialCast(quad);
2933 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2934 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
2935 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2936 resource_provider->TargetForTesting(
2937 io_surface_draw_quad->io_surface_resource_id));
2939 if (delegating_renderer()) {
2940 // The io surface layer's resource should be sent to the parent.
2941 EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM(
2942 _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2943 } else {
2944 // The io surface layer's texture is drawn.
2945 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2946 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2947 .Times(AtLeast(1));
2950 return draw_result;
2953 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2954 Mock::VerifyAndClearExpectations(&mock_context_);
2956 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2957 EndTest();
2960 void AfterTest() override {}
2962 int io_surface_id_;
2963 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2964 gfx::Size io_surface_size_;
2967 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2969 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2970 public:
2971 void BeginTest() override {
2972 frame_ = 0;
2973 PostSetNeedsCommitToMainThread();
2976 // Round 1: commit + draw
2977 // Round 2: commit only (no draw/swap)
2978 // Round 3: draw only (no commit)
2980 void DidCommit() override {
2981 int commit = layer_tree_host()->source_frame_number();
2982 switch (commit) {
2983 case 2:
2984 // Round 2 done.
2985 EXPECT_EQ(1, frame_);
2986 layer_tree_host()->SetNeedsRedraw();
2987 break;
2991 void DidCompleteSwapBuffers() override {
2992 int commit = layer_tree_host()->source_frame_number();
2993 ++frame_;
2994 switch (frame_) {
2995 case 1:
2996 // Round 1 done.
2997 EXPECT_EQ(1, commit);
2998 layer_tree_host()->SetNeedsCommit();
2999 break;
3000 case 2:
3001 // Round 3 done.
3002 EXPECT_EQ(2, commit);
3003 EndTest();
3004 break;
3008 void AfterTest() override {}
3010 protected:
3011 int frame_;
3014 // Flaky on all platforms: http://crbug.com/327498
3015 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
3016 RunTest(true, true, true);
3019 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
3020 RunTest(true, false, true);
3023 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
3024 public:
3025 void InitializeSettings(LayerTreeSettings* settings) override {
3026 // PictureLayer can only be used with impl side painting enabled.
3027 settings->impl_side_painting = true;
3030 void SetupTree() override {
3031 layer_ = FakePictureLayer::Create(&client_);
3032 // Force commits to not be aborted so new frames get drawn, otherwise
3033 // the renderer gets deferred initialized but nothing new needs drawing.
3034 layer_->set_always_update_resources(true);
3035 layer_tree_host()->SetRootLayer(layer_);
3036 LayerTreeHostTest::SetupTree();
3039 void BeginTest() override {
3040 did_initialize_gl_ = false;
3041 did_release_gl_ = false;
3042 last_source_frame_number_drawn_ = -1; // Never drawn.
3043 PostSetNeedsCommitToMainThread();
3046 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3047 scoped_ptr<TestWebGraphicsContext3D> context3d(
3048 TestWebGraphicsContext3D::Create());
3050 return FakeOutputSurface::CreateDeferredGL(
3051 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
3052 delegating_renderer());
3055 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
3056 ASSERT_TRUE(host_impl->RootLayer());
3057 FakePictureLayerImpl* layer_impl =
3058 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
3060 // The same frame can be draw multiple times if new visible tiles are
3061 // rasterized. But we want to make sure we only post DeferredInitialize
3062 // and ReleaseGL once, so early out if the same frame is drawn again.
3063 if (last_source_frame_number_drawn_ ==
3064 host_impl->active_tree()->source_frame_number())
3065 return;
3067 last_source_frame_number_drawn_ =
3068 host_impl->active_tree()->source_frame_number();
3070 if (!did_initialize_gl_) {
3071 EXPECT_LE(1u, layer_impl->append_quads_count());
3072 ImplThreadTaskRunner()->PostTask(
3073 FROM_HERE,
3074 base::Bind(
3075 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3076 base::Unretained(this),
3077 base::Unretained(host_impl)));
3078 } else if (did_initialize_gl_ && !did_release_gl_) {
3079 EXPECT_LE(2u, layer_impl->append_quads_count());
3080 ImplThreadTaskRunner()->PostTask(
3081 FROM_HERE,
3082 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3083 base::Unretained(this),
3084 base::Unretained(host_impl)));
3085 } else if (did_initialize_gl_ && did_release_gl_) {
3086 EXPECT_LE(3u, layer_impl->append_quads_count());
3087 EndTest();
3091 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
3092 EXPECT_FALSE(did_initialize_gl_);
3093 // SetAndInitializeContext3D calls SetNeedsCommit.
3094 FakeOutputSurface* fake_output_surface =
3095 static_cast<FakeOutputSurface*>(host_impl->output_surface());
3096 scoped_refptr<TestContextProvider> context_provider =
3097 TestContextProvider::Create(); // Not bound to thread.
3098 scoped_refptr<TestContextProvider> worker_context_provider =
3099 TestContextProvider::Create(); // Not bound to thread.
3100 EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d(
3101 context_provider, worker_context_provider));
3102 did_initialize_gl_ = true;
3105 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3106 EXPECT_TRUE(did_initialize_gl_);
3107 EXPECT_FALSE(did_release_gl_);
3108 // ReleaseGL calls SetNeedsCommit.
3109 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3110 did_release_gl_ = true;
3113 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
3114 ASSERT_TRUE(result);
3115 DelegatedFrameData* delegated_frame_data =
3116 output_surface()->last_sent_frame().delegated_frame_data.get();
3117 if (!delegated_frame_data)
3118 return;
3120 // Return all resources immediately.
3121 TransferableResourceArray resources_to_return =
3122 output_surface()->resources_held_by_parent();
3124 CompositorFrameAck ack;
3125 for (size_t i = 0; i < resources_to_return.size(); ++i)
3126 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
3127 host_impl->ReclaimResources(&ack);
3130 void AfterTest() override {
3131 EXPECT_TRUE(did_initialize_gl_);
3132 EXPECT_TRUE(did_release_gl_);
3135 private:
3136 FakeContentLayerClient client_;
3137 scoped_refptr<FakePictureLayer> layer_;
3138 bool did_initialize_gl_;
3139 bool did_release_gl_;
3140 int last_source_frame_number_drawn_;
3143 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3145 class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest {
3146 public:
3147 void SetupTree() override {
3148 root_layer_ = FakePictureLayer::Create(&client_);
3149 root_layer_->SetIsDrawable(true);
3150 root_layer_->SetBounds(gfx::Size(50, 50));
3152 parent_layer_ = FakePictureLayer::Create(&client_);
3153 parent_layer_->SetIsDrawable(true);
3154 parent_layer_->SetBounds(gfx::Size(50, 50));
3155 parent_layer_->SetForceRenderSurface(true);
3157 child_layer_ = FakePictureLayer::Create(&client_);
3158 child_layer_->SetIsDrawable(true);
3159 child_layer_->SetBounds(gfx::Size(50, 50));
3161 root_layer_->AddChild(parent_layer_);
3162 parent_layer_->AddChild(child_layer_);
3163 layer_tree_host()->SetRootLayer(root_layer_);
3165 LayerTreeHostTest::SetupTree();
3168 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3169 return FakeOutputSurface::CreateDeferredGL(
3170 make_scoped_ptr(new SoftwareOutputDevice), delegating_renderer());
3173 void BeginTest() override {
3174 PostSetNeedsCommitToMainThread();
3175 swap_count_ = 0;
3178 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3179 LayerTreeHostImpl::FrameData* frame_data,
3180 DrawResult draw_result) override {
3181 if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
3182 EXPECT_EQ(1u, frame_data->render_passes.size());
3183 // Has at least 3 quads for each layer.
3184 RenderPass* render_pass = frame_data->render_passes[0];
3185 EXPECT_GE(render_pass->quad_list.size(), 3u);
3186 } else {
3187 EXPECT_EQ(2u, frame_data->render_passes.size());
3189 // At least root layer quad in root render pass.
3190 EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u);
3191 // At least parent and child layer quads in parent render pass.
3192 EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u);
3194 return draw_result;
3197 void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3198 swap_count_++;
3199 switch (swap_count_) {
3200 case 1: {
3201 gfx::Transform identity;
3202 gfx::Rect empty_rect;
3203 bool resourceless_software_draw = true;
3204 host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect,
3205 empty_rect, identity,
3206 resourceless_software_draw);
3207 host_impl->SetFullRootLayerDamage();
3208 host_impl->SetNeedsRedraw();
3209 break;
3211 case 2:
3212 EndTest();
3213 break;
3214 default:
3215 NOTREACHED();
3219 void AfterTest() override {}
3221 private:
3222 FakeContentLayerClient client_;
3223 scoped_refptr<Layer> root_layer_;
3224 scoped_refptr<Layer> parent_layer_;
3225 scoped_refptr<Layer> child_layer_;
3226 int swap_count_;
3229 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw);
3231 class LayerTreeHostTestDeferredInitializeWithGpuRasterization
3232 : public LayerTreeHostTestDeferredInitialize {
3233 void InitializeSettings(LayerTreeSettings* settings) override {
3234 // PictureLayer can only be used with impl side painting enabled.
3235 settings->impl_side_painting = true;
3236 settings->gpu_rasterization_enabled = true;
3237 settings->gpu_rasterization_forced = true;
3241 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization);
3243 // Test for UI Resource management.
3244 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3245 public:
3246 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
3248 void InitializeSettings(LayerTreeSettings* settings) override {
3249 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
3252 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3254 void DidCommit() override {
3255 int frame = layer_tree_host()->source_frame_number();
3256 switch (frame) {
3257 case 1:
3258 CreateResource();
3259 CreateResource();
3260 PostSetNeedsCommitToMainThread();
3261 break;
3262 case 2:
3263 // Usually ScopedUIResource are deleted from the manager in their
3264 // destructor. Here we just want to test that a direct call to
3265 // DeleteUIResource works.
3266 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3267 PostSetNeedsCommitToMainThread();
3268 break;
3269 case 3:
3270 // DeleteUIResource can be called with an invalid id.
3271 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3272 PostSetNeedsCommitToMainThread();
3273 break;
3274 case 4:
3275 CreateResource();
3276 CreateResource();
3277 PostSetNeedsCommitToMainThread();
3278 break;
3279 case 5:
3280 ClearResources();
3281 EndTest();
3282 break;
3286 void PerformTest(LayerTreeHostImpl* impl) {
3287 TestWebGraphicsContext3D* context = TestContext();
3289 int frame = impl->active_tree()->source_frame_number();
3290 switch (frame) {
3291 case 0:
3292 ASSERT_EQ(0u, context->NumTextures());
3293 break;
3294 case 1:
3295 // Created two textures.
3296 ASSERT_EQ(2u, context->NumTextures());
3297 break;
3298 case 2:
3299 // One texture left after one deletion.
3300 ASSERT_EQ(1u, context->NumTextures());
3301 break;
3302 case 3:
3303 // Resource manager state should not change when delete is called on an
3304 // invalid id.
3305 ASSERT_EQ(1u, context->NumTextures());
3306 break;
3307 case 4:
3308 // Creation after deletion: two more creates should total up to
3309 // three textures.
3310 ASSERT_EQ(3u, context->NumTextures());
3311 break;
3315 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3316 if (!impl->settings().impl_side_painting)
3317 PerformTest(impl);
3320 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3321 if (impl->settings().impl_side_painting)
3322 PerformTest(impl);
3325 void AfterTest() override {}
3327 private:
3328 // Must clear all resources before exiting.
3329 void ClearResources() {
3330 for (int i = 0; i < num_ui_resources_; i++)
3331 ui_resources_[i] = nullptr;
3334 void CreateResource() {
3335 ui_resources_[num_ui_resources_++] =
3336 FakeScopedUIResource::Create(layer_tree_host());
3339 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3340 int num_ui_resources_;
3343 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3345 class PushPropertiesCountingLayerImpl : public LayerImpl {
3346 public:
3347 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
3348 LayerTreeImpl* tree_impl, int id) {
3349 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
3352 ~PushPropertiesCountingLayerImpl() override {}
3354 void PushPropertiesTo(LayerImpl* layer) override {
3355 LayerImpl::PushPropertiesTo(layer);
3356 push_properties_count_++;
3357 // Push state to the active tree because we can only access it from there.
3358 static_cast<PushPropertiesCountingLayerImpl*>(
3359 layer)->push_properties_count_ = push_properties_count_;
3362 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3363 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3366 size_t push_properties_count() const { return push_properties_count_; }
3367 void reset_push_properties_count() { push_properties_count_ = 0; }
3369 private:
3370 size_t push_properties_count_;
3372 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
3373 : LayerImpl(tree_impl, id),
3374 push_properties_count_(0) {
3375 SetBounds(gfx::Size(1, 1));
3379 class PushPropertiesCountingLayer : public Layer {
3380 public:
3381 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3382 return new PushPropertiesCountingLayer();
3385 void PushPropertiesTo(LayerImpl* layer) override {
3386 Layer::PushPropertiesTo(layer);
3387 push_properties_count_++;
3388 if (persist_needs_push_properties_)
3389 needs_push_properties_ = true;
3392 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3393 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3396 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
3398 size_t push_properties_count() const { return push_properties_count_; }
3399 void reset_push_properties_count() { push_properties_count_ = 0; }
3401 void set_persist_needs_push_properties(bool persist) {
3402 persist_needs_push_properties_ = persist;
3405 private:
3406 PushPropertiesCountingLayer()
3407 : push_properties_count_(0), persist_needs_push_properties_(false) {
3408 SetBounds(gfx::Size(1, 1));
3410 ~PushPropertiesCountingLayer() override {}
3412 size_t push_properties_count_;
3413 bool persist_needs_push_properties_;
3416 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3417 protected:
3418 void BeginTest() override {
3419 num_commits_ = 0;
3420 expected_push_properties_root_ = 0;
3421 expected_push_properties_child_ = 0;
3422 expected_push_properties_grandchild_ = 0;
3423 expected_push_properties_child2_ = 0;
3424 expected_push_properties_other_root_ = 0;
3425 expected_push_properties_leaf_layer_ = 0;
3426 PostSetNeedsCommitToMainThread();
3429 void SetupTree() override {
3430 root_ = PushPropertiesCountingLayer::Create();
3431 root_->CreateRenderSurface();
3432 child_ = PushPropertiesCountingLayer::Create();
3433 child2_ = PushPropertiesCountingLayer::Create();
3434 grandchild_ = PushPropertiesCountingLayer::Create();
3435 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3436 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3438 root_->AddChild(child_);
3439 root_->AddChild(child2_);
3440 child_->AddChild(grandchild_);
3441 child2_->AddChild(leaf_always_pushing_layer_);
3443 other_root_ = PushPropertiesCountingLayer::Create();
3444 other_root_->CreateRenderSurface();
3446 // Don't set the root layer here.
3447 LayerTreeHostTest::SetupTree();
3450 void DidCommitAndDrawFrame() override {
3451 ++num_commits_;
3453 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3454 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3455 EXPECT_EQ(expected_push_properties_grandchild_,
3456 grandchild_->push_properties_count());
3457 EXPECT_EQ(expected_push_properties_child2_,
3458 child2_->push_properties_count());
3459 EXPECT_EQ(expected_push_properties_other_root_,
3460 other_root_->push_properties_count());
3461 EXPECT_EQ(expected_push_properties_leaf_layer_,
3462 leaf_always_pushing_layer_->push_properties_count());
3464 // The scrollbar layer always needs to be pushed.
3465 if (root_->layer_tree_host()) {
3466 EXPECT_TRUE(root_->descendant_needs_push_properties());
3467 EXPECT_FALSE(root_->needs_push_properties());
3469 if (child2_->layer_tree_host()) {
3470 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3471 EXPECT_FALSE(child2_->needs_push_properties());
3473 if (leaf_always_pushing_layer_->layer_tree_host()) {
3474 EXPECT_FALSE(
3475 leaf_always_pushing_layer_->descendant_needs_push_properties());
3476 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3479 // child_ and grandchild_ don't persist their need to push properties.
3480 if (child_->layer_tree_host()) {
3481 EXPECT_FALSE(child_->descendant_needs_push_properties());
3482 EXPECT_FALSE(child_->needs_push_properties());
3484 if (grandchild_->layer_tree_host()) {
3485 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3486 EXPECT_FALSE(grandchild_->needs_push_properties());
3489 if (other_root_->layer_tree_host()) {
3490 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3491 EXPECT_FALSE(other_root_->needs_push_properties());
3494 switch (num_commits_) {
3495 case 1:
3496 layer_tree_host()->SetRootLayer(root_);
3497 // Layers added to the tree get committed.
3498 ++expected_push_properties_root_;
3499 ++expected_push_properties_child_;
3500 ++expected_push_properties_grandchild_;
3501 ++expected_push_properties_child2_;
3502 break;
3503 case 2:
3504 layer_tree_host()->SetNeedsCommit();
3505 // No layers need commit.
3506 break;
3507 case 3:
3508 layer_tree_host()->SetRootLayer(other_root_);
3509 // Layers added to the tree get committed.
3510 ++expected_push_properties_other_root_;
3511 break;
3512 case 4:
3513 layer_tree_host()->SetRootLayer(root_);
3514 // Layers added to the tree get committed.
3515 ++expected_push_properties_root_;
3516 ++expected_push_properties_child_;
3517 ++expected_push_properties_grandchild_;
3518 ++expected_push_properties_child2_;
3519 break;
3520 case 5:
3521 layer_tree_host()->SetNeedsCommit();
3522 // No layers need commit.
3523 break;
3524 case 6:
3525 child_->RemoveFromParent();
3526 // No layers need commit.
3527 break;
3528 case 7:
3529 root_->AddChild(child_);
3530 // Layers added to the tree get committed.
3531 ++expected_push_properties_child_;
3532 ++expected_push_properties_grandchild_;
3533 break;
3534 case 8:
3535 grandchild_->RemoveFromParent();
3536 // No layers need commit.
3537 break;
3538 case 9:
3539 child_->AddChild(grandchild_);
3540 // Layers added to the tree get committed.
3541 ++expected_push_properties_grandchild_;
3542 break;
3543 case 10:
3544 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3545 // No layers need commit.
3546 break;
3547 case 11:
3548 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3549 // No layers need commit.
3550 break;
3551 case 12:
3552 child_->SetPosition(gfx::Point(1, 1));
3553 // The modified layer needs commit
3554 ++expected_push_properties_child_;
3555 break;
3556 case 13:
3557 child2_->SetPosition(gfx::Point(1, 1));
3558 // The modified layer needs commit
3559 ++expected_push_properties_child2_;
3560 break;
3561 case 14:
3562 child_->RemoveFromParent();
3563 root_->AddChild(child_);
3564 // Layers added to the tree get committed.
3565 ++expected_push_properties_child_;
3566 ++expected_push_properties_grandchild_;
3567 break;
3568 case 15:
3569 grandchild_->SetPosition(gfx::Point(1, 1));
3570 // The modified layer needs commit
3571 ++expected_push_properties_grandchild_;
3572 break;
3573 case 16:
3574 // SetNeedsDisplay does not always set needs commit (so call it
3575 // explicitly), but is a property change.
3576 child_->SetNeedsDisplay();
3577 ++expected_push_properties_child_;
3578 layer_tree_host()->SetNeedsCommit();
3579 break;
3580 case 17:
3581 EndTest();
3582 break;
3585 // The leaf layer always pushes.
3586 if (leaf_always_pushing_layer_->layer_tree_host())
3587 ++expected_push_properties_leaf_layer_;
3590 void AfterTest() override {}
3592 int num_commits_;
3593 FakeContentLayerClient client_;
3594 scoped_refptr<PushPropertiesCountingLayer> root_;
3595 scoped_refptr<PushPropertiesCountingLayer> child_;
3596 scoped_refptr<PushPropertiesCountingLayer> child2_;
3597 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3598 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3599 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3600 size_t expected_push_properties_root_;
3601 size_t expected_push_properties_child_;
3602 size_t expected_push_properties_child2_;
3603 size_t expected_push_properties_grandchild_;
3604 size_t expected_push_properties_other_root_;
3605 size_t expected_push_properties_leaf_layer_;
3608 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3610 class LayerTreeHostTestImplLayersPushProperties
3611 : public LayerTreeHostTestLayersPushProperties {
3612 protected:
3613 void BeginTest() override {
3614 expected_push_properties_root_impl_ = 0;
3615 expected_push_properties_child_impl_ = 0;
3616 expected_push_properties_grandchild_impl_ = 0;
3617 expected_push_properties_child2_impl_ = 0;
3618 expected_push_properties_grandchild2_impl_ = 0;
3619 LayerTreeHostTestLayersPushProperties::BeginTest();
3622 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3623 // These commits are in response to the changes made in
3624 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3625 switch (num_commits_) {
3626 case 0:
3627 // Tree hasn't been setup yet don't bother to check anything.
3628 return;
3629 case 1:
3630 // Root gets set up, Everyone is initialized.
3631 ++expected_push_properties_root_impl_;
3632 ++expected_push_properties_child_impl_;
3633 ++expected_push_properties_grandchild_impl_;
3634 ++expected_push_properties_child2_impl_;
3635 ++expected_push_properties_grandchild2_impl_;
3636 break;
3637 case 2:
3638 // Tree doesn't change but the one leaf that always pushes is pushed.
3639 ++expected_push_properties_grandchild2_impl_;
3640 break;
3641 case 3:
3642 // Root is swapped here.
3643 // Clear the expected push properties the tree will be rebuilt.
3644 expected_push_properties_root_impl_ = 0;
3645 expected_push_properties_child_impl_ = 0;
3646 expected_push_properties_grandchild_impl_ = 0;
3647 expected_push_properties_child2_impl_ = 0;
3648 expected_push_properties_grandchild2_impl_ = 0;
3650 // Make sure the new root is pushed.
3651 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3652 host_impl->RootLayer())->push_properties_count());
3653 return;
3654 case 4:
3655 // Root is swapped back all of the layers in the tree get pushed.
3656 ++expected_push_properties_root_impl_;
3657 ++expected_push_properties_child_impl_;
3658 ++expected_push_properties_grandchild_impl_;
3659 ++expected_push_properties_child2_impl_;
3660 ++expected_push_properties_grandchild2_impl_;
3661 break;
3662 case 5:
3663 // Tree doesn't change but the one leaf that always pushes is pushed.
3664 ++expected_push_properties_grandchild2_impl_;
3665 break;
3666 case 6:
3667 // First child is removed. Structure of the tree changes here so swap
3668 // some of the values. child_impl becomes child2_impl.
3669 expected_push_properties_child_impl_ =
3670 expected_push_properties_child2_impl_;
3671 expected_push_properties_child2_impl_ = 0;
3672 // grandchild_impl becomes grandchild2_impl.
3673 expected_push_properties_grandchild_impl_ =
3674 expected_push_properties_grandchild2_impl_;
3675 expected_push_properties_grandchild2_impl_ = 0;
3677 // grandchild_impl is now the leaf that always pushes. It is pushed.
3678 ++expected_push_properties_grandchild_impl_;
3679 break;
3680 case 7:
3681 // The leaf that always pushes is pushed.
3682 ++expected_push_properties_grandchild_impl_;
3684 // Child is added back. New layers are initialized.
3685 ++expected_push_properties_grandchild2_impl_;
3686 ++expected_push_properties_child2_impl_;
3687 break;
3688 case 8:
3689 // Leaf is removed.
3690 expected_push_properties_grandchild2_impl_ = 0;
3692 // Always pushing.
3693 ++expected_push_properties_grandchild_impl_;
3694 break;
3695 case 9:
3696 // Leaf is added back
3697 ++expected_push_properties_grandchild2_impl_;
3699 // The leaf that always pushes is pushed.
3700 ++expected_push_properties_grandchild_impl_;
3701 break;
3702 case 10:
3703 // The leaf that always pushes is pushed.
3704 ++expected_push_properties_grandchild_impl_;
3705 break;
3706 case 11:
3707 // The leaf that always pushes is pushed.
3708 ++expected_push_properties_grandchild_impl_;
3709 break;
3710 case 12:
3711 // The leaf that always pushes is pushed.
3712 ++expected_push_properties_grandchild_impl_;
3714 // This child position was changed.
3715 ++expected_push_properties_child2_impl_;
3716 break;
3717 case 13:
3718 // The position of this child was changed.
3719 ++expected_push_properties_child_impl_;
3721 // The leaf that always pushes is pushed.
3722 ++expected_push_properties_grandchild_impl_;
3723 break;
3724 case 14:
3725 // Second child is removed from tree. Don't discard counts because
3726 // they are added back before commit.
3728 // The leaf that always pushes is pushed.
3729 ++expected_push_properties_grandchild_impl_;
3731 // Second child added back.
3732 ++expected_push_properties_child2_impl_;
3733 ++expected_push_properties_grandchild2_impl_;
3735 break;
3736 case 15:
3737 // The position of this child was changed.
3738 ++expected_push_properties_grandchild2_impl_;
3740 // The leaf that always pushes is pushed.
3741 ++expected_push_properties_grandchild_impl_;
3742 break;
3743 case 16:
3744 // Second child is invalidated with SetNeedsDisplay
3745 ++expected_push_properties_child2_impl_;
3747 // The leaf that always pushed is pushed.
3748 ++expected_push_properties_grandchild_impl_;
3749 break;
3752 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3753 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3754 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3755 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3756 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3758 // Pull the layers that we need from the tree assuming the same structure
3759 // as LayerTreeHostTestLayersPushProperties
3760 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3761 host_impl->RootLayer());
3763 if (root_impl_ && root_impl_->children().size() > 0) {
3764 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3765 root_impl_->children()[0]);
3767 if (child_impl_ && child_impl_->children().size() > 0)
3768 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3769 child_impl_->children()[0]);
3772 if (root_impl_ && root_impl_->children().size() > 1) {
3773 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3774 root_impl_->children()[1]);
3776 if (child2_impl_ && child2_impl_->children().size() > 0)
3777 leaf_always_pushing_layer_impl_ =
3778 static_cast<PushPropertiesCountingLayerImpl*>(
3779 child2_impl_->children()[0]);
3782 if (root_impl_)
3783 EXPECT_EQ(expected_push_properties_root_impl_,
3784 root_impl_->push_properties_count());
3785 if (child_impl_)
3786 EXPECT_EQ(expected_push_properties_child_impl_,
3787 child_impl_->push_properties_count());
3788 if (grandchild_impl_)
3789 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3790 grandchild_impl_->push_properties_count());
3791 if (child2_impl_)
3792 EXPECT_EQ(expected_push_properties_child2_impl_,
3793 child2_impl_->push_properties_count());
3794 if (leaf_always_pushing_layer_impl_)
3795 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3796 leaf_always_pushing_layer_impl_->push_properties_count());
3799 size_t expected_push_properties_root_impl_;
3800 size_t expected_push_properties_child_impl_;
3801 size_t expected_push_properties_child2_impl_;
3802 size_t expected_push_properties_grandchild_impl_;
3803 size_t expected_push_properties_grandchild2_impl_;
3806 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3807 RunTestWithImplSidePainting();
3810 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3811 : public LayerTreeHostTest {
3812 protected:
3813 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3815 void SetupTree() override {
3816 root_ = Layer::Create();
3817 root_->CreateRenderSurface();
3818 root_->SetBounds(gfx::Size(1, 1));
3820 bool paint_scrollbar = true;
3821 bool has_thumb = false;
3822 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3823 paint_scrollbar, has_thumb, root_->id());
3825 root_->AddChild(scrollbar_layer_);
3827 layer_tree_host()->SetRootLayer(root_);
3828 LayerTreeHostTest::SetupTree();
3831 void DidCommitAndDrawFrame() override {
3832 switch (layer_tree_host()->source_frame_number()) {
3833 case 0:
3834 break;
3835 case 1: {
3836 // During update, the ignore_set_needs_commit_ bit is set to true to
3837 // avoid causing a second commit to be scheduled. If a property change
3838 // is made during this, however, it needs to be pushed in the upcoming
3839 // commit.
3840 scoped_ptr<base::AutoReset<bool>> ignore =
3841 scrollbar_layer_->IgnoreSetNeedsCommit();
3843 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3845 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3846 EXPECT_TRUE(root_->descendant_needs_push_properties());
3847 layer_tree_host()->SetNeedsCommit();
3849 scrollbar_layer_->reset_push_properties_count();
3850 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3851 break;
3853 case 2:
3854 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3855 EndTest();
3856 break;
3860 void AfterTest() override {}
3862 scoped_refptr<Layer> root_;
3863 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3866 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3868 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3869 protected:
3870 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3872 void SetupTree() override {
3873 root_ = PushPropertiesCountingLayer::Create();
3874 root_->CreateRenderSurface();
3875 child_ = PushPropertiesCountingLayer::Create();
3876 root_->AddChild(child_);
3878 layer_tree_host()->SetRootLayer(root_);
3879 LayerTreeHostTest::SetupTree();
3882 void DidCommitAndDrawFrame() override {
3883 switch (layer_tree_host()->source_frame_number()) {
3884 case 0:
3885 break;
3886 case 1: {
3887 // During update, the ignore_set_needs_commit_ bit is set to true to
3888 // avoid causing a second commit to be scheduled. If a property change
3889 // is made during this, however, it needs to be pushed in the upcoming
3890 // commit.
3891 EXPECT_FALSE(root_->needs_push_properties());
3892 EXPECT_FALSE(child_->needs_push_properties());
3893 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3894 root_->reset_push_properties_count();
3895 child_->reset_push_properties_count();
3896 child_->SetDrawsContent(true);
3897 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3898 EXPECT_EQ(0u, root_->push_properties_count());
3899 EXPECT_EQ(0u, child_->push_properties_count());
3900 EXPECT_TRUE(root_->needs_push_properties());
3901 EXPECT_TRUE(child_->needs_push_properties());
3902 break;
3904 case 2:
3905 EXPECT_EQ(1u, root_->push_properties_count());
3906 EXPECT_EQ(1u, child_->push_properties_count());
3907 EXPECT_FALSE(root_->needs_push_properties());
3908 EXPECT_FALSE(child_->needs_push_properties());
3909 EndTest();
3910 break;
3914 void AfterTest() override {}
3916 scoped_refptr<PushPropertiesCountingLayer> root_;
3917 scoped_refptr<PushPropertiesCountingLayer> child_;
3920 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3922 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3923 : public LayerTreeHostTest {
3924 protected:
3925 void BeginTest() override {
3926 expected_push_properties_root_ = 0;
3927 expected_push_properties_child_ = 0;
3928 expected_push_properties_grandchild1_ = 0;
3929 expected_push_properties_grandchild2_ = 0;
3930 expected_push_properties_grandchild3_ = 0;
3931 PostSetNeedsCommitToMainThread();
3934 void SetupTree() override {
3935 root_ = PushPropertiesCountingLayer::Create();
3936 root_->CreateRenderSurface();
3937 child_ = PushPropertiesCountingLayer::Create();
3938 grandchild1_ = PushPropertiesCountingLayer::Create();
3939 grandchild2_ = PushPropertiesCountingLayer::Create();
3940 grandchild3_ = PushPropertiesCountingLayer::Create();
3942 root_->AddChild(child_);
3943 child_->AddChild(grandchild1_);
3944 child_->AddChild(grandchild2_);
3945 child_->AddChild(grandchild3_);
3947 // Don't set the root layer here.
3948 LayerTreeHostTest::SetupTree();
3951 void AfterTest() override {}
3953 FakeContentLayerClient client_;
3954 scoped_refptr<PushPropertiesCountingLayer> root_;
3955 scoped_refptr<PushPropertiesCountingLayer> child_;
3956 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3957 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3958 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3959 size_t expected_push_properties_root_;
3960 size_t expected_push_properties_child_;
3961 size_t expected_push_properties_grandchild1_;
3962 size_t expected_push_properties_grandchild2_;
3963 size_t expected_push_properties_grandchild3_;
3966 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3967 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3968 protected:
3969 void DidCommitAndDrawFrame() override {
3970 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3971 switch (last_source_frame_number) {
3972 case 0:
3973 EXPECT_FALSE(root_->needs_push_properties());
3974 EXPECT_FALSE(root_->descendant_needs_push_properties());
3975 EXPECT_FALSE(child_->needs_push_properties());
3976 EXPECT_FALSE(child_->descendant_needs_push_properties());
3977 EXPECT_FALSE(grandchild1_->needs_push_properties());
3978 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3979 EXPECT_FALSE(grandchild2_->needs_push_properties());
3980 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3981 EXPECT_FALSE(grandchild3_->needs_push_properties());
3982 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3984 layer_tree_host()->SetRootLayer(root_);
3986 EXPECT_TRUE(root_->needs_push_properties());
3987 EXPECT_TRUE(root_->descendant_needs_push_properties());
3988 EXPECT_TRUE(child_->needs_push_properties());
3989 EXPECT_TRUE(child_->descendant_needs_push_properties());
3990 EXPECT_TRUE(grandchild1_->needs_push_properties());
3991 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3992 EXPECT_TRUE(grandchild2_->needs_push_properties());
3993 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3994 EXPECT_TRUE(grandchild3_->needs_push_properties());
3995 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3996 break;
3997 case 1:
3998 EndTest();
3999 break;
4004 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
4006 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
4007 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4008 protected:
4009 void DidCommitAndDrawFrame() override {
4010 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4011 switch (last_source_frame_number) {
4012 case 0:
4013 layer_tree_host()->SetRootLayer(root_);
4014 break;
4015 case 1:
4016 EXPECT_FALSE(root_->needs_push_properties());
4017 EXPECT_FALSE(root_->descendant_needs_push_properties());
4018 EXPECT_FALSE(child_->needs_push_properties());
4019 EXPECT_FALSE(child_->descendant_needs_push_properties());
4020 EXPECT_FALSE(grandchild1_->needs_push_properties());
4021 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4022 EXPECT_FALSE(grandchild2_->needs_push_properties());
4023 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4024 EXPECT_FALSE(grandchild3_->needs_push_properties());
4025 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4027 grandchild1_->RemoveFromParent();
4028 grandchild1_->SetPosition(gfx::Point(1, 1));
4030 EXPECT_FALSE(root_->needs_push_properties());
4031 EXPECT_FALSE(root_->descendant_needs_push_properties());
4032 EXPECT_FALSE(child_->needs_push_properties());
4033 EXPECT_FALSE(child_->descendant_needs_push_properties());
4034 EXPECT_FALSE(grandchild2_->needs_push_properties());
4035 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4036 EXPECT_FALSE(grandchild3_->needs_push_properties());
4037 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4039 child_->AddChild(grandchild1_);
4041 EXPECT_FALSE(root_->needs_push_properties());
4042 EXPECT_TRUE(root_->descendant_needs_push_properties());
4043 EXPECT_FALSE(child_->needs_push_properties());
4044 EXPECT_TRUE(child_->descendant_needs_push_properties());
4045 EXPECT_TRUE(grandchild1_->needs_push_properties());
4046 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4047 EXPECT_FALSE(grandchild2_->needs_push_properties());
4048 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4049 EXPECT_FALSE(grandchild3_->needs_push_properties());
4050 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4052 grandchild2_->SetPosition(gfx::Point(1, 1));
4054 EXPECT_FALSE(root_->needs_push_properties());
4055 EXPECT_TRUE(root_->descendant_needs_push_properties());
4056 EXPECT_FALSE(child_->needs_push_properties());
4057 EXPECT_TRUE(child_->descendant_needs_push_properties());
4058 EXPECT_TRUE(grandchild1_->needs_push_properties());
4059 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4060 EXPECT_TRUE(grandchild2_->needs_push_properties());
4061 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4062 EXPECT_FALSE(grandchild3_->needs_push_properties());
4063 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4065 // grandchild2_ will still need a push properties.
4066 grandchild1_->RemoveFromParent();
4068 EXPECT_FALSE(root_->needs_push_properties());
4069 EXPECT_TRUE(root_->descendant_needs_push_properties());
4070 EXPECT_FALSE(child_->needs_push_properties());
4071 EXPECT_TRUE(child_->descendant_needs_push_properties());
4073 // grandchild3_ does not need a push properties, so recursing should
4074 // no longer be needed.
4075 grandchild2_->RemoveFromParent();
4077 EXPECT_FALSE(root_->needs_push_properties());
4078 EXPECT_FALSE(root_->descendant_needs_push_properties());
4079 EXPECT_FALSE(child_->needs_push_properties());
4080 EXPECT_FALSE(child_->descendant_needs_push_properties());
4081 EndTest();
4082 break;
4087 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
4089 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
4090 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4091 protected:
4092 void DidCommitAndDrawFrame() override {
4093 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4094 switch (last_source_frame_number) {
4095 case 0:
4096 layer_tree_host()->SetRootLayer(root_);
4097 grandchild1_->set_persist_needs_push_properties(true);
4098 grandchild2_->set_persist_needs_push_properties(true);
4099 break;
4100 case 1:
4101 EXPECT_FALSE(root_->needs_push_properties());
4102 EXPECT_TRUE(root_->descendant_needs_push_properties());
4103 EXPECT_FALSE(child_->needs_push_properties());
4104 EXPECT_TRUE(child_->descendant_needs_push_properties());
4105 EXPECT_TRUE(grandchild1_->needs_push_properties());
4106 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4107 EXPECT_TRUE(grandchild2_->needs_push_properties());
4108 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4109 EXPECT_FALSE(grandchild3_->needs_push_properties());
4110 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4112 // grandchild2_ will still need a push properties.
4113 grandchild1_->RemoveFromParent();
4115 EXPECT_FALSE(root_->needs_push_properties());
4116 EXPECT_TRUE(root_->descendant_needs_push_properties());
4117 EXPECT_FALSE(child_->needs_push_properties());
4118 EXPECT_TRUE(child_->descendant_needs_push_properties());
4120 // grandchild3_ does not need a push properties, so recursing should
4121 // no longer be needed.
4122 grandchild2_->RemoveFromParent();
4124 EXPECT_FALSE(root_->needs_push_properties());
4125 EXPECT_FALSE(root_->descendant_needs_push_properties());
4126 EXPECT_FALSE(child_->needs_push_properties());
4127 EXPECT_FALSE(child_->descendant_needs_push_properties());
4128 EndTest();
4129 break;
4134 MULTI_THREAD_TEST_F(
4135 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
4137 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
4138 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4139 protected:
4140 void DidCommitAndDrawFrame() override {
4141 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4142 switch (last_source_frame_number) {
4143 case 0:
4144 layer_tree_host()->SetRootLayer(root_);
4145 break;
4146 case 1:
4147 EXPECT_FALSE(root_->needs_push_properties());
4148 EXPECT_FALSE(root_->descendant_needs_push_properties());
4149 EXPECT_FALSE(child_->needs_push_properties());
4150 EXPECT_FALSE(child_->descendant_needs_push_properties());
4151 EXPECT_FALSE(grandchild1_->needs_push_properties());
4152 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4153 EXPECT_FALSE(grandchild2_->needs_push_properties());
4154 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4155 EXPECT_FALSE(grandchild3_->needs_push_properties());
4156 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4158 // Change grandchildren while their parent is not in the tree.
4159 child_->RemoveFromParent();
4160 grandchild1_->SetPosition(gfx::Point(1, 1));
4161 grandchild2_->SetPosition(gfx::Point(1, 1));
4162 root_->AddChild(child_);
4164 EXPECT_FALSE(root_->needs_push_properties());
4165 EXPECT_TRUE(root_->descendant_needs_push_properties());
4166 EXPECT_TRUE(child_->needs_push_properties());
4167 EXPECT_TRUE(child_->descendant_needs_push_properties());
4168 EXPECT_TRUE(grandchild1_->needs_push_properties());
4169 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4170 EXPECT_TRUE(grandchild2_->needs_push_properties());
4171 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4172 EXPECT_TRUE(grandchild3_->needs_push_properties());
4173 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4175 grandchild1_->RemoveFromParent();
4177 EXPECT_FALSE(root_->needs_push_properties());
4178 EXPECT_TRUE(root_->descendant_needs_push_properties());
4179 EXPECT_TRUE(child_->needs_push_properties());
4180 EXPECT_TRUE(child_->descendant_needs_push_properties());
4182 grandchild2_->RemoveFromParent();
4184 EXPECT_FALSE(root_->needs_push_properties());
4185 EXPECT_TRUE(root_->descendant_needs_push_properties());
4186 EXPECT_TRUE(child_->needs_push_properties());
4187 EXPECT_TRUE(child_->descendant_needs_push_properties());
4189 grandchild3_->RemoveFromParent();
4191 EXPECT_FALSE(root_->needs_push_properties());
4192 EXPECT_TRUE(root_->descendant_needs_push_properties());
4193 EXPECT_TRUE(child_->needs_push_properties());
4194 EXPECT_FALSE(child_->descendant_needs_push_properties());
4196 EndTest();
4197 break;
4202 MULTI_THREAD_TEST_F(
4203 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4205 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4206 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4207 protected:
4208 void DidCommitAndDrawFrame() override {
4209 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4210 switch (last_source_frame_number) {
4211 case 0:
4212 layer_tree_host()->SetRootLayer(root_);
4213 break;
4214 case 1:
4215 EXPECT_FALSE(root_->needs_push_properties());
4216 EXPECT_FALSE(root_->descendant_needs_push_properties());
4217 EXPECT_FALSE(child_->needs_push_properties());
4218 EXPECT_FALSE(child_->descendant_needs_push_properties());
4219 EXPECT_FALSE(grandchild1_->needs_push_properties());
4220 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4221 EXPECT_FALSE(grandchild2_->needs_push_properties());
4222 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4223 EXPECT_FALSE(grandchild3_->needs_push_properties());
4224 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4226 child_->SetPosition(gfx::Point(1, 1));
4227 grandchild1_->SetPosition(gfx::Point(1, 1));
4228 grandchild2_->SetPosition(gfx::Point(1, 1));
4230 EXPECT_FALSE(root_->needs_push_properties());
4231 EXPECT_TRUE(root_->descendant_needs_push_properties());
4232 EXPECT_TRUE(child_->needs_push_properties());
4233 EXPECT_TRUE(child_->descendant_needs_push_properties());
4234 EXPECT_TRUE(grandchild1_->needs_push_properties());
4235 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4236 EXPECT_TRUE(grandchild2_->needs_push_properties());
4237 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4238 EXPECT_FALSE(grandchild3_->needs_push_properties());
4239 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4241 grandchild1_->RemoveFromParent();
4243 EXPECT_FALSE(root_->needs_push_properties());
4244 EXPECT_TRUE(root_->descendant_needs_push_properties());
4245 EXPECT_TRUE(child_->needs_push_properties());
4246 EXPECT_TRUE(child_->descendant_needs_push_properties());
4248 grandchild2_->RemoveFromParent();
4250 EXPECT_FALSE(root_->needs_push_properties());
4251 EXPECT_TRUE(root_->descendant_needs_push_properties());
4252 EXPECT_TRUE(child_->needs_push_properties());
4253 EXPECT_FALSE(child_->descendant_needs_push_properties());
4255 child_->RemoveFromParent();
4257 EXPECT_FALSE(root_->needs_push_properties());
4258 EXPECT_FALSE(root_->descendant_needs_push_properties());
4260 EndTest();
4261 break;
4266 MULTI_THREAD_TEST_F(
4267 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4269 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4270 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4271 protected:
4272 void DidCommitAndDrawFrame() override {
4273 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4274 switch (last_source_frame_number) {
4275 case 0:
4276 layer_tree_host()->SetRootLayer(root_);
4277 break;
4278 case 1:
4279 EXPECT_FALSE(root_->needs_push_properties());
4280 EXPECT_FALSE(root_->descendant_needs_push_properties());
4281 EXPECT_FALSE(child_->needs_push_properties());
4282 EXPECT_FALSE(child_->descendant_needs_push_properties());
4283 EXPECT_FALSE(grandchild1_->needs_push_properties());
4284 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4285 EXPECT_FALSE(grandchild2_->needs_push_properties());
4286 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4287 EXPECT_FALSE(grandchild3_->needs_push_properties());
4288 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4290 grandchild1_->SetPosition(gfx::Point(1, 1));
4291 grandchild2_->SetPosition(gfx::Point(1, 1));
4292 child_->SetPosition(gfx::Point(1, 1));
4294 EXPECT_FALSE(root_->needs_push_properties());
4295 EXPECT_TRUE(root_->descendant_needs_push_properties());
4296 EXPECT_TRUE(child_->needs_push_properties());
4297 EXPECT_TRUE(child_->descendant_needs_push_properties());
4298 EXPECT_TRUE(grandchild1_->needs_push_properties());
4299 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4300 EXPECT_TRUE(grandchild2_->needs_push_properties());
4301 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4302 EXPECT_FALSE(grandchild3_->needs_push_properties());
4303 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4305 grandchild1_->RemoveFromParent();
4307 EXPECT_FALSE(root_->needs_push_properties());
4308 EXPECT_TRUE(root_->descendant_needs_push_properties());
4309 EXPECT_TRUE(child_->needs_push_properties());
4310 EXPECT_TRUE(child_->descendant_needs_push_properties());
4312 grandchild2_->RemoveFromParent();
4314 EXPECT_FALSE(root_->needs_push_properties());
4315 EXPECT_TRUE(root_->descendant_needs_push_properties());
4316 EXPECT_TRUE(child_->needs_push_properties());
4317 EXPECT_FALSE(child_->descendant_needs_push_properties());
4319 child_->RemoveFromParent();
4321 EXPECT_FALSE(root_->needs_push_properties());
4322 EXPECT_FALSE(root_->descendant_needs_push_properties());
4324 EndTest();
4325 break;
4330 MULTI_THREAD_TEST_F(
4331 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4333 // This test verifies that the tree activation callback is invoked correctly.
4334 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4335 public:
4336 LayerTreeHostTestTreeActivationCallback()
4337 : num_commits_(0), callback_count_(0) {}
4339 void BeginTest() override {
4340 EXPECT_TRUE(HasImplThread());
4341 PostSetNeedsCommitToMainThread();
4344 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4345 LayerTreeHostImpl::FrameData* frame_data,
4346 DrawResult draw_result) override {
4347 ++num_commits_;
4348 switch (num_commits_) {
4349 case 1:
4350 EXPECT_EQ(0, callback_count_);
4351 callback_count_ = 0;
4352 SetCallback(true);
4353 PostSetNeedsCommitToMainThread();
4354 break;
4355 case 2:
4356 EXPECT_EQ(1, callback_count_);
4357 callback_count_ = 0;
4358 SetCallback(false);
4359 PostSetNeedsCommitToMainThread();
4360 break;
4361 case 3:
4362 EXPECT_EQ(0, callback_count_);
4363 callback_count_ = 0;
4364 EndTest();
4365 break;
4366 default:
4367 ADD_FAILURE() << num_commits_;
4368 EndTest();
4369 break;
4371 return LayerTreeHostTest::PrepareToDrawOnThread(
4372 host_impl, frame_data, draw_result);
4375 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
4377 void SetCallback(bool enable) {
4378 output_surface()->SetTreeActivationCallback(
4379 enable
4380 ? base::Bind(
4381 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4382 base::Unretained(this))
4383 : base::Closure());
4386 void ActivationCallback() { ++callback_count_; }
4388 int num_commits_;
4389 int callback_count_;
4392 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4393 RunTest(true, false, true);
4396 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4397 RunTest(true, true, true);
4400 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4401 public:
4402 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4404 void BeginTest() override {
4405 ASSERT_TRUE(!!invalidate_layer_.get())
4406 << "Derived tests must set this in SetupTree";
4408 // One initial commit.
4409 PostSetNeedsCommitToMainThread();
4412 void DidCommitAndDrawFrame() override {
4413 // After commit, invalidate the layer. This should cause a commit.
4414 if (layer_tree_host()->source_frame_number() == 1)
4415 invalidate_layer_->SetNeedsDisplay();
4418 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4419 num_draws_++;
4420 if (impl->active_tree()->source_frame_number() == 1)
4421 EndTest();
4424 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4425 num_commits_++;
4428 void AfterTest() override {
4429 EXPECT_GE(2, num_commits_);
4430 EXPECT_GE(2, num_draws_);
4433 protected:
4434 scoped_refptr<Layer> invalidate_layer_;
4436 private:
4437 int num_commits_;
4438 int num_draws_;
4441 // VideoLayer must support being invalidated and then passing that along
4442 // to the compositor thread, even though no resources are updated in
4443 // response to that invalidation.
4444 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4445 public:
4446 void SetupTree() override {
4447 LayerTreeHostTest::SetupTree();
4448 scoped_refptr<VideoLayer> video_layer =
4449 VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
4450 video_layer->SetBounds(gfx::Size(10, 10));
4451 video_layer->SetIsDrawable(true);
4452 layer_tree_host()->root_layer()->AddChild(video_layer);
4454 invalidate_layer_ = video_layer;
4457 private:
4458 FakeVideoFrameProvider provider_;
4461 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4463 // IOSurfaceLayer must support being invalidated and then passing that along
4464 // to the compositor thread, even though no resources are updated in
4465 // response to that invalidation.
4466 class LayerTreeHostTestIOSurfaceLayerInvalidate
4467 : public LayerInvalidateCausesDraw {
4468 public:
4469 void SetupTree() override {
4470 LayerTreeHostTest::SetupTree();
4471 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4472 layer->SetBounds(gfx::Size(10, 10));
4473 uint32_t fake_io_surface_id = 7;
4474 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4475 layer->SetIsDrawable(true);
4476 layer_tree_host()->root_layer()->AddChild(layer);
4478 invalidate_layer_ = layer;
4482 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4483 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4484 LayerTreeHostTestIOSurfaceLayerInvalidate);
4486 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4487 protected:
4488 void SetupTree() override {
4489 root_layer_ = Layer::Create();
4490 root_layer_->CreateRenderSurface();
4491 root_layer_->SetPosition(gfx::Point());
4492 root_layer_->SetBounds(gfx::Size(10, 10));
4494 parent_layer_ = SolidColorLayer::Create();
4495 parent_layer_->SetPosition(gfx::Point());
4496 parent_layer_->SetBounds(gfx::Size(10, 10));
4497 parent_layer_->SetIsDrawable(true);
4498 root_layer_->AddChild(parent_layer_);
4500 child_layer_ = SolidColorLayer::Create();
4501 child_layer_->SetPosition(gfx::Point());
4502 child_layer_->SetBounds(gfx::Size(10, 10));
4503 child_layer_->SetIsDrawable(true);
4504 parent_layer_->AddChild(child_layer_);
4506 layer_tree_host()->SetRootLayer(root_layer_);
4507 LayerTreeHostTest::SetupTree();
4510 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4512 void DidCommitAndDrawFrame() override {
4513 switch (layer_tree_host()->source_frame_number()) {
4514 case 1:
4515 // The layer type used does not need to push properties every frame.
4516 EXPECT_FALSE(child_layer_->needs_push_properties());
4518 // Change the bounds of the child layer, but make it skipped
4519 // by CalculateDrawProperties.
4520 parent_layer_->SetOpacity(0.f);
4521 child_layer_->SetBounds(gfx::Size(5, 5));
4522 break;
4523 case 2:
4524 // The bounds of the child layer were pushed to the impl side.
4525 EXPECT_FALSE(child_layer_->needs_push_properties());
4527 EndTest();
4528 break;
4532 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4533 LayerImpl* root = impl->active_tree()->root_layer();
4534 LayerImpl* parent = root->children()[0];
4535 LayerImpl* child = parent->children()[0];
4537 switch (impl->active_tree()->source_frame_number()) {
4538 case 1:
4539 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4540 break;
4544 void AfterTest() override {}
4546 scoped_refptr<Layer> root_layer_;
4547 scoped_refptr<SolidColorLayer> parent_layer_;
4548 scoped_refptr<SolidColorLayer> child_layer_;
4551 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4553 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4554 protected:
4555 void InitializeSettings(LayerTreeSettings* settings) override {
4556 settings->impl_side_painting = true;
4559 void SetupTree() override {
4560 root_layer_ = FakePictureLayer::Create(&client_);
4561 root_layer_->SetBounds(gfx::Size(10, 10));
4563 layer_tree_host()->SetRootLayer(root_layer_);
4564 LayerTreeHostTest::SetupTree();
4567 void BeginTest() override {
4568 // The viewport is empty, but we still need to update layers on the main
4569 // thread.
4570 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4571 PostSetNeedsCommitToMainThread();
4574 void DidCommit() override {
4575 // The layer should be updated even though the viewport is empty, so we
4576 // are capable of drawing it on the impl tree.
4577 EXPECT_GT(root_layer_->update_count(), 0u);
4578 EndTest();
4581 void AfterTest() override {}
4583 FakeContentLayerClient client_;
4584 scoped_refptr<FakePictureLayer> root_layer_;
4587 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4589 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4590 public:
4591 LayerTreeHostTestAbortEvictedTextures()
4592 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4594 protected:
4595 void SetupTree() override {
4596 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4597 root_layer->SetBounds(gfx::Size(200, 200));
4598 root_layer->SetIsDrawable(true);
4599 root_layer->CreateRenderSurface();
4601 layer_tree_host()->SetRootLayer(root_layer);
4602 LayerTreeHostTest::SetupTree();
4605 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4607 void WillBeginMainFrame() override {
4608 num_will_begin_main_frames_++;
4609 switch (num_will_begin_main_frames_) {
4610 case 2:
4611 // Send a redraw to the compositor thread. This will (wrongly) be
4612 // ignored unless aborting resets the texture state.
4613 layer_tree_host()->SetNeedsRedraw();
4614 break;
4618 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
4619 num_impl_commits_++;
4622 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4623 switch (impl->SourceAnimationFrameNumber()) {
4624 case 1:
4625 // Prevent draws until commit.
4626 impl->active_tree()->SetContentsTexturesPurged();
4627 EXPECT_FALSE(impl->CanDraw());
4628 // Trigger an abortable commit.
4629 impl->SetNeedsCommit();
4630 break;
4631 case 2:
4632 EndTest();
4633 break;
4637 void AfterTest() override {
4638 // Ensure that the commit was truly aborted.
4639 EXPECT_EQ(2, num_will_begin_main_frames_);
4640 EXPECT_EQ(1, num_impl_commits_);
4643 private:
4644 int num_will_begin_main_frames_;
4645 int num_impl_commits_;
4648 // Commits can only be aborted when using the thread proxy.
4649 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4651 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4652 protected:
4653 void InitializeSettings(LayerTreeSettings* settings) override {
4654 settings->impl_side_painting = true;
4655 settings->use_zero_copy = false;
4656 settings->use_one_copy = false;
4659 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4660 scoped_refptr<TestContextProvider> context_provider =
4661 TestContextProvider::Create();
4662 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
4663 if (delegating_renderer())
4664 return FakeOutputSurface::CreateDelegating3d(context_provider);
4665 else
4666 return FakeOutputSurface::Create3d(context_provider);
4669 void SetupTree() override {
4670 client_.set_fill_with_nonsolid_color(true);
4671 scoped_refptr<FakePictureLayer> root_layer =
4672 FakePictureLayer::Create(&client_);
4673 root_layer->SetBounds(gfx::Size(1024, 1024));
4674 root_layer->SetIsDrawable(true);
4676 layer_tree_host()->SetRootLayer(root_layer);
4677 LayerTreeHostTest::SetupTree();
4680 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4682 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4683 TestWebGraphicsContext3D* context = TestContext();
4685 // Expect that the transfer buffer memory used is equal to the
4686 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4687 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
4688 EndTest();
4691 void AfterTest() override {}
4693 private:
4694 FakeContentLayerClient client_;
4697 // Impl-side painting is a multi-threaded compositor feature.
4698 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4700 // Test ensuring that memory limits are sent to the prioritized resource
4701 // manager.
4702 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4703 public:
4704 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4706 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4708 void WillCommit() override {
4709 // Some commits are aborted, so increment number of attempted commits here.
4710 num_commits_++;
4713 void DidCommit() override {
4714 switch (num_commits_) {
4715 case 1:
4716 // Verify default values.
4717 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4718 layer_tree_host()
4719 ->contents_texture_manager()
4720 ->MaxMemoryLimitBytes());
4721 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4722 layer_tree_host()
4723 ->contents_texture_manager()
4724 ->ExternalPriorityCutoff());
4725 PostSetNeedsCommitToMainThread();
4726 break;
4727 case 2:
4728 // The values should remain the same until the commit after the policy
4729 // is changed.
4730 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4731 layer_tree_host()
4732 ->contents_texture_manager()
4733 ->MaxMemoryLimitBytes());
4734 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4735 layer_tree_host()
4736 ->contents_texture_manager()
4737 ->ExternalPriorityCutoff());
4738 break;
4739 case 3:
4740 // Verify values were correctly passed.
4741 EXPECT_EQ(16u * 1024u * 1024u,
4742 layer_tree_host()
4743 ->contents_texture_manager()
4744 ->MaxMemoryLimitBytes());
4745 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4746 layer_tree_host()
4747 ->contents_texture_manager()
4748 ->ExternalPriorityCutoff());
4749 EndTest();
4750 break;
4751 case 4:
4752 // Make sure no extra commits happen.
4753 NOTREACHED();
4754 break;
4758 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4759 switch (num_commits_) {
4760 case 1:
4761 break;
4762 case 2:
4763 // This will trigger a commit because the priority cutoff has changed.
4764 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4765 16u * 1024u * 1024u,
4766 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4767 1000));
4768 break;
4769 case 3:
4770 // This will not trigger a commit because the priority cutoff has not
4771 // changed, and there is already enough memory for all allocations.
4772 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4773 32u * 1024u * 1024u,
4774 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4775 1000));
4776 break;
4777 case 4:
4778 NOTREACHED();
4779 break;
4783 void AfterTest() override {}
4785 private:
4786 int num_commits_;
4789 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4791 } // namespace
4793 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4794 : public LayerTreeHostTest {
4795 protected:
4796 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4797 : first_output_surface_memory_limit_(4321234),
4798 second_output_surface_memory_limit_(1234321) {}
4800 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4801 if (!first_context_provider_.get()) {
4802 first_context_provider_ = TestContextProvider::Create();
4803 } else {
4804 EXPECT_FALSE(second_context_provider_.get());
4805 second_context_provider_ = TestContextProvider::Create();
4808 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4809 ? second_context_provider_
4810 : first_context_provider_);
4811 scoped_ptr<FakeOutputSurface> output_surface;
4812 if (delegating_renderer())
4813 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4814 else
4815 output_surface = FakeOutputSurface::Create3d(provider);
4816 output_surface->SetMemoryPolicyToSetAtBind(
4817 make_scoped_ptr(new ManagedMemoryPolicy(
4818 second_context_provider_.get() ? second_output_surface_memory_limit_
4819 : first_output_surface_memory_limit_,
4820 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4821 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4822 return output_surface.Pass();
4825 void SetupTree() override {
4826 if (layer_tree_host()->settings().impl_side_painting)
4827 root_ = FakePictureLayer::Create(&client_);
4828 else
4829 root_ = FakeContentLayer::Create(&client_);
4830 root_->SetBounds(gfx::Size(20, 20));
4831 layer_tree_host()->SetRootLayer(root_);
4832 LayerTreeHostTest::SetupTree();
4835 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4837 void DidCommitAndDrawFrame() override {
4838 // Lost context sometimes takes two frames to recreate. The third frame
4839 // is sometimes aborted, so wait until the fourth frame to verify that
4840 // the memory has been set, and the fifth frame to end the test.
4841 if (layer_tree_host()->source_frame_number() < 5) {
4842 layer_tree_host()->SetNeedsCommit();
4843 } else if (layer_tree_host()->source_frame_number() == 5) {
4844 EndTest();
4848 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
4849 switch (impl->active_tree()->source_frame_number()) {
4850 case 1:
4851 EXPECT_EQ(first_output_surface_memory_limit_,
4852 impl->memory_allocation_limit_bytes());
4853 // Lose the output surface.
4854 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4855 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4856 break;
4857 case 4:
4858 EXPECT_EQ(second_output_surface_memory_limit_,
4859 impl->memory_allocation_limit_bytes());
4860 break;
4864 void AfterTest() override {}
4866 scoped_refptr<TestContextProvider> first_context_provider_;
4867 scoped_refptr<TestContextProvider> second_context_provider_;
4868 size_t first_output_surface_memory_limit_;
4869 size_t second_output_surface_memory_limit_;
4870 FakeContentLayerClient client_;
4871 scoped_refptr<Layer> root_;
4874 SINGLE_AND_MULTI_THREAD_TEST_F(
4875 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4877 struct TestSwapPromiseResult {
4878 TestSwapPromiseResult()
4879 : did_swap_called(false),
4880 did_not_swap_called(false),
4881 dtor_called(false),
4882 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4884 bool did_swap_called;
4885 bool did_not_swap_called;
4886 bool dtor_called;
4887 SwapPromise::DidNotSwapReason reason;
4888 base::Lock lock;
4891 class TestSwapPromise : public SwapPromise {
4892 public:
4893 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4895 ~TestSwapPromise() override {
4896 base::AutoLock lock(result_->lock);
4897 result_->dtor_called = true;
4900 void DidSwap(CompositorFrameMetadata* metadata) override {
4901 base::AutoLock lock(result_->lock);
4902 EXPECT_FALSE(result_->did_swap_called);
4903 EXPECT_FALSE(result_->did_not_swap_called);
4904 result_->did_swap_called = true;
4907 void DidNotSwap(DidNotSwapReason reason) override {
4908 base::AutoLock lock(result_->lock);
4909 EXPECT_FALSE(result_->did_swap_called);
4910 EXPECT_FALSE(result_->did_not_swap_called);
4911 result_->did_not_swap_called = true;
4912 result_->reason = reason;
4915 int64 TraceId() const override { return 0; }
4917 private:
4918 // Not owned.
4919 TestSwapPromiseResult* result_;
4922 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4923 protected:
4924 LayerTreeHostTestBreakSwapPromise()
4925 : commit_count_(0), commit_complete_count_(0) {}
4927 void WillBeginMainFrame() override {
4928 ASSERT_LE(commit_count_, 2);
4929 scoped_ptr<SwapPromise> swap_promise(
4930 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4931 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4934 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4936 void DidCommit() override {
4937 commit_count_++;
4938 if (commit_count_ == 2) {
4939 // This commit will finish.
4940 layer_tree_host()->SetNeedsCommit();
4944 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4945 commit_complete_count_++;
4946 if (commit_complete_count_ == 1) {
4947 // This commit will be aborted because no actual update.
4948 PostSetNeedsUpdateLayersToMainThread();
4949 } else {
4950 EndTest();
4954 void AfterTest() override {
4955 // 3 commits are scheduled. 2 completes. 1 is aborted.
4956 EXPECT_EQ(commit_count_, 3);
4957 EXPECT_EQ(commit_complete_count_, 2);
4960 // The first commit completes and causes swap buffer which finishes
4961 // the promise.
4962 base::AutoLock lock(swap_promise_result_[0].lock);
4963 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4964 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4965 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4969 // The second commit is aborted since it contains no updates.
4970 base::AutoLock lock(swap_promise_result_[1].lock);
4971 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4972 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4973 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
4974 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4978 // The last commit completes but it does not cause swap buffer because
4979 // there is no damage in the frame data.
4980 base::AutoLock lock(swap_promise_result_[2].lock);
4981 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4982 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4983 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4984 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4988 int commit_count_;
4989 int commit_complete_count_;
4990 TestSwapPromiseResult swap_promise_result_[3];
4993 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4995 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
4996 public:
4997 LayerTreeHostTestKeepSwapPromise() {}
4999 void BeginTest() override {
5000 layer_ = SolidColorLayer::Create();
5001 layer_->SetIsDrawable(true);
5002 layer_->SetBounds(gfx::Size(10, 10));
5003 layer_tree_host()->SetRootLayer(layer_);
5004 gfx::Size bounds(100, 100);
5005 layer_tree_host()->SetViewportSize(bounds);
5006 PostSetNeedsCommitToMainThread();
5009 void DidCommit() override {
5010 MainThreadTaskRunner()->PostTask(
5011 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
5012 base::Unretained(this)));
5015 void ChangeFrame() {
5016 switch (layer_tree_host()->source_frame_number()) {
5017 case 1:
5018 layer_->SetBounds(gfx::Size(10, 11));
5019 layer_tree_host()->QueueSwapPromise(
5020 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
5021 break;
5022 case 2:
5023 break;
5024 default:
5025 NOTREACHED();
5026 break;
5030 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
5031 EXPECT_TRUE(result);
5032 if (host_impl->active_tree()->source_frame_number() >= 1) {
5033 // The commit changes layers so it should cause a swap.
5034 base::AutoLock lock(swap_promise_result_.lock);
5035 EXPECT_TRUE(swap_promise_result_.did_swap_called);
5036 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5037 EXPECT_TRUE(swap_promise_result_.dtor_called);
5038 EndTest();
5042 void AfterTest() override {}
5044 private:
5045 scoped_refptr<Layer> layer_;
5046 TestSwapPromiseResult swap_promise_result_;
5049 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
5051 class LayerTreeHostTestBreakSwapPromiseForVisibility
5052 : public LayerTreeHostTest {
5053 protected:
5054 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5056 void SetVisibleFalseAndQueueSwapPromise() {
5057 layer_tree_host()->SetVisible(false);
5058 scoped_ptr<SwapPromise> swap_promise(
5059 new TestSwapPromise(&swap_promise_result_));
5060 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5063 void ScheduledActionWillSendBeginMainFrame() override {
5064 MainThreadTaskRunner()->PostTask(
5065 FROM_HERE,
5066 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility
5067 ::SetVisibleFalseAndQueueSwapPromise,
5068 base::Unretained(this)));
5071 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5072 CommitEarlyOutReason reason) override {
5073 EndTest();
5076 void AfterTest() override {
5078 base::AutoLock lock(swap_promise_result_.lock);
5079 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5080 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5081 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5082 EXPECT_TRUE(swap_promise_result_.dtor_called);
5086 TestSwapPromiseResult swap_promise_result_;
5089 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
5091 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest {
5092 protected:
5093 LayerTreeHostTestBreakSwapPromiseForContext()
5094 : output_surface_lost_triggered_(false) {
5097 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5099 void LoseOutputSurfaceAndQueueSwapPromise() {
5100 layer_tree_host()->DidLoseOutputSurface();
5101 scoped_ptr<SwapPromise> swap_promise(
5102 new TestSwapPromise(&swap_promise_result_));
5103 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5106 void ScheduledActionWillSendBeginMainFrame() override {
5107 if (output_surface_lost_triggered_)
5108 return;
5109 output_surface_lost_triggered_ = true;
5111 MainThreadTaskRunner()->PostTask(
5112 FROM_HERE,
5113 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext
5114 ::LoseOutputSurfaceAndQueueSwapPromise,
5115 base::Unretained(this)));
5118 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5119 CommitEarlyOutReason reason) override {
5120 // This is needed so that the impl-thread state matches main-thread state.
5121 host_impl->DidLoseOutputSurface();
5122 EndTest();
5125 void AfterTest() override {
5127 base::AutoLock lock(swap_promise_result_.lock);
5128 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5129 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5130 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5131 EXPECT_TRUE(swap_promise_result_.dtor_called);
5135 bool output_surface_lost_triggered_;
5136 TestSwapPromiseResult swap_promise_result_;
5139 SINGLE_AND_MULTI_THREAD_TEST_F(
5140 LayerTreeHostTestBreakSwapPromiseForContext);
5142 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
5143 public:
5144 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
5145 LayerTreeHostImpl* layer_tree_host_impl,
5146 int* set_needs_commit_count,
5147 int* set_needs_redraw_count)
5148 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
5149 set_needs_commit_count_(set_needs_commit_count) {}
5151 ~SimpleSwapPromiseMonitor() override {}
5153 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
5155 void OnSetNeedsRedrawOnImpl() override {
5156 ADD_FAILURE() << "Should not get called on main thread.";
5159 void OnForwardScrollUpdateToMainThreadOnImpl() override {
5160 ADD_FAILURE() << "Should not get called on main thread.";
5163 private:
5164 int* set_needs_commit_count_;
5167 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
5168 public:
5169 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5171 void WillBeginMainFrame() override {
5172 if (TestEnded())
5173 return;
5175 int set_needs_commit_count = 0;
5176 int set_needs_redraw_count = 0;
5179 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5180 new SimpleSwapPromiseMonitor(layer_tree_host(),
5181 NULL,
5182 &set_needs_commit_count,
5183 &set_needs_redraw_count));
5184 layer_tree_host()->SetNeedsCommit();
5185 EXPECT_EQ(1, set_needs_commit_count);
5186 EXPECT_EQ(0, set_needs_redraw_count);
5189 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
5190 // monitored.
5191 layer_tree_host()->SetNeedsCommit();
5192 EXPECT_EQ(1, set_needs_commit_count);
5193 EXPECT_EQ(0, set_needs_redraw_count);
5196 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5197 new SimpleSwapPromiseMonitor(layer_tree_host(),
5198 NULL,
5199 &set_needs_commit_count,
5200 &set_needs_redraw_count));
5201 layer_tree_host()->SetNeedsUpdateLayers();
5202 EXPECT_EQ(2, set_needs_commit_count);
5203 EXPECT_EQ(0, set_needs_redraw_count);
5207 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5208 new SimpleSwapPromiseMonitor(layer_tree_host(),
5209 NULL,
5210 &set_needs_commit_count,
5211 &set_needs_redraw_count));
5212 layer_tree_host()->SetNeedsAnimate();
5213 EXPECT_EQ(3, set_needs_commit_count);
5214 EXPECT_EQ(0, set_needs_redraw_count);
5217 EndTest();
5220 void AfterTest() override {}
5223 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
5225 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
5226 : public LayerTreeHostTest {
5227 protected:
5228 void InitializeSettings(LayerTreeSettings* settings) override {
5229 settings->impl_side_painting = true;
5232 void SetupTree() override {
5233 LayerTreeHostTest::SetupTree();
5234 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
5237 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5239 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5240 host_impl->EvictAllUIResources();
5241 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
5242 // mode. Active tree should require high-res to draw after entering this
5243 // mode to ensure that high-res tiles are also required for a pending tree
5244 // to be activated.
5245 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5248 void DidCommit() override {
5249 int frame = layer_tree_host()->source_frame_number();
5250 switch (frame) {
5251 case 1:
5252 PostSetNeedsCommitToMainThread();
5253 break;
5254 case 2:
5255 ui_resource_ = nullptr;
5256 EndTest();
5257 break;
5261 void AfterTest() override {}
5263 FakeContentLayerClient client_;
5264 scoped_ptr<FakeScopedUIResource> ui_resource_;
5267 // This test is flaky, see http://crbug.com/386199
5268 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
5270 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
5271 protected:
5272 void InitializeSettings(LayerTreeSettings* settings) override {
5273 settings->impl_side_painting = true;
5275 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5276 EXPECT_FALSE(settings->gpu_rasterization_forced);
5279 void SetupTree() override {
5280 LayerTreeHostTest::SetupTree();
5282 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5283 layer->SetBounds(gfx::Size(10, 10));
5284 layer->SetIsDrawable(true);
5285 layer_tree_host()->root_layer()->AddChild(layer);
5288 void BeginTest() override {
5289 Layer* root = layer_tree_host()->root_layer();
5290 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5291 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5293 // Verify default values.
5294 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5295 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5296 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5297 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5298 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5300 // Setting gpu rasterization trigger does not enable gpu rasterization.
5301 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5302 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5303 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5305 PostSetNeedsCommitToMainThread();
5308 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5309 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5310 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5313 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5314 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5315 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5316 EndTest();
5319 void AfterTest() override {}
5321 FakeContentLayerClient layer_client_;
5324 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
5326 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
5327 protected:
5328 void InitializeSettings(LayerTreeSettings* settings) override {
5329 settings->impl_side_painting = true;
5331 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5332 settings->gpu_rasterization_enabled = true;
5335 void SetupTree() override {
5336 LayerTreeHostTest::SetupTree();
5338 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5339 layer->SetBounds(gfx::Size(10, 10));
5340 layer->SetIsDrawable(true);
5341 layer_tree_host()->root_layer()->AddChild(layer);
5344 void BeginTest() override {
5345 Layer* root = layer_tree_host()->root_layer();
5346 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5347 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5349 // Verify default values.
5350 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5351 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5352 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5353 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5354 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5356 // Gpu rasterization trigger is relevant.
5357 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5358 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5359 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5361 // Content-based veto is relevant as well.
5362 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5363 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5364 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5365 // Veto will take effect when layers are updated.
5366 // The results will be verified after commit is completed below.
5367 // Since we are manually marking picture pile as unsuitable,
5368 // make sure that the layer gets a chance to update.
5369 layer->SetNeedsDisplay();
5370 PostSetNeedsCommitToMainThread();
5373 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5374 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5375 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5378 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5379 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5380 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5381 EndTest();
5384 void AfterTest() override {}
5386 FakeContentLayerClient layer_client_;
5389 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
5391 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
5392 protected:
5393 void InitializeSettings(LayerTreeSettings* settings) override {
5394 ASSERT_TRUE(settings->impl_side_painting);
5396 EXPECT_FALSE(settings->gpu_rasterization_forced);
5397 settings->gpu_rasterization_forced = true;
5400 void SetupTree() override {
5401 LayerTreeHostTest::SetupTree();
5403 scoped_refptr<FakePictureLayer> layer =
5404 FakePictureLayer::Create(&layer_client_);
5405 layer->SetBounds(gfx::Size(10, 10));
5406 layer->SetIsDrawable(true);
5407 layer_tree_host()->root_layer()->AddChild(layer);
5410 void BeginTest() override {
5411 Layer* root = layer_tree_host()->root_layer();
5412 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5413 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5415 // Verify default values.
5416 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5417 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5418 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5419 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5421 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
5422 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5423 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5424 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5425 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5427 // Content-based veto is irrelevant as well.
5428 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5429 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5430 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5431 // Veto will take effect when layers are updated.
5432 // The results will be verified after commit is completed below.
5433 // Since we are manually marking picture pile as unsuitable,
5434 // make sure that the layer gets a chance to update.
5435 layer->SetNeedsDisplay();
5436 PostSetNeedsCommitToMainThread();
5439 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5440 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
5441 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5444 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5445 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
5446 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5447 EndTest();
5450 void AfterTest() override {}
5452 FakeContentLayerClient layer_client_;
5455 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
5457 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
5458 public:
5459 LayerTreeHostTestContinuousPainting()
5460 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
5462 protected:
5463 enum { kExpectedNumCommits = 10 };
5465 void SetupTree() override {
5466 scoped_refptr<Layer> root_layer = Layer::Create();
5467 root_layer->SetBounds(bounds_);
5468 root_layer->CreateRenderSurface();
5470 if (layer_tree_host()->settings().impl_side_painting) {
5471 picture_layer_ = FakePictureLayer::Create(&client_);
5472 child_layer_ = picture_layer_.get();
5473 } else {
5474 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
5475 child_layer_ = content_layer_.get();
5477 child_layer_->SetBounds(bounds_);
5478 child_layer_->SetIsDrawable(true);
5479 root_layer->AddChild(child_layer_);
5481 layer_tree_host()->SetRootLayer(root_layer);
5482 layer_tree_host()->SetViewportSize(bounds_);
5483 LayerTreeHostTest::SetupTree();
5486 void BeginTest() override {
5487 MainThreadTaskRunner()->PostTask(
5488 FROM_HERE,
5489 base::Bind(
5490 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
5491 base::Unretained(this)));
5492 // Wait 50x longer than expected.
5493 double milliseconds_per_frame =
5494 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
5495 MainThreadTaskRunner()->PostDelayedTask(
5496 FROM_HERE,
5497 base::Bind(
5498 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
5499 base::Unretained(this)),
5500 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
5501 milliseconds_per_frame));
5504 void BeginMainFrame(const BeginFrameArgs& args) override {
5505 child_layer_->SetNeedsDisplay();
5508 void AfterTest() override {
5509 EXPECT_LE(kExpectedNumCommits, num_commits_);
5510 EXPECT_LE(kExpectedNumCommits, num_draws_);
5511 int update_count = content_layer_.get()
5512 ? content_layer_->PaintContentsCount()
5513 : picture_layer_->update_count();
5514 EXPECT_LE(kExpectedNumCommits, update_count);
5517 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5518 if (++num_draws_ == kExpectedNumCommits)
5519 EndTest();
5522 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5523 ++num_commits_;
5526 private:
5527 void EnableContinuousPainting() {
5528 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5529 debug_state.continuous_painting = true;
5530 layer_tree_host()->SetDebugState(debug_state);
5533 void DisableContinuousPainting() {
5534 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5535 debug_state.continuous_painting = false;
5536 layer_tree_host()->SetDebugState(debug_state);
5537 EndTest();
5540 int num_commits_;
5541 int num_draws_;
5542 const gfx::Size bounds_;
5543 FakeContentLayerClient client_;
5544 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5545 scoped_refptr<FakePictureLayer> picture_layer_;
5546 Layer* child_layer_;
5549 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5551 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
5552 public:
5553 LayerTreeHostTestSendBeginFramesToChildren()
5554 : begin_frame_sent_to_children_(false) {
5557 void BeginTest() override {
5558 // Kick off the test with a commit.
5559 PostSetNeedsCommitToMainThread();
5562 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5563 begin_frame_sent_to_children_ = true;
5564 EndTest();
5567 void DidBeginMainFrame() override {
5568 // Children requested BeginFrames.
5569 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5572 void AfterTest() override {
5573 // Ensure that BeginFrame message is sent to children during parent
5574 // scheduler handles its BeginFrame.
5575 EXPECT_TRUE(begin_frame_sent_to_children_);
5578 private:
5579 bool begin_frame_sent_to_children_;
5582 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
5584 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
5585 : public LayerTreeHostTest {
5586 public:
5587 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
5588 : begin_frame_sent_to_children_(false) {
5591 void InitializeSettings(LayerTreeSettings* settings) override {
5592 settings->use_external_begin_frame_source = true;
5595 void BeginTest() override {
5596 // Kick off the test with a commit.
5597 PostSetNeedsCommitToMainThread();
5600 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5601 begin_frame_sent_to_children_ = true;
5602 EndTest();
5605 void DidBeginMainFrame() override {
5606 // Children requested BeginFrames.
5607 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5610 void AfterTest() override {
5611 // Ensure that BeginFrame message is sent to children during parent
5612 // scheduler handles its BeginFrame.
5613 EXPECT_TRUE(begin_frame_sent_to_children_);
5616 private:
5617 bool begin_frame_sent_to_children_;
5620 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
5622 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5623 public:
5624 LayerTreeHostTestActivateOnInvisible()
5625 : activation_count_(0), visible_(true) {}
5627 void InitializeSettings(LayerTreeSettings* settings) override {
5628 settings->impl_side_painting = true;
5631 void BeginTest() override {
5632 // Kick off the test with a commit.
5633 PostSetNeedsCommitToMainThread();
5636 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5637 // Make sure we don't activate using the notify signal from tile manager.
5638 host_impl->BlockNotifyReadyToActivateForTesting(true);
5641 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5643 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5644 bool visible) override {
5645 visible_ = visible;
5647 // Once invisible, we can go visible again.
5648 if (!visible) {
5649 PostSetVisibleToMainThread(true);
5650 } else {
5651 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5652 EndTest();
5656 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5657 ++activation_count_;
5658 EXPECT_FALSE(visible_);
5661 void AfterTest() override {
5662 // Ensure we activated even though the signal was blocked.
5663 EXPECT_EQ(1, activation_count_);
5664 EXPECT_TRUE(visible_);
5667 private:
5668 int activation_count_;
5669 bool visible_;
5671 FakeContentLayerClient client_;
5672 scoped_refptr<FakePictureLayer> picture_layer_;
5675 // TODO(vmpstr): Enable with single thread impl-side painting.
5676 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5678 // Do a synchronous composite and assert that the swap promise succeeds.
5679 class LayerTreeHostTestSynchronousCompositeSwapPromise
5680 : public LayerTreeHostTest {
5681 public:
5682 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5684 void InitializeSettings(LayerTreeSettings* settings) override {
5685 settings->single_thread_proxy_scheduler = false;
5688 void BeginTest() override {
5689 // Successful composite.
5690 scoped_ptr<SwapPromise> swap_promise0(
5691 new TestSwapPromise(&swap_promise_result_[0]));
5692 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5693 layer_tree_host()->Composite(gfx::FrameTime::Now());
5695 // Fail to swap (no damage).
5696 scoped_ptr<SwapPromise> swap_promise1(
5697 new TestSwapPromise(&swap_promise_result_[1]));
5698 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5699 layer_tree_host()->SetNeedsCommit();
5700 layer_tree_host()->Composite(gfx::FrameTime::Now());
5702 // Fail to draw (not visible).
5703 scoped_ptr<SwapPromise> swap_promise2(
5704 new TestSwapPromise(&swap_promise_result_[2]));
5705 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5706 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5707 layer_tree_host()->SetVisible(false);
5708 layer_tree_host()->Composite(gfx::FrameTime::Now());
5710 EndTest();
5713 void DidCommit() override {
5714 commit_count_++;
5715 ASSERT_LE(commit_count_, 3);
5718 void AfterTest() override {
5719 EXPECT_EQ(3, commit_count_);
5721 // Initial swap promise should have succeded.
5723 base::AutoLock lock(swap_promise_result_[0].lock);
5724 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5725 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5726 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5729 // Second swap promise fails to swap.
5731 base::AutoLock lock(swap_promise_result_[1].lock);
5732 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5733 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5734 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5735 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5738 // Third swap promises also fails to swap (and draw).
5740 base::AutoLock lock(swap_promise_result_[2].lock);
5741 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5742 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5743 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5744 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5748 int commit_count_;
5749 TestSwapPromiseResult swap_promise_result_[3];
5752 // Impl-side painting is not supported for synchronous compositing.
5753 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
5755 // Make sure page scale and top control deltas are applied to the client even
5756 // when the LayerTreeHost doesn't have a root layer.
5757 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
5758 : public LayerTreeHostTest {
5759 public:
5760 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
5761 : deltas_sent_to_client_(false) {}
5763 void BeginTest() override {
5764 layer_tree_host()->SetRootLayer(nullptr);
5765 info_.page_scale_delta = 3.14f;
5766 info_.top_controls_delta = 2.73f;
5768 PostSetNeedsCommitToMainThread();
5771 void BeginMainFrame(const BeginFrameArgs& args) override {
5772 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
5774 layer_tree_host()->ApplyScrollAndScale(&info_);
5775 EndTest();
5778 void ApplyViewportDeltas(const gfx::Vector2dF& inner,
5779 const gfx::Vector2dF& outer,
5780 const gfx::Vector2dF& elastic_overscroll_delta,
5781 float scale_delta,
5782 float top_controls_delta) override {
5783 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5784 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5785 deltas_sent_to_client_ = true;
5788 void ApplyViewportDeltas(
5789 const gfx::Vector2d& scroll,
5790 float scale_delta,
5791 float top_controls_delta) override {
5792 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5793 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5794 deltas_sent_to_client_ = true;
5797 void AfterTest() override {
5798 EXPECT_TRUE(deltas_sent_to_client_);
5801 ScrollAndScaleSet info_;
5802 bool deltas_sent_to_client_;
5805 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5807 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
5808 protected:
5809 LayerTreeHostTestCrispUpAfterPinchEnds()
5810 : playback_allowed_event_(true, true) {}
5812 void SetupTree() override {
5813 frame_ = 1;
5814 posted_ = false;
5815 client_.set_fill_with_nonsolid_color(true);
5817 scoped_refptr<Layer> root = Layer::Create();
5818 root->SetBounds(gfx::Size(500, 500));
5820 scoped_refptr<Layer> pinch = Layer::Create();
5821 pinch->SetBounds(gfx::Size(500, 500));
5822 pinch->SetScrollClipLayerId(root->id());
5823 pinch->SetIsContainerForFixedPositionLayers(true);
5824 root->AddChild(pinch);
5826 scoped_ptr<FakePicturePile> pile(
5827 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5828 ImplSidePaintingSettings().default_tile_grid_size));
5829 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5830 scoped_refptr<FakePictureLayer> layer =
5831 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5832 layer->SetBounds(gfx::Size(500, 500));
5833 layer->SetContentsOpaque(true);
5834 // Avoid LCD text on the layer so we don't cause extra commits when we
5835 // pinch.
5836 layer->disable_lcd_text();
5837 pinch->AddChild(layer);
5839 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5840 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5841 layer_tree_host()->SetRootLayer(root);
5842 LayerTreeHostTest::SetupTree();
5845 // Returns the delta scale of all quads in the frame's root pass from their
5846 // ideal, or 0 if they are not all the same.
5847 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5848 if (frame_data->has_no_damage)
5849 return 0.f;
5850 float frame_scale = 0.f;
5851 RenderPass* root_pass = frame_data->render_passes.back();
5852 for (const auto& draw_quad : root_pass->quad_list) {
5853 // Checkerboards mean an incomplete frame.
5854 if (draw_quad->material != DrawQuad::TILED_CONTENT)
5855 return 0.f;
5856 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5857 float quad_scale =
5858 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5859 float transform_scale =
5860 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5861 float scale = quad_scale / transform_scale;
5862 if (frame_scale != 0.f && frame_scale != scale)
5863 return 0.f;
5864 frame_scale = scale;
5866 return frame_scale;
5869 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5871 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5872 LayerTreeHostImpl::FrameData* frame_data,
5873 DrawResult draw_result) override {
5874 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5875 switch (frame_) {
5876 case 1:
5877 // Drew at page scale 1 before any pinching.
5878 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5879 EXPECT_EQ(1.f, quad_scale_delta);
5880 PostNextAfterDraw(host_impl);
5881 break;
5882 case 2:
5883 if (quad_scale_delta != 1.f)
5884 break;
5885 // Drew at page scale 1.5 after pinching in.
5886 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5887 EXPECT_EQ(1.f, quad_scale_delta);
5888 PostNextAfterDraw(host_impl);
5889 break;
5890 case 3:
5891 // By pinching out, we will create a new tiling and raster it. This may
5892 // cause some additional draws, though we should still be drawing with
5893 // the old 1.5 tiling.
5894 if (frame_data->has_no_damage)
5895 break;
5896 // Drew at page scale 1 with the 1.5 tiling while pinching out.
5897 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5898 EXPECT_EQ(1.5f, quad_scale_delta);
5899 // We don't PostNextAfterDraw here, instead we wait for the new tiling
5900 // to finish rastering so we don't get any noise in further steps.
5901 break;
5902 case 4:
5903 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
5904 // while waiting for texture uploads to complete.
5905 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5906 // This frame will not have any damage, since it's actually the same as
5907 // the last frame, and should contain no incomplete tiles. We just want
5908 // to make sure we drew here at least once after the pinch ended to be
5909 // sure that drawing after pinch doesn't leave us at the wrong scale
5910 EXPECT_TRUE(frame_data->has_no_damage);
5911 PostNextAfterDraw(host_impl);
5912 break;
5913 case 5:
5914 if (quad_scale_delta != 1.f)
5915 break;
5916 // Drew at scale 1 after texture uploads are done.
5917 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5918 EXPECT_EQ(1.f, quad_scale_delta);
5919 EndTest();
5920 break;
5922 return draw_result;
5925 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
5926 if (posted_)
5927 return;
5928 posted_ = true;
5929 ImplThreadTaskRunner()->PostDelayedTask(
5930 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
5931 base::Unretained(this), host_impl),
5932 // Use a delay to allow raster/upload to happen in between frames. This
5933 // should cause flakiness if we fail to block raster/upload when
5934 // desired.
5935 base::TimeDelta::FromMilliseconds(16 * 4));
5938 void Next(LayerTreeHostImpl* host_impl) {
5939 ++frame_;
5940 posted_ = false;
5941 switch (frame_) {
5942 case 2:
5943 // Pinch zoom in.
5944 host_impl->PinchGestureBegin();
5945 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
5946 host_impl->PinchGestureEnd();
5947 break;
5948 case 3:
5949 // Pinch zoom back to 1.f but don't end it.
5950 host_impl->PinchGestureBegin();
5951 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
5952 break;
5953 case 4:
5954 // End the pinch, but delay tile production.
5955 playback_allowed_event_.Reset();
5956 host_impl->PinchGestureEnd();
5957 break;
5958 case 5:
5959 // Let tiles complete.
5960 playback_allowed_event_.Signal();
5961 break;
5965 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5966 const Tile* tile) override {
5967 if (frame_ == 3) {
5968 // On frame 3, we will have a lower res tile complete for the pinch-out
5969 // gesture even though it's not displayed. We wait for it here to prevent
5970 // flakiness.
5971 EXPECT_EQ(0.75f, tile->contents_scale());
5972 PostNextAfterDraw(host_impl);
5974 // On frame_ == 4, we are preventing texture uploads from completing,
5975 // so this verifies they are not completing before frame_ == 5.
5976 // Flaky failures here indicate we're failing to prevent uploads from
5977 // completing.
5978 EXPECT_NE(4, frame_) << tile->contents_scale();
5981 void AfterTest() override {}
5983 FakeContentLayerClient client_;
5984 int frame_;
5985 bool posted_;
5986 base::WaitableEvent playback_allowed_event_;
5989 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
5991 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
5992 : public LayerTreeHostTestCrispUpAfterPinchEnds {
5993 protected:
5994 void InitializeSettings(LayerTreeSettings* settings) override {
5995 settings->use_one_copy = true;
5998 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
5999 scoped_ptr<TestWebGraphicsContext3D> context3d =
6000 TestWebGraphicsContext3D::Create();
6001 context3d->set_support_image(true);
6002 context3d->set_support_sync_query(true);
6003 #if defined(OS_MACOSX)
6004 context3d->set_support_texture_rectangle(true);
6005 #endif
6007 if (delegating_renderer())
6008 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
6009 else
6010 return FakeOutputSurface::Create3d(context3d.Pass());
6014 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
6016 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
6017 protected:
6018 RasterizeWithGpuRasterizationCreatesResources() {}
6020 void InitializeSettings(LayerTreeSettings* settings) override {
6021 settings->impl_side_painting = true;
6022 settings->gpu_rasterization_forced = true;
6025 void SetupTree() override {
6026 client_.set_fill_with_nonsolid_color(true);
6028 scoped_refptr<Layer> root = Layer::Create();
6029 root->SetBounds(gfx::Size(500, 500));
6031 scoped_ptr<FakePicturePile> pile(
6032 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6033 ImplSidePaintingSettings().default_tile_grid_size));
6034 scoped_refptr<FakePictureLayer> layer =
6035 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6036 layer->SetBounds(gfx::Size(500, 500));
6037 layer->SetContentsOpaque(true);
6038 root->AddChild(layer);
6040 layer_tree_host()->SetRootLayer(root);
6041 LayerTreeHostTest::SetupTree();
6044 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6046 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6047 LayerTreeHostImpl::FrameData* frame_data,
6048 DrawResult draw_result) override {
6049 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
6050 EndTest();
6051 return draw_result;
6053 void AfterTest() override {}
6055 FakeContentLayerClient client_;
6058 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
6060 class SynchronousGpuRasterizationRasterizesVisibleOnly
6061 : public LayerTreeHostTest {
6062 protected:
6063 SynchronousGpuRasterizationRasterizesVisibleOnly()
6064 : viewport_size_(1024, 2048) {}
6066 void InitializeSettings(LayerTreeSettings* settings) override {
6067 settings->impl_side_painting = true;
6068 settings->gpu_rasterization_enabled = true;
6069 settings->gpu_rasterization_forced = true;
6070 settings->threaded_gpu_rasterization_enabled = false;
6073 void SetupTree() override {
6074 client_.set_fill_with_nonsolid_color(true);
6076 scoped_ptr<FakePicturePile> pile(
6077 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6078 ImplSidePaintingSettings().default_tile_grid_size));
6079 scoped_refptr<FakePictureLayer> root =
6080 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6081 root->SetBounds(gfx::Size(viewport_size_.width(), 10000));
6082 root->SetContentsOpaque(true);
6084 layer_tree_host()->SetRootLayer(root);
6085 LayerTreeHostTest::SetupTree();
6086 layer_tree_host()->SetViewportSize(viewport_size_);
6089 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6091 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6092 LayerTreeHostImpl::FrameData* frame_data,
6093 DrawResult draw_result) override {
6094 EXPECT_EQ(4u, host_impl->resource_provider()->num_resources());
6096 // Verify which tiles got resources using an eviction iterator, which has to
6097 // return all tiles that have resources.
6098 scoped_ptr<EvictionTilePriorityQueue> eviction_queue(
6099 host_impl->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES));
6100 int tile_count = 0;
6101 for (; !eviction_queue->IsEmpty(); eviction_queue->Pop()) {
6102 Tile* tile = eviction_queue->Top();
6103 // Ensure this tile is within the viewport.
6104 EXPECT_TRUE(tile->content_rect().Intersects(gfx::Rect(viewport_size_)));
6105 // Ensure that the tile is 1/4 of the viewport tall (plus padding).
6106 EXPECT_EQ(tile->content_rect().height(),
6107 (viewport_size_.height() / 4) + 2);
6108 ++tile_count;
6110 EXPECT_EQ(4, tile_count);
6111 EndTest();
6112 return draw_result;
6115 void AfterTest() override {}
6117 private:
6118 FakeContentLayerClient client_;
6119 gfx::Size viewport_size_;
6122 MULTI_THREAD_IMPL_TEST_F(SynchronousGpuRasterizationRasterizesVisibleOnly);
6124 class ThreadedGpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
6125 protected:
6126 ThreadedGpuRasterizationRasterizesBorderTiles()
6127 : viewport_size_(1024, 2048) {}
6129 void InitializeSettings(LayerTreeSettings* settings) override {
6130 settings->impl_side_painting = true;
6131 settings->gpu_rasterization_enabled = true;
6132 settings->gpu_rasterization_forced = true;
6133 settings->threaded_gpu_rasterization_enabled = true;
6136 void SetupTree() override {
6137 client_.set_fill_with_nonsolid_color(true);
6139 scoped_ptr<FakePicturePile> pile(
6140 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6141 ImplSidePaintingSettings().default_tile_grid_size));
6142 scoped_refptr<FakePictureLayer> root =
6143 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6144 root->SetBounds(gfx::Size(10000, 10000));
6145 root->SetContentsOpaque(true);
6147 layer_tree_host()->SetRootLayer(root);
6148 LayerTreeHostTest::SetupTree();
6149 layer_tree_host()->SetViewportSize(viewport_size_);
6152 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6154 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6155 LayerTreeHostImpl::FrameData* frame_data,
6156 DrawResult draw_result) override {
6157 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources());
6158 EndTest();
6159 return draw_result;
6162 void AfterTest() override {}
6164 private:
6165 FakeContentLayerClient client_;
6166 gfx::Size viewport_size_;
6169 MULTI_THREAD_IMPL_TEST_F(ThreadedGpuRasterizationRasterizesBorderTiles);
6171 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
6172 : public LayerTreeHostTest {
6173 protected:
6174 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
6175 : playback_allowed_event_(true, true) {}
6177 void InitializeSettings(LayerTreeSettings* settings) override {
6178 settings->impl_side_painting = true;
6181 void SetupTree() override {
6182 step_ = 1;
6183 continuous_draws_ = 0;
6184 client_.set_fill_with_nonsolid_color(true);
6186 scoped_refptr<Layer> root = Layer::Create();
6187 root->SetBounds(gfx::Size(500, 500));
6189 scoped_refptr<Layer> pinch = Layer::Create();
6190 pinch->SetBounds(gfx::Size(500, 500));
6191 pinch->SetScrollClipLayerId(root->id());
6192 pinch->SetIsContainerForFixedPositionLayers(true);
6193 root->AddChild(pinch);
6195 scoped_ptr<FakePicturePile> pile(
6196 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6197 ImplSidePaintingSettings().default_tile_grid_size));
6198 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
6199 scoped_refptr<FakePictureLayer> layer =
6200 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6201 layer->SetBounds(gfx::Size(500, 500));
6202 layer->SetContentsOpaque(true);
6203 // Avoid LCD text on the layer so we don't cause extra commits when we
6204 // pinch.
6205 layer->disable_lcd_text();
6206 pinch->AddChild(layer);
6208 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
6209 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6210 layer_tree_host()->SetRootLayer(root);
6211 LayerTreeHostTest::SetupTree();
6214 // Returns the delta scale of all quads in the frame's root pass from their
6215 // ideal, or 0 if they are not all the same.
6216 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6217 if (frame_data->has_no_damage)
6218 return 0.f;
6219 float frame_scale = 0.f;
6220 RenderPass* root_pass = frame_data->render_passes.back();
6221 for (const auto& draw_quad : root_pass->quad_list) {
6222 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
6223 float quad_scale =
6224 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6225 float transform_scale =
6226 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
6227 float scale = quad_scale / transform_scale;
6228 if (frame_scale != 0.f && frame_scale != scale)
6229 return 0.f;
6230 frame_scale = scale;
6232 return frame_scale;
6235 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6237 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6238 LayerTreeHostImpl::FrameData* frame_data,
6239 DrawResult draw_result) override {
6240 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6241 switch (step_) {
6242 case 1:
6243 // Drew at scale 1 before any pinching.
6244 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6245 EXPECT_EQ(1.f, quad_scale_delta);
6246 break;
6247 case 2:
6248 if (quad_scale_delta != 1.f / 1.5f)
6249 break;
6250 // Drew at scale 1 still though the ideal is 1.5.
6251 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6252 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6253 break;
6254 case 3:
6255 // Continuous draws are attempted.
6256 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6257 if (!frame_data->has_no_damage)
6258 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6259 break;
6260 case 4:
6261 if (quad_scale_delta != 1.f)
6262 break;
6263 // Drew at scale 1.5 when all the tiles completed.
6264 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6265 EXPECT_EQ(1.f, quad_scale_delta);
6266 break;
6267 case 5:
6268 // TODO(danakj): We get more draws before the NotifyReadyToDraw
6269 // because it is asynchronous from the previous draw and happens late.
6270 break;
6271 case 6:
6272 // NotifyReadyToDraw happened. If we were already inside a frame, we may
6273 // try to draw once more.
6274 break;
6275 case 7:
6276 NOTREACHED() << "No draws should happen once we have a complete frame.";
6277 break;
6279 return draw_result;
6282 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6283 switch (step_) {
6284 case 1:
6285 // Delay tile production.
6286 playback_allowed_event_.Reset();
6287 // Pinch zoom in to cause new tiles to be required.
6288 host_impl->PinchGestureBegin();
6289 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6290 host_impl->PinchGestureEnd();
6291 ++step_;
6292 break;
6293 case 2:
6294 ++step_;
6295 break;
6296 case 3:
6297 // We should continue to try draw while there are incomplete visible
6298 // tiles.
6299 if (++continuous_draws_ > 5) {
6300 // Allow the tiles to complete.
6301 playback_allowed_event_.Signal();
6302 ++step_;
6304 break;
6305 case 4:
6306 ++step_;
6307 break;
6308 case 5:
6309 // Waiting for NotifyReadyToDraw.
6310 break;
6311 case 6:
6312 // NotifyReadyToDraw happened.
6313 ++step_;
6314 break;
6318 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
6319 if (step_ == 5) {
6320 ++step_;
6321 // NotifyReadyToDraw has happened, we may draw once more, but should not
6322 // get any more draws after that. End the test after a timeout to watch
6323 // for any extraneous draws.
6324 // TODO(brianderson): We could remove this delay and instead wait until
6325 // the BeginFrameSource decides it doesn't need to send frames anymore,
6326 // or test that it already doesn't here.
6327 EndTestAfterDelayMs(16 * 4);
6331 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6332 const Tile* tile) override {
6333 // On step_ == 2, we are preventing texture uploads from completing,
6334 // so this verifies they are not completing before step_ == 3.
6335 // Flaky failures here indicate we're failing to prevent uploads from
6336 // completing.
6337 EXPECT_NE(2, step_);
6340 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
6342 FakeContentLayerClient client_;
6343 int step_;
6344 int continuous_draws_;
6345 base::WaitableEvent playback_allowed_event_;
6348 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
6350 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
6351 public:
6352 LayerTreeHostTestOneActivatePerPrepareTiles()
6353 : notify_ready_to_activate_count_(0u),
6354 scheduled_prepare_tiles_count_(0) {}
6356 void SetupTree() override {
6357 client_.set_fill_with_nonsolid_color(true);
6358 scoped_refptr<FakePictureLayer> root_layer =
6359 FakePictureLayer::Create(&client_);
6360 root_layer->SetBounds(gfx::Size(1500, 1500));
6361 root_layer->SetIsDrawable(true);
6363 layer_tree_host()->SetRootLayer(root_layer);
6364 LayerTreeHostTest::SetupTree();
6367 void BeginTest() override {
6368 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
6369 PostSetNeedsCommitToMainThread();
6372 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
6373 bool success) override {
6374 ASSERT_TRUE(success);
6375 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
6378 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6379 ++notify_ready_to_activate_count_;
6380 EndTestAfterDelayMs(100);
6383 void ScheduledActionPrepareTiles() override {
6384 ++scheduled_prepare_tiles_count_;
6387 void AfterTest() override {
6388 // Expect at most a notification for each scheduled prepare tiles, plus one
6389 // for the initial commit (which doesn't go through scheduled actions).
6390 // The reason this is not an equality is because depending on timing, we
6391 // might get a prepare tiles but not yet get a notification that we're
6392 // ready to activate. The intent of a test is to ensure that we don't
6393 // get more than one notification per prepare tiles, so this is OK.
6394 EXPECT_LE(notify_ready_to_activate_count_,
6395 1u + scheduled_prepare_tiles_count_);
6398 protected:
6399 FakeContentLayerClient client_;
6400 size_t notify_ready_to_activate_count_;
6401 size_t scheduled_prepare_tiles_count_;
6404 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
6406 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
6407 : public LayerTreeHostTest {
6408 public:
6409 LayerTreeHostTestFrameTimingRequestsSaveTimestamps()
6410 : check_results_on_commit_(false) {}
6412 void SetupTree() override {
6413 scoped_refptr<FakePictureLayer> root_layer =
6414 FakePictureLayer::Create(&client_);
6415 root_layer->SetBounds(gfx::Size(200, 200));
6416 root_layer->SetIsDrawable(true);
6418 scoped_refptr<FakePictureLayer> child_layer =
6419 FakePictureLayer::Create(&client_);
6420 child_layer->SetBounds(gfx::Size(1500, 1500));
6421 child_layer->SetIsDrawable(true);
6423 std::vector<FrameTimingRequest> requests;
6424 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100)));
6425 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100)));
6426 child_layer->SetFrameTimingRequests(requests);
6428 root_layer->AddChild(child_layer);
6429 layer_tree_host()->SetRootLayer(root_layer);
6430 LayerTreeHostTest::SetupTree();
6433 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6435 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
6436 if (!check_results_on_commit_)
6437 return;
6439 // Since in reality, the events will be read by LayerTreeHost during commit,
6440 // we check the requests here to ensure that they are correct at the next
6441 // commit time (as opposed to checking in DrawLayers for instance).
6442 // TODO(vmpstr): Change this to read things from the main thread when this
6443 // information is propagated to the main thread (not yet implemented).
6444 FrameTimingTracker* tracker = host_impl->frame_timing_tracker();
6445 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set =
6446 tracker->GroupCountsByRectId();
6447 EXPECT_EQ(1u, timing_set->size());
6448 auto rect_1_it = timing_set->find(1);
6449 EXPECT_TRUE(rect_1_it != timing_set->end());
6450 const auto& timing_events = rect_1_it->second;
6451 EXPECT_EQ(1u, timing_events.size());
6452 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6453 timing_events[0].frame_id);
6454 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6456 EndTest();
6459 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6460 check_results_on_commit_ = true;
6461 PostSetNeedsCommitToMainThread();
6464 void AfterTest() override {}
6466 private:
6467 FakeContentLayerClient client_;
6468 bool check_results_on_commit_;
6471 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
6473 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
6474 public:
6475 LayerTreeHostTestActivationCausesPrepareTiles()
6476 : scheduled_prepare_tiles_count_(0) {}
6478 void SetupTree() override {
6479 client_.set_fill_with_nonsolid_color(true);
6480 scoped_refptr<FakePictureLayer> root_layer =
6481 FakePictureLayer::Create(&client_);
6482 root_layer->SetBounds(gfx::Size(150, 150));
6483 root_layer->SetIsDrawable(true);
6485 layer_tree_host()->SetRootLayer(root_layer);
6486 LayerTreeHostTest::SetupTree();
6489 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6491 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6492 // Ensure we've already activated.
6493 EXPECT_FALSE(impl->pending_tree());
6495 // After activating, we either need to prepare tiles, or we've already
6496 // called a scheduled prepare tiles. This is done because activation might
6497 // cause us to have to memory available (old active tree is gone), so we
6498 // need to ensure we will get a PrepareTiles call.
6499 if (!impl->prepare_tiles_needed())
6500 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
6501 EndTest();
6504 void ScheduledActionPrepareTiles() override {
6505 ++scheduled_prepare_tiles_count_;
6508 void AfterTest() override {}
6510 protected:
6511 FakeContentLayerClient client_;
6512 int scheduled_prepare_tiles_count_;
6515 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
6517 // This tests an assertion that DidCommit and WillCommit happen in the same
6518 // stack frame with no tasks that run between them. Various embedders of
6519 // cc depend on this logic. ui::Compositor holds a compositor lock between
6520 // these events and the inspector timeline wants begin/end CompositeLayers
6521 // to be properly nested with other begin/end events.
6522 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
6523 : public LayerTreeHostTest {
6524 public:
6525 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
6527 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6529 void WillCommit() override {
6530 MainThreadTaskRunner()->PostTask(
6531 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
6532 EndTestShouldRunAfterDidCommit,
6533 base::Unretained(this)));
6536 void EndTestShouldRunAfterDidCommit() {
6537 EXPECT_TRUE(did_commit_);
6538 EndTest();
6541 void DidCommit() override {
6542 EXPECT_FALSE(did_commit_);
6543 did_commit_ = true;
6546 void AfterTest() override { EXPECT_TRUE(did_commit_); }
6548 private:
6549 bool did_commit_;
6552 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
6554 // Verify that if a LayerImpl holds onto a copy request for multiple
6555 // frames that it will continue to have a render surface through
6556 // multiple commits, even though the Layer itself has no reason
6557 // to have a render surface.
6558 class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest {
6559 protected:
6560 void SetupTree() override {
6561 scoped_refptr<Layer> root = Layer::Create();
6562 root->CreateRenderSurface();
6563 root->SetBounds(gfx::Size(10, 10));
6564 child_ = Layer::Create();
6565 child_->SetBounds(gfx::Size(20, 20));
6566 root->AddChild(child_);
6568 layer_tree_host()->SetRootLayer(root);
6569 LayerTreeHostTest::SetupTree();
6572 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6574 void BeginTest() override {
6575 child_->RequestCopyOfOutput(
6576 CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback)));
6577 EXPECT_TRUE(child_->HasCopyRequest());
6578 PostSetNeedsCommitToMainThread();
6581 void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); }
6583 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6584 LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id());
6586 switch (host_impl->sync_tree()->source_frame_number()) {
6587 case 0:
6588 EXPECT_TRUE(child_impl->HasCopyRequest());
6589 EXPECT_TRUE(child_impl->render_surface());
6590 break;
6591 case 1:
6592 if (host_impl->proxy()->CommitToActiveTree()) {
6593 EXPECT_TRUE(child_impl->HasCopyRequest());
6594 EXPECT_TRUE(child_impl->render_surface());
6595 } else {
6596 EXPECT_FALSE(child_impl->HasCopyRequest());
6597 EXPECT_FALSE(child_impl->render_surface());
6599 break;
6600 default:
6601 NOTREACHED();
6602 break;
6606 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6607 LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id());
6608 EXPECT_TRUE(child_impl->HasCopyRequest());
6609 EXPECT_TRUE(child_impl->render_surface());
6611 switch (host_impl->active_tree()->source_frame_number()) {
6612 case 0:
6613 // Lose output surface to prevent drawing and cause another commit.
6614 host_impl->DidLoseOutputSurface();
6615 break;
6616 case 1:
6617 EndTest();
6618 break;
6619 default:
6620 NOTREACHED();
6621 break;
6625 void AfterTest() override {}
6627 private:
6628 scoped_refptr<Layer> child_;
6631 SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests);
6633 } // namespace cc