Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob53de1496d8c4b749a8fc4a0ee13e7a29058ac74c
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include <algorithm>
9 #include "base/auto_reset.h"
10 #include "base/location.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/synchronization/lock.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "cc/animation/timing_function.h"
15 #include "cc/debug/frame_rate_counter.h"
16 #include "cc/layers/content_layer.h"
17 #include "cc/layers/content_layer_client.h"
18 #include "cc/layers/io_surface_layer.h"
19 #include "cc/layers/layer_impl.h"
20 #include "cc/layers/painted_scrollbar_layer.h"
21 #include "cc/layers/picture_layer.h"
22 #include "cc/layers/solid_color_layer.h"
23 #include "cc/layers/video_layer.h"
24 #include "cc/output/begin_frame_args.h"
25 #include "cc/output/compositor_frame_ack.h"
26 #include "cc/output/copy_output_request.h"
27 #include "cc/output/copy_output_result.h"
28 #include "cc/output/output_surface.h"
29 #include "cc/output/swap_promise.h"
30 #include "cc/quads/draw_quad.h"
31 #include "cc/quads/io_surface_draw_quad.h"
32 #include "cc/quads/render_pass_draw_quad.h"
33 #include "cc/quads/tile_draw_quad.h"
34 #include "cc/resources/prioritized_resource.h"
35 #include "cc/resources/prioritized_resource_manager.h"
36 #include "cc/resources/resource_update_queue.h"
37 #include "cc/test/fake_content_layer.h"
38 #include "cc/test/fake_content_layer_client.h"
39 #include "cc/test/fake_content_layer_impl.h"
40 #include "cc/test/fake_layer_tree_host_client.h"
41 #include "cc/test/fake_output_surface.h"
42 #include "cc/test/fake_painted_scrollbar_layer.h"
43 #include "cc/test/fake_picture_layer.h"
44 #include "cc/test/fake_picture_layer_impl.h"
45 #include "cc/test/fake_picture_pile.h"
46 #include "cc/test/fake_proxy.h"
47 #include "cc/test/fake_scoped_ui_resource.h"
48 #include "cc/test/fake_video_frame_provider.h"
49 #include "cc/test/geometry_test_utils.h"
50 #include "cc/test/impl_side_painting_settings.h"
51 #include "cc/test/layer_tree_test.h"
52 #include "cc/test/test_shared_bitmap_manager.h"
53 #include "cc/test/test_web_graphics_context_3d.h"
54 #include "cc/trees/layer_tree_host_impl.h"
55 #include "cc/trees/layer_tree_impl.h"
56 #include "cc/trees/single_thread_proxy.h"
57 #include "cc/trees/thread_proxy.h"
58 #include "gpu/GLES2/gl2extchromium.h"
59 #include "skia/ext/refptr.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "third_party/khronos/GLES2/gl2.h"
62 #include "third_party/khronos/GLES2/gl2ext.h"
63 #include "third_party/skia/include/core/SkPicture.h"
64 #include "ui/gfx/geometry/point_conversions.h"
65 #include "ui/gfx/geometry/size_conversions.h"
66 #include "ui/gfx/geometry/vector2d_conversions.h"
68 using testing::_;
69 using testing::AnyNumber;
70 using testing::AtLeast;
71 using testing::Mock;
73 namespace cc {
74 namespace {
76 class LayerTreeHostTest : public LayerTreeTest {
77 public:
78 LayerTreeHostTest() : contents_texture_manager_(nullptr) {}
80 void DidInitializeOutputSurface() override {
81 contents_texture_manager_ = layer_tree_host()->contents_texture_manager();
84 protected:
85 PrioritizedResourceManager* contents_texture_manager_;
88 class LayerTreeHostTestHasImplThreadTest : public LayerTreeHostTest {
89 public:
90 LayerTreeHostTestHasImplThreadTest() : threaded_(false) {}
92 void RunTest(bool threaded,
93 bool delegating_renderer,
94 bool impl_side_painting) override {
95 threaded_ = threaded;
96 LayerTreeHostTest::RunTest(threaded, delegating_renderer,
97 impl_side_painting);
100 void BeginTest() override {
101 EXPECT_EQ(threaded_, HasImplThread());
102 EndTest();
105 void AfterTest() override { EXPECT_EQ(threaded_, HasImplThread()); }
107 private:
108 bool threaded_;
111 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestHasImplThreadTest);
113 class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest {
114 protected:
115 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
117 void Layout() override {
118 // This shouldn't cause a second commit to happen.
119 layer_tree_host()->SetNeedsCommit();
122 void DidCommit() override {
123 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
124 EndTest();
127 void AfterTest() override {}
130 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
131 LayerTreeHostTestSetNeedsCommitInsideLayout);
133 class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest {
134 protected:
135 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
137 void Layout() override {
138 // This shouldn't cause a second commit to happen.
139 layer_tree_host()->SetNeedsUpdateLayers();
142 void DidCommit() override {
143 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
144 EndTest();
147 void AfterTest() override {}
150 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
151 LayerTreeHostTestSetNeedsUpdateInsideLayout);
153 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
154 // when no raster tasks get scheduled.
155 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
156 public:
157 LayerTreeHostTestReadyToActivateEmpty()
158 : did_notify_ready_to_activate_(false),
159 all_tiles_required_for_activation_are_ready_to_draw_(false),
160 required_for_activation_count_(0) {}
162 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
164 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
165 const std::vector<PictureLayerImpl*>& layers =
166 impl->sync_tree()->picture_layers();
167 required_for_activation_count_ = 0;
168 for (const auto& layer : layers) {
169 FakePictureLayerImpl* fake_layer =
170 static_cast<FakePictureLayerImpl*>(layer);
171 required_for_activation_count_ +=
172 fake_layer->CountTilesRequiredForActivation();
176 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
177 did_notify_ready_to_activate_ = true;
178 all_tiles_required_for_activation_are_ready_to_draw_ =
179 impl->tile_manager()->IsReadyToActivate();
180 EndTest();
183 void AfterTest() override {
184 EXPECT_TRUE(did_notify_ready_to_activate_);
185 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
186 EXPECT_EQ(size_t(0), required_for_activation_count_);
189 protected:
190 bool did_notify_ready_to_activate_;
191 bool all_tiles_required_for_activation_are_ready_to_draw_;
192 size_t required_for_activation_count_;
195 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
197 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
198 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
199 class LayerTreeHostTestReadyToActivateNonEmpty
200 : public LayerTreeHostTestReadyToActivateEmpty {
201 public:
202 void SetupTree() override {
203 client_.set_fill_with_nonsolid_color(true);
204 scoped_refptr<FakePictureLayer> root_layer =
205 FakePictureLayer::Create(layer_settings(), &client_);
206 root_layer->SetBounds(gfx::Size(1024, 1024));
207 root_layer->SetIsDrawable(true);
209 layer_tree_host()->SetRootLayer(root_layer);
210 LayerTreeHostTest::SetupTree();
213 void AfterTest() override {
214 EXPECT_TRUE(did_notify_ready_to_activate_);
215 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
216 EXPECT_LE(size_t(1), required_for_activation_count_);
219 private:
220 FakeContentLayerClient client_;
223 // Multi-thread only because in single thread the commit goes directly to the
224 // active tree, so notify ready to activate is skipped.
225 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
227 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
228 // no raster tasks get scheduled.
229 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
230 public:
231 LayerTreeHostTestReadyToDrawEmpty()
232 : did_notify_ready_to_draw_(false),
233 all_tiles_required_for_draw_are_ready_to_draw_(false),
234 required_for_draw_count_(0) {}
236 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
238 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
239 did_notify_ready_to_draw_ = true;
240 const std::vector<PictureLayerImpl*>& layers =
241 impl->active_tree()->picture_layers();
242 all_tiles_required_for_draw_are_ready_to_draw_ =
243 impl->tile_manager()->IsReadyToDraw();
244 for (const auto& layer : layers) {
245 FakePictureLayerImpl* fake_layer =
246 static_cast<FakePictureLayerImpl*>(layer);
247 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw();
250 EndTest();
253 void AfterTest() override {
254 EXPECT_TRUE(did_notify_ready_to_draw_);
255 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
256 EXPECT_EQ(size_t(0), required_for_draw_count_);
259 protected:
260 bool did_notify_ready_to_draw_;
261 bool all_tiles_required_for_draw_are_ready_to_draw_;
262 size_t required_for_draw_count_;
265 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
267 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
268 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
269 class LayerTreeHostTestReadyToDrawNonEmpty
270 : public LayerTreeHostTestReadyToDrawEmpty {
271 public:
272 void SetupTree() override {
273 client_.set_fill_with_nonsolid_color(true);
274 scoped_refptr<FakePictureLayer> root_layer =
275 FakePictureLayer::Create(layer_settings(), &client_);
276 root_layer->SetBounds(gfx::Size(1024, 1024));
277 root_layer->SetIsDrawable(true);
279 layer_tree_host()->SetRootLayer(root_layer);
280 LayerTreeHostTest::SetupTree();
283 void AfterTest() override {
284 EXPECT_TRUE(did_notify_ready_to_draw_);
285 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
286 EXPECT_LE(size_t(1), required_for_draw_count_);
289 private:
290 FakeContentLayerClient client_;
293 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
294 // single threaded mode.
295 SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
297 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
298 // draw with frame 0.
299 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
300 public:
301 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
303 void BeginTest() override {
304 PostSetNeedsCommitToMainThread();
305 PostSetNeedsCommitToMainThread();
308 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
309 num_draws_++;
310 if (!impl->active_tree()->source_frame_number())
311 EndTest();
314 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
315 num_commits_++;
318 void AfterTest() override {
319 EXPECT_LE(1, num_commits_);
320 EXPECT_LE(1, num_draws_);
323 private:
324 int num_commits_;
325 int num_draws_;
328 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
330 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
331 // first committed frame draws should lead to another commit.
332 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
333 public:
334 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
336 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
338 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
340 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
341 ++num_commits_;
342 switch (num_commits_) {
343 case 1:
344 PostSetNeedsCommitToMainThread();
345 break;
346 case 2:
347 EndTest();
348 break;
349 default:
350 NOTREACHED();
354 void AfterTest() override {
355 EXPECT_EQ(2, num_commits_);
356 EXPECT_LE(1, num_draws_);
359 private:
360 int num_commits_;
361 int num_draws_;
364 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
366 // Verify that we pass property values in PushPropertiesTo.
367 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
368 protected:
369 void SetupTree() override {
370 scoped_refptr<Layer> root = Layer::Create(layer_settings());
371 root->CreateRenderSurface();
372 root->SetBounds(gfx::Size(10, 10));
373 layer_tree_host()->SetRootLayer(root);
374 LayerTreeHostTest::SetupTree();
377 enum Properties {
378 STARTUP,
379 BOUNDS,
380 HIDE_LAYER_AND_SUBTREE,
381 DRAWS_CONTENT,
382 DONE,
385 void BeginTest() override {
386 index_ = STARTUP;
387 PostSetNeedsCommitToMainThread();
390 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
391 VerifyAfterValues(impl->active_tree()->root_layer());
394 void DidCommitAndDrawFrame() override {
395 SetBeforeValues(layer_tree_host()->root_layer());
396 VerifyBeforeValues(layer_tree_host()->root_layer());
398 ++index_;
399 if (index_ == DONE) {
400 EndTest();
401 return;
404 SetAfterValues(layer_tree_host()->root_layer());
407 void AfterTest() override {}
409 void VerifyBeforeValues(Layer* layer) {
410 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
411 EXPECT_FALSE(layer->hide_layer_and_subtree());
412 EXPECT_FALSE(layer->DrawsContent());
415 void SetBeforeValues(Layer* layer) {
416 layer->SetBounds(gfx::Size(10, 10));
417 layer->SetHideLayerAndSubtree(false);
418 layer->SetIsDrawable(false);
421 void VerifyAfterValues(LayerImpl* layer) {
422 switch (static_cast<Properties>(index_)) {
423 case STARTUP:
424 case DONE:
425 break;
426 case BOUNDS:
427 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
428 break;
429 case HIDE_LAYER_AND_SUBTREE:
430 EXPECT_TRUE(layer->hide_layer_and_subtree());
431 break;
432 case DRAWS_CONTENT:
433 EXPECT_TRUE(layer->DrawsContent());
434 break;
438 void SetAfterValues(Layer* layer) {
439 switch (static_cast<Properties>(index_)) {
440 case STARTUP:
441 case DONE:
442 break;
443 case BOUNDS:
444 layer->SetBounds(gfx::Size(20, 20));
445 break;
446 case HIDE_LAYER_AND_SUBTREE:
447 layer->SetHideLayerAndSubtree(true);
448 break;
449 case DRAWS_CONTENT:
450 layer->SetIsDrawable(true);
451 break;
455 int index_;
458 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
460 // 1 setNeedsRedraw after the first commit has completed should lead to 1
461 // additional draw.
462 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
463 public:
464 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
466 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
468 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
469 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
470 if (!num_draws_) {
471 // Redraw again to verify that the second redraw doesn't commit.
472 PostSetNeedsRedrawToMainThread();
473 } else {
474 EndTest();
476 num_draws_++;
479 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
480 EXPECT_EQ(0, num_draws_);
481 num_commits_++;
484 void AfterTest() override {
485 EXPECT_GE(2, num_draws_);
486 EXPECT_EQ(1, num_commits_);
489 private:
490 int num_commits_;
491 int num_draws_;
494 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
496 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
497 // must contain invalid_rect.
498 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
499 public:
500 LayerTreeHostTestSetNeedsRedrawRect()
501 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
503 void BeginTest() override {
504 if (layer_tree_host()->settings().impl_side_painting)
505 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
506 else
507 root_layer_ = ContentLayer::Create(layer_settings(), &client_);
508 root_layer_->SetIsDrawable(true);
509 root_layer_->SetBounds(bounds_);
510 layer_tree_host()->SetRootLayer(root_layer_);
511 layer_tree_host()->SetViewportSize(bounds_);
512 PostSetNeedsCommitToMainThread();
515 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
516 LayerTreeHostImpl::FrameData* frame_data,
517 DrawResult draw_result) override {
518 EXPECT_EQ(DRAW_SUCCESS, draw_result);
520 gfx::RectF root_damage_rect;
521 if (!frame_data->render_passes.empty())
522 root_damage_rect = frame_data->render_passes.back()->damage_rect;
524 if (!num_draws_) {
525 // If this is the first frame, expect full frame damage.
526 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_));
527 } else {
528 // Check that invalid_rect_ is indeed repainted.
529 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
532 return draw_result;
535 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
536 if (!num_draws_) {
537 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
538 } else {
539 EndTest();
541 num_draws_++;
544 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
546 private:
547 int num_draws_;
548 const gfx::Size bounds_;
549 const gfx::Rect invalid_rect_;
550 FakeContentLayerClient client_;
551 scoped_refptr<Layer> root_layer_;
554 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
556 // Ensure the texture size of the pending and active trees are identical when a
557 // layer is not in the viewport and a resize happens on the viewport
558 class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
559 public:
560 LayerTreeHostTestGpuRasterDeviceSizeChanged()
561 : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {}
563 void BeginTest() override {
564 client_.set_fill_with_nonsolid_color(true);
565 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
566 root_layer_->SetIsDrawable(true);
567 gfx::Transform transform;
568 // Translate the layer out of the viewport to force it to not update its
569 // tile size via PushProperties.
570 transform.Translate(10000.0, 10000.0);
571 root_layer_->SetTransform(transform);
572 root_layer_->SetBounds(bounds_);
573 layer_tree_host()->SetRootLayer(root_layer_);
574 layer_tree_host()->SetViewportSize(bounds_);
576 PostSetNeedsCommitToMainThread();
579 void InitializeSettings(LayerTreeSettings* settings) override {
580 settings->gpu_rasterization_enabled = true;
581 settings->gpu_rasterization_forced = true;
584 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
585 // Perform 2 commits.
586 if (!num_draws_) {
587 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
588 } else {
589 EndTest();
591 num_draws_++;
594 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
595 if (num_draws_ == 2) {
596 auto pending_tree = host_impl->pending_tree();
597 auto pending_layer_impl =
598 static_cast<FakePictureLayerImpl*>(pending_tree->root_layer());
599 EXPECT_NE(pending_layer_impl, nullptr);
601 auto active_tree = host_impl->pending_tree();
602 auto active_layer_impl =
603 static_cast<FakePictureLayerImpl*>(active_tree->root_layer());
604 EXPECT_NE(pending_layer_impl, nullptr);
606 auto active_tiling_set = active_layer_impl->picture_layer_tiling_set();
607 auto active_tiling = active_tiling_set->tiling_at(0);
608 auto pending_tiling_set = pending_layer_impl->picture_layer_tiling_set();
609 auto pending_tiling = pending_tiling_set->tiling_at(0);
610 EXPECT_EQ(
611 pending_tiling->TilingDataForTesting().max_texture_size().width(),
612 active_tiling->TilingDataForTesting().max_texture_size().width());
616 void DidCommitAndDrawFrame() override {
617 // On the second commit, resize the viewport.
618 if (num_draws_ == 1) {
619 layer_tree_host()->SetViewportSize(gfx::Size(400, 64));
623 void AfterTest() override {}
625 private:
626 int num_draws_;
627 const gfx::Size bounds_;
628 const gfx::Rect invalid_rect_;
629 FakeContentLayerClient client_;
630 scoped_refptr<FakePictureLayer> root_layer_;
633 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
634 LayerTreeHostTestGpuRasterDeviceSizeChanged);
636 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
637 public:
638 void InitializeSettings(LayerTreeSettings* settings) override {
639 settings->layer_transforms_should_scale_layer_contents = true;
642 void SetupTree() override {
643 root_layer_ = Layer::Create(layer_settings());
644 root_layer_->SetBounds(gfx::Size(10, 20));
645 root_layer_->CreateRenderSurface();
647 if (layer_tree_host()->settings().impl_side_painting)
648 scaled_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
649 else
650 scaled_layer_ = FakeContentLayer::Create(layer_settings(), &client_);
651 scaled_layer_->SetBounds(gfx::Size(1, 1));
652 root_layer_->AddChild(scaled_layer_);
654 layer_tree_host()->SetRootLayer(root_layer_);
655 LayerTreeHostTest::SetupTree();
658 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
660 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
661 if (host_impl->active_tree()->source_frame_number() == 1)
662 EndTest();
665 void DidCommit() override {
666 switch (layer_tree_host()->source_frame_number()) {
667 case 1:
668 // SetBounds grows the layer and exposes new content.
669 scaled_layer_->SetBounds(gfx::Size(4, 4));
670 break;
671 default:
672 // No extra commits.
673 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
677 void AfterTest() override {
678 EXPECT_EQ(gfx::Size(4, 4).ToString(), scaled_layer_->bounds().ToString());
681 private:
682 FakeContentLayerClient client_;
683 scoped_refptr<Layer> root_layer_;
684 scoped_refptr<Layer> scaled_layer_;
687 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
689 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
690 : public LayerTreeHostTest {
691 public:
692 void InitializeSettings(LayerTreeSettings* settings) override {
693 settings->layer_transforms_should_scale_layer_contents = true;
696 void SetupTree() override {
697 root_layer_ = Layer::Create(layer_settings());
698 root_layer_->SetBounds(gfx::Size(10, 20));
699 root_layer_->CreateRenderSurface();
701 bool paint_scrollbar = true;
702 bool has_thumb = false;
703 scrollbar_ = FakePaintedScrollbarLayer::Create(
704 layer_settings(), paint_scrollbar, has_thumb, root_layer_->id());
705 scrollbar_->SetPosition(gfx::Point(0, 10));
706 scrollbar_->SetBounds(gfx::Size(10, 10));
708 root_layer_->AddChild(scrollbar_);
710 layer_tree_host()->SetRootLayer(root_layer_);
711 LayerTreeHostTest::SetupTree();
714 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
716 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
717 if (host_impl->active_tree()->source_frame_number() == 1)
718 EndTest();
721 void DidCommit() override {
722 switch (layer_tree_host()->source_frame_number()) {
723 case 1:
724 // Changing the device scale factor causes a commit. It also changes
725 // the content bounds of |scrollbar_|, which should not generate
726 // a second commit as a result.
727 layer_tree_host()->SetDeviceScaleFactor(4.f);
728 break;
729 default:
730 // No extra commits.
731 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
732 break;
736 void AfterTest() override {
739 private:
740 FakeContentLayerClient client_;
741 scoped_refptr<Layer> root_layer_;
742 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
745 SINGLE_AND_MULTI_THREAD_TEST_F(
746 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
748 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
749 public:
750 LayerTreeHostTestSetNextCommitForcesRedraw()
751 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
753 void BeginTest() override {
754 if (layer_tree_host()->settings().impl_side_painting)
755 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
756 else
757 root_layer_ = ContentLayer::Create(layer_settings(), &client_);
758 root_layer_->SetIsDrawable(true);
759 root_layer_->SetBounds(bounds_);
760 layer_tree_host()->SetRootLayer(root_layer_);
761 layer_tree_host()->SetViewportSize(bounds_);
762 PostSetNeedsCommitToMainThread();
765 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
766 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
767 host_impl->SetNeedsRedrawRect(invalid_rect_);
770 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
771 LayerTreeHostImpl::FrameData* frame_data,
772 DrawResult draw_result) override {
773 EXPECT_EQ(DRAW_SUCCESS, draw_result);
775 gfx::RectF root_damage_rect;
776 if (!frame_data->render_passes.empty())
777 root_damage_rect = frame_data->render_passes.back()->damage_rect;
779 switch (num_draws_) {
780 case 0:
781 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
782 break;
783 case 1:
784 case 2:
785 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
786 break;
787 case 3:
788 EXPECT_EQ(invalid_rect_, root_damage_rect);
789 break;
790 case 4:
791 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
792 break;
793 default:
794 NOTREACHED();
797 return draw_result;
800 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
801 switch (num_draws_) {
802 case 0:
803 case 1:
804 // Cycle through a couple of empty commits to ensure we're observing the
805 // right behavior
806 PostSetNeedsCommitToMainThread();
807 break;
808 case 2:
809 // Should force full frame damage on the next commit
810 PostSetNextCommitForcesRedrawToMainThread();
811 PostSetNeedsCommitToMainThread();
812 if (host_impl->settings().impl_side_painting)
813 host_impl->BlockNotifyReadyToActivateForTesting(true);
814 else
815 num_draws_++;
816 break;
817 case 3:
818 host_impl->BlockNotifyReadyToActivateForTesting(false);
819 break;
820 default:
821 EndTest();
822 break;
824 num_draws_++;
827 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
829 private:
830 int num_draws_;
831 const gfx::Size bounds_;
832 const gfx::Rect invalid_rect_;
833 FakeContentLayerClient client_;
834 scoped_refptr<Layer> root_layer_;
837 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
838 LayerTreeHostTestSetNextCommitForcesRedraw);
840 // Tests that if a layer is not drawn because of some reason in the parent then
841 // its damage is preserved until the next time it is drawn.
842 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
843 public:
844 LayerTreeHostTestUndrawnLayersDamageLater() {}
846 void InitializeSettings(LayerTreeSettings* settings) override {
847 // If we don't set the minimum contents scale, it's harder to verify whether
848 // the damage we get is correct. For other scale amounts, please see
849 // LayerTreeHostTestDamageWithScale.
850 settings->minimum_contents_scale = 1.f;
853 void SetupTree() override {
854 if (layer_tree_host()->settings().impl_side_painting)
855 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
856 else
857 root_layer_ = ContentLayer::Create(layer_settings(), &client_);
858 root_layer_->SetIsDrawable(true);
859 root_layer_->SetBounds(gfx::Size(50, 50));
860 layer_tree_host()->SetRootLayer(root_layer_);
862 // The initially transparent layer has a larger child layer, which is
863 // not initially drawn because of the this (parent) layer.
864 if (layer_tree_host()->settings().impl_side_painting)
865 parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
866 else
867 parent_layer_ = FakeContentLayer::Create(layer_settings(), &client_);
868 parent_layer_->SetBounds(gfx::Size(15, 15));
869 parent_layer_->SetOpacity(0.0f);
870 root_layer_->AddChild(parent_layer_);
872 if (layer_tree_host()->settings().impl_side_painting)
873 child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
874 else
875 child_layer_ = FakeContentLayer::Create(layer_settings(), &client_);
876 child_layer_->SetBounds(gfx::Size(25, 25));
877 parent_layer_->AddChild(child_layer_);
879 LayerTreeHostTest::SetupTree();
882 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
884 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
885 LayerTreeHostImpl::FrameData* frame_data,
886 DrawResult draw_result) override {
887 EXPECT_EQ(DRAW_SUCCESS, draw_result);
889 gfx::RectF root_damage_rect;
890 if (!frame_data->render_passes.empty())
891 root_damage_rect = frame_data->render_passes.back()->damage_rect;
893 // The first time, the whole view needs be drawn.
894 // Afterwards, just the opacity of surface_layer1 is changed a few times,
895 // and each damage should be the bounding box of it and its child. If this
896 // was working improperly, the damage might not include its childs bounding
897 // box.
898 switch (host_impl->active_tree()->source_frame_number()) {
899 case 0:
900 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
901 break;
902 case 1:
903 case 2:
904 case 3:
905 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
906 break;
907 default:
908 NOTREACHED();
911 return draw_result;
914 void DidCommitAndDrawFrame() override {
915 switch (layer_tree_host()->source_frame_number()) {
916 case 1:
917 // Test not owning the surface.
918 parent_layer_->SetOpacity(1.0f);
919 break;
920 case 2:
921 parent_layer_->SetOpacity(0.0f);
922 break;
923 case 3:
924 // Test owning the surface.
925 parent_layer_->SetOpacity(0.5f);
926 parent_layer_->SetForceRenderSurface(true);
927 break;
928 case 4:
929 EndTest();
930 break;
931 default:
932 NOTREACHED();
936 void AfterTest() override {}
938 private:
939 FakeContentLayerClient client_;
940 scoped_refptr<Layer> root_layer_;
941 scoped_refptr<Layer> parent_layer_;
942 scoped_refptr<Layer> child_layer_;
945 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
947 // Tests that if a layer is not drawn because of some reason in the parent then
948 // its damage is preserved until the next time it is drawn.
949 class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest {
950 public:
951 LayerTreeHostTestDamageWithScale() {}
953 void SetupTree() override {
954 client_.set_fill_with_nonsolid_color(true);
956 scoped_ptr<FakePicturePile> pile(
957 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
958 ImplSidePaintingSettings().default_tile_grid_size));
959 root_layer_ = FakePictureLayer::CreateWithRecordingSource(
960 layer_settings(), &client_, pile.Pass());
961 root_layer_->SetBounds(gfx::Size(50, 50));
963 pile.reset(
964 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
965 ImplSidePaintingSettings().default_tile_grid_size));
966 child_layer_ = FakePictureLayer::CreateWithRecordingSource(
967 layer_settings(), &client_, pile.Pass());
968 child_layer_->SetBounds(gfx::Size(25, 25));
969 child_layer_->SetIsDrawable(true);
970 child_layer_->SetContentsOpaque(true);
971 root_layer_->AddChild(child_layer_);
973 layer_tree_host()->SetRootLayer(root_layer_);
974 LayerTreeHostTest::SetupTree();
977 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
978 // Force the layer to have a tiling at 1.3f scale. Note that if we simply
979 // add tiling, it will be gone by the time we draw because of aggressive
980 // cleanup. AddTilingUntilNextDraw ensures that it remains there during
981 // damage calculation.
982 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
983 host_impl->active_tree()->LayerById(child_layer_->id()));
984 child_layer_impl->AddTilingUntilNextDraw(1.3f);
987 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
989 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
990 LayerTreeHostImpl::FrameData* frame_data,
991 DrawResult draw_result) override {
992 EXPECT_EQ(DRAW_SUCCESS, draw_result);
994 gfx::RectF root_damage_rect;
995 if (!frame_data->render_passes.empty())
996 root_damage_rect = frame_data->render_passes.back()->damage_rect;
998 // The first time, the whole view needs be drawn.
999 // Afterwards, just the opacity of surface_layer1 is changed a few times,
1000 // and each damage should be the bounding box of it and its child. If this
1001 // was working improperly, the damage might not include its childs bounding
1002 // box.
1003 switch (host_impl->active_tree()->source_frame_number()) {
1004 case 0:
1005 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
1006 break;
1007 case 1: {
1008 FakePictureLayerImpl* child_layer_impl =
1009 static_cast<FakePictureLayerImpl*>(
1010 host_impl->active_tree()->LayerById(child_layer_->id()));
1011 // We remove tilings pretty aggressively if they are not ideal. Add this
1012 // back in so that we can compare
1013 // child_layer_impl->GetEnclosingRectInTargetSpace to the damage.
1014 child_layer_impl->AddTilingUntilNextDraw(1.3f);
1016 EXPECT_EQ(gfx::Rect(26, 26), root_damage_rect);
1017 EXPECT_EQ(child_layer_impl->GetEnclosingRectInTargetSpace(),
1018 root_damage_rect);
1019 EXPECT_TRUE(child_layer_impl->GetEnclosingRectInTargetSpace().Contains(
1020 gfx::Rect(child_layer_->bounds())));
1021 break;
1023 default:
1024 NOTREACHED();
1027 return draw_result;
1030 void DidCommitAndDrawFrame() override {
1031 switch (layer_tree_host()->source_frame_number()) {
1032 case 1: {
1033 // Test not owning the surface.
1034 child_layer_->SetOpacity(0.5f);
1035 break;
1037 case 2:
1038 EndTest();
1039 break;
1040 default:
1041 NOTREACHED();
1045 void AfterTest() override {}
1047 private:
1048 FakeContentLayerClient client_;
1049 scoped_refptr<Layer> root_layer_;
1050 scoped_refptr<Layer> child_layer_;
1053 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestDamageWithScale);
1055 // Tests that if a layer is not drawn because of some reason in the parent,
1056 // causing its content bounds to not be computed, then when it is later drawn,
1057 // its content bounds get pushed.
1058 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
1059 : public LayerTreeHostTest {
1060 public:
1061 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
1062 : root_layer_(Layer::Create(layer_settings())) {}
1064 void SetupTree() override {
1065 root_layer_->CreateRenderSurface();
1066 root_layer_->SetIsDrawable(true);
1067 root_layer_->SetBounds(gfx::Size(20, 20));
1068 layer_tree_host()->SetRootLayer(root_layer_);
1070 parent_layer_ = Layer::Create(layer_settings());
1071 parent_layer_->SetBounds(gfx::Size(20, 20));
1072 parent_layer_->SetOpacity(0.0f);
1073 root_layer_->AddChild(parent_layer_);
1075 child_layer_ = Layer::Create(layer_settings());
1076 child_layer_->SetBounds(gfx::Size(15, 15));
1077 parent_layer_->AddChild(child_layer_);
1079 LayerTreeHostTest::SetupTree();
1082 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1084 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1085 LayerImpl* root = host_impl->active_tree()->root_layer();
1086 LayerImpl* parent = root->children()[0];
1087 LayerImpl* child = parent->children()[0];
1089 switch (host_impl->active_tree()->source_frame_number()) {
1090 case 0:
1091 EXPECT_EQ(0.f, parent->opacity());
1092 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
1093 break;
1094 case 1:
1095 EXPECT_EQ(1.f, parent->opacity());
1096 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
1097 EndTest();
1098 break;
1099 default:
1100 NOTREACHED();
1104 void DidCommit() override {
1105 switch (layer_tree_host()->source_frame_number()) {
1106 case 1:
1107 parent_layer_->SetOpacity(1.0f);
1108 break;
1109 case 2:
1110 break;
1111 default:
1112 NOTREACHED();
1116 void AfterTest() override {}
1118 private:
1119 scoped_refptr<Layer> root_layer_;
1120 scoped_refptr<Layer> parent_layer_;
1121 scoped_refptr<Layer> child_layer_;
1124 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
1125 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
1127 // This test verifies that properties on the layer tree host are commited
1128 // to the impl side.
1129 class LayerTreeHostTestCommit : public LayerTreeHostTest {
1130 public:
1131 LayerTreeHostTestCommit() {}
1133 void BeginTest() override {
1134 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1135 layer_tree_host()->set_background_color(SK_ColorGRAY);
1137 PostSetNeedsCommitToMainThread();
1140 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1141 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
1142 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
1144 EndTest();
1147 void AfterTest() override {}
1150 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
1152 // This test verifies that LayerTreeHostImpl's current frame time gets
1153 // updated in consecutive frames when it doesn't draw due to tree
1154 // activation failure.
1155 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
1156 : public LayerTreeHostTest {
1157 public:
1158 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
1159 : frame_count_with_pending_tree_(0) {}
1161 void BeginTest() override {
1162 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1163 layer_tree_host()->set_background_color(SK_ColorGRAY);
1165 PostSetNeedsCommitToMainThread();
1168 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
1169 EXPECT_EQ(frame_count_with_pending_tree_, 0);
1170 if (impl->settings().impl_side_painting)
1171 impl->BlockNotifyReadyToActivateForTesting(true);
1174 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1175 const BeginFrameArgs& args) override {
1176 if (impl->pending_tree())
1177 frame_count_with_pending_tree_++;
1179 if (frame_count_with_pending_tree_ == 1) {
1180 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
1181 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1182 } else if (frame_count_with_pending_tree_ == 2 &&
1183 impl->settings().impl_side_painting) {
1184 impl->BlockNotifyReadyToActivateForTesting(false);
1188 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1189 if (frame_count_with_pending_tree_ > 1) {
1190 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
1191 EXPECT_NE(first_frame_time_.ToInternalValue(),
1192 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
1193 EndTest();
1194 return;
1197 EXPECT_FALSE(impl->settings().impl_side_painting);
1198 EndTest();
1200 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1201 if (impl->settings().impl_side_painting)
1202 EXPECT_NE(frame_count_with_pending_tree_, 1);
1205 void AfterTest() override {}
1207 private:
1208 int frame_count_with_pending_tree_;
1209 base::TimeTicks first_frame_time_;
1212 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1213 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
1215 // This test verifies that LayerTreeHostImpl's current frame time gets
1216 // updated in consecutive frames when it draws in each frame.
1217 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
1218 public:
1219 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
1221 void BeginTest() override {
1222 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1223 layer_tree_host()->set_background_color(SK_ColorGRAY);
1225 PostSetNeedsCommitToMainThread();
1228 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1229 frame_++;
1230 if (frame_ == 1) {
1231 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1232 impl->SetNeedsRedraw();
1234 // Since we might use a low-resolution clock on Windows, we need to
1235 // make sure that the clock has incremented past first_frame_time_.
1236 while (first_frame_time_ == base::TimeTicks::Now()) {
1239 return;
1242 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
1243 EndTest();
1246 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1247 // Ensure there isn't a commit between the two draws, to ensure that a
1248 // commit isn't required for updating the current frame time. We can
1249 // only check for this in the multi-threaded case, since in the single-
1250 // threaded case there will always be a commit between consecutive draws.
1251 if (HasImplThread())
1252 EXPECT_EQ(0, frame_);
1255 void AfterTest() override {}
1257 private:
1258 int frame_;
1259 base::TimeTicks first_frame_time_;
1262 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1264 // Verifies that StartPageScaleAnimation events propagate correctly
1265 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1266 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
1267 public:
1268 LayerTreeHostTestStartPageScaleAnimation() {}
1270 void SetupTree() override {
1271 LayerTreeHostTest::SetupTree();
1273 scoped_refptr<FakePictureLayer> layer =
1274 FakePictureLayer::Create(layer_settings(), &client_);
1275 layer->set_always_update_resources(true);
1276 scroll_layer_ = layer;
1278 Layer* root_layer = layer_tree_host()->root_layer();
1279 scroll_layer_->SetScrollClipLayerId(root_layer->id());
1280 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
1281 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
1282 2 * root_layer->bounds().height()));
1283 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
1284 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1285 // This test requires the page_scale and inner viewport layers to be
1286 // identified.
1287 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
1288 scroll_layer_.get(), NULL);
1289 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1292 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1294 void ApplyViewportDeltas(const gfx::Vector2dF& scroll_delta,
1295 const gfx::Vector2dF&,
1296 const gfx::Vector2dF& elastic_overscroll_delta,
1297 float scale,
1298 float) override {
1299 gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
1300 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset,
1301 scroll_delta));
1302 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1305 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1306 // We get one commit before the first draw, and the animation doesn't happen
1307 // until the second draw.
1308 switch (impl->active_tree()->source_frame_number()) {
1309 case 0:
1310 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1311 // We'll start an animation when we get back to the main thread.
1312 break;
1313 case 1:
1314 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1315 break;
1316 case 2:
1317 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
1318 EndTest();
1319 break;
1320 default:
1321 NOTREACHED();
1325 void DidCommitAndDrawFrame() override {
1326 switch (layer_tree_host()->source_frame_number()) {
1327 case 1:
1328 layer_tree_host()->StartPageScaleAnimation(
1329 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1330 break;
1334 void AfterTest() override {}
1336 FakeContentLayerClient client_;
1337 scoped_refptr<Layer> scroll_layer_;
1340 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1342 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1343 public:
1344 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1346 void BeginTest() override {
1347 PostSetNeedsCommitToMainThread();
1348 PostSetVisibleToMainThread(false);
1349 // This is suppressed while we're invisible.
1350 PostSetNeedsRedrawToMainThread();
1351 // Triggers the redraw.
1352 PostSetVisibleToMainThread(true);
1355 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1356 EXPECT_TRUE(impl->visible());
1357 ++num_draws_;
1358 EndTest();
1361 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
1363 private:
1364 int num_draws_;
1367 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1369 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1370 public:
1371 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1373 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1375 void PaintContents(SkCanvas* canvas,
1376 const gfx::Rect& clip,
1377 PaintingControlSetting picture_control) override {
1378 // Set layer opacity to 0.
1379 if (test_layer_)
1380 test_layer_->SetOpacity(0.f);
1382 void PaintContentsToDisplayList(
1383 DisplayItemList* display_list,
1384 const gfx::Rect& clip,
1385 PaintingControlSetting picture_control) override {
1386 NOTIMPLEMENTED();
1388 bool FillsBoundsCompletely() const override { return false; }
1390 private:
1391 Layer* test_layer_;
1394 class ContentLayerWithUpdateTracking : public ContentLayer {
1395 public:
1396 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1397 const LayerSettings& settings,
1398 ContentLayerClient* client) {
1399 return make_scoped_refptr(
1400 new ContentLayerWithUpdateTracking(settings, client));
1403 int PaintContentsCount() { return paint_contents_count_; }
1404 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1406 bool Update(ResourceUpdateQueue* queue,
1407 const OcclusionTracker<Layer>* occlusion) override {
1408 bool updated = ContentLayer::Update(queue, occlusion);
1409 paint_contents_count_++;
1410 return updated;
1413 private:
1414 ContentLayerWithUpdateTracking(const LayerSettings& settings,
1415 ContentLayerClient* client)
1416 : ContentLayer(settings, client), paint_contents_count_(0) {
1417 SetBounds(gfx::Size(10, 10));
1418 SetIsDrawable(true);
1420 ~ContentLayerWithUpdateTracking() override {}
1422 int paint_contents_count_;
1425 // Layer opacity change during paint should not prevent compositor resources
1426 // from being updated during commit.
1427 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1428 public:
1429 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {}
1431 void BeginTest() override {
1432 if (layer_tree_host()->settings().impl_side_painting) {
1433 update_check_picture_layer_ = FakePictureLayer::Create(
1434 layer_settings(), &test_opacity_change_delegate_);
1435 test_opacity_change_delegate_.SetTestLayer(
1436 update_check_picture_layer_.get());
1437 is_impl_paint_ = true;
1438 } else {
1439 update_check_content_layer_ = ContentLayerWithUpdateTracking::Create(
1440 layer_settings(), &test_opacity_change_delegate_);
1441 test_opacity_change_delegate_.SetTestLayer(
1442 update_check_content_layer_.get());
1443 is_impl_paint_ = false;
1445 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1446 if (layer_tree_host()->settings().impl_side_painting)
1447 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
1448 else
1449 layer_tree_host()->root_layer()->AddChild(update_check_content_layer_);
1451 PostSetNeedsCommitToMainThread();
1454 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
1456 void AfterTest() override {
1457 // Update() should have been called once.
1458 if (is_impl_paint_)
1459 EXPECT_EQ(1u, update_check_picture_layer_->update_count());
1460 else
1461 EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount());
1464 private:
1465 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1466 scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_;
1467 scoped_refptr<FakePictureLayer> update_check_picture_layer_;
1468 bool is_impl_paint_;
1471 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1473 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1474 : public LayerTreeHostTest {
1475 public:
1476 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {}
1478 void InitializeSettings(LayerTreeSettings* settings) override {
1479 // PictureLayer can only be used with impl side painting enabled.
1480 settings->impl_side_painting = true;
1483 void BeginTest() override {
1484 client_.set_fill_with_nonsolid_color(true);
1485 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1486 child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1488 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1489 layer_tree_host()->SetDeviceScaleFactor(1.5);
1490 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1492 root_layer_->AddChild(child_layer_);
1494 root_layer_->SetIsDrawable(true);
1495 root_layer_->SetBounds(gfx::Size(30, 30));
1497 child_layer_->SetIsDrawable(true);
1498 child_layer_->SetPosition(gfx::Point(2, 2));
1499 child_layer_->SetBounds(gfx::Size(10, 10));
1501 layer_tree_host()->SetRootLayer(root_layer_);
1503 PostSetNeedsCommitToMainThread();
1506 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1507 // Should only do one commit.
1508 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1509 // Device scale factor should come over to impl.
1510 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1512 // Both layers are on impl.
1513 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1515 // Device viewport is scaled.
1516 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1518 FakePictureLayerImpl* root =
1519 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
1520 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
1521 impl->active_tree()->root_layer()->children()[0]);
1523 // Positions remain in layout pixels.
1524 EXPECT_EQ(gfx::Point(0, 0), root->position());
1525 EXPECT_EQ(gfx::Point(2, 2), child->position());
1527 // Compute all the layer transforms for the frame.
1528 LayerTreeHostImpl::FrameData frame_data;
1529 impl->PrepareToDraw(&frame_data);
1530 impl->DidDrawAllLayers(frame_data);
1532 const LayerImplList& render_surface_layer_list =
1533 *frame_data.render_surface_layer_list;
1535 // Both layers should be drawing into the root render surface.
1536 ASSERT_EQ(1u, render_surface_layer_list.size());
1537 ASSERT_EQ(root->render_surface(),
1538 render_surface_layer_list[0]->render_surface());
1539 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1541 // The root render surface is the size of the viewport.
1542 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect());
1544 // The max tiling scale of the child should be scaled.
1545 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale());
1547 gfx::Transform scale_transform;
1548 scale_transform.Scale(impl->device_scale_factor(),
1549 impl->device_scale_factor());
1551 // The root layer is scaled by 2x.
1552 gfx::Transform root_screen_space_transform = scale_transform;
1553 gfx::Transform root_draw_transform = scale_transform;
1555 EXPECT_EQ(root_draw_transform, root->draw_transform());
1556 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1558 // The child is at position 2,2, which is transformed to 3,3 after the scale
1559 gfx::Transform child_transform;
1560 child_transform.Translate(3.f, 3.f);
1561 child_transform.Scale(child->MaximumTilingContentsScale(),
1562 child->MaximumTilingContentsScale());
1564 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform());
1565 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform,
1566 child->screen_space_transform());
1568 EndTest();
1571 void AfterTest() override {}
1573 private:
1574 FakeContentLayerClient client_;
1575 scoped_refptr<FakePictureLayer> root_layer_;
1576 scoped_refptr<FakePictureLayer> child_layer_;
1579 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1581 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1582 // Verify atomicity of commits and reuse of textures.
1583 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1584 public:
1585 void InitializeSettings(LayerTreeSettings* settings) override {
1586 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1587 // Make sure partial texture updates are turned off.
1588 settings->max_partial_texture_updates = 0;
1589 // Linear fade animator prevents scrollbars from drawing immediately.
1590 settings->scrollbar_animator = LayerTreeSettings::NO_ANIMATOR;
1593 void SetupTree() override {
1594 layer_ = FakeContentLayer::Create(layer_settings(), &client_);
1595 layer_->SetBounds(gfx::Size(10, 20));
1597 bool paint_scrollbar = true;
1598 bool has_thumb = false;
1599 scrollbar_ = FakePaintedScrollbarLayer::Create(
1600 layer_settings(), paint_scrollbar, has_thumb, layer_->id());
1601 scrollbar_->SetPosition(gfx::Point(0, 10));
1602 scrollbar_->SetBounds(gfx::Size(10, 10));
1604 layer_->AddChild(scrollbar_);
1606 layer_tree_host()->SetRootLayer(layer_);
1607 LayerTreeHostTest::SetupTree();
1610 void BeginTest() override {
1611 drew_frame_ = -1;
1612 PostSetNeedsCommitToMainThread();
1615 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1616 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
1618 TestWebGraphicsContext3D* context = TestContext();
1620 switch (impl->active_tree()->source_frame_number()) {
1621 case 0:
1622 // Number of textures should be one for each layer
1623 ASSERT_EQ(2u, context->NumTextures());
1624 // Number of textures used for commit should be one for each layer.
1625 EXPECT_EQ(2u, context->NumUsedTextures());
1626 // Verify that used texture is correct.
1627 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1628 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1630 context->ResetUsedTextures();
1631 break;
1632 case 1:
1633 // Number of textures should be one for scrollbar layer since it was
1634 // requested and deleted on the impl-thread, and double for the content
1635 // layer since its first texture is used by impl thread and cannot by
1636 // used for update.
1637 ASSERT_EQ(3u, context->NumTextures());
1638 // Number of textures used for commit should be one for each layer.
1639 EXPECT_EQ(2u, context->NumUsedTextures());
1640 // First textures should not have been used.
1641 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1642 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1643 // New textures should have been used.
1644 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1645 context->ResetUsedTextures();
1646 break;
1647 case 2:
1648 EndTest();
1649 break;
1650 default:
1651 NOTREACHED();
1652 break;
1656 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1657 TestWebGraphicsContext3D* context = TestContext();
1659 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1660 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1661 return;
1663 drew_frame_ = impl->active_tree()->source_frame_number();
1665 // We draw/ship one texture each frame for each layer.
1666 EXPECT_EQ(2u, context->NumUsedTextures());
1667 context->ResetUsedTextures();
1669 if (!TestEnded())
1670 PostSetNeedsCommitToMainThread();
1673 void Layout() override {
1674 layer_->SetNeedsDisplay();
1675 scrollbar_->SetNeedsDisplay();
1678 void AfterTest() override {}
1680 protected:
1681 FakeContentLayerClient client_;
1682 scoped_refptr<FakeContentLayer> layer_;
1683 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1684 int drew_frame_;
1687 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1688 LayerTreeHostTestDirectRendererAtomicCommit);
1690 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1691 class LayerTreeHostTestDelegatingRendererAtomicCommit
1692 : public LayerTreeHostTestDirectRendererAtomicCommit {
1693 public:
1694 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1695 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
1697 TestWebGraphicsContext3D* context = TestContext();
1699 switch (impl->active_tree()->source_frame_number()) {
1700 case 0:
1701 // Number of textures should be one for each layer
1702 ASSERT_EQ(2u, context->NumTextures());
1703 // Number of textures used for commit should be one for each layer.
1704 EXPECT_EQ(2u, context->NumUsedTextures());
1705 // Verify that used texture is correct.
1706 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1707 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1708 break;
1709 case 1:
1710 // Number of textures should be doubled as the first context layer
1711 // texture is being used by the impl-thread and cannot be used for
1712 // update. The scrollbar behavior is different direct renderer because
1713 // UI resource deletion with delegating renderer occurs after tree
1714 // activation.
1715 ASSERT_EQ(4u, context->NumTextures());
1716 // Number of textures used for commit should still be
1717 // one for each layer.
1718 EXPECT_EQ(2u, context->NumUsedTextures());
1719 // First textures should not have been used.
1720 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1721 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1722 // New textures should have been used.
1723 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1724 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1725 break;
1726 case 2:
1727 EndTest();
1728 break;
1729 default:
1730 NOTREACHED();
1731 break;
1736 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1737 LayerTreeHostTestDelegatingRendererAtomicCommit);
1739 static void SetLayerPropertiesForTesting(Layer* layer,
1740 Layer* parent,
1741 const gfx::Transform& transform,
1742 const gfx::Point3F& transform_origin,
1743 const gfx::PointF& position,
1744 const gfx::Size& bounds,
1745 bool opaque) {
1746 layer->RemoveAllChildren();
1747 if (parent)
1748 parent->AddChild(layer);
1749 layer->SetTransform(transform);
1750 layer->SetTransformOrigin(transform_origin);
1751 layer->SetPosition(position);
1752 layer->SetBounds(bounds);
1753 layer->SetContentsOpaque(opaque);
1756 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1757 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1758 : public LayerTreeHostTest {
1759 public:
1760 void InitializeSettings(LayerTreeSettings* settings) override {
1761 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1762 // Allow one partial texture update.
1763 settings->max_partial_texture_updates = 1;
1764 // No partial updates when impl side painting is enabled.
1765 settings->impl_side_painting = false;
1768 void SetupTree() override {
1769 parent_ = FakeContentLayer::Create(layer_settings(), &client_);
1770 parent_->SetBounds(gfx::Size(10, 20));
1772 child_ = FakeContentLayer::Create(layer_settings(), &client_);
1773 child_->SetPosition(gfx::Point(0, 10));
1774 child_->SetBounds(gfx::Size(3, 10));
1776 parent_->AddChild(child_);
1778 layer_tree_host()->SetRootLayer(parent_);
1779 LayerTreeHostTest::SetupTree();
1782 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1784 void DidCommitAndDrawFrame() override {
1785 switch (layer_tree_host()->source_frame_number()) {
1786 case 1:
1787 parent_->SetNeedsDisplay();
1788 child_->SetNeedsDisplay();
1789 break;
1790 case 2:
1791 // Damage part of layers.
1792 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1793 child_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1794 break;
1795 case 3:
1796 child_->SetNeedsDisplay();
1797 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1798 break;
1799 case 4:
1800 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1801 break;
1802 case 5:
1803 EndTest();
1804 break;
1805 default:
1806 NOTREACHED() << layer_tree_host()->source_frame_number();
1807 break;
1811 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1812 ASSERT_EQ(1u, impl->settings().max_partial_texture_updates);
1814 TestWebGraphicsContext3D* context = TestContext();
1816 switch (impl->active_tree()->source_frame_number()) {
1817 case 0:
1818 // Number of textures should be one for each layer.
1819 ASSERT_EQ(2u, context->NumTextures());
1820 // Number of textures used for commit should be one for each layer.
1821 EXPECT_EQ(2u, context->NumUsedTextures());
1822 // Verify that used textures are correct.
1823 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1824 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1825 context->ResetUsedTextures();
1826 break;
1827 case 1:
1828 if (HasImplThread()) {
1829 // Number of textures should be two for each content layer.
1830 ASSERT_EQ(4u, context->NumTextures());
1831 } else {
1832 // In single thread we can always do partial updates, so the limit has
1833 // no effect.
1834 ASSERT_EQ(2u, context->NumTextures());
1836 // Number of textures used for commit should be one for each content
1837 // layer.
1838 EXPECT_EQ(2u, context->NumUsedTextures());
1840 if (HasImplThread()) {
1841 // First content textures should not have been used.
1842 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1843 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1844 // New textures should have been used.
1845 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1846 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1847 } else {
1848 // In single thread we can always do partial updates, so the limit has
1849 // no effect.
1850 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1851 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1854 context->ResetUsedTextures();
1855 break;
1856 case 2:
1857 if (HasImplThread()) {
1858 // Number of textures should be two for each content layer.
1859 ASSERT_EQ(4u, context->NumTextures());
1860 } else {
1861 // In single thread we can always do partial updates, so the limit has
1862 // no effect.
1863 ASSERT_EQ(2u, context->NumTextures());
1865 // Number of textures used for commit should be one for each content
1866 // layer.
1867 EXPECT_EQ(2u, context->NumUsedTextures());
1869 if (HasImplThread()) {
1870 // One content layer does a partial update also.
1871 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1872 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1873 } else {
1874 // In single thread we can always do partial updates, so the limit has
1875 // no effect.
1876 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1877 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1880 context->ResetUsedTextures();
1881 break;
1882 case 3:
1883 // No textures should be used for commit.
1884 EXPECT_EQ(0u, context->NumUsedTextures());
1886 context->ResetUsedTextures();
1887 break;
1888 case 4:
1889 // Number of textures used for commit should be one, for the
1890 // content layer.
1891 EXPECT_EQ(1u, context->NumUsedTextures());
1893 context->ResetUsedTextures();
1894 break;
1895 default:
1896 NOTREACHED();
1897 break;
1901 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1902 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1904 TestWebGraphicsContext3D* context = TestContext();
1906 // Number of textures used for drawing should one per layer except for
1907 // frame 3 where the viewport only contains one layer.
1908 if (impl->active_tree()->source_frame_number() == 3) {
1909 EXPECT_EQ(1u, context->NumUsedTextures());
1910 } else {
1911 EXPECT_EQ(2u, context->NumUsedTextures())
1912 << "For frame " << impl->active_tree()->source_frame_number();
1915 context->ResetUsedTextures();
1918 void AfterTest() override {}
1920 private:
1921 FakeContentLayerClient client_;
1922 scoped_refptr<FakeContentLayer> parent_;
1923 scoped_refptr<FakeContentLayer> child_;
1926 // Partial updates are not possible with a delegating renderer.
1927 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1928 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1930 // TODO(sohanjg) : Make it work with impl-side painting.
1931 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1932 : public LayerTreeHostTest {
1933 protected:
1934 void SetupTree() override {
1935 root_layer_ = FakeContentLayer::Create(layer_settings(), &client_);
1936 root_layer_->SetBounds(gfx::Size(100, 100));
1938 surface_layer1_ = FakeContentLayer::Create(layer_settings(), &client_);
1939 surface_layer1_->SetBounds(gfx::Size(100, 100));
1940 surface_layer1_->SetForceRenderSurface(true);
1941 surface_layer1_->SetOpacity(0.5f);
1942 root_layer_->AddChild(surface_layer1_);
1944 surface_layer2_ = FakeContentLayer::Create(layer_settings(), &client_);
1945 surface_layer2_->SetBounds(gfx::Size(100, 100));
1946 surface_layer2_->SetForceRenderSurface(true);
1947 surface_layer2_->SetOpacity(0.5f);
1948 surface_layer1_->AddChild(surface_layer2_);
1950 replica_layer1_ = FakeContentLayer::Create(layer_settings(), &client_);
1951 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1953 replica_layer2_ = FakeContentLayer::Create(layer_settings(), &client_);
1954 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1956 layer_tree_host()->SetRootLayer(root_layer_);
1957 LayerTreeHostTest::SetupTree();
1960 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1962 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1963 Renderer* renderer = host_impl->renderer();
1964 RenderPassId surface1_render_pass_id = host_impl->active_tree()
1965 ->root_layer()
1966 ->children()[0]
1967 ->render_surface()
1968 ->GetRenderPassId();
1969 RenderPassId surface2_render_pass_id = host_impl->active_tree()
1970 ->root_layer()
1971 ->children()[0]
1972 ->children()[0]
1973 ->render_surface()
1974 ->GetRenderPassId();
1976 switch (host_impl->active_tree()->source_frame_number()) {
1977 case 0:
1978 EXPECT_TRUE(
1979 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1980 EXPECT_TRUE(
1981 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1983 // Reduce the memory limit to only fit the root layer and one render
1984 // surface. This prevents any contents drawing into surfaces
1985 // from being allocated.
1986 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1987 break;
1988 case 1:
1989 EXPECT_FALSE(
1990 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1991 EXPECT_FALSE(
1992 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1994 EndTest();
1995 break;
1999 void DidCommitAndDrawFrame() override {
2000 if (layer_tree_host()->source_frame_number() < 2)
2001 root_layer_->SetNeedsDisplay();
2004 void AfterTest() override {
2005 EXPECT_LE(2u, root_layer_->update_count());
2006 EXPECT_LE(2u, surface_layer1_->update_count());
2007 EXPECT_LE(2u, surface_layer2_->update_count());
2010 FakeContentLayerClient client_;
2011 scoped_refptr<FakeContentLayer> root_layer_;
2012 scoped_refptr<FakeContentLayer> surface_layer1_;
2013 scoped_refptr<FakeContentLayer> replica_layer1_;
2014 scoped_refptr<FakeContentLayer> surface_layer2_;
2015 scoped_refptr<FakeContentLayer> replica_layer2_;
2018 // Surfaces don't exist with a delegated renderer.
2019 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
2020 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
2022 class EvictionTestLayer : public Layer {
2023 public:
2024 static scoped_refptr<EvictionTestLayer> Create(
2025 const LayerSettings& settings) {
2026 return make_scoped_refptr(new EvictionTestLayer(settings));
2029 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override;
2030 bool DrawsContent() const override { return true; }
2032 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
2033 void PushPropertiesTo(LayerImpl* impl) override;
2034 void SetTexturePriorities(const PriorityCalculator&) override;
2036 bool HaveBackingTexture() const {
2037 return texture_.get() ? texture_->have_backing_texture() : false;
2040 private:
2041 explicit EvictionTestLayer(const LayerSettings& settings) : Layer(settings) {}
2042 ~EvictionTestLayer() override {}
2044 void CreateTextureIfNeeded() {
2045 if (texture_)
2046 return;
2047 texture_ = PrioritizedResource::Create(
2048 layer_tree_host()->contents_texture_manager());
2049 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
2050 bitmap_.allocN32Pixels(10, 10);
2053 scoped_ptr<PrioritizedResource> texture_;
2054 SkBitmap bitmap_;
2057 class EvictionTestLayerImpl : public LayerImpl {
2058 public:
2059 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
2060 int id) {
2061 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
2063 ~EvictionTestLayerImpl() override {}
2065 void AppendQuads(RenderPass* render_pass,
2066 AppendQuadsData* append_quads_data) override {
2067 ASSERT_TRUE(has_texture_);
2068 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
2071 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
2073 private:
2074 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
2075 : LayerImpl(tree_impl, id), has_texture_(false) {}
2077 bool has_texture_;
2080 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
2081 CreateTextureIfNeeded();
2082 if (!texture_)
2083 return;
2084 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
2087 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
2088 const OcclusionTracker<Layer>* occlusion) {
2089 CreateTextureIfNeeded();
2090 if (!texture_)
2091 return false;
2093 gfx::Rect full_rect(0, 0, 10, 10);
2094 ResourceUpdate upload = ResourceUpdate::Create(
2095 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
2096 queue->AppendFullUpload(upload);
2097 return true;
2100 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
2101 LayerTreeImpl* tree_impl) {
2102 return EvictionTestLayerImpl::Create(tree_impl, layer_id_);
2105 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
2106 Layer::PushPropertiesTo(layer_impl);
2108 EvictionTestLayerImpl* test_layer_impl =
2109 static_cast<EvictionTestLayerImpl*>(layer_impl);
2110 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
2113 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
2114 public:
2115 LayerTreeHostTestEvictTextures()
2116 : layer_(EvictionTestLayer::Create(layer_settings())),
2117 impl_for_evict_textures_(0),
2118 num_commits_(0) {}
2120 void BeginTest() override {
2121 layer_tree_host()->SetRootLayer(layer_);
2122 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
2124 gfx::Transform identity_matrix;
2125 SetLayerPropertiesForTesting(layer_.get(),
2127 identity_matrix,
2128 gfx::Point3F(0.f, 0.f, 0.f),
2129 gfx::PointF(0.f, 0.f),
2130 gfx::Size(10, 20),
2131 true);
2133 PostSetNeedsCommitToMainThread();
2136 void PostEvictTextures() {
2137 ImplThreadTaskRunner()->PostTask(
2138 FROM_HERE,
2139 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
2140 base::Unretained(this)));
2143 void EvictTexturesOnImplThread() {
2144 DCHECK(impl_for_evict_textures_);
2145 impl_for_evict_textures_->EvictTexturesForTesting();
2148 // Commit 1: Just commit and draw normally, then post an eviction at the end
2149 // that will trigger a commit.
2150 // Commit 2: Triggered by the eviction, let it go through and then set
2151 // needsCommit.
2152 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
2153 // task, which will be handled before the commit. Don't set needsCommit, it
2154 // should have been posted. A frame should not be drawn (note,
2155 // didCommitAndDrawFrame may be called anyway).
2156 // Commit 4: Triggered by the eviction, let it go through and then set
2157 // needsCommit.
2158 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
2159 // Layout(), a frame should not be drawn but a commit will be posted.
2160 // Commit 6: Triggered by the eviction, post an eviction task in
2161 // Layout(), which will be a noop, letting the commit (which recreates the
2162 // textures) go through and draw a frame, then end the test.
2164 // Commits 1+2 test the eviction recovery path where eviction happens outside
2165 // of the beginFrame/commit pair.
2166 // Commits 3+4 test the eviction recovery path where eviction happens inside
2167 // the beginFrame/commit pair.
2168 // Commits 5+6 test the path where an eviction happens during the eviction
2169 // recovery path.
2170 void DidCommit() override {
2171 switch (num_commits_) {
2172 case 1:
2173 EXPECT_TRUE(layer_->HaveBackingTexture());
2174 PostEvictTextures();
2175 break;
2176 case 2:
2177 EXPECT_TRUE(layer_->HaveBackingTexture());
2178 layer_tree_host()->SetNeedsCommit();
2179 break;
2180 case 3:
2181 break;
2182 case 4:
2183 EXPECT_TRUE(layer_->HaveBackingTexture());
2184 layer_tree_host()->SetNeedsCommit();
2185 break;
2186 case 5:
2187 break;
2188 case 6:
2189 EXPECT_TRUE(layer_->HaveBackingTexture());
2190 EndTest();
2191 break;
2192 default:
2193 NOTREACHED();
2194 break;
2198 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2199 impl_for_evict_textures_ = impl;
2202 void Layout() override {
2203 ++num_commits_;
2204 switch (num_commits_) {
2205 case 1:
2206 case 2:
2207 break;
2208 case 3:
2209 PostEvictTextures();
2210 break;
2211 case 4:
2212 // We couldn't check in didCommitAndDrawFrame on commit 3,
2213 // so check here.
2214 EXPECT_FALSE(layer_->HaveBackingTexture());
2215 break;
2216 case 5:
2217 PostEvictTextures();
2218 break;
2219 case 6:
2220 // We couldn't check in didCommitAndDrawFrame on commit 5,
2221 // so check here.
2222 EXPECT_FALSE(layer_->HaveBackingTexture());
2223 PostEvictTextures();
2224 break;
2225 default:
2226 NOTREACHED();
2227 break;
2231 void AfterTest() override {}
2233 private:
2234 FakeContentLayerClient client_;
2235 scoped_refptr<EvictionTestLayer> layer_;
2236 LayerTreeHostImpl* impl_for_evict_textures_;
2237 int num_commits_;
2240 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
2242 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
2243 public:
2244 LayerTreeHostTestContinuousInvalidate()
2245 : num_commit_complete_(0), num_draw_layers_(0) {}
2247 void BeginTest() override {
2248 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2249 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2251 if (layer_tree_host()->settings().impl_side_painting)
2252 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
2253 else
2254 layer_ = FakeContentLayer::Create(layer_settings(), &client_);
2256 layer_->SetBounds(gfx::Size(10, 10));
2257 layer_->SetPosition(gfx::PointF(0.f, 0.f));
2258 layer_->SetIsDrawable(true);
2259 layer_tree_host()->root_layer()->AddChild(layer_);
2261 PostSetNeedsCommitToMainThread();
2264 void DidCommitAndDrawFrame() override {
2265 if (num_draw_layers_ == 2)
2266 return;
2267 layer_->SetNeedsDisplay();
2270 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2271 if (num_draw_layers_ == 1)
2272 num_commit_complete_++;
2275 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2276 num_draw_layers_++;
2277 if (num_draw_layers_ == 2)
2278 EndTest();
2281 void AfterTest() override {
2282 // Check that we didn't commit twice between first and second draw.
2283 EXPECT_EQ(1, num_commit_complete_);
2286 private:
2287 FakeContentLayerClient client_;
2288 scoped_refptr<Layer> layer_;
2289 int num_commit_complete_;
2290 int num_draw_layers_;
2293 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
2295 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2296 public:
2297 LayerTreeHostTestDeferCommits()
2298 : num_will_begin_impl_frame_(0),
2299 num_send_begin_main_frame_(0) {}
2301 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2303 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
2304 const BeginFrameArgs& args) override {
2305 num_will_begin_impl_frame_++;
2306 switch (num_will_begin_impl_frame_) {
2307 case 1:
2308 break;
2309 case 2:
2310 case 3:
2311 case 4:
2312 // Post a number of frames to increase the chance that, if there exist
2313 // bugs, an unexpected BeginMainFrame will be issued.
2314 PostSetNeedsCommitToMainThread();
2315 PostSetNeedsRedrawToMainThread();
2316 break;
2317 case 5:
2318 PostSetDeferCommitsToMainThread(false);
2319 break;
2320 default:
2321 // Sometimes |num_will_begin_impl_frame_| will be greater than 5 if the
2322 // main thread is slow to respond.
2323 break;
2327 void ScheduledActionSendBeginMainFrame() override {
2328 num_send_begin_main_frame_++;
2329 switch (num_send_begin_main_frame_) {
2330 case 1:
2331 PostSetDeferCommitsToMainThread(true);
2332 break;
2333 case 2:
2334 EndTest();
2335 break;
2336 default:
2337 NOTREACHED();
2338 break;
2342 void AfterTest() override {
2343 EXPECT_GE(num_will_begin_impl_frame_, 5);
2344 EXPECT_EQ(2, num_send_begin_main_frame_);
2347 private:
2348 int num_will_begin_impl_frame_;
2349 int num_send_begin_main_frame_;
2352 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2354 class LayerTreeHostTestCompositeImmediatelyStateTransitions
2355 : public LayerTreeHostTest {
2356 public:
2357 enum {
2358 kInvalid,
2359 kStartedTest,
2360 kStartedImplFrame,
2361 kStartedMainFrame,
2362 kStartedCommit,
2363 kCompletedCommit,
2364 kCompletedMainFrame,
2365 kCompletedImplFrame,
2368 LayerTreeHostTestCompositeImmediatelyStateTransitions()
2369 : current_state_(kInvalid), current_begin_frame_args_() {}
2371 void InitializeSettings(LayerTreeSettings* settings) override {
2372 settings->single_thread_proxy_scheduler = false;
2373 settings->use_zero_copy = true;
2376 void BeginTest() override {
2377 current_state_ = kStartedTest;
2378 PostCompositeImmediatelyToMainThread();
2381 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
2382 const BeginFrameArgs& args) override {
2383 EXPECT_EQ(current_state_, kStartedTest);
2384 current_state_ = kStartedImplFrame;
2386 EXPECT_FALSE(current_begin_frame_args_.IsValid());
2387 EXPECT_TRUE(args.IsValid());
2388 current_begin_frame_args_ = args;
2390 void WillBeginMainFrame() override {
2391 EXPECT_EQ(current_state_, kStartedImplFrame);
2392 current_state_ = kStartedMainFrame;
2394 void BeginMainFrame(const BeginFrameArgs& args) override {
2395 EXPECT_EQ(current_state_, kStartedMainFrame);
2396 EXPECT_EQ(args.frame_time, current_begin_frame_args_.frame_time);
2398 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
2399 EXPECT_EQ(current_state_, kStartedMainFrame);
2400 current_state_ = kStartedCommit;
2402 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2403 EXPECT_EQ(current_state_, kStartedCommit);
2404 current_state_ = kCompletedCommit;
2406 void DidBeginMainFrame() override {
2407 EXPECT_EQ(current_state_, kCompletedCommit);
2408 current_state_ = kCompletedMainFrame;
2410 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
2411 EXPECT_EQ(current_state_, kCompletedMainFrame);
2412 current_state_ = kCompletedImplFrame;
2413 EndTest();
2415 void AfterTest() override { EXPECT_EQ(current_state_, kCompletedImplFrame); }
2417 private:
2418 int current_state_;
2419 BeginFrameArgs current_begin_frame_args_;
2422 SINGLE_THREAD_TEST_F(LayerTreeHostTestCompositeImmediatelyStateTransitions);
2424 class LayerTreeHostWithProxy : public LayerTreeHost {
2425 public:
2426 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2427 scoped_ptr<FakeProxy> proxy,
2428 LayerTreeHost::InitParams* params)
2429 : LayerTreeHost(params) {
2430 proxy->SetLayerTreeHost(this);
2431 client->SetLayerTreeHost(this);
2432 InitializeForTesting(proxy.Pass());
2436 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2437 // When partial updates are not allowed, max updates should be 0.
2439 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2441 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2442 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2443 proxy->SetMaxPartialTextureUpdates(5);
2445 LayerTreeSettings settings;
2446 settings.impl_side_painting = false;
2447 settings.max_partial_texture_updates = 10;
2449 LayerTreeHost::InitParams params;
2450 params.client = &client;
2451 params.settings = &settings;
2452 LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
2454 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2457 // When partial updates are allowed,
2458 // max updates should be limited by the proxy.
2460 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2462 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2463 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2464 proxy->SetMaxPartialTextureUpdates(5);
2466 LayerTreeSettings settings;
2467 settings.impl_side_painting = false;
2468 settings.max_partial_texture_updates = 10;
2470 LayerTreeHost::InitParams params;
2471 params.client = &client;
2472 params.settings = &settings;
2473 LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
2475 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2478 // When partial updates are allowed,
2479 // max updates should also be limited by the settings.
2481 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2483 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2484 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2485 proxy->SetMaxPartialTextureUpdates(20);
2487 LayerTreeSettings settings;
2488 settings.impl_side_painting = false;
2489 settings.max_partial_texture_updates = 10;
2491 LayerTreeHost::InitParams params;
2492 params.client = &client;
2493 params.settings = &settings;
2494 LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
2496 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2500 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2501 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2503 LayerTreeSettings settings;
2504 settings.max_partial_texture_updates = 4;
2505 settings.single_thread_proxy_scheduler = false;
2506 settings.impl_side_painting = false;
2508 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2509 new TestSharedBitmapManager());
2510 LayerTreeHost::InitParams params;
2511 params.client = &client;
2512 params.shared_bitmap_manager = shared_bitmap_manager.get();
2513 params.settings = &settings;
2514 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
2515 scoped_ptr<LayerTreeHost> host =
2516 LayerTreeHost::CreateSingleThreaded(&client, &params);
2517 client.SetLayerTreeHost(host.get());
2518 host->Composite(base::TimeTicks::Now());
2520 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2523 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2524 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2526 LayerTreeSettings settings;
2527 settings.max_partial_texture_updates = 4;
2528 settings.single_thread_proxy_scheduler = false;
2529 settings.impl_side_painting = false;
2531 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2532 new TestSharedBitmapManager());
2533 LayerTreeHost::InitParams params;
2534 params.client = &client;
2535 params.shared_bitmap_manager = shared_bitmap_manager.get();
2536 params.settings = &settings;
2537 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
2538 scoped_ptr<LayerTreeHost> host =
2539 LayerTreeHost::CreateSingleThreaded(&client, &params);
2540 client.SetLayerTreeHost(host.get());
2541 host->Composite(base::TimeTicks::Now());
2543 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2546 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2547 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2549 LayerTreeSettings settings;
2550 settings.max_partial_texture_updates = 4;
2551 settings.single_thread_proxy_scheduler = false;
2552 settings.impl_side_painting = false;
2554 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2555 new TestSharedBitmapManager());
2556 LayerTreeHost::InitParams params;
2557 params.client = &client;
2558 params.shared_bitmap_manager = shared_bitmap_manager.get();
2559 params.settings = &settings;
2560 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
2561 scoped_ptr<LayerTreeHost> host =
2562 LayerTreeHost::CreateSingleThreaded(&client, &params);
2563 client.SetLayerTreeHost(host.get());
2564 host->Composite(base::TimeTicks::Now());
2566 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2569 TEST(LayerTreeHostTest,
2570 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2571 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2573 LayerTreeSettings settings;
2574 settings.max_partial_texture_updates = 4;
2575 settings.single_thread_proxy_scheduler = false;
2576 settings.impl_side_painting = false;
2578 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2579 new TestSharedBitmapManager());
2580 LayerTreeHost::InitParams params;
2581 params.client = &client;
2582 params.shared_bitmap_manager = shared_bitmap_manager.get();
2583 params.settings = &settings;
2584 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
2585 scoped_ptr<LayerTreeHost> host =
2586 LayerTreeHost::CreateSingleThreaded(&client, &params);
2587 client.SetLayerTreeHost(host.get());
2588 host->Composite(base::TimeTicks::Now());
2590 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2593 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
2594 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2595 : public LayerTreeHostTest {
2596 public:
2597 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2598 : root_layer_(FakeContentLayer::Create(layer_settings(), &client_)),
2599 child_layer1_(FakeContentLayer::Create(layer_settings(), &client_)),
2600 child_layer2_(FakeContentLayer::Create(layer_settings(), &client_)),
2601 num_commits_(0) {}
2603 void BeginTest() override {
2604 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2605 root_layer_->SetBounds(gfx::Size(100, 100));
2606 child_layer1_->SetBounds(gfx::Size(100, 100));
2607 child_layer2_->SetBounds(gfx::Size(100, 100));
2608 root_layer_->AddChild(child_layer1_);
2609 root_layer_->AddChild(child_layer2_);
2610 layer_tree_host()->SetRootLayer(root_layer_);
2611 PostSetNeedsCommitToMainThread();
2614 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2615 bool visible) override {
2616 if (visible) {
2617 // One backing should remain unevicted.
2618 EXPECT_EQ(100u * 100u * 4u * 1u,
2619 contents_texture_manager_->MemoryUseBytes());
2620 } else {
2621 EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes());
2624 // Make sure that contents textures are marked as having been
2625 // purged.
2626 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2627 // End the test in this state.
2628 EndTest();
2631 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2632 ++num_commits_;
2633 switch (num_commits_) {
2634 case 1:
2635 // All three backings should have memory.
2636 EXPECT_EQ(100u * 100u * 4u * 3u,
2637 contents_texture_manager_->MemoryUseBytes());
2639 // Set a new policy that will kick out 1 of the 3 resources.
2640 // Because a resource was evicted, a commit will be kicked off.
2641 host_impl->SetMemoryPolicy(
2642 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2643 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2644 1000));
2645 break;
2646 case 2:
2647 // Only two backings should have memory.
2648 EXPECT_EQ(100u * 100u * 4u * 2u,
2649 contents_texture_manager_->MemoryUseBytes());
2650 // Become backgrounded, which will cause 1 more resource to be
2651 // evicted.
2652 PostSetVisibleToMainThread(false);
2653 break;
2654 default:
2655 // No further commits should happen because this is not visible
2656 // anymore.
2657 NOTREACHED();
2658 break;
2662 void AfterTest() override {}
2664 private:
2665 FakeContentLayerClient client_;
2666 scoped_refptr<FakeContentLayer> root_layer_;
2667 scoped_refptr<FakeContentLayer> child_layer1_;
2668 scoped_refptr<FakeContentLayer> child_layer2_;
2669 int num_commits_;
2672 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2673 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2675 class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
2676 public:
2677 void SetupTree() override {
2678 num_tiles_rastered_ = 0;
2680 scoped_refptr<Layer> root_layer =
2681 PictureLayer::Create(layer_settings(), &client_);
2682 client_.set_fill_with_nonsolid_color(true);
2683 root_layer->SetIsDrawable(true);
2684 root_layer->SetBounds(gfx::Size(10, 10));
2685 root_layer->SetContentsOpaque(true);
2687 layer_tree_host()->SetRootLayer(root_layer);
2689 // The expectations are based on the assumption that the default
2690 // LCD settings are:
2691 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2693 LayerTreeHostTest::SetupTree();
2696 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2698 void DidCommitAndDrawFrame() override {
2699 switch (layer_tree_host()->source_frame_number()) {
2700 case 1:
2701 PostSetNeedsCommitToMainThread();
2702 break;
2703 case 2:
2704 // Change layer opacity that should trigger lcd change.
2705 layer_tree_host()->root_layer()->SetOpacity(.5f);
2706 break;
2707 case 3:
2708 // Change layer opacity that should not trigger lcd change.
2709 layer_tree_host()->root_layer()->SetOpacity(1.f);
2710 break;
2711 case 4:
2712 EndTest();
2713 break;
2717 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
2718 const Tile* tile) override {
2719 ++num_tiles_rastered_;
2722 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2723 PictureLayerImpl* root_layer =
2724 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer());
2725 bool can_use_lcd_text =
2726 host_impl->active_tree()->root_layer()->can_use_lcd_text();
2727 switch (host_impl->active_tree()->source_frame_number()) {
2728 case 0:
2729 // The first draw.
2730 EXPECT_EQ(1, num_tiles_rastered_);
2731 EXPECT_TRUE(can_use_lcd_text);
2732 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2733 break;
2734 case 1:
2735 // Nothing changed on the layer.
2736 EXPECT_EQ(1, num_tiles_rastered_);
2737 EXPECT_TRUE(can_use_lcd_text);
2738 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2739 break;
2740 case 2:
2741 // LCD text was disabled; it should be re-rastered with LCD text off.
2742 EXPECT_EQ(2, num_tiles_rastered_);
2743 EXPECT_FALSE(can_use_lcd_text);
2744 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2745 break;
2746 case 3:
2747 // LCD text was enabled, but it's sticky and stays off.
2748 EXPECT_EQ(2, num_tiles_rastered_);
2749 EXPECT_TRUE(can_use_lcd_text);
2750 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2751 break;
2755 void AfterTest() override {}
2757 private:
2758 FakeContentLayerClient client_;
2759 int num_tiles_rastered_;
2762 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
2764 // Verify that the BeginFrame notification is used to initiate rendering.
2765 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2766 public:
2767 void InitializeSettings(LayerTreeSettings* settings) override {
2768 settings->use_external_begin_frame_source = true;
2771 void BeginTest() override {
2772 // This will trigger a SetNeedsBeginFrame which will trigger a
2773 // BeginFrame.
2774 PostSetNeedsCommitToMainThread();
2777 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2778 LayerTreeHostImpl::FrameData* frame,
2779 DrawResult draw_result) override {
2780 EndTest();
2781 return DRAW_SUCCESS;
2784 void AfterTest() override {}
2786 private:
2787 base::TimeTicks frame_time_;
2790 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2792 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2793 : public LayerTreeHostTest {
2794 public:
2795 void InitializeSettings(LayerTreeSettings* settings) override {
2796 settings->use_external_begin_frame_source = true;
2797 settings->using_synchronous_renderer_compositor = true;
2800 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2802 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2803 // The BeginFrame notification is turned off now but will get enabled
2804 // once we return. End test while it's enabled.
2805 ImplThreadTaskRunner()->PostTask(
2806 FROM_HERE,
2807 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2808 base::Unretained(this)));
2811 void AfterTest() override {}
2814 MULTI_THREAD_TEST_F(
2815 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2817 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2818 protected:
2819 LayerTreeHostTestAbortedCommitDoesntStall()
2820 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2822 void InitializeSettings(LayerTreeSettings* settings) override {
2823 settings->use_external_begin_frame_source = true;
2826 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2828 void DidCommit() override {
2829 commit_count_++;
2830 if (commit_count_ == 4) {
2831 // After two aborted commits, request a real commit now to make sure a
2832 // real commit following an aborted commit will still complete and
2833 // end the test even when the Impl thread is idle.
2834 layer_tree_host()->SetNeedsCommit();
2838 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2839 CommitEarlyOutReason reason) override {
2840 commit_abort_count_++;
2841 // Initiate another abortable commit.
2842 host_impl->SetNeedsCommit();
2845 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2846 commit_complete_count_++;
2847 if (commit_complete_count_ == 1) {
2848 // Initiate an abortable commit after the first commit.
2849 host_impl->SetNeedsCommit();
2850 } else {
2851 EndTest();
2855 void AfterTest() override {
2856 EXPECT_EQ(commit_count_, 5);
2857 EXPECT_EQ(commit_abort_count_, 3);
2858 EXPECT_EQ(commit_complete_count_, 2);
2861 int commit_count_;
2862 int commit_abort_count_;
2863 int commit_complete_count_;
2866 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2867 : public LayerTreeHostTestAbortedCommitDoesntStall {
2868 protected:
2869 void InitializeSettings(LayerTreeSettings* settings) override {
2870 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2871 settings->using_synchronous_renderer_compositor = true;
2874 void ScheduledActionInvalidateOutputSurface() override {
2875 ImplThreadTaskRunner()->PostTask(
2876 FROM_HERE,
2877 base::Bind(
2878 &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor::
2879 CallOnDraw,
2880 base::Unretained(this)));
2883 void CallOnDraw() {
2884 // Synchronous compositor does not draw unless told to do so by the output
2885 // surface.
2886 output_surface()->client()->OnDraw();
2890 MULTI_THREAD_TEST_F(
2891 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2893 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2894 : public LayerTreeHostTestAbortedCommitDoesntStall {
2895 void InitializeSettings(LayerTreeSettings* settings) override {
2896 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2897 settings->renderer_settings.disable_gpu_vsync = true;
2901 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2903 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2904 : public LayerTreeHostTest {
2905 protected:
2906 void InitializeSettings(LayerTreeSettings* settings) override {
2907 settings->impl_side_painting = true;
2910 void SetupTree() override {
2911 LayerTreeHostTest::SetupTree();
2913 scoped_refptr<Layer> layer =
2914 PictureLayer::Create(layer_settings(), &client_);
2915 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2916 layer->SetBounds(gfx::Size(10, 10));
2917 layer_tree_host()->root_layer()->AddChild(layer);
2920 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2922 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2923 EndTest();
2926 void AfterTest() override {}
2928 FakeContentLayerClient client_;
2931 MULTI_THREAD_TEST_F(
2932 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2934 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2935 : public LayerTreeHostTest {
2936 public:
2937 class SetBoundsClient : public ContentLayerClient {
2938 public:
2939 SetBoundsClient() : layer_(0) {}
2941 void set_layer(Layer* layer) { layer_ = layer; }
2943 void PaintContents(SkCanvas* canvas,
2944 const gfx::Rect& clip,
2945 PaintingControlSetting picture_control) override {
2946 layer_->SetBounds(gfx::Size(2, 2));
2949 void PaintContentsToDisplayList(
2950 DisplayItemList* display_list,
2951 const gfx::Rect& clip,
2952 PaintingControlSetting picture_control) override {
2953 NOTIMPLEMENTED();
2956 bool FillsBoundsCompletely() const override { return false; }
2958 private:
2959 Layer* layer_;
2962 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2964 void SetupTree() override {
2965 if (layer_tree_host()->settings().impl_side_painting) {
2966 scoped_refptr<PictureLayer> root_layer =
2967 PictureLayer::Create(layer_settings(), &client_);
2968 layer_tree_host()->SetRootLayer(root_layer);
2969 } else {
2970 scoped_refptr<ContentLayer> root_layer =
2971 ContentLayer::Create(layer_settings(), &client_);
2972 layer_tree_host()->SetRootLayer(root_layer);
2974 Layer* root_layer = layer_tree_host()->root_layer();
2975 root_layer->SetIsDrawable(true);
2976 root_layer->SetBounds(gfx::Size(1, 1));
2978 client_.set_layer(root_layer);
2980 LayerTreeHostTest::SetupTree();
2983 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2984 void AfterTest() override {}
2986 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2987 num_commits_++;
2988 if (num_commits_ == 1) {
2989 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2990 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds());
2991 } else {
2992 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2993 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds());
2994 EndTest();
2998 private:
2999 SetBoundsClient client_;
3000 int num_commits_;
3003 SINGLE_AND_MULTI_THREAD_TEST_F(
3004 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
3006 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
3007 public:
3008 MockIOSurfaceWebGraphicsContext3D() {
3009 test_capabilities_.gpu.iosurface = true;
3010 test_capabilities_.gpu.texture_rectangle = true;
3013 GLuint createTexture() override { return 1; }
3014 MOCK_METHOD1(activeTexture, void(GLenum texture));
3015 MOCK_METHOD2(bindTexture, void(GLenum target,
3016 GLuint texture_id));
3017 MOCK_METHOD3(texParameteri, void(GLenum target,
3018 GLenum pname,
3019 GLint param));
3020 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
3021 GLint width,
3022 GLint height,
3023 GLuint ioSurfaceId,
3024 GLuint plane));
3025 MOCK_METHOD4(drawElements, void(GLenum mode,
3026 GLsizei count,
3027 GLenum type,
3028 GLintptr offset));
3029 MOCK_METHOD1(deleteTexture, void(GLenum texture));
3030 MOCK_METHOD3(produceTextureDirectCHROMIUM,
3031 void(GLuint texture, GLenum target, const GLbyte* mailbox));
3034 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
3035 protected:
3036 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3037 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
3038 new MockIOSurfaceWebGraphicsContext3D);
3039 mock_context_ = mock_context_owned.get();
3041 if (delegating_renderer())
3042 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
3043 else
3044 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
3047 void SetupTree() override {
3048 LayerTreeHostTest::SetupTree();
3050 layer_tree_host()->root_layer()->SetIsDrawable(false);
3052 io_surface_id_ = 9;
3053 io_surface_size_ = gfx::Size(6, 7);
3055 scoped_refptr<IOSurfaceLayer> io_surface_layer =
3056 IOSurfaceLayer::Create(layer_settings());
3057 io_surface_layer->SetBounds(gfx::Size(10, 10));
3058 io_surface_layer->SetIsDrawable(true);
3059 io_surface_layer->SetContentsOpaque(true);
3060 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
3061 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
3064 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3066 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3067 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
3068 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
3070 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
3071 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
3072 .Times(AtLeast(1));
3073 EXPECT_CALL(*mock_context_,
3074 texParameteri(
3075 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
3076 .Times(1);
3077 EXPECT_CALL(*mock_context_,
3078 texParameteri(
3079 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
3080 .Times(1);
3081 EXPECT_CALL(*mock_context_,
3082 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
3083 GL_TEXTURE_POOL_CHROMIUM,
3084 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
3085 EXPECT_CALL(*mock_context_,
3086 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
3087 GL_TEXTURE_WRAP_S,
3088 GL_CLAMP_TO_EDGE)).Times(1);
3089 EXPECT_CALL(*mock_context_,
3090 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
3091 GL_TEXTURE_WRAP_T,
3092 GL_CLAMP_TO_EDGE)).Times(1);
3094 EXPECT_CALL(*mock_context_,
3095 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
3096 io_surface_size_.width(),
3097 io_surface_size_.height(),
3098 io_surface_id_,
3099 0)).Times(1);
3101 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
3104 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3105 LayerTreeHostImpl::FrameData* frame,
3106 DrawResult draw_result) override {
3107 Mock::VerifyAndClearExpectations(&mock_context_);
3108 ResourceProvider* resource_provider = host_impl->resource_provider();
3109 EXPECT_EQ(1u, resource_provider->num_resources());
3110 CHECK_EQ(1u, frame->render_passes.size());
3111 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
3112 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
3113 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
3114 const IOSurfaceDrawQuad* io_surface_draw_quad =
3115 IOSurfaceDrawQuad::MaterialCast(quad);
3116 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
3117 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
3118 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
3119 resource_provider->TargetForTesting(
3120 io_surface_draw_quad->io_surface_resource_id));
3122 if (delegating_renderer()) {
3123 // The io surface layer's resource should be sent to the parent.
3124 EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM(
3125 _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
3126 } else {
3127 // The io surface layer's texture is drawn.
3128 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
3129 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
3130 .Times(AtLeast(1));
3133 return draw_result;
3136 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
3137 Mock::VerifyAndClearExpectations(&mock_context_);
3139 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
3140 EndTest();
3143 void AfterTest() override {}
3145 int io_surface_id_;
3146 MockIOSurfaceWebGraphicsContext3D* mock_context_;
3147 gfx::Size io_surface_size_;
3150 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
3152 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
3153 public:
3154 void BeginTest() override {
3155 frame_ = 0;
3156 PostSetNeedsCommitToMainThread();
3159 // Round 1: commit + draw
3160 // Round 2: commit only (no draw/swap)
3161 // Round 3: draw only (no commit)
3163 void DidCommit() override {
3164 int commit = layer_tree_host()->source_frame_number();
3165 switch (commit) {
3166 case 2:
3167 // Round 2 done.
3168 EXPECT_EQ(1, frame_);
3169 layer_tree_host()->SetNeedsRedraw();
3170 break;
3174 void DidCompleteSwapBuffers() override {
3175 int commit = layer_tree_host()->source_frame_number();
3176 ++frame_;
3177 switch (frame_) {
3178 case 1:
3179 // Round 1 done.
3180 EXPECT_EQ(1, commit);
3181 layer_tree_host()->SetNeedsCommit();
3182 break;
3183 case 2:
3184 // Round 3 done.
3185 EXPECT_EQ(2, commit);
3186 EndTest();
3187 break;
3191 void AfterTest() override {}
3193 protected:
3194 int frame_;
3197 // Flaky on all platforms: http://crbug.com/327498
3198 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
3199 RunTest(true, true, true);
3202 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
3203 RunTest(true, false, true);
3206 class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest {
3207 public:
3208 void SetupTree() override {
3209 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
3210 root_layer_->SetIsDrawable(true);
3211 root_layer_->SetBounds(gfx::Size(50, 50));
3213 parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
3214 parent_layer_->SetIsDrawable(true);
3215 parent_layer_->SetBounds(gfx::Size(50, 50));
3216 parent_layer_->SetForceRenderSurface(true);
3218 child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
3219 child_layer_->SetIsDrawable(true);
3220 child_layer_->SetBounds(gfx::Size(50, 50));
3222 root_layer_->AddChild(parent_layer_);
3223 parent_layer_->AddChild(child_layer_);
3224 layer_tree_host()->SetRootLayer(root_layer_);
3226 LayerTreeHostTest::SetupTree();
3229 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3230 if (delegating_renderer()) {
3231 return FakeOutputSurface::CreateDelegatingSoftware(
3232 make_scoped_ptr(new SoftwareOutputDevice));
3233 } else {
3234 return FakeOutputSurface::CreateSoftware(
3235 make_scoped_ptr(new SoftwareOutputDevice));
3239 void BeginTest() override {
3240 PostSetNeedsCommitToMainThread();
3241 swap_count_ = 0;
3244 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3245 LayerTreeHostImpl::FrameData* frame_data,
3246 DrawResult draw_result) override {
3247 if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
3248 EXPECT_EQ(1u, frame_data->render_passes.size());
3249 // Has at least 3 quads for each layer.
3250 RenderPass* render_pass = frame_data->render_passes[0];
3251 EXPECT_GE(render_pass->quad_list.size(), 3u);
3252 } else {
3253 EXPECT_EQ(2u, frame_data->render_passes.size());
3255 // At least root layer quad in root render pass.
3256 EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u);
3257 // At least parent and child layer quads in parent render pass.
3258 EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u);
3260 return draw_result;
3263 void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3264 swap_count_++;
3265 switch (swap_count_) {
3266 case 1: {
3267 gfx::Transform identity;
3268 gfx::Rect empty_rect;
3269 bool resourceless_software_draw = true;
3270 host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect,
3271 empty_rect, identity,
3272 resourceless_software_draw);
3273 host_impl->SetFullRootLayerDamage();
3274 host_impl->SetNeedsRedraw();
3275 break;
3277 case 2:
3278 EndTest();
3279 break;
3280 default:
3281 NOTREACHED();
3285 void AfterTest() override {}
3287 private:
3288 FakeContentLayerClient client_;
3289 scoped_refptr<Layer> root_layer_;
3290 scoped_refptr<Layer> parent_layer_;
3291 scoped_refptr<Layer> child_layer_;
3292 int swap_count_;
3295 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw);
3297 // Test for UI Resource management.
3298 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3299 public:
3300 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
3302 void InitializeSettings(LayerTreeSettings* settings) override {
3303 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
3306 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3308 void DidCommit() override {
3309 int frame = layer_tree_host()->source_frame_number();
3310 switch (frame) {
3311 case 1:
3312 CreateResource();
3313 CreateResource();
3314 PostSetNeedsCommitToMainThread();
3315 break;
3316 case 2:
3317 // Usually ScopedUIResource are deleted from the manager in their
3318 // destructor. Here we just want to test that a direct call to
3319 // DeleteUIResource works.
3320 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3321 PostSetNeedsCommitToMainThread();
3322 break;
3323 case 3:
3324 // DeleteUIResource can be called with an invalid id.
3325 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3326 PostSetNeedsCommitToMainThread();
3327 break;
3328 case 4:
3329 CreateResource();
3330 CreateResource();
3331 PostSetNeedsCommitToMainThread();
3332 break;
3333 case 5:
3334 ClearResources();
3335 EndTest();
3336 break;
3340 void PerformTest(LayerTreeHostImpl* impl) {
3341 TestWebGraphicsContext3D* context = TestContext();
3343 int frame = impl->active_tree()->source_frame_number();
3344 switch (frame) {
3345 case 0:
3346 ASSERT_EQ(0u, context->NumTextures());
3347 break;
3348 case 1:
3349 // Created two textures.
3350 ASSERT_EQ(2u, context->NumTextures());
3351 break;
3352 case 2:
3353 // One texture left after one deletion.
3354 ASSERT_EQ(1u, context->NumTextures());
3355 break;
3356 case 3:
3357 // Resource manager state should not change when delete is called on an
3358 // invalid id.
3359 ASSERT_EQ(1u, context->NumTextures());
3360 break;
3361 case 4:
3362 // Creation after deletion: two more creates should total up to
3363 // three textures.
3364 ASSERT_EQ(3u, context->NumTextures());
3365 break;
3369 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3370 if (!impl->settings().impl_side_painting)
3371 PerformTest(impl);
3374 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3375 if (impl->settings().impl_side_painting)
3376 PerformTest(impl);
3379 void AfterTest() override {}
3381 private:
3382 // Must clear all resources before exiting.
3383 void ClearResources() {
3384 for (int i = 0; i < num_ui_resources_; i++)
3385 ui_resources_[i] = nullptr;
3388 void CreateResource() {
3389 ui_resources_[num_ui_resources_++] =
3390 FakeScopedUIResource::Create(layer_tree_host());
3393 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3394 int num_ui_resources_;
3397 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3399 class PushPropertiesCountingLayerImpl : public LayerImpl {
3400 public:
3401 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
3402 LayerTreeImpl* tree_impl, int id) {
3403 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
3406 ~PushPropertiesCountingLayerImpl() override {}
3408 void PushPropertiesTo(LayerImpl* layer) override {
3409 LayerImpl::PushPropertiesTo(layer);
3410 push_properties_count_++;
3411 // Push state to the active tree because we can only access it from there.
3412 static_cast<PushPropertiesCountingLayerImpl*>(
3413 layer)->push_properties_count_ = push_properties_count_;
3416 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3417 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3420 size_t push_properties_count() const { return push_properties_count_; }
3421 void reset_push_properties_count() { push_properties_count_ = 0; }
3423 private:
3424 size_t push_properties_count_;
3426 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
3427 : LayerImpl(tree_impl, id),
3428 push_properties_count_(0) {
3429 SetBounds(gfx::Size(1, 1));
3433 class PushPropertiesCountingLayer : public Layer {
3434 public:
3435 static scoped_refptr<PushPropertiesCountingLayer> Create(
3436 const LayerSettings& settings) {
3437 return new PushPropertiesCountingLayer(settings);
3440 void PushPropertiesTo(LayerImpl* layer) override {
3441 Layer::PushPropertiesTo(layer);
3442 push_properties_count_++;
3443 if (persist_needs_push_properties_)
3444 needs_push_properties_ = true;
3447 // Something to make this layer push properties, but no other layer.
3448 void MakePushProperties() { SetContentsOpaque(!contents_opaque()); }
3450 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3451 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3454 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
3456 size_t push_properties_count() const { return push_properties_count_; }
3457 void reset_push_properties_count() { push_properties_count_ = 0; }
3459 void set_persist_needs_push_properties(bool persist) {
3460 persist_needs_push_properties_ = persist;
3463 private:
3464 explicit PushPropertiesCountingLayer(const LayerSettings& settings)
3465 : Layer(settings),
3466 push_properties_count_(0),
3467 persist_needs_push_properties_(false) {
3468 SetBounds(gfx::Size(1, 1));
3470 ~PushPropertiesCountingLayer() override {}
3472 size_t push_properties_count_;
3473 bool persist_needs_push_properties_;
3476 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3477 protected:
3478 void BeginTest() override {
3479 num_commits_ = 0;
3480 expected_push_properties_root_ = 0;
3481 expected_push_properties_child_ = 0;
3482 expected_push_properties_grandchild_ = 0;
3483 expected_push_properties_child2_ = 0;
3484 expected_push_properties_other_root_ = 0;
3485 expected_push_properties_leaf_layer_ = 0;
3486 PostSetNeedsCommitToMainThread();
3489 void SetupTree() override {
3490 root_ = PushPropertiesCountingLayer::Create(layer_settings());
3491 root_->CreateRenderSurface();
3492 child_ = PushPropertiesCountingLayer::Create(layer_settings());
3493 child2_ = PushPropertiesCountingLayer::Create(layer_settings());
3494 grandchild_ = PushPropertiesCountingLayer::Create(layer_settings());
3495 leaf_always_pushing_layer_ =
3496 PushPropertiesCountingLayer::Create(layer_settings());
3497 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3499 root_->AddChild(child_);
3500 root_->AddChild(child2_);
3501 child_->AddChild(grandchild_);
3502 child2_->AddChild(leaf_always_pushing_layer_);
3504 other_root_ = PushPropertiesCountingLayer::Create(layer_settings());
3505 other_root_->CreateRenderSurface();
3507 // Don't set the root layer here.
3508 LayerTreeHostTest::SetupTree();
3511 void DidCommitAndDrawFrame() override {
3512 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count())
3513 << "num_commits: " << num_commits_;
3514 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count())
3515 << "num_commits: " << num_commits_;
3516 EXPECT_EQ(expected_push_properties_grandchild_,
3517 grandchild_->push_properties_count())
3518 << "num_commits: " << num_commits_;
3519 EXPECT_EQ(expected_push_properties_child2_,
3520 child2_->push_properties_count())
3521 << "num_commits: " << num_commits_;
3522 EXPECT_EQ(expected_push_properties_other_root_,
3523 other_root_->push_properties_count())
3524 << "num_commits: " << num_commits_;
3525 EXPECT_EQ(expected_push_properties_leaf_layer_,
3526 leaf_always_pushing_layer_->push_properties_count())
3527 << "num_commits: " << num_commits_;
3529 ++num_commits_;
3531 // The scrollbar layer always needs to be pushed.
3532 if (root_->layer_tree_host()) {
3533 EXPECT_TRUE(root_->descendant_needs_push_properties());
3534 EXPECT_FALSE(root_->needs_push_properties());
3536 if (child2_->layer_tree_host()) {
3537 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3538 EXPECT_FALSE(child2_->needs_push_properties());
3540 if (leaf_always_pushing_layer_->layer_tree_host()) {
3541 EXPECT_FALSE(
3542 leaf_always_pushing_layer_->descendant_needs_push_properties());
3543 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3546 // child_ and grandchild_ don't persist their need to push properties.
3547 if (child_->layer_tree_host()) {
3548 EXPECT_FALSE(child_->descendant_needs_push_properties());
3549 EXPECT_FALSE(child_->needs_push_properties());
3551 if (grandchild_->layer_tree_host()) {
3552 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3553 EXPECT_FALSE(grandchild_->needs_push_properties());
3556 if (other_root_->layer_tree_host()) {
3557 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3558 EXPECT_FALSE(other_root_->needs_push_properties());
3561 switch (num_commits_) {
3562 case 1:
3563 layer_tree_host()->SetRootLayer(root_);
3564 // Layers added to the tree get committed.
3565 ++expected_push_properties_root_;
3566 ++expected_push_properties_child_;
3567 ++expected_push_properties_grandchild_;
3568 ++expected_push_properties_child2_;
3569 break;
3570 case 2:
3571 layer_tree_host()->SetNeedsCommit();
3572 // No layers need commit.
3573 break;
3574 case 3:
3575 layer_tree_host()->SetRootLayer(other_root_);
3576 // Layers added to the tree get committed.
3577 ++expected_push_properties_other_root_;
3578 break;
3579 case 4:
3580 layer_tree_host()->SetRootLayer(root_);
3581 // Layers added to the tree get committed.
3582 ++expected_push_properties_root_;
3583 ++expected_push_properties_child_;
3584 ++expected_push_properties_grandchild_;
3585 ++expected_push_properties_child2_;
3586 break;
3587 case 5:
3588 layer_tree_host()->SetNeedsCommit();
3589 // No layers need commit.
3590 break;
3591 case 6:
3592 child_->RemoveFromParent();
3593 // No layers need commit.
3594 break;
3595 case 7:
3596 root_->AddChild(child_);
3597 // Layers added to the tree get committed.
3598 ++expected_push_properties_child_;
3599 ++expected_push_properties_grandchild_;
3600 break;
3601 case 8:
3602 grandchild_->RemoveFromParent();
3603 // No layers need commit.
3604 break;
3605 case 9:
3606 child_->AddChild(grandchild_);
3607 // Layers added to the tree get committed.
3608 ++expected_push_properties_grandchild_;
3609 break;
3610 case 10:
3611 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3612 // No layers need commit.
3613 break;
3614 case 11:
3615 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3616 // No layers need commit.
3617 break;
3618 case 12:
3619 child_->MakePushProperties();
3620 // The modified layer needs commit
3621 ++expected_push_properties_child_;
3622 break;
3623 case 13:
3624 child2_->MakePushProperties();
3625 // The modified layer needs commit
3626 ++expected_push_properties_child2_;
3627 break;
3628 case 14:
3629 child_->RemoveFromParent();
3630 root_->AddChild(child_);
3631 // Layers added to the tree get committed.
3632 ++expected_push_properties_child_;
3633 ++expected_push_properties_grandchild_;
3634 break;
3635 case 15:
3636 grandchild_->MakePushProperties();
3637 // The modified layer needs commit
3638 ++expected_push_properties_grandchild_;
3639 break;
3640 case 16:
3641 // SetNeedsDisplay does not always set needs commit (so call it
3642 // explicitly), but is a property change.
3643 child_->SetNeedsDisplay();
3644 ++expected_push_properties_child_;
3645 layer_tree_host()->SetNeedsCommit();
3646 break;
3647 case 17:
3648 EndTest();
3649 break;
3652 // The leaf layer always pushes.
3653 if (leaf_always_pushing_layer_->layer_tree_host())
3654 ++expected_push_properties_leaf_layer_;
3657 void AfterTest() override {}
3659 int num_commits_;
3660 FakeContentLayerClient client_;
3661 scoped_refptr<PushPropertiesCountingLayer> root_;
3662 scoped_refptr<PushPropertiesCountingLayer> child_;
3663 scoped_refptr<PushPropertiesCountingLayer> child2_;
3664 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3665 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3666 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3667 size_t expected_push_properties_root_;
3668 size_t expected_push_properties_child_;
3669 size_t expected_push_properties_child2_;
3670 size_t expected_push_properties_grandchild_;
3671 size_t expected_push_properties_other_root_;
3672 size_t expected_push_properties_leaf_layer_;
3675 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3677 class LayerTreeHostTestImplLayersPushProperties
3678 : public LayerTreeHostTestLayersPushProperties {
3679 protected:
3680 void BeginTest() override {
3681 expected_push_properties_root_impl_ = 0;
3682 expected_push_properties_child_impl_ = 0;
3683 expected_push_properties_grandchild_impl_ = 0;
3684 expected_push_properties_child2_impl_ = 0;
3685 expected_push_properties_grandchild2_impl_ = 0;
3686 LayerTreeHostTestLayersPushProperties::BeginTest();
3689 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3690 // These commits are in response to the changes made in
3691 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3692 switch (num_commits_) {
3693 case 0:
3694 // Tree hasn't been setup yet don't bother to check anything.
3695 return;
3696 case 1:
3697 // Root gets set up, Everyone is initialized.
3698 ++expected_push_properties_root_impl_;
3699 ++expected_push_properties_child_impl_;
3700 ++expected_push_properties_grandchild_impl_;
3701 ++expected_push_properties_child2_impl_;
3702 ++expected_push_properties_grandchild2_impl_;
3703 break;
3704 case 2:
3705 // Tree doesn't change but the one leaf that always pushes is pushed.
3706 ++expected_push_properties_grandchild2_impl_;
3707 break;
3708 case 3:
3709 // Root is swapped here.
3710 // Clear the expected push properties the tree will be rebuilt.
3711 expected_push_properties_root_impl_ = 0;
3712 expected_push_properties_child_impl_ = 0;
3713 expected_push_properties_grandchild_impl_ = 0;
3714 expected_push_properties_child2_impl_ = 0;
3715 expected_push_properties_grandchild2_impl_ = 0;
3717 // Make sure the new root is pushed.
3718 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3719 host_impl->RootLayer())->push_properties_count());
3720 return;
3721 case 4:
3722 // Root is swapped back all of the layers in the tree get pushed.
3723 ++expected_push_properties_root_impl_;
3724 ++expected_push_properties_child_impl_;
3725 ++expected_push_properties_grandchild_impl_;
3726 ++expected_push_properties_child2_impl_;
3727 ++expected_push_properties_grandchild2_impl_;
3728 break;
3729 case 5:
3730 // Tree doesn't change but the one leaf that always pushes is pushed.
3731 ++expected_push_properties_grandchild2_impl_;
3732 break;
3733 case 6:
3734 // First child is removed. Structure of the tree changes here so swap
3735 // some of the values. child_impl becomes child2_impl.
3736 expected_push_properties_child_impl_ =
3737 expected_push_properties_child2_impl_;
3738 expected_push_properties_child2_impl_ = 0;
3739 // grandchild_impl becomes grandchild2_impl.
3740 expected_push_properties_grandchild_impl_ =
3741 expected_push_properties_grandchild2_impl_;
3742 expected_push_properties_grandchild2_impl_ = 0;
3744 // grandchild_impl is now the leaf that always pushes. It is pushed.
3745 ++expected_push_properties_grandchild_impl_;
3746 break;
3747 case 7:
3748 // The leaf that always pushes is pushed.
3749 ++expected_push_properties_grandchild_impl_;
3751 // Child is added back. New layers are initialized.
3752 ++expected_push_properties_grandchild2_impl_;
3753 ++expected_push_properties_child2_impl_;
3754 break;
3755 case 8:
3756 // Leaf is removed.
3757 expected_push_properties_grandchild2_impl_ = 0;
3759 // Always pushing.
3760 ++expected_push_properties_grandchild_impl_;
3761 break;
3762 case 9:
3763 // Leaf is added back
3764 ++expected_push_properties_grandchild2_impl_;
3766 // The leaf that always pushes is pushed.
3767 ++expected_push_properties_grandchild_impl_;
3768 break;
3769 case 10:
3770 // The leaf that always pushes is pushed.
3771 ++expected_push_properties_grandchild_impl_;
3772 break;
3773 case 11:
3774 // The leaf that always pushes is pushed.
3775 ++expected_push_properties_grandchild_impl_;
3776 break;
3777 case 12:
3778 // The leaf that always pushes is pushed.
3779 ++expected_push_properties_grandchild_impl_;
3781 // This child position was changed.
3782 ++expected_push_properties_child2_impl_;
3783 break;
3784 case 13:
3785 // The position of this child was changed.
3786 ++expected_push_properties_child_impl_;
3788 // The leaf that always pushes is pushed.
3789 ++expected_push_properties_grandchild_impl_;
3790 break;
3791 case 14:
3792 // Second child is removed from tree. Don't discard counts because
3793 // they are added back before commit.
3795 // The leaf that always pushes is pushed.
3796 ++expected_push_properties_grandchild_impl_;
3798 // Second child added back.
3799 ++expected_push_properties_child2_impl_;
3800 ++expected_push_properties_grandchild2_impl_;
3802 break;
3803 case 15:
3804 // The position of this child was changed.
3805 ++expected_push_properties_grandchild2_impl_;
3807 // The leaf that always pushes is pushed.
3808 ++expected_push_properties_grandchild_impl_;
3809 break;
3810 case 16:
3811 // Second child is invalidated with SetNeedsDisplay
3812 ++expected_push_properties_child2_impl_;
3814 // The leaf that always pushed is pushed.
3815 ++expected_push_properties_grandchild_impl_;
3816 break;
3819 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3820 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3821 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3822 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3823 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3825 // Pull the layers that we need from the tree assuming the same structure
3826 // as LayerTreeHostTestLayersPushProperties
3827 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3828 host_impl->RootLayer());
3830 if (root_impl_ && root_impl_->children().size() > 0) {
3831 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3832 root_impl_->children()[0]);
3834 if (child_impl_ && child_impl_->children().size() > 0)
3835 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3836 child_impl_->children()[0]);
3839 if (root_impl_ && root_impl_->children().size() > 1) {
3840 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3841 root_impl_->children()[1]);
3843 if (child2_impl_ && child2_impl_->children().size() > 0)
3844 leaf_always_pushing_layer_impl_ =
3845 static_cast<PushPropertiesCountingLayerImpl*>(
3846 child2_impl_->children()[0]);
3849 if (root_impl_)
3850 EXPECT_EQ(expected_push_properties_root_impl_,
3851 root_impl_->push_properties_count());
3852 if (child_impl_)
3853 EXPECT_EQ(expected_push_properties_child_impl_,
3854 child_impl_->push_properties_count());
3855 if (grandchild_impl_)
3856 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3857 grandchild_impl_->push_properties_count());
3858 if (child2_impl_)
3859 EXPECT_EQ(expected_push_properties_child2_impl_,
3860 child2_impl_->push_properties_count());
3861 if (leaf_always_pushing_layer_impl_)
3862 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3863 leaf_always_pushing_layer_impl_->push_properties_count());
3866 size_t expected_push_properties_root_impl_;
3867 size_t expected_push_properties_child_impl_;
3868 size_t expected_push_properties_child2_impl_;
3869 size_t expected_push_properties_grandchild_impl_;
3870 size_t expected_push_properties_grandchild2_impl_;
3873 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3874 RunTestWithImplSidePainting();
3877 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3878 : public LayerTreeHostTest {
3879 protected:
3880 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3882 void SetupTree() override {
3883 root_ = Layer::Create(layer_settings());
3884 root_->CreateRenderSurface();
3885 root_->SetBounds(gfx::Size(1, 1));
3887 bool paint_scrollbar = true;
3888 bool has_thumb = false;
3889 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3890 layer_settings(), paint_scrollbar, has_thumb, root_->id());
3892 root_->AddChild(scrollbar_layer_);
3894 layer_tree_host()->SetRootLayer(root_);
3895 LayerTreeHostTest::SetupTree();
3898 void DidCommitAndDrawFrame() override {
3899 switch (layer_tree_host()->source_frame_number()) {
3900 case 0:
3901 break;
3902 case 1: {
3903 // During update, the ignore_set_needs_commit_ bit is set to true to
3904 // avoid causing a second commit to be scheduled. If a property change
3905 // is made during this, however, it needs to be pushed in the upcoming
3906 // commit.
3907 scoped_ptr<base::AutoReset<bool>> ignore =
3908 scrollbar_layer_->IgnoreSetNeedsCommit();
3910 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3912 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3913 EXPECT_TRUE(root_->descendant_needs_push_properties());
3914 layer_tree_host()->SetNeedsCommit();
3916 scrollbar_layer_->reset_push_properties_count();
3917 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3918 break;
3920 case 2:
3921 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3922 EndTest();
3923 break;
3927 void AfterTest() override {}
3929 scoped_refptr<Layer> root_;
3930 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3933 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3935 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3936 protected:
3937 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3939 void SetupTree() override {
3940 root_ = PushPropertiesCountingLayer::Create(layer_settings());
3941 root_->CreateRenderSurface();
3942 child_ = PushPropertiesCountingLayer::Create(layer_settings());
3943 root_->AddChild(child_);
3945 layer_tree_host()->SetRootLayer(root_);
3946 LayerTreeHostTest::SetupTree();
3949 void DidCommitAndDrawFrame() override {
3950 switch (layer_tree_host()->source_frame_number()) {
3951 case 0:
3952 break;
3953 case 1: {
3954 // During update, the ignore_set_needs_commit_ bit is set to true to
3955 // avoid causing a second commit to be scheduled. If a property change
3956 // is made during this, however, it needs to be pushed in the upcoming
3957 // commit.
3958 EXPECT_FALSE(root_->needs_push_properties());
3959 EXPECT_FALSE(child_->needs_push_properties());
3960 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3961 root_->reset_push_properties_count();
3962 child_->reset_push_properties_count();
3963 child_->SetDrawsContent(true);
3964 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3965 EXPECT_EQ(0u, root_->push_properties_count());
3966 EXPECT_EQ(0u, child_->push_properties_count());
3967 EXPECT_TRUE(root_->needs_push_properties());
3968 EXPECT_TRUE(child_->needs_push_properties());
3969 break;
3971 case 2:
3972 EXPECT_EQ(1u, root_->push_properties_count());
3973 EXPECT_EQ(1u, child_->push_properties_count());
3974 EXPECT_FALSE(root_->needs_push_properties());
3975 EXPECT_FALSE(child_->needs_push_properties());
3976 EndTest();
3977 break;
3981 void AfterTest() override {}
3983 scoped_refptr<PushPropertiesCountingLayer> root_;
3984 scoped_refptr<PushPropertiesCountingLayer> child_;
3987 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3989 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3990 : public LayerTreeHostTest {
3991 protected:
3992 void BeginTest() override {
3993 expected_push_properties_root_ = 0;
3994 expected_push_properties_child_ = 0;
3995 expected_push_properties_grandchild1_ = 0;
3996 expected_push_properties_grandchild2_ = 0;
3997 expected_push_properties_grandchild3_ = 0;
3998 PostSetNeedsCommitToMainThread();
4001 void SetupTree() override {
4002 root_ = PushPropertiesCountingLayer::Create(layer_settings());
4003 root_->CreateRenderSurface();
4004 child_ = PushPropertiesCountingLayer::Create(layer_settings());
4005 grandchild1_ = PushPropertiesCountingLayer::Create(layer_settings());
4006 grandchild2_ = PushPropertiesCountingLayer::Create(layer_settings());
4007 grandchild3_ = PushPropertiesCountingLayer::Create(layer_settings());
4009 root_->AddChild(child_);
4010 child_->AddChild(grandchild1_);
4011 child_->AddChild(grandchild2_);
4012 child_->AddChild(grandchild3_);
4014 // Don't set the root layer here.
4015 LayerTreeHostTest::SetupTree();
4018 void AfterTest() override {}
4020 FakeContentLayerClient client_;
4021 scoped_refptr<PushPropertiesCountingLayer> root_;
4022 scoped_refptr<PushPropertiesCountingLayer> child_;
4023 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
4024 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
4025 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
4026 size_t expected_push_properties_root_;
4027 size_t expected_push_properties_child_;
4028 size_t expected_push_properties_grandchild1_;
4029 size_t expected_push_properties_grandchild2_;
4030 size_t expected_push_properties_grandchild3_;
4033 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
4034 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4035 protected:
4036 void DidCommitAndDrawFrame() override {
4037 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4038 switch (last_source_frame_number) {
4039 case 0:
4040 EXPECT_FALSE(root_->needs_push_properties());
4041 EXPECT_FALSE(root_->descendant_needs_push_properties());
4042 EXPECT_FALSE(child_->needs_push_properties());
4043 EXPECT_FALSE(child_->descendant_needs_push_properties());
4044 EXPECT_FALSE(grandchild1_->needs_push_properties());
4045 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4046 EXPECT_FALSE(grandchild2_->needs_push_properties());
4047 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4048 EXPECT_FALSE(grandchild3_->needs_push_properties());
4049 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4051 layer_tree_host()->SetRootLayer(root_);
4053 EXPECT_TRUE(root_->needs_push_properties());
4054 EXPECT_TRUE(root_->descendant_needs_push_properties());
4055 EXPECT_TRUE(child_->needs_push_properties());
4056 EXPECT_TRUE(child_->descendant_needs_push_properties());
4057 EXPECT_TRUE(grandchild1_->needs_push_properties());
4058 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4059 EXPECT_TRUE(grandchild2_->needs_push_properties());
4060 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4061 EXPECT_TRUE(grandchild3_->needs_push_properties());
4062 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4063 break;
4064 case 1:
4065 EndTest();
4066 break;
4071 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
4073 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
4074 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4075 protected:
4076 void DidCommitAndDrawFrame() override {
4077 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4078 switch (last_source_frame_number) {
4079 case 0:
4080 layer_tree_host()->SetRootLayer(root_);
4081 break;
4082 case 1:
4083 EXPECT_FALSE(root_->needs_push_properties());
4084 EXPECT_FALSE(root_->descendant_needs_push_properties());
4085 EXPECT_FALSE(child_->needs_push_properties());
4086 EXPECT_FALSE(child_->descendant_needs_push_properties());
4087 EXPECT_FALSE(grandchild1_->needs_push_properties());
4088 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4089 EXPECT_FALSE(grandchild2_->needs_push_properties());
4090 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4091 EXPECT_FALSE(grandchild3_->needs_push_properties());
4092 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4094 grandchild1_->RemoveFromParent();
4095 grandchild1_->SetPosition(gfx::Point(1, 1));
4097 EXPECT_FALSE(root_->needs_push_properties());
4098 EXPECT_FALSE(root_->descendant_needs_push_properties());
4099 EXPECT_FALSE(child_->needs_push_properties());
4100 EXPECT_FALSE(child_->descendant_needs_push_properties());
4101 EXPECT_FALSE(grandchild2_->needs_push_properties());
4102 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4103 EXPECT_FALSE(grandchild3_->needs_push_properties());
4104 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4106 child_->AddChild(grandchild1_);
4108 EXPECT_FALSE(root_->needs_push_properties());
4109 EXPECT_TRUE(root_->descendant_needs_push_properties());
4110 EXPECT_FALSE(child_->needs_push_properties());
4111 EXPECT_TRUE(child_->descendant_needs_push_properties());
4112 EXPECT_TRUE(grandchild1_->needs_push_properties());
4113 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4114 EXPECT_FALSE(grandchild2_->needs_push_properties());
4115 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4116 EXPECT_FALSE(grandchild3_->needs_push_properties());
4117 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4119 grandchild2_->SetPosition(gfx::Point(1, 1));
4121 EXPECT_FALSE(root_->needs_push_properties());
4122 EXPECT_TRUE(root_->descendant_needs_push_properties());
4123 EXPECT_FALSE(child_->needs_push_properties());
4124 EXPECT_TRUE(child_->descendant_needs_push_properties());
4125 EXPECT_TRUE(grandchild1_->needs_push_properties());
4126 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4127 EXPECT_TRUE(grandchild2_->needs_push_properties());
4128 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4129 EXPECT_FALSE(grandchild3_->needs_push_properties());
4130 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4132 // grandchild2_ will still need a push properties.
4133 grandchild1_->RemoveFromParent();
4135 EXPECT_FALSE(root_->needs_push_properties());
4136 EXPECT_TRUE(root_->descendant_needs_push_properties());
4137 EXPECT_FALSE(child_->needs_push_properties());
4138 EXPECT_TRUE(child_->descendant_needs_push_properties());
4140 // grandchild3_ does not need a push properties, so recursing should
4141 // no longer be needed.
4142 grandchild2_->RemoveFromParent();
4144 EXPECT_FALSE(root_->needs_push_properties());
4145 EXPECT_FALSE(root_->descendant_needs_push_properties());
4146 EXPECT_FALSE(child_->needs_push_properties());
4147 EXPECT_FALSE(child_->descendant_needs_push_properties());
4148 EndTest();
4149 break;
4154 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
4156 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
4157 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4158 protected:
4159 void DidCommitAndDrawFrame() override {
4160 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4161 switch (last_source_frame_number) {
4162 case 0:
4163 layer_tree_host()->SetRootLayer(root_);
4164 grandchild1_->set_persist_needs_push_properties(true);
4165 grandchild2_->set_persist_needs_push_properties(true);
4166 break;
4167 case 1:
4168 EXPECT_FALSE(root_->needs_push_properties());
4169 EXPECT_TRUE(root_->descendant_needs_push_properties());
4170 EXPECT_FALSE(child_->needs_push_properties());
4171 EXPECT_TRUE(child_->descendant_needs_push_properties());
4172 EXPECT_TRUE(grandchild1_->needs_push_properties());
4173 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4174 EXPECT_TRUE(grandchild2_->needs_push_properties());
4175 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4176 EXPECT_FALSE(grandchild3_->needs_push_properties());
4177 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4179 // grandchild2_ will still need a push properties.
4180 grandchild1_->RemoveFromParent();
4182 EXPECT_FALSE(root_->needs_push_properties());
4183 EXPECT_TRUE(root_->descendant_needs_push_properties());
4184 EXPECT_FALSE(child_->needs_push_properties());
4185 EXPECT_TRUE(child_->descendant_needs_push_properties());
4187 // grandchild3_ does not need a push properties, so recursing should
4188 // no longer be needed.
4189 grandchild2_->RemoveFromParent();
4191 EXPECT_FALSE(root_->needs_push_properties());
4192 EXPECT_FALSE(root_->descendant_needs_push_properties());
4193 EXPECT_FALSE(child_->needs_push_properties());
4194 EXPECT_FALSE(child_->descendant_needs_push_properties());
4195 EndTest();
4196 break;
4201 MULTI_THREAD_TEST_F(
4202 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
4204 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
4205 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4206 protected:
4207 void DidCommitAndDrawFrame() override {
4208 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4209 switch (last_source_frame_number) {
4210 case 0:
4211 layer_tree_host()->SetRootLayer(root_);
4212 break;
4213 case 1:
4214 EXPECT_FALSE(root_->needs_push_properties());
4215 EXPECT_FALSE(root_->descendant_needs_push_properties());
4216 EXPECT_FALSE(child_->needs_push_properties());
4217 EXPECT_FALSE(child_->descendant_needs_push_properties());
4218 EXPECT_FALSE(grandchild1_->needs_push_properties());
4219 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4220 EXPECT_FALSE(grandchild2_->needs_push_properties());
4221 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4222 EXPECT_FALSE(grandchild3_->needs_push_properties());
4223 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4225 // Change grandchildren while their parent is not in the tree.
4226 child_->RemoveFromParent();
4227 grandchild1_->SetPosition(gfx::Point(1, 1));
4228 grandchild2_->SetPosition(gfx::Point(1, 1));
4229 root_->AddChild(child_);
4231 EXPECT_FALSE(root_->needs_push_properties());
4232 EXPECT_TRUE(root_->descendant_needs_push_properties());
4233 EXPECT_TRUE(child_->needs_push_properties());
4234 EXPECT_TRUE(child_->descendant_needs_push_properties());
4235 EXPECT_TRUE(grandchild1_->needs_push_properties());
4236 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4237 EXPECT_TRUE(grandchild2_->needs_push_properties());
4238 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4239 EXPECT_TRUE(grandchild3_->needs_push_properties());
4240 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4242 grandchild1_->RemoveFromParent();
4244 EXPECT_FALSE(root_->needs_push_properties());
4245 EXPECT_TRUE(root_->descendant_needs_push_properties());
4246 EXPECT_TRUE(child_->needs_push_properties());
4247 EXPECT_TRUE(child_->descendant_needs_push_properties());
4249 grandchild2_->RemoveFromParent();
4251 EXPECT_FALSE(root_->needs_push_properties());
4252 EXPECT_TRUE(root_->descendant_needs_push_properties());
4253 EXPECT_TRUE(child_->needs_push_properties());
4254 EXPECT_TRUE(child_->descendant_needs_push_properties());
4256 grandchild3_->RemoveFromParent();
4258 EXPECT_FALSE(root_->needs_push_properties());
4259 EXPECT_TRUE(root_->descendant_needs_push_properties());
4260 EXPECT_TRUE(child_->needs_push_properties());
4261 EXPECT_FALSE(child_->descendant_needs_push_properties());
4263 EndTest();
4264 break;
4269 MULTI_THREAD_TEST_F(
4270 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4272 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4273 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4274 protected:
4275 void DidCommitAndDrawFrame() override {
4276 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4277 switch (last_source_frame_number) {
4278 case 0:
4279 layer_tree_host()->SetRootLayer(root_);
4280 break;
4281 case 1:
4282 EXPECT_FALSE(root_->needs_push_properties());
4283 EXPECT_FALSE(root_->descendant_needs_push_properties());
4284 EXPECT_FALSE(child_->needs_push_properties());
4285 EXPECT_FALSE(child_->descendant_needs_push_properties());
4286 EXPECT_FALSE(grandchild1_->needs_push_properties());
4287 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4288 EXPECT_FALSE(grandchild2_->needs_push_properties());
4289 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4290 EXPECT_FALSE(grandchild3_->needs_push_properties());
4291 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4293 child_->SetPosition(gfx::Point(1, 1));
4294 grandchild1_->SetPosition(gfx::Point(1, 1));
4295 grandchild2_->SetPosition(gfx::Point(1, 1));
4297 EXPECT_FALSE(root_->needs_push_properties());
4298 EXPECT_TRUE(root_->descendant_needs_push_properties());
4299 EXPECT_TRUE(child_->needs_push_properties());
4300 EXPECT_TRUE(child_->descendant_needs_push_properties());
4301 EXPECT_TRUE(grandchild1_->needs_push_properties());
4302 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4303 EXPECT_TRUE(grandchild2_->needs_push_properties());
4304 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4305 EXPECT_FALSE(grandchild3_->needs_push_properties());
4306 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4308 grandchild1_->RemoveFromParent();
4310 EXPECT_FALSE(root_->needs_push_properties());
4311 EXPECT_TRUE(root_->descendant_needs_push_properties());
4312 EXPECT_TRUE(child_->needs_push_properties());
4313 EXPECT_TRUE(child_->descendant_needs_push_properties());
4315 grandchild2_->RemoveFromParent();
4317 EXPECT_FALSE(root_->needs_push_properties());
4318 EXPECT_TRUE(root_->descendant_needs_push_properties());
4319 EXPECT_TRUE(child_->needs_push_properties());
4320 EXPECT_FALSE(child_->descendant_needs_push_properties());
4322 child_->RemoveFromParent();
4324 EXPECT_FALSE(root_->needs_push_properties());
4325 EXPECT_FALSE(root_->descendant_needs_push_properties());
4327 EndTest();
4328 break;
4333 MULTI_THREAD_TEST_F(
4334 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4336 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4337 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4338 protected:
4339 void DidCommitAndDrawFrame() override {
4340 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4341 switch (last_source_frame_number) {
4342 case 0:
4343 layer_tree_host()->SetRootLayer(root_);
4344 break;
4345 case 1:
4346 EXPECT_FALSE(root_->needs_push_properties());
4347 EXPECT_FALSE(root_->descendant_needs_push_properties());
4348 EXPECT_FALSE(child_->needs_push_properties());
4349 EXPECT_FALSE(child_->descendant_needs_push_properties());
4350 EXPECT_FALSE(grandchild1_->needs_push_properties());
4351 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4352 EXPECT_FALSE(grandchild2_->needs_push_properties());
4353 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4354 EXPECT_FALSE(grandchild3_->needs_push_properties());
4355 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4357 grandchild1_->SetPosition(gfx::Point(1, 1));
4358 grandchild2_->SetPosition(gfx::Point(1, 1));
4359 child_->SetPosition(gfx::Point(1, 1));
4361 EXPECT_FALSE(root_->needs_push_properties());
4362 EXPECT_TRUE(root_->descendant_needs_push_properties());
4363 EXPECT_TRUE(child_->needs_push_properties());
4364 EXPECT_TRUE(child_->descendant_needs_push_properties());
4365 EXPECT_TRUE(grandchild1_->needs_push_properties());
4366 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4367 EXPECT_TRUE(grandchild2_->needs_push_properties());
4368 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4369 EXPECT_FALSE(grandchild3_->needs_push_properties());
4370 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4372 grandchild1_->RemoveFromParent();
4374 EXPECT_FALSE(root_->needs_push_properties());
4375 EXPECT_TRUE(root_->descendant_needs_push_properties());
4376 EXPECT_TRUE(child_->needs_push_properties());
4377 EXPECT_TRUE(child_->descendant_needs_push_properties());
4379 grandchild2_->RemoveFromParent();
4381 EXPECT_FALSE(root_->needs_push_properties());
4382 EXPECT_TRUE(root_->descendant_needs_push_properties());
4383 EXPECT_TRUE(child_->needs_push_properties());
4384 EXPECT_FALSE(child_->descendant_needs_push_properties());
4386 child_->RemoveFromParent();
4388 EXPECT_FALSE(root_->needs_push_properties());
4389 EXPECT_FALSE(root_->descendant_needs_push_properties());
4391 EndTest();
4392 break;
4397 MULTI_THREAD_TEST_F(
4398 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4400 // This test verifies that the tree activation callback is invoked correctly.
4401 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4402 public:
4403 LayerTreeHostTestTreeActivationCallback()
4404 : num_commits_(0), callback_count_(0) {}
4406 void BeginTest() override {
4407 EXPECT_TRUE(HasImplThread());
4408 PostSetNeedsCommitToMainThread();
4411 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4412 LayerTreeHostImpl::FrameData* frame_data,
4413 DrawResult draw_result) override {
4414 ++num_commits_;
4415 switch (num_commits_) {
4416 case 1:
4417 EXPECT_EQ(0, callback_count_);
4418 callback_count_ = 0;
4419 SetCallback(true);
4420 PostSetNeedsCommitToMainThread();
4421 break;
4422 case 2:
4423 EXPECT_EQ(1, callback_count_);
4424 callback_count_ = 0;
4425 SetCallback(false);
4426 PostSetNeedsCommitToMainThread();
4427 break;
4428 case 3:
4429 EXPECT_EQ(0, callback_count_);
4430 callback_count_ = 0;
4431 EndTest();
4432 break;
4433 default:
4434 ADD_FAILURE() << num_commits_;
4435 EndTest();
4436 break;
4438 return LayerTreeHostTest::PrepareToDrawOnThread(
4439 host_impl, frame_data, draw_result);
4442 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
4444 void SetCallback(bool enable) {
4445 output_surface()->SetTreeActivationCallback(
4446 enable
4447 ? base::Bind(
4448 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4449 base::Unretained(this))
4450 : base::Closure());
4453 void ActivationCallback() { ++callback_count_; }
4455 int num_commits_;
4456 int callback_count_;
4459 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4460 RunTest(true, false, true);
4463 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4464 RunTest(true, true, true);
4467 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4468 public:
4469 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4471 void BeginTest() override {
4472 ASSERT_TRUE(invalidate_layer_)
4473 << "Derived tests must set this in SetupTree";
4475 // One initial commit.
4476 PostSetNeedsCommitToMainThread();
4479 void DidCommitAndDrawFrame() override {
4480 // After commit, invalidate the layer. This should cause a commit.
4481 if (layer_tree_host()->source_frame_number() == 1)
4482 invalidate_layer_->SetNeedsDisplay();
4485 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4486 num_draws_++;
4487 if (impl->active_tree()->source_frame_number() == 1)
4488 EndTest();
4491 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4492 num_commits_++;
4495 void AfterTest() override {
4496 EXPECT_GE(2, num_commits_);
4497 EXPECT_GE(2, num_draws_);
4500 protected:
4501 scoped_refptr<Layer> invalidate_layer_;
4503 private:
4504 int num_commits_;
4505 int num_draws_;
4508 // VideoLayer must support being invalidated and then passing that along
4509 // to the compositor thread, even though no resources are updated in
4510 // response to that invalidation.
4511 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4512 public:
4513 void SetupTree() override {
4514 LayerTreeHostTest::SetupTree();
4515 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(
4516 layer_settings(), &provider_, media::VIDEO_ROTATION_0);
4517 video_layer->SetBounds(gfx::Size(10, 10));
4518 video_layer->SetIsDrawable(true);
4519 layer_tree_host()->root_layer()->AddChild(video_layer);
4521 invalidate_layer_ = video_layer;
4524 private:
4525 FakeVideoFrameProvider provider_;
4528 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4530 // IOSurfaceLayer must support being invalidated and then passing that along
4531 // to the compositor thread, even though no resources are updated in
4532 // response to that invalidation.
4533 class LayerTreeHostTestIOSurfaceLayerInvalidate
4534 : public LayerInvalidateCausesDraw {
4535 public:
4536 void SetupTree() override {
4537 LayerTreeHostTest::SetupTree();
4538 scoped_refptr<IOSurfaceLayer> layer =
4539 IOSurfaceLayer::Create(layer_settings());
4540 layer->SetBounds(gfx::Size(10, 10));
4541 uint32_t fake_io_surface_id = 7;
4542 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4543 layer->SetIsDrawable(true);
4544 layer_tree_host()->root_layer()->AddChild(layer);
4546 invalidate_layer_ = layer;
4550 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4551 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4552 LayerTreeHostTestIOSurfaceLayerInvalidate);
4554 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4555 protected:
4556 void SetupTree() override {
4557 root_layer_ = Layer::Create(layer_settings());
4558 root_layer_->CreateRenderSurface();
4559 root_layer_->SetPosition(gfx::Point());
4560 root_layer_->SetBounds(gfx::Size(10, 10));
4562 parent_layer_ = SolidColorLayer::Create(layer_settings());
4563 parent_layer_->SetPosition(gfx::Point());
4564 parent_layer_->SetBounds(gfx::Size(10, 10));
4565 parent_layer_->SetIsDrawable(true);
4566 root_layer_->AddChild(parent_layer_);
4568 child_layer_ = SolidColorLayer::Create(layer_settings());
4569 child_layer_->SetPosition(gfx::Point());
4570 child_layer_->SetBounds(gfx::Size(10, 10));
4571 child_layer_->SetIsDrawable(true);
4572 parent_layer_->AddChild(child_layer_);
4574 layer_tree_host()->SetRootLayer(root_layer_);
4575 LayerTreeHostTest::SetupTree();
4578 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4580 void DidCommitAndDrawFrame() override {
4581 switch (layer_tree_host()->source_frame_number()) {
4582 case 1:
4583 // The layer type used does not need to push properties every frame.
4584 EXPECT_FALSE(child_layer_->needs_push_properties());
4586 // Change the bounds of the child layer, but make it skipped
4587 // by CalculateDrawProperties.
4588 parent_layer_->SetOpacity(0.f);
4589 child_layer_->SetBounds(gfx::Size(5, 5));
4590 break;
4591 case 2:
4592 // The bounds of the child layer were pushed to the impl side.
4593 EXPECT_FALSE(child_layer_->needs_push_properties());
4595 EndTest();
4596 break;
4600 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4601 LayerImpl* root = impl->active_tree()->root_layer();
4602 LayerImpl* parent = root->children()[0];
4603 LayerImpl* child = parent->children()[0];
4605 switch (impl->active_tree()->source_frame_number()) {
4606 case 1:
4607 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4608 break;
4612 void AfterTest() override {}
4614 scoped_refptr<Layer> root_layer_;
4615 scoped_refptr<SolidColorLayer> parent_layer_;
4616 scoped_refptr<SolidColorLayer> child_layer_;
4619 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4621 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4622 protected:
4623 void InitializeSettings(LayerTreeSettings* settings) override {
4624 settings->impl_side_painting = true;
4627 void SetupTree() override {
4628 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
4629 root_layer_->SetBounds(gfx::Size(10, 10));
4631 layer_tree_host()->SetRootLayer(root_layer_);
4632 LayerTreeHostTest::SetupTree();
4635 void BeginTest() override {
4636 // The viewport is empty, but we still need to update layers on the main
4637 // thread.
4638 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4639 PostSetNeedsCommitToMainThread();
4642 void DidCommit() override {
4643 // The layer should be updated even though the viewport is empty, so we
4644 // are capable of drawing it on the impl tree.
4645 EXPECT_GT(root_layer_->update_count(), 0u);
4646 EndTest();
4649 void AfterTest() override {}
4651 FakeContentLayerClient client_;
4652 scoped_refptr<FakePictureLayer> root_layer_;
4655 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4657 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4658 public:
4659 LayerTreeHostTestAbortEvictedTextures()
4660 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4662 protected:
4663 void SetupTree() override {
4664 scoped_refptr<SolidColorLayer> root_layer =
4665 SolidColorLayer::Create(layer_settings());
4666 root_layer->SetBounds(gfx::Size(200, 200));
4667 root_layer->SetIsDrawable(true);
4668 root_layer->CreateRenderSurface();
4670 layer_tree_host()->SetRootLayer(root_layer);
4671 LayerTreeHostTest::SetupTree();
4674 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4676 void WillBeginMainFrame() override {
4677 num_will_begin_main_frames_++;
4678 switch (num_will_begin_main_frames_) {
4679 case 2:
4680 // Send a redraw to the compositor thread. This will (wrongly) be
4681 // ignored unless aborting resets the texture state.
4682 layer_tree_host()->SetNeedsRedraw();
4683 break;
4687 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
4688 num_impl_commits_++;
4691 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4692 switch (impl->SourceAnimationFrameNumber()) {
4693 case 1:
4694 // Prevent draws until commit.
4695 impl->active_tree()->SetContentsTexturesPurged();
4696 EXPECT_FALSE(impl->CanDraw());
4697 // Trigger an abortable commit.
4698 impl->SetNeedsCommit();
4699 break;
4700 case 2:
4701 EndTest();
4702 break;
4706 void AfterTest() override {
4707 // Ensure that the commit was truly aborted.
4708 EXPECT_EQ(2, num_will_begin_main_frames_);
4709 EXPECT_EQ(1, num_impl_commits_);
4712 private:
4713 int num_will_begin_main_frames_;
4714 int num_impl_commits_;
4717 // Commits can only be aborted when using the thread proxy.
4718 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4720 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4721 protected:
4722 void InitializeSettings(LayerTreeSettings* settings) override {
4723 settings->impl_side_painting = true;
4724 settings->use_zero_copy = false;
4725 settings->use_one_copy = false;
4728 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4729 scoped_refptr<TestContextProvider> context_provider =
4730 TestContextProvider::Create();
4731 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
4732 if (delegating_renderer())
4733 return FakeOutputSurface::CreateDelegating3d(context_provider);
4734 else
4735 return FakeOutputSurface::Create3d(context_provider);
4738 void SetupTree() override {
4739 client_.set_fill_with_nonsolid_color(true);
4740 scoped_refptr<FakePictureLayer> root_layer =
4741 FakePictureLayer::Create(layer_settings(), &client_);
4742 root_layer->SetBounds(gfx::Size(1024, 1024));
4743 root_layer->SetIsDrawable(true);
4745 layer_tree_host()->SetRootLayer(root_layer);
4746 LayerTreeHostTest::SetupTree();
4749 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4751 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4752 TestWebGraphicsContext3D* context = TestContext();
4754 // Expect that the transfer buffer memory used is equal to the
4755 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4756 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
4757 EndTest();
4760 void AfterTest() override {}
4762 private:
4763 FakeContentLayerClient client_;
4766 // Impl-side painting is a multi-threaded compositor feature.
4767 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4769 // Test ensuring that memory limits are sent to the prioritized resource
4770 // manager.
4771 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4772 public:
4773 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4775 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4777 void WillCommit() override {
4778 // Some commits are aborted, so increment number of attempted commits here.
4779 num_commits_++;
4782 void DidCommit() override {
4783 switch (num_commits_) {
4784 case 1:
4785 // Verify default values.
4786 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4787 layer_tree_host()
4788 ->contents_texture_manager()
4789 ->MaxMemoryLimitBytes());
4790 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4791 layer_tree_host()
4792 ->contents_texture_manager()
4793 ->ExternalPriorityCutoff());
4794 PostSetNeedsCommitToMainThread();
4795 break;
4796 case 2:
4797 // The values should remain the same until the commit after the policy
4798 // is changed.
4799 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4800 layer_tree_host()
4801 ->contents_texture_manager()
4802 ->MaxMemoryLimitBytes());
4803 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4804 layer_tree_host()
4805 ->contents_texture_manager()
4806 ->ExternalPriorityCutoff());
4807 break;
4808 case 3:
4809 // Verify values were correctly passed.
4810 EXPECT_EQ(16u * 1024u * 1024u,
4811 layer_tree_host()
4812 ->contents_texture_manager()
4813 ->MaxMemoryLimitBytes());
4814 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4815 layer_tree_host()
4816 ->contents_texture_manager()
4817 ->ExternalPriorityCutoff());
4818 EndTest();
4819 break;
4820 case 4:
4821 // Make sure no extra commits happen.
4822 NOTREACHED();
4823 break;
4827 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4828 switch (num_commits_) {
4829 case 1:
4830 break;
4831 case 2:
4832 // This will trigger a commit because the priority cutoff has changed.
4833 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4834 16u * 1024u * 1024u,
4835 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4836 1000));
4837 break;
4838 case 3:
4839 // This will not trigger a commit because the priority cutoff has not
4840 // changed, and there is already enough memory for all allocations.
4841 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4842 32u * 1024u * 1024u,
4843 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4844 1000));
4845 break;
4846 case 4:
4847 NOTREACHED();
4848 break;
4852 void AfterTest() override {}
4854 private:
4855 int num_commits_;
4858 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4860 } // namespace
4862 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4863 : public LayerTreeHostTest {
4864 protected:
4865 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4866 : first_output_surface_memory_limit_(4321234),
4867 second_output_surface_memory_limit_(1234321) {}
4869 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4870 if (!first_context_provider_.get()) {
4871 first_context_provider_ = TestContextProvider::Create();
4872 } else {
4873 EXPECT_FALSE(second_context_provider_.get());
4874 second_context_provider_ = TestContextProvider::Create();
4877 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4878 ? second_context_provider_
4879 : first_context_provider_);
4880 scoped_ptr<FakeOutputSurface> output_surface;
4881 if (delegating_renderer())
4882 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4883 else
4884 output_surface = FakeOutputSurface::Create3d(provider);
4885 output_surface->SetMemoryPolicyToSetAtBind(
4886 make_scoped_ptr(new ManagedMemoryPolicy(
4887 second_context_provider_.get() ? second_output_surface_memory_limit_
4888 : first_output_surface_memory_limit_,
4889 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4890 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4891 return output_surface.Pass();
4894 void SetupTree() override {
4895 if (layer_tree_host()->settings().impl_side_painting)
4896 root_ = FakePictureLayer::Create(layer_settings(), &client_);
4897 else
4898 root_ = FakeContentLayer::Create(layer_settings(), &client_);
4899 root_->SetBounds(gfx::Size(20, 20));
4900 layer_tree_host()->SetRootLayer(root_);
4901 LayerTreeHostTest::SetupTree();
4904 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4906 void DidCommitAndDrawFrame() override {
4907 // Lost context sometimes takes two frames to recreate. The third frame
4908 // is sometimes aborted, so wait until the fourth frame to verify that
4909 // the memory has been set, and the fifth frame to end the test.
4910 if (layer_tree_host()->source_frame_number() < 5) {
4911 layer_tree_host()->SetNeedsCommit();
4912 } else if (layer_tree_host()->source_frame_number() == 5) {
4913 EndTest();
4917 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
4918 switch (impl->active_tree()->source_frame_number()) {
4919 case 1:
4920 EXPECT_EQ(first_output_surface_memory_limit_,
4921 impl->memory_allocation_limit_bytes());
4922 // Lose the output surface.
4923 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4924 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4925 break;
4926 case 4:
4927 EXPECT_EQ(second_output_surface_memory_limit_,
4928 impl->memory_allocation_limit_bytes());
4929 break;
4933 void AfterTest() override {}
4935 scoped_refptr<TestContextProvider> first_context_provider_;
4936 scoped_refptr<TestContextProvider> second_context_provider_;
4937 size_t first_output_surface_memory_limit_;
4938 size_t second_output_surface_memory_limit_;
4939 FakeContentLayerClient client_;
4940 scoped_refptr<Layer> root_;
4943 SINGLE_AND_MULTI_THREAD_TEST_F(
4944 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4946 struct TestSwapPromiseResult {
4947 TestSwapPromiseResult()
4948 : did_activate_called(false),
4949 did_swap_called(false),
4950 did_not_swap_called(false),
4951 dtor_called(false),
4952 reason(SwapPromise::COMMIT_FAILS) {}
4954 bool did_activate_called;
4955 bool did_swap_called;
4956 bool did_not_swap_called;
4957 bool dtor_called;
4958 SwapPromise::DidNotSwapReason reason;
4959 base::Lock lock;
4962 class TestSwapPromise : public SwapPromise {
4963 public:
4964 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4966 ~TestSwapPromise() override {
4967 base::AutoLock lock(result_->lock);
4968 result_->dtor_called = true;
4971 void DidActivate() override {
4972 base::AutoLock lock(result_->lock);
4973 EXPECT_FALSE(result_->did_activate_called);
4974 EXPECT_FALSE(result_->did_swap_called);
4975 EXPECT_FALSE(result_->did_not_swap_called);
4976 result_->did_activate_called = true;
4979 void DidSwap(CompositorFrameMetadata* metadata) override {
4980 base::AutoLock lock(result_->lock);
4981 EXPECT_TRUE(result_->did_activate_called);
4982 EXPECT_FALSE(result_->did_swap_called);
4983 EXPECT_FALSE(result_->did_not_swap_called);
4984 result_->did_swap_called = true;
4987 void DidNotSwap(DidNotSwapReason reason) override {
4988 base::AutoLock lock(result_->lock);
4989 EXPECT_FALSE(result_->did_swap_called);
4990 EXPECT_FALSE(result_->did_not_swap_called);
4991 EXPECT_FALSE(result_->did_activate_called &&
4992 reason != DidNotSwapReason::SWAP_FAILS);
4993 result_->did_not_swap_called = true;
4994 result_->reason = reason;
4997 int64 TraceId() const override { return 0; }
4999 private:
5000 // Not owned.
5001 TestSwapPromiseResult* result_;
5004 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
5005 protected:
5006 LayerTreeHostTestBreakSwapPromise()
5007 : commit_count_(0), commit_complete_count_(0) {}
5009 void WillBeginMainFrame() override {
5010 ASSERT_LE(commit_count_, 2);
5011 scoped_ptr<SwapPromise> swap_promise(
5012 new TestSwapPromise(&swap_promise_result_[commit_count_]));
5013 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5016 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5018 void DidCommit() override {
5019 commit_count_++;
5020 if (commit_count_ == 2) {
5021 // This commit will finish.
5022 layer_tree_host()->SetNeedsCommit();
5026 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5027 if (host_impl->pending_tree()) {
5028 int frame = host_impl->pending_tree()->source_frame_number();
5029 base::AutoLock lock(swap_promise_result_[frame].lock);
5030 EXPECT_FALSE(swap_promise_result_[frame].did_activate_called);
5031 EXPECT_FALSE(swap_promise_result_[frame].did_swap_called);
5035 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5036 int frame = host_impl->active_tree()->source_frame_number();
5037 base::AutoLock lock(swap_promise_result_[frame].lock);
5038 EXPECT_TRUE(swap_promise_result_[frame].did_activate_called);
5039 EXPECT_FALSE(swap_promise_result_[frame].did_swap_called);
5042 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5043 commit_complete_count_++;
5044 if (commit_complete_count_ == 1) {
5045 // This commit will be aborted because no actual update.
5046 PostSetNeedsUpdateLayersToMainThread();
5047 } else {
5048 EndTest();
5052 void AfterTest() override {
5053 // 3 commits are scheduled. 2 completes. 1 is aborted.
5054 EXPECT_EQ(commit_count_, 3);
5055 EXPECT_EQ(commit_complete_count_, 2);
5058 // The first commit completes and causes swap buffer which finishes
5059 // the promise.
5060 base::AutoLock lock(swap_promise_result_[0].lock);
5061 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5062 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5063 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5067 // The second commit is aborted since it contains no updates.
5068 base::AutoLock lock(swap_promise_result_[1].lock);
5069 EXPECT_FALSE(swap_promise_result_[1].did_activate_called);
5070 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5071 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5072 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
5073 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5077 // The last commit completes but it does not cause swap buffer because
5078 // there is no damage in the frame data.
5079 base::AutoLock lock(swap_promise_result_[2].lock);
5080 EXPECT_TRUE(swap_promise_result_[2].did_activate_called);
5081 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5082 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5083 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5084 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5088 int commit_count_;
5089 int commit_complete_count_;
5090 TestSwapPromiseResult swap_promise_result_[3];
5093 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
5095 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
5096 public:
5097 LayerTreeHostTestKeepSwapPromise() {}
5099 void BeginTest() override {
5100 layer_ = SolidColorLayer::Create(layer_settings());
5101 layer_->SetIsDrawable(true);
5102 layer_->SetBounds(gfx::Size(10, 10));
5103 layer_tree_host()->SetRootLayer(layer_);
5104 gfx::Size bounds(100, 100);
5105 layer_tree_host()->SetViewportSize(bounds);
5106 PostSetNeedsCommitToMainThread();
5109 void DidCommit() override {
5110 MainThreadTaskRunner()->PostTask(
5111 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
5112 base::Unretained(this)));
5115 void ChangeFrame() {
5116 switch (layer_tree_host()->source_frame_number()) {
5117 case 1:
5118 layer_->SetBounds(gfx::Size(10, 11));
5119 layer_tree_host()->QueueSwapPromise(
5120 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
5121 break;
5122 case 2:
5123 break;
5124 default:
5125 NOTREACHED();
5126 break;
5130 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5131 if (host_impl->pending_tree()) {
5132 if (host_impl->pending_tree()->source_frame_number() == 1) {
5133 base::AutoLock lock(swap_promise_result_.lock);
5134 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5135 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5136 SetCallback(true);
5137 } else {
5138 SetCallback(false);
5143 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5144 if (host_impl->active_tree()->source_frame_number() == 1) {
5145 base::AutoLock lock(swap_promise_result_.lock);
5146 EXPECT_TRUE(swap_promise_result_.did_activate_called);
5147 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5151 void ActivationCallback() {
5152 // DidActivate needs to happen before the tree activation callback.
5153 base::AutoLock lock(swap_promise_result_.lock);
5154 EXPECT_TRUE(swap_promise_result_.did_activate_called);
5157 void SetCallback(bool enable) {
5158 output_surface()->SetTreeActivationCallback(
5159 enable
5160 ? base::Bind(&LayerTreeHostTestKeepSwapPromise::ActivationCallback,
5161 base::Unretained(this))
5162 : base::Closure());
5165 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
5166 EXPECT_TRUE(result);
5167 if (host_impl->active_tree()->source_frame_number() >= 1) {
5168 // The commit changes layers so it should cause a swap.
5169 base::AutoLock lock(swap_promise_result_.lock);
5170 EXPECT_TRUE(swap_promise_result_.did_swap_called);
5171 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5172 EXPECT_TRUE(swap_promise_result_.dtor_called);
5173 EndTest();
5177 void AfterTest() override {}
5179 private:
5180 scoped_refptr<Layer> layer_;
5181 TestSwapPromiseResult swap_promise_result_;
5184 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
5186 class LayerTreeHostTestBreakSwapPromiseForVisibility
5187 : public LayerTreeHostTest {
5188 protected:
5189 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5191 void SetVisibleFalseAndQueueSwapPromise() {
5192 layer_tree_host()->SetVisible(false);
5193 scoped_ptr<SwapPromise> swap_promise(
5194 new TestSwapPromise(&swap_promise_result_));
5195 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5198 void ScheduledActionWillSendBeginMainFrame() override {
5199 MainThreadTaskRunner()->PostTask(
5200 FROM_HERE,
5201 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility
5202 ::SetVisibleFalseAndQueueSwapPromise,
5203 base::Unretained(this)));
5206 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5207 CommitEarlyOutReason reason) override {
5208 EndTest();
5211 void AfterTest() override {
5213 base::AutoLock lock(swap_promise_result_.lock);
5214 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5215 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5216 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5217 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5218 EXPECT_TRUE(swap_promise_result_.dtor_called);
5222 TestSwapPromiseResult swap_promise_result_;
5225 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
5227 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest {
5228 protected:
5229 LayerTreeHostTestBreakSwapPromiseForContext()
5230 : output_surface_lost_triggered_(false) {
5233 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5235 void LoseOutputSurfaceAndQueueSwapPromise() {
5236 layer_tree_host()->DidLoseOutputSurface();
5237 scoped_ptr<SwapPromise> swap_promise(
5238 new TestSwapPromise(&swap_promise_result_));
5239 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5242 void ScheduledActionWillSendBeginMainFrame() override {
5243 if (output_surface_lost_triggered_)
5244 return;
5245 output_surface_lost_triggered_ = true;
5247 MainThreadTaskRunner()->PostTask(
5248 FROM_HERE,
5249 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext
5250 ::LoseOutputSurfaceAndQueueSwapPromise,
5251 base::Unretained(this)));
5254 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5255 CommitEarlyOutReason reason) override {
5256 // This is needed so that the impl-thread state matches main-thread state.
5257 host_impl->DidLoseOutputSurface();
5258 EndTest();
5261 void AfterTest() override {
5263 base::AutoLock lock(swap_promise_result_.lock);
5264 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5265 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5266 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5267 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5268 EXPECT_TRUE(swap_promise_result_.dtor_called);
5272 bool output_surface_lost_triggered_;
5273 TestSwapPromiseResult swap_promise_result_;
5276 SINGLE_AND_MULTI_THREAD_TEST_F(
5277 LayerTreeHostTestBreakSwapPromiseForContext);
5279 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
5280 public:
5281 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
5282 LayerTreeHostImpl* layer_tree_host_impl,
5283 int* set_needs_commit_count,
5284 int* set_needs_redraw_count)
5285 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
5286 set_needs_commit_count_(set_needs_commit_count) {}
5288 ~SimpleSwapPromiseMonitor() override {}
5290 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
5292 void OnSetNeedsRedrawOnImpl() override {
5293 ADD_FAILURE() << "Should not get called on main thread.";
5296 void OnForwardScrollUpdateToMainThreadOnImpl() override {
5297 ADD_FAILURE() << "Should not get called on main thread.";
5300 private:
5301 int* set_needs_commit_count_;
5304 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
5305 public:
5306 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5308 void WillBeginMainFrame() override {
5309 if (TestEnded())
5310 return;
5312 int set_needs_commit_count = 0;
5313 int set_needs_redraw_count = 0;
5316 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5317 new SimpleSwapPromiseMonitor(layer_tree_host(),
5318 NULL,
5319 &set_needs_commit_count,
5320 &set_needs_redraw_count));
5321 layer_tree_host()->SetNeedsCommit();
5322 EXPECT_EQ(1, set_needs_commit_count);
5323 EXPECT_EQ(0, set_needs_redraw_count);
5326 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
5327 // monitored.
5328 layer_tree_host()->SetNeedsCommit();
5329 EXPECT_EQ(1, set_needs_commit_count);
5330 EXPECT_EQ(0, set_needs_redraw_count);
5333 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5334 new SimpleSwapPromiseMonitor(layer_tree_host(),
5335 NULL,
5336 &set_needs_commit_count,
5337 &set_needs_redraw_count));
5338 layer_tree_host()->SetNeedsUpdateLayers();
5339 EXPECT_EQ(2, set_needs_commit_count);
5340 EXPECT_EQ(0, set_needs_redraw_count);
5344 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5345 new SimpleSwapPromiseMonitor(layer_tree_host(),
5346 NULL,
5347 &set_needs_commit_count,
5348 &set_needs_redraw_count));
5349 layer_tree_host()->SetNeedsAnimate();
5350 EXPECT_EQ(3, set_needs_commit_count);
5351 EXPECT_EQ(0, set_needs_redraw_count);
5354 EndTest();
5357 void AfterTest() override {}
5360 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
5362 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
5363 : public LayerTreeHostTest {
5364 protected:
5365 void InitializeSettings(LayerTreeSettings* settings) override {
5366 settings->impl_side_painting = true;
5369 void SetupTree() override {
5370 LayerTreeHostTest::SetupTree();
5371 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
5374 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5376 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5377 host_impl->EvictAllUIResources();
5378 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
5379 // mode. Active tree should require high-res to draw after entering this
5380 // mode to ensure that high-res tiles are also required for a pending tree
5381 // to be activated.
5382 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5385 void DidCommit() override {
5386 int frame = layer_tree_host()->source_frame_number();
5387 switch (frame) {
5388 case 1:
5389 PostSetNeedsCommitToMainThread();
5390 break;
5391 case 2:
5392 ui_resource_ = nullptr;
5393 EndTest();
5394 break;
5398 void AfterTest() override {}
5400 FakeContentLayerClient client_;
5401 scoped_ptr<FakeScopedUIResource> ui_resource_;
5404 // This test is flaky, see http://crbug.com/386199
5405 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
5407 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
5408 protected:
5409 void InitializeSettings(LayerTreeSettings* settings) override {
5410 settings->impl_side_painting = true;
5412 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5413 EXPECT_FALSE(settings->gpu_rasterization_forced);
5416 void SetupTree() override {
5417 LayerTreeHostTest::SetupTree();
5419 scoped_refptr<PictureLayer> layer =
5420 PictureLayer::Create(layer_settings(), &layer_client_);
5421 layer->SetBounds(gfx::Size(10, 10));
5422 layer->SetIsDrawable(true);
5423 layer_tree_host()->root_layer()->AddChild(layer);
5426 void BeginTest() override {
5427 Layer* root = layer_tree_host()->root_layer();
5428 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5429 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5431 // Verify default values.
5432 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5433 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5434 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5435 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5437 // Setting gpu rasterization trigger does not enable gpu rasterization.
5438 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5439 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5441 PostSetNeedsCommitToMainThread();
5444 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5445 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5446 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5449 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5450 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5451 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5452 EndTest();
5455 void AfterTest() override {}
5457 FakeContentLayerClient layer_client_;
5460 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
5462 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
5463 protected:
5464 void InitializeSettings(LayerTreeSettings* settings) override {
5465 settings->impl_side_painting = true;
5467 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5468 settings->gpu_rasterization_enabled = true;
5471 void SetupTree() override {
5472 LayerTreeHostTest::SetupTree();
5474 scoped_refptr<PictureLayer> layer =
5475 PictureLayer::Create(layer_settings(), &layer_client_);
5476 layer->SetBounds(gfx::Size(10, 10));
5477 layer->SetIsDrawable(true);
5478 layer_tree_host()->root_layer()->AddChild(layer);
5481 void BeginTest() override {
5482 Layer* root = layer_tree_host()->root_layer();
5483 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5484 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5486 // Verify default values.
5487 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5488 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5489 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5490 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5492 // Gpu rasterization trigger is relevant.
5493 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5494 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5496 // Content-based veto is relevant as well.
5497 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5498 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5499 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5500 // Veto will take effect when layers are updated.
5501 // The results will be verified after commit is completed below.
5502 // Since we are manually marking picture pile as unsuitable,
5503 // make sure that the layer gets a chance to update.
5504 layer->SetNeedsDisplay();
5505 PostSetNeedsCommitToMainThread();
5508 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5509 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5510 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5513 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5514 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5515 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5516 EndTest();
5519 void AfterTest() override {}
5521 FakeContentLayerClient layer_client_;
5524 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
5526 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
5527 protected:
5528 void InitializeSettings(LayerTreeSettings* settings) override {
5529 ASSERT_TRUE(settings->impl_side_painting);
5531 EXPECT_FALSE(settings->gpu_rasterization_forced);
5532 settings->gpu_rasterization_forced = true;
5535 void SetupTree() override {
5536 LayerTreeHostTest::SetupTree();
5538 scoped_refptr<FakePictureLayer> layer =
5539 FakePictureLayer::Create(layer_settings(), &layer_client_);
5540 layer->SetBounds(gfx::Size(10, 10));
5541 layer->SetIsDrawable(true);
5542 layer_tree_host()->root_layer()->AddChild(layer);
5545 void BeginTest() override {
5546 Layer* root = layer_tree_host()->root_layer();
5547 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5548 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5550 // Verify default values.
5551 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5552 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5553 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5554 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5556 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
5557 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5558 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5560 // Content-based veto is irrelevant as well.
5561 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5562 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5563 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5564 // Veto will take effect when layers are updated.
5565 // The results will be verified after commit is completed below.
5566 // Since we are manually marking picture pile as unsuitable,
5567 // make sure that the layer gets a chance to update.
5568 layer->SetNeedsDisplay();
5569 PostSetNeedsCommitToMainThread();
5572 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5573 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
5574 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5577 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5578 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
5579 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5580 EndTest();
5583 void AfterTest() override {}
5585 FakeContentLayerClient layer_client_;
5588 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
5590 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
5591 public:
5592 LayerTreeHostTestContinuousPainting()
5593 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
5595 protected:
5596 enum { kExpectedNumCommits = 10 };
5598 void SetupTree() override {
5599 scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
5600 root_layer->SetBounds(bounds_);
5601 root_layer->CreateRenderSurface();
5603 if (layer_tree_host()->settings().impl_side_painting) {
5604 picture_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
5605 child_layer_ = picture_layer_.get();
5606 } else {
5607 content_layer_ =
5608 ContentLayerWithUpdateTracking::Create(layer_settings(), &client_);
5609 child_layer_ = content_layer_.get();
5611 child_layer_->SetBounds(bounds_);
5612 child_layer_->SetIsDrawable(true);
5613 root_layer->AddChild(child_layer_);
5615 layer_tree_host()->SetRootLayer(root_layer);
5616 layer_tree_host()->SetViewportSize(bounds_);
5617 LayerTreeHostTest::SetupTree();
5620 void BeginTest() override {
5621 MainThreadTaskRunner()->PostTask(
5622 FROM_HERE,
5623 base::Bind(
5624 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
5625 base::Unretained(this)));
5626 // Wait 50x longer than expected.
5627 double milliseconds_per_frame =
5628 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
5629 MainThreadTaskRunner()->PostDelayedTask(
5630 FROM_HERE,
5631 base::Bind(
5632 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
5633 base::Unretained(this)),
5634 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
5635 milliseconds_per_frame));
5638 void BeginMainFrame(const BeginFrameArgs& args) override {
5639 child_layer_->SetNeedsDisplay();
5642 void AfterTest() override {
5643 EXPECT_LE(kExpectedNumCommits, num_commits_);
5644 EXPECT_LE(kExpectedNumCommits, num_draws_);
5645 int update_count = content_layer_.get()
5646 ? content_layer_->PaintContentsCount()
5647 : picture_layer_->update_count();
5648 EXPECT_LE(kExpectedNumCommits, update_count);
5651 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5652 if (++num_draws_ == kExpectedNumCommits)
5653 EndTest();
5656 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5657 ++num_commits_;
5660 private:
5661 void EnableContinuousPainting() {
5662 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5663 debug_state.continuous_painting = true;
5664 layer_tree_host()->SetDebugState(debug_state);
5667 void DisableContinuousPainting() {
5668 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5669 debug_state.continuous_painting = false;
5670 layer_tree_host()->SetDebugState(debug_state);
5671 EndTest();
5674 int num_commits_;
5675 int num_draws_;
5676 const gfx::Size bounds_;
5677 FakeContentLayerClient client_;
5678 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5679 scoped_refptr<FakePictureLayer> picture_layer_;
5680 Layer* child_layer_;
5683 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5685 class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
5686 : public LayerTreeHostTest {
5687 public:
5688 enum { kExpectedNumImplFrames = 10 };
5690 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame()
5691 : will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {}
5693 void BeginTest() override {
5694 PostSetNeedsCommitToMainThread();
5697 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
5698 const BeginFrameArgs& args) override {
5699 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5700 EXPECT_FALSE(TestEnded());
5701 will_begin_impl_frame_count_++;
5704 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
5705 did_finish_impl_frame_count_++;
5706 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5708 // Request a number of commits to cause multiple impl frames. We expect to
5709 // get one more impl frames than the number of commits requested because
5710 // after a commit it takes one frame to become idle.
5711 if (did_finish_impl_frame_count_ < kExpectedNumImplFrames - 1)
5712 PostSetNeedsCommitToMainThread();
5715 void SendBeginMainFrameNotExpectedSoon() override { EndTest(); }
5717 void AfterTest() override {
5718 EXPECT_GT(will_begin_impl_frame_count_, 0);
5719 EXPECT_GT(did_finish_impl_frame_count_, 0);
5720 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
5722 // TODO(mithro): Figure out why the multithread version of this test
5723 // sometimes has one more frame then expected. Possibly related to
5724 // http://crbug.com/443185
5725 if (!HasImplThread()) {
5726 EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
5727 EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
5731 private:
5732 int will_begin_impl_frame_count_;
5733 int did_finish_impl_frame_count_;
5736 SINGLE_AND_MULTI_THREAD_TEST_F(
5737 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame);
5739 ::testing::AssertionResult AssertFrameTimeContained(
5740 const char* haystack_expr,
5741 const char* needle_expr,
5742 const std::vector<BeginFrameArgs>& haystack,
5743 const BeginFrameArgs& needle) {
5744 auto failure = ::testing::AssertionFailure()
5745 << needle.frame_time << " (" << needle_expr
5746 << ") not found in " << haystack_expr;
5748 if (haystack.size() == 0) {
5749 failure << " which is empty.";
5750 } else {
5751 failure << " which contains:\n";
5752 for (size_t i = 0; i < haystack.size(); i++) {
5753 if (haystack[i].frame_time == needle.frame_time)
5754 return ::testing::AssertionSuccess();
5755 failure << " [" << i << "]: " << haystack[i].frame_time << "\n";
5759 return failure;
5762 class LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime
5763 : public LayerTreeHostTest {
5764 public:
5765 LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime()
5766 : impl_frame_args_(), will_begin_impl_frame_count_(0) {}
5768 void BeginTest() override {
5769 // Kick off the test with a commit.
5770 PostSetNeedsCommitToMainThread();
5773 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
5774 const BeginFrameArgs& args) override {
5775 impl_frame_args_.push_back(args);
5777 will_begin_impl_frame_count_++;
5778 if (will_begin_impl_frame_count_ < 10)
5779 PostSetNeedsCommitToMainThread();
5782 void BeginMainFrame(const BeginFrameArgs& args) override {
5783 ASSERT_GT(impl_frame_args_.size(), 0U)
5784 << "BeginMainFrame called before BeginImplFrame called!";
5785 EXPECT_PRED_FORMAT2(AssertFrameTimeContained, impl_frame_args_, args);
5788 void SendBeginMainFrameNotExpectedSoon() override { EndTest(); }
5790 void AfterTest() override {
5791 EXPECT_GT(impl_frame_args_.size(), 0U);
5792 EXPECT_GE(will_begin_impl_frame_count_, 10);
5795 private:
5796 std::vector<BeginFrameArgs> impl_frame_args_;
5797 int will_begin_impl_frame_count_;
5800 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
5801 LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime);
5803 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
5804 public:
5805 LayerTreeHostTestSendBeginFramesToChildren()
5806 : begin_frame_sent_to_children_(false) {
5809 void BeginTest() override {
5810 // Kick off the test with a commit.
5811 PostSetNeedsCommitToMainThread();
5814 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5815 begin_frame_sent_to_children_ = true;
5816 EndTest();
5819 void DidBeginMainFrame() override {
5820 // Children requested BeginFrames.
5821 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5824 void AfterTest() override {
5825 // Ensure that BeginFrame message is sent to children during parent
5826 // scheduler handles its BeginFrame.
5827 EXPECT_TRUE(begin_frame_sent_to_children_);
5830 private:
5831 bool begin_frame_sent_to_children_;
5834 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
5836 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
5837 : public LayerTreeHostTest {
5838 public:
5839 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
5840 : begin_frame_sent_to_children_(false) {
5843 void InitializeSettings(LayerTreeSettings* settings) override {
5844 settings->use_external_begin_frame_source = true;
5847 void BeginTest() override {
5848 // Kick off the test with a commit.
5849 PostSetNeedsCommitToMainThread();
5852 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5853 begin_frame_sent_to_children_ = true;
5854 EndTest();
5857 void DidBeginMainFrame() override {
5858 // Children requested BeginFrames.
5859 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5862 void AfterTest() override {
5863 // Ensure that BeginFrame message is sent to children during parent
5864 // scheduler handles its BeginFrame.
5865 EXPECT_TRUE(begin_frame_sent_to_children_);
5868 private:
5869 bool begin_frame_sent_to_children_;
5872 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
5874 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5875 public:
5876 LayerTreeHostTestActivateOnInvisible()
5877 : activation_count_(0), visible_(true) {}
5879 void InitializeSettings(LayerTreeSettings* settings) override {
5880 settings->impl_side_painting = true;
5883 void BeginTest() override {
5884 // Kick off the test with a commit.
5885 PostSetNeedsCommitToMainThread();
5888 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5889 // Make sure we don't activate using the notify signal from tile manager.
5890 host_impl->BlockNotifyReadyToActivateForTesting(true);
5893 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5895 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5896 bool visible) override {
5897 visible_ = visible;
5899 // Once invisible, we can go visible again.
5900 if (!visible) {
5901 PostSetVisibleToMainThread(true);
5902 } else {
5903 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5904 EndTest();
5908 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5909 ++activation_count_;
5910 EXPECT_FALSE(visible_);
5913 void AfterTest() override {
5914 // Ensure we activated even though the signal was blocked.
5915 EXPECT_EQ(1, activation_count_);
5916 EXPECT_TRUE(visible_);
5919 private:
5920 int activation_count_;
5921 bool visible_;
5923 FakeContentLayerClient client_;
5924 scoped_refptr<FakePictureLayer> picture_layer_;
5927 // TODO(vmpstr): Enable with single thread impl-side painting.
5928 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5930 // Do a synchronous composite and assert that the swap promise succeeds.
5931 class LayerTreeHostTestSynchronousCompositeSwapPromise
5932 : public LayerTreeHostTest {
5933 public:
5934 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5936 void InitializeSettings(LayerTreeSettings* settings) override {
5937 settings->single_thread_proxy_scheduler = false;
5938 settings->use_zero_copy = true;
5941 void BeginTest() override {
5942 // Successful composite.
5943 scoped_ptr<SwapPromise> swap_promise0(
5944 new TestSwapPromise(&swap_promise_result_[0]));
5945 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5946 layer_tree_host()->Composite(base::TimeTicks::Now());
5948 // Fail to swap (no damage).
5949 scoped_ptr<SwapPromise> swap_promise1(
5950 new TestSwapPromise(&swap_promise_result_[1]));
5951 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5952 layer_tree_host()->SetNeedsCommit();
5953 layer_tree_host()->Composite(base::TimeTicks::Now());
5955 // Fail to draw (not visible).
5956 scoped_ptr<SwapPromise> swap_promise2(
5957 new TestSwapPromise(&swap_promise_result_[2]));
5958 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5959 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5960 layer_tree_host()->SetVisible(false);
5961 layer_tree_host()->Composite(base::TimeTicks::Now());
5963 EndTest();
5966 void DidCommit() override {
5967 commit_count_++;
5968 ASSERT_LE(commit_count_, 3);
5971 void AfterTest() override {
5972 EXPECT_EQ(3, commit_count_);
5974 // Initial swap promise should have succeded.
5976 base::AutoLock lock(swap_promise_result_[0].lock);
5977 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5978 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5979 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5982 // Second swap promise fails to swap.
5984 base::AutoLock lock(swap_promise_result_[1].lock);
5985 EXPECT_TRUE(swap_promise_result_[1].did_activate_called);
5986 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5987 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5988 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5989 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5992 // Third swap promises also fails to swap (and draw).
5994 base::AutoLock lock(swap_promise_result_[2].lock);
5995 EXPECT_TRUE(swap_promise_result_[2].did_activate_called);
5996 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5997 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5998 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5999 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
6003 int commit_count_;
6004 TestSwapPromiseResult swap_promise_result_[3];
6007 // Impl-side painting is not supported for synchronous compositing.
6008 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
6010 // Make sure page scale and top control deltas are applied to the client even
6011 // when the LayerTreeHost doesn't have a root layer.
6012 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
6013 : public LayerTreeHostTest {
6014 public:
6015 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
6016 : deltas_sent_to_client_(false) {}
6018 void BeginTest() override {
6019 layer_tree_host()->SetRootLayer(nullptr);
6020 info_.page_scale_delta = 3.14f;
6021 info_.top_controls_delta = 2.73f;
6023 PostSetNeedsCommitToMainThread();
6026 void BeginMainFrame(const BeginFrameArgs& args) override {
6027 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
6029 layer_tree_host()->ApplyScrollAndScale(&info_);
6030 EndTest();
6033 void ApplyViewportDeltas(const gfx::Vector2dF& inner,
6034 const gfx::Vector2dF& outer,
6035 const gfx::Vector2dF& elastic_overscroll_delta,
6036 float scale_delta,
6037 float top_controls_delta) override {
6038 EXPECT_EQ(info_.page_scale_delta, scale_delta);
6039 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
6040 deltas_sent_to_client_ = true;
6043 void AfterTest() override {
6044 EXPECT_TRUE(deltas_sent_to_client_);
6047 ScrollAndScaleSet info_;
6048 bool deltas_sent_to_client_;
6051 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
6053 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
6054 protected:
6055 LayerTreeHostTestCrispUpAfterPinchEnds()
6056 : playback_allowed_event_(true, true) {}
6058 void SetupTree() override {
6059 frame_ = 1;
6060 posted_ = false;
6061 client_.set_fill_with_nonsolid_color(true);
6063 scoped_refptr<Layer> root = Layer::Create(layer_settings());
6064 root->SetBounds(gfx::Size(500, 500));
6066 scoped_refptr<Layer> pinch = Layer::Create(layer_settings());
6067 pinch->SetBounds(gfx::Size(500, 500));
6068 pinch->SetScrollClipLayerId(root->id());
6069 pinch->SetIsContainerForFixedPositionLayers(true);
6070 root->AddChild(pinch);
6072 scoped_ptr<FakePicturePile> pile(
6073 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6074 ImplSidePaintingSettings().default_tile_grid_size));
6075 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
6076 scoped_refptr<FakePictureLayer> layer =
6077 FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
6078 pile.Pass());
6079 layer->SetBounds(gfx::Size(500, 500));
6080 layer->SetContentsOpaque(true);
6081 // Avoid LCD text on the layer so we don't cause extra commits when we
6082 // pinch.
6083 layer->disable_lcd_text();
6084 pinch->AddChild(layer);
6086 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
6087 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6088 layer_tree_host()->SetRootLayer(root);
6089 LayerTreeHostTest::SetupTree();
6092 // Returns the delta scale of all quads in the frame's root pass from their
6093 // ideal, or 0 if they are not all the same.
6094 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6095 if (frame_data->has_no_damage)
6096 return 0.f;
6097 float frame_scale = 0.f;
6098 RenderPass* root_pass = frame_data->render_passes.back();
6099 for (const auto& draw_quad : root_pass->quad_list) {
6100 // Checkerboards mean an incomplete frame.
6101 if (draw_quad->material != DrawQuad::TILED_CONTENT)
6102 return 0.f;
6103 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
6104 float quad_scale =
6105 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6106 float transform_scale =
6107 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
6108 float scale = quad_scale / transform_scale;
6109 if (frame_scale != 0.f && frame_scale != scale)
6110 return 0.f;
6111 frame_scale = scale;
6113 return frame_scale;
6116 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6118 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6119 LayerTreeHostImpl::FrameData* frame_data,
6120 DrawResult draw_result) override {
6121 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6122 switch (frame_) {
6123 case 1:
6124 // Drew at page scale 1 before any pinching.
6125 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6126 EXPECT_EQ(1.f, quad_scale_delta);
6127 PostNextAfterDraw(host_impl);
6128 break;
6129 case 2:
6130 if (quad_scale_delta != 1.f)
6131 break;
6132 // Drew at page scale 1.5 after pinching in.
6133 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6134 EXPECT_EQ(1.f, quad_scale_delta);
6135 PostNextAfterDraw(host_impl);
6136 break;
6137 case 3:
6138 // By pinching out, we will create a new tiling and raster it. This may
6139 // cause some additional draws, though we should still be drawing with
6140 // the old 1.5 tiling.
6141 if (frame_data->has_no_damage)
6142 break;
6143 // Drew at page scale 1 with the 1.5 tiling while pinching out.
6144 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6145 EXPECT_EQ(1.5f, quad_scale_delta);
6146 // We don't PostNextAfterDraw here, instead we wait for the new tiling
6147 // to finish rastering so we don't get any noise in further steps.
6148 break;
6149 case 4:
6150 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
6151 // while waiting for texture uploads to complete.
6152 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6153 // This frame will not have any damage, since it's actually the same as
6154 // the last frame, and should contain no incomplete tiles. We just want
6155 // to make sure we drew here at least once after the pinch ended to be
6156 // sure that drawing after pinch doesn't leave us at the wrong scale
6157 EXPECT_TRUE(frame_data->has_no_damage);
6158 PostNextAfterDraw(host_impl);
6159 break;
6160 case 5:
6161 if (quad_scale_delta != 1.f)
6162 break;
6163 // Drew at scale 1 after texture uploads are done.
6164 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6165 EXPECT_EQ(1.f, quad_scale_delta);
6166 EndTest();
6167 break;
6169 return draw_result;
6172 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
6173 if (posted_)
6174 return;
6175 posted_ = true;
6176 ImplThreadTaskRunner()->PostDelayedTask(
6177 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
6178 base::Unretained(this), host_impl),
6179 // Use a delay to allow raster/upload to happen in between frames. This
6180 // should cause flakiness if we fail to block raster/upload when
6181 // desired.
6182 base::TimeDelta::FromMilliseconds(16 * 4));
6185 void Next(LayerTreeHostImpl* host_impl) {
6186 ++frame_;
6187 posted_ = false;
6188 switch (frame_) {
6189 case 2:
6190 // Pinch zoom in.
6191 host_impl->PinchGestureBegin();
6192 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6193 host_impl->PinchGestureEnd();
6194 break;
6195 case 3:
6196 // Pinch zoom back to 1.f but don't end it.
6197 host_impl->PinchGestureBegin();
6198 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
6199 break;
6200 case 4:
6201 // End the pinch, but delay tile production.
6202 playback_allowed_event_.Reset();
6203 host_impl->PinchGestureEnd();
6204 break;
6205 case 5:
6206 // Let tiles complete.
6207 playback_allowed_event_.Signal();
6208 break;
6212 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6213 const Tile* tile) override {
6214 if (frame_ == 3) {
6215 // On frame 3, we will have a lower res tile complete for the pinch-out
6216 // gesture even though it's not displayed. We wait for it here to prevent
6217 // flakiness.
6218 EXPECT_EQ(0.75f, tile->contents_scale());
6219 PostNextAfterDraw(host_impl);
6221 // On frame_ == 4, we are preventing texture uploads from completing,
6222 // so this verifies they are not completing before frame_ == 5.
6223 // Flaky failures here indicate we're failing to prevent uploads from
6224 // completing.
6225 EXPECT_NE(4, frame_) << tile->contents_scale();
6228 void AfterTest() override {}
6230 FakeContentLayerClient client_;
6231 int frame_;
6232 bool posted_;
6233 base::WaitableEvent playback_allowed_event_;
6236 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
6238 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
6239 : public LayerTreeHostTestCrispUpAfterPinchEnds {
6240 protected:
6241 void InitializeSettings(LayerTreeSettings* settings) override {
6242 settings->use_one_copy = true;
6245 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
6246 scoped_ptr<TestWebGraphicsContext3D> context3d =
6247 TestWebGraphicsContext3D::Create();
6248 context3d->set_support_image(true);
6249 context3d->set_support_sync_query(true);
6250 #if defined(OS_MACOSX)
6251 context3d->set_support_texture_rectangle(true);
6252 #endif
6254 if (delegating_renderer())
6255 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
6256 else
6257 return FakeOutputSurface::Create3d(context3d.Pass());
6261 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
6263 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
6264 protected:
6265 RasterizeWithGpuRasterizationCreatesResources() {}
6267 void InitializeSettings(LayerTreeSettings* settings) override {
6268 settings->impl_side_painting = true;
6269 settings->gpu_rasterization_forced = true;
6272 void SetupTree() override {
6273 client_.set_fill_with_nonsolid_color(true);
6275 scoped_refptr<Layer> root = Layer::Create(layer_settings());
6276 root->SetBounds(gfx::Size(500, 500));
6278 scoped_ptr<FakePicturePile> pile(
6279 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6280 ImplSidePaintingSettings().default_tile_grid_size));
6281 scoped_refptr<FakePictureLayer> layer =
6282 FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
6283 pile.Pass());
6284 layer->SetBounds(gfx::Size(500, 500));
6285 layer->SetContentsOpaque(true);
6286 root->AddChild(layer);
6288 layer_tree_host()->SetRootLayer(root);
6289 LayerTreeHostTest::SetupTree();
6292 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6294 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6295 LayerTreeHostImpl::FrameData* frame_data,
6296 DrawResult draw_result) override {
6297 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
6298 EndTest();
6299 return draw_result;
6301 void AfterTest() override {}
6303 FakeContentLayerClient client_;
6306 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
6308 class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
6309 protected:
6310 GpuRasterizationRasterizesBorderTiles() : viewport_size_(1024, 2048) {}
6312 void InitializeSettings(LayerTreeSettings* settings) override {
6313 settings->impl_side_painting = true;
6314 settings->gpu_rasterization_enabled = true;
6315 settings->gpu_rasterization_forced = true;
6318 void SetupTree() override {
6319 client_.set_fill_with_nonsolid_color(true);
6321 scoped_ptr<FakePicturePile> pile(
6322 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6323 ImplSidePaintingSettings().default_tile_grid_size));
6324 scoped_refptr<FakePictureLayer> root =
6325 FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
6326 pile.Pass());
6327 root->SetBounds(gfx::Size(10000, 10000));
6328 root->SetContentsOpaque(true);
6330 layer_tree_host()->SetRootLayer(root);
6331 LayerTreeHostTest::SetupTree();
6332 layer_tree_host()->SetViewportSize(viewport_size_);
6335 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6337 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6338 LayerTreeHostImpl::FrameData* frame_data,
6339 DrawResult draw_result) override {
6340 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources());
6341 EndTest();
6342 return draw_result;
6345 void AfterTest() override {}
6347 private:
6348 FakeContentLayerClient client_;
6349 gfx::Size viewport_size_;
6352 MULTI_THREAD_IMPL_TEST_F(GpuRasterizationRasterizesBorderTiles);
6354 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
6355 : public LayerTreeHostTest {
6356 protected:
6357 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
6358 : playback_allowed_event_(true, true) {}
6360 void InitializeSettings(LayerTreeSettings* settings) override {
6361 settings->impl_side_painting = true;
6364 void SetupTree() override {
6365 step_ = 1;
6366 continuous_draws_ = 0;
6367 client_.set_fill_with_nonsolid_color(true);
6369 scoped_refptr<Layer> root = Layer::Create(layer_settings());
6370 root->SetBounds(gfx::Size(500, 500));
6372 scoped_refptr<Layer> pinch = Layer::Create(layer_settings());
6373 pinch->SetBounds(gfx::Size(500, 500));
6374 pinch->SetScrollClipLayerId(root->id());
6375 pinch->SetIsContainerForFixedPositionLayers(true);
6376 root->AddChild(pinch);
6378 scoped_ptr<FakePicturePile> pile(
6379 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6380 ImplSidePaintingSettings().default_tile_grid_size));
6381 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
6382 scoped_refptr<FakePictureLayer> layer =
6383 FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
6384 pile.Pass());
6385 layer->SetBounds(gfx::Size(500, 500));
6386 layer->SetContentsOpaque(true);
6387 // Avoid LCD text on the layer so we don't cause extra commits when we
6388 // pinch.
6389 layer->disable_lcd_text();
6390 pinch->AddChild(layer);
6392 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
6393 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6394 layer_tree_host()->SetRootLayer(root);
6395 LayerTreeHostTest::SetupTree();
6398 // Returns the delta scale of all quads in the frame's root pass from their
6399 // ideal, or 0 if they are not all the same.
6400 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6401 if (frame_data->has_no_damage)
6402 return 0.f;
6403 float frame_scale = 0.f;
6404 RenderPass* root_pass = frame_data->render_passes.back();
6405 for (const auto& draw_quad : root_pass->quad_list) {
6406 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
6407 float quad_scale =
6408 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6409 float transform_scale =
6410 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
6411 float scale = quad_scale / transform_scale;
6412 if (frame_scale != 0.f && frame_scale != scale)
6413 return 0.f;
6414 frame_scale = scale;
6416 return frame_scale;
6419 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6421 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6422 LayerTreeHostImpl::FrameData* frame_data,
6423 DrawResult draw_result) override {
6424 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6425 switch (step_) {
6426 case 1:
6427 // Drew at scale 1 before any pinching.
6428 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6429 EXPECT_EQ(1.f, quad_scale_delta);
6430 break;
6431 case 2:
6432 if (quad_scale_delta != 1.f / 1.5f)
6433 break;
6434 // Drew at scale 1 still though the ideal is 1.5.
6435 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6436 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6437 break;
6438 case 3:
6439 // Continuous draws are attempted.
6440 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6441 if (!frame_data->has_no_damage)
6442 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6443 break;
6444 case 4:
6445 if (quad_scale_delta != 1.f)
6446 break;
6447 // Drew at scale 1.5 when all the tiles completed.
6448 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6449 EXPECT_EQ(1.f, quad_scale_delta);
6450 break;
6451 case 5:
6452 // TODO(danakj): We get more draws before the NotifyReadyToDraw
6453 // because it is asynchronous from the previous draw and happens late.
6454 break;
6455 case 6:
6456 // NotifyReadyToDraw happened. If we were already inside a frame, we may
6457 // try to draw once more.
6458 break;
6459 case 7:
6460 NOTREACHED() << "No draws should happen once we have a complete frame.";
6461 break;
6463 return draw_result;
6466 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6467 switch (step_) {
6468 case 1:
6469 // Delay tile production.
6470 playback_allowed_event_.Reset();
6471 // Pinch zoom in to cause new tiles to be required.
6472 host_impl->PinchGestureBegin();
6473 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6474 host_impl->PinchGestureEnd();
6475 ++step_;
6476 break;
6477 case 2:
6478 ++step_;
6479 break;
6480 case 3:
6481 // We should continue to try draw while there are incomplete visible
6482 // tiles.
6483 if (++continuous_draws_ > 5) {
6484 // Allow the tiles to complete.
6485 playback_allowed_event_.Signal();
6486 ++step_;
6488 break;
6489 case 4:
6490 ++step_;
6491 break;
6492 case 5:
6493 // Waiting for NotifyReadyToDraw.
6494 break;
6495 case 6:
6496 // NotifyReadyToDraw happened.
6497 ++step_;
6498 break;
6502 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
6503 if (step_ == 5) {
6504 ++step_;
6505 // NotifyReadyToDraw has happened, we may draw once more, but should not
6506 // get any more draws after that. End the test after a timeout to watch
6507 // for any extraneous draws.
6508 // TODO(brianderson): We could remove this delay and instead wait until
6509 // the BeginFrameSource decides it doesn't need to send frames anymore,
6510 // or test that it already doesn't here.
6511 EndTestAfterDelayMs(16 * 4);
6515 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6516 const Tile* tile) override {
6517 // On step_ == 2, we are preventing texture uploads from completing,
6518 // so this verifies they are not completing before step_ == 3.
6519 // Flaky failures here indicate we're failing to prevent uploads from
6520 // completing.
6521 EXPECT_NE(2, step_);
6524 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
6526 FakeContentLayerClient client_;
6527 int step_;
6528 int continuous_draws_;
6529 base::WaitableEvent playback_allowed_event_;
6532 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
6534 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
6535 public:
6536 LayerTreeHostTestOneActivatePerPrepareTiles()
6537 : notify_ready_to_activate_count_(0u),
6538 scheduled_prepare_tiles_count_(0) {}
6540 void SetupTree() override {
6541 client_.set_fill_with_nonsolid_color(true);
6542 scoped_refptr<FakePictureLayer> root_layer =
6543 FakePictureLayer::Create(layer_settings(), &client_);
6544 root_layer->SetBounds(gfx::Size(1500, 1500));
6545 root_layer->SetIsDrawable(true);
6547 layer_tree_host()->SetRootLayer(root_layer);
6548 LayerTreeHostTest::SetupTree();
6551 void BeginTest() override {
6552 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
6553 PostSetNeedsCommitToMainThread();
6556 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
6557 bool success) override {
6558 ASSERT_TRUE(success);
6559 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
6562 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6563 ++notify_ready_to_activate_count_;
6564 EndTestAfterDelayMs(100);
6567 void ScheduledActionPrepareTiles() override {
6568 ++scheduled_prepare_tiles_count_;
6571 void AfterTest() override {
6572 // Expect at most a notification for each scheduled prepare tiles, plus one
6573 // for the initial commit (which doesn't go through scheduled actions).
6574 // The reason this is not an equality is because depending on timing, we
6575 // might get a prepare tiles but not yet get a notification that we're
6576 // ready to activate. The intent of a test is to ensure that we don't
6577 // get more than one notification per prepare tiles, so this is OK.
6578 EXPECT_LE(notify_ready_to_activate_count_,
6579 1u + scheduled_prepare_tiles_count_);
6582 protected:
6583 FakeContentLayerClient client_;
6584 size_t notify_ready_to_activate_count_;
6585 size_t scheduled_prepare_tiles_count_;
6588 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
6590 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
6591 : public LayerTreeHostTest {
6592 public:
6593 LayerTreeHostTestFrameTimingRequestsSaveTimestamps()
6594 : check_results_on_commit_(false) {}
6596 void SetupTree() override {
6597 scoped_refptr<FakePictureLayer> root_layer =
6598 FakePictureLayer::Create(layer_settings(), &client_);
6599 root_layer->SetBounds(gfx::Size(200, 200));
6600 root_layer->SetIsDrawable(true);
6602 scoped_refptr<FakePictureLayer> child_layer =
6603 FakePictureLayer::Create(layer_settings(), &client_);
6604 child_layer->SetBounds(gfx::Size(1500, 1500));
6605 child_layer->SetIsDrawable(true);
6607 std::vector<FrameTimingRequest> requests;
6608 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100)));
6609 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100)));
6610 child_layer->SetFrameTimingRequests(requests);
6612 root_layer->AddChild(child_layer);
6613 layer_tree_host()->SetRootLayer(root_layer);
6614 LayerTreeHostTest::SetupTree();
6617 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6619 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
6620 if (!check_results_on_commit_)
6621 return;
6623 // Since in reality, the events will be read by LayerTreeHost during commit,
6624 // we check the requests here to ensure that they are correct at the next
6625 // commit time (as opposed to checking in DrawLayers for instance).
6626 // TODO(vmpstr): Change this to read things from the main thread when this
6627 // information is propagated to the main thread (not yet implemented).
6628 FrameTimingTracker* tracker = host_impl->frame_timing_tracker();
6630 // Check composite events.
6632 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set =
6633 tracker->GroupCompositeCountsByRectId();
6634 EXPECT_EQ(1u, timing_set->size());
6635 auto rect_1_it = timing_set->find(1);
6636 EXPECT_TRUE(rect_1_it != timing_set->end());
6637 const auto& timing_events = rect_1_it->second;
6638 EXPECT_EQ(1u, timing_events.size());
6639 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6640 timing_events[0].frame_id);
6641 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6644 // Check main frame events.
6646 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> timing_set =
6647 tracker->GroupMainFrameCountsByRectId();
6648 EXPECT_EQ(2u, timing_set->size());
6649 auto rect_1_it = timing_set->find(1);
6650 EXPECT_TRUE(rect_1_it != timing_set->end());
6651 const auto& timing_events = rect_1_it->second;
6652 EXPECT_EQ(1u, timing_events.size());
6653 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6654 timing_events[0].frame_id);
6655 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6656 EXPECT_GT(timing_events[0].end_time, timing_events[0].timestamp);
6659 EndTest();
6662 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6663 check_results_on_commit_ = true;
6664 PostSetNeedsCommitToMainThread();
6667 void AfterTest() override {}
6669 private:
6670 FakeContentLayerClient client_;
6671 bool check_results_on_commit_;
6674 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
6676 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
6677 public:
6678 LayerTreeHostTestActivationCausesPrepareTiles()
6679 : scheduled_prepare_tiles_count_(0) {}
6681 void SetupTree() override {
6682 client_.set_fill_with_nonsolid_color(true);
6683 scoped_refptr<FakePictureLayer> root_layer =
6684 FakePictureLayer::Create(layer_settings(), &client_);
6685 root_layer->SetBounds(gfx::Size(150, 150));
6686 root_layer->SetIsDrawable(true);
6688 layer_tree_host()->SetRootLayer(root_layer);
6689 LayerTreeHostTest::SetupTree();
6692 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6694 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6695 // Ensure we've already activated.
6696 EXPECT_FALSE(impl->pending_tree());
6698 // After activating, we either need to prepare tiles, or we've already
6699 // called a scheduled prepare tiles. This is done because activation might
6700 // cause us to have to memory available (old active tree is gone), so we
6701 // need to ensure we will get a PrepareTiles call.
6702 if (!impl->prepare_tiles_needed())
6703 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
6704 EndTest();
6707 void ScheduledActionPrepareTiles() override {
6708 ++scheduled_prepare_tiles_count_;
6711 void AfterTest() override {}
6713 protected:
6714 FakeContentLayerClient client_;
6715 int scheduled_prepare_tiles_count_;
6718 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
6720 // This tests an assertion that DidCommit and WillCommit happen in the same
6721 // stack frame with no tasks that run between them. Various embedders of
6722 // cc depend on this logic. ui::Compositor holds a compositor lock between
6723 // these events and the inspector timeline wants begin/end CompositeLayers
6724 // to be properly nested with other begin/end events.
6725 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
6726 : public LayerTreeHostTest {
6727 public:
6728 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
6730 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6732 void WillCommit() override {
6733 MainThreadTaskRunner()->PostTask(
6734 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
6735 EndTestShouldRunAfterDidCommit,
6736 base::Unretained(this)));
6739 void EndTestShouldRunAfterDidCommit() {
6740 EXPECT_TRUE(did_commit_);
6741 EndTest();
6744 void DidCommit() override {
6745 EXPECT_FALSE(did_commit_);
6746 did_commit_ = true;
6749 void AfterTest() override { EXPECT_TRUE(did_commit_); }
6751 private:
6752 bool did_commit_;
6755 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
6757 // Verify that if a LayerImpl holds onto a copy request for multiple
6758 // frames that it will continue to have a render surface through
6759 // multiple commits, even though the Layer itself has no reason
6760 // to have a render surface.
6761 class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest {
6762 protected:
6763 void SetupTree() override {
6764 scoped_refptr<Layer> root = Layer::Create(layer_settings());
6765 root->CreateRenderSurface();
6766 root->SetBounds(gfx::Size(10, 10));
6767 child_ = Layer::Create(layer_settings());
6768 child_->SetBounds(gfx::Size(20, 20));
6769 root->AddChild(child_);
6771 layer_tree_host()->SetRootLayer(root);
6772 LayerTreeHostTest::SetupTree();
6775 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6777 void BeginTest() override {
6778 child_->RequestCopyOfOutput(
6779 CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback)));
6780 EXPECT_TRUE(child_->HasCopyRequest());
6781 PostSetNeedsCommitToMainThread();
6784 void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); }
6786 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6787 LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id());
6789 switch (host_impl->sync_tree()->source_frame_number()) {
6790 case 0:
6791 EXPECT_TRUE(child_impl->HasCopyRequest());
6792 EXPECT_TRUE(child_impl->render_surface());
6793 break;
6794 case 1:
6795 if (host_impl->proxy()->CommitToActiveTree()) {
6796 EXPECT_TRUE(child_impl->HasCopyRequest());
6797 EXPECT_TRUE(child_impl->render_surface());
6798 } else {
6799 EXPECT_FALSE(child_impl->HasCopyRequest());
6800 EXPECT_FALSE(child_impl->render_surface());
6802 break;
6803 default:
6804 NOTREACHED();
6805 break;
6809 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6810 LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id());
6811 EXPECT_TRUE(child_impl->HasCopyRequest());
6812 EXPECT_TRUE(child_impl->render_surface());
6814 switch (host_impl->active_tree()->source_frame_number()) {
6815 case 0:
6816 // Lose output surface to prevent drawing and cause another commit.
6817 host_impl->DidLoseOutputSurface();
6818 break;
6819 case 1:
6820 EndTest();
6821 break;
6822 default:
6823 NOTREACHED();
6824 break;
6828 void AfterTest() override {}
6830 private:
6831 scoped_refptr<Layer> child_;
6834 SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests);
6836 class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
6837 protected:
6838 void SetupTree() override {
6839 root = Layer::Create(layer_settings());
6840 child = Layer::Create(layer_settings());
6841 root->AddChild(child);
6842 layer_tree_host()->SetRootLayer(root);
6843 LayerTreeHostTest::SetupTree();
6846 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6848 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6850 void DidCommit() override {
6851 switch (layer_tree_host()->source_frame_number()) {
6852 case 1:
6853 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
6854 base::Bind(CopyOutputCallback)));
6855 EXPECT_TRUE(
6856 root->draw_properties().layer_or_descendant_has_copy_request);
6857 break;
6858 case 2:
6859 EXPECT_FALSE(
6860 root->draw_properties().layer_or_descendant_has_copy_request);
6861 EndTest();
6862 break;
6866 void AfterTest() override {}
6868 private:
6869 scoped_refptr<Layer> root;
6870 scoped_refptr<Layer> child;
6873 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
6875 class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
6876 protected:
6877 void SetupTree() override {
6878 // The masked layer has bounds 50x50, but it has a child that causes
6879 // the surface bounds to be larger. It also has a parent that clips the
6880 // masked layer and its surface.
6882 scoped_refptr<Layer> root = Layer::Create(layer_settings());
6884 scoped_refptr<Layer> clipping_layer = Layer::Create(layer_settings());
6885 root->AddChild(clipping_layer);
6887 scoped_refptr<FakePictureLayer> content_layer =
6888 FakePictureLayer::Create(layer_settings(), &client_);
6889 clipping_layer->AddChild(content_layer);
6891 scoped_refptr<FakePictureLayer> content_child_layer =
6892 FakePictureLayer::Create(layer_settings(), &client_);
6893 content_layer->AddChild(content_child_layer);
6895 scoped_refptr<FakePictureLayer> mask_layer =
6896 FakePictureLayer::Create(layer_settings(), &client_);
6897 content_layer->SetMaskLayer(mask_layer.get());
6899 gfx::Size root_size(100, 100);
6900 root->SetBounds(root_size);
6902 gfx::Rect clipping_rect(20, 10, 10, 20);
6903 clipping_layer->SetBounds(clipping_rect.size());
6904 clipping_layer->SetPosition(clipping_rect.origin());
6905 clipping_layer->SetMasksToBounds(true);
6907 gfx::Size layer_size(50, 50);
6908 content_layer->SetBounds(layer_size);
6909 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin());
6911 gfx::Size child_size(50, 50);
6912 content_child_layer->SetBounds(child_size);
6913 content_child_layer->SetPosition(gfx::Point(20, 0));
6915 gfx::Size mask_size(100, 100);
6916 mask_layer->SetBounds(mask_size);
6917 mask_layer->SetIsMask(true);
6919 layer_tree_host()->SetRootLayer(root);
6920 LayerTreeTest::SetupTree();
6923 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6925 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6926 LayerTreeHostImpl::FrameData* frame_data,
6927 DrawResult draw_result) override {
6928 EXPECT_EQ(2u, frame_data->render_passes.size());
6929 RenderPass* root_pass = frame_data->render_passes.back();
6930 EXPECT_EQ(2u, root_pass->quad_list.size());
6932 // There's a solid color quad under everything.
6933 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
6935 // The surface is clipped to 10x20.
6936 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
6937 const RenderPassDrawQuad* render_pass_quad =
6938 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
6939 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
6940 render_pass_quad->rect.ToString());
6941 // The masked layer is 50x50, but the surface size is 10x20. So the texture
6942 // coords in the mask are scaled by 10/50 and 20/50.
6943 // The surface is clipped to (20,10) so the mask texture coords are offset
6944 // by 20/50 and 10/50
6945 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
6946 .ToString(),
6947 render_pass_quad->MaskUVRect().ToString());
6948 EXPECT_EQ(gfx::Vector2dF(10.f / 50.f, 20.f / 50.f).ToString(),
6949 render_pass_quad->mask_uv_scale.ToString());
6950 EndTest();
6951 return draw_result;
6954 void AfterTest() override {}
6956 FakeContentLayerClient client_;
6959 SINGLE_AND_MULTI_THREAD_TEST_F(
6960 LayerTreeTestMaskLayerForSurfaceWithClippedLayer);
6962 class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
6963 protected:
6964 void InitializeSettings(LayerTreeSettings* settings) override {
6965 settings->layer_transforms_should_scale_layer_contents = true;
6968 void SetupTree() override {
6969 // Root
6970 // |
6971 // +-- Scaling Layer (adds a 2x scale)
6972 // |
6973 // +-- Content Layer
6974 // +--Mask
6976 scoped_refptr<Layer> root = Layer::Create(layer_settings());
6978 scoped_refptr<Layer> scaling_layer = Layer::Create(layer_settings());
6979 root->AddChild(scaling_layer);
6981 scoped_refptr<FakePictureLayer> content_layer =
6982 FakePictureLayer::Create(layer_settings(), &client_);
6983 scaling_layer->AddChild(content_layer);
6985 scoped_refptr<FakePictureLayer> mask_layer =
6986 FakePictureLayer::Create(layer_settings(), &client_);
6987 content_layer->SetMaskLayer(mask_layer.get());
6989 gfx::Size root_size(100, 100);
6990 root->SetBounds(root_size);
6992 gfx::Size scaling_layer_size(50, 50);
6993 scaling_layer->SetBounds(scaling_layer_size);
6994 gfx::Transform scale;
6995 scale.Scale(2.f, 2.f);
6996 scaling_layer->SetTransform(scale);
6998 content_layer->SetBounds(scaling_layer_size);
7000 mask_layer->SetBounds(scaling_layer_size);
7001 mask_layer->SetIsMask(true);
7003 layer_tree_host()->SetRootLayer(root);
7004 LayerTreeTest::SetupTree();
7007 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7009 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7010 LayerTreeHostImpl::FrameData* frame_data,
7011 DrawResult draw_result) override {
7012 EXPECT_EQ(2u, frame_data->render_passes.size());
7013 RenderPass* root_pass = frame_data->render_passes.back();
7014 EXPECT_EQ(2u, root_pass->quad_list.size());
7016 // There's a solid color quad under everything.
7017 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7019 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
7020 const RenderPassDrawQuad* render_pass_quad =
7021 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
7022 switch (host_impl->active_tree()->source_frame_number()) {
7023 case 0:
7024 // Check that the tree scaling is correctly taken into account for the
7025 // mask, that should fully map onto the quad.
7026 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
7027 render_pass_quad->rect.ToString());
7028 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7029 render_pass_quad->MaskUVRect().ToString());
7030 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7031 render_pass_quad->mask_uv_scale.ToString());
7032 break;
7033 case 1:
7034 // Applying a DSF should change the render surface size, but won't
7035 // affect which part of the mask is used.
7036 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
7037 render_pass_quad->rect.ToString());
7038 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7039 render_pass_quad->MaskUVRect().ToString());
7040 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7041 render_pass_quad->mask_uv_scale.ToString());
7042 EndTest();
7043 break;
7045 return draw_result;
7048 void DidCommit() override {
7049 switch (layer_tree_host()->source_frame_number()) {
7050 case 1:
7051 gfx::Size double_root_size(200, 200);
7052 layer_tree_host()->SetViewportSize(double_root_size);
7053 layer_tree_host()->SetDeviceScaleFactor(2.f);
7054 break;
7058 void AfterTest() override {}
7060 FakeContentLayerClient client_;
7063 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling);
7065 class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest {
7066 protected:
7067 void SetupTree() override {
7068 // The mask layer has bounds 100x100 but is attached to a layer with bounds
7069 // 50x50.
7071 scoped_refptr<Layer> root = Layer::Create(layer_settings());
7073 scoped_refptr<FakePictureLayer> content_layer =
7074 FakePictureLayer::Create(layer_settings(), &client_);
7075 root->AddChild(content_layer);
7077 scoped_refptr<FakePictureLayer> mask_layer =
7078 FakePictureLayer::Create(layer_settings(), &client_);
7079 content_layer->SetMaskLayer(mask_layer.get());
7081 gfx::Size root_size(100, 100);
7082 root->SetBounds(root_size);
7084 gfx::Size layer_size(50, 50);
7085 content_layer->SetBounds(layer_size);
7087 gfx::Size mask_size(100, 100);
7088 mask_layer->SetBounds(mask_size);
7089 mask_layer->SetIsMask(true);
7091 layer_tree_host()->SetRootLayer(root);
7092 LayerTreeTest::SetupTree();
7095 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7097 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7098 LayerTreeHostImpl::FrameData* frame_data,
7099 DrawResult draw_result) override {
7100 EXPECT_EQ(2u, frame_data->render_passes.size());
7101 RenderPass* root_pass = frame_data->render_passes.back();
7102 EXPECT_EQ(2u, root_pass->quad_list.size());
7104 // There's a solid color quad under everything.
7105 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7107 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
7108 const RenderPassDrawQuad* render_pass_quad =
7109 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
7110 switch (host_impl->active_tree()->source_frame_number()) {
7111 case 0:
7112 // Check that the mask fills the surface.
7113 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
7114 render_pass_quad->rect.ToString());
7115 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7116 render_pass_quad->MaskUVRect().ToString());
7117 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7118 render_pass_quad->mask_uv_scale.ToString());
7119 break;
7120 case 1:
7121 // Applying a DSF should change the render surface size, but won't
7122 // affect which part of the mask is used.
7123 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
7124 render_pass_quad->rect.ToString());
7125 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7126 render_pass_quad->MaskUVRect().ToString());
7127 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7128 render_pass_quad->mask_uv_scale.ToString());
7129 EndTest();
7130 break;
7132 return draw_result;
7135 void DidCommit() override {
7136 switch (layer_tree_host()->source_frame_number()) {
7137 case 1:
7138 gfx::Size double_root_size(200, 200);
7139 layer_tree_host()->SetViewportSize(double_root_size);
7140 layer_tree_host()->SetDeviceScaleFactor(2.f);
7141 break;
7145 void AfterTest() override {}
7147 FakeContentLayerClient client_;
7150 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithDifferentBounds);
7152 class LayerTreeTestReflectionMaskLayerWithDifferentBounds
7153 : public LayerTreeTest {
7154 protected:
7155 void SetupTree() override {
7156 // The replica's mask layer has bounds 100x100 but the replica is of a
7157 // layer with bounds 50x50.
7159 scoped_refptr<Layer> root = Layer::Create(layer_settings());
7161 scoped_refptr<FakePictureLayer> content_layer =
7162 FakePictureLayer::Create(layer_settings(), &client_);
7163 root->AddChild(content_layer);
7165 scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings());
7166 content_layer->SetReplicaLayer(replica_layer.get());
7168 scoped_refptr<FakePictureLayer> mask_layer =
7169 FakePictureLayer::Create(layer_settings(), &client_);
7170 replica_layer->SetMaskLayer(mask_layer.get());
7172 gfx::Size root_size(100, 100);
7173 root->SetBounds(root_size);
7175 gfx::Size layer_size(50, 50);
7176 content_layer->SetBounds(layer_size);
7178 gfx::Size mask_size(100, 100);
7179 mask_layer->SetBounds(mask_size);
7180 mask_layer->SetIsMask(true);
7182 layer_tree_host()->SetRootLayer(root);
7183 LayerTreeTest::SetupTree();
7186 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7188 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7189 LayerTreeHostImpl::FrameData* frame_data,
7190 DrawResult draw_result) override {
7191 EXPECT_EQ(2u, frame_data->render_passes.size());
7192 RenderPass* root_pass = frame_data->render_passes.back();
7193 EXPECT_EQ(3u, root_pass->quad_list.size());
7195 // There's a solid color quad under everything.
7196 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7198 EXPECT_EQ(DrawQuad::RENDER_PASS,
7199 root_pass->quad_list.ElementAt(1)->material);
7200 const RenderPassDrawQuad* render_pass_quad =
7201 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.ElementAt(1));
7202 switch (host_impl->active_tree()->source_frame_number()) {
7203 case 0:
7204 // Check that the mask fills the surface.
7205 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
7206 render_pass_quad->rect.ToString());
7207 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7208 render_pass_quad->MaskUVRect().ToString());
7209 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7210 render_pass_quad->mask_uv_scale.ToString());
7211 break;
7212 case 1:
7213 // Applying a DSF should change the render surface size, but won't
7214 // affect which part of the mask is used.
7215 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
7216 render_pass_quad->rect.ToString());
7217 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
7218 render_pass_quad->MaskUVRect().ToString());
7219 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
7220 render_pass_quad->mask_uv_scale.ToString());
7221 EndTest();
7222 break;
7224 return draw_result;
7227 void DidCommit() override {
7228 switch (layer_tree_host()->source_frame_number()) {
7229 case 1:
7230 gfx::Size double_root_size(200, 200);
7231 layer_tree_host()->SetViewportSize(double_root_size);
7232 layer_tree_host()->SetDeviceScaleFactor(2.f);
7233 break;
7237 void AfterTest() override {}
7239 FakeContentLayerClient client_;
7242 SINGLE_AND_MULTI_THREAD_TEST_F(
7243 LayerTreeTestReflectionMaskLayerWithDifferentBounds);
7245 class LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild
7246 : public LayerTreeTest {
7247 protected:
7248 void SetupTree() override {
7249 // The replica is of a layer with bounds 50x50, but it has a child that
7250 // causes the surface bounds to be larger.
7252 scoped_refptr<Layer> root = Layer::Create(layer_settings());
7254 scoped_refptr<FakePictureLayer> content_layer =
7255 FakePictureLayer::Create(layer_settings(), &client_);
7256 root->AddChild(content_layer);
7258 content_child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
7259 content_layer->AddChild(content_child_layer_);
7261 scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings());
7262 content_layer->SetReplicaLayer(replica_layer.get());
7264 scoped_refptr<FakePictureLayer> mask_layer =
7265 FakePictureLayer::Create(layer_settings(), &client_);
7266 replica_layer->SetMaskLayer(mask_layer.get());
7268 gfx::Size root_size(100, 100);
7269 root->SetBounds(root_size);
7271 gfx::Size layer_size(50, 50);
7272 content_layer->SetBounds(layer_size);
7273 content_child_layer_->SetBounds(layer_size);
7274 content_child_layer_->SetPosition(gfx::PointF(50.f, 0.f));
7276 gfx::Size mask_size(100, 100);
7277 mask_layer->SetBounds(mask_size);
7278 mask_layer->SetIsMask(true);
7280 layer_tree_host()->SetRootLayer(root);
7281 LayerTreeTest::SetupTree();
7284 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7286 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7287 LayerTreeHostImpl::FrameData* frame_data,
7288 DrawResult draw_result) override {
7289 EXPECT_EQ(2u, frame_data->render_passes.size());
7290 RenderPass* root_pass = frame_data->render_passes.back();
7291 EXPECT_EQ(3u, root_pass->quad_list.size());
7293 // There's a solid color quad under everything.
7294 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
7296 EXPECT_EQ(DrawQuad::RENDER_PASS,
7297 root_pass->quad_list.ElementAt(1)->material);
7298 const RenderPassDrawQuad* replica_quad =
7299 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.ElementAt(1));
7300 switch (host_impl->active_tree()->source_frame_number()) {
7301 case 0:
7302 // The surface is 100x50.
7303 // The mask covers the owning layer only.
7304 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
7305 replica_quad->rect.ToString());
7306 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
7307 replica_quad->MaskUVRect().ToString());
7308 EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
7309 replica_quad->mask_uv_scale.ToString());
7310 break;
7311 case 1:
7312 // The surface is 100x50 with its origin at (-50, 0).
7313 // The mask covers the owning layer only.
7314 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
7315 replica_quad->rect.ToString());
7316 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
7317 replica_quad->MaskUVRect().ToString());
7318 EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
7319 replica_quad->mask_uv_scale.ToString());
7320 EndTest();
7321 break;
7323 return draw_result;
7326 void DidCommit() override {
7327 switch (layer_tree_host()->source_frame_number()) {
7328 case 1:
7329 // Move the child to (-50, 0) instead. Now the mask should be moved to
7330 // still cover the layer being replicated.
7331 content_child_layer_->SetPosition(gfx::PointF(-50.f, 0.f));
7332 break;
7336 void AfterTest() override {}
7338 scoped_refptr<FakePictureLayer> content_child_layer_;
7339 FakeContentLayerClient client_;
7342 SINGLE_AND_MULTI_THREAD_TEST_F(
7343 LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild);
7345 } // namespace cc