Revert "Added incident report for variations seed signature mismatch."
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob8fb9b8cc142a28f025edb31073e1dcbb110f81f2
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/resources/prioritized_resource.h"
30 #include "cc/resources/prioritized_resource_manager.h"
31 #include "cc/resources/resource_update_queue.h"
32 #include "cc/test/fake_content_layer.h"
33 #include "cc/test/fake_content_layer_client.h"
34 #include "cc/test/fake_content_layer_impl.h"
35 #include "cc/test/fake_layer_tree_host_client.h"
36 #include "cc/test/fake_output_surface.h"
37 #include "cc/test/fake_painted_scrollbar_layer.h"
38 #include "cc/test/fake_picture_layer.h"
39 #include "cc/test/fake_picture_layer_impl.h"
40 #include "cc/test/fake_proxy.h"
41 #include "cc/test/fake_scoped_ui_resource.h"
42 #include "cc/test/fake_video_frame_provider.h"
43 #include "cc/test/geometry_test_utils.h"
44 #include "cc/test/layer_tree_test.h"
45 #include "cc/test/test_shared_bitmap_manager.h"
46 #include "cc/test/test_web_graphics_context_3d.h"
47 #include "cc/trees/layer_tree_host_impl.h"
48 #include "cc/trees/layer_tree_impl.h"
49 #include "cc/trees/single_thread_proxy.h"
50 #include "cc/trees/thread_proxy.h"
51 #include "gpu/GLES2/gl2extchromium.h"
52 #include "skia/ext/refptr.h"
53 #include "testing/gmock/include/gmock/gmock.h"
54 #include "third_party/khronos/GLES2/gl2.h"
55 #include "third_party/khronos/GLES2/gl2ext.h"
56 #include "third_party/skia/include/core/SkPicture.h"
57 #include "ui/gfx/frame_time.h"
58 #include "ui/gfx/point_conversions.h"
59 #include "ui/gfx/size_conversions.h"
60 #include "ui/gfx/vector2d_conversions.h"
62 using testing::_;
63 using testing::AnyNumber;
64 using testing::AtLeast;
65 using testing::Mock;
67 namespace cc {
68 namespace {
70 class LayerTreeHostTest : public LayerTreeTest {};
72 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
73 // draw with frame 0.
74 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
75 public:
76 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
78 void BeginTest() override {
79 PostSetNeedsCommitToMainThread();
80 PostSetNeedsCommitToMainThread();
83 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
84 num_draws_++;
85 if (!impl->active_tree()->source_frame_number())
86 EndTest();
89 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
90 num_commits_++;
93 void AfterTest() override {
94 EXPECT_LE(1, num_commits_);
95 EXPECT_LE(1, num_draws_);
98 private:
99 int num_commits_;
100 int num_draws_;
103 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
105 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
106 // first committed frame draws should lead to another commit.
107 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
108 public:
109 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
111 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
113 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
115 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
116 ++num_commits_;
117 switch (num_commits_) {
118 case 1:
119 PostSetNeedsCommitToMainThread();
120 break;
121 case 2:
122 EndTest();
123 break;
124 default:
125 NOTREACHED();
129 void AfterTest() override {
130 EXPECT_EQ(2, num_commits_);
131 EXPECT_LE(1, num_draws_);
134 private:
135 int num_commits_;
136 int num_draws_;
139 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
141 // Verify that we pass property values in PushPropertiesTo.
142 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
143 protected:
144 void SetupTree() override {
145 scoped_refptr<Layer> root = Layer::Create();
146 root->SetBounds(gfx::Size(10, 10));
147 layer_tree_host()->SetRootLayer(root);
148 LayerTreeHostTest::SetupTree();
151 enum Properties {
152 STARTUP,
153 BOUNDS,
154 HIDE_LAYER_AND_SUBTREE,
155 DRAWS_CONTENT,
156 DONE,
159 void BeginTest() override {
160 index_ = STARTUP;
161 PostSetNeedsCommitToMainThread();
164 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
165 VerifyAfterValues(impl->active_tree()->root_layer());
168 void DidCommitAndDrawFrame() override {
169 SetBeforeValues(layer_tree_host()->root_layer());
170 VerifyBeforeValues(layer_tree_host()->root_layer());
172 ++index_;
173 if (index_ == DONE) {
174 EndTest();
175 return;
178 SetAfterValues(layer_tree_host()->root_layer());
181 void AfterTest() override {}
183 void VerifyBeforeValues(Layer* layer) {
184 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
185 EXPECT_FALSE(layer->hide_layer_and_subtree());
186 EXPECT_FALSE(layer->DrawsContent());
189 void SetBeforeValues(Layer* layer) {
190 layer->SetBounds(gfx::Size(10, 10));
191 layer->SetHideLayerAndSubtree(false);
192 layer->SetIsDrawable(false);
195 void VerifyAfterValues(LayerImpl* layer) {
196 switch (static_cast<Properties>(index_)) {
197 case STARTUP:
198 case DONE:
199 break;
200 case BOUNDS:
201 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
202 break;
203 case HIDE_LAYER_AND_SUBTREE:
204 EXPECT_TRUE(layer->hide_layer_and_subtree());
205 break;
206 case DRAWS_CONTENT:
207 EXPECT_TRUE(layer->DrawsContent());
208 break;
212 void SetAfterValues(Layer* layer) {
213 switch (static_cast<Properties>(index_)) {
214 case STARTUP:
215 case DONE:
216 break;
217 case BOUNDS:
218 layer->SetBounds(gfx::Size(20, 20));
219 break;
220 case HIDE_LAYER_AND_SUBTREE:
221 layer->SetHideLayerAndSubtree(true);
222 break;
223 case DRAWS_CONTENT:
224 layer->SetIsDrawable(true);
225 break;
229 int index_;
232 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
234 // 1 setNeedsRedraw after the first commit has completed should lead to 1
235 // additional draw.
236 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
237 public:
238 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
240 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
242 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
243 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
244 if (!num_draws_) {
245 // Redraw again to verify that the second redraw doesn't commit.
246 PostSetNeedsRedrawToMainThread();
247 } else {
248 EndTest();
250 num_draws_++;
253 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
254 EXPECT_EQ(0, num_draws_);
255 num_commits_++;
258 void AfterTest() override {
259 EXPECT_GE(2, num_draws_);
260 EXPECT_EQ(1, num_commits_);
263 private:
264 int num_commits_;
265 int num_draws_;
268 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
270 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
271 // must contain invalid_rect.
272 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
273 public:
274 LayerTreeHostTestSetNeedsRedrawRect()
275 : num_draws_(0),
276 bounds_(50, 50),
277 invalid_rect_(10, 10, 20, 20),
278 root_layer_(ContentLayer::Create(&client_)) {}
280 void BeginTest() override {
281 root_layer_->SetIsDrawable(true);
282 root_layer_->SetBounds(bounds_);
283 layer_tree_host()->SetRootLayer(root_layer_);
284 layer_tree_host()->SetViewportSize(bounds_);
285 PostSetNeedsCommitToMainThread();
288 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
289 LayerTreeHostImpl::FrameData* frame_data,
290 DrawResult draw_result) override {
291 EXPECT_EQ(DRAW_SUCCESS, draw_result);
293 gfx::RectF root_damage_rect;
294 if (!frame_data->render_passes.empty())
295 root_damage_rect = frame_data->render_passes.back()->damage_rect;
297 if (!num_draws_) {
298 // If this is the first frame, expect full frame damage.
299 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
300 } else {
301 // Check that invalid_rect_ is indeed repainted.
302 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
305 return draw_result;
308 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
309 if (!num_draws_) {
310 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
311 } else {
312 EndTest();
314 num_draws_++;
317 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
319 private:
320 int num_draws_;
321 const gfx::Size bounds_;
322 const gfx::Rect invalid_rect_;
323 FakeContentLayerClient client_;
324 scoped_refptr<ContentLayer> root_layer_;
327 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
329 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
330 public:
331 void InitializeSettings(LayerTreeSettings* settings) override {
332 settings->layer_transforms_should_scale_layer_contents = true;
335 void SetupTree() override {
336 root_layer_ = Layer::Create();
337 root_layer_->SetBounds(gfx::Size(10, 20));
339 scaled_layer_ = FakeContentLayer::Create(&client_);
340 scaled_layer_->SetBounds(gfx::Size(1, 1));
341 root_layer_->AddChild(scaled_layer_);
343 layer_tree_host()->SetRootLayer(root_layer_);
344 LayerTreeHostTest::SetupTree();
347 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
349 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
350 if (host_impl->active_tree()->source_frame_number() == 1)
351 EndTest();
354 void DidCommit() override {
355 switch (layer_tree_host()->source_frame_number()) {
356 case 1:
357 // Changing the device scale factor causes a commit. It also changes
358 // the content bounds of |scaled_layer_|, which should not generate
359 // a second commit as a result.
360 layer_tree_host()->SetDeviceScaleFactor(4.f);
361 break;
362 default:
363 // No extra commits.
364 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
368 void AfterTest() override {
369 EXPECT_EQ(gfx::Size(4, 4).ToString(),
370 scaled_layer_->content_bounds().ToString());
373 private:
374 FakeContentLayerClient client_;
375 scoped_refptr<Layer> root_layer_;
376 scoped_refptr<FakeContentLayer> scaled_layer_;
379 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
381 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
382 : public LayerTreeHostTest {
383 public:
384 void InitializeSettings(LayerTreeSettings* settings) override {
385 settings->layer_transforms_should_scale_layer_contents = true;
388 void SetupTree() override {
389 root_layer_ = Layer::Create();
390 root_layer_->SetBounds(gfx::Size(10, 20));
392 bool paint_scrollbar = true;
393 bool has_thumb = false;
394 scrollbar_ = FakePaintedScrollbarLayer::Create(
395 paint_scrollbar, has_thumb, root_layer_->id());
396 scrollbar_->SetPosition(gfx::Point(0, 10));
397 scrollbar_->SetBounds(gfx::Size(10, 10));
399 root_layer_->AddChild(scrollbar_);
401 layer_tree_host()->SetRootLayer(root_layer_);
402 LayerTreeHostTest::SetupTree();
405 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
407 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
408 if (host_impl->active_tree()->source_frame_number() == 1)
409 EndTest();
412 void DidCommit() override {
413 switch (layer_tree_host()->source_frame_number()) {
414 case 1:
415 // Changing the device scale factor causes a commit. It also changes
416 // the content bounds of |scrollbar_|, which should not generate
417 // a second commit as a result.
418 layer_tree_host()->SetDeviceScaleFactor(4.f);
419 break;
420 default:
421 // No extra commits.
422 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
426 void AfterTest() override {
427 EXPECT_EQ(gfx::Size(40, 40).ToString(),
428 scrollbar_->content_bounds().ToString());
431 private:
432 FakeContentLayerClient client_;
433 scoped_refptr<Layer> root_layer_;
434 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
437 SINGLE_AND_MULTI_THREAD_TEST_F(
438 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
440 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
441 public:
442 LayerTreeHostTestSetNextCommitForcesRedraw()
443 : num_draws_(0),
444 bounds_(50, 50),
445 invalid_rect_(10, 10, 20, 20),
446 root_layer_(ContentLayer::Create(&client_)) {}
448 void BeginTest() override {
449 root_layer_->SetIsDrawable(true);
450 root_layer_->SetBounds(bounds_);
451 layer_tree_host()->SetRootLayer(root_layer_);
452 layer_tree_host()->SetViewportSize(bounds_);
453 PostSetNeedsCommitToMainThread();
456 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
457 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
458 host_impl->SetNeedsRedrawRect(invalid_rect_);
461 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
462 LayerTreeHostImpl::FrameData* frame_data,
463 DrawResult draw_result) override {
464 EXPECT_EQ(DRAW_SUCCESS, draw_result);
466 gfx::RectF root_damage_rect;
467 if (!frame_data->render_passes.empty())
468 root_damage_rect = frame_data->render_passes.back()->damage_rect;
470 switch (num_draws_) {
471 case 0:
472 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
473 break;
474 case 1:
475 case 2:
476 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
477 break;
478 case 3:
479 EXPECT_RECT_EQ(invalid_rect_, root_damage_rect);
480 break;
481 case 4:
482 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
483 break;
484 default:
485 NOTREACHED();
488 return draw_result;
491 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
492 switch (num_draws_) {
493 case 0:
494 case 1:
495 // Cycle through a couple of empty commits to ensure we're observing the
496 // right behavior
497 PostSetNeedsCommitToMainThread();
498 break;
499 case 2:
500 // Should force full frame damage on the next commit
501 PostSetNextCommitForcesRedrawToMainThread();
502 PostSetNeedsCommitToMainThread();
503 if (host_impl->settings().impl_side_painting)
504 host_impl->BlockNotifyReadyToActivateForTesting(true);
505 else
506 num_draws_++;
507 break;
508 case 3:
509 host_impl->BlockNotifyReadyToActivateForTesting(false);
510 break;
511 default:
512 EndTest();
513 break;
515 num_draws_++;
518 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
520 private:
521 int num_draws_;
522 const gfx::Size bounds_;
523 const gfx::Rect invalid_rect_;
524 FakeContentLayerClient client_;
525 scoped_refptr<ContentLayer> root_layer_;
528 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
529 LayerTreeHostTestSetNextCommitForcesRedraw);
531 // Tests that if a layer is not drawn because of some reason in the parent then
532 // its damage is preserved until the next time it is drawn.
533 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
534 public:
535 LayerTreeHostTestUndrawnLayersDamageLater()
536 : root_layer_(ContentLayer::Create(&client_)) {}
538 void SetupTree() override {
539 root_layer_->SetIsDrawable(true);
540 root_layer_->SetBounds(gfx::Size(50, 50));
541 layer_tree_host()->SetRootLayer(root_layer_);
543 // The initially transparent layer has a larger child layer, which is
544 // not initially drawn because of the this (parent) layer.
545 parent_layer_ = FakeContentLayer::Create(&client_);
546 parent_layer_->SetBounds(gfx::Size(15, 15));
547 parent_layer_->SetOpacity(0.0f);
548 root_layer_->AddChild(parent_layer_);
550 child_layer_ = FakeContentLayer::Create(&client_);
551 child_layer_->SetBounds(gfx::Size(25, 25));
552 parent_layer_->AddChild(child_layer_);
554 LayerTreeHostTest::SetupTree();
557 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
559 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
560 LayerTreeHostImpl::FrameData* frame_data,
561 DrawResult draw_result) override {
562 EXPECT_EQ(DRAW_SUCCESS, draw_result);
564 gfx::RectF root_damage_rect;
565 if (!frame_data->render_passes.empty())
566 root_damage_rect = frame_data->render_passes.back()->damage_rect;
568 // The first time, the whole view needs be drawn.
569 // Afterwards, just the opacity of surface_layer1 is changed a few times,
570 // and each damage should be the bounding box of it and its child. If this
571 // was working improperly, the damage might not include its childs bounding
572 // box.
573 switch (host_impl->active_tree()->source_frame_number()) {
574 case 0:
575 EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
576 break;
577 case 1:
578 case 2:
579 case 3:
580 EXPECT_RECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
581 break;
582 default:
583 NOTREACHED();
586 return draw_result;
589 void DidCommitAndDrawFrame() override {
590 switch (layer_tree_host()->source_frame_number()) {
591 case 1:
592 // Test not owning the surface.
593 parent_layer_->SetOpacity(1.0f);
594 break;
595 case 2:
596 parent_layer_->SetOpacity(0.0f);
597 break;
598 case 3:
599 // Test owning the surface.
600 parent_layer_->SetOpacity(0.5f);
601 parent_layer_->SetForceRenderSurface(true);
602 break;
603 case 4:
604 EndTest();
605 break;
606 default:
607 NOTREACHED();
611 void AfterTest() override {}
613 private:
614 FakeContentLayerClient client_;
615 scoped_refptr<ContentLayer> root_layer_;
616 scoped_refptr<FakeContentLayer> parent_layer_;
617 scoped_refptr<FakeContentLayer> child_layer_;
620 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
622 // Tests that if a layer is not drawn because of some reason in the parent,
623 // causing its content bounds to not be computed, then when it is later drawn,
624 // its content bounds get pushed.
625 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
626 : public LayerTreeHostTest {
627 public:
628 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
629 : root_layer_(Layer::Create()) {}
631 void SetupTree() override {
632 root_layer_->SetIsDrawable(true);
633 root_layer_->SetBounds(gfx::Size(20, 20));
634 layer_tree_host()->SetRootLayer(root_layer_);
636 parent_layer_ = Layer::Create();
637 parent_layer_->SetBounds(gfx::Size(20, 20));
638 parent_layer_->SetOpacity(0.0f);
639 root_layer_->AddChild(parent_layer_);
641 child_layer_ = Layer::Create();
642 child_layer_->SetBounds(gfx::Size(15, 15));
643 parent_layer_->AddChild(child_layer_);
645 LayerTreeHostTest::SetupTree();
648 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
650 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
651 LayerImpl* root = host_impl->active_tree()->root_layer();
652 LayerImpl* parent = root->children()[0];
653 LayerImpl* child = parent->children()[0];
655 switch (host_impl->active_tree()->source_frame_number()) {
656 case 0:
657 EXPECT_EQ(0.f, parent->opacity());
658 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
659 break;
660 case 1:
661 EXPECT_EQ(1.f, parent->opacity());
662 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
663 EndTest();
664 break;
665 default:
666 NOTREACHED();
670 void DidCommit() override {
671 switch (layer_tree_host()->source_frame_number()) {
672 case 1:
673 parent_layer_->SetOpacity(1.0f);
674 break;
675 case 2:
676 break;
677 default:
678 NOTREACHED();
682 void AfterTest() override {}
684 private:
685 scoped_refptr<Layer> root_layer_;
686 scoped_refptr<Layer> parent_layer_;
687 scoped_refptr<Layer> child_layer_;
690 SINGLE_AND_MULTI_THREAD_TEST_F(
691 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
693 // This test verifies that properties on the layer tree host are commited
694 // to the impl side.
695 class LayerTreeHostTestCommit : public LayerTreeHostTest {
696 public:
697 LayerTreeHostTestCommit() {}
699 void BeginTest() override {
700 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
701 layer_tree_host()->set_background_color(SK_ColorGRAY);
703 PostSetNeedsCommitToMainThread();
706 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
707 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
708 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
710 EndTest();
713 void AfterTest() override {}
716 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
718 // This test verifies that LayerTreeHostImpl's current frame time gets
719 // updated in consecutive frames when it doesn't draw due to tree
720 // activation failure.
721 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
722 : public LayerTreeHostTest {
723 public:
724 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
725 : frame_count_with_pending_tree_(0) {}
727 void BeginTest() override {
728 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
729 layer_tree_host()->set_background_color(SK_ColorGRAY);
731 PostSetNeedsCommitToMainThread();
734 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
735 EXPECT_EQ(frame_count_with_pending_tree_, 0);
736 if (impl->settings().impl_side_painting)
737 impl->BlockNotifyReadyToActivateForTesting(true);
740 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
741 const BeginFrameArgs& args) override {
742 if (impl->pending_tree())
743 frame_count_with_pending_tree_++;
745 if (frame_count_with_pending_tree_ == 1) {
746 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
747 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
748 } else if (frame_count_with_pending_tree_ == 2 &&
749 impl->settings().impl_side_painting) {
750 impl->BlockNotifyReadyToActivateForTesting(false);
754 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
755 if (frame_count_with_pending_tree_ > 1) {
756 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
757 EXPECT_NE(first_frame_time_.ToInternalValue(),
758 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
759 EndTest();
760 return;
763 EXPECT_FALSE(impl->settings().impl_side_painting);
764 EndTest();
766 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
767 if (impl->settings().impl_side_painting)
768 EXPECT_NE(frame_count_with_pending_tree_, 1);
771 void AfterTest() override {}
773 private:
774 int frame_count_with_pending_tree_;
775 base::TimeTicks first_frame_time_;
778 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
779 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
781 // This test verifies that LayerTreeHostImpl's current frame time gets
782 // updated in consecutive frames when it draws in each frame.
783 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
784 public:
785 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
787 void BeginTest() override {
788 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
789 layer_tree_host()->set_background_color(SK_ColorGRAY);
791 PostSetNeedsCommitToMainThread();
794 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
795 frame_++;
796 if (frame_ == 1) {
797 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
798 impl->SetNeedsRedraw();
800 // Since we might use a low-resolution clock on Windows, we need to
801 // make sure that the clock has incremented past first_frame_time_.
802 while (first_frame_time_ == gfx::FrameTime::Now()) {
805 return;
808 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
809 EndTest();
812 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
813 // Ensure there isn't a commit between the two draws, to ensure that a
814 // commit isn't required for updating the current frame time. We can
815 // only check for this in the multi-threaded case, since in the single-
816 // threaded case there will always be a commit between consecutive draws.
817 if (HasImplThread())
818 EXPECT_EQ(0, frame_);
821 void AfterTest() override {}
823 private:
824 int frame_;
825 base::TimeTicks first_frame_time_;
828 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
830 // Verifies that StartPageScaleAnimation events propagate correctly
831 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
832 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
833 public:
834 LayerTreeHostTestStartPageScaleAnimation() {}
836 void SetupTree() override {
837 LayerTreeHostTest::SetupTree();
839 if (layer_tree_host()->settings().impl_side_painting) {
840 scoped_refptr<FakePictureLayer> layer =
841 FakePictureLayer::Create(&client_);
842 layer->set_always_update_resources(true);
843 scroll_layer_ = layer;
844 } else {
845 scroll_layer_ = FakeContentLayer::Create(&client_);
848 Layer* root_layer = layer_tree_host()->root_layer();
849 scroll_layer_->SetScrollClipLayerId(root_layer->id());
850 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
851 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
852 2 * root_layer->bounds().height()));
853 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
854 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
855 // This test requires the page_scale and inner viewport layers to be
856 // identified.
857 layer_tree_host()->RegisterViewportLayers(
858 root_layer, scroll_layer_.get(), NULL);
859 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
862 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
864 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
865 float scale,
866 float) override {
867 gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
868 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset,
869 scroll_delta));
870 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
873 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
874 // We get one commit before the first draw, and the animation doesn't happen
875 // until the second draw.
876 switch (impl->active_tree()->source_frame_number()) {
877 case 0:
878 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
879 // We'll start an animation when we get back to the main thread.
880 break;
881 case 1:
882 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
883 break;
884 case 2:
885 EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
886 EndTest();
887 break;
888 default:
889 NOTREACHED();
893 void DidCommitAndDrawFrame() override {
894 switch (layer_tree_host()->source_frame_number()) {
895 case 1:
896 layer_tree_host()->StartPageScaleAnimation(
897 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
898 break;
902 void AfterTest() override {}
904 FakeContentLayerClient client_;
905 scoped_refptr<Layer> scroll_layer_;
908 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
910 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
911 public:
912 LayerTreeHostTestSetVisible() : num_draws_(0) {}
914 void BeginTest() override {
915 PostSetNeedsCommitToMainThread();
916 PostSetVisibleToMainThread(false);
917 // This is suppressed while we're invisible.
918 PostSetNeedsRedrawToMainThread();
919 // Triggers the redraw.
920 PostSetVisibleToMainThread(true);
923 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
924 EXPECT_TRUE(impl->visible());
925 ++num_draws_;
926 EndTest();
929 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
931 private:
932 int num_draws_;
935 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
937 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
938 public:
939 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
941 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
943 void PaintContents(
944 SkCanvas* canvas,
945 const gfx::Rect& clip,
946 ContentLayerClient::GraphicsContextStatus gc_status) override {
947 // Set layer opacity to 0.
948 if (test_layer_)
949 test_layer_->SetOpacity(0.f);
951 void DidChangeLayerCanUseLCDText() override {}
952 bool FillsBoundsCompletely() const override { return false; }
954 private:
955 Layer* test_layer_;
958 class ContentLayerWithUpdateTracking : public ContentLayer {
959 public:
960 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
961 ContentLayerClient* client) {
962 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
965 int PaintContentsCount() { return paint_contents_count_; }
966 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
968 bool Update(ResourceUpdateQueue* queue,
969 const OcclusionTracker<Layer>* occlusion) override {
970 bool updated = ContentLayer::Update(queue, occlusion);
971 paint_contents_count_++;
972 return updated;
975 private:
976 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
977 : ContentLayer(client), paint_contents_count_(0) {
978 SetBounds(gfx::Size(10, 10));
979 SetIsDrawable(true);
981 ~ContentLayerWithUpdateTracking() override {}
983 int paint_contents_count_;
986 // Layer opacity change during paint should not prevent compositor resources
987 // from being updated during commit.
988 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
989 public:
990 LayerTreeHostTestOpacityChange()
991 : test_opacity_change_delegate_(),
992 update_check_layer_(ContentLayerWithUpdateTracking::Create(
993 &test_opacity_change_delegate_)) {
994 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
997 void BeginTest() override {
998 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
999 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
1001 PostSetNeedsCommitToMainThread();
1004 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
1006 void AfterTest() override {
1007 // Update() should have been called once.
1008 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
1011 private:
1012 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1013 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
1016 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1018 class NoScaleContentLayer : public ContentLayer {
1019 public:
1020 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
1021 return make_scoped_refptr(new NoScaleContentLayer(client));
1024 void CalculateContentsScale(float ideal_contents_scale,
1025 float* contents_scale_x,
1026 float* contents_scale_y,
1027 gfx::Size* contentBounds) override {
1028 // Skip over the ContentLayer's method to the base Layer class.
1029 Layer::CalculateContentsScale(ideal_contents_scale,
1030 contents_scale_x,
1031 contents_scale_y,
1032 contentBounds);
1035 private:
1036 explicit NoScaleContentLayer(ContentLayerClient* client)
1037 : ContentLayer(client) {}
1038 ~NoScaleContentLayer() override {}
1041 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1042 : public LayerTreeHostTest {
1043 public:
1044 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1045 : root_layer_(NoScaleContentLayer::Create(&client_)),
1046 child_layer_(ContentLayer::Create(&client_)) {}
1048 void BeginTest() override {
1049 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1050 layer_tree_host()->SetDeviceScaleFactor(1.5);
1051 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1053 root_layer_->AddChild(child_layer_);
1055 root_layer_->SetIsDrawable(true);
1056 root_layer_->SetBounds(gfx::Size(30, 30));
1058 child_layer_->SetIsDrawable(true);
1059 child_layer_->SetPosition(gfx::Point(2, 2));
1060 child_layer_->SetBounds(gfx::Size(10, 10));
1062 layer_tree_host()->SetRootLayer(root_layer_);
1064 PostSetNeedsCommitToMainThread();
1067 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1068 // Should only do one commit.
1069 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1070 // Device scale factor should come over to impl.
1071 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1073 // Both layers are on impl.
1074 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1076 // Device viewport is scaled.
1077 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1079 LayerImpl* root = impl->active_tree()->root_layer();
1080 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1082 // Positions remain in layout pixels.
1083 EXPECT_EQ(gfx::Point(0, 0), root->position());
1084 EXPECT_EQ(gfx::Point(2, 2), child->position());
1086 // Compute all the layer transforms for the frame.
1087 LayerTreeHostImpl::FrameData frame_data;
1088 impl->PrepareToDraw(&frame_data);
1089 impl->DidDrawAllLayers(frame_data);
1091 const LayerImplList& render_surface_layer_list =
1092 *frame_data.render_surface_layer_list;
1094 // Both layers should be drawing into the root render surface.
1095 ASSERT_EQ(1u, render_surface_layer_list.size());
1096 ASSERT_EQ(root->render_surface(),
1097 render_surface_layer_list[0]->render_surface());
1098 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1100 // The root render surface is the size of the viewport.
1101 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1102 root->render_surface()->content_rect());
1104 // The content bounds of the child should be scaled.
1105 gfx::Size child_bounds_scaled =
1106 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1107 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1109 gfx::Transform scale_transform;
1110 scale_transform.Scale(impl->device_scale_factor(),
1111 impl->device_scale_factor());
1113 // The root layer is scaled by 2x.
1114 gfx::Transform root_screen_space_transform = scale_transform;
1115 gfx::Transform root_draw_transform = scale_transform;
1117 EXPECT_EQ(root_draw_transform, root->draw_transform());
1118 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1120 // The child is at position 2,2, which is transformed to 3,3 after the scale
1121 gfx::Transform child_screen_space_transform;
1122 child_screen_space_transform.Translate(3.f, 3.f);
1123 gfx::Transform child_draw_transform = child_screen_space_transform;
1125 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1126 child->draw_transform());
1127 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1128 child->screen_space_transform());
1130 EndTest();
1133 void AfterTest() override {}
1135 private:
1136 FakeContentLayerClient client_;
1137 scoped_refptr<NoScaleContentLayer> root_layer_;
1138 scoped_refptr<ContentLayer> child_layer_;
1141 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1143 // Verify atomicity of commits and reuse of textures.
1144 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1145 public:
1146 void InitializeSettings(LayerTreeSettings* settings) override {
1147 settings->texture_id_allocation_chunk_size = 1;
1148 // Make sure partial texture updates are turned off.
1149 settings->max_partial_texture_updates = 0;
1150 // Linear fade animator prevents scrollbars from drawing immediately.
1151 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1154 void SetupTree() override {
1155 layer_ = FakeContentLayer::Create(&client_);
1156 layer_->SetBounds(gfx::Size(10, 20));
1158 bool paint_scrollbar = true;
1159 bool has_thumb = false;
1160 scrollbar_ = FakePaintedScrollbarLayer::Create(
1161 paint_scrollbar, has_thumb, layer_->id());
1162 scrollbar_->SetPosition(gfx::Point(0, 10));
1163 scrollbar_->SetBounds(gfx::Size(10, 10));
1165 layer_->AddChild(scrollbar_);
1167 layer_tree_host()->SetRootLayer(layer_);
1168 LayerTreeHostTest::SetupTree();
1171 void BeginTest() override {
1172 drew_frame_ = -1;
1173 PostSetNeedsCommitToMainThread();
1176 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1177 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1179 TestWebGraphicsContext3D* context = TestContext();
1181 switch (impl->active_tree()->source_frame_number()) {
1182 case 0:
1183 // Number of textures should be one for each layer
1184 ASSERT_EQ(2u, context->NumTextures());
1185 // Number of textures used for commit should be one for each layer.
1186 EXPECT_EQ(2u, context->NumUsedTextures());
1187 // Verify that used texture is correct.
1188 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1189 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1191 context->ResetUsedTextures();
1192 break;
1193 case 1:
1194 // Number of textures should be one for scrollbar layer since it was
1195 // requested and deleted on the impl-thread, and double for the content
1196 // layer since its first texture is used by impl thread and cannot by
1197 // used for update.
1198 ASSERT_EQ(3u, context->NumTextures());
1199 // Number of textures used for commit should be one for each layer.
1200 EXPECT_EQ(2u, context->NumUsedTextures());
1201 // First textures should not have been used.
1202 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1203 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1204 // New textures should have been used.
1205 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1206 context->ResetUsedTextures();
1207 break;
1208 case 2:
1209 EndTest();
1210 break;
1211 default:
1212 NOTREACHED();
1213 break;
1217 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1218 TestWebGraphicsContext3D* context = TestContext();
1220 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1221 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1222 return;
1224 drew_frame_ = impl->active_tree()->source_frame_number();
1226 // We draw/ship one texture each frame for each layer.
1227 EXPECT_EQ(2u, context->NumUsedTextures());
1228 context->ResetUsedTextures();
1230 if (!TestEnded())
1231 PostSetNeedsCommitToMainThread();
1234 void Layout() override {
1235 layer_->SetNeedsDisplay();
1236 scrollbar_->SetNeedsDisplay();
1239 void AfterTest() override {}
1241 protected:
1242 FakeContentLayerClient client_;
1243 scoped_refptr<FakeContentLayer> layer_;
1244 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1245 int drew_frame_;
1248 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1249 LayerTreeHostTestDirectRendererAtomicCommit);
1251 class LayerTreeHostTestDelegatingRendererAtomicCommit
1252 : public LayerTreeHostTestDirectRendererAtomicCommit {
1253 public:
1254 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1255 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1257 TestWebGraphicsContext3D* context = TestContext();
1259 switch (impl->active_tree()->source_frame_number()) {
1260 case 0:
1261 // Number of textures should be one for each layer
1262 ASSERT_EQ(2u, context->NumTextures());
1263 // Number of textures used for commit should be one for each layer.
1264 EXPECT_EQ(2u, context->NumUsedTextures());
1265 // Verify that used texture is correct.
1266 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1267 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1268 context->ResetUsedTextures();
1269 break;
1270 case 1:
1271 // Number of textures should be doubled as the first context layer
1272 // texture is being used by the impl-thread and cannot be used for
1273 // update. The scrollbar behavior is different direct renderer because
1274 // UI resource deletion with delegating renderer occurs after tree
1275 // activation.
1276 ASSERT_EQ(4u, context->NumTextures());
1277 // Number of textures used for commit should still be
1278 // one for each layer.
1279 EXPECT_EQ(2u, context->NumUsedTextures());
1280 // First textures should not have been used.
1281 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1282 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1283 // New textures should have been used.
1284 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1285 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1286 context->ResetUsedTextures();
1287 break;
1288 case 2:
1289 EndTest();
1290 break;
1291 default:
1292 NOTREACHED();
1293 break;
1298 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1299 LayerTreeHostTestDelegatingRendererAtomicCommit);
1301 static void SetLayerPropertiesForTesting(Layer* layer,
1302 Layer* parent,
1303 const gfx::Transform& transform,
1304 const gfx::Point3F& transform_origin,
1305 const gfx::PointF& position,
1306 const gfx::Size& bounds,
1307 bool opaque) {
1308 layer->RemoveAllChildren();
1309 if (parent)
1310 parent->AddChild(layer);
1311 layer->SetTransform(transform);
1312 layer->SetTransformOrigin(transform_origin);
1313 layer->SetPosition(position);
1314 layer->SetBounds(bounds);
1315 layer->SetContentsOpaque(opaque);
1318 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1319 : public LayerTreeHostTest {
1320 public:
1321 void InitializeSettings(LayerTreeSettings* settings) override {
1322 settings->texture_id_allocation_chunk_size = 1;
1323 // Allow one partial texture update.
1324 settings->max_partial_texture_updates = 1;
1325 // No partial updates when impl side painting is enabled.
1326 settings->impl_side_painting = false;
1329 void SetupTree() override {
1330 parent_ = FakeContentLayer::Create(&client_);
1331 parent_->SetBounds(gfx::Size(10, 20));
1333 child_ = FakeContentLayer::Create(&client_);
1334 child_->SetPosition(gfx::Point(0, 10));
1335 child_->SetBounds(gfx::Size(3, 10));
1337 parent_->AddChild(child_);
1339 layer_tree_host()->SetRootLayer(parent_);
1340 LayerTreeHostTest::SetupTree();
1343 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1345 void DidCommitAndDrawFrame() override {
1346 switch (layer_tree_host()->source_frame_number()) {
1347 case 1:
1348 parent_->SetNeedsDisplay();
1349 child_->SetNeedsDisplay();
1350 break;
1351 case 2:
1352 // Damage part of layers.
1353 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1354 child_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1355 break;
1356 case 3:
1357 child_->SetNeedsDisplay();
1358 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1359 break;
1360 case 4:
1361 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1362 break;
1363 case 5:
1364 EndTest();
1365 break;
1366 default:
1367 NOTREACHED() << layer_tree_host()->source_frame_number();
1368 break;
1372 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1373 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1375 TestWebGraphicsContext3D* context = TestContext();
1377 switch (impl->active_tree()->source_frame_number()) {
1378 case 0:
1379 // Number of textures should be one for each layer.
1380 ASSERT_EQ(2u, context->NumTextures());
1381 // Number of textures used for commit should be one for each layer.
1382 EXPECT_EQ(2u, context->NumUsedTextures());
1383 // Verify that used textures are correct.
1384 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1385 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1386 context->ResetUsedTextures();
1387 break;
1388 case 1:
1389 if (HasImplThread()) {
1390 // Number of textures should be two for each content layer.
1391 ASSERT_EQ(4u, context->NumTextures());
1392 } else {
1393 // In single thread we can always do partial updates, so the limit has
1394 // no effect.
1395 ASSERT_EQ(2u, context->NumTextures());
1397 // Number of textures used for commit should be one for each content
1398 // layer.
1399 EXPECT_EQ(2u, context->NumUsedTextures());
1401 if (HasImplThread()) {
1402 // First content textures should not have been used.
1403 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1404 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1405 // New textures should have been used.
1406 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1407 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1408 } else {
1409 // In single thread we can always do partial updates, so the limit has
1410 // no effect.
1411 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1412 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1415 context->ResetUsedTextures();
1416 break;
1417 case 2:
1418 if (HasImplThread()) {
1419 // Number of textures should be two for each content layer.
1420 ASSERT_EQ(4u, context->NumTextures());
1421 } else {
1422 // In single thread we can always do partial updates, so the limit has
1423 // no effect.
1424 ASSERT_EQ(2u, context->NumTextures());
1426 // Number of textures used for commit should be one for each content
1427 // layer.
1428 EXPECT_EQ(2u, context->NumUsedTextures());
1430 if (HasImplThread()) {
1431 // One content layer does a partial update also.
1432 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1433 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1434 } else {
1435 // In single thread we can always do partial updates, so the limit has
1436 // no effect.
1437 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1438 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1441 context->ResetUsedTextures();
1442 break;
1443 case 3:
1444 // No textures should be used for commit.
1445 EXPECT_EQ(0u, context->NumUsedTextures());
1447 context->ResetUsedTextures();
1448 break;
1449 case 4:
1450 // Number of textures used for commit should be one, for the
1451 // content layer.
1452 EXPECT_EQ(1u, context->NumUsedTextures());
1454 context->ResetUsedTextures();
1455 break;
1456 default:
1457 NOTREACHED();
1458 break;
1462 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1463 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1465 TestWebGraphicsContext3D* context = TestContext();
1467 // Number of textures used for drawing should one per layer except for
1468 // frame 3 where the viewport only contains one layer.
1469 if (impl->active_tree()->source_frame_number() == 3) {
1470 EXPECT_EQ(1u, context->NumUsedTextures());
1471 } else {
1472 EXPECT_EQ(2u, context->NumUsedTextures())
1473 << "For frame " << impl->active_tree()->source_frame_number();
1476 context->ResetUsedTextures();
1479 void AfterTest() override {}
1481 private:
1482 FakeContentLayerClient client_;
1483 scoped_refptr<FakeContentLayer> parent_;
1484 scoped_refptr<FakeContentLayer> child_;
1487 // Partial updates are not possible with a delegating renderer.
1488 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1489 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1491 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1492 : public LayerTreeHostTest {
1493 protected:
1494 void SetupTree() override {
1495 root_layer_ = FakeContentLayer::Create(&client_);
1496 root_layer_->SetBounds(gfx::Size(100, 100));
1498 surface_layer1_ = FakeContentLayer::Create(&client_);
1499 surface_layer1_->SetBounds(gfx::Size(100, 100));
1500 surface_layer1_->SetForceRenderSurface(true);
1501 surface_layer1_->SetOpacity(0.5f);
1502 root_layer_->AddChild(surface_layer1_);
1504 surface_layer2_ = FakeContentLayer::Create(&client_);
1505 surface_layer2_->SetBounds(gfx::Size(100, 100));
1506 surface_layer2_->SetForceRenderSurface(true);
1507 surface_layer2_->SetOpacity(0.5f);
1508 surface_layer1_->AddChild(surface_layer2_);
1510 replica_layer1_ = FakeContentLayer::Create(&client_);
1511 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1513 replica_layer2_ = FakeContentLayer::Create(&client_);
1514 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1516 layer_tree_host()->SetRootLayer(root_layer_);
1517 LayerTreeHostTest::SetupTree();
1520 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1522 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1523 Renderer* renderer = host_impl->renderer();
1524 RenderPassId surface1_render_pass_id = host_impl->active_tree()
1525 ->root_layer()
1526 ->children()[0]
1527 ->render_surface()
1528 ->GetRenderPassId();
1529 RenderPassId surface2_render_pass_id = host_impl->active_tree()
1530 ->root_layer()
1531 ->children()[0]
1532 ->children()[0]
1533 ->render_surface()
1534 ->GetRenderPassId();
1536 switch (host_impl->active_tree()->source_frame_number()) {
1537 case 0:
1538 EXPECT_TRUE(
1539 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1540 EXPECT_TRUE(
1541 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1543 // Reduce the memory limit to only fit the root layer and one render
1544 // surface. This prevents any contents drawing into surfaces
1545 // from being allocated.
1546 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1547 break;
1548 case 1:
1549 EXPECT_FALSE(
1550 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1551 EXPECT_FALSE(
1552 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1554 EndTest();
1555 break;
1559 void DidCommitAndDrawFrame() override {
1560 if (layer_tree_host()->source_frame_number() < 2)
1561 root_layer_->SetNeedsDisplay();
1564 void AfterTest() override {
1565 EXPECT_LE(2u, root_layer_->update_count());
1566 EXPECT_LE(2u, surface_layer1_->update_count());
1567 EXPECT_LE(2u, surface_layer2_->update_count());
1570 FakeContentLayerClient client_;
1571 scoped_refptr<FakeContentLayer> root_layer_;
1572 scoped_refptr<FakeContentLayer> surface_layer1_;
1573 scoped_refptr<FakeContentLayer> replica_layer1_;
1574 scoped_refptr<FakeContentLayer> surface_layer2_;
1575 scoped_refptr<FakeContentLayer> replica_layer2_;
1578 // Surfaces don't exist with a delegated renderer.
1579 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1580 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1582 class EvictionTestLayer : public Layer {
1583 public:
1584 static scoped_refptr<EvictionTestLayer> Create() {
1585 return make_scoped_refptr(new EvictionTestLayer());
1588 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override;
1589 bool DrawsContent() const override { return true; }
1591 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
1592 void PushPropertiesTo(LayerImpl* impl) override;
1593 void SetTexturePriorities(const PriorityCalculator&) override;
1595 bool HaveBackingTexture() const {
1596 return texture_.get() ? texture_->have_backing_texture() : false;
1599 private:
1600 EvictionTestLayer() : Layer() {}
1601 ~EvictionTestLayer() override {}
1603 void CreateTextureIfNeeded() {
1604 if (texture_)
1605 return;
1606 texture_ = PrioritizedResource::Create(
1607 layer_tree_host()->contents_texture_manager());
1608 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1609 bitmap_.allocN32Pixels(10, 10);
1612 scoped_ptr<PrioritizedResource> texture_;
1613 SkBitmap bitmap_;
1616 class EvictionTestLayerImpl : public LayerImpl {
1617 public:
1618 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1619 int id) {
1620 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1622 ~EvictionTestLayerImpl() override {}
1624 void AppendQuads(RenderPass* render_pass,
1625 const Occlusion& occlusion_in_content_space,
1626 AppendQuadsData* append_quads_data) override {
1627 ASSERT_TRUE(has_texture_);
1628 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1631 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1633 private:
1634 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1635 : LayerImpl(tree_impl, id), has_texture_(false) {}
1637 bool has_texture_;
1640 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1641 CreateTextureIfNeeded();
1642 if (!texture_)
1643 return;
1644 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1647 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1648 const OcclusionTracker<Layer>* occlusion) {
1649 CreateTextureIfNeeded();
1650 if (!texture_)
1651 return false;
1653 gfx::Rect full_rect(0, 0, 10, 10);
1654 ResourceUpdate upload = ResourceUpdate::Create(
1655 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1656 queue->AppendFullUpload(upload);
1657 return true;
1660 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1661 LayerTreeImpl* tree_impl) {
1662 return EvictionTestLayerImpl::Create(tree_impl, layer_id_);
1665 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1666 Layer::PushPropertiesTo(layer_impl);
1668 EvictionTestLayerImpl* test_layer_impl =
1669 static_cast<EvictionTestLayerImpl*>(layer_impl);
1670 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1673 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1674 public:
1675 LayerTreeHostTestEvictTextures()
1676 : layer_(EvictionTestLayer::Create()),
1677 impl_for_evict_textures_(0),
1678 num_commits_(0) {}
1680 void BeginTest() override {
1681 layer_tree_host()->SetRootLayer(layer_);
1682 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1684 gfx::Transform identity_matrix;
1685 SetLayerPropertiesForTesting(layer_.get(),
1687 identity_matrix,
1688 gfx::Point3F(0.f, 0.f, 0.f),
1689 gfx::PointF(0.f, 0.f),
1690 gfx::Size(10, 20),
1691 true);
1693 PostSetNeedsCommitToMainThread();
1696 void PostEvictTextures() {
1697 ImplThreadTaskRunner()->PostTask(
1698 FROM_HERE,
1699 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1700 base::Unretained(this)));
1703 void EvictTexturesOnImplThread() {
1704 DCHECK(impl_for_evict_textures_);
1705 impl_for_evict_textures_->EvictTexturesForTesting();
1708 // Commit 1: Just commit and draw normally, then post an eviction at the end
1709 // that will trigger a commit.
1710 // Commit 2: Triggered by the eviction, let it go through and then set
1711 // needsCommit.
1712 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1713 // task, which will be handled before the commit. Don't set needsCommit, it
1714 // should have been posted. A frame should not be drawn (note,
1715 // didCommitAndDrawFrame may be called anyway).
1716 // Commit 4: Triggered by the eviction, let it go through and then set
1717 // needsCommit.
1718 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1719 // Layout(), a frame should not be drawn but a commit will be posted.
1720 // Commit 6: Triggered by the eviction, post an eviction task in
1721 // Layout(), which will be a noop, letting the commit (which recreates the
1722 // textures) go through and draw a frame, then end the test.
1724 // Commits 1+2 test the eviction recovery path where eviction happens outside
1725 // of the beginFrame/commit pair.
1726 // Commits 3+4 test the eviction recovery path where eviction happens inside
1727 // the beginFrame/commit pair.
1728 // Commits 5+6 test the path where an eviction happens during the eviction
1729 // recovery path.
1730 void DidCommit() override {
1731 switch (num_commits_) {
1732 case 1:
1733 EXPECT_TRUE(layer_->HaveBackingTexture());
1734 PostEvictTextures();
1735 break;
1736 case 2:
1737 EXPECT_TRUE(layer_->HaveBackingTexture());
1738 layer_tree_host()->SetNeedsCommit();
1739 break;
1740 case 3:
1741 break;
1742 case 4:
1743 EXPECT_TRUE(layer_->HaveBackingTexture());
1744 layer_tree_host()->SetNeedsCommit();
1745 break;
1746 case 5:
1747 break;
1748 case 6:
1749 EXPECT_TRUE(layer_->HaveBackingTexture());
1750 EndTest();
1751 break;
1752 default:
1753 NOTREACHED();
1754 break;
1758 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1759 impl_for_evict_textures_ = impl;
1762 void Layout() override {
1763 ++num_commits_;
1764 switch (num_commits_) {
1765 case 1:
1766 case 2:
1767 break;
1768 case 3:
1769 PostEvictTextures();
1770 break;
1771 case 4:
1772 // We couldn't check in didCommitAndDrawFrame on commit 3,
1773 // so check here.
1774 EXPECT_FALSE(layer_->HaveBackingTexture());
1775 break;
1776 case 5:
1777 PostEvictTextures();
1778 break;
1779 case 6:
1780 // We couldn't check in didCommitAndDrawFrame on commit 5,
1781 // so check here.
1782 EXPECT_FALSE(layer_->HaveBackingTexture());
1783 PostEvictTextures();
1784 break;
1785 default:
1786 NOTREACHED();
1787 break;
1791 void AfterTest() override {}
1793 private:
1794 FakeContentLayerClient client_;
1795 scoped_refptr<EvictionTestLayer> layer_;
1796 LayerTreeHostImpl* impl_for_evict_textures_;
1797 int num_commits_;
1800 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
1802 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1803 public:
1804 LayerTreeHostTestContinuousInvalidate()
1805 : num_commit_complete_(0), num_draw_layers_(0) {}
1807 void BeginTest() override {
1808 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1809 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1811 content_layer_ = ContentLayer::Create(&client_);
1812 content_layer_->SetBounds(gfx::Size(10, 10));
1813 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
1814 content_layer_->SetIsDrawable(true);
1815 layer_tree_host()->root_layer()->AddChild(content_layer_);
1817 PostSetNeedsCommitToMainThread();
1820 void DidCommitAndDrawFrame() override {
1821 if (num_draw_layers_ == 2)
1822 return;
1823 content_layer_->SetNeedsDisplay();
1826 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1827 if (num_draw_layers_ == 1)
1828 num_commit_complete_++;
1831 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1832 num_draw_layers_++;
1833 if (num_draw_layers_ == 2)
1834 EndTest();
1837 void AfterTest() override {
1838 // Check that we didn't commit twice between first and second draw.
1839 EXPECT_EQ(1, num_commit_complete_);
1842 private:
1843 FakeContentLayerClient client_;
1844 scoped_refptr<Layer> content_layer_;
1845 int num_commit_complete_;
1846 int num_draw_layers_;
1849 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestContinuousInvalidate);
1851 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
1852 public:
1853 LayerTreeHostTestDeferCommits()
1854 : num_commits_deferred_(0), num_complete_commits_(0) {}
1856 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1858 void DidDeferCommit() override {
1859 num_commits_deferred_++;
1860 layer_tree_host()->SetDeferCommits(false);
1863 void DidCommit() override {
1864 num_complete_commits_++;
1865 switch (num_complete_commits_) {
1866 case 1:
1867 EXPECT_EQ(0, num_commits_deferred_);
1868 layer_tree_host()->SetDeferCommits(true);
1869 PostSetNeedsCommitToMainThread();
1870 break;
1871 case 2:
1872 EndTest();
1873 break;
1874 default:
1875 NOTREACHED();
1876 break;
1880 void AfterTest() override {
1881 EXPECT_EQ(1, num_commits_deferred_);
1882 EXPECT_EQ(2, num_complete_commits_);
1885 private:
1886 int num_commits_deferred_;
1887 int num_complete_commits_;
1890 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
1892 class LayerTreeHostWithProxy : public LayerTreeHost {
1893 public:
1894 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
1895 const LayerTreeSettings& settings,
1896 scoped_ptr<FakeProxy> proxy)
1897 : LayerTreeHost(client, NULL, NULL, settings) {
1898 proxy->SetLayerTreeHost(this);
1899 client->SetLayerTreeHost(this);
1900 InitializeForTesting(proxy.Pass());
1904 TEST(LayerTreeHostTest, LimitPartialUpdates) {
1905 // When partial updates are not allowed, max updates should be 0.
1907 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1909 scoped_ptr<FakeProxy> proxy(new FakeProxy);
1910 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
1911 proxy->SetMaxPartialTextureUpdates(5);
1913 LayerTreeSettings settings;
1914 settings.max_partial_texture_updates = 10;
1916 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1917 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
1919 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
1922 // When partial updates are allowed,
1923 // max updates should be limited by the proxy.
1925 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1927 scoped_ptr<FakeProxy> proxy(new FakeProxy);
1928 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1929 proxy->SetMaxPartialTextureUpdates(5);
1931 LayerTreeSettings settings;
1932 settings.max_partial_texture_updates = 10;
1934 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1935 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
1937 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
1940 // When partial updates are allowed,
1941 // max updates should also be limited by the settings.
1943 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1945 scoped_ptr<FakeProxy> proxy(new FakeProxy);
1946 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1947 proxy->SetMaxPartialTextureUpdates(20);
1949 LayerTreeSettings settings;
1950 settings.max_partial_texture_updates = 10;
1952 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1953 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
1955 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
1959 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
1960 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1962 LayerTreeSettings settings;
1963 settings.max_partial_texture_updates = 4;
1964 settings.single_thread_proxy_scheduler = false;
1966 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1967 new TestSharedBitmapManager());
1968 scoped_ptr<LayerTreeHost> host =
1969 LayerTreeHost::CreateSingleThreaded(&client,
1970 &client,
1971 shared_bitmap_manager.get(),
1972 NULL,
1973 settings,
1974 base::MessageLoopProxy::current());
1975 client.SetLayerTreeHost(host.get());
1976 host->Composite(base::TimeTicks::Now());
1978 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
1981 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
1982 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
1984 LayerTreeSettings settings;
1985 settings.max_partial_texture_updates = 4;
1986 settings.single_thread_proxy_scheduler = false;
1988 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1989 new TestSharedBitmapManager());
1990 scoped_ptr<LayerTreeHost> host =
1991 LayerTreeHost::CreateSingleThreaded(&client,
1992 &client,
1993 shared_bitmap_manager.get(),
1994 NULL,
1995 settings,
1996 base::MessageLoopProxy::current());
1997 client.SetLayerTreeHost(host.get());
1998 host->Composite(base::TimeTicks::Now());
2000 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2003 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2004 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2006 LayerTreeSettings settings;
2007 settings.max_partial_texture_updates = 4;
2008 settings.single_thread_proxy_scheduler = false;
2010 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2011 new TestSharedBitmapManager());
2012 scoped_ptr<LayerTreeHost> host =
2013 LayerTreeHost::CreateSingleThreaded(&client,
2014 &client,
2015 shared_bitmap_manager.get(),
2016 NULL,
2017 settings,
2018 base::MessageLoopProxy::current());
2019 client.SetLayerTreeHost(host.get());
2020 host->Composite(base::TimeTicks::Now());
2022 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2025 TEST(LayerTreeHostTest,
2026 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2027 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2029 LayerTreeSettings settings;
2030 settings.max_partial_texture_updates = 4;
2031 settings.single_thread_proxy_scheduler = false;
2033 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2034 new TestSharedBitmapManager());
2035 scoped_ptr<LayerTreeHost> host =
2036 LayerTreeHost::CreateSingleThreaded(&client,
2037 &client,
2038 shared_bitmap_manager.get(),
2039 NULL,
2040 settings,
2041 base::MessageLoopProxy::current());
2042 client.SetLayerTreeHost(host.get());
2043 host->Composite(base::TimeTicks::Now());
2045 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2048 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2049 : public LayerTreeHostTest {
2050 public:
2051 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2052 : root_layer_(FakeContentLayer::Create(&client_)),
2053 child_layer1_(FakeContentLayer::Create(&client_)),
2054 child_layer2_(FakeContentLayer::Create(&client_)),
2055 num_commits_(0) {}
2057 void BeginTest() override {
2058 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2059 root_layer_->SetBounds(gfx::Size(100, 100));
2060 child_layer1_->SetBounds(gfx::Size(100, 100));
2061 child_layer2_->SetBounds(gfx::Size(100, 100));
2062 root_layer_->AddChild(child_layer1_);
2063 root_layer_->AddChild(child_layer2_);
2064 layer_tree_host()->SetRootLayer(root_layer_);
2065 PostSetNeedsCommitToMainThread();
2068 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2069 bool visible) override {
2070 if (visible) {
2071 // One backing should remain unevicted.
2072 EXPECT_EQ(
2073 100u * 100u * 4u * 1u,
2074 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2075 } else {
2076 EXPECT_EQ(
2077 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2080 // Make sure that contents textures are marked as having been
2081 // purged.
2082 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2083 // End the test in this state.
2084 EndTest();
2087 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2088 ++num_commits_;
2089 switch (num_commits_) {
2090 case 1:
2091 // All three backings should have memory.
2092 EXPECT_EQ(
2093 100u * 100u * 4u * 3u,
2094 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2095 // Set a new policy that will kick out 1 of the 3 resources.
2096 // Because a resource was evicted, a commit will be kicked off.
2097 host_impl->SetMemoryPolicy(
2098 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2099 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2100 1000));
2101 break;
2102 case 2:
2103 // Only two backings should have memory.
2104 EXPECT_EQ(
2105 100u * 100u * 4u * 2u,
2106 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2107 // Become backgrounded, which will cause 1 more resource to be
2108 // evicted.
2109 PostSetVisibleToMainThread(false);
2110 break;
2111 default:
2112 // No further commits should happen because this is not visible
2113 // anymore.
2114 NOTREACHED();
2115 break;
2119 void AfterTest() override {}
2121 private:
2122 FakeContentLayerClient client_;
2123 scoped_refptr<FakeContentLayer> root_layer_;
2124 scoped_refptr<FakeContentLayer> child_layer1_;
2125 scoped_refptr<FakeContentLayer> child_layer2_;
2126 int num_commits_;
2129 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2130 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2132 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2133 public:
2134 class NotificationClient : public ContentLayerClient {
2135 public:
2136 NotificationClient()
2137 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2139 void set_layer(Layer* layer) { layer_ = layer; }
2140 int paint_count() const { return paint_count_; }
2141 int lcd_notification_count() const { return lcd_notification_count_; }
2143 void PaintContents(
2144 SkCanvas* canvas,
2145 const gfx::Rect& clip,
2146 ContentLayerClient::GraphicsContextStatus gc_status) override {
2147 ++paint_count_;
2149 void DidChangeLayerCanUseLCDText() override {
2150 ++lcd_notification_count_;
2151 layer_->SetNeedsDisplay();
2153 bool FillsBoundsCompletely() const override { return false; }
2155 private:
2156 Layer* layer_;
2157 int paint_count_;
2158 int lcd_notification_count_;
2161 void SetupTree() override {
2162 scoped_refptr<Layer> root_layer;
2163 if (layer_tree_host()->settings().impl_side_painting)
2164 root_layer = PictureLayer::Create(&client_);
2165 else
2166 root_layer = ContentLayer::Create(&client_);
2167 root_layer->SetIsDrawable(true);
2168 root_layer->SetBounds(gfx::Size(1, 1));
2170 layer_tree_host()->SetRootLayer(root_layer);
2171 client_.set_layer(root_layer.get());
2173 // The expecations are based on the assumption that the default
2174 // LCD settings are:
2175 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2176 EXPECT_FALSE(root_layer->can_use_lcd_text());
2178 LayerTreeHostTest::SetupTree();
2181 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2182 void AfterTest() override {}
2184 void DidCommit() override {
2185 switch (layer_tree_host()->source_frame_number()) {
2186 case 1:
2187 // The first update consists of one LCD notification and one paint.
2188 EXPECT_EQ(1, client_.lcd_notification_count());
2189 EXPECT_EQ(1, client_.paint_count());
2190 // LCD text must have been enabled on the layer.
2191 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2192 PostSetNeedsCommitToMainThread();
2193 break;
2194 case 2:
2195 // Since nothing changed on layer, there should be no notification
2196 // or paint on the second update.
2197 EXPECT_EQ(1, client_.lcd_notification_count());
2198 EXPECT_EQ(1, client_.paint_count());
2199 // LCD text must not have changed.
2200 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2201 // Change layer opacity that should trigger lcd notification.
2202 layer_tree_host()->root_layer()->SetOpacity(.5f);
2203 // No need to request a commit - setting opacity will do it.
2204 break;
2205 default:
2206 // Verify that there is no extra commit due to layer invalidation.
2207 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
2208 // LCD notification count should have incremented due to
2209 // change in layer opacity.
2210 EXPECT_EQ(2, client_.lcd_notification_count());
2211 // Paint count should be incremented due to invalidation.
2212 EXPECT_EQ(2, client_.paint_count());
2213 // LCD text must have been disabled on the layer due to opacity.
2214 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2215 EndTest();
2216 break;
2220 private:
2221 NotificationClient client_;
2224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2226 // Verify that the BeginFrame notification is used to initiate rendering.
2227 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2228 public:
2229 void InitializeSettings(LayerTreeSettings* settings) override {
2230 settings->begin_frame_scheduling_enabled = true;
2233 void BeginTest() override {
2234 // This will trigger a SetNeedsBeginFrame which will trigger a
2235 // BeginFrame.
2236 PostSetNeedsCommitToMainThread();
2239 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2240 LayerTreeHostImpl::FrameData* frame,
2241 DrawResult draw_result) override {
2242 EndTest();
2243 return DRAW_SUCCESS;
2246 void AfterTest() override {}
2248 private:
2249 base::TimeTicks frame_time_;
2252 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2254 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2255 : public LayerTreeHostTest {
2256 public:
2257 void InitializeSettings(LayerTreeSettings* settings) override {
2258 settings->begin_frame_scheduling_enabled = true;
2259 settings->using_synchronous_renderer_compositor = true;
2262 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2264 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2265 // The BeginFrame notification is turned off now but will get enabled
2266 // once we return. End test while it's enabled.
2267 ImplThreadTaskRunner()->PostTask(
2268 FROM_HERE,
2269 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2270 base::Unretained(this)));
2273 void AfterTest() override {}
2276 MULTI_THREAD_TEST_F(
2277 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2279 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2280 protected:
2281 LayerTreeHostTestAbortedCommitDoesntStall()
2282 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2284 void InitializeSettings(LayerTreeSettings* settings) override {
2285 settings->begin_frame_scheduling_enabled = true;
2288 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2290 void DidCommit() override {
2291 commit_count_++;
2292 if (commit_count_ == 4) {
2293 // After two aborted commits, request a real commit now to make sure a
2294 // real commit following an aborted commit will still complete and
2295 // end the test even when the Impl thread is idle.
2296 layer_tree_host()->SetNeedsCommit();
2300 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2301 bool did_handle) override {
2302 commit_abort_count_++;
2303 // Initiate another abortable commit.
2304 host_impl->SetNeedsCommit();
2307 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2308 commit_complete_count_++;
2309 if (commit_complete_count_ == 1) {
2310 // Initiate an abortable commit after the first commit.
2311 host_impl->SetNeedsCommit();
2312 } else {
2313 EndTest();
2317 void AfterTest() override {
2318 EXPECT_EQ(commit_count_, 5);
2319 EXPECT_EQ(commit_abort_count_, 3);
2320 EXPECT_EQ(commit_complete_count_, 2);
2323 int commit_count_;
2324 int commit_abort_count_;
2325 int commit_complete_count_;
2328 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2329 : public LayerTreeHostTestAbortedCommitDoesntStall {
2330 void InitializeSettings(LayerTreeSettings* settings) override {
2331 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2332 settings->using_synchronous_renderer_compositor = true;
2336 MULTI_THREAD_TEST_F(
2337 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2339 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2340 : public LayerTreeHostTestAbortedCommitDoesntStall {
2341 void InitializeSettings(LayerTreeSettings* settings) override {
2342 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2343 settings->throttle_frame_production = false;
2347 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2349 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2350 : public LayerTreeHostTest {
2351 protected:
2352 void InitializeSettings(LayerTreeSettings* settings) override {
2353 settings->impl_side_painting = true;
2356 void SetupTree() override {
2357 LayerTreeHostTest::SetupTree();
2359 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2360 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2361 layer->SetBounds(gfx::Size(10, 10));
2362 layer_tree_host()->root_layer()->AddChild(layer);
2365 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2367 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2368 EndTest();
2371 void AfterTest() override {}
2373 FakeContentLayerClient client_;
2376 MULTI_THREAD_TEST_F(
2377 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2379 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2380 : public LayerTreeHostTest {
2381 public:
2382 class SetBoundsClient : public ContentLayerClient {
2383 public:
2384 SetBoundsClient() : layer_(0) {}
2386 void set_layer(Layer* layer) { layer_ = layer; }
2388 void PaintContents(
2389 SkCanvas* canvas,
2390 const gfx::Rect& clip,
2391 ContentLayerClient::GraphicsContextStatus gc_status) override {
2392 layer_->SetBounds(gfx::Size(2, 2));
2395 void DidChangeLayerCanUseLCDText() override {}
2397 bool FillsBoundsCompletely() const override { return false; }
2399 private:
2400 Layer* layer_;
2403 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2405 void SetupTree() override {
2406 if (layer_tree_host()->settings().impl_side_painting) {
2407 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_);
2408 layer_tree_host()->SetRootLayer(root_layer);
2409 } else {
2410 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2411 layer_tree_host()->SetRootLayer(root_layer);
2413 Layer* root_layer = layer_tree_host()->root_layer();
2414 root_layer->SetIsDrawable(true);
2415 root_layer->SetBounds(gfx::Size(1, 1));
2417 client_.set_layer(root_layer);
2419 LayerTreeHostTest::SetupTree();
2422 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2423 void AfterTest() override {}
2425 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2426 num_commits_++;
2427 if (num_commits_ == 1) {
2428 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2429 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2430 } else {
2431 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2432 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2433 EndTest();
2437 private:
2438 SetBoundsClient client_;
2439 int num_commits_;
2442 SINGLE_AND_MULTI_THREAD_TEST_F(
2443 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2445 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2446 public:
2447 MockIOSurfaceWebGraphicsContext3D() {
2448 test_capabilities_.gpu.iosurface = true;
2449 test_capabilities_.gpu.texture_rectangle = true;
2452 virtual GLuint createTexture() override {
2453 return 1;
2455 MOCK_METHOD1(activeTexture, void(GLenum texture));
2456 MOCK_METHOD2(bindTexture, void(GLenum target,
2457 GLuint texture_id));
2458 MOCK_METHOD3(texParameteri, void(GLenum target,
2459 GLenum pname,
2460 GLint param));
2461 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2462 GLint width,
2463 GLint height,
2464 GLuint ioSurfaceId,
2465 GLuint plane));
2466 MOCK_METHOD4(drawElements, void(GLenum mode,
2467 GLsizei count,
2468 GLenum type,
2469 GLintptr offset));
2470 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2471 MOCK_METHOD2(produceTextureCHROMIUM,
2472 void(GLenum target, const GLbyte* mailbox));
2475 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2476 protected:
2477 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
2478 bool fallback) override {
2479 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2480 new MockIOSurfaceWebGraphicsContext3D);
2481 mock_context_ = mock_context_owned.get();
2483 if (delegating_renderer())
2484 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
2485 else
2486 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
2489 void SetupTree() override {
2490 LayerTreeHostTest::SetupTree();
2492 layer_tree_host()->root_layer()->SetIsDrawable(false);
2494 io_surface_id_ = 9;
2495 io_surface_size_ = gfx::Size(6, 7);
2497 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2498 io_surface_layer->SetBounds(gfx::Size(10, 10));
2499 io_surface_layer->SetIsDrawable(true);
2500 io_surface_layer->SetContentsOpaque(true);
2501 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2502 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2505 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2507 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2508 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2509 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2511 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2512 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2513 .Times(AtLeast(1));
2514 EXPECT_CALL(*mock_context_,
2515 texParameteri(
2516 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2517 .Times(1);
2518 EXPECT_CALL(*mock_context_,
2519 texParameteri(
2520 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2521 .Times(1);
2522 EXPECT_CALL(*mock_context_,
2523 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2524 GL_TEXTURE_POOL_CHROMIUM,
2525 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2526 EXPECT_CALL(*mock_context_,
2527 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2528 GL_TEXTURE_WRAP_S,
2529 GL_CLAMP_TO_EDGE)).Times(1);
2530 EXPECT_CALL(*mock_context_,
2531 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2532 GL_TEXTURE_WRAP_T,
2533 GL_CLAMP_TO_EDGE)).Times(1);
2535 EXPECT_CALL(*mock_context_,
2536 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2537 io_surface_size_.width(),
2538 io_surface_size_.height(),
2539 io_surface_id_,
2540 0)).Times(1);
2542 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2545 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2546 LayerTreeHostImpl::FrameData* frame,
2547 DrawResult draw_result) override {
2548 Mock::VerifyAndClearExpectations(&mock_context_);
2549 ResourceProvider* resource_provider = host_impl->resource_provider();
2550 EXPECT_EQ(1u, resource_provider->num_resources());
2551 CHECK_EQ(1u, frame->render_passes.size());
2552 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2553 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
2554 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2555 const IOSurfaceDrawQuad* io_surface_draw_quad =
2556 IOSurfaceDrawQuad::MaterialCast(quad);
2557 EXPECT_SIZE_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2558 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
2559 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2560 resource_provider->TargetForTesting(
2561 io_surface_draw_quad->io_surface_resource_id));
2563 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2564 .Times(1);
2565 if (delegating_renderer()) {
2566 // The io surface layer's resource should be sent to the parent.
2567 EXPECT_CALL(*mock_context_,
2568 produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2569 } else {
2570 // The io surface layer's texture is drawn.
2571 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2572 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2573 .Times(AtLeast(1));
2576 return draw_result;
2579 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2580 Mock::VerifyAndClearExpectations(&mock_context_);
2582 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2583 EndTest();
2586 void AfterTest() override {}
2588 int io_surface_id_;
2589 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2590 gfx::Size io_surface_size_;
2593 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2595 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2596 public:
2597 void BeginTest() override {
2598 frame_ = 0;
2599 PostSetNeedsCommitToMainThread();
2602 // Round 1: commit + draw
2603 // Round 2: commit only (no draw/swap)
2604 // Round 3: draw only (no commit)
2606 void DidCommit() override {
2607 int commit = layer_tree_host()->source_frame_number();
2608 switch (commit) {
2609 case 2:
2610 // Round 2 done.
2611 EXPECT_EQ(1, frame_);
2612 layer_tree_host()->SetNeedsRedraw();
2613 break;
2617 void DidCompleteSwapBuffers() override {
2618 int commit = layer_tree_host()->source_frame_number();
2619 ++frame_;
2620 switch (frame_) {
2621 case 1:
2622 // Round 1 done.
2623 EXPECT_EQ(1, commit);
2624 layer_tree_host()->SetNeedsCommit();
2625 break;
2626 case 2:
2627 // Round 3 done.
2628 EXPECT_EQ(2, commit);
2629 EndTest();
2630 break;
2634 void AfterTest() override {}
2636 protected:
2637 int frame_;
2640 // Flaky on all platforms: http://crbug.com/327498
2641 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
2642 RunTest(true, true, true);
2645 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
2646 RunTest(true, false, true);
2649 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
2650 public:
2651 void InitializeSettings(LayerTreeSettings* settings) override {
2652 // PictureLayer can only be used with impl side painting enabled.
2653 settings->impl_side_painting = true;
2656 void SetupTree() override {
2657 layer_ = FakePictureLayer::Create(&client_);
2658 // Force commits to not be aborted so new frames get drawn, otherwise
2659 // the renderer gets deferred initialized but nothing new needs drawing.
2660 layer_->set_always_update_resources(true);
2661 layer_tree_host()->SetRootLayer(layer_);
2662 LayerTreeHostTest::SetupTree();
2665 void BeginTest() override {
2666 did_initialize_gl_ = false;
2667 did_release_gl_ = false;
2668 last_source_frame_number_drawn_ = -1; // Never drawn.
2669 PostSetNeedsCommitToMainThread();
2672 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
2673 bool fallback) override {
2674 scoped_ptr<TestWebGraphicsContext3D> context3d(
2675 TestWebGraphicsContext3D::Create());
2677 return FakeOutputSurface::CreateDeferredGL(
2678 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
2679 delegating_renderer());
2682 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2683 ASSERT_TRUE(host_impl->RootLayer());
2684 FakePictureLayerImpl* layer_impl =
2685 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
2687 // The same frame can be draw multiple times if new visible tiles are
2688 // rasterized. But we want to make sure we only post DeferredInitialize
2689 // and ReleaseGL once, so early out if the same frame is drawn again.
2690 if (last_source_frame_number_drawn_ ==
2691 host_impl->active_tree()->source_frame_number())
2692 return;
2694 last_source_frame_number_drawn_ =
2695 host_impl->active_tree()->source_frame_number();
2697 if (!did_initialize_gl_) {
2698 EXPECT_LE(1u, layer_impl->append_quads_count());
2699 ImplThreadTaskRunner()->PostTask(
2700 FROM_HERE,
2701 base::Bind(
2702 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
2703 base::Unretained(this),
2704 base::Unretained(host_impl)));
2705 } else if (did_initialize_gl_ && !did_release_gl_) {
2706 EXPECT_LE(2u, layer_impl->append_quads_count());
2707 ImplThreadTaskRunner()->PostTask(
2708 FROM_HERE,
2709 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
2710 base::Unretained(this),
2711 base::Unretained(host_impl)));
2712 } else if (did_initialize_gl_ && did_release_gl_) {
2713 EXPECT_LE(3u, layer_impl->append_quads_count());
2714 EndTest();
2718 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
2719 EXPECT_FALSE(did_initialize_gl_);
2720 // SetAndInitializeContext3D calls SetNeedsCommit.
2721 FakeOutputSurface* fake_output_surface =
2722 static_cast<FakeOutputSurface*>(host_impl->output_surface());
2723 scoped_refptr<TestContextProvider> context_provider =
2724 TestContextProvider::Create(); // Not bound to thread.
2725 EXPECT_TRUE(
2726 fake_output_surface->InitializeAndSetContext3d(context_provider));
2727 did_initialize_gl_ = true;
2730 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
2731 EXPECT_TRUE(did_initialize_gl_);
2732 EXPECT_FALSE(did_release_gl_);
2733 // ReleaseGL calls SetNeedsCommit.
2734 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
2735 did_release_gl_ = true;
2738 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
2739 ASSERT_TRUE(result);
2740 DelegatedFrameData* delegated_frame_data =
2741 output_surface()->last_sent_frame().delegated_frame_data.get();
2742 if (!delegated_frame_data)
2743 return;
2745 // Return all resources immediately.
2746 TransferableResourceArray resources_to_return =
2747 output_surface()->resources_held_by_parent();
2749 CompositorFrameAck ack;
2750 for (size_t i = 0; i < resources_to_return.size(); ++i)
2751 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
2752 host_impl->ReclaimResources(&ack);
2755 void AfterTest() override {
2756 EXPECT_TRUE(did_initialize_gl_);
2757 EXPECT_TRUE(did_release_gl_);
2760 private:
2761 FakeContentLayerClient client_;
2762 scoped_refptr<FakePictureLayer> layer_;
2763 bool did_initialize_gl_;
2764 bool did_release_gl_;
2765 int last_source_frame_number_drawn_;
2768 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
2770 class LayerTreeHostTestDeferredInitializeWithGpuRasterization
2771 : public LayerTreeHostTestDeferredInitialize {
2772 void InitializeSettings(LayerTreeSettings* settings) override {
2773 // PictureLayer can only be used with impl side painting enabled.
2774 settings->impl_side_painting = true;
2775 settings->gpu_rasterization_enabled = true;
2776 settings->gpu_rasterization_forced = true;
2780 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization);
2782 // Test for UI Resource management.
2783 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
2784 public:
2785 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
2787 void InitializeSettings(LayerTreeSettings* settings) override {
2788 settings->texture_id_allocation_chunk_size = 1;
2791 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2793 void DidCommit() override {
2794 int frame = layer_tree_host()->source_frame_number();
2795 switch (frame) {
2796 case 1:
2797 CreateResource();
2798 CreateResource();
2799 PostSetNeedsCommitToMainThread();
2800 break;
2801 case 2:
2802 // Usually ScopedUIResource are deleted from the manager in their
2803 // destructor. Here we just want to test that a direct call to
2804 // DeleteUIResource works.
2805 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
2806 PostSetNeedsCommitToMainThread();
2807 break;
2808 case 3:
2809 // DeleteUIResource can be called with an invalid id.
2810 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
2811 PostSetNeedsCommitToMainThread();
2812 break;
2813 case 4:
2814 CreateResource();
2815 CreateResource();
2816 PostSetNeedsCommitToMainThread();
2817 break;
2818 case 5:
2819 ClearResources();
2820 EndTest();
2821 break;
2825 void PerformTest(LayerTreeHostImpl* impl) {
2826 TestWebGraphicsContext3D* context = TestContext();
2828 int frame = impl->active_tree()->source_frame_number();
2829 switch (frame) {
2830 case 0:
2831 ASSERT_EQ(0u, context->NumTextures());
2832 break;
2833 case 1:
2834 // Created two textures.
2835 ASSERT_EQ(2u, context->NumTextures());
2836 break;
2837 case 2:
2838 // One texture left after one deletion.
2839 ASSERT_EQ(1u, context->NumTextures());
2840 break;
2841 case 3:
2842 // Resource manager state should not change when delete is called on an
2843 // invalid id.
2844 ASSERT_EQ(1u, context->NumTextures());
2845 break;
2846 case 4:
2847 // Creation after deletion: two more creates should total up to
2848 // three textures.
2849 ASSERT_EQ(3u, context->NumTextures());
2850 break;
2854 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2855 if (!layer_tree_host()->settings().impl_side_painting)
2856 PerformTest(impl);
2859 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
2860 if (layer_tree_host()->settings().impl_side_painting)
2861 PerformTest(impl);
2864 void AfterTest() override {}
2866 private:
2867 // Must clear all resources before exiting.
2868 void ClearResources() {
2869 for (int i = 0; i < num_ui_resources_; i++)
2870 ui_resources_[i] = nullptr;
2873 void CreateResource() {
2874 ui_resources_[num_ui_resources_++] =
2875 FakeScopedUIResource::Create(layer_tree_host());
2878 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
2879 int num_ui_resources_;
2882 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
2884 class PushPropertiesCountingLayerImpl : public LayerImpl {
2885 public:
2886 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
2887 LayerTreeImpl* tree_impl, int id) {
2888 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
2891 ~PushPropertiesCountingLayerImpl() override {}
2893 void PushPropertiesTo(LayerImpl* layer) override {
2894 LayerImpl::PushPropertiesTo(layer);
2895 push_properties_count_++;
2896 // Push state to the active tree because we can only access it from there.
2897 static_cast<PushPropertiesCountingLayerImpl*>(
2898 layer)->push_properties_count_ = push_properties_count_;
2901 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
2902 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
2905 size_t push_properties_count() const { return push_properties_count_; }
2906 void reset_push_properties_count() { push_properties_count_ = 0; }
2908 private:
2909 size_t push_properties_count_;
2911 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
2912 : LayerImpl(tree_impl, id),
2913 push_properties_count_(0) {
2914 SetBounds(gfx::Size(1, 1));
2918 class PushPropertiesCountingLayer : public Layer {
2919 public:
2920 static scoped_refptr<PushPropertiesCountingLayer> Create() {
2921 return new PushPropertiesCountingLayer();
2924 void PushPropertiesTo(LayerImpl* layer) override {
2925 Layer::PushPropertiesTo(layer);
2926 push_properties_count_++;
2927 if (persist_needs_push_properties_)
2928 needs_push_properties_ = true;
2931 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
2932 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
2935 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
2937 size_t push_properties_count() const { return push_properties_count_; }
2938 void reset_push_properties_count() { push_properties_count_ = 0; }
2940 void set_persist_needs_push_properties(bool persist) {
2941 persist_needs_push_properties_ = persist;
2944 private:
2945 PushPropertiesCountingLayer()
2946 : push_properties_count_(0), persist_needs_push_properties_(false) {
2947 SetBounds(gfx::Size(1, 1));
2949 ~PushPropertiesCountingLayer() override {}
2951 size_t push_properties_count_;
2952 bool persist_needs_push_properties_;
2955 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
2956 protected:
2957 void BeginTest() override {
2958 num_commits_ = 0;
2959 expected_push_properties_root_ = 0;
2960 expected_push_properties_child_ = 0;
2961 expected_push_properties_grandchild_ = 0;
2962 expected_push_properties_child2_ = 0;
2963 expected_push_properties_other_root_ = 0;
2964 expected_push_properties_leaf_layer_ = 0;
2965 PostSetNeedsCommitToMainThread();
2968 void SetupTree() override {
2969 root_ = PushPropertiesCountingLayer::Create();
2970 child_ = PushPropertiesCountingLayer::Create();
2971 child2_ = PushPropertiesCountingLayer::Create();
2972 grandchild_ = PushPropertiesCountingLayer::Create();
2973 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
2974 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
2976 root_->AddChild(child_);
2977 root_->AddChild(child2_);
2978 child_->AddChild(grandchild_);
2979 child2_->AddChild(leaf_always_pushing_layer_);
2981 other_root_ = PushPropertiesCountingLayer::Create();
2983 // Don't set the root layer here.
2984 LayerTreeHostTest::SetupTree();
2987 void DidCommitAndDrawFrame() override {
2988 ++num_commits_;
2990 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
2991 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
2992 EXPECT_EQ(expected_push_properties_grandchild_,
2993 grandchild_->push_properties_count());
2994 EXPECT_EQ(expected_push_properties_child2_,
2995 child2_->push_properties_count());
2996 EXPECT_EQ(expected_push_properties_other_root_,
2997 other_root_->push_properties_count());
2998 EXPECT_EQ(expected_push_properties_leaf_layer_,
2999 leaf_always_pushing_layer_->push_properties_count());
3001 // The scrollbar layer always needs to be pushed.
3002 if (root_->layer_tree_host()) {
3003 EXPECT_TRUE(root_->descendant_needs_push_properties());
3004 EXPECT_FALSE(root_->needs_push_properties());
3006 if (child2_->layer_tree_host()) {
3007 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3008 EXPECT_FALSE(child2_->needs_push_properties());
3010 if (leaf_always_pushing_layer_->layer_tree_host()) {
3011 EXPECT_FALSE(
3012 leaf_always_pushing_layer_->descendant_needs_push_properties());
3013 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3016 // child_ and grandchild_ don't persist their need to push properties.
3017 if (child_->layer_tree_host()) {
3018 EXPECT_FALSE(child_->descendant_needs_push_properties());
3019 EXPECT_FALSE(child_->needs_push_properties());
3021 if (grandchild_->layer_tree_host()) {
3022 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3023 EXPECT_FALSE(grandchild_->needs_push_properties());
3026 if (other_root_->layer_tree_host()) {
3027 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3028 EXPECT_FALSE(other_root_->needs_push_properties());
3031 switch (num_commits_) {
3032 case 1:
3033 layer_tree_host()->SetRootLayer(root_);
3034 // Layers added to the tree get committed.
3035 ++expected_push_properties_root_;
3036 ++expected_push_properties_child_;
3037 ++expected_push_properties_grandchild_;
3038 ++expected_push_properties_child2_;
3039 break;
3040 case 2:
3041 layer_tree_host()->SetNeedsCommit();
3042 // No layers need commit.
3043 break;
3044 case 3:
3045 layer_tree_host()->SetRootLayer(other_root_);
3046 // Layers added to the tree get committed.
3047 ++expected_push_properties_other_root_;
3048 break;
3049 case 4:
3050 layer_tree_host()->SetRootLayer(root_);
3051 // Layers added to the tree get committed.
3052 ++expected_push_properties_root_;
3053 ++expected_push_properties_child_;
3054 ++expected_push_properties_grandchild_;
3055 ++expected_push_properties_child2_;
3056 break;
3057 case 5:
3058 layer_tree_host()->SetNeedsCommit();
3059 // No layers need commit.
3060 break;
3061 case 6:
3062 child_->RemoveFromParent();
3063 // No layers need commit.
3064 break;
3065 case 7:
3066 root_->AddChild(child_);
3067 // Layers added to the tree get committed.
3068 ++expected_push_properties_child_;
3069 ++expected_push_properties_grandchild_;
3070 break;
3071 case 8:
3072 grandchild_->RemoveFromParent();
3073 // No layers need commit.
3074 break;
3075 case 9:
3076 child_->AddChild(grandchild_);
3077 // Layers added to the tree get committed.
3078 ++expected_push_properties_grandchild_;
3079 break;
3080 case 10:
3081 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3082 // No layers need commit.
3083 break;
3084 case 11:
3085 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3086 // No layers need commit.
3087 break;
3088 case 12:
3089 child_->SetPosition(gfx::Point(1, 1));
3090 // The modified layer needs commit
3091 ++expected_push_properties_child_;
3092 break;
3093 case 13:
3094 child2_->SetPosition(gfx::Point(1, 1));
3095 // The modified layer needs commit
3096 ++expected_push_properties_child2_;
3097 break;
3098 case 14:
3099 child_->RemoveFromParent();
3100 root_->AddChild(child_);
3101 // Layers added to the tree get committed.
3102 ++expected_push_properties_child_;
3103 ++expected_push_properties_grandchild_;
3104 break;
3105 case 15:
3106 grandchild_->SetPosition(gfx::Point(1, 1));
3107 // The modified layer needs commit
3108 ++expected_push_properties_grandchild_;
3109 break;
3110 case 16:
3111 // SetNeedsDisplay does not always set needs commit (so call it
3112 // explicitly), but is a property change.
3113 child_->SetNeedsDisplay();
3114 ++expected_push_properties_child_;
3115 layer_tree_host()->SetNeedsCommit();
3116 break;
3117 case 17:
3118 EndTest();
3119 break;
3122 // The leaf layer always pushes.
3123 if (leaf_always_pushing_layer_->layer_tree_host())
3124 ++expected_push_properties_leaf_layer_;
3127 void AfterTest() override {}
3129 int num_commits_;
3130 FakeContentLayerClient client_;
3131 scoped_refptr<PushPropertiesCountingLayer> root_;
3132 scoped_refptr<PushPropertiesCountingLayer> child_;
3133 scoped_refptr<PushPropertiesCountingLayer> child2_;
3134 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3135 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3136 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3137 size_t expected_push_properties_root_;
3138 size_t expected_push_properties_child_;
3139 size_t expected_push_properties_child2_;
3140 size_t expected_push_properties_grandchild_;
3141 size_t expected_push_properties_other_root_;
3142 size_t expected_push_properties_leaf_layer_;
3145 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3147 class LayerTreeHostTestImplLayersPushProperties
3148 : public LayerTreeHostTestLayersPushProperties {
3149 protected:
3150 void BeginTest() override {
3151 expected_push_properties_root_impl_ = 0;
3152 expected_push_properties_child_impl_ = 0;
3153 expected_push_properties_grandchild_impl_ = 0;
3154 expected_push_properties_child2_impl_ = 0;
3155 expected_push_properties_grandchild2_impl_ = 0;
3156 LayerTreeHostTestLayersPushProperties::BeginTest();
3159 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3160 // These commits are in response to the changes made in
3161 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3162 switch (num_commits_) {
3163 case 0:
3164 // Tree hasn't been setup yet don't bother to check anything.
3165 return;
3166 case 1:
3167 // Root gets set up, Everyone is initialized.
3168 ++expected_push_properties_root_impl_;
3169 ++expected_push_properties_child_impl_;
3170 ++expected_push_properties_grandchild_impl_;
3171 ++expected_push_properties_child2_impl_;
3172 ++expected_push_properties_grandchild2_impl_;
3173 break;
3174 case 2:
3175 // Tree doesn't change but the one leaf that always pushes is pushed.
3176 ++expected_push_properties_grandchild2_impl_;
3177 break;
3178 case 3:
3179 // Root is swapped here.
3180 // Clear the expected push properties the tree will be rebuilt.
3181 expected_push_properties_root_impl_ = 0;
3182 expected_push_properties_child_impl_ = 0;
3183 expected_push_properties_grandchild_impl_ = 0;
3184 expected_push_properties_child2_impl_ = 0;
3185 expected_push_properties_grandchild2_impl_ = 0;
3187 // Make sure the new root is pushed.
3188 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3189 host_impl->RootLayer())->push_properties_count());
3190 return;
3191 case 4:
3192 // Root is swapped back all of the layers in the tree get pushed.
3193 ++expected_push_properties_root_impl_;
3194 ++expected_push_properties_child_impl_;
3195 ++expected_push_properties_grandchild_impl_;
3196 ++expected_push_properties_child2_impl_;
3197 ++expected_push_properties_grandchild2_impl_;
3198 break;
3199 case 5:
3200 // Tree doesn't change but the one leaf that always pushes is pushed.
3201 ++expected_push_properties_grandchild2_impl_;
3202 break;
3203 case 6:
3204 // First child is removed. Structure of the tree changes here so swap
3205 // some of the values. child_impl becomes child2_impl.
3206 expected_push_properties_child_impl_ =
3207 expected_push_properties_child2_impl_;
3208 expected_push_properties_child2_impl_ = 0;
3209 // grandchild_impl becomes grandchild2_impl.
3210 expected_push_properties_grandchild_impl_ =
3211 expected_push_properties_grandchild2_impl_;
3212 expected_push_properties_grandchild2_impl_ = 0;
3214 // grandchild_impl is now the leaf that always pushes. It is pushed.
3215 ++expected_push_properties_grandchild_impl_;
3216 break;
3217 case 7:
3218 // The leaf that always pushes is pushed.
3219 ++expected_push_properties_grandchild_impl_;
3221 // Child is added back. New layers are initialized.
3222 ++expected_push_properties_grandchild2_impl_;
3223 ++expected_push_properties_child2_impl_;
3224 break;
3225 case 8:
3226 // Leaf is removed.
3227 expected_push_properties_grandchild2_impl_ = 0;
3229 // Always pushing.
3230 ++expected_push_properties_grandchild_impl_;
3231 break;
3232 case 9:
3233 // Leaf is added back
3234 ++expected_push_properties_grandchild2_impl_;
3236 // The leaf that always pushes is pushed.
3237 ++expected_push_properties_grandchild_impl_;
3238 break;
3239 case 10:
3240 // The leaf that always pushes is pushed.
3241 ++expected_push_properties_grandchild_impl_;
3242 break;
3243 case 11:
3244 // The leaf that always pushes is pushed.
3245 ++expected_push_properties_grandchild_impl_;
3246 break;
3247 case 12:
3248 // The leaf that always pushes is pushed.
3249 ++expected_push_properties_grandchild_impl_;
3251 // This child position was changed.
3252 ++expected_push_properties_child2_impl_;
3253 break;
3254 case 13:
3255 // The position of this child was changed.
3256 ++expected_push_properties_child_impl_;
3258 // The leaf that always pushes is pushed.
3259 ++expected_push_properties_grandchild_impl_;
3260 break;
3261 case 14:
3262 // Second child is removed from tree. Don't discard counts because
3263 // they are added back before commit.
3265 // The leaf that always pushes is pushed.
3266 ++expected_push_properties_grandchild_impl_;
3268 // Second child added back.
3269 ++expected_push_properties_child2_impl_;
3270 ++expected_push_properties_grandchild2_impl_;
3272 break;
3273 case 15:
3274 // The position of this child was changed.
3275 ++expected_push_properties_grandchild2_impl_;
3277 // The leaf that always pushes is pushed.
3278 ++expected_push_properties_grandchild_impl_;
3279 break;
3280 case 16:
3281 // Second child is invalidated with SetNeedsDisplay
3282 ++expected_push_properties_child2_impl_;
3284 // The leaf that always pushed is pushed.
3285 ++expected_push_properties_grandchild_impl_;
3286 break;
3289 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3290 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3291 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3292 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3293 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3295 // Pull the layers that we need from the tree assuming the same structure
3296 // as LayerTreeHostTestLayersPushProperties
3297 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3298 host_impl->RootLayer());
3300 if (root_impl_ && root_impl_->children().size() > 0) {
3301 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3302 root_impl_->children()[0]);
3304 if (child_impl_ && child_impl_->children().size() > 0)
3305 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3306 child_impl_->children()[0]);
3309 if (root_impl_ && root_impl_->children().size() > 1) {
3310 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3311 root_impl_->children()[1]);
3313 if (child2_impl_ && child2_impl_->children().size() > 0)
3314 leaf_always_pushing_layer_impl_ =
3315 static_cast<PushPropertiesCountingLayerImpl*>(
3316 child2_impl_->children()[0]);
3319 if (root_impl_)
3320 EXPECT_EQ(expected_push_properties_root_impl_,
3321 root_impl_->push_properties_count());
3322 if (child_impl_)
3323 EXPECT_EQ(expected_push_properties_child_impl_,
3324 child_impl_->push_properties_count());
3325 if (grandchild_impl_)
3326 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3327 grandchild_impl_->push_properties_count());
3328 if (child2_impl_)
3329 EXPECT_EQ(expected_push_properties_child2_impl_,
3330 child2_impl_->push_properties_count());
3331 if (leaf_always_pushing_layer_impl_)
3332 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3333 leaf_always_pushing_layer_impl_->push_properties_count());
3336 size_t expected_push_properties_root_impl_;
3337 size_t expected_push_properties_child_impl_;
3338 size_t expected_push_properties_child2_impl_;
3339 size_t expected_push_properties_grandchild_impl_;
3340 size_t expected_push_properties_grandchild2_impl_;
3343 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3344 RunTestWithImplSidePainting();
3347 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3348 : public LayerTreeHostTest {
3349 protected:
3350 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3352 void SetupTree() override {
3353 root_ = Layer::Create();
3354 root_->SetBounds(gfx::Size(1, 1));
3356 bool paint_scrollbar = true;
3357 bool has_thumb = false;
3358 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3359 paint_scrollbar, has_thumb, root_->id());
3361 root_->AddChild(scrollbar_layer_);
3363 layer_tree_host()->SetRootLayer(root_);
3364 LayerTreeHostTest::SetupTree();
3367 void DidCommitAndDrawFrame() override {
3368 switch (layer_tree_host()->source_frame_number()) {
3369 case 0:
3370 break;
3371 case 1: {
3372 // During update, the ignore_set_needs_commit_ bit is set to true to
3373 // avoid causing a second commit to be scheduled. If a property change
3374 // is made during this, however, it needs to be pushed in the upcoming
3375 // commit.
3376 scoped_ptr<base::AutoReset<bool>> ignore =
3377 scrollbar_layer_->IgnoreSetNeedsCommit();
3379 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3381 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3382 EXPECT_TRUE(root_->descendant_needs_push_properties());
3383 layer_tree_host()->SetNeedsCommit();
3385 scrollbar_layer_->reset_push_properties_count();
3386 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3387 break;
3389 case 2:
3390 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3391 EndTest();
3392 break;
3396 void AfterTest() override {}
3398 scoped_refptr<Layer> root_;
3399 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3402 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3404 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3405 protected:
3406 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3408 void SetupTree() override {
3409 root_ = PushPropertiesCountingLayer::Create();
3410 child_ = PushPropertiesCountingLayer::Create();
3411 root_->AddChild(child_);
3413 layer_tree_host()->SetRootLayer(root_);
3414 LayerTreeHostTest::SetupTree();
3417 void DidCommitAndDrawFrame() override {
3418 switch (layer_tree_host()->source_frame_number()) {
3419 case 0:
3420 break;
3421 case 1: {
3422 // During update, the ignore_set_needs_commit_ bit is set to true to
3423 // avoid causing a second commit to be scheduled. If a property change
3424 // is made during this, however, it needs to be pushed in the upcoming
3425 // commit.
3426 EXPECT_FALSE(root_->needs_push_properties());
3427 EXPECT_FALSE(child_->needs_push_properties());
3428 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3429 root_->reset_push_properties_count();
3430 child_->reset_push_properties_count();
3431 child_->SetDrawsContent(true);
3432 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3433 EXPECT_EQ(0u, root_->push_properties_count());
3434 EXPECT_EQ(0u, child_->push_properties_count());
3435 EXPECT_TRUE(root_->needs_push_properties());
3436 EXPECT_TRUE(child_->needs_push_properties());
3437 break;
3439 case 2:
3440 EXPECT_EQ(1u, root_->push_properties_count());
3441 EXPECT_EQ(1u, child_->push_properties_count());
3442 EXPECT_FALSE(root_->needs_push_properties());
3443 EXPECT_FALSE(child_->needs_push_properties());
3444 EndTest();
3445 break;
3449 void AfterTest() override {}
3451 scoped_refptr<PushPropertiesCountingLayer> root_;
3452 scoped_refptr<PushPropertiesCountingLayer> child_;
3455 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3457 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3458 : public LayerTreeHostTest {
3459 protected:
3460 void BeginTest() override {
3461 expected_push_properties_root_ = 0;
3462 expected_push_properties_child_ = 0;
3463 expected_push_properties_grandchild1_ = 0;
3464 expected_push_properties_grandchild2_ = 0;
3465 expected_push_properties_grandchild3_ = 0;
3466 PostSetNeedsCommitToMainThread();
3469 void SetupTree() override {
3470 root_ = PushPropertiesCountingLayer::Create();
3471 child_ = PushPropertiesCountingLayer::Create();
3472 grandchild1_ = PushPropertiesCountingLayer::Create();
3473 grandchild2_ = PushPropertiesCountingLayer::Create();
3474 grandchild3_ = PushPropertiesCountingLayer::Create();
3476 root_->AddChild(child_);
3477 child_->AddChild(grandchild1_);
3478 child_->AddChild(grandchild2_);
3479 child_->AddChild(grandchild3_);
3481 // Don't set the root layer here.
3482 LayerTreeHostTest::SetupTree();
3485 void AfterTest() override {}
3487 FakeContentLayerClient client_;
3488 scoped_refptr<PushPropertiesCountingLayer> root_;
3489 scoped_refptr<PushPropertiesCountingLayer> child_;
3490 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3491 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3492 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3493 size_t expected_push_properties_root_;
3494 size_t expected_push_properties_child_;
3495 size_t expected_push_properties_grandchild1_;
3496 size_t expected_push_properties_grandchild2_;
3497 size_t expected_push_properties_grandchild3_;
3500 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3501 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3502 protected:
3503 void DidCommitAndDrawFrame() override {
3504 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3505 switch (last_source_frame_number) {
3506 case 0:
3507 EXPECT_FALSE(root_->needs_push_properties());
3508 EXPECT_FALSE(root_->descendant_needs_push_properties());
3509 EXPECT_FALSE(child_->needs_push_properties());
3510 EXPECT_FALSE(child_->descendant_needs_push_properties());
3511 EXPECT_FALSE(grandchild1_->needs_push_properties());
3512 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3513 EXPECT_FALSE(grandchild2_->needs_push_properties());
3514 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3515 EXPECT_FALSE(grandchild3_->needs_push_properties());
3516 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3518 layer_tree_host()->SetRootLayer(root_);
3520 EXPECT_TRUE(root_->needs_push_properties());
3521 EXPECT_TRUE(root_->descendant_needs_push_properties());
3522 EXPECT_TRUE(child_->needs_push_properties());
3523 EXPECT_TRUE(child_->descendant_needs_push_properties());
3524 EXPECT_TRUE(grandchild1_->needs_push_properties());
3525 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3526 EXPECT_TRUE(grandchild2_->needs_push_properties());
3527 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3528 EXPECT_TRUE(grandchild3_->needs_push_properties());
3529 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3530 break;
3531 case 1:
3532 EndTest();
3533 break;
3538 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3540 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3541 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3542 protected:
3543 void DidCommitAndDrawFrame() override {
3544 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3545 switch (last_source_frame_number) {
3546 case 0:
3547 layer_tree_host()->SetRootLayer(root_);
3548 break;
3549 case 1:
3550 EXPECT_FALSE(root_->needs_push_properties());
3551 EXPECT_FALSE(root_->descendant_needs_push_properties());
3552 EXPECT_FALSE(child_->needs_push_properties());
3553 EXPECT_FALSE(child_->descendant_needs_push_properties());
3554 EXPECT_FALSE(grandchild1_->needs_push_properties());
3555 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3556 EXPECT_FALSE(grandchild2_->needs_push_properties());
3557 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3558 EXPECT_FALSE(grandchild3_->needs_push_properties());
3559 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3561 grandchild1_->RemoveFromParent();
3562 grandchild1_->SetPosition(gfx::Point(1, 1));
3564 EXPECT_FALSE(root_->needs_push_properties());
3565 EXPECT_FALSE(root_->descendant_needs_push_properties());
3566 EXPECT_FALSE(child_->needs_push_properties());
3567 EXPECT_FALSE(child_->descendant_needs_push_properties());
3568 EXPECT_FALSE(grandchild2_->needs_push_properties());
3569 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3570 EXPECT_FALSE(grandchild3_->needs_push_properties());
3571 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3573 child_->AddChild(grandchild1_);
3575 EXPECT_FALSE(root_->needs_push_properties());
3576 EXPECT_TRUE(root_->descendant_needs_push_properties());
3577 EXPECT_FALSE(child_->needs_push_properties());
3578 EXPECT_TRUE(child_->descendant_needs_push_properties());
3579 EXPECT_TRUE(grandchild1_->needs_push_properties());
3580 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3581 EXPECT_FALSE(grandchild2_->needs_push_properties());
3582 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3583 EXPECT_FALSE(grandchild3_->needs_push_properties());
3584 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3586 grandchild2_->SetPosition(gfx::Point(1, 1));
3588 EXPECT_FALSE(root_->needs_push_properties());
3589 EXPECT_TRUE(root_->descendant_needs_push_properties());
3590 EXPECT_FALSE(child_->needs_push_properties());
3591 EXPECT_TRUE(child_->descendant_needs_push_properties());
3592 EXPECT_TRUE(grandchild1_->needs_push_properties());
3593 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3594 EXPECT_TRUE(grandchild2_->needs_push_properties());
3595 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3596 EXPECT_FALSE(grandchild3_->needs_push_properties());
3597 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3599 // grandchild2_ will still need a push properties.
3600 grandchild1_->RemoveFromParent();
3602 EXPECT_FALSE(root_->needs_push_properties());
3603 EXPECT_TRUE(root_->descendant_needs_push_properties());
3604 EXPECT_FALSE(child_->needs_push_properties());
3605 EXPECT_TRUE(child_->descendant_needs_push_properties());
3607 // grandchild3_ does not need a push properties, so recursing should
3608 // no longer be needed.
3609 grandchild2_->RemoveFromParent();
3611 EXPECT_FALSE(root_->needs_push_properties());
3612 EXPECT_FALSE(root_->descendant_needs_push_properties());
3613 EXPECT_FALSE(child_->needs_push_properties());
3614 EXPECT_FALSE(child_->descendant_needs_push_properties());
3615 EndTest();
3616 break;
3621 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3623 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3624 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3625 protected:
3626 void DidCommitAndDrawFrame() override {
3627 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3628 switch (last_source_frame_number) {
3629 case 0:
3630 layer_tree_host()->SetRootLayer(root_);
3631 grandchild1_->set_persist_needs_push_properties(true);
3632 grandchild2_->set_persist_needs_push_properties(true);
3633 break;
3634 case 1:
3635 EXPECT_FALSE(root_->needs_push_properties());
3636 EXPECT_TRUE(root_->descendant_needs_push_properties());
3637 EXPECT_FALSE(child_->needs_push_properties());
3638 EXPECT_TRUE(child_->descendant_needs_push_properties());
3639 EXPECT_TRUE(grandchild1_->needs_push_properties());
3640 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3641 EXPECT_TRUE(grandchild2_->needs_push_properties());
3642 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3643 EXPECT_FALSE(grandchild3_->needs_push_properties());
3644 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3646 // grandchild2_ will still need a push properties.
3647 grandchild1_->RemoveFromParent();
3649 EXPECT_FALSE(root_->needs_push_properties());
3650 EXPECT_TRUE(root_->descendant_needs_push_properties());
3651 EXPECT_FALSE(child_->needs_push_properties());
3652 EXPECT_TRUE(child_->descendant_needs_push_properties());
3654 // grandchild3_ does not need a push properties, so recursing should
3655 // no longer be needed.
3656 grandchild2_->RemoveFromParent();
3658 EXPECT_FALSE(root_->needs_push_properties());
3659 EXPECT_FALSE(root_->descendant_needs_push_properties());
3660 EXPECT_FALSE(child_->needs_push_properties());
3661 EXPECT_FALSE(child_->descendant_needs_push_properties());
3662 EndTest();
3663 break;
3668 MULTI_THREAD_TEST_F(
3669 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3671 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3672 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3673 protected:
3674 void DidCommitAndDrawFrame() override {
3675 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3676 switch (last_source_frame_number) {
3677 case 0:
3678 layer_tree_host()->SetRootLayer(root_);
3679 break;
3680 case 1:
3681 EXPECT_FALSE(root_->needs_push_properties());
3682 EXPECT_FALSE(root_->descendant_needs_push_properties());
3683 EXPECT_FALSE(child_->needs_push_properties());
3684 EXPECT_FALSE(child_->descendant_needs_push_properties());
3685 EXPECT_FALSE(grandchild1_->needs_push_properties());
3686 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3687 EXPECT_FALSE(grandchild2_->needs_push_properties());
3688 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3689 EXPECT_FALSE(grandchild3_->needs_push_properties());
3690 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3692 // Change grandchildren while their parent is not in the tree.
3693 child_->RemoveFromParent();
3694 grandchild1_->SetPosition(gfx::Point(1, 1));
3695 grandchild2_->SetPosition(gfx::Point(1, 1));
3696 root_->AddChild(child_);
3698 EXPECT_FALSE(root_->needs_push_properties());
3699 EXPECT_TRUE(root_->descendant_needs_push_properties());
3700 EXPECT_TRUE(child_->needs_push_properties());
3701 EXPECT_TRUE(child_->descendant_needs_push_properties());
3702 EXPECT_TRUE(grandchild1_->needs_push_properties());
3703 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3704 EXPECT_TRUE(grandchild2_->needs_push_properties());
3705 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3706 EXPECT_TRUE(grandchild3_->needs_push_properties());
3707 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3709 grandchild1_->RemoveFromParent();
3711 EXPECT_FALSE(root_->needs_push_properties());
3712 EXPECT_TRUE(root_->descendant_needs_push_properties());
3713 EXPECT_TRUE(child_->needs_push_properties());
3714 EXPECT_TRUE(child_->descendant_needs_push_properties());
3716 grandchild2_->RemoveFromParent();
3718 EXPECT_FALSE(root_->needs_push_properties());
3719 EXPECT_TRUE(root_->descendant_needs_push_properties());
3720 EXPECT_TRUE(child_->needs_push_properties());
3721 EXPECT_TRUE(child_->descendant_needs_push_properties());
3723 grandchild3_->RemoveFromParent();
3725 EXPECT_FALSE(root_->needs_push_properties());
3726 EXPECT_TRUE(root_->descendant_needs_push_properties());
3727 EXPECT_TRUE(child_->needs_push_properties());
3728 EXPECT_FALSE(child_->descendant_needs_push_properties());
3730 EndTest();
3731 break;
3736 MULTI_THREAD_TEST_F(
3737 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3739 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3740 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3741 protected:
3742 void DidCommitAndDrawFrame() override {
3743 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3744 switch (last_source_frame_number) {
3745 case 0:
3746 layer_tree_host()->SetRootLayer(root_);
3747 break;
3748 case 1:
3749 EXPECT_FALSE(root_->needs_push_properties());
3750 EXPECT_FALSE(root_->descendant_needs_push_properties());
3751 EXPECT_FALSE(child_->needs_push_properties());
3752 EXPECT_FALSE(child_->descendant_needs_push_properties());
3753 EXPECT_FALSE(grandchild1_->needs_push_properties());
3754 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3755 EXPECT_FALSE(grandchild2_->needs_push_properties());
3756 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3757 EXPECT_FALSE(grandchild3_->needs_push_properties());
3758 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3760 child_->SetPosition(gfx::Point(1, 1));
3761 grandchild1_->SetPosition(gfx::Point(1, 1));
3762 grandchild2_->SetPosition(gfx::Point(1, 1));
3764 EXPECT_FALSE(root_->needs_push_properties());
3765 EXPECT_TRUE(root_->descendant_needs_push_properties());
3766 EXPECT_TRUE(child_->needs_push_properties());
3767 EXPECT_TRUE(child_->descendant_needs_push_properties());
3768 EXPECT_TRUE(grandchild1_->needs_push_properties());
3769 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3770 EXPECT_TRUE(grandchild2_->needs_push_properties());
3771 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3772 EXPECT_FALSE(grandchild3_->needs_push_properties());
3773 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3775 grandchild1_->RemoveFromParent();
3777 EXPECT_FALSE(root_->needs_push_properties());
3778 EXPECT_TRUE(root_->descendant_needs_push_properties());
3779 EXPECT_TRUE(child_->needs_push_properties());
3780 EXPECT_TRUE(child_->descendant_needs_push_properties());
3782 grandchild2_->RemoveFromParent();
3784 EXPECT_FALSE(root_->needs_push_properties());
3785 EXPECT_TRUE(root_->descendant_needs_push_properties());
3786 EXPECT_TRUE(child_->needs_push_properties());
3787 EXPECT_FALSE(child_->descendant_needs_push_properties());
3789 child_->RemoveFromParent();
3791 EXPECT_FALSE(root_->needs_push_properties());
3792 EXPECT_FALSE(root_->descendant_needs_push_properties());
3794 EndTest();
3795 break;
3800 MULTI_THREAD_TEST_F(
3801 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
3803 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
3804 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3805 protected:
3806 void DidCommitAndDrawFrame() override {
3807 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3808 switch (last_source_frame_number) {
3809 case 0:
3810 layer_tree_host()->SetRootLayer(root_);
3811 break;
3812 case 1:
3813 EXPECT_FALSE(root_->needs_push_properties());
3814 EXPECT_FALSE(root_->descendant_needs_push_properties());
3815 EXPECT_FALSE(child_->needs_push_properties());
3816 EXPECT_FALSE(child_->descendant_needs_push_properties());
3817 EXPECT_FALSE(grandchild1_->needs_push_properties());
3818 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3819 EXPECT_FALSE(grandchild2_->needs_push_properties());
3820 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3821 EXPECT_FALSE(grandchild3_->needs_push_properties());
3822 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3824 grandchild1_->SetPosition(gfx::Point(1, 1));
3825 grandchild2_->SetPosition(gfx::Point(1, 1));
3826 child_->SetPosition(gfx::Point(1, 1));
3828 EXPECT_FALSE(root_->needs_push_properties());
3829 EXPECT_TRUE(root_->descendant_needs_push_properties());
3830 EXPECT_TRUE(child_->needs_push_properties());
3831 EXPECT_TRUE(child_->descendant_needs_push_properties());
3832 EXPECT_TRUE(grandchild1_->needs_push_properties());
3833 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3834 EXPECT_TRUE(grandchild2_->needs_push_properties());
3835 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3836 EXPECT_FALSE(grandchild3_->needs_push_properties());
3837 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3839 grandchild1_->RemoveFromParent();
3841 EXPECT_FALSE(root_->needs_push_properties());
3842 EXPECT_TRUE(root_->descendant_needs_push_properties());
3843 EXPECT_TRUE(child_->needs_push_properties());
3844 EXPECT_TRUE(child_->descendant_needs_push_properties());
3846 grandchild2_->RemoveFromParent();
3848 EXPECT_FALSE(root_->needs_push_properties());
3849 EXPECT_TRUE(root_->descendant_needs_push_properties());
3850 EXPECT_TRUE(child_->needs_push_properties());
3851 EXPECT_FALSE(child_->descendant_needs_push_properties());
3853 child_->RemoveFromParent();
3855 EXPECT_FALSE(root_->needs_push_properties());
3856 EXPECT_FALSE(root_->descendant_needs_push_properties());
3858 EndTest();
3859 break;
3864 MULTI_THREAD_TEST_F(
3865 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
3867 // This test verifies that the tree activation callback is invoked correctly.
3868 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
3869 public:
3870 LayerTreeHostTestTreeActivationCallback()
3871 : num_commits_(0), callback_count_(0) {}
3873 void BeginTest() override {
3874 EXPECT_TRUE(HasImplThread());
3875 PostSetNeedsCommitToMainThread();
3878 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3879 LayerTreeHostImpl::FrameData* frame_data,
3880 DrawResult draw_result) override {
3881 ++num_commits_;
3882 switch (num_commits_) {
3883 case 1:
3884 EXPECT_EQ(0, callback_count_);
3885 callback_count_ = 0;
3886 SetCallback(true);
3887 PostSetNeedsCommitToMainThread();
3888 break;
3889 case 2:
3890 EXPECT_EQ(1, callback_count_);
3891 callback_count_ = 0;
3892 SetCallback(false);
3893 PostSetNeedsCommitToMainThread();
3894 break;
3895 case 3:
3896 EXPECT_EQ(0, callback_count_);
3897 callback_count_ = 0;
3898 EndTest();
3899 break;
3900 default:
3901 ADD_FAILURE() << num_commits_;
3902 EndTest();
3903 break;
3905 return LayerTreeHostTest::PrepareToDrawOnThread(
3906 host_impl, frame_data, draw_result);
3909 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
3911 void SetCallback(bool enable) {
3912 output_surface()->SetTreeActivationCallback(
3913 enable
3914 ? base::Bind(
3915 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
3916 base::Unretained(this))
3917 : base::Closure());
3920 void ActivationCallback() { ++callback_count_; }
3922 int num_commits_;
3923 int callback_count_;
3926 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
3927 RunTest(true, false, true);
3930 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
3931 RunTest(true, true, true);
3934 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
3935 public:
3936 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
3938 void BeginTest() override {
3939 ASSERT_TRUE(!!invalidate_layer_.get())
3940 << "Derived tests must set this in SetupTree";
3942 // One initial commit.
3943 PostSetNeedsCommitToMainThread();
3946 void DidCommitAndDrawFrame() override {
3947 // After commit, invalidate the layer. This should cause a commit.
3948 if (layer_tree_host()->source_frame_number() == 1)
3949 invalidate_layer_->SetNeedsDisplay();
3952 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
3953 num_draws_++;
3954 if (impl->active_tree()->source_frame_number() == 1)
3955 EndTest();
3958 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3959 num_commits_++;
3962 void AfterTest() override {
3963 EXPECT_GE(2, num_commits_);
3964 EXPECT_GE(2, num_draws_);
3967 protected:
3968 scoped_refptr<Layer> invalidate_layer_;
3970 private:
3971 int num_commits_;
3972 int num_draws_;
3975 // VideoLayer must support being invalidated and then passing that along
3976 // to the compositor thread, even though no resources are updated in
3977 // response to that invalidation.
3978 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
3979 public:
3980 void SetupTree() override {
3981 LayerTreeHostTest::SetupTree();
3982 scoped_refptr<VideoLayer> video_layer =
3983 VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
3984 video_layer->SetBounds(gfx::Size(10, 10));
3985 video_layer->SetIsDrawable(true);
3986 layer_tree_host()->root_layer()->AddChild(video_layer);
3988 invalidate_layer_ = video_layer;
3991 private:
3992 FakeVideoFrameProvider provider_;
3995 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
3997 // IOSurfaceLayer must support being invalidated and then passing that along
3998 // to the compositor thread, even though no resources are updated in
3999 // response to that invalidation.
4000 class LayerTreeHostTestIOSurfaceLayerInvalidate
4001 : public LayerInvalidateCausesDraw {
4002 public:
4003 void SetupTree() override {
4004 LayerTreeHostTest::SetupTree();
4005 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4006 layer->SetBounds(gfx::Size(10, 10));
4007 uint32_t fake_io_surface_id = 7;
4008 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4009 layer->SetIsDrawable(true);
4010 layer_tree_host()->root_layer()->AddChild(layer);
4012 invalidate_layer_ = layer;
4016 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4017 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4018 LayerTreeHostTestIOSurfaceLayerInvalidate);
4020 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4021 protected:
4022 void SetupTree() override {
4023 root_layer_ = Layer::Create();
4024 root_layer_->SetPosition(gfx::Point());
4025 root_layer_->SetBounds(gfx::Size(10, 10));
4027 parent_layer_ = SolidColorLayer::Create();
4028 parent_layer_->SetPosition(gfx::Point());
4029 parent_layer_->SetBounds(gfx::Size(10, 10));
4030 parent_layer_->SetIsDrawable(true);
4031 root_layer_->AddChild(parent_layer_);
4033 child_layer_ = SolidColorLayer::Create();
4034 child_layer_->SetPosition(gfx::Point());
4035 child_layer_->SetBounds(gfx::Size(10, 10));
4036 child_layer_->SetIsDrawable(true);
4037 parent_layer_->AddChild(child_layer_);
4039 layer_tree_host()->SetRootLayer(root_layer_);
4040 LayerTreeHostTest::SetupTree();
4043 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4045 void DidCommitAndDrawFrame() override {
4046 switch (layer_tree_host()->source_frame_number()) {
4047 case 1:
4048 // The layer type used does not need to push properties every frame.
4049 EXPECT_FALSE(child_layer_->needs_push_properties());
4051 // Change the bounds of the child layer, but make it skipped
4052 // by CalculateDrawProperties.
4053 parent_layer_->SetOpacity(0.f);
4054 child_layer_->SetBounds(gfx::Size(5, 5));
4055 break;
4056 case 2:
4057 // The bounds of the child layer were pushed to the impl side.
4058 EXPECT_FALSE(child_layer_->needs_push_properties());
4060 EndTest();
4061 break;
4065 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4066 LayerImpl* root = impl->active_tree()->root_layer();
4067 LayerImpl* parent = root->children()[0];
4068 LayerImpl* child = parent->children()[0];
4070 switch (impl->active_tree()->source_frame_number()) {
4071 case 1:
4072 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4073 break;
4077 void AfterTest() override {}
4079 scoped_refptr<Layer> root_layer_;
4080 scoped_refptr<SolidColorLayer> parent_layer_;
4081 scoped_refptr<SolidColorLayer> child_layer_;
4084 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4086 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4087 protected:
4088 void InitializeSettings(LayerTreeSettings* settings) override {
4089 settings->impl_side_painting = true;
4092 void SetupTree() override {
4093 root_layer_ = FakePictureLayer::Create(&client_);
4094 root_layer_->SetBounds(gfx::Size(10, 10));
4096 layer_tree_host()->SetRootLayer(root_layer_);
4097 LayerTreeHostTest::SetupTree();
4100 void BeginTest() override {
4101 // The viewport is empty, but we still need to update layers on the main
4102 // thread.
4103 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4104 PostSetNeedsCommitToMainThread();
4107 void DidCommit() override {
4108 // The layer should be updated even though the viewport is empty, so we
4109 // are capable of drawing it on the impl tree.
4110 EXPECT_GT(root_layer_->update_count(), 0u);
4111 EndTest();
4114 void AfterTest() override {}
4116 FakeContentLayerClient client_;
4117 scoped_refptr<FakePictureLayer> root_layer_;
4120 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4122 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4123 public:
4124 LayerTreeHostTestAbortEvictedTextures()
4125 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4127 protected:
4128 void SetupTree() override {
4129 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4130 root_layer->SetBounds(gfx::Size(200, 200));
4131 root_layer->SetIsDrawable(true);
4133 layer_tree_host()->SetRootLayer(root_layer);
4134 LayerTreeHostTest::SetupTree();
4137 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4139 void WillBeginMainFrame() override {
4140 num_will_begin_main_frames_++;
4141 switch (num_will_begin_main_frames_) {
4142 case 2:
4143 // Send a redraw to the compositor thread. This will (wrongly) be
4144 // ignored unless aborting resets the texture state.
4145 layer_tree_host()->SetNeedsRedraw();
4146 break;
4150 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
4151 num_impl_commits_++;
4154 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4155 switch (impl->SourceAnimationFrameNumber()) {
4156 case 1:
4157 // Prevent draws until commit.
4158 impl->active_tree()->SetContentsTexturesPurged();
4159 EXPECT_FALSE(impl->CanDraw());
4160 // Trigger an abortable commit.
4161 impl->SetNeedsCommit();
4162 break;
4163 case 2:
4164 EndTest();
4165 break;
4169 void AfterTest() override {
4170 // Ensure that the commit was truly aborted.
4171 EXPECT_EQ(2, num_will_begin_main_frames_);
4172 EXPECT_EQ(1, num_impl_commits_);
4175 private:
4176 int num_will_begin_main_frames_;
4177 int num_impl_commits_;
4180 // Commits can only be aborted when using the thread proxy.
4181 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4183 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4184 protected:
4185 void InitializeSettings(LayerTreeSettings* settings) override {
4186 settings->impl_side_painting = true;
4189 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
4190 bool fallback) override {
4191 scoped_refptr<TestContextProvider> context_provider =
4192 TestContextProvider::Create();
4193 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
4194 if (delegating_renderer())
4195 return FakeOutputSurface::CreateDelegating3d(context_provider);
4196 else
4197 return FakeOutputSurface::Create3d(context_provider);
4200 void SetupTree() override {
4201 client_.set_fill_with_nonsolid_color(true);
4202 scoped_refptr<FakePictureLayer> root_layer =
4203 FakePictureLayer::Create(&client_);
4204 root_layer->SetBounds(gfx::Size(6000, 6000));
4205 root_layer->SetIsDrawable(true);
4207 layer_tree_host()->SetRootLayer(root_layer);
4208 LayerTreeHostTest::SetupTree();
4211 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4213 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4214 TestWebGraphicsContext3D* context = TestContext();
4216 // Expect that the transfer buffer memory used is equal to the
4217 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4218 EXPECT_EQ(1024 * 1024u, context->max_used_transfer_buffer_usage_bytes());
4219 EndTest();
4222 void AfterTest() override {}
4224 private:
4225 FakeContentLayerClient client_;
4228 // Impl-side painting is a multi-threaded compositor feature.
4229 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4231 // Test ensuring that memory limits are sent to the prioritized resource
4232 // manager.
4233 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4234 public:
4235 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4237 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4239 void WillCommit() override {
4240 // Some commits are aborted, so increment number of attempted commits here.
4241 num_commits_++;
4244 void DidCommit() override {
4245 switch (num_commits_) {
4246 case 1:
4247 // Verify default values.
4248 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4249 layer_tree_host()
4250 ->contents_texture_manager()
4251 ->MaxMemoryLimitBytes());
4252 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4253 layer_tree_host()
4254 ->contents_texture_manager()
4255 ->ExternalPriorityCutoff());
4256 PostSetNeedsCommitToMainThread();
4257 break;
4258 case 2:
4259 // The values should remain the same until the commit after the policy
4260 // is changed.
4261 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4262 layer_tree_host()
4263 ->contents_texture_manager()
4264 ->MaxMemoryLimitBytes());
4265 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4266 layer_tree_host()
4267 ->contents_texture_manager()
4268 ->ExternalPriorityCutoff());
4269 break;
4270 case 3:
4271 // Verify values were correctly passed.
4272 EXPECT_EQ(16u * 1024u * 1024u,
4273 layer_tree_host()
4274 ->contents_texture_manager()
4275 ->MaxMemoryLimitBytes());
4276 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4277 layer_tree_host()
4278 ->contents_texture_manager()
4279 ->ExternalPriorityCutoff());
4280 EndTest();
4281 break;
4282 case 4:
4283 // Make sure no extra commits happen.
4284 NOTREACHED();
4285 break;
4289 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4290 switch (num_commits_) {
4291 case 1:
4292 break;
4293 case 2:
4294 // This will trigger a commit because the priority cutoff has changed.
4295 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4296 16u * 1024u * 1024u,
4297 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4298 1000));
4299 break;
4300 case 3:
4301 // This will not trigger a commit because the priority cutoff has not
4302 // changed, and there is already enough memory for all allocations.
4303 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4304 32u * 1024u * 1024u,
4305 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4306 1000));
4307 break;
4308 case 4:
4309 NOTREACHED();
4310 break;
4314 void AfterTest() override {}
4316 private:
4317 int num_commits_;
4320 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4322 } // namespace
4324 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4325 : public LayerTreeHostTest {
4326 protected:
4327 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4328 : first_output_surface_memory_limit_(4321234),
4329 second_output_surface_memory_limit_(1234321) {}
4331 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
4332 bool fallback) override {
4333 if (!first_context_provider_.get()) {
4334 first_context_provider_ = TestContextProvider::Create();
4335 } else {
4336 EXPECT_FALSE(second_context_provider_.get());
4337 second_context_provider_ = TestContextProvider::Create();
4340 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4341 ? second_context_provider_
4342 : first_context_provider_);
4343 scoped_ptr<FakeOutputSurface> output_surface;
4344 if (delegating_renderer())
4345 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4346 else
4347 output_surface = FakeOutputSurface::Create3d(provider);
4348 output_surface->SetMemoryPolicyToSetAtBind(
4349 make_scoped_ptr(new ManagedMemoryPolicy(
4350 second_context_provider_.get() ? second_output_surface_memory_limit_
4351 : first_output_surface_memory_limit_,
4352 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4353 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4354 return output_surface.Pass();
4357 void SetupTree() override {
4358 root_ = FakeContentLayer::Create(&client_);
4359 root_->SetBounds(gfx::Size(20, 20));
4360 layer_tree_host()->SetRootLayer(root_);
4361 LayerTreeHostTest::SetupTree();
4364 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4366 void DidCommitAndDrawFrame() override {
4367 // Lost context sometimes takes two frames to recreate. The third frame
4368 // is sometimes aborted, so wait until the fourth frame to verify that
4369 // the memory has been set, and the fifth frame to end the test.
4370 if (layer_tree_host()->source_frame_number() < 5) {
4371 layer_tree_host()->SetNeedsCommit();
4372 } else if (layer_tree_host()->source_frame_number() == 5) {
4373 EndTest();
4377 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
4378 switch (impl->active_tree()->source_frame_number()) {
4379 case 1:
4380 EXPECT_EQ(first_output_surface_memory_limit_,
4381 impl->memory_allocation_limit_bytes());
4382 // Lose the output surface.
4383 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4384 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4385 break;
4386 case 4:
4387 EXPECT_EQ(second_output_surface_memory_limit_,
4388 impl->memory_allocation_limit_bytes());
4389 break;
4393 void AfterTest() override {}
4395 scoped_refptr<TestContextProvider> first_context_provider_;
4396 scoped_refptr<TestContextProvider> second_context_provider_;
4397 size_t first_output_surface_memory_limit_;
4398 size_t second_output_surface_memory_limit_;
4399 FakeContentLayerClient client_;
4400 scoped_refptr<FakeContentLayer> root_;
4403 // No output to copy for delegated renderers.
4404 SINGLE_AND_MULTI_THREAD_TEST_F(
4405 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4407 struct TestSwapPromiseResult {
4408 TestSwapPromiseResult()
4409 : did_swap_called(false),
4410 did_not_swap_called(false),
4411 dtor_called(false),
4412 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4414 bool did_swap_called;
4415 bool did_not_swap_called;
4416 bool dtor_called;
4417 SwapPromise::DidNotSwapReason reason;
4418 base::Lock lock;
4421 class TestSwapPromise : public SwapPromise {
4422 public:
4423 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4425 ~TestSwapPromise() override {
4426 base::AutoLock lock(result_->lock);
4427 result_->dtor_called = true;
4430 void DidSwap(CompositorFrameMetadata* metadata) override {
4431 base::AutoLock lock(result_->lock);
4432 EXPECT_FALSE(result_->did_swap_called);
4433 EXPECT_FALSE(result_->did_not_swap_called);
4434 result_->did_swap_called = true;
4437 void DidNotSwap(DidNotSwapReason reason) override {
4438 base::AutoLock lock(result_->lock);
4439 EXPECT_FALSE(result_->did_swap_called);
4440 EXPECT_FALSE(result_->did_not_swap_called);
4441 result_->did_not_swap_called = true;
4442 result_->reason = reason;
4445 int64 TraceId() const override { return 0; }
4447 private:
4448 // Not owned.
4449 TestSwapPromiseResult* result_;
4452 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4453 protected:
4454 LayerTreeHostTestBreakSwapPromise()
4455 : commit_count_(0), commit_complete_count_(0) {}
4457 void WillBeginMainFrame() override {
4458 ASSERT_LE(commit_count_, 2);
4459 scoped_ptr<SwapPromise> swap_promise(
4460 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4461 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4464 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4466 void DidCommit() override {
4467 commit_count_++;
4468 if (commit_count_ == 2) {
4469 // This commit will finish.
4470 layer_tree_host()->SetNeedsCommit();
4474 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4475 commit_complete_count_++;
4476 if (commit_complete_count_ == 1) {
4477 // This commit will be aborted because no actual update.
4478 PostSetNeedsUpdateLayersToMainThread();
4479 } else {
4480 EndTest();
4484 void AfterTest() override {
4485 // 3 commits are scheduled. 2 completes. 1 is aborted.
4486 EXPECT_EQ(commit_count_, 3);
4487 EXPECT_EQ(commit_complete_count_, 2);
4490 // The first commit completes and causes swap buffer which finishes
4491 // the promise.
4492 base::AutoLock lock(swap_promise_result_[0].lock);
4493 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4494 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4495 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4499 // The second commit is aborted since it contains no updates.
4500 base::AutoLock lock(swap_promise_result_[1].lock);
4501 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4502 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4503 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
4504 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4508 // The last commit completes but it does not cause swap buffer because
4509 // there is no damage in the frame data.
4510 base::AutoLock lock(swap_promise_result_[2].lock);
4511 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4512 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4513 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4514 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4518 int commit_count_;
4519 int commit_complete_count_;
4520 TestSwapPromiseResult swap_promise_result_[3];
4523 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4525 class LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit
4526 : public LayerTreeHostTest {
4527 protected:
4528 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4530 void DidCommit() override {
4531 layer_tree_host()->SetDeferCommits(true);
4532 layer_tree_host()->SetNeedsCommit();
4535 void DidDeferCommit() override {
4536 layer_tree_host()->SetVisible(false);
4537 scoped_ptr<SwapPromise> swap_promise(
4538 new TestSwapPromise(&swap_promise_result_));
4539 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4540 layer_tree_host()->SetDeferCommits(false);
4543 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4544 bool did_handle) override {
4545 EndTest();
4548 void AfterTest() override {
4550 base::AutoLock lock(swap_promise_result_.lock);
4551 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4552 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4553 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4554 EXPECT_TRUE(swap_promise_result_.dtor_called);
4558 TestSwapPromiseResult swap_promise_result_;
4561 SINGLE_AND_MULTI_THREAD_TEST_F(
4562 LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit);
4564 class LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit
4565 : public LayerTreeHostTest {
4566 protected:
4567 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4569 void DidCommit() override {
4570 if (TestEnded())
4571 return;
4572 layer_tree_host()->SetDeferCommits(true);
4573 layer_tree_host()->SetNeedsCommit();
4576 void DidDeferCommit() override {
4577 layer_tree_host()->DidLoseOutputSurface();
4578 scoped_ptr<SwapPromise> swap_promise(
4579 new TestSwapPromise(&swap_promise_result_));
4580 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4581 layer_tree_host()->SetDeferCommits(false);
4584 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4585 bool did_handle) override {
4586 EndTest();
4587 // This lets the test finally commit and exit.
4588 MainThreadTaskRunner()->PostTask(
4589 FROM_HERE,
4590 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit::
4591 FindOutputSurface,
4592 base::Unretained(this)));
4595 void FindOutputSurface() {
4596 layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(true);
4599 void AfterTest() override {
4601 base::AutoLock lock(swap_promise_result_.lock);
4602 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4603 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4604 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4605 EXPECT_TRUE(swap_promise_result_.dtor_called);
4609 TestSwapPromiseResult swap_promise_result_;
4612 SINGLE_AND_MULTI_THREAD_TEST_F(
4613 LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit);
4615 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
4616 public:
4617 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
4618 LayerTreeHostImpl* layer_tree_host_impl,
4619 int* set_needs_commit_count,
4620 int* set_needs_redraw_count)
4621 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
4622 set_needs_commit_count_(set_needs_commit_count) {}
4624 ~SimpleSwapPromiseMonitor() override {}
4626 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
4628 void OnSetNeedsRedrawOnImpl() override {
4629 ADD_FAILURE() << "Should not get called on main thread.";
4632 void OnForwardScrollUpdateToMainThreadOnImpl() override {
4633 ADD_FAILURE() << "Should not get called on main thread.";
4636 private:
4637 int* set_needs_commit_count_;
4640 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
4641 public:
4642 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4644 void WillBeginMainFrame() override {
4645 if (TestEnded())
4646 return;
4648 int set_needs_commit_count = 0;
4649 int set_needs_redraw_count = 0;
4652 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4653 new SimpleSwapPromiseMonitor(layer_tree_host(),
4654 NULL,
4655 &set_needs_commit_count,
4656 &set_needs_redraw_count));
4657 layer_tree_host()->SetNeedsCommit();
4658 EXPECT_EQ(1, set_needs_commit_count);
4659 EXPECT_EQ(0, set_needs_redraw_count);
4662 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
4663 // monitored.
4664 layer_tree_host()->SetNeedsCommit();
4665 EXPECT_EQ(1, set_needs_commit_count);
4666 EXPECT_EQ(0, set_needs_redraw_count);
4669 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4670 new SimpleSwapPromiseMonitor(layer_tree_host(),
4671 NULL,
4672 &set_needs_commit_count,
4673 &set_needs_redraw_count));
4674 layer_tree_host()->SetNeedsUpdateLayers();
4675 EXPECT_EQ(2, set_needs_commit_count);
4676 EXPECT_EQ(0, set_needs_redraw_count);
4680 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4681 new SimpleSwapPromiseMonitor(layer_tree_host(),
4682 NULL,
4683 &set_needs_commit_count,
4684 &set_needs_redraw_count));
4685 layer_tree_host()->SetNeedsAnimate();
4686 EXPECT_EQ(3, set_needs_commit_count);
4687 EXPECT_EQ(0, set_needs_redraw_count);
4690 EndTest();
4693 void AfterTest() override {}
4696 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
4698 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
4699 : public LayerTreeHostTest {
4700 protected:
4701 void InitializeSettings(LayerTreeSettings* settings) override {
4702 settings->impl_side_painting = true;
4705 void SetupTree() override {
4706 LayerTreeHostTest::SetupTree();
4707 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
4710 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4712 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4713 host_impl->EvictAllUIResources();
4714 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
4715 // mode. Active tree should require high-res to draw after entering this
4716 // mode to ensure that high-res tiles are also required for a pending tree
4717 // to be activated.
4718 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
4721 void DidCommit() override {
4722 int frame = layer_tree_host()->source_frame_number();
4723 switch (frame) {
4724 case 1:
4725 PostSetNeedsCommitToMainThread();
4726 break;
4727 case 2:
4728 ui_resource_ = nullptr;
4729 EndTest();
4730 break;
4734 void AfterTest() override {}
4736 FakeContentLayerClient client_;
4737 scoped_ptr<FakeScopedUIResource> ui_resource_;
4740 // This test is flaky, see http://crbug.com/386199
4741 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
4743 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
4744 protected:
4745 void InitializeSettings(LayerTreeSettings* settings) override {
4746 settings->impl_side_painting = true;
4748 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4749 EXPECT_FALSE(settings->gpu_rasterization_forced);
4752 void SetupTree() override {
4753 LayerTreeHostTest::SetupTree();
4755 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4756 layer->SetBounds(gfx::Size(10, 10));
4757 layer->SetIsDrawable(true);
4758 layer_tree_host()->root_layer()->AddChild(layer);
4761 void BeginTest() override {
4762 Layer* root = layer_tree_host()->root_layer();
4763 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4764 PicturePile* pile = layer->GetPicturePileForTesting();
4766 // Verify default values.
4767 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4768 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4769 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4770 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4771 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4773 // Setting gpu rasterization trigger does not enable gpu rasterization.
4774 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4775 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4776 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4778 PostSetNeedsCommitToMainThread();
4781 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4782 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4783 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4786 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4787 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4788 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4789 EndTest();
4792 void AfterTest() override {}
4794 FakeContentLayerClient layer_client_;
4797 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
4799 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
4800 protected:
4801 void InitializeSettings(LayerTreeSettings* settings) override {
4802 settings->impl_side_painting = true;
4804 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4805 settings->gpu_rasterization_enabled = true;
4808 void SetupTree() override {
4809 LayerTreeHostTest::SetupTree();
4811 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4812 layer->SetBounds(gfx::Size(10, 10));
4813 layer->SetIsDrawable(true);
4814 layer_tree_host()->root_layer()->AddChild(layer);
4817 void BeginTest() override {
4818 Layer* root = layer_tree_host()->root_layer();
4819 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4820 PicturePile* pile = layer->GetPicturePileForTesting();
4822 // Verify default values.
4823 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4824 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4825 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4826 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4827 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4829 // Gpu rasterization trigger is relevant.
4830 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4831 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4832 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4834 // Content-based veto is relevant as well.
4835 pile->SetUnsuitableForGpuRasterizationForTesting();
4836 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
4837 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4838 // Veto will take effect when layers are updated.
4839 // The results will be verified after commit is completed below.
4840 // Since we are manually marking picture pile as unsuitable,
4841 // make sure that the layer gets a chance to update.
4842 layer->SetNeedsDisplay();
4843 PostSetNeedsCommitToMainThread();
4846 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4847 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4848 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4851 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4852 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4853 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4854 EndTest();
4857 void AfterTest() override {}
4859 FakeContentLayerClient layer_client_;
4862 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
4864 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
4865 protected:
4866 void InitializeSettings(LayerTreeSettings* settings) override {
4867 settings->impl_side_painting = true;
4869 EXPECT_FALSE(settings->gpu_rasterization_forced);
4870 settings->gpu_rasterization_forced = true;
4873 void SetupTree() override {
4874 LayerTreeHostTest::SetupTree();
4876 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4877 layer->SetBounds(gfx::Size(10, 10));
4878 layer->SetIsDrawable(true);
4879 layer_tree_host()->root_layer()->AddChild(layer);
4882 void BeginTest() override {
4883 Layer* root = layer_tree_host()->root_layer();
4884 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4885 PicturePile* pile = layer->GetPicturePileForTesting();
4887 // Verify default values.
4888 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4889 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4890 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4891 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4893 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
4894 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4895 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4896 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4897 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4899 // Content-based veto is irrelevant as well.
4900 pile->SetUnsuitableForGpuRasterizationForTesting();
4901 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
4902 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4903 // Veto will take effect when layers are updated.
4904 // The results will be verified after commit is completed below.
4905 // Since we are manually marking picture pile as unsuitable,
4906 // make sure that the layer gets a chance to update.
4907 layer->SetNeedsDisplay();
4908 PostSetNeedsCommitToMainThread();
4911 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4912 EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
4913 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4916 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4917 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
4918 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4919 EndTest();
4922 void AfterTest() override {}
4924 FakeContentLayerClient layer_client_;
4927 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
4929 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
4930 public:
4931 LayerTreeHostTestContinuousPainting()
4932 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
4934 protected:
4935 enum { kExpectedNumCommits = 10 };
4937 void SetupTree() override {
4938 scoped_refptr<Layer> root_layer = Layer::Create();
4939 root_layer->SetBounds(bounds_);
4941 if (layer_tree_host()->settings().impl_side_painting) {
4942 picture_layer_ = FakePictureLayer::Create(&client_);
4943 child_layer_ = picture_layer_.get();
4944 } else {
4945 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
4946 child_layer_ = content_layer_.get();
4948 child_layer_->SetBounds(bounds_);
4949 child_layer_->SetIsDrawable(true);
4950 root_layer->AddChild(child_layer_);
4952 layer_tree_host()->SetRootLayer(root_layer);
4953 layer_tree_host()->SetViewportSize(bounds_);
4954 LayerTreeHostTest::SetupTree();
4957 void BeginTest() override {
4958 MainThreadTaskRunner()->PostTask(
4959 FROM_HERE,
4960 base::Bind(
4961 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
4962 base::Unretained(this)));
4963 // Wait 50x longer than expected.
4964 double milliseconds_per_frame =
4965 1000.0 / layer_tree_host()->settings().refresh_rate;
4966 MainThreadTaskRunner()->PostDelayedTask(
4967 FROM_HERE,
4968 base::Bind(
4969 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
4970 base::Unretained(this)),
4971 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
4972 milliseconds_per_frame));
4975 void BeginMainFrame(const BeginFrameArgs& args) override {
4976 child_layer_->SetNeedsDisplay();
4979 void AfterTest() override {
4980 EXPECT_LE(kExpectedNumCommits, num_commits_);
4981 EXPECT_LE(kExpectedNumCommits, num_draws_);
4982 int update_count = content_layer_.get()
4983 ? content_layer_->PaintContentsCount()
4984 : picture_layer_->update_count();
4985 EXPECT_LE(kExpectedNumCommits, update_count);
4988 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4989 if (++num_draws_ == kExpectedNumCommits)
4990 EndTest();
4993 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4994 ++num_commits_;
4997 private:
4998 void EnableContinuousPainting() {
4999 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5000 debug_state.continuous_painting = true;
5001 layer_tree_host()->SetDebugState(debug_state);
5004 void DisableContinuousPainting() {
5005 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5006 debug_state.continuous_painting = false;
5007 layer_tree_host()->SetDebugState(debug_state);
5008 EndTest();
5011 int num_commits_;
5012 int num_draws_;
5013 const gfx::Size bounds_;
5014 FakeContentLayerClient client_;
5015 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5016 scoped_refptr<FakePictureLayer> picture_layer_;
5017 Layer* child_layer_;
5020 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5022 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5023 public:
5024 LayerTreeHostTestActivateOnInvisible()
5025 : activation_count_(0), visible_(true) {}
5027 void InitializeSettings(LayerTreeSettings* settings) override {
5028 settings->impl_side_painting = true;
5031 void BeginTest() override {
5032 // Kick off the test with a commit.
5033 PostSetNeedsCommitToMainThread();
5036 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5037 // Make sure we don't activate using the notify signal from tile manager.
5038 host_impl->BlockNotifyReadyToActivateForTesting(true);
5041 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5043 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5044 bool visible) override {
5045 visible_ = visible;
5047 // Once invisible, we can go visible again.
5048 if (!visible) {
5049 PostSetVisibleToMainThread(true);
5050 } else {
5051 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5052 EndTest();
5056 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5057 ++activation_count_;
5058 EXPECT_FALSE(visible_);
5061 void AfterTest() override {
5062 // Ensure we activated even though the signal was blocked.
5063 EXPECT_EQ(1, activation_count_);
5064 EXPECT_TRUE(visible_);
5067 private:
5068 int activation_count_;
5069 bool visible_;
5071 FakeContentLayerClient client_;
5072 scoped_refptr<FakePictureLayer> picture_layer_;
5075 // TODO(vmpstr): Enable with single thread impl-side painting.
5076 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5078 // Do a synchronous composite and assert that the swap promise succeeds.
5079 class LayerTreeHostTestSynchronousCompositeSwapPromise
5080 : public LayerTreeHostTest {
5081 public:
5082 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5084 void InitializeSettings(LayerTreeSettings* settings) override {
5085 settings->single_thread_proxy_scheduler = false;
5088 void BeginTest() override {
5089 // Successful composite.
5090 scoped_ptr<SwapPromise> swap_promise0(
5091 new TestSwapPromise(&swap_promise_result_[0]));
5092 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5093 layer_tree_host()->Composite(gfx::FrameTime::Now());
5095 // Fail to swap (no damage).
5096 scoped_ptr<SwapPromise> swap_promise1(
5097 new TestSwapPromise(&swap_promise_result_[1]));
5098 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5099 layer_tree_host()->SetNeedsCommit();
5100 layer_tree_host()->Composite(gfx::FrameTime::Now());
5102 // Fail to draw (not visible).
5103 scoped_ptr<SwapPromise> swap_promise2(
5104 new TestSwapPromise(&swap_promise_result_[2]));
5105 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5106 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5107 layer_tree_host()->SetVisible(false);
5108 layer_tree_host()->Composite(gfx::FrameTime::Now());
5110 EndTest();
5113 void DidCommit() override {
5114 commit_count_++;
5115 ASSERT_LE(commit_count_, 3);
5118 void AfterTest() override {
5119 EXPECT_EQ(3, commit_count_);
5121 // Initial swap promise should have succeded.
5123 base::AutoLock lock(swap_promise_result_[0].lock);
5124 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5125 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5126 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5129 // Second swap promise fails to swap.
5131 base::AutoLock lock(swap_promise_result_[1].lock);
5132 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5133 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5134 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5135 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5138 // Third swap promises also fails to swap (and draw).
5140 base::AutoLock lock(swap_promise_result_[2].lock);
5141 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5142 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5143 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5144 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5148 int commit_count_;
5149 TestSwapPromiseResult swap_promise_result_[3];
5152 // Impl-side painting is not supported for synchronous compositing.
5153 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
5155 } // namespace cc