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"
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/copy_output_request.h"
24 #include "cc/output/copy_output_result.h"
25 #include "cc/output/output_surface.h"
26 #include "cc/resources/prioritized_resource.h"
27 #include "cc/resources/prioritized_resource_manager.h"
28 #include "cc/resources/resource_update_queue.h"
29 #include "cc/scheduler/frame_rate_controller.h"
30 #include "cc/test/fake_content_layer.h"
31 #include "cc/test/fake_content_layer_client.h"
32 #include "cc/test/fake_content_layer_impl.h"
33 #include "cc/test/fake_layer_tree_host_client.h"
34 #include "cc/test/fake_output_surface.h"
35 #include "cc/test/fake_painted_scrollbar_layer.h"
36 #include "cc/test/fake_picture_layer.h"
37 #include "cc/test/fake_picture_layer_impl.h"
38 #include "cc/test/fake_proxy.h"
39 #include "cc/test/fake_scoped_ui_resource.h"
40 #include "cc/test/fake_video_frame_provider.h"
41 #include "cc/test/geometry_test_utils.h"
42 #include "cc/test/layer_tree_test.h"
43 #include "cc/test/occlusion_tracker_test_common.h"
44 #include "cc/test/test_web_graphics_context_3d.h"
45 #include "cc/trees/layer_tree_host_impl.h"
46 #include "cc/trees/layer_tree_impl.h"
47 #include "cc/trees/single_thread_proxy.h"
48 #include "cc/trees/thread_proxy.h"
49 #include "gpu/GLES2/gl2extchromium.h"
50 #include "skia/ext/refptr.h"
51 #include "testing/gmock/include/gmock/gmock.h"
52 #include "third_party/khronos/GLES2/gl2.h"
53 #include "third_party/khronos/GLES2/gl2ext.h"
54 #include "third_party/skia/include/core/SkPicture.h"
55 #include "ui/gfx/frame_time.h"
56 #include "ui/gfx/point_conversions.h"
57 #include "ui/gfx/size_conversions.h"
58 #include "ui/gfx/vector2d_conversions.h"
61 using testing::AnyNumber;
62 using testing::AtLeast;
68 class LayerTreeHostTest : public LayerTreeTest {};
70 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
72 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
74 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
76 virtual void BeginTest() OVERRIDE {
77 PostSetNeedsCommitToMainThread();
78 PostSetNeedsCommitToMainThread();
81 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
83 if (!impl->active_tree()->source_frame_number())
87 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
91 virtual void AfterTest() OVERRIDE {
92 EXPECT_GE(1, num_commits_);
93 EXPECT_GE(1, num_draws_);
101 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
103 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
104 // first committed frame draws should lead to another commit.
105 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
107 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
109 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
111 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
115 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
117 switch (num_commits_) {
119 PostSetNeedsCommitToMainThread();
129 virtual void AfterTest() OVERRIDE {
130 EXPECT_EQ(2, num_commits_);
131 EXPECT_LE(1, num_draws_);
139 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
141 // Verify that we pass property values in PushPropertiesTo.
142 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
144 virtual 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();
154 HIDE_LAYER_AND_SUBTREE,
159 virtual void BeginTest() OVERRIDE {
161 PostSetNeedsCommitToMainThread();
164 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
165 VerifyAfterValues(impl->active_tree()->root_layer());
168 virtual void DidCommitAndDrawFrame() OVERRIDE {
169 SetBeforeValues(layer_tree_host()->root_layer());
170 VerifyBeforeValues(layer_tree_host()->root_layer());
173 if (index_ == DONE) {
178 SetAfterValues(layer_tree_host()->root_layer());
181 virtual 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_)) {
201 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
203 case HIDE_LAYER_AND_SUBTREE:
204 EXPECT_TRUE(layer->hide_layer_and_subtree());
207 EXPECT_TRUE(layer->DrawsContent());
212 void SetAfterValues(Layer* layer) {
213 switch (static_cast<Properties>(index_)) {
218 layer->SetBounds(gfx::Size(20, 20));
220 case HIDE_LAYER_AND_SUBTREE:
221 layer->SetHideLayerAndSubtree(true);
224 layer->SetIsDrawable(true);
232 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
234 // 1 setNeedsRedraw after the first commit has completed should lead to 1
236 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
238 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
240 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
242 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
243 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
245 // Redraw again to verify that the second redraw doesn't commit.
246 PostSetNeedsRedrawToMainThread();
253 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
254 EXPECT_EQ(0, num_draws_);
258 virtual void AfterTest() OVERRIDE {
259 EXPECT_GE(2, num_draws_);
260 EXPECT_EQ(1, num_commits_);
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 {
274 LayerTreeHostTestSetNeedsRedrawRect()
277 invalid_rect_(10, 10, 20, 20),
278 root_layer_(ContentLayer::Create(&client_)) {}
280 virtual 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 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
289 LayerTreeHostImpl* host_impl,
290 LayerTreeHostImpl::FrameData* frame_data,
291 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
292 EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
294 gfx::RectF root_damage_rect;
295 if (!frame_data->render_passes.empty())
296 root_damage_rect = frame_data->render_passes.back()->damage_rect;
299 // If this is the first frame, expect full frame damage.
300 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
302 // Check that invalid_rect_ is indeed repainted.
303 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
309 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
311 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
318 virtual void AfterTest() OVERRIDE { EXPECT_EQ(2, num_draws_); }
322 const gfx::Size bounds_;
323 const gfx::Rect invalid_rect_;
324 FakeContentLayerClient client_;
325 scoped_refptr<ContentLayer> root_layer_;
328 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
330 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
332 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
333 settings->layer_transforms_should_scale_layer_contents = true;
336 virtual void SetupTree() OVERRIDE {
337 root_layer_ = Layer::Create();
338 root_layer_->SetBounds(gfx::Size(10, 20));
340 scaled_layer_ = FakeContentLayer::Create(&client_);
341 scaled_layer_->SetBounds(gfx::Size(1, 1));
342 root_layer_->AddChild(scaled_layer_);
344 layer_tree_host()->SetRootLayer(root_layer_);
345 LayerTreeHostTest::SetupTree();
348 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
350 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
351 if (host_impl->active_tree()->source_frame_number() == 1)
355 virtual void DidCommit() OVERRIDE {
356 switch (layer_tree_host()->source_frame_number()) {
358 // Changing the device scale factor causes a commit. It also changes
359 // the content bounds of |scaled_layer_|, which should not generate
360 // a second commit as a result.
361 layer_tree_host()->SetDeviceScaleFactor(4.f);
365 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
369 virtual void AfterTest() OVERRIDE {
370 EXPECT_EQ(gfx::Size(4, 4).ToString(),
371 scaled_layer_->content_bounds().ToString());
375 FakeContentLayerClient client_;
376 scoped_refptr<Layer> root_layer_;
377 scoped_refptr<FakeContentLayer> scaled_layer_;
380 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
382 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
383 : public LayerTreeHostTest {
385 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
386 settings->layer_transforms_should_scale_layer_contents = true;
389 virtual void SetupTree() OVERRIDE {
390 root_layer_ = Layer::Create();
391 root_layer_->SetBounds(gfx::Size(10, 20));
393 bool paint_scrollbar = true;
394 bool has_thumb = false;
395 scrollbar_ = FakePaintedScrollbarLayer::Create(
396 paint_scrollbar, has_thumb, root_layer_->id());
397 scrollbar_->SetPosition(gfx::Point(0, 10));
398 scrollbar_->SetBounds(gfx::Size(10, 10));
400 root_layer_->AddChild(scrollbar_);
402 layer_tree_host()->SetRootLayer(root_layer_);
403 LayerTreeHostTest::SetupTree();
406 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
408 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
409 if (host_impl->active_tree()->source_frame_number() == 1)
413 virtual void DidCommit() OVERRIDE {
414 switch (layer_tree_host()->source_frame_number()) {
416 // Changing the device scale factor causes a commit. It also changes
417 // the content bounds of |scrollbar_|, which should not generate
418 // a second commit as a result.
419 layer_tree_host()->SetDeviceScaleFactor(4.f);
423 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
427 virtual void AfterTest() OVERRIDE {
428 EXPECT_EQ(gfx::Size(40, 40).ToString(),
429 scrollbar_->content_bounds().ToString());
433 FakeContentLayerClient client_;
434 scoped_refptr<Layer> root_layer_;
435 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
438 SINGLE_AND_MULTI_THREAD_TEST_F(
439 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
441 class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
443 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
445 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
447 virtual void DidCommit() OVERRIDE {
449 if (num_commits_ == 1) {
451 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
452 } else if (num_commits_ == 2) {
453 // This is inside the readback. We should get another commit after it.
454 } else if (num_commits_ == 3) {
461 virtual void AfterTest() OVERRIDE {}
467 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback);
469 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
470 : public LayerTreeHostTest {
472 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
475 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
477 virtual void DidCommit() OVERRIDE {
479 if (num_commits_ == 1) {
480 layer_tree_host()->SetNeedsCommit();
481 } else if (num_commits_ == 2) {
483 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
484 } else if (num_commits_ == 3) {
485 // This is inside the readback. We should get another commit after it.
486 } else if (num_commits_ == 4) {
493 virtual void AfterTest() OVERRIDE {}
500 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws);
502 class LayerTreeHostTestCompositeAndReadbackDuringForcedDraw
503 : public LayerTreeHostTest {
505 static const int kFirstCommitSourceFrameNumber = 0;
506 static const int kReadbackSourceFrameNumber = 1;
507 static const int kReadbackReplacementAndForcedDrawSourceFrameNumber = 2;
509 LayerTreeHostTestCompositeAndReadbackDuringForcedDraw()
510 : did_post_readback_(false) {}
512 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
513 // This enables forced draws after a single prepare to draw failure.
514 settings->timeout_and_draw_when_animation_checkerboards = true;
515 settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
518 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
520 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
521 LayerTreeHostImpl* host_impl,
522 LayerTreeHostImpl::FrameData* frame_data,
523 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
524 int sfn = host_impl->active_tree()->source_frame_number();
525 EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
526 sfn == kReadbackSourceFrameNumber ||
527 sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
530 // Before we react to the failed draw by initiating the forced draw
531 // sequence, start a readback on the main thread.
532 if (sfn == kFirstCommitSourceFrameNumber && !did_post_readback_) {
533 did_post_readback_ = true;
534 PostReadbackToMainThread();
537 // Aborting for checkerboarding animations will result in a forced draw.
538 return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
541 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
542 // We should only draw for the readback and the forced draw.
543 int sfn = host_impl->active_tree()->source_frame_number();
544 EXPECT_TRUE(sfn == kReadbackSourceFrameNumber ||
545 sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
549 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
550 bool result) OVERRIDE {
551 // We should only swap for the forced draw.
552 int sfn = host_impl->active_tree()->source_frame_number();
553 EXPECT_TRUE(sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
558 virtual void AfterTest() OVERRIDE {}
560 bool did_post_readback_;
563 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackDuringForcedDraw);
565 class LayerTreeHostTestCompositeAndReadbackAfterForcedDraw
566 : public LayerTreeHostTest {
568 static const int kFirstCommitSourceFrameNumber = 0;
569 static const int kForcedDrawSourceFrameNumber = 1;
570 static const int kReadbackSourceFrameNumber = 2;
571 static const int kReadbackReplacementSourceFrameNumber = 3;
573 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
574 // This enables forced draws after a single prepare to draw failure.
575 settings->timeout_and_draw_when_animation_checkerboards = true;
576 settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
579 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
581 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
582 LayerTreeHostImpl* host_impl,
583 LayerTreeHostImpl::FrameData* frame_data,
584 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
585 int sfn = host_impl->active_tree()->source_frame_number();
586 EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
587 sfn == kForcedDrawSourceFrameNumber ||
588 sfn == kReadbackSourceFrameNumber ||
589 sfn == kReadbackReplacementSourceFrameNumber)
592 // Aborting for checkerboarding animations will result in a forced draw.
593 return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
596 virtual void DidCommit() OVERRIDE {
597 if (layer_tree_host()->source_frame_number() ==
598 kForcedDrawSourceFrameNumber) {
599 // Avoid aborting the forced draw commit so source_frame_number
601 layer_tree_host()->SetNeedsCommit();
602 } else if (layer_tree_host()->source_frame_number() ==
603 kReadbackSourceFrameNumber) {
604 // Perform a readback immediately after the forced draw's commit.
606 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
610 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
611 // We should only draw for the the forced draw, readback, and
612 // replacement commit.
613 int sfn = host_impl->active_tree()->source_frame_number();
614 EXPECT_TRUE(sfn == kForcedDrawSourceFrameNumber ||
615 sfn == kReadbackSourceFrameNumber ||
616 sfn == kReadbackReplacementSourceFrameNumber)
620 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
621 bool result) OVERRIDE {
622 // We should only swap for the forced draw and replacement commit.
623 int sfn = host_impl->active_tree()->source_frame_number();
624 EXPECT_TRUE(sfn == kForcedDrawSourceFrameNumber ||
625 sfn == kReadbackReplacementSourceFrameNumber)
628 if (sfn == kReadbackReplacementSourceFrameNumber)
632 virtual void AfterTest() OVERRIDE {}
635 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackAfterForcedDraw);
637 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
639 LayerTreeHostTestSetNextCommitForcesRedraw()
642 invalid_rect_(10, 10, 20, 20),
643 root_layer_(ContentLayer::Create(&client_)) {}
645 virtual void BeginTest() OVERRIDE {
646 root_layer_->SetIsDrawable(true);
647 root_layer_->SetBounds(bounds_);
648 layer_tree_host()->SetRootLayer(root_layer_);
649 layer_tree_host()->SetViewportSize(bounds_);
650 PostSetNeedsCommitToMainThread();
653 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
654 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
655 host_impl->SetNeedsRedrawRect(invalid_rect_);
658 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
659 LayerTreeHostImpl* host_impl,
660 LayerTreeHostImpl::FrameData* frame_data,
661 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
662 EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
664 gfx::RectF root_damage_rect;
665 if (!frame_data->render_passes.empty())
666 root_damage_rect = frame_data->render_passes.back()->damage_rect;
668 switch (num_draws_) {
670 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
674 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
677 EXPECT_RECT_EQ(invalid_rect_, root_damage_rect);
680 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
689 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
690 switch (num_draws_) {
693 // Cycle through a couple of empty commits to ensure we're observing the
695 PostSetNeedsCommitToMainThread();
698 // Should force full frame damage on the next commit
699 PostSetNextCommitForcesRedrawToMainThread();
700 PostSetNeedsCommitToMainThread();
701 if (host_impl->settings().impl_side_painting)
702 host_impl->BlockNotifyReadyToActivateForTesting(true);
707 host_impl->BlockNotifyReadyToActivateForTesting(false);
716 virtual void AfterTest() OVERRIDE { EXPECT_EQ(5, num_draws_); }
720 const gfx::Size bounds_;
721 const gfx::Rect invalid_rect_;
722 FakeContentLayerClient client_;
723 scoped_refptr<ContentLayer> root_layer_;
726 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw);
728 // Tests that if a layer is not drawn because of some reason in the parent then
729 // its damage is preserved until the next time it is drawn.
730 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
732 LayerTreeHostTestUndrawnLayersDamageLater()
733 : root_layer_(ContentLayer::Create(&client_)) {}
735 virtual void SetupTree() OVERRIDE {
736 root_layer_->SetIsDrawable(true);
737 root_layer_->SetBounds(gfx::Size(50, 50));
738 layer_tree_host()->SetRootLayer(root_layer_);
740 // The initially transparent layer has a larger child layer, which is
741 // not initially drawn because of the this (parent) layer.
742 parent_layer_ = FakeContentLayer::Create(&client_);
743 parent_layer_->SetBounds(gfx::Size(15, 15));
744 parent_layer_->SetOpacity(0.0f);
745 root_layer_->AddChild(parent_layer_);
747 child_layer_ = FakeContentLayer::Create(&client_);
748 child_layer_->SetBounds(gfx::Size(25, 25));
749 parent_layer_->AddChild(child_layer_);
751 LayerTreeHostTest::SetupTree();
754 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
756 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
757 LayerTreeHostImpl* host_impl,
758 LayerTreeHostImpl::FrameData* frame_data,
759 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
760 EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
762 gfx::RectF root_damage_rect;
763 if (!frame_data->render_passes.empty())
764 root_damage_rect = frame_data->render_passes.back()->damage_rect;
766 // The first time, the whole view needs be drawn.
767 // Afterwards, just the opacity of surface_layer1 is changed a few times,
768 // and each damage should be the bounding box of it and its child. If this
769 // was working improperly, the damage might not include its childs bounding
771 switch (layer_tree_host()->source_frame_number()) {
773 EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
778 EXPECT_RECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
787 virtual void DidCommitAndDrawFrame() OVERRIDE {
788 switch (layer_tree_host()->source_frame_number()) {
790 // Test not owning the surface.
791 parent_layer_->SetOpacity(1.0f);
794 parent_layer_->SetOpacity(0.0f);
797 // Test owning the surface.
798 parent_layer_->SetOpacity(0.5f);
799 parent_layer_->SetForceRenderSurface(true);
809 virtual void AfterTest() OVERRIDE {}
812 FakeContentLayerClient client_;
813 scoped_refptr<ContentLayer> root_layer_;
814 scoped_refptr<FakeContentLayer> parent_layer_;
815 scoped_refptr<FakeContentLayer> child_layer_;
818 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
820 // If the layerTreeHost says it can't draw, Then we should not try to draw.
821 class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
823 LayerTreeHostTestCanDrawBlocksDrawing() : done_(false) {}
825 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
827 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
830 // Only the initial draw should bring us here.
831 EXPECT_TRUE(impl->CanDraw());
832 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
835 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
838 if (LastCommittedSourceFrameNumber(impl) >= 1) {
839 // After the first commit, we should not be able to draw.
840 EXPECT_FALSE(impl->CanDraw());
844 virtual void DidCommit() OVERRIDE {
845 switch (layer_tree_host()->source_frame_number()) {
847 // Make the viewport empty so the host says it can't draw.
848 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
852 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
856 // Let it draw so we go idle and end the test.
857 layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
864 virtual void AfterTest() OVERRIDE {}
870 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
872 // beginLayerWrite should prevent draws from executing until a commit occurs
873 class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
875 LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
877 virtual void BeginTest() OVERRIDE {
878 PostAcquireLayerTextures();
879 PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
880 PostSetNeedsCommitToMainThread();
883 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
885 EXPECT_EQ(num_draws_, num_commits_);
888 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
893 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
900 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw);
902 // Verify that when resuming visibility, Requesting layer write permission
903 // will not deadlock the main thread even though there are not yet any
904 // scheduled redraws. This behavior is critical for reliably surviving tab
905 // switching. There are no failure conditions to this test, it just passes
906 // by not timing out.
907 class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
909 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
911 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
913 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
915 if (num_commits_ == 2)
917 else if (num_commits_ < 2) {
918 PostSetVisibleToMainThread(false);
919 PostSetVisibleToMainThread(true);
920 PostAcquireLayerTextures();
921 PostSetNeedsCommitToMainThread();
925 virtual void AfterTest() OVERRIDE {}
931 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
933 // A compositeAndReadback while invisible should force a normal commit without
935 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
936 : public LayerTreeHostTest {
938 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
940 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
942 virtual void DidCommitAndDrawFrame() OVERRIDE {
944 if (num_commits_ == 1) {
945 layer_tree_host()->SetVisible(false);
946 layer_tree_host()->SetNeedsCommit();
947 layer_tree_host()->SetNeedsCommit();
949 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
955 virtual void AfterTest() OVERRIDE {}
961 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible);
963 class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
965 LayerTreeHostTestAbortFrameWhenInvisible() {}
967 virtual void BeginTest() OVERRIDE {
968 // Request a commit (from the main thread), Which will trigger the commit
969 // flow from the impl side.
970 layer_tree_host()->SetNeedsCommit();
971 // Then mark ourselves as not visible before processing any more messages
972 // on the main thread.
973 layer_tree_host()->SetVisible(false);
974 // If we make it without kicking a frame, we pass!
975 EndTestAfterDelay(1);
978 virtual void Layout() OVERRIDE {
983 virtual void AfterTest() OVERRIDE {}
986 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
988 // This test verifies that properties on the layer tree host are commited
990 class LayerTreeHostTestCommit : public LayerTreeHostTest {
992 LayerTreeHostTestCommit() {}
994 virtual void BeginTest() OVERRIDE {
995 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
996 layer_tree_host()->set_background_color(SK_ColorGRAY);
998 PostSetNeedsCommitToMainThread();
1001 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1002 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
1003 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
1008 virtual void AfterTest() OVERRIDE {}
1011 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
1013 // This test verifies that LayerTreeHostImpl's current frame time gets
1014 // updated in consecutive frames when it doesn't draw due to tree
1015 // activation failure.
1016 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
1017 : public LayerTreeHostTest {
1019 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
1020 : frame_count_with_pending_tree_(0) {}
1022 virtual void BeginTest() OVERRIDE {
1023 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1024 layer_tree_host()->set_background_color(SK_ColorGRAY);
1026 PostSetNeedsCommitToMainThread();
1029 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1030 EXPECT_EQ(frame_count_with_pending_tree_, 0);
1031 impl->BlockNotifyReadyToActivateForTesting(true);
1034 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1035 const BeginFrameArgs& args) OVERRIDE {
1036 if (impl->pending_tree())
1037 frame_count_with_pending_tree_++;
1039 if (frame_count_with_pending_tree_ == 2)
1040 impl->BlockNotifyReadyToActivateForTesting(false);
1043 virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1044 const BeginFrameArgs& args) OVERRIDE {
1045 if (frame_count_with_pending_tree_ == 1) {
1046 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
1047 first_frame_time_ = impl->CurrentFrameTimeTicks();
1051 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1052 if (frame_count_with_pending_tree_ > 1) {
1053 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
1054 EXPECT_NE(first_frame_time_.ToInternalValue(),
1055 impl->CurrentFrameTimeTicks().ToInternalValue());
1060 EXPECT_FALSE(impl->settings().impl_side_painting);
1063 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1064 if (impl->settings().impl_side_painting)
1065 EXPECT_NE(frame_count_with_pending_tree_, 1);
1068 virtual void AfterTest() OVERRIDE {}
1071 int frame_count_with_pending_tree_;
1072 base::TimeTicks first_frame_time_;
1075 SINGLE_AND_MULTI_THREAD_TEST_F(
1076 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
1078 // This test verifies that LayerTreeHostImpl's current frame time gets
1079 // updated in consecutive frames when it draws in each frame.
1080 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
1082 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
1084 virtual void BeginTest() OVERRIDE {
1085 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1086 layer_tree_host()->set_background_color(SK_ColorGRAY);
1088 PostSetNeedsCommitToMainThread();
1091 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1094 first_frame_time_ = impl->CurrentFrameTimeTicks();
1095 impl->SetNeedsRedraw();
1097 // Since we might use a low-resolution clock on Windows, we need to
1098 // make sure that the clock has incremented past first_frame_time_.
1099 while (first_frame_time_ == gfx::FrameTime::Now()) {
1105 EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
1109 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1110 // Ensure there isn't a commit between the two draws, to ensure that a
1111 // commit isn't required for updating the current frame time. We can
1112 // only check for this in the multi-threaded case, since in the single-
1113 // threaded case there will always be a commit between consecutive draws.
1114 if (HasImplThread())
1115 EXPECT_EQ(0, frame_);
1118 virtual void AfterTest() OVERRIDE {}
1122 base::TimeTicks first_frame_time_;
1125 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1127 // Verifies that StartPageScaleAnimation events propagate correctly
1128 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1129 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
1131 LayerTreeHostTestStartPageScaleAnimation() {}
1133 virtual void SetupTree() OVERRIDE {
1134 LayerTreeHostTest::SetupTree();
1136 if (layer_tree_host()->settings().impl_side_painting) {
1137 scoped_refptr<FakePictureLayer> layer =
1138 FakePictureLayer::Create(&client_);
1139 layer->set_always_update_resources(true);
1140 scroll_layer_ = layer;
1142 scroll_layer_ = FakeContentLayer::Create(&client_);
1145 Layer* root_layer = layer_tree_host()->root_layer();
1146 scroll_layer_->SetScrollClipLayerId(root_layer->id());
1147 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
1148 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
1149 2 * root_layer->bounds().height()));
1150 scroll_layer_->SetScrollOffset(gfx::Vector2d());
1151 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1152 // This test requires the page_scale and inner viewport layers to be
1154 layer_tree_host()->RegisterViewportLayers(
1155 root_layer, scroll_layer_.get(), NULL);
1156 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1159 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1161 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
1162 float scale) OVERRIDE {
1163 gfx::Vector2d offset = scroll_layer_->scroll_offset();
1164 scroll_layer_->SetScrollOffset(offset + scroll_delta);
1165 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1168 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1169 // We get one commit before the first draw, and the animation doesn't happen
1170 // until the second draw.
1171 switch (impl->active_tree()->source_frame_number()) {
1173 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
1174 // We'll start an animation when we get back to the main thread.
1177 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
1180 EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
1188 virtual void DidCommitAndDrawFrame() OVERRIDE {
1189 switch (layer_tree_host()->source_frame_number()) {
1191 layer_tree_host()->StartPageScaleAnimation(
1192 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1197 virtual void AfterTest() OVERRIDE {}
1199 FakeContentLayerClient client_;
1200 scoped_refptr<Layer> scroll_layer_;
1203 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1205 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1207 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1209 virtual void BeginTest() OVERRIDE {
1210 PostSetNeedsCommitToMainThread();
1211 PostSetVisibleToMainThread(false);
1212 // This is suppressed while we're invisible.
1213 PostSetNeedsRedrawToMainThread();
1214 // Triggers the redraw.
1215 PostSetVisibleToMainThread(true);
1218 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1219 EXPECT_TRUE(impl->visible());
1224 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
1230 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1232 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1234 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1236 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1238 virtual void PaintContents(SkCanvas*, const gfx::Rect&,
1239 gfx::RectF*) OVERRIDE {
1240 // Set layer opacity to 0.
1242 test_layer_->SetOpacity(0.f);
1244 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
1250 class ContentLayerWithUpdateTracking : public ContentLayer {
1252 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1253 ContentLayerClient* client) {
1254 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1257 int PaintContentsCount() { return paint_contents_count_; }
1258 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1260 virtual bool Update(ResourceUpdateQueue* queue,
1261 const OcclusionTracker* occlusion) OVERRIDE {
1262 bool updated = ContentLayer::Update(queue, occlusion);
1263 paint_contents_count_++;
1268 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1269 : ContentLayer(client), paint_contents_count_(0) {
1270 SetAnchorPoint(gfx::PointF(0.f, 0.f));
1271 SetBounds(gfx::Size(10, 10));
1272 SetIsDrawable(true);
1274 virtual ~ContentLayerWithUpdateTracking() {}
1276 int paint_contents_count_;
1279 // Layer opacity change during paint should not prevent compositor resources
1280 // from being updated during commit.
1281 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1283 LayerTreeHostTestOpacityChange()
1284 : test_opacity_change_delegate_(),
1285 update_check_layer_(ContentLayerWithUpdateTracking::Create(
1286 &test_opacity_change_delegate_)) {
1287 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
1290 virtual void BeginTest() OVERRIDE {
1291 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1292 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
1294 PostSetNeedsCommitToMainThread();
1297 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1301 virtual void AfterTest() OVERRIDE {
1302 // Update() should have been called once.
1303 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
1307 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1308 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
1311 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1313 class NoScaleContentLayer : public ContentLayer {
1315 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
1316 return make_scoped_refptr(new NoScaleContentLayer(client));
1319 virtual void CalculateContentsScale(float ideal_contents_scale,
1320 float device_scale_factor,
1321 float page_scale_factor,
1322 bool animating_transform_to_screen,
1323 float* contents_scale_x,
1324 float* contents_scale_y,
1325 gfx::Size* contentBounds) OVERRIDE {
1326 // Skip over the ContentLayer's method to the base Layer class.
1327 Layer::CalculateContentsScale(ideal_contents_scale,
1328 device_scale_factor,
1330 animating_transform_to_screen,
1337 explicit NoScaleContentLayer(ContentLayerClient* client)
1338 : ContentLayer(client) {}
1339 virtual ~NoScaleContentLayer() {}
1342 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1343 : public LayerTreeHostTest {
1345 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1346 : root_layer_(NoScaleContentLayer::Create(&client_)),
1347 child_layer_(ContentLayer::Create(&client_)) {}
1349 virtual void BeginTest() OVERRIDE {
1350 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1351 layer_tree_host()->SetDeviceScaleFactor(1.5);
1352 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1354 root_layer_->AddChild(child_layer_);
1356 root_layer_->SetIsDrawable(true);
1357 root_layer_->SetBounds(gfx::Size(30, 30));
1358 root_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1360 child_layer_->SetIsDrawable(true);
1361 child_layer_->SetPosition(gfx::Point(2, 2));
1362 child_layer_->SetBounds(gfx::Size(10, 10));
1363 child_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1365 layer_tree_host()->SetRootLayer(root_layer_);
1367 PostSetNeedsCommitToMainThread();
1370 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1371 // Should only do one commit.
1372 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1373 // Device scale factor should come over to impl.
1374 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1376 // Both layers are on impl.
1377 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1379 // Device viewport is scaled.
1380 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1382 LayerImpl* root = impl->active_tree()->root_layer();
1383 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1385 // Positions remain in layout pixels.
1386 EXPECT_EQ(gfx::Point(0, 0), root->position());
1387 EXPECT_EQ(gfx::Point(2, 2), child->position());
1389 // Compute all the layer transforms for the frame.
1390 LayerTreeHostImpl::FrameData frame_data;
1391 impl->PrepareToDraw(&frame_data, gfx::Rect());
1392 impl->DidDrawAllLayers(frame_data);
1394 const LayerImplList& render_surface_layer_list =
1395 *frame_data.render_surface_layer_list;
1397 // Both layers should be drawing into the root render surface.
1398 ASSERT_EQ(1u, render_surface_layer_list.size());
1399 ASSERT_EQ(root->render_surface(),
1400 render_surface_layer_list[0]->render_surface());
1401 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1403 // The root render surface is the size of the viewport.
1404 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1405 root->render_surface()->content_rect());
1407 // The content bounds of the child should be scaled.
1408 gfx::Size child_bounds_scaled =
1409 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1410 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1412 gfx::Transform scale_transform;
1413 scale_transform.Scale(impl->device_scale_factor(),
1414 impl->device_scale_factor());
1416 // The root layer is scaled by 2x.
1417 gfx::Transform root_screen_space_transform = scale_transform;
1418 gfx::Transform root_draw_transform = scale_transform;
1420 EXPECT_EQ(root_draw_transform, root->draw_transform());
1421 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1423 // The child is at position 2,2, which is transformed to 3,3 after the scale
1424 gfx::Transform child_screen_space_transform;
1425 child_screen_space_transform.Translate(3.f, 3.f);
1426 gfx::Transform child_draw_transform = child_screen_space_transform;
1428 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1429 child->draw_transform());
1430 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1431 child->screen_space_transform());
1436 virtual void AfterTest() OVERRIDE {}
1439 FakeContentLayerClient client_;
1440 scoped_refptr<NoScaleContentLayer> root_layer_;
1441 scoped_refptr<ContentLayer> child_layer_;
1444 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1446 // Verify atomicity of commits and reuse of textures.
1447 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1449 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1450 settings->texture_id_allocation_chunk_size = 1;
1451 // Make sure partial texture updates are turned off.
1452 settings->max_partial_texture_updates = 0;
1453 // Linear fade animator prevents scrollbars from drawing immediately.
1454 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1457 virtual void SetupTree() OVERRIDE {
1458 layer_ = FakeContentLayer::Create(&client_);
1459 layer_->SetBounds(gfx::Size(10, 20));
1461 bool paint_scrollbar = true;
1462 bool has_thumb = false;
1463 scrollbar_ = FakePaintedScrollbarLayer::Create(
1464 paint_scrollbar, has_thumb, layer_->id());
1465 scrollbar_->SetPosition(gfx::Point(0, 10));
1466 scrollbar_->SetBounds(gfx::Size(10, 10));
1468 layer_->AddChild(scrollbar_);
1470 layer_tree_host()->SetRootLayer(layer_);
1471 LayerTreeHostTest::SetupTree();
1474 virtual void BeginTest() OVERRIDE {
1476 PostSetNeedsCommitToMainThread();
1479 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1480 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1482 TestWebGraphicsContext3D* context = TestContext();
1484 switch (impl->active_tree()->source_frame_number()) {
1486 // Number of textures should be one for each layer
1487 ASSERT_EQ(2u, context->NumTextures());
1488 // Number of textures used for commit should be one for each layer.
1489 EXPECT_EQ(2u, context->NumUsedTextures());
1490 // Verify that used texture is correct.
1491 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1492 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1494 context->ResetUsedTextures();
1495 PostSetNeedsCommitToMainThread();
1498 // Number of textures should be one for scrollbar layer since it was
1499 // requested and deleted on the impl-thread, and double for the content
1500 // layer since its first texture is used by impl thread and cannot by
1502 ASSERT_EQ(3u, context->NumTextures());
1503 // Number of textures used for commit should be one for each layer.
1504 EXPECT_EQ(2u, context->NumUsedTextures());
1505 // First textures should not have been used.
1506 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1507 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1508 // New textures should have been used.
1509 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1510 context->ResetUsedTextures();
1511 PostSetNeedsCommitToMainThread();
1522 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1523 TestWebGraphicsContext3D* context = TestContext();
1525 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1526 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1529 drew_frame_ = impl->active_tree()->source_frame_number();
1531 // We draw/ship one texture each frame for each layer.
1532 EXPECT_EQ(2u, context->NumUsedTextures());
1533 context->ResetUsedTextures();
1536 virtual void Layout() OVERRIDE {
1537 layer_->SetNeedsDisplay();
1538 scrollbar_->SetNeedsDisplay();
1541 virtual void AfterTest() OVERRIDE {}
1544 FakeContentLayerClient client_;
1545 scoped_refptr<FakeContentLayer> layer_;
1546 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1550 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1551 LayerTreeHostTestDirectRendererAtomicCommit);
1553 class LayerTreeHostTestDelegatingRendererAtomicCommit
1554 : public LayerTreeHostTestDirectRendererAtomicCommit {
1556 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1557 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1559 TestWebGraphicsContext3D* context = TestContext();
1561 switch (impl->active_tree()->source_frame_number()) {
1563 // Number of textures should be one for each layer
1564 ASSERT_EQ(2u, context->NumTextures());
1565 // Number of textures used for commit should be one for each layer.
1566 EXPECT_EQ(2u, context->NumUsedTextures());
1567 // Verify that used texture is correct.
1568 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1569 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1570 context->ResetUsedTextures();
1571 PostSetNeedsCommitToMainThread();
1574 // Number of textures should be doubled as the first context layer
1575 // texture is being used by the impl-thread and cannot be used for
1576 // update. The scrollbar behavior is different direct renderer because
1577 // UI resource deletion with delegating renderer occurs after tree
1579 ASSERT_EQ(4u, context->NumTextures());
1580 // Number of textures used for commit should still be
1581 // one for each layer.
1582 EXPECT_EQ(2u, context->NumUsedTextures());
1583 // First textures should not have been used.
1584 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1585 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1586 // New textures should have been used.
1587 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1588 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1589 context->ResetUsedTextures();
1590 PostSetNeedsCommitToMainThread();
1602 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1603 LayerTreeHostTestDelegatingRendererAtomicCommit);
1605 static void SetLayerPropertiesForTesting(Layer* layer,
1607 const gfx::Transform& transform,
1608 const gfx::PointF& anchor,
1609 const gfx::PointF& position,
1610 const gfx::Size& bounds,
1612 layer->RemoveAllChildren();
1614 parent->AddChild(layer);
1615 layer->SetTransform(transform);
1616 layer->SetAnchorPoint(anchor);
1617 layer->SetPosition(position);
1618 layer->SetBounds(bounds);
1619 layer->SetContentsOpaque(opaque);
1622 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1623 : public LayerTreeHostTest {
1625 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1626 settings->texture_id_allocation_chunk_size = 1;
1627 // Allow one partial texture update.
1628 settings->max_partial_texture_updates = 1;
1629 // No partial updates when impl side painting is enabled.
1630 settings->impl_side_painting = false;
1633 virtual void SetupTree() OVERRIDE {
1634 parent_ = FakeContentLayer::Create(&client_);
1635 parent_->SetBounds(gfx::Size(10, 20));
1637 child_ = FakeContentLayer::Create(&client_);
1638 child_->SetPosition(gfx::Point(0, 10));
1639 child_->SetBounds(gfx::Size(3, 10));
1641 parent_->AddChild(child_);
1643 layer_tree_host()->SetRootLayer(parent_);
1644 LayerTreeHostTest::SetupTree();
1647 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1649 virtual void DidCommitAndDrawFrame() OVERRIDE {
1650 switch (layer_tree_host()->source_frame_number()) {
1652 parent_->SetNeedsDisplay();
1653 child_->SetNeedsDisplay();
1656 // Damage part of layers.
1657 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1658 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1661 child_->SetNeedsDisplay();
1662 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1665 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1671 NOTREACHED() << layer_tree_host()->source_frame_number();
1676 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1677 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1679 TestWebGraphicsContext3D* context = TestContext();
1681 switch (impl->active_tree()->source_frame_number()) {
1683 // Number of textures should be one for each layer.
1684 ASSERT_EQ(2u, context->NumTextures());
1685 // Number of textures used for commit should be one for each layer.
1686 EXPECT_EQ(2u, context->NumUsedTextures());
1687 // Verify that used textures are correct.
1688 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1689 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1690 context->ResetUsedTextures();
1693 if (HasImplThread()) {
1694 // Number of textures should be two for each content layer.
1695 ASSERT_EQ(4u, context->NumTextures());
1697 // In single thread we can always do partial updates, so the limit has
1699 ASSERT_EQ(2u, context->NumTextures());
1701 // Number of textures used for commit should be one for each content
1703 EXPECT_EQ(2u, context->NumUsedTextures());
1705 if (HasImplThread()) {
1706 // First content textures should not have been used.
1707 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1708 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1709 // New textures should have been used.
1710 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1711 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1713 // In single thread we can always do partial updates, so the limit has
1715 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1716 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1719 context->ResetUsedTextures();
1722 if (HasImplThread()) {
1723 // Number of textures should be two for each content layer.
1724 ASSERT_EQ(4u, context->NumTextures());
1726 // In single thread we can always do partial updates, so the limit has
1728 ASSERT_EQ(2u, context->NumTextures());
1730 // Number of textures used for commit should be one for each content
1732 EXPECT_EQ(2u, context->NumUsedTextures());
1734 if (HasImplThread()) {
1735 // One content layer does a partial update also.
1736 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1737 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1739 // In single thread we can always do partial updates, so the limit has
1741 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1742 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1745 context->ResetUsedTextures();
1748 // No textures should be used for commit.
1749 EXPECT_EQ(0u, context->NumUsedTextures());
1751 context->ResetUsedTextures();
1754 // Number of textures used for commit should be one, for the
1756 EXPECT_EQ(1u, context->NumUsedTextures());
1758 context->ResetUsedTextures();
1766 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1767 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1769 TestWebGraphicsContext3D* context = TestContext();
1771 // Number of textures used for drawing should one per layer except for
1772 // frame 3 where the viewport only contains one layer.
1773 if (impl->active_tree()->source_frame_number() == 3) {
1774 EXPECT_EQ(1u, context->NumUsedTextures());
1776 EXPECT_EQ(2u, context->NumUsedTextures())
1777 << "For frame " << impl->active_tree()->source_frame_number();
1780 context->ResetUsedTextures();
1783 virtual void AfterTest() OVERRIDE {}
1786 FakeContentLayerClient client_;
1787 scoped_refptr<FakeContentLayer> parent_;
1788 scoped_refptr<FakeContentLayer> child_;
1791 // Partial updates are not possible with a delegating renderer.
1792 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1793 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1795 class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
1797 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1799 virtual void BeginTest() OVERRIDE {
1800 layer_tree_host()->SetNeedsRedraw();
1801 PostSetNeedsCommitToMainThread();
1804 virtual void DidCommitAndDrawFrame() OVERRIDE {
1808 layer_tree_host()->SetNeedsRedraw();
1809 layer_tree_host()->AcquireLayerTextures();
1811 base::AutoLock lock(lock_);
1814 layer_tree_host()->FinishAllRendering();
1816 base::AutoLock lock(lock_);
1817 EXPECT_EQ(0, draw_count_);
1822 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1823 base::AutoLock lock(lock_);
1827 virtual void AfterTest() OVERRIDE {}
1835 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering);
1837 class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
1839 virtual void BeginTest() OVERRIDE {
1840 Layer* root_layer = layer_tree_host()->root_layer();
1843 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
1844 gfx::Rect(0, 0, 1, 1));
1845 EXPECT_FALSE(root_layer->render_surface());
1850 virtual void AfterTest() OVERRIDE {}
1853 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup);
1855 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1856 : public LayerTreeHostTest {
1858 virtual void SetupTree() OVERRIDE {
1859 root_layer_ = FakeContentLayer::Create(&client_);
1860 root_layer_->SetBounds(gfx::Size(100, 100));
1862 surface_layer1_ = FakeContentLayer::Create(&client_);
1863 surface_layer1_->SetBounds(gfx::Size(100, 100));
1864 surface_layer1_->SetForceRenderSurface(true);
1865 surface_layer1_->SetOpacity(0.5f);
1866 root_layer_->AddChild(surface_layer1_);
1868 surface_layer2_ = FakeContentLayer::Create(&client_);
1869 surface_layer2_->SetBounds(gfx::Size(100, 100));
1870 surface_layer2_->SetForceRenderSurface(true);
1871 surface_layer2_->SetOpacity(0.5f);
1872 surface_layer1_->AddChild(surface_layer2_);
1874 replica_layer1_ = FakeContentLayer::Create(&client_);
1875 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1877 replica_layer2_ = FakeContentLayer::Create(&client_);
1878 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1880 layer_tree_host()->SetRootLayer(root_layer_);
1881 LayerTreeHostTest::SetupTree();
1884 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1886 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1887 Renderer* renderer = host_impl->renderer();
1888 RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1893 RenderPass::Id surface2_render_pass_id = host_impl->active_tree()
1900 switch (host_impl->active_tree()->source_frame_number()) {
1903 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1905 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1907 // Reduce the memory limit to only fit the root layer and one render
1908 // surface. This prevents any contents drawing into surfaces
1909 // from being allocated.
1910 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1914 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1916 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1923 virtual void DidCommitAndDrawFrame() OVERRIDE {
1924 if (layer_tree_host()->source_frame_number() < 2)
1925 root_layer_->SetNeedsDisplay();
1928 virtual void AfterTest() OVERRIDE {
1929 EXPECT_LE(2u, root_layer_->update_count());
1930 EXPECT_LE(2u, surface_layer1_->update_count());
1931 EXPECT_LE(2u, surface_layer2_->update_count());
1934 FakeContentLayerClient client_;
1935 scoped_refptr<FakeContentLayer> root_layer_;
1936 scoped_refptr<FakeContentLayer> surface_layer1_;
1937 scoped_refptr<FakeContentLayer> replica_layer1_;
1938 scoped_refptr<FakeContentLayer> surface_layer2_;
1939 scoped_refptr<FakeContentLayer> replica_layer2_;
1942 // Surfaces don't exist with a delegated renderer.
1943 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1944 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1946 class EvictionTestLayer : public Layer {
1948 static scoped_refptr<EvictionTestLayer> Create() {
1949 return make_scoped_refptr(new EvictionTestLayer());
1952 virtual bool Update(ResourceUpdateQueue*, const OcclusionTracker*) OVERRIDE;
1953 virtual bool DrawsContent() const OVERRIDE { return true; }
1955 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1957 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1958 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1960 bool HaveBackingTexture() const {
1961 return texture_.get() ? texture_->have_backing_texture() : false;
1965 EvictionTestLayer() : Layer() {}
1966 virtual ~EvictionTestLayer() {}
1968 void CreateTextureIfNeeded() {
1971 texture_ = PrioritizedResource::Create(
1972 layer_tree_host()->contents_texture_manager());
1973 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1974 bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
1975 bitmap_.allocPixels();
1978 scoped_ptr<PrioritizedResource> texture_;
1982 class EvictionTestLayerImpl : public LayerImpl {
1984 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1986 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1988 virtual ~EvictionTestLayerImpl() {}
1990 virtual void AppendQuads(QuadSink* quad_sink,
1991 AppendQuadsData* append_quads_data) OVERRIDE {
1992 ASSERT_TRUE(has_texture_);
1993 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1996 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1999 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
2000 : LayerImpl(tree_impl, id), has_texture_(false) {}
2005 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
2006 CreateTextureIfNeeded();
2009 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
2012 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
2013 const OcclusionTracker*) {
2014 CreateTextureIfNeeded();
2018 gfx::Rect full_rect(0, 0, 10, 10);
2019 ResourceUpdate upload = ResourceUpdate::Create(
2020 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
2021 queue->AppendFullUpload(upload);
2025 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
2026 LayerTreeImpl* tree_impl) {
2027 return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
2028 .PassAs<LayerImpl>();
2031 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
2032 Layer::PushPropertiesTo(layer_impl);
2034 EvictionTestLayerImpl* test_layer_impl =
2035 static_cast<EvictionTestLayerImpl*>(layer_impl);
2036 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
2039 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
2041 LayerTreeHostTestEvictTextures()
2042 : layer_(EvictionTestLayer::Create()),
2043 impl_for_evict_textures_(0),
2046 virtual void BeginTest() OVERRIDE {
2047 layer_tree_host()->SetRootLayer(layer_);
2048 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
2050 gfx::Transform identity_matrix;
2051 SetLayerPropertiesForTesting(layer_.get(),
2054 gfx::PointF(0.f, 0.f),
2055 gfx::PointF(0.f, 0.f),
2059 PostSetNeedsCommitToMainThread();
2062 void PostEvictTextures() {
2063 ImplThreadTaskRunner()->PostTask(
2065 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
2066 base::Unretained(this)));
2069 void EvictTexturesOnImplThread() {
2070 DCHECK(impl_for_evict_textures_);
2071 impl_for_evict_textures_->EvictTexturesForTesting();
2074 // Commit 1: Just commit and draw normally, then post an eviction at the end
2075 // that will trigger a commit.
2076 // Commit 2: Triggered by the eviction, let it go through and then set
2078 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
2079 // task, which will be handled before the commit. Don't set needsCommit, it
2080 // should have been posted. A frame should not be drawn (note,
2081 // didCommitAndDrawFrame may be called anyway).
2082 // Commit 4: Triggered by the eviction, let it go through and then set
2084 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
2085 // Layout(), a frame should not be drawn but a commit will be posted.
2086 // Commit 6: Triggered by the eviction, post an eviction task in
2087 // Layout(), which will be a noop, letting the commit (which recreates the
2088 // textures) go through and draw a frame, then end the test.
2090 // Commits 1+2 test the eviction recovery path where eviction happens outside
2091 // of the beginFrame/commit pair.
2092 // Commits 3+4 test the eviction recovery path where eviction happens inside
2093 // the beginFrame/commit pair.
2094 // Commits 5+6 test the path where an eviction happens during the eviction
2096 virtual void DidCommit() OVERRIDE {
2097 switch (num_commits_) {
2099 EXPECT_TRUE(layer_->HaveBackingTexture());
2100 PostEvictTextures();
2103 EXPECT_TRUE(layer_->HaveBackingTexture());
2104 layer_tree_host()->SetNeedsCommit();
2109 EXPECT_TRUE(layer_->HaveBackingTexture());
2110 layer_tree_host()->SetNeedsCommit();
2115 EXPECT_TRUE(layer_->HaveBackingTexture());
2124 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2125 impl_for_evict_textures_ = impl;
2128 virtual void Layout() OVERRIDE {
2130 switch (num_commits_) {
2135 PostEvictTextures();
2138 // We couldn't check in didCommitAndDrawFrame on commit 3,
2140 EXPECT_FALSE(layer_->HaveBackingTexture());
2143 PostEvictTextures();
2146 // We couldn't check in didCommitAndDrawFrame on commit 5,
2148 EXPECT_FALSE(layer_->HaveBackingTexture());
2149 PostEvictTextures();
2157 virtual void AfterTest() OVERRIDE {}
2160 FakeContentLayerClient client_;
2161 scoped_refptr<EvictionTestLayer> layer_;
2162 LayerTreeHostImpl* impl_for_evict_textures_;
2166 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
2168 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
2170 LayerTreeHostTestContinuousCommit()
2171 : num_commit_complete_(0), num_draw_layers_(0) {}
2173 virtual void BeginTest() OVERRIDE {
2174 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2175 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2177 PostSetNeedsCommitToMainThread();
2180 virtual void DidCommit() OVERRIDE {
2181 if (num_draw_layers_ == 2)
2183 layer_tree_host()->SetNeedsCommit();
2186 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2187 if (num_draw_layers_ == 1)
2188 num_commit_complete_++;
2191 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2193 if (num_draw_layers_ == 2)
2197 virtual void AfterTest() OVERRIDE {
2198 // Check that we didn't commit twice between first and second draw.
2199 EXPECT_EQ(1, num_commit_complete_);
2203 int num_commit_complete_;
2204 int num_draw_layers_;
2207 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
2209 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
2211 LayerTreeHostTestContinuousInvalidate()
2212 : num_commit_complete_(0), num_draw_layers_(0) {}
2214 virtual void BeginTest() OVERRIDE {
2215 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2216 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2218 content_layer_ = ContentLayer::Create(&client_);
2219 content_layer_->SetBounds(gfx::Size(10, 10));
2220 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
2221 content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
2222 content_layer_->SetIsDrawable(true);
2223 layer_tree_host()->root_layer()->AddChild(content_layer_);
2225 PostSetNeedsCommitToMainThread();
2228 virtual void DidCommitAndDrawFrame() OVERRIDE {
2229 if (num_draw_layers_ == 2)
2231 content_layer_->SetNeedsDisplay();
2234 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2235 if (num_draw_layers_ == 1)
2236 num_commit_complete_++;
2239 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2241 if (num_draw_layers_ == 2)
2245 virtual void AfterTest() OVERRIDE {
2246 // Check that we didn't commit twice between first and second draw.
2247 EXPECT_EQ(1, num_commit_complete_);
2251 FakeContentLayerClient client_;
2252 scoped_refptr<Layer> content_layer_;
2253 int num_commit_complete_;
2254 int num_draw_layers_;
2257 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestContinuousInvalidate);
2259 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2261 LayerTreeHostTestDeferCommits()
2262 : num_commits_deferred_(0), num_complete_commits_(0) {}
2264 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2266 virtual void DidDeferCommit() OVERRIDE {
2267 num_commits_deferred_++;
2268 layer_tree_host()->SetDeferCommits(false);
2271 virtual void DidCommit() OVERRIDE {
2272 num_complete_commits_++;
2273 switch (num_complete_commits_) {
2275 EXPECT_EQ(0, num_commits_deferred_);
2276 layer_tree_host()->SetDeferCommits(true);
2277 PostSetNeedsCommitToMainThread();
2288 virtual void AfterTest() OVERRIDE {
2289 EXPECT_EQ(1, num_commits_deferred_);
2290 EXPECT_EQ(2, num_complete_commits_);
2294 int num_commits_deferred_;
2295 int num_complete_commits_;
2298 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2300 class LayerTreeHostWithProxy : public LayerTreeHost {
2302 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2303 const LayerTreeSettings& settings,
2304 scoped_ptr<FakeProxy> proxy)
2305 : LayerTreeHost(client, NULL, settings) {
2306 proxy->SetLayerTreeHost(this);
2307 InitializeForTesting(proxy.PassAs<Proxy>());
2311 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2312 // When partial updates are not allowed, max updates should be 0.
2314 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2316 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2317 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2318 proxy->SetMaxPartialTextureUpdates(5);
2320 LayerTreeSettings settings;
2321 settings.max_partial_texture_updates = 10;
2323 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2324 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2326 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2329 // When partial updates are allowed,
2330 // max updates should be limited by the proxy.
2332 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2334 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2335 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2336 proxy->SetMaxPartialTextureUpdates(5);
2338 LayerTreeSettings settings;
2339 settings.max_partial_texture_updates = 10;
2341 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2342 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2344 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2347 // When partial updates are allowed,
2348 // max updates should also be limited by the settings.
2350 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2352 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2353 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2354 proxy->SetMaxPartialTextureUpdates(20);
2356 LayerTreeSettings settings;
2357 settings.max_partial_texture_updates = 10;
2359 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2360 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2362 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2366 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2367 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2369 LayerTreeSettings settings;
2370 settings.max_partial_texture_updates = 4;
2372 scoped_ptr<LayerTreeHost> host =
2373 LayerTreeHost::CreateSingleThreaded(&client, &client, NULL, settings);
2374 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2375 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2378 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2379 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2381 LayerTreeSettings settings;
2382 settings.max_partial_texture_updates = 4;
2384 scoped_ptr<LayerTreeHost> host =
2385 LayerTreeHost::CreateSingleThreaded(&client, &client, NULL, settings);
2386 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2387 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2390 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2391 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2393 LayerTreeSettings settings;
2394 settings.max_partial_texture_updates = 4;
2396 scoped_ptr<LayerTreeHost> host =
2397 LayerTreeHost::CreateSingleThreaded(&client, &client, NULL, settings);
2398 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2399 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2402 TEST(LayerTreeHostTest,
2403 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2404 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2406 LayerTreeSettings settings;
2407 settings.max_partial_texture_updates = 4;
2409 scoped_ptr<LayerTreeHost> host =
2410 LayerTreeHost::CreateSingleThreaded(&client, &client, NULL, settings);
2411 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2412 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2415 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2416 : public LayerTreeHostTest {
2418 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2419 : root_layer_(FakeContentLayer::Create(&client_)),
2420 child_layer1_(FakeContentLayer::Create(&client_)),
2421 child_layer2_(FakeContentLayer::Create(&client_)),
2424 virtual void BeginTest() OVERRIDE {
2425 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2426 root_layer_->SetBounds(gfx::Size(100, 100));
2427 child_layer1_->SetBounds(gfx::Size(100, 100));
2428 child_layer2_->SetBounds(gfx::Size(100, 100));
2429 root_layer_->AddChild(child_layer1_);
2430 root_layer_->AddChild(child_layer2_);
2431 layer_tree_host()->SetRootLayer(root_layer_);
2432 PostSetNeedsCommitToMainThread();
2435 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2436 bool visible) OVERRIDE {
2438 // One backing should remain unevicted.
2440 100u * 100u * 4u * 1u,
2441 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2444 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2447 // Make sure that contents textures are marked as having been
2449 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2450 // End the test in this state.
2454 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2456 switch (num_commits_) {
2458 // All three backings should have memory.
2460 100u * 100u * 4u * 3u,
2461 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2462 // Set a new policy that will kick out 1 of the 3 resources.
2463 // Because a resource was evicted, a commit will be kicked off.
2464 host_impl->SetMemoryPolicy(
2465 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2466 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2470 // Only two backings should have memory.
2472 100u * 100u * 4u * 2u,
2473 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2474 // Become backgrounded, which will cause 1 more resource to be
2476 PostSetVisibleToMainThread(false);
2479 // No further commits should happen because this is not visible
2486 virtual void AfterTest() OVERRIDE {}
2489 FakeContentLayerClient client_;
2490 scoped_refptr<FakeContentLayer> root_layer_;
2491 scoped_refptr<FakeContentLayer> child_layer1_;
2492 scoped_refptr<FakeContentLayer> child_layer2_;
2496 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2497 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2499 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2501 class NotificationClient : public ContentLayerClient {
2503 NotificationClient()
2504 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2506 void set_layer(Layer* layer) { layer_ = layer; }
2507 int paint_count() const { return paint_count_; }
2508 int lcd_notification_count() const { return lcd_notification_count_; }
2510 virtual void PaintContents(SkCanvas* canvas,
2511 const gfx::Rect& clip,
2512 gfx::RectF* opaque) OVERRIDE {
2515 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2516 ++lcd_notification_count_;
2517 layer_->SetNeedsDisplay();
2523 int lcd_notification_count_;
2526 virtual void SetupTree() OVERRIDE {
2527 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2528 root_layer->SetIsDrawable(true);
2529 root_layer->SetBounds(gfx::Size(1, 1));
2531 layer_tree_host()->SetRootLayer(root_layer);
2532 client_.set_layer(root_layer.get());
2534 // The expecations are based on the assumption that the default
2535 // LCD settings are:
2536 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2537 EXPECT_FALSE(root_layer->can_use_lcd_text());
2539 LayerTreeHostTest::SetupTree();
2542 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2543 virtual void AfterTest() OVERRIDE {}
2545 virtual void DidCommit() OVERRIDE {
2546 switch (layer_tree_host()->source_frame_number()) {
2548 // The first update consists one LCD notification and one paint.
2549 EXPECT_EQ(1, client_.lcd_notification_count());
2550 EXPECT_EQ(1, client_.paint_count());
2551 // LCD text must have been enabled on the layer.
2552 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2553 PostSetNeedsCommitToMainThread();
2556 // Since nothing changed on layer, there should be no notification
2557 // or paint on the second update.
2558 EXPECT_EQ(1, client_.lcd_notification_count());
2559 EXPECT_EQ(1, client_.paint_count());
2560 // LCD text must not have changed.
2561 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2562 // Change layer opacity that should trigger lcd notification.
2563 layer_tree_host()->root_layer()->SetOpacity(.5f);
2564 // No need to request a commit - setting opacity will do it.
2567 // Verify that there is not extra commit due to layer invalidation.
2568 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
2569 // LCD notification count should have incremented due to
2570 // change in layer opacity.
2571 EXPECT_EQ(2, client_.lcd_notification_count());
2572 // Paint count should be incremented due to invalidation.
2573 EXPECT_EQ(2, client_.paint_count());
2574 // LCD text must have been disabled on the layer due to opacity.
2575 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2582 NotificationClient client_;
2585 SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2587 // Verify that the BeginImplFrame notification is used to initiate rendering.
2588 class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest {
2590 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2591 settings->begin_impl_frame_scheduling_enabled = true;
2594 virtual void BeginTest() OVERRIDE {
2595 // This will trigger a SetNeedsBeginImplFrame which will trigger a
2597 PostSetNeedsCommitToMainThread();
2600 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
2601 LayerTreeHostImpl* host_impl,
2602 LayerTreeHostImpl::FrameData* frame,
2603 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
2605 return DrawSwapReadbackResult::DRAW_SUCCESS;
2608 virtual void AfterTest() OVERRIDE {}
2611 base::TimeTicks frame_time_;
2614 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginImplFrameNotification);
2616 class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled
2617 : public LayerTreeHostTest {
2619 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2620 settings->begin_impl_frame_scheduling_enabled = true;
2621 settings->using_synchronous_renderer_compositor = true;
2624 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2626 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2627 // The BeginImplFrame notification is turned off now but will get enabled
2628 // once we return. End test while it's enabled.
2629 ImplThreadTaskRunner()->PostTask(
2631 base::Bind(&LayerTreeHostTestBeginImplFrameNotification::EndTest,
2632 base::Unretained(this)));
2635 virtual void AfterTest() OVERRIDE {}
2638 MULTI_THREAD_TEST_F(
2639 LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled);
2641 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2643 LayerTreeHostTestAbortedCommitDoesntStall()
2644 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2646 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2647 settings->begin_impl_frame_scheduling_enabled = true;
2650 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2652 virtual void DidCommit() OVERRIDE {
2654 if (commit_count_ == 4) {
2655 // After two aborted commits, request a real commit now to make sure a
2656 // real commit following an aborted commit will still complete and
2657 // end the test even when the Impl thread is idle.
2658 layer_tree_host()->SetNeedsCommit();
2662 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2663 bool did_handle) OVERRIDE {
2664 commit_abort_count_++;
2665 // Initiate another abortable commit.
2666 host_impl->SetNeedsCommit();
2669 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2670 commit_complete_count_++;
2671 if (commit_complete_count_ == 1) {
2672 // Initiate an abortable commit after the first commit.
2673 host_impl->SetNeedsCommit();
2679 virtual void AfterTest() OVERRIDE {
2680 EXPECT_EQ(commit_count_, 5);
2681 EXPECT_EQ(commit_abort_count_, 3);
2682 EXPECT_EQ(commit_complete_count_, 2);
2686 int commit_abort_count_;
2687 int commit_complete_count_;
2690 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2691 : public LayerTreeHostTestAbortedCommitDoesntStall {
2692 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2693 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2694 settings->using_synchronous_renderer_compositor = true;
2698 MULTI_THREAD_TEST_F(
2699 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2701 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2702 : public LayerTreeHostTestAbortedCommitDoesntStall {
2703 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2704 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2705 settings->throttle_frame_production = false;
2709 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2711 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2712 : public LayerTreeHostTest {
2714 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2715 settings->impl_side_painting = true;
2718 virtual void SetupTree() OVERRIDE {
2719 LayerTreeHostTest::SetupTree();
2721 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2722 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2723 layer->SetBounds(gfx::Size(10, 10));
2724 layer_tree_host()->root_layer()->AddChild(layer);
2727 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2729 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2733 virtual void AfterTest() OVERRIDE {}
2735 FakeContentLayerClient client_;
2738 MULTI_THREAD_TEST_F(
2739 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2741 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2742 : public LayerTreeHostTest {
2744 class SetBoundsClient : public ContentLayerClient {
2746 SetBoundsClient() : layer_(0) {}
2748 void set_layer(Layer* layer) { layer_ = layer; }
2750 virtual void PaintContents(SkCanvas* canvas,
2751 const gfx::Rect& clip,
2752 gfx::RectF* opaque) OVERRIDE {
2753 layer_->SetBounds(gfx::Size(2, 2));
2756 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2762 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2764 virtual void SetupTree() OVERRIDE {
2765 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2766 root_layer->SetIsDrawable(true);
2767 root_layer->SetBounds(gfx::Size(1, 1));
2769 layer_tree_host()->SetRootLayer(root_layer);
2770 client_.set_layer(root_layer.get());
2772 LayerTreeHostTest::SetupTree();
2775 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2776 virtual void AfterTest() OVERRIDE {}
2778 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2780 if (num_commits_ == 1) {
2781 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2782 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2784 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2785 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2791 SetBoundsClient client_;
2795 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2797 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2799 MockIOSurfaceWebGraphicsContext3D() {
2800 test_capabilities_.gpu.iosurface = true;
2801 test_capabilities_.gpu.texture_rectangle = true;
2804 virtual GLuint createTexture() OVERRIDE {
2807 MOCK_METHOD1(activeTexture, void(GLenum texture));
2808 MOCK_METHOD2(bindTexture, void(GLenum target,
2809 GLuint texture_id));
2810 MOCK_METHOD3(texParameteri, void(GLenum target,
2813 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2818 MOCK_METHOD4(drawElements, void(GLenum mode,
2822 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2825 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2827 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
2829 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2830 new MockIOSurfaceWebGraphicsContext3D);
2831 mock_context_ = mock_context_owned.get();
2833 return FakeOutputSurface::Create3d(
2834 mock_context_owned.PassAs<TestWebGraphicsContext3D>());
2837 virtual void SetupTree() OVERRIDE {
2838 LayerTreeHostTest::SetupTree();
2840 layer_tree_host()->root_layer()->SetIsDrawable(false);
2843 io_surface_size_ = gfx::Size(6, 7);
2845 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2846 io_surface_layer->SetBounds(gfx::Size(10, 10));
2847 io_surface_layer->SetAnchorPoint(gfx::PointF());
2848 io_surface_layer->SetIsDrawable(true);
2849 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2850 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2853 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2855 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2856 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2858 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2859 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2861 EXPECT_CALL(*mock_context_,
2863 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2865 EXPECT_CALL(*mock_context_,
2867 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2869 EXPECT_CALL(*mock_context_,
2870 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2872 GL_CLAMP_TO_EDGE)).Times(1);
2873 EXPECT_CALL(*mock_context_,
2874 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2876 GL_CLAMP_TO_EDGE)).Times(1);
2878 EXPECT_CALL(*mock_context_,
2879 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2880 io_surface_size_.width(),
2881 io_surface_size_.height(),
2885 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2888 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
2889 LayerTreeHostImpl* host_impl,
2890 LayerTreeHostImpl::FrameData* frame,
2891 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
2892 Mock::VerifyAndClearExpectations(&mock_context_);
2894 // The io surface layer's texture is drawn.
2895 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2896 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2898 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2904 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2905 Mock::VerifyAndClearExpectations(&mock_context_);
2907 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(1);
2911 virtual void AfterTest() OVERRIDE {}
2914 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2915 gfx::Size io_surface_size_;
2918 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
2919 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2920 LayerTreeHostTestIOSurfaceDrawing);
2922 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2924 virtual void BeginTest() OVERRIDE {
2926 PostSetNeedsCommitToMainThread();
2929 // Round 1: commit + draw
2930 // Round 2: commit only (no draw/swap)
2931 // Round 3: draw only (no commit)
2932 // Round 4: composite & readback (2 commits, no draw/swap)
2933 // Round 5: commit + draw
2935 virtual void DidCommit() OVERRIDE {
2936 int commit = layer_tree_host()->source_frame_number();
2940 EXPECT_EQ(1, frame_);
2941 layer_tree_host()->SetNeedsRedraw();
2944 // CompositeAndReadback in Round 4, first commit.
2945 EXPECT_EQ(2, frame_);
2949 EXPECT_EQ(2, frame_);
2950 layer_tree_host()->SetNeedsCommit();
2951 layer_tree_host()->SetNeedsRedraw();
2956 virtual void DidCompleteSwapBuffers() OVERRIDE {
2957 int commit = layer_tree_host()->source_frame_number();
2959 char pixels[4] = {0};
2963 EXPECT_EQ(1, commit);
2964 layer_tree_host()->SetNeedsCommit();
2968 EXPECT_EQ(2, commit);
2969 layer_tree_host()->CompositeAndReadback(pixels, gfx::Rect(0, 0, 1, 1));
2973 EXPECT_EQ(5, commit);
2979 virtual void AfterTest() OVERRIDE {}
2985 TEST_F(LayerTreeHostTestNumFramesPending, DelegatingRenderer) {
2986 RunTest(true, true, true);
2989 TEST_F(LayerTreeHostTestNumFramesPending, GLRenderer) {
2990 RunTest(true, false, true);
2993 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
2995 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2996 // PictureLayer can only be used with impl side painting enabled.
2997 settings->impl_side_painting = true;
3000 virtual void SetupTree() OVERRIDE {
3001 layer_ = FakePictureLayer::Create(&client_);
3002 // Force commits to not be aborted so new frames get drawn, otherwise
3003 // the renderer gets deferred initialized but nothing new needs drawing.
3004 layer_->set_always_update_resources(true);
3005 layer_tree_host()->SetRootLayer(layer_);
3006 LayerTreeHostTest::SetupTree();
3009 virtual void BeginTest() OVERRIDE {
3010 did_initialize_gl_ = false;
3011 did_release_gl_ = false;
3012 last_source_frame_number_drawn_ = -1; // Never drawn.
3013 PostSetNeedsCommitToMainThread();
3016 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
3018 scoped_ptr<TestWebGraphicsContext3D> context3d(
3019 TestWebGraphicsContext3D::Create());
3021 return FakeOutputSurface::CreateDeferredGL(
3022 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice));
3025 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3026 ASSERT_TRUE(host_impl->RootLayer());
3027 FakePictureLayerImpl* layer_impl =
3028 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
3030 // The same frame can be draw multiple times if new visible tiles are
3031 // rasterized. But we want to make sure we only post DeferredInitialize
3032 // and ReleaseGL once, so early out if the same frame is drawn again.
3033 if (last_source_frame_number_drawn_ ==
3034 host_impl->active_tree()->source_frame_number())
3037 last_source_frame_number_drawn_ =
3038 host_impl->active_tree()->source_frame_number();
3040 if (!did_initialize_gl_) {
3041 EXPECT_LE(1u, layer_impl->append_quads_count());
3042 ImplThreadTaskRunner()->PostTask(
3045 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3046 base::Unretained(this),
3047 base::Unretained(host_impl)));
3048 } else if (did_initialize_gl_ && !did_release_gl_) {
3049 EXPECT_LE(2u, layer_impl->append_quads_count());
3050 ImplThreadTaskRunner()->PostTask(
3052 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3053 base::Unretained(this),
3054 base::Unretained(host_impl)));
3055 } else if (did_initialize_gl_ && did_release_gl_) {
3056 EXPECT_LE(3u, layer_impl->append_quads_count());
3061 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
3062 EXPECT_FALSE(did_initialize_gl_);
3063 // SetAndInitializeContext3D calls SetNeedsCommit.
3064 FakeOutputSurface* fake_output_surface =
3065 static_cast<FakeOutputSurface*>(host_impl->output_surface());
3066 scoped_refptr<TestContextProvider> context_provider =
3067 TestContextProvider::Create(); // Not bound to thread.
3069 fake_output_surface->InitializeAndSetContext3d(context_provider, NULL));
3070 did_initialize_gl_ = true;
3073 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3074 EXPECT_TRUE(did_initialize_gl_);
3075 EXPECT_FALSE(did_release_gl_);
3076 // ReleaseGL calls SetNeedsCommit.
3077 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3078 did_release_gl_ = true;
3081 virtual void AfterTest() OVERRIDE {
3082 EXPECT_TRUE(did_initialize_gl_);
3083 EXPECT_TRUE(did_release_gl_);
3087 FakeContentLayerClient client_;
3088 scoped_refptr<FakePictureLayer> layer_;
3089 bool did_initialize_gl_;
3090 bool did_release_gl_;
3091 int last_source_frame_number_drawn_;
3094 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3096 // Test for UI Resource management.
3097 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3099 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
3101 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3102 settings->texture_id_allocation_chunk_size = 1;
3105 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3107 virtual void DidCommit() OVERRIDE {
3108 int frame = layer_tree_host()->source_frame_number();
3113 PostSetNeedsCommitToMainThread();
3116 // Usually ScopedUIResource are deleted from the manager in their
3117 // destructor. Here we just want to test that a direct call to
3118 // DeleteUIResource works.
3119 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3120 PostSetNeedsCommitToMainThread();
3123 // DeleteUIResource can be called with an invalid id.
3124 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3125 PostSetNeedsCommitToMainThread();
3130 PostSetNeedsCommitToMainThread();
3139 void PerformTest(LayerTreeHostImpl* impl) {
3140 TestWebGraphicsContext3D* context = TestContext();
3142 int frame = impl->active_tree()->source_frame_number();
3145 ASSERT_EQ(0u, context->NumTextures());
3148 // Created two textures.
3149 ASSERT_EQ(2u, context->NumTextures());
3152 // One texture left after one deletion.
3153 ASSERT_EQ(1u, context->NumTextures());
3156 // Resource manager state should not change when delete is called on an
3158 ASSERT_EQ(1u, context->NumTextures());
3161 // Creation after deletion: two more creates should total up to
3163 ASSERT_EQ(3u, context->NumTextures());
3168 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3169 if (!layer_tree_host()->settings().impl_side_painting)
3173 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3174 if (layer_tree_host()->settings().impl_side_painting)
3178 virtual void AfterTest() OVERRIDE {}
3181 // Must clear all resources before exiting.
3182 void ClearResources() {
3183 for (int i = 0; i < num_ui_resources_; i++)
3184 ui_resources_[i].reset();
3187 void CreateResource() {
3188 ui_resources_[num_ui_resources_++] =
3189 FakeScopedUIResource::Create(layer_tree_host());
3192 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3193 int num_ui_resources_;
3196 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3198 class PushPropertiesCountingLayerImpl : public LayerImpl {
3200 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
3201 LayerTreeImpl* tree_impl, int id) {
3202 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
3205 virtual ~PushPropertiesCountingLayerImpl() {}
3207 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
3208 LayerImpl::PushPropertiesTo(layer);
3209 push_properties_count_++;
3210 // Push state to the active tree because we can only access it from there.
3211 static_cast<PushPropertiesCountingLayerImpl*>(
3212 layer)->push_properties_count_ = push_properties_count_;
3215 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
3217 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
3218 PassAs<LayerImpl>();
3221 size_t push_properties_count() const { return push_properties_count_; }
3222 void reset_push_properties_count() { push_properties_count_ = 0; }
3225 size_t push_properties_count_;
3227 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
3228 : LayerImpl(tree_impl, id),
3229 push_properties_count_(0) {
3230 SetAnchorPoint(gfx::PointF());
3231 SetBounds(gfx::Size(1, 1));
3235 class PushPropertiesCountingLayer : public Layer {
3237 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3238 return new PushPropertiesCountingLayer();
3241 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
3242 Layer::PushPropertiesTo(layer);
3243 push_properties_count_++;
3244 if (persist_needs_push_properties_)
3245 needs_push_properties_ = true;
3248 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
3250 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
3251 PassAs<LayerImpl>();
3254 size_t push_properties_count() const { return push_properties_count_; }
3255 void reset_push_properties_count() { push_properties_count_ = 0; }
3257 void set_persist_needs_push_properties(bool persist) {
3258 persist_needs_push_properties_ = persist;
3262 PushPropertiesCountingLayer()
3263 : push_properties_count_(0), persist_needs_push_properties_(false) {
3264 SetAnchorPoint(gfx::PointF());
3265 SetBounds(gfx::Size(1, 1));
3266 SetIsDrawable(true);
3268 virtual ~PushPropertiesCountingLayer() {}
3270 size_t push_properties_count_;
3271 bool persist_needs_push_properties_;
3274 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3276 virtual void BeginTest() OVERRIDE {
3278 expected_push_properties_root_ = 0;
3279 expected_push_properties_child_ = 0;
3280 expected_push_properties_grandchild_ = 0;
3281 expected_push_properties_child2_ = 0;
3282 expected_push_properties_other_root_ = 0;
3283 expected_push_properties_leaf_layer_ = 0;
3284 PostSetNeedsCommitToMainThread();
3287 virtual void SetupTree() OVERRIDE {
3288 root_ = PushPropertiesCountingLayer::Create();
3289 child_ = PushPropertiesCountingLayer::Create();
3290 child2_ = PushPropertiesCountingLayer::Create();
3291 grandchild_ = PushPropertiesCountingLayer::Create();
3292 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3293 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3295 root_->AddChild(child_);
3296 root_->AddChild(child2_);
3297 child_->AddChild(grandchild_);
3298 child2_->AddChild(leaf_always_pushing_layer_);
3300 other_root_ = PushPropertiesCountingLayer::Create();
3302 // Don't set the root layer here.
3303 LayerTreeHostTest::SetupTree();
3306 virtual void DidCommitAndDrawFrame() OVERRIDE {
3309 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3310 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3311 EXPECT_EQ(expected_push_properties_grandchild_,
3312 grandchild_->push_properties_count());
3313 EXPECT_EQ(expected_push_properties_child2_,
3314 child2_->push_properties_count());
3315 EXPECT_EQ(expected_push_properties_other_root_,
3316 other_root_->push_properties_count());
3317 EXPECT_EQ(expected_push_properties_leaf_layer_,
3318 leaf_always_pushing_layer_->push_properties_count());
3320 // The scrollbar layer always needs to be pushed.
3321 if (root_->layer_tree_host()) {
3322 EXPECT_TRUE(root_->descendant_needs_push_properties());
3323 EXPECT_FALSE(root_->needs_push_properties());
3325 if (child2_->layer_tree_host()) {
3326 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3327 EXPECT_FALSE(child2_->needs_push_properties());
3329 if (leaf_always_pushing_layer_->layer_tree_host()) {
3331 leaf_always_pushing_layer_->descendant_needs_push_properties());
3332 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3335 // child_ and grandchild_ don't persist their need to push properties.
3336 if (child_->layer_tree_host()) {
3337 EXPECT_FALSE(child_->descendant_needs_push_properties());
3338 EXPECT_FALSE(child_->needs_push_properties());
3340 if (grandchild_->layer_tree_host()) {
3341 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3342 EXPECT_FALSE(grandchild_->needs_push_properties());
3345 if (other_root_->layer_tree_host()) {
3346 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3347 EXPECT_FALSE(other_root_->needs_push_properties());
3350 switch (num_commits_) {
3352 layer_tree_host()->SetRootLayer(root_);
3353 // Layers added to the tree get committed.
3354 ++expected_push_properties_root_;
3355 ++expected_push_properties_child_;
3356 ++expected_push_properties_grandchild_;
3357 ++expected_push_properties_child2_;
3360 layer_tree_host()->SetNeedsCommit();
3361 // No layers need commit.
3364 layer_tree_host()->SetRootLayer(other_root_);
3365 // Layers added to the tree get committed.
3366 ++expected_push_properties_other_root_;
3369 layer_tree_host()->SetRootLayer(root_);
3370 // Layers added to the tree get committed.
3371 ++expected_push_properties_root_;
3372 ++expected_push_properties_child_;
3373 ++expected_push_properties_grandchild_;
3374 ++expected_push_properties_child2_;
3377 layer_tree_host()->SetNeedsCommit();
3378 // No layers need commit.
3381 child_->RemoveFromParent();
3382 // No layers need commit.
3385 root_->AddChild(child_);
3386 // Layers added to the tree get committed.
3387 ++expected_push_properties_child_;
3388 ++expected_push_properties_grandchild_;
3391 grandchild_->RemoveFromParent();
3392 // No layers need commit.
3395 child_->AddChild(grandchild_);
3396 // Layers added to the tree get committed.
3397 ++expected_push_properties_grandchild_;
3400 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3401 // No layers need commit.
3404 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3405 // No layers need commit.
3408 child_->SetPosition(gfx::Point(1, 1));
3409 // The modified layer needs commit
3410 ++expected_push_properties_child_;
3413 child2_->SetPosition(gfx::Point(1, 1));
3414 // The modified layer needs commit
3415 ++expected_push_properties_child2_;
3418 child_->RemoveFromParent();
3419 root_->AddChild(child_);
3420 // Layers added to the tree get committed.
3421 ++expected_push_properties_child_;
3422 ++expected_push_properties_grandchild_;
3425 grandchild_->SetPosition(gfx::Point(1, 1));
3426 // The modified layer needs commit
3427 ++expected_push_properties_grandchild_;
3430 // SetNeedsDisplay does not always set needs commit (so call it
3431 // explicitly), but is a property change.
3432 child_->SetNeedsDisplay();
3433 ++expected_push_properties_child_;
3434 layer_tree_host()->SetNeedsCommit();
3441 // The leaf layer always pushes.
3442 if (leaf_always_pushing_layer_->layer_tree_host())
3443 ++expected_push_properties_leaf_layer_;
3446 virtual void AfterTest() OVERRIDE {}
3449 FakeContentLayerClient client_;
3450 scoped_refptr<PushPropertiesCountingLayer> root_;
3451 scoped_refptr<PushPropertiesCountingLayer> child_;
3452 scoped_refptr<PushPropertiesCountingLayer> child2_;
3453 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3454 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3455 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3456 size_t expected_push_properties_root_;
3457 size_t expected_push_properties_child_;
3458 size_t expected_push_properties_child2_;
3459 size_t expected_push_properties_grandchild_;
3460 size_t expected_push_properties_other_root_;
3461 size_t expected_push_properties_leaf_layer_;
3464 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3466 class LayerTreeHostTestImplLayersPushProperties
3467 : public LayerTreeHostTestLayersPushProperties {
3469 virtual void BeginTest() OVERRIDE {
3470 expected_push_properties_root_impl_ = 0;
3471 expected_push_properties_child_impl_ = 0;
3472 expected_push_properties_grandchild_impl_ = 0;
3473 expected_push_properties_child2_impl_ = 0;
3474 expected_push_properties_grandchild2_impl_ = 0;
3475 LayerTreeHostTestLayersPushProperties::BeginTest();
3478 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3479 // These commits are in response to the changes made in
3480 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3481 switch (num_commits_) {
3483 // Tree hasn't been setup yet don't bother to check anything.
3486 // Root gets set up, Everyone is initialized.
3487 ++expected_push_properties_root_impl_;
3488 ++expected_push_properties_child_impl_;
3489 ++expected_push_properties_grandchild_impl_;
3490 ++expected_push_properties_child2_impl_;
3491 ++expected_push_properties_grandchild2_impl_;
3494 // Tree doesn't change but the one leaf that always pushes is pushed.
3495 ++expected_push_properties_grandchild2_impl_;
3498 // Root is swapped here.
3499 // Clear the expected push properties the tree will be rebuilt.
3500 expected_push_properties_root_impl_ = 0;
3501 expected_push_properties_child_impl_ = 0;
3502 expected_push_properties_grandchild_impl_ = 0;
3503 expected_push_properties_child2_impl_ = 0;
3504 expected_push_properties_grandchild2_impl_ = 0;
3506 // Make sure the new root is pushed.
3507 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3508 host_impl->RootLayer())->push_properties_count());
3511 // Root is swapped back all of the layers in the tree get pushed.
3512 ++expected_push_properties_root_impl_;
3513 ++expected_push_properties_child_impl_;
3514 ++expected_push_properties_grandchild_impl_;
3515 ++expected_push_properties_child2_impl_;
3516 ++expected_push_properties_grandchild2_impl_;
3519 // Tree doesn't change but the one leaf that always pushes is pushed.
3520 ++expected_push_properties_grandchild2_impl_;
3523 // First child is removed. Structure of the tree changes here so swap
3524 // some of the values. child_impl becomes child2_impl.
3525 expected_push_properties_child_impl_ =
3526 expected_push_properties_child2_impl_;
3527 expected_push_properties_child2_impl_ = 0;
3528 // grandchild_impl becomes grandchild2_impl.
3529 expected_push_properties_grandchild_impl_ =
3530 expected_push_properties_grandchild2_impl_;
3531 expected_push_properties_grandchild2_impl_ = 0;
3533 // grandchild_impl is now the leaf that always pushes. It is pushed.
3534 ++expected_push_properties_grandchild_impl_;
3537 // The leaf that always pushes is pushed.
3538 ++expected_push_properties_grandchild_impl_;
3540 // Child is added back. New layers are initialized.
3541 ++expected_push_properties_grandchild2_impl_;
3542 ++expected_push_properties_child2_impl_;
3546 expected_push_properties_grandchild2_impl_ = 0;
3549 ++expected_push_properties_grandchild_impl_;
3552 // Leaf is added back
3553 ++expected_push_properties_grandchild2_impl_;
3555 // The leaf that always pushes is pushed.
3556 ++expected_push_properties_grandchild_impl_;
3559 // The leaf that always pushes is pushed.
3560 ++expected_push_properties_grandchild_impl_;
3563 // The leaf that always pushes is pushed.
3564 ++expected_push_properties_grandchild_impl_;
3567 // The leaf that always pushes is pushed.
3568 ++expected_push_properties_grandchild_impl_;
3570 // This child position was changed.
3571 ++expected_push_properties_child2_impl_;
3574 // The position of this child was changed.
3575 ++expected_push_properties_child_impl_;
3577 // The leaf that always pushes is pushed.
3578 ++expected_push_properties_grandchild_impl_;
3581 // Second child is removed from tree. Don't discard counts because
3582 // they are added back before commit.
3584 // The leaf that always pushes is pushed.
3585 ++expected_push_properties_grandchild_impl_;
3587 // Second child added back.
3588 ++expected_push_properties_child2_impl_;
3589 ++expected_push_properties_grandchild2_impl_;
3593 // The position of this child was changed.
3594 ++expected_push_properties_grandchild2_impl_;
3596 // The leaf that always pushes is pushed.
3597 ++expected_push_properties_grandchild_impl_;
3600 // Second child is invalidated with SetNeedsDisplay
3601 ++expected_push_properties_child2_impl_;
3603 // The leaf that always pushed is pushed.
3604 ++expected_push_properties_grandchild_impl_;
3608 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3609 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3610 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3611 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3612 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3614 // Pull the layers that we need from the tree assuming the same structure
3615 // as LayerTreeHostTestLayersPushProperties
3616 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3617 host_impl->RootLayer());
3619 if (root_impl_ && root_impl_->children().size() > 0) {
3620 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3621 root_impl_->children()[0]);
3623 if (child_impl_ && child_impl_->children().size() > 0)
3624 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3625 child_impl_->children()[0]);
3628 if (root_impl_ && root_impl_->children().size() > 1) {
3629 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3630 root_impl_->children()[1]);
3632 if (child2_impl_ && child2_impl_->children().size() > 0)
3633 leaf_always_pushing_layer_impl_ =
3634 static_cast<PushPropertiesCountingLayerImpl*>(
3635 child2_impl_->children()[0]);
3639 EXPECT_EQ(expected_push_properties_root_impl_,
3640 root_impl_->push_properties_count());
3642 EXPECT_EQ(expected_push_properties_child_impl_,
3643 child_impl_->push_properties_count());
3644 if (grandchild_impl_)
3645 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3646 grandchild_impl_->push_properties_count());
3648 EXPECT_EQ(expected_push_properties_child2_impl_,
3649 child2_impl_->push_properties_count());
3650 if (leaf_always_pushing_layer_impl_)
3651 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3652 leaf_always_pushing_layer_impl_->push_properties_count());
3655 size_t expected_push_properties_root_impl_;
3656 size_t expected_push_properties_child_impl_;
3657 size_t expected_push_properties_child2_impl_;
3658 size_t expected_push_properties_grandchild_impl_;
3659 size_t expected_push_properties_grandchild2_impl_;
3662 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3663 RunTestWithImplSidePainting();
3666 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3667 : public LayerTreeHostTest {
3669 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3671 virtual void SetupTree() OVERRIDE {
3672 root_ = Layer::Create();
3673 root_->SetBounds(gfx::Size(1, 1));
3675 bool paint_scrollbar = true;
3676 bool has_thumb = false;
3677 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3678 paint_scrollbar, has_thumb, root_->id());
3680 root_->AddChild(scrollbar_layer_);
3682 layer_tree_host()->SetRootLayer(root_);
3683 LayerTreeHostTest::SetupTree();
3686 virtual void DidCommitAndDrawFrame() OVERRIDE {
3687 switch (layer_tree_host()->source_frame_number()) {
3691 // During update, the ignore_set_needs_commit_ bit is set to true to
3692 // avoid causing a second commit to be scheduled. If a property change
3693 // is made during this, however, it needs to be pushed in the upcoming
3695 scoped_ptr<base::AutoReset<bool> > ignore =
3696 scrollbar_layer_->IgnoreSetNeedsCommit();
3698 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3700 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3701 EXPECT_TRUE(root_->descendant_needs_push_properties());
3702 layer_tree_host()->SetNeedsCommit();
3704 scrollbar_layer_->reset_push_properties_count();
3705 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3709 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3715 virtual void AfterTest() OVERRIDE {}
3717 scoped_refptr<Layer> root_;
3718 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3721 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3723 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3724 : public LayerTreeHostTest {
3726 virtual void BeginTest() OVERRIDE {
3727 expected_push_properties_root_ = 0;
3728 expected_push_properties_child_ = 0;
3729 expected_push_properties_grandchild1_ = 0;
3730 expected_push_properties_grandchild2_ = 0;
3731 expected_push_properties_grandchild3_ = 0;
3732 PostSetNeedsCommitToMainThread();
3735 virtual void SetupTree() OVERRIDE {
3736 root_ = PushPropertiesCountingLayer::Create();
3737 child_ = PushPropertiesCountingLayer::Create();
3738 grandchild1_ = PushPropertiesCountingLayer::Create();
3739 grandchild2_ = PushPropertiesCountingLayer::Create();
3740 grandchild3_ = PushPropertiesCountingLayer::Create();
3742 root_->AddChild(child_);
3743 child_->AddChild(grandchild1_);
3744 child_->AddChild(grandchild2_);
3745 child_->AddChild(grandchild3_);
3747 // Don't set the root layer here.
3748 LayerTreeHostTest::SetupTree();
3751 virtual void AfterTest() OVERRIDE {}
3753 FakeContentLayerClient client_;
3754 scoped_refptr<PushPropertiesCountingLayer> root_;
3755 scoped_refptr<PushPropertiesCountingLayer> child_;
3756 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3757 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3758 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3759 size_t expected_push_properties_root_;
3760 size_t expected_push_properties_child_;
3761 size_t expected_push_properties_grandchild1_;
3762 size_t expected_push_properties_grandchild2_;
3763 size_t expected_push_properties_grandchild3_;
3766 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3767 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3769 virtual void DidCommitAndDrawFrame() OVERRIDE {
3770 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3771 switch (last_source_frame_number) {
3773 EXPECT_FALSE(root_->needs_push_properties());
3774 EXPECT_FALSE(root_->descendant_needs_push_properties());
3775 EXPECT_FALSE(child_->needs_push_properties());
3776 EXPECT_FALSE(child_->descendant_needs_push_properties());
3777 EXPECT_FALSE(grandchild1_->needs_push_properties());
3778 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3779 EXPECT_FALSE(grandchild2_->needs_push_properties());
3780 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3781 EXPECT_FALSE(grandchild3_->needs_push_properties());
3782 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3784 layer_tree_host()->SetRootLayer(root_);
3786 EXPECT_TRUE(root_->needs_push_properties());
3787 EXPECT_TRUE(root_->descendant_needs_push_properties());
3788 EXPECT_TRUE(child_->needs_push_properties());
3789 EXPECT_TRUE(child_->descendant_needs_push_properties());
3790 EXPECT_TRUE(grandchild1_->needs_push_properties());
3791 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3792 EXPECT_TRUE(grandchild2_->needs_push_properties());
3793 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3794 EXPECT_TRUE(grandchild3_->needs_push_properties());
3795 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3804 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3806 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3807 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3809 virtual void DidCommitAndDrawFrame() OVERRIDE {
3810 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3811 switch (last_source_frame_number) {
3813 layer_tree_host()->SetRootLayer(root_);
3816 EXPECT_FALSE(root_->needs_push_properties());
3817 EXPECT_FALSE(root_->descendant_needs_push_properties());
3818 EXPECT_FALSE(child_->needs_push_properties());
3819 EXPECT_FALSE(child_->descendant_needs_push_properties());
3820 EXPECT_FALSE(grandchild1_->needs_push_properties());
3821 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3822 EXPECT_FALSE(grandchild2_->needs_push_properties());
3823 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3824 EXPECT_FALSE(grandchild3_->needs_push_properties());
3825 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3827 grandchild1_->RemoveFromParent();
3828 grandchild1_->SetPosition(gfx::Point(1, 1));
3830 EXPECT_FALSE(root_->needs_push_properties());
3831 EXPECT_FALSE(root_->descendant_needs_push_properties());
3832 EXPECT_FALSE(child_->needs_push_properties());
3833 EXPECT_FALSE(child_->descendant_needs_push_properties());
3834 EXPECT_FALSE(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 child_->AddChild(grandchild1_);
3841 EXPECT_FALSE(root_->needs_push_properties());
3842 EXPECT_TRUE(root_->descendant_needs_push_properties());
3843 EXPECT_FALSE(child_->needs_push_properties());
3844 EXPECT_TRUE(child_->descendant_needs_push_properties());
3845 EXPECT_TRUE(grandchild1_->needs_push_properties());
3846 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3847 EXPECT_FALSE(grandchild2_->needs_push_properties());
3848 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3849 EXPECT_FALSE(grandchild3_->needs_push_properties());
3850 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3852 grandchild2_->SetPosition(gfx::Point(1, 1));
3854 EXPECT_FALSE(root_->needs_push_properties());
3855 EXPECT_TRUE(root_->descendant_needs_push_properties());
3856 EXPECT_FALSE(child_->needs_push_properties());
3857 EXPECT_TRUE(child_->descendant_needs_push_properties());
3858 EXPECT_TRUE(grandchild1_->needs_push_properties());
3859 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3860 EXPECT_TRUE(grandchild2_->needs_push_properties());
3861 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3862 EXPECT_FALSE(grandchild3_->needs_push_properties());
3863 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3865 // grandchild2_ will still need a push properties.
3866 grandchild1_->RemoveFromParent();
3868 EXPECT_FALSE(root_->needs_push_properties());
3869 EXPECT_TRUE(root_->descendant_needs_push_properties());
3870 EXPECT_FALSE(child_->needs_push_properties());
3871 EXPECT_TRUE(child_->descendant_needs_push_properties());
3873 // grandchild3_ does not need a push properties, so recursing should
3874 // no longer be needed.
3875 grandchild2_->RemoveFromParent();
3877 EXPECT_FALSE(root_->needs_push_properties());
3878 EXPECT_FALSE(root_->descendant_needs_push_properties());
3879 EXPECT_FALSE(child_->needs_push_properties());
3880 EXPECT_FALSE(child_->descendant_needs_push_properties());
3887 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3889 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3890 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3892 virtual void DidCommitAndDrawFrame() OVERRIDE {
3893 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3894 switch (last_source_frame_number) {
3896 layer_tree_host()->SetRootLayer(root_);
3897 grandchild1_->set_persist_needs_push_properties(true);
3898 grandchild2_->set_persist_needs_push_properties(true);
3901 EXPECT_FALSE(root_->needs_push_properties());
3902 EXPECT_TRUE(root_->descendant_needs_push_properties());
3903 EXPECT_FALSE(child_->needs_push_properties());
3904 EXPECT_TRUE(child_->descendant_needs_push_properties());
3905 EXPECT_TRUE(grandchild1_->needs_push_properties());
3906 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3907 EXPECT_TRUE(grandchild2_->needs_push_properties());
3908 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3909 EXPECT_FALSE(grandchild3_->needs_push_properties());
3910 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3912 // grandchild2_ will still need a push properties.
3913 grandchild1_->RemoveFromParent();
3915 EXPECT_FALSE(root_->needs_push_properties());
3916 EXPECT_TRUE(root_->descendant_needs_push_properties());
3917 EXPECT_FALSE(child_->needs_push_properties());
3918 EXPECT_TRUE(child_->descendant_needs_push_properties());
3920 // grandchild3_ does not need a push properties, so recursing should
3921 // no longer be needed.
3922 grandchild2_->RemoveFromParent();
3924 EXPECT_FALSE(root_->needs_push_properties());
3925 EXPECT_FALSE(root_->descendant_needs_push_properties());
3926 EXPECT_FALSE(child_->needs_push_properties());
3927 EXPECT_FALSE(child_->descendant_needs_push_properties());
3934 MULTI_THREAD_TEST_F(
3935 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3937 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3938 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3940 virtual void DidCommitAndDrawFrame() OVERRIDE {
3941 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3942 switch (last_source_frame_number) {
3944 layer_tree_host()->SetRootLayer(root_);
3947 EXPECT_FALSE(root_->needs_push_properties());
3948 EXPECT_FALSE(root_->descendant_needs_push_properties());
3949 EXPECT_FALSE(child_->needs_push_properties());
3950 EXPECT_FALSE(child_->descendant_needs_push_properties());
3951 EXPECT_FALSE(grandchild1_->needs_push_properties());
3952 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3953 EXPECT_FALSE(grandchild2_->needs_push_properties());
3954 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3955 EXPECT_FALSE(grandchild3_->needs_push_properties());
3956 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3958 // Change grandchildren while their parent is not in the tree.
3959 child_->RemoveFromParent();
3960 grandchild1_->SetPosition(gfx::Point(1, 1));
3961 grandchild2_->SetPosition(gfx::Point(1, 1));
3962 root_->AddChild(child_);
3964 EXPECT_FALSE(root_->needs_push_properties());
3965 EXPECT_TRUE(root_->descendant_needs_push_properties());
3966 EXPECT_TRUE(child_->needs_push_properties());
3967 EXPECT_TRUE(child_->descendant_needs_push_properties());
3968 EXPECT_TRUE(grandchild1_->needs_push_properties());
3969 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3970 EXPECT_TRUE(grandchild2_->needs_push_properties());
3971 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3972 EXPECT_TRUE(grandchild3_->needs_push_properties());
3973 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3975 grandchild1_->RemoveFromParent();
3977 EXPECT_FALSE(root_->needs_push_properties());
3978 EXPECT_TRUE(root_->descendant_needs_push_properties());
3979 EXPECT_TRUE(child_->needs_push_properties());
3980 EXPECT_TRUE(child_->descendant_needs_push_properties());
3982 grandchild2_->RemoveFromParent();
3984 EXPECT_FALSE(root_->needs_push_properties());
3985 EXPECT_TRUE(root_->descendant_needs_push_properties());
3986 EXPECT_TRUE(child_->needs_push_properties());
3987 EXPECT_TRUE(child_->descendant_needs_push_properties());
3989 grandchild3_->RemoveFromParent();
3991 EXPECT_FALSE(root_->needs_push_properties());
3992 EXPECT_TRUE(root_->descendant_needs_push_properties());
3993 EXPECT_TRUE(child_->needs_push_properties());
3994 EXPECT_FALSE(child_->descendant_needs_push_properties());
4002 MULTI_THREAD_TEST_F(
4003 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4005 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4006 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4008 virtual void DidCommitAndDrawFrame() OVERRIDE {
4009 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4010 switch (last_source_frame_number) {
4012 layer_tree_host()->SetRootLayer(root_);
4015 EXPECT_FALSE(root_->needs_push_properties());
4016 EXPECT_FALSE(root_->descendant_needs_push_properties());
4017 EXPECT_FALSE(child_->needs_push_properties());
4018 EXPECT_FALSE(child_->descendant_needs_push_properties());
4019 EXPECT_FALSE(grandchild1_->needs_push_properties());
4020 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4021 EXPECT_FALSE(grandchild2_->needs_push_properties());
4022 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4023 EXPECT_FALSE(grandchild3_->needs_push_properties());
4024 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4026 child_->SetPosition(gfx::Point(1, 1));
4027 grandchild1_->SetPosition(gfx::Point(1, 1));
4028 grandchild2_->SetPosition(gfx::Point(1, 1));
4030 EXPECT_FALSE(root_->needs_push_properties());
4031 EXPECT_TRUE(root_->descendant_needs_push_properties());
4032 EXPECT_TRUE(child_->needs_push_properties());
4033 EXPECT_TRUE(child_->descendant_needs_push_properties());
4034 EXPECT_TRUE(grandchild1_->needs_push_properties());
4035 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4036 EXPECT_TRUE(grandchild2_->needs_push_properties());
4037 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4038 EXPECT_FALSE(grandchild3_->needs_push_properties());
4039 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4041 grandchild1_->RemoveFromParent();
4043 EXPECT_FALSE(root_->needs_push_properties());
4044 EXPECT_TRUE(root_->descendant_needs_push_properties());
4045 EXPECT_TRUE(child_->needs_push_properties());
4046 EXPECT_TRUE(child_->descendant_needs_push_properties());
4048 grandchild2_->RemoveFromParent();
4050 EXPECT_FALSE(root_->needs_push_properties());
4051 EXPECT_TRUE(root_->descendant_needs_push_properties());
4052 EXPECT_TRUE(child_->needs_push_properties());
4053 EXPECT_FALSE(child_->descendant_needs_push_properties());
4055 child_->RemoveFromParent();
4057 EXPECT_FALSE(root_->needs_push_properties());
4058 EXPECT_FALSE(root_->descendant_needs_push_properties());
4066 MULTI_THREAD_TEST_F(
4067 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4069 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4070 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4072 virtual void DidCommitAndDrawFrame() OVERRIDE {
4073 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4074 switch (last_source_frame_number) {
4076 layer_tree_host()->SetRootLayer(root_);
4079 EXPECT_FALSE(root_->needs_push_properties());
4080 EXPECT_FALSE(root_->descendant_needs_push_properties());
4081 EXPECT_FALSE(child_->needs_push_properties());
4082 EXPECT_FALSE(child_->descendant_needs_push_properties());
4083 EXPECT_FALSE(grandchild1_->needs_push_properties());
4084 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4085 EXPECT_FALSE(grandchild2_->needs_push_properties());
4086 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4087 EXPECT_FALSE(grandchild3_->needs_push_properties());
4088 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4090 grandchild1_->SetPosition(gfx::Point(1, 1));
4091 grandchild2_->SetPosition(gfx::Point(1, 1));
4092 child_->SetPosition(gfx::Point(1, 1));
4094 EXPECT_FALSE(root_->needs_push_properties());
4095 EXPECT_TRUE(root_->descendant_needs_push_properties());
4096 EXPECT_TRUE(child_->needs_push_properties());
4097 EXPECT_TRUE(child_->descendant_needs_push_properties());
4098 EXPECT_TRUE(grandchild1_->needs_push_properties());
4099 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4100 EXPECT_TRUE(grandchild2_->needs_push_properties());
4101 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4102 EXPECT_FALSE(grandchild3_->needs_push_properties());
4103 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4105 grandchild1_->RemoveFromParent();
4107 EXPECT_FALSE(root_->needs_push_properties());
4108 EXPECT_TRUE(root_->descendant_needs_push_properties());
4109 EXPECT_TRUE(child_->needs_push_properties());
4110 EXPECT_TRUE(child_->descendant_needs_push_properties());
4112 grandchild2_->RemoveFromParent();
4114 EXPECT_FALSE(root_->needs_push_properties());
4115 EXPECT_TRUE(root_->descendant_needs_push_properties());
4116 EXPECT_TRUE(child_->needs_push_properties());
4117 EXPECT_FALSE(child_->descendant_needs_push_properties());
4119 child_->RemoveFromParent();
4121 EXPECT_FALSE(root_->needs_push_properties());
4122 EXPECT_FALSE(root_->descendant_needs_push_properties());
4130 MULTI_THREAD_TEST_F(
4131 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4133 // This test verifies that the tree activation callback is invoked correctly.
4134 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4136 LayerTreeHostTestTreeActivationCallback()
4137 : num_commits_(0), callback_count_(0) {}
4139 virtual void BeginTest() OVERRIDE {
4140 EXPECT_TRUE(HasImplThread());
4141 PostSetNeedsCommitToMainThread();
4144 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
4145 LayerTreeHostImpl* host_impl,
4146 LayerTreeHostImpl::FrameData* frame_data,
4147 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
4149 switch (num_commits_) {
4151 EXPECT_EQ(0, callback_count_);
4152 callback_count_ = 0;
4154 PostSetNeedsCommitToMainThread();
4157 EXPECT_EQ(1, callback_count_);
4158 callback_count_ = 0;
4160 PostSetNeedsCommitToMainThread();
4163 EXPECT_EQ(0, callback_count_);
4164 callback_count_ = 0;
4168 ADD_FAILURE() << num_commits_;
4172 return LayerTreeHostTest::PrepareToDrawOnThread(
4173 host_impl, frame_data, draw_result);
4176 virtual void AfterTest() OVERRIDE { EXPECT_EQ(3, num_commits_); }
4178 void SetCallback(bool enable) {
4179 output_surface()->SetTreeActivationCallback(
4182 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4183 base::Unretained(this))
4187 void ActivationCallback() { ++callback_count_; }
4190 int callback_count_;
4193 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4194 RunTest(true, false, true);
4197 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4198 RunTest(true, true, true);
4201 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4203 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4205 virtual void BeginTest() OVERRIDE {
4206 ASSERT_TRUE(!!invalidate_layer_)
4207 << "Derived tests must set this in SetupTree";
4209 // One initial commit.
4210 PostSetNeedsCommitToMainThread();
4213 virtual void DidCommitAndDrawFrame() OVERRIDE {
4214 // After commit, invalidate the layer. This should cause a commit.
4215 if (layer_tree_host()->source_frame_number() == 1)
4216 invalidate_layer_->SetNeedsDisplay();
4219 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4221 if (impl->active_tree()->source_frame_number() == 1)
4225 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4229 virtual void AfterTest() OVERRIDE {
4230 EXPECT_GE(2, num_commits_);
4231 EXPECT_GE(2, num_draws_);
4235 scoped_refptr<Layer> invalidate_layer_;
4242 // VideoLayer must support being invalidated and then passing that along
4243 // to the compositor thread, even though no resources are updated in
4244 // response to that invalidation.
4245 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4247 virtual void SetupTree() OVERRIDE {
4248 LayerTreeHostTest::SetupTree();
4249 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
4250 video_layer->SetBounds(gfx::Size(10, 10));
4251 video_layer->SetIsDrawable(true);
4252 layer_tree_host()->root_layer()->AddChild(video_layer);
4254 invalidate_layer_ = video_layer;
4258 FakeVideoFrameProvider provider_;
4261 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4263 // IOSurfaceLayer must support being invalidated and then passing that along
4264 // to the compositor thread, even though no resources are updated in
4265 // response to that invalidation.
4266 class LayerTreeHostTestIOSurfaceLayerInvalidate
4267 : public LayerInvalidateCausesDraw {
4269 virtual void SetupTree() OVERRIDE {
4270 LayerTreeHostTest::SetupTree();
4271 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4272 layer->SetBounds(gfx::Size(10, 10));
4273 uint32_t fake_io_surface_id = 7;
4274 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4275 layer->SetIsDrawable(true);
4276 layer_tree_host()->root_layer()->AddChild(layer);
4278 invalidate_layer_ = layer;
4282 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4283 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4284 LayerTreeHostTestIOSurfaceLayerInvalidate);
4286 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4288 virtual void SetupTree() OVERRIDE {
4289 root_layer_ = Layer::Create();
4290 root_layer_->SetAnchorPoint(gfx::PointF());
4291 root_layer_->SetPosition(gfx::Point());
4292 root_layer_->SetBounds(gfx::Size(10, 10));
4294 parent_layer_ = SolidColorLayer::Create();
4295 parent_layer_->SetAnchorPoint(gfx::PointF());
4296 parent_layer_->SetPosition(gfx::Point());
4297 parent_layer_->SetBounds(gfx::Size(10, 10));
4298 parent_layer_->SetIsDrawable(true);
4299 root_layer_->AddChild(parent_layer_);
4301 child_layer_ = SolidColorLayer::Create();
4302 child_layer_->SetAnchorPoint(gfx::PointF());
4303 child_layer_->SetPosition(gfx::Point());
4304 child_layer_->SetBounds(gfx::Size(10, 10));
4305 child_layer_->SetIsDrawable(true);
4306 parent_layer_->AddChild(child_layer_);
4308 layer_tree_host()->SetRootLayer(root_layer_);
4309 LayerTreeHostTest::SetupTree();
4312 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4314 virtual void DidCommitAndDrawFrame() OVERRIDE {
4315 switch (layer_tree_host()->source_frame_number()) {
4317 // The layer type used does not need to push properties every frame.
4318 EXPECT_FALSE(child_layer_->needs_push_properties());
4320 // Change the bounds of the child layer, but make it skipped
4321 // by CalculateDrawProperties.
4322 parent_layer_->SetOpacity(0.f);
4323 child_layer_->SetBounds(gfx::Size(5, 5));
4326 // The bounds of the child layer were pushed to the impl side.
4327 EXPECT_FALSE(child_layer_->needs_push_properties());
4334 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4335 LayerImpl* root = impl->active_tree()->root_layer();
4336 LayerImpl* parent = root->children()[0];
4337 LayerImpl* child = parent->children()[0];
4339 switch (impl->active_tree()->source_frame_number()) {
4341 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4346 virtual void AfterTest() OVERRIDE {}
4348 scoped_refptr<Layer> root_layer_;
4349 scoped_refptr<SolidColorLayer> parent_layer_;
4350 scoped_refptr<SolidColorLayer> child_layer_;
4353 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4355 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4357 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4358 settings->impl_side_painting = true;
4361 virtual void SetupTree() OVERRIDE {
4362 root_layer_ = FakePictureLayer::Create(&client_);
4363 root_layer_->SetAnchorPoint(gfx::PointF());
4364 root_layer_->SetBounds(gfx::Size(10, 10));
4366 layer_tree_host()->SetRootLayer(root_layer_);
4367 LayerTreeHostTest::SetupTree();
4370 virtual void BeginTest() OVERRIDE {
4371 // The viewport is empty, but we still need to update layers on the main
4373 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4374 PostSetNeedsCommitToMainThread();
4377 virtual void DidCommit() OVERRIDE {
4378 // The layer should be updated even though the viewport is empty, so we
4379 // are capable of drawing it on the impl tree.
4380 EXPECT_GT(root_layer_->update_count(), 0u);
4384 virtual void AfterTest() OVERRIDE {}
4386 FakeContentLayerClient client_;
4387 scoped_refptr<FakePictureLayer> root_layer_;
4390 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4392 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4394 LayerTreeHostTestAbortEvictedTextures()
4395 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4398 virtual void SetupTree() OVERRIDE {
4399 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4400 root_layer->SetBounds(gfx::Size(200, 200));
4401 root_layer->SetIsDrawable(true);
4403 layer_tree_host()->SetRootLayer(root_layer);
4404 LayerTreeHostTest::SetupTree();
4407 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4409 virtual void WillBeginMainFrame() OVERRIDE {
4410 num_will_begin_main_frames_++;
4411 switch (num_will_begin_main_frames_) {
4413 // Send a redraw to the compositor thread. This will (wrongly) be
4414 // ignored unless aborting resets the texture state.
4415 layer_tree_host()->SetNeedsRedraw();
4420 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4421 num_impl_commits_++;
4424 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4425 switch (impl->SourceAnimationFrameNumber()) {
4427 // Prevent draws until commit.
4428 impl->active_tree()->SetContentsTexturesPurged();
4429 EXPECT_FALSE(impl->CanDraw());
4430 // Trigger an abortable commit.
4431 impl->SetNeedsCommit();
4439 virtual void AfterTest() OVERRIDE {
4440 // Ensure that the commit was truly aborted.
4441 EXPECT_EQ(2, num_will_begin_main_frames_);
4442 EXPECT_EQ(1, num_impl_commits_);
4446 int num_will_begin_main_frames_;
4447 int num_impl_commits_;
4450 // Commits can only be aborted when using the thread proxy.
4451 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4453 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4455 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4456 settings->impl_side_painting = true;
4457 settings->default_tile_size = gfx::Size(128, 128);
4460 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
4462 scoped_refptr<TestContextProvider> context_provider =
4463 TestContextProvider::Create();
4464 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
4465 return FakeOutputSurface::Create3d(context_provider);
4468 virtual void SetupTree() OVERRIDE {
4469 scoped_refptr<FakePictureLayer> root_layer =
4470 FakePictureLayer::Create(&client_);
4471 root_layer->SetBounds(gfx::Size(6000, 6000));
4472 root_layer->SetIsDrawable(true);
4474 layer_tree_host()->SetRootLayer(root_layer);
4475 LayerTreeHostTest::SetupTree();
4478 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4480 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4481 TestWebGraphicsContext3D* context = TestContext();
4483 // Expect that the transfer buffer memory used is equal to the
4484 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4485 // NOTE: This is now 1/2 due to raster memory limit in TileManager.
4486 // Only half the limit will be reached unless the task set
4487 // thrashes to a completly new set of tiles.
4488 EXPECT_EQ(512 * 1024u, context->GetPeakTransferBufferMemoryUsedBytes());
4492 virtual void AfterTest() OVERRIDE {}
4495 FakeContentLayerClient client_;
4498 // Impl-side painting is a multi-threaded compositor feature.
4499 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4501 // Test ensuring that memory limits are sent to the prioritized resource
4503 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4505 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4507 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4509 virtual void WillCommit() OVERRIDE {
4510 // Some commits are aborted, so increment number of attempted commits here.
4514 virtual void DidCommit() OVERRIDE {
4515 switch (num_commits_) {
4517 // Verify default values.
4518 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4520 ->contents_texture_manager()
4521 ->MaxMemoryLimitBytes());
4522 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4524 ->contents_texture_manager()
4525 ->ExternalPriorityCutoff());
4526 PostSetNeedsCommitToMainThread();
4529 // The values should remain the same until the commit after the policy
4531 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4533 ->contents_texture_manager()
4534 ->MaxMemoryLimitBytes());
4535 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4537 ->contents_texture_manager()
4538 ->ExternalPriorityCutoff());
4541 // Verify values were correctly passed.
4542 EXPECT_EQ(16u * 1024u * 1024u,
4544 ->contents_texture_manager()
4545 ->MaxMemoryLimitBytes());
4546 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4548 ->contents_texture_manager()
4549 ->ExternalPriorityCutoff());
4553 // Make sure no extra commits happen.
4559 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4560 switch (num_commits_) {
4564 // This will trigger a commit because the priority cutoff has changed.
4565 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4566 16u * 1024u * 1024u,
4567 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4571 // This will not trigger a commit because the priority cutoff has not
4572 // changed, and there is already enough memory for all allocations.
4573 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4574 32u * 1024u * 1024u,
4575 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4584 virtual void AfterTest() OVERRIDE {}
4590 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4592 class LayerSetsNeedsFilterContext : public Layer {
4594 static scoped_refptr<LayerSetsNeedsFilterContext> Create() {
4595 return make_scoped_refptr(new LayerSetsNeedsFilterContext());
4598 virtual bool Update(ResourceUpdateQueue* queue,
4599 const OcclusionTracker* occlusion) OVERRIDE {
4600 bool updated = Layer::Update(queue, occlusion);
4601 if (needs_context_) {
4602 layer_tree_host()->set_needs_filter_context();
4608 void set_needs_context(bool need) { needs_context_ = need; }
4611 LayerSetsNeedsFilterContext() : needs_context_(false) {}
4612 virtual ~LayerSetsNeedsFilterContext() {}
4614 bool needs_context_;
4617 class LayerTreeHostTestOffscreenContext : public LayerTreeHostTest {
4619 virtual void SetupTree() OVERRIDE {
4620 scoped_refptr<LayerSetsNeedsFilterContext> root =
4621 LayerSetsNeedsFilterContext::Create();
4622 root->SetIsDrawable(true);
4623 root->SetAnchorPoint(gfx::PointF());
4624 root->SetBounds(gfx::Size(10, 10));
4625 root->set_needs_context(with_context_);
4626 layer_tree_host()->SetRootLayer(root);
4627 LayerTreeHostTest::SetupTree();
4630 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4632 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4633 bool expect_context = with_context_;
4634 if (delegating_renderer())
4635 expect_context = false;
4636 EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
4640 virtual void AfterTest() OVERRIDE {}
4645 class LayerTreeHostTestOffscreenContext_NoContext
4646 : public LayerTreeHostTestOffscreenContext {
4648 LayerTreeHostTestOffscreenContext_NoContext() { with_context_ = false; }
4651 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_NoContext);
4653 class LayerTreeHostTestOffscreenContext_WithContext
4654 : public LayerTreeHostTestOffscreenContext {
4656 LayerTreeHostTestOffscreenContext_WithContext() { with_context_ = true; }
4659 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_WithContext);
4661 class LayerTreeHostTestNoQuadsForEmptyLayer : public LayerTreeHostTest {
4663 virtual void SetupTree() OVERRIDE {
4664 LayerTreeHostTest::SetupTree();
4665 root_layer_ = FakeContentLayer::Create(&client_);
4666 root_layer_->SetBounds(gfx::Size(10, 10));
4667 root_layer_->SetIsDrawable(false);
4668 root_layer_->SetHaveWheelEventHandlers(true);
4669 layer_tree_host()->SetRootLayer(root_layer_);
4670 LayerTreeHostTest::SetupTree();
4673 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4675 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4676 FakeContentLayerImpl* layer_impl =
4677 static_cast<FakeContentLayerImpl*>(impl->RootLayer());
4678 EXPECT_FALSE(layer_impl->DrawsContent());
4679 EXPECT_EQ(0u, layer_impl->append_quads_count());
4682 virtual void DidCommit() OVERRIDE {
4683 // The layer is not drawable, so it should not be updated.
4684 EXPECT_EQ(0u, root_layer_->update_count());
4687 virtual void AfterTest() OVERRIDE {}
4690 FakeContentLayerClient client_;
4691 scoped_refptr<FakeContentLayer> root_layer_;
4694 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoQuadsForEmptyLayer);
4698 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4699 : public LayerTreeHostTest {
4701 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4702 : first_output_surface_memory_limit_(4321234),
4703 second_output_surface_memory_limit_(1234321) {}
4705 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
4707 if (!first_context_provider_) {
4708 first_context_provider_ = TestContextProvider::Create();
4710 EXPECT_FALSE(second_context_provider_);
4711 second_context_provider_ = TestContextProvider::Create();
4714 scoped_ptr<FakeOutputSurface> output_surface(FakeOutputSurface::Create3d(
4715 second_context_provider_ ? second_context_provider_
4716 : first_context_provider_));
4717 output_surface->SetMemoryPolicyToSetAtBind(
4718 make_scoped_ptr(new ManagedMemoryPolicy(
4719 second_context_provider_ ? second_output_surface_memory_limit_
4720 : first_output_surface_memory_limit_,
4721 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4722 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4723 return output_surface.Pass();
4726 virtual void SetupTree() OVERRIDE {
4727 root_ = FakeContentLayer::Create(&client_);
4728 root_->SetBounds(gfx::Size(20, 20));
4729 layer_tree_host()->SetRootLayer(root_);
4730 LayerTreeHostTest::SetupTree();
4733 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4735 virtual void DidCommitAndDrawFrame() OVERRIDE {
4736 // Lost context sometimes takes two frames to recreate. The third frame
4737 // is sometimes aborted, so wait until the fourth frame to verify that
4738 // the memory has been set, and the fifth frame to end the test.
4739 if (layer_tree_host()->source_frame_number() < 5) {
4740 layer_tree_host()->SetNeedsCommit();
4741 } else if (layer_tree_host()->source_frame_number() == 5) {
4746 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
4747 bool result) OVERRIDE {
4748 switch (impl->active_tree()->source_frame_number()) {
4750 EXPECT_EQ(first_output_surface_memory_limit_,
4751 impl->memory_allocation_limit_bytes());
4752 // Lose the output surface.
4753 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4754 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4757 EXPECT_EQ(second_output_surface_memory_limit_,
4758 impl->memory_allocation_limit_bytes());
4763 virtual void AfterTest() OVERRIDE {}
4765 scoped_refptr<TestContextProvider> first_context_provider_;
4766 scoped_refptr<TestContextProvider> second_context_provider_;
4767 size_t first_output_surface_memory_limit_;
4768 size_t second_output_surface_memory_limit_;
4769 FakeContentLayerClient client_;
4770 scoped_refptr<FakeContentLayer> root_;
4773 // No output to copy for delegated renderers.
4774 SINGLE_AND_MULTI_THREAD_TEST_F(
4775 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4777 struct TestSwapPromiseResult {
4778 TestSwapPromiseResult()
4779 : did_swap_called(false),
4780 did_not_swap_called(false),
4782 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4784 bool did_swap_called;
4785 bool did_not_swap_called;
4787 SwapPromise::DidNotSwapReason reason;
4791 class TestSwapPromise : public SwapPromise {
4793 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4795 virtual ~TestSwapPromise() {
4796 base::AutoLock lock(result_->lock);
4797 result_->dtor_called = true;
4800 virtual void DidSwap(CompositorFrameMetadata* metadata) OVERRIDE {
4801 base::AutoLock lock(result_->lock);
4802 EXPECT_FALSE(result_->did_swap_called);
4803 EXPECT_FALSE(result_->did_not_swap_called);
4804 result_->did_swap_called = true;
4807 virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE {
4808 base::AutoLock lock(result_->lock);
4809 EXPECT_FALSE(result_->did_swap_called);
4810 EXPECT_FALSE(result_->did_not_swap_called);
4811 result_->did_not_swap_called = true;
4812 result_->reason = reason;
4817 TestSwapPromiseResult* result_;
4820 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4822 LayerTreeHostTestBreakSwapPromise()
4823 : commit_count_(0), commit_complete_count_(0) {}
4825 virtual void WillBeginMainFrame() OVERRIDE {
4826 ASSERT_LE(commit_count_, 2);
4827 scoped_ptr<SwapPromise> swap_promise(
4828 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4829 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4832 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4834 virtual void DidCommit() OVERRIDE {
4836 if (commit_count_ == 2) {
4837 // This commit will finish.
4838 layer_tree_host()->SetNeedsCommit();
4842 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4843 commit_complete_count_++;
4844 if (commit_complete_count_ == 1) {
4845 // This commit will be aborted because no actual update.
4846 PostSetNeedsUpdateLayersToMainThread();
4852 virtual void AfterTest() OVERRIDE {
4853 // 3 commits are scheduled. 2 completes. 1 is aborted.
4854 EXPECT_EQ(commit_count_, 3);
4855 EXPECT_EQ(commit_complete_count_, 2);
4858 // The first commit completes and causes swap buffer which finishes
4860 base::AutoLock lock(swap_promise_result_[0].lock);
4861 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4862 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4863 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4867 // The second commit aborts.
4868 base::AutoLock lock(swap_promise_result_[1].lock);
4869 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4870 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4871 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_[1].reason);
4872 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4876 // The last commit completes but it does not cause swap buffer because
4877 // there is no damage in the frame data.
4878 base::AutoLock lock(swap_promise_result_[2].lock);
4879 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4880 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4881 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4882 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4887 int commit_complete_count_;
4888 TestSwapPromiseResult swap_promise_result_[3];
4891 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4893 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
4895 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
4896 LayerTreeHostImpl* layer_tree_host_impl,
4897 int* set_needs_commit_count,
4898 int* set_needs_redraw_count)
4899 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
4900 set_needs_commit_count_(set_needs_commit_count),
4901 set_needs_redraw_count_(set_needs_redraw_count) {}
4903 virtual ~SimpleSwapPromiseMonitor() {}
4905 virtual void OnSetNeedsCommitOnMain() OVERRIDE {
4906 (*set_needs_commit_count_)++;
4909 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE {
4910 (*set_needs_redraw_count_)++;
4914 int* set_needs_commit_count_;
4915 int* set_needs_redraw_count_;
4918 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
4920 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4922 virtual void WillBeginMainFrame() OVERRIDE {
4923 int set_needs_commit_count = 0;
4924 int set_needs_redraw_count = 0;
4927 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4928 new SimpleSwapPromiseMonitor(layer_tree_host(),
4930 &set_needs_commit_count,
4931 &set_needs_redraw_count));
4932 layer_tree_host()->SetNeedsCommit();
4933 EXPECT_EQ(1, set_needs_commit_count);
4934 EXPECT_EQ(0, set_needs_redraw_count);
4937 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
4939 layer_tree_host()->SetNeedsCommit();
4940 EXPECT_EQ(1, set_needs_commit_count);
4941 EXPECT_EQ(0, set_needs_redraw_count);
4944 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4945 new SimpleSwapPromiseMonitor(layer_tree_host(),
4947 &set_needs_commit_count,
4948 &set_needs_redraw_count));
4949 layer_tree_host()->SetNeedsUpdateLayers();
4950 EXPECT_EQ(2, set_needs_commit_count);
4951 EXPECT_EQ(0, set_needs_redraw_count);
4955 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4956 new SimpleSwapPromiseMonitor(layer_tree_host(),
4958 &set_needs_commit_count,
4959 &set_needs_redraw_count));
4960 layer_tree_host()->SetNeedsAnimate();
4961 EXPECT_EQ(3, set_needs_commit_count);
4962 EXPECT_EQ(0, set_needs_redraw_count);
4968 virtual void AfterTest() OVERRIDE {}
4971 MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
4973 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
4974 : public LayerTreeHostTest {
4976 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4977 settings->impl_side_painting = true;
4980 virtual void SetupTree() OVERRIDE {
4981 LayerTreeHostTest::SetupTree();
4982 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
4985 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4987 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4988 host_impl->EvictAllUIResources();
4989 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
4990 // mode. Active tree should require high-res to draw after entering this
4991 // mode to ensure that high-res tiles are also required for a pending tree
4993 EXPECT_TRUE(host_impl->active_tree()->RequiresHighResToDraw());
4996 virtual void DidCommit() OVERRIDE {
4997 int frame = layer_tree_host()->source_frame_number();
5000 PostSetNeedsCommitToMainThread();
5003 ui_resource_.reset();
5009 virtual void AfterTest() OVERRIDE {}
5011 FakeContentLayerClient client_;
5012 scoped_ptr<FakeScopedUIResource> ui_resource_;
5015 MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources);