Disable failing NavigationPopupTest
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blobb71972d929b076cd63cee04a02391da34910ff5a
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_client.h"
17 #include "cc/layers/io_surface_layer.h"
18 #include "cc/layers/layer_impl.h"
19 #include "cc/layers/painted_scrollbar_layer.h"
20 #include "cc/layers/picture_layer.h"
21 #include "cc/layers/solid_color_layer.h"
22 #include "cc/layers/video_layer.h"
23 #include "cc/output/begin_frame_args.h"
24 #include "cc/output/compositor_frame_ack.h"
25 #include "cc/output/copy_output_request.h"
26 #include "cc/output/copy_output_result.h"
27 #include "cc/output/output_surface.h"
28 #include "cc/output/swap_promise.h"
29 #include "cc/quads/draw_quad.h"
30 #include "cc/quads/io_surface_draw_quad.h"
31 #include "cc/quads/render_pass_draw_quad.h"
32 #include "cc/quads/tile_draw_quad.h"
33 #include "cc/test/fake_content_layer_client.h"
34 #include "cc/test/fake_layer_tree_host_client.h"
35 #include "cc/test/fake_output_surface.h"
36 #include "cc/test/fake_painted_scrollbar_layer.h"
37 #include "cc/test/fake_picture_layer.h"
38 #include "cc/test/fake_picture_layer_impl.h"
39 #include "cc/test/fake_picture_pile.h"
40 #include "cc/test/fake_proxy.h"
41 #include "cc/test/fake_scoped_ui_resource.h"
42 #include "cc/test/fake_video_frame_provider.h"
43 #include "cc/test/geometry_test_utils.h"
44 #include "cc/test/layer_tree_test.h"
45 #include "cc/test/test_shared_bitmap_manager.h"
46 #include "cc/test/test_web_graphics_context_3d.h"
47 #include "cc/trees/layer_tree_host_impl.h"
48 #include "cc/trees/layer_tree_impl.h"
49 #include "cc/trees/single_thread_proxy.h"
50 #include "cc/trees/thread_proxy.h"
51 #include "gpu/GLES2/gl2extchromium.h"
52 #include "skia/ext/refptr.h"
53 #include "testing/gmock/include/gmock/gmock.h"
54 #include "third_party/khronos/GLES2/gl2.h"
55 #include "third_party/khronos/GLES2/gl2ext.h"
56 #include "third_party/skia/include/core/SkPicture.h"
57 #include "ui/gfx/geometry/point_conversions.h"
58 #include "ui/gfx/geometry/size_conversions.h"
59 #include "ui/gfx/geometry/vector2d_conversions.h"
61 using testing::_;
62 using testing::AnyNumber;
63 using testing::AtLeast;
64 using testing::Mock;
66 namespace cc {
67 namespace {
69 class LayerTreeHostTest : public LayerTreeTest {};
71 class LayerTreeHostTestHasImplThreadTest : public LayerTreeHostTest {
72 public:
73 LayerTreeHostTestHasImplThreadTest() : threaded_(false) {}
75 void RunTest(bool threaded, bool delegating_renderer) override {
76 threaded_ = threaded;
77 LayerTreeHostTest::RunTest(threaded, delegating_renderer);
80 void BeginTest() override {
81 EXPECT_EQ(threaded_, HasImplThread());
82 EndTest();
85 void AfterTest() override { EXPECT_EQ(threaded_, HasImplThread()); }
87 private:
88 bool threaded_;
91 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHasImplThreadTest);
93 class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest {
94 protected:
95 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
97 void Layout() override {
98 // This shouldn't cause a second commit to happen.
99 layer_tree_host()->SetNeedsCommit();
102 void DidCommit() override {
103 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
104 EndTest();
107 void AfterTest() override {}
110 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommitInsideLayout);
112 class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest {
113 protected:
114 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
116 void Layout() override {
117 // This shouldn't cause a second commit to happen.
118 layer_tree_host()->SetNeedsUpdateLayers();
121 void DidCommit() override {
122 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
123 EndTest();
126 void AfterTest() override {}
129 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsUpdateInsideLayout);
131 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
132 // when no raster tasks get scheduled.
133 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
134 public:
135 LayerTreeHostTestReadyToActivateEmpty()
136 : did_notify_ready_to_activate_(false),
137 all_tiles_required_for_activation_are_ready_to_draw_(false),
138 required_for_activation_count_(0) {}
140 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
142 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
143 const std::vector<PictureLayerImpl*>& layers =
144 impl->sync_tree()->picture_layers();
145 required_for_activation_count_ = 0;
146 for (const auto& layer : layers) {
147 FakePictureLayerImpl* fake_layer =
148 static_cast<FakePictureLayerImpl*>(layer);
149 required_for_activation_count_ +=
150 fake_layer->CountTilesRequiredForActivation();
154 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
155 did_notify_ready_to_activate_ = true;
156 all_tiles_required_for_activation_are_ready_to_draw_ =
157 impl->tile_manager()->IsReadyToActivate();
158 EndTest();
161 void AfterTest() override {
162 EXPECT_TRUE(did_notify_ready_to_activate_);
163 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
164 EXPECT_EQ(size_t(0), required_for_activation_count_);
167 protected:
168 bool did_notify_ready_to_activate_;
169 bool all_tiles_required_for_activation_are_ready_to_draw_;
170 size_t required_for_activation_count_;
173 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
175 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
176 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
177 class LayerTreeHostTestReadyToActivateNonEmpty
178 : public LayerTreeHostTestReadyToActivateEmpty {
179 public:
180 void SetupTree() override {
181 client_.set_fill_with_nonsolid_color(true);
182 scoped_refptr<FakePictureLayer> root_layer =
183 FakePictureLayer::Create(layer_settings(), &client_);
184 root_layer->SetBounds(gfx::Size(1024, 1024));
185 root_layer->SetIsDrawable(true);
187 layer_tree_host()->SetRootLayer(root_layer);
188 LayerTreeHostTest::SetupTree();
191 void AfterTest() override {
192 EXPECT_TRUE(did_notify_ready_to_activate_);
193 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
194 EXPECT_LE(size_t(1), required_for_activation_count_);
197 private:
198 FakeContentLayerClient client_;
201 // Multi-thread only because in single thread the commit goes directly to the
202 // active tree, so notify ready to activate is skipped.
203 MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
205 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
206 // no raster tasks get scheduled.
207 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
208 public:
209 LayerTreeHostTestReadyToDrawEmpty()
210 : did_notify_ready_to_draw_(false),
211 all_tiles_required_for_draw_are_ready_to_draw_(false),
212 required_for_draw_count_(0) {}
214 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
216 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
217 did_notify_ready_to_draw_ = true;
218 const std::vector<PictureLayerImpl*>& layers =
219 impl->active_tree()->picture_layers();
220 all_tiles_required_for_draw_are_ready_to_draw_ =
221 impl->tile_manager()->IsReadyToDraw();
222 for (const auto& layer : layers) {
223 FakePictureLayerImpl* fake_layer =
224 static_cast<FakePictureLayerImpl*>(layer);
225 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw();
228 EndTest();
231 void AfterTest() override {
232 EXPECT_TRUE(did_notify_ready_to_draw_);
233 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
234 EXPECT_EQ(size_t(0), required_for_draw_count_);
237 protected:
238 bool did_notify_ready_to_draw_;
239 bool all_tiles_required_for_draw_are_ready_to_draw_;
240 size_t required_for_draw_count_;
243 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
245 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
246 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
247 class LayerTreeHostTestReadyToDrawNonEmpty
248 : public LayerTreeHostTestReadyToDrawEmpty {
249 public:
250 void SetupTree() override {
251 client_.set_fill_with_nonsolid_color(true);
252 scoped_refptr<FakePictureLayer> root_layer =
253 FakePictureLayer::Create(layer_settings(), &client_);
254 root_layer->SetBounds(gfx::Size(1024, 1024));
255 root_layer->SetIsDrawable(true);
257 layer_tree_host()->SetRootLayer(root_layer);
258 LayerTreeHostTest::SetupTree();
261 void AfterTest() override {
262 EXPECT_TRUE(did_notify_ready_to_draw_);
263 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
264 EXPECT_LE(size_t(1), required_for_draw_count_);
267 private:
268 FakeContentLayerClient client_;
271 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
272 // single threaded mode.
273 SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
275 class LayerTreeHostFreeWorkerContextResourcesTest : public LayerTreeHostTest {
276 public:
277 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
278 auto output_surface = make_scoped_ptr(new testing::StrictMock<
279 MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface>(
280 delegating_renderer()));
282 // At init, we expect one call to set visibility to true.
283 testing::Expectation visibility_true =
284 EXPECT_CALL(*output_surface,
285 SetWorkerContextShouldAggressivelyFreeResources(false))
286 .Times(1);
288 // After running, we should get exactly one call to
289 // FreeWorkerContextGpuResources.
290 EXPECT_CALL(*output_surface,
291 SetWorkerContextShouldAggressivelyFreeResources(true))
292 .After(visibility_true)
293 .WillOnce(testing::Invoke([this](bool is_visible) { EndTest(); }));
294 return output_surface.Pass();
297 void InitializeSettings(LayerTreeSettings* settings) override {
298 settings->gpu_rasterization_enabled = true;
299 settings->gpu_rasterization_forced = true;
302 void BeginTest() override {
303 // Logic is handled in InitializedRendererOnThread to ensure that our
304 // LTHI is fully set up.
307 void AfterTest() override {
308 // Expectations handled via mock.
311 private:
312 class MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface
313 : public FakeOutputSurface {
314 public:
315 ~MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface() {}
316 explicit MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface(
317 bool delegated_rendering)
318 : FakeOutputSurface(TestContextProvider::Create(),
319 TestContextProvider::Create(),
320 delegated_rendering) {}
321 MOCK_METHOD1(SetWorkerContextShouldAggressivelyFreeResources,
322 void(bool is_visible));
326 // Test if the LTH successfully frees resources on the worker context when
327 // visibility is set to false.
328 class LayerTreeHostFreeWorkerContextResourcesOnInvisible
329 : public LayerTreeHostFreeWorkerContextResourcesTest {
330 public:
331 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
332 bool success) override {
333 PostSetVisibleToMainThread(false);
337 SINGLE_AND_MULTI_THREAD_TEST_F(
338 LayerTreeHostFreeWorkerContextResourcesOnInvisible);
340 // Test if the LTH successfully frees resources on the worker context when
341 // hard memory limit is set to zero.
342 class LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit
343 : public LayerTreeHostFreeWorkerContextResourcesTest {
344 public:
345 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
346 bool success) override {
347 ManagedMemoryPolicy zero_policy(
348 0, gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING, 0);
349 host_impl->SetMemoryPolicy(zero_policy);
353 SINGLE_AND_MULTI_THREAD_TEST_F(
354 LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit);
356 // Test if the LTH successfully frees resources on the worker context when
357 // hard memory limit is set to zero while using a synchronous compositor (like
358 // Android WebView).
359 class LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimitSynchronous
360 : public LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit {
361 public:
362 void InitializeSettings(LayerTreeSettings* settings) override {
363 LayerTreeHostFreeWorkerContextResourcesTest::InitializeSettings(settings);
364 settings->use_external_begin_frame_source = true;
365 settings->using_synchronous_renderer_compositor = true;
369 SINGLE_AND_MULTI_THREAD_TEST_F(
370 LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimitSynchronous);
372 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
373 // draw with frame 0.
374 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
375 public:
376 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
378 void BeginTest() override {
379 PostSetNeedsCommitToMainThread();
380 PostSetNeedsCommitToMainThread();
383 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
384 num_draws_++;
385 if (!impl->active_tree()->source_frame_number())
386 EndTest();
389 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
390 num_commits_++;
393 void AfterTest() override {
394 EXPECT_LE(1, num_commits_);
395 EXPECT_LE(1, num_draws_);
398 private:
399 int num_commits_;
400 int num_draws_;
403 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
405 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
406 // first committed frame draws should lead to another commit.
407 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
408 public:
409 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
411 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
413 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
415 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
416 ++num_commits_;
417 switch (num_commits_) {
418 case 1:
419 PostSetNeedsCommitToMainThread();
420 break;
421 case 2:
422 EndTest();
423 break;
424 default:
425 NOTREACHED();
429 void AfterTest() override {
430 EXPECT_EQ(2, num_commits_);
431 EXPECT_LE(1, num_draws_);
434 private:
435 int num_commits_;
436 int num_draws_;
439 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
441 // Verify that we pass property values in PushPropertiesTo.
442 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
443 protected:
444 void SetupTree() override {
445 scoped_refptr<Layer> root = Layer::Create(layer_settings());
446 root->CreateRenderSurface();
447 root->SetBounds(gfx::Size(10, 10));
448 layer_tree_host()->SetRootLayer(root);
449 LayerTreeHostTest::SetupTree();
452 enum Properties {
453 STARTUP,
454 BOUNDS,
455 HIDE_LAYER_AND_SUBTREE,
456 DRAWS_CONTENT,
457 DONE,
460 void BeginTest() override {
461 index_ = STARTUP;
462 PostSetNeedsCommitToMainThread();
465 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
466 VerifyAfterValues(impl->active_tree()->root_layer());
469 void DidCommitAndDrawFrame() override {
470 SetBeforeValues(layer_tree_host()->root_layer());
471 VerifyBeforeValues(layer_tree_host()->root_layer());
473 ++index_;
474 if (index_ == DONE) {
475 EndTest();
476 return;
479 SetAfterValues(layer_tree_host()->root_layer());
482 void AfterTest() override {}
484 void VerifyBeforeValues(Layer* layer) {
485 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
486 EXPECT_FALSE(layer->hide_layer_and_subtree());
487 EXPECT_FALSE(layer->DrawsContent());
490 void SetBeforeValues(Layer* layer) {
491 layer->SetBounds(gfx::Size(10, 10));
492 layer->SetHideLayerAndSubtree(false);
493 layer->SetIsDrawable(false);
496 void VerifyAfterValues(LayerImpl* layer) {
497 switch (static_cast<Properties>(index_)) {
498 case STARTUP:
499 case DONE:
500 break;
501 case BOUNDS:
502 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
503 break;
504 case HIDE_LAYER_AND_SUBTREE:
505 EXPECT_TRUE(layer->hide_layer_and_subtree());
506 break;
507 case DRAWS_CONTENT:
508 EXPECT_TRUE(layer->DrawsContent());
509 break;
513 void SetAfterValues(Layer* layer) {
514 switch (static_cast<Properties>(index_)) {
515 case STARTUP:
516 case DONE:
517 break;
518 case BOUNDS:
519 layer->SetBounds(gfx::Size(20, 20));
520 break;
521 case HIDE_LAYER_AND_SUBTREE:
522 layer->SetHideLayerAndSubtree(true);
523 break;
524 case DRAWS_CONTENT:
525 layer->SetIsDrawable(true);
526 break;
530 int index_;
533 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
535 // 1 setNeedsRedraw after the first commit has completed should lead to 1
536 // additional draw.
537 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
538 public:
539 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
541 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
543 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
544 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
545 if (!num_draws_) {
546 // Redraw again to verify that the second redraw doesn't commit.
547 PostSetNeedsRedrawToMainThread();
548 } else {
549 EndTest();
551 num_draws_++;
554 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
555 EXPECT_EQ(0, num_draws_);
556 num_commits_++;
559 void AfterTest() override {
560 EXPECT_GE(2, num_draws_);
561 EXPECT_EQ(1, num_commits_);
564 private:
565 int num_commits_;
566 int num_draws_;
569 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
571 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
572 // must contain invalid_rect.
573 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
574 public:
575 LayerTreeHostTestSetNeedsRedrawRect()
576 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
578 void BeginTest() override {
579 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
580 root_layer_->SetIsDrawable(true);
581 root_layer_->SetBounds(bounds_);
582 layer_tree_host()->SetRootLayer(root_layer_);
583 layer_tree_host()->SetViewportSize(bounds_);
584 PostSetNeedsCommitToMainThread();
587 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
588 LayerTreeHostImpl::FrameData* frame_data,
589 DrawResult draw_result) override {
590 EXPECT_EQ(DRAW_SUCCESS, draw_result);
592 gfx::RectF root_damage_rect;
593 if (!frame_data->render_passes.empty())
594 root_damage_rect = frame_data->render_passes.back()->damage_rect;
596 if (!num_draws_) {
597 // If this is the first frame, expect full frame damage.
598 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_));
599 } else {
600 // Check that invalid_rect_ is indeed repainted.
601 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
604 return draw_result;
607 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
608 if (!num_draws_) {
609 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
610 } else {
611 EndTest();
613 num_draws_++;
616 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
618 private:
619 int num_draws_;
620 const gfx::Size bounds_;
621 const gfx::Rect invalid_rect_;
622 FakeContentLayerClient client_;
623 scoped_refptr<FakePictureLayer> root_layer_;
626 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
628 // Ensure the texture size of the pending and active trees are identical when a
629 // layer is not in the viewport and a resize happens on the viewport
630 class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
631 public:
632 LayerTreeHostTestGpuRasterDeviceSizeChanged()
633 : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {}
635 void BeginTest() override {
636 client_.set_fill_with_nonsolid_color(true);
637 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
638 root_layer_->SetIsDrawable(true);
639 gfx::Transform transform;
640 // Translate the layer out of the viewport to force it to not update its
641 // tile size via PushProperties.
642 transform.Translate(10000.0, 10000.0);
643 root_layer_->SetTransform(transform);
644 root_layer_->SetBounds(bounds_);
645 layer_tree_host()->SetRootLayer(root_layer_);
646 layer_tree_host()->SetViewportSize(bounds_);
648 PostSetNeedsCommitToMainThread();
651 void InitializeSettings(LayerTreeSettings* settings) override {
652 settings->gpu_rasterization_enabled = true;
653 settings->gpu_rasterization_forced = true;
656 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
657 // Perform 2 commits.
658 if (!num_draws_) {
659 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
660 } else {
661 EndTest();
663 num_draws_++;
666 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
667 if (num_draws_ == 2) {
668 auto pending_tree = host_impl->pending_tree();
669 auto pending_layer_impl =
670 static_cast<FakePictureLayerImpl*>(pending_tree->root_layer());
671 EXPECT_NE(pending_layer_impl, nullptr);
673 auto active_tree = host_impl->pending_tree();
674 auto active_layer_impl =
675 static_cast<FakePictureLayerImpl*>(active_tree->root_layer());
676 EXPECT_NE(pending_layer_impl, nullptr);
678 auto active_tiling_set = active_layer_impl->picture_layer_tiling_set();
679 auto active_tiling = active_tiling_set->tiling_at(0);
680 auto pending_tiling_set = pending_layer_impl->picture_layer_tiling_set();
681 auto pending_tiling = pending_tiling_set->tiling_at(0);
682 EXPECT_EQ(
683 pending_tiling->TilingDataForTesting().max_texture_size().width(),
684 active_tiling->TilingDataForTesting().max_texture_size().width());
688 void DidCommitAndDrawFrame() override {
689 // On the second commit, resize the viewport.
690 if (num_draws_ == 1) {
691 layer_tree_host()->SetViewportSize(gfx::Size(400, 64));
695 void AfterTest() override {}
697 private:
698 int num_draws_;
699 const gfx::Size bounds_;
700 const gfx::Rect invalid_rect_;
701 FakeContentLayerClient client_;
702 scoped_refptr<FakePictureLayer> root_layer_;
705 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterDeviceSizeChanged);
707 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
708 public:
709 void InitializeSettings(LayerTreeSettings* settings) override {
710 settings->layer_transforms_should_scale_layer_contents = true;
713 void SetupTree() override {
714 root_layer_ = Layer::Create(layer_settings());
715 root_layer_->SetBounds(gfx::Size(10, 20));
716 root_layer_->CreateRenderSurface();
718 scaled_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
719 scaled_layer_->SetBounds(gfx::Size(1, 1));
720 root_layer_->AddChild(scaled_layer_);
722 layer_tree_host()->SetRootLayer(root_layer_);
723 LayerTreeHostTest::SetupTree();
726 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
728 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
729 if (host_impl->active_tree()->source_frame_number() == 1)
730 EndTest();
733 void DidCommit() override {
734 switch (layer_tree_host()->source_frame_number()) {
735 case 1:
736 // SetBounds grows the layer and exposes new content.
737 scaled_layer_->SetBounds(gfx::Size(4, 4));
738 break;
739 default:
740 // No extra commits.
741 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
745 void AfterTest() override {
746 EXPECT_EQ(gfx::Size(4, 4).ToString(), scaled_layer_->bounds().ToString());
749 private:
750 FakeContentLayerClient client_;
751 scoped_refptr<Layer> root_layer_;
752 scoped_refptr<Layer> scaled_layer_;
755 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
757 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
758 : public LayerTreeHostTest {
759 public:
760 void InitializeSettings(LayerTreeSettings* settings) override {
761 settings->layer_transforms_should_scale_layer_contents = true;
764 void SetupTree() override {
765 root_layer_ = Layer::Create(layer_settings());
766 root_layer_->SetBounds(gfx::Size(10, 20));
767 root_layer_->CreateRenderSurface();
769 bool paint_scrollbar = true;
770 bool has_thumb = false;
771 scrollbar_ = FakePaintedScrollbarLayer::Create(
772 layer_settings(), paint_scrollbar, has_thumb, root_layer_->id());
773 scrollbar_->SetPosition(gfx::Point(0, 10));
774 scrollbar_->SetBounds(gfx::Size(10, 10));
776 root_layer_->AddChild(scrollbar_);
778 layer_tree_host()->SetRootLayer(root_layer_);
779 LayerTreeHostTest::SetupTree();
782 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
784 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
785 if (host_impl->active_tree()->source_frame_number() == 1)
786 EndTest();
789 void DidCommit() override {
790 switch (layer_tree_host()->source_frame_number()) {
791 case 1:
792 // Changing the device scale factor causes a commit. It also changes
793 // the content bounds of |scrollbar_|, which should not generate
794 // a second commit as a result.
795 layer_tree_host()->SetDeviceScaleFactor(4.f);
796 break;
797 default:
798 // No extra commits.
799 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
800 break;
804 void AfterTest() override {
807 private:
808 FakeContentLayerClient client_;
809 scoped_refptr<Layer> root_layer_;
810 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
813 SINGLE_AND_MULTI_THREAD_TEST_F(
814 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
816 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
817 public:
818 LayerTreeHostTestSetNextCommitForcesRedraw()
819 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
821 void BeginTest() override {
822 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
823 root_layer_->SetIsDrawable(true);
824 root_layer_->SetBounds(bounds_);
825 layer_tree_host()->SetRootLayer(root_layer_);
826 layer_tree_host()->SetViewportSize(bounds_);
827 PostSetNeedsCommitToMainThread();
830 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
831 if (num_draws_ == 3)
832 host_impl->SetNeedsRedrawRect(invalid_rect_);
835 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
836 LayerTreeHostImpl::FrameData* frame_data,
837 DrawResult draw_result) override {
838 EXPECT_EQ(DRAW_SUCCESS, draw_result);
840 gfx::RectF root_damage_rect;
841 if (!frame_data->render_passes.empty())
842 root_damage_rect = frame_data->render_passes.back()->damage_rect;
844 switch (num_draws_) {
845 case 0:
846 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
847 break;
848 case 1:
849 case 2:
850 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
851 break;
852 case 3:
853 EXPECT_EQ(invalid_rect_, root_damage_rect);
854 break;
855 case 4:
856 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
857 break;
858 default:
859 NOTREACHED();
862 return draw_result;
865 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
866 switch (num_draws_) {
867 case 0:
868 case 1:
869 // Cycle through a couple of empty commits to ensure we're observing the
870 // right behavior
871 PostSetNeedsCommitToMainThread();
872 break;
873 case 2:
874 // Should force full frame damage on the next commit
875 PostSetNextCommitForcesRedrawToMainThread();
876 PostSetNeedsCommitToMainThread();
877 host_impl->BlockNotifyReadyToActivateForTesting(true);
878 break;
879 case 3:
880 host_impl->BlockNotifyReadyToActivateForTesting(false);
881 break;
882 default:
883 EndTest();
884 break;
886 num_draws_++;
889 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
891 private:
892 int num_draws_;
893 const gfx::Size bounds_;
894 const gfx::Rect invalid_rect_;
895 FakeContentLayerClient client_;
896 scoped_refptr<FakePictureLayer> root_layer_;
899 // This test blocks activation which is not supported for single thread mode.
900 MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw);
902 // Tests that if a layer is not drawn because of some reason in the parent then
903 // its damage is preserved until the next time it is drawn.
904 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
905 public:
906 void InitializeSettings(LayerTreeSettings* settings) override {
907 // If we don't set the minimum contents scale, it's harder to verify whether
908 // the damage we get is correct. For other scale amounts, please see
909 // LayerTreeHostTestDamageWithScale.
910 settings->minimum_contents_scale = 1.f;
913 void SetupTree() override {
914 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
915 root_layer_->SetIsDrawable(true);
916 root_layer_->SetBounds(gfx::Size(50, 50));
917 layer_tree_host()->SetRootLayer(root_layer_);
919 // The initially transparent layer has a larger child layer, which is
920 // not initially drawn because of the this (parent) layer.
921 parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
922 parent_layer_->SetBounds(gfx::Size(15, 15));
923 parent_layer_->SetOpacity(0.0f);
924 root_layer_->AddChild(parent_layer_);
926 child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
927 child_layer_->SetBounds(gfx::Size(25, 25));
928 parent_layer_->AddChild(child_layer_);
930 LayerTreeHostTest::SetupTree();
933 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
935 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
936 LayerTreeHostImpl::FrameData* frame_data,
937 DrawResult draw_result) override {
938 EXPECT_EQ(DRAW_SUCCESS, draw_result);
940 gfx::RectF root_damage_rect;
941 if (!frame_data->render_passes.empty())
942 root_damage_rect = frame_data->render_passes.back()->damage_rect;
944 // The first time, the whole view needs be drawn.
945 // Afterwards, just the opacity of surface_layer1 is changed a few times,
946 // and each damage should be the bounding box of it and its child. If this
947 // was working improperly, the damage might not include its childs bounding
948 // box.
949 switch (host_impl->active_tree()->source_frame_number()) {
950 case 0:
951 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
952 break;
953 case 1:
954 case 2:
955 case 3:
956 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
957 break;
958 default:
959 NOTREACHED();
962 return draw_result;
965 void DidCommitAndDrawFrame() override {
966 switch (layer_tree_host()->source_frame_number()) {
967 case 1:
968 // Test not owning the surface.
969 parent_layer_->SetOpacity(1.0f);
970 break;
971 case 2:
972 parent_layer_->SetOpacity(0.0f);
973 break;
974 case 3:
975 // Test owning the surface.
976 parent_layer_->SetOpacity(0.5f);
977 parent_layer_->SetForceRenderSurface(true);
978 break;
979 case 4:
980 EndTest();
981 break;
982 default:
983 NOTREACHED();
987 void AfterTest() override {}
989 private:
990 FakeContentLayerClient client_;
991 scoped_refptr<FakePictureLayer> root_layer_;
992 scoped_refptr<FakePictureLayer> parent_layer_;
993 scoped_refptr<FakePictureLayer> child_layer_;
996 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
998 // Tests that if a layer is not drawn because of some reason in the parent then
999 // its damage is preserved until the next time it is drawn.
1000 class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest {
1001 public:
1002 LayerTreeHostTestDamageWithScale() {}
1004 void SetupTree() override {
1005 client_.set_fill_with_nonsolid_color(true);
1007 scoped_ptr<FakePicturePile> pile(
1008 new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
1009 LayerTreeSettings().default_tile_grid_size));
1010 root_layer_ = FakePictureLayer::CreateWithRecordingSource(
1011 layer_settings(), &client_, pile.Pass());
1012 root_layer_->SetBounds(gfx::Size(50, 50));
1014 pile.reset(new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
1015 LayerTreeSettings().default_tile_grid_size));
1016 child_layer_ = FakePictureLayer::CreateWithRecordingSource(
1017 layer_settings(), &client_, pile.Pass());
1018 child_layer_->SetBounds(gfx::Size(25, 25));
1019 child_layer_->SetIsDrawable(true);
1020 child_layer_->SetContentsOpaque(true);
1021 root_layer_->AddChild(child_layer_);
1023 layer_tree_host()->SetRootLayer(root_layer_);
1024 LayerTreeHostTest::SetupTree();
1027 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1028 // Force the layer to have a tiling at 1.3f scale. Note that if we simply
1029 // add tiling, it will be gone by the time we draw because of aggressive
1030 // cleanup. AddTilingUntilNextDraw ensures that it remains there during
1031 // damage calculation.
1032 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
1033 host_impl->active_tree()->LayerById(child_layer_->id()));
1034 child_layer_impl->AddTilingUntilNextDraw(1.3f);
1037 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1039 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1040 LayerTreeHostImpl::FrameData* frame_data,
1041 DrawResult draw_result) override {
1042 EXPECT_EQ(DRAW_SUCCESS, draw_result);
1044 gfx::RectF root_damage_rect;
1045 if (!frame_data->render_passes.empty())
1046 root_damage_rect = frame_data->render_passes.back()->damage_rect;
1048 // The first time, the whole view needs be drawn.
1049 // Afterwards, just the opacity of surface_layer1 is changed a few times,
1050 // and each damage should be the bounding box of it and its child. If this
1051 // was working improperly, the damage might not include its childs bounding
1052 // box.
1053 switch (host_impl->active_tree()->source_frame_number()) {
1054 case 0:
1055 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
1056 break;
1057 case 1: {
1058 FakePictureLayerImpl* child_layer_impl =
1059 static_cast<FakePictureLayerImpl*>(
1060 host_impl->active_tree()->LayerById(child_layer_->id()));
1061 // We remove tilings pretty aggressively if they are not ideal. Add this
1062 // back in so that we can compare
1063 // child_layer_impl->GetEnclosingRectInTargetSpace to the damage.
1064 child_layer_impl->AddTilingUntilNextDraw(1.3f);
1066 EXPECT_EQ(gfx::Rect(26, 26), root_damage_rect);
1067 EXPECT_EQ(child_layer_impl->GetEnclosingRectInTargetSpace(),
1068 root_damage_rect);
1069 EXPECT_TRUE(child_layer_impl->GetEnclosingRectInTargetSpace().Contains(
1070 gfx::Rect(child_layer_->bounds())));
1071 break;
1073 default:
1074 NOTREACHED();
1077 return draw_result;
1080 void DidCommitAndDrawFrame() override {
1081 switch (layer_tree_host()->source_frame_number()) {
1082 case 1: {
1083 // Test not owning the surface.
1084 child_layer_->SetOpacity(0.5f);
1085 break;
1087 case 2:
1088 EndTest();
1089 break;
1090 default:
1091 NOTREACHED();
1095 void AfterTest() override {}
1097 private:
1098 FakeContentLayerClient client_;
1099 scoped_refptr<Layer> root_layer_;
1100 scoped_refptr<Layer> child_layer_;
1103 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDamageWithScale);
1105 // This test verifies that properties on the layer tree host are commited
1106 // to the impl side.
1107 class LayerTreeHostTestCommit : public LayerTreeHostTest {
1108 public:
1109 LayerTreeHostTestCommit() {}
1111 void BeginTest() override {
1112 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1113 layer_tree_host()->set_background_color(SK_ColorGRAY);
1115 PostSetNeedsCommitToMainThread();
1118 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1119 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
1120 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
1122 EndTest();
1125 void AfterTest() override {}
1128 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
1130 // This test verifies that LayerTreeHostImpl's current frame time gets
1131 // updated in consecutive frames when it doesn't draw due to tree
1132 // activation failure.
1133 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
1134 : public LayerTreeHostTest {
1135 public:
1136 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
1137 : frame_count_with_pending_tree_(0) {}
1139 void BeginTest() override {
1140 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1141 layer_tree_host()->set_background_color(SK_ColorGRAY);
1143 PostSetNeedsCommitToMainThread();
1146 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
1147 EXPECT_EQ(frame_count_with_pending_tree_, 0);
1148 impl->BlockNotifyReadyToActivateForTesting(true);
1151 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1152 const BeginFrameArgs& args) override {
1153 if (impl->pending_tree())
1154 frame_count_with_pending_tree_++;
1156 if (frame_count_with_pending_tree_ == 1) {
1157 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
1158 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1159 } else if (frame_count_with_pending_tree_ == 2) {
1160 impl->BlockNotifyReadyToActivateForTesting(false);
1164 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1165 EXPECT_GT(frame_count_with_pending_tree_, 1);
1166 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
1167 EXPECT_NE(first_frame_time_.ToInternalValue(),
1168 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
1169 EndTest();
1172 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1173 EXPECT_GT(frame_count_with_pending_tree_, 1);
1176 void AfterTest() override {}
1178 private:
1179 int frame_count_with_pending_tree_;
1180 base::TimeTicks first_frame_time_;
1183 // This test blocks activation which is not supported for single thread mode.
1184 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1185 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
1187 // This test verifies that LayerTreeHostImpl's current frame time gets
1188 // updated in consecutive frames when it draws in each frame.
1189 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
1190 public:
1191 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
1193 void BeginTest() override {
1194 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1195 layer_tree_host()->set_background_color(SK_ColorGRAY);
1197 PostSetNeedsCommitToMainThread();
1200 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1201 frame_++;
1202 if (frame_ == 1) {
1203 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1204 impl->SetNeedsRedraw();
1206 // Since we might use a low-resolution clock on Windows, we need to
1207 // make sure that the clock has incremented past first_frame_time_.
1208 while (first_frame_time_ == base::TimeTicks::Now()) {
1211 return;
1214 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
1215 EndTest();
1218 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1219 // Ensure there isn't a commit between the two draws, to ensure that a
1220 // commit isn't required for updating the current frame time. We can
1221 // only check for this in the multi-threaded case, since in the single-
1222 // threaded case there will always be a commit between consecutive draws.
1223 if (HasImplThread())
1224 EXPECT_EQ(0, frame_);
1227 void AfterTest() override {}
1229 private:
1230 int frame_;
1231 base::TimeTicks first_frame_time_;
1234 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1236 // Verifies that StartPageScaleAnimation events propagate correctly
1237 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1238 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
1239 public:
1240 LayerTreeHostTestStartPageScaleAnimation() {}
1242 void SetupTree() override {
1243 LayerTreeHostTest::SetupTree();
1245 Layer* root_layer = layer_tree_host()->root_layer();
1247 scoped_refptr<FakePictureLayer> layer =
1248 FakePictureLayer::Create(layer_settings(), &client_);
1249 layer->set_always_update_resources(true);
1250 scroll_layer_ = layer;
1252 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
1253 2 * root_layer->bounds().height()));
1254 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
1256 CreateVirtualViewportLayers(root_layer,
1257 scroll_layer_,
1258 root_layer->bounds(),
1259 root_layer->bounds(),
1260 layer_tree_host(),
1261 layer_settings());
1263 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1266 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1268 void ApplyViewportDeltas(const gfx::Vector2dF& scroll_delta,
1269 const gfx::Vector2dF&,
1270 const gfx::Vector2dF& elastic_overscroll_delta,
1271 float scale,
1272 float) override {
1273 gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
1274 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset,
1275 scroll_delta));
1276 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1279 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1280 // We get one commit before the first draw, and the animation doesn't happen
1281 // until the second draw.
1282 switch (impl->active_tree()->source_frame_number()) {
1283 case 0:
1284 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1285 // We'll start an animation when we get back to the main thread.
1286 break;
1287 case 1:
1288 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1289 break;
1290 case 2:
1291 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
1292 EndTest();
1293 break;
1294 default:
1295 NOTREACHED();
1299 void DidCommitAndDrawFrame() override {
1300 switch (layer_tree_host()->source_frame_number()) {
1301 case 1:
1302 layer_tree_host()->StartPageScaleAnimation(
1303 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1304 break;
1308 void AfterTest() override {}
1310 FakeContentLayerClient client_;
1311 scoped_refptr<Layer> scroll_layer_;
1314 // Single thread proxy does not support impl-side page scale changes.
1315 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1317 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1318 public:
1319 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1321 void BeginTest() override {
1322 PostSetNeedsCommitToMainThread();
1323 PostSetVisibleToMainThread(false);
1324 // This is suppressed while we're invisible.
1325 PostSetNeedsRedrawToMainThread();
1326 // Triggers the redraw.
1327 PostSetVisibleToMainThread(true);
1330 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1331 EXPECT_TRUE(impl->visible());
1332 ++num_draws_;
1333 EndTest();
1336 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
1338 private:
1339 int num_draws_;
1342 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1344 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1345 public:
1346 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1348 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1350 void PaintContents(SkCanvas* canvas,
1351 const gfx::Rect& clip,
1352 PaintingControlSetting picture_control) override {
1353 // Set layer opacity to 0.
1354 if (test_layer_)
1355 test_layer_->SetOpacity(0.f);
1357 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
1358 const gfx::Rect& clip,
1359 PaintingControlSetting picture_control) override {
1360 NOTIMPLEMENTED();
1361 return nullptr;
1363 bool FillsBoundsCompletely() const override { return false; }
1364 size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
1366 private:
1367 Layer* test_layer_;
1370 // Layer opacity change during paint should not prevent compositor resources
1371 // from being updated during commit.
1372 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1373 public:
1374 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {}
1376 void SetupTree() override {
1377 LayerTreeHostTest::SetupTree();
1379 update_check_picture_layer_ = FakePictureLayer::Create(
1380 layer_settings(), &test_opacity_change_delegate_);
1381 test_opacity_change_delegate_.SetTestLayer(
1382 update_check_picture_layer_.get());
1383 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
1386 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1388 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
1390 void AfterTest() override {
1391 // Update() should have been called once.
1392 EXPECT_EQ(1, update_check_picture_layer_->update_count());
1395 private:
1396 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1397 scoped_refptr<FakePictureLayer> update_check_picture_layer_;
1400 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1402 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1403 : public LayerTreeHostTest {
1404 public:
1405 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {}
1407 void BeginTest() override {
1408 client_.set_fill_with_nonsolid_color(true);
1409 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1410 child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1412 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1413 layer_tree_host()->SetDeviceScaleFactor(1.5);
1414 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1416 root_layer_->AddChild(child_layer_);
1418 root_layer_->SetIsDrawable(true);
1419 root_layer_->SetBounds(gfx::Size(30, 30));
1421 child_layer_->SetIsDrawable(true);
1422 child_layer_->SetPosition(gfx::Point(2, 2));
1423 child_layer_->SetBounds(gfx::Size(10, 10));
1425 layer_tree_host()->SetRootLayer(root_layer_);
1427 PostSetNeedsCommitToMainThread();
1430 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1431 // Should only do one commit.
1432 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1433 // Device scale factor should come over to impl.
1434 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1436 // Both layers are on impl.
1437 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1439 // Device viewport is scaled.
1440 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1442 FakePictureLayerImpl* root =
1443 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
1444 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
1445 impl->active_tree()->root_layer()->children()[0]);
1447 // Positions remain in layout pixels.
1448 EXPECT_EQ(gfx::Point(0, 0), root->position());
1449 EXPECT_EQ(gfx::Point(2, 2), child->position());
1451 // Compute all the layer transforms for the frame.
1452 LayerTreeHostImpl::FrameData frame_data;
1453 impl->PrepareToDraw(&frame_data);
1454 impl->DidDrawAllLayers(frame_data);
1456 const LayerImplList& render_surface_layer_list =
1457 *frame_data.render_surface_layer_list;
1459 // Both layers should be drawing into the root render surface.
1460 ASSERT_EQ(1u, render_surface_layer_list.size());
1461 ASSERT_EQ(root->render_surface(),
1462 render_surface_layer_list[0]->render_surface());
1463 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1465 // The root render surface is the size of the viewport.
1466 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect());
1468 // The max tiling scale of the child should be scaled.
1469 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale());
1471 gfx::Transform scale_transform;
1472 scale_transform.Scale(impl->device_scale_factor(),
1473 impl->device_scale_factor());
1475 // The root layer is scaled by 2x.
1476 gfx::Transform root_screen_space_transform = scale_transform;
1477 gfx::Transform root_draw_transform = scale_transform;
1479 EXPECT_EQ(root_draw_transform, root->draw_transform());
1480 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1482 // The child is at position 2,2, which is transformed to 3,3 after the scale
1483 gfx::Transform child_transform;
1484 child_transform.Translate(3.f, 3.f);
1485 child_transform.Scale(child->MaximumTilingContentsScale(),
1486 child->MaximumTilingContentsScale());
1488 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform());
1489 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform,
1490 child->screen_space_transform());
1492 EndTest();
1495 void AfterTest() override {}
1497 private:
1498 FakeContentLayerClient client_;
1499 scoped_refptr<FakePictureLayer> root_layer_;
1500 scoped_refptr<FakePictureLayer> child_layer_;
1503 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1505 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1506 public:
1507 LayerTreeHostTestContinuousInvalidate()
1508 : num_commit_complete_(0), num_draw_layers_(0) {}
1510 void BeginTest() override {
1511 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1512 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1514 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1515 layer_->SetBounds(gfx::Size(10, 10));
1516 layer_->SetPosition(gfx::PointF(0.f, 0.f));
1517 layer_->SetIsDrawable(true);
1518 layer_tree_host()->root_layer()->AddChild(layer_);
1520 PostSetNeedsCommitToMainThread();
1523 void DidCommitAndDrawFrame() override {
1524 if (num_draw_layers_ == 2)
1525 return;
1526 layer_->SetNeedsDisplay();
1529 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1530 if (num_draw_layers_ == 1)
1531 num_commit_complete_++;
1534 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1535 num_draw_layers_++;
1536 if (num_draw_layers_ == 2)
1537 EndTest();
1540 void AfterTest() override {
1541 // Check that we didn't commit twice between first and second draw.
1542 EXPECT_EQ(1, num_commit_complete_);
1545 private:
1546 FakeContentLayerClient client_;
1547 scoped_refptr<Layer> layer_;
1548 int num_commit_complete_;
1549 int num_draw_layers_;
1552 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
1554 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
1555 public:
1556 LayerTreeHostTestDeferCommits()
1557 : num_will_begin_impl_frame_(0),
1558 num_send_begin_main_frame_(0) {}
1560 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1562 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
1563 const BeginFrameArgs& args) override {
1564 num_will_begin_impl_frame_++;
1565 switch (num_will_begin_impl_frame_) {
1566 case 1:
1567 break;
1568 case 2:
1569 case 3:
1570 case 4:
1571 // Post a number of frames to increase the chance that, if there exist
1572 // bugs, an unexpected BeginMainFrame will be issued.
1573 PostSetNeedsCommitToMainThread();
1574 PostSetNeedsRedrawToMainThread();
1575 break;
1576 case 5:
1577 PostSetDeferCommitsToMainThread(false);
1578 break;
1579 default:
1580 // Sometimes |num_will_begin_impl_frame_| will be greater than 5 if the
1581 // main thread is slow to respond.
1582 break;
1586 void ScheduledActionSendBeginMainFrame() override {
1587 num_send_begin_main_frame_++;
1588 switch (num_send_begin_main_frame_) {
1589 case 1:
1590 PostSetDeferCommitsToMainThread(true);
1591 break;
1592 case 2:
1593 EndTest();
1594 break;
1595 default:
1596 NOTREACHED();
1597 break;
1601 void AfterTest() override {
1602 EXPECT_GE(num_will_begin_impl_frame_, 5);
1603 EXPECT_EQ(2, num_send_begin_main_frame_);
1606 private:
1607 int num_will_begin_impl_frame_;
1608 int num_send_begin_main_frame_;
1611 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
1613 class LayerTreeHostTestCompositeImmediatelyStateTransitions
1614 : public LayerTreeHostTest {
1615 public:
1616 enum {
1617 kInvalid,
1618 kStartedTest,
1619 kStartedImplFrame,
1620 kStartedMainFrame,
1621 kStartedCommit,
1622 kCompletedCommit,
1623 kCompletedMainFrame,
1624 kCompletedImplFrame,
1627 LayerTreeHostTestCompositeImmediatelyStateTransitions()
1628 : current_state_(kInvalid), current_begin_frame_args_() {}
1630 void InitializeSettings(LayerTreeSettings* settings) override {
1631 settings->single_thread_proxy_scheduler = false;
1632 settings->use_zero_copy = true;
1633 settings->use_one_copy = false;
1636 void BeginTest() override {
1637 current_state_ = kStartedTest;
1638 PostCompositeImmediatelyToMainThread();
1641 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
1642 const BeginFrameArgs& args) override {
1643 EXPECT_EQ(current_state_, kStartedTest);
1644 current_state_ = kStartedImplFrame;
1646 EXPECT_FALSE(current_begin_frame_args_.IsValid());
1647 EXPECT_TRUE(args.IsValid());
1648 current_begin_frame_args_ = args;
1650 void WillBeginMainFrame() override {
1651 EXPECT_EQ(current_state_, kStartedImplFrame);
1652 current_state_ = kStartedMainFrame;
1654 void BeginMainFrame(const BeginFrameArgs& args) override {
1655 EXPECT_EQ(current_state_, kStartedMainFrame);
1656 EXPECT_EQ(args.frame_time, current_begin_frame_args_.frame_time);
1658 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
1659 EXPECT_EQ(current_state_, kStartedMainFrame);
1660 current_state_ = kStartedCommit;
1662 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1663 EXPECT_EQ(current_state_, kStartedCommit);
1664 current_state_ = kCompletedCommit;
1666 void DidBeginMainFrame() override {
1667 EXPECT_EQ(current_state_, kCompletedCommit);
1668 current_state_ = kCompletedMainFrame;
1670 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
1671 EXPECT_EQ(current_state_, kCompletedMainFrame);
1672 current_state_ = kCompletedImplFrame;
1673 EndTest();
1675 void AfterTest() override { EXPECT_EQ(current_state_, kCompletedImplFrame); }
1677 private:
1678 int current_state_;
1679 BeginFrameArgs current_begin_frame_args_;
1682 SINGLE_THREAD_TEST_F(LayerTreeHostTestCompositeImmediatelyStateTransitions);
1684 class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
1685 public:
1686 void SetupTree() override {
1687 num_tiles_rastered_ = 0;
1689 scoped_refptr<Layer> root_layer =
1690 PictureLayer::Create(layer_settings(), &client_);
1691 client_.set_fill_with_nonsolid_color(true);
1692 root_layer->SetIsDrawable(true);
1693 root_layer->SetBounds(gfx::Size(10, 10));
1694 root_layer->SetContentsOpaque(true);
1696 layer_tree_host()->SetRootLayer(root_layer);
1698 // The expectations are based on the assumption that the default
1699 // LCD settings are:
1700 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
1702 LayerTreeHostTest::SetupTree();
1705 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1707 void DidCommitAndDrawFrame() override {
1708 switch (layer_tree_host()->source_frame_number()) {
1709 case 1:
1710 PostSetNeedsCommitToMainThread();
1711 break;
1712 case 2:
1713 // Change layer opacity that should trigger lcd change.
1714 layer_tree_host()->root_layer()->SetOpacity(.5f);
1715 break;
1716 case 3:
1717 // Change layer opacity that should not trigger lcd change.
1718 layer_tree_host()->root_layer()->SetOpacity(1.f);
1719 break;
1720 case 4:
1721 EndTest();
1722 break;
1726 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
1727 const Tile* tile) override {
1728 ++num_tiles_rastered_;
1731 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1732 PictureLayerImpl* root_layer =
1733 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer());
1734 bool can_use_lcd_text =
1735 host_impl->active_tree()->root_layer()->can_use_lcd_text();
1736 switch (host_impl->active_tree()->source_frame_number()) {
1737 case 0:
1738 // The first draw.
1739 EXPECT_EQ(1, num_tiles_rastered_);
1740 EXPECT_TRUE(can_use_lcd_text);
1741 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
1742 break;
1743 case 1:
1744 // Nothing changed on the layer.
1745 EXPECT_EQ(1, num_tiles_rastered_);
1746 EXPECT_TRUE(can_use_lcd_text);
1747 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
1748 break;
1749 case 2:
1750 // LCD text was disabled; it should be re-rastered with LCD text off.
1751 EXPECT_EQ(2, num_tiles_rastered_);
1752 EXPECT_FALSE(can_use_lcd_text);
1753 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
1754 break;
1755 case 3:
1756 // LCD text was enabled, but it's sticky and stays off.
1757 EXPECT_EQ(2, num_tiles_rastered_);
1758 EXPECT_TRUE(can_use_lcd_text);
1759 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
1760 break;
1764 void AfterTest() override {}
1766 private:
1767 FakeContentLayerClient client_;
1768 int num_tiles_rastered_;
1771 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDChange);
1773 // Verify that the BeginFrame notification is used to initiate rendering.
1774 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
1775 public:
1776 void InitializeSettings(LayerTreeSettings* settings) override {
1777 settings->use_external_begin_frame_source = true;
1780 void BeginTest() override {
1781 // This will trigger a SetNeedsBeginFrame which will trigger a
1782 // BeginFrame.
1783 PostSetNeedsCommitToMainThread();
1786 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1787 LayerTreeHostImpl::FrameData* frame,
1788 DrawResult draw_result) override {
1789 EndTest();
1790 return DRAW_SUCCESS;
1793 void AfterTest() override {}
1795 private:
1796 base::TimeTicks frame_time_;
1799 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
1801 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
1802 : public LayerTreeHostTest {
1803 public:
1804 void InitializeSettings(LayerTreeSettings* settings) override {
1805 settings->use_external_begin_frame_source = true;
1806 settings->using_synchronous_renderer_compositor = true;
1809 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1811 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1812 // The BeginFrame notification is turned off now but will get enabled
1813 // once we return. End test while it's enabled.
1814 ImplThreadTaskRunner()->PostTask(
1815 FROM_HERE,
1816 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
1817 base::Unretained(this)));
1820 void AfterTest() override {}
1823 MULTI_THREAD_TEST_F(
1824 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
1826 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
1827 protected:
1828 LayerTreeHostTestAbortedCommitDoesntStall()
1829 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
1831 void InitializeSettings(LayerTreeSettings* settings) override {
1832 settings->use_external_begin_frame_source = true;
1835 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1837 void DidCommit() override {
1838 commit_count_++;
1839 if (commit_count_ == 4) {
1840 // After two aborted commits, request a real commit now to make sure a
1841 // real commit following an aborted commit will still complete and
1842 // end the test even when the Impl thread is idle.
1843 layer_tree_host()->SetNeedsCommit();
1847 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
1848 CommitEarlyOutReason reason) override {
1849 commit_abort_count_++;
1850 // Initiate another abortable commit.
1851 host_impl->SetNeedsCommit();
1854 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1855 commit_complete_count_++;
1856 if (commit_complete_count_ == 1) {
1857 // Initiate an abortable commit after the first commit.
1858 host_impl->SetNeedsCommit();
1859 } else {
1860 EndTest();
1864 void AfterTest() override {
1865 EXPECT_EQ(commit_count_, 5);
1866 EXPECT_EQ(commit_abort_count_, 3);
1867 EXPECT_EQ(commit_complete_count_, 2);
1870 int commit_count_;
1871 int commit_abort_count_;
1872 int commit_complete_count_;
1875 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
1876 : public LayerTreeHostTestAbortedCommitDoesntStall {
1877 protected:
1878 void InitializeSettings(LayerTreeSettings* settings) override {
1879 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
1880 settings->using_synchronous_renderer_compositor = true;
1883 void ScheduledActionInvalidateOutputSurface() override {
1884 ImplThreadTaskRunner()->PostTask(
1885 FROM_HERE,
1886 base::Bind(
1887 &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor::
1888 CallOnDraw,
1889 base::Unretained(this)));
1892 void CallOnDraw() {
1893 // Synchronous compositor does not draw unless told to do so by the output
1894 // surface.
1895 output_surface()->client()->OnDraw();
1899 MULTI_THREAD_TEST_F(
1900 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
1902 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
1903 : public LayerTreeHostTestAbortedCommitDoesntStall {
1904 void InitializeSettings(LayerTreeSettings* settings) override {
1905 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
1906 settings->wait_for_beginframe_interval = false;
1907 settings->renderer_settings.disable_display_vsync = true;
1911 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
1913 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
1914 : public LayerTreeHostTest {
1915 protected:
1916 void SetupTree() override {
1917 LayerTreeHostTest::SetupTree();
1919 scoped_refptr<Layer> layer =
1920 PictureLayer::Create(layer_settings(), &client_);
1921 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
1922 layer->SetBounds(gfx::Size(10, 10));
1923 layer_tree_host()->root_layer()->AddChild(layer);
1926 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1928 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1929 EndTest();
1932 void AfterTest() override {}
1934 FakeContentLayerClient client_;
1937 SINGLE_AND_MULTI_THREAD_TEST_F(
1938 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
1940 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
1941 : public LayerTreeHostTest {
1942 public:
1943 class SetBoundsClient : public ContentLayerClient {
1944 public:
1945 SetBoundsClient() : layer_(0) {}
1947 void set_layer(Layer* layer) { layer_ = layer; }
1949 void PaintContents(SkCanvas* canvas,
1950 const gfx::Rect& clip,
1951 PaintingControlSetting picture_control) override {
1952 layer_->SetBounds(gfx::Size(2, 2));
1955 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
1956 const gfx::Rect& clip,
1957 PaintingControlSetting picture_control) override {
1958 NOTIMPLEMENTED();
1959 return nullptr;
1962 bool FillsBoundsCompletely() const override { return false; }
1963 size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
1965 private:
1966 Layer* layer_;
1969 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
1971 void SetupTree() override {
1972 scoped_refptr<PictureLayer> root_layer =
1973 PictureLayer::Create(layer_settings(), &client_);
1974 root_layer->SetIsDrawable(true);
1975 root_layer->SetBounds(gfx::Size(1, 1));
1976 client_.set_layer(root_layer.get());
1978 layer_tree_host()->SetRootLayer(root_layer);
1979 LayerTreeHostTest::SetupTree();
1982 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1983 void AfterTest() override {}
1985 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1986 num_commits_++;
1987 if (num_commits_ == 1) {
1988 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
1989 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds());
1990 } else {
1991 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
1992 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds());
1993 EndTest();
1997 private:
1998 SetBoundsClient client_;
1999 int num_commits_;
2002 SINGLE_AND_MULTI_THREAD_TEST_F(
2003 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2005 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2006 public:
2007 MockIOSurfaceWebGraphicsContext3D() {
2008 test_capabilities_.gpu.iosurface = true;
2009 test_capabilities_.gpu.texture_rectangle = true;
2012 GLuint createTexture() override { return 1; }
2013 MOCK_METHOD1(activeTexture, void(GLenum texture));
2014 MOCK_METHOD2(bindTexture, void(GLenum target,
2015 GLuint texture_id));
2016 MOCK_METHOD3(texParameteri, void(GLenum target,
2017 GLenum pname,
2018 GLint param));
2019 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2020 GLint width,
2021 GLint height,
2022 GLuint ioSurfaceId,
2023 GLuint plane));
2024 MOCK_METHOD4(drawElements, void(GLenum mode,
2025 GLsizei count,
2026 GLenum type,
2027 GLintptr offset));
2028 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2029 MOCK_METHOD3(produceTextureDirectCHROMIUM,
2030 void(GLuint texture, GLenum target, const GLbyte* mailbox));
2033 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2034 protected:
2035 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2036 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2037 new MockIOSurfaceWebGraphicsContext3D);
2038 mock_context_ = mock_context_owned.get();
2040 if (delegating_renderer())
2041 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
2042 else
2043 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
2046 void SetupTree() override {
2047 LayerTreeHostTest::SetupTree();
2049 layer_tree_host()->root_layer()->SetIsDrawable(false);
2051 io_surface_id_ = 9;
2052 io_surface_size_ = gfx::Size(6, 7);
2054 scoped_refptr<IOSurfaceLayer> io_surface_layer =
2055 IOSurfaceLayer::Create(layer_settings());
2056 io_surface_layer->SetBounds(gfx::Size(10, 10));
2057 io_surface_layer->SetIsDrawable(true);
2058 io_surface_layer->SetContentsOpaque(true);
2059 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2060 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2063 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2065 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2066 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2067 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2069 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2070 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2071 .Times(AtLeast(1));
2072 EXPECT_CALL(*mock_context_,
2073 texParameteri(
2074 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2075 .Times(1);
2076 EXPECT_CALL(*mock_context_,
2077 texParameteri(
2078 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2079 .Times(1);
2080 EXPECT_CALL(*mock_context_,
2081 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2082 GL_TEXTURE_POOL_CHROMIUM,
2083 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2084 EXPECT_CALL(*mock_context_,
2085 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2086 GL_TEXTURE_WRAP_S,
2087 GL_CLAMP_TO_EDGE)).Times(1);
2088 EXPECT_CALL(*mock_context_,
2089 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2090 GL_TEXTURE_WRAP_T,
2091 GL_CLAMP_TO_EDGE)).Times(1);
2093 EXPECT_CALL(*mock_context_,
2094 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2095 io_surface_size_.width(),
2096 io_surface_size_.height(),
2097 io_surface_id_,
2098 0)).Times(1);
2100 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2103 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2104 LayerTreeHostImpl::FrameData* frame,
2105 DrawResult draw_result) override {
2106 Mock::VerifyAndClearExpectations(&mock_context_);
2107 ResourceProvider* resource_provider = host_impl->resource_provider();
2108 EXPECT_EQ(1u, resource_provider->num_resources());
2109 CHECK_EQ(1u, frame->render_passes.size());
2110 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2111 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
2112 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2113 const IOSurfaceDrawQuad* io_surface_draw_quad =
2114 IOSurfaceDrawQuad::MaterialCast(quad);
2115 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2116 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id());
2117 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2118 resource_provider->TargetForTesting(
2119 io_surface_draw_quad->io_surface_resource_id()));
2121 if (delegating_renderer()) {
2122 // The io surface layer's resource should be sent to the parent.
2123 EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM(
2124 _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2125 } else {
2126 // The io surface layer's texture is drawn.
2127 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2128 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2129 .Times(AtLeast(1));
2132 return draw_result;
2135 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2136 Mock::VerifyAndClearExpectations(&mock_context_);
2138 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2139 EndTest();
2142 void AfterTest() override {}
2144 int io_surface_id_;
2145 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2146 gfx::Size io_surface_size_;
2149 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2151 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2152 public:
2153 void BeginTest() override {
2154 frame_ = 0;
2155 PostSetNeedsCommitToMainThread();
2158 // Round 1: commit + draw
2159 // Round 2: commit only (no draw/swap)
2160 // Round 3: draw only (no commit)
2162 void DidCommit() override {
2163 int commit = layer_tree_host()->source_frame_number();
2164 switch (commit) {
2165 case 2:
2166 // Round 2 done.
2167 EXPECT_EQ(1, frame_);
2168 layer_tree_host()->SetNeedsRedraw();
2169 break;
2173 void DidCompleteSwapBuffers() override {
2174 int commit = layer_tree_host()->source_frame_number();
2175 ++frame_;
2176 switch (frame_) {
2177 case 1:
2178 // Round 1 done.
2179 EXPECT_EQ(1, commit);
2180 layer_tree_host()->SetNeedsCommit();
2181 break;
2182 case 2:
2183 // Round 3 done.
2184 EXPECT_EQ(2, commit);
2185 EndTest();
2186 break;
2190 void AfterTest() override {}
2192 protected:
2193 int frame_;
2196 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNumFramesPending);
2198 class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest {
2199 public:
2200 void SetupTree() override {
2201 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
2202 root_layer_->SetIsDrawable(true);
2203 root_layer_->SetBounds(gfx::Size(50, 50));
2205 parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
2206 parent_layer_->SetIsDrawable(true);
2207 parent_layer_->SetBounds(gfx::Size(50, 50));
2208 parent_layer_->SetForceRenderSurface(true);
2210 child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
2211 child_layer_->SetIsDrawable(true);
2212 child_layer_->SetBounds(gfx::Size(50, 50));
2214 root_layer_->AddChild(parent_layer_);
2215 parent_layer_->AddChild(child_layer_);
2216 layer_tree_host()->SetRootLayer(root_layer_);
2218 LayerTreeHostTest::SetupTree();
2221 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2222 if (delegating_renderer()) {
2223 return FakeOutputSurface::CreateDelegatingSoftware(
2224 make_scoped_ptr(new SoftwareOutputDevice));
2225 } else {
2226 return FakeOutputSurface::CreateSoftware(
2227 make_scoped_ptr(new SoftwareOutputDevice));
2231 void BeginTest() override {
2232 PostSetNeedsCommitToMainThread();
2233 swap_count_ = 0;
2236 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2237 LayerTreeHostImpl::FrameData* frame_data,
2238 DrawResult draw_result) override {
2239 if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
2240 EXPECT_EQ(1u, frame_data->render_passes.size());
2241 // Has at least 3 quads for each layer.
2242 RenderPass* render_pass = frame_data->render_passes[0];
2243 EXPECT_GE(render_pass->quad_list.size(), 3u);
2244 } else {
2245 EXPECT_EQ(2u, frame_data->render_passes.size());
2247 // At least root layer quad in root render pass.
2248 EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u);
2249 // At least parent and child layer quads in parent render pass.
2250 EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u);
2252 return draw_result;
2255 void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2256 swap_count_++;
2257 switch (swap_count_) {
2258 case 1: {
2259 gfx::Transform identity;
2260 gfx::Rect empty_rect;
2261 bool resourceless_software_draw = true;
2262 host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect,
2263 empty_rect, identity,
2264 resourceless_software_draw);
2265 host_impl->SetFullRootLayerDamage();
2266 host_impl->SetNeedsRedraw();
2267 break;
2269 case 2:
2270 EndTest();
2271 break;
2272 default:
2273 NOTREACHED();
2277 void AfterTest() override {}
2279 private:
2280 FakeContentLayerClient client_;
2281 scoped_refptr<Layer> root_layer_;
2282 scoped_refptr<Layer> parent_layer_;
2283 scoped_refptr<Layer> child_layer_;
2284 int swap_count_;
2287 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw);
2289 // Test for UI Resource management.
2290 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
2291 public:
2292 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
2294 void InitializeSettings(LayerTreeSettings* settings) override {
2295 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
2298 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2300 void DidCommit() override {
2301 int frame = layer_tree_host()->source_frame_number();
2302 switch (frame) {
2303 case 1:
2304 CreateResource();
2305 CreateResource();
2306 PostSetNeedsCommitToMainThread();
2307 break;
2308 case 2:
2309 // Usually ScopedUIResource are deleted from the manager in their
2310 // destructor. Here we just want to test that a direct call to
2311 // DeleteUIResource works.
2312 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
2313 PostSetNeedsCommitToMainThread();
2314 break;
2315 case 3:
2316 // DeleteUIResource can be called with an invalid id.
2317 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
2318 PostSetNeedsCommitToMainThread();
2319 break;
2320 case 4:
2321 CreateResource();
2322 CreateResource();
2323 PostSetNeedsCommitToMainThread();
2324 break;
2325 case 5:
2326 ClearResources();
2327 EndTest();
2328 break;
2332 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
2333 TestWebGraphicsContext3D* context = TestContext();
2335 int frame = impl->active_tree()->source_frame_number();
2336 switch (frame) {
2337 case 0:
2338 ASSERT_EQ(0u, context->NumTextures());
2339 break;
2340 case 1:
2341 // Created two textures.
2342 ASSERT_EQ(2u, context->NumTextures());
2343 break;
2344 case 2:
2345 // One texture left after one deletion.
2346 ASSERT_EQ(1u, context->NumTextures());
2347 break;
2348 case 3:
2349 // Resource manager state should not change when delete is called on an
2350 // invalid id.
2351 ASSERT_EQ(1u, context->NumTextures());
2352 break;
2353 case 4:
2354 // Creation after deletion: two more creates should total up to
2355 // three textures.
2356 ASSERT_EQ(3u, context->NumTextures());
2357 break;
2361 void AfterTest() override {}
2363 private:
2364 // Must clear all resources before exiting.
2365 void ClearResources() {
2366 for (int i = 0; i < num_ui_resources_; i++)
2367 ui_resources_[i] = nullptr;
2370 void CreateResource() {
2371 ui_resources_[num_ui_resources_++] =
2372 FakeScopedUIResource::Create(layer_tree_host());
2375 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
2376 int num_ui_resources_;
2379 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
2381 class PushPropertiesCountingLayerImpl : public LayerImpl {
2382 public:
2383 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
2384 LayerTreeImpl* tree_impl, int id) {
2385 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
2388 ~PushPropertiesCountingLayerImpl() override {}
2390 void PushPropertiesTo(LayerImpl* layer) override {
2391 LayerImpl::PushPropertiesTo(layer);
2392 push_properties_count_++;
2393 // Push state to the active tree because we can only access it from there.
2394 static_cast<PushPropertiesCountingLayerImpl*>(
2395 layer)->push_properties_count_ = push_properties_count_;
2398 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
2399 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
2402 size_t push_properties_count() const { return push_properties_count_; }
2403 void reset_push_properties_count() { push_properties_count_ = 0; }
2405 private:
2406 size_t push_properties_count_;
2408 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
2409 : LayerImpl(tree_impl, id),
2410 push_properties_count_(0) {
2411 SetBounds(gfx::Size(1, 1));
2415 class PushPropertiesCountingLayer : public Layer {
2416 public:
2417 static scoped_refptr<PushPropertiesCountingLayer> Create(
2418 const LayerSettings& settings) {
2419 return new PushPropertiesCountingLayer(settings);
2422 void PushPropertiesTo(LayerImpl* layer) override {
2423 Layer::PushPropertiesTo(layer);
2424 push_properties_count_++;
2425 if (persist_needs_push_properties_)
2426 needs_push_properties_ = true;
2429 // Something to make this layer push properties, but no other layer.
2430 void MakePushProperties() { SetContentsOpaque(!contents_opaque()); }
2432 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
2433 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
2436 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
2438 size_t push_properties_count() const { return push_properties_count_; }
2439 void reset_push_properties_count() { push_properties_count_ = 0; }
2441 void set_persist_needs_push_properties(bool persist) {
2442 persist_needs_push_properties_ = persist;
2445 private:
2446 explicit PushPropertiesCountingLayer(const LayerSettings& settings)
2447 : Layer(settings),
2448 push_properties_count_(0),
2449 persist_needs_push_properties_(false) {
2450 SetBounds(gfx::Size(1, 1));
2452 ~PushPropertiesCountingLayer() override {}
2454 size_t push_properties_count_;
2455 bool persist_needs_push_properties_;
2458 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
2459 protected:
2460 void BeginTest() override {
2461 num_commits_ = 0;
2462 expected_push_properties_root_ = 0;
2463 expected_push_properties_child_ = 0;
2464 expected_push_properties_grandchild_ = 0;
2465 expected_push_properties_child2_ = 0;
2466 expected_push_properties_other_root_ = 0;
2467 expected_push_properties_leaf_layer_ = 0;
2468 PostSetNeedsCommitToMainThread();
2471 void SetupTree() override {
2472 root_ = PushPropertiesCountingLayer::Create(layer_settings());
2473 root_->CreateRenderSurface();
2474 child_ = PushPropertiesCountingLayer::Create(layer_settings());
2475 child2_ = PushPropertiesCountingLayer::Create(layer_settings());
2476 grandchild_ = PushPropertiesCountingLayer::Create(layer_settings());
2477 leaf_always_pushing_layer_ =
2478 PushPropertiesCountingLayer::Create(layer_settings());
2479 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
2481 root_->AddChild(child_);
2482 root_->AddChild(child2_);
2483 child_->AddChild(grandchild_);
2484 child2_->AddChild(leaf_always_pushing_layer_);
2486 other_root_ = PushPropertiesCountingLayer::Create(layer_settings());
2487 other_root_->CreateRenderSurface();
2489 // Don't set the root layer here.
2490 LayerTreeHostTest::SetupTree();
2493 void DidCommitAndDrawFrame() override {
2494 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count())
2495 << "num_commits: " << num_commits_;
2496 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count())
2497 << "num_commits: " << num_commits_;
2498 EXPECT_EQ(expected_push_properties_grandchild_,
2499 grandchild_->push_properties_count())
2500 << "num_commits: " << num_commits_;
2501 EXPECT_EQ(expected_push_properties_child2_,
2502 child2_->push_properties_count())
2503 << "num_commits: " << num_commits_;
2504 EXPECT_EQ(expected_push_properties_other_root_,
2505 other_root_->push_properties_count())
2506 << "num_commits: " << num_commits_;
2507 EXPECT_EQ(expected_push_properties_leaf_layer_,
2508 leaf_always_pushing_layer_->push_properties_count())
2509 << "num_commits: " << num_commits_;
2511 ++num_commits_;
2513 // The scrollbar layer always needs to be pushed.
2514 if (root_->layer_tree_host()) {
2515 EXPECT_TRUE(root_->descendant_needs_push_properties());
2516 EXPECT_FALSE(root_->needs_push_properties());
2518 if (child2_->layer_tree_host()) {
2519 EXPECT_TRUE(child2_->descendant_needs_push_properties());
2520 EXPECT_FALSE(child2_->needs_push_properties());
2522 if (leaf_always_pushing_layer_->layer_tree_host()) {
2523 EXPECT_FALSE(
2524 leaf_always_pushing_layer_->descendant_needs_push_properties());
2525 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
2528 // child_ and grandchild_ don't persist their need to push properties.
2529 if (child_->layer_tree_host()) {
2530 EXPECT_FALSE(child_->descendant_needs_push_properties());
2531 EXPECT_FALSE(child_->needs_push_properties());
2533 if (grandchild_->layer_tree_host()) {
2534 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
2535 EXPECT_FALSE(grandchild_->needs_push_properties());
2538 if (other_root_->layer_tree_host()) {
2539 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
2540 EXPECT_FALSE(other_root_->needs_push_properties());
2543 switch (num_commits_) {
2544 case 1:
2545 layer_tree_host()->SetRootLayer(root_);
2546 // Layers added to the tree get committed.
2547 ++expected_push_properties_root_;
2548 ++expected_push_properties_child_;
2549 ++expected_push_properties_grandchild_;
2550 ++expected_push_properties_child2_;
2551 break;
2552 case 2:
2553 layer_tree_host()->SetNeedsCommit();
2554 // No layers need commit.
2555 break;
2556 case 3:
2557 layer_tree_host()->SetRootLayer(other_root_);
2558 // Layers added to the tree get committed.
2559 ++expected_push_properties_other_root_;
2560 break;
2561 case 4:
2562 layer_tree_host()->SetRootLayer(root_);
2563 // Layers added to the tree get committed.
2564 ++expected_push_properties_root_;
2565 ++expected_push_properties_child_;
2566 ++expected_push_properties_grandchild_;
2567 ++expected_push_properties_child2_;
2568 break;
2569 case 5:
2570 layer_tree_host()->SetNeedsCommit();
2571 // No layers need commit.
2572 break;
2573 case 6:
2574 child_->RemoveFromParent();
2575 // No layers need commit.
2576 break;
2577 case 7:
2578 root_->AddChild(child_);
2579 // Layers added to the tree get committed.
2580 ++expected_push_properties_child_;
2581 ++expected_push_properties_grandchild_;
2582 break;
2583 case 8:
2584 grandchild_->RemoveFromParent();
2585 // No layers need commit.
2586 break;
2587 case 9:
2588 child_->AddChild(grandchild_);
2589 // Layers added to the tree get committed.
2590 ++expected_push_properties_grandchild_;
2591 break;
2592 case 10:
2593 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
2594 // No layers need commit.
2595 break;
2596 case 11:
2597 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
2598 // No layers need commit.
2599 break;
2600 case 12:
2601 child_->MakePushProperties();
2602 // The modified layer needs commit
2603 ++expected_push_properties_child_;
2604 break;
2605 case 13:
2606 child2_->MakePushProperties();
2607 // The modified layer needs commit
2608 ++expected_push_properties_child2_;
2609 break;
2610 case 14:
2611 child_->RemoveFromParent();
2612 root_->AddChild(child_);
2613 // Layers added to the tree get committed.
2614 ++expected_push_properties_child_;
2615 ++expected_push_properties_grandchild_;
2616 break;
2617 case 15:
2618 grandchild_->MakePushProperties();
2619 // The modified layer needs commit
2620 ++expected_push_properties_grandchild_;
2621 break;
2622 case 16:
2623 // SetNeedsDisplay does not always set needs commit (so call it
2624 // explicitly), but is a property change.
2625 child_->SetNeedsDisplay();
2626 ++expected_push_properties_child_;
2627 layer_tree_host()->SetNeedsCommit();
2628 break;
2629 case 17:
2630 EndTest();
2631 break;
2634 // The leaf layer always pushes.
2635 if (leaf_always_pushing_layer_->layer_tree_host())
2636 ++expected_push_properties_leaf_layer_;
2639 void AfterTest() override {}
2641 int num_commits_;
2642 FakeContentLayerClient client_;
2643 scoped_refptr<PushPropertiesCountingLayer> root_;
2644 scoped_refptr<PushPropertiesCountingLayer> child_;
2645 scoped_refptr<PushPropertiesCountingLayer> child2_;
2646 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
2647 scoped_refptr<PushPropertiesCountingLayer> other_root_;
2648 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
2649 size_t expected_push_properties_root_;
2650 size_t expected_push_properties_child_;
2651 size_t expected_push_properties_child2_;
2652 size_t expected_push_properties_grandchild_;
2653 size_t expected_push_properties_other_root_;
2654 size_t expected_push_properties_leaf_layer_;
2657 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
2659 class LayerTreeHostTestImplLayersPushProperties
2660 : public LayerTreeHostTestLayersPushProperties {
2661 protected:
2662 void BeginTest() override {
2663 expected_push_properties_root_impl_ = 0;
2664 expected_push_properties_child_impl_ = 0;
2665 expected_push_properties_grandchild_impl_ = 0;
2666 expected_push_properties_child2_impl_ = 0;
2667 expected_push_properties_grandchild2_impl_ = 0;
2668 LayerTreeHostTestLayersPushProperties::BeginTest();
2671 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2672 // These commits are in response to the changes made in
2673 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
2674 switch (num_commits_) {
2675 case 0:
2676 // Tree hasn't been setup yet don't bother to check anything.
2677 return;
2678 case 1:
2679 // Root gets set up, Everyone is initialized.
2680 ++expected_push_properties_root_impl_;
2681 ++expected_push_properties_child_impl_;
2682 ++expected_push_properties_grandchild_impl_;
2683 ++expected_push_properties_child2_impl_;
2684 ++expected_push_properties_grandchild2_impl_;
2685 break;
2686 case 2:
2687 // Tree doesn't change but the one leaf that always pushes is pushed.
2688 ++expected_push_properties_grandchild2_impl_;
2689 break;
2690 case 3:
2691 // Root is swapped here.
2692 // Clear the expected push properties the tree will be rebuilt.
2693 expected_push_properties_root_impl_ = 0;
2694 expected_push_properties_child_impl_ = 0;
2695 expected_push_properties_grandchild_impl_ = 0;
2696 expected_push_properties_child2_impl_ = 0;
2697 expected_push_properties_grandchild2_impl_ = 0;
2699 // Make sure the new root is pushed.
2700 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
2701 host_impl->RootLayer())->push_properties_count());
2702 return;
2703 case 4:
2704 // Root is swapped back all of the layers in the tree get pushed.
2705 ++expected_push_properties_root_impl_;
2706 ++expected_push_properties_child_impl_;
2707 ++expected_push_properties_grandchild_impl_;
2708 ++expected_push_properties_child2_impl_;
2709 ++expected_push_properties_grandchild2_impl_;
2710 break;
2711 case 5:
2712 // Tree doesn't change but the one leaf that always pushes is pushed.
2713 ++expected_push_properties_grandchild2_impl_;
2714 break;
2715 case 6:
2716 // First child is removed. Structure of the tree changes here so swap
2717 // some of the values. child_impl becomes child2_impl.
2718 expected_push_properties_child_impl_ =
2719 expected_push_properties_child2_impl_;
2720 expected_push_properties_child2_impl_ = 0;
2721 // grandchild_impl becomes grandchild2_impl.
2722 expected_push_properties_grandchild_impl_ =
2723 expected_push_properties_grandchild2_impl_;
2724 expected_push_properties_grandchild2_impl_ = 0;
2726 // grandchild_impl is now the leaf that always pushes. It is pushed.
2727 ++expected_push_properties_grandchild_impl_;
2728 break;
2729 case 7:
2730 // The leaf that always pushes is pushed.
2731 ++expected_push_properties_grandchild_impl_;
2733 // Child is added back. New layers are initialized.
2734 ++expected_push_properties_grandchild2_impl_;
2735 ++expected_push_properties_child2_impl_;
2736 break;
2737 case 8:
2738 // Leaf is removed.
2739 expected_push_properties_grandchild2_impl_ = 0;
2741 // Always pushing.
2742 ++expected_push_properties_grandchild_impl_;
2743 break;
2744 case 9:
2745 // Leaf is added back
2746 ++expected_push_properties_grandchild2_impl_;
2748 // The leaf that always pushes is pushed.
2749 ++expected_push_properties_grandchild_impl_;
2750 break;
2751 case 10:
2752 // The leaf that always pushes is pushed.
2753 ++expected_push_properties_grandchild_impl_;
2754 break;
2755 case 11:
2756 // The leaf that always pushes is pushed.
2757 ++expected_push_properties_grandchild_impl_;
2758 break;
2759 case 12:
2760 // The leaf that always pushes is pushed.
2761 ++expected_push_properties_grandchild_impl_;
2763 // This child position was changed.
2764 ++expected_push_properties_child2_impl_;
2765 break;
2766 case 13:
2767 // The position of this child was changed.
2768 ++expected_push_properties_child_impl_;
2770 // The leaf that always pushes is pushed.
2771 ++expected_push_properties_grandchild_impl_;
2772 break;
2773 case 14:
2774 // Second child is removed from tree. Don't discard counts because
2775 // they are added back before commit.
2777 // The leaf that always pushes is pushed.
2778 ++expected_push_properties_grandchild_impl_;
2780 // Second child added back.
2781 ++expected_push_properties_child2_impl_;
2782 ++expected_push_properties_grandchild2_impl_;
2784 break;
2785 case 15:
2786 // The position of this child was changed.
2787 ++expected_push_properties_grandchild2_impl_;
2789 // The leaf that always pushes is pushed.
2790 ++expected_push_properties_grandchild_impl_;
2791 break;
2792 case 16:
2793 // Second child is invalidated with SetNeedsDisplay
2794 ++expected_push_properties_child2_impl_;
2796 // The leaf that always pushed is pushed.
2797 ++expected_push_properties_grandchild_impl_;
2798 break;
2801 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
2802 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
2803 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
2804 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
2805 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
2807 // Pull the layers that we need from the tree assuming the same structure
2808 // as LayerTreeHostTestLayersPushProperties
2809 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
2810 host_impl->RootLayer());
2812 if (root_impl_ && root_impl_->children().size() > 0) {
2813 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
2814 root_impl_->children()[0]);
2816 if (child_impl_ && child_impl_->children().size() > 0)
2817 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
2818 child_impl_->children()[0]);
2821 if (root_impl_ && root_impl_->children().size() > 1) {
2822 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
2823 root_impl_->children()[1]);
2825 if (child2_impl_ && child2_impl_->children().size() > 0)
2826 leaf_always_pushing_layer_impl_ =
2827 static_cast<PushPropertiesCountingLayerImpl*>(
2828 child2_impl_->children()[0]);
2831 if (root_impl_)
2832 EXPECT_EQ(expected_push_properties_root_impl_,
2833 root_impl_->push_properties_count());
2834 if (child_impl_)
2835 EXPECT_EQ(expected_push_properties_child_impl_,
2836 child_impl_->push_properties_count());
2837 if (grandchild_impl_)
2838 EXPECT_EQ(expected_push_properties_grandchild_impl_,
2839 grandchild_impl_->push_properties_count());
2840 if (child2_impl_)
2841 EXPECT_EQ(expected_push_properties_child2_impl_,
2842 child2_impl_->push_properties_count());
2843 if (leaf_always_pushing_layer_impl_)
2844 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
2845 leaf_always_pushing_layer_impl_->push_properties_count());
2848 size_t expected_push_properties_root_impl_;
2849 size_t expected_push_properties_child_impl_;
2850 size_t expected_push_properties_child2_impl_;
2851 size_t expected_push_properties_grandchild_impl_;
2852 size_t expected_push_properties_grandchild2_impl_;
2855 // In single thread there's no pending tree to push properties from.
2856 MULTI_THREAD_TEST_F(LayerTreeHostTestImplLayersPushProperties);
2858 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
2859 : public LayerTreeHostTest {
2860 protected:
2861 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2863 void SetupTree() override {
2864 root_ = Layer::Create(layer_settings());
2865 root_->CreateRenderSurface();
2866 root_->SetBounds(gfx::Size(1, 1));
2868 bool paint_scrollbar = true;
2869 bool has_thumb = false;
2870 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
2871 layer_settings(), paint_scrollbar, has_thumb, root_->id());
2873 root_->AddChild(scrollbar_layer_);
2875 layer_tree_host()->SetRootLayer(root_);
2876 LayerTreeHostTest::SetupTree();
2879 void DidCommitAndDrawFrame() override {
2880 switch (layer_tree_host()->source_frame_number()) {
2881 case 0:
2882 break;
2883 case 1: {
2884 // During update, the ignore_set_needs_commit_ bit is set to true to
2885 // avoid causing a second commit to be scheduled. If a property change
2886 // is made during this, however, it needs to be pushed in the upcoming
2887 // commit.
2888 scoped_ptr<base::AutoReset<bool>> ignore =
2889 scrollbar_layer_->IgnoreSetNeedsCommit();
2891 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
2893 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
2894 EXPECT_TRUE(root_->descendant_needs_push_properties());
2895 layer_tree_host()->SetNeedsCommit();
2897 scrollbar_layer_->reset_push_properties_count();
2898 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
2899 break;
2901 case 2:
2902 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
2903 EndTest();
2904 break;
2908 void AfterTest() override {}
2910 scoped_refptr<Layer> root_;
2911 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
2914 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
2916 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
2917 protected:
2918 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2920 void SetupTree() override {
2921 root_ = PushPropertiesCountingLayer::Create(layer_settings());
2922 root_->CreateRenderSurface();
2923 child_ = PushPropertiesCountingLayer::Create(layer_settings());
2924 root_->AddChild(child_);
2926 layer_tree_host()->SetRootLayer(root_);
2927 LayerTreeHostTest::SetupTree();
2930 void DidCommitAndDrawFrame() override {
2931 switch (layer_tree_host()->source_frame_number()) {
2932 case 0:
2933 break;
2934 case 1: {
2935 // During update, the ignore_set_needs_commit_ bit is set to true to
2936 // avoid causing a second commit to be scheduled. If a property change
2937 // is made during this, however, it needs to be pushed in the upcoming
2938 // commit.
2939 EXPECT_FALSE(root_->needs_push_properties());
2940 EXPECT_FALSE(child_->needs_push_properties());
2941 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
2942 root_->reset_push_properties_count();
2943 child_->reset_push_properties_count();
2944 child_->SetDrawsContent(true);
2945 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
2946 EXPECT_EQ(0u, root_->push_properties_count());
2947 EXPECT_EQ(0u, child_->push_properties_count());
2948 EXPECT_TRUE(root_->needs_push_properties());
2949 EXPECT_TRUE(child_->needs_push_properties());
2950 break;
2952 case 2:
2953 EXPECT_EQ(1u, root_->push_properties_count());
2954 EXPECT_EQ(1u, child_->push_properties_count());
2955 EXPECT_FALSE(root_->needs_push_properties());
2956 EXPECT_FALSE(child_->needs_push_properties());
2957 EndTest();
2958 break;
2962 void AfterTest() override {}
2964 scoped_refptr<PushPropertiesCountingLayer> root_;
2965 scoped_refptr<PushPropertiesCountingLayer> child_;
2968 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
2970 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
2971 : public LayerTreeHostTest {
2972 protected:
2973 void BeginTest() override {
2974 expected_push_properties_root_ = 0;
2975 expected_push_properties_child_ = 0;
2976 expected_push_properties_grandchild1_ = 0;
2977 expected_push_properties_grandchild2_ = 0;
2978 expected_push_properties_grandchild3_ = 0;
2979 PostSetNeedsCommitToMainThread();
2982 void SetupTree() override {
2983 root_ = PushPropertiesCountingLayer::Create(layer_settings());
2984 root_->CreateRenderSurface();
2985 child_ = PushPropertiesCountingLayer::Create(layer_settings());
2986 grandchild1_ = PushPropertiesCountingLayer::Create(layer_settings());
2987 grandchild2_ = PushPropertiesCountingLayer::Create(layer_settings());
2988 grandchild3_ = PushPropertiesCountingLayer::Create(layer_settings());
2990 root_->AddChild(child_);
2991 child_->AddChild(grandchild1_);
2992 child_->AddChild(grandchild2_);
2993 child_->AddChild(grandchild3_);
2995 // Don't set the root layer here.
2996 LayerTreeHostTest::SetupTree();
2999 void AfterTest() override {}
3001 FakeContentLayerClient client_;
3002 scoped_refptr<PushPropertiesCountingLayer> root_;
3003 scoped_refptr<PushPropertiesCountingLayer> child_;
3004 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3005 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3006 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3007 size_t expected_push_properties_root_;
3008 size_t expected_push_properties_child_;
3009 size_t expected_push_properties_grandchild1_;
3010 size_t expected_push_properties_grandchild2_;
3011 size_t expected_push_properties_grandchild3_;
3014 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3015 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3016 protected:
3017 void DidCommitAndDrawFrame() override {
3018 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3019 switch (last_source_frame_number) {
3020 case 0:
3021 EXPECT_FALSE(root_->needs_push_properties());
3022 EXPECT_FALSE(root_->descendant_needs_push_properties());
3023 EXPECT_FALSE(child_->needs_push_properties());
3024 EXPECT_FALSE(child_->descendant_needs_push_properties());
3025 EXPECT_FALSE(grandchild1_->needs_push_properties());
3026 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3027 EXPECT_FALSE(grandchild2_->needs_push_properties());
3028 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3029 EXPECT_FALSE(grandchild3_->needs_push_properties());
3030 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3032 layer_tree_host()->SetRootLayer(root_);
3034 EXPECT_TRUE(root_->needs_push_properties());
3035 EXPECT_TRUE(root_->descendant_needs_push_properties());
3036 EXPECT_TRUE(child_->needs_push_properties());
3037 EXPECT_TRUE(child_->descendant_needs_push_properties());
3038 EXPECT_TRUE(grandchild1_->needs_push_properties());
3039 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3040 EXPECT_TRUE(grandchild2_->needs_push_properties());
3041 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3042 EXPECT_TRUE(grandchild3_->needs_push_properties());
3043 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3044 break;
3045 case 1:
3046 EndTest();
3047 break;
3052 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3054 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3055 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3056 protected:
3057 void DidCommitAndDrawFrame() override {
3058 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3059 switch (last_source_frame_number) {
3060 case 0:
3061 layer_tree_host()->SetRootLayer(root_);
3062 break;
3063 case 1:
3064 EXPECT_FALSE(root_->needs_push_properties());
3065 EXPECT_FALSE(root_->descendant_needs_push_properties());
3066 EXPECT_FALSE(child_->needs_push_properties());
3067 EXPECT_FALSE(child_->descendant_needs_push_properties());
3068 EXPECT_FALSE(grandchild1_->needs_push_properties());
3069 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3070 EXPECT_FALSE(grandchild2_->needs_push_properties());
3071 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3072 EXPECT_FALSE(grandchild3_->needs_push_properties());
3073 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3075 grandchild1_->RemoveFromParent();
3076 grandchild1_->SetPosition(gfx::Point(1, 1));
3078 EXPECT_FALSE(root_->needs_push_properties());
3079 EXPECT_FALSE(root_->descendant_needs_push_properties());
3080 EXPECT_FALSE(child_->needs_push_properties());
3081 EXPECT_FALSE(child_->descendant_needs_push_properties());
3082 EXPECT_FALSE(grandchild2_->needs_push_properties());
3083 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3084 EXPECT_FALSE(grandchild3_->needs_push_properties());
3085 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3087 child_->AddChild(grandchild1_);
3089 EXPECT_FALSE(root_->needs_push_properties());
3090 EXPECT_TRUE(root_->descendant_needs_push_properties());
3091 EXPECT_FALSE(child_->needs_push_properties());
3092 EXPECT_TRUE(child_->descendant_needs_push_properties());
3093 EXPECT_TRUE(grandchild1_->needs_push_properties());
3094 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3095 EXPECT_FALSE(grandchild2_->needs_push_properties());
3096 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3097 EXPECT_FALSE(grandchild3_->needs_push_properties());
3098 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3100 grandchild2_->SetPosition(gfx::Point(1, 1));
3102 EXPECT_FALSE(root_->needs_push_properties());
3103 EXPECT_TRUE(root_->descendant_needs_push_properties());
3104 EXPECT_FALSE(child_->needs_push_properties());
3105 EXPECT_TRUE(child_->descendant_needs_push_properties());
3106 EXPECT_TRUE(grandchild1_->needs_push_properties());
3107 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3108 EXPECT_TRUE(grandchild2_->needs_push_properties());
3109 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3110 EXPECT_FALSE(grandchild3_->needs_push_properties());
3111 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3113 // grandchild2_ will still need a push properties.
3114 grandchild1_->RemoveFromParent();
3116 EXPECT_FALSE(root_->needs_push_properties());
3117 EXPECT_TRUE(root_->descendant_needs_push_properties());
3118 EXPECT_FALSE(child_->needs_push_properties());
3119 EXPECT_TRUE(child_->descendant_needs_push_properties());
3121 // grandchild3_ does not need a push properties, so recursing should
3122 // no longer be needed.
3123 grandchild2_->RemoveFromParent();
3125 EXPECT_FALSE(root_->needs_push_properties());
3126 EXPECT_FALSE(root_->descendant_needs_push_properties());
3127 EXPECT_FALSE(child_->needs_push_properties());
3128 EXPECT_FALSE(child_->descendant_needs_push_properties());
3129 EndTest();
3130 break;
3135 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3137 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3138 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3139 protected:
3140 void DidCommitAndDrawFrame() override {
3141 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3142 switch (last_source_frame_number) {
3143 case 0:
3144 layer_tree_host()->SetRootLayer(root_);
3145 grandchild1_->set_persist_needs_push_properties(true);
3146 grandchild2_->set_persist_needs_push_properties(true);
3147 break;
3148 case 1:
3149 EXPECT_FALSE(root_->needs_push_properties());
3150 EXPECT_TRUE(root_->descendant_needs_push_properties());
3151 EXPECT_FALSE(child_->needs_push_properties());
3152 EXPECT_TRUE(child_->descendant_needs_push_properties());
3153 EXPECT_TRUE(grandchild1_->needs_push_properties());
3154 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3155 EXPECT_TRUE(grandchild2_->needs_push_properties());
3156 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3157 EXPECT_FALSE(grandchild3_->needs_push_properties());
3158 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3160 // grandchild2_ will still need a push properties.
3161 grandchild1_->RemoveFromParent();
3163 EXPECT_FALSE(root_->needs_push_properties());
3164 EXPECT_TRUE(root_->descendant_needs_push_properties());
3165 EXPECT_FALSE(child_->needs_push_properties());
3166 EXPECT_TRUE(child_->descendant_needs_push_properties());
3168 // grandchild3_ does not need a push properties, so recursing should
3169 // no longer be needed.
3170 grandchild2_->RemoveFromParent();
3172 EXPECT_FALSE(root_->needs_push_properties());
3173 EXPECT_FALSE(root_->descendant_needs_push_properties());
3174 EXPECT_FALSE(child_->needs_push_properties());
3175 EXPECT_FALSE(child_->descendant_needs_push_properties());
3176 EndTest();
3177 break;
3182 MULTI_THREAD_TEST_F(
3183 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3185 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3186 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3187 protected:
3188 void DidCommitAndDrawFrame() override {
3189 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3190 switch (last_source_frame_number) {
3191 case 0:
3192 layer_tree_host()->SetRootLayer(root_);
3193 break;
3194 case 1:
3195 EXPECT_FALSE(root_->needs_push_properties());
3196 EXPECT_FALSE(root_->descendant_needs_push_properties());
3197 EXPECT_FALSE(child_->needs_push_properties());
3198 EXPECT_FALSE(child_->descendant_needs_push_properties());
3199 EXPECT_FALSE(grandchild1_->needs_push_properties());
3200 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3201 EXPECT_FALSE(grandchild2_->needs_push_properties());
3202 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3203 EXPECT_FALSE(grandchild3_->needs_push_properties());
3204 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3206 // Change grandchildren while their parent is not in the tree.
3207 child_->RemoveFromParent();
3208 grandchild1_->SetPosition(gfx::Point(1, 1));
3209 grandchild2_->SetPosition(gfx::Point(1, 1));
3210 root_->AddChild(child_);
3212 EXPECT_FALSE(root_->needs_push_properties());
3213 EXPECT_TRUE(root_->descendant_needs_push_properties());
3214 EXPECT_TRUE(child_->needs_push_properties());
3215 EXPECT_TRUE(child_->descendant_needs_push_properties());
3216 EXPECT_TRUE(grandchild1_->needs_push_properties());
3217 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3218 EXPECT_TRUE(grandchild2_->needs_push_properties());
3219 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3220 EXPECT_TRUE(grandchild3_->needs_push_properties());
3221 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3223 grandchild1_->RemoveFromParent();
3225 EXPECT_FALSE(root_->needs_push_properties());
3226 EXPECT_TRUE(root_->descendant_needs_push_properties());
3227 EXPECT_TRUE(child_->needs_push_properties());
3228 EXPECT_TRUE(child_->descendant_needs_push_properties());
3230 grandchild2_->RemoveFromParent();
3232 EXPECT_FALSE(root_->needs_push_properties());
3233 EXPECT_TRUE(root_->descendant_needs_push_properties());
3234 EXPECT_TRUE(child_->needs_push_properties());
3235 EXPECT_TRUE(child_->descendant_needs_push_properties());
3237 grandchild3_->RemoveFromParent();
3239 EXPECT_FALSE(root_->needs_push_properties());
3240 EXPECT_TRUE(root_->descendant_needs_push_properties());
3241 EXPECT_TRUE(child_->needs_push_properties());
3242 EXPECT_FALSE(child_->descendant_needs_push_properties());
3244 EndTest();
3245 break;
3250 MULTI_THREAD_TEST_F(
3251 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3253 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3254 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3255 protected:
3256 void DidCommitAndDrawFrame() override {
3257 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3258 switch (last_source_frame_number) {
3259 case 0:
3260 layer_tree_host()->SetRootLayer(root_);
3261 break;
3262 case 1:
3263 EXPECT_FALSE(root_->needs_push_properties());
3264 EXPECT_FALSE(root_->descendant_needs_push_properties());
3265 EXPECT_FALSE(child_->needs_push_properties());
3266 EXPECT_FALSE(child_->descendant_needs_push_properties());
3267 EXPECT_FALSE(grandchild1_->needs_push_properties());
3268 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3269 EXPECT_FALSE(grandchild2_->needs_push_properties());
3270 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3271 EXPECT_FALSE(grandchild3_->needs_push_properties());
3272 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3274 child_->SetPosition(gfx::Point(1, 1));
3275 grandchild1_->SetPosition(gfx::Point(1, 1));
3276 grandchild2_->SetPosition(gfx::Point(1, 1));
3278 EXPECT_FALSE(root_->needs_push_properties());
3279 EXPECT_TRUE(root_->descendant_needs_push_properties());
3280 EXPECT_TRUE(child_->needs_push_properties());
3281 EXPECT_TRUE(child_->descendant_needs_push_properties());
3282 EXPECT_TRUE(grandchild1_->needs_push_properties());
3283 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3284 EXPECT_TRUE(grandchild2_->needs_push_properties());
3285 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3286 EXPECT_FALSE(grandchild3_->needs_push_properties());
3287 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3289 grandchild1_->RemoveFromParent();
3291 EXPECT_FALSE(root_->needs_push_properties());
3292 EXPECT_TRUE(root_->descendant_needs_push_properties());
3293 EXPECT_TRUE(child_->needs_push_properties());
3294 EXPECT_TRUE(child_->descendant_needs_push_properties());
3296 grandchild2_->RemoveFromParent();
3298 EXPECT_FALSE(root_->needs_push_properties());
3299 EXPECT_TRUE(root_->descendant_needs_push_properties());
3300 EXPECT_TRUE(child_->needs_push_properties());
3301 EXPECT_FALSE(child_->descendant_needs_push_properties());
3303 child_->RemoveFromParent();
3305 EXPECT_FALSE(root_->needs_push_properties());
3306 EXPECT_FALSE(root_->descendant_needs_push_properties());
3308 EndTest();
3309 break;
3314 MULTI_THREAD_TEST_F(
3315 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
3317 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
3318 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3319 protected:
3320 void DidCommitAndDrawFrame() override {
3321 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3322 switch (last_source_frame_number) {
3323 case 0:
3324 layer_tree_host()->SetRootLayer(root_);
3325 break;
3326 case 1:
3327 EXPECT_FALSE(root_->needs_push_properties());
3328 EXPECT_FALSE(root_->descendant_needs_push_properties());
3329 EXPECT_FALSE(child_->needs_push_properties());
3330 EXPECT_FALSE(child_->descendant_needs_push_properties());
3331 EXPECT_FALSE(grandchild1_->needs_push_properties());
3332 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3333 EXPECT_FALSE(grandchild2_->needs_push_properties());
3334 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3335 EXPECT_FALSE(grandchild3_->needs_push_properties());
3336 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3338 grandchild1_->SetPosition(gfx::Point(1, 1));
3339 grandchild2_->SetPosition(gfx::Point(1, 1));
3340 child_->SetPosition(gfx::Point(1, 1));
3342 EXPECT_FALSE(root_->needs_push_properties());
3343 EXPECT_TRUE(root_->descendant_needs_push_properties());
3344 EXPECT_TRUE(child_->needs_push_properties());
3345 EXPECT_TRUE(child_->descendant_needs_push_properties());
3346 EXPECT_TRUE(grandchild1_->needs_push_properties());
3347 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3348 EXPECT_TRUE(grandchild2_->needs_push_properties());
3349 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3350 EXPECT_FALSE(grandchild3_->needs_push_properties());
3351 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3353 grandchild1_->RemoveFromParent();
3355 EXPECT_FALSE(root_->needs_push_properties());
3356 EXPECT_TRUE(root_->descendant_needs_push_properties());
3357 EXPECT_TRUE(child_->needs_push_properties());
3358 EXPECT_TRUE(child_->descendant_needs_push_properties());
3360 grandchild2_->RemoveFromParent();
3362 EXPECT_FALSE(root_->needs_push_properties());
3363 EXPECT_TRUE(root_->descendant_needs_push_properties());
3364 EXPECT_TRUE(child_->needs_push_properties());
3365 EXPECT_FALSE(child_->descendant_needs_push_properties());
3367 child_->RemoveFromParent();
3369 EXPECT_FALSE(root_->needs_push_properties());
3370 EXPECT_FALSE(root_->descendant_needs_push_properties());
3372 EndTest();
3373 break;
3378 MULTI_THREAD_TEST_F(
3379 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
3381 // This test verifies that the tree activation callback is invoked correctly.
3382 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
3383 public:
3384 LayerTreeHostTestTreeActivationCallback()
3385 : num_commits_(0), callback_count_(0) {}
3387 void BeginTest() override {
3388 PostSetNeedsCommitToMainThread();
3391 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3392 LayerTreeHostImpl::FrameData* frame_data,
3393 DrawResult draw_result) override {
3394 ++num_commits_;
3395 switch (num_commits_) {
3396 case 1:
3397 EXPECT_EQ(0, callback_count_);
3398 callback_count_ = 0;
3399 SetCallback(true);
3400 PostSetNeedsCommitToMainThread();
3401 break;
3402 case 2:
3403 EXPECT_EQ(1, callback_count_);
3404 callback_count_ = 0;
3405 SetCallback(false);
3406 PostSetNeedsCommitToMainThread();
3407 break;
3408 case 3:
3409 EXPECT_EQ(0, callback_count_);
3410 callback_count_ = 0;
3411 EndTest();
3412 break;
3413 default:
3414 ADD_FAILURE() << num_commits_;
3415 EndTest();
3416 break;
3418 return LayerTreeHostTest::PrepareToDrawOnThread(
3419 host_impl, frame_data, draw_result);
3422 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
3424 void SetCallback(bool enable) {
3425 output_surface()->SetTreeActivationCallback(
3426 enable
3427 ? base::Bind(
3428 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
3429 base::Unretained(this))
3430 : base::Closure());
3433 void ActivationCallback() { ++callback_count_; }
3435 int num_commits_;
3436 int callback_count_;
3439 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTreeActivationCallback);
3441 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
3442 public:
3443 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
3445 void BeginTest() override {
3446 ASSERT_TRUE(invalidate_layer_)
3447 << "Derived tests must set this in SetupTree";
3449 // One initial commit.
3450 PostSetNeedsCommitToMainThread();
3453 void DidCommitAndDrawFrame() override {
3454 // After commit, invalidate the layer. This should cause a commit.
3455 if (layer_tree_host()->source_frame_number() == 1)
3456 invalidate_layer_->SetNeedsDisplay();
3459 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
3460 num_draws_++;
3461 if (impl->active_tree()->source_frame_number() == 1)
3462 EndTest();
3465 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3466 num_commits_++;
3469 void AfterTest() override {
3470 EXPECT_GE(2, num_commits_);
3471 EXPECT_GE(2, num_draws_);
3474 protected:
3475 scoped_refptr<Layer> invalidate_layer_;
3477 private:
3478 int num_commits_;
3479 int num_draws_;
3482 // VideoLayer must support being invalidated and then passing that along
3483 // to the compositor thread, even though no resources are updated in
3484 // response to that invalidation.
3485 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
3486 public:
3487 void SetupTree() override {
3488 LayerTreeHostTest::SetupTree();
3489 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(
3490 layer_settings(), &provider_, media::VIDEO_ROTATION_0);
3491 video_layer->SetBounds(gfx::Size(10, 10));
3492 video_layer->SetIsDrawable(true);
3493 layer_tree_host()->root_layer()->AddChild(video_layer);
3495 invalidate_layer_ = video_layer;
3498 private:
3499 FakeVideoFrameProvider provider_;
3502 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
3504 // IOSurfaceLayer must support being invalidated and then passing that along
3505 // to the compositor thread, even though no resources are updated in
3506 // response to that invalidation.
3507 class LayerTreeHostTestIOSurfaceLayerInvalidate
3508 : public LayerInvalidateCausesDraw {
3509 public:
3510 void SetupTree() override {
3511 LayerTreeHostTest::SetupTree();
3512 scoped_refptr<IOSurfaceLayer> layer =
3513 IOSurfaceLayer::Create(layer_settings());
3514 layer->SetBounds(gfx::Size(10, 10));
3515 uint32_t fake_io_surface_id = 7;
3516 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
3517 layer->SetIsDrawable(true);
3518 layer_tree_host()->root_layer()->AddChild(layer);
3520 invalidate_layer_ = layer;
3524 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceLayerInvalidate);
3526 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
3527 protected:
3528 void SetupTree() override {
3529 root_layer_ = Layer::Create(layer_settings());
3530 root_layer_->CreateRenderSurface();
3531 root_layer_->SetPosition(gfx::Point());
3532 root_layer_->SetBounds(gfx::Size(10, 10));
3534 parent_layer_ = SolidColorLayer::Create(layer_settings());
3535 parent_layer_->SetPosition(gfx::Point());
3536 parent_layer_->SetBounds(gfx::Size(10, 10));
3537 parent_layer_->SetIsDrawable(true);
3538 root_layer_->AddChild(parent_layer_);
3540 child_layer_ = SolidColorLayer::Create(layer_settings());
3541 child_layer_->SetPosition(gfx::Point());
3542 child_layer_->SetBounds(gfx::Size(10, 10));
3543 child_layer_->SetIsDrawable(true);
3544 parent_layer_->AddChild(child_layer_);
3546 layer_tree_host()->SetRootLayer(root_layer_);
3547 LayerTreeHostTest::SetupTree();
3550 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3552 void DidCommitAndDrawFrame() override {
3553 switch (layer_tree_host()->source_frame_number()) {
3554 case 1:
3555 // The layer type used does not need to push properties every frame.
3556 EXPECT_FALSE(child_layer_->needs_push_properties());
3558 // Change the bounds of the child layer, but make it skipped
3559 // by CalculateDrawProperties.
3560 parent_layer_->SetOpacity(0.f);
3561 child_layer_->SetBounds(gfx::Size(5, 5));
3562 break;
3563 case 2:
3564 // The bounds of the child layer were pushed to the impl side.
3565 EXPECT_FALSE(child_layer_->needs_push_properties());
3567 EndTest();
3568 break;
3572 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3573 LayerImpl* root = impl->active_tree()->root_layer();
3574 LayerImpl* parent = root->children()[0];
3575 LayerImpl* child = parent->children()[0];
3577 switch (impl->active_tree()->source_frame_number()) {
3578 case 1:
3579 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
3580 break;
3584 void AfterTest() override {}
3586 scoped_refptr<Layer> root_layer_;
3587 scoped_refptr<SolidColorLayer> parent_layer_;
3588 scoped_refptr<SolidColorLayer> child_layer_;
3591 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
3593 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
3594 protected:
3595 void SetupTree() override {
3596 root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
3597 root_layer_->SetBounds(gfx::Size(10, 10));
3599 layer_tree_host()->SetRootLayer(root_layer_);
3600 LayerTreeHostTest::SetupTree();
3603 void BeginTest() override {
3604 // The viewport is empty, but we still need to update layers on the main
3605 // thread.
3606 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
3607 PostSetNeedsCommitToMainThread();
3610 void DidCommit() override {
3611 // The layer should be updated even though the viewport is empty, so we
3612 // are capable of drawing it on the impl tree.
3613 EXPECT_GT(root_layer_->update_count(), 0);
3614 EndTest();
3617 void AfterTest() override {}
3619 FakeContentLayerClient client_;
3620 scoped_refptr<FakePictureLayer> root_layer_;
3623 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
3625 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
3626 protected:
3627 void InitializeSettings(LayerTreeSettings* settings) override {
3628 // Testing async uploads.
3629 settings->use_zero_copy = false;
3630 settings->use_one_copy = false;
3633 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3634 scoped_refptr<TestContextProvider> context_provider =
3635 TestContextProvider::Create();
3636 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
3637 if (delegating_renderer())
3638 return FakeOutputSurface::CreateDelegating3d(context_provider);
3639 else
3640 return FakeOutputSurface::Create3d(context_provider);
3643 void SetupTree() override {
3644 client_.set_fill_with_nonsolid_color(true);
3645 scoped_refptr<FakePictureLayer> root_layer =
3646 FakePictureLayer::Create(layer_settings(), &client_);
3647 root_layer->SetBounds(gfx::Size(1024, 1024));
3648 root_layer->SetIsDrawable(true);
3650 layer_tree_host()->SetRootLayer(root_layer);
3651 LayerTreeHostTest::SetupTree();
3654 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3656 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3657 TestWebGraphicsContext3D* context = TestContext();
3659 // Expect that the transfer buffer memory used is equal to the
3660 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
3661 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
3662 EndTest();
3665 void AfterTest() override {}
3667 private:
3668 FakeContentLayerClient client_;
3671 // Impl-side painting is a multi-threaded compositor feature.
3672 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
3674 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
3675 : public LayerTreeHostTest {
3676 protected:
3677 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
3678 : first_output_surface_memory_limit_(4321234),
3679 second_output_surface_memory_limit_(1234321) {}
3681 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3682 if (!first_context_provider_.get()) {
3683 first_context_provider_ = TestContextProvider::Create();
3684 } else {
3685 EXPECT_FALSE(second_context_provider_.get());
3686 second_context_provider_ = TestContextProvider::Create();
3689 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
3690 ? second_context_provider_
3691 : first_context_provider_);
3692 scoped_ptr<FakeOutputSurface> output_surface;
3693 if (delegating_renderer())
3694 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
3695 else
3696 output_surface = FakeOutputSurface::Create3d(provider);
3697 output_surface->SetMemoryPolicyToSetAtBind(
3698 make_scoped_ptr(new ManagedMemoryPolicy(
3699 second_context_provider_.get() ? second_output_surface_memory_limit_
3700 : first_output_surface_memory_limit_,
3701 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
3702 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
3703 return output_surface.Pass();
3706 void SetupTree() override {
3707 root_ = FakePictureLayer::Create(layer_settings(), &client_);
3708 root_->SetBounds(gfx::Size(20, 20));
3709 layer_tree_host()->SetRootLayer(root_);
3710 LayerTreeHostTest::SetupTree();
3713 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3715 void DidCommitAndDrawFrame() override {
3716 // Lost context sometimes takes two frames to recreate. The third frame
3717 // is sometimes aborted, so wait until the fourth frame to verify that
3718 // the memory has been set, and the fifth frame to end the test.
3719 if (layer_tree_host()->source_frame_number() < 5) {
3720 layer_tree_host()->SetNeedsCommit();
3721 } else if (layer_tree_host()->source_frame_number() == 5) {
3722 EndTest();
3726 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
3727 switch (impl->active_tree()->source_frame_number()) {
3728 case 1:
3729 EXPECT_EQ(first_output_surface_memory_limit_,
3730 impl->memory_allocation_limit_bytes());
3731 // Lose the output surface.
3732 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
3733 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
3734 break;
3735 case 4:
3736 EXPECT_EQ(second_output_surface_memory_limit_,
3737 impl->memory_allocation_limit_bytes());
3738 break;
3742 void AfterTest() override {}
3744 scoped_refptr<TestContextProvider> first_context_provider_;
3745 scoped_refptr<TestContextProvider> second_context_provider_;
3746 size_t first_output_surface_memory_limit_;
3747 size_t second_output_surface_memory_limit_;
3748 FakeContentLayerClient client_;
3749 scoped_refptr<Layer> root_;
3752 SINGLE_AND_MULTI_THREAD_TEST_F(
3753 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
3755 struct TestSwapPromiseResult {
3756 TestSwapPromiseResult()
3757 : did_activate_called(false),
3758 did_swap_called(false),
3759 did_not_swap_called(false),
3760 dtor_called(false),
3761 reason(SwapPromise::COMMIT_FAILS) {}
3763 bool did_activate_called;
3764 bool did_swap_called;
3765 bool did_not_swap_called;
3766 bool dtor_called;
3767 SwapPromise::DidNotSwapReason reason;
3768 base::Lock lock;
3771 class TestSwapPromise : public SwapPromise {
3772 public:
3773 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
3775 ~TestSwapPromise() override {
3776 base::AutoLock lock(result_->lock);
3777 result_->dtor_called = true;
3780 void DidActivate() override {
3781 base::AutoLock lock(result_->lock);
3782 EXPECT_FALSE(result_->did_activate_called);
3783 EXPECT_FALSE(result_->did_swap_called);
3784 EXPECT_FALSE(result_->did_not_swap_called);
3785 result_->did_activate_called = true;
3788 void DidSwap(CompositorFrameMetadata* metadata) override {
3789 base::AutoLock lock(result_->lock);
3790 EXPECT_TRUE(result_->did_activate_called);
3791 EXPECT_FALSE(result_->did_swap_called);
3792 EXPECT_FALSE(result_->did_not_swap_called);
3793 result_->did_swap_called = true;
3796 void DidNotSwap(DidNotSwapReason reason) override {
3797 base::AutoLock lock(result_->lock);
3798 EXPECT_FALSE(result_->did_swap_called);
3799 EXPECT_FALSE(result_->did_not_swap_called);
3800 EXPECT_FALSE(result_->did_activate_called &&
3801 reason != DidNotSwapReason::SWAP_FAILS);
3802 result_->did_not_swap_called = true;
3803 result_->reason = reason;
3806 int64 TraceId() const override { return 0; }
3808 private:
3809 // Not owned.
3810 TestSwapPromiseResult* result_;
3813 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
3814 protected:
3815 LayerTreeHostTestBreakSwapPromise()
3816 : commit_count_(0), commit_complete_count_(0) {}
3818 void WillBeginMainFrame() override {
3819 ASSERT_LE(commit_count_, 2);
3820 scoped_ptr<SwapPromise> swap_promise(
3821 new TestSwapPromise(&swap_promise_result_[commit_count_]));
3822 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
3825 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3827 void DidCommit() override {
3828 commit_count_++;
3829 if (commit_count_ == 2) {
3830 // This commit will finish.
3831 layer_tree_host()->SetNeedsCommit();
3835 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3836 if (host_impl->pending_tree()) {
3837 int frame = host_impl->pending_tree()->source_frame_number();
3838 base::AutoLock lock(swap_promise_result_[frame].lock);
3839 EXPECT_FALSE(swap_promise_result_[frame].did_activate_called);
3840 EXPECT_FALSE(swap_promise_result_[frame].did_swap_called);
3844 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3845 int frame = host_impl->active_tree()->source_frame_number();
3846 base::AutoLock lock(swap_promise_result_[frame].lock);
3847 EXPECT_TRUE(swap_promise_result_[frame].did_activate_called);
3848 EXPECT_FALSE(swap_promise_result_[frame].did_swap_called);
3851 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3852 commit_complete_count_++;
3853 if (commit_complete_count_ == 1) {
3854 // This commit will be aborted because no actual update.
3855 PostSetNeedsUpdateLayersToMainThread();
3859 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
3860 int frame = host_impl->active_tree()->source_frame_number();
3861 if (frame == 2) {
3862 EndTest();
3866 void AfterTest() override {
3867 // 3 commits are scheduled. 2 completes. 1 is aborted.
3868 EXPECT_EQ(commit_count_, 3);
3869 EXPECT_EQ(commit_complete_count_, 2);
3872 // The first commit completes and causes swap buffer which finishes
3873 // the promise.
3874 base::AutoLock lock(swap_promise_result_[0].lock);
3875 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
3876 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
3877 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
3881 // The second commit is aborted since it contains no updates.
3882 base::AutoLock lock(swap_promise_result_[1].lock);
3883 EXPECT_FALSE(swap_promise_result_[1].did_activate_called);
3884 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
3885 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
3886 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
3887 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
3891 // The last commit completes but it does not cause swap buffer because
3892 // there is no damage in the frame data.
3893 base::AutoLock lock(swap_promise_result_[2].lock);
3894 EXPECT_TRUE(swap_promise_result_[2].did_activate_called);
3895 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
3896 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
3897 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
3898 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
3902 int commit_count_;
3903 int commit_complete_count_;
3904 TestSwapPromiseResult swap_promise_result_[3];
3907 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
3909 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
3910 public:
3911 LayerTreeHostTestKeepSwapPromise() {}
3913 void BeginTest() override {
3914 layer_ = SolidColorLayer::Create(layer_settings());
3915 layer_->SetIsDrawable(true);
3916 layer_->SetBounds(gfx::Size(10, 10));
3917 layer_tree_host()->SetRootLayer(layer_);
3918 gfx::Size bounds(100, 100);
3919 layer_tree_host()->SetViewportSize(bounds);
3920 PostSetNeedsCommitToMainThread();
3923 void DidCommit() override {
3924 MainThreadTaskRunner()->PostTask(
3925 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
3926 base::Unretained(this)));
3929 void ChangeFrame() {
3930 switch (layer_tree_host()->source_frame_number()) {
3931 case 1:
3932 layer_->SetBounds(gfx::Size(10, 11));
3933 layer_tree_host()->QueueSwapPromise(
3934 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
3935 break;
3936 case 2:
3937 break;
3938 default:
3939 NOTREACHED();
3940 break;
3944 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3945 if (host_impl->pending_tree()) {
3946 if (host_impl->pending_tree()->source_frame_number() == 1) {
3947 base::AutoLock lock(swap_promise_result_.lock);
3948 EXPECT_FALSE(swap_promise_result_.did_activate_called);
3949 EXPECT_FALSE(swap_promise_result_.did_swap_called);
3950 SetCallback(true);
3951 } else {
3952 SetCallback(false);
3957 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3958 if (host_impl->active_tree()->source_frame_number() == 1) {
3959 base::AutoLock lock(swap_promise_result_.lock);
3960 EXPECT_TRUE(swap_promise_result_.did_activate_called);
3961 EXPECT_FALSE(swap_promise_result_.did_swap_called);
3965 void ActivationCallback() {
3966 // DidActivate needs to happen before the tree activation callback.
3967 base::AutoLock lock(swap_promise_result_.lock);
3968 EXPECT_TRUE(swap_promise_result_.did_activate_called);
3971 void SetCallback(bool enable) {
3972 output_surface()->SetTreeActivationCallback(
3973 enable
3974 ? base::Bind(&LayerTreeHostTestKeepSwapPromise::ActivationCallback,
3975 base::Unretained(this))
3976 : base::Closure());
3979 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
3980 EXPECT_TRUE(result);
3981 if (host_impl->active_tree()->source_frame_number() >= 1) {
3982 // The commit changes layers so it should cause a swap.
3983 base::AutoLock lock(swap_promise_result_.lock);
3984 EXPECT_TRUE(swap_promise_result_.did_swap_called);
3985 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
3986 EXPECT_TRUE(swap_promise_result_.dtor_called);
3987 EndTest();
3991 void AfterTest() override {}
3993 private:
3994 scoped_refptr<Layer> layer_;
3995 TestSwapPromiseResult swap_promise_result_;
3998 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
4000 class LayerTreeHostTestBreakSwapPromiseForVisibility
4001 : public LayerTreeHostTest {
4002 protected:
4003 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4005 void SetVisibleFalseAndQueueSwapPromise() {
4006 layer_tree_host()->SetVisible(false);
4007 scoped_ptr<SwapPromise> swap_promise(
4008 new TestSwapPromise(&swap_promise_result_));
4009 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4012 void ScheduledActionWillSendBeginMainFrame() override {
4013 MainThreadTaskRunner()->PostTask(
4014 FROM_HERE,
4015 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility
4016 ::SetVisibleFalseAndQueueSwapPromise,
4017 base::Unretained(this)));
4020 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4021 CommitEarlyOutReason reason) override {
4022 EndTest();
4025 void AfterTest() override {
4027 base::AutoLock lock(swap_promise_result_.lock);
4028 EXPECT_FALSE(swap_promise_result_.did_activate_called);
4029 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4030 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4031 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4032 EXPECT_TRUE(swap_promise_result_.dtor_called);
4036 TestSwapPromiseResult swap_promise_result_;
4039 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
4041 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest {
4042 protected:
4043 LayerTreeHostTestBreakSwapPromiseForContext()
4044 : output_surface_lost_triggered_(false) {
4047 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4049 void LoseOutputSurfaceAndQueueSwapPromise() {
4050 layer_tree_host()->DidLoseOutputSurface();
4051 scoped_ptr<SwapPromise> swap_promise(
4052 new TestSwapPromise(&swap_promise_result_));
4053 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4056 void ScheduledActionWillSendBeginMainFrame() override {
4057 if (output_surface_lost_triggered_)
4058 return;
4059 output_surface_lost_triggered_ = true;
4061 MainThreadTaskRunner()->PostTask(
4062 FROM_HERE,
4063 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext
4064 ::LoseOutputSurfaceAndQueueSwapPromise,
4065 base::Unretained(this)));
4068 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4069 CommitEarlyOutReason reason) override {
4070 // This is needed so that the impl-thread state matches main-thread state.
4071 host_impl->DidLoseOutputSurface();
4072 EndTest();
4075 void AfterTest() override {
4077 base::AutoLock lock(swap_promise_result_.lock);
4078 EXPECT_FALSE(swap_promise_result_.did_activate_called);
4079 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4080 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4081 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4082 EXPECT_TRUE(swap_promise_result_.dtor_called);
4086 bool output_surface_lost_triggered_;
4087 TestSwapPromiseResult swap_promise_result_;
4090 SINGLE_AND_MULTI_THREAD_TEST_F(
4091 LayerTreeHostTestBreakSwapPromiseForContext);
4093 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
4094 public:
4095 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
4096 LayerTreeHostImpl* layer_tree_host_impl,
4097 int* set_needs_commit_count,
4098 int* set_needs_redraw_count)
4099 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
4100 set_needs_commit_count_(set_needs_commit_count) {}
4102 ~SimpleSwapPromiseMonitor() override {}
4104 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
4106 void OnSetNeedsRedrawOnImpl() override {
4107 ADD_FAILURE() << "Should not get called on main thread.";
4110 void OnForwardScrollUpdateToMainThreadOnImpl() override {
4111 ADD_FAILURE() << "Should not get called on main thread.";
4114 private:
4115 int* set_needs_commit_count_;
4118 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
4119 public:
4120 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4122 void WillBeginMainFrame() override {
4123 if (TestEnded())
4124 return;
4126 int set_needs_commit_count = 0;
4127 int set_needs_redraw_count = 0;
4130 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4131 new SimpleSwapPromiseMonitor(layer_tree_host(),
4132 NULL,
4133 &set_needs_commit_count,
4134 &set_needs_redraw_count));
4135 layer_tree_host()->SetNeedsCommit();
4136 EXPECT_EQ(1, set_needs_commit_count);
4137 EXPECT_EQ(0, set_needs_redraw_count);
4140 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
4141 // monitored.
4142 layer_tree_host()->SetNeedsCommit();
4143 EXPECT_EQ(1, set_needs_commit_count);
4144 EXPECT_EQ(0, set_needs_redraw_count);
4147 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4148 new SimpleSwapPromiseMonitor(layer_tree_host(),
4149 NULL,
4150 &set_needs_commit_count,
4151 &set_needs_redraw_count));
4152 layer_tree_host()->SetNeedsUpdateLayers();
4153 EXPECT_EQ(2, set_needs_commit_count);
4154 EXPECT_EQ(0, set_needs_redraw_count);
4158 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4159 new SimpleSwapPromiseMonitor(layer_tree_host(),
4160 NULL,
4161 &set_needs_commit_count,
4162 &set_needs_redraw_count));
4163 layer_tree_host()->SetNeedsAnimate();
4164 EXPECT_EQ(3, set_needs_commit_count);
4165 EXPECT_EQ(0, set_needs_redraw_count);
4168 EndTest();
4171 void AfterTest() override {}
4174 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
4176 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
4177 : public LayerTreeHostTest {
4178 protected:
4179 void SetupTree() override {
4180 LayerTreeHostTest::SetupTree();
4181 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
4184 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4186 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4187 host_impl->EvictAllUIResources();
4188 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
4189 // mode. Active tree should require high-res to draw after entering this
4190 // mode to ensure that high-res tiles are also required for a pending tree
4191 // to be activated.
4192 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
4195 void DidCommit() override {
4196 int frame = layer_tree_host()->source_frame_number();
4197 switch (frame) {
4198 case 1:
4199 PostSetNeedsCommitToMainThread();
4200 break;
4201 case 2:
4202 ui_resource_ = nullptr;
4203 EndTest();
4204 break;
4208 void AfterTest() override {}
4210 FakeContentLayerClient client_;
4211 scoped_ptr<FakeScopedUIResource> ui_resource_;
4214 // This test is flaky, see http://crbug.com/386199
4215 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
4217 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
4218 protected:
4219 void InitializeSettings(LayerTreeSettings* settings) override {
4220 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4221 EXPECT_FALSE(settings->gpu_rasterization_forced);
4224 void SetupTree() override {
4225 LayerTreeHostTest::SetupTree();
4227 scoped_refptr<PictureLayer> layer =
4228 PictureLayer::Create(layer_settings(), &layer_client_);
4229 layer->SetBounds(gfx::Size(10, 10));
4230 layer->SetIsDrawable(true);
4231 layer_tree_host()->root_layer()->AddChild(layer);
4234 void BeginTest() override {
4235 Layer* root = layer_tree_host()->root_layer();
4236 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4237 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
4239 // Verify default values.
4240 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4241 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4242 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
4243 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4245 // Setting gpu rasterization trigger does not enable gpu rasterization.
4246 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4247 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4249 PostSetNeedsCommitToMainThread();
4252 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4253 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4254 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4257 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4258 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4259 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4260 EndTest();
4263 void AfterTest() override {}
4265 FakeContentLayerClient layer_client_;
4268 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
4270 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
4271 protected:
4272 void InitializeSettings(LayerTreeSettings* settings) override {
4273 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4274 settings->gpu_rasterization_enabled = true;
4277 void SetupTree() override {
4278 LayerTreeHostTest::SetupTree();
4280 scoped_refptr<PictureLayer> layer =
4281 PictureLayer::Create(layer_settings(), &layer_client_);
4282 layer->SetBounds(gfx::Size(10, 10));
4283 layer->SetIsDrawable(true);
4284 layer_tree_host()->root_layer()->AddChild(layer);
4287 void BeginTest() override {
4288 Layer* root = layer_tree_host()->root_layer();
4289 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4290 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
4292 // Verify default values.
4293 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4294 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4295 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
4296 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4298 // Gpu rasterization trigger is relevant.
4299 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4300 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4302 // Content-based veto is relevant as well.
4303 recording_source->SetUnsuitableForGpuRasterizationForTesting();
4304 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
4305 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4306 // Veto will take effect when layers are updated.
4307 // The results will be verified after commit is completed below.
4308 // Since we are manually marking picture pile as unsuitable,
4309 // make sure that the layer gets a chance to update.
4310 layer->SetNeedsDisplay();
4311 PostSetNeedsCommitToMainThread();
4314 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4315 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4316 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4319 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4320 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4321 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4322 EndTest();
4325 void AfterTest() override {}
4327 FakeContentLayerClient layer_client_;
4330 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
4332 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
4333 protected:
4334 void InitializeSettings(LayerTreeSettings* settings) override {
4335 EXPECT_FALSE(settings->gpu_rasterization_forced);
4336 settings->gpu_rasterization_forced = true;
4339 void SetupTree() override {
4340 LayerTreeHostTest::SetupTree();
4342 scoped_refptr<FakePictureLayer> layer =
4343 FakePictureLayer::Create(layer_settings(), &layer_client_);
4344 layer->SetBounds(gfx::Size(10, 10));
4345 layer->SetIsDrawable(true);
4346 layer_tree_host()->root_layer()->AddChild(layer);
4349 void BeginTest() override {
4350 Layer* root = layer_tree_host()->root_layer();
4351 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4352 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
4354 // Verify default values.
4355 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4356 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4357 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
4358 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4360 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
4361 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4362 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4364 // Content-based veto is irrelevant as well.
4365 recording_source->SetUnsuitableForGpuRasterizationForTesting();
4366 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
4367 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4368 // Veto will take effect when layers are updated.
4369 // The results will be verified after commit is completed below.
4370 // Since we are manually marking picture pile as unsuitable,
4371 // make sure that the layer gets a chance to update.
4372 layer->SetNeedsDisplay();
4373 PostSetNeedsCommitToMainThread();
4376 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4377 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
4378 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4381 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4382 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
4383 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4384 EndTest();
4387 void AfterTest() override {}
4389 FakeContentLayerClient layer_client_;
4392 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
4394 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
4395 public:
4396 LayerTreeHostTestContinuousPainting()
4397 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
4399 protected:
4400 enum { kExpectedNumCommits = 10 };
4402 void SetupTree() override {
4403 scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
4404 root_layer->SetBounds(bounds_);
4405 root_layer->CreateRenderSurface();
4407 child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
4408 child_layer_->SetBounds(bounds_);
4409 child_layer_->SetIsDrawable(true);
4410 root_layer->AddChild(child_layer_);
4412 layer_tree_host()->SetRootLayer(root_layer);
4413 layer_tree_host()->SetViewportSize(bounds_);
4414 LayerTreeHostTest::SetupTree();
4417 void BeginTest() override {
4418 MainThreadTaskRunner()->PostTask(
4419 FROM_HERE,
4420 base::Bind(
4421 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
4422 base::Unretained(this)));
4423 // Wait 50x longer than expected.
4424 double milliseconds_per_frame =
4425 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
4426 MainThreadTaskRunner()->PostDelayedTask(
4427 FROM_HERE,
4428 base::Bind(
4429 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
4430 base::Unretained(this)),
4431 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
4432 milliseconds_per_frame));
4435 void BeginMainFrame(const BeginFrameArgs& args) override {
4436 child_layer_->SetNeedsDisplay();
4439 void AfterTest() override {
4440 EXPECT_LE(kExpectedNumCommits, num_commits_);
4441 EXPECT_LE(kExpectedNumCommits, num_draws_);
4442 EXPECT_LE(kExpectedNumCommits, child_layer_->update_count());
4445 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4446 if (++num_draws_ == kExpectedNumCommits)
4447 EndTest();
4450 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4451 ++num_commits_;
4454 private:
4455 void EnableContinuousPainting() {
4456 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
4457 debug_state.continuous_painting = true;
4458 layer_tree_host()->SetDebugState(debug_state);
4461 void DisableContinuousPainting() {
4462 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
4463 debug_state.continuous_painting = false;
4464 layer_tree_host()->SetDebugState(debug_state);
4465 EndTest();
4468 int num_commits_;
4469 int num_draws_;
4470 const gfx::Size bounds_;
4471 FakeContentLayerClient client_;
4472 scoped_refptr<FakePictureLayer> child_layer_;
4475 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
4477 class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
4478 : public LayerTreeHostTest {
4479 public:
4480 enum { kExpectedNumImplFrames = 10 };
4482 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame()
4483 : will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {}
4485 void BeginTest() override {
4486 // Kick off the test with a commit.
4487 PostSetNeedsCommitToMainThread();
4490 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
4491 const BeginFrameArgs& args) override {
4492 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
4493 EXPECT_FALSE(TestEnded());
4494 will_begin_impl_frame_count_++;
4497 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
4498 did_finish_impl_frame_count_++;
4499 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
4501 // Request a number of commits to cause multiple impl frames. We expect to
4502 // get one more impl frames than the number of commits requested because
4503 // after a commit it takes one frame to become idle.
4504 if (did_finish_impl_frame_count_ < kExpectedNumImplFrames - 1)
4505 PostSetNeedsCommitToMainThread();
4508 void SendBeginMainFrameNotExpectedSoon() override { EndTest(); }
4510 void AfterTest() override {
4511 EXPECT_GT(will_begin_impl_frame_count_, 0);
4512 EXPECT_GT(did_finish_impl_frame_count_, 0);
4513 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
4515 // TODO(mithro): Figure out why the multithread version of this test
4516 // sometimes has one more frame then expected. Possibly related to
4517 // http://crbug.com/443185
4518 if (!HasImplThread()) {
4519 EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
4520 EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
4524 private:
4525 int will_begin_impl_frame_count_;
4526 int did_finish_impl_frame_count_;
4529 SINGLE_AND_MULTI_THREAD_TEST_F(
4530 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame);
4532 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
4533 public:
4534 LayerTreeHostTestSendBeginFramesToChildren()
4535 : begin_frame_sent_to_children_(false) {
4538 void BeginTest() override {
4539 // Kick off the test with a commit.
4540 PostSetNeedsCommitToMainThread();
4543 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
4544 begin_frame_sent_to_children_ = true;
4545 EndTest();
4548 void DidBeginMainFrame() override {
4549 // Children requested BeginFrames.
4550 layer_tree_host()->SetChildrenNeedBeginFrames(true);
4553 void AfterTest() override {
4554 // Ensure that BeginFrame message is sent to children during parent
4555 // scheduler handles its BeginFrame.
4556 EXPECT_TRUE(begin_frame_sent_to_children_);
4559 private:
4560 bool begin_frame_sent_to_children_;
4563 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
4565 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
4566 : public LayerTreeHostTest {
4567 public:
4568 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
4569 : begin_frame_sent_to_children_(false) {
4572 void InitializeSettings(LayerTreeSettings* settings) override {
4573 settings->use_external_begin_frame_source = true;
4576 void BeginTest() override {
4577 // Kick off the test with a commit.
4578 PostSetNeedsCommitToMainThread();
4581 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
4582 begin_frame_sent_to_children_ = true;
4583 EndTest();
4586 void DidBeginMainFrame() override {
4587 // Children requested BeginFrames.
4588 layer_tree_host()->SetChildrenNeedBeginFrames(true);
4591 void AfterTest() override {
4592 // Ensure that BeginFrame message is sent to children during parent
4593 // scheduler handles its BeginFrame.
4594 EXPECT_TRUE(begin_frame_sent_to_children_);
4597 private:
4598 bool begin_frame_sent_to_children_;
4601 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
4603 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
4604 public:
4605 LayerTreeHostTestActivateOnInvisible()
4606 : activation_count_(0), visible_(true) {}
4608 void BeginTest() override {
4609 // Kick off the test with a commit.
4610 PostSetNeedsCommitToMainThread();
4613 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
4614 // Make sure we don't activate using the notify signal from tile manager.
4615 host_impl->BlockNotifyReadyToActivateForTesting(true);
4618 void DidCommit() override { layer_tree_host()->SetVisible(false); }
4620 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
4621 bool visible) override {
4622 visible_ = visible;
4624 // Once invisible, we can go visible again.
4625 if (!visible) {
4626 PostSetVisibleToMainThread(true);
4627 } else {
4628 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
4629 EndTest();
4633 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4634 ++activation_count_;
4635 EXPECT_FALSE(visible_);
4638 void AfterTest() override {
4639 // Ensure we activated even though the signal was blocked.
4640 EXPECT_EQ(1, activation_count_);
4641 EXPECT_TRUE(visible_);
4644 private:
4645 int activation_count_;
4646 bool visible_;
4648 FakeContentLayerClient client_;
4649 scoped_refptr<FakePictureLayer> picture_layer_;
4652 // TODO(vmpstr): Enable with single thread impl-side painting.
4653 // This test blocks activation which is not supported for single thread mode.
4654 MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestActivateOnInvisible);
4656 // Do a synchronous composite and assert that the swap promise succeeds.
4657 class LayerTreeHostTestSynchronousCompositeSwapPromise
4658 : public LayerTreeHostTest {
4659 public:
4660 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
4662 void InitializeSettings(LayerTreeSettings* settings) override {
4663 settings->single_thread_proxy_scheduler = false;
4664 settings->use_zero_copy = true;
4665 settings->use_one_copy = false;
4668 void BeginTest() override {
4669 // Successful composite.
4670 scoped_ptr<SwapPromise> swap_promise0(
4671 new TestSwapPromise(&swap_promise_result_[0]));
4672 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
4673 layer_tree_host()->Composite(base::TimeTicks::Now());
4675 // Fail to swap (no damage).
4676 scoped_ptr<SwapPromise> swap_promise1(
4677 new TestSwapPromise(&swap_promise_result_[1]));
4678 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
4679 layer_tree_host()->SetNeedsCommit();
4680 layer_tree_host()->Composite(base::TimeTicks::Now());
4682 // Fail to draw (not visible).
4683 scoped_ptr<SwapPromise> swap_promise2(
4684 new TestSwapPromise(&swap_promise_result_[2]));
4685 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
4686 layer_tree_host()->SetNeedsDisplayOnAllLayers();
4687 layer_tree_host()->SetVisible(false);
4688 layer_tree_host()->Composite(base::TimeTicks::Now());
4690 EndTest();
4693 void DidCommit() override {
4694 commit_count_++;
4695 ASSERT_LE(commit_count_, 3);
4698 void AfterTest() override {
4699 EXPECT_EQ(3, commit_count_);
4701 // Initial swap promise should have succeded.
4703 base::AutoLock lock(swap_promise_result_[0].lock);
4704 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4705 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4706 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4709 // Second swap promise fails to swap.
4711 base::AutoLock lock(swap_promise_result_[1].lock);
4712 EXPECT_TRUE(swap_promise_result_[1].did_activate_called);
4713 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4714 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4715 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
4716 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4719 // Third swap promises also fails to swap (and draw).
4721 base::AutoLock lock(swap_promise_result_[2].lock);
4722 EXPECT_TRUE(swap_promise_result_[2].did_activate_called);
4723 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4724 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4725 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4726 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4730 int commit_count_;
4731 TestSwapPromiseResult swap_promise_result_[3];
4734 SINGLE_THREAD_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
4736 // Make sure page scale and top control deltas are applied to the client even
4737 // when the LayerTreeHost doesn't have a root layer.
4738 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
4739 : public LayerTreeHostTest {
4740 public:
4741 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
4742 : deltas_sent_to_client_(false) {}
4744 void BeginTest() override {
4745 layer_tree_host()->SetRootLayer(nullptr);
4746 info_.page_scale_delta = 3.14f;
4747 info_.top_controls_delta = 2.73f;
4749 PostSetNeedsCommitToMainThread();
4752 void BeginMainFrame(const BeginFrameArgs& args) override {
4753 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
4755 layer_tree_host()->ApplyScrollAndScale(&info_);
4756 EndTest();
4759 void ApplyViewportDeltas(const gfx::Vector2dF& inner,
4760 const gfx::Vector2dF& outer,
4761 const gfx::Vector2dF& elastic_overscroll_delta,
4762 float scale_delta,
4763 float top_controls_delta) override {
4764 EXPECT_EQ(info_.page_scale_delta, scale_delta);
4765 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
4766 deltas_sent_to_client_ = true;
4769 void AfterTest() override {
4770 EXPECT_TRUE(deltas_sent_to_client_);
4773 ScrollAndScaleSet info_;
4774 bool deltas_sent_to_client_;
4777 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
4779 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
4780 protected:
4781 LayerTreeHostTestCrispUpAfterPinchEnds()
4782 : playback_allowed_event_(true, true) {}
4784 void SetupTree() override {
4785 frame_ = 1;
4786 posted_ = false;
4787 client_.set_fill_with_nonsolid_color(true);
4789 scoped_refptr<Layer> root = Layer::Create(layer_settings());
4790 root->SetBounds(gfx::Size(500, 500));
4792 scoped_refptr<Layer> pinch = Layer::Create(layer_settings());
4793 pinch->SetBounds(gfx::Size(500, 500));
4794 pinch->SetScrollClipLayerId(root->id());
4795 pinch->SetIsContainerForFixedPositionLayers(true);
4796 root->AddChild(pinch);
4798 scoped_ptr<FakePicturePile> pile(
4799 new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
4800 LayerTreeSettings().default_tile_grid_size));
4801 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
4802 scoped_refptr<FakePictureLayer> layer =
4803 FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
4804 pile.Pass());
4805 layer->SetBounds(gfx::Size(500, 500));
4806 layer->SetContentsOpaque(true);
4807 // Avoid LCD text on the layer so we don't cause extra commits when we
4808 // pinch.
4809 layer->disable_lcd_text();
4810 pinch->AddChild(layer);
4812 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
4813 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
4814 layer_tree_host()->SetRootLayer(root);
4815 LayerTreeHostTest::SetupTree();
4818 // Returns the delta scale of all quads in the frame's root pass from their
4819 // ideal, or 0 if they are not all the same.
4820 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
4821 if (frame_data->has_no_damage)
4822 return 0.f;
4823 float frame_scale = 0.f;
4824 RenderPass* root_pass = frame_data->render_passes.back();
4825 for (const auto& draw_quad : root_pass->quad_list) {
4826 // Checkerboards mean an incomplete frame.
4827 if (draw_quad->material != DrawQuad::TILED_CONTENT)
4828 return 0.f;
4829 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
4830 float quad_scale =
4831 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
4832 float transform_scale = SkMScalarToFloat(
4833 quad->shared_quad_state->quad_to_target_transform.matrix().get(0, 0));
4834 float scale = quad_scale / transform_scale;
4835 if (frame_scale != 0.f && frame_scale != scale)
4836 return 0.f;
4837 frame_scale = scale;
4839 return frame_scale;
4842 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4844 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4845 LayerTreeHostImpl::FrameData* frame_data,
4846 DrawResult draw_result) override {
4847 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
4848 switch (frame_) {
4849 case 1:
4850 // Drew at page scale 1 before any pinching.
4851 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
4852 EXPECT_EQ(1.f, quad_scale_delta);
4853 PostNextAfterDraw(host_impl);
4854 break;
4855 case 2:
4856 if (quad_scale_delta != 1.f)
4857 break;
4858 // Drew at page scale 1.5 after pinching in.
4859 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
4860 EXPECT_EQ(1.f, quad_scale_delta);
4861 PostNextAfterDraw(host_impl);
4862 break;
4863 case 3:
4864 // By pinching out, we will create a new tiling and raster it. This may
4865 // cause some additional draws, though we should still be drawing with
4866 // the old 1.5 tiling.
4867 if (frame_data->has_no_damage)
4868 break;
4869 // Drew at page scale 1 with the 1.5 tiling while pinching out.
4870 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
4871 EXPECT_EQ(1.5f, quad_scale_delta);
4872 // We don't PostNextAfterDraw here, instead we wait for the new tiling
4873 // to finish rastering so we don't get any noise in further steps.
4874 break;
4875 case 4:
4876 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
4877 // while waiting for texture uploads to complete.
4878 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
4879 // This frame will not have any damage, since it's actually the same as
4880 // the last frame, and should contain no incomplete tiles. We just want
4881 // to make sure we drew here at least once after the pinch ended to be
4882 // sure that drawing after pinch doesn't leave us at the wrong scale
4883 EXPECT_TRUE(frame_data->has_no_damage);
4884 PostNextAfterDraw(host_impl);
4885 break;
4886 case 5:
4887 if (quad_scale_delta != 1.f)
4888 break;
4889 // Drew at scale 1 after texture uploads are done.
4890 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
4891 EXPECT_EQ(1.f, quad_scale_delta);
4892 EndTest();
4893 break;
4895 return draw_result;
4898 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
4899 if (posted_)
4900 return;
4901 posted_ = true;
4902 ImplThreadTaskRunner()->PostDelayedTask(
4903 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
4904 base::Unretained(this), host_impl),
4905 // Use a delay to allow raster/upload to happen in between frames. This
4906 // should cause flakiness if we fail to block raster/upload when
4907 // desired.
4908 base::TimeDelta::FromMilliseconds(16 * 4));
4911 void Next(LayerTreeHostImpl* host_impl) {
4912 ++frame_;
4913 posted_ = false;
4914 switch (frame_) {
4915 case 2:
4916 // Pinch zoom in.
4917 host_impl->PinchGestureBegin();
4918 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
4919 host_impl->PinchGestureEnd();
4920 break;
4921 case 3:
4922 // Pinch zoom back to 1.f but don't end it.
4923 host_impl->PinchGestureBegin();
4924 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
4925 break;
4926 case 4:
4927 // End the pinch, but delay tile production.
4928 playback_allowed_event_.Reset();
4929 host_impl->PinchGestureEnd();
4930 break;
4931 case 5:
4932 // Let tiles complete.
4933 playback_allowed_event_.Signal();
4934 break;
4938 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
4939 const Tile* tile) override {
4940 if (frame_ == 3) {
4941 // On frame 3, we will have a lower res tile complete for the pinch-out
4942 // gesture even though it's not displayed. We wait for it here to prevent
4943 // flakiness.
4944 EXPECT_EQ(0.75f, tile->contents_scale());
4945 PostNextAfterDraw(host_impl);
4947 // On frame_ == 4, we are preventing texture uploads from completing,
4948 // so this verifies they are not completing before frame_ == 5.
4949 // Flaky failures here indicate we're failing to prevent uploads from
4950 // completing.
4951 EXPECT_NE(4, frame_) << tile->contents_scale();
4954 void AfterTest() override {}
4956 FakeContentLayerClient client_;
4957 int frame_;
4958 bool posted_;
4959 base::WaitableEvent playback_allowed_event_;
4962 // This test does pinching on the impl side which is not supported in single
4963 // thread.
4964 MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
4966 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
4967 : public LayerTreeHostTestCrispUpAfterPinchEnds {
4968 protected:
4969 void InitializeSettings(LayerTreeSettings* settings) override {
4970 settings->use_one_copy = true;
4973 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4974 scoped_ptr<TestWebGraphicsContext3D> context3d =
4975 TestWebGraphicsContext3D::Create();
4976 context3d->set_support_image(true);
4977 context3d->set_support_sync_query(true);
4978 #if defined(OS_MACOSX)
4979 context3d->set_support_texture_rectangle(true);
4980 #endif
4982 if (delegating_renderer())
4983 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
4984 else
4985 return FakeOutputSurface::Create3d(context3d.Pass());
4989 // This test does pinching on the impl side which is not supported in single
4990 // thread.
4991 MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
4993 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
4994 protected:
4995 RasterizeWithGpuRasterizationCreatesResources() {}
4997 void InitializeSettings(LayerTreeSettings* settings) override {
4998 settings->gpu_rasterization_forced = true;
5001 void SetupTree() override {
5002 client_.set_fill_with_nonsolid_color(true);
5004 scoped_refptr<Layer> root = Layer::Create(layer_settings());
5005 root->SetBounds(gfx::Size(500, 500));
5007 scoped_ptr<FakePicturePile> pile(
5008 new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
5009 LayerTreeSettings().default_tile_grid_size));
5010 scoped_refptr<FakePictureLayer> layer =
5011 FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
5012 pile.Pass());
5013 layer->SetBounds(gfx::Size(500, 500));
5014 layer->SetContentsOpaque(true);
5015 root->AddChild(layer);
5017 layer_tree_host()->SetRootLayer(root);
5018 LayerTreeHostTest::SetupTree();
5021 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5023 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5024 LayerTreeHostImpl::FrameData* frame_data,
5025 DrawResult draw_result) override {
5026 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
5027 EndTest();
5028 return draw_result;
5030 void AfterTest() override {}
5032 FakeContentLayerClient client_;
5035 SINGLE_AND_MULTI_THREAD_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
5037 class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
5038 protected:
5039 GpuRasterizationRasterizesBorderTiles() : viewport_size_(1024, 2048) {}
5041 void InitializeSettings(LayerTreeSettings* settings) override {
5042 settings->gpu_rasterization_enabled = true;
5043 settings->gpu_rasterization_forced = true;
5046 void SetupTree() override {
5047 client_.set_fill_with_nonsolid_color(true);
5049 scoped_ptr<FakePicturePile> pile(
5050 new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
5051 LayerTreeSettings().default_tile_grid_size));
5052 scoped_refptr<FakePictureLayer> root =
5053 FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
5054 pile.Pass());
5055 root->SetBounds(gfx::Size(10000, 10000));
5056 root->SetContentsOpaque(true);
5058 layer_tree_host()->SetRootLayer(root);
5059 LayerTreeHostTest::SetupTree();
5060 layer_tree_host()->SetViewportSize(viewport_size_);
5063 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5065 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5066 LayerTreeHostImpl::FrameData* frame_data,
5067 DrawResult draw_result) override {
5068 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources());
5069 EndTest();
5070 return draw_result;
5073 void AfterTest() override {}
5075 private:
5076 FakeContentLayerClient client_;
5077 gfx::Size viewport_size_;
5080 SINGLE_AND_MULTI_THREAD_TEST_F(GpuRasterizationRasterizesBorderTiles);
5082 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
5083 : public LayerTreeHostTest {
5084 protected:
5085 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
5086 : playback_allowed_event_(true, true) {}
5088 void SetupTree() override {
5089 step_ = 1;
5090 continuous_draws_ = 0;
5091 client_.set_fill_with_nonsolid_color(true);
5093 scoped_refptr<Layer> root = Layer::Create(layer_settings());
5094 root->SetBounds(gfx::Size(500, 500));
5096 scoped_refptr<Layer> pinch = Layer::Create(layer_settings());
5097 pinch->SetBounds(gfx::Size(500, 500));
5098 pinch->SetScrollClipLayerId(root->id());
5099 pinch->SetIsContainerForFixedPositionLayers(true);
5100 root->AddChild(pinch);
5102 scoped_ptr<FakePicturePile> pile(
5103 new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
5104 LayerTreeSettings().default_tile_grid_size));
5105 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5106 scoped_refptr<FakePictureLayer> layer =
5107 FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
5108 pile.Pass());
5109 layer->SetBounds(gfx::Size(500, 500));
5110 layer->SetContentsOpaque(true);
5111 // Avoid LCD text on the layer so we don't cause extra commits when we
5112 // pinch.
5113 layer->disable_lcd_text();
5114 pinch->AddChild(layer);
5116 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5117 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5118 layer_tree_host()->SetRootLayer(root);
5119 LayerTreeHostTest::SetupTree();
5122 // Returns the delta scale of all quads in the frame's root pass from their
5123 // ideal, or 0 if they are not all the same.
5124 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5125 if (frame_data->has_no_damage)
5126 return 0.f;
5127 float frame_scale = 0.f;
5128 RenderPass* root_pass = frame_data->render_passes.back();
5129 for (const auto& draw_quad : root_pass->quad_list) {
5130 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5131 float quad_scale =
5132 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5133 float transform_scale = SkMScalarToFloat(
5134 quad->shared_quad_state->quad_to_target_transform.matrix().get(0, 0));
5135 float scale = quad_scale / transform_scale;
5136 if (frame_scale != 0.f && frame_scale != scale)
5137 return 0.f;
5138 frame_scale = scale;
5140 return frame_scale;
5143 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5145 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5146 LayerTreeHostImpl::FrameData* frame_data,
5147 DrawResult draw_result) override {
5148 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5149 switch (step_) {
5150 case 1:
5151 // Drew at scale 1 before any pinching.
5152 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5153 EXPECT_EQ(1.f, quad_scale_delta);
5154 break;
5155 case 2:
5156 if (quad_scale_delta != 1.f / 1.5f)
5157 break;
5158 // Drew at scale 1 still though the ideal is 1.5.
5159 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5160 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
5161 break;
5162 case 3:
5163 // Continuous draws are attempted.
5164 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5165 if (!frame_data->has_no_damage)
5166 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
5167 break;
5168 case 4:
5169 if (quad_scale_delta != 1.f)
5170 break;
5171 // Drew at scale 1.5 when all the tiles completed.
5172 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5173 EXPECT_EQ(1.f, quad_scale_delta);
5174 break;
5175 case 5:
5176 // TODO(danakj): We get more draws before the NotifyReadyToDraw
5177 // because it is asynchronous from the previous draw and happens late.
5178 break;
5179 case 6:
5180 // NotifyReadyToDraw happened. If we were already inside a frame, we may
5181 // try to draw once more.
5182 break;
5183 case 7:
5184 NOTREACHED() << "No draws should happen once we have a complete frame.";
5185 break;
5187 return draw_result;
5190 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
5191 switch (step_) {
5192 case 1:
5193 // Delay tile production.
5194 playback_allowed_event_.Reset();
5195 // Pinch zoom in to cause new tiles to be required.
5196 host_impl->PinchGestureBegin();
5197 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
5198 host_impl->PinchGestureEnd();
5199 ++step_;
5200 break;
5201 case 2:
5202 ++step_;
5203 break;
5204 case 3:
5205 // We should continue to try draw while there are incomplete visible
5206 // tiles.
5207 if (++continuous_draws_ > 5) {
5208 // Allow the tiles to complete.
5209 playback_allowed_event_.Signal();
5210 ++step_;
5212 break;
5213 case 4:
5214 ++step_;
5215 break;
5216 case 5:
5217 // Waiting for NotifyReadyToDraw.
5218 break;
5219 case 6:
5220 // NotifyReadyToDraw happened.
5221 ++step_;
5222 break;
5226 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
5227 if (step_ == 5) {
5228 ++step_;
5229 // NotifyReadyToDraw has happened, we may draw once more, but should not
5230 // get any more draws after that. End the test after a timeout to watch
5231 // for any extraneous draws.
5232 // TODO(brianderson): We could remove this delay and instead wait until
5233 // the BeginFrameSource decides it doesn't need to send frames anymore,
5234 // or test that it already doesn't here.
5235 EndTestAfterDelayMs(16 * 4);
5239 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5240 const Tile* tile) override {
5241 // On step_ == 2, we are preventing texture uploads from completing,
5242 // so this verifies they are not completing before step_ == 3.
5243 // Flaky failures here indicate we're failing to prevent uploads from
5244 // completing.
5245 EXPECT_NE(2, step_);
5248 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
5250 FakeContentLayerClient client_;
5251 int step_;
5252 int continuous_draws_;
5253 base::WaitableEvent playback_allowed_event_;
5256 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
5258 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
5259 public:
5260 LayerTreeHostTestOneActivatePerPrepareTiles()
5261 : notify_ready_to_activate_count_(0u),
5262 scheduled_prepare_tiles_count_(0) {}
5264 void SetupTree() override {
5265 client_.set_fill_with_nonsolid_color(true);
5266 scoped_refptr<FakePictureLayer> root_layer =
5267 FakePictureLayer::Create(layer_settings(), &client_);
5268 root_layer->SetBounds(gfx::Size(1500, 1500));
5269 root_layer->SetIsDrawable(true);
5271 layer_tree_host()->SetRootLayer(root_layer);
5272 LayerTreeHostTest::SetupTree();
5275 void BeginTest() override {
5276 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
5277 PostSetNeedsCommitToMainThread();
5280 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
5281 bool success) override {
5282 ASSERT_TRUE(success);
5283 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
5286 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
5287 ++notify_ready_to_activate_count_;
5288 EndTestAfterDelayMs(100);
5291 void ScheduledActionPrepareTiles() override {
5292 ++scheduled_prepare_tiles_count_;
5295 void AfterTest() override {
5296 // Expect at most a notification for each scheduled prepare tiles, plus one
5297 // for the initial commit (which doesn't go through scheduled actions).
5298 // The reason this is not an equality is because depending on timing, we
5299 // might get a prepare tiles but not yet get a notification that we're
5300 // ready to activate. The intent of a test is to ensure that we don't
5301 // get more than one notification per prepare tiles, so this is OK.
5302 EXPECT_LE(notify_ready_to_activate_count_,
5303 1u + scheduled_prepare_tiles_count_);
5306 protected:
5307 FakeContentLayerClient client_;
5308 size_t notify_ready_to_activate_count_;
5309 size_t scheduled_prepare_tiles_count_;
5312 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
5314 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
5315 : public LayerTreeHostTest {
5316 public:
5317 LayerTreeHostTestFrameTimingRequestsSaveTimestamps()
5318 : check_results_on_commit_(false) {}
5320 void SetupTree() override {
5321 scoped_refptr<FakePictureLayer> root_layer =
5322 FakePictureLayer::Create(layer_settings(), &client_);
5323 root_layer->SetBounds(gfx::Size(200, 200));
5324 root_layer->SetIsDrawable(true);
5326 scoped_refptr<FakePictureLayer> child_layer =
5327 FakePictureLayer::Create(layer_settings(), &client_);
5328 child_layer->SetBounds(gfx::Size(1500, 1500));
5329 child_layer->SetIsDrawable(true);
5331 std::vector<FrameTimingRequest> requests;
5332 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100)));
5333 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100)));
5334 child_layer->SetFrameTimingRequests(requests);
5336 root_layer->AddChild(child_layer);
5337 layer_tree_host()->SetRootLayer(root_layer);
5338 LayerTreeHostTest::SetupTree();
5341 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5343 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5344 if (!check_results_on_commit_)
5345 return;
5347 // Since in reality, the events will be read by LayerTreeHost during commit,
5348 // we check the requests here to ensure that they are correct at the next
5349 // commit time (as opposed to checking in DrawLayers for instance).
5350 // TODO(vmpstr): Change this to read things from the main thread when this
5351 // information is propagated to the main thread (not yet implemented).
5352 FrameTimingTracker* tracker = host_impl->frame_timing_tracker();
5354 // Check composite events.
5356 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set =
5357 tracker->GroupCompositeCountsByRectId();
5358 EXPECT_EQ(1u, timing_set->size());
5359 auto rect_1_it = timing_set->find(1);
5360 EXPECT_TRUE(rect_1_it != timing_set->end());
5361 const auto& timing_events = rect_1_it->second;
5362 EXPECT_EQ(1u, timing_events.size());
5363 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
5364 timing_events[0].frame_id);
5365 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
5368 // Check main frame events.
5370 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> timing_set =
5371 tracker->GroupMainFrameCountsByRectId();
5372 EXPECT_EQ(2u, timing_set->size());
5373 auto rect_1_it = timing_set->find(1);
5374 EXPECT_TRUE(rect_1_it != timing_set->end());
5375 const auto& timing_events = rect_1_it->second;
5376 EXPECT_EQ(1u, timing_events.size());
5377 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
5378 timing_events[0].frame_id);
5379 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
5380 EXPECT_GT(timing_events[0].end_time, timing_events[0].timestamp);
5383 EndTest();
5386 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
5387 check_results_on_commit_ = true;
5388 PostSetNeedsCommitToMainThread();
5391 void AfterTest() override {}
5393 private:
5394 FakeContentLayerClient client_;
5395 bool check_results_on_commit_;
5398 // Frame timing is not implemented in single thread proxy.
5399 MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
5401 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
5402 public:
5403 LayerTreeHostTestActivationCausesPrepareTiles()
5404 : scheduled_prepare_tiles_count_(0) {}
5406 void SetupTree() override {
5407 client_.set_fill_with_nonsolid_color(true);
5408 scoped_refptr<FakePictureLayer> root_layer =
5409 FakePictureLayer::Create(layer_settings(), &client_);
5410 root_layer->SetBounds(gfx::Size(150, 150));
5411 root_layer->SetIsDrawable(true);
5413 layer_tree_host()->SetRootLayer(root_layer);
5414 LayerTreeHostTest::SetupTree();
5417 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5419 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
5420 // Ensure we've already activated.
5421 EXPECT_FALSE(impl->pending_tree());
5423 // After activating, we either need to prepare tiles, or we've already
5424 // called a scheduled prepare tiles. This is done because activation might
5425 // cause us to have to memory available (old active tree is gone), so we
5426 // need to ensure we will get a PrepareTiles call.
5427 if (!impl->prepare_tiles_needed())
5428 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
5429 EndTest();
5432 void ScheduledActionPrepareTiles() override {
5433 ++scheduled_prepare_tiles_count_;
5436 void AfterTest() override {}
5438 protected:
5439 FakeContentLayerClient client_;
5440 int scheduled_prepare_tiles_count_;
5443 // This test is testing activation from a pending tree and doesn't make sense
5444 // with single thread commit-to-active.
5445 MULTI_THREAD_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
5447 // This tests an assertion that DidCommit and WillCommit happen in the same
5448 // stack frame with no tasks that run between them. Various embedders of
5449 // cc depend on this logic. ui::Compositor holds a compositor lock between
5450 // these events and the inspector timeline wants begin/end CompositeLayers
5451 // to be properly nested with other begin/end events.
5452 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
5453 : public LayerTreeHostTest {
5454 public:
5455 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
5457 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5459 void WillCommit() override {
5460 MainThreadTaskRunner()->PostTask(
5461 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
5462 EndTestShouldRunAfterDidCommit,
5463 base::Unretained(this)));
5466 void EndTestShouldRunAfterDidCommit() {
5467 EXPECT_TRUE(did_commit_);
5468 EndTest();
5471 void DidCommit() override {
5472 EXPECT_FALSE(did_commit_);
5473 did_commit_ = true;
5476 void AfterTest() override { EXPECT_TRUE(did_commit_); }
5478 private:
5479 bool did_commit_;
5482 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
5484 class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
5485 protected:
5486 void SetupTree() override {
5487 root = Layer::Create(layer_settings());
5488 child = Layer::Create(layer_settings());
5489 root->AddChild(child);
5490 layer_tree_host()->SetRootLayer(root);
5491 LayerTreeHostTest::SetupTree();
5494 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
5496 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5498 void DidCommit() override {
5499 switch (layer_tree_host()->source_frame_number()) {
5500 case 1:
5501 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
5502 base::Bind(CopyOutputCallback)));
5503 EXPECT_TRUE(
5504 root->draw_properties().layer_or_descendant_has_copy_request);
5505 break;
5506 case 2:
5507 EXPECT_FALSE(
5508 root->draw_properties().layer_or_descendant_has_copy_request);
5509 EndTest();
5510 break;
5514 void AfterTest() override {}
5516 private:
5517 scoped_refptr<Layer> root;
5518 scoped_refptr<Layer> child;
5521 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
5523 class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
5524 protected:
5525 void SetupTree() override {
5526 // The masked layer has bounds 50x50, but it has a child that causes
5527 // the surface bounds to be larger. It also has a parent that clips the
5528 // masked layer and its surface.
5530 scoped_refptr<Layer> root = Layer::Create(layer_settings());
5532 scoped_refptr<Layer> clipping_layer = Layer::Create(layer_settings());
5533 root->AddChild(clipping_layer);
5535 scoped_refptr<FakePictureLayer> content_layer =
5536 FakePictureLayer::Create(layer_settings(), &client_);
5537 clipping_layer->AddChild(content_layer);
5539 scoped_refptr<FakePictureLayer> content_child_layer =
5540 FakePictureLayer::Create(layer_settings(), &client_);
5541 content_layer->AddChild(content_child_layer);
5543 scoped_refptr<FakePictureLayer> mask_layer =
5544 FakePictureLayer::Create(layer_settings(), &client_);
5545 content_layer->SetMaskLayer(mask_layer.get());
5547 gfx::Size root_size(100, 100);
5548 root->SetBounds(root_size);
5550 gfx::Rect clipping_rect(20, 10, 10, 20);
5551 clipping_layer->SetBounds(clipping_rect.size());
5552 clipping_layer->SetPosition(clipping_rect.origin());
5553 clipping_layer->SetMasksToBounds(true);
5555 gfx::Size layer_size(50, 50);
5556 content_layer->SetBounds(layer_size);
5557 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin());
5559 gfx::Size child_size(50, 50);
5560 content_child_layer->SetBounds(child_size);
5561 content_child_layer->SetPosition(gfx::Point(20, 0));
5563 gfx::Size mask_size(100, 100);
5564 mask_layer->SetBounds(mask_size);
5565 mask_layer->SetIsMask(true);
5567 layer_tree_host()->SetRootLayer(root);
5568 LayerTreeTest::SetupTree();
5571 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5573 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5574 LayerTreeHostImpl::FrameData* frame_data,
5575 DrawResult draw_result) override {
5576 EXPECT_EQ(2u, frame_data->render_passes.size());
5577 RenderPass* root_pass = frame_data->render_passes.back();
5578 EXPECT_EQ(2u, root_pass->quad_list.size());
5580 // There's a solid color quad under everything.
5581 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
5583 // The surface is clipped to 10x20.
5584 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
5585 const RenderPassDrawQuad* render_pass_quad =
5586 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
5587 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
5588 render_pass_quad->rect.ToString());
5589 // The masked layer is 50x50, but the surface size is 10x20. So the texture
5590 // coords in the mask are scaled by 10/50 and 20/50.
5591 // The surface is clipped to (20,10) so the mask texture coords are offset
5592 // by 20/50 and 10/50
5593 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
5594 .ToString(),
5595 render_pass_quad->MaskUVRect().ToString());
5596 EXPECT_EQ(gfx::Vector2dF(10.f / 50.f, 20.f / 50.f).ToString(),
5597 render_pass_quad->mask_uv_scale.ToString());
5598 EndTest();
5599 return draw_result;
5602 void AfterTest() override {}
5604 FakeContentLayerClient client_;
5607 SINGLE_AND_MULTI_THREAD_TEST_F(
5608 LayerTreeTestMaskLayerForSurfaceWithClippedLayer);
5610 class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
5611 protected:
5612 void InitializeSettings(LayerTreeSettings* settings) override {
5613 settings->layer_transforms_should_scale_layer_contents = true;
5616 void SetupTree() override {
5617 // Root
5618 // |
5619 // +-- Scaling Layer (adds a 2x scale)
5620 // |
5621 // +-- Content Layer
5622 // +--Mask
5624 scoped_refptr<Layer> root = Layer::Create(layer_settings());
5626 scoped_refptr<Layer> scaling_layer = Layer::Create(layer_settings());
5627 root->AddChild(scaling_layer);
5629 scoped_refptr<FakePictureLayer> content_layer =
5630 FakePictureLayer::Create(layer_settings(), &client_);
5631 scaling_layer->AddChild(content_layer);
5633 scoped_refptr<FakePictureLayer> mask_layer =
5634 FakePictureLayer::Create(layer_settings(), &client_);
5635 content_layer->SetMaskLayer(mask_layer.get());
5637 gfx::Size root_size(100, 100);
5638 root->SetBounds(root_size);
5640 gfx::Size scaling_layer_size(50, 50);
5641 scaling_layer->SetBounds(scaling_layer_size);
5642 gfx::Transform scale;
5643 scale.Scale(2.f, 2.f);
5644 scaling_layer->SetTransform(scale);
5646 content_layer->SetBounds(scaling_layer_size);
5648 mask_layer->SetBounds(scaling_layer_size);
5649 mask_layer->SetIsMask(true);
5651 layer_tree_host()->SetRootLayer(root);
5652 LayerTreeTest::SetupTree();
5655 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5657 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5658 LayerTreeHostImpl::FrameData* frame_data,
5659 DrawResult draw_result) override {
5660 EXPECT_EQ(2u, frame_data->render_passes.size());
5661 RenderPass* root_pass = frame_data->render_passes.back();
5662 EXPECT_EQ(2u, root_pass->quad_list.size());
5664 // There's a solid color quad under everything.
5665 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
5667 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
5668 const RenderPassDrawQuad* render_pass_quad =
5669 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
5670 switch (host_impl->active_tree()->source_frame_number()) {
5671 case 0:
5672 // Check that the tree scaling is correctly taken into account for the
5673 // mask, that should fully map onto the quad.
5674 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5675 render_pass_quad->rect.ToString());
5676 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5677 render_pass_quad->MaskUVRect().ToString());
5678 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5679 render_pass_quad->mask_uv_scale.ToString());
5680 break;
5681 case 1:
5682 // Applying a DSF should change the render surface size, but won't
5683 // affect which part of the mask is used.
5684 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5685 render_pass_quad->rect.ToString());
5686 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5687 render_pass_quad->MaskUVRect().ToString());
5688 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5689 render_pass_quad->mask_uv_scale.ToString());
5690 EndTest();
5691 break;
5693 return draw_result;
5696 void DidCommit() override {
5697 switch (layer_tree_host()->source_frame_number()) {
5698 case 1:
5699 gfx::Size double_root_size(200, 200);
5700 layer_tree_host()->SetViewportSize(double_root_size);
5701 layer_tree_host()->SetDeviceScaleFactor(2.f);
5702 break;
5706 void AfterTest() override {}
5708 FakeContentLayerClient client_;
5711 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling);
5713 class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest {
5714 protected:
5715 void SetupTree() override {
5716 // The mask layer has bounds 100x100 but is attached to a layer with bounds
5717 // 50x50.
5719 scoped_refptr<Layer> root = Layer::Create(layer_settings());
5721 scoped_refptr<FakePictureLayer> content_layer =
5722 FakePictureLayer::Create(layer_settings(), &client_);
5723 root->AddChild(content_layer);
5725 scoped_refptr<FakePictureLayer> mask_layer =
5726 FakePictureLayer::Create(layer_settings(), &client_);
5727 content_layer->SetMaskLayer(mask_layer.get());
5729 gfx::Size root_size(100, 100);
5730 root->SetBounds(root_size);
5732 gfx::Size layer_size(50, 50);
5733 content_layer->SetBounds(layer_size);
5735 gfx::Size mask_size(100, 100);
5736 mask_layer->SetBounds(mask_size);
5737 mask_layer->SetIsMask(true);
5739 layer_tree_host()->SetRootLayer(root);
5740 LayerTreeTest::SetupTree();
5743 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5745 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5746 LayerTreeHostImpl::FrameData* frame_data,
5747 DrawResult draw_result) override {
5748 EXPECT_EQ(2u, frame_data->render_passes.size());
5749 RenderPass* root_pass = frame_data->render_passes.back();
5750 EXPECT_EQ(2u, root_pass->quad_list.size());
5752 // There's a solid color quad under everything.
5753 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
5755 EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material);
5756 const RenderPassDrawQuad* render_pass_quad =
5757 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
5758 switch (host_impl->active_tree()->source_frame_number()) {
5759 case 0:
5760 // Check that the mask fills the surface.
5761 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5762 render_pass_quad->rect.ToString());
5763 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5764 render_pass_quad->MaskUVRect().ToString());
5765 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5766 render_pass_quad->mask_uv_scale.ToString());
5767 break;
5768 case 1:
5769 // Applying a DSF should change the render surface size, but won't
5770 // affect which part of the mask is used.
5771 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5772 render_pass_quad->rect.ToString());
5773 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5774 render_pass_quad->MaskUVRect().ToString());
5775 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5776 render_pass_quad->mask_uv_scale.ToString());
5777 EndTest();
5778 break;
5780 return draw_result;
5783 void DidCommit() override {
5784 switch (layer_tree_host()->source_frame_number()) {
5785 case 1:
5786 gfx::Size double_root_size(200, 200);
5787 layer_tree_host()->SetViewportSize(double_root_size);
5788 layer_tree_host()->SetDeviceScaleFactor(2.f);
5789 break;
5793 void AfterTest() override {}
5795 FakeContentLayerClient client_;
5798 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithDifferentBounds);
5800 class LayerTreeTestReflectionMaskLayerWithDifferentBounds
5801 : public LayerTreeTest {
5802 protected:
5803 void SetupTree() override {
5804 // The replica's mask layer has bounds 100x100 but the replica is of a
5805 // layer with bounds 50x50.
5807 scoped_refptr<Layer> root = Layer::Create(layer_settings());
5809 scoped_refptr<FakePictureLayer> content_layer =
5810 FakePictureLayer::Create(layer_settings(), &client_);
5811 root->AddChild(content_layer);
5813 scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings());
5814 content_layer->SetReplicaLayer(replica_layer.get());
5816 scoped_refptr<FakePictureLayer> mask_layer =
5817 FakePictureLayer::Create(layer_settings(), &client_);
5818 replica_layer->SetMaskLayer(mask_layer.get());
5820 gfx::Size root_size(100, 100);
5821 root->SetBounds(root_size);
5823 gfx::Size layer_size(50, 50);
5824 content_layer->SetBounds(layer_size);
5826 gfx::Size mask_size(100, 100);
5827 mask_layer->SetBounds(mask_size);
5828 mask_layer->SetIsMask(true);
5830 layer_tree_host()->SetRootLayer(root);
5831 LayerTreeTest::SetupTree();
5834 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5836 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5837 LayerTreeHostImpl::FrameData* frame_data,
5838 DrawResult draw_result) override {
5839 EXPECT_EQ(2u, frame_data->render_passes.size());
5840 RenderPass* root_pass = frame_data->render_passes.back();
5841 EXPECT_EQ(3u, root_pass->quad_list.size());
5843 // There's a solid color quad under everything.
5844 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
5846 EXPECT_EQ(DrawQuad::RENDER_PASS,
5847 root_pass->quad_list.ElementAt(1)->material);
5848 const RenderPassDrawQuad* render_pass_quad =
5849 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.ElementAt(1));
5850 switch (host_impl->active_tree()->source_frame_number()) {
5851 case 0:
5852 // Check that the mask fills the surface.
5853 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5854 render_pass_quad->rect.ToString());
5855 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5856 render_pass_quad->MaskUVRect().ToString());
5857 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5858 render_pass_quad->mask_uv_scale.ToString());
5859 break;
5860 case 1:
5861 // Applying a DSF should change the render surface size, but won't
5862 // affect which part of the mask is used.
5863 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5864 render_pass_quad->rect.ToString());
5865 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5866 render_pass_quad->MaskUVRect().ToString());
5867 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5868 render_pass_quad->mask_uv_scale.ToString());
5869 EndTest();
5870 break;
5872 return draw_result;
5875 void DidCommit() override {
5876 switch (layer_tree_host()->source_frame_number()) {
5877 case 1:
5878 gfx::Size double_root_size(200, 200);
5879 layer_tree_host()->SetViewportSize(double_root_size);
5880 layer_tree_host()->SetDeviceScaleFactor(2.f);
5881 break;
5885 void AfterTest() override {}
5887 FakeContentLayerClient client_;
5890 SINGLE_AND_MULTI_THREAD_TEST_F(
5891 LayerTreeTestReflectionMaskLayerWithDifferentBounds);
5893 class LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild
5894 : public LayerTreeTest {
5895 protected:
5896 void SetupTree() override {
5897 // The replica is of a layer with bounds 50x50, but it has a child that
5898 // causes the surface bounds to be larger.
5900 scoped_refptr<Layer> root = Layer::Create(layer_settings());
5902 scoped_refptr<FakePictureLayer> content_layer =
5903 FakePictureLayer::Create(layer_settings(), &client_);
5904 root->AddChild(content_layer);
5906 content_child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
5907 content_layer->AddChild(content_child_layer_);
5909 scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings());
5910 content_layer->SetReplicaLayer(replica_layer.get());
5912 scoped_refptr<FakePictureLayer> mask_layer =
5913 FakePictureLayer::Create(layer_settings(), &client_);
5914 replica_layer->SetMaskLayer(mask_layer.get());
5916 gfx::Size root_size(100, 100);
5917 root->SetBounds(root_size);
5919 gfx::Size layer_size(50, 50);
5920 content_layer->SetBounds(layer_size);
5921 content_child_layer_->SetBounds(layer_size);
5922 content_child_layer_->SetPosition(gfx::PointF(50.f, 0.f));
5924 gfx::Size mask_size(100, 100);
5925 mask_layer->SetBounds(mask_size);
5926 mask_layer->SetIsMask(true);
5928 layer_tree_host()->SetRootLayer(root);
5929 LayerTreeTest::SetupTree();
5932 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5934 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5935 LayerTreeHostImpl::FrameData* frame_data,
5936 DrawResult draw_result) override {
5937 EXPECT_EQ(2u, frame_data->render_passes.size());
5938 RenderPass* root_pass = frame_data->render_passes.back();
5939 EXPECT_EQ(3u, root_pass->quad_list.size());
5941 // There's a solid color quad under everything.
5942 EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material);
5944 EXPECT_EQ(DrawQuad::RENDER_PASS,
5945 root_pass->quad_list.ElementAt(1)->material);
5946 const RenderPassDrawQuad* replica_quad =
5947 RenderPassDrawQuad::MaterialCast(root_pass->quad_list.ElementAt(1));
5948 switch (host_impl->active_tree()->source_frame_number()) {
5949 case 0:
5950 // The surface is 100x50.
5951 // The mask covers the owning layer only.
5952 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5953 replica_quad->rect.ToString());
5954 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
5955 replica_quad->MaskUVRect().ToString());
5956 EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
5957 replica_quad->mask_uv_scale.ToString());
5958 break;
5959 case 1:
5960 // The surface is 100x50 with its origin at (-50, 0).
5961 // The mask covers the owning layer only.
5962 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5963 replica_quad->rect.ToString());
5964 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
5965 replica_quad->MaskUVRect().ToString());
5966 EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
5967 replica_quad->mask_uv_scale.ToString());
5968 EndTest();
5969 break;
5971 return draw_result;
5974 void DidCommit() override {
5975 switch (layer_tree_host()->source_frame_number()) {
5976 case 1:
5977 // Move the child to (-50, 0) instead. Now the mask should be moved to
5978 // still cover the layer being replicated.
5979 content_child_layer_->SetPosition(gfx::PointF(-50.f, 0.f));
5980 break;
5984 void AfterTest() override {}
5986 scoped_refptr<FakePictureLayer> content_child_layer_;
5987 FakeContentLayerClient client_;
5990 SINGLE_AND_MULTI_THREAD_TEST_F(
5991 LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild);
5993 class LayerTreeTestPageScaleFlags : public LayerTreeTest {
5994 protected:
5995 void SetupTree() override {
5996 // -root
5997 // -pre page scale
5998 // -page scale
5999 // -page scale child1
6000 // -page scale grandchild
6001 // -page scale child2
6002 // -post page scale
6004 scoped_refptr<Layer> root = Layer::Create(layer_settings());
6005 scoped_refptr<Layer> pre_page_scale = Layer::Create(layer_settings());
6006 scoped_refptr<Layer> page_scale = Layer::Create(layer_settings());
6007 scoped_refptr<Layer> page_scale_child1 = Layer::Create(layer_settings());
6008 scoped_refptr<Layer> page_scale_grandchild =
6009 Layer::Create(layer_settings());
6010 scoped_refptr<Layer> page_scale_child2 = Layer::Create(layer_settings());
6011 scoped_refptr<Layer> post_page_scale = Layer::Create(layer_settings());
6013 root->AddChild(pre_page_scale);
6014 root->AddChild(page_scale);
6015 root->AddChild(post_page_scale);
6017 page_scale->AddChild(page_scale_child1);
6018 page_scale->AddChild(page_scale_child2);
6019 page_scale_child1->AddChild(page_scale_grandchild);
6021 layer_tree_host()->SetRootLayer(root);
6022 LayerTreeTest::SetupTree();
6024 scoped_refptr<Layer> overscroll_elasticity_layer = nullptr;
6025 scoped_refptr<Layer> inner_viewport_scroll_layer = nullptr;
6026 scoped_refptr<Layer> outer_viewport_scroll_layer = nullptr;
6027 layer_tree_host()->RegisterViewportLayers(
6028 overscroll_elasticity_layer, page_scale, inner_viewport_scroll_layer,
6029 outer_viewport_scroll_layer);
6031 affected_by_page_scale_.push_back(page_scale->id());
6032 affected_by_page_scale_.push_back(page_scale_child1->id());
6033 affected_by_page_scale_.push_back(page_scale_child2->id());
6034 affected_by_page_scale_.push_back(page_scale_grandchild->id());
6036 not_affected_by_page_scale_.push_back(root->id());
6037 not_affected_by_page_scale_.push_back(pre_page_scale->id());
6038 not_affected_by_page_scale_.push_back(post_page_scale->id());
6041 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6043 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6044 LayerTreeHostCommon::CallFunctionForSubtree(
6045 host_impl->sync_tree()->root_layer(), [this](LayerImpl* layer) {
6046 const std::vector<int>& list =
6047 layer->IsAffectedByPageScale()
6048 ? this->affected_by_page_scale_
6049 : this->not_affected_by_page_scale_;
6050 EXPECT_TRUE(std::find(list.begin(), list.end(), layer->id()) !=
6051 list.end());
6054 EndTest();
6057 void AfterTest() override {}
6059 std::vector<int> affected_by_page_scale_;
6060 std::vector<int> not_affected_by_page_scale_;
6063 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestPageScaleFlags);
6065 } // namespace
6066 } // namespace cc