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/debug/frame_rate_counter.h"
13 #include "cc/layers/content_layer.h"
14 #include "cc/layers/content_layer_client.h"
15 #include "cc/layers/io_surface_layer.h"
16 #include "cc/layers/layer_impl.h"
17 #include "cc/layers/painted_scrollbar_layer.h"
18 #include "cc/layers/picture_layer.h"
19 #include "cc/layers/solid_color_layer.h"
20 #include "cc/layers/video_layer.h"
21 #include "cc/output/begin_frame_args.h"
22 #include "cc/output/copy_output_request.h"
23 #include "cc/output/copy_output_result.h"
24 #include "cc/output/output_surface.h"
25 #include "cc/resources/prioritized_resource.h"
26 #include "cc/resources/prioritized_resource_manager.h"
27 #include "cc/resources/resource_update_queue.h"
28 #include "cc/scheduler/frame_rate_controller.h"
29 #include "cc/test/fake_content_layer.h"
30 #include "cc/test/fake_content_layer_client.h"
31 #include "cc/test/fake_content_layer_impl.h"
32 #include "cc/test/fake_layer_tree_host_client.h"
33 #include "cc/test/fake_output_surface.h"
34 #include "cc/test/fake_painted_scrollbar_layer.h"
35 #include "cc/test/fake_picture_layer.h"
36 #include "cc/test/fake_picture_layer_impl.h"
37 #include "cc/test/fake_proxy.h"
38 #include "cc/test/fake_scoped_ui_resource.h"
39 #include "cc/test/fake_video_frame_provider.h"
40 #include "cc/test/geometry_test_utils.h"
41 #include "cc/test/layer_tree_test.h"
42 #include "cc/test/occlusion_tracker_test_common.h"
43 #include "cc/test/test_web_graphics_context_3d.h"
44 #include "cc/trees/layer_tree_host_impl.h"
45 #include "cc/trees/layer_tree_impl.h"
46 #include "cc/trees/single_thread_proxy.h"
47 #include "cc/trees/thread_proxy.h"
48 #include "gpu/GLES2/gl2extchromium.h"
49 #include "skia/ext/refptr.h"
50 #include "testing/gmock/include/gmock/gmock.h"
51 #include "third_party/khronos/GLES2/gl2.h"
52 #include "third_party/khronos/GLES2/gl2ext.h"
53 #include "third_party/skia/include/core/SkPicture.h"
54 #include "ui/gfx/frame_time.h"
55 #include "ui/gfx/point_conversions.h"
56 #include "ui/gfx/size_conversions.h"
57 #include "ui/gfx/vector2d_conversions.h"
60 using testing::AnyNumber;
61 using testing::AtLeast;
67 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_)) {
281 virtual void BeginTest() OVERRIDE {
282 root_layer_->SetIsDrawable(true);
283 root_layer_->SetBounds(bounds_);
284 layer_tree_host()->SetRootLayer(root_layer_);
285 layer_tree_host()->SetViewportSize(bounds_);
286 PostSetNeedsCommitToMainThread();
289 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
290 LayerTreeHostImpl::FrameData* frame_data,
291 bool result) OVERRIDE {
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 {
319 EXPECT_EQ(2, num_draws_);
324 const gfx::Size bounds_;
325 const gfx::Rect invalid_rect_;
326 FakeContentLayerClient client_;
327 scoped_refptr<ContentLayer> root_layer_;
330 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
332 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
334 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
335 settings->layer_transforms_should_scale_layer_contents = true;
338 virtual void SetupTree() OVERRIDE {
339 root_layer_ = Layer::Create();
340 root_layer_->SetBounds(gfx::Size(10, 20));
342 scaled_layer_ = FakeContentLayer::Create(&client_);
343 scaled_layer_->SetBounds(gfx::Size(1, 1));
344 root_layer_->AddChild(scaled_layer_);
346 layer_tree_host()->SetRootLayer(root_layer_);
347 LayerTreeHostTest::SetupTree();
350 virtual void BeginTest() OVERRIDE {
351 PostSetNeedsCommitToMainThread();
354 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
355 if (host_impl->active_tree()->source_frame_number() == 1)
359 virtual void DidCommit() OVERRIDE {
360 switch (layer_tree_host()->source_frame_number()) {
362 // Changing the device scale factor causes a commit. It also changes
363 // the content bounds of |scaled_layer_|, which should not generate
364 // a second commit as a result.
365 layer_tree_host()->SetDeviceScaleFactor(4.f);
369 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
373 virtual void AfterTest() OVERRIDE {
374 EXPECT_EQ(gfx::Size(4, 4).ToString(),
375 scaled_layer_->content_bounds().ToString());
379 FakeContentLayerClient client_;
380 scoped_refptr<Layer> root_layer_;
381 scoped_refptr<FakeContentLayer> scaled_layer_;
384 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
386 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
387 : public LayerTreeHostTest {
389 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
390 settings->layer_transforms_should_scale_layer_contents = true;
393 virtual void SetupTree() OVERRIDE {
394 root_layer_ = Layer::Create();
395 root_layer_->SetBounds(gfx::Size(10, 20));
397 bool paint_scrollbar = true;
398 bool has_thumb = false;
399 scrollbar_ = FakePaintedScrollbarLayer::Create(
400 paint_scrollbar, has_thumb, root_layer_->id());
401 scrollbar_->SetPosition(gfx::Point(0, 10));
402 scrollbar_->SetBounds(gfx::Size(10, 10));
404 root_layer_->AddChild(scrollbar_);
406 layer_tree_host()->SetRootLayer(root_layer_);
407 LayerTreeHostTest::SetupTree();
410 virtual void BeginTest() OVERRIDE {
411 PostSetNeedsCommitToMainThread();
414 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
415 if (host_impl->active_tree()->source_frame_number() == 1)
419 virtual void DidCommit() OVERRIDE {
420 switch (layer_tree_host()->source_frame_number()) {
422 // Changing the device scale factor causes a commit. It also changes
423 // the content bounds of |scrollbar_|, which should not generate
424 // a second commit as a result.
425 layer_tree_host()->SetDeviceScaleFactor(4.f);
429 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
433 virtual void AfterTest() OVERRIDE {
434 EXPECT_EQ(gfx::Size(40, 40).ToString(),
435 scrollbar_->content_bounds().ToString());
439 FakeContentLayerClient client_;
440 scoped_refptr<Layer> root_layer_;
441 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
444 SINGLE_AND_MULTI_THREAD_TEST_F(
445 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
447 class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
449 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
451 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
453 virtual void DidCommit() OVERRIDE {
455 if (num_commits_ == 1) {
457 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
458 } else if (num_commits_ == 2) {
459 // This is inside the readback. We should get another commit after it.
460 } else if (num_commits_ == 3) {
467 virtual void AfterTest() OVERRIDE {}
473 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback);
475 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
476 : public LayerTreeHostTest {
478 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
481 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
483 virtual void DidCommit() OVERRIDE {
485 if (num_commits_ == 1) {
486 layer_tree_host()->SetNeedsCommit();
487 } else if (num_commits_ == 2) {
489 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
490 } else if (num_commits_ == 3) {
491 // This is inside the readback. We should get another commit after it.
492 } else if (num_commits_ == 4) {
499 virtual void AfterTest() OVERRIDE {}
506 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws);
508 class LayerTreeHostTestCompositeAndReadbackDuringForcedDraw
509 : public LayerTreeHostTest {
511 static const int kFirstCommitSourceFrameNumber = 0;
512 static const int kReadbackSourceFrameNumber = 1;
513 static const int kReadbackReplacementAndForcedDrawSourceFrameNumber = 2;
515 LayerTreeHostTestCompositeAndReadbackDuringForcedDraw()
516 : did_post_readback_(false) {}
518 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
519 // This enables forced draws after a single prepare to draw failure.
520 settings->timeout_and_draw_when_animation_checkerboards = true;
521 settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
524 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
526 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
527 LayerTreeHostImpl::FrameData* frame_data,
528 bool result) OVERRIDE {
529 int sfn = host_impl->active_tree()->source_frame_number();
530 EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
531 sfn == kReadbackSourceFrameNumber ||
532 sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
535 // Before we react to the failed draw by initiating the forced draw
536 // sequence, start a readback on the main thread.
537 if (sfn == kFirstCommitSourceFrameNumber && !did_post_readback_) {
538 did_post_readback_ = true;
539 PostReadbackToMainThread();
542 // Returning false will result in a forced draw.
546 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
547 // We should only draw for the readback and the forced draw.
548 int sfn = host_impl->active_tree()->source_frame_number();
549 EXPECT_TRUE(sfn == kReadbackSourceFrameNumber ||
550 sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
554 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
555 bool result) OVERRIDE {
556 // We should only swap for the forced draw.
557 int sfn = host_impl->active_tree()->source_frame_number();
558 EXPECT_TRUE(sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
563 virtual void AfterTest() OVERRIDE {}
565 bool did_post_readback_;
568 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackDuringForcedDraw);
570 class LayerTreeHostTestCompositeAndReadbackAfterForcedDraw
571 : public LayerTreeHostTest {
573 static const int kFirstCommitSourceFrameNumber = 0;
574 static const int kForcedDrawSourceFrameNumber = 1;
575 static const int kReadbackSourceFrameNumber = 2;
576 static const int kReadbackReplacementSourceFrameNumber = 3;
578 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
579 // This enables forced draws after a single prepare to draw failure.
580 settings->timeout_and_draw_when_animation_checkerboards = true;
581 settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
584 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
586 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
587 LayerTreeHostImpl::FrameData* frame_data,
588 bool result) OVERRIDE {
589 int sfn = host_impl->active_tree()->source_frame_number();
590 EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
591 sfn == kForcedDrawSourceFrameNumber ||
592 sfn == kReadbackSourceFrameNumber ||
593 sfn == kReadbackReplacementSourceFrameNumber)
596 // Returning false will result in a forced draw.
600 virtual void DidCommit() OVERRIDE {
601 if (layer_tree_host()->source_frame_number() ==
602 kForcedDrawSourceFrameNumber) {
603 // Avoid aborting the forced draw commit so source_frame_number
605 layer_tree_host()->SetNeedsCommit();
606 } else if (layer_tree_host()->source_frame_number() ==
607 kReadbackSourceFrameNumber) {
608 // Perform a readback immediately after the forced draw's commit.
610 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
614 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
615 // We should only draw for the the forced draw, readback, and
616 // replacement commit.
617 int sfn = host_impl->active_tree()->source_frame_number();
618 EXPECT_TRUE(sfn == kForcedDrawSourceFrameNumber ||
619 sfn == kReadbackSourceFrameNumber ||
620 sfn == kReadbackReplacementSourceFrameNumber)
624 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
625 bool result) OVERRIDE {
626 // We should only swap for the forced draw and replacement commit.
627 int sfn = host_impl->active_tree()->source_frame_number();
628 EXPECT_TRUE(sfn == kForcedDrawSourceFrameNumber ||
629 sfn == kReadbackReplacementSourceFrameNumber)
632 if (sfn == kReadbackReplacementSourceFrameNumber)
636 virtual void AfterTest() OVERRIDE {}
639 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackAfterForcedDraw);
641 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
643 LayerTreeHostTestSetNextCommitForcesRedraw()
646 invalid_rect_(10, 10, 20, 20),
647 root_layer_(ContentLayer::Create(&client_)) {
650 virtual void BeginTest() OVERRIDE {
651 root_layer_->SetIsDrawable(true);
652 root_layer_->SetBounds(bounds_);
653 layer_tree_host()->SetRootLayer(root_layer_);
654 layer_tree_host()->SetViewportSize(bounds_);
655 PostSetNeedsCommitToMainThread();
658 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
659 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
660 host_impl->SetNeedsRedrawRect(invalid_rect_);
663 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
664 LayerTreeHostImpl::FrameData* frame_data,
665 bool result) OVERRIDE {
668 gfx::RectF root_damage_rect;
669 if (!frame_data->render_passes.empty())
670 root_damage_rect = frame_data->render_passes.back()->damage_rect;
672 switch (num_draws_) {
674 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
678 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
681 EXPECT_RECT_EQ(invalid_rect_, root_damage_rect);
684 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
693 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
694 switch (num_draws_) {
697 // Cycle through a couple of empty commits to ensure we're observing the
699 PostSetNeedsCommitToMainThread();
702 // Should force full frame damage on the next commit
703 PostSetNextCommitForcesRedrawToMainThread();
704 PostSetNeedsCommitToMainThread();
705 if (host_impl->settings().impl_side_painting)
706 host_impl->BlockNotifyReadyToActivateForTesting(true);
711 host_impl->BlockNotifyReadyToActivateForTesting(false);
720 virtual void AfterTest() OVERRIDE {
721 EXPECT_EQ(5, num_draws_);
726 const gfx::Size bounds_;
727 const gfx::Rect invalid_rect_;
728 FakeContentLayerClient client_;
729 scoped_refptr<ContentLayer> root_layer_;
732 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw);
734 // Tests that if a layer is not drawn because of some reason in the parent then
735 // its damage is preserved until the next time it is drawn.
736 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
738 LayerTreeHostTestUndrawnLayersDamageLater()
739 : root_layer_(ContentLayer::Create(&client_)) {
742 virtual void SetupTree() OVERRIDE {
743 root_layer_->SetIsDrawable(true);
744 root_layer_->SetBounds(gfx::Size(50, 50));
745 layer_tree_host()->SetRootLayer(root_layer_);
747 // The initially transparent layer has a larger child layer, which is
748 // not initially drawn because of the this (parent) layer.
749 parent_layer_ = FakeContentLayer::Create(&client_);
750 parent_layer_->SetBounds(gfx::Size(15, 15));
751 parent_layer_->SetOpacity(0.0f);
752 root_layer_->AddChild(parent_layer_);
754 child_layer_ = FakeContentLayer::Create(&client_);
755 child_layer_->SetBounds(gfx::Size(25, 25));
756 parent_layer_->AddChild(child_layer_);
758 LayerTreeHostTest::SetupTree();
761 virtual void BeginTest() OVERRIDE {
762 PostSetNeedsCommitToMainThread();
765 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
766 LayerTreeHostImpl::FrameData* frame_data,
767 bool result) OVERRIDE {
770 gfx::RectF root_damage_rect;
771 if (!frame_data->render_passes.empty())
772 root_damage_rect = frame_data->render_passes.back()->damage_rect;
774 // The first time, the whole view needs be drawn.
775 // Afterwards, just the opacity of surface_layer1 is changed a few times,
776 // and each damage should be the bounding box of it and its child. If this
777 // was working improperly, the damage might not include its childs bounding
779 switch (layer_tree_host()->source_frame_number()) {
781 EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
786 EXPECT_RECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
795 virtual void DidCommitAndDrawFrame() OVERRIDE {
796 switch (layer_tree_host()->source_frame_number()) {
798 // Test not owning the surface.
799 parent_layer_->SetOpacity(1.0f);
802 parent_layer_->SetOpacity(0.0f);
805 // Test owning the surface.
806 parent_layer_->SetOpacity(0.5f);
807 parent_layer_->SetForceRenderSurface(true);
818 virtual void AfterTest() OVERRIDE {}
821 FakeContentLayerClient client_;
822 scoped_refptr<ContentLayer> root_layer_;
823 scoped_refptr<FakeContentLayer> parent_layer_;
824 scoped_refptr<FakeContentLayer> child_layer_;
827 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
829 // If the layerTreeHost says it can't draw, Then we should not try to draw.
830 class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
832 LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
834 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
836 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
839 // Only the initial draw should bring us here.
840 EXPECT_TRUE(impl->CanDraw());
841 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
844 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
847 if (num_commits_ >= 1) {
848 // After the first commit, we should not be able to draw.
849 EXPECT_FALSE(impl->CanDraw());
853 virtual void DidCommit() OVERRIDE {
855 if (num_commits_ == 1) {
856 // Make the viewport empty so the host says it can't draw.
857 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
858 } else if (num_commits_ == 2) {
860 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
861 } else if (num_commits_ == 3) {
862 // Let it draw so we go idle and end the test.
863 layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
869 virtual void AfterTest() OVERRIDE {}
876 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
878 // beginLayerWrite should prevent draws from executing until a commit occurs
879 class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
881 LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
883 virtual void BeginTest() OVERRIDE {
884 PostAcquireLayerTextures();
885 PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
886 PostSetNeedsCommitToMainThread();
889 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
891 EXPECT_EQ(num_draws_, num_commits_);
894 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
899 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
906 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw);
908 // Verify that when resuming visibility, Requesting layer write permission
909 // will not deadlock the main thread even though there are not yet any
910 // scheduled redraws. This behavior is critical for reliably surviving tab
911 // switching. There are no failure conditions to this test, it just passes
912 // by not timing out.
913 class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
915 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
917 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
919 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
921 if (num_commits_ == 2)
923 else if (num_commits_ < 2) {
924 PostSetVisibleToMainThread(false);
925 PostSetVisibleToMainThread(true);
926 PostAcquireLayerTextures();
927 PostSetNeedsCommitToMainThread();
931 virtual void AfterTest() OVERRIDE {}
937 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
939 // A compositeAndReadback while invisible should force a normal commit without
941 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
942 : public LayerTreeHostTest {
944 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
946 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
948 virtual void DidCommitAndDrawFrame() OVERRIDE {
950 if (num_commits_ == 1) {
951 layer_tree_host()->SetVisible(false);
952 layer_tree_host()->SetNeedsCommit();
953 layer_tree_host()->SetNeedsCommit();
955 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
961 virtual void AfterTest() OVERRIDE {}
967 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible);
969 class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
971 LayerTreeHostTestAbortFrameWhenInvisible() {}
973 virtual void BeginTest() OVERRIDE {
974 // Request a commit (from the main thread), Which will trigger the commit
975 // flow from the impl side.
976 layer_tree_host()->SetNeedsCommit();
977 // Then mark ourselves as not visible before processing any more messages
978 // on the main thread.
979 layer_tree_host()->SetVisible(false);
980 // If we make it without kicking a frame, we pass!
981 EndTestAfterDelay(1);
984 virtual void Layout() OVERRIDE {
989 virtual void AfterTest() OVERRIDE {}
992 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
994 // This test verifies that properties on the layer tree host are commited
996 class LayerTreeHostTestCommit : public LayerTreeHostTest {
998 LayerTreeHostTestCommit() {}
1000 virtual void BeginTest() OVERRIDE {
1001 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1002 layer_tree_host()->set_background_color(SK_ColorGRAY);
1004 PostSetNeedsCommitToMainThread();
1007 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1008 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
1009 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
1014 virtual void AfterTest() OVERRIDE {}
1017 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
1019 // This test verifies that LayerTreeHostImpl's current frame time gets
1020 // updated in consecutive frames when it doesn't draw due to tree
1021 // activation failure.
1022 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
1023 : public LayerTreeHostTest {
1025 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
1026 : frame_count_with_pending_tree_(0) {}
1028 virtual void BeginTest() OVERRIDE {
1029 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1030 layer_tree_host()->set_background_color(SK_ColorGRAY);
1032 PostSetNeedsCommitToMainThread();
1035 virtual void BeginCommitOnThread(LayerTreeHostImpl *impl) OVERRIDE {
1036 EXPECT_EQ(frame_count_with_pending_tree_, 0);
1037 impl->BlockNotifyReadyToActivateForTesting(true);
1040 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1041 const BeginFrameArgs& args) OVERRIDE {
1042 if (impl->pending_tree())
1043 frame_count_with_pending_tree_++;
1045 if (frame_count_with_pending_tree_ == 2)
1046 impl->BlockNotifyReadyToActivateForTesting(false);
1049 virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1050 const BeginFrameArgs& args) OVERRIDE {
1051 if (frame_count_with_pending_tree_ == 1) {
1052 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
1053 first_frame_time_ = impl->CurrentFrameTimeTicks();
1057 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1058 if (frame_count_with_pending_tree_ > 1) {
1059 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
1060 EXPECT_NE(first_frame_time_.ToInternalValue(),
1061 impl->CurrentFrameTimeTicks().ToInternalValue());
1066 EXPECT_FALSE(impl->settings().impl_side_painting);
1069 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1070 if (impl->settings().impl_side_painting)
1071 EXPECT_NE(frame_count_with_pending_tree_, 1);
1074 virtual void AfterTest() OVERRIDE {}
1077 int frame_count_with_pending_tree_;
1078 base::TimeTicks first_frame_time_;
1081 SINGLE_AND_MULTI_THREAD_TEST_F(
1082 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
1084 // This test verifies that LayerTreeHostImpl's current frame time gets
1085 // updated in consecutive frames when it draws in each frame.
1086 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
1088 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
1090 virtual void BeginTest() OVERRIDE {
1091 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1092 layer_tree_host()->set_background_color(SK_ColorGRAY);
1094 PostSetNeedsCommitToMainThread();
1097 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1100 first_frame_time_ = impl->CurrentFrameTimeTicks();
1101 impl->SetNeedsRedraw();
1103 // Since we might use a low-resolution clock on Windows, we need to
1104 // make sure that the clock has incremented past first_frame_time_.
1105 while (first_frame_time_ == gfx::FrameTime::Now()) {}
1110 EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
1114 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1115 // Ensure there isn't a commit between the two draws, to ensure that a
1116 // commit isn't required for updating the current frame time. We can
1117 // only check for this in the multi-threaded case, since in the single-
1118 // threaded case there will always be a commit between consecutive draws.
1119 if (HasImplThread())
1120 EXPECT_EQ(0, frame_);
1123 virtual void AfterTest() OVERRIDE {}
1127 base::TimeTicks first_frame_time_;
1130 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1132 // Verifies that StartPageScaleAnimation events propagate correctly
1133 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1134 class LayerTreeHostTestStartPageScaleAnimation
1135 : public LayerTreeHostTest {
1137 LayerTreeHostTestStartPageScaleAnimation() {}
1139 virtual void SetupTree() OVERRIDE {
1140 LayerTreeHostTest::SetupTree();
1142 if (layer_tree_host()->settings().impl_side_painting) {
1143 scoped_refptr<FakePictureLayer> layer =
1144 FakePictureLayer::Create(&client_);
1145 layer->set_always_update_resources(true);
1146 scroll_layer_ = layer;
1148 scroll_layer_ = FakeContentLayer::Create(&client_);
1151 scroll_layer_->SetScrollable(true);
1152 scroll_layer_->SetScrollOffset(gfx::Vector2d());
1153 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1154 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1157 virtual void BeginTest() OVERRIDE {
1158 PostSetNeedsCommitToMainThread();
1161 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float scale)
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*, gfx::Rect, gfx::RectF*) OVERRIDE {
1239 // Set layer opacity to 0.
1241 test_layer_->SetOpacity(0.f);
1243 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
1249 class ContentLayerWithUpdateTracking : public ContentLayer {
1251 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1252 ContentLayerClient* client) {
1253 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1256 int PaintContentsCount() { return paint_contents_count_; }
1257 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1259 virtual bool Update(ResourceUpdateQueue* queue,
1260 const OcclusionTracker* occlusion) OVERRIDE {
1261 bool updated = ContentLayer::Update(queue, occlusion);
1262 paint_contents_count_++;
1267 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1268 : ContentLayer(client), paint_contents_count_(0) {
1269 SetAnchorPoint(gfx::PointF(0.f, 0.f));
1270 SetBounds(gfx::Size(10, 10));
1271 SetIsDrawable(true);
1273 virtual ~ContentLayerWithUpdateTracking() {}
1275 int paint_contents_count_;
1278 // Layer opacity change during paint should not prevent compositor resources
1279 // from being updated during commit.
1280 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1282 LayerTreeHostTestOpacityChange()
1283 : test_opacity_change_delegate_(),
1284 update_check_layer_(ContentLayerWithUpdateTracking::Create(
1285 &test_opacity_change_delegate_)) {
1286 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
1289 virtual void BeginTest() OVERRIDE {
1290 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1291 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
1293 PostSetNeedsCommitToMainThread();
1296 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1300 virtual void AfterTest() OVERRIDE {
1301 // Update() should have been called once.
1302 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
1306 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1307 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
1310 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1312 class NoScaleContentLayer : public ContentLayer {
1314 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
1315 return make_scoped_refptr(new NoScaleContentLayer(client));
1318 virtual void CalculateContentsScale(float ideal_contents_scale,
1319 float device_scale_factor,
1320 float page_scale_factor,
1321 bool animating_transform_to_screen,
1322 float* contents_scale_x,
1323 float* contents_scale_y,
1324 gfx::Size* contentBounds) OVERRIDE {
1325 // Skip over the ContentLayer's method to the base Layer class.
1326 Layer::CalculateContentsScale(ideal_contents_scale,
1327 device_scale_factor,
1329 animating_transform_to_screen,
1336 explicit NoScaleContentLayer(ContentLayerClient* client)
1337 : ContentLayer(client) {}
1338 virtual ~NoScaleContentLayer() {}
1341 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1342 : public LayerTreeHostTest {
1344 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1345 : root_layer_(NoScaleContentLayer::Create(&client_)),
1346 child_layer_(ContentLayer::Create(&client_)) {}
1348 virtual void BeginTest() OVERRIDE {
1349 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1350 layer_tree_host()->SetDeviceScaleFactor(1.5);
1351 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1353 root_layer_->AddChild(child_layer_);
1355 root_layer_->SetIsDrawable(true);
1356 root_layer_->SetBounds(gfx::Size(30, 30));
1357 root_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1359 child_layer_->SetIsDrawable(true);
1360 child_layer_->SetPosition(gfx::Point(2, 2));
1361 child_layer_->SetBounds(gfx::Size(10, 10));
1362 child_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1364 layer_tree_host()->SetRootLayer(root_layer_);
1366 PostSetNeedsCommitToMainThread();
1369 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1370 // Should only do one commit.
1371 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1372 // Device scale factor should come over to impl.
1373 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1375 // Both layers are on impl.
1376 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1378 // Device viewport is scaled.
1379 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1381 LayerImpl* root = impl->active_tree()->root_layer();
1382 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1384 // Positions remain in layout pixels.
1385 EXPECT_EQ(gfx::Point(0, 0), root->position());
1386 EXPECT_EQ(gfx::Point(2, 2), child->position());
1388 // Compute all the layer transforms for the frame.
1389 LayerTreeHostImpl::FrameData frame_data;
1390 impl->PrepareToDraw(&frame_data, gfx::Rect());
1391 impl->DidDrawAllLayers(frame_data);
1393 const LayerImplList& render_surface_layer_list =
1394 *frame_data.render_surface_layer_list;
1396 // Both layers should be drawing into the root render surface.
1397 ASSERT_EQ(1u, render_surface_layer_list.size());
1398 ASSERT_EQ(root->render_surface(),
1399 render_surface_layer_list[0]->render_surface());
1400 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1402 // The root render surface is the size of the viewport.
1403 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1404 root->render_surface()->content_rect());
1406 // The content bounds of the child should be scaled.
1407 gfx::Size child_bounds_scaled =
1408 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1409 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1411 gfx::Transform scale_transform;
1412 scale_transform.Scale(impl->device_scale_factor(),
1413 impl->device_scale_factor());
1415 // The root layer is scaled by 2x.
1416 gfx::Transform root_screen_space_transform = scale_transform;
1417 gfx::Transform root_draw_transform = scale_transform;
1419 EXPECT_EQ(root_draw_transform, root->draw_transform());
1420 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1422 // The child is at position 2,2, which is transformed to 3,3 after the scale
1423 gfx::Transform child_screen_space_transform;
1424 child_screen_space_transform.Translate(3.f, 3.f);
1425 gfx::Transform child_draw_transform = child_screen_space_transform;
1427 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1428 child->draw_transform());
1429 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1430 child->screen_space_transform());
1435 virtual void AfterTest() OVERRIDE {}
1438 FakeContentLayerClient client_;
1439 scoped_refptr<NoScaleContentLayer> root_layer_;
1440 scoped_refptr<ContentLayer> child_layer_;
1443 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1445 // Verify atomicity of commits and reuse of textures.
1446 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1448 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1449 settings->texture_id_allocation_chunk_size = 1;
1450 // Make sure partial texture updates are turned off.
1451 settings->max_partial_texture_updates = 0;
1452 // Linear fade animator prevents scrollbars from drawing immediately.
1453 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1456 virtual void SetupTree() OVERRIDE {
1457 layer_ = FakeContentLayer::Create(&client_);
1458 layer_->SetBounds(gfx::Size(10, 20));
1460 bool paint_scrollbar = true;
1461 bool has_thumb = false;
1462 scrollbar_ = FakePaintedScrollbarLayer::Create(
1463 paint_scrollbar, has_thumb, layer_->id());
1464 scrollbar_->SetPosition(gfx::Point(0, 10));
1465 scrollbar_->SetBounds(gfx::Size(10, 10));
1467 layer_->AddChild(scrollbar_);
1469 layer_tree_host()->SetRootLayer(layer_);
1470 LayerTreeHostTest::SetupTree();
1473 virtual void BeginTest() OVERRIDE {
1475 PostSetNeedsCommitToMainThread();
1478 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1479 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1481 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1482 impl->output_surface()->context_provider()->Context3d());
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 = static_cast<TestWebGraphicsContext3D*>(
1524 impl->output_surface()->context_provider()->Context3d());
1526 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1527 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1530 drew_frame_ = impl->active_tree()->source_frame_number();
1532 // We draw/ship one texture each frame for each layer.
1533 EXPECT_EQ(2u, context->NumUsedTextures());
1534 context->ResetUsedTextures();
1537 virtual void Layout() OVERRIDE {
1538 layer_->SetNeedsDisplay();
1539 scrollbar_->SetNeedsDisplay();
1542 virtual void AfterTest() OVERRIDE {}
1545 FakeContentLayerClient client_;
1546 scoped_refptr<FakeContentLayer> layer_;
1547 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1551 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1552 LayerTreeHostTestDirectRendererAtomicCommit);
1554 class LayerTreeHostTestDelegatingRendererAtomicCommit
1555 : public LayerTreeHostTestDirectRendererAtomicCommit {
1557 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1558 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1560 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1561 impl->output_surface()->context_provider()->Context3d());
1563 switch (impl->active_tree()->source_frame_number()) {
1565 // Number of textures should be one for each layer
1566 ASSERT_EQ(2u, context->NumTextures());
1567 // Number of textures used for commit should be one for each layer.
1568 EXPECT_EQ(2u, context->NumUsedTextures());
1569 // Verify that used texture is correct.
1570 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1571 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1572 context->ResetUsedTextures();
1573 PostSetNeedsCommitToMainThread();
1576 // Number of textures should be doubled as the first context layer
1577 // texture is being used by the impl-thread and cannot be used for
1578 // update. The scrollbar behavior is different direct renderer because
1579 // UI resource deletion with delegating renderer occurs after tree
1581 ASSERT_EQ(4u, context->NumTextures());
1582 // Number of textures used for commit should still be
1583 // one for each layer.
1584 EXPECT_EQ(2u, context->NumUsedTextures());
1585 // First textures should not have been used.
1586 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1587 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1588 // New textures should have been used.
1589 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1590 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1591 context->ResetUsedTextures();
1592 PostSetNeedsCommitToMainThread();
1604 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1605 LayerTreeHostTestDelegatingRendererAtomicCommit);
1607 static void SetLayerPropertiesForTesting(Layer* layer,
1609 const gfx::Transform& transform,
1611 gfx::PointF position,
1614 layer->RemoveAllChildren();
1616 parent->AddChild(layer);
1617 layer->SetTransform(transform);
1618 layer->SetAnchorPoint(anchor);
1619 layer->SetPosition(position);
1620 layer->SetBounds(bounds);
1621 layer->SetContentsOpaque(opaque);
1624 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1625 : public LayerTreeHostTest {
1627 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1628 settings->texture_id_allocation_chunk_size = 1;
1629 // Allow one partial texture update.
1630 settings->max_partial_texture_updates = 1;
1631 // No partial updates when impl side painting is enabled.
1632 settings->impl_side_painting = false;
1635 virtual void SetupTree() OVERRIDE {
1636 parent_ = FakeContentLayer::Create(&client_);
1637 parent_->SetBounds(gfx::Size(10, 20));
1639 child_ = FakeContentLayer::Create(&client_);
1640 child_->SetPosition(gfx::Point(0, 10));
1641 child_->SetBounds(gfx::Size(3, 10));
1643 parent_->AddChild(child_);
1645 layer_tree_host()->SetRootLayer(parent_);
1646 LayerTreeHostTest::SetupTree();
1649 virtual void BeginTest() OVERRIDE {
1650 PostSetNeedsCommitToMainThread();
1653 virtual void DidCommitAndDrawFrame() OVERRIDE {
1654 switch (layer_tree_host()->source_frame_number()) {
1656 parent_->SetNeedsDisplay();
1657 child_->SetNeedsDisplay();
1660 // Damage part of layers.
1661 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1662 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1665 child_->SetNeedsDisplay();
1666 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1669 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1675 NOTREACHED() << layer_tree_host()->source_frame_number();
1680 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1681 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1683 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1684 impl->output_surface()->context_provider()->Context3d());
1686 switch (impl->active_tree()->source_frame_number()) {
1688 // Number of textures should be one for each layer.
1689 ASSERT_EQ(2u, context->NumTextures());
1690 // Number of textures used for commit should be one for each layer.
1691 EXPECT_EQ(2u, context->NumUsedTextures());
1692 // Verify that used textures are correct.
1693 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1694 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1695 context->ResetUsedTextures();
1698 if (HasImplThread()) {
1699 // Number of textures should be two for each content layer.
1700 ASSERT_EQ(4u, context->NumTextures());
1702 // In single thread we can always do partial updates, so the limit has
1704 ASSERT_EQ(2u, context->NumTextures());
1706 // Number of textures used for commit should be one for each content
1708 EXPECT_EQ(2u, context->NumUsedTextures());
1710 if (HasImplThread()) {
1711 // First content textures should not have been used.
1712 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1713 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1714 // New textures should have been used.
1715 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1716 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1718 // In single thread we can always do partial updates, so the limit has
1720 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1721 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1724 context->ResetUsedTextures();
1727 if (HasImplThread()) {
1728 // Number of textures should be two for each content layer.
1729 ASSERT_EQ(4u, context->NumTextures());
1731 // In single thread we can always do partial updates, so the limit has
1733 ASSERT_EQ(2u, context->NumTextures());
1735 // Number of textures used for commit should be one for each content
1737 EXPECT_EQ(2u, context->NumUsedTextures());
1739 if (HasImplThread()) {
1740 // One content layer does a partial update also.
1741 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1742 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1744 // In single thread we can always do partial updates, so the limit has
1746 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1747 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1750 context->ResetUsedTextures();
1753 // No textures should be used for commit.
1754 EXPECT_EQ(0u, context->NumUsedTextures());
1756 context->ResetUsedTextures();
1759 // Number of textures used for commit should be one, for the
1761 EXPECT_EQ(1u, context->NumUsedTextures());
1763 context->ResetUsedTextures();
1771 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1772 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1774 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1775 impl->output_surface()->context_provider()->Context3d());
1777 // Number of textures used for drawing should one per layer except for
1778 // frame 3 where the viewport only contains one layer.
1779 if (impl->active_tree()->source_frame_number() == 3) {
1780 EXPECT_EQ(1u, context->NumUsedTextures());
1782 EXPECT_EQ(2u, context->NumUsedTextures()) <<
1783 "For frame " << impl->active_tree()->source_frame_number();
1786 context->ResetUsedTextures();
1789 virtual void AfterTest() OVERRIDE {}
1792 FakeContentLayerClient client_;
1793 scoped_refptr<FakeContentLayer> parent_;
1794 scoped_refptr<FakeContentLayer> child_;
1797 // Partial updates are not possible with a delegating renderer.
1798 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1799 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1801 class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
1803 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1805 virtual void BeginTest() OVERRIDE {
1806 layer_tree_host()->SetNeedsRedraw();
1807 PostSetNeedsCommitToMainThread();
1810 virtual void DidCommitAndDrawFrame() OVERRIDE {
1814 layer_tree_host()->SetNeedsRedraw();
1815 layer_tree_host()->AcquireLayerTextures();
1817 base::AutoLock lock(lock_);
1820 layer_tree_host()->FinishAllRendering();
1822 base::AutoLock lock(lock_);
1823 EXPECT_EQ(0, draw_count_);
1828 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1829 base::AutoLock lock(lock_);
1833 virtual void AfterTest() OVERRIDE {}
1841 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering);
1843 class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
1845 virtual void BeginTest() OVERRIDE {
1846 Layer* root_layer = layer_tree_host()->root_layer();
1849 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
1850 gfx::Rect(0, 0, 1, 1));
1851 EXPECT_FALSE(root_layer->render_surface());
1856 virtual void AfterTest() OVERRIDE {}
1859 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup);
1861 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1862 : public LayerTreeHostTest {
1864 virtual void SetupTree() OVERRIDE {
1865 root_layer_ = FakeContentLayer::Create(&client_);
1866 root_layer_->SetBounds(gfx::Size(100, 100));
1868 surface_layer1_ = FakeContentLayer::Create(&client_);
1869 surface_layer1_->SetBounds(gfx::Size(100, 100));
1870 surface_layer1_->SetForceRenderSurface(true);
1871 surface_layer1_->SetOpacity(0.5f);
1872 root_layer_->AddChild(surface_layer1_);
1874 surface_layer2_ = FakeContentLayer::Create(&client_);
1875 surface_layer2_->SetBounds(gfx::Size(100, 100));
1876 surface_layer2_->SetForceRenderSurface(true);
1877 surface_layer2_->SetOpacity(0.5f);
1878 surface_layer1_->AddChild(surface_layer2_);
1880 replica_layer1_ = FakeContentLayer::Create(&client_);
1881 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1883 replica_layer2_ = FakeContentLayer::Create(&client_);
1884 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1886 layer_tree_host()->SetRootLayer(root_layer_);
1887 LayerTreeHostTest::SetupTree();
1890 virtual void BeginTest() OVERRIDE {
1891 PostSetNeedsCommitToMainThread();
1894 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1895 Renderer* renderer = host_impl->renderer();
1896 RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1897 ->root_layer()->children()[0]->render_surface()->RenderPassId();
1898 RenderPass::Id surface2_render_pass_id =
1899 host_impl->active_tree()->root_layer()->children()[0]->children()[0]
1900 ->render_surface()->RenderPassId();
1902 switch (host_impl->active_tree()->source_frame_number()) {
1904 EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
1905 surface1_render_pass_id));
1906 EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
1907 surface2_render_pass_id));
1909 // Reduce the memory limit to only fit the root layer and one render
1910 // surface. This prevents any contents drawing into surfaces
1911 // from being allocated.
1912 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1915 EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
1916 surface1_render_pass_id));
1917 EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
1918 surface2_render_pass_id));
1925 virtual void DidCommitAndDrawFrame() OVERRIDE {
1926 if (layer_tree_host()->source_frame_number() < 2)
1927 root_layer_->SetNeedsDisplay();
1930 virtual void AfterTest() OVERRIDE {
1931 EXPECT_LE(2u, root_layer_->update_count());
1932 EXPECT_LE(2u, surface_layer1_->update_count());
1933 EXPECT_LE(2u, surface_layer2_->update_count());
1936 FakeContentLayerClient client_;
1937 scoped_refptr<FakeContentLayer> root_layer_;
1938 scoped_refptr<FakeContentLayer> surface_layer1_;
1939 scoped_refptr<FakeContentLayer> replica_layer1_;
1940 scoped_refptr<FakeContentLayer> surface_layer2_;
1941 scoped_refptr<FakeContentLayer> replica_layer2_;
1944 // Surfaces don't exist with a delegated renderer.
1945 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1946 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1948 class EvictionTestLayer : public Layer {
1950 static scoped_refptr<EvictionTestLayer> Create() {
1951 return make_scoped_refptr(new EvictionTestLayer());
1954 virtual bool Update(ResourceUpdateQueue*,
1955 const OcclusionTracker*) OVERRIDE;
1956 virtual bool DrawsContent() const OVERRIDE { return true; }
1958 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1960 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1961 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1963 bool HaveBackingTexture() const {
1964 return texture_.get() ? texture_->have_backing_texture() : false;
1968 EvictionTestLayer() : Layer() {}
1969 virtual ~EvictionTestLayer() {}
1971 void CreateTextureIfNeeded() {
1974 texture_ = PrioritizedResource::Create(
1975 layer_tree_host()->contents_texture_manager());
1976 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1977 bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
1978 bitmap_.allocPixels();
1981 scoped_ptr<PrioritizedResource> texture_;
1985 class EvictionTestLayerImpl : public LayerImpl {
1987 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1989 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1991 virtual ~EvictionTestLayerImpl() {}
1993 virtual void AppendQuads(QuadSink* quad_sink,
1994 AppendQuadsData* append_quads_data) OVERRIDE {
1995 ASSERT_TRUE(has_texture_);
1996 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1999 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
2002 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
2003 : LayerImpl(tree_impl, id), has_texture_(false) {}
2008 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
2009 CreateTextureIfNeeded();
2012 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
2015 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
2016 const OcclusionTracker*) {
2017 CreateTextureIfNeeded();
2021 gfx::Rect full_rect(0, 0, 10, 10);
2022 ResourceUpdate upload = ResourceUpdate::Create(
2023 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
2024 queue->AppendFullUpload(upload);
2028 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
2029 LayerTreeImpl* tree_impl) {
2030 return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
2031 .PassAs<LayerImpl>();
2034 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
2035 Layer::PushPropertiesTo(layer_impl);
2037 EvictionTestLayerImpl* test_layer_impl =
2038 static_cast<EvictionTestLayerImpl*>(layer_impl);
2039 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
2042 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
2044 LayerTreeHostTestEvictTextures()
2045 : layer_(EvictionTestLayer::Create()),
2046 impl_for_evict_textures_(0),
2049 virtual void BeginTest() OVERRIDE {
2050 layer_tree_host()->SetRootLayer(layer_);
2051 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
2053 gfx::Transform identity_matrix;
2054 SetLayerPropertiesForTesting(layer_.get(),
2057 gfx::PointF(0.f, 0.f),
2058 gfx::PointF(0.f, 0.f),
2062 PostSetNeedsCommitToMainThread();
2065 void PostEvictTextures() {
2066 ImplThreadTaskRunner()->PostTask(
2068 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
2069 base::Unretained(this)));
2072 void EvictTexturesOnImplThread() {
2073 DCHECK(impl_for_evict_textures_);
2074 impl_for_evict_textures_->EvictTexturesForTesting();
2077 // Commit 1: Just commit and draw normally, then post an eviction at the end
2078 // that will trigger a commit.
2079 // Commit 2: Triggered by the eviction, let it go through and then set
2081 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
2082 // task, which will be handled before the commit. Don't set needsCommit, it
2083 // should have been posted. A frame should not be drawn (note,
2084 // didCommitAndDrawFrame may be called anyway).
2085 // Commit 4: Triggered by the eviction, let it go through and then set
2087 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
2088 // Layout(), a frame should not be drawn but a commit will be posted.
2089 // Commit 6: Triggered by the eviction, post an eviction task in
2090 // Layout(), which will be a noop, letting the commit (which recreates the
2091 // textures) go through and draw a frame, then end the test.
2093 // Commits 1+2 test the eviction recovery path where eviction happens outside
2094 // of the beginFrame/commit pair.
2095 // Commits 3+4 test the eviction recovery path where eviction happens inside
2096 // the beginFrame/commit pair.
2097 // Commits 5+6 test the path where an eviction happens during the eviction
2099 virtual void DidCommit() OVERRIDE {
2100 switch (num_commits_) {
2102 EXPECT_TRUE(layer_->HaveBackingTexture());
2103 PostEvictTextures();
2106 EXPECT_TRUE(layer_->HaveBackingTexture());
2107 layer_tree_host()->SetNeedsCommit();
2112 EXPECT_TRUE(layer_->HaveBackingTexture());
2113 layer_tree_host()->SetNeedsCommit();
2118 EXPECT_TRUE(layer_->HaveBackingTexture());
2127 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2128 impl_for_evict_textures_ = impl;
2131 virtual void Layout() OVERRIDE {
2133 switch (num_commits_) {
2138 PostEvictTextures();
2141 // We couldn't check in didCommitAndDrawFrame on commit 3,
2143 EXPECT_FALSE(layer_->HaveBackingTexture());
2146 PostEvictTextures();
2149 // We couldn't check in didCommitAndDrawFrame on commit 5,
2151 EXPECT_FALSE(layer_->HaveBackingTexture());
2152 PostEvictTextures();
2160 virtual void AfterTest() OVERRIDE {}
2163 FakeContentLayerClient client_;
2164 scoped_refptr<EvictionTestLayer> layer_;
2165 LayerTreeHostImpl* impl_for_evict_textures_;
2169 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
2171 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
2173 LayerTreeHostTestContinuousCommit()
2174 : num_commit_complete_(0), num_draw_layers_(0) {}
2176 virtual void BeginTest() OVERRIDE {
2177 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2178 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2180 PostSetNeedsCommitToMainThread();
2183 virtual void DidCommit() OVERRIDE {
2184 if (num_draw_layers_ == 2)
2186 layer_tree_host()->SetNeedsCommit();
2189 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2190 if (num_draw_layers_ == 1)
2191 num_commit_complete_++;
2194 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2196 if (num_draw_layers_ == 2)
2200 virtual void AfterTest() OVERRIDE {
2201 // Check that we didn't commit twice between first and second draw.
2202 EXPECT_EQ(1, num_commit_complete_);
2206 int num_commit_complete_;
2207 int num_draw_layers_;
2210 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
2212 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
2214 LayerTreeHostTestContinuousInvalidate()
2215 : num_commit_complete_(0), num_draw_layers_(0) {}
2217 virtual void BeginTest() OVERRIDE {
2218 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2219 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2221 content_layer_ = ContentLayer::Create(&client_);
2222 content_layer_->SetBounds(gfx::Size(10, 10));
2223 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
2224 content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
2225 content_layer_->SetIsDrawable(true);
2226 layer_tree_host()->root_layer()->AddChild(content_layer_);
2228 PostSetNeedsCommitToMainThread();
2231 virtual void DidCommitAndDrawFrame() OVERRIDE {
2232 if (num_draw_layers_ == 2)
2234 content_layer_->SetNeedsDisplay();
2237 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2238 if (num_draw_layers_ == 1)
2239 num_commit_complete_++;
2242 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2244 if (num_draw_layers_ == 2)
2248 virtual void AfterTest() OVERRIDE {
2249 // Check that we didn't commit twice between first and second draw.
2250 EXPECT_EQ(1, num_commit_complete_);
2254 FakeContentLayerClient client_;
2255 scoped_refptr<Layer> content_layer_;
2256 int num_commit_complete_;
2257 int num_draw_layers_;
2260 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestContinuousInvalidate);
2262 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2264 LayerTreeHostTestDeferCommits()
2265 : num_commits_deferred_(0), num_complete_commits_(0) {}
2267 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2269 virtual void DidDeferCommit() OVERRIDE {
2270 num_commits_deferred_++;
2271 layer_tree_host()->SetDeferCommits(false);
2274 virtual void DidCommit() OVERRIDE {
2275 num_complete_commits_++;
2276 switch (num_complete_commits_) {
2278 EXPECT_EQ(0, num_commits_deferred_);
2279 layer_tree_host()->SetDeferCommits(true);
2280 PostSetNeedsCommitToMainThread();
2291 virtual void AfterTest() OVERRIDE {
2292 EXPECT_EQ(1, num_commits_deferred_);
2293 EXPECT_EQ(2, num_complete_commits_);
2297 int num_commits_deferred_;
2298 int num_complete_commits_;
2301 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2303 class LayerTreeHostWithProxy : public LayerTreeHost {
2305 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2306 const LayerTreeSettings& settings,
2307 scoped_ptr<FakeProxy> proxy)
2308 : LayerTreeHost(client, NULL, settings) {
2309 proxy->SetLayerTreeHost(this);
2310 EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>()));
2314 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2315 // When partial updates are not allowed, max updates should be 0.
2317 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2319 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2320 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2321 proxy->SetMaxPartialTextureUpdates(5);
2323 LayerTreeSettings settings;
2324 settings.max_partial_texture_updates = 10;
2326 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2327 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2329 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2332 // When partial updates are allowed,
2333 // max updates should be limited by the proxy.
2335 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2337 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2338 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2339 proxy->SetMaxPartialTextureUpdates(5);
2341 LayerTreeSettings settings;
2342 settings.max_partial_texture_updates = 10;
2344 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2345 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2347 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2350 // When partial updates are allowed,
2351 // max updates should also be limited by the settings.
2353 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2355 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2356 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2357 proxy->SetMaxPartialTextureUpdates(20);
2359 LayerTreeSettings settings;
2360 settings.max_partial_texture_updates = 10;
2362 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2363 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2365 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2369 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2370 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2372 LayerTreeSettings settings;
2373 settings.max_partial_texture_updates = 4;
2375 scoped_ptr<LayerTreeHost> host =
2376 LayerTreeHost::Create(&client, NULL, settings, NULL);
2377 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2378 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2381 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2382 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2384 LayerTreeSettings settings;
2385 settings.max_partial_texture_updates = 4;
2387 scoped_ptr<LayerTreeHost> host =
2388 LayerTreeHost::Create(&client, NULL, settings, NULL);
2389 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2390 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2393 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2394 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2396 LayerTreeSettings settings;
2397 settings.max_partial_texture_updates = 4;
2399 scoped_ptr<LayerTreeHost> host =
2400 LayerTreeHost::Create(&client, NULL, settings, NULL);
2401 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2402 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2405 TEST(LayerTreeHostTest,
2406 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2407 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2409 LayerTreeSettings settings;
2410 settings.max_partial_texture_updates = 4;
2412 scoped_ptr<LayerTreeHost> host =
2413 LayerTreeHost::Create(&client, NULL, settings, NULL);
2414 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2415 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2418 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2419 : public LayerTreeHostTest {
2421 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2422 : root_layer_(FakeContentLayer::Create(&client_)),
2423 child_layer1_(FakeContentLayer::Create(&client_)),
2424 child_layer2_(FakeContentLayer::Create(&client_)),
2427 virtual void BeginTest() OVERRIDE {
2428 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2429 root_layer_->SetBounds(gfx::Size(100, 100));
2430 child_layer1_->SetBounds(gfx::Size(100, 100));
2431 child_layer2_->SetBounds(gfx::Size(100, 100));
2432 root_layer_->AddChild(child_layer1_);
2433 root_layer_->AddChild(child_layer2_);
2434 layer_tree_host()->SetRootLayer(root_layer_);
2435 PostSetNeedsCommitToMainThread();
2438 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2439 bool visible) OVERRIDE {
2441 // One backing should remain unevicted.
2443 100u * 100u * 4u * 1u,
2444 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2448 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2451 // Make sure that contents textures are marked as having been
2453 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2454 // End the test in this state.
2458 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2460 switch (num_commits_) {
2462 // All three backings should have memory.
2464 100u * 100u * 4u * 3u,
2465 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2466 // Set a new policy that will kick out 1 of the 3 resources.
2467 // Because a resource was evicted, a commit will be kicked off.
2468 host_impl->SetMemoryPolicy(
2469 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2470 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2474 // Only two backings should have memory.
2476 100u * 100u * 4u * 2u,
2477 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2478 // Become backgrounded, which will cause 1 more resource to be
2480 PostSetVisibleToMainThread(false);
2483 // No further commits should happen because this is not visible
2490 virtual void AfterTest() OVERRIDE {}
2493 FakeContentLayerClient client_;
2494 scoped_refptr<FakeContentLayer> root_layer_;
2495 scoped_refptr<FakeContentLayer> child_layer1_;
2496 scoped_refptr<FakeContentLayer> child_layer2_;
2500 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2501 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2503 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2505 class NotificationClient : public ContentLayerClient {
2507 NotificationClient()
2508 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2510 void set_layer(Layer* layer) { layer_ = layer; }
2511 int paint_count() const { return paint_count_; }
2512 int lcd_notification_count() const { return lcd_notification_count_; }
2514 virtual void PaintContents(SkCanvas* canvas,
2516 gfx::RectF* opaque) OVERRIDE {
2519 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2520 ++lcd_notification_count_;
2521 layer_->SetNeedsDisplay();
2527 int lcd_notification_count_;
2530 virtual void SetupTree() OVERRIDE {
2531 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2532 root_layer->SetIsDrawable(true);
2533 root_layer->SetBounds(gfx::Size(1, 1));
2535 layer_tree_host()->SetRootLayer(root_layer);
2536 client_.set_layer(root_layer.get());
2538 // The expecations are based on the assumption that the default
2539 // LCD settings are:
2540 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2541 EXPECT_FALSE(root_layer->can_use_lcd_text());
2543 LayerTreeHostTest::SetupTree();
2546 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2547 virtual void AfterTest() OVERRIDE {}
2549 virtual void DidCommit() OVERRIDE {
2550 switch (layer_tree_host()->source_frame_number()) {
2552 // The first update consists one LCD notification and one paint.
2553 EXPECT_EQ(1, client_.lcd_notification_count());
2554 EXPECT_EQ(1, client_.paint_count());
2555 // LCD text must have been enabled on the layer.
2556 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2557 PostSetNeedsCommitToMainThread();
2560 // Since nothing changed on layer, there should be no notification
2561 // or paint on the second update.
2562 EXPECT_EQ(1, client_.lcd_notification_count());
2563 EXPECT_EQ(1, client_.paint_count());
2564 // LCD text must not have changed.
2565 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2566 // Change layer opacity that should trigger lcd notification.
2567 layer_tree_host()->root_layer()->SetOpacity(.5f);
2568 // No need to request a commit - setting opacity will do it.
2571 // Verify that there is not extra commit due to layer invalidation.
2572 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
2573 // LCD notification count should have incremented due to
2574 // change in layer opacity.
2575 EXPECT_EQ(2, client_.lcd_notification_count());
2576 // Paint count should be incremented due to invalidation.
2577 EXPECT_EQ(2, client_.paint_count());
2578 // LCD text must have been disabled on the layer due to opacity.
2579 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2586 NotificationClient client_;
2589 SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2591 // Verify that the BeginImplFrame notification is used to initiate rendering.
2592 class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest {
2594 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2595 settings->begin_impl_frame_scheduling_enabled = true;
2598 virtual void BeginTest() OVERRIDE {
2599 // This will trigger a SetNeedsBeginImplFrame which will trigger a
2601 PostSetNeedsCommitToMainThread();
2604 virtual bool PrepareToDrawOnThread(
2605 LayerTreeHostImpl* host_impl,
2606 LayerTreeHostImpl::FrameData* frame,
2607 bool result) OVERRIDE {
2612 virtual void AfterTest() OVERRIDE {}
2615 base::TimeTicks frame_time_;
2618 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginImplFrameNotification);
2620 class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled
2621 : public LayerTreeHostTest {
2623 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2624 settings->begin_impl_frame_scheduling_enabled = true;
2625 settings->using_synchronous_renderer_compositor = true;
2628 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2630 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2631 // The BeginImplFrame notification is turned off now but will get enabled
2632 // once we return. End test while it's enabled.
2633 ImplThreadTaskRunner()->PostTask(
2635 base::Bind(&LayerTreeHostTestBeginImplFrameNotification::EndTest,
2636 base::Unretained(this)));
2639 virtual void AfterTest() OVERRIDE {}
2642 MULTI_THREAD_TEST_F(
2643 LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled);
2645 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2647 LayerTreeHostTestAbortedCommitDoesntStall()
2648 : commit_count_(0), commit_complete_count_(0) {}
2650 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2651 settings->begin_impl_frame_scheduling_enabled = true;
2654 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2656 virtual void DidCommit() OVERRIDE {
2658 if (commit_count_ == 2) {
2659 // A commit was just aborted, request a real commit now to make sure a
2660 // real commit following an aborted commit will still complete and
2661 // end the test even when the Impl thread is idle.
2662 layer_tree_host()->SetNeedsCommit();
2666 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2667 commit_complete_count_++;
2668 if (commit_complete_count_ == 1) {
2669 // Initiate an aborted commit after the first commit.
2670 host_impl->SetNeedsCommit();
2676 virtual void AfterTest() OVERRIDE {
2677 EXPECT_EQ(commit_count_, 3);
2678 EXPECT_EQ(commit_complete_count_, 2);
2682 int commit_complete_count_;
2685 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2686 : public LayerTreeHostTestAbortedCommitDoesntStall {
2687 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2688 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2689 settings->using_synchronous_renderer_compositor = true;
2693 MULTI_THREAD_TEST_F(
2694 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2696 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2697 : public LayerTreeHostTestAbortedCommitDoesntStall {
2698 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2699 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2700 settings->throttle_frame_production = false;
2704 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2706 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2707 : public LayerTreeHostTest {
2709 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2710 settings->impl_side_painting = true;
2713 virtual void SetupTree() OVERRIDE {
2714 LayerTreeHostTest::SetupTree();
2716 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2717 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2718 layer->SetBounds(gfx::Size(10, 10));
2719 layer_tree_host()->root_layer()->AddChild(layer);
2722 virtual void BeginTest() OVERRIDE {
2723 PostSetNeedsCommitToMainThread();
2726 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2730 virtual void AfterTest() OVERRIDE {
2733 FakeContentLayerClient client_;
2736 MULTI_THREAD_TEST_F(
2737 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2739 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2740 : public LayerTreeHostTest {
2742 class SetBoundsClient : public ContentLayerClient {
2744 SetBoundsClient() : layer_(0) {}
2746 void set_layer(Layer* layer) { layer_ = layer; }
2748 virtual void PaintContents(SkCanvas* canvas,
2750 gfx::RectF* opaque) OVERRIDE {
2751 layer_->SetBounds(gfx::Size(2, 2));
2754 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2760 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2762 virtual void SetupTree() OVERRIDE {
2763 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2764 root_layer->SetIsDrawable(true);
2765 root_layer->SetBounds(gfx::Size(1, 1));
2767 layer_tree_host()->SetRootLayer(root_layer);
2768 client_.set_layer(root_layer.get());
2770 LayerTreeHostTest::SetupTree();
2773 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2774 virtual void AfterTest() OVERRIDE {}
2776 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2778 if (num_commits_ == 1) {
2779 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2780 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2782 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2783 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2789 SetBoundsClient client_;
2793 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2795 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2797 MockIOSurfaceWebGraphicsContext3D() {
2798 test_capabilities_.iosurface = true;
2799 test_capabilities_.texture_rectangle = true;
2802 virtual WebKit::WebGLId createTexture() OVERRIDE {
2806 MOCK_METHOD1(activeTexture, void(WebKit::WGC3Denum texture));
2807 MOCK_METHOD2(bindTexture, void(WebKit::WGC3Denum target,
2808 WebKit::WebGLId texture_id));
2809 MOCK_METHOD3(texParameteri, void(WebKit::WGC3Denum target,
2810 WebKit::WGC3Denum pname,
2811 WebKit::WGC3Dint param));
2812 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(WebKit::WGC3Denum target,
2813 WebKit::WGC3Dint width,
2814 WebKit::WGC3Dint height,
2815 WebKit::WGC3Duint ioSurfaceId,
2816 WebKit::WGC3Duint plane));
2817 MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
2818 WebKit::WGC3Dsizei count,
2819 WebKit::WGC3Denum type,
2820 WebKit::WGC3Dintptr offset));
2821 MOCK_METHOD1(deleteTexture, void(WebKit::WGC3Denum texture));
2825 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2827 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
2829 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2830 new MockIOSurfaceWebGraphicsContext3D);
2831 mock_context_ = mock_context_owned.get();
2833 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
2834 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
2835 return output_surface.Pass();
2838 virtual void SetupTree() OVERRIDE {
2839 LayerTreeHostTest::SetupTree();
2841 layer_tree_host()->root_layer()->SetIsDrawable(false);
2844 io_surface_size_ = gfx::Size(6, 7);
2846 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2847 io_surface_layer->SetBounds(gfx::Size(10, 10));
2848 io_surface_layer->SetAnchorPoint(gfx::PointF());
2849 io_surface_layer->SetIsDrawable(true);
2850 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2851 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2854 virtual void BeginTest() OVERRIDE {
2855 PostSetNeedsCommitToMainThread();
2858 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2859 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2861 EXPECT_CALL(*mock_context_, activeTexture(_))
2863 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2865 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2866 GL_TEXTURE_MIN_FILTER,
2869 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2870 GL_TEXTURE_MAG_FILTER,
2873 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2877 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2882 EXPECT_CALL(*mock_context_, texImageIOSurface2DCHROMIUM(
2883 GL_TEXTURE_RECTANGLE_ARB,
2884 io_surface_size_.width(),
2885 io_surface_size_.height(),
2890 EXPECT_CALL(*mock_context_, bindTexture(_, 0))
2891 .Times(AnyNumber());
2894 virtual bool PrepareToDrawOnThread(
2895 LayerTreeHostImpl* host_impl,
2896 LayerTreeHostImpl::FrameData* frame,
2897 bool result) OVERRIDE {
2898 Mock::VerifyAndClearExpectations(&mock_context_);
2900 // The io surface layer's texture is drawn.
2901 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0))
2903 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2905 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2911 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2912 Mock::VerifyAndClearExpectations(&mock_context_);
2914 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(1);
2918 virtual void AfterTest() OVERRIDE {}
2921 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2922 gfx::Size io_surface_size_;
2925 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
2926 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2927 LayerTreeHostTestIOSurfaceDrawing);
2929 class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
2931 virtual void SetupTree() OVERRIDE {
2932 root = FakeContentLayer::Create(&client_);
2933 root->SetBounds(gfx::Size(20, 20));
2935 child = FakeContentLayer::Create(&client_);
2936 child->SetBounds(gfx::Size(10, 10));
2937 root->AddChild(child);
2939 layer_tree_host()->SetRootLayer(root);
2940 LayerTreeHostTest::SetupTree();
2943 virtual void BeginTest() OVERRIDE {
2944 PostSetNeedsCommitToMainThread();
2947 virtual void DidCommitAndDrawFrame() OVERRIDE {
2951 void WaitForCallback() {
2952 base::MessageLoop::current()->PostTask(
2955 &LayerTreeHostTestAsyncReadback::NextStep,
2956 base::Unretained(this)));
2960 int frame = layer_tree_host()->source_frame_number();
2963 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2964 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2965 base::Unretained(this))));
2966 EXPECT_EQ(0u, callbacks_.size());
2969 if (callbacks_.size() < 1u) {
2973 EXPECT_EQ(1u, callbacks_.size());
2974 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
2976 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2977 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2978 base::Unretained(this))));
2979 root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2980 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2981 base::Unretained(this))));
2982 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2983 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2984 base::Unretained(this))));
2985 EXPECT_EQ(1u, callbacks_.size());
2988 if (callbacks_.size() < 4u) {
2992 EXPECT_EQ(4u, callbacks_.size());
2993 // The child was copied to a bitmap and passed back twice.
2994 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
2995 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
2996 // The root was copied to a bitmap and passed back also.
2997 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
3003 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3004 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3005 EXPECT_TRUE(result->HasBitmap());
3006 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
3007 EXPECT_EQ(result->size().ToString(),
3008 gfx::Size(bitmap->width(), bitmap->height()).ToString());
3009 callbacks_.push_back(result->size());
3012 virtual void AfterTest() OVERRIDE {
3013 EXPECT_EQ(4u, callbacks_.size());
3016 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3018 scoped_ptr<FakeOutputSurface> output_surface;
3019 if (use_gl_renderer_) {
3020 output_surface = FakeOutputSurface::Create3d().Pass();
3022 output_surface = FakeOutputSurface::CreateSoftware(
3023 make_scoped_ptr(new SoftwareOutputDevice)).Pass();
3025 return output_surface.PassAs<OutputSurface>();
3028 bool use_gl_renderer_;
3029 std::vector<gfx::Size> callbacks_;
3030 FakeContentLayerClient client_;
3031 scoped_refptr<FakeContentLayer> root;
3032 scoped_refptr<FakeContentLayer> child;
3035 // Readback can't be done with a delegating renderer.
3036 TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
3037 use_gl_renderer_ = true;
3038 RunTest(false, false, false);
3041 TEST_F(LayerTreeHostTestAsyncReadback,
3042 GLRenderer_RunMultiThread_MainThreadPainting) {
3043 use_gl_renderer_ = true;
3044 RunTest(true, false, false);
3047 TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
3048 use_gl_renderer_ = false;
3049 RunTest(false, false, false);
3052 TEST_F(LayerTreeHostTestAsyncReadback,
3053 SoftwareRenderer_RunMultiThread_MainThreadPainting) {
3054 use_gl_renderer_ = false;
3055 RunTest(true, false, false);
3058 class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
3060 virtual void SetupTree() OVERRIDE {
3061 root_ = FakeContentLayer::Create(&client_);
3062 root_->SetBounds(gfx::Size(20, 20));
3064 main_destroyed_ = FakeContentLayer::Create(&client_);
3065 main_destroyed_->SetBounds(gfx::Size(15, 15));
3066 root_->AddChild(main_destroyed_);
3068 impl_destroyed_ = FakeContentLayer::Create(&client_);
3069 impl_destroyed_->SetBounds(gfx::Size(10, 10));
3070 root_->AddChild(impl_destroyed_);
3072 layer_tree_host()->SetRootLayer(root_);
3073 LayerTreeHostTest::SetupTree();
3076 virtual void BeginTest() OVERRIDE {
3077 callback_count_ = 0;
3078 PostSetNeedsCommitToMainThread();
3081 virtual void DidCommit() OVERRIDE {
3082 int frame = layer_tree_host()->source_frame_number();
3085 main_destroyed_->RequestCopyOfOutput(
3086 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3087 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
3089 base::Unretained(this))));
3090 impl_destroyed_->RequestCopyOfOutput(
3091 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3092 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
3094 base::Unretained(this))));
3095 EXPECT_EQ(0, callback_count_);
3097 // Destroy the main thread layer right away.
3098 main_destroyed_->RemoveFromParent();
3099 main_destroyed_ = NULL;
3101 // Should callback with a NULL bitmap.
3102 EXPECT_EQ(1, callback_count_);
3104 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
3105 layer_tree_host()->SetViewportSize(gfx::Size());
3108 // Flush the message loops and make sure the callbacks run.
3109 layer_tree_host()->SetNeedsCommit();
3112 // No drawing means no readback yet.
3113 EXPECT_EQ(1, callback_count_);
3115 // Destroy the impl thread layer.
3116 impl_destroyed_->RemoveFromParent();
3117 impl_destroyed_ = NULL;
3119 // No callback yet because it's on the impl side.
3120 EXPECT_EQ(1, callback_count_);
3123 // Flush the message loops and make sure the callbacks run.
3124 layer_tree_host()->SetNeedsCommit();
3127 // We should get another callback with a NULL bitmap.
3128 EXPECT_EQ(2, callback_count_);
3134 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3135 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3136 EXPECT_TRUE(result->IsEmpty());
3140 virtual void AfterTest() OVERRIDE {}
3142 int callback_count_;
3143 FakeContentLayerClient client_;
3144 scoped_refptr<FakeContentLayer> root_;
3145 scoped_refptr<FakeContentLayer> main_destroyed_;
3146 scoped_refptr<FakeContentLayer> impl_destroyed_;
3149 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed);
3151 class LayerTreeHostTestAsyncReadbackInHiddenSubtree : public LayerTreeHostTest {
3153 virtual void SetupTree() OVERRIDE {
3154 root_ = FakeContentLayer::Create(&client_);
3155 root_->SetBounds(gfx::Size(20, 20));
3157 grand_parent_layer_ = FakeContentLayer::Create(&client_);
3158 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
3159 root_->AddChild(grand_parent_layer_);
3161 // parent_layer_ owns a render surface.
3162 parent_layer_ = FakeContentLayer::Create(&client_);
3163 parent_layer_->SetBounds(gfx::Size(15, 15));
3164 parent_layer_->SetForceRenderSurface(true);
3165 grand_parent_layer_->AddChild(parent_layer_);
3167 copy_layer_ = FakeContentLayer::Create(&client_);
3168 copy_layer_->SetBounds(gfx::Size(10, 10));
3169 parent_layer_->AddChild(copy_layer_);
3171 layer_tree_host()->SetRootLayer(root_);
3172 LayerTreeHostTest::SetupTree();
3175 void AddCopyRequest(Layer* layer) {
3176 layer->RequestCopyOfOutput(
3177 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3178 &LayerTreeHostTestAsyncReadbackInHiddenSubtree::CopyOutputCallback,
3179 base::Unretained(this))));
3182 virtual void BeginTest() OVERRIDE {
3183 callback_count_ = 0;
3184 PostSetNeedsCommitToMainThread();
3186 AddCopyRequest(copy_layer_.get());
3189 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3190 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3191 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3194 switch (callback_count_) {
3196 // Hide the copy request layer.
3197 grand_parent_layer_->SetHideLayerAndSubtree(false);
3198 parent_layer_->SetHideLayerAndSubtree(false);
3199 copy_layer_->SetHideLayerAndSubtree(true);
3200 AddCopyRequest(copy_layer_.get());
3203 // Hide the copy request layer's parent only.
3204 grand_parent_layer_->SetHideLayerAndSubtree(false);
3205 parent_layer_->SetHideLayerAndSubtree(true);
3206 copy_layer_->SetHideLayerAndSubtree(false);
3207 AddCopyRequest(copy_layer_.get());
3210 // Hide the copy request layer's grand parent only.
3211 grand_parent_layer_->SetHideLayerAndSubtree(true);
3212 parent_layer_->SetHideLayerAndSubtree(false);
3213 copy_layer_->SetHideLayerAndSubtree(false);
3214 AddCopyRequest(copy_layer_.get());
3217 // Hide the copy request layer's parent and grandparent.
3218 grand_parent_layer_->SetHideLayerAndSubtree(true);
3219 parent_layer_->SetHideLayerAndSubtree(true);
3220 copy_layer_->SetHideLayerAndSubtree(false);
3221 AddCopyRequest(copy_layer_.get());
3224 // Hide the copy request layer as well as its parent and grandparent.
3225 grand_parent_layer_->SetHideLayerAndSubtree(true);
3226 parent_layer_->SetHideLayerAndSubtree(true);
3227 copy_layer_->SetHideLayerAndSubtree(true);
3228 AddCopyRequest(copy_layer_.get());
3236 virtual void AfterTest() OVERRIDE {}
3238 int callback_count_;
3239 FakeContentLayerClient client_;
3240 scoped_refptr<FakeContentLayer> root_;
3241 scoped_refptr<FakeContentLayer> grand_parent_layer_;
3242 scoped_refptr<FakeContentLayer> parent_layer_;
3243 scoped_refptr<FakeContentLayer> copy_layer_;
3246 // No output to copy for delegated renderers.
3247 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3248 LayerTreeHostTestAsyncReadbackInHiddenSubtree);
3250 class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
3251 : public LayerTreeHostTest {
3253 virtual void SetupTree() OVERRIDE {
3254 root_ = FakeContentLayer::Create(&client_);
3255 root_->SetBounds(gfx::Size(20, 20));
3257 grand_parent_layer_ = FakeContentLayer::Create(&client_);
3258 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
3259 grand_parent_layer_->SetHideLayerAndSubtree(true);
3260 root_->AddChild(grand_parent_layer_);
3262 // parent_layer_ owns a render surface.
3263 parent_layer_ = FakeContentLayer::Create(&client_);
3264 parent_layer_->SetBounds(gfx::Size(15, 15));
3265 parent_layer_->SetForceRenderSurface(true);
3266 grand_parent_layer_->AddChild(parent_layer_);
3268 copy_layer_ = FakeContentLayer::Create(&client_);
3269 copy_layer_->SetBounds(gfx::Size(10, 10));
3270 parent_layer_->AddChild(copy_layer_);
3272 layer_tree_host()->SetRootLayer(root_);
3273 LayerTreeHostTest::SetupTree();
3276 virtual void BeginTest() OVERRIDE {
3278 PostSetNeedsCommitToMainThread();
3280 copy_layer_->RequestCopyOfOutput(
3281 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3282 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
3284 base::Unretained(this))));
3287 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3288 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3289 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3293 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3294 Renderer* renderer = host_impl->renderer();
3296 LayerImpl* root = host_impl->active_tree()->root_layer();
3297 LayerImpl* grand_parent = root->children()[0];
3298 LayerImpl* parent = grand_parent->children()[0];
3299 LayerImpl* copy_layer = parent->children()[0];
3301 // |parent| owns a surface, but it was hidden and not part of the copy
3302 // request so it should not allocate any resource.
3303 EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
3304 parent->render_surface()->RenderPassId()));
3306 // |copy_layer| should have been rendered to a texture since it was needed
3307 // for a copy request.
3308 EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
3309 copy_layer->render_surface()->RenderPassId()));
3314 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
3316 FakeContentLayerClient client_;
3318 scoped_refptr<FakeContentLayer> root_;
3319 scoped_refptr<FakeContentLayer> grand_parent_layer_;
3320 scoped_refptr<FakeContentLayer> parent_layer_;
3321 scoped_refptr<FakeContentLayer> copy_layer_;
3324 // No output to copy for delegated renderers.
3325 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3326 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
3328 class LayerTreeHostTestAsyncReadbackClippedOut : public LayerTreeHostTest {
3330 virtual void SetupTree() OVERRIDE {
3331 root_ = FakeContentLayer::Create(&client_);
3332 root_->SetBounds(gfx::Size(20, 20));
3334 parent_layer_ = FakeContentLayer::Create(&client_);
3335 parent_layer_->SetBounds(gfx::Size(15, 15));
3336 parent_layer_->SetMasksToBounds(true);
3337 root_->AddChild(parent_layer_);
3339 copy_layer_ = FakeContentLayer::Create(&client_);
3340 copy_layer_->SetPosition(gfx::Point(15, 15));
3341 copy_layer_->SetBounds(gfx::Size(10, 10));
3342 parent_layer_->AddChild(copy_layer_);
3344 layer_tree_host()->SetRootLayer(root_);
3345 LayerTreeHostTest::SetupTree();
3348 virtual void BeginTest() OVERRIDE {
3349 PostSetNeedsCommitToMainThread();
3351 copy_layer_->RequestCopyOfOutput(
3352 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3353 &LayerTreeHostTestAsyncReadbackClippedOut::CopyOutputCallback,
3354 base::Unretained(this))));
3357 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3358 // We should still get a callback with no output if the copy requested layer
3359 // was completely clipped away.
3360 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3361 EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
3365 virtual void AfterTest() OVERRIDE {}
3367 FakeContentLayerClient client_;
3368 scoped_refptr<FakeContentLayer> root_;
3369 scoped_refptr<FakeContentLayer> parent_layer_;
3370 scoped_refptr<FakeContentLayer> copy_layer_;
3373 // No output to copy for delegated renderers.
3374 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3375 LayerTreeHostTestAsyncReadbackClippedOut);
3377 class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostTest {
3379 virtual void SetupTree() OVERRIDE {
3380 root_ = FakeContentLayer::Create(&client_);
3381 root_->SetBounds(gfx::Size(20, 20));
3383 copy_layer_ = FakeContentLayer::Create(&client_);
3384 copy_layer_->SetBounds(gfx::Size(10, 10));
3385 root_->AddChild(copy_layer_);
3387 layer_tree_host()->SetRootLayer(root_);
3388 LayerTreeHostTest::SetupTree();
3391 void AddCopyRequest(Layer* layer) {
3392 layer->RequestCopyOfOutput(
3393 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3394 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
3395 base::Unretained(this))));
3398 virtual void BeginTest() OVERRIDE {
3399 saw_copy_request_ = false;
3400 callback_count_ = 0;
3401 PostSetNeedsCommitToMainThread();
3404 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
3406 AddCopyRequest(copy_layer_.get());
3409 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3410 if (impl->active_tree()->source_frame_number() == 0) {
3411 LayerImpl* root = impl->active_tree()->root_layer();
3412 EXPECT_TRUE(root->children()[0]->HasCopyRequest());
3413 saw_copy_request_ = true;
3417 virtual void DidCommit() OVERRIDE {
3418 if (layer_tree_host()->source_frame_number() == 1) {
3420 layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
3422 AddCopyRequest(copy_layer_.get());
3426 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3427 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3428 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3431 if (callback_count_ == 2)
3435 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
3437 bool saw_copy_request_;
3438 int callback_count_;
3439 FakeContentLayerClient client_;
3440 scoped_refptr<FakeContentLayer> root_;
3441 scoped_refptr<FakeContentLayer> copy_layer_;
3444 // No output to copy for delegated renderers.
3445 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3446 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
3448 class LayerTreeHostTestAsyncReadbackLostOutputSurface
3449 : public LayerTreeHostTest {
3451 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3453 if (!first_context_provider_.get()) {
3454 first_context_provider_ = TestContextProvider::Create();
3455 return FakeOutputSurface::Create3d(first_context_provider_)
3456 .PassAs<OutputSurface>();
3459 EXPECT_FALSE(second_context_provider_.get());
3460 second_context_provider_ = TestContextProvider::Create();
3461 return FakeOutputSurface::Create3d(second_context_provider_)
3462 .PassAs<OutputSurface>();
3465 virtual void SetupTree() OVERRIDE {
3466 root_ = FakeContentLayer::Create(&client_);
3467 root_->SetBounds(gfx::Size(20, 20));
3469 copy_layer_ = FakeContentLayer::Create(&client_);
3470 copy_layer_->SetBounds(gfx::Size(10, 10));
3471 root_->AddChild(copy_layer_);
3473 layer_tree_host()->SetRootLayer(root_);
3474 LayerTreeHostTest::SetupTree();
3477 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3479 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3480 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3481 EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString());
3482 EXPECT_TRUE(result->HasTexture());
3484 // Save the result for later.
3485 EXPECT_FALSE(result_);
3486 result_ = result.Pass();
3488 // Post a commit to lose the output surface.
3489 layer_tree_host()->SetNeedsCommit();
3492 virtual void DidCommitAndDrawFrame() OVERRIDE {
3493 switch (layer_tree_host()->source_frame_number()) {
3495 // The layers have been pushed to the impl side. The layer textures have
3498 // Request a copy of the layer. This will use another texture.
3499 copy_layer_->RequestCopyOfOutput(
3500 CopyOutputRequest::CreateRequest(base::Bind(
3501 &LayerTreeHostTestAsyncReadbackLostOutputSurface::
3503 base::Unretained(this))));
3506 // With SingleThreadProxy it takes two commits to finally swap after a
3509 // Now destroy the CopyOutputResult, releasing the texture inside back
3510 // to the compositor.
3511 EXPECT_TRUE(result_);
3514 // Check that it is released.
3515 ImplThreadTaskRunner()->PostTask(
3517 base::Bind(&LayerTreeHostTestAsyncReadbackLostOutputSurface::
3519 base::Unretained(this),
3520 num_textures_after_loss_ - 1));
3525 virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result)
3527 switch (impl->active_tree()->source_frame_number()) {
3529 // The layers have been drawn, so their textures have been allocated.
3530 EXPECT_FALSE(result_);
3531 num_textures_without_readback_ =
3532 first_context_provider_->TestContext3d()->NumTextures();
3535 // We did a readback, so there will be a readback texture around now.
3536 EXPECT_LT(num_textures_without_readback_,
3537 first_context_provider_->TestContext3d()->NumTextures());
3540 // The readback texture is collected.
3541 EXPECT_TRUE(result_);
3543 // Lose the output surface.
3544 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
3545 GL_GUILTY_CONTEXT_RESET_ARB,
3546 GL_INNOCENT_CONTEXT_RESET_ARB);
3549 // With SingleThreadProxy it takes two commits to finally swap after a
3552 // The output surface has been recreated.
3553 EXPECT_TRUE(second_context_provider_.get());
3555 num_textures_after_loss_ =
3556 first_context_provider_->TestContext3d()->NumTextures();
3561 void CheckNumTextures(size_t expected_num_textures) {
3562 EXPECT_EQ(expected_num_textures,
3563 first_context_provider_->TestContext3d()->NumTextures());
3567 virtual void AfterTest() OVERRIDE {}
3569 scoped_refptr<TestContextProvider> first_context_provider_;
3570 scoped_refptr<TestContextProvider> second_context_provider_;
3571 size_t num_textures_without_readback_;
3572 size_t num_textures_after_loss_;
3573 FakeContentLayerClient client_;
3574 scoped_refptr<FakeContentLayer> root_;
3575 scoped_refptr<FakeContentLayer> copy_layer_;
3576 scoped_ptr<CopyOutputResult> result_;
3579 // No output to copy for delegated renderers.
3580 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3581 LayerTreeHostTestAsyncReadbackLostOutputSurface);
3583 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
3585 virtual void BeginTest() OVERRIDE {
3587 PostSetNeedsCommitToMainThread();
3590 // Round 1: commit + draw
3591 // Round 2: commit only (no draw/swap)
3592 // Round 3: draw only (no commit)
3593 // Round 4: composite & readback (2 commits, no draw/swap)
3594 // Round 5: commit + draw
3596 virtual void DidCommit() OVERRIDE {
3597 int commit = layer_tree_host()->source_frame_number();
3601 EXPECT_EQ(1, frame_);
3602 layer_tree_host()->SetNeedsRedraw();
3605 // CompositeAndReadback in Round 4, first commit.
3606 EXPECT_EQ(2, frame_);
3610 EXPECT_EQ(2, frame_);
3611 layer_tree_host()->SetNeedsCommit();
3612 layer_tree_host()->SetNeedsRedraw();
3617 virtual void DidCompleteSwapBuffers() OVERRIDE {
3618 int commit = layer_tree_host()->source_frame_number();
3620 char pixels[4] = {0};
3624 EXPECT_EQ(1, commit);
3625 layer_tree_host()->SetNeedsCommit();
3629 EXPECT_EQ(2, commit);
3630 layer_tree_host()->CompositeAndReadback(pixels, gfx::Rect(0, 0, 1, 1));
3634 EXPECT_EQ(5, commit);
3640 virtual void AfterTest() OVERRIDE {}
3646 TEST_F(LayerTreeHostTestNumFramesPending, DelegatingRenderer) {
3647 RunTest(true, true, true);
3650 TEST_F(LayerTreeHostTestNumFramesPending, GLRenderer) {
3651 RunTest(true, false, true);
3654 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
3656 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3657 // PictureLayer can only be used with impl side painting enabled.
3658 settings->impl_side_painting = true;
3661 virtual void SetupTree() OVERRIDE {
3662 layer_ = FakePictureLayer::Create(&client_);
3663 // Force commits to not be aborted so new frames get drawn, otherwise
3664 // the renderer gets deferred initialized but nothing new needs drawing.
3665 layer_->set_always_update_resources(true);
3666 layer_tree_host()->SetRootLayer(layer_);
3667 LayerTreeHostTest::SetupTree();
3670 virtual void BeginTest() OVERRIDE {
3671 did_initialize_gl_ = false;
3672 did_release_gl_ = false;
3673 last_source_frame_number_drawn_ = -1; // Never drawn.
3674 PostSetNeedsCommitToMainThread();
3677 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3679 scoped_ptr<TestWebGraphicsContext3D> context3d(
3680 TestWebGraphicsContext3D::Create());
3681 context3d->set_support_swapbuffers_complete_callback(false);
3683 return FakeOutputSurface::CreateDeferredGL(
3684 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice))
3685 .PassAs<OutputSurface>();
3688 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3689 ASSERT_TRUE(host_impl->RootLayer());
3690 FakePictureLayerImpl* layer_impl =
3691 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
3693 // The same frame can be draw multiple times if new visible tiles are
3694 // rasterized. But we want to make sure we only post DeferredInitialize
3695 // and ReleaseGL once, so early out if the same frame is drawn again.
3696 if (last_source_frame_number_drawn_ ==
3697 host_impl->active_tree()->source_frame_number())
3700 last_source_frame_number_drawn_ =
3701 host_impl->active_tree()->source_frame_number();
3703 if (!did_initialize_gl_) {
3704 EXPECT_LE(1u, layer_impl->append_quads_count());
3705 ImplThreadTaskRunner()->PostTask(
3708 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3709 base::Unretained(this),
3710 base::Unretained(host_impl)));
3711 } else if (did_initialize_gl_ && !did_release_gl_) {
3712 EXPECT_LE(2u, layer_impl->append_quads_count());
3713 ImplThreadTaskRunner()->PostTask(
3716 &LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3717 base::Unretained(this),
3718 base::Unretained(host_impl)));
3719 } else if (did_initialize_gl_ && did_release_gl_) {
3720 EXPECT_LE(3u, layer_impl->append_quads_count());
3725 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
3726 EXPECT_FALSE(did_initialize_gl_);
3727 // SetAndInitializeContext3D calls SetNeedsCommit.
3728 FakeOutputSurface* fake_output_surface =
3729 static_cast<FakeOutputSurface*>(host_impl->output_surface());
3730 scoped_refptr<TestContextProvider> context_provider =
3731 TestContextProvider::Create(); // Not bound to thread.
3732 EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d(
3733 context_provider, NULL));
3734 did_initialize_gl_ = true;
3737 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3738 EXPECT_TRUE(did_initialize_gl_);
3739 EXPECT_FALSE(did_release_gl_);
3740 // ReleaseGL calls SetNeedsCommit.
3741 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3742 did_release_gl_ = true;
3745 virtual void AfterTest() OVERRIDE {
3746 EXPECT_TRUE(did_initialize_gl_);
3747 EXPECT_TRUE(did_release_gl_);
3751 FakeContentLayerClient client_;
3752 scoped_refptr<FakePictureLayer> layer_;
3753 bool did_initialize_gl_;
3754 bool did_release_gl_;
3755 int last_source_frame_number_drawn_;
3758 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3760 // Test for UI Resource management.
3761 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3763 LayerTreeHostTestUIResource() : num_ui_resources_(0), num_commits_(0) {}
3765 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3766 settings->texture_id_allocation_chunk_size = 1;
3769 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3771 virtual void DidCommit() OVERRIDE {
3772 int frame = num_commits_;
3777 PostSetNeedsCommitToMainThread();
3780 // Usually ScopedUIResource are deleted from the manager in their
3781 // destructor. Here we just want to test that a direct call to
3782 // DeleteUIResource works.
3783 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3784 PostSetNeedsCommitToMainThread();
3787 // DeleteUIResource can be called with an invalid id.
3788 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3789 PostSetNeedsCommitToMainThread();
3794 PostSetNeedsCommitToMainThread();
3803 void PerformTest(LayerTreeHostImpl* impl) {
3804 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
3805 impl->output_surface()->context_provider()->Context3d());
3807 int frame = num_commits_;
3810 ASSERT_EQ(0u, context->NumTextures());
3813 // Created two textures.
3814 ASSERT_EQ(2u, context->NumTextures());
3817 // One texture left after one deletion.
3818 ASSERT_EQ(1u, context->NumTextures());
3821 // Resource manager state should not change when delete is called on an
3823 ASSERT_EQ(1u, context->NumTextures());
3826 // Creation after deletion: two more creates should total up to
3828 ASSERT_EQ(3u, context->NumTextures());
3833 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3835 if (!layer_tree_host()->settings().impl_side_painting)
3839 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3840 if (layer_tree_host()->settings().impl_side_painting)
3844 virtual void AfterTest() OVERRIDE {}
3847 // Must clear all resources before exiting.
3848 void ClearResources() {
3849 for (int i = 0; i < num_ui_resources_; i++)
3850 ui_resources_[i].reset();
3853 void CreateResource() {
3854 ui_resources_[num_ui_resources_++] =
3855 FakeScopedUIResource::Create(layer_tree_host());
3858 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3859 int num_ui_resources_;
3863 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3865 class PushPropertiesCountingLayer : public Layer {
3867 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3868 return new PushPropertiesCountingLayer();
3871 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
3872 Layer::PushPropertiesTo(layer);
3873 push_properties_count_++;
3874 if (persist_needs_push_properties_)
3875 needs_push_properties_ = true;
3878 size_t push_properties_count() const { return push_properties_count_; }
3879 void reset_push_properties_count() { push_properties_count_ = 0; }
3881 void set_persist_needs_push_properties(bool persist) {
3882 persist_needs_push_properties_ = persist;
3886 PushPropertiesCountingLayer()
3887 : push_properties_count_(0),
3888 persist_needs_push_properties_(false) {
3889 SetAnchorPoint(gfx::PointF());
3890 SetBounds(gfx::Size(1, 1));
3891 SetIsDrawable(true);
3893 virtual ~PushPropertiesCountingLayer() {}
3895 size_t push_properties_count_;
3896 bool persist_needs_push_properties_;
3899 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3901 virtual void BeginTest() OVERRIDE {
3903 expected_push_properties_root_ = 0;
3904 expected_push_properties_child_ = 0;
3905 expected_push_properties_grandchild_ = 0;
3906 expected_push_properties_child2_ = 0;
3907 expected_push_properties_other_root_ = 0;
3908 expected_push_properties_leaf_layer_ = 0;
3909 PostSetNeedsCommitToMainThread();
3912 virtual void SetupTree() OVERRIDE {
3913 root_ = PushPropertiesCountingLayer::Create();
3914 child_ = PushPropertiesCountingLayer::Create();
3915 child2_ = PushPropertiesCountingLayer::Create();
3916 grandchild_ = PushPropertiesCountingLayer::Create();
3917 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3918 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3920 root_->AddChild(child_);
3921 root_->AddChild(child2_);
3922 child_->AddChild(grandchild_);
3923 child2_->AddChild(leaf_always_pushing_layer_);
3925 other_root_ = PushPropertiesCountingLayer::Create();
3927 // Don't set the root layer here.
3928 LayerTreeHostTest::SetupTree();
3931 virtual void DidCommitAndDrawFrame() OVERRIDE {
3934 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3935 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3936 EXPECT_EQ(expected_push_properties_grandchild_,
3937 grandchild_->push_properties_count());
3938 EXPECT_EQ(expected_push_properties_child2_,
3939 child2_->push_properties_count());
3940 EXPECT_EQ(expected_push_properties_other_root_,
3941 other_root_->push_properties_count());
3942 EXPECT_EQ(expected_push_properties_leaf_layer_,
3943 leaf_always_pushing_layer_->push_properties_count());
3945 // The scrollbar layer always needs to be pushed.
3946 if (root_->layer_tree_host()) {
3947 EXPECT_TRUE(root_->descendant_needs_push_properties());
3948 EXPECT_FALSE(root_->needs_push_properties());
3950 if (child2_->layer_tree_host()) {
3951 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3952 EXPECT_FALSE(child2_->needs_push_properties());
3954 if (leaf_always_pushing_layer_->layer_tree_host()) {
3956 leaf_always_pushing_layer_->descendant_needs_push_properties());
3957 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3960 // child_ and grandchild_ don't persist their need to push properties.
3961 if (child_->layer_tree_host()) {
3962 EXPECT_FALSE(child_->descendant_needs_push_properties());
3963 EXPECT_FALSE(child_->needs_push_properties());
3965 if (grandchild_->layer_tree_host()) {
3966 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3967 EXPECT_FALSE(grandchild_->needs_push_properties());
3970 if (other_root_->layer_tree_host()) {
3971 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3972 EXPECT_FALSE(other_root_->needs_push_properties());
3975 switch (num_commits_) {
3977 layer_tree_host()->SetRootLayer(root_);
3978 // Layers added to the tree get committed.
3979 ++expected_push_properties_root_;
3980 ++expected_push_properties_child_;
3981 ++expected_push_properties_grandchild_;
3982 ++expected_push_properties_child2_;
3985 layer_tree_host()->SetNeedsCommit();
3986 // No layers need commit.
3989 layer_tree_host()->SetRootLayer(other_root_);
3990 // Layers added to the tree get committed.
3991 ++expected_push_properties_other_root_;
3994 layer_tree_host()->SetRootLayer(root_);
3995 // Layers added to the tree get committed.
3996 ++expected_push_properties_root_;
3997 ++expected_push_properties_child_;
3998 ++expected_push_properties_grandchild_;
3999 ++expected_push_properties_child2_;
4002 layer_tree_host()->SetNeedsCommit();
4003 // No layers need commit.
4006 child_->RemoveFromParent();
4007 // No layers need commit.
4010 root_->AddChild(child_);
4011 // Layers added to the tree get committed.
4012 ++expected_push_properties_child_;
4013 ++expected_push_properties_grandchild_;
4016 grandchild_->RemoveFromParent();
4017 // No layers need commit.
4020 child_->AddChild(grandchild_);
4021 // Layers added to the tree get committed.
4022 ++expected_push_properties_grandchild_;
4025 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
4026 // No layers need commit.
4029 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
4030 // No layers need commit.
4033 child_->SetPosition(gfx::Point(1, 1));
4034 // The modified layer needs commit
4035 ++expected_push_properties_child_;
4038 child2_->SetPosition(gfx::Point(1, 1));
4039 // The modified layer needs commit
4040 ++expected_push_properties_child2_;
4043 child_->RemoveFromParent();
4044 root_->AddChild(child_);
4045 // Layers added to the tree get committed.
4046 ++expected_push_properties_child_;
4047 ++expected_push_properties_grandchild_;
4050 grandchild_->SetPosition(gfx::Point(1, 1));
4051 // The modified layer needs commit
4052 ++expected_push_properties_grandchild_;
4055 // SetNeedsDisplay does not always set needs commit (so call it
4056 // explicitly), but is a property change.
4057 child_->SetNeedsDisplay();
4058 ++expected_push_properties_child_;
4059 layer_tree_host()->SetNeedsCommit();
4066 // The leaf layer always pushes.
4067 if (leaf_always_pushing_layer_->layer_tree_host())
4068 ++expected_push_properties_leaf_layer_;
4071 virtual void AfterTest() OVERRIDE {}
4074 FakeContentLayerClient client_;
4075 scoped_refptr<PushPropertiesCountingLayer> root_;
4076 scoped_refptr<PushPropertiesCountingLayer> child_;
4077 scoped_refptr<PushPropertiesCountingLayer> child2_;
4078 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
4079 scoped_refptr<PushPropertiesCountingLayer> other_root_;
4080 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
4081 size_t expected_push_properties_root_;
4082 size_t expected_push_properties_child_;
4083 size_t expected_push_properties_child2_;
4084 size_t expected_push_properties_grandchild_;
4085 size_t expected_push_properties_other_root_;
4086 size_t expected_push_properties_leaf_layer_;
4089 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
4091 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
4092 : public LayerTreeHostTest {
4094 virtual void BeginTest() OVERRIDE {
4095 PostSetNeedsCommitToMainThread();
4098 virtual void SetupTree() OVERRIDE {
4099 root_ = Layer::Create();
4100 root_->SetBounds(gfx::Size(1, 1));
4102 bool paint_scrollbar = true;
4103 bool has_thumb = false;
4104 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
4105 paint_scrollbar, has_thumb, root_->id());
4107 root_->AddChild(scrollbar_layer_);
4109 layer_tree_host()->SetRootLayer(root_);
4110 LayerTreeHostTest::SetupTree();
4113 virtual void DidCommitAndDrawFrame() OVERRIDE {
4114 switch (layer_tree_host()->source_frame_number()) {
4118 // During update, the ignore_set_needs_commit_ bit is set to true to
4119 // avoid causing a second commit to be scheduled. If a property change
4120 // is made during this, however, it needs to be pushed in the upcoming
4122 scoped_ptr<base::AutoReset<bool> > ignore =
4123 scrollbar_layer_->IgnoreSetNeedsCommit();
4125 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
4127 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
4128 EXPECT_TRUE(root_->descendant_needs_push_properties());
4129 layer_tree_host()->SetNeedsCommit();
4131 scrollbar_layer_->reset_push_properties_count();
4132 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
4136 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
4142 virtual void AfterTest() OVERRIDE {}
4144 scoped_refptr<Layer> root_;
4145 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
4148 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
4150 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
4151 : public LayerTreeHostTest {
4153 virtual void BeginTest() OVERRIDE {
4154 expected_push_properties_root_ = 0;
4155 expected_push_properties_child_ = 0;
4156 expected_push_properties_grandchild1_ = 0;
4157 expected_push_properties_grandchild2_ = 0;
4158 expected_push_properties_grandchild3_ = 0;
4159 PostSetNeedsCommitToMainThread();
4162 virtual void SetupTree() OVERRIDE {
4163 root_ = PushPropertiesCountingLayer::Create();
4164 child_ = PushPropertiesCountingLayer::Create();
4165 grandchild1_ = PushPropertiesCountingLayer::Create();
4166 grandchild2_ = PushPropertiesCountingLayer::Create();
4167 grandchild3_ = PushPropertiesCountingLayer::Create();
4169 root_->AddChild(child_);
4170 child_->AddChild(grandchild1_);
4171 child_->AddChild(grandchild2_);
4172 child_->AddChild(grandchild3_);
4174 // Don't set the root layer here.
4175 LayerTreeHostTest::SetupTree();
4178 virtual void AfterTest() OVERRIDE {}
4180 FakeContentLayerClient client_;
4181 scoped_refptr<PushPropertiesCountingLayer> root_;
4182 scoped_refptr<PushPropertiesCountingLayer> child_;
4183 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
4184 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
4185 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
4186 size_t expected_push_properties_root_;
4187 size_t expected_push_properties_child_;
4188 size_t expected_push_properties_grandchild1_;
4189 size_t expected_push_properties_grandchild2_;
4190 size_t expected_push_properties_grandchild3_;
4193 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
4194 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4196 virtual void DidCommitAndDrawFrame() OVERRIDE {
4197 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4198 switch (last_source_frame_number) {
4200 EXPECT_FALSE(root_->needs_push_properties());
4201 EXPECT_FALSE(root_->descendant_needs_push_properties());
4202 EXPECT_FALSE(child_->needs_push_properties());
4203 EXPECT_FALSE(child_->descendant_needs_push_properties());
4204 EXPECT_FALSE(grandchild1_->needs_push_properties());
4205 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4206 EXPECT_FALSE(grandchild2_->needs_push_properties());
4207 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4208 EXPECT_FALSE(grandchild3_->needs_push_properties());
4209 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4211 layer_tree_host()->SetRootLayer(root_);
4213 EXPECT_TRUE(root_->needs_push_properties());
4214 EXPECT_TRUE(root_->descendant_needs_push_properties());
4215 EXPECT_TRUE(child_->needs_push_properties());
4216 EXPECT_TRUE(child_->descendant_needs_push_properties());
4217 EXPECT_TRUE(grandchild1_->needs_push_properties());
4218 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4219 EXPECT_TRUE(grandchild2_->needs_push_properties());
4220 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4221 EXPECT_TRUE(grandchild3_->needs_push_properties());
4222 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4231 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
4233 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
4234 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4236 virtual void DidCommitAndDrawFrame() OVERRIDE {
4237 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4238 switch (last_source_frame_number) {
4240 layer_tree_host()->SetRootLayer(root_);
4243 EXPECT_FALSE(root_->needs_push_properties());
4244 EXPECT_FALSE(root_->descendant_needs_push_properties());
4245 EXPECT_FALSE(child_->needs_push_properties());
4246 EXPECT_FALSE(child_->descendant_needs_push_properties());
4247 EXPECT_FALSE(grandchild1_->needs_push_properties());
4248 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4249 EXPECT_FALSE(grandchild2_->needs_push_properties());
4250 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4251 EXPECT_FALSE(grandchild3_->needs_push_properties());
4252 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4254 grandchild1_->RemoveFromParent();
4255 grandchild1_->SetPosition(gfx::Point(1, 1));
4257 EXPECT_FALSE(root_->needs_push_properties());
4258 EXPECT_FALSE(root_->descendant_needs_push_properties());
4259 EXPECT_FALSE(child_->needs_push_properties());
4260 EXPECT_FALSE(child_->descendant_needs_push_properties());
4261 EXPECT_FALSE(grandchild2_->needs_push_properties());
4262 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4263 EXPECT_FALSE(grandchild3_->needs_push_properties());
4264 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4266 child_->AddChild(grandchild1_);
4268 EXPECT_FALSE(root_->needs_push_properties());
4269 EXPECT_TRUE(root_->descendant_needs_push_properties());
4270 EXPECT_FALSE(child_->needs_push_properties());
4271 EXPECT_TRUE(child_->descendant_needs_push_properties());
4272 EXPECT_TRUE(grandchild1_->needs_push_properties());
4273 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4274 EXPECT_FALSE(grandchild2_->needs_push_properties());
4275 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4276 EXPECT_FALSE(grandchild3_->needs_push_properties());
4277 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4279 grandchild2_->SetPosition(gfx::Point(1, 1));
4281 EXPECT_FALSE(root_->needs_push_properties());
4282 EXPECT_TRUE(root_->descendant_needs_push_properties());
4283 EXPECT_FALSE(child_->needs_push_properties());
4284 EXPECT_TRUE(child_->descendant_needs_push_properties());
4285 EXPECT_TRUE(grandchild1_->needs_push_properties());
4286 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4287 EXPECT_TRUE(grandchild2_->needs_push_properties());
4288 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4289 EXPECT_FALSE(grandchild3_->needs_push_properties());
4290 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4292 // grandchild2_ will still need a push properties.
4293 grandchild1_->RemoveFromParent();
4295 EXPECT_FALSE(root_->needs_push_properties());
4296 EXPECT_TRUE(root_->descendant_needs_push_properties());
4297 EXPECT_FALSE(child_->needs_push_properties());
4298 EXPECT_TRUE(child_->descendant_needs_push_properties());
4300 // grandchild3_ does not need a push properties, so recursing should
4301 // no longer be needed.
4302 grandchild2_->RemoveFromParent();
4304 EXPECT_FALSE(root_->needs_push_properties());
4305 EXPECT_FALSE(root_->descendant_needs_push_properties());
4306 EXPECT_FALSE(child_->needs_push_properties());
4307 EXPECT_FALSE(child_->descendant_needs_push_properties());
4314 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
4316 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
4317 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4319 virtual void DidCommitAndDrawFrame() OVERRIDE {
4320 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4321 switch (last_source_frame_number) {
4323 layer_tree_host()->SetRootLayer(root_);
4324 grandchild1_->set_persist_needs_push_properties(true);
4325 grandchild2_->set_persist_needs_push_properties(true);
4328 EXPECT_FALSE(root_->needs_push_properties());
4329 EXPECT_TRUE(root_->descendant_needs_push_properties());
4330 EXPECT_FALSE(child_->needs_push_properties());
4331 EXPECT_TRUE(child_->descendant_needs_push_properties());
4332 EXPECT_TRUE(grandchild1_->needs_push_properties());
4333 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4334 EXPECT_TRUE(grandchild2_->needs_push_properties());
4335 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4336 EXPECT_FALSE(grandchild3_->needs_push_properties());
4337 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4339 // grandchild2_ will still need a push properties.
4340 grandchild1_->RemoveFromParent();
4342 EXPECT_FALSE(root_->needs_push_properties());
4343 EXPECT_TRUE(root_->descendant_needs_push_properties());
4344 EXPECT_FALSE(child_->needs_push_properties());
4345 EXPECT_TRUE(child_->descendant_needs_push_properties());
4347 // grandchild3_ does not need a push properties, so recursing should
4348 // no longer be needed.
4349 grandchild2_->RemoveFromParent();
4351 EXPECT_FALSE(root_->needs_push_properties());
4352 EXPECT_FALSE(root_->descendant_needs_push_properties());
4353 EXPECT_FALSE(child_->needs_push_properties());
4354 EXPECT_FALSE(child_->descendant_needs_push_properties());
4361 MULTI_THREAD_TEST_F(
4362 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
4364 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
4365 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4367 virtual void DidCommitAndDrawFrame() OVERRIDE {
4368 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4369 switch (last_source_frame_number) {
4371 layer_tree_host()->SetRootLayer(root_);
4374 EXPECT_FALSE(root_->needs_push_properties());
4375 EXPECT_FALSE(root_->descendant_needs_push_properties());
4376 EXPECT_FALSE(child_->needs_push_properties());
4377 EXPECT_FALSE(child_->descendant_needs_push_properties());
4378 EXPECT_FALSE(grandchild1_->needs_push_properties());
4379 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4380 EXPECT_FALSE(grandchild2_->needs_push_properties());
4381 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4382 EXPECT_FALSE(grandchild3_->needs_push_properties());
4383 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4385 // Change grandchildren while their parent is not in the tree.
4386 child_->RemoveFromParent();
4387 grandchild1_->SetPosition(gfx::Point(1, 1));
4388 grandchild2_->SetPosition(gfx::Point(1, 1));
4389 root_->AddChild(child_);
4391 EXPECT_FALSE(root_->needs_push_properties());
4392 EXPECT_TRUE(root_->descendant_needs_push_properties());
4393 EXPECT_TRUE(child_->needs_push_properties());
4394 EXPECT_TRUE(child_->descendant_needs_push_properties());
4395 EXPECT_TRUE(grandchild1_->needs_push_properties());
4396 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4397 EXPECT_TRUE(grandchild2_->needs_push_properties());
4398 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4399 EXPECT_TRUE(grandchild3_->needs_push_properties());
4400 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4402 grandchild1_->RemoveFromParent();
4404 EXPECT_FALSE(root_->needs_push_properties());
4405 EXPECT_TRUE(root_->descendant_needs_push_properties());
4406 EXPECT_TRUE(child_->needs_push_properties());
4407 EXPECT_TRUE(child_->descendant_needs_push_properties());
4409 grandchild2_->RemoveFromParent();
4411 EXPECT_FALSE(root_->needs_push_properties());
4412 EXPECT_TRUE(root_->descendant_needs_push_properties());
4413 EXPECT_TRUE(child_->needs_push_properties());
4414 EXPECT_TRUE(child_->descendant_needs_push_properties());
4416 grandchild3_->RemoveFromParent();
4418 EXPECT_FALSE(root_->needs_push_properties());
4419 EXPECT_TRUE(root_->descendant_needs_push_properties());
4420 EXPECT_TRUE(child_->needs_push_properties());
4421 EXPECT_FALSE(child_->descendant_needs_push_properties());
4429 MULTI_THREAD_TEST_F(
4430 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4432 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4433 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4435 virtual void DidCommitAndDrawFrame() OVERRIDE {
4436 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4437 switch (last_source_frame_number) {
4439 layer_tree_host()->SetRootLayer(root_);
4442 EXPECT_FALSE(root_->needs_push_properties());
4443 EXPECT_FALSE(root_->descendant_needs_push_properties());
4444 EXPECT_FALSE(child_->needs_push_properties());
4445 EXPECT_FALSE(child_->descendant_needs_push_properties());
4446 EXPECT_FALSE(grandchild1_->needs_push_properties());
4447 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4448 EXPECT_FALSE(grandchild2_->needs_push_properties());
4449 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4450 EXPECT_FALSE(grandchild3_->needs_push_properties());
4451 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4453 child_->SetPosition(gfx::Point(1, 1));
4454 grandchild1_->SetPosition(gfx::Point(1, 1));
4455 grandchild2_->SetPosition(gfx::Point(1, 1));
4457 EXPECT_FALSE(root_->needs_push_properties());
4458 EXPECT_TRUE(root_->descendant_needs_push_properties());
4459 EXPECT_TRUE(child_->needs_push_properties());
4460 EXPECT_TRUE(child_->descendant_needs_push_properties());
4461 EXPECT_TRUE(grandchild1_->needs_push_properties());
4462 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4463 EXPECT_TRUE(grandchild2_->needs_push_properties());
4464 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4465 EXPECT_FALSE(grandchild3_->needs_push_properties());
4466 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4468 grandchild1_->RemoveFromParent();
4470 EXPECT_FALSE(root_->needs_push_properties());
4471 EXPECT_TRUE(root_->descendant_needs_push_properties());
4472 EXPECT_TRUE(child_->needs_push_properties());
4473 EXPECT_TRUE(child_->descendant_needs_push_properties());
4475 grandchild2_->RemoveFromParent();
4477 EXPECT_FALSE(root_->needs_push_properties());
4478 EXPECT_TRUE(root_->descendant_needs_push_properties());
4479 EXPECT_TRUE(child_->needs_push_properties());
4480 EXPECT_FALSE(child_->descendant_needs_push_properties());
4482 child_->RemoveFromParent();
4484 EXPECT_FALSE(root_->needs_push_properties());
4485 EXPECT_FALSE(root_->descendant_needs_push_properties());
4493 MULTI_THREAD_TEST_F(
4494 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4496 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4497 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4499 virtual void DidCommitAndDrawFrame() OVERRIDE {
4500 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4501 switch (last_source_frame_number) {
4503 layer_tree_host()->SetRootLayer(root_);
4506 EXPECT_FALSE(root_->needs_push_properties());
4507 EXPECT_FALSE(root_->descendant_needs_push_properties());
4508 EXPECT_FALSE(child_->needs_push_properties());
4509 EXPECT_FALSE(child_->descendant_needs_push_properties());
4510 EXPECT_FALSE(grandchild1_->needs_push_properties());
4511 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4512 EXPECT_FALSE(grandchild2_->needs_push_properties());
4513 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4514 EXPECT_FALSE(grandchild3_->needs_push_properties());
4515 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4517 grandchild1_->SetPosition(gfx::Point(1, 1));
4518 grandchild2_->SetPosition(gfx::Point(1, 1));
4519 child_->SetPosition(gfx::Point(1, 1));
4521 EXPECT_FALSE(root_->needs_push_properties());
4522 EXPECT_TRUE(root_->descendant_needs_push_properties());
4523 EXPECT_TRUE(child_->needs_push_properties());
4524 EXPECT_TRUE(child_->descendant_needs_push_properties());
4525 EXPECT_TRUE(grandchild1_->needs_push_properties());
4526 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4527 EXPECT_TRUE(grandchild2_->needs_push_properties());
4528 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4529 EXPECT_FALSE(grandchild3_->needs_push_properties());
4530 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4532 grandchild1_->RemoveFromParent();
4534 EXPECT_FALSE(root_->needs_push_properties());
4535 EXPECT_TRUE(root_->descendant_needs_push_properties());
4536 EXPECT_TRUE(child_->needs_push_properties());
4537 EXPECT_TRUE(child_->descendant_needs_push_properties());
4539 grandchild2_->RemoveFromParent();
4541 EXPECT_FALSE(root_->needs_push_properties());
4542 EXPECT_TRUE(root_->descendant_needs_push_properties());
4543 EXPECT_TRUE(child_->needs_push_properties());
4544 EXPECT_FALSE(child_->descendant_needs_push_properties());
4546 child_->RemoveFromParent();
4548 EXPECT_FALSE(root_->needs_push_properties());
4549 EXPECT_FALSE(root_->descendant_needs_push_properties());
4557 MULTI_THREAD_TEST_F(
4558 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4560 // This test verifies that the tree activation callback is invoked correctly.
4561 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4563 LayerTreeHostTestTreeActivationCallback()
4564 : num_commits_(0), callback_count_(0) {}
4566 virtual void BeginTest() OVERRIDE {
4567 EXPECT_TRUE(HasImplThread());
4568 PostSetNeedsCommitToMainThread();
4571 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4572 LayerTreeHostImpl::FrameData* frame_data,
4573 bool result) OVERRIDE {
4575 switch (num_commits_) {
4577 EXPECT_EQ(0, callback_count_);
4578 callback_count_ = 0;
4580 PostSetNeedsCommitToMainThread();
4583 EXPECT_EQ(1, callback_count_);
4584 callback_count_ = 0;
4586 PostSetNeedsCommitToMainThread();
4589 EXPECT_EQ(0, callback_count_);
4590 callback_count_ = 0;
4594 ADD_FAILURE() << num_commits_;
4598 return LayerTreeHostTest::PrepareToDrawOnThread(host_impl, frame_data,
4602 virtual void AfterTest() OVERRIDE {
4603 EXPECT_EQ(3, num_commits_);
4606 void SetCallback(bool enable) {
4607 output_surface()->SetTreeActivationCallback(enable ?
4608 base::Bind(&LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4609 base::Unretained(this)) :
4613 void ActivationCallback() {
4618 int callback_count_;
4621 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4622 RunTest(true, false, true);
4625 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4626 RunTest(true, true, true);
4629 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4631 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4633 virtual void BeginTest() OVERRIDE {
4634 ASSERT_TRUE(!!invalidate_layer_)
4635 << "Derived tests must set this in SetupTree";
4637 // One initial commit.
4638 PostSetNeedsCommitToMainThread();
4641 virtual void DidCommitAndDrawFrame() OVERRIDE {
4642 // After commit, invalidate the layer. This should cause a commit.
4643 if (layer_tree_host()->source_frame_number() == 1)
4644 invalidate_layer_->SetNeedsDisplay();
4647 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4649 if (impl->active_tree()->source_frame_number() == 1)
4653 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4657 virtual void AfterTest() OVERRIDE {
4658 EXPECT_GE(2, num_commits_);
4659 EXPECT_GE(2, num_draws_);
4663 scoped_refptr<Layer> invalidate_layer_;
4670 // VideoLayer must support being invalidated and then passing that along
4671 // to the compositor thread, even though no resources are updated in
4672 // response to that invalidation.
4673 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4675 virtual void SetupTree() OVERRIDE {
4676 LayerTreeHostTest::SetupTree();
4677 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
4678 video_layer->SetBounds(gfx::Size(10, 10));
4679 video_layer->SetIsDrawable(true);
4680 layer_tree_host()->root_layer()->AddChild(video_layer);
4682 invalidate_layer_ = video_layer;
4686 FakeVideoFrameProvider provider_;
4689 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4691 // IOSurfaceLayer must support being invalidated and then passing that along
4692 // to the compositor thread, even though no resources are updated in
4693 // response to that invalidation.
4694 class LayerTreeHostTestIOSurfaceLayerInvalidate
4695 : public LayerInvalidateCausesDraw {
4697 virtual void SetupTree() OVERRIDE {
4698 LayerTreeHostTest::SetupTree();
4699 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4700 layer->SetBounds(gfx::Size(10, 10));
4701 uint32_t fake_io_surface_id = 7;
4702 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4703 layer->SetIsDrawable(true);
4704 layer_tree_host()->root_layer()->AddChild(layer);
4706 invalidate_layer_ = layer;
4710 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4711 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4712 LayerTreeHostTestIOSurfaceLayerInvalidate);
4714 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4716 virtual void SetupTree() OVERRIDE {
4717 root_layer_ = Layer::Create();
4718 root_layer_->SetAnchorPoint(gfx::PointF());
4719 root_layer_->SetPosition(gfx::Point());
4720 root_layer_->SetBounds(gfx::Size(10, 10));
4722 parent_layer_ = SolidColorLayer::Create();
4723 parent_layer_->SetAnchorPoint(gfx::PointF());
4724 parent_layer_->SetPosition(gfx::Point());
4725 parent_layer_->SetBounds(gfx::Size(10, 10));
4726 parent_layer_->SetIsDrawable(true);
4727 root_layer_->AddChild(parent_layer_);
4729 child_layer_ = SolidColorLayer::Create();
4730 child_layer_->SetAnchorPoint(gfx::PointF());
4731 child_layer_->SetPosition(gfx::Point());
4732 child_layer_->SetBounds(gfx::Size(10, 10));
4733 child_layer_->SetIsDrawable(true);
4734 parent_layer_->AddChild(child_layer_);
4736 layer_tree_host()->SetRootLayer(root_layer_);
4737 LayerTreeHostTest::SetupTree();
4740 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4742 virtual void DidCommitAndDrawFrame() OVERRIDE {
4743 switch (layer_tree_host()->source_frame_number()) {
4745 // The layer type used does not need to push properties every frame.
4746 EXPECT_FALSE(child_layer_->needs_push_properties());
4748 // Change the bounds of the child layer, but make it skipped
4749 // by CalculateDrawProperties.
4750 parent_layer_->SetOpacity(0.f);
4751 child_layer_->SetBounds(gfx::Size(5, 5));
4754 // The bounds of the child layer were pushed to the impl side.
4755 EXPECT_FALSE(child_layer_->needs_push_properties());
4762 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4763 LayerImpl* root = impl->active_tree()->root_layer();
4764 LayerImpl* parent = root->children()[0];
4765 LayerImpl* child = parent->children()[0];
4767 switch (impl->active_tree()->source_frame_number()) {
4769 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4774 virtual void AfterTest() OVERRIDE {}
4776 scoped_refptr<Layer> root_layer_;
4777 scoped_refptr<SolidColorLayer> parent_layer_;
4778 scoped_refptr<SolidColorLayer> child_layer_;
4781 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4783 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4785 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4786 settings->impl_side_painting = true;
4789 virtual void SetupTree() OVERRIDE {
4790 root_layer_ = FakePictureLayer::Create(&client_);
4791 root_layer_->SetAnchorPoint(gfx::PointF());
4792 root_layer_->SetBounds(gfx::Size(10, 10));
4794 layer_tree_host()->SetRootLayer(root_layer_);
4795 LayerTreeHostTest::SetupTree();
4798 virtual void BeginTest() OVERRIDE {
4799 // The viewport is empty, but we still need to update layers on the main
4801 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4802 PostSetNeedsCommitToMainThread();
4805 virtual void DidCommit() OVERRIDE {
4806 // The layer should be updated even though the viewport is empty, so we
4807 // are capable of drawing it on the impl tree.
4808 EXPECT_GT(root_layer_->update_count(), 0u);
4812 virtual void AfterTest() OVERRIDE {}
4814 FakeContentLayerClient client_;
4815 scoped_refptr<FakePictureLayer> root_layer_;
4818 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4820 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4822 LayerTreeHostTestAbortEvictedTextures()
4823 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4826 virtual void SetupTree() OVERRIDE {
4827 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4828 root_layer->SetBounds(gfx::Size(200, 200));
4829 root_layer->SetIsDrawable(true);
4831 layer_tree_host()->SetRootLayer(root_layer);
4832 LayerTreeHostTest::SetupTree();
4835 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4837 virtual void WillBeginMainFrame() OVERRIDE {
4838 num_will_begin_main_frames_++;
4839 switch (num_will_begin_main_frames_) {
4841 // Send a redraw to the compositor thread. This will (wrongly) be
4842 // ignored unless aborting resets the texture state.
4843 layer_tree_host()->SetNeedsRedraw();
4848 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4849 num_impl_commits_++;
4852 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4853 switch (impl->SourceAnimationFrameNumber()) {
4855 // Prevent draws until commit.
4856 impl->active_tree()->SetContentsTexturesPurged();
4857 EXPECT_FALSE(impl->CanDraw());
4858 // Trigger an abortable commit.
4859 impl->SetNeedsCommit();
4867 virtual void AfterTest() OVERRIDE {
4868 // Ensure that the commit was truly aborted.
4869 EXPECT_EQ(2, num_will_begin_main_frames_);
4870 EXPECT_EQ(1, num_impl_commits_);
4874 int num_will_begin_main_frames_;
4875 int num_impl_commits_;
4878 // Commits can only be aborted when using the thread proxy.
4879 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4881 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4883 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4884 settings->impl_side_painting = true;
4887 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
4889 scoped_refptr<TestContextProvider> context_provider =
4890 TestContextProvider::Create();
4891 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
4892 return FakeOutputSurface::Create3d(context_provider)
4893 .PassAs<OutputSurface>();
4896 virtual void SetupTree() OVERRIDE {
4897 scoped_refptr<FakePictureLayer> root_layer =
4898 FakePictureLayer::Create(&client_);
4899 root_layer->SetBounds(gfx::Size(6000, 6000));
4900 root_layer->SetIsDrawable(true);
4902 layer_tree_host()->SetRootLayer(root_layer);
4903 LayerTreeHostTest::SetupTree();
4906 virtual void BeginTest() OVERRIDE {
4907 PostSetNeedsCommitToMainThread();
4910 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4911 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
4912 impl->output_surface()->context_provider()->Context3d());
4914 // Expect that the transfer buffer memory used is equal to the
4915 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4916 EXPECT_EQ(1024 * 1024u,
4917 context->GetTransferBufferMemoryUsedBytes());
4921 virtual void AfterTest() OVERRIDE {}
4924 FakeContentLayerClient client_;
4927 // Impl-side painting is a multi-threaded compositor feature.
4928 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4930 // Test ensuring that memory limits are sent to the prioritized resource
4932 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4934 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4936 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4938 virtual void DidCommit() OVERRIDE {
4939 int frame = num_commits_;
4942 // Verify default values.
4944 PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4945 layer_tree_host()->contents_texture_manager()->
4946 MaxMemoryLimitBytes());
4948 PriorityCalculator::AllowEverythingCutoff(),
4949 layer_tree_host()->contents_texture_manager()->
4950 ExternalPriorityCutoff());
4951 PostSetNeedsCommitToMainThread();
4954 // The values should remain the same until the commit after the policy
4957 PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4958 layer_tree_host()->contents_texture_manager()->
4959 MaxMemoryLimitBytes());
4961 PriorityCalculator::AllowEverythingCutoff(),
4962 layer_tree_host()->contents_texture_manager()->
4963 ExternalPriorityCutoff());
4966 // Verify values were correctly passed.
4969 layer_tree_host()->contents_texture_manager()->
4970 MaxMemoryLimitBytes());
4972 PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4973 layer_tree_host()->contents_texture_manager()->
4974 ExternalPriorityCutoff());
4978 // Make sure no extra commits happen.
4986 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4987 int frame = num_commits_;
4992 // This will trigger a commit because the priority cutoff has changed.
4993 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4995 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4999 // This will not trigger a commit because the priority cutoff has not
5000 // changed, and there is already enough memory for all allocations.
5001 impl->SetMemoryPolicy(ManagedMemoryPolicy(
5003 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
5012 virtual void AfterTest() OVERRIDE {}
5018 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
5020 class LayerSetsNeedsFilterContext : public Layer {
5022 static scoped_refptr<LayerSetsNeedsFilterContext> Create() {
5023 return make_scoped_refptr(new LayerSetsNeedsFilterContext());
5026 virtual bool Update(ResourceUpdateQueue* queue,
5027 const OcclusionTracker* occlusion) OVERRIDE {
5028 bool updated = Layer::Update(queue, occlusion);
5029 if (needs_context_) {
5030 layer_tree_host()->set_needs_filter_context();
5036 void set_needs_context(bool need) { needs_context_ = need; }
5039 LayerSetsNeedsFilterContext() : needs_context_(false) {}
5040 virtual ~LayerSetsNeedsFilterContext() {}
5042 bool needs_context_;
5045 class LayerTreeHostTestOffscreenContext : public LayerTreeHostTest {
5047 virtual void SetupTree() OVERRIDE {
5048 scoped_refptr<LayerSetsNeedsFilterContext> root =
5049 LayerSetsNeedsFilterContext::Create();
5050 root->SetIsDrawable(true);
5051 root->SetAnchorPoint(gfx::PointF());
5052 root->SetBounds(gfx::Size(10, 10));
5053 root->set_needs_context(with_context_);
5054 layer_tree_host()->SetRootLayer(root);
5055 LayerTreeHostTest::SetupTree();
5058 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
5060 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
5061 bool expect_context = with_context_;
5062 if (delegating_renderer())
5063 expect_context = false;
5064 EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
5068 virtual void AfterTest() OVERRIDE {}
5073 class LayerTreeHostTestOffscreenContext_NoContext
5074 : public LayerTreeHostTestOffscreenContext {
5076 LayerTreeHostTestOffscreenContext_NoContext() { with_context_ = false; }
5079 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_NoContext);
5081 class LayerTreeHostTestOffscreenContext_WithContext
5082 : public LayerTreeHostTestOffscreenContext {
5084 LayerTreeHostTestOffscreenContext_WithContext() { with_context_ = true; }
5087 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_WithContext);
5089 class LayerTreeHostTestNoQuadsForEmptyLayer : public LayerTreeHostTest {
5091 virtual void SetupTree() OVERRIDE {
5092 LayerTreeHostTest::SetupTree();
5093 root_layer_ = FakeContentLayer::Create(&client_);
5094 root_layer_->SetBounds(gfx::Size(10, 10));
5095 root_layer_->SetIsDrawable(false);
5096 root_layer_->SetHaveWheelEventHandlers(true);
5097 layer_tree_host()->SetRootLayer(root_layer_);
5098 LayerTreeHostTest::SetupTree();
5101 virtual void BeginTest() OVERRIDE {
5102 PostSetNeedsCommitToMainThread();
5105 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
5106 FakeContentLayerImpl* layer_impl =
5107 static_cast<FakeContentLayerImpl*>(impl->RootLayer());
5108 EXPECT_FALSE(layer_impl->DrawsContent());
5109 EXPECT_EQ(0u, layer_impl->append_quads_count());
5112 virtual void DidCommit() OVERRIDE {
5113 // The layer is not drawable, so it should not be updated.
5114 EXPECT_EQ(0u, root_layer_->update_count());
5117 virtual void AfterTest() OVERRIDE {}
5120 FakeContentLayerClient client_;
5121 scoped_refptr<FakeContentLayer> root_layer_;
5124 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoQuadsForEmptyLayer);
5129 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
5130 : public LayerTreeHostTest {
5132 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
5133 : first_output_surface_memory_limit_(4321234),
5134 second_output_surface_memory_limit_(1234321) {}
5136 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
5138 if (!first_context_provider_) {
5139 first_context_provider_ = TestContextProvider::Create();
5141 EXPECT_FALSE(second_context_provider_);
5142 second_context_provider_ = TestContextProvider::Create();
5145 scoped_ptr<FakeOutputSurface> output_surface(
5146 FakeOutputSurface::Create3d(
5147 second_context_provider_ ?
5148 second_context_provider_ :
5149 first_context_provider_));
5150 output_surface->SetMemoryPolicyToSetAtBind(make_scoped_ptr(
5151 new ManagedMemoryPolicy(
5152 second_context_provider_ ?
5153 second_output_surface_memory_limit_ :
5154 first_output_surface_memory_limit_,
5155 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
5156 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
5157 return output_surface.PassAs<OutputSurface>();
5160 virtual void SetupTree() OVERRIDE {
5161 root_ = FakeContentLayer::Create(&client_);
5162 root_->SetBounds(gfx::Size(20, 20));
5163 layer_tree_host()->SetRootLayer(root_);
5164 LayerTreeHostTest::SetupTree();
5167 virtual void BeginTest() OVERRIDE {
5168 PostSetNeedsCommitToMainThread();
5171 virtual void DidCommitAndDrawFrame() OVERRIDE {
5172 // Lost context sometimes takes two frames to recreate. The third frame
5173 // is sometimes aborted, so wait until the fourth frame to verify that
5174 // the memory has been set, and the fifth frame to end the test.
5175 if (layer_tree_host()->source_frame_number() < 5) {
5176 layer_tree_host()->SetNeedsCommit();
5177 } else if (layer_tree_host()->source_frame_number() == 5) {
5182 virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result)
5184 switch (impl->active_tree()->source_frame_number()) {
5186 EXPECT_EQ(first_output_surface_memory_limit_,
5187 impl->memory_allocation_limit_bytes());
5188 // Lose the output surface.
5189 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
5190 GL_GUILTY_CONTEXT_RESET_ARB,
5191 GL_INNOCENT_CONTEXT_RESET_ARB);
5194 EXPECT_EQ(second_output_surface_memory_limit_,
5195 impl->memory_allocation_limit_bytes());
5200 virtual void AfterTest() OVERRIDE {}
5202 scoped_refptr<TestContextProvider> first_context_provider_;
5203 scoped_refptr<TestContextProvider> second_context_provider_;
5204 size_t first_output_surface_memory_limit_;
5205 size_t second_output_surface_memory_limit_;
5206 FakeContentLayerClient client_;
5207 scoped_refptr<FakeContentLayer> root_;
5210 // No output to copy for delegated renderers.
5211 SINGLE_AND_MULTI_THREAD_TEST_F(
5212 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);