Revert of cc: Remove tile and scale specific code from raster source (patchset #4...
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob50ace9b7d78c4b707cbab9db9c9611365e4dd967
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include <algorithm>
9 #include "base/auto_reset.h"
10 #include "base/synchronization/lock.h"
11 #include "cc/animation/timing_function.h"
12 #include "cc/base/swap_promise.h"
13 #include "cc/debug/frame_rate_counter.h"
14 #include "cc/layers/content_layer.h"
15 #include "cc/layers/content_layer_client.h"
16 #include "cc/layers/io_surface_layer.h"
17 #include "cc/layers/layer_impl.h"
18 #include "cc/layers/painted_scrollbar_layer.h"
19 #include "cc/layers/picture_layer.h"
20 #include "cc/layers/solid_color_layer.h"
21 #include "cc/layers/video_layer.h"
22 #include "cc/output/begin_frame_args.h"
23 #include "cc/output/compositor_frame_ack.h"
24 #include "cc/output/copy_output_request.h"
25 #include "cc/output/copy_output_result.h"
26 #include "cc/output/output_surface.h"
27 #include "cc/quads/draw_quad.h"
28 #include "cc/quads/io_surface_draw_quad.h"
29 #include "cc/quads/tile_draw_quad.h"
30 #include "cc/resources/prioritized_resource.h"
31 #include "cc/resources/prioritized_resource_manager.h"
32 #include "cc/resources/resource_update_queue.h"
33 #include "cc/test/fake_content_layer.h"
34 #include "cc/test/fake_content_layer_client.h"
35 #include "cc/test/fake_content_layer_impl.h"
36 #include "cc/test/fake_layer_tree_host_client.h"
37 #include "cc/test/fake_output_surface.h"
38 #include "cc/test/fake_painted_scrollbar_layer.h"
39 #include "cc/test/fake_picture_layer.h"
40 #include "cc/test/fake_picture_layer_impl.h"
41 #include "cc/test/fake_picture_pile.h"
42 #include "cc/test/fake_proxy.h"
43 #include "cc/test/fake_scoped_ui_resource.h"
44 #include "cc/test/fake_video_frame_provider.h"
45 #include "cc/test/geometry_test_utils.h"
46 #include "cc/test/layer_tree_test.h"
47 #include "cc/test/test_shared_bitmap_manager.h"
48 #include "cc/test/test_web_graphics_context_3d.h"
49 #include "cc/trees/layer_tree_host_impl.h"
50 #include "cc/trees/layer_tree_impl.h"
51 #include "cc/trees/single_thread_proxy.h"
52 #include "cc/trees/thread_proxy.h"
53 #include "gpu/GLES2/gl2extchromium.h"
54 #include "skia/ext/refptr.h"
55 #include "testing/gmock/include/gmock/gmock.h"
56 #include "third_party/khronos/GLES2/gl2.h"
57 #include "third_party/khronos/GLES2/gl2ext.h"
58 #include "third_party/skia/include/core/SkPicture.h"
59 #include "ui/gfx/frame_time.h"
60 #include "ui/gfx/geometry/point_conversions.h"
61 #include "ui/gfx/geometry/size_conversions.h"
62 #include "ui/gfx/geometry/vector2d_conversions.h"
64 using testing::_;
65 using testing::AnyNumber;
66 using testing::AtLeast;
67 using testing::Mock;
69 namespace cc {
70 namespace {
72 class LayerTreeHostTest : public LayerTreeTest {};
74 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
75 // when no raster tasks get scheduled.
76 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
77 public:
78 LayerTreeHostTestReadyToActivateEmpty()
79 : did_notify_ready_to_activate_(false),
80 all_tiles_required_for_activation_are_ready_to_draw_(false),
81 required_for_activation_count_(0) {}
83 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
85 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
86 const std::vector<PictureLayerImpl*>& layers = impl->GetPictureLayers();
87 required_for_activation_count_ = 0;
88 for (const auto& layer : layers) {
89 FakePictureLayerImpl* fake_layer =
90 static_cast<FakePictureLayerImpl*>(layer);
91 required_for_activation_count_ +=
92 fake_layer->CountTilesRequiredForActivation();
96 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
97 did_notify_ready_to_activate_ = true;
98 const std::vector<PictureLayerImpl*>& layers = impl->GetPictureLayers();
99 all_tiles_required_for_activation_are_ready_to_draw_ = true;
100 for (const auto& layer : layers) {
101 if (!layer->AllTilesRequiredForActivationAreReadyToDraw())
102 all_tiles_required_for_activation_are_ready_to_draw_ = false;
104 EndTest();
107 void AfterTest() override {
108 EXPECT_TRUE(did_notify_ready_to_activate_);
109 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
110 EXPECT_EQ(size_t(0), required_for_activation_count_);
113 protected:
114 bool did_notify_ready_to_activate_;
115 bool all_tiles_required_for_activation_are_ready_to_draw_;
116 size_t required_for_activation_count_;
119 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
121 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
122 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
123 class LayerTreeHostTestReadyToActivateNonEmpty
124 : public LayerTreeHostTestReadyToActivateEmpty {
125 public:
126 void SetupTree() override {
127 client_.set_fill_with_nonsolid_color(true);
128 scoped_refptr<FakePictureLayer> root_layer =
129 FakePictureLayer::Create(&client_);
130 root_layer->SetBounds(gfx::Size(1024, 1024));
131 root_layer->SetIsDrawable(true);
133 layer_tree_host()->SetRootLayer(root_layer);
134 LayerTreeHostTest::SetupTree();
137 void AfterTest() override {
138 EXPECT_TRUE(did_notify_ready_to_activate_);
139 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
140 EXPECT_LE(size_t(1), required_for_activation_count_);
143 private:
144 FakeContentLayerClient client_;
147 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
149 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
150 // no raster tasks get scheduled.
151 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
152 public:
153 LayerTreeHostTestReadyToDrawEmpty()
154 : did_notify_ready_to_draw_(false),
155 all_tiles_required_for_draw_are_ready_to_draw_(false),
156 required_for_draw_count_(0) {}
158 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
160 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
161 did_notify_ready_to_draw_ = true;
162 const std::vector<PictureLayerImpl*>& layers = impl->GetPictureLayers();
163 all_tiles_required_for_draw_are_ready_to_draw_ = true;
164 for (const auto& layer : layers) {
165 if (!layer->AllTilesRequiredForDrawAreReadyToDraw())
166 all_tiles_required_for_draw_are_ready_to_draw_ = false;
167 FakePictureLayerImpl* fake_layer =
168 static_cast<FakePictureLayerImpl*>(layer);
169 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw();
172 EndTest();
175 void AfterTest() override {
176 EXPECT_TRUE(did_notify_ready_to_draw_);
177 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
178 EXPECT_EQ(size_t(0), required_for_draw_count_);
181 protected:
182 bool did_notify_ready_to_draw_;
183 bool all_tiles_required_for_draw_are_ready_to_draw_;
184 size_t required_for_draw_count_;
187 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
189 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
190 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
191 class LayerTreeHostTestReadyToDrawNonEmpty
192 : public LayerTreeHostTestReadyToDrawEmpty {
193 public:
194 void SetupTree() override {
195 client_.set_fill_with_nonsolid_color(true);
196 scoped_refptr<FakePictureLayer> root_layer =
197 FakePictureLayer::Create(&client_);
198 root_layer->SetBounds(gfx::Size(1024, 1024));
199 root_layer->SetIsDrawable(true);
201 layer_tree_host()->SetRootLayer(root_layer);
202 LayerTreeHostTest::SetupTree();
205 void AfterTest() override {
206 EXPECT_TRUE(did_notify_ready_to_draw_);
207 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
208 EXPECT_LE(size_t(1), required_for_draw_count_);
211 private:
212 FakeContentLayerClient client_;
215 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
216 // single threaded mode.
217 SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
219 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
220 // draw with frame 0.
221 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
222 public:
223 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
225 void BeginTest() override {
226 PostSetNeedsCommitToMainThread();
227 PostSetNeedsCommitToMainThread();
230 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
231 num_draws_++;
232 if (!impl->active_tree()->source_frame_number())
233 EndTest();
236 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
237 num_commits_++;
240 void AfterTest() override {
241 EXPECT_LE(1, num_commits_);
242 EXPECT_LE(1, num_draws_);
245 private:
246 int num_commits_;
247 int num_draws_;
250 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
252 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
253 // first committed frame draws should lead to another commit.
254 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
255 public:
256 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
258 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
260 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
262 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
263 ++num_commits_;
264 switch (num_commits_) {
265 case 1:
266 PostSetNeedsCommitToMainThread();
267 break;
268 case 2:
269 EndTest();
270 break;
271 default:
272 NOTREACHED();
276 void AfterTest() override {
277 EXPECT_EQ(2, num_commits_);
278 EXPECT_LE(1, num_draws_);
281 private:
282 int num_commits_;
283 int num_draws_;
286 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
288 // Verify that we pass property values in PushPropertiesTo.
289 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
290 protected:
291 void SetupTree() override {
292 scoped_refptr<Layer> root = Layer::Create();
293 root->CreateRenderSurface();
294 root->SetBounds(gfx::Size(10, 10));
295 layer_tree_host()->SetRootLayer(root);
296 LayerTreeHostTest::SetupTree();
299 enum Properties {
300 STARTUP,
301 BOUNDS,
302 HIDE_LAYER_AND_SUBTREE,
303 DRAWS_CONTENT,
304 DONE,
307 void BeginTest() override {
308 index_ = STARTUP;
309 PostSetNeedsCommitToMainThread();
312 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
313 VerifyAfterValues(impl->active_tree()->root_layer());
316 void DidCommitAndDrawFrame() override {
317 SetBeforeValues(layer_tree_host()->root_layer());
318 VerifyBeforeValues(layer_tree_host()->root_layer());
320 ++index_;
321 if (index_ == DONE) {
322 EndTest();
323 return;
326 SetAfterValues(layer_tree_host()->root_layer());
329 void AfterTest() override {}
331 void VerifyBeforeValues(Layer* layer) {
332 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
333 EXPECT_FALSE(layer->hide_layer_and_subtree());
334 EXPECT_FALSE(layer->DrawsContent());
337 void SetBeforeValues(Layer* layer) {
338 layer->SetBounds(gfx::Size(10, 10));
339 layer->SetHideLayerAndSubtree(false);
340 layer->SetIsDrawable(false);
343 void VerifyAfterValues(LayerImpl* layer) {
344 switch (static_cast<Properties>(index_)) {
345 case STARTUP:
346 case DONE:
347 break;
348 case BOUNDS:
349 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
350 break;
351 case HIDE_LAYER_AND_SUBTREE:
352 EXPECT_TRUE(layer->hide_layer_and_subtree());
353 break;
354 case DRAWS_CONTENT:
355 EXPECT_TRUE(layer->DrawsContent());
356 break;
360 void SetAfterValues(Layer* layer) {
361 switch (static_cast<Properties>(index_)) {
362 case STARTUP:
363 case DONE:
364 break;
365 case BOUNDS:
366 layer->SetBounds(gfx::Size(20, 20));
367 break;
368 case HIDE_LAYER_AND_SUBTREE:
369 layer->SetHideLayerAndSubtree(true);
370 break;
371 case DRAWS_CONTENT:
372 layer->SetIsDrawable(true);
373 break;
377 int index_;
380 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
382 // 1 setNeedsRedraw after the first commit has completed should lead to 1
383 // additional draw.
384 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
385 public:
386 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
388 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
390 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
391 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
392 if (!num_draws_) {
393 // Redraw again to verify that the second redraw doesn't commit.
394 PostSetNeedsRedrawToMainThread();
395 } else {
396 EndTest();
398 num_draws_++;
401 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
402 EXPECT_EQ(0, num_draws_);
403 num_commits_++;
406 void AfterTest() override {
407 EXPECT_GE(2, num_draws_);
408 EXPECT_EQ(1, num_commits_);
411 private:
412 int num_commits_;
413 int num_draws_;
416 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
418 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
419 // must contain invalid_rect.
420 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
421 public:
422 LayerTreeHostTestSetNeedsRedrawRect()
423 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
425 void BeginTest() override {
426 if (layer_tree_host()->settings().impl_side_painting)
427 root_layer_ = FakePictureLayer::Create(&client_);
428 else
429 root_layer_ = ContentLayer::Create(&client_);
430 root_layer_->SetIsDrawable(true);
431 root_layer_->SetBounds(bounds_);
432 layer_tree_host()->SetRootLayer(root_layer_);
433 layer_tree_host()->SetViewportSize(bounds_);
434 PostSetNeedsCommitToMainThread();
437 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
438 LayerTreeHostImpl::FrameData* frame_data,
439 DrawResult draw_result) override {
440 EXPECT_EQ(DRAW_SUCCESS, draw_result);
442 gfx::RectF root_damage_rect;
443 if (!frame_data->render_passes.empty())
444 root_damage_rect = frame_data->render_passes.back()->damage_rect;
446 if (!num_draws_) {
447 // If this is the first frame, expect full frame damage.
448 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_));
449 } else {
450 // Check that invalid_rect_ is indeed repainted.
451 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
454 return draw_result;
457 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
458 if (!num_draws_) {
459 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
460 } else {
461 EndTest();
463 num_draws_++;
466 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
468 private:
469 int num_draws_;
470 const gfx::Size bounds_;
471 const gfx::Rect invalid_rect_;
472 FakeContentLayerClient client_;
473 scoped_refptr<Layer> root_layer_;
476 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
478 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
479 public:
480 void InitializeSettings(LayerTreeSettings* settings) override {
481 settings->layer_transforms_should_scale_layer_contents = true;
484 void SetupTree() override {
485 root_layer_ = Layer::Create();
486 root_layer_->SetBounds(gfx::Size(10, 20));
487 root_layer_->CreateRenderSurface();
489 if (layer_tree_host()->settings().impl_side_painting)
490 scaled_layer_ = FakePictureLayer::Create(&client_);
491 else
492 scaled_layer_ = FakeContentLayer::Create(&client_);
493 scaled_layer_->SetBounds(gfx::Size(1, 1));
494 root_layer_->AddChild(scaled_layer_);
496 layer_tree_host()->SetRootLayer(root_layer_);
497 LayerTreeHostTest::SetupTree();
500 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
502 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
503 if (host_impl->active_tree()->source_frame_number() == 1)
504 EndTest();
507 void DidCommit() override {
508 switch (layer_tree_host()->source_frame_number()) {
509 case 1:
510 // SetBounds grows the layer and exposes new content.
511 if (layer_tree_host()->settings().impl_side_painting) {
512 scaled_layer_->SetBounds(gfx::Size(4, 4));
513 } else {
514 // Changing the device scale factor causes a commit. It also changes
515 // the content bounds of |scaled_layer_|, which should not generate
516 // a second commit as a result.
517 layer_tree_host()->SetDeviceScaleFactor(4.f);
519 break;
520 default:
521 // No extra commits.
522 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
526 void AfterTest() override {
527 EXPECT_EQ(gfx::Size(4, 4).ToString(),
528 scaled_layer_->content_bounds().ToString());
531 private:
532 FakeContentLayerClient client_;
533 scoped_refptr<Layer> root_layer_;
534 scoped_refptr<Layer> scaled_layer_;
537 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
539 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
540 : public LayerTreeHostTest {
541 public:
542 void InitializeSettings(LayerTreeSettings* settings) override {
543 settings->layer_transforms_should_scale_layer_contents = true;
546 void SetupTree() override {
547 root_layer_ = Layer::Create();
548 root_layer_->SetBounds(gfx::Size(10, 20));
549 root_layer_->CreateRenderSurface();
551 bool paint_scrollbar = true;
552 bool has_thumb = false;
553 scrollbar_ = FakePaintedScrollbarLayer::Create(
554 paint_scrollbar, has_thumb, root_layer_->id());
555 scrollbar_->SetPosition(gfx::Point(0, 10));
556 scrollbar_->SetBounds(gfx::Size(10, 10));
558 root_layer_->AddChild(scrollbar_);
560 layer_tree_host()->SetRootLayer(root_layer_);
561 LayerTreeHostTest::SetupTree();
564 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
566 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
567 if (host_impl->active_tree()->source_frame_number() == 1)
568 EndTest();
571 void DidCommit() override {
572 switch (layer_tree_host()->source_frame_number()) {
573 case 1:
574 // Changing the device scale factor causes a commit. It also changes
575 // the content bounds of |scrollbar_|, which should not generate
576 // a second commit as a result.
577 layer_tree_host()->SetDeviceScaleFactor(4.f);
578 break;
579 default:
580 // No extra commits.
581 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
585 void AfterTest() override {
586 EXPECT_EQ(gfx::Size(40, 40).ToString(),
587 scrollbar_->content_bounds().ToString());
590 private:
591 FakeContentLayerClient client_;
592 scoped_refptr<Layer> root_layer_;
593 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
596 SINGLE_AND_MULTI_THREAD_TEST_F(
597 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
599 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
600 public:
601 LayerTreeHostTestSetNextCommitForcesRedraw()
602 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
604 void BeginTest() override {
605 if (layer_tree_host()->settings().impl_side_painting)
606 root_layer_ = FakePictureLayer::Create(&client_);
607 else
608 root_layer_ = ContentLayer::Create(&client_);
609 root_layer_->SetIsDrawable(true);
610 root_layer_->SetBounds(bounds_);
611 layer_tree_host()->SetRootLayer(root_layer_);
612 layer_tree_host()->SetViewportSize(bounds_);
613 PostSetNeedsCommitToMainThread();
616 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
617 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
618 host_impl->SetNeedsRedrawRect(invalid_rect_);
621 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
622 LayerTreeHostImpl::FrameData* frame_data,
623 DrawResult draw_result) override {
624 EXPECT_EQ(DRAW_SUCCESS, draw_result);
626 gfx::RectF root_damage_rect;
627 if (!frame_data->render_passes.empty())
628 root_damage_rect = frame_data->render_passes.back()->damage_rect;
630 switch (num_draws_) {
631 case 0:
632 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
633 break;
634 case 1:
635 case 2:
636 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
637 break;
638 case 3:
639 EXPECT_EQ(invalid_rect_, root_damage_rect);
640 break;
641 case 4:
642 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
643 break;
644 default:
645 NOTREACHED();
648 return draw_result;
651 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
652 switch (num_draws_) {
653 case 0:
654 case 1:
655 // Cycle through a couple of empty commits to ensure we're observing the
656 // right behavior
657 PostSetNeedsCommitToMainThread();
658 break;
659 case 2:
660 // Should force full frame damage on the next commit
661 PostSetNextCommitForcesRedrawToMainThread();
662 PostSetNeedsCommitToMainThread();
663 if (host_impl->settings().impl_side_painting)
664 host_impl->BlockNotifyReadyToActivateForTesting(true);
665 else
666 num_draws_++;
667 break;
668 case 3:
669 host_impl->BlockNotifyReadyToActivateForTesting(false);
670 break;
671 default:
672 EndTest();
673 break;
675 num_draws_++;
678 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
680 private:
681 int num_draws_;
682 const gfx::Size bounds_;
683 const gfx::Rect invalid_rect_;
684 FakeContentLayerClient client_;
685 scoped_refptr<Layer> root_layer_;
688 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
689 LayerTreeHostTestSetNextCommitForcesRedraw);
691 // Tests that if a layer is not drawn because of some reason in the parent then
692 // its damage is preserved until the next time it is drawn.
693 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
694 public:
695 LayerTreeHostTestUndrawnLayersDamageLater() {}
697 void SetupTree() override {
698 if (layer_tree_host()->settings().impl_side_painting)
699 root_layer_ = FakePictureLayer::Create(&client_);
700 else
701 root_layer_ = ContentLayer::Create(&client_);
702 root_layer_->SetIsDrawable(true);
703 root_layer_->SetBounds(gfx::Size(50, 50));
704 layer_tree_host()->SetRootLayer(root_layer_);
706 // The initially transparent layer has a larger child layer, which is
707 // not initially drawn because of the this (parent) layer.
708 if (layer_tree_host()->settings().impl_side_painting)
709 parent_layer_ = FakePictureLayer::Create(&client_);
710 else
711 parent_layer_ = FakeContentLayer::Create(&client_);
712 parent_layer_->SetBounds(gfx::Size(15, 15));
713 parent_layer_->SetOpacity(0.0f);
714 root_layer_->AddChild(parent_layer_);
716 if (layer_tree_host()->settings().impl_side_painting)
717 child_layer_ = FakePictureLayer::Create(&client_);
718 else
719 child_layer_ = FakeContentLayer::Create(&client_);
720 child_layer_->SetBounds(gfx::Size(25, 25));
721 parent_layer_->AddChild(child_layer_);
723 LayerTreeHostTest::SetupTree();
726 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
728 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
729 LayerTreeHostImpl::FrameData* frame_data,
730 DrawResult draw_result) override {
731 EXPECT_EQ(DRAW_SUCCESS, draw_result);
733 gfx::RectF root_damage_rect;
734 if (!frame_data->render_passes.empty())
735 root_damage_rect = frame_data->render_passes.back()->damage_rect;
737 // The first time, the whole view needs be drawn.
738 // Afterwards, just the opacity of surface_layer1 is changed a few times,
739 // and each damage should be the bounding box of it and its child. If this
740 // was working improperly, the damage might not include its childs bounding
741 // box.
742 switch (host_impl->active_tree()->source_frame_number()) {
743 case 0:
744 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
745 break;
746 case 1:
747 case 2:
748 case 3:
749 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
750 break;
751 default:
752 NOTREACHED();
755 return draw_result;
758 void DidCommitAndDrawFrame() override {
759 switch (layer_tree_host()->source_frame_number()) {
760 case 1:
761 // Test not owning the surface.
762 parent_layer_->SetOpacity(1.0f);
763 break;
764 case 2:
765 parent_layer_->SetOpacity(0.0f);
766 break;
767 case 3:
768 // Test owning the surface.
769 parent_layer_->SetOpacity(0.5f);
770 parent_layer_->SetForceRenderSurface(true);
771 break;
772 case 4:
773 EndTest();
774 break;
775 default:
776 NOTREACHED();
780 void AfterTest() override {}
782 private:
783 FakeContentLayerClient client_;
784 scoped_refptr<Layer> root_layer_;
785 scoped_refptr<Layer> parent_layer_;
786 scoped_refptr<Layer> child_layer_;
789 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
791 // Tests that if a layer is not drawn because of some reason in the parent,
792 // causing its content bounds to not be computed, then when it is later drawn,
793 // its content bounds get pushed.
794 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
795 : public LayerTreeHostTest {
796 public:
797 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
798 : root_layer_(Layer::Create()) {}
800 void SetupTree() override {
801 root_layer_->CreateRenderSurface();
802 root_layer_->SetIsDrawable(true);
803 root_layer_->SetBounds(gfx::Size(20, 20));
804 layer_tree_host()->SetRootLayer(root_layer_);
806 parent_layer_ = Layer::Create();
807 parent_layer_->SetBounds(gfx::Size(20, 20));
808 parent_layer_->SetOpacity(0.0f);
809 root_layer_->AddChild(parent_layer_);
811 child_layer_ = Layer::Create();
812 child_layer_->SetBounds(gfx::Size(15, 15));
813 parent_layer_->AddChild(child_layer_);
815 LayerTreeHostTest::SetupTree();
818 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
820 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
821 LayerImpl* root = host_impl->active_tree()->root_layer();
822 LayerImpl* parent = root->children()[0];
823 LayerImpl* child = parent->children()[0];
825 switch (host_impl->active_tree()->source_frame_number()) {
826 case 0:
827 EXPECT_EQ(0.f, parent->opacity());
828 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
829 break;
830 case 1:
831 EXPECT_EQ(1.f, parent->opacity());
832 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
833 EndTest();
834 break;
835 default:
836 NOTREACHED();
840 void DidCommit() override {
841 switch (layer_tree_host()->source_frame_number()) {
842 case 1:
843 parent_layer_->SetOpacity(1.0f);
844 break;
845 case 2:
846 break;
847 default:
848 NOTREACHED();
852 void AfterTest() override {}
854 private:
855 scoped_refptr<Layer> root_layer_;
856 scoped_refptr<Layer> parent_layer_;
857 scoped_refptr<Layer> child_layer_;
860 SINGLE_AND_MULTI_THREAD_TEST_F(
861 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
863 // This test verifies that properties on the layer tree host are commited
864 // to the impl side.
865 class LayerTreeHostTestCommit : public LayerTreeHostTest {
866 public:
867 LayerTreeHostTestCommit() {}
869 void BeginTest() override {
870 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
871 layer_tree_host()->set_background_color(SK_ColorGRAY);
873 PostSetNeedsCommitToMainThread();
876 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
877 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
878 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
880 EndTest();
883 void AfterTest() override {}
886 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
888 // This test verifies that LayerTreeHostImpl's current frame time gets
889 // updated in consecutive frames when it doesn't draw due to tree
890 // activation failure.
891 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
892 : public LayerTreeHostTest {
893 public:
894 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
895 : frame_count_with_pending_tree_(0) {}
897 void BeginTest() override {
898 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
899 layer_tree_host()->set_background_color(SK_ColorGRAY);
901 PostSetNeedsCommitToMainThread();
904 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
905 EXPECT_EQ(frame_count_with_pending_tree_, 0);
906 if (impl->settings().impl_side_painting)
907 impl->BlockNotifyReadyToActivateForTesting(true);
910 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
911 const BeginFrameArgs& args) override {
912 if (impl->pending_tree())
913 frame_count_with_pending_tree_++;
915 if (frame_count_with_pending_tree_ == 1) {
916 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
917 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
918 } else if (frame_count_with_pending_tree_ == 2 &&
919 impl->settings().impl_side_painting) {
920 impl->BlockNotifyReadyToActivateForTesting(false);
924 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
925 if (frame_count_with_pending_tree_ > 1) {
926 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
927 EXPECT_NE(first_frame_time_.ToInternalValue(),
928 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
929 EndTest();
930 return;
933 EXPECT_FALSE(impl->settings().impl_side_painting);
934 EndTest();
936 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
937 if (impl->settings().impl_side_painting)
938 EXPECT_NE(frame_count_with_pending_tree_, 1);
941 void AfterTest() override {}
943 private:
944 int frame_count_with_pending_tree_;
945 base::TimeTicks first_frame_time_;
948 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
949 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
951 // This test verifies that LayerTreeHostImpl's current frame time gets
952 // updated in consecutive frames when it draws in each frame.
953 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
954 public:
955 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
957 void BeginTest() override {
958 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
959 layer_tree_host()->set_background_color(SK_ColorGRAY);
961 PostSetNeedsCommitToMainThread();
964 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
965 frame_++;
966 if (frame_ == 1) {
967 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
968 impl->SetNeedsRedraw();
970 // Since we might use a low-resolution clock on Windows, we need to
971 // make sure that the clock has incremented past first_frame_time_.
972 while (first_frame_time_ == gfx::FrameTime::Now()) {
975 return;
978 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
979 EndTest();
982 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
983 // Ensure there isn't a commit between the two draws, to ensure that a
984 // commit isn't required for updating the current frame time. We can
985 // only check for this in the multi-threaded case, since in the single-
986 // threaded case there will always be a commit between consecutive draws.
987 if (HasImplThread())
988 EXPECT_EQ(0, frame_);
991 void AfterTest() override {}
993 private:
994 int frame_;
995 base::TimeTicks first_frame_time_;
998 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1000 // Verifies that StartPageScaleAnimation events propagate correctly
1001 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1002 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
1003 public:
1004 LayerTreeHostTestStartPageScaleAnimation() {}
1006 void SetupTree() override {
1007 LayerTreeHostTest::SetupTree();
1009 if (layer_tree_host()->settings().impl_side_painting) {
1010 scoped_refptr<FakePictureLayer> layer =
1011 FakePictureLayer::Create(&client_);
1012 layer->set_always_update_resources(true);
1013 scroll_layer_ = layer;
1014 } else {
1015 scroll_layer_ = FakeContentLayer::Create(&client_);
1018 Layer* root_layer = layer_tree_host()->root_layer();
1019 scroll_layer_->SetScrollClipLayerId(root_layer->id());
1020 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
1021 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
1022 2 * root_layer->bounds().height()));
1023 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
1024 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1025 // This test requires the page_scale and inner viewport layers to be
1026 // identified.
1027 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
1028 scroll_layer_.get(), NULL);
1029 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1032 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1034 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
1035 float scale,
1036 float) override {
1037 gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
1038 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset,
1039 scroll_delta));
1040 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1043 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1044 // We get one commit before the first draw, and the animation doesn't happen
1045 // until the second draw.
1046 switch (impl->active_tree()->source_frame_number()) {
1047 case 0:
1048 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1049 // We'll start an animation when we get back to the main thread.
1050 break;
1051 case 1:
1052 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1053 break;
1054 case 2:
1055 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
1056 EndTest();
1057 break;
1058 default:
1059 NOTREACHED();
1063 void DidCommitAndDrawFrame() override {
1064 switch (layer_tree_host()->source_frame_number()) {
1065 case 1:
1066 layer_tree_host()->StartPageScaleAnimation(
1067 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1068 break;
1072 void AfterTest() override {}
1074 FakeContentLayerClient client_;
1075 scoped_refptr<Layer> scroll_layer_;
1078 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1080 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1081 public:
1082 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1084 void BeginTest() override {
1085 PostSetNeedsCommitToMainThread();
1086 PostSetVisibleToMainThread(false);
1087 // This is suppressed while we're invisible.
1088 PostSetNeedsRedrawToMainThread();
1089 // Triggers the redraw.
1090 PostSetVisibleToMainThread(true);
1093 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1094 EXPECT_TRUE(impl->visible());
1095 ++num_draws_;
1096 EndTest();
1099 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
1101 private:
1102 int num_draws_;
1105 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1107 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1108 public:
1109 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1111 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1113 void PaintContents(
1114 SkCanvas* canvas,
1115 const gfx::Rect& clip,
1116 ContentLayerClient::GraphicsContextStatus gc_status) override {
1117 // Set layer opacity to 0.
1118 if (test_layer_)
1119 test_layer_->SetOpacity(0.f);
1121 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
1122 const gfx::Rect& clip,
1123 GraphicsContextStatus gc_status) override {
1124 NOTIMPLEMENTED();
1125 return DisplayItemList::Create();
1127 bool FillsBoundsCompletely() const override { return false; }
1129 private:
1130 Layer* test_layer_;
1133 class ContentLayerWithUpdateTracking : public ContentLayer {
1134 public:
1135 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1136 ContentLayerClient* client) {
1137 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1140 int PaintContentsCount() { return paint_contents_count_; }
1141 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1143 bool Update(ResourceUpdateQueue* queue,
1144 const OcclusionTracker<Layer>* occlusion) override {
1145 bool updated = ContentLayer::Update(queue, occlusion);
1146 paint_contents_count_++;
1147 return updated;
1150 private:
1151 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1152 : ContentLayer(client), paint_contents_count_(0) {
1153 SetBounds(gfx::Size(10, 10));
1154 SetIsDrawable(true);
1156 ~ContentLayerWithUpdateTracking() override {}
1158 int paint_contents_count_;
1161 // Layer opacity change during paint should not prevent compositor resources
1162 // from being updated during commit.
1163 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1164 public:
1165 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {}
1167 void BeginTest() override {
1168 if (layer_tree_host()->settings().impl_side_painting) {
1169 update_check_picture_layer_ =
1170 FakePictureLayer::Create(&test_opacity_change_delegate_);
1171 test_opacity_change_delegate_.SetTestLayer(
1172 update_check_picture_layer_.get());
1173 is_impl_paint_ = true;
1174 } else {
1175 update_check_content_layer_ = ContentLayerWithUpdateTracking::Create(
1176 &test_opacity_change_delegate_);
1177 test_opacity_change_delegate_.SetTestLayer(
1178 update_check_content_layer_.get());
1179 is_impl_paint_ = false;
1181 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1182 if (layer_tree_host()->settings().impl_side_painting)
1183 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
1184 else
1185 layer_tree_host()->root_layer()->AddChild(update_check_content_layer_);
1187 PostSetNeedsCommitToMainThread();
1190 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
1192 void AfterTest() override {
1193 // Update() should have been called once.
1194 if (is_impl_paint_)
1195 EXPECT_EQ(1u, update_check_picture_layer_->update_count());
1196 else
1197 EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount());
1200 private:
1201 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1202 scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_;
1203 scoped_refptr<FakePictureLayer> update_check_picture_layer_;
1204 bool is_impl_paint_;
1207 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1209 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1210 : public LayerTreeHostTest {
1211 public:
1212 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {}
1214 void InitializeSettings(LayerTreeSettings* settings) override {
1215 // PictureLayer can only be used with impl side painting enabled.
1216 settings->impl_side_painting = true;
1219 void BeginTest() override {
1220 client_.set_fill_with_nonsolid_color(true);
1221 root_layer_ = FakePictureLayer::Create(&client_);
1222 child_layer_ = FakePictureLayer::Create(&client_);
1224 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1225 layer_tree_host()->SetDeviceScaleFactor(1.5);
1226 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1228 root_layer_->AddChild(child_layer_);
1230 root_layer_->SetIsDrawable(true);
1231 root_layer_->SetBounds(gfx::Size(30, 30));
1233 child_layer_->SetIsDrawable(true);
1234 child_layer_->SetPosition(gfx::Point(2, 2));
1235 child_layer_->SetBounds(gfx::Size(10, 10));
1237 layer_tree_host()->SetRootLayer(root_layer_);
1239 PostSetNeedsCommitToMainThread();
1242 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1243 // Should only do one commit.
1244 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1245 // Device scale factor should come over to impl.
1246 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1248 // Both layers are on impl.
1249 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1251 // Device viewport is scaled.
1252 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1254 FakePictureLayerImpl* root =
1255 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
1256 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
1257 impl->active_tree()->root_layer()->children()[0]);
1259 // Positions remain in layout pixels.
1260 EXPECT_EQ(gfx::Point(0, 0), root->position());
1261 EXPECT_EQ(gfx::Point(2, 2), child->position());
1263 // Compute all the layer transforms for the frame.
1264 LayerTreeHostImpl::FrameData frame_data;
1265 impl->PrepareToDraw(&frame_data);
1266 impl->DidDrawAllLayers(frame_data);
1268 const LayerImplList& render_surface_layer_list =
1269 *frame_data.render_surface_layer_list;
1271 // Both layers should be drawing into the root render surface.
1272 ASSERT_EQ(1u, render_surface_layer_list.size());
1273 ASSERT_EQ(root->render_surface(),
1274 render_surface_layer_list[0]->render_surface());
1275 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1277 // The root render surface is the size of the viewport.
1278 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect());
1280 // The max tiling scale of the child should be scaled.
1281 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale());
1283 gfx::Transform scale_transform;
1284 scale_transform.Scale(impl->device_scale_factor(),
1285 impl->device_scale_factor());
1287 // The root layer is scaled by 2x.
1288 gfx::Transform root_screen_space_transform = scale_transform;
1289 gfx::Transform root_draw_transform = scale_transform;
1291 EXPECT_EQ(root_draw_transform, root->draw_transform());
1292 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1294 // The child is at position 2,2, which is transformed to 3,3 after the scale
1295 gfx::Transform child_transform;
1296 child_transform.Translate(3.f, 3.f);
1297 child_transform.Scale(child->MaximumTilingContentsScale(),
1298 child->MaximumTilingContentsScale());
1300 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform());
1301 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform,
1302 child->screen_space_transform());
1304 EndTest();
1307 void AfterTest() override {}
1309 private:
1310 FakeContentLayerClient client_;
1311 scoped_refptr<FakePictureLayer> root_layer_;
1312 scoped_refptr<FakePictureLayer> child_layer_;
1315 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1317 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1318 // Verify atomicity of commits and reuse of textures.
1319 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1320 public:
1321 void InitializeSettings(LayerTreeSettings* settings) override {
1322 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1323 // Make sure partial texture updates are turned off.
1324 settings->max_partial_texture_updates = 0;
1325 // Linear fade animator prevents scrollbars from drawing immediately.
1326 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1329 void SetupTree() override {
1330 layer_ = FakeContentLayer::Create(&client_);
1331 layer_->SetBounds(gfx::Size(10, 20));
1333 bool paint_scrollbar = true;
1334 bool has_thumb = false;
1335 scrollbar_ = FakePaintedScrollbarLayer::Create(
1336 paint_scrollbar, has_thumb, layer_->id());
1337 scrollbar_->SetPosition(gfx::Point(0, 10));
1338 scrollbar_->SetBounds(gfx::Size(10, 10));
1340 layer_->AddChild(scrollbar_);
1342 layer_tree_host()->SetRootLayer(layer_);
1343 LayerTreeHostTest::SetupTree();
1346 void BeginTest() override {
1347 drew_frame_ = -1;
1348 PostSetNeedsCommitToMainThread();
1351 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1352 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1354 TestWebGraphicsContext3D* context = TestContext();
1356 switch (impl->active_tree()->source_frame_number()) {
1357 case 0:
1358 // Number of textures should be one for each layer
1359 ASSERT_EQ(2u, context->NumTextures());
1360 // Number of textures used for commit should be one for each layer.
1361 EXPECT_EQ(2u, context->NumUsedTextures());
1362 // Verify that used texture is correct.
1363 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1364 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1366 context->ResetUsedTextures();
1367 break;
1368 case 1:
1369 // Number of textures should be one for scrollbar layer since it was
1370 // requested and deleted on the impl-thread, and double for the content
1371 // layer since its first texture is used by impl thread and cannot by
1372 // used for update.
1373 ASSERT_EQ(3u, context->NumTextures());
1374 // Number of textures used for commit should be one for each layer.
1375 EXPECT_EQ(2u, context->NumUsedTextures());
1376 // First textures should not have been used.
1377 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1378 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1379 // New textures should have been used.
1380 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1381 context->ResetUsedTextures();
1382 break;
1383 case 2:
1384 EndTest();
1385 break;
1386 default:
1387 NOTREACHED();
1388 break;
1392 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1393 TestWebGraphicsContext3D* context = TestContext();
1395 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1396 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1397 return;
1399 drew_frame_ = impl->active_tree()->source_frame_number();
1401 // We draw/ship one texture each frame for each layer.
1402 EXPECT_EQ(2u, context->NumUsedTextures());
1403 context->ResetUsedTextures();
1405 if (!TestEnded())
1406 PostSetNeedsCommitToMainThread();
1409 void Layout() override {
1410 layer_->SetNeedsDisplay();
1411 scrollbar_->SetNeedsDisplay();
1414 void AfterTest() override {}
1416 protected:
1417 FakeContentLayerClient client_;
1418 scoped_refptr<FakeContentLayer> layer_;
1419 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1420 int drew_frame_;
1423 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1424 LayerTreeHostTestDirectRendererAtomicCommit);
1426 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1427 class LayerTreeHostTestDelegatingRendererAtomicCommit
1428 : public LayerTreeHostTestDirectRendererAtomicCommit {
1429 public:
1430 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1431 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1433 TestWebGraphicsContext3D* context = TestContext();
1435 switch (impl->active_tree()->source_frame_number()) {
1436 case 0:
1437 // Number of textures should be one for each layer
1438 ASSERT_EQ(2u, context->NumTextures());
1439 // Number of textures used for commit should be one for each layer.
1440 EXPECT_EQ(2u, context->NumUsedTextures());
1441 // Verify that used texture is correct.
1442 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1443 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1444 context->ResetUsedTextures();
1445 break;
1446 case 1:
1447 // Number of textures should be doubled as the first context layer
1448 // texture is being used by the impl-thread and cannot be used for
1449 // update. The scrollbar behavior is different direct renderer because
1450 // UI resource deletion with delegating renderer occurs after tree
1451 // activation.
1452 ASSERT_EQ(4u, context->NumTextures());
1453 // Number of textures used for commit should still be
1454 // one for each layer.
1455 EXPECT_EQ(2u, context->NumUsedTextures());
1456 // First textures should not have been used.
1457 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1458 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1459 // New textures should have been used.
1460 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1461 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1462 context->ResetUsedTextures();
1463 break;
1464 case 2:
1465 EndTest();
1466 break;
1467 default:
1468 NOTREACHED();
1469 break;
1474 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1475 LayerTreeHostTestDelegatingRendererAtomicCommit);
1477 static void SetLayerPropertiesForTesting(Layer* layer,
1478 Layer* parent,
1479 const gfx::Transform& transform,
1480 const gfx::Point3F& transform_origin,
1481 const gfx::PointF& position,
1482 const gfx::Size& bounds,
1483 bool opaque) {
1484 layer->RemoveAllChildren();
1485 if (parent)
1486 parent->AddChild(layer);
1487 layer->SetTransform(transform);
1488 layer->SetTransformOrigin(transform_origin);
1489 layer->SetPosition(position);
1490 layer->SetBounds(bounds);
1491 layer->SetContentsOpaque(opaque);
1494 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1495 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1496 : public LayerTreeHostTest {
1497 public:
1498 void InitializeSettings(LayerTreeSettings* settings) override {
1499 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1500 // Allow one partial texture update.
1501 settings->max_partial_texture_updates = 1;
1502 // No partial updates when impl side painting is enabled.
1503 settings->impl_side_painting = false;
1506 void SetupTree() override {
1507 parent_ = FakeContentLayer::Create(&client_);
1508 parent_->SetBounds(gfx::Size(10, 20));
1510 child_ = FakeContentLayer::Create(&client_);
1511 child_->SetPosition(gfx::Point(0, 10));
1512 child_->SetBounds(gfx::Size(3, 10));
1514 parent_->AddChild(child_);
1516 layer_tree_host()->SetRootLayer(parent_);
1517 LayerTreeHostTest::SetupTree();
1520 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1522 void DidCommitAndDrawFrame() override {
1523 switch (layer_tree_host()->source_frame_number()) {
1524 case 1:
1525 parent_->SetNeedsDisplay();
1526 child_->SetNeedsDisplay();
1527 break;
1528 case 2:
1529 // Damage part of layers.
1530 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1531 child_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1532 break;
1533 case 3:
1534 child_->SetNeedsDisplay();
1535 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1536 break;
1537 case 4:
1538 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1539 break;
1540 case 5:
1541 EndTest();
1542 break;
1543 default:
1544 NOTREACHED() << layer_tree_host()->source_frame_number();
1545 break;
1549 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1550 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1552 TestWebGraphicsContext3D* context = TestContext();
1554 switch (impl->active_tree()->source_frame_number()) {
1555 case 0:
1556 // Number of textures should be one for each layer.
1557 ASSERT_EQ(2u, context->NumTextures());
1558 // Number of textures used for commit should be one for each layer.
1559 EXPECT_EQ(2u, context->NumUsedTextures());
1560 // Verify that used textures are correct.
1561 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1562 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1563 context->ResetUsedTextures();
1564 break;
1565 case 1:
1566 if (HasImplThread()) {
1567 // Number of textures should be two for each content layer.
1568 ASSERT_EQ(4u, context->NumTextures());
1569 } else {
1570 // In single thread we can always do partial updates, so the limit has
1571 // no effect.
1572 ASSERT_EQ(2u, context->NumTextures());
1574 // Number of textures used for commit should be one for each content
1575 // layer.
1576 EXPECT_EQ(2u, context->NumUsedTextures());
1578 if (HasImplThread()) {
1579 // First content textures should not have been used.
1580 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1581 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1582 // New textures should have been used.
1583 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1584 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1585 } else {
1586 // In single thread we can always do partial updates, so the limit has
1587 // no effect.
1588 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1589 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1592 context->ResetUsedTextures();
1593 break;
1594 case 2:
1595 if (HasImplThread()) {
1596 // Number of textures should be two for each content layer.
1597 ASSERT_EQ(4u, context->NumTextures());
1598 } else {
1599 // In single thread we can always do partial updates, so the limit has
1600 // no effect.
1601 ASSERT_EQ(2u, context->NumTextures());
1603 // Number of textures used for commit should be one for each content
1604 // layer.
1605 EXPECT_EQ(2u, context->NumUsedTextures());
1607 if (HasImplThread()) {
1608 // One content layer does a partial update also.
1609 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1610 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1611 } else {
1612 // In single thread we can always do partial updates, so the limit has
1613 // no effect.
1614 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1615 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1618 context->ResetUsedTextures();
1619 break;
1620 case 3:
1621 // No textures should be used for commit.
1622 EXPECT_EQ(0u, context->NumUsedTextures());
1624 context->ResetUsedTextures();
1625 break;
1626 case 4:
1627 // Number of textures used for commit should be one, for the
1628 // content layer.
1629 EXPECT_EQ(1u, context->NumUsedTextures());
1631 context->ResetUsedTextures();
1632 break;
1633 default:
1634 NOTREACHED();
1635 break;
1639 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1640 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1642 TestWebGraphicsContext3D* context = TestContext();
1644 // Number of textures used for drawing should one per layer except for
1645 // frame 3 where the viewport only contains one layer.
1646 if (impl->active_tree()->source_frame_number() == 3) {
1647 EXPECT_EQ(1u, context->NumUsedTextures());
1648 } else {
1649 EXPECT_EQ(2u, context->NumUsedTextures())
1650 << "For frame " << impl->active_tree()->source_frame_number();
1653 context->ResetUsedTextures();
1656 void AfterTest() override {}
1658 private:
1659 FakeContentLayerClient client_;
1660 scoped_refptr<FakeContentLayer> parent_;
1661 scoped_refptr<FakeContentLayer> child_;
1664 // Partial updates are not possible with a delegating renderer.
1665 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1666 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1668 // TODO(sohanjg) : Make it work with impl-side painting.
1669 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1670 : public LayerTreeHostTest {
1671 protected:
1672 void SetupTree() override {
1673 root_layer_ = FakeContentLayer::Create(&client_);
1674 root_layer_->SetBounds(gfx::Size(100, 100));
1676 surface_layer1_ = FakeContentLayer::Create(&client_);
1677 surface_layer1_->SetBounds(gfx::Size(100, 100));
1678 surface_layer1_->SetForceRenderSurface(true);
1679 surface_layer1_->SetOpacity(0.5f);
1680 root_layer_->AddChild(surface_layer1_);
1682 surface_layer2_ = FakeContentLayer::Create(&client_);
1683 surface_layer2_->SetBounds(gfx::Size(100, 100));
1684 surface_layer2_->SetForceRenderSurface(true);
1685 surface_layer2_->SetOpacity(0.5f);
1686 surface_layer1_->AddChild(surface_layer2_);
1688 replica_layer1_ = FakeContentLayer::Create(&client_);
1689 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1691 replica_layer2_ = FakeContentLayer::Create(&client_);
1692 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1694 layer_tree_host()->SetRootLayer(root_layer_);
1695 LayerTreeHostTest::SetupTree();
1698 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1700 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1701 Renderer* renderer = host_impl->renderer();
1702 RenderPassId surface1_render_pass_id = host_impl->active_tree()
1703 ->root_layer()
1704 ->children()[0]
1705 ->render_surface()
1706 ->GetRenderPassId();
1707 RenderPassId surface2_render_pass_id = host_impl->active_tree()
1708 ->root_layer()
1709 ->children()[0]
1710 ->children()[0]
1711 ->render_surface()
1712 ->GetRenderPassId();
1714 switch (host_impl->active_tree()->source_frame_number()) {
1715 case 0:
1716 EXPECT_TRUE(
1717 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1718 EXPECT_TRUE(
1719 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1721 // Reduce the memory limit to only fit the root layer and one render
1722 // surface. This prevents any contents drawing into surfaces
1723 // from being allocated.
1724 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1725 break;
1726 case 1:
1727 EXPECT_FALSE(
1728 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1729 EXPECT_FALSE(
1730 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1732 EndTest();
1733 break;
1737 void DidCommitAndDrawFrame() override {
1738 if (layer_tree_host()->source_frame_number() < 2)
1739 root_layer_->SetNeedsDisplay();
1742 void AfterTest() override {
1743 EXPECT_LE(2u, root_layer_->update_count());
1744 EXPECT_LE(2u, surface_layer1_->update_count());
1745 EXPECT_LE(2u, surface_layer2_->update_count());
1748 FakeContentLayerClient client_;
1749 scoped_refptr<FakeContentLayer> root_layer_;
1750 scoped_refptr<FakeContentLayer> surface_layer1_;
1751 scoped_refptr<FakeContentLayer> replica_layer1_;
1752 scoped_refptr<FakeContentLayer> surface_layer2_;
1753 scoped_refptr<FakeContentLayer> replica_layer2_;
1756 // Surfaces don't exist with a delegated renderer.
1757 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1758 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1760 class EvictionTestLayer : public Layer {
1761 public:
1762 static scoped_refptr<EvictionTestLayer> Create() {
1763 return make_scoped_refptr(new EvictionTestLayer());
1766 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override;
1767 bool DrawsContent() const override { return true; }
1769 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
1770 void PushPropertiesTo(LayerImpl* impl) override;
1771 void SetTexturePriorities(const PriorityCalculator&) override;
1773 bool HaveBackingTexture() const {
1774 return texture_.get() ? texture_->have_backing_texture() : false;
1777 private:
1778 EvictionTestLayer() : Layer() {}
1779 ~EvictionTestLayer() override {}
1781 void CreateTextureIfNeeded() {
1782 if (texture_)
1783 return;
1784 texture_ = PrioritizedResource::Create(
1785 layer_tree_host()->contents_texture_manager());
1786 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1787 bitmap_.allocN32Pixels(10, 10);
1790 scoped_ptr<PrioritizedResource> texture_;
1791 SkBitmap bitmap_;
1794 class EvictionTestLayerImpl : public LayerImpl {
1795 public:
1796 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1797 int id) {
1798 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1800 ~EvictionTestLayerImpl() override {}
1802 void AppendQuads(RenderPass* render_pass,
1803 const Occlusion& occlusion_in_content_space,
1804 AppendQuadsData* append_quads_data) override {
1805 ASSERT_TRUE(has_texture_);
1806 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1809 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1811 private:
1812 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1813 : LayerImpl(tree_impl, id), has_texture_(false) {}
1815 bool has_texture_;
1818 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1819 CreateTextureIfNeeded();
1820 if (!texture_)
1821 return;
1822 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1825 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1826 const OcclusionTracker<Layer>* occlusion) {
1827 CreateTextureIfNeeded();
1828 if (!texture_)
1829 return false;
1831 gfx::Rect full_rect(0, 0, 10, 10);
1832 ResourceUpdate upload = ResourceUpdate::Create(
1833 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1834 queue->AppendFullUpload(upload);
1835 return true;
1838 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1839 LayerTreeImpl* tree_impl) {
1840 return EvictionTestLayerImpl::Create(tree_impl, layer_id_);
1843 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1844 Layer::PushPropertiesTo(layer_impl);
1846 EvictionTestLayerImpl* test_layer_impl =
1847 static_cast<EvictionTestLayerImpl*>(layer_impl);
1848 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1851 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1852 public:
1853 LayerTreeHostTestEvictTextures()
1854 : layer_(EvictionTestLayer::Create()),
1855 impl_for_evict_textures_(0),
1856 num_commits_(0) {}
1858 void BeginTest() override {
1859 layer_tree_host()->SetRootLayer(layer_);
1860 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1862 gfx::Transform identity_matrix;
1863 SetLayerPropertiesForTesting(layer_.get(),
1865 identity_matrix,
1866 gfx::Point3F(0.f, 0.f, 0.f),
1867 gfx::PointF(0.f, 0.f),
1868 gfx::Size(10, 20),
1869 true);
1871 PostSetNeedsCommitToMainThread();
1874 void PostEvictTextures() {
1875 ImplThreadTaskRunner()->PostTask(
1876 FROM_HERE,
1877 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1878 base::Unretained(this)));
1881 void EvictTexturesOnImplThread() {
1882 DCHECK(impl_for_evict_textures_);
1883 impl_for_evict_textures_->EvictTexturesForTesting();
1886 // Commit 1: Just commit and draw normally, then post an eviction at the end
1887 // that will trigger a commit.
1888 // Commit 2: Triggered by the eviction, let it go through and then set
1889 // needsCommit.
1890 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1891 // task, which will be handled before the commit. Don't set needsCommit, it
1892 // should have been posted. A frame should not be drawn (note,
1893 // didCommitAndDrawFrame may be called anyway).
1894 // Commit 4: Triggered by the eviction, let it go through and then set
1895 // needsCommit.
1896 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1897 // Layout(), a frame should not be drawn but a commit will be posted.
1898 // Commit 6: Triggered by the eviction, post an eviction task in
1899 // Layout(), which will be a noop, letting the commit (which recreates the
1900 // textures) go through and draw a frame, then end the test.
1902 // Commits 1+2 test the eviction recovery path where eviction happens outside
1903 // of the beginFrame/commit pair.
1904 // Commits 3+4 test the eviction recovery path where eviction happens inside
1905 // the beginFrame/commit pair.
1906 // Commits 5+6 test the path where an eviction happens during the eviction
1907 // recovery path.
1908 void DidCommit() override {
1909 switch (num_commits_) {
1910 case 1:
1911 EXPECT_TRUE(layer_->HaveBackingTexture());
1912 PostEvictTextures();
1913 break;
1914 case 2:
1915 EXPECT_TRUE(layer_->HaveBackingTexture());
1916 layer_tree_host()->SetNeedsCommit();
1917 break;
1918 case 3:
1919 break;
1920 case 4:
1921 EXPECT_TRUE(layer_->HaveBackingTexture());
1922 layer_tree_host()->SetNeedsCommit();
1923 break;
1924 case 5:
1925 break;
1926 case 6:
1927 EXPECT_TRUE(layer_->HaveBackingTexture());
1928 EndTest();
1929 break;
1930 default:
1931 NOTREACHED();
1932 break;
1936 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1937 impl_for_evict_textures_ = impl;
1940 void Layout() override {
1941 ++num_commits_;
1942 switch (num_commits_) {
1943 case 1:
1944 case 2:
1945 break;
1946 case 3:
1947 PostEvictTextures();
1948 break;
1949 case 4:
1950 // We couldn't check in didCommitAndDrawFrame on commit 3,
1951 // so check here.
1952 EXPECT_FALSE(layer_->HaveBackingTexture());
1953 break;
1954 case 5:
1955 PostEvictTextures();
1956 break;
1957 case 6:
1958 // We couldn't check in didCommitAndDrawFrame on commit 5,
1959 // so check here.
1960 EXPECT_FALSE(layer_->HaveBackingTexture());
1961 PostEvictTextures();
1962 break;
1963 default:
1964 NOTREACHED();
1965 break;
1969 void AfterTest() override {}
1971 private:
1972 FakeContentLayerClient client_;
1973 scoped_refptr<EvictionTestLayer> layer_;
1974 LayerTreeHostImpl* impl_for_evict_textures_;
1975 int num_commits_;
1978 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
1980 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1981 public:
1982 LayerTreeHostTestContinuousInvalidate()
1983 : num_commit_complete_(0), num_draw_layers_(0) {}
1985 void BeginTest() override {
1986 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1987 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1989 if (layer_tree_host()->settings().impl_side_painting)
1990 layer_ = FakePictureLayer::Create(&client_);
1991 else
1992 layer_ = FakeContentLayer::Create(&client_);
1994 layer_->SetBounds(gfx::Size(10, 10));
1995 layer_->SetPosition(gfx::PointF(0.f, 0.f));
1996 layer_->SetIsDrawable(true);
1997 layer_tree_host()->root_layer()->AddChild(layer_);
1999 PostSetNeedsCommitToMainThread();
2002 void DidCommitAndDrawFrame() override {
2003 if (num_draw_layers_ == 2)
2004 return;
2005 layer_->SetNeedsDisplay();
2008 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2009 if (num_draw_layers_ == 1)
2010 num_commit_complete_++;
2013 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2014 num_draw_layers_++;
2015 if (num_draw_layers_ == 2)
2016 EndTest();
2019 void AfterTest() override {
2020 // Check that we didn't commit twice between first and second draw.
2021 EXPECT_EQ(1, num_commit_complete_);
2024 private:
2025 FakeContentLayerClient client_;
2026 scoped_refptr<Layer> layer_;
2027 int num_commit_complete_;
2028 int num_draw_layers_;
2031 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
2033 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2034 public:
2035 LayerTreeHostTestDeferCommits()
2036 : num_commits_deferred_(0), num_complete_commits_(0) {}
2038 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2040 void DidDeferCommit() override {
2041 num_commits_deferred_++;
2042 layer_tree_host()->SetDeferCommits(false);
2045 void DidCommit() override {
2046 num_complete_commits_++;
2047 switch (num_complete_commits_) {
2048 case 1:
2049 EXPECT_EQ(0, num_commits_deferred_);
2050 layer_tree_host()->SetDeferCommits(true);
2051 PostSetNeedsCommitToMainThread();
2052 break;
2053 case 2:
2054 EndTest();
2055 break;
2056 default:
2057 NOTREACHED();
2058 break;
2062 void AfterTest() override {
2063 EXPECT_EQ(1, num_commits_deferred_);
2064 EXPECT_EQ(2, num_complete_commits_);
2067 private:
2068 int num_commits_deferred_;
2069 int num_complete_commits_;
2072 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2074 class LayerTreeHostWithProxy : public LayerTreeHost {
2075 public:
2076 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2077 const LayerTreeSettings& settings,
2078 scoped_ptr<FakeProxy> proxy)
2079 : LayerTreeHost(client, NULL, NULL, settings) {
2080 proxy->SetLayerTreeHost(this);
2081 client->SetLayerTreeHost(this);
2082 InitializeForTesting(proxy.Pass());
2086 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2087 // When partial updates are not allowed, max updates should be 0.
2089 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2091 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2092 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2093 proxy->SetMaxPartialTextureUpdates(5);
2095 LayerTreeSettings settings;
2096 settings.max_partial_texture_updates = 10;
2098 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2100 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2103 // When partial updates are allowed,
2104 // max updates should be limited by the proxy.
2106 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2108 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2109 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2110 proxy->SetMaxPartialTextureUpdates(5);
2112 LayerTreeSettings settings;
2113 settings.max_partial_texture_updates = 10;
2115 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2117 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2120 // When partial updates are allowed,
2121 // max updates should also be limited by the settings.
2123 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2125 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2126 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2127 proxy->SetMaxPartialTextureUpdates(20);
2129 LayerTreeSettings settings;
2130 settings.max_partial_texture_updates = 10;
2132 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2134 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2138 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2139 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2141 LayerTreeSettings settings;
2142 settings.max_partial_texture_updates = 4;
2143 settings.single_thread_proxy_scheduler = false;
2145 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2146 new TestSharedBitmapManager());
2147 scoped_ptr<LayerTreeHost> host =
2148 LayerTreeHost::CreateSingleThreaded(&client,
2149 &client,
2150 shared_bitmap_manager.get(),
2151 NULL,
2152 settings,
2153 base::MessageLoopProxy::current(),
2154 nullptr);
2155 client.SetLayerTreeHost(host.get());
2156 host->Composite(base::TimeTicks::Now());
2158 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2161 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2162 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2164 LayerTreeSettings settings;
2165 settings.max_partial_texture_updates = 4;
2166 settings.single_thread_proxy_scheduler = false;
2168 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2169 new TestSharedBitmapManager());
2170 scoped_ptr<LayerTreeHost> host =
2171 LayerTreeHost::CreateSingleThreaded(&client,
2172 &client,
2173 shared_bitmap_manager.get(),
2174 NULL,
2175 settings,
2176 base::MessageLoopProxy::current(),
2177 nullptr);
2178 client.SetLayerTreeHost(host.get());
2179 host->Composite(base::TimeTicks::Now());
2181 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2184 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2185 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2187 LayerTreeSettings settings;
2188 settings.max_partial_texture_updates = 4;
2189 settings.single_thread_proxy_scheduler = false;
2191 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2192 new TestSharedBitmapManager());
2193 scoped_ptr<LayerTreeHost> host =
2194 LayerTreeHost::CreateSingleThreaded(&client,
2195 &client,
2196 shared_bitmap_manager.get(),
2197 NULL,
2198 settings,
2199 base::MessageLoopProxy::current(),
2200 nullptr);
2201 client.SetLayerTreeHost(host.get());
2202 host->Composite(base::TimeTicks::Now());
2204 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2207 TEST(LayerTreeHostTest,
2208 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2209 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2211 LayerTreeSettings settings;
2212 settings.max_partial_texture_updates = 4;
2213 settings.single_thread_proxy_scheduler = false;
2215 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2216 new TestSharedBitmapManager());
2217 scoped_ptr<LayerTreeHost> host =
2218 LayerTreeHost::CreateSingleThreaded(&client,
2219 &client,
2220 shared_bitmap_manager.get(),
2221 NULL,
2222 settings,
2223 base::MessageLoopProxy::current(),
2224 nullptr);
2225 client.SetLayerTreeHost(host.get());
2226 host->Composite(base::TimeTicks::Now());
2228 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2231 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
2232 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2233 : public LayerTreeHostTest {
2234 public:
2235 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2236 : root_layer_(FakeContentLayer::Create(&client_)),
2237 child_layer1_(FakeContentLayer::Create(&client_)),
2238 child_layer2_(FakeContentLayer::Create(&client_)),
2239 num_commits_(0) {}
2241 void BeginTest() override {
2242 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2243 root_layer_->SetBounds(gfx::Size(100, 100));
2244 child_layer1_->SetBounds(gfx::Size(100, 100));
2245 child_layer2_->SetBounds(gfx::Size(100, 100));
2246 root_layer_->AddChild(child_layer1_);
2247 root_layer_->AddChild(child_layer2_);
2248 layer_tree_host()->SetRootLayer(root_layer_);
2249 PostSetNeedsCommitToMainThread();
2252 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2253 bool visible) override {
2254 if (visible) {
2255 // One backing should remain unevicted.
2256 EXPECT_EQ(
2257 100u * 100u * 4u * 1u,
2258 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2259 } else {
2260 EXPECT_EQ(
2261 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2264 // Make sure that contents textures are marked as having been
2265 // purged.
2266 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2267 // End the test in this state.
2268 EndTest();
2271 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2272 ++num_commits_;
2273 switch (num_commits_) {
2274 case 1:
2275 // All three backings should have memory.
2276 EXPECT_EQ(
2277 100u * 100u * 4u * 3u,
2278 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2279 // Set a new policy that will kick out 1 of the 3 resources.
2280 // Because a resource was evicted, a commit will be kicked off.
2281 host_impl->SetMemoryPolicy(
2282 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2283 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2284 1000));
2285 break;
2286 case 2:
2287 // Only two backings should have memory.
2288 EXPECT_EQ(
2289 100u * 100u * 4u * 2u,
2290 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2291 // Become backgrounded, which will cause 1 more resource to be
2292 // evicted.
2293 PostSetVisibleToMainThread(false);
2294 break;
2295 default:
2296 // No further commits should happen because this is not visible
2297 // anymore.
2298 NOTREACHED();
2299 break;
2303 void AfterTest() override {}
2305 private:
2306 FakeContentLayerClient client_;
2307 scoped_refptr<FakeContentLayer> root_layer_;
2308 scoped_refptr<FakeContentLayer> child_layer1_;
2309 scoped_refptr<FakeContentLayer> child_layer2_;
2310 int num_commits_;
2313 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2314 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2316 class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
2317 public:
2318 class PaintClient : public FakeContentLayerClient {
2319 public:
2320 PaintClient() : paint_count_(0) {}
2322 int paint_count() const { return paint_count_; }
2324 void PaintContents(
2325 SkCanvas* canvas,
2326 const gfx::Rect& clip,
2327 ContentLayerClient::GraphicsContextStatus gc_status) override {
2328 FakeContentLayerClient::PaintContents(canvas, clip, gc_status);
2329 ++paint_count_;
2332 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
2333 const gfx::Rect& clip,
2334 GraphicsContextStatus gc_status) override {
2335 NOTIMPLEMENTED();
2336 return DisplayItemList::Create();
2339 bool FillsBoundsCompletely() const override { return false; }
2341 private:
2342 int paint_count_;
2345 void SetupTree() override {
2346 num_tiles_rastered_ = 0;
2348 scoped_refptr<Layer> root_layer;
2349 if (layer_tree_host()->settings().impl_side_painting)
2350 root_layer = PictureLayer::Create(&client_);
2351 else
2352 root_layer = ContentLayer::Create(&client_);
2353 client_.set_fill_with_nonsolid_color(true);
2354 root_layer->SetIsDrawable(true);
2355 root_layer->SetBounds(gfx::Size(10, 10));
2356 root_layer->SetContentsOpaque(true);
2358 layer_tree_host()->SetRootLayer(root_layer);
2360 // The expecations are based on the assumption that the default
2361 // LCD settings are:
2362 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2363 EXPECT_FALSE(root_layer->can_use_lcd_text());
2365 LayerTreeHostTest::SetupTree();
2368 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2370 void DidCommitAndDrawFrame() override {
2371 switch (layer_tree_host()->source_frame_number()) {
2372 case 1:
2373 // The first update consists of a paint of the whole layer.
2374 EXPECT_EQ(1, client_.paint_count());
2375 // LCD text must have been enabled on the layer.
2376 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2377 PostSetNeedsCommitToMainThread();
2378 break;
2379 case 2:
2380 // Since nothing changed on layer, there should be no paint.
2381 EXPECT_EQ(1, client_.paint_count());
2382 // LCD text must not have changed.
2383 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2384 // Change layer opacity that should trigger lcd change.
2385 layer_tree_host()->root_layer()->SetOpacity(.5f);
2386 break;
2387 case 3:
2388 // LCD text doesn't require re-recording, so no painting should occur.
2389 EXPECT_EQ(1, client_.paint_count());
2390 // LCD text must have been disabled on the layer due to opacity.
2391 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2392 // Change layer opacity that should not trigger lcd change.
2393 layer_tree_host()->root_layer()->SetOpacity(1.f);
2394 break;
2395 case 4:
2396 // LCD text doesn't require re-recording, so no painting should occur.
2397 EXPECT_EQ(1, client_.paint_count());
2398 // Even though LCD text could be allowed.
2399 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2400 EndTest();
2401 break;
2405 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
2406 const Tile* tile) override {
2407 ++num_tiles_rastered_;
2410 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2411 switch (host_impl->active_tree()->source_frame_number()) {
2412 case 0:
2413 // The first draw.
2414 EXPECT_EQ(1, num_tiles_rastered_);
2415 break;
2416 case 1:
2417 // Nothing changed on the layer.
2418 EXPECT_EQ(1, num_tiles_rastered_);
2419 break;
2420 case 2:
2421 // LCD text was disabled, it should be re-rastered with LCD text off.
2422 EXPECT_EQ(2, num_tiles_rastered_);
2423 break;
2424 case 3:
2425 // LCD text was enabled but it's sticky and stays off.
2426 EXPECT_EQ(2, num_tiles_rastered_);
2427 break;
2431 void AfterTest() override {}
2433 private:
2434 PaintClient client_;
2435 int num_tiles_rastered_;
2438 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
2440 // Verify that the BeginFrame notification is used to initiate rendering.
2441 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2442 public:
2443 void InitializeSettings(LayerTreeSettings* settings) override {
2444 settings->use_external_begin_frame_source = true;
2447 void BeginTest() override {
2448 // This will trigger a SetNeedsBeginFrame which will trigger a
2449 // BeginFrame.
2450 PostSetNeedsCommitToMainThread();
2453 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2454 LayerTreeHostImpl::FrameData* frame,
2455 DrawResult draw_result) override {
2456 EndTest();
2457 return DRAW_SUCCESS;
2460 void AfterTest() override {}
2462 private:
2463 base::TimeTicks frame_time_;
2466 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2468 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2469 : public LayerTreeHostTest {
2470 public:
2471 void InitializeSettings(LayerTreeSettings* settings) override {
2472 settings->use_external_begin_frame_source = true;
2473 settings->using_synchronous_renderer_compositor = true;
2476 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2478 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2479 // The BeginFrame notification is turned off now but will get enabled
2480 // once we return. End test while it's enabled.
2481 ImplThreadTaskRunner()->PostTask(
2482 FROM_HERE,
2483 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2484 base::Unretained(this)));
2487 void AfterTest() override {}
2490 MULTI_THREAD_TEST_F(
2491 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2493 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2494 protected:
2495 LayerTreeHostTestAbortedCommitDoesntStall()
2496 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2498 void InitializeSettings(LayerTreeSettings* settings) override {
2499 settings->use_external_begin_frame_source = true;
2502 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2504 void DidCommit() override {
2505 commit_count_++;
2506 if (commit_count_ == 4) {
2507 // After two aborted commits, request a real commit now to make sure a
2508 // real commit following an aborted commit will still complete and
2509 // end the test even when the Impl thread is idle.
2510 layer_tree_host()->SetNeedsCommit();
2514 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2515 CommitEarlyOutReason reason) override {
2516 commit_abort_count_++;
2517 // Initiate another abortable commit.
2518 host_impl->SetNeedsCommit();
2521 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2522 commit_complete_count_++;
2523 if (commit_complete_count_ == 1) {
2524 // Initiate an abortable commit after the first commit.
2525 host_impl->SetNeedsCommit();
2526 } else {
2527 EndTest();
2531 void AfterTest() override {
2532 EXPECT_EQ(commit_count_, 5);
2533 EXPECT_EQ(commit_abort_count_, 3);
2534 EXPECT_EQ(commit_complete_count_, 2);
2537 int commit_count_;
2538 int commit_abort_count_;
2539 int commit_complete_count_;
2542 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2543 : public LayerTreeHostTestAbortedCommitDoesntStall {
2544 void InitializeSettings(LayerTreeSettings* settings) override {
2545 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2546 settings->using_synchronous_renderer_compositor = true;
2550 MULTI_THREAD_TEST_F(
2551 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2553 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2554 : public LayerTreeHostTestAbortedCommitDoesntStall {
2555 void InitializeSettings(LayerTreeSettings* settings) override {
2556 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2557 settings->throttle_frame_production = false;
2561 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2563 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2564 : public LayerTreeHostTest {
2565 protected:
2566 void InitializeSettings(LayerTreeSettings* settings) override {
2567 settings->impl_side_painting = true;
2570 void SetupTree() override {
2571 LayerTreeHostTest::SetupTree();
2573 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2574 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2575 layer->SetBounds(gfx::Size(10, 10));
2576 layer_tree_host()->root_layer()->AddChild(layer);
2579 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2581 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2582 EndTest();
2585 void AfterTest() override {}
2587 FakeContentLayerClient client_;
2590 MULTI_THREAD_TEST_F(
2591 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2593 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2594 : public LayerTreeHostTest {
2595 public:
2596 class SetBoundsClient : public ContentLayerClient {
2597 public:
2598 SetBoundsClient() : layer_(0) {}
2600 void set_layer(Layer* layer) { layer_ = layer; }
2602 void PaintContents(
2603 SkCanvas* canvas,
2604 const gfx::Rect& clip,
2605 ContentLayerClient::GraphicsContextStatus gc_status) override {
2606 layer_->SetBounds(gfx::Size(2, 2));
2609 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
2610 const gfx::Rect& clip,
2611 GraphicsContextStatus gc_status) override {
2612 NOTIMPLEMENTED();
2613 return DisplayItemList::Create();
2616 bool FillsBoundsCompletely() const override { return false; }
2618 private:
2619 Layer* layer_;
2622 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2624 void SetupTree() override {
2625 if (layer_tree_host()->settings().impl_side_painting) {
2626 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_);
2627 layer_tree_host()->SetRootLayer(root_layer);
2628 } else {
2629 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2630 layer_tree_host()->SetRootLayer(root_layer);
2632 Layer* root_layer = layer_tree_host()->root_layer();
2633 root_layer->SetIsDrawable(true);
2634 root_layer->SetBounds(gfx::Size(1, 1));
2636 client_.set_layer(root_layer);
2638 LayerTreeHostTest::SetupTree();
2641 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2642 void AfterTest() override {}
2644 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2645 num_commits_++;
2646 if (num_commits_ == 1) {
2647 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2648 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds());
2649 } else {
2650 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2651 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds());
2652 EndTest();
2656 private:
2657 SetBoundsClient client_;
2658 int num_commits_;
2661 SINGLE_AND_MULTI_THREAD_TEST_F(
2662 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2664 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2665 public:
2666 MockIOSurfaceWebGraphicsContext3D() {
2667 test_capabilities_.gpu.iosurface = true;
2668 test_capabilities_.gpu.texture_rectangle = true;
2671 GLuint createTexture() override { return 1; }
2672 MOCK_METHOD1(activeTexture, void(GLenum texture));
2673 MOCK_METHOD2(bindTexture, void(GLenum target,
2674 GLuint texture_id));
2675 MOCK_METHOD3(texParameteri, void(GLenum target,
2676 GLenum pname,
2677 GLint param));
2678 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2679 GLint width,
2680 GLint height,
2681 GLuint ioSurfaceId,
2682 GLuint plane));
2683 MOCK_METHOD4(drawElements, void(GLenum mode,
2684 GLsizei count,
2685 GLenum type,
2686 GLintptr offset));
2687 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2688 MOCK_METHOD2(produceTextureCHROMIUM,
2689 void(GLenum target, const GLbyte* mailbox));
2692 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2693 protected:
2694 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2695 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2696 new MockIOSurfaceWebGraphicsContext3D);
2697 mock_context_ = mock_context_owned.get();
2699 if (delegating_renderer())
2700 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
2701 else
2702 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
2705 void SetupTree() override {
2706 LayerTreeHostTest::SetupTree();
2708 layer_tree_host()->root_layer()->SetIsDrawable(false);
2710 io_surface_id_ = 9;
2711 io_surface_size_ = gfx::Size(6, 7);
2713 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2714 io_surface_layer->SetBounds(gfx::Size(10, 10));
2715 io_surface_layer->SetIsDrawable(true);
2716 io_surface_layer->SetContentsOpaque(true);
2717 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2718 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2721 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2723 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2724 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2725 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2727 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2728 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2729 .Times(AtLeast(1));
2730 EXPECT_CALL(*mock_context_,
2731 texParameteri(
2732 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2733 .Times(1);
2734 EXPECT_CALL(*mock_context_,
2735 texParameteri(
2736 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2737 .Times(1);
2738 EXPECT_CALL(*mock_context_,
2739 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2740 GL_TEXTURE_POOL_CHROMIUM,
2741 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2742 EXPECT_CALL(*mock_context_,
2743 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2744 GL_TEXTURE_WRAP_S,
2745 GL_CLAMP_TO_EDGE)).Times(1);
2746 EXPECT_CALL(*mock_context_,
2747 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2748 GL_TEXTURE_WRAP_T,
2749 GL_CLAMP_TO_EDGE)).Times(1);
2751 EXPECT_CALL(*mock_context_,
2752 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2753 io_surface_size_.width(),
2754 io_surface_size_.height(),
2755 io_surface_id_,
2756 0)).Times(1);
2758 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2761 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2762 LayerTreeHostImpl::FrameData* frame,
2763 DrawResult draw_result) override {
2764 Mock::VerifyAndClearExpectations(&mock_context_);
2765 ResourceProvider* resource_provider = host_impl->resource_provider();
2766 EXPECT_EQ(1u, resource_provider->num_resources());
2767 CHECK_EQ(1u, frame->render_passes.size());
2768 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2769 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
2770 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2771 const IOSurfaceDrawQuad* io_surface_draw_quad =
2772 IOSurfaceDrawQuad::MaterialCast(quad);
2773 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2774 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
2775 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2776 resource_provider->TargetForTesting(
2777 io_surface_draw_quad->io_surface_resource_id));
2779 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2780 .Times(1);
2781 if (delegating_renderer()) {
2782 // The io surface layer's resource should be sent to the parent.
2783 EXPECT_CALL(*mock_context_,
2784 produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2785 } else {
2786 // The io surface layer's texture is drawn.
2787 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2788 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2789 .Times(AtLeast(1));
2792 return draw_result;
2795 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2796 Mock::VerifyAndClearExpectations(&mock_context_);
2798 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2799 EndTest();
2802 void AfterTest() override {}
2804 int io_surface_id_;
2805 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2806 gfx::Size io_surface_size_;
2809 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2811 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2812 public:
2813 void BeginTest() override {
2814 frame_ = 0;
2815 PostSetNeedsCommitToMainThread();
2818 // Round 1: commit + draw
2819 // Round 2: commit only (no draw/swap)
2820 // Round 3: draw only (no commit)
2822 void DidCommit() override {
2823 int commit = layer_tree_host()->source_frame_number();
2824 switch (commit) {
2825 case 2:
2826 // Round 2 done.
2827 EXPECT_EQ(1, frame_);
2828 layer_tree_host()->SetNeedsRedraw();
2829 break;
2833 void DidCompleteSwapBuffers() override {
2834 int commit = layer_tree_host()->source_frame_number();
2835 ++frame_;
2836 switch (frame_) {
2837 case 1:
2838 // Round 1 done.
2839 EXPECT_EQ(1, commit);
2840 layer_tree_host()->SetNeedsCommit();
2841 break;
2842 case 2:
2843 // Round 3 done.
2844 EXPECT_EQ(2, commit);
2845 EndTest();
2846 break;
2850 void AfterTest() override {}
2852 protected:
2853 int frame_;
2856 // Flaky on all platforms: http://crbug.com/327498
2857 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
2858 RunTest(true, true, true);
2861 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
2862 RunTest(true, false, true);
2865 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
2866 public:
2867 void InitializeSettings(LayerTreeSettings* settings) override {
2868 // PictureLayer can only be used with impl side painting enabled.
2869 settings->impl_side_painting = true;
2872 void SetupTree() override {
2873 layer_ = FakePictureLayer::Create(&client_);
2874 // Force commits to not be aborted so new frames get drawn, otherwise
2875 // the renderer gets deferred initialized but nothing new needs drawing.
2876 layer_->set_always_update_resources(true);
2877 layer_tree_host()->SetRootLayer(layer_);
2878 LayerTreeHostTest::SetupTree();
2881 void BeginTest() override {
2882 did_initialize_gl_ = false;
2883 did_release_gl_ = false;
2884 last_source_frame_number_drawn_ = -1; // Never drawn.
2885 PostSetNeedsCommitToMainThread();
2888 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2889 scoped_ptr<TestWebGraphicsContext3D> context3d(
2890 TestWebGraphicsContext3D::Create());
2892 return FakeOutputSurface::CreateDeferredGL(
2893 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
2894 delegating_renderer());
2897 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2898 ASSERT_TRUE(host_impl->RootLayer());
2899 FakePictureLayerImpl* layer_impl =
2900 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
2902 // The same frame can be draw multiple times if new visible tiles are
2903 // rasterized. But we want to make sure we only post DeferredInitialize
2904 // and ReleaseGL once, so early out if the same frame is drawn again.
2905 if (last_source_frame_number_drawn_ ==
2906 host_impl->active_tree()->source_frame_number())
2907 return;
2909 last_source_frame_number_drawn_ =
2910 host_impl->active_tree()->source_frame_number();
2912 if (!did_initialize_gl_) {
2913 EXPECT_LE(1u, layer_impl->append_quads_count());
2914 ImplThreadTaskRunner()->PostTask(
2915 FROM_HERE,
2916 base::Bind(
2917 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
2918 base::Unretained(this),
2919 base::Unretained(host_impl)));
2920 } else if (did_initialize_gl_ && !did_release_gl_) {
2921 EXPECT_LE(2u, layer_impl->append_quads_count());
2922 ImplThreadTaskRunner()->PostTask(
2923 FROM_HERE,
2924 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
2925 base::Unretained(this),
2926 base::Unretained(host_impl)));
2927 } else if (did_initialize_gl_ && did_release_gl_) {
2928 EXPECT_LE(3u, layer_impl->append_quads_count());
2929 EndTest();
2933 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
2934 EXPECT_FALSE(did_initialize_gl_);
2935 // SetAndInitializeContext3D calls SetNeedsCommit.
2936 FakeOutputSurface* fake_output_surface =
2937 static_cast<FakeOutputSurface*>(host_impl->output_surface());
2938 scoped_refptr<TestContextProvider> context_provider =
2939 TestContextProvider::Create(); // Not bound to thread.
2940 EXPECT_TRUE(
2941 fake_output_surface->InitializeAndSetContext3d(context_provider));
2942 did_initialize_gl_ = true;
2945 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
2946 EXPECT_TRUE(did_initialize_gl_);
2947 EXPECT_FALSE(did_release_gl_);
2948 // ReleaseGL calls SetNeedsCommit.
2949 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
2950 did_release_gl_ = true;
2953 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2954 ASSERT_TRUE(result);
2955 DelegatedFrameData* delegated_frame_data =
2956 output_surface()->last_sent_frame().delegated_frame_data.get();
2957 if (!delegated_frame_data)
2958 return;
2960 // Return all resources immediately.
2961 TransferableResourceArray resources_to_return =
2962 output_surface()->resources_held_by_parent();
2964 CompositorFrameAck ack;
2965 for (size_t i = 0; i < resources_to_return.size(); ++i)
2966 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
2967 host_impl->ReclaimResources(&ack);
2970 void AfterTest() override {
2971 EXPECT_TRUE(did_initialize_gl_);
2972 EXPECT_TRUE(did_release_gl_);
2975 private:
2976 FakeContentLayerClient client_;
2977 scoped_refptr<FakePictureLayer> layer_;
2978 bool did_initialize_gl_;
2979 bool did_release_gl_;
2980 int last_source_frame_number_drawn_;
2983 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
2985 class LayerTreeHostTestDeferredInitializeWithGpuRasterization
2986 : public LayerTreeHostTestDeferredInitialize {
2987 void InitializeSettings(LayerTreeSettings* settings) override {
2988 // PictureLayer can only be used with impl side painting enabled.
2989 settings->impl_side_painting = true;
2990 settings->gpu_rasterization_enabled = true;
2991 settings->gpu_rasterization_forced = true;
2995 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization);
2997 // Test for UI Resource management.
2998 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
2999 public:
3000 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
3002 void InitializeSettings(LayerTreeSettings* settings) override {
3003 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
3006 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3008 void DidCommit() override {
3009 int frame = layer_tree_host()->source_frame_number();
3010 switch (frame) {
3011 case 1:
3012 CreateResource();
3013 CreateResource();
3014 PostSetNeedsCommitToMainThread();
3015 break;
3016 case 2:
3017 // Usually ScopedUIResource are deleted from the manager in their
3018 // destructor. Here we just want to test that a direct call to
3019 // DeleteUIResource works.
3020 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3021 PostSetNeedsCommitToMainThread();
3022 break;
3023 case 3:
3024 // DeleteUIResource can be called with an invalid id.
3025 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3026 PostSetNeedsCommitToMainThread();
3027 break;
3028 case 4:
3029 CreateResource();
3030 CreateResource();
3031 PostSetNeedsCommitToMainThread();
3032 break;
3033 case 5:
3034 ClearResources();
3035 EndTest();
3036 break;
3040 void PerformTest(LayerTreeHostImpl* impl) {
3041 TestWebGraphicsContext3D* context = TestContext();
3043 int frame = impl->active_tree()->source_frame_number();
3044 switch (frame) {
3045 case 0:
3046 ASSERT_EQ(0u, context->NumTextures());
3047 break;
3048 case 1:
3049 // Created two textures.
3050 ASSERT_EQ(2u, context->NumTextures());
3051 break;
3052 case 2:
3053 // One texture left after one deletion.
3054 ASSERT_EQ(1u, context->NumTextures());
3055 break;
3056 case 3:
3057 // Resource manager state should not change when delete is called on an
3058 // invalid id.
3059 ASSERT_EQ(1u, context->NumTextures());
3060 break;
3061 case 4:
3062 // Creation after deletion: two more creates should total up to
3063 // three textures.
3064 ASSERT_EQ(3u, context->NumTextures());
3065 break;
3069 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3070 if (!layer_tree_host()->settings().impl_side_painting)
3071 PerformTest(impl);
3074 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3075 if (layer_tree_host()->settings().impl_side_painting)
3076 PerformTest(impl);
3079 void AfterTest() override {}
3081 private:
3082 // Must clear all resources before exiting.
3083 void ClearResources() {
3084 for (int i = 0; i < num_ui_resources_; i++)
3085 ui_resources_[i] = nullptr;
3088 void CreateResource() {
3089 ui_resources_[num_ui_resources_++] =
3090 FakeScopedUIResource::Create(layer_tree_host());
3093 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3094 int num_ui_resources_;
3097 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3099 class PushPropertiesCountingLayerImpl : public LayerImpl {
3100 public:
3101 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
3102 LayerTreeImpl* tree_impl, int id) {
3103 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
3106 ~PushPropertiesCountingLayerImpl() override {}
3108 void PushPropertiesTo(LayerImpl* layer) override {
3109 LayerImpl::PushPropertiesTo(layer);
3110 push_properties_count_++;
3111 // Push state to the active tree because we can only access it from there.
3112 static_cast<PushPropertiesCountingLayerImpl*>(
3113 layer)->push_properties_count_ = push_properties_count_;
3116 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3117 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3120 size_t push_properties_count() const { return push_properties_count_; }
3121 void reset_push_properties_count() { push_properties_count_ = 0; }
3123 private:
3124 size_t push_properties_count_;
3126 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
3127 : LayerImpl(tree_impl, id),
3128 push_properties_count_(0) {
3129 SetBounds(gfx::Size(1, 1));
3133 class PushPropertiesCountingLayer : public Layer {
3134 public:
3135 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3136 return new PushPropertiesCountingLayer();
3139 void PushPropertiesTo(LayerImpl* layer) override {
3140 Layer::PushPropertiesTo(layer);
3141 push_properties_count_++;
3142 if (persist_needs_push_properties_)
3143 needs_push_properties_ = true;
3146 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3147 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3150 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
3152 size_t push_properties_count() const { return push_properties_count_; }
3153 void reset_push_properties_count() { push_properties_count_ = 0; }
3155 void set_persist_needs_push_properties(bool persist) {
3156 persist_needs_push_properties_ = persist;
3159 private:
3160 PushPropertiesCountingLayer()
3161 : push_properties_count_(0), persist_needs_push_properties_(false) {
3162 SetBounds(gfx::Size(1, 1));
3164 ~PushPropertiesCountingLayer() override {}
3166 size_t push_properties_count_;
3167 bool persist_needs_push_properties_;
3170 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3171 protected:
3172 void BeginTest() override {
3173 num_commits_ = 0;
3174 expected_push_properties_root_ = 0;
3175 expected_push_properties_child_ = 0;
3176 expected_push_properties_grandchild_ = 0;
3177 expected_push_properties_child2_ = 0;
3178 expected_push_properties_other_root_ = 0;
3179 expected_push_properties_leaf_layer_ = 0;
3180 PostSetNeedsCommitToMainThread();
3183 void SetupTree() override {
3184 root_ = PushPropertiesCountingLayer::Create();
3185 root_->CreateRenderSurface();
3186 child_ = PushPropertiesCountingLayer::Create();
3187 child2_ = PushPropertiesCountingLayer::Create();
3188 grandchild_ = PushPropertiesCountingLayer::Create();
3189 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3190 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3192 root_->AddChild(child_);
3193 root_->AddChild(child2_);
3194 child_->AddChild(grandchild_);
3195 child2_->AddChild(leaf_always_pushing_layer_);
3197 other_root_ = PushPropertiesCountingLayer::Create();
3198 other_root_->CreateRenderSurface();
3200 // Don't set the root layer here.
3201 LayerTreeHostTest::SetupTree();
3204 void DidCommitAndDrawFrame() override {
3205 ++num_commits_;
3207 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3208 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3209 EXPECT_EQ(expected_push_properties_grandchild_,
3210 grandchild_->push_properties_count());
3211 EXPECT_EQ(expected_push_properties_child2_,
3212 child2_->push_properties_count());
3213 EXPECT_EQ(expected_push_properties_other_root_,
3214 other_root_->push_properties_count());
3215 EXPECT_EQ(expected_push_properties_leaf_layer_,
3216 leaf_always_pushing_layer_->push_properties_count());
3218 // The scrollbar layer always needs to be pushed.
3219 if (root_->layer_tree_host()) {
3220 EXPECT_TRUE(root_->descendant_needs_push_properties());
3221 EXPECT_FALSE(root_->needs_push_properties());
3223 if (child2_->layer_tree_host()) {
3224 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3225 EXPECT_FALSE(child2_->needs_push_properties());
3227 if (leaf_always_pushing_layer_->layer_tree_host()) {
3228 EXPECT_FALSE(
3229 leaf_always_pushing_layer_->descendant_needs_push_properties());
3230 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3233 // child_ and grandchild_ don't persist their need to push properties.
3234 if (child_->layer_tree_host()) {
3235 EXPECT_FALSE(child_->descendant_needs_push_properties());
3236 EXPECT_FALSE(child_->needs_push_properties());
3238 if (grandchild_->layer_tree_host()) {
3239 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3240 EXPECT_FALSE(grandchild_->needs_push_properties());
3243 if (other_root_->layer_tree_host()) {
3244 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3245 EXPECT_FALSE(other_root_->needs_push_properties());
3248 switch (num_commits_) {
3249 case 1:
3250 layer_tree_host()->SetRootLayer(root_);
3251 // Layers added to the tree get committed.
3252 ++expected_push_properties_root_;
3253 ++expected_push_properties_child_;
3254 ++expected_push_properties_grandchild_;
3255 ++expected_push_properties_child2_;
3256 break;
3257 case 2:
3258 layer_tree_host()->SetNeedsCommit();
3259 // No layers need commit.
3260 break;
3261 case 3:
3262 layer_tree_host()->SetRootLayer(other_root_);
3263 // Layers added to the tree get committed.
3264 ++expected_push_properties_other_root_;
3265 break;
3266 case 4:
3267 layer_tree_host()->SetRootLayer(root_);
3268 // Layers added to the tree get committed.
3269 ++expected_push_properties_root_;
3270 ++expected_push_properties_child_;
3271 ++expected_push_properties_grandchild_;
3272 ++expected_push_properties_child2_;
3273 break;
3274 case 5:
3275 layer_tree_host()->SetNeedsCommit();
3276 // No layers need commit.
3277 break;
3278 case 6:
3279 child_->RemoveFromParent();
3280 // No layers need commit.
3281 break;
3282 case 7:
3283 root_->AddChild(child_);
3284 // Layers added to the tree get committed.
3285 ++expected_push_properties_child_;
3286 ++expected_push_properties_grandchild_;
3287 break;
3288 case 8:
3289 grandchild_->RemoveFromParent();
3290 // No layers need commit.
3291 break;
3292 case 9:
3293 child_->AddChild(grandchild_);
3294 // Layers added to the tree get committed.
3295 ++expected_push_properties_grandchild_;
3296 break;
3297 case 10:
3298 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3299 // No layers need commit.
3300 break;
3301 case 11:
3302 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3303 // No layers need commit.
3304 break;
3305 case 12:
3306 child_->SetPosition(gfx::Point(1, 1));
3307 // The modified layer needs commit
3308 ++expected_push_properties_child_;
3309 break;
3310 case 13:
3311 child2_->SetPosition(gfx::Point(1, 1));
3312 // The modified layer needs commit
3313 ++expected_push_properties_child2_;
3314 break;
3315 case 14:
3316 child_->RemoveFromParent();
3317 root_->AddChild(child_);
3318 // Layers added to the tree get committed.
3319 ++expected_push_properties_child_;
3320 ++expected_push_properties_grandchild_;
3321 break;
3322 case 15:
3323 grandchild_->SetPosition(gfx::Point(1, 1));
3324 // The modified layer needs commit
3325 ++expected_push_properties_grandchild_;
3326 break;
3327 case 16:
3328 // SetNeedsDisplay does not always set needs commit (so call it
3329 // explicitly), but is a property change.
3330 child_->SetNeedsDisplay();
3331 ++expected_push_properties_child_;
3332 layer_tree_host()->SetNeedsCommit();
3333 break;
3334 case 17:
3335 EndTest();
3336 break;
3339 // The leaf layer always pushes.
3340 if (leaf_always_pushing_layer_->layer_tree_host())
3341 ++expected_push_properties_leaf_layer_;
3344 void AfterTest() override {}
3346 int num_commits_;
3347 FakeContentLayerClient client_;
3348 scoped_refptr<PushPropertiesCountingLayer> root_;
3349 scoped_refptr<PushPropertiesCountingLayer> child_;
3350 scoped_refptr<PushPropertiesCountingLayer> child2_;
3351 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3352 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3353 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3354 size_t expected_push_properties_root_;
3355 size_t expected_push_properties_child_;
3356 size_t expected_push_properties_child2_;
3357 size_t expected_push_properties_grandchild_;
3358 size_t expected_push_properties_other_root_;
3359 size_t expected_push_properties_leaf_layer_;
3362 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3364 class LayerTreeHostTestImplLayersPushProperties
3365 : public LayerTreeHostTestLayersPushProperties {
3366 protected:
3367 void BeginTest() override {
3368 expected_push_properties_root_impl_ = 0;
3369 expected_push_properties_child_impl_ = 0;
3370 expected_push_properties_grandchild_impl_ = 0;
3371 expected_push_properties_child2_impl_ = 0;
3372 expected_push_properties_grandchild2_impl_ = 0;
3373 LayerTreeHostTestLayersPushProperties::BeginTest();
3376 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3377 // These commits are in response to the changes made in
3378 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3379 switch (num_commits_) {
3380 case 0:
3381 // Tree hasn't been setup yet don't bother to check anything.
3382 return;
3383 case 1:
3384 // Root gets set up, Everyone is initialized.
3385 ++expected_push_properties_root_impl_;
3386 ++expected_push_properties_child_impl_;
3387 ++expected_push_properties_grandchild_impl_;
3388 ++expected_push_properties_child2_impl_;
3389 ++expected_push_properties_grandchild2_impl_;
3390 break;
3391 case 2:
3392 // Tree doesn't change but the one leaf that always pushes is pushed.
3393 ++expected_push_properties_grandchild2_impl_;
3394 break;
3395 case 3:
3396 // Root is swapped here.
3397 // Clear the expected push properties the tree will be rebuilt.
3398 expected_push_properties_root_impl_ = 0;
3399 expected_push_properties_child_impl_ = 0;
3400 expected_push_properties_grandchild_impl_ = 0;
3401 expected_push_properties_child2_impl_ = 0;
3402 expected_push_properties_grandchild2_impl_ = 0;
3404 // Make sure the new root is pushed.
3405 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3406 host_impl->RootLayer())->push_properties_count());
3407 return;
3408 case 4:
3409 // Root is swapped back all of the layers in the tree get pushed.
3410 ++expected_push_properties_root_impl_;
3411 ++expected_push_properties_child_impl_;
3412 ++expected_push_properties_grandchild_impl_;
3413 ++expected_push_properties_child2_impl_;
3414 ++expected_push_properties_grandchild2_impl_;
3415 break;
3416 case 5:
3417 // Tree doesn't change but the one leaf that always pushes is pushed.
3418 ++expected_push_properties_grandchild2_impl_;
3419 break;
3420 case 6:
3421 // First child is removed. Structure of the tree changes here so swap
3422 // some of the values. child_impl becomes child2_impl.
3423 expected_push_properties_child_impl_ =
3424 expected_push_properties_child2_impl_;
3425 expected_push_properties_child2_impl_ = 0;
3426 // grandchild_impl becomes grandchild2_impl.
3427 expected_push_properties_grandchild_impl_ =
3428 expected_push_properties_grandchild2_impl_;
3429 expected_push_properties_grandchild2_impl_ = 0;
3431 // grandchild_impl is now the leaf that always pushes. It is pushed.
3432 ++expected_push_properties_grandchild_impl_;
3433 break;
3434 case 7:
3435 // The leaf that always pushes is pushed.
3436 ++expected_push_properties_grandchild_impl_;
3438 // Child is added back. New layers are initialized.
3439 ++expected_push_properties_grandchild2_impl_;
3440 ++expected_push_properties_child2_impl_;
3441 break;
3442 case 8:
3443 // Leaf is removed.
3444 expected_push_properties_grandchild2_impl_ = 0;
3446 // Always pushing.
3447 ++expected_push_properties_grandchild_impl_;
3448 break;
3449 case 9:
3450 // Leaf is added back
3451 ++expected_push_properties_grandchild2_impl_;
3453 // The leaf that always pushes is pushed.
3454 ++expected_push_properties_grandchild_impl_;
3455 break;
3456 case 10:
3457 // The leaf that always pushes is pushed.
3458 ++expected_push_properties_grandchild_impl_;
3459 break;
3460 case 11:
3461 // The leaf that always pushes is pushed.
3462 ++expected_push_properties_grandchild_impl_;
3463 break;
3464 case 12:
3465 // The leaf that always pushes is pushed.
3466 ++expected_push_properties_grandchild_impl_;
3468 // This child position was changed.
3469 ++expected_push_properties_child2_impl_;
3470 break;
3471 case 13:
3472 // The position of this child was changed.
3473 ++expected_push_properties_child_impl_;
3475 // The leaf that always pushes is pushed.
3476 ++expected_push_properties_grandchild_impl_;
3477 break;
3478 case 14:
3479 // Second child is removed from tree. Don't discard counts because
3480 // they are added back before commit.
3482 // The leaf that always pushes is pushed.
3483 ++expected_push_properties_grandchild_impl_;
3485 // Second child added back.
3486 ++expected_push_properties_child2_impl_;
3487 ++expected_push_properties_grandchild2_impl_;
3489 break;
3490 case 15:
3491 // The position of this child was changed.
3492 ++expected_push_properties_grandchild2_impl_;
3494 // The leaf that always pushes is pushed.
3495 ++expected_push_properties_grandchild_impl_;
3496 break;
3497 case 16:
3498 // Second child is invalidated with SetNeedsDisplay
3499 ++expected_push_properties_child2_impl_;
3501 // The leaf that always pushed is pushed.
3502 ++expected_push_properties_grandchild_impl_;
3503 break;
3506 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3507 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3508 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3509 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3510 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3512 // Pull the layers that we need from the tree assuming the same structure
3513 // as LayerTreeHostTestLayersPushProperties
3514 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3515 host_impl->RootLayer());
3517 if (root_impl_ && root_impl_->children().size() > 0) {
3518 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3519 root_impl_->children()[0]);
3521 if (child_impl_ && child_impl_->children().size() > 0)
3522 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3523 child_impl_->children()[0]);
3526 if (root_impl_ && root_impl_->children().size() > 1) {
3527 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3528 root_impl_->children()[1]);
3530 if (child2_impl_ && child2_impl_->children().size() > 0)
3531 leaf_always_pushing_layer_impl_ =
3532 static_cast<PushPropertiesCountingLayerImpl*>(
3533 child2_impl_->children()[0]);
3536 if (root_impl_)
3537 EXPECT_EQ(expected_push_properties_root_impl_,
3538 root_impl_->push_properties_count());
3539 if (child_impl_)
3540 EXPECT_EQ(expected_push_properties_child_impl_,
3541 child_impl_->push_properties_count());
3542 if (grandchild_impl_)
3543 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3544 grandchild_impl_->push_properties_count());
3545 if (child2_impl_)
3546 EXPECT_EQ(expected_push_properties_child2_impl_,
3547 child2_impl_->push_properties_count());
3548 if (leaf_always_pushing_layer_impl_)
3549 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3550 leaf_always_pushing_layer_impl_->push_properties_count());
3553 size_t expected_push_properties_root_impl_;
3554 size_t expected_push_properties_child_impl_;
3555 size_t expected_push_properties_child2_impl_;
3556 size_t expected_push_properties_grandchild_impl_;
3557 size_t expected_push_properties_grandchild2_impl_;
3560 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3561 RunTestWithImplSidePainting();
3564 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3565 : public LayerTreeHostTest {
3566 protected:
3567 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3569 void SetupTree() override {
3570 root_ = Layer::Create();
3571 root_->CreateRenderSurface();
3572 root_->SetBounds(gfx::Size(1, 1));
3574 bool paint_scrollbar = true;
3575 bool has_thumb = false;
3576 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3577 paint_scrollbar, has_thumb, root_->id());
3579 root_->AddChild(scrollbar_layer_);
3581 layer_tree_host()->SetRootLayer(root_);
3582 LayerTreeHostTest::SetupTree();
3585 void DidCommitAndDrawFrame() override {
3586 switch (layer_tree_host()->source_frame_number()) {
3587 case 0:
3588 break;
3589 case 1: {
3590 // During update, the ignore_set_needs_commit_ bit is set to true to
3591 // avoid causing a second commit to be scheduled. If a property change
3592 // is made during this, however, it needs to be pushed in the upcoming
3593 // commit.
3594 scoped_ptr<base::AutoReset<bool>> ignore =
3595 scrollbar_layer_->IgnoreSetNeedsCommit();
3597 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3599 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3600 EXPECT_TRUE(root_->descendant_needs_push_properties());
3601 layer_tree_host()->SetNeedsCommit();
3603 scrollbar_layer_->reset_push_properties_count();
3604 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3605 break;
3607 case 2:
3608 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3609 EndTest();
3610 break;
3614 void AfterTest() override {}
3616 scoped_refptr<Layer> root_;
3617 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3620 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3622 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3623 protected:
3624 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3626 void SetupTree() override {
3627 root_ = PushPropertiesCountingLayer::Create();
3628 root_->CreateRenderSurface();
3629 child_ = PushPropertiesCountingLayer::Create();
3630 root_->AddChild(child_);
3632 layer_tree_host()->SetRootLayer(root_);
3633 LayerTreeHostTest::SetupTree();
3636 void DidCommitAndDrawFrame() override {
3637 switch (layer_tree_host()->source_frame_number()) {
3638 case 0:
3639 break;
3640 case 1: {
3641 // During update, the ignore_set_needs_commit_ bit is set to true to
3642 // avoid causing a second commit to be scheduled. If a property change
3643 // is made during this, however, it needs to be pushed in the upcoming
3644 // commit.
3645 EXPECT_FALSE(root_->needs_push_properties());
3646 EXPECT_FALSE(child_->needs_push_properties());
3647 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3648 root_->reset_push_properties_count();
3649 child_->reset_push_properties_count();
3650 child_->SetDrawsContent(true);
3651 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3652 EXPECT_EQ(0u, root_->push_properties_count());
3653 EXPECT_EQ(0u, child_->push_properties_count());
3654 EXPECT_TRUE(root_->needs_push_properties());
3655 EXPECT_TRUE(child_->needs_push_properties());
3656 break;
3658 case 2:
3659 EXPECT_EQ(1u, root_->push_properties_count());
3660 EXPECT_EQ(1u, child_->push_properties_count());
3661 EXPECT_FALSE(root_->needs_push_properties());
3662 EXPECT_FALSE(child_->needs_push_properties());
3663 EndTest();
3664 break;
3668 void AfterTest() override {}
3670 scoped_refptr<PushPropertiesCountingLayer> root_;
3671 scoped_refptr<PushPropertiesCountingLayer> child_;
3674 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3676 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3677 : public LayerTreeHostTest {
3678 protected:
3679 void BeginTest() override {
3680 expected_push_properties_root_ = 0;
3681 expected_push_properties_child_ = 0;
3682 expected_push_properties_grandchild1_ = 0;
3683 expected_push_properties_grandchild2_ = 0;
3684 expected_push_properties_grandchild3_ = 0;
3685 PostSetNeedsCommitToMainThread();
3688 void SetupTree() override {
3689 root_ = PushPropertiesCountingLayer::Create();
3690 root_->CreateRenderSurface();
3691 child_ = PushPropertiesCountingLayer::Create();
3692 grandchild1_ = PushPropertiesCountingLayer::Create();
3693 grandchild2_ = PushPropertiesCountingLayer::Create();
3694 grandchild3_ = PushPropertiesCountingLayer::Create();
3696 root_->AddChild(child_);
3697 child_->AddChild(grandchild1_);
3698 child_->AddChild(grandchild2_);
3699 child_->AddChild(grandchild3_);
3701 // Don't set the root layer here.
3702 LayerTreeHostTest::SetupTree();
3705 void AfterTest() override {}
3707 FakeContentLayerClient client_;
3708 scoped_refptr<PushPropertiesCountingLayer> root_;
3709 scoped_refptr<PushPropertiesCountingLayer> child_;
3710 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3711 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3712 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3713 size_t expected_push_properties_root_;
3714 size_t expected_push_properties_child_;
3715 size_t expected_push_properties_grandchild1_;
3716 size_t expected_push_properties_grandchild2_;
3717 size_t expected_push_properties_grandchild3_;
3720 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3721 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3722 protected:
3723 void DidCommitAndDrawFrame() override {
3724 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3725 switch (last_source_frame_number) {
3726 case 0:
3727 EXPECT_FALSE(root_->needs_push_properties());
3728 EXPECT_FALSE(root_->descendant_needs_push_properties());
3729 EXPECT_FALSE(child_->needs_push_properties());
3730 EXPECT_FALSE(child_->descendant_needs_push_properties());
3731 EXPECT_FALSE(grandchild1_->needs_push_properties());
3732 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3733 EXPECT_FALSE(grandchild2_->needs_push_properties());
3734 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3735 EXPECT_FALSE(grandchild3_->needs_push_properties());
3736 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3738 layer_tree_host()->SetRootLayer(root_);
3740 EXPECT_TRUE(root_->needs_push_properties());
3741 EXPECT_TRUE(root_->descendant_needs_push_properties());
3742 EXPECT_TRUE(child_->needs_push_properties());
3743 EXPECT_TRUE(child_->descendant_needs_push_properties());
3744 EXPECT_TRUE(grandchild1_->needs_push_properties());
3745 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3746 EXPECT_TRUE(grandchild2_->needs_push_properties());
3747 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3748 EXPECT_TRUE(grandchild3_->needs_push_properties());
3749 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3750 break;
3751 case 1:
3752 EndTest();
3753 break;
3758 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3760 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3761 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3762 protected:
3763 void DidCommitAndDrawFrame() override {
3764 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3765 switch (last_source_frame_number) {
3766 case 0:
3767 layer_tree_host()->SetRootLayer(root_);
3768 break;
3769 case 1:
3770 EXPECT_FALSE(root_->needs_push_properties());
3771 EXPECT_FALSE(root_->descendant_needs_push_properties());
3772 EXPECT_FALSE(child_->needs_push_properties());
3773 EXPECT_FALSE(child_->descendant_needs_push_properties());
3774 EXPECT_FALSE(grandchild1_->needs_push_properties());
3775 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3776 EXPECT_FALSE(grandchild2_->needs_push_properties());
3777 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3778 EXPECT_FALSE(grandchild3_->needs_push_properties());
3779 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3781 grandchild1_->RemoveFromParent();
3782 grandchild1_->SetPosition(gfx::Point(1, 1));
3784 EXPECT_FALSE(root_->needs_push_properties());
3785 EXPECT_FALSE(root_->descendant_needs_push_properties());
3786 EXPECT_FALSE(child_->needs_push_properties());
3787 EXPECT_FALSE(child_->descendant_needs_push_properties());
3788 EXPECT_FALSE(grandchild2_->needs_push_properties());
3789 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3790 EXPECT_FALSE(grandchild3_->needs_push_properties());
3791 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3793 child_->AddChild(grandchild1_);
3795 EXPECT_FALSE(root_->needs_push_properties());
3796 EXPECT_TRUE(root_->descendant_needs_push_properties());
3797 EXPECT_FALSE(child_->needs_push_properties());
3798 EXPECT_TRUE(child_->descendant_needs_push_properties());
3799 EXPECT_TRUE(grandchild1_->needs_push_properties());
3800 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3801 EXPECT_FALSE(grandchild2_->needs_push_properties());
3802 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3803 EXPECT_FALSE(grandchild3_->needs_push_properties());
3804 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3806 grandchild2_->SetPosition(gfx::Point(1, 1));
3808 EXPECT_FALSE(root_->needs_push_properties());
3809 EXPECT_TRUE(root_->descendant_needs_push_properties());
3810 EXPECT_FALSE(child_->needs_push_properties());
3811 EXPECT_TRUE(child_->descendant_needs_push_properties());
3812 EXPECT_TRUE(grandchild1_->needs_push_properties());
3813 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3814 EXPECT_TRUE(grandchild2_->needs_push_properties());
3815 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3816 EXPECT_FALSE(grandchild3_->needs_push_properties());
3817 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3819 // grandchild2_ will still need a push properties.
3820 grandchild1_->RemoveFromParent();
3822 EXPECT_FALSE(root_->needs_push_properties());
3823 EXPECT_TRUE(root_->descendant_needs_push_properties());
3824 EXPECT_FALSE(child_->needs_push_properties());
3825 EXPECT_TRUE(child_->descendant_needs_push_properties());
3827 // grandchild3_ does not need a push properties, so recursing should
3828 // no longer be needed.
3829 grandchild2_->RemoveFromParent();
3831 EXPECT_FALSE(root_->needs_push_properties());
3832 EXPECT_FALSE(root_->descendant_needs_push_properties());
3833 EXPECT_FALSE(child_->needs_push_properties());
3834 EXPECT_FALSE(child_->descendant_needs_push_properties());
3835 EndTest();
3836 break;
3841 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3843 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3844 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3845 protected:
3846 void DidCommitAndDrawFrame() override {
3847 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3848 switch (last_source_frame_number) {
3849 case 0:
3850 layer_tree_host()->SetRootLayer(root_);
3851 grandchild1_->set_persist_needs_push_properties(true);
3852 grandchild2_->set_persist_needs_push_properties(true);
3853 break;
3854 case 1:
3855 EXPECT_FALSE(root_->needs_push_properties());
3856 EXPECT_TRUE(root_->descendant_needs_push_properties());
3857 EXPECT_FALSE(child_->needs_push_properties());
3858 EXPECT_TRUE(child_->descendant_needs_push_properties());
3859 EXPECT_TRUE(grandchild1_->needs_push_properties());
3860 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3861 EXPECT_TRUE(grandchild2_->needs_push_properties());
3862 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3863 EXPECT_FALSE(grandchild3_->needs_push_properties());
3864 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3866 // grandchild2_ will still need a push properties.
3867 grandchild1_->RemoveFromParent();
3869 EXPECT_FALSE(root_->needs_push_properties());
3870 EXPECT_TRUE(root_->descendant_needs_push_properties());
3871 EXPECT_FALSE(child_->needs_push_properties());
3872 EXPECT_TRUE(child_->descendant_needs_push_properties());
3874 // grandchild3_ does not need a push properties, so recursing should
3875 // no longer be needed.
3876 grandchild2_->RemoveFromParent();
3878 EXPECT_FALSE(root_->needs_push_properties());
3879 EXPECT_FALSE(root_->descendant_needs_push_properties());
3880 EXPECT_FALSE(child_->needs_push_properties());
3881 EXPECT_FALSE(child_->descendant_needs_push_properties());
3882 EndTest();
3883 break;
3888 MULTI_THREAD_TEST_F(
3889 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3891 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3892 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3893 protected:
3894 void DidCommitAndDrawFrame() override {
3895 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3896 switch (last_source_frame_number) {
3897 case 0:
3898 layer_tree_host()->SetRootLayer(root_);
3899 break;
3900 case 1:
3901 EXPECT_FALSE(root_->needs_push_properties());
3902 EXPECT_FALSE(root_->descendant_needs_push_properties());
3903 EXPECT_FALSE(child_->needs_push_properties());
3904 EXPECT_FALSE(child_->descendant_needs_push_properties());
3905 EXPECT_FALSE(grandchild1_->needs_push_properties());
3906 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3907 EXPECT_FALSE(grandchild2_->needs_push_properties());
3908 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3909 EXPECT_FALSE(grandchild3_->needs_push_properties());
3910 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3912 // Change grandchildren while their parent is not in the tree.
3913 child_->RemoveFromParent();
3914 grandchild1_->SetPosition(gfx::Point(1, 1));
3915 grandchild2_->SetPosition(gfx::Point(1, 1));
3916 root_->AddChild(child_);
3918 EXPECT_FALSE(root_->needs_push_properties());
3919 EXPECT_TRUE(root_->descendant_needs_push_properties());
3920 EXPECT_TRUE(child_->needs_push_properties());
3921 EXPECT_TRUE(child_->descendant_needs_push_properties());
3922 EXPECT_TRUE(grandchild1_->needs_push_properties());
3923 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3924 EXPECT_TRUE(grandchild2_->needs_push_properties());
3925 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3926 EXPECT_TRUE(grandchild3_->needs_push_properties());
3927 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3929 grandchild1_->RemoveFromParent();
3931 EXPECT_FALSE(root_->needs_push_properties());
3932 EXPECT_TRUE(root_->descendant_needs_push_properties());
3933 EXPECT_TRUE(child_->needs_push_properties());
3934 EXPECT_TRUE(child_->descendant_needs_push_properties());
3936 grandchild2_->RemoveFromParent();
3938 EXPECT_FALSE(root_->needs_push_properties());
3939 EXPECT_TRUE(root_->descendant_needs_push_properties());
3940 EXPECT_TRUE(child_->needs_push_properties());
3941 EXPECT_TRUE(child_->descendant_needs_push_properties());
3943 grandchild3_->RemoveFromParent();
3945 EXPECT_FALSE(root_->needs_push_properties());
3946 EXPECT_TRUE(root_->descendant_needs_push_properties());
3947 EXPECT_TRUE(child_->needs_push_properties());
3948 EXPECT_FALSE(child_->descendant_needs_push_properties());
3950 EndTest();
3951 break;
3956 MULTI_THREAD_TEST_F(
3957 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3959 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3960 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3961 protected:
3962 void DidCommitAndDrawFrame() override {
3963 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3964 switch (last_source_frame_number) {
3965 case 0:
3966 layer_tree_host()->SetRootLayer(root_);
3967 break;
3968 case 1:
3969 EXPECT_FALSE(root_->needs_push_properties());
3970 EXPECT_FALSE(root_->descendant_needs_push_properties());
3971 EXPECT_FALSE(child_->needs_push_properties());
3972 EXPECT_FALSE(child_->descendant_needs_push_properties());
3973 EXPECT_FALSE(grandchild1_->needs_push_properties());
3974 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3975 EXPECT_FALSE(grandchild2_->needs_push_properties());
3976 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3977 EXPECT_FALSE(grandchild3_->needs_push_properties());
3978 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3980 child_->SetPosition(gfx::Point(1, 1));
3981 grandchild1_->SetPosition(gfx::Point(1, 1));
3982 grandchild2_->SetPosition(gfx::Point(1, 1));
3984 EXPECT_FALSE(root_->needs_push_properties());
3985 EXPECT_TRUE(root_->descendant_needs_push_properties());
3986 EXPECT_TRUE(child_->needs_push_properties());
3987 EXPECT_TRUE(child_->descendant_needs_push_properties());
3988 EXPECT_TRUE(grandchild1_->needs_push_properties());
3989 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3990 EXPECT_TRUE(grandchild2_->needs_push_properties());
3991 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3992 EXPECT_FALSE(grandchild3_->needs_push_properties());
3993 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3995 grandchild1_->RemoveFromParent();
3997 EXPECT_FALSE(root_->needs_push_properties());
3998 EXPECT_TRUE(root_->descendant_needs_push_properties());
3999 EXPECT_TRUE(child_->needs_push_properties());
4000 EXPECT_TRUE(child_->descendant_needs_push_properties());
4002 grandchild2_->RemoveFromParent();
4004 EXPECT_FALSE(root_->needs_push_properties());
4005 EXPECT_TRUE(root_->descendant_needs_push_properties());
4006 EXPECT_TRUE(child_->needs_push_properties());
4007 EXPECT_FALSE(child_->descendant_needs_push_properties());
4009 child_->RemoveFromParent();
4011 EXPECT_FALSE(root_->needs_push_properties());
4012 EXPECT_FALSE(root_->descendant_needs_push_properties());
4014 EndTest();
4015 break;
4020 MULTI_THREAD_TEST_F(
4021 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4023 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4024 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4025 protected:
4026 void DidCommitAndDrawFrame() override {
4027 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4028 switch (last_source_frame_number) {
4029 case 0:
4030 layer_tree_host()->SetRootLayer(root_);
4031 break;
4032 case 1:
4033 EXPECT_FALSE(root_->needs_push_properties());
4034 EXPECT_FALSE(root_->descendant_needs_push_properties());
4035 EXPECT_FALSE(child_->needs_push_properties());
4036 EXPECT_FALSE(child_->descendant_needs_push_properties());
4037 EXPECT_FALSE(grandchild1_->needs_push_properties());
4038 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4039 EXPECT_FALSE(grandchild2_->needs_push_properties());
4040 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4041 EXPECT_FALSE(grandchild3_->needs_push_properties());
4042 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4044 grandchild1_->SetPosition(gfx::Point(1, 1));
4045 grandchild2_->SetPosition(gfx::Point(1, 1));
4046 child_->SetPosition(gfx::Point(1, 1));
4048 EXPECT_FALSE(root_->needs_push_properties());
4049 EXPECT_TRUE(root_->descendant_needs_push_properties());
4050 EXPECT_TRUE(child_->needs_push_properties());
4051 EXPECT_TRUE(child_->descendant_needs_push_properties());
4052 EXPECT_TRUE(grandchild1_->needs_push_properties());
4053 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4054 EXPECT_TRUE(grandchild2_->needs_push_properties());
4055 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4056 EXPECT_FALSE(grandchild3_->needs_push_properties());
4057 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4059 grandchild1_->RemoveFromParent();
4061 EXPECT_FALSE(root_->needs_push_properties());
4062 EXPECT_TRUE(root_->descendant_needs_push_properties());
4063 EXPECT_TRUE(child_->needs_push_properties());
4064 EXPECT_TRUE(child_->descendant_needs_push_properties());
4066 grandchild2_->RemoveFromParent();
4068 EXPECT_FALSE(root_->needs_push_properties());
4069 EXPECT_TRUE(root_->descendant_needs_push_properties());
4070 EXPECT_TRUE(child_->needs_push_properties());
4071 EXPECT_FALSE(child_->descendant_needs_push_properties());
4073 child_->RemoveFromParent();
4075 EXPECT_FALSE(root_->needs_push_properties());
4076 EXPECT_FALSE(root_->descendant_needs_push_properties());
4078 EndTest();
4079 break;
4084 MULTI_THREAD_TEST_F(
4085 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4087 // This test verifies that the tree activation callback is invoked correctly.
4088 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4089 public:
4090 LayerTreeHostTestTreeActivationCallback()
4091 : num_commits_(0), callback_count_(0) {}
4093 void BeginTest() override {
4094 EXPECT_TRUE(HasImplThread());
4095 PostSetNeedsCommitToMainThread();
4098 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4099 LayerTreeHostImpl::FrameData* frame_data,
4100 DrawResult draw_result) override {
4101 ++num_commits_;
4102 switch (num_commits_) {
4103 case 1:
4104 EXPECT_EQ(0, callback_count_);
4105 callback_count_ = 0;
4106 SetCallback(true);
4107 PostSetNeedsCommitToMainThread();
4108 break;
4109 case 2:
4110 EXPECT_EQ(1, callback_count_);
4111 callback_count_ = 0;
4112 SetCallback(false);
4113 PostSetNeedsCommitToMainThread();
4114 break;
4115 case 3:
4116 EXPECT_EQ(0, callback_count_);
4117 callback_count_ = 0;
4118 EndTest();
4119 break;
4120 default:
4121 ADD_FAILURE() << num_commits_;
4122 EndTest();
4123 break;
4125 return LayerTreeHostTest::PrepareToDrawOnThread(
4126 host_impl, frame_data, draw_result);
4129 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
4131 void SetCallback(bool enable) {
4132 output_surface()->SetTreeActivationCallback(
4133 enable
4134 ? base::Bind(
4135 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4136 base::Unretained(this))
4137 : base::Closure());
4140 void ActivationCallback() { ++callback_count_; }
4142 int num_commits_;
4143 int callback_count_;
4146 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4147 RunTest(true, false, true);
4150 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4151 RunTest(true, true, true);
4154 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4155 public:
4156 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4158 void BeginTest() override {
4159 ASSERT_TRUE(!!invalidate_layer_.get())
4160 << "Derived tests must set this in SetupTree";
4162 // One initial commit.
4163 PostSetNeedsCommitToMainThread();
4166 void DidCommitAndDrawFrame() override {
4167 // After commit, invalidate the layer. This should cause a commit.
4168 if (layer_tree_host()->source_frame_number() == 1)
4169 invalidate_layer_->SetNeedsDisplay();
4172 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4173 num_draws_++;
4174 if (impl->active_tree()->source_frame_number() == 1)
4175 EndTest();
4178 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4179 num_commits_++;
4182 void AfterTest() override {
4183 EXPECT_GE(2, num_commits_);
4184 EXPECT_GE(2, num_draws_);
4187 protected:
4188 scoped_refptr<Layer> invalidate_layer_;
4190 private:
4191 int num_commits_;
4192 int num_draws_;
4195 // VideoLayer must support being invalidated and then passing that along
4196 // to the compositor thread, even though no resources are updated in
4197 // response to that invalidation.
4198 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4199 public:
4200 void SetupTree() override {
4201 LayerTreeHostTest::SetupTree();
4202 scoped_refptr<VideoLayer> video_layer =
4203 VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
4204 video_layer->SetBounds(gfx::Size(10, 10));
4205 video_layer->SetIsDrawable(true);
4206 layer_tree_host()->root_layer()->AddChild(video_layer);
4208 invalidate_layer_ = video_layer;
4211 private:
4212 FakeVideoFrameProvider provider_;
4215 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4217 // IOSurfaceLayer must support being invalidated and then passing that along
4218 // to the compositor thread, even though no resources are updated in
4219 // response to that invalidation.
4220 class LayerTreeHostTestIOSurfaceLayerInvalidate
4221 : public LayerInvalidateCausesDraw {
4222 public:
4223 void SetupTree() override {
4224 LayerTreeHostTest::SetupTree();
4225 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4226 layer->SetBounds(gfx::Size(10, 10));
4227 uint32_t fake_io_surface_id = 7;
4228 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4229 layer->SetIsDrawable(true);
4230 layer_tree_host()->root_layer()->AddChild(layer);
4232 invalidate_layer_ = layer;
4236 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4237 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4238 LayerTreeHostTestIOSurfaceLayerInvalidate);
4240 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4241 protected:
4242 void SetupTree() override {
4243 root_layer_ = Layer::Create();
4244 root_layer_->CreateRenderSurface();
4245 root_layer_->SetPosition(gfx::Point());
4246 root_layer_->SetBounds(gfx::Size(10, 10));
4248 parent_layer_ = SolidColorLayer::Create();
4249 parent_layer_->SetPosition(gfx::Point());
4250 parent_layer_->SetBounds(gfx::Size(10, 10));
4251 parent_layer_->SetIsDrawable(true);
4252 root_layer_->AddChild(parent_layer_);
4254 child_layer_ = SolidColorLayer::Create();
4255 child_layer_->SetPosition(gfx::Point());
4256 child_layer_->SetBounds(gfx::Size(10, 10));
4257 child_layer_->SetIsDrawable(true);
4258 parent_layer_->AddChild(child_layer_);
4260 layer_tree_host()->SetRootLayer(root_layer_);
4261 LayerTreeHostTest::SetupTree();
4264 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4266 void DidCommitAndDrawFrame() override {
4267 switch (layer_tree_host()->source_frame_number()) {
4268 case 1:
4269 // The layer type used does not need to push properties every frame.
4270 EXPECT_FALSE(child_layer_->needs_push_properties());
4272 // Change the bounds of the child layer, but make it skipped
4273 // by CalculateDrawProperties.
4274 parent_layer_->SetOpacity(0.f);
4275 child_layer_->SetBounds(gfx::Size(5, 5));
4276 break;
4277 case 2:
4278 // The bounds of the child layer were pushed to the impl side.
4279 EXPECT_FALSE(child_layer_->needs_push_properties());
4281 EndTest();
4282 break;
4286 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4287 LayerImpl* root = impl->active_tree()->root_layer();
4288 LayerImpl* parent = root->children()[0];
4289 LayerImpl* child = parent->children()[0];
4291 switch (impl->active_tree()->source_frame_number()) {
4292 case 1:
4293 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4294 break;
4298 void AfterTest() override {}
4300 scoped_refptr<Layer> root_layer_;
4301 scoped_refptr<SolidColorLayer> parent_layer_;
4302 scoped_refptr<SolidColorLayer> child_layer_;
4305 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4307 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4308 protected:
4309 void InitializeSettings(LayerTreeSettings* settings) override {
4310 settings->impl_side_painting = true;
4313 void SetupTree() override {
4314 root_layer_ = FakePictureLayer::Create(&client_);
4315 root_layer_->SetBounds(gfx::Size(10, 10));
4317 layer_tree_host()->SetRootLayer(root_layer_);
4318 LayerTreeHostTest::SetupTree();
4321 void BeginTest() override {
4322 // The viewport is empty, but we still need to update layers on the main
4323 // thread.
4324 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4325 PostSetNeedsCommitToMainThread();
4328 void DidCommit() override {
4329 // The layer should be updated even though the viewport is empty, so we
4330 // are capable of drawing it on the impl tree.
4331 EXPECT_GT(root_layer_->update_count(), 0u);
4332 EndTest();
4335 void AfterTest() override {}
4337 FakeContentLayerClient client_;
4338 scoped_refptr<FakePictureLayer> root_layer_;
4341 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4343 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4344 public:
4345 LayerTreeHostTestAbortEvictedTextures()
4346 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4348 protected:
4349 void SetupTree() override {
4350 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4351 root_layer->SetBounds(gfx::Size(200, 200));
4352 root_layer->SetIsDrawable(true);
4353 root_layer->CreateRenderSurface();
4355 layer_tree_host()->SetRootLayer(root_layer);
4356 LayerTreeHostTest::SetupTree();
4359 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4361 void WillBeginMainFrame() override {
4362 num_will_begin_main_frames_++;
4363 switch (num_will_begin_main_frames_) {
4364 case 2:
4365 // Send a redraw to the compositor thread. This will (wrongly) be
4366 // ignored unless aborting resets the texture state.
4367 layer_tree_host()->SetNeedsRedraw();
4368 break;
4372 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
4373 num_impl_commits_++;
4376 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4377 switch (impl->SourceAnimationFrameNumber()) {
4378 case 1:
4379 // Prevent draws until commit.
4380 impl->active_tree()->SetContentsTexturesPurged();
4381 EXPECT_FALSE(impl->CanDraw());
4382 // Trigger an abortable commit.
4383 impl->SetNeedsCommit();
4384 break;
4385 case 2:
4386 EndTest();
4387 break;
4391 void AfterTest() override {
4392 // Ensure that the commit was truly aborted.
4393 EXPECT_EQ(2, num_will_begin_main_frames_);
4394 EXPECT_EQ(1, num_impl_commits_);
4397 private:
4398 int num_will_begin_main_frames_;
4399 int num_impl_commits_;
4402 // Commits can only be aborted when using the thread proxy.
4403 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4405 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4406 protected:
4407 void InitializeSettings(LayerTreeSettings* settings) override {
4408 settings->impl_side_painting = true;
4409 settings->use_zero_copy = false;
4410 settings->use_one_copy = false;
4413 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4414 scoped_refptr<TestContextProvider> context_provider =
4415 TestContextProvider::Create();
4416 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
4417 if (delegating_renderer())
4418 return FakeOutputSurface::CreateDelegating3d(context_provider);
4419 else
4420 return FakeOutputSurface::Create3d(context_provider);
4423 void SetupTree() override {
4424 client_.set_fill_with_nonsolid_color(true);
4425 scoped_refptr<FakePictureLayer> root_layer =
4426 FakePictureLayer::Create(&client_);
4427 root_layer->SetBounds(gfx::Size(1024, 1024));
4428 root_layer->SetIsDrawable(true);
4430 layer_tree_host()->SetRootLayer(root_layer);
4431 LayerTreeHostTest::SetupTree();
4434 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4436 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4437 TestWebGraphicsContext3D* context = TestContext();
4439 // Expect that the transfer buffer memory used is equal to the
4440 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4441 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
4442 EndTest();
4445 void AfterTest() override {}
4447 private:
4448 FakeContentLayerClient client_;
4451 // Impl-side painting is a multi-threaded compositor feature.
4452 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4454 // Test ensuring that memory limits are sent to the prioritized resource
4455 // manager.
4456 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4457 public:
4458 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4460 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4462 void WillCommit() override {
4463 // Some commits are aborted, so increment number of attempted commits here.
4464 num_commits_++;
4467 void DidCommit() override {
4468 switch (num_commits_) {
4469 case 1:
4470 // Verify default values.
4471 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4472 layer_tree_host()
4473 ->contents_texture_manager()
4474 ->MaxMemoryLimitBytes());
4475 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4476 layer_tree_host()
4477 ->contents_texture_manager()
4478 ->ExternalPriorityCutoff());
4479 PostSetNeedsCommitToMainThread();
4480 break;
4481 case 2:
4482 // The values should remain the same until the commit after the policy
4483 // is changed.
4484 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4485 layer_tree_host()
4486 ->contents_texture_manager()
4487 ->MaxMemoryLimitBytes());
4488 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4489 layer_tree_host()
4490 ->contents_texture_manager()
4491 ->ExternalPriorityCutoff());
4492 break;
4493 case 3:
4494 // Verify values were correctly passed.
4495 EXPECT_EQ(16u * 1024u * 1024u,
4496 layer_tree_host()
4497 ->contents_texture_manager()
4498 ->MaxMemoryLimitBytes());
4499 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4500 layer_tree_host()
4501 ->contents_texture_manager()
4502 ->ExternalPriorityCutoff());
4503 EndTest();
4504 break;
4505 case 4:
4506 // Make sure no extra commits happen.
4507 NOTREACHED();
4508 break;
4512 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4513 switch (num_commits_) {
4514 case 1:
4515 break;
4516 case 2:
4517 // This will trigger a commit because the priority cutoff has changed.
4518 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4519 16u * 1024u * 1024u,
4520 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4521 1000));
4522 break;
4523 case 3:
4524 // This will not trigger a commit because the priority cutoff has not
4525 // changed, and there is already enough memory for all allocations.
4526 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4527 32u * 1024u * 1024u,
4528 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4529 1000));
4530 break;
4531 case 4:
4532 NOTREACHED();
4533 break;
4537 void AfterTest() override {}
4539 private:
4540 int num_commits_;
4543 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4545 } // namespace
4547 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4548 : public LayerTreeHostTest {
4549 protected:
4550 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4551 : first_output_surface_memory_limit_(4321234),
4552 second_output_surface_memory_limit_(1234321) {}
4554 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4555 if (!first_context_provider_.get()) {
4556 first_context_provider_ = TestContextProvider::Create();
4557 } else {
4558 EXPECT_FALSE(second_context_provider_.get());
4559 second_context_provider_ = TestContextProvider::Create();
4562 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4563 ? second_context_provider_
4564 : first_context_provider_);
4565 scoped_ptr<FakeOutputSurface> output_surface;
4566 if (delegating_renderer())
4567 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4568 else
4569 output_surface = FakeOutputSurface::Create3d(provider);
4570 output_surface->SetMemoryPolicyToSetAtBind(
4571 make_scoped_ptr(new ManagedMemoryPolicy(
4572 second_context_provider_.get() ? second_output_surface_memory_limit_
4573 : first_output_surface_memory_limit_,
4574 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4575 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4576 return output_surface.Pass();
4579 void SetupTree() override {
4580 if (layer_tree_host()->settings().impl_side_painting)
4581 root_ = FakePictureLayer::Create(&client_);
4582 else
4583 root_ = FakeContentLayer::Create(&client_);
4584 root_->SetBounds(gfx::Size(20, 20));
4585 layer_tree_host()->SetRootLayer(root_);
4586 LayerTreeHostTest::SetupTree();
4589 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4591 void DidCommitAndDrawFrame() override {
4592 // Lost context sometimes takes two frames to recreate. The third frame
4593 // is sometimes aborted, so wait until the fourth frame to verify that
4594 // the memory has been set, and the fifth frame to end the test.
4595 if (layer_tree_host()->source_frame_number() < 5) {
4596 layer_tree_host()->SetNeedsCommit();
4597 } else if (layer_tree_host()->source_frame_number() == 5) {
4598 EndTest();
4602 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
4603 switch (impl->active_tree()->source_frame_number()) {
4604 case 1:
4605 EXPECT_EQ(first_output_surface_memory_limit_,
4606 impl->memory_allocation_limit_bytes());
4607 // Lose the output surface.
4608 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4609 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4610 break;
4611 case 4:
4612 EXPECT_EQ(second_output_surface_memory_limit_,
4613 impl->memory_allocation_limit_bytes());
4614 break;
4618 void AfterTest() override {}
4620 scoped_refptr<TestContextProvider> first_context_provider_;
4621 scoped_refptr<TestContextProvider> second_context_provider_;
4622 size_t first_output_surface_memory_limit_;
4623 size_t second_output_surface_memory_limit_;
4624 FakeContentLayerClient client_;
4625 scoped_refptr<Layer> root_;
4628 SINGLE_AND_MULTI_THREAD_TEST_F(
4629 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4631 struct TestSwapPromiseResult {
4632 TestSwapPromiseResult()
4633 : did_swap_called(false),
4634 did_not_swap_called(false),
4635 dtor_called(false),
4636 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4638 bool did_swap_called;
4639 bool did_not_swap_called;
4640 bool dtor_called;
4641 SwapPromise::DidNotSwapReason reason;
4642 base::Lock lock;
4645 class TestSwapPromise : public SwapPromise {
4646 public:
4647 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4649 ~TestSwapPromise() override {
4650 base::AutoLock lock(result_->lock);
4651 result_->dtor_called = true;
4654 void DidSwap(CompositorFrameMetadata* metadata) override {
4655 base::AutoLock lock(result_->lock);
4656 EXPECT_FALSE(result_->did_swap_called);
4657 EXPECT_FALSE(result_->did_not_swap_called);
4658 result_->did_swap_called = true;
4661 void DidNotSwap(DidNotSwapReason reason) override {
4662 base::AutoLock lock(result_->lock);
4663 EXPECT_FALSE(result_->did_swap_called);
4664 EXPECT_FALSE(result_->did_not_swap_called);
4665 result_->did_not_swap_called = true;
4666 result_->reason = reason;
4669 int64 TraceId() const override { return 0; }
4671 private:
4672 // Not owned.
4673 TestSwapPromiseResult* result_;
4676 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4677 protected:
4678 LayerTreeHostTestBreakSwapPromise()
4679 : commit_count_(0), commit_complete_count_(0) {}
4681 void WillBeginMainFrame() override {
4682 ASSERT_LE(commit_count_, 2);
4683 scoped_ptr<SwapPromise> swap_promise(
4684 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4685 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4688 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4690 void DidCommit() override {
4691 commit_count_++;
4692 if (commit_count_ == 2) {
4693 // This commit will finish.
4694 layer_tree_host()->SetNeedsCommit();
4698 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4699 commit_complete_count_++;
4700 if (commit_complete_count_ == 1) {
4701 // This commit will be aborted because no actual update.
4702 PostSetNeedsUpdateLayersToMainThread();
4703 } else {
4704 EndTest();
4708 void AfterTest() override {
4709 // 3 commits are scheduled. 2 completes. 1 is aborted.
4710 EXPECT_EQ(commit_count_, 3);
4711 EXPECT_EQ(commit_complete_count_, 2);
4714 // The first commit completes and causes swap buffer which finishes
4715 // the promise.
4716 base::AutoLock lock(swap_promise_result_[0].lock);
4717 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4718 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4719 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4723 // The second commit is aborted since it contains no updates.
4724 base::AutoLock lock(swap_promise_result_[1].lock);
4725 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4726 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4727 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
4728 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4732 // The last commit completes but it does not cause swap buffer because
4733 // there is no damage in the frame data.
4734 base::AutoLock lock(swap_promise_result_[2].lock);
4735 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4736 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4737 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4738 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4742 int commit_count_;
4743 int commit_complete_count_;
4744 TestSwapPromiseResult swap_promise_result_[3];
4747 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4749 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
4750 public:
4751 LayerTreeHostTestKeepSwapPromise() {}
4753 void BeginTest() override {
4754 layer_ = SolidColorLayer::Create();
4755 layer_->SetIsDrawable(true);
4756 layer_->SetBounds(gfx::Size(10, 10));
4757 layer_tree_host()->SetRootLayer(layer_);
4758 gfx::Size bounds(100, 100);
4759 layer_tree_host()->SetViewportSize(bounds);
4760 PostSetNeedsCommitToMainThread();
4763 void DidCommit() override {
4764 MainThreadTaskRunner()->PostTask(
4765 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
4766 base::Unretained(this)));
4769 void ChangeFrame() {
4770 switch (layer_tree_host()->source_frame_number()) {
4771 case 1:
4772 layer_->SetBounds(gfx::Size(10, 11));
4773 layer_tree_host()->QueueSwapPromise(
4774 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
4775 break;
4776 case 2:
4777 break;
4778 default:
4779 NOTREACHED();
4780 break;
4784 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
4785 EXPECT_TRUE(result);
4786 if (host_impl->active_tree()->source_frame_number() >= 1) {
4787 // The commit changes layers so it should cause a swap.
4788 base::AutoLock lock(swap_promise_result_.lock);
4789 EXPECT_TRUE(swap_promise_result_.did_swap_called);
4790 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
4791 EXPECT_TRUE(swap_promise_result_.dtor_called);
4792 EndTest();
4796 void AfterTest() override {}
4798 private:
4799 scoped_refptr<Layer> layer_;
4800 TestSwapPromiseResult swap_promise_result_;
4803 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
4805 class LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit
4806 : public LayerTreeHostTest {
4807 protected:
4808 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4810 void DidCommit() override {
4811 layer_tree_host()->SetDeferCommits(true);
4812 layer_tree_host()->SetNeedsCommit();
4815 void DidDeferCommit() override {
4816 layer_tree_host()->SetVisible(false);
4817 scoped_ptr<SwapPromise> swap_promise(
4818 new TestSwapPromise(&swap_promise_result_));
4819 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4820 layer_tree_host()->SetDeferCommits(false);
4823 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4824 CommitEarlyOutReason reason) override {
4825 EndTest();
4828 void AfterTest() override {
4830 base::AutoLock lock(swap_promise_result_.lock);
4831 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4832 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4833 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4834 EXPECT_TRUE(swap_promise_result_.dtor_called);
4838 TestSwapPromiseResult swap_promise_result_;
4841 SINGLE_AND_MULTI_THREAD_TEST_F(
4842 LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit);
4844 class LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit
4845 : public LayerTreeHostTest {
4846 protected:
4847 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4849 void DidCommit() override {
4850 if (TestEnded())
4851 return;
4852 layer_tree_host()->SetDeferCommits(true);
4853 layer_tree_host()->SetNeedsCommit();
4856 void DidDeferCommit() override {
4857 layer_tree_host()->DidLoseOutputSurface();
4858 scoped_ptr<SwapPromise> swap_promise(
4859 new TestSwapPromise(&swap_promise_result_));
4860 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4861 layer_tree_host()->SetDeferCommits(false);
4864 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4865 CommitEarlyOutReason reason) override {
4866 // This is needed so that the impl-thread state matches main-thread state.
4867 host_impl->DidLoseOutputSurface();
4868 EndTest();
4871 void AfterTest() override {
4873 base::AutoLock lock(swap_promise_result_.lock);
4874 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4875 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4876 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4877 EXPECT_TRUE(swap_promise_result_.dtor_called);
4881 TestSwapPromiseResult swap_promise_result_;
4884 SINGLE_AND_MULTI_THREAD_TEST_F(
4885 LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit);
4887 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
4888 public:
4889 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
4890 LayerTreeHostImpl* layer_tree_host_impl,
4891 int* set_needs_commit_count,
4892 int* set_needs_redraw_count)
4893 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
4894 set_needs_commit_count_(set_needs_commit_count) {}
4896 ~SimpleSwapPromiseMonitor() override {}
4898 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
4900 void OnSetNeedsRedrawOnImpl() override {
4901 ADD_FAILURE() << "Should not get called on main thread.";
4904 void OnForwardScrollUpdateToMainThreadOnImpl() override {
4905 ADD_FAILURE() << "Should not get called on main thread.";
4908 private:
4909 int* set_needs_commit_count_;
4912 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
4913 public:
4914 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4916 void WillBeginMainFrame() override {
4917 if (TestEnded())
4918 return;
4920 int set_needs_commit_count = 0;
4921 int set_needs_redraw_count = 0;
4924 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4925 new SimpleSwapPromiseMonitor(layer_tree_host(),
4926 NULL,
4927 &set_needs_commit_count,
4928 &set_needs_redraw_count));
4929 layer_tree_host()->SetNeedsCommit();
4930 EXPECT_EQ(1, set_needs_commit_count);
4931 EXPECT_EQ(0, set_needs_redraw_count);
4934 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
4935 // monitored.
4936 layer_tree_host()->SetNeedsCommit();
4937 EXPECT_EQ(1, set_needs_commit_count);
4938 EXPECT_EQ(0, set_needs_redraw_count);
4941 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4942 new SimpleSwapPromiseMonitor(layer_tree_host(),
4943 NULL,
4944 &set_needs_commit_count,
4945 &set_needs_redraw_count));
4946 layer_tree_host()->SetNeedsUpdateLayers();
4947 EXPECT_EQ(2, set_needs_commit_count);
4948 EXPECT_EQ(0, set_needs_redraw_count);
4952 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4953 new SimpleSwapPromiseMonitor(layer_tree_host(),
4954 NULL,
4955 &set_needs_commit_count,
4956 &set_needs_redraw_count));
4957 layer_tree_host()->SetNeedsAnimate();
4958 EXPECT_EQ(3, set_needs_commit_count);
4959 EXPECT_EQ(0, set_needs_redraw_count);
4962 EndTest();
4965 void AfterTest() override {}
4968 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
4970 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
4971 : public LayerTreeHostTest {
4972 protected:
4973 void InitializeSettings(LayerTreeSettings* settings) override {
4974 settings->impl_side_painting = true;
4977 void SetupTree() override {
4978 LayerTreeHostTest::SetupTree();
4979 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
4982 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4984 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4985 host_impl->EvictAllUIResources();
4986 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
4987 // mode. Active tree should require high-res to draw after entering this
4988 // mode to ensure that high-res tiles are also required for a pending tree
4989 // to be activated.
4990 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
4993 void DidCommit() override {
4994 int frame = layer_tree_host()->source_frame_number();
4995 switch (frame) {
4996 case 1:
4997 PostSetNeedsCommitToMainThread();
4998 break;
4999 case 2:
5000 ui_resource_ = nullptr;
5001 EndTest();
5002 break;
5006 void AfterTest() override {}
5008 FakeContentLayerClient client_;
5009 scoped_ptr<FakeScopedUIResource> ui_resource_;
5012 // This test is flaky, see http://crbug.com/386199
5013 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
5015 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
5016 protected:
5017 void InitializeSettings(LayerTreeSettings* settings) override {
5018 settings->impl_side_painting = true;
5020 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5021 EXPECT_FALSE(settings->gpu_rasterization_forced);
5024 void SetupTree() override {
5025 LayerTreeHostTest::SetupTree();
5027 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5028 layer->SetBounds(gfx::Size(10, 10));
5029 layer->SetIsDrawable(true);
5030 layer_tree_host()->root_layer()->AddChild(layer);
5033 void BeginTest() override {
5034 Layer* root = layer_tree_host()->root_layer();
5035 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5036 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5038 // Verify default values.
5039 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5040 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5041 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5042 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5043 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5045 // Setting gpu rasterization trigger does not enable gpu rasterization.
5046 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5047 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5048 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5050 PostSetNeedsCommitToMainThread();
5053 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5054 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5055 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5058 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5059 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5060 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5061 EndTest();
5064 void AfterTest() override {}
5066 FakeContentLayerClient layer_client_;
5069 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
5071 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
5072 protected:
5073 void InitializeSettings(LayerTreeSettings* settings) override {
5074 settings->impl_side_painting = true;
5076 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5077 settings->gpu_rasterization_enabled = true;
5080 void SetupTree() override {
5081 LayerTreeHostTest::SetupTree();
5083 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5084 layer->SetBounds(gfx::Size(10, 10));
5085 layer->SetIsDrawable(true);
5086 layer_tree_host()->root_layer()->AddChild(layer);
5089 void BeginTest() override {
5090 Layer* root = layer_tree_host()->root_layer();
5091 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5092 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5094 // Verify default values.
5095 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5096 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5097 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5098 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5099 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5101 // Gpu rasterization trigger is relevant.
5102 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5103 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5104 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5106 // Content-based veto is relevant as well.
5107 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5108 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5109 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5110 // Veto will take effect when layers are updated.
5111 // The results will be verified after commit is completed below.
5112 // Since we are manually marking picture pile as unsuitable,
5113 // make sure that the layer gets a chance to update.
5114 layer->SetNeedsDisplay();
5115 PostSetNeedsCommitToMainThread();
5118 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5119 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5120 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5123 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5124 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5125 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5126 EndTest();
5129 void AfterTest() override {}
5131 FakeContentLayerClient layer_client_;
5134 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
5136 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
5137 protected:
5138 void InitializeSettings(LayerTreeSettings* settings) override {
5139 ASSERT_TRUE(settings->impl_side_painting);
5141 EXPECT_FALSE(settings->gpu_rasterization_forced);
5142 settings->gpu_rasterization_forced = true;
5145 void SetupTree() override {
5146 LayerTreeHostTest::SetupTree();
5148 scoped_refptr<FakePictureLayer> layer =
5149 FakePictureLayer::Create(&layer_client_);
5150 layer->SetBounds(gfx::Size(10, 10));
5151 layer->SetIsDrawable(true);
5152 layer_tree_host()->root_layer()->AddChild(layer);
5155 void BeginTest() override {
5156 Layer* root = layer_tree_host()->root_layer();
5157 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5158 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5160 // Verify default values.
5161 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5162 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5163 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5164 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5166 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
5167 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5168 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5169 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5170 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5172 // Content-based veto is irrelevant as well.
5173 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5174 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5175 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5176 // Veto will take effect when layers are updated.
5177 // The results will be verified after commit is completed below.
5178 // Since we are manually marking picture pile as unsuitable,
5179 // make sure that the layer gets a chance to update.
5180 layer->SetNeedsDisplay();
5181 PostSetNeedsCommitToMainThread();
5184 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5185 EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
5186 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5189 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5190 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
5191 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5192 EndTest();
5195 void AfterTest() override {}
5197 FakeContentLayerClient layer_client_;
5200 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
5202 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
5203 public:
5204 LayerTreeHostTestContinuousPainting()
5205 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
5207 protected:
5208 enum { kExpectedNumCommits = 10 };
5210 void SetupTree() override {
5211 scoped_refptr<Layer> root_layer = Layer::Create();
5212 root_layer->SetBounds(bounds_);
5213 root_layer->CreateRenderSurface();
5215 if (layer_tree_host()->settings().impl_side_painting) {
5216 picture_layer_ = FakePictureLayer::Create(&client_);
5217 child_layer_ = picture_layer_.get();
5218 } else {
5219 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
5220 child_layer_ = content_layer_.get();
5222 child_layer_->SetBounds(bounds_);
5223 child_layer_->SetIsDrawable(true);
5224 root_layer->AddChild(child_layer_);
5226 layer_tree_host()->SetRootLayer(root_layer);
5227 layer_tree_host()->SetViewportSize(bounds_);
5228 LayerTreeHostTest::SetupTree();
5231 void BeginTest() override {
5232 MainThreadTaskRunner()->PostTask(
5233 FROM_HERE,
5234 base::Bind(
5235 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
5236 base::Unretained(this)));
5237 // Wait 50x longer than expected.
5238 double milliseconds_per_frame =
5239 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
5240 MainThreadTaskRunner()->PostDelayedTask(
5241 FROM_HERE,
5242 base::Bind(
5243 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
5244 base::Unretained(this)),
5245 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
5246 milliseconds_per_frame));
5249 void BeginMainFrame(const BeginFrameArgs& args) override {
5250 child_layer_->SetNeedsDisplay();
5253 void AfterTest() override {
5254 EXPECT_LE(kExpectedNumCommits, num_commits_);
5255 EXPECT_LE(kExpectedNumCommits, num_draws_);
5256 int update_count = content_layer_.get()
5257 ? content_layer_->PaintContentsCount()
5258 : picture_layer_->update_count();
5259 EXPECT_LE(kExpectedNumCommits, update_count);
5262 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5263 if (++num_draws_ == kExpectedNumCommits)
5264 EndTest();
5267 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5268 ++num_commits_;
5271 private:
5272 void EnableContinuousPainting() {
5273 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5274 debug_state.continuous_painting = true;
5275 layer_tree_host()->SetDebugState(debug_state);
5278 void DisableContinuousPainting() {
5279 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5280 debug_state.continuous_painting = false;
5281 layer_tree_host()->SetDebugState(debug_state);
5282 EndTest();
5285 int num_commits_;
5286 int num_draws_;
5287 const gfx::Size bounds_;
5288 FakeContentLayerClient client_;
5289 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5290 scoped_refptr<FakePictureLayer> picture_layer_;
5291 Layer* child_layer_;
5294 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5296 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
5297 public:
5298 LayerTreeHostTestSendBeginFramesToChildren()
5299 : begin_frame_sent_to_children_(false) {
5302 void InitializeSettings(LayerTreeSettings* settings) override {
5303 settings->forward_begin_frames_to_children = true;
5306 void BeginTest() override {
5307 // Kick off the test with a commit.
5308 PostSetNeedsCommitToMainThread();
5311 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5312 begin_frame_sent_to_children_ = true;
5313 EndTest();
5316 void DidBeginMainFrame() override {
5317 // Children requested BeginFrames.
5318 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5321 void AfterTest() override {
5322 // Ensure that BeginFrame message is sent to children during parent
5323 // scheduler handles its BeginFrame.
5324 EXPECT_TRUE(begin_frame_sent_to_children_);
5327 private:
5328 bool begin_frame_sent_to_children_;
5331 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
5333 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
5334 : public LayerTreeHostTest {
5335 public:
5336 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
5337 : begin_frame_sent_to_children_(false) {
5340 void InitializeSettings(LayerTreeSettings* settings) override {
5341 settings->use_external_begin_frame_source = true;
5342 settings->forward_begin_frames_to_children = true;
5345 void BeginTest() override {
5346 // Kick off the test with a commit.
5347 PostSetNeedsCommitToMainThread();
5350 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5351 begin_frame_sent_to_children_ = true;
5352 EndTest();
5355 void DidBeginMainFrame() override {
5356 // Children requested BeginFrames.
5357 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5360 void AfterTest() override {
5361 // Ensure that BeginFrame message is sent to children during parent
5362 // scheduler handles its BeginFrame.
5363 EXPECT_TRUE(begin_frame_sent_to_children_);
5366 private:
5367 bool begin_frame_sent_to_children_;
5370 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
5372 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5373 public:
5374 LayerTreeHostTestActivateOnInvisible()
5375 : activation_count_(0), visible_(true) {}
5377 void InitializeSettings(LayerTreeSettings* settings) override {
5378 settings->impl_side_painting = true;
5381 void BeginTest() override {
5382 // Kick off the test with a commit.
5383 PostSetNeedsCommitToMainThread();
5386 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5387 // Make sure we don't activate using the notify signal from tile manager.
5388 host_impl->BlockNotifyReadyToActivateForTesting(true);
5391 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5393 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5394 bool visible) override {
5395 visible_ = visible;
5397 // Once invisible, we can go visible again.
5398 if (!visible) {
5399 PostSetVisibleToMainThread(true);
5400 } else {
5401 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5402 EndTest();
5406 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5407 ++activation_count_;
5408 EXPECT_FALSE(visible_);
5411 void AfterTest() override {
5412 // Ensure we activated even though the signal was blocked.
5413 EXPECT_EQ(1, activation_count_);
5414 EXPECT_TRUE(visible_);
5417 private:
5418 int activation_count_;
5419 bool visible_;
5421 FakeContentLayerClient client_;
5422 scoped_refptr<FakePictureLayer> picture_layer_;
5425 // TODO(vmpstr): Enable with single thread impl-side painting.
5426 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5428 // Do a synchronous composite and assert that the swap promise succeeds.
5429 class LayerTreeHostTestSynchronousCompositeSwapPromise
5430 : public LayerTreeHostTest {
5431 public:
5432 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5434 void InitializeSettings(LayerTreeSettings* settings) override {
5435 settings->single_thread_proxy_scheduler = false;
5438 void BeginTest() override {
5439 // Successful composite.
5440 scoped_ptr<SwapPromise> swap_promise0(
5441 new TestSwapPromise(&swap_promise_result_[0]));
5442 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5443 layer_tree_host()->Composite(gfx::FrameTime::Now());
5445 // Fail to swap (no damage).
5446 scoped_ptr<SwapPromise> swap_promise1(
5447 new TestSwapPromise(&swap_promise_result_[1]));
5448 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5449 layer_tree_host()->SetNeedsCommit();
5450 layer_tree_host()->Composite(gfx::FrameTime::Now());
5452 // Fail to draw (not visible).
5453 scoped_ptr<SwapPromise> swap_promise2(
5454 new TestSwapPromise(&swap_promise_result_[2]));
5455 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5456 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5457 layer_tree_host()->SetVisible(false);
5458 layer_tree_host()->Composite(gfx::FrameTime::Now());
5460 EndTest();
5463 void DidCommit() override {
5464 commit_count_++;
5465 ASSERT_LE(commit_count_, 3);
5468 void AfterTest() override {
5469 EXPECT_EQ(3, commit_count_);
5471 // Initial swap promise should have succeded.
5473 base::AutoLock lock(swap_promise_result_[0].lock);
5474 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5475 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5476 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5479 // Second swap promise fails to swap.
5481 base::AutoLock lock(swap_promise_result_[1].lock);
5482 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5483 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5484 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5485 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5488 // Third swap promises also fails to swap (and draw).
5490 base::AutoLock lock(swap_promise_result_[2].lock);
5491 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5492 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5493 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5494 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5498 int commit_count_;
5499 TestSwapPromiseResult swap_promise_result_[3];
5502 // Impl-side painting is not supported for synchronous compositing.
5503 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
5505 // Make sure page scale and top control deltas are applied to the client even
5506 // when the LayerTreeHost doesn't have a root layer.
5507 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
5508 : public LayerTreeHostTest {
5509 public:
5510 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
5511 : deltas_sent_to_client_(false) {}
5513 void BeginTest() override {
5514 layer_tree_host()->SetRootLayer(nullptr);
5515 info_.page_scale_delta = 3.14f;
5516 info_.top_controls_delta = 2.73f;
5518 PostSetNeedsCommitToMainThread();
5521 void BeginMainFrame(const BeginFrameArgs& args) override {
5522 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
5524 layer_tree_host()->ApplyScrollAndScale(&info_);
5525 EndTest();
5528 void ApplyViewportDeltas(const gfx::Vector2d& inner,
5529 const gfx::Vector2d& outer,
5530 const gfx::Vector2dF& elastic_overscroll_delta,
5531 float scale_delta,
5532 float top_controls_delta) override {
5533 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5534 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5535 deltas_sent_to_client_ = true;
5538 void ApplyViewportDeltas(
5539 const gfx::Vector2d& scroll,
5540 float scale_delta,
5541 float top_controls_delta) override {
5542 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5543 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5544 deltas_sent_to_client_ = true;
5547 void AfterTest() override {
5548 EXPECT_TRUE(deltas_sent_to_client_);
5551 ScrollAndScaleSet info_;
5552 bool deltas_sent_to_client_;
5555 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5557 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
5558 protected:
5559 LayerTreeHostTestCrispUpAfterPinchEnds()
5560 : playback_allowed_event_(true, true) {}
5562 void SetupTree() override {
5563 frame_ = 1;
5564 posted_ = false;
5565 client_.set_fill_with_nonsolid_color(true);
5567 scoped_refptr<Layer> root = Layer::Create();
5568 root->SetBounds(gfx::Size(500, 500));
5570 scoped_refptr<Layer> pinch = Layer::Create();
5571 pinch->SetBounds(gfx::Size(500, 500));
5572 pinch->SetScrollClipLayerId(root->id());
5573 pinch->SetIsContainerForFixedPositionLayers(true);
5574 root->AddChild(pinch);
5576 scoped_ptr<FakePicturePile> pile(new FakePicturePile);
5577 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5578 scoped_refptr<FakePictureLayer> layer =
5579 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5580 layer->SetBounds(gfx::Size(500, 500));
5581 layer->SetContentsOpaque(true);
5582 // Avoid LCD text on the layer so we don't cause extra commits when we
5583 // pinch.
5584 layer->disable_lcd_text();
5585 pinch->AddChild(layer);
5587 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5588 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5589 layer_tree_host()->SetRootLayer(root);
5590 LayerTreeHostTest::SetupTree();
5593 // Returns the delta scale of all quads in the frame's root pass from their
5594 // ideal, or 0 if they are not all the same.
5595 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5596 if (frame_data->has_no_damage)
5597 return 0.f;
5598 float frame_scale = 0.f;
5599 RenderPass* root_pass = frame_data->render_passes.back();
5600 for (const auto& draw_quad : root_pass->quad_list) {
5601 // Checkerboards mean an incomplete frame.
5602 if (draw_quad->material != DrawQuad::TILED_CONTENT)
5603 return 0.f;
5604 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5605 float quad_scale =
5606 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5607 float transform_scale =
5608 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5609 float scale = quad_scale / transform_scale;
5610 if (frame_scale != 0.f && frame_scale != scale)
5611 return 0.f;
5612 frame_scale = scale;
5614 return frame_scale;
5617 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5619 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5620 LayerTreeHostImpl::FrameData* frame_data,
5621 DrawResult draw_result) override {
5622 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5623 switch (frame_) {
5624 case 1:
5625 // Drew at page scale 1 before any pinching.
5626 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5627 EXPECT_EQ(1.f, quad_scale_delta);
5628 PostNextAfterDraw(host_impl);
5629 break;
5630 case 2:
5631 if (quad_scale_delta != 1.f)
5632 break;
5633 // Drew at page scale 1.5 after pinching in.
5634 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5635 EXPECT_EQ(1.f, quad_scale_delta);
5636 PostNextAfterDraw(host_impl);
5637 break;
5638 case 3:
5639 // By pinching out, we will create a new tiling and raster it. This may
5640 // cause some additional draws, though we should still be drawing with
5641 // the old 1.5 tiling.
5642 if (frame_data->has_no_damage)
5643 break;
5644 // Drew at page scale 1 with the 1.5 tiling while pinching out.
5645 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5646 EXPECT_EQ(1.5f, quad_scale_delta);
5647 // We don't PostNextAfterDraw here, instead we wait for the new tiling
5648 // to finish rastering so we don't get any noise in further steps.
5649 break;
5650 case 4:
5651 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
5652 // while waiting for texture uploads to complete.
5653 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5654 // This frame will not have any damage, since it's actually the same as
5655 // the last frame, and should contain no incomplete tiles. We just want
5656 // to make sure we drew here at least once after the pinch ended to be
5657 // sure that drawing after pinch doesn't leave us at the wrong scale
5658 EXPECT_TRUE(frame_data->has_no_damage);
5659 PostNextAfterDraw(host_impl);
5660 break;
5661 case 5:
5662 if (quad_scale_delta != 1.f)
5663 break;
5664 // Drew at scale 1 after texture uploads are done.
5665 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5666 EXPECT_EQ(1.f, quad_scale_delta);
5667 EndTest();
5668 break;
5670 return draw_result;
5673 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
5674 if (posted_)
5675 return;
5676 posted_ = true;
5677 ImplThreadTaskRunner()->PostDelayedTask(
5678 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
5679 base::Unretained(this), host_impl),
5680 // Use a delay to allow raster/upload to happen in between frames. This
5681 // should cause flakiness if we fail to block raster/upload when
5682 // desired.
5683 base::TimeDelta::FromMilliseconds(16 * 4));
5686 void Next(LayerTreeHostImpl* host_impl) {
5687 ++frame_;
5688 posted_ = false;
5689 switch (frame_) {
5690 case 2:
5691 // Pinch zoom in.
5692 host_impl->PinchGestureBegin();
5693 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
5694 host_impl->PinchGestureEnd();
5695 break;
5696 case 3:
5697 // Pinch zoom back to 1.f but don't end it.
5698 host_impl->PinchGestureBegin();
5699 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
5700 break;
5701 case 4:
5702 // End the pinch, but delay tile production.
5703 playback_allowed_event_.Reset();
5704 host_impl->PinchGestureEnd();
5705 break;
5706 case 5:
5707 // Let tiles complete.
5708 playback_allowed_event_.Signal();
5709 break;
5713 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5714 const Tile* tile) override {
5715 if (frame_ == 3) {
5716 // On frame 3, we will have a lower res tile complete for the pinch-out
5717 // gesture even though it's not displayed. We wait for it here to prevent
5718 // flakiness.
5719 EXPECT_EQ(0.75f, tile->contents_scale());
5720 PostNextAfterDraw(host_impl);
5722 // On frame_ == 4, we are preventing texture uploads from completing,
5723 // so this verifies they are not completing before frame_ == 5.
5724 // Flaky failures here indicate we're failing to prevent uploads from
5725 // completing.
5726 EXPECT_NE(4, frame_) << tile->contents_scale();
5729 void AfterTest() override {}
5731 FakeContentLayerClient client_;
5732 int frame_;
5733 bool posted_;
5734 base::WaitableEvent playback_allowed_event_;
5737 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
5739 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
5740 : public LayerTreeHostTestCrispUpAfterPinchEnds {
5741 protected:
5742 void InitializeSettings(LayerTreeSettings* settings) override {
5743 settings->use_one_copy = true;
5746 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
5747 scoped_ptr<TestWebGraphicsContext3D> context3d =
5748 TestWebGraphicsContext3D::Create();
5749 context3d->set_support_image(true);
5750 context3d->set_support_sync_query(true);
5751 #if defined(OS_MACOSX)
5752 context3d->set_support_texture_rectangle(true);
5753 #endif
5755 if (delegating_renderer())
5756 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
5757 else
5758 return FakeOutputSurface::Create3d(context3d.Pass());
5762 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
5764 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
5765 protected:
5766 RasterizeWithGpuRasterizationCreatesResources() {}
5768 void InitializeSettings(LayerTreeSettings* settings) override {
5769 settings->impl_side_painting = true;
5770 settings->gpu_rasterization_forced = true;
5773 void SetupTree() override {
5774 client_.set_fill_with_nonsolid_color(true);
5776 scoped_refptr<Layer> root = Layer::Create();
5777 root->SetBounds(gfx::Size(500, 500));
5779 scoped_ptr<FakePicturePile> pile(new FakePicturePile);
5780 scoped_refptr<FakePictureLayer> layer =
5781 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5782 layer->SetBounds(gfx::Size(500, 500));
5783 layer->SetContentsOpaque(true);
5784 root->AddChild(layer);
5786 layer_tree_host()->SetRootLayer(root);
5787 LayerTreeHostTest::SetupTree();
5790 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5792 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5793 LayerTreeHostImpl::FrameData* frame_data,
5794 DrawResult draw_result) override {
5795 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
5796 EndTest();
5797 return draw_result;
5799 void AfterTest() override {}
5801 FakeContentLayerClient client_;
5804 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
5806 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
5807 : public LayerTreeHostTest {
5808 protected:
5809 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
5810 : playback_allowed_event_(true, true) {}
5812 void InitializeSettings(LayerTreeSettings* settings) override {
5813 settings->impl_side_painting = true;
5816 void SetupTree() override {
5817 step_ = 1;
5818 continuous_draws_ = 0;
5819 client_.set_fill_with_nonsolid_color(true);
5821 scoped_refptr<Layer> root = Layer::Create();
5822 root->SetBounds(gfx::Size(500, 500));
5824 scoped_refptr<Layer> pinch = Layer::Create();
5825 pinch->SetBounds(gfx::Size(500, 500));
5826 pinch->SetScrollClipLayerId(root->id());
5827 pinch->SetIsContainerForFixedPositionLayers(true);
5828 root->AddChild(pinch);
5830 scoped_ptr<FakePicturePile> pile(new FakePicturePile);
5831 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5832 scoped_refptr<FakePictureLayer> layer =
5833 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5834 layer->SetBounds(gfx::Size(500, 500));
5835 layer->SetContentsOpaque(true);
5836 // Avoid LCD text on the layer so we don't cause extra commits when we
5837 // pinch.
5838 layer->disable_lcd_text();
5839 pinch->AddChild(layer);
5841 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5842 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5843 layer_tree_host()->SetRootLayer(root);
5844 LayerTreeHostTest::SetupTree();
5847 // Returns the delta scale of all quads in the frame's root pass from their
5848 // ideal, or 0 if they are not all the same.
5849 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5850 if (frame_data->has_no_damage)
5851 return 0.f;
5852 float frame_scale = 0.f;
5853 RenderPass* root_pass = frame_data->render_passes.back();
5854 for (const auto& draw_quad : root_pass->quad_list) {
5855 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5856 float quad_scale =
5857 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5858 float transform_scale =
5859 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5860 float scale = quad_scale / transform_scale;
5861 if (frame_scale != 0.f && frame_scale != scale)
5862 return 0.f;
5863 frame_scale = scale;
5865 return frame_scale;
5868 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5870 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5871 LayerTreeHostImpl::FrameData* frame_data,
5872 DrawResult draw_result) override {
5873 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5874 switch (step_) {
5875 case 1:
5876 // Drew at scale 1 before any pinching.
5877 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5878 EXPECT_EQ(1.f, quad_scale_delta);
5879 break;
5880 case 2:
5881 if (quad_scale_delta != 1.f / 1.5f)
5882 break;
5883 // Drew at scale 1 still though the ideal is 1.5.
5884 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5885 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
5886 break;
5887 case 3:
5888 // Continuous draws are attempted.
5889 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5890 if (!frame_data->has_no_damage)
5891 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
5892 break;
5893 case 4:
5894 if (quad_scale_delta != 1.f)
5895 break;
5896 // Drew at scale 1.5 when all the tiles completed.
5897 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5898 EXPECT_EQ(1.f, quad_scale_delta);
5899 break;
5900 case 5:
5901 // TODO(danakj): We get more draws before the NotifyReadyToDraw
5902 // because it is asynchronous from the previous draw and happens late.
5903 break;
5904 case 6:
5905 // NotifyReadyToDraw happened. If we were already inside a frame, we may
5906 // try to draw once more.
5907 break;
5908 case 7:
5909 NOTREACHED() << "No draws should happen once we have a complete frame.";
5910 break;
5912 return draw_result;
5915 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
5916 switch (step_) {
5917 case 1:
5918 // Delay tile production.
5919 playback_allowed_event_.Reset();
5920 // Pinch zoom in to cause new tiles to be required.
5921 host_impl->PinchGestureBegin();
5922 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
5923 host_impl->PinchGestureEnd();
5924 ++step_;
5925 break;
5926 case 2:
5927 ++step_;
5928 break;
5929 case 3:
5930 // We should continue to try draw while there are incomplete visible
5931 // tiles.
5932 if (++continuous_draws_ > 5) {
5933 // Allow the tiles to complete.
5934 playback_allowed_event_.Signal();
5935 ++step_;
5937 break;
5938 case 4:
5939 ++step_;
5940 break;
5941 case 5:
5942 // Waiting for NotifyReadyToDraw.
5943 break;
5944 case 6:
5945 // NotifyReadyToDraw happened.
5946 ++step_;
5947 break;
5951 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
5952 if (step_ == 5) {
5953 ++step_;
5954 // NotifyReadyToDraw has happened, we may draw once more, but should not
5955 // get any more draws after that. End the test after a timeout to watch
5956 // for any extraneous draws.
5957 // TODO(brianderson): We could remove this delay and instead wait until
5958 // the BeginFrameSource decides it doesn't need to send frames anymore,
5959 // or test that it already doesn't here.
5960 EndTestAfterDelayMs(16 * 4);
5964 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5965 const Tile* tile) override {
5966 // On step_ == 2, we are preventing texture uploads from completing,
5967 // so this verifies they are not completing before step_ == 3.
5968 // Flaky failures here indicate we're failing to prevent uploads from
5969 // completing.
5970 EXPECT_NE(2, step_);
5973 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
5975 FakeContentLayerClient client_;
5976 int step_;
5977 int continuous_draws_;
5978 base::WaitableEvent playback_allowed_event_;
5981 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
5983 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
5984 public:
5985 LayerTreeHostTestOneActivatePerPrepareTiles()
5986 : notify_ready_to_activate_count_(0u),
5987 scheduled_prepare_tiles_count_(0) {}
5989 void SetupTree() override {
5990 client_.set_fill_with_nonsolid_color(true);
5991 scoped_refptr<FakePictureLayer> root_layer =
5992 FakePictureLayer::Create(&client_);
5993 root_layer->SetBounds(gfx::Size(1500, 1500));
5994 root_layer->SetIsDrawable(true);
5996 layer_tree_host()->SetRootLayer(root_layer);
5997 LayerTreeHostTest::SetupTree();
6000 void BeginTest() override {
6001 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
6002 PostSetNeedsCommitToMainThread();
6005 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
6006 bool success) override {
6007 ASSERT_TRUE(success);
6008 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
6011 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6012 ++notify_ready_to_activate_count_;
6013 EndTestAfterDelayMs(100);
6016 void ScheduledActionPrepareTiles() override {
6017 ++scheduled_prepare_tiles_count_;
6020 void AfterTest() override {
6021 // Expect at most a notification for each scheduled prepare tiles, plus one
6022 // for the initial commit (which doesn't go through scheduled actions).
6023 // The reason this is not an equality is because depending on timing, we
6024 // might get a prepare tiles but not yet get a notification that we're
6025 // ready to activate. The intent of a test is to ensure that we don't
6026 // get more than one notification per prepare tiles, so this is OK.
6027 EXPECT_LE(notify_ready_to_activate_count_,
6028 1u + scheduled_prepare_tiles_count_);
6031 protected:
6032 FakeContentLayerClient client_;
6033 size_t notify_ready_to_activate_count_;
6034 size_t scheduled_prepare_tiles_count_;
6037 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
6039 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
6040 public:
6041 LayerTreeHostTestActivationCausesPrepareTiles()
6042 : scheduled_prepare_tiles_count_(0) {}
6044 void SetupTree() override {
6045 client_.set_fill_with_nonsolid_color(true);
6046 scoped_refptr<FakePictureLayer> root_layer =
6047 FakePictureLayer::Create(&client_);
6048 root_layer->SetBounds(gfx::Size(150, 150));
6049 root_layer->SetIsDrawable(true);
6051 layer_tree_host()->SetRootLayer(root_layer);
6052 LayerTreeHostTest::SetupTree();
6055 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6057 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6058 // Ensure we've already activated.
6059 EXPECT_FALSE(impl->pending_tree());
6061 // After activating, we either need to prepare tiles, or we've already
6062 // called a scheduled prepare tiles. This is done because activation might
6063 // cause us to have to memory available (old active tree is gone), so we
6064 // need to ensure we will get a PrepareTiles call.
6065 if (!impl->prepare_tiles_needed())
6066 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
6067 EndTest();
6070 void ScheduledActionPrepareTiles() override {
6071 ++scheduled_prepare_tiles_count_;
6074 void AfterTest() override {}
6076 protected:
6077 FakeContentLayerClient client_;
6078 int scheduled_prepare_tiles_count_;
6081 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
6083 // This tests an assertion that DidCommit and WillCommit happen in the same
6084 // stack frame with no tasks that run between them. Various embedders of
6085 // cc depend on this logic. ui::Compositor holds a compositor lock between
6086 // these events and the inspector timeline wants begin/end CompositeLayers
6087 // to be properly nested with other begin/end events.
6088 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
6089 : public LayerTreeHostTest {
6090 public:
6091 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
6093 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6095 void WillCommit() override {
6096 MainThreadTaskRunner()->PostTask(
6097 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
6098 EndTestShouldRunAfterDidCommit,
6099 base::Unretained(this)));
6102 void EndTestShouldRunAfterDidCommit() {
6103 EXPECT_TRUE(did_commit_);
6104 EndTest();
6107 void DidCommit() override {
6108 EXPECT_FALSE(did_commit_);
6109 did_commit_ = true;
6112 void AfterTest() override { EXPECT_TRUE(did_commit_); }
6114 private:
6115 bool did_commit_;
6118 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
6120 } // namespace cc