Lots of random cleanups, mostly for native_theme_win.cc:
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob01aae1488bd948e1a41cd4e58729bd7b9b1d12a4
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include <algorithm>
9 #include "base/auto_reset.h"
10 #include "base/synchronization/lock.h"
11 #include "cc/animation/timing_function.h"
12 #include "cc/base/swap_promise.h"
13 #include "cc/debug/frame_rate_counter.h"
14 #include "cc/layers/content_layer.h"
15 #include "cc/layers/content_layer_client.h"
16 #include "cc/layers/io_surface_layer.h"
17 #include "cc/layers/layer_impl.h"
18 #include "cc/layers/painted_scrollbar_layer.h"
19 #include "cc/layers/picture_layer.h"
20 #include "cc/layers/solid_color_layer.h"
21 #include "cc/layers/video_layer.h"
22 #include "cc/output/begin_frame_args.h"
23 #include "cc/output/compositor_frame_ack.h"
24 #include "cc/output/copy_output_request.h"
25 #include "cc/output/copy_output_result.h"
26 #include "cc/output/output_surface.h"
27 #include "cc/quads/draw_quad.h"
28 #include "cc/quads/io_surface_draw_quad.h"
29 #include "cc/resources/prioritized_resource.h"
30 #include "cc/resources/prioritized_resource_manager.h"
31 #include "cc/resources/resource_update_queue.h"
32 #include "cc/test/fake_content_layer.h"
33 #include "cc/test/fake_content_layer_client.h"
34 #include "cc/test/fake_content_layer_impl.h"
35 #include "cc/test/fake_layer_tree_host_client.h"
36 #include "cc/test/fake_output_surface.h"
37 #include "cc/test/fake_painted_scrollbar_layer.h"
38 #include "cc/test/fake_picture_layer.h"
39 #include "cc/test/fake_picture_layer_impl.h"
40 #include "cc/test/fake_proxy.h"
41 #include "cc/test/fake_scoped_ui_resource.h"
42 #include "cc/test/fake_video_frame_provider.h"
43 #include "cc/test/geometry_test_utils.h"
44 #include "cc/test/layer_tree_test.h"
45 #include "cc/test/test_shared_bitmap_manager.h"
46 #include "cc/test/test_web_graphics_context_3d.h"
47 #include "cc/trees/layer_tree_host_impl.h"
48 #include "cc/trees/layer_tree_impl.h"
49 #include "cc/trees/single_thread_proxy.h"
50 #include "cc/trees/thread_proxy.h"
51 #include "gpu/GLES2/gl2extchromium.h"
52 #include "skia/ext/refptr.h"
53 #include "testing/gmock/include/gmock/gmock.h"
54 #include "third_party/khronos/GLES2/gl2.h"
55 #include "third_party/khronos/GLES2/gl2ext.h"
56 #include "third_party/skia/include/core/SkPicture.h"
57 #include "ui/gfx/frame_time.h"
58 #include "ui/gfx/point_conversions.h"
59 #include "ui/gfx/size_conversions.h"
60 #include "ui/gfx/vector2d_conversions.h"
62 using testing::_;
63 using testing::AnyNumber;
64 using testing::AtLeast;
65 using testing::Mock;
67 namespace cc {
68 namespace {
70 class LayerTreeHostTest : public LayerTreeTest {};
72 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
73 // draw with frame 0.
74 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
75 public:
76 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
78 virtual void BeginTest() OVERRIDE {
79 PostSetNeedsCommitToMainThread();
80 PostSetNeedsCommitToMainThread();
83 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
84 num_draws_++;
85 if (!impl->active_tree()->source_frame_number())
86 EndTest();
89 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
90 num_commits_++;
93 virtual void AfterTest() OVERRIDE {
94 EXPECT_GE(1, num_commits_);
95 EXPECT_GE(1, num_draws_);
98 private:
99 int num_commits_;
100 int num_draws_;
103 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
105 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
106 // first committed frame draws should lead to another commit.
107 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
108 public:
109 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
111 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
113 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
114 ++num_draws_;
117 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
118 ++num_commits_;
119 switch (num_commits_) {
120 case 1:
121 PostSetNeedsCommitToMainThread();
122 break;
123 case 2:
124 EndTest();
125 break;
126 default:
127 NOTREACHED();
131 virtual void AfterTest() OVERRIDE {
132 EXPECT_EQ(2, num_commits_);
133 EXPECT_LE(1, num_draws_);
136 private:
137 int num_commits_;
138 int num_draws_;
141 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
143 // Verify that we pass property values in PushPropertiesTo.
144 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
145 protected:
146 virtual void SetupTree() OVERRIDE {
147 scoped_refptr<Layer> root = Layer::Create();
148 root->SetBounds(gfx::Size(10, 10));
149 layer_tree_host()->SetRootLayer(root);
150 LayerTreeHostTest::SetupTree();
153 enum Properties {
154 STARTUP,
155 BOUNDS,
156 HIDE_LAYER_AND_SUBTREE,
157 DRAWS_CONTENT,
158 DONE,
161 virtual void BeginTest() OVERRIDE {
162 index_ = STARTUP;
163 PostSetNeedsCommitToMainThread();
166 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
167 VerifyAfterValues(impl->active_tree()->root_layer());
170 virtual void DidCommitAndDrawFrame() OVERRIDE {
171 SetBeforeValues(layer_tree_host()->root_layer());
172 VerifyBeforeValues(layer_tree_host()->root_layer());
174 ++index_;
175 if (index_ == DONE) {
176 EndTest();
177 return;
180 SetAfterValues(layer_tree_host()->root_layer());
183 virtual void AfterTest() OVERRIDE {}
185 void VerifyBeforeValues(Layer* layer) {
186 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
187 EXPECT_FALSE(layer->hide_layer_and_subtree());
188 EXPECT_FALSE(layer->DrawsContent());
191 void SetBeforeValues(Layer* layer) {
192 layer->SetBounds(gfx::Size(10, 10));
193 layer->SetHideLayerAndSubtree(false);
194 layer->SetIsDrawable(false);
197 void VerifyAfterValues(LayerImpl* layer) {
198 switch (static_cast<Properties>(index_)) {
199 case STARTUP:
200 case DONE:
201 break;
202 case BOUNDS:
203 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
204 break;
205 case HIDE_LAYER_AND_SUBTREE:
206 EXPECT_TRUE(layer->hide_layer_and_subtree());
207 break;
208 case DRAWS_CONTENT:
209 EXPECT_TRUE(layer->DrawsContent());
210 break;
214 void SetAfterValues(Layer* layer) {
215 switch (static_cast<Properties>(index_)) {
216 case STARTUP:
217 case DONE:
218 break;
219 case BOUNDS:
220 layer->SetBounds(gfx::Size(20, 20));
221 break;
222 case HIDE_LAYER_AND_SUBTREE:
223 layer->SetHideLayerAndSubtree(true);
224 break;
225 case DRAWS_CONTENT:
226 layer->SetIsDrawable(true);
227 break;
231 int index_;
234 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
236 // 1 setNeedsRedraw after the first commit has completed should lead to 1
237 // additional draw.
238 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
239 public:
240 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
242 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
244 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
245 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
246 if (!num_draws_) {
247 // Redraw again to verify that the second redraw doesn't commit.
248 PostSetNeedsRedrawToMainThread();
249 } else {
250 EndTest();
252 num_draws_++;
255 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
256 EXPECT_EQ(0, num_draws_);
257 num_commits_++;
260 virtual void AfterTest() OVERRIDE {
261 EXPECT_GE(2, num_draws_);
262 EXPECT_EQ(1, num_commits_);
265 private:
266 int num_commits_;
267 int num_draws_;
270 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
272 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
273 // must contain invalid_rect.
274 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
275 public:
276 LayerTreeHostTestSetNeedsRedrawRect()
277 : num_draws_(0),
278 bounds_(50, 50),
279 invalid_rect_(10, 10, 20, 20),
280 root_layer_(ContentLayer::Create(&client_)) {}
282 virtual void BeginTest() OVERRIDE {
283 root_layer_->SetIsDrawable(true);
284 root_layer_->SetBounds(bounds_);
285 layer_tree_host()->SetRootLayer(root_layer_);
286 layer_tree_host()->SetViewportSize(bounds_);
287 PostSetNeedsCommitToMainThread();
290 virtual DrawResult PrepareToDrawOnThread(
291 LayerTreeHostImpl* host_impl,
292 LayerTreeHostImpl::FrameData* frame_data,
293 DrawResult draw_result) OVERRIDE {
294 EXPECT_EQ(DRAW_SUCCESS, draw_result);
296 gfx::RectF root_damage_rect;
297 if (!frame_data->render_passes.empty())
298 root_damage_rect = frame_data->render_passes.back()->damage_rect;
300 if (!num_draws_) {
301 // If this is the first frame, expect full frame damage.
302 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
303 } else {
304 // Check that invalid_rect_ is indeed repainted.
305 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
308 return draw_result;
311 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
312 if (!num_draws_) {
313 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
314 } else {
315 EndTest();
317 num_draws_++;
320 virtual void AfterTest() OVERRIDE { EXPECT_EQ(2, num_draws_); }
322 private:
323 int 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 {
333 public:
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 { PostSetNeedsCommitToMainThread(); }
352 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
353 if (host_impl->active_tree()->source_frame_number() == 1)
354 EndTest();
357 virtual void DidCommit() OVERRIDE {
358 switch (layer_tree_host()->source_frame_number()) {
359 case 1:
360 // Changing the device scale factor causes a commit. It also changes
361 // the content bounds of |scaled_layer_|, which should not generate
362 // a second commit as a result.
363 layer_tree_host()->SetDeviceScaleFactor(4.f);
364 break;
365 default:
366 // No extra commits.
367 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
371 virtual void AfterTest() OVERRIDE {
372 EXPECT_EQ(gfx::Size(4, 4).ToString(),
373 scaled_layer_->content_bounds().ToString());
376 private:
377 FakeContentLayerClient client_;
378 scoped_refptr<Layer> root_layer_;
379 scoped_refptr<FakeContentLayer> scaled_layer_;
382 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
384 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
385 : public LayerTreeHostTest {
386 public:
387 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
388 settings->layer_transforms_should_scale_layer_contents = true;
391 virtual void SetupTree() OVERRIDE {
392 root_layer_ = Layer::Create();
393 root_layer_->SetBounds(gfx::Size(10, 20));
395 bool paint_scrollbar = true;
396 bool has_thumb = false;
397 scrollbar_ = FakePaintedScrollbarLayer::Create(
398 paint_scrollbar, has_thumb, root_layer_->id());
399 scrollbar_->SetPosition(gfx::Point(0, 10));
400 scrollbar_->SetBounds(gfx::Size(10, 10));
402 root_layer_->AddChild(scrollbar_);
404 layer_tree_host()->SetRootLayer(root_layer_);
405 LayerTreeHostTest::SetupTree();
408 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
410 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
411 if (host_impl->active_tree()->source_frame_number() == 1)
412 EndTest();
415 virtual void DidCommit() OVERRIDE {
416 switch (layer_tree_host()->source_frame_number()) {
417 case 1:
418 // Changing the device scale factor causes a commit. It also changes
419 // the content bounds of |scrollbar_|, which should not generate
420 // a second commit as a result.
421 layer_tree_host()->SetDeviceScaleFactor(4.f);
422 break;
423 default:
424 // No extra commits.
425 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
429 virtual void AfterTest() OVERRIDE {
430 EXPECT_EQ(gfx::Size(40, 40).ToString(),
431 scrollbar_->content_bounds().ToString());
434 private:
435 FakeContentLayerClient client_;
436 scoped_refptr<Layer> root_layer_;
437 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
440 SINGLE_AND_MULTI_THREAD_TEST_F(
441 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
443 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
444 public:
445 LayerTreeHostTestSetNextCommitForcesRedraw()
446 : num_draws_(0),
447 bounds_(50, 50),
448 invalid_rect_(10, 10, 20, 20),
449 root_layer_(ContentLayer::Create(&client_)) {}
451 virtual void BeginTest() OVERRIDE {
452 root_layer_->SetIsDrawable(true);
453 root_layer_->SetBounds(bounds_);
454 layer_tree_host()->SetRootLayer(root_layer_);
455 layer_tree_host()->SetViewportSize(bounds_);
456 PostSetNeedsCommitToMainThread();
459 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
460 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
461 host_impl->SetNeedsRedrawRect(invalid_rect_);
464 virtual DrawResult PrepareToDrawOnThread(
465 LayerTreeHostImpl* host_impl,
466 LayerTreeHostImpl::FrameData* frame_data,
467 DrawResult draw_result) OVERRIDE {
468 EXPECT_EQ(DRAW_SUCCESS, draw_result);
470 gfx::RectF root_damage_rect;
471 if (!frame_data->render_passes.empty())
472 root_damage_rect = frame_data->render_passes.back()->damage_rect;
474 switch (num_draws_) {
475 case 0:
476 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
477 break;
478 case 1:
479 case 2:
480 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
481 break;
482 case 3:
483 EXPECT_RECT_EQ(invalid_rect_, root_damage_rect);
484 break;
485 case 4:
486 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
487 break;
488 default:
489 NOTREACHED();
492 return draw_result;
495 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
496 switch (num_draws_) {
497 case 0:
498 case 1:
499 // Cycle through a couple of empty commits to ensure we're observing the
500 // right behavior
501 PostSetNeedsCommitToMainThread();
502 break;
503 case 2:
504 // Should force full frame damage on the next commit
505 PostSetNextCommitForcesRedrawToMainThread();
506 PostSetNeedsCommitToMainThread();
507 if (host_impl->settings().impl_side_painting)
508 host_impl->BlockNotifyReadyToActivateForTesting(true);
509 else
510 num_draws_++;
511 break;
512 case 3:
513 host_impl->BlockNotifyReadyToActivateForTesting(false);
514 break;
515 default:
516 EndTest();
517 break;
519 num_draws_++;
522 virtual void AfterTest() OVERRIDE { EXPECT_EQ(5, num_draws_); }
524 private:
525 int num_draws_;
526 const gfx::Size bounds_;
527 const gfx::Rect invalid_rect_;
528 FakeContentLayerClient client_;
529 scoped_refptr<ContentLayer> root_layer_;
532 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw);
534 // Tests that if a layer is not drawn because of some reason in the parent then
535 // its damage is preserved until the next time it is drawn.
536 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
537 public:
538 LayerTreeHostTestUndrawnLayersDamageLater()
539 : root_layer_(ContentLayer::Create(&client_)) {}
541 virtual void SetupTree() OVERRIDE {
542 root_layer_->SetIsDrawable(true);
543 root_layer_->SetBounds(gfx::Size(50, 50));
544 layer_tree_host()->SetRootLayer(root_layer_);
546 // The initially transparent layer has a larger child layer, which is
547 // not initially drawn because of the this (parent) layer.
548 parent_layer_ = FakeContentLayer::Create(&client_);
549 parent_layer_->SetBounds(gfx::Size(15, 15));
550 parent_layer_->SetOpacity(0.0f);
551 root_layer_->AddChild(parent_layer_);
553 child_layer_ = FakeContentLayer::Create(&client_);
554 child_layer_->SetBounds(gfx::Size(25, 25));
555 parent_layer_->AddChild(child_layer_);
557 LayerTreeHostTest::SetupTree();
560 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
562 virtual DrawResult PrepareToDrawOnThread(
563 LayerTreeHostImpl* host_impl,
564 LayerTreeHostImpl::FrameData* frame_data,
565 DrawResult draw_result) OVERRIDE {
566 EXPECT_EQ(DRAW_SUCCESS, draw_result);
568 gfx::RectF root_damage_rect;
569 if (!frame_data->render_passes.empty())
570 root_damage_rect = frame_data->render_passes.back()->damage_rect;
572 // The first time, the whole view needs be drawn.
573 // Afterwards, just the opacity of surface_layer1 is changed a few times,
574 // and each damage should be the bounding box of it and its child. If this
575 // was working improperly, the damage might not include its childs bounding
576 // box.
577 switch (host_impl->active_tree()->source_frame_number()) {
578 case 0:
579 EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
580 break;
581 case 1:
582 case 2:
583 case 3:
584 EXPECT_RECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
585 break;
586 default:
587 NOTREACHED();
590 return draw_result;
593 virtual void DidCommitAndDrawFrame() OVERRIDE {
594 switch (layer_tree_host()->source_frame_number()) {
595 case 1:
596 // Test not owning the surface.
597 parent_layer_->SetOpacity(1.0f);
598 break;
599 case 2:
600 parent_layer_->SetOpacity(0.0f);
601 break;
602 case 3:
603 // Test owning the surface.
604 parent_layer_->SetOpacity(0.5f);
605 parent_layer_->SetForceRenderSurface(true);
606 break;
607 case 4:
608 EndTest();
609 break;
610 default:
611 NOTREACHED();
615 virtual void AfterTest() OVERRIDE {}
617 private:
618 FakeContentLayerClient client_;
619 scoped_refptr<ContentLayer> root_layer_;
620 scoped_refptr<FakeContentLayer> parent_layer_;
621 scoped_refptr<FakeContentLayer> child_layer_;
624 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
626 // Tests that if a layer is not drawn because of some reason in the parent,
627 // causing its content bounds to not be computed, then when it is later drawn,
628 // its content bounds get pushed.
629 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
630 : public LayerTreeHostTest {
631 public:
632 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
633 : root_layer_(Layer::Create()) {}
635 virtual void SetupTree() OVERRIDE {
636 root_layer_->SetIsDrawable(true);
637 root_layer_->SetBounds(gfx::Size(20, 20));
638 layer_tree_host()->SetRootLayer(root_layer_);
640 parent_layer_ = Layer::Create();
641 parent_layer_->SetBounds(gfx::Size(20, 20));
642 parent_layer_->SetOpacity(0.0f);
643 root_layer_->AddChild(parent_layer_);
645 child_layer_ = Layer::Create();
646 child_layer_->SetBounds(gfx::Size(15, 15));
647 parent_layer_->AddChild(child_layer_);
649 LayerTreeHostTest::SetupTree();
652 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
654 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
655 LayerImpl* root = host_impl->active_tree()->root_layer();
656 LayerImpl* parent = root->children()[0];
657 LayerImpl* child = parent->children()[0];
659 switch (host_impl->active_tree()->source_frame_number()) {
660 case 0:
661 EXPECT_EQ(0.f, parent->opacity());
662 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
663 break;
664 case 1:
665 EXPECT_EQ(1.f, parent->opacity());
666 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
667 EndTest();
668 break;
669 default:
670 NOTREACHED();
674 virtual void DidCommit() OVERRIDE {
675 switch (layer_tree_host()->source_frame_number()) {
676 case 1:
677 parent_layer_->SetOpacity(1.0f);
678 break;
679 case 2:
680 break;
681 default:
682 NOTREACHED();
686 virtual void AfterTest() OVERRIDE {}
688 private:
689 scoped_refptr<Layer> root_layer_;
690 scoped_refptr<Layer> parent_layer_;
691 scoped_refptr<Layer> child_layer_;
694 SINGLE_AND_MULTI_THREAD_TEST_F(
695 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
697 class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
698 public:
699 LayerTreeHostTestAbortFrameWhenInvisible() {}
701 virtual void BeginTest() OVERRIDE {
702 // Request a commit (from the main thread), Which will trigger the commit
703 // flow from the impl side.
704 layer_tree_host()->SetNeedsCommit();
705 // Then mark ourselves as not visible before processing any more messages
706 // on the main thread.
707 layer_tree_host()->SetVisible(false);
708 // If we make it without kicking a frame, we pass!
709 EndTestAfterDelay(1);
712 virtual void Layout() OVERRIDE {
713 ASSERT_FALSE(true);
714 EndTest();
717 virtual void AfterTest() OVERRIDE {}
720 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
722 // This test verifies that properties on the layer tree host are commited
723 // to the impl side.
724 class LayerTreeHostTestCommit : public LayerTreeHostTest {
725 public:
726 LayerTreeHostTestCommit() {}
728 virtual void BeginTest() OVERRIDE {
729 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
730 layer_tree_host()->set_background_color(SK_ColorGRAY);
732 PostSetNeedsCommitToMainThread();
735 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
736 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
737 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
739 EndTest();
742 virtual void AfterTest() OVERRIDE {}
745 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
747 // This test verifies that LayerTreeHostImpl's current frame time gets
748 // updated in consecutive frames when it doesn't draw due to tree
749 // activation failure.
750 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
751 : public LayerTreeHostTest {
752 public:
753 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
754 : frame_count_with_pending_tree_(0) {}
756 virtual void BeginTest() OVERRIDE {
757 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
758 layer_tree_host()->set_background_color(SK_ColorGRAY);
760 PostSetNeedsCommitToMainThread();
763 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
764 EXPECT_EQ(frame_count_with_pending_tree_, 0);
765 impl->BlockNotifyReadyToActivateForTesting(true);
768 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
769 const BeginFrameArgs& args) OVERRIDE {
770 if (impl->pending_tree())
771 frame_count_with_pending_tree_++;
773 if (frame_count_with_pending_tree_ == 1) {
774 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
775 first_frame_time_ = impl->CurrentFrameTimeTicks();
776 } else if (frame_count_with_pending_tree_ == 2) {
777 impl->BlockNotifyReadyToActivateForTesting(false);
781 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
782 if (frame_count_with_pending_tree_ > 1) {
783 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
784 EXPECT_NE(first_frame_time_.ToInternalValue(),
785 impl->CurrentFrameTimeTicks().ToInternalValue());
786 EndTest();
787 return;
790 EXPECT_FALSE(impl->settings().impl_side_painting);
791 EndTest();
793 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
794 if (impl->settings().impl_side_painting)
795 EXPECT_NE(frame_count_with_pending_tree_, 1);
798 virtual void AfterTest() OVERRIDE {}
800 private:
801 int frame_count_with_pending_tree_;
802 base::TimeTicks first_frame_time_;
805 SINGLE_AND_MULTI_THREAD_TEST_F(
806 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
808 // This test verifies that LayerTreeHostImpl's current frame time gets
809 // updated in consecutive frames when it draws in each frame.
810 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
811 public:
812 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
814 virtual void BeginTest() OVERRIDE {
815 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
816 layer_tree_host()->set_background_color(SK_ColorGRAY);
818 PostSetNeedsCommitToMainThread();
821 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
822 frame_++;
823 if (frame_ == 1) {
824 first_frame_time_ = impl->CurrentFrameTimeTicks();
825 impl->SetNeedsRedraw();
827 // Since we might use a low-resolution clock on Windows, we need to
828 // make sure that the clock has incremented past first_frame_time_.
829 while (first_frame_time_ == gfx::FrameTime::Now()) {
832 return;
835 EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
836 EndTest();
839 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
840 // Ensure there isn't a commit between the two draws, to ensure that a
841 // commit isn't required for updating the current frame time. We can
842 // only check for this in the multi-threaded case, since in the single-
843 // threaded case there will always be a commit between consecutive draws.
844 if (HasImplThread())
845 EXPECT_EQ(0, frame_);
848 virtual void AfterTest() OVERRIDE {}
850 private:
851 int frame_;
852 base::TimeTicks first_frame_time_;
855 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
857 // Verifies that StartPageScaleAnimation events propagate correctly
858 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
859 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
860 public:
861 LayerTreeHostTestStartPageScaleAnimation() {}
863 virtual void SetupTree() OVERRIDE {
864 LayerTreeHostTest::SetupTree();
866 if (layer_tree_host()->settings().impl_side_painting) {
867 scoped_refptr<FakePictureLayer> layer =
868 FakePictureLayer::Create(&client_);
869 layer->set_always_update_resources(true);
870 scroll_layer_ = layer;
871 } else {
872 scroll_layer_ = FakeContentLayer::Create(&client_);
875 Layer* root_layer = layer_tree_host()->root_layer();
876 scroll_layer_->SetScrollClipLayerId(root_layer->id());
877 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
878 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
879 2 * root_layer->bounds().height()));
880 scroll_layer_->SetScrollOffset(gfx::Vector2d());
881 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
882 // This test requires the page_scale and inner viewport layers to be
883 // identified.
884 layer_tree_host()->RegisterViewportLayers(
885 root_layer, scroll_layer_.get(), NULL);
886 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
889 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
891 virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
892 float scale) OVERRIDE {
893 gfx::Vector2d offset = scroll_layer_->scroll_offset();
894 scroll_layer_->SetScrollOffset(offset + scroll_delta);
895 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
898 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
899 // We get one commit before the first draw, and the animation doesn't happen
900 // until the second draw.
901 switch (impl->active_tree()->source_frame_number()) {
902 case 0:
903 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
904 // We'll start an animation when we get back to the main thread.
905 break;
906 case 1:
907 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
908 break;
909 case 2:
910 EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
911 EndTest();
912 break;
913 default:
914 NOTREACHED();
918 virtual void DidCommitAndDrawFrame() OVERRIDE {
919 switch (layer_tree_host()->source_frame_number()) {
920 case 1:
921 layer_tree_host()->StartPageScaleAnimation(
922 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
923 break;
927 virtual void AfterTest() OVERRIDE {}
929 FakeContentLayerClient client_;
930 scoped_refptr<Layer> scroll_layer_;
933 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
935 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
936 public:
937 LayerTreeHostTestSetVisible() : num_draws_(0) {}
939 virtual void BeginTest() OVERRIDE {
940 PostSetNeedsCommitToMainThread();
941 PostSetVisibleToMainThread(false);
942 // This is suppressed while we're invisible.
943 PostSetNeedsRedrawToMainThread();
944 // Triggers the redraw.
945 PostSetVisibleToMainThread(true);
948 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
949 EXPECT_TRUE(impl->visible());
950 ++num_draws_;
951 EndTest();
954 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
956 private:
957 int num_draws_;
960 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
962 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
963 public:
964 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
966 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
968 virtual void PaintContents(
969 SkCanvas* canvas,
970 const gfx::Rect& clip,
971 gfx::RectF* opaque,
972 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
973 // Set layer opacity to 0.
974 if (test_layer_)
975 test_layer_->SetOpacity(0.f);
977 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
978 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
980 private:
981 Layer* test_layer_;
984 class ContentLayerWithUpdateTracking : public ContentLayer {
985 public:
986 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
987 ContentLayerClient* client) {
988 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
991 int PaintContentsCount() { return paint_contents_count_; }
992 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
994 virtual bool Update(ResourceUpdateQueue* queue,
995 const OcclusionTracker<Layer>* occlusion) OVERRIDE {
996 bool updated = ContentLayer::Update(queue, occlusion);
997 paint_contents_count_++;
998 return updated;
1001 private:
1002 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1003 : ContentLayer(client), paint_contents_count_(0) {
1004 SetBounds(gfx::Size(10, 10));
1005 SetIsDrawable(true);
1007 virtual ~ContentLayerWithUpdateTracking() {}
1009 int paint_contents_count_;
1012 // Layer opacity change during paint should not prevent compositor resources
1013 // from being updated during commit.
1014 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1015 public:
1016 LayerTreeHostTestOpacityChange()
1017 : test_opacity_change_delegate_(),
1018 update_check_layer_(ContentLayerWithUpdateTracking::Create(
1019 &test_opacity_change_delegate_)) {
1020 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
1023 virtual void BeginTest() OVERRIDE {
1024 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1025 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
1027 PostSetNeedsCommitToMainThread();
1030 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1031 EndTest();
1034 virtual void AfterTest() OVERRIDE {
1035 // Update() should have been called once.
1036 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
1039 private:
1040 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1041 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
1044 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1046 class NoScaleContentLayer : public ContentLayer {
1047 public:
1048 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
1049 return make_scoped_refptr(new NoScaleContentLayer(client));
1052 virtual void CalculateContentsScale(float ideal_contents_scale,
1053 float device_scale_factor,
1054 float page_scale_factor,
1055 float maximum_animation_contents_scale,
1056 bool animating_transform_to_screen,
1057 float* contents_scale_x,
1058 float* contents_scale_y,
1059 gfx::Size* contentBounds) OVERRIDE {
1060 // Skip over the ContentLayer's method to the base Layer class.
1061 Layer::CalculateContentsScale(ideal_contents_scale,
1062 device_scale_factor,
1063 page_scale_factor,
1064 maximum_animation_contents_scale,
1065 animating_transform_to_screen,
1066 contents_scale_x,
1067 contents_scale_y,
1068 contentBounds);
1071 private:
1072 explicit NoScaleContentLayer(ContentLayerClient* client)
1073 : ContentLayer(client) {}
1074 virtual ~NoScaleContentLayer() {}
1077 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1078 : public LayerTreeHostTest {
1079 public:
1080 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1081 : root_layer_(NoScaleContentLayer::Create(&client_)),
1082 child_layer_(ContentLayer::Create(&client_)) {}
1084 virtual void BeginTest() OVERRIDE {
1085 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1086 layer_tree_host()->SetDeviceScaleFactor(1.5);
1087 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1089 root_layer_->AddChild(child_layer_);
1091 root_layer_->SetIsDrawable(true);
1092 root_layer_->SetBounds(gfx::Size(30, 30));
1094 child_layer_->SetIsDrawable(true);
1095 child_layer_->SetPosition(gfx::Point(2, 2));
1096 child_layer_->SetBounds(gfx::Size(10, 10));
1098 layer_tree_host()->SetRootLayer(root_layer_);
1100 PostSetNeedsCommitToMainThread();
1103 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1104 // Should only do one commit.
1105 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1106 // Device scale factor should come over to impl.
1107 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1109 // Both layers are on impl.
1110 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1112 // Device viewport is scaled.
1113 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1115 LayerImpl* root = impl->active_tree()->root_layer();
1116 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1118 // Positions remain in layout pixels.
1119 EXPECT_EQ(gfx::Point(0, 0), root->position());
1120 EXPECT_EQ(gfx::Point(2, 2), child->position());
1122 // Compute all the layer transforms for the frame.
1123 LayerTreeHostImpl::FrameData frame_data;
1124 impl->PrepareToDraw(&frame_data);
1125 impl->DidDrawAllLayers(frame_data);
1127 const LayerImplList& render_surface_layer_list =
1128 *frame_data.render_surface_layer_list;
1130 // Both layers should be drawing into the root render surface.
1131 ASSERT_EQ(1u, render_surface_layer_list.size());
1132 ASSERT_EQ(root->render_surface(),
1133 render_surface_layer_list[0]->render_surface());
1134 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1136 // The root render surface is the size of the viewport.
1137 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1138 root->render_surface()->content_rect());
1140 // The content bounds of the child should be scaled.
1141 gfx::Size child_bounds_scaled =
1142 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1143 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1145 gfx::Transform scale_transform;
1146 scale_transform.Scale(impl->device_scale_factor(),
1147 impl->device_scale_factor());
1149 // The root layer is scaled by 2x.
1150 gfx::Transform root_screen_space_transform = scale_transform;
1151 gfx::Transform root_draw_transform = scale_transform;
1153 EXPECT_EQ(root_draw_transform, root->draw_transform());
1154 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1156 // The child is at position 2,2, which is transformed to 3,3 after the scale
1157 gfx::Transform child_screen_space_transform;
1158 child_screen_space_transform.Translate(3.f, 3.f);
1159 gfx::Transform child_draw_transform = child_screen_space_transform;
1161 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1162 child->draw_transform());
1163 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1164 child->screen_space_transform());
1166 EndTest();
1169 virtual void AfterTest() OVERRIDE {}
1171 private:
1172 FakeContentLayerClient client_;
1173 scoped_refptr<NoScaleContentLayer> root_layer_;
1174 scoped_refptr<ContentLayer> child_layer_;
1177 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1179 // Verify atomicity of commits and reuse of textures.
1180 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1181 public:
1182 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1183 settings->texture_id_allocation_chunk_size = 1;
1184 // Make sure partial texture updates are turned off.
1185 settings->max_partial_texture_updates = 0;
1186 // Linear fade animator prevents scrollbars from drawing immediately.
1187 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1190 virtual void SetupTree() OVERRIDE {
1191 layer_ = FakeContentLayer::Create(&client_);
1192 layer_->SetBounds(gfx::Size(10, 20));
1194 bool paint_scrollbar = true;
1195 bool has_thumb = false;
1196 scrollbar_ = FakePaintedScrollbarLayer::Create(
1197 paint_scrollbar, has_thumb, layer_->id());
1198 scrollbar_->SetPosition(gfx::Point(0, 10));
1199 scrollbar_->SetBounds(gfx::Size(10, 10));
1201 layer_->AddChild(scrollbar_);
1203 layer_tree_host()->SetRootLayer(layer_);
1204 LayerTreeHostTest::SetupTree();
1207 virtual void BeginTest() OVERRIDE {
1208 drew_frame_ = -1;
1209 PostSetNeedsCommitToMainThread();
1212 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1213 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1215 TestWebGraphicsContext3D* context = TestContext();
1217 switch (impl->active_tree()->source_frame_number()) {
1218 case 0:
1219 // Number of textures should be one for each layer
1220 ASSERT_EQ(2u, context->NumTextures());
1221 // Number of textures used for commit should be one for each layer.
1222 EXPECT_EQ(2u, context->NumUsedTextures());
1223 // Verify that used texture is correct.
1224 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1225 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1227 context->ResetUsedTextures();
1228 break;
1229 case 1:
1230 // Number of textures should be one for scrollbar layer since it was
1231 // requested and deleted on the impl-thread, and double for the content
1232 // layer since its first texture is used by impl thread and cannot by
1233 // used for update.
1234 ASSERT_EQ(3u, context->NumTextures());
1235 // Number of textures used for commit should be one for each layer.
1236 EXPECT_EQ(2u, context->NumUsedTextures());
1237 // First textures should not have been used.
1238 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1239 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1240 // New textures should have been used.
1241 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1242 context->ResetUsedTextures();
1243 break;
1244 case 2:
1245 EndTest();
1246 break;
1247 default:
1248 NOTREACHED();
1249 break;
1253 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1254 TestWebGraphicsContext3D* context = TestContext();
1256 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1257 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1258 return;
1260 drew_frame_ = impl->active_tree()->source_frame_number();
1262 // We draw/ship one texture each frame for each layer.
1263 EXPECT_EQ(2u, context->NumUsedTextures());
1264 context->ResetUsedTextures();
1266 if (!TestEnded())
1267 PostSetNeedsCommitToMainThread();
1270 virtual void Layout() OVERRIDE {
1271 layer_->SetNeedsDisplay();
1272 scrollbar_->SetNeedsDisplay();
1275 virtual void AfterTest() OVERRIDE {}
1277 protected:
1278 FakeContentLayerClient client_;
1279 scoped_refptr<FakeContentLayer> layer_;
1280 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1281 int drew_frame_;
1284 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1285 LayerTreeHostTestDirectRendererAtomicCommit);
1287 class LayerTreeHostTestDelegatingRendererAtomicCommit
1288 : public LayerTreeHostTestDirectRendererAtomicCommit {
1289 public:
1290 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1291 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1293 TestWebGraphicsContext3D* context = TestContext();
1295 switch (impl->active_tree()->source_frame_number()) {
1296 case 0:
1297 // Number of textures should be one for each layer
1298 ASSERT_EQ(2u, context->NumTextures());
1299 // Number of textures used for commit should be one for each layer.
1300 EXPECT_EQ(2u, context->NumUsedTextures());
1301 // Verify that used texture is correct.
1302 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1303 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1304 context->ResetUsedTextures();
1305 break;
1306 case 1:
1307 // Number of textures should be doubled as the first context layer
1308 // texture is being used by the impl-thread and cannot be used for
1309 // update. The scrollbar behavior is different direct renderer because
1310 // UI resource deletion with delegating renderer occurs after tree
1311 // activation.
1312 ASSERT_EQ(4u, context->NumTextures());
1313 // Number of textures used for commit should still be
1314 // one for each layer.
1315 EXPECT_EQ(2u, context->NumUsedTextures());
1316 // First textures should not have been used.
1317 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1318 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1319 // New textures should have been used.
1320 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1321 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1322 context->ResetUsedTextures();
1323 break;
1324 case 2:
1325 EndTest();
1326 break;
1327 default:
1328 NOTREACHED();
1329 break;
1334 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1335 LayerTreeHostTestDelegatingRendererAtomicCommit);
1337 static void SetLayerPropertiesForTesting(Layer* layer,
1338 Layer* parent,
1339 const gfx::Transform& transform,
1340 const gfx::Point3F& transform_origin,
1341 const gfx::PointF& position,
1342 const gfx::Size& bounds,
1343 bool opaque) {
1344 layer->RemoveAllChildren();
1345 if (parent)
1346 parent->AddChild(layer);
1347 layer->SetTransform(transform);
1348 layer->SetTransformOrigin(transform_origin);
1349 layer->SetPosition(position);
1350 layer->SetBounds(bounds);
1351 layer->SetContentsOpaque(opaque);
1354 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1355 : public LayerTreeHostTest {
1356 public:
1357 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1358 settings->texture_id_allocation_chunk_size = 1;
1359 // Allow one partial texture update.
1360 settings->max_partial_texture_updates = 1;
1361 // No partial updates when impl side painting is enabled.
1362 settings->impl_side_painting = false;
1365 virtual void SetupTree() OVERRIDE {
1366 parent_ = FakeContentLayer::Create(&client_);
1367 parent_->SetBounds(gfx::Size(10, 20));
1369 child_ = FakeContentLayer::Create(&client_);
1370 child_->SetPosition(gfx::Point(0, 10));
1371 child_->SetBounds(gfx::Size(3, 10));
1373 parent_->AddChild(child_);
1375 layer_tree_host()->SetRootLayer(parent_);
1376 LayerTreeHostTest::SetupTree();
1379 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1381 virtual void DidCommitAndDrawFrame() OVERRIDE {
1382 switch (layer_tree_host()->source_frame_number()) {
1383 case 1:
1384 parent_->SetNeedsDisplay();
1385 child_->SetNeedsDisplay();
1386 break;
1387 case 2:
1388 // Damage part of layers.
1389 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1390 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1391 break;
1392 case 3:
1393 child_->SetNeedsDisplay();
1394 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1395 break;
1396 case 4:
1397 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1398 break;
1399 case 5:
1400 EndTest();
1401 break;
1402 default:
1403 NOTREACHED() << layer_tree_host()->source_frame_number();
1404 break;
1408 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1409 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1411 TestWebGraphicsContext3D* context = TestContext();
1413 switch (impl->active_tree()->source_frame_number()) {
1414 case 0:
1415 // Number of textures should be one for each layer.
1416 ASSERT_EQ(2u, context->NumTextures());
1417 // Number of textures used for commit should be one for each layer.
1418 EXPECT_EQ(2u, context->NumUsedTextures());
1419 // Verify that used textures are correct.
1420 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1421 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1422 context->ResetUsedTextures();
1423 break;
1424 case 1:
1425 if (HasImplThread()) {
1426 // Number of textures should be two for each content layer.
1427 ASSERT_EQ(4u, context->NumTextures());
1428 } else {
1429 // In single thread we can always do partial updates, so the limit has
1430 // no effect.
1431 ASSERT_EQ(2u, context->NumTextures());
1433 // Number of textures used for commit should be one for each content
1434 // layer.
1435 EXPECT_EQ(2u, context->NumUsedTextures());
1437 if (HasImplThread()) {
1438 // First content textures should not have been used.
1439 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1440 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1441 // New textures should have been used.
1442 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1443 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1444 } else {
1445 // In single thread we can always do partial updates, so the limit has
1446 // no effect.
1447 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1448 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1451 context->ResetUsedTextures();
1452 break;
1453 case 2:
1454 if (HasImplThread()) {
1455 // Number of textures should be two for each content layer.
1456 ASSERT_EQ(4u, context->NumTextures());
1457 } else {
1458 // In single thread we can always do partial updates, so the limit has
1459 // no effect.
1460 ASSERT_EQ(2u, context->NumTextures());
1462 // Number of textures used for commit should be one for each content
1463 // layer.
1464 EXPECT_EQ(2u, context->NumUsedTextures());
1466 if (HasImplThread()) {
1467 // One content layer does a partial update also.
1468 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1469 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1470 } else {
1471 // In single thread we can always do partial updates, so the limit has
1472 // no effect.
1473 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1474 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1477 context->ResetUsedTextures();
1478 break;
1479 case 3:
1480 // No textures should be used for commit.
1481 EXPECT_EQ(0u, context->NumUsedTextures());
1483 context->ResetUsedTextures();
1484 break;
1485 case 4:
1486 // Number of textures used for commit should be one, for the
1487 // content layer.
1488 EXPECT_EQ(1u, context->NumUsedTextures());
1490 context->ResetUsedTextures();
1491 break;
1492 default:
1493 NOTREACHED();
1494 break;
1498 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1499 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1501 TestWebGraphicsContext3D* context = TestContext();
1503 // Number of textures used for drawing should one per layer except for
1504 // frame 3 where the viewport only contains one layer.
1505 if (impl->active_tree()->source_frame_number() == 3) {
1506 EXPECT_EQ(1u, context->NumUsedTextures());
1507 } else {
1508 EXPECT_EQ(2u, context->NumUsedTextures())
1509 << "For frame " << impl->active_tree()->source_frame_number();
1512 context->ResetUsedTextures();
1515 virtual void AfterTest() OVERRIDE {}
1517 private:
1518 FakeContentLayerClient client_;
1519 scoped_refptr<FakeContentLayer> parent_;
1520 scoped_refptr<FakeContentLayer> child_;
1523 // Partial updates are not possible with a delegating renderer.
1524 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1525 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1527 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1528 : public LayerTreeHostTest {
1529 protected:
1530 virtual void SetupTree() OVERRIDE {
1531 root_layer_ = FakeContentLayer::Create(&client_);
1532 root_layer_->SetBounds(gfx::Size(100, 100));
1534 surface_layer1_ = FakeContentLayer::Create(&client_);
1535 surface_layer1_->SetBounds(gfx::Size(100, 100));
1536 surface_layer1_->SetForceRenderSurface(true);
1537 surface_layer1_->SetOpacity(0.5f);
1538 root_layer_->AddChild(surface_layer1_);
1540 surface_layer2_ = FakeContentLayer::Create(&client_);
1541 surface_layer2_->SetBounds(gfx::Size(100, 100));
1542 surface_layer2_->SetForceRenderSurface(true);
1543 surface_layer2_->SetOpacity(0.5f);
1544 surface_layer1_->AddChild(surface_layer2_);
1546 replica_layer1_ = FakeContentLayer::Create(&client_);
1547 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1549 replica_layer2_ = FakeContentLayer::Create(&client_);
1550 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1552 layer_tree_host()->SetRootLayer(root_layer_);
1553 LayerTreeHostTest::SetupTree();
1556 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1558 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1559 Renderer* renderer = host_impl->renderer();
1560 RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1561 ->root_layer()
1562 ->children()[0]
1563 ->render_surface()
1564 ->RenderPassId();
1565 RenderPass::Id surface2_render_pass_id = host_impl->active_tree()
1566 ->root_layer()
1567 ->children()[0]
1568 ->children()[0]
1569 ->render_surface()
1570 ->RenderPassId();
1572 switch (host_impl->active_tree()->source_frame_number()) {
1573 case 0:
1574 EXPECT_TRUE(
1575 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1576 EXPECT_TRUE(
1577 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1579 // Reduce the memory limit to only fit the root layer and one render
1580 // surface. This prevents any contents drawing into surfaces
1581 // from being allocated.
1582 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1583 break;
1584 case 1:
1585 EXPECT_FALSE(
1586 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1587 EXPECT_FALSE(
1588 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1590 EndTest();
1591 break;
1595 virtual void DidCommitAndDrawFrame() OVERRIDE {
1596 if (layer_tree_host()->source_frame_number() < 2)
1597 root_layer_->SetNeedsDisplay();
1600 virtual void AfterTest() OVERRIDE {
1601 EXPECT_LE(2u, root_layer_->update_count());
1602 EXPECT_LE(2u, surface_layer1_->update_count());
1603 EXPECT_LE(2u, surface_layer2_->update_count());
1606 FakeContentLayerClient client_;
1607 scoped_refptr<FakeContentLayer> root_layer_;
1608 scoped_refptr<FakeContentLayer> surface_layer1_;
1609 scoped_refptr<FakeContentLayer> replica_layer1_;
1610 scoped_refptr<FakeContentLayer> surface_layer2_;
1611 scoped_refptr<FakeContentLayer> replica_layer2_;
1614 // Surfaces don't exist with a delegated renderer.
1615 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1616 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1618 class EvictionTestLayer : public Layer {
1619 public:
1620 static scoped_refptr<EvictionTestLayer> Create() {
1621 return make_scoped_refptr(new EvictionTestLayer());
1624 virtual bool Update(ResourceUpdateQueue*,
1625 const OcclusionTracker<Layer>*) OVERRIDE;
1626 virtual bool DrawsContent() const OVERRIDE { return true; }
1628 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1629 OVERRIDE;
1630 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1631 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1633 bool HaveBackingTexture() const {
1634 return texture_.get() ? texture_->have_backing_texture() : false;
1637 private:
1638 EvictionTestLayer() : Layer() {}
1639 virtual ~EvictionTestLayer() {}
1641 void CreateTextureIfNeeded() {
1642 if (texture_)
1643 return;
1644 texture_ = PrioritizedResource::Create(
1645 layer_tree_host()->contents_texture_manager());
1646 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1647 bitmap_.allocN32Pixels(10, 10);
1650 scoped_ptr<PrioritizedResource> texture_;
1651 SkBitmap bitmap_;
1654 class EvictionTestLayerImpl : public LayerImpl {
1655 public:
1656 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1657 int id) {
1658 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1660 virtual ~EvictionTestLayerImpl() {}
1662 virtual void AppendQuads(RenderPass* render_pass,
1663 const OcclusionTracker<LayerImpl>& occlusion_tracker,
1664 AppendQuadsData* append_quads_data) OVERRIDE {
1665 ASSERT_TRUE(has_texture_);
1666 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1669 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1671 private:
1672 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1673 : LayerImpl(tree_impl, id), has_texture_(false) {}
1675 bool has_texture_;
1678 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1679 CreateTextureIfNeeded();
1680 if (!texture_)
1681 return;
1682 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1685 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1686 const OcclusionTracker<Layer>* occlusion) {
1687 CreateTextureIfNeeded();
1688 if (!texture_)
1689 return false;
1691 gfx::Rect full_rect(0, 0, 10, 10);
1692 ResourceUpdate upload = ResourceUpdate::Create(
1693 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1694 queue->AppendFullUpload(upload);
1695 return true;
1698 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1699 LayerTreeImpl* tree_impl) {
1700 return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
1701 .PassAs<LayerImpl>();
1704 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1705 Layer::PushPropertiesTo(layer_impl);
1707 EvictionTestLayerImpl* test_layer_impl =
1708 static_cast<EvictionTestLayerImpl*>(layer_impl);
1709 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1712 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1713 public:
1714 LayerTreeHostTestEvictTextures()
1715 : layer_(EvictionTestLayer::Create()),
1716 impl_for_evict_textures_(0),
1717 num_commits_(0) {}
1719 virtual void BeginTest() OVERRIDE {
1720 layer_tree_host()->SetRootLayer(layer_);
1721 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1723 gfx::Transform identity_matrix;
1724 SetLayerPropertiesForTesting(layer_.get(),
1726 identity_matrix,
1727 gfx::Point3F(0.f, 0.f, 0.f),
1728 gfx::PointF(0.f, 0.f),
1729 gfx::Size(10, 20),
1730 true);
1732 PostSetNeedsCommitToMainThread();
1735 void PostEvictTextures() {
1736 ImplThreadTaskRunner()->PostTask(
1737 FROM_HERE,
1738 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1739 base::Unretained(this)));
1742 void EvictTexturesOnImplThread() {
1743 DCHECK(impl_for_evict_textures_);
1744 impl_for_evict_textures_->EvictTexturesForTesting();
1747 // Commit 1: Just commit and draw normally, then post an eviction at the end
1748 // that will trigger a commit.
1749 // Commit 2: Triggered by the eviction, let it go through and then set
1750 // needsCommit.
1751 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1752 // task, which will be handled before the commit. Don't set needsCommit, it
1753 // should have been posted. A frame should not be drawn (note,
1754 // didCommitAndDrawFrame may be called anyway).
1755 // Commit 4: Triggered by the eviction, let it go through and then set
1756 // needsCommit.
1757 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1758 // Layout(), a frame should not be drawn but a commit will be posted.
1759 // Commit 6: Triggered by the eviction, post an eviction task in
1760 // Layout(), which will be a noop, letting the commit (which recreates the
1761 // textures) go through and draw a frame, then end the test.
1763 // Commits 1+2 test the eviction recovery path where eviction happens outside
1764 // of the beginFrame/commit pair.
1765 // Commits 3+4 test the eviction recovery path where eviction happens inside
1766 // the beginFrame/commit pair.
1767 // Commits 5+6 test the path where an eviction happens during the eviction
1768 // recovery path.
1769 virtual void DidCommit() OVERRIDE {
1770 switch (num_commits_) {
1771 case 1:
1772 EXPECT_TRUE(layer_->HaveBackingTexture());
1773 PostEvictTextures();
1774 break;
1775 case 2:
1776 EXPECT_TRUE(layer_->HaveBackingTexture());
1777 layer_tree_host()->SetNeedsCommit();
1778 break;
1779 case 3:
1780 break;
1781 case 4:
1782 EXPECT_TRUE(layer_->HaveBackingTexture());
1783 layer_tree_host()->SetNeedsCommit();
1784 break;
1785 case 5:
1786 break;
1787 case 6:
1788 EXPECT_TRUE(layer_->HaveBackingTexture());
1789 EndTest();
1790 break;
1791 default:
1792 NOTREACHED();
1793 break;
1797 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1798 impl_for_evict_textures_ = impl;
1801 virtual void Layout() OVERRIDE {
1802 ++num_commits_;
1803 switch (num_commits_) {
1804 case 1:
1805 case 2:
1806 break;
1807 case 3:
1808 PostEvictTextures();
1809 break;
1810 case 4:
1811 // We couldn't check in didCommitAndDrawFrame on commit 3,
1812 // so check here.
1813 EXPECT_FALSE(layer_->HaveBackingTexture());
1814 break;
1815 case 5:
1816 PostEvictTextures();
1817 break;
1818 case 6:
1819 // We couldn't check in didCommitAndDrawFrame on commit 5,
1820 // so check here.
1821 EXPECT_FALSE(layer_->HaveBackingTexture());
1822 PostEvictTextures();
1823 break;
1824 default:
1825 NOTREACHED();
1826 break;
1830 virtual void AfterTest() OVERRIDE {}
1832 private:
1833 FakeContentLayerClient client_;
1834 scoped_refptr<EvictionTestLayer> layer_;
1835 LayerTreeHostImpl* impl_for_evict_textures_;
1836 int num_commits_;
1839 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
1841 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
1842 public:
1843 LayerTreeHostTestContinuousCommit()
1844 : num_commit_complete_(0), num_draw_layers_(0) {}
1846 virtual void BeginTest() OVERRIDE {
1847 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1848 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1850 PostSetNeedsCommitToMainThread();
1853 virtual void DidCommit() OVERRIDE {
1854 if (num_draw_layers_ == 2)
1855 return;
1856 layer_tree_host()->SetNeedsCommit();
1859 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1860 if (num_draw_layers_ == 1)
1861 num_commit_complete_++;
1864 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1865 num_draw_layers_++;
1866 if (num_draw_layers_ == 2)
1867 EndTest();
1870 virtual void AfterTest() OVERRIDE {
1871 // Check that we didn't commit twice between first and second draw.
1872 EXPECT_EQ(1, num_commit_complete_);
1875 private:
1876 int num_commit_complete_;
1877 int num_draw_layers_;
1880 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
1882 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1883 public:
1884 LayerTreeHostTestContinuousInvalidate()
1885 : num_commit_complete_(0), num_draw_layers_(0) {}
1887 virtual void BeginTest() OVERRIDE {
1888 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1889 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1891 content_layer_ = ContentLayer::Create(&client_);
1892 content_layer_->SetBounds(gfx::Size(10, 10));
1893 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
1894 content_layer_->SetIsDrawable(true);
1895 layer_tree_host()->root_layer()->AddChild(content_layer_);
1897 PostSetNeedsCommitToMainThread();
1900 virtual void DidCommitAndDrawFrame() OVERRIDE {
1901 if (num_draw_layers_ == 2)
1902 return;
1903 content_layer_->SetNeedsDisplay();
1906 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1907 if (num_draw_layers_ == 1)
1908 num_commit_complete_++;
1911 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1912 num_draw_layers_++;
1913 if (num_draw_layers_ == 2)
1914 EndTest();
1917 virtual void AfterTest() OVERRIDE {
1918 // Check that we didn't commit twice between first and second draw.
1919 EXPECT_EQ(1, num_commit_complete_);
1922 private:
1923 FakeContentLayerClient client_;
1924 scoped_refptr<Layer> content_layer_;
1925 int num_commit_complete_;
1926 int num_draw_layers_;
1929 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestContinuousInvalidate);
1931 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
1932 public:
1933 LayerTreeHostTestDeferCommits()
1934 : num_commits_deferred_(0), num_complete_commits_(0) {}
1936 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1938 virtual void DidDeferCommit() OVERRIDE {
1939 num_commits_deferred_++;
1940 layer_tree_host()->SetDeferCommits(false);
1943 virtual void DidCommit() OVERRIDE {
1944 num_complete_commits_++;
1945 switch (num_complete_commits_) {
1946 case 1:
1947 EXPECT_EQ(0, num_commits_deferred_);
1948 layer_tree_host()->SetDeferCommits(true);
1949 PostSetNeedsCommitToMainThread();
1950 break;
1951 case 2:
1952 EndTest();
1953 break;
1954 default:
1955 NOTREACHED();
1956 break;
1960 virtual void AfterTest() OVERRIDE {
1961 EXPECT_EQ(1, num_commits_deferred_);
1962 EXPECT_EQ(2, num_complete_commits_);
1965 private:
1966 int num_commits_deferred_;
1967 int num_complete_commits_;
1970 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
1972 class LayerTreeHostWithProxy : public LayerTreeHost {
1973 public:
1974 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
1975 const LayerTreeSettings& settings,
1976 scoped_ptr<FakeProxy> proxy)
1977 : LayerTreeHost(client, NULL, settings) {
1978 proxy->SetLayerTreeHost(this);
1979 InitializeForTesting(proxy.PassAs<Proxy>());
1983 TEST(LayerTreeHostTest, LimitPartialUpdates) {
1984 // When partial updates are not allowed, max updates should be 0.
1986 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1988 scoped_ptr<FakeProxy> proxy(new FakeProxy);
1989 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
1990 proxy->SetMaxPartialTextureUpdates(5);
1992 LayerTreeSettings settings;
1993 settings.max_partial_texture_updates = 10;
1995 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1996 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
1998 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2001 // When partial updates are allowed,
2002 // max updates should be limited by the proxy.
2004 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2006 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2007 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2008 proxy->SetMaxPartialTextureUpdates(5);
2010 LayerTreeSettings settings;
2011 settings.max_partial_texture_updates = 10;
2013 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2014 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
2016 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2019 // When partial updates are allowed,
2020 // max updates should also be limited by the settings.
2022 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2024 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2025 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2026 proxy->SetMaxPartialTextureUpdates(20);
2028 LayerTreeSettings settings;
2029 settings.max_partial_texture_updates = 10;
2031 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2032 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
2034 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2038 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2039 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2041 LayerTreeSettings settings;
2042 settings.max_partial_texture_updates = 4;
2044 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2045 new TestSharedBitmapManager());
2046 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2047 &client, &client, shared_bitmap_manager.get(), settings);
2048 host->Composite(base::TimeTicks::Now());
2050 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2053 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2054 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2056 LayerTreeSettings settings;
2057 settings.max_partial_texture_updates = 4;
2059 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2060 new TestSharedBitmapManager());
2061 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2062 &client, &client, shared_bitmap_manager.get(), settings);
2063 host->Composite(base::TimeTicks::Now());
2065 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2068 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2069 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2071 LayerTreeSettings settings;
2072 settings.max_partial_texture_updates = 4;
2074 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2075 new TestSharedBitmapManager());
2076 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2077 &client, &client, shared_bitmap_manager.get(), settings);
2078 host->Composite(base::TimeTicks::Now());
2080 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2083 TEST(LayerTreeHostTest,
2084 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2085 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2087 LayerTreeSettings settings;
2088 settings.max_partial_texture_updates = 4;
2090 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2091 new TestSharedBitmapManager());
2092 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2093 &client, &client, shared_bitmap_manager.get(), settings);
2094 host->Composite(base::TimeTicks::Now());
2096 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2099 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2100 : public LayerTreeHostTest {
2101 public:
2102 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2103 : root_layer_(FakeContentLayer::Create(&client_)),
2104 child_layer1_(FakeContentLayer::Create(&client_)),
2105 child_layer2_(FakeContentLayer::Create(&client_)),
2106 num_commits_(0) {}
2108 virtual void BeginTest() OVERRIDE {
2109 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2110 root_layer_->SetBounds(gfx::Size(100, 100));
2111 child_layer1_->SetBounds(gfx::Size(100, 100));
2112 child_layer2_->SetBounds(gfx::Size(100, 100));
2113 root_layer_->AddChild(child_layer1_);
2114 root_layer_->AddChild(child_layer2_);
2115 layer_tree_host()->SetRootLayer(root_layer_);
2116 PostSetNeedsCommitToMainThread();
2119 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2120 bool visible) OVERRIDE {
2121 if (visible) {
2122 // One backing should remain unevicted.
2123 EXPECT_EQ(
2124 100u * 100u * 4u * 1u,
2125 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2126 } else {
2127 EXPECT_EQ(
2128 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2131 // Make sure that contents textures are marked as having been
2132 // purged.
2133 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2134 // End the test in this state.
2135 EndTest();
2138 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2139 ++num_commits_;
2140 switch (num_commits_) {
2141 case 1:
2142 // All three backings should have memory.
2143 EXPECT_EQ(
2144 100u * 100u * 4u * 3u,
2145 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2146 // Set a new policy that will kick out 1 of the 3 resources.
2147 // Because a resource was evicted, a commit will be kicked off.
2148 host_impl->SetMemoryPolicy(
2149 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2150 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2151 1000));
2152 break;
2153 case 2:
2154 // Only two backings should have memory.
2155 EXPECT_EQ(
2156 100u * 100u * 4u * 2u,
2157 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2158 // Become backgrounded, which will cause 1 more resource to be
2159 // evicted.
2160 PostSetVisibleToMainThread(false);
2161 break;
2162 default:
2163 // No further commits should happen because this is not visible
2164 // anymore.
2165 NOTREACHED();
2166 break;
2170 virtual void AfterTest() OVERRIDE {}
2172 private:
2173 FakeContentLayerClient client_;
2174 scoped_refptr<FakeContentLayer> root_layer_;
2175 scoped_refptr<FakeContentLayer> child_layer1_;
2176 scoped_refptr<FakeContentLayer> child_layer2_;
2177 int num_commits_;
2180 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2181 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2183 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2184 public:
2185 class NotificationClient : public ContentLayerClient {
2186 public:
2187 NotificationClient()
2188 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2190 void set_layer(Layer* layer) { layer_ = layer; }
2191 int paint_count() const { return paint_count_; }
2192 int lcd_notification_count() const { return lcd_notification_count_; }
2194 virtual void PaintContents(
2195 SkCanvas* canvas,
2196 const gfx::Rect& clip,
2197 gfx::RectF* opaque,
2198 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
2199 ++paint_count_;
2201 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2202 ++lcd_notification_count_;
2203 layer_->SetNeedsDisplay();
2205 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
2207 private:
2208 Layer* layer_;
2209 int paint_count_;
2210 int lcd_notification_count_;
2213 virtual void SetupTree() OVERRIDE {
2214 scoped_refptr<Layer> root_layer;
2215 if (layer_tree_host()->settings().impl_side_painting)
2216 root_layer = PictureLayer::Create(&client_);
2217 else
2218 root_layer = ContentLayer::Create(&client_);
2219 root_layer->SetIsDrawable(true);
2220 root_layer->SetBounds(gfx::Size(1, 1));
2222 layer_tree_host()->SetRootLayer(root_layer);
2223 client_.set_layer(root_layer.get());
2225 // The expecations are based on the assumption that the default
2226 // LCD settings are:
2227 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2228 EXPECT_FALSE(root_layer->can_use_lcd_text());
2230 LayerTreeHostTest::SetupTree();
2233 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2234 virtual void AfterTest() OVERRIDE {}
2236 virtual void DidCommit() OVERRIDE {
2237 switch (layer_tree_host()->source_frame_number()) {
2238 case 1:
2239 // The first update consists of one LCD notification and one paint.
2240 EXPECT_EQ(1, client_.lcd_notification_count());
2241 EXPECT_EQ(1, client_.paint_count());
2242 // LCD text must have been enabled on the layer.
2243 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2244 PostSetNeedsCommitToMainThread();
2245 break;
2246 case 2:
2247 // Since nothing changed on layer, there should be no notification
2248 // or paint on the second update.
2249 EXPECT_EQ(1, client_.lcd_notification_count());
2250 EXPECT_EQ(1, client_.paint_count());
2251 // LCD text must not have changed.
2252 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2253 // Change layer opacity that should trigger lcd notification.
2254 layer_tree_host()->root_layer()->SetOpacity(.5f);
2255 // No need to request a commit - setting opacity will do it.
2256 break;
2257 default:
2258 // Verify that there is no extra commit due to layer invalidation.
2259 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
2260 // LCD notification count should have incremented due to
2261 // change in layer opacity.
2262 EXPECT_EQ(2, client_.lcd_notification_count());
2263 // Paint count should be incremented due to invalidation.
2264 EXPECT_EQ(2, client_.paint_count());
2265 // LCD text must have been disabled on the layer due to opacity.
2266 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2267 EndTest();
2268 break;
2272 private:
2273 NotificationClient client_;
2276 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2278 // Verify that the BeginFrame notification is used to initiate rendering.
2279 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2280 public:
2281 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2282 settings->begin_frame_scheduling_enabled = true;
2285 virtual void BeginTest() OVERRIDE {
2286 // This will trigger a SetNeedsBeginFrame which will trigger a
2287 // BeginFrame.
2288 PostSetNeedsCommitToMainThread();
2291 virtual DrawResult PrepareToDrawOnThread(
2292 LayerTreeHostImpl* host_impl,
2293 LayerTreeHostImpl::FrameData* frame,
2294 DrawResult draw_result) OVERRIDE {
2295 EndTest();
2296 return DRAW_SUCCESS;
2299 virtual void AfterTest() OVERRIDE {}
2301 private:
2302 base::TimeTicks frame_time_;
2305 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2307 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2308 : public LayerTreeHostTest {
2309 public:
2310 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2311 settings->begin_frame_scheduling_enabled = true;
2312 settings->using_synchronous_renderer_compositor = true;
2315 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2317 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2318 // The BeginFrame notification is turned off now but will get enabled
2319 // once we return. End test while it's enabled.
2320 ImplThreadTaskRunner()->PostTask(
2321 FROM_HERE,
2322 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2323 base::Unretained(this)));
2326 virtual void AfterTest() OVERRIDE {}
2329 MULTI_THREAD_TEST_F(
2330 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2332 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2333 protected:
2334 LayerTreeHostTestAbortedCommitDoesntStall()
2335 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2337 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2338 settings->begin_frame_scheduling_enabled = true;
2341 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2343 virtual void DidCommit() OVERRIDE {
2344 commit_count_++;
2345 if (commit_count_ == 4) {
2346 // After two aborted commits, request a real commit now to make sure a
2347 // real commit following an aborted commit will still complete and
2348 // end the test even when the Impl thread is idle.
2349 layer_tree_host()->SetNeedsCommit();
2353 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2354 bool did_handle) OVERRIDE {
2355 commit_abort_count_++;
2356 // Initiate another abortable commit.
2357 host_impl->SetNeedsCommit();
2360 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2361 commit_complete_count_++;
2362 if (commit_complete_count_ == 1) {
2363 // Initiate an abortable commit after the first commit.
2364 host_impl->SetNeedsCommit();
2365 } else {
2366 EndTest();
2370 virtual void AfterTest() OVERRIDE {
2371 EXPECT_EQ(commit_count_, 5);
2372 EXPECT_EQ(commit_abort_count_, 3);
2373 EXPECT_EQ(commit_complete_count_, 2);
2376 int commit_count_;
2377 int commit_abort_count_;
2378 int commit_complete_count_;
2381 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2382 : public LayerTreeHostTestAbortedCommitDoesntStall {
2383 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2384 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2385 settings->using_synchronous_renderer_compositor = true;
2389 MULTI_THREAD_TEST_F(
2390 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2392 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2393 : public LayerTreeHostTestAbortedCommitDoesntStall {
2394 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2395 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2396 settings->throttle_frame_production = false;
2400 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2402 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2403 : public LayerTreeHostTest {
2404 protected:
2405 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2406 settings->impl_side_painting = true;
2409 virtual void SetupTree() OVERRIDE {
2410 LayerTreeHostTest::SetupTree();
2412 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2413 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2414 layer->SetBounds(gfx::Size(10, 10));
2415 layer_tree_host()->root_layer()->AddChild(layer);
2418 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2420 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2421 EndTest();
2424 virtual void AfterTest() OVERRIDE {}
2426 FakeContentLayerClient client_;
2429 MULTI_THREAD_TEST_F(
2430 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2432 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2433 : public LayerTreeHostTest {
2434 public:
2435 class SetBoundsClient : public ContentLayerClient {
2436 public:
2437 SetBoundsClient() : layer_(0) {}
2439 void set_layer(Layer* layer) { layer_ = layer; }
2441 virtual void PaintContents(
2442 SkCanvas* canvas,
2443 const gfx::Rect& clip,
2444 gfx::RectF* opaque,
2445 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
2446 layer_->SetBounds(gfx::Size(2, 2));
2449 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2451 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
2453 private:
2454 Layer* layer_;
2457 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2459 virtual void SetupTree() OVERRIDE {
2460 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2461 root_layer->SetIsDrawable(true);
2462 root_layer->SetBounds(gfx::Size(1, 1));
2464 layer_tree_host()->SetRootLayer(root_layer);
2465 client_.set_layer(root_layer.get());
2467 LayerTreeHostTest::SetupTree();
2470 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2471 virtual void AfterTest() OVERRIDE {}
2473 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2474 num_commits_++;
2475 if (num_commits_ == 1) {
2476 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2477 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2478 } else {
2479 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2480 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2481 EndTest();
2485 private:
2486 SetBoundsClient client_;
2487 int num_commits_;
2490 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2492 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2493 public:
2494 MockIOSurfaceWebGraphicsContext3D() {
2495 test_capabilities_.gpu.iosurface = true;
2496 test_capabilities_.gpu.texture_rectangle = true;
2499 virtual GLuint createTexture() OVERRIDE {
2500 return 1;
2502 MOCK_METHOD1(activeTexture, void(GLenum texture));
2503 MOCK_METHOD2(bindTexture, void(GLenum target,
2504 GLuint texture_id));
2505 MOCK_METHOD3(texParameteri, void(GLenum target,
2506 GLenum pname,
2507 GLint param));
2508 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2509 GLint width,
2510 GLint height,
2511 GLuint ioSurfaceId,
2512 GLuint plane));
2513 MOCK_METHOD4(drawElements, void(GLenum mode,
2514 GLsizei count,
2515 GLenum type,
2516 GLintptr offset));
2517 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2518 MOCK_METHOD2(produceTextureCHROMIUM,
2519 void(GLenum target, const GLbyte* mailbox));
2522 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2523 protected:
2524 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
2525 OVERRIDE {
2526 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2527 new MockIOSurfaceWebGraphicsContext3D);
2528 mock_context_ = mock_context_owned.get();
2530 if (delegating_renderer()) {
2531 return FakeOutputSurface::CreateDelegating3d(
2532 mock_context_owned.PassAs<TestWebGraphicsContext3D>());
2533 } else {
2534 return FakeOutputSurface::Create3d(
2535 mock_context_owned.PassAs<TestWebGraphicsContext3D>());
2539 virtual void SetupTree() OVERRIDE {
2540 LayerTreeHostTest::SetupTree();
2542 layer_tree_host()->root_layer()->SetIsDrawable(false);
2544 io_surface_id_ = 9;
2545 io_surface_size_ = gfx::Size(6, 7);
2547 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2548 io_surface_layer->SetBounds(gfx::Size(10, 10));
2549 io_surface_layer->SetIsDrawable(true);
2550 io_surface_layer->SetContentsOpaque(true);
2551 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2552 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2555 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2557 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2558 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2559 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2561 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2562 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2563 .Times(AtLeast(1));
2564 EXPECT_CALL(*mock_context_,
2565 texParameteri(
2566 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2567 .Times(1);
2568 EXPECT_CALL(*mock_context_,
2569 texParameteri(
2570 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2571 .Times(1);
2572 EXPECT_CALL(*mock_context_,
2573 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2574 GL_TEXTURE_POOL_CHROMIUM,
2575 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2576 EXPECT_CALL(*mock_context_,
2577 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2578 GL_TEXTURE_WRAP_S,
2579 GL_CLAMP_TO_EDGE)).Times(1);
2580 EXPECT_CALL(*mock_context_,
2581 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2582 GL_TEXTURE_WRAP_T,
2583 GL_CLAMP_TO_EDGE)).Times(1);
2585 EXPECT_CALL(*mock_context_,
2586 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2587 io_surface_size_.width(),
2588 io_surface_size_.height(),
2589 io_surface_id_,
2590 0)).Times(1);
2592 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2595 virtual DrawResult PrepareToDrawOnThread(
2596 LayerTreeHostImpl* host_impl,
2597 LayerTreeHostImpl::FrameData* frame,
2598 DrawResult draw_result) OVERRIDE {
2599 Mock::VerifyAndClearExpectations(&mock_context_);
2600 ResourceProvider* resource_provider = host_impl->resource_provider();
2601 EXPECT_EQ(1u, resource_provider->num_resources());
2602 CHECK_EQ(1u, frame->render_passes.size());
2603 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2604 const DrawQuad* quad = frame->render_passes[0]->quad_list[0];
2605 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2606 const IOSurfaceDrawQuad* io_surface_draw_quad =
2607 IOSurfaceDrawQuad::MaterialCast(quad);
2608 EXPECT_SIZE_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2609 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
2610 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2611 resource_provider->TargetForTesting(
2612 io_surface_draw_quad->io_surface_resource_id));
2614 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2615 .Times(1);
2616 if (delegating_renderer()) {
2617 // The io surface layer's resource should be sent to the parent.
2618 EXPECT_CALL(*mock_context_,
2619 produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2620 } else {
2621 // The io surface layer's texture is drawn.
2622 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2623 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2624 .Times(AtLeast(1));
2627 return draw_result;
2630 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2631 Mock::VerifyAndClearExpectations(&mock_context_);
2633 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2634 EndTest();
2637 virtual void AfterTest() OVERRIDE {}
2639 int io_surface_id_;
2640 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2641 gfx::Size io_surface_size_;
2644 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2646 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2647 public:
2648 virtual void BeginTest() OVERRIDE {
2649 frame_ = 0;
2650 PostSetNeedsCommitToMainThread();
2653 // Round 1: commit + draw
2654 // Round 2: commit only (no draw/swap)
2655 // Round 3: draw only (no commit)
2657 virtual void DidCommit() OVERRIDE {
2658 int commit = layer_tree_host()->source_frame_number();
2659 switch (commit) {
2660 case 2:
2661 // Round 2 done.
2662 EXPECT_EQ(1, frame_);
2663 layer_tree_host()->SetNeedsRedraw();
2664 break;
2668 virtual void DidCompleteSwapBuffers() OVERRIDE {
2669 int commit = layer_tree_host()->source_frame_number();
2670 ++frame_;
2671 switch (frame_) {
2672 case 1:
2673 // Round 1 done.
2674 EXPECT_EQ(1, commit);
2675 layer_tree_host()->SetNeedsCommit();
2676 break;
2677 case 2:
2678 // Round 3 done.
2679 EXPECT_EQ(2, commit);
2680 EndTest();
2681 break;
2685 virtual void AfterTest() OVERRIDE {}
2687 protected:
2688 int frame_;
2691 // Flaky on all platforms: http://crbug.com/327498
2692 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
2693 RunTest(true, true, true);
2696 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
2697 RunTest(true, false, true);
2700 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
2701 public:
2702 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2703 // PictureLayer can only be used with impl side painting enabled.
2704 settings->impl_side_painting = true;
2707 virtual void SetupTree() OVERRIDE {
2708 layer_ = FakePictureLayer::Create(&client_);
2709 // Force commits to not be aborted so new frames get drawn, otherwise
2710 // the renderer gets deferred initialized but nothing new needs drawing.
2711 layer_->set_always_update_resources(true);
2712 layer_tree_host()->SetRootLayer(layer_);
2713 LayerTreeHostTest::SetupTree();
2716 virtual void BeginTest() OVERRIDE {
2717 did_initialize_gl_ = false;
2718 did_release_gl_ = false;
2719 last_source_frame_number_drawn_ = -1; // Never drawn.
2720 PostSetNeedsCommitToMainThread();
2723 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
2724 OVERRIDE {
2725 scoped_ptr<TestWebGraphicsContext3D> context3d(
2726 TestWebGraphicsContext3D::Create());
2728 return FakeOutputSurface::CreateDeferredGL(
2729 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
2730 delegating_renderer());
2733 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2734 ASSERT_TRUE(host_impl->RootLayer());
2735 FakePictureLayerImpl* layer_impl =
2736 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
2738 // The same frame can be draw multiple times if new visible tiles are
2739 // rasterized. But we want to make sure we only post DeferredInitialize
2740 // and ReleaseGL once, so early out if the same frame is drawn again.
2741 if (last_source_frame_number_drawn_ ==
2742 host_impl->active_tree()->source_frame_number())
2743 return;
2745 last_source_frame_number_drawn_ =
2746 host_impl->active_tree()->source_frame_number();
2748 if (!did_initialize_gl_) {
2749 EXPECT_LE(1u, layer_impl->append_quads_count());
2750 ImplThreadTaskRunner()->PostTask(
2751 FROM_HERE,
2752 base::Bind(
2753 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
2754 base::Unretained(this),
2755 base::Unretained(host_impl)));
2756 } else if (did_initialize_gl_ && !did_release_gl_) {
2757 EXPECT_LE(2u, layer_impl->append_quads_count());
2758 ImplThreadTaskRunner()->PostTask(
2759 FROM_HERE,
2760 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
2761 base::Unretained(this),
2762 base::Unretained(host_impl)));
2763 } else if (did_initialize_gl_ && did_release_gl_) {
2764 EXPECT_LE(3u, layer_impl->append_quads_count());
2765 EndTest();
2769 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
2770 EXPECT_FALSE(did_initialize_gl_);
2771 // SetAndInitializeContext3D calls SetNeedsCommit.
2772 FakeOutputSurface* fake_output_surface =
2773 static_cast<FakeOutputSurface*>(host_impl->output_surface());
2774 scoped_refptr<TestContextProvider> context_provider =
2775 TestContextProvider::Create(); // Not bound to thread.
2776 EXPECT_TRUE(
2777 fake_output_surface->InitializeAndSetContext3d(context_provider));
2778 did_initialize_gl_ = true;
2781 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
2782 EXPECT_TRUE(did_initialize_gl_);
2783 EXPECT_FALSE(did_release_gl_);
2784 // ReleaseGL calls SetNeedsCommit.
2785 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
2786 did_release_gl_ = true;
2789 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
2790 bool result) OVERRIDE {
2791 ASSERT_TRUE(result);
2792 DelegatedFrameData* delegated_frame_data =
2793 output_surface()->last_sent_frame().delegated_frame_data.get();
2794 if (!delegated_frame_data)
2795 return;
2797 // Return all resources immediately.
2798 TransferableResourceArray resources_to_return =
2799 output_surface()->resources_held_by_parent();
2801 CompositorFrameAck ack;
2802 for (size_t i = 0; i < resources_to_return.size(); ++i)
2803 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
2804 host_impl->ReclaimResources(&ack);
2807 virtual void AfterTest() OVERRIDE {
2808 EXPECT_TRUE(did_initialize_gl_);
2809 EXPECT_TRUE(did_release_gl_);
2812 private:
2813 FakeContentLayerClient client_;
2814 scoped_refptr<FakePictureLayer> layer_;
2815 bool did_initialize_gl_;
2816 bool did_release_gl_;
2817 int last_source_frame_number_drawn_;
2820 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
2822 // Test for UI Resource management.
2823 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
2824 public:
2825 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
2827 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2828 settings->texture_id_allocation_chunk_size = 1;
2831 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2833 virtual void DidCommit() OVERRIDE {
2834 int frame = layer_tree_host()->source_frame_number();
2835 switch (frame) {
2836 case 1:
2837 CreateResource();
2838 CreateResource();
2839 PostSetNeedsCommitToMainThread();
2840 break;
2841 case 2:
2842 // Usually ScopedUIResource are deleted from the manager in their
2843 // destructor. Here we just want to test that a direct call to
2844 // DeleteUIResource works.
2845 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
2846 PostSetNeedsCommitToMainThread();
2847 break;
2848 case 3:
2849 // DeleteUIResource can be called with an invalid id.
2850 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
2851 PostSetNeedsCommitToMainThread();
2852 break;
2853 case 4:
2854 CreateResource();
2855 CreateResource();
2856 PostSetNeedsCommitToMainThread();
2857 break;
2858 case 5:
2859 ClearResources();
2860 EndTest();
2861 break;
2865 void PerformTest(LayerTreeHostImpl* impl) {
2866 TestWebGraphicsContext3D* context = TestContext();
2868 int frame = impl->active_tree()->source_frame_number();
2869 switch (frame) {
2870 case 0:
2871 ASSERT_EQ(0u, context->NumTextures());
2872 break;
2873 case 1:
2874 // Created two textures.
2875 ASSERT_EQ(2u, context->NumTextures());
2876 break;
2877 case 2:
2878 // One texture left after one deletion.
2879 ASSERT_EQ(1u, context->NumTextures());
2880 break;
2881 case 3:
2882 // Resource manager state should not change when delete is called on an
2883 // invalid id.
2884 ASSERT_EQ(1u, context->NumTextures());
2885 break;
2886 case 4:
2887 // Creation after deletion: two more creates should total up to
2888 // three textures.
2889 ASSERT_EQ(3u, context->NumTextures());
2890 break;
2894 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2895 if (!layer_tree_host()->settings().impl_side_painting)
2896 PerformTest(impl);
2899 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2900 if (layer_tree_host()->settings().impl_side_painting)
2901 PerformTest(impl);
2904 virtual void AfterTest() OVERRIDE {}
2906 private:
2907 // Must clear all resources before exiting.
2908 void ClearResources() {
2909 for (int i = 0; i < num_ui_resources_; i++)
2910 ui_resources_[i].reset();
2913 void CreateResource() {
2914 ui_resources_[num_ui_resources_++] =
2915 FakeScopedUIResource::Create(layer_tree_host());
2918 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
2919 int num_ui_resources_;
2922 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
2924 class PushPropertiesCountingLayerImpl : public LayerImpl {
2925 public:
2926 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
2927 LayerTreeImpl* tree_impl, int id) {
2928 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
2931 virtual ~PushPropertiesCountingLayerImpl() {}
2933 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
2934 LayerImpl::PushPropertiesTo(layer);
2935 push_properties_count_++;
2936 // Push state to the active tree because we can only access it from there.
2937 static_cast<PushPropertiesCountingLayerImpl*>(
2938 layer)->push_properties_count_ = push_properties_count_;
2941 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
2942 OVERRIDE {
2943 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
2944 PassAs<LayerImpl>();
2947 size_t push_properties_count() const { return push_properties_count_; }
2948 void reset_push_properties_count() { push_properties_count_ = 0; }
2950 private:
2951 size_t push_properties_count_;
2953 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
2954 : LayerImpl(tree_impl, id),
2955 push_properties_count_(0) {
2956 SetBounds(gfx::Size(1, 1));
2960 class PushPropertiesCountingLayer : public Layer {
2961 public:
2962 static scoped_refptr<PushPropertiesCountingLayer> Create() {
2963 return new PushPropertiesCountingLayer();
2966 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
2967 Layer::PushPropertiesTo(layer);
2968 push_properties_count_++;
2969 if (persist_needs_push_properties_)
2970 needs_push_properties_ = true;
2973 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
2974 OVERRIDE {
2975 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
2976 PassAs<LayerImpl>();
2979 size_t push_properties_count() const { return push_properties_count_; }
2980 void reset_push_properties_count() { push_properties_count_ = 0; }
2982 void set_persist_needs_push_properties(bool persist) {
2983 persist_needs_push_properties_ = persist;
2986 private:
2987 PushPropertiesCountingLayer()
2988 : push_properties_count_(0), persist_needs_push_properties_(false) {
2989 SetBounds(gfx::Size(1, 1));
2990 SetIsDrawable(true);
2992 virtual ~PushPropertiesCountingLayer() {}
2994 size_t push_properties_count_;
2995 bool persist_needs_push_properties_;
2998 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
2999 protected:
3000 virtual void BeginTest() OVERRIDE {
3001 num_commits_ = 0;
3002 expected_push_properties_root_ = 0;
3003 expected_push_properties_child_ = 0;
3004 expected_push_properties_grandchild_ = 0;
3005 expected_push_properties_child2_ = 0;
3006 expected_push_properties_other_root_ = 0;
3007 expected_push_properties_leaf_layer_ = 0;
3008 PostSetNeedsCommitToMainThread();
3011 virtual void SetupTree() OVERRIDE {
3012 root_ = PushPropertiesCountingLayer::Create();
3013 child_ = PushPropertiesCountingLayer::Create();
3014 child2_ = PushPropertiesCountingLayer::Create();
3015 grandchild_ = PushPropertiesCountingLayer::Create();
3016 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3017 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3019 root_->AddChild(child_);
3020 root_->AddChild(child2_);
3021 child_->AddChild(grandchild_);
3022 child2_->AddChild(leaf_always_pushing_layer_);
3024 other_root_ = PushPropertiesCountingLayer::Create();
3026 // Don't set the root layer here.
3027 LayerTreeHostTest::SetupTree();
3030 virtual void DidCommitAndDrawFrame() OVERRIDE {
3031 ++num_commits_;
3033 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3034 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3035 EXPECT_EQ(expected_push_properties_grandchild_,
3036 grandchild_->push_properties_count());
3037 EXPECT_EQ(expected_push_properties_child2_,
3038 child2_->push_properties_count());
3039 EXPECT_EQ(expected_push_properties_other_root_,
3040 other_root_->push_properties_count());
3041 EXPECT_EQ(expected_push_properties_leaf_layer_,
3042 leaf_always_pushing_layer_->push_properties_count());
3044 // The scrollbar layer always needs to be pushed.
3045 if (root_->layer_tree_host()) {
3046 EXPECT_TRUE(root_->descendant_needs_push_properties());
3047 EXPECT_FALSE(root_->needs_push_properties());
3049 if (child2_->layer_tree_host()) {
3050 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3051 EXPECT_FALSE(child2_->needs_push_properties());
3053 if (leaf_always_pushing_layer_->layer_tree_host()) {
3054 EXPECT_FALSE(
3055 leaf_always_pushing_layer_->descendant_needs_push_properties());
3056 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3059 // child_ and grandchild_ don't persist their need to push properties.
3060 if (child_->layer_tree_host()) {
3061 EXPECT_FALSE(child_->descendant_needs_push_properties());
3062 EXPECT_FALSE(child_->needs_push_properties());
3064 if (grandchild_->layer_tree_host()) {
3065 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3066 EXPECT_FALSE(grandchild_->needs_push_properties());
3069 if (other_root_->layer_tree_host()) {
3070 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3071 EXPECT_FALSE(other_root_->needs_push_properties());
3074 switch (num_commits_) {
3075 case 1:
3076 layer_tree_host()->SetRootLayer(root_);
3077 // Layers added to the tree get committed.
3078 ++expected_push_properties_root_;
3079 ++expected_push_properties_child_;
3080 ++expected_push_properties_grandchild_;
3081 ++expected_push_properties_child2_;
3082 break;
3083 case 2:
3084 layer_tree_host()->SetNeedsCommit();
3085 // No layers need commit.
3086 break;
3087 case 3:
3088 layer_tree_host()->SetRootLayer(other_root_);
3089 // Layers added to the tree get committed.
3090 ++expected_push_properties_other_root_;
3091 break;
3092 case 4:
3093 layer_tree_host()->SetRootLayer(root_);
3094 // Layers added to the tree get committed.
3095 ++expected_push_properties_root_;
3096 ++expected_push_properties_child_;
3097 ++expected_push_properties_grandchild_;
3098 ++expected_push_properties_child2_;
3099 break;
3100 case 5:
3101 layer_tree_host()->SetNeedsCommit();
3102 // No layers need commit.
3103 break;
3104 case 6:
3105 child_->RemoveFromParent();
3106 // No layers need commit.
3107 break;
3108 case 7:
3109 root_->AddChild(child_);
3110 // Layers added to the tree get committed.
3111 ++expected_push_properties_child_;
3112 ++expected_push_properties_grandchild_;
3113 break;
3114 case 8:
3115 grandchild_->RemoveFromParent();
3116 // No layers need commit.
3117 break;
3118 case 9:
3119 child_->AddChild(grandchild_);
3120 // Layers added to the tree get committed.
3121 ++expected_push_properties_grandchild_;
3122 break;
3123 case 10:
3124 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3125 // No layers need commit.
3126 break;
3127 case 11:
3128 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3129 // No layers need commit.
3130 break;
3131 case 12:
3132 child_->SetPosition(gfx::Point(1, 1));
3133 // The modified layer needs commit
3134 ++expected_push_properties_child_;
3135 break;
3136 case 13:
3137 child2_->SetPosition(gfx::Point(1, 1));
3138 // The modified layer needs commit
3139 ++expected_push_properties_child2_;
3140 break;
3141 case 14:
3142 child_->RemoveFromParent();
3143 root_->AddChild(child_);
3144 // Layers added to the tree get committed.
3145 ++expected_push_properties_child_;
3146 ++expected_push_properties_grandchild_;
3147 break;
3148 case 15:
3149 grandchild_->SetPosition(gfx::Point(1, 1));
3150 // The modified layer needs commit
3151 ++expected_push_properties_grandchild_;
3152 break;
3153 case 16:
3154 // SetNeedsDisplay does not always set needs commit (so call it
3155 // explicitly), but is a property change.
3156 child_->SetNeedsDisplay();
3157 ++expected_push_properties_child_;
3158 layer_tree_host()->SetNeedsCommit();
3159 break;
3160 case 17:
3161 EndTest();
3162 break;
3165 // The leaf layer always pushes.
3166 if (leaf_always_pushing_layer_->layer_tree_host())
3167 ++expected_push_properties_leaf_layer_;
3170 virtual void AfterTest() OVERRIDE {}
3172 int num_commits_;
3173 FakeContentLayerClient client_;
3174 scoped_refptr<PushPropertiesCountingLayer> root_;
3175 scoped_refptr<PushPropertiesCountingLayer> child_;
3176 scoped_refptr<PushPropertiesCountingLayer> child2_;
3177 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3178 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3179 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3180 size_t expected_push_properties_root_;
3181 size_t expected_push_properties_child_;
3182 size_t expected_push_properties_child2_;
3183 size_t expected_push_properties_grandchild_;
3184 size_t expected_push_properties_other_root_;
3185 size_t expected_push_properties_leaf_layer_;
3188 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3190 class LayerTreeHostTestImplLayersPushProperties
3191 : public LayerTreeHostTestLayersPushProperties {
3192 protected:
3193 virtual void BeginTest() OVERRIDE {
3194 expected_push_properties_root_impl_ = 0;
3195 expected_push_properties_child_impl_ = 0;
3196 expected_push_properties_grandchild_impl_ = 0;
3197 expected_push_properties_child2_impl_ = 0;
3198 expected_push_properties_grandchild2_impl_ = 0;
3199 LayerTreeHostTestLayersPushProperties::BeginTest();
3202 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3203 // These commits are in response to the changes made in
3204 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3205 switch (num_commits_) {
3206 case 0:
3207 // Tree hasn't been setup yet don't bother to check anything.
3208 return;
3209 case 1:
3210 // Root gets set up, Everyone is initialized.
3211 ++expected_push_properties_root_impl_;
3212 ++expected_push_properties_child_impl_;
3213 ++expected_push_properties_grandchild_impl_;
3214 ++expected_push_properties_child2_impl_;
3215 ++expected_push_properties_grandchild2_impl_;
3216 break;
3217 case 2:
3218 // Tree doesn't change but the one leaf that always pushes is pushed.
3219 ++expected_push_properties_grandchild2_impl_;
3220 break;
3221 case 3:
3222 // Root is swapped here.
3223 // Clear the expected push properties the tree will be rebuilt.
3224 expected_push_properties_root_impl_ = 0;
3225 expected_push_properties_child_impl_ = 0;
3226 expected_push_properties_grandchild_impl_ = 0;
3227 expected_push_properties_child2_impl_ = 0;
3228 expected_push_properties_grandchild2_impl_ = 0;
3230 // Make sure the new root is pushed.
3231 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3232 host_impl->RootLayer())->push_properties_count());
3233 return;
3234 case 4:
3235 // Root is swapped back all of the layers in the tree get pushed.
3236 ++expected_push_properties_root_impl_;
3237 ++expected_push_properties_child_impl_;
3238 ++expected_push_properties_grandchild_impl_;
3239 ++expected_push_properties_child2_impl_;
3240 ++expected_push_properties_grandchild2_impl_;
3241 break;
3242 case 5:
3243 // Tree doesn't change but the one leaf that always pushes is pushed.
3244 ++expected_push_properties_grandchild2_impl_;
3245 break;
3246 case 6:
3247 // First child is removed. Structure of the tree changes here so swap
3248 // some of the values. child_impl becomes child2_impl.
3249 expected_push_properties_child_impl_ =
3250 expected_push_properties_child2_impl_;
3251 expected_push_properties_child2_impl_ = 0;
3252 // grandchild_impl becomes grandchild2_impl.
3253 expected_push_properties_grandchild_impl_ =
3254 expected_push_properties_grandchild2_impl_;
3255 expected_push_properties_grandchild2_impl_ = 0;
3257 // grandchild_impl is now the leaf that always pushes. It is pushed.
3258 ++expected_push_properties_grandchild_impl_;
3259 break;
3260 case 7:
3261 // The leaf that always pushes is pushed.
3262 ++expected_push_properties_grandchild_impl_;
3264 // Child is added back. New layers are initialized.
3265 ++expected_push_properties_grandchild2_impl_;
3266 ++expected_push_properties_child2_impl_;
3267 break;
3268 case 8:
3269 // Leaf is removed.
3270 expected_push_properties_grandchild2_impl_ = 0;
3272 // Always pushing.
3273 ++expected_push_properties_grandchild_impl_;
3274 break;
3275 case 9:
3276 // Leaf is added back
3277 ++expected_push_properties_grandchild2_impl_;
3279 // The leaf that always pushes is pushed.
3280 ++expected_push_properties_grandchild_impl_;
3281 break;
3282 case 10:
3283 // The leaf that always pushes is pushed.
3284 ++expected_push_properties_grandchild_impl_;
3285 break;
3286 case 11:
3287 // The leaf that always pushes is pushed.
3288 ++expected_push_properties_grandchild_impl_;
3289 break;
3290 case 12:
3291 // The leaf that always pushes is pushed.
3292 ++expected_push_properties_grandchild_impl_;
3294 // This child position was changed.
3295 ++expected_push_properties_child2_impl_;
3296 break;
3297 case 13:
3298 // The position of this child was changed.
3299 ++expected_push_properties_child_impl_;
3301 // The leaf that always pushes is pushed.
3302 ++expected_push_properties_grandchild_impl_;
3303 break;
3304 case 14:
3305 // Second child is removed from tree. Don't discard counts because
3306 // they are added back before commit.
3308 // The leaf that always pushes is pushed.
3309 ++expected_push_properties_grandchild_impl_;
3311 // Second child added back.
3312 ++expected_push_properties_child2_impl_;
3313 ++expected_push_properties_grandchild2_impl_;
3315 break;
3316 case 15:
3317 // The position of this child was changed.
3318 ++expected_push_properties_grandchild2_impl_;
3320 // The leaf that always pushes is pushed.
3321 ++expected_push_properties_grandchild_impl_;
3322 break;
3323 case 16:
3324 // Second child is invalidated with SetNeedsDisplay
3325 ++expected_push_properties_child2_impl_;
3327 // The leaf that always pushed is pushed.
3328 ++expected_push_properties_grandchild_impl_;
3329 break;
3332 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3333 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3334 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3335 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3336 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3338 // Pull the layers that we need from the tree assuming the same structure
3339 // as LayerTreeHostTestLayersPushProperties
3340 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3341 host_impl->RootLayer());
3343 if (root_impl_ && root_impl_->children().size() > 0) {
3344 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3345 root_impl_->children()[0]);
3347 if (child_impl_ && child_impl_->children().size() > 0)
3348 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3349 child_impl_->children()[0]);
3352 if (root_impl_ && root_impl_->children().size() > 1) {
3353 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3354 root_impl_->children()[1]);
3356 if (child2_impl_ && child2_impl_->children().size() > 0)
3357 leaf_always_pushing_layer_impl_ =
3358 static_cast<PushPropertiesCountingLayerImpl*>(
3359 child2_impl_->children()[0]);
3362 if (root_impl_)
3363 EXPECT_EQ(expected_push_properties_root_impl_,
3364 root_impl_->push_properties_count());
3365 if (child_impl_)
3366 EXPECT_EQ(expected_push_properties_child_impl_,
3367 child_impl_->push_properties_count());
3368 if (grandchild_impl_)
3369 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3370 grandchild_impl_->push_properties_count());
3371 if (child2_impl_)
3372 EXPECT_EQ(expected_push_properties_child2_impl_,
3373 child2_impl_->push_properties_count());
3374 if (leaf_always_pushing_layer_impl_)
3375 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3376 leaf_always_pushing_layer_impl_->push_properties_count());
3379 size_t expected_push_properties_root_impl_;
3380 size_t expected_push_properties_child_impl_;
3381 size_t expected_push_properties_child2_impl_;
3382 size_t expected_push_properties_grandchild_impl_;
3383 size_t expected_push_properties_grandchild2_impl_;
3386 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3387 RunTestWithImplSidePainting();
3390 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3391 : public LayerTreeHostTest {
3392 protected:
3393 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3395 virtual void SetupTree() OVERRIDE {
3396 root_ = Layer::Create();
3397 root_->SetBounds(gfx::Size(1, 1));
3399 bool paint_scrollbar = true;
3400 bool has_thumb = false;
3401 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3402 paint_scrollbar, has_thumb, root_->id());
3404 root_->AddChild(scrollbar_layer_);
3406 layer_tree_host()->SetRootLayer(root_);
3407 LayerTreeHostTest::SetupTree();
3410 virtual void DidCommitAndDrawFrame() OVERRIDE {
3411 switch (layer_tree_host()->source_frame_number()) {
3412 case 0:
3413 break;
3414 case 1: {
3415 // During update, the ignore_set_needs_commit_ bit is set to true to
3416 // avoid causing a second commit to be scheduled. If a property change
3417 // is made during this, however, it needs to be pushed in the upcoming
3418 // commit.
3419 scoped_ptr<base::AutoReset<bool> > ignore =
3420 scrollbar_layer_->IgnoreSetNeedsCommit();
3422 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3424 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3425 EXPECT_TRUE(root_->descendant_needs_push_properties());
3426 layer_tree_host()->SetNeedsCommit();
3428 scrollbar_layer_->reset_push_properties_count();
3429 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3430 break;
3432 case 2:
3433 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3434 EndTest();
3435 break;
3439 virtual void AfterTest() OVERRIDE {}
3441 scoped_refptr<Layer> root_;
3442 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3445 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3447 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3448 : public LayerTreeHostTest {
3449 protected:
3450 virtual void BeginTest() OVERRIDE {
3451 expected_push_properties_root_ = 0;
3452 expected_push_properties_child_ = 0;
3453 expected_push_properties_grandchild1_ = 0;
3454 expected_push_properties_grandchild2_ = 0;
3455 expected_push_properties_grandchild3_ = 0;
3456 PostSetNeedsCommitToMainThread();
3459 virtual void SetupTree() OVERRIDE {
3460 root_ = PushPropertiesCountingLayer::Create();
3461 child_ = PushPropertiesCountingLayer::Create();
3462 grandchild1_ = PushPropertiesCountingLayer::Create();
3463 grandchild2_ = PushPropertiesCountingLayer::Create();
3464 grandchild3_ = PushPropertiesCountingLayer::Create();
3466 root_->AddChild(child_);
3467 child_->AddChild(grandchild1_);
3468 child_->AddChild(grandchild2_);
3469 child_->AddChild(grandchild3_);
3471 // Don't set the root layer here.
3472 LayerTreeHostTest::SetupTree();
3475 virtual void AfterTest() OVERRIDE {}
3477 FakeContentLayerClient client_;
3478 scoped_refptr<PushPropertiesCountingLayer> root_;
3479 scoped_refptr<PushPropertiesCountingLayer> child_;
3480 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3481 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3482 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3483 size_t expected_push_properties_root_;
3484 size_t expected_push_properties_child_;
3485 size_t expected_push_properties_grandchild1_;
3486 size_t expected_push_properties_grandchild2_;
3487 size_t expected_push_properties_grandchild3_;
3490 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3491 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3492 protected:
3493 virtual void DidCommitAndDrawFrame() OVERRIDE {
3494 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3495 switch (last_source_frame_number) {
3496 case 0:
3497 EXPECT_FALSE(root_->needs_push_properties());
3498 EXPECT_FALSE(root_->descendant_needs_push_properties());
3499 EXPECT_FALSE(child_->needs_push_properties());
3500 EXPECT_FALSE(child_->descendant_needs_push_properties());
3501 EXPECT_FALSE(grandchild1_->needs_push_properties());
3502 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3503 EXPECT_FALSE(grandchild2_->needs_push_properties());
3504 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3505 EXPECT_FALSE(grandchild3_->needs_push_properties());
3506 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3508 layer_tree_host()->SetRootLayer(root_);
3510 EXPECT_TRUE(root_->needs_push_properties());
3511 EXPECT_TRUE(root_->descendant_needs_push_properties());
3512 EXPECT_TRUE(child_->needs_push_properties());
3513 EXPECT_TRUE(child_->descendant_needs_push_properties());
3514 EXPECT_TRUE(grandchild1_->needs_push_properties());
3515 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3516 EXPECT_TRUE(grandchild2_->needs_push_properties());
3517 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3518 EXPECT_TRUE(grandchild3_->needs_push_properties());
3519 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3520 break;
3521 case 1:
3522 EndTest();
3523 break;
3528 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3530 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3531 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3532 protected:
3533 virtual void DidCommitAndDrawFrame() OVERRIDE {
3534 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3535 switch (last_source_frame_number) {
3536 case 0:
3537 layer_tree_host()->SetRootLayer(root_);
3538 break;
3539 case 1:
3540 EXPECT_FALSE(root_->needs_push_properties());
3541 EXPECT_FALSE(root_->descendant_needs_push_properties());
3542 EXPECT_FALSE(child_->needs_push_properties());
3543 EXPECT_FALSE(child_->descendant_needs_push_properties());
3544 EXPECT_FALSE(grandchild1_->needs_push_properties());
3545 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3546 EXPECT_FALSE(grandchild2_->needs_push_properties());
3547 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3548 EXPECT_FALSE(grandchild3_->needs_push_properties());
3549 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3551 grandchild1_->RemoveFromParent();
3552 grandchild1_->SetPosition(gfx::Point(1, 1));
3554 EXPECT_FALSE(root_->needs_push_properties());
3555 EXPECT_FALSE(root_->descendant_needs_push_properties());
3556 EXPECT_FALSE(child_->needs_push_properties());
3557 EXPECT_FALSE(child_->descendant_needs_push_properties());
3558 EXPECT_FALSE(grandchild2_->needs_push_properties());
3559 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3560 EXPECT_FALSE(grandchild3_->needs_push_properties());
3561 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3563 child_->AddChild(grandchild1_);
3565 EXPECT_FALSE(root_->needs_push_properties());
3566 EXPECT_TRUE(root_->descendant_needs_push_properties());
3567 EXPECT_FALSE(child_->needs_push_properties());
3568 EXPECT_TRUE(child_->descendant_needs_push_properties());
3569 EXPECT_TRUE(grandchild1_->needs_push_properties());
3570 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3571 EXPECT_FALSE(grandchild2_->needs_push_properties());
3572 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3573 EXPECT_FALSE(grandchild3_->needs_push_properties());
3574 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3576 grandchild2_->SetPosition(gfx::Point(1, 1));
3578 EXPECT_FALSE(root_->needs_push_properties());
3579 EXPECT_TRUE(root_->descendant_needs_push_properties());
3580 EXPECT_FALSE(child_->needs_push_properties());
3581 EXPECT_TRUE(child_->descendant_needs_push_properties());
3582 EXPECT_TRUE(grandchild1_->needs_push_properties());
3583 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3584 EXPECT_TRUE(grandchild2_->needs_push_properties());
3585 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3586 EXPECT_FALSE(grandchild3_->needs_push_properties());
3587 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3589 // grandchild2_ will still need a push properties.
3590 grandchild1_->RemoveFromParent();
3592 EXPECT_FALSE(root_->needs_push_properties());
3593 EXPECT_TRUE(root_->descendant_needs_push_properties());
3594 EXPECT_FALSE(child_->needs_push_properties());
3595 EXPECT_TRUE(child_->descendant_needs_push_properties());
3597 // grandchild3_ does not need a push properties, so recursing should
3598 // no longer be needed.
3599 grandchild2_->RemoveFromParent();
3601 EXPECT_FALSE(root_->needs_push_properties());
3602 EXPECT_FALSE(root_->descendant_needs_push_properties());
3603 EXPECT_FALSE(child_->needs_push_properties());
3604 EXPECT_FALSE(child_->descendant_needs_push_properties());
3605 EndTest();
3606 break;
3611 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3613 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3614 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3615 protected:
3616 virtual void DidCommitAndDrawFrame() OVERRIDE {
3617 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3618 switch (last_source_frame_number) {
3619 case 0:
3620 layer_tree_host()->SetRootLayer(root_);
3621 grandchild1_->set_persist_needs_push_properties(true);
3622 grandchild2_->set_persist_needs_push_properties(true);
3623 break;
3624 case 1:
3625 EXPECT_FALSE(root_->needs_push_properties());
3626 EXPECT_TRUE(root_->descendant_needs_push_properties());
3627 EXPECT_FALSE(child_->needs_push_properties());
3628 EXPECT_TRUE(child_->descendant_needs_push_properties());
3629 EXPECT_TRUE(grandchild1_->needs_push_properties());
3630 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3631 EXPECT_TRUE(grandchild2_->needs_push_properties());
3632 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3633 EXPECT_FALSE(grandchild3_->needs_push_properties());
3634 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3636 // grandchild2_ will still need a push properties.
3637 grandchild1_->RemoveFromParent();
3639 EXPECT_FALSE(root_->needs_push_properties());
3640 EXPECT_TRUE(root_->descendant_needs_push_properties());
3641 EXPECT_FALSE(child_->needs_push_properties());
3642 EXPECT_TRUE(child_->descendant_needs_push_properties());
3644 // grandchild3_ does not need a push properties, so recursing should
3645 // no longer be needed.
3646 grandchild2_->RemoveFromParent();
3648 EXPECT_FALSE(root_->needs_push_properties());
3649 EXPECT_FALSE(root_->descendant_needs_push_properties());
3650 EXPECT_FALSE(child_->needs_push_properties());
3651 EXPECT_FALSE(child_->descendant_needs_push_properties());
3652 EndTest();
3653 break;
3658 MULTI_THREAD_TEST_F(
3659 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3661 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3662 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3663 protected:
3664 virtual void DidCommitAndDrawFrame() OVERRIDE {
3665 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3666 switch (last_source_frame_number) {
3667 case 0:
3668 layer_tree_host()->SetRootLayer(root_);
3669 break;
3670 case 1:
3671 EXPECT_FALSE(root_->needs_push_properties());
3672 EXPECT_FALSE(root_->descendant_needs_push_properties());
3673 EXPECT_FALSE(child_->needs_push_properties());
3674 EXPECT_FALSE(child_->descendant_needs_push_properties());
3675 EXPECT_FALSE(grandchild1_->needs_push_properties());
3676 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3677 EXPECT_FALSE(grandchild2_->needs_push_properties());
3678 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3679 EXPECT_FALSE(grandchild3_->needs_push_properties());
3680 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3682 // Change grandchildren while their parent is not in the tree.
3683 child_->RemoveFromParent();
3684 grandchild1_->SetPosition(gfx::Point(1, 1));
3685 grandchild2_->SetPosition(gfx::Point(1, 1));
3686 root_->AddChild(child_);
3688 EXPECT_FALSE(root_->needs_push_properties());
3689 EXPECT_TRUE(root_->descendant_needs_push_properties());
3690 EXPECT_TRUE(child_->needs_push_properties());
3691 EXPECT_TRUE(child_->descendant_needs_push_properties());
3692 EXPECT_TRUE(grandchild1_->needs_push_properties());
3693 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3694 EXPECT_TRUE(grandchild2_->needs_push_properties());
3695 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3696 EXPECT_TRUE(grandchild3_->needs_push_properties());
3697 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3699 grandchild1_->RemoveFromParent();
3701 EXPECT_FALSE(root_->needs_push_properties());
3702 EXPECT_TRUE(root_->descendant_needs_push_properties());
3703 EXPECT_TRUE(child_->needs_push_properties());
3704 EXPECT_TRUE(child_->descendant_needs_push_properties());
3706 grandchild2_->RemoveFromParent();
3708 EXPECT_FALSE(root_->needs_push_properties());
3709 EXPECT_TRUE(root_->descendant_needs_push_properties());
3710 EXPECT_TRUE(child_->needs_push_properties());
3711 EXPECT_TRUE(child_->descendant_needs_push_properties());
3713 grandchild3_->RemoveFromParent();
3715 EXPECT_FALSE(root_->needs_push_properties());
3716 EXPECT_TRUE(root_->descendant_needs_push_properties());
3717 EXPECT_TRUE(child_->needs_push_properties());
3718 EXPECT_FALSE(child_->descendant_needs_push_properties());
3720 EndTest();
3721 break;
3726 MULTI_THREAD_TEST_F(
3727 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3729 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3730 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3731 protected:
3732 virtual void DidCommitAndDrawFrame() OVERRIDE {
3733 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3734 switch (last_source_frame_number) {
3735 case 0:
3736 layer_tree_host()->SetRootLayer(root_);
3737 break;
3738 case 1:
3739 EXPECT_FALSE(root_->needs_push_properties());
3740 EXPECT_FALSE(root_->descendant_needs_push_properties());
3741 EXPECT_FALSE(child_->needs_push_properties());
3742 EXPECT_FALSE(child_->descendant_needs_push_properties());
3743 EXPECT_FALSE(grandchild1_->needs_push_properties());
3744 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3745 EXPECT_FALSE(grandchild2_->needs_push_properties());
3746 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3747 EXPECT_FALSE(grandchild3_->needs_push_properties());
3748 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3750 child_->SetPosition(gfx::Point(1, 1));
3751 grandchild1_->SetPosition(gfx::Point(1, 1));
3752 grandchild2_->SetPosition(gfx::Point(1, 1));
3754 EXPECT_FALSE(root_->needs_push_properties());
3755 EXPECT_TRUE(root_->descendant_needs_push_properties());
3756 EXPECT_TRUE(child_->needs_push_properties());
3757 EXPECT_TRUE(child_->descendant_needs_push_properties());
3758 EXPECT_TRUE(grandchild1_->needs_push_properties());
3759 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3760 EXPECT_TRUE(grandchild2_->needs_push_properties());
3761 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3762 EXPECT_FALSE(grandchild3_->needs_push_properties());
3763 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3765 grandchild1_->RemoveFromParent();
3767 EXPECT_FALSE(root_->needs_push_properties());
3768 EXPECT_TRUE(root_->descendant_needs_push_properties());
3769 EXPECT_TRUE(child_->needs_push_properties());
3770 EXPECT_TRUE(child_->descendant_needs_push_properties());
3772 grandchild2_->RemoveFromParent();
3774 EXPECT_FALSE(root_->needs_push_properties());
3775 EXPECT_TRUE(root_->descendant_needs_push_properties());
3776 EXPECT_TRUE(child_->needs_push_properties());
3777 EXPECT_FALSE(child_->descendant_needs_push_properties());
3779 child_->RemoveFromParent();
3781 EXPECT_FALSE(root_->needs_push_properties());
3782 EXPECT_FALSE(root_->descendant_needs_push_properties());
3784 EndTest();
3785 break;
3790 MULTI_THREAD_TEST_F(
3791 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
3793 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
3794 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3795 protected:
3796 virtual void DidCommitAndDrawFrame() OVERRIDE {
3797 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3798 switch (last_source_frame_number) {
3799 case 0:
3800 layer_tree_host()->SetRootLayer(root_);
3801 break;
3802 case 1:
3803 EXPECT_FALSE(root_->needs_push_properties());
3804 EXPECT_FALSE(root_->descendant_needs_push_properties());
3805 EXPECT_FALSE(child_->needs_push_properties());
3806 EXPECT_FALSE(child_->descendant_needs_push_properties());
3807 EXPECT_FALSE(grandchild1_->needs_push_properties());
3808 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3809 EXPECT_FALSE(grandchild2_->needs_push_properties());
3810 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3811 EXPECT_FALSE(grandchild3_->needs_push_properties());
3812 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3814 grandchild1_->SetPosition(gfx::Point(1, 1));
3815 grandchild2_->SetPosition(gfx::Point(1, 1));
3816 child_->SetPosition(gfx::Point(1, 1));
3818 EXPECT_FALSE(root_->needs_push_properties());
3819 EXPECT_TRUE(root_->descendant_needs_push_properties());
3820 EXPECT_TRUE(child_->needs_push_properties());
3821 EXPECT_TRUE(child_->descendant_needs_push_properties());
3822 EXPECT_TRUE(grandchild1_->needs_push_properties());
3823 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3824 EXPECT_TRUE(grandchild2_->needs_push_properties());
3825 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3826 EXPECT_FALSE(grandchild3_->needs_push_properties());
3827 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3829 grandchild1_->RemoveFromParent();
3831 EXPECT_FALSE(root_->needs_push_properties());
3832 EXPECT_TRUE(root_->descendant_needs_push_properties());
3833 EXPECT_TRUE(child_->needs_push_properties());
3834 EXPECT_TRUE(child_->descendant_needs_push_properties());
3836 grandchild2_->RemoveFromParent();
3838 EXPECT_FALSE(root_->needs_push_properties());
3839 EXPECT_TRUE(root_->descendant_needs_push_properties());
3840 EXPECT_TRUE(child_->needs_push_properties());
3841 EXPECT_FALSE(child_->descendant_needs_push_properties());
3843 child_->RemoveFromParent();
3845 EXPECT_FALSE(root_->needs_push_properties());
3846 EXPECT_FALSE(root_->descendant_needs_push_properties());
3848 EndTest();
3849 break;
3854 MULTI_THREAD_TEST_F(
3855 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
3857 // This test verifies that the tree activation callback is invoked correctly.
3858 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
3859 public:
3860 LayerTreeHostTestTreeActivationCallback()
3861 : num_commits_(0), callback_count_(0) {}
3863 virtual void BeginTest() OVERRIDE {
3864 EXPECT_TRUE(HasImplThread());
3865 PostSetNeedsCommitToMainThread();
3868 virtual DrawResult PrepareToDrawOnThread(
3869 LayerTreeHostImpl* host_impl,
3870 LayerTreeHostImpl::FrameData* frame_data,
3871 DrawResult draw_result) OVERRIDE {
3872 ++num_commits_;
3873 switch (num_commits_) {
3874 case 1:
3875 EXPECT_EQ(0, callback_count_);
3876 callback_count_ = 0;
3877 SetCallback(true);
3878 PostSetNeedsCommitToMainThread();
3879 break;
3880 case 2:
3881 EXPECT_EQ(1, callback_count_);
3882 callback_count_ = 0;
3883 SetCallback(false);
3884 PostSetNeedsCommitToMainThread();
3885 break;
3886 case 3:
3887 EXPECT_EQ(0, callback_count_);
3888 callback_count_ = 0;
3889 EndTest();
3890 break;
3891 default:
3892 ADD_FAILURE() << num_commits_;
3893 EndTest();
3894 break;
3896 return LayerTreeHostTest::PrepareToDrawOnThread(
3897 host_impl, frame_data, draw_result);
3900 virtual void AfterTest() OVERRIDE { EXPECT_EQ(3, num_commits_); }
3902 void SetCallback(bool enable) {
3903 output_surface()->SetTreeActivationCallback(
3904 enable
3905 ? base::Bind(
3906 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
3907 base::Unretained(this))
3908 : base::Closure());
3911 void ActivationCallback() { ++callback_count_; }
3913 int num_commits_;
3914 int callback_count_;
3917 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
3918 RunTest(true, false, true);
3921 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
3922 RunTest(true, true, true);
3925 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
3926 public:
3927 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
3929 virtual void BeginTest() OVERRIDE {
3930 ASSERT_TRUE(!!invalidate_layer_)
3931 << "Derived tests must set this in SetupTree";
3933 // One initial commit.
3934 PostSetNeedsCommitToMainThread();
3937 virtual void DidCommitAndDrawFrame() OVERRIDE {
3938 // After commit, invalidate the layer. This should cause a commit.
3939 if (layer_tree_host()->source_frame_number() == 1)
3940 invalidate_layer_->SetNeedsDisplay();
3943 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3944 num_draws_++;
3945 if (impl->active_tree()->source_frame_number() == 1)
3946 EndTest();
3949 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3950 num_commits_++;
3953 virtual void AfterTest() OVERRIDE {
3954 EXPECT_GE(2, num_commits_);
3955 EXPECT_GE(2, num_draws_);
3958 protected:
3959 scoped_refptr<Layer> invalidate_layer_;
3961 private:
3962 int num_commits_;
3963 int num_draws_;
3966 // VideoLayer must support being invalidated and then passing that along
3967 // to the compositor thread, even though no resources are updated in
3968 // response to that invalidation.
3969 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
3970 public:
3971 virtual void SetupTree() OVERRIDE {
3972 LayerTreeHostTest::SetupTree();
3973 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
3974 video_layer->SetBounds(gfx::Size(10, 10));
3975 video_layer->SetIsDrawable(true);
3976 layer_tree_host()->root_layer()->AddChild(video_layer);
3978 invalidate_layer_ = video_layer;
3981 private:
3982 FakeVideoFrameProvider provider_;
3985 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
3987 // IOSurfaceLayer must support being invalidated and then passing that along
3988 // to the compositor thread, even though no resources are updated in
3989 // response to that invalidation.
3990 class LayerTreeHostTestIOSurfaceLayerInvalidate
3991 : public LayerInvalidateCausesDraw {
3992 public:
3993 virtual void SetupTree() OVERRIDE {
3994 LayerTreeHostTest::SetupTree();
3995 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
3996 layer->SetBounds(gfx::Size(10, 10));
3997 uint32_t fake_io_surface_id = 7;
3998 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
3999 layer->SetIsDrawable(true);
4000 layer_tree_host()->root_layer()->AddChild(layer);
4002 invalidate_layer_ = layer;
4006 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4007 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4008 LayerTreeHostTestIOSurfaceLayerInvalidate);
4010 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4011 protected:
4012 virtual void SetupTree() OVERRIDE {
4013 root_layer_ = Layer::Create();
4014 root_layer_->SetPosition(gfx::Point());
4015 root_layer_->SetBounds(gfx::Size(10, 10));
4017 parent_layer_ = SolidColorLayer::Create();
4018 parent_layer_->SetPosition(gfx::Point());
4019 parent_layer_->SetBounds(gfx::Size(10, 10));
4020 parent_layer_->SetIsDrawable(true);
4021 root_layer_->AddChild(parent_layer_);
4023 child_layer_ = SolidColorLayer::Create();
4024 child_layer_->SetPosition(gfx::Point());
4025 child_layer_->SetBounds(gfx::Size(10, 10));
4026 child_layer_->SetIsDrawable(true);
4027 parent_layer_->AddChild(child_layer_);
4029 layer_tree_host()->SetRootLayer(root_layer_);
4030 LayerTreeHostTest::SetupTree();
4033 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4035 virtual void DidCommitAndDrawFrame() OVERRIDE {
4036 switch (layer_tree_host()->source_frame_number()) {
4037 case 1:
4038 // The layer type used does not need to push properties every frame.
4039 EXPECT_FALSE(child_layer_->needs_push_properties());
4041 // Change the bounds of the child layer, but make it skipped
4042 // by CalculateDrawProperties.
4043 parent_layer_->SetOpacity(0.f);
4044 child_layer_->SetBounds(gfx::Size(5, 5));
4045 break;
4046 case 2:
4047 // The bounds of the child layer were pushed to the impl side.
4048 EXPECT_FALSE(child_layer_->needs_push_properties());
4050 EndTest();
4051 break;
4055 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4056 LayerImpl* root = impl->active_tree()->root_layer();
4057 LayerImpl* parent = root->children()[0];
4058 LayerImpl* child = parent->children()[0];
4060 switch (impl->active_tree()->source_frame_number()) {
4061 case 1:
4062 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4063 break;
4067 virtual void AfterTest() OVERRIDE {}
4069 scoped_refptr<Layer> root_layer_;
4070 scoped_refptr<SolidColorLayer> parent_layer_;
4071 scoped_refptr<SolidColorLayer> child_layer_;
4074 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4076 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4077 protected:
4078 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4079 settings->impl_side_painting = true;
4082 virtual void SetupTree() OVERRIDE {
4083 root_layer_ = FakePictureLayer::Create(&client_);
4084 root_layer_->SetBounds(gfx::Size(10, 10));
4086 layer_tree_host()->SetRootLayer(root_layer_);
4087 LayerTreeHostTest::SetupTree();
4090 virtual void BeginTest() OVERRIDE {
4091 // The viewport is empty, but we still need to update layers on the main
4092 // thread.
4093 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4094 PostSetNeedsCommitToMainThread();
4097 virtual void DidCommit() OVERRIDE {
4098 // The layer should be updated even though the viewport is empty, so we
4099 // are capable of drawing it on the impl tree.
4100 EXPECT_GT(root_layer_->update_count(), 0u);
4101 EndTest();
4104 virtual void AfterTest() OVERRIDE {}
4106 FakeContentLayerClient client_;
4107 scoped_refptr<FakePictureLayer> root_layer_;
4110 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4112 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4113 public:
4114 LayerTreeHostTestAbortEvictedTextures()
4115 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4117 protected:
4118 virtual void SetupTree() OVERRIDE {
4119 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4120 root_layer->SetBounds(gfx::Size(200, 200));
4121 root_layer->SetIsDrawable(true);
4123 layer_tree_host()->SetRootLayer(root_layer);
4124 LayerTreeHostTest::SetupTree();
4127 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4129 virtual void WillBeginMainFrame() OVERRIDE {
4130 num_will_begin_main_frames_++;
4131 switch (num_will_begin_main_frames_) {
4132 case 2:
4133 // Send a redraw to the compositor thread. This will (wrongly) be
4134 // ignored unless aborting resets the texture state.
4135 layer_tree_host()->SetNeedsRedraw();
4136 break;
4140 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4141 num_impl_commits_++;
4144 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4145 switch (impl->SourceAnimationFrameNumber()) {
4146 case 1:
4147 // Prevent draws until commit.
4148 impl->active_tree()->SetContentsTexturesPurged();
4149 EXPECT_FALSE(impl->CanDraw());
4150 // Trigger an abortable commit.
4151 impl->SetNeedsCommit();
4152 break;
4153 case 2:
4154 EndTest();
4155 break;
4159 virtual void AfterTest() OVERRIDE {
4160 // Ensure that the commit was truly aborted.
4161 EXPECT_EQ(2, num_will_begin_main_frames_);
4162 EXPECT_EQ(1, num_impl_commits_);
4165 private:
4166 int num_will_begin_main_frames_;
4167 int num_impl_commits_;
4170 // Commits can only be aborted when using the thread proxy.
4171 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4173 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4174 protected:
4175 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4176 settings->impl_side_painting = true;
4179 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
4180 OVERRIDE {
4181 scoped_refptr<TestContextProvider> context_provider =
4182 TestContextProvider::Create();
4183 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
4184 if (delegating_renderer())
4185 return FakeOutputSurface::CreateDelegating3d(context_provider);
4186 else
4187 return FakeOutputSurface::Create3d(context_provider);
4190 virtual void SetupTree() OVERRIDE {
4191 scoped_refptr<FakePictureLayer> root_layer =
4192 FakePictureLayer::Create(&client_);
4193 root_layer->SetBounds(gfx::Size(6000, 6000));
4194 root_layer->SetIsDrawable(true);
4196 layer_tree_host()->SetRootLayer(root_layer);
4197 LayerTreeHostTest::SetupTree();
4200 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4202 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4203 TestWebGraphicsContext3D* context = TestContext();
4205 // Expect that the transfer buffer memory used is equal to the
4206 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4207 EXPECT_EQ(1024 * 1024u, context->max_used_transfer_buffer_usage_bytes());
4208 EndTest();
4211 virtual void AfterTest() OVERRIDE {}
4213 private:
4214 FakeContentLayerClient client_;
4217 // Impl-side painting is a multi-threaded compositor feature.
4218 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4220 // Test ensuring that memory limits are sent to the prioritized resource
4221 // manager.
4222 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4223 public:
4224 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4226 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4228 virtual void WillCommit() OVERRIDE {
4229 // Some commits are aborted, so increment number of attempted commits here.
4230 num_commits_++;
4233 virtual void DidCommit() OVERRIDE {
4234 switch (num_commits_) {
4235 case 1:
4236 // Verify default values.
4237 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4238 layer_tree_host()
4239 ->contents_texture_manager()
4240 ->MaxMemoryLimitBytes());
4241 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4242 layer_tree_host()
4243 ->contents_texture_manager()
4244 ->ExternalPriorityCutoff());
4245 PostSetNeedsCommitToMainThread();
4246 break;
4247 case 2:
4248 // The values should remain the same until the commit after the policy
4249 // is changed.
4250 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4251 layer_tree_host()
4252 ->contents_texture_manager()
4253 ->MaxMemoryLimitBytes());
4254 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4255 layer_tree_host()
4256 ->contents_texture_manager()
4257 ->ExternalPriorityCutoff());
4258 break;
4259 case 3:
4260 // Verify values were correctly passed.
4261 EXPECT_EQ(16u * 1024u * 1024u,
4262 layer_tree_host()
4263 ->contents_texture_manager()
4264 ->MaxMemoryLimitBytes());
4265 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4266 layer_tree_host()
4267 ->contents_texture_manager()
4268 ->ExternalPriorityCutoff());
4269 EndTest();
4270 break;
4271 case 4:
4272 // Make sure no extra commits happen.
4273 NOTREACHED();
4274 break;
4278 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4279 switch (num_commits_) {
4280 case 1:
4281 break;
4282 case 2:
4283 // This will trigger a commit because the priority cutoff has changed.
4284 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4285 16u * 1024u * 1024u,
4286 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4287 1000));
4288 break;
4289 case 3:
4290 // This will not trigger a commit because the priority cutoff has not
4291 // changed, and there is already enough memory for all allocations.
4292 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4293 32u * 1024u * 1024u,
4294 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4295 1000));
4296 break;
4297 case 4:
4298 NOTREACHED();
4299 break;
4303 virtual void AfterTest() OVERRIDE {}
4305 private:
4306 int num_commits_;
4309 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4311 } // namespace
4313 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4314 : public LayerTreeHostTest {
4315 protected:
4316 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4317 : first_output_surface_memory_limit_(4321234),
4318 second_output_surface_memory_limit_(1234321) {}
4320 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
4321 OVERRIDE {
4322 if (!first_context_provider_) {
4323 first_context_provider_ = TestContextProvider::Create();
4324 } else {
4325 EXPECT_FALSE(second_context_provider_);
4326 second_context_provider_ = TestContextProvider::Create();
4329 scoped_refptr<TestContextProvider> provider(second_context_provider_
4330 ? second_context_provider_
4331 : first_context_provider_);
4332 scoped_ptr<FakeOutputSurface> output_surface;
4333 if (delegating_renderer())
4334 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4335 else
4336 output_surface = FakeOutputSurface::Create3d(provider);
4337 output_surface->SetMemoryPolicyToSetAtBind(
4338 make_scoped_ptr(new ManagedMemoryPolicy(
4339 second_context_provider_ ? second_output_surface_memory_limit_
4340 : first_output_surface_memory_limit_,
4341 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4342 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4343 return output_surface.Pass();
4346 virtual void SetupTree() OVERRIDE {
4347 root_ = FakeContentLayer::Create(&client_);
4348 root_->SetBounds(gfx::Size(20, 20));
4349 layer_tree_host()->SetRootLayer(root_);
4350 LayerTreeHostTest::SetupTree();
4353 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4355 virtual void DidCommitAndDrawFrame() OVERRIDE {
4356 // Lost context sometimes takes two frames to recreate. The third frame
4357 // is sometimes aborted, so wait until the fourth frame to verify that
4358 // the memory has been set, and the fifth frame to end the test.
4359 if (layer_tree_host()->source_frame_number() < 5) {
4360 layer_tree_host()->SetNeedsCommit();
4361 } else if (layer_tree_host()->source_frame_number() == 5) {
4362 EndTest();
4366 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
4367 bool result) OVERRIDE {
4368 switch (impl->active_tree()->source_frame_number()) {
4369 case 1:
4370 EXPECT_EQ(first_output_surface_memory_limit_,
4371 impl->memory_allocation_limit_bytes());
4372 // Lose the output surface.
4373 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4374 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4375 break;
4376 case 4:
4377 EXPECT_EQ(second_output_surface_memory_limit_,
4378 impl->memory_allocation_limit_bytes());
4379 break;
4383 virtual void AfterTest() OVERRIDE {}
4385 scoped_refptr<TestContextProvider> first_context_provider_;
4386 scoped_refptr<TestContextProvider> second_context_provider_;
4387 size_t first_output_surface_memory_limit_;
4388 size_t second_output_surface_memory_limit_;
4389 FakeContentLayerClient client_;
4390 scoped_refptr<FakeContentLayer> root_;
4393 // No output to copy for delegated renderers.
4394 SINGLE_AND_MULTI_THREAD_TEST_F(
4395 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4397 struct TestSwapPromiseResult {
4398 TestSwapPromiseResult()
4399 : did_swap_called(false),
4400 did_not_swap_called(false),
4401 dtor_called(false),
4402 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4404 bool did_swap_called;
4405 bool did_not_swap_called;
4406 bool dtor_called;
4407 SwapPromise::DidNotSwapReason reason;
4408 base::Lock lock;
4411 class TestSwapPromise : public SwapPromise {
4412 public:
4413 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4415 virtual ~TestSwapPromise() {
4416 base::AutoLock lock(result_->lock);
4417 result_->dtor_called = true;
4420 virtual void DidSwap(CompositorFrameMetadata* metadata) OVERRIDE {
4421 base::AutoLock lock(result_->lock);
4422 EXPECT_FALSE(result_->did_swap_called);
4423 EXPECT_FALSE(result_->did_not_swap_called);
4424 result_->did_swap_called = true;
4427 virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE {
4428 base::AutoLock lock(result_->lock);
4429 EXPECT_FALSE(result_->did_swap_called);
4430 EXPECT_FALSE(result_->did_not_swap_called);
4431 result_->did_not_swap_called = true;
4432 result_->reason = reason;
4435 virtual int64 TraceId() const OVERRIDE { return 0; }
4437 private:
4438 // Not owned.
4439 TestSwapPromiseResult* result_;
4442 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4443 protected:
4444 LayerTreeHostTestBreakSwapPromise()
4445 : commit_count_(0), commit_complete_count_(0) {}
4447 virtual void WillBeginMainFrame() OVERRIDE {
4448 ASSERT_LE(commit_count_, 2);
4449 scoped_ptr<SwapPromise> swap_promise(
4450 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4451 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4454 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4456 virtual void DidCommit() OVERRIDE {
4457 commit_count_++;
4458 if (commit_count_ == 2) {
4459 // This commit will finish.
4460 layer_tree_host()->SetNeedsCommit();
4464 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4465 commit_complete_count_++;
4466 if (commit_complete_count_ == 1) {
4467 // This commit will be aborted because no actual update.
4468 PostSetNeedsUpdateLayersToMainThread();
4469 } else {
4470 EndTest();
4474 virtual void AfterTest() OVERRIDE {
4475 // 3 commits are scheduled. 2 completes. 1 is aborted.
4476 EXPECT_EQ(commit_count_, 3);
4477 EXPECT_EQ(commit_complete_count_, 2);
4480 // The first commit completes and causes swap buffer which finishes
4481 // the promise.
4482 base::AutoLock lock(swap_promise_result_[0].lock);
4483 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4484 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4485 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4489 // The second commit aborts.
4490 base::AutoLock lock(swap_promise_result_[1].lock);
4491 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4492 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4493 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_[1].reason);
4494 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4498 // The last commit completes but it does not cause swap buffer because
4499 // there is no damage in the frame data.
4500 base::AutoLock lock(swap_promise_result_[2].lock);
4501 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4502 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4503 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4504 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4508 int commit_count_;
4509 int commit_complete_count_;
4510 TestSwapPromiseResult swap_promise_result_[3];
4513 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4515 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
4516 public:
4517 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
4518 LayerTreeHostImpl* layer_tree_host_impl,
4519 int* set_needs_commit_count,
4520 int* set_needs_redraw_count)
4521 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
4522 set_needs_commit_count_(set_needs_commit_count) {}
4524 virtual ~SimpleSwapPromiseMonitor() {}
4526 virtual void OnSetNeedsCommitOnMain() OVERRIDE {
4527 (*set_needs_commit_count_)++;
4530 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE {
4531 ADD_FAILURE() << "Should not get called on main thread.";
4534 virtual void OnForwardScrollUpdateToMainThreadOnImpl() OVERRIDE {
4535 ADD_FAILURE() << "Should not get called on main thread.";
4538 private:
4539 int* set_needs_commit_count_;
4542 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
4543 public:
4544 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4546 virtual void WillBeginMainFrame() OVERRIDE {
4547 int set_needs_commit_count = 0;
4548 int set_needs_redraw_count = 0;
4551 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4552 new SimpleSwapPromiseMonitor(layer_tree_host(),
4553 NULL,
4554 &set_needs_commit_count,
4555 &set_needs_redraw_count));
4556 layer_tree_host()->SetNeedsCommit();
4557 EXPECT_EQ(1, set_needs_commit_count);
4558 EXPECT_EQ(0, set_needs_redraw_count);
4561 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
4562 // monitored.
4563 layer_tree_host()->SetNeedsCommit();
4564 EXPECT_EQ(1, set_needs_commit_count);
4565 EXPECT_EQ(0, set_needs_redraw_count);
4568 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4569 new SimpleSwapPromiseMonitor(layer_tree_host(),
4570 NULL,
4571 &set_needs_commit_count,
4572 &set_needs_redraw_count));
4573 layer_tree_host()->SetNeedsUpdateLayers();
4574 EXPECT_EQ(2, set_needs_commit_count);
4575 EXPECT_EQ(0, set_needs_redraw_count);
4579 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4580 new SimpleSwapPromiseMonitor(layer_tree_host(),
4581 NULL,
4582 &set_needs_commit_count,
4583 &set_needs_redraw_count));
4584 layer_tree_host()->SetNeedsAnimate();
4585 EXPECT_EQ(3, set_needs_commit_count);
4586 EXPECT_EQ(0, set_needs_redraw_count);
4589 EndTest();
4592 virtual void AfterTest() OVERRIDE {}
4595 MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
4597 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
4598 : public LayerTreeHostTest {
4599 protected:
4600 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4601 settings->impl_side_painting = true;
4604 virtual void SetupTree() OVERRIDE {
4605 LayerTreeHostTest::SetupTree();
4606 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
4609 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4611 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4612 host_impl->EvictAllUIResources();
4613 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
4614 // mode. Active tree should require high-res to draw after entering this
4615 // mode to ensure that high-res tiles are also required for a pending tree
4616 // to be activated.
4617 EXPECT_TRUE(host_impl->active_tree()->RequiresHighResToDraw());
4620 virtual void DidCommit() OVERRIDE {
4621 int frame = layer_tree_host()->source_frame_number();
4622 switch (frame) {
4623 case 1:
4624 PostSetNeedsCommitToMainThread();
4625 break;
4626 case 2:
4627 ui_resource_.reset();
4628 EndTest();
4629 break;
4633 virtual void AfterTest() OVERRIDE {}
4635 FakeContentLayerClient client_;
4636 scoped_ptr<FakeScopedUIResource> ui_resource_;
4639 // This test is flaky, see http://crbug.com/386199
4640 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
4642 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
4643 protected:
4644 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4645 settings->impl_side_painting = true;
4647 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4648 EXPECT_FALSE(settings->gpu_rasterization_forced);
4651 virtual void SetupTree() OVERRIDE {
4652 LayerTreeHostTest::SetupTree();
4654 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4655 layer->SetBounds(gfx::Size(10, 10));
4656 layer->SetIsDrawable(true);
4657 layer_tree_host()->root_layer()->AddChild(layer);
4660 virtual void BeginTest() OVERRIDE {
4661 Layer* root = layer_tree_host()->root_layer();
4662 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4663 PicturePile* pile = layer->GetPicturePileForTesting();
4665 // Verify default values.
4666 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4667 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4668 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4669 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4670 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4672 // Setting gpu rasterization trigger does not enable gpu rasterization.
4673 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4674 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4675 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4677 PostSetNeedsCommitToMainThread();
4680 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4681 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4682 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4685 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4686 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4687 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4688 EndTest();
4691 virtual void AfterTest() OVERRIDE {}
4693 FakeContentLayerClient layer_client_;
4696 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
4698 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
4699 protected:
4700 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4701 settings->impl_side_painting = true;
4703 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4704 settings->gpu_rasterization_enabled = true;
4707 virtual void SetupTree() OVERRIDE {
4708 LayerTreeHostTest::SetupTree();
4710 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4711 layer->SetBounds(gfx::Size(10, 10));
4712 layer->SetIsDrawable(true);
4713 layer_tree_host()->root_layer()->AddChild(layer);
4716 virtual void BeginTest() OVERRIDE {
4717 Layer* root = layer_tree_host()->root_layer();
4718 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4719 PicturePile* pile = layer->GetPicturePileForTesting();
4721 // Verify default values.
4722 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4723 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4724 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4725 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4726 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4728 // Gpu rasterization trigger is relevant.
4729 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4730 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4731 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4733 // Content-based veto is relevant as well.
4734 pile->SetUnsuitableForGpuRasterizationForTesting();
4735 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
4736 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4737 // Veto will take effect when layers are updated.
4738 // The results will be verified after commit is completed below.
4739 // Since we are manually marking picture pile as unsuitable,
4740 // make sure that the layer gets a chance to update.
4741 layer->SetNeedsDisplay();
4742 PostSetNeedsCommitToMainThread();
4745 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4746 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4747 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4750 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4751 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4752 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4753 EndTest();
4756 virtual void AfterTest() OVERRIDE {}
4758 FakeContentLayerClient layer_client_;
4761 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
4763 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
4764 protected:
4765 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4766 settings->impl_side_painting = true;
4768 EXPECT_FALSE(settings->gpu_rasterization_forced);
4769 settings->gpu_rasterization_forced = true;
4772 virtual void SetupTree() OVERRIDE {
4773 LayerTreeHostTest::SetupTree();
4775 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4776 layer->SetBounds(gfx::Size(10, 10));
4777 layer->SetIsDrawable(true);
4778 layer_tree_host()->root_layer()->AddChild(layer);
4781 virtual void BeginTest() OVERRIDE {
4782 Layer* root = layer_tree_host()->root_layer();
4783 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4784 PicturePile* pile = layer->GetPicturePileForTesting();
4786 // Verify default values.
4787 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4788 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4789 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4790 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4792 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
4793 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4794 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4795 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4796 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4798 // Content-based veto is irrelevant as well.
4799 pile->SetUnsuitableForGpuRasterizationForTesting();
4800 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
4801 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4802 // Veto will take effect when layers are updated.
4803 // The results will be verified after commit is completed below.
4804 // Since we are manually marking picture pile as unsuitable,
4805 // make sure that the layer gets a chance to update.
4806 layer->SetNeedsDisplay();
4807 PostSetNeedsCommitToMainThread();
4810 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4811 EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
4812 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4815 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4816 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
4817 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4818 EndTest();
4821 virtual void AfterTest() OVERRIDE {}
4823 FakeContentLayerClient layer_client_;
4826 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
4828 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
4829 public:
4830 LayerTreeHostTestContinuousPainting()
4831 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
4833 protected:
4834 enum { kExpectedNumCommits = 10 };
4836 virtual void SetupTree() OVERRIDE {
4837 scoped_refptr<Layer> root_layer = Layer::Create();
4838 root_layer->SetBounds(bounds_);
4840 if (layer_tree_host()->settings().impl_side_painting) {
4841 picture_layer_ = FakePictureLayer::Create(&client_);
4842 child_layer_ = picture_layer_.get();
4843 } else {
4844 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
4845 child_layer_ = content_layer_.get();
4847 child_layer_->SetBounds(bounds_);
4848 child_layer_->SetIsDrawable(true);
4849 root_layer->AddChild(child_layer_);
4851 layer_tree_host()->SetRootLayer(root_layer);
4852 layer_tree_host()->SetViewportSize(bounds_);
4853 LayerTreeHostTest::SetupTree();
4856 virtual void BeginTest() OVERRIDE {
4857 // Wait 50x longer than expected.
4858 double milliseconds_per_frame =
4859 1000 / layer_tree_host()->settings().refresh_rate;
4860 EndTestAfterDelay(50 * kExpectedNumCommits * milliseconds_per_frame);
4861 MainThreadTaskRunner()->PostTask(
4862 FROM_HERE,
4863 base::Bind(
4864 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
4865 base::Unretained(this)));
4868 virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE {
4869 child_layer_->SetNeedsDisplay();
4872 virtual void AfterTest() OVERRIDE {
4873 EXPECT_LE(kExpectedNumCommits, num_commits_);
4874 EXPECT_LE(kExpectedNumCommits, num_draws_);
4875 int update_count = content_layer_ ? content_layer_->PaintContentsCount()
4876 : picture_layer_->update_count();
4877 EXPECT_LE(kExpectedNumCommits, update_count);
4880 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4881 if (++num_draws_ == kExpectedNumCommits)
4882 EndTest();
4885 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4886 ++num_commits_;
4889 private:
4890 void EnableContinuousPainting() {
4891 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
4892 debug_state.continuous_painting = true;
4893 layer_tree_host()->SetDebugState(debug_state);
4896 int num_commits_;
4897 int num_draws_;
4898 const gfx::Size bounds_;
4899 FakeContentLayerClient client_;
4900 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
4901 scoped_refptr<FakePictureLayer> picture_layer_;
4902 Layer* child_layer_;
4905 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
4907 } // namespace cc