Add trace event for addition/removal of GPU rasterization trigger
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob88dbeab656235e7685a8e36effa064f2613b3974
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 (layer_tree_host()->source_frame_number()) {
578 case 1:
579 EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
580 break;
581 case 2:
582 case 3:
583 case 4:
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 SetAnchorPoint(gfx::PointF(0.f, 0.f));
1005 SetBounds(gfx::Size(10, 10));
1006 SetIsDrawable(true);
1008 virtual ~ContentLayerWithUpdateTracking() {}
1010 int paint_contents_count_;
1013 // Layer opacity change during paint should not prevent compositor resources
1014 // from being updated during commit.
1015 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1016 public:
1017 LayerTreeHostTestOpacityChange()
1018 : test_opacity_change_delegate_(),
1019 update_check_layer_(ContentLayerWithUpdateTracking::Create(
1020 &test_opacity_change_delegate_)) {
1021 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
1024 virtual void BeginTest() OVERRIDE {
1025 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1026 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
1028 PostSetNeedsCommitToMainThread();
1031 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1032 EndTest();
1035 virtual void AfterTest() OVERRIDE {
1036 // Update() should have been called once.
1037 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
1040 private:
1041 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1042 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
1045 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1047 class NoScaleContentLayer : public ContentLayer {
1048 public:
1049 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
1050 return make_scoped_refptr(new NoScaleContentLayer(client));
1053 virtual void CalculateContentsScale(float ideal_contents_scale,
1054 float device_scale_factor,
1055 float page_scale_factor,
1056 float maximum_animation_contents_scale,
1057 bool animating_transform_to_screen,
1058 float* contents_scale_x,
1059 float* contents_scale_y,
1060 gfx::Size* contentBounds) OVERRIDE {
1061 // Skip over the ContentLayer's method to the base Layer class.
1062 Layer::CalculateContentsScale(ideal_contents_scale,
1063 device_scale_factor,
1064 page_scale_factor,
1065 maximum_animation_contents_scale,
1066 animating_transform_to_screen,
1067 contents_scale_x,
1068 contents_scale_y,
1069 contentBounds);
1072 private:
1073 explicit NoScaleContentLayer(ContentLayerClient* client)
1074 : ContentLayer(client) {}
1075 virtual ~NoScaleContentLayer() {}
1078 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1079 : public LayerTreeHostTest {
1080 public:
1081 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1082 : root_layer_(NoScaleContentLayer::Create(&client_)),
1083 child_layer_(ContentLayer::Create(&client_)) {}
1085 virtual void BeginTest() OVERRIDE {
1086 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1087 layer_tree_host()->SetDeviceScaleFactor(1.5);
1088 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1090 root_layer_->AddChild(child_layer_);
1092 root_layer_->SetIsDrawable(true);
1093 root_layer_->SetBounds(gfx::Size(30, 30));
1094 root_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1096 child_layer_->SetIsDrawable(true);
1097 child_layer_->SetPosition(gfx::Point(2, 2));
1098 child_layer_->SetBounds(gfx::Size(10, 10));
1099 child_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1101 layer_tree_host()->SetRootLayer(root_layer_);
1103 PostSetNeedsCommitToMainThread();
1106 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1107 // Should only do one commit.
1108 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1109 // Device scale factor should come over to impl.
1110 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1112 // Both layers are on impl.
1113 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1115 // Device viewport is scaled.
1116 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1118 LayerImpl* root = impl->active_tree()->root_layer();
1119 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1121 // Positions remain in layout pixels.
1122 EXPECT_EQ(gfx::Point(0, 0), root->position());
1123 EXPECT_EQ(gfx::Point(2, 2), child->position());
1125 // Compute all the layer transforms for the frame.
1126 LayerTreeHostImpl::FrameData frame_data;
1127 impl->PrepareToDraw(&frame_data);
1128 impl->DidDrawAllLayers(frame_data);
1130 const LayerImplList& render_surface_layer_list =
1131 *frame_data.render_surface_layer_list;
1133 // Both layers should be drawing into the root render surface.
1134 ASSERT_EQ(1u, render_surface_layer_list.size());
1135 ASSERT_EQ(root->render_surface(),
1136 render_surface_layer_list[0]->render_surface());
1137 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1139 // The root render surface is the size of the viewport.
1140 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1141 root->render_surface()->content_rect());
1143 // The content bounds of the child should be scaled.
1144 gfx::Size child_bounds_scaled =
1145 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1146 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1148 gfx::Transform scale_transform;
1149 scale_transform.Scale(impl->device_scale_factor(),
1150 impl->device_scale_factor());
1152 // The root layer is scaled by 2x.
1153 gfx::Transform root_screen_space_transform = scale_transform;
1154 gfx::Transform root_draw_transform = scale_transform;
1156 EXPECT_EQ(root_draw_transform, root->draw_transform());
1157 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1159 // The child is at position 2,2, which is transformed to 3,3 after the scale
1160 gfx::Transform child_screen_space_transform;
1161 child_screen_space_transform.Translate(3.f, 3.f);
1162 gfx::Transform child_draw_transform = child_screen_space_transform;
1164 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1165 child->draw_transform());
1166 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1167 child->screen_space_transform());
1169 EndTest();
1172 virtual void AfterTest() OVERRIDE {}
1174 private:
1175 FakeContentLayerClient client_;
1176 scoped_refptr<NoScaleContentLayer> root_layer_;
1177 scoped_refptr<ContentLayer> child_layer_;
1180 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1182 // Verify atomicity of commits and reuse of textures.
1183 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1184 public:
1185 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1186 settings->texture_id_allocation_chunk_size = 1;
1187 // Make sure partial texture updates are turned off.
1188 settings->max_partial_texture_updates = 0;
1189 // Linear fade animator prevents scrollbars from drawing immediately.
1190 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1193 virtual void SetupTree() OVERRIDE {
1194 layer_ = FakeContentLayer::Create(&client_);
1195 layer_->SetBounds(gfx::Size(10, 20));
1197 bool paint_scrollbar = true;
1198 bool has_thumb = false;
1199 scrollbar_ = FakePaintedScrollbarLayer::Create(
1200 paint_scrollbar, has_thumb, layer_->id());
1201 scrollbar_->SetPosition(gfx::Point(0, 10));
1202 scrollbar_->SetBounds(gfx::Size(10, 10));
1204 layer_->AddChild(scrollbar_);
1206 layer_tree_host()->SetRootLayer(layer_);
1207 LayerTreeHostTest::SetupTree();
1210 virtual void BeginTest() OVERRIDE {
1211 drew_frame_ = -1;
1212 PostSetNeedsCommitToMainThread();
1215 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1216 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1218 TestWebGraphicsContext3D* context = TestContext();
1220 switch (impl->active_tree()->source_frame_number()) {
1221 case 0:
1222 // Number of textures should be one for each layer
1223 ASSERT_EQ(2u, context->NumTextures());
1224 // Number of textures used for commit should be one for each layer.
1225 EXPECT_EQ(2u, context->NumUsedTextures());
1226 // Verify that used texture is correct.
1227 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1228 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1230 context->ResetUsedTextures();
1231 break;
1232 case 1:
1233 // Number of textures should be one for scrollbar layer since it was
1234 // requested and deleted on the impl-thread, and double for the content
1235 // layer since its first texture is used by impl thread and cannot by
1236 // used for update.
1237 ASSERT_EQ(3u, context->NumTextures());
1238 // Number of textures used for commit should be one for each layer.
1239 EXPECT_EQ(2u, context->NumUsedTextures());
1240 // First textures should not have been used.
1241 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1242 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1243 // New textures should have been used.
1244 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1245 context->ResetUsedTextures();
1246 break;
1247 case 2:
1248 EndTest();
1249 break;
1250 default:
1251 NOTREACHED();
1252 break;
1256 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1257 TestWebGraphicsContext3D* context = TestContext();
1259 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1260 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1261 return;
1263 drew_frame_ = impl->active_tree()->source_frame_number();
1265 // We draw/ship one texture each frame for each layer.
1266 EXPECT_EQ(2u, context->NumUsedTextures());
1267 context->ResetUsedTextures();
1269 if (!TestEnded())
1270 PostSetNeedsCommitToMainThread();
1273 virtual void Layout() OVERRIDE {
1274 layer_->SetNeedsDisplay();
1275 scrollbar_->SetNeedsDisplay();
1278 virtual void AfterTest() OVERRIDE {}
1280 protected:
1281 FakeContentLayerClient client_;
1282 scoped_refptr<FakeContentLayer> layer_;
1283 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1284 int drew_frame_;
1287 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1288 LayerTreeHostTestDirectRendererAtomicCommit);
1290 class LayerTreeHostTestDelegatingRendererAtomicCommit
1291 : public LayerTreeHostTestDirectRendererAtomicCommit {
1292 public:
1293 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1294 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1296 TestWebGraphicsContext3D* context = TestContext();
1298 switch (impl->active_tree()->source_frame_number()) {
1299 case 0:
1300 // Number of textures should be one for each layer
1301 ASSERT_EQ(2u, context->NumTextures());
1302 // Number of textures used for commit should be one for each layer.
1303 EXPECT_EQ(2u, context->NumUsedTextures());
1304 // Verify that used texture is correct.
1305 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1306 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1307 context->ResetUsedTextures();
1308 break;
1309 case 1:
1310 // Number of textures should be doubled as the first context layer
1311 // texture is being used by the impl-thread and cannot be used for
1312 // update. The scrollbar behavior is different direct renderer because
1313 // UI resource deletion with delegating renderer occurs after tree
1314 // activation.
1315 ASSERT_EQ(4u, context->NumTextures());
1316 // Number of textures used for commit should still be
1317 // one for each layer.
1318 EXPECT_EQ(2u, context->NumUsedTextures());
1319 // First textures should not have been used.
1320 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1321 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1322 // New textures should have been used.
1323 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1324 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1325 context->ResetUsedTextures();
1326 break;
1327 case 2:
1328 EndTest();
1329 break;
1330 default:
1331 NOTREACHED();
1332 break;
1337 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1338 LayerTreeHostTestDelegatingRendererAtomicCommit);
1340 static void SetLayerPropertiesForTesting(Layer* layer,
1341 Layer* parent,
1342 const gfx::Transform& transform,
1343 const gfx::PointF& anchor,
1344 const gfx::PointF& position,
1345 const gfx::Size& bounds,
1346 bool opaque) {
1347 layer->RemoveAllChildren();
1348 if (parent)
1349 parent->AddChild(layer);
1350 layer->SetTransform(transform);
1351 layer->SetAnchorPoint(anchor);
1352 layer->SetPosition(position);
1353 layer->SetBounds(bounds);
1354 layer->SetContentsOpaque(opaque);
1357 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1358 : public LayerTreeHostTest {
1359 public:
1360 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1361 settings->texture_id_allocation_chunk_size = 1;
1362 // Allow one partial texture update.
1363 settings->max_partial_texture_updates = 1;
1364 // No partial updates when impl side painting is enabled.
1365 settings->impl_side_painting = false;
1368 virtual void SetupTree() OVERRIDE {
1369 parent_ = FakeContentLayer::Create(&client_);
1370 parent_->SetBounds(gfx::Size(10, 20));
1372 child_ = FakeContentLayer::Create(&client_);
1373 child_->SetPosition(gfx::Point(0, 10));
1374 child_->SetBounds(gfx::Size(3, 10));
1376 parent_->AddChild(child_);
1378 layer_tree_host()->SetRootLayer(parent_);
1379 LayerTreeHostTest::SetupTree();
1382 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1384 virtual void DidCommitAndDrawFrame() OVERRIDE {
1385 switch (layer_tree_host()->source_frame_number()) {
1386 case 1:
1387 parent_->SetNeedsDisplay();
1388 child_->SetNeedsDisplay();
1389 break;
1390 case 2:
1391 // Damage part of layers.
1392 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1393 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1394 break;
1395 case 3:
1396 child_->SetNeedsDisplay();
1397 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1398 break;
1399 case 4:
1400 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1401 break;
1402 case 5:
1403 EndTest();
1404 break;
1405 default:
1406 NOTREACHED() << layer_tree_host()->source_frame_number();
1407 break;
1411 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1412 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1414 TestWebGraphicsContext3D* context = TestContext();
1416 switch (impl->active_tree()->source_frame_number()) {
1417 case 0:
1418 // Number of textures should be one for each layer.
1419 ASSERT_EQ(2u, context->NumTextures());
1420 // Number of textures used for commit should be one for each layer.
1421 EXPECT_EQ(2u, context->NumUsedTextures());
1422 // Verify that used textures are correct.
1423 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1424 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1425 context->ResetUsedTextures();
1426 break;
1427 case 1:
1428 if (HasImplThread()) {
1429 // Number of textures should be two for each content layer.
1430 ASSERT_EQ(4u, context->NumTextures());
1431 } else {
1432 // In single thread we can always do partial updates, so the limit has
1433 // no effect.
1434 ASSERT_EQ(2u, context->NumTextures());
1436 // Number of textures used for commit should be one for each content
1437 // layer.
1438 EXPECT_EQ(2u, context->NumUsedTextures());
1440 if (HasImplThread()) {
1441 // First content textures should not have been used.
1442 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1443 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1444 // New textures should have been used.
1445 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1446 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1447 } else {
1448 // In single thread we can always do partial updates, so the limit has
1449 // no effect.
1450 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1451 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1454 context->ResetUsedTextures();
1455 break;
1456 case 2:
1457 if (HasImplThread()) {
1458 // Number of textures should be two for each content layer.
1459 ASSERT_EQ(4u, context->NumTextures());
1460 } else {
1461 // In single thread we can always do partial updates, so the limit has
1462 // no effect.
1463 ASSERT_EQ(2u, context->NumTextures());
1465 // Number of textures used for commit should be one for each content
1466 // layer.
1467 EXPECT_EQ(2u, context->NumUsedTextures());
1469 if (HasImplThread()) {
1470 // One content layer does a partial update also.
1471 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1472 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1473 } else {
1474 // In single thread we can always do partial updates, so the limit has
1475 // no effect.
1476 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1477 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1480 context->ResetUsedTextures();
1481 break;
1482 case 3:
1483 // No textures should be used for commit.
1484 EXPECT_EQ(0u, context->NumUsedTextures());
1486 context->ResetUsedTextures();
1487 break;
1488 case 4:
1489 // Number of textures used for commit should be one, for the
1490 // content layer.
1491 EXPECT_EQ(1u, context->NumUsedTextures());
1493 context->ResetUsedTextures();
1494 break;
1495 default:
1496 NOTREACHED();
1497 break;
1501 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1502 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1504 TestWebGraphicsContext3D* context = TestContext();
1506 // Number of textures used for drawing should one per layer except for
1507 // frame 3 where the viewport only contains one layer.
1508 if (impl->active_tree()->source_frame_number() == 3) {
1509 EXPECT_EQ(1u, context->NumUsedTextures());
1510 } else {
1511 EXPECT_EQ(2u, context->NumUsedTextures())
1512 << "For frame " << impl->active_tree()->source_frame_number();
1515 context->ResetUsedTextures();
1518 virtual void AfterTest() OVERRIDE {}
1520 private:
1521 FakeContentLayerClient client_;
1522 scoped_refptr<FakeContentLayer> parent_;
1523 scoped_refptr<FakeContentLayer> child_;
1526 // Partial updates are not possible with a delegating renderer.
1527 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1528 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1530 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1531 : public LayerTreeHostTest {
1532 protected:
1533 virtual void SetupTree() OVERRIDE {
1534 root_layer_ = FakeContentLayer::Create(&client_);
1535 root_layer_->SetBounds(gfx::Size(100, 100));
1537 surface_layer1_ = FakeContentLayer::Create(&client_);
1538 surface_layer1_->SetBounds(gfx::Size(100, 100));
1539 surface_layer1_->SetForceRenderSurface(true);
1540 surface_layer1_->SetOpacity(0.5f);
1541 root_layer_->AddChild(surface_layer1_);
1543 surface_layer2_ = FakeContentLayer::Create(&client_);
1544 surface_layer2_->SetBounds(gfx::Size(100, 100));
1545 surface_layer2_->SetForceRenderSurface(true);
1546 surface_layer2_->SetOpacity(0.5f);
1547 surface_layer1_->AddChild(surface_layer2_);
1549 replica_layer1_ = FakeContentLayer::Create(&client_);
1550 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1552 replica_layer2_ = FakeContentLayer::Create(&client_);
1553 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1555 layer_tree_host()->SetRootLayer(root_layer_);
1556 LayerTreeHostTest::SetupTree();
1559 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1561 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1562 Renderer* renderer = host_impl->renderer();
1563 RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1564 ->root_layer()
1565 ->children()[0]
1566 ->render_surface()
1567 ->RenderPassId();
1568 RenderPass::Id surface2_render_pass_id = host_impl->active_tree()
1569 ->root_layer()
1570 ->children()[0]
1571 ->children()[0]
1572 ->render_surface()
1573 ->RenderPassId();
1575 switch (host_impl->active_tree()->source_frame_number()) {
1576 case 0:
1577 EXPECT_TRUE(
1578 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1579 EXPECT_TRUE(
1580 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1582 // Reduce the memory limit to only fit the root layer and one render
1583 // surface. This prevents any contents drawing into surfaces
1584 // from being allocated.
1585 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1586 break;
1587 case 1:
1588 EXPECT_FALSE(
1589 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1590 EXPECT_FALSE(
1591 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1593 EndTest();
1594 break;
1598 virtual void DidCommitAndDrawFrame() OVERRIDE {
1599 if (layer_tree_host()->source_frame_number() < 2)
1600 root_layer_->SetNeedsDisplay();
1603 virtual void AfterTest() OVERRIDE {
1604 EXPECT_LE(2u, root_layer_->update_count());
1605 EXPECT_LE(2u, surface_layer1_->update_count());
1606 EXPECT_LE(2u, surface_layer2_->update_count());
1609 FakeContentLayerClient client_;
1610 scoped_refptr<FakeContentLayer> root_layer_;
1611 scoped_refptr<FakeContentLayer> surface_layer1_;
1612 scoped_refptr<FakeContentLayer> replica_layer1_;
1613 scoped_refptr<FakeContentLayer> surface_layer2_;
1614 scoped_refptr<FakeContentLayer> replica_layer2_;
1617 // Surfaces don't exist with a delegated renderer.
1618 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1619 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1621 class EvictionTestLayer : public Layer {
1622 public:
1623 static scoped_refptr<EvictionTestLayer> Create() {
1624 return make_scoped_refptr(new EvictionTestLayer());
1627 virtual bool Update(ResourceUpdateQueue*,
1628 const OcclusionTracker<Layer>*) OVERRIDE;
1629 virtual bool DrawsContent() const OVERRIDE { return true; }
1631 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1632 OVERRIDE;
1633 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1634 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1636 bool HaveBackingTexture() const {
1637 return texture_.get() ? texture_->have_backing_texture() : false;
1640 private:
1641 EvictionTestLayer() : Layer() {}
1642 virtual ~EvictionTestLayer() {}
1644 void CreateTextureIfNeeded() {
1645 if (texture_)
1646 return;
1647 texture_ = PrioritizedResource::Create(
1648 layer_tree_host()->contents_texture_manager());
1649 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1650 bitmap_.allocN32Pixels(10, 10);
1653 scoped_ptr<PrioritizedResource> texture_;
1654 SkBitmap bitmap_;
1657 class EvictionTestLayerImpl : public LayerImpl {
1658 public:
1659 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1660 int id) {
1661 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1663 virtual ~EvictionTestLayerImpl() {}
1665 virtual void AppendQuads(QuadSink* quad_sink,
1666 AppendQuadsData* append_quads_data) OVERRIDE {
1667 ASSERT_TRUE(has_texture_);
1668 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1671 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1673 private:
1674 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1675 : LayerImpl(tree_impl, id), has_texture_(false) {}
1677 bool has_texture_;
1680 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1681 CreateTextureIfNeeded();
1682 if (!texture_)
1683 return;
1684 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1687 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1688 const OcclusionTracker<Layer>* occlusion) {
1689 CreateTextureIfNeeded();
1690 if (!texture_)
1691 return false;
1693 gfx::Rect full_rect(0, 0, 10, 10);
1694 ResourceUpdate upload = ResourceUpdate::Create(
1695 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1696 queue->AppendFullUpload(upload);
1697 return true;
1700 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1701 LayerTreeImpl* tree_impl) {
1702 return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
1703 .PassAs<LayerImpl>();
1706 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1707 Layer::PushPropertiesTo(layer_impl);
1709 EvictionTestLayerImpl* test_layer_impl =
1710 static_cast<EvictionTestLayerImpl*>(layer_impl);
1711 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1714 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1715 public:
1716 LayerTreeHostTestEvictTextures()
1717 : layer_(EvictionTestLayer::Create()),
1718 impl_for_evict_textures_(0),
1719 num_commits_(0) {}
1721 virtual void BeginTest() OVERRIDE {
1722 layer_tree_host()->SetRootLayer(layer_);
1723 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1725 gfx::Transform identity_matrix;
1726 SetLayerPropertiesForTesting(layer_.get(),
1728 identity_matrix,
1729 gfx::PointF(0.f, 0.f),
1730 gfx::PointF(0.f, 0.f),
1731 gfx::Size(10, 20),
1732 true);
1734 PostSetNeedsCommitToMainThread();
1737 void PostEvictTextures() {
1738 ImplThreadTaskRunner()->PostTask(
1739 FROM_HERE,
1740 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1741 base::Unretained(this)));
1744 void EvictTexturesOnImplThread() {
1745 DCHECK(impl_for_evict_textures_);
1746 impl_for_evict_textures_->EvictTexturesForTesting();
1749 // Commit 1: Just commit and draw normally, then post an eviction at the end
1750 // that will trigger a commit.
1751 // Commit 2: Triggered by the eviction, let it go through and then set
1752 // needsCommit.
1753 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1754 // task, which will be handled before the commit. Don't set needsCommit, it
1755 // should have been posted. A frame should not be drawn (note,
1756 // didCommitAndDrawFrame may be called anyway).
1757 // Commit 4: Triggered by the eviction, let it go through and then set
1758 // needsCommit.
1759 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1760 // Layout(), a frame should not be drawn but a commit will be posted.
1761 // Commit 6: Triggered by the eviction, post an eviction task in
1762 // Layout(), which will be a noop, letting the commit (which recreates the
1763 // textures) go through and draw a frame, then end the test.
1765 // Commits 1+2 test the eviction recovery path where eviction happens outside
1766 // of the beginFrame/commit pair.
1767 // Commits 3+4 test the eviction recovery path where eviction happens inside
1768 // the beginFrame/commit pair.
1769 // Commits 5+6 test the path where an eviction happens during the eviction
1770 // recovery path.
1771 virtual void DidCommit() OVERRIDE {
1772 switch (num_commits_) {
1773 case 1:
1774 EXPECT_TRUE(layer_->HaveBackingTexture());
1775 PostEvictTextures();
1776 break;
1777 case 2:
1778 EXPECT_TRUE(layer_->HaveBackingTexture());
1779 layer_tree_host()->SetNeedsCommit();
1780 break;
1781 case 3:
1782 break;
1783 case 4:
1784 EXPECT_TRUE(layer_->HaveBackingTexture());
1785 layer_tree_host()->SetNeedsCommit();
1786 break;
1787 case 5:
1788 break;
1789 case 6:
1790 EXPECT_TRUE(layer_->HaveBackingTexture());
1791 EndTest();
1792 break;
1793 default:
1794 NOTREACHED();
1795 break;
1799 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1800 impl_for_evict_textures_ = impl;
1803 virtual void Layout() OVERRIDE {
1804 ++num_commits_;
1805 switch (num_commits_) {
1806 case 1:
1807 case 2:
1808 break;
1809 case 3:
1810 PostEvictTextures();
1811 break;
1812 case 4:
1813 // We couldn't check in didCommitAndDrawFrame on commit 3,
1814 // so check here.
1815 EXPECT_FALSE(layer_->HaveBackingTexture());
1816 break;
1817 case 5:
1818 PostEvictTextures();
1819 break;
1820 case 6:
1821 // We couldn't check in didCommitAndDrawFrame on commit 5,
1822 // so check here.
1823 EXPECT_FALSE(layer_->HaveBackingTexture());
1824 PostEvictTextures();
1825 break;
1826 default:
1827 NOTREACHED();
1828 break;
1832 virtual void AfterTest() OVERRIDE {}
1834 private:
1835 FakeContentLayerClient client_;
1836 scoped_refptr<EvictionTestLayer> layer_;
1837 LayerTreeHostImpl* impl_for_evict_textures_;
1838 int num_commits_;
1841 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
1843 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
1844 public:
1845 LayerTreeHostTestContinuousCommit()
1846 : num_commit_complete_(0), num_draw_layers_(0) {}
1848 virtual void BeginTest() OVERRIDE {
1849 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1850 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1852 PostSetNeedsCommitToMainThread();
1855 virtual void DidCommit() OVERRIDE {
1856 if (num_draw_layers_ == 2)
1857 return;
1858 layer_tree_host()->SetNeedsCommit();
1861 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1862 if (num_draw_layers_ == 1)
1863 num_commit_complete_++;
1866 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1867 num_draw_layers_++;
1868 if (num_draw_layers_ == 2)
1869 EndTest();
1872 virtual void AfterTest() OVERRIDE {
1873 // Check that we didn't commit twice between first and second draw.
1874 EXPECT_EQ(1, num_commit_complete_);
1877 private:
1878 int num_commit_complete_;
1879 int num_draw_layers_;
1882 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
1884 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1885 public:
1886 LayerTreeHostTestContinuousInvalidate()
1887 : num_commit_complete_(0), num_draw_layers_(0) {}
1889 virtual void BeginTest() OVERRIDE {
1890 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1891 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1893 content_layer_ = ContentLayer::Create(&client_);
1894 content_layer_->SetBounds(gfx::Size(10, 10));
1895 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
1896 content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1897 content_layer_->SetIsDrawable(true);
1898 layer_tree_host()->root_layer()->AddChild(content_layer_);
1900 PostSetNeedsCommitToMainThread();
1903 virtual void DidCommitAndDrawFrame() OVERRIDE {
1904 if (num_draw_layers_ == 2)
1905 return;
1906 content_layer_->SetNeedsDisplay();
1909 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1910 if (num_draw_layers_ == 1)
1911 num_commit_complete_++;
1914 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1915 num_draw_layers_++;
1916 if (num_draw_layers_ == 2)
1917 EndTest();
1920 virtual void AfterTest() OVERRIDE {
1921 // Check that we didn't commit twice between first and second draw.
1922 EXPECT_EQ(1, num_commit_complete_);
1925 private:
1926 FakeContentLayerClient client_;
1927 scoped_refptr<Layer> content_layer_;
1928 int num_commit_complete_;
1929 int num_draw_layers_;
1932 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestContinuousInvalidate);
1934 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
1935 public:
1936 LayerTreeHostTestDeferCommits()
1937 : num_commits_deferred_(0), num_complete_commits_(0) {}
1939 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1941 virtual void DidDeferCommit() OVERRIDE {
1942 num_commits_deferred_++;
1943 layer_tree_host()->SetDeferCommits(false);
1946 virtual void DidCommit() OVERRIDE {
1947 num_complete_commits_++;
1948 switch (num_complete_commits_) {
1949 case 1:
1950 EXPECT_EQ(0, num_commits_deferred_);
1951 layer_tree_host()->SetDeferCommits(true);
1952 PostSetNeedsCommitToMainThread();
1953 break;
1954 case 2:
1955 EndTest();
1956 break;
1957 default:
1958 NOTREACHED();
1959 break;
1963 virtual void AfterTest() OVERRIDE {
1964 EXPECT_EQ(1, num_commits_deferred_);
1965 EXPECT_EQ(2, num_complete_commits_);
1968 private:
1969 int num_commits_deferred_;
1970 int num_complete_commits_;
1973 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
1975 class LayerTreeHostWithProxy : public LayerTreeHost {
1976 public:
1977 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
1978 const LayerTreeSettings& settings,
1979 scoped_ptr<FakeProxy> proxy)
1980 : LayerTreeHost(client, NULL, settings) {
1981 proxy->SetLayerTreeHost(this);
1982 InitializeForTesting(proxy.PassAs<Proxy>());
1986 TEST(LayerTreeHostTest, LimitPartialUpdates) {
1987 // When partial updates are not allowed, max updates should be 0.
1989 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1991 scoped_ptr<FakeProxy> proxy(new FakeProxy);
1992 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
1993 proxy->SetMaxPartialTextureUpdates(5);
1995 LayerTreeSettings settings;
1996 settings.max_partial_texture_updates = 10;
1998 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1999 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
2001 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2004 // When partial updates are allowed,
2005 // max updates should be limited by the proxy.
2007 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2009 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2010 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2011 proxy->SetMaxPartialTextureUpdates(5);
2013 LayerTreeSettings settings;
2014 settings.max_partial_texture_updates = 10;
2016 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2017 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
2019 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2022 // When partial updates are allowed,
2023 // max updates should also be limited by the settings.
2025 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2027 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2028 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2029 proxy->SetMaxPartialTextureUpdates(20);
2031 LayerTreeSettings settings;
2032 settings.max_partial_texture_updates = 10;
2034 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2035 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
2037 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2041 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2042 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2044 LayerTreeSettings settings;
2045 settings.max_partial_texture_updates = 4;
2047 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2048 new TestSharedBitmapManager());
2049 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2050 &client, &client, shared_bitmap_manager.get(), settings);
2051 host->Composite(base::TimeTicks::Now());
2053 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2056 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2057 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2059 LayerTreeSettings settings;
2060 settings.max_partial_texture_updates = 4;
2062 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2063 new TestSharedBitmapManager());
2064 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2065 &client, &client, shared_bitmap_manager.get(), settings);
2066 host->Composite(base::TimeTicks::Now());
2068 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2071 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2072 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2074 LayerTreeSettings settings;
2075 settings.max_partial_texture_updates = 4;
2077 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2078 new TestSharedBitmapManager());
2079 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2080 &client, &client, shared_bitmap_manager.get(), settings);
2081 host->Composite(base::TimeTicks::Now());
2083 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2086 TEST(LayerTreeHostTest,
2087 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2088 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2090 LayerTreeSettings settings;
2091 settings.max_partial_texture_updates = 4;
2093 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2094 new TestSharedBitmapManager());
2095 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2096 &client, &client, shared_bitmap_manager.get(), settings);
2097 host->Composite(base::TimeTicks::Now());
2099 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2102 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2103 : public LayerTreeHostTest {
2104 public:
2105 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2106 : root_layer_(FakeContentLayer::Create(&client_)),
2107 child_layer1_(FakeContentLayer::Create(&client_)),
2108 child_layer2_(FakeContentLayer::Create(&client_)),
2109 num_commits_(0) {}
2111 virtual void BeginTest() OVERRIDE {
2112 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2113 root_layer_->SetBounds(gfx::Size(100, 100));
2114 child_layer1_->SetBounds(gfx::Size(100, 100));
2115 child_layer2_->SetBounds(gfx::Size(100, 100));
2116 root_layer_->AddChild(child_layer1_);
2117 root_layer_->AddChild(child_layer2_);
2118 layer_tree_host()->SetRootLayer(root_layer_);
2119 PostSetNeedsCommitToMainThread();
2122 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2123 bool visible) OVERRIDE {
2124 if (visible) {
2125 // One backing should remain unevicted.
2126 EXPECT_EQ(
2127 100u * 100u * 4u * 1u,
2128 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2129 } else {
2130 EXPECT_EQ(
2131 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2134 // Make sure that contents textures are marked as having been
2135 // purged.
2136 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2137 // End the test in this state.
2138 EndTest();
2141 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2142 ++num_commits_;
2143 switch (num_commits_) {
2144 case 1:
2145 // All three backings should have memory.
2146 EXPECT_EQ(
2147 100u * 100u * 4u * 3u,
2148 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2149 // Set a new policy that will kick out 1 of the 3 resources.
2150 // Because a resource was evicted, a commit will be kicked off.
2151 host_impl->SetMemoryPolicy(
2152 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2153 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2154 1000));
2155 break;
2156 case 2:
2157 // Only two backings should have memory.
2158 EXPECT_EQ(
2159 100u * 100u * 4u * 2u,
2160 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2161 // Become backgrounded, which will cause 1 more resource to be
2162 // evicted.
2163 PostSetVisibleToMainThread(false);
2164 break;
2165 default:
2166 // No further commits should happen because this is not visible
2167 // anymore.
2168 NOTREACHED();
2169 break;
2173 virtual void AfterTest() OVERRIDE {}
2175 private:
2176 FakeContentLayerClient client_;
2177 scoped_refptr<FakeContentLayer> root_layer_;
2178 scoped_refptr<FakeContentLayer> child_layer1_;
2179 scoped_refptr<FakeContentLayer> child_layer2_;
2180 int num_commits_;
2183 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2184 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2186 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2187 public:
2188 class NotificationClient : public ContentLayerClient {
2189 public:
2190 NotificationClient()
2191 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2193 void set_layer(Layer* layer) { layer_ = layer; }
2194 int paint_count() const { return paint_count_; }
2195 int lcd_notification_count() const { return lcd_notification_count_; }
2197 virtual void PaintContents(
2198 SkCanvas* canvas,
2199 const gfx::Rect& clip,
2200 gfx::RectF* opaque,
2201 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
2202 ++paint_count_;
2204 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2205 ++lcd_notification_count_;
2206 layer_->SetNeedsDisplay();
2208 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
2210 private:
2211 Layer* layer_;
2212 int paint_count_;
2213 int lcd_notification_count_;
2216 virtual void SetupTree() OVERRIDE {
2217 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2218 root_layer->SetIsDrawable(true);
2219 root_layer->SetBounds(gfx::Size(1, 1));
2221 layer_tree_host()->SetRootLayer(root_layer);
2222 client_.set_layer(root_layer.get());
2224 // The expecations are based on the assumption that the default
2225 // LCD settings are:
2226 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2227 EXPECT_FALSE(root_layer->can_use_lcd_text());
2229 LayerTreeHostTest::SetupTree();
2232 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2233 virtual void AfterTest() OVERRIDE {}
2235 virtual void DidCommit() OVERRIDE {
2236 switch (layer_tree_host()->source_frame_number()) {
2237 case 1:
2238 // The first update consists one LCD notification and one paint.
2239 EXPECT_EQ(1, client_.lcd_notification_count());
2240 EXPECT_EQ(1, client_.paint_count());
2241 // LCD text must have been enabled on the layer.
2242 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2243 PostSetNeedsCommitToMainThread();
2244 break;
2245 case 2:
2246 // Since nothing changed on layer, there should be no notification
2247 // or paint on the second update.
2248 EXPECT_EQ(1, client_.lcd_notification_count());
2249 EXPECT_EQ(1, client_.paint_count());
2250 // LCD text must not have changed.
2251 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2252 // Change layer opacity that should trigger lcd notification.
2253 layer_tree_host()->root_layer()->SetOpacity(.5f);
2254 // No need to request a commit - setting opacity will do it.
2255 break;
2256 default:
2257 // Verify that there is not extra commit due to layer invalidation.
2258 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
2259 // LCD notification count should have incremented due to
2260 // change in layer opacity.
2261 EXPECT_EQ(2, client_.lcd_notification_count());
2262 // Paint count should be incremented due to invalidation.
2263 EXPECT_EQ(2, client_.paint_count());
2264 // LCD text must have been disabled on the layer due to opacity.
2265 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2266 EndTest();
2267 break;
2271 private:
2272 NotificationClient client_;
2275 SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2277 // Verify that the BeginFrame notification is used to initiate rendering.
2278 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2279 public:
2280 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2281 settings->begin_frame_scheduling_enabled = true;
2284 virtual void BeginTest() OVERRIDE {
2285 // This will trigger a SetNeedsBeginFrame which will trigger a
2286 // BeginFrame.
2287 PostSetNeedsCommitToMainThread();
2290 virtual DrawResult PrepareToDrawOnThread(
2291 LayerTreeHostImpl* host_impl,
2292 LayerTreeHostImpl::FrameData* frame,
2293 DrawResult draw_result) OVERRIDE {
2294 EndTest();
2295 return DRAW_SUCCESS;
2298 virtual void AfterTest() OVERRIDE {}
2300 private:
2301 base::TimeTicks frame_time_;
2304 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2306 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2307 : public LayerTreeHostTest {
2308 public:
2309 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2310 settings->begin_frame_scheduling_enabled = true;
2311 settings->using_synchronous_renderer_compositor = true;
2314 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2316 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2317 // The BeginFrame notification is turned off now but will get enabled
2318 // once we return. End test while it's enabled.
2319 ImplThreadTaskRunner()->PostTask(
2320 FROM_HERE,
2321 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2322 base::Unretained(this)));
2325 virtual void AfterTest() OVERRIDE {}
2328 MULTI_THREAD_TEST_F(
2329 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2331 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2332 protected:
2333 LayerTreeHostTestAbortedCommitDoesntStall()
2334 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2336 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2337 settings->begin_frame_scheduling_enabled = true;
2340 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2342 virtual void DidCommit() OVERRIDE {
2343 commit_count_++;
2344 if (commit_count_ == 4) {
2345 // After two aborted commits, request a real commit now to make sure a
2346 // real commit following an aborted commit will still complete and
2347 // end the test even when the Impl thread is idle.
2348 layer_tree_host()->SetNeedsCommit();
2352 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2353 bool did_handle) OVERRIDE {
2354 commit_abort_count_++;
2355 // Initiate another abortable commit.
2356 host_impl->SetNeedsCommit();
2359 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2360 commit_complete_count_++;
2361 if (commit_complete_count_ == 1) {
2362 // Initiate an abortable commit after the first commit.
2363 host_impl->SetNeedsCommit();
2364 } else {
2365 EndTest();
2369 virtual void AfterTest() OVERRIDE {
2370 EXPECT_EQ(commit_count_, 5);
2371 EXPECT_EQ(commit_abort_count_, 3);
2372 EXPECT_EQ(commit_complete_count_, 2);
2375 int commit_count_;
2376 int commit_abort_count_;
2377 int commit_complete_count_;
2380 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2381 : public LayerTreeHostTestAbortedCommitDoesntStall {
2382 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2383 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2384 settings->using_synchronous_renderer_compositor = true;
2388 MULTI_THREAD_TEST_F(
2389 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2391 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2392 : public LayerTreeHostTestAbortedCommitDoesntStall {
2393 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2394 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2395 settings->throttle_frame_production = false;
2399 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2401 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2402 : public LayerTreeHostTest {
2403 protected:
2404 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2405 settings->impl_side_painting = true;
2408 virtual void SetupTree() OVERRIDE {
2409 LayerTreeHostTest::SetupTree();
2411 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2412 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2413 layer->SetBounds(gfx::Size(10, 10));
2414 layer_tree_host()->root_layer()->AddChild(layer);
2417 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2419 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2420 EndTest();
2423 virtual void AfterTest() OVERRIDE {}
2425 FakeContentLayerClient client_;
2428 MULTI_THREAD_TEST_F(
2429 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2431 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2432 : public LayerTreeHostTest {
2433 public:
2434 class SetBoundsClient : public ContentLayerClient {
2435 public:
2436 SetBoundsClient() : layer_(0) {}
2438 void set_layer(Layer* layer) { layer_ = layer; }
2440 virtual void PaintContents(
2441 SkCanvas* canvas,
2442 const gfx::Rect& clip,
2443 gfx::RectF* opaque,
2444 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
2445 layer_->SetBounds(gfx::Size(2, 2));
2448 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2450 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
2452 private:
2453 Layer* layer_;
2456 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2458 virtual void SetupTree() OVERRIDE {
2459 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2460 root_layer->SetIsDrawable(true);
2461 root_layer->SetBounds(gfx::Size(1, 1));
2463 layer_tree_host()->SetRootLayer(root_layer);
2464 client_.set_layer(root_layer.get());
2466 LayerTreeHostTest::SetupTree();
2469 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2470 virtual void AfterTest() OVERRIDE {}
2472 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2473 num_commits_++;
2474 if (num_commits_ == 1) {
2475 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2476 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2477 } else {
2478 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2479 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2480 EndTest();
2484 private:
2485 SetBoundsClient client_;
2486 int num_commits_;
2489 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2491 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2492 public:
2493 MockIOSurfaceWebGraphicsContext3D() {
2494 test_capabilities_.gpu.iosurface = true;
2495 test_capabilities_.gpu.texture_rectangle = true;
2498 virtual GLuint createTexture() OVERRIDE {
2499 return 1;
2501 MOCK_METHOD1(activeTexture, void(GLenum texture));
2502 MOCK_METHOD2(bindTexture, void(GLenum target,
2503 GLuint texture_id));
2504 MOCK_METHOD3(texParameteri, void(GLenum target,
2505 GLenum pname,
2506 GLint param));
2507 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2508 GLint width,
2509 GLint height,
2510 GLuint ioSurfaceId,
2511 GLuint plane));
2512 MOCK_METHOD4(drawElements, void(GLenum mode,
2513 GLsizei count,
2514 GLenum type,
2515 GLintptr offset));
2516 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2517 MOCK_METHOD2(produceTextureCHROMIUM,
2518 void(GLenum target, const GLbyte* mailbox));
2521 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2522 protected:
2523 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
2524 OVERRIDE {
2525 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2526 new MockIOSurfaceWebGraphicsContext3D);
2527 mock_context_ = mock_context_owned.get();
2529 if (delegating_renderer()) {
2530 return FakeOutputSurface::CreateDelegating3d(
2531 mock_context_owned.PassAs<TestWebGraphicsContext3D>());
2532 } else {
2533 return FakeOutputSurface::Create3d(
2534 mock_context_owned.PassAs<TestWebGraphicsContext3D>());
2538 virtual void SetupTree() OVERRIDE {
2539 LayerTreeHostTest::SetupTree();
2541 layer_tree_host()->root_layer()->SetIsDrawable(false);
2543 io_surface_id_ = 9;
2544 io_surface_size_ = gfx::Size(6, 7);
2546 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2547 io_surface_layer->SetBounds(gfx::Size(10, 10));
2548 io_surface_layer->SetAnchorPoint(gfx::PointF());
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 SetAnchorPoint(gfx::PointF());
2957 SetBounds(gfx::Size(1, 1));
2961 class PushPropertiesCountingLayer : public Layer {
2962 public:
2963 static scoped_refptr<PushPropertiesCountingLayer> Create() {
2964 return new PushPropertiesCountingLayer();
2967 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
2968 Layer::PushPropertiesTo(layer);
2969 push_properties_count_++;
2970 if (persist_needs_push_properties_)
2971 needs_push_properties_ = true;
2974 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
2975 OVERRIDE {
2976 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
2977 PassAs<LayerImpl>();
2980 size_t push_properties_count() const { return push_properties_count_; }
2981 void reset_push_properties_count() { push_properties_count_ = 0; }
2983 void set_persist_needs_push_properties(bool persist) {
2984 persist_needs_push_properties_ = persist;
2987 private:
2988 PushPropertiesCountingLayer()
2989 : push_properties_count_(0), persist_needs_push_properties_(false) {
2990 SetAnchorPoint(gfx::PointF());
2991 SetBounds(gfx::Size(1, 1));
2992 SetIsDrawable(true);
2994 virtual ~PushPropertiesCountingLayer() {}
2996 size_t push_properties_count_;
2997 bool persist_needs_push_properties_;
3000 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3001 protected:
3002 virtual void BeginTest() OVERRIDE {
3003 num_commits_ = 0;
3004 expected_push_properties_root_ = 0;
3005 expected_push_properties_child_ = 0;
3006 expected_push_properties_grandchild_ = 0;
3007 expected_push_properties_child2_ = 0;
3008 expected_push_properties_other_root_ = 0;
3009 expected_push_properties_leaf_layer_ = 0;
3010 PostSetNeedsCommitToMainThread();
3013 virtual void SetupTree() OVERRIDE {
3014 root_ = PushPropertiesCountingLayer::Create();
3015 child_ = PushPropertiesCountingLayer::Create();
3016 child2_ = PushPropertiesCountingLayer::Create();
3017 grandchild_ = PushPropertiesCountingLayer::Create();
3018 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3019 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3021 root_->AddChild(child_);
3022 root_->AddChild(child2_);
3023 child_->AddChild(grandchild_);
3024 child2_->AddChild(leaf_always_pushing_layer_);
3026 other_root_ = PushPropertiesCountingLayer::Create();
3028 // Don't set the root layer here.
3029 LayerTreeHostTest::SetupTree();
3032 virtual void DidCommitAndDrawFrame() OVERRIDE {
3033 ++num_commits_;
3035 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3036 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3037 EXPECT_EQ(expected_push_properties_grandchild_,
3038 grandchild_->push_properties_count());
3039 EXPECT_EQ(expected_push_properties_child2_,
3040 child2_->push_properties_count());
3041 EXPECT_EQ(expected_push_properties_other_root_,
3042 other_root_->push_properties_count());
3043 EXPECT_EQ(expected_push_properties_leaf_layer_,
3044 leaf_always_pushing_layer_->push_properties_count());
3046 // The scrollbar layer always needs to be pushed.
3047 if (root_->layer_tree_host()) {
3048 EXPECT_TRUE(root_->descendant_needs_push_properties());
3049 EXPECT_FALSE(root_->needs_push_properties());
3051 if (child2_->layer_tree_host()) {
3052 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3053 EXPECT_FALSE(child2_->needs_push_properties());
3055 if (leaf_always_pushing_layer_->layer_tree_host()) {
3056 EXPECT_FALSE(
3057 leaf_always_pushing_layer_->descendant_needs_push_properties());
3058 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3061 // child_ and grandchild_ don't persist their need to push properties.
3062 if (child_->layer_tree_host()) {
3063 EXPECT_FALSE(child_->descendant_needs_push_properties());
3064 EXPECT_FALSE(child_->needs_push_properties());
3066 if (grandchild_->layer_tree_host()) {
3067 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3068 EXPECT_FALSE(grandchild_->needs_push_properties());
3071 if (other_root_->layer_tree_host()) {
3072 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3073 EXPECT_FALSE(other_root_->needs_push_properties());
3076 switch (num_commits_) {
3077 case 1:
3078 layer_tree_host()->SetRootLayer(root_);
3079 // Layers added to the tree get committed.
3080 ++expected_push_properties_root_;
3081 ++expected_push_properties_child_;
3082 ++expected_push_properties_grandchild_;
3083 ++expected_push_properties_child2_;
3084 break;
3085 case 2:
3086 layer_tree_host()->SetNeedsCommit();
3087 // No layers need commit.
3088 break;
3089 case 3:
3090 layer_tree_host()->SetRootLayer(other_root_);
3091 // Layers added to the tree get committed.
3092 ++expected_push_properties_other_root_;
3093 break;
3094 case 4:
3095 layer_tree_host()->SetRootLayer(root_);
3096 // Layers added to the tree get committed.
3097 ++expected_push_properties_root_;
3098 ++expected_push_properties_child_;
3099 ++expected_push_properties_grandchild_;
3100 ++expected_push_properties_child2_;
3101 break;
3102 case 5:
3103 layer_tree_host()->SetNeedsCommit();
3104 // No layers need commit.
3105 break;
3106 case 6:
3107 child_->RemoveFromParent();
3108 // No layers need commit.
3109 break;
3110 case 7:
3111 root_->AddChild(child_);
3112 // Layers added to the tree get committed.
3113 ++expected_push_properties_child_;
3114 ++expected_push_properties_grandchild_;
3115 break;
3116 case 8:
3117 grandchild_->RemoveFromParent();
3118 // No layers need commit.
3119 break;
3120 case 9:
3121 child_->AddChild(grandchild_);
3122 // Layers added to the tree get committed.
3123 ++expected_push_properties_grandchild_;
3124 break;
3125 case 10:
3126 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3127 // No layers need commit.
3128 break;
3129 case 11:
3130 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3131 // No layers need commit.
3132 break;
3133 case 12:
3134 child_->SetPosition(gfx::Point(1, 1));
3135 // The modified layer needs commit
3136 ++expected_push_properties_child_;
3137 break;
3138 case 13:
3139 child2_->SetPosition(gfx::Point(1, 1));
3140 // The modified layer needs commit
3141 ++expected_push_properties_child2_;
3142 break;
3143 case 14:
3144 child_->RemoveFromParent();
3145 root_->AddChild(child_);
3146 // Layers added to the tree get committed.
3147 ++expected_push_properties_child_;
3148 ++expected_push_properties_grandchild_;
3149 break;
3150 case 15:
3151 grandchild_->SetPosition(gfx::Point(1, 1));
3152 // The modified layer needs commit
3153 ++expected_push_properties_grandchild_;
3154 break;
3155 case 16:
3156 // SetNeedsDisplay does not always set needs commit (so call it
3157 // explicitly), but is a property change.
3158 child_->SetNeedsDisplay();
3159 ++expected_push_properties_child_;
3160 layer_tree_host()->SetNeedsCommit();
3161 break;
3162 case 17:
3163 EndTest();
3164 break;
3167 // The leaf layer always pushes.
3168 if (leaf_always_pushing_layer_->layer_tree_host())
3169 ++expected_push_properties_leaf_layer_;
3172 virtual void AfterTest() OVERRIDE {}
3174 int num_commits_;
3175 FakeContentLayerClient client_;
3176 scoped_refptr<PushPropertiesCountingLayer> root_;
3177 scoped_refptr<PushPropertiesCountingLayer> child_;
3178 scoped_refptr<PushPropertiesCountingLayer> child2_;
3179 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3180 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3181 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3182 size_t expected_push_properties_root_;
3183 size_t expected_push_properties_child_;
3184 size_t expected_push_properties_child2_;
3185 size_t expected_push_properties_grandchild_;
3186 size_t expected_push_properties_other_root_;
3187 size_t expected_push_properties_leaf_layer_;
3190 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3192 class LayerTreeHostTestImplLayersPushProperties
3193 : public LayerTreeHostTestLayersPushProperties {
3194 protected:
3195 virtual void BeginTest() OVERRIDE {
3196 expected_push_properties_root_impl_ = 0;
3197 expected_push_properties_child_impl_ = 0;
3198 expected_push_properties_grandchild_impl_ = 0;
3199 expected_push_properties_child2_impl_ = 0;
3200 expected_push_properties_grandchild2_impl_ = 0;
3201 LayerTreeHostTestLayersPushProperties::BeginTest();
3204 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3205 // These commits are in response to the changes made in
3206 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3207 switch (num_commits_) {
3208 case 0:
3209 // Tree hasn't been setup yet don't bother to check anything.
3210 return;
3211 case 1:
3212 // Root gets set up, Everyone is initialized.
3213 ++expected_push_properties_root_impl_;
3214 ++expected_push_properties_child_impl_;
3215 ++expected_push_properties_grandchild_impl_;
3216 ++expected_push_properties_child2_impl_;
3217 ++expected_push_properties_grandchild2_impl_;
3218 break;
3219 case 2:
3220 // Tree doesn't change but the one leaf that always pushes is pushed.
3221 ++expected_push_properties_grandchild2_impl_;
3222 break;
3223 case 3:
3224 // Root is swapped here.
3225 // Clear the expected push properties the tree will be rebuilt.
3226 expected_push_properties_root_impl_ = 0;
3227 expected_push_properties_child_impl_ = 0;
3228 expected_push_properties_grandchild_impl_ = 0;
3229 expected_push_properties_child2_impl_ = 0;
3230 expected_push_properties_grandchild2_impl_ = 0;
3232 // Make sure the new root is pushed.
3233 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3234 host_impl->RootLayer())->push_properties_count());
3235 return;
3236 case 4:
3237 // Root is swapped back all of the layers in the tree get pushed.
3238 ++expected_push_properties_root_impl_;
3239 ++expected_push_properties_child_impl_;
3240 ++expected_push_properties_grandchild_impl_;
3241 ++expected_push_properties_child2_impl_;
3242 ++expected_push_properties_grandchild2_impl_;
3243 break;
3244 case 5:
3245 // Tree doesn't change but the one leaf that always pushes is pushed.
3246 ++expected_push_properties_grandchild2_impl_;
3247 break;
3248 case 6:
3249 // First child is removed. Structure of the tree changes here so swap
3250 // some of the values. child_impl becomes child2_impl.
3251 expected_push_properties_child_impl_ =
3252 expected_push_properties_child2_impl_;
3253 expected_push_properties_child2_impl_ = 0;
3254 // grandchild_impl becomes grandchild2_impl.
3255 expected_push_properties_grandchild_impl_ =
3256 expected_push_properties_grandchild2_impl_;
3257 expected_push_properties_grandchild2_impl_ = 0;
3259 // grandchild_impl is now the leaf that always pushes. It is pushed.
3260 ++expected_push_properties_grandchild_impl_;
3261 break;
3262 case 7:
3263 // The leaf that always pushes is pushed.
3264 ++expected_push_properties_grandchild_impl_;
3266 // Child is added back. New layers are initialized.
3267 ++expected_push_properties_grandchild2_impl_;
3268 ++expected_push_properties_child2_impl_;
3269 break;
3270 case 8:
3271 // Leaf is removed.
3272 expected_push_properties_grandchild2_impl_ = 0;
3274 // Always pushing.
3275 ++expected_push_properties_grandchild_impl_;
3276 break;
3277 case 9:
3278 // Leaf is added back
3279 ++expected_push_properties_grandchild2_impl_;
3281 // The leaf that always pushes is pushed.
3282 ++expected_push_properties_grandchild_impl_;
3283 break;
3284 case 10:
3285 // The leaf that always pushes is pushed.
3286 ++expected_push_properties_grandchild_impl_;
3287 break;
3288 case 11:
3289 // The leaf that always pushes is pushed.
3290 ++expected_push_properties_grandchild_impl_;
3291 break;
3292 case 12:
3293 // The leaf that always pushes is pushed.
3294 ++expected_push_properties_grandchild_impl_;
3296 // This child position was changed.
3297 ++expected_push_properties_child2_impl_;
3298 break;
3299 case 13:
3300 // The position of this child was changed.
3301 ++expected_push_properties_child_impl_;
3303 // The leaf that always pushes is pushed.
3304 ++expected_push_properties_grandchild_impl_;
3305 break;
3306 case 14:
3307 // Second child is removed from tree. Don't discard counts because
3308 // they are added back before commit.
3310 // The leaf that always pushes is pushed.
3311 ++expected_push_properties_grandchild_impl_;
3313 // Second child added back.
3314 ++expected_push_properties_child2_impl_;
3315 ++expected_push_properties_grandchild2_impl_;
3317 break;
3318 case 15:
3319 // The position of this child was changed.
3320 ++expected_push_properties_grandchild2_impl_;
3322 // The leaf that always pushes is pushed.
3323 ++expected_push_properties_grandchild_impl_;
3324 break;
3325 case 16:
3326 // Second child is invalidated with SetNeedsDisplay
3327 ++expected_push_properties_child2_impl_;
3329 // The leaf that always pushed is pushed.
3330 ++expected_push_properties_grandchild_impl_;
3331 break;
3334 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3335 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3336 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3337 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3338 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3340 // Pull the layers that we need from the tree assuming the same structure
3341 // as LayerTreeHostTestLayersPushProperties
3342 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3343 host_impl->RootLayer());
3345 if (root_impl_ && root_impl_->children().size() > 0) {
3346 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3347 root_impl_->children()[0]);
3349 if (child_impl_ && child_impl_->children().size() > 0)
3350 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3351 child_impl_->children()[0]);
3354 if (root_impl_ && root_impl_->children().size() > 1) {
3355 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3356 root_impl_->children()[1]);
3358 if (child2_impl_ && child2_impl_->children().size() > 0)
3359 leaf_always_pushing_layer_impl_ =
3360 static_cast<PushPropertiesCountingLayerImpl*>(
3361 child2_impl_->children()[0]);
3364 if (root_impl_)
3365 EXPECT_EQ(expected_push_properties_root_impl_,
3366 root_impl_->push_properties_count());
3367 if (child_impl_)
3368 EXPECT_EQ(expected_push_properties_child_impl_,
3369 child_impl_->push_properties_count());
3370 if (grandchild_impl_)
3371 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3372 grandchild_impl_->push_properties_count());
3373 if (child2_impl_)
3374 EXPECT_EQ(expected_push_properties_child2_impl_,
3375 child2_impl_->push_properties_count());
3376 if (leaf_always_pushing_layer_impl_)
3377 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3378 leaf_always_pushing_layer_impl_->push_properties_count());
3381 size_t expected_push_properties_root_impl_;
3382 size_t expected_push_properties_child_impl_;
3383 size_t expected_push_properties_child2_impl_;
3384 size_t expected_push_properties_grandchild_impl_;
3385 size_t expected_push_properties_grandchild2_impl_;
3388 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3389 RunTestWithImplSidePainting();
3392 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3393 : public LayerTreeHostTest {
3394 protected:
3395 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3397 virtual void SetupTree() OVERRIDE {
3398 root_ = Layer::Create();
3399 root_->SetBounds(gfx::Size(1, 1));
3401 bool paint_scrollbar = true;
3402 bool has_thumb = false;
3403 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3404 paint_scrollbar, has_thumb, root_->id());
3406 root_->AddChild(scrollbar_layer_);
3408 layer_tree_host()->SetRootLayer(root_);
3409 LayerTreeHostTest::SetupTree();
3412 virtual void DidCommitAndDrawFrame() OVERRIDE {
3413 switch (layer_tree_host()->source_frame_number()) {
3414 case 0:
3415 break;
3416 case 1: {
3417 // During update, the ignore_set_needs_commit_ bit is set to true to
3418 // avoid causing a second commit to be scheduled. If a property change
3419 // is made during this, however, it needs to be pushed in the upcoming
3420 // commit.
3421 scoped_ptr<base::AutoReset<bool> > ignore =
3422 scrollbar_layer_->IgnoreSetNeedsCommit();
3424 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3426 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3427 EXPECT_TRUE(root_->descendant_needs_push_properties());
3428 layer_tree_host()->SetNeedsCommit();
3430 scrollbar_layer_->reset_push_properties_count();
3431 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3432 break;
3434 case 2:
3435 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3436 EndTest();
3437 break;
3441 virtual void AfterTest() OVERRIDE {}
3443 scoped_refptr<Layer> root_;
3444 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3447 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3449 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3450 : public LayerTreeHostTest {
3451 protected:
3452 virtual void BeginTest() OVERRIDE {
3453 expected_push_properties_root_ = 0;
3454 expected_push_properties_child_ = 0;
3455 expected_push_properties_grandchild1_ = 0;
3456 expected_push_properties_grandchild2_ = 0;
3457 expected_push_properties_grandchild3_ = 0;
3458 PostSetNeedsCommitToMainThread();
3461 virtual void SetupTree() OVERRIDE {
3462 root_ = PushPropertiesCountingLayer::Create();
3463 child_ = PushPropertiesCountingLayer::Create();
3464 grandchild1_ = PushPropertiesCountingLayer::Create();
3465 grandchild2_ = PushPropertiesCountingLayer::Create();
3466 grandchild3_ = PushPropertiesCountingLayer::Create();
3468 root_->AddChild(child_);
3469 child_->AddChild(grandchild1_);
3470 child_->AddChild(grandchild2_);
3471 child_->AddChild(grandchild3_);
3473 // Don't set the root layer here.
3474 LayerTreeHostTest::SetupTree();
3477 virtual void AfterTest() OVERRIDE {}
3479 FakeContentLayerClient client_;
3480 scoped_refptr<PushPropertiesCountingLayer> root_;
3481 scoped_refptr<PushPropertiesCountingLayer> child_;
3482 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3483 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3484 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3485 size_t expected_push_properties_root_;
3486 size_t expected_push_properties_child_;
3487 size_t expected_push_properties_grandchild1_;
3488 size_t expected_push_properties_grandchild2_;
3489 size_t expected_push_properties_grandchild3_;
3492 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3493 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3494 protected:
3495 virtual void DidCommitAndDrawFrame() OVERRIDE {
3496 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3497 switch (last_source_frame_number) {
3498 case 0:
3499 EXPECT_FALSE(root_->needs_push_properties());
3500 EXPECT_FALSE(root_->descendant_needs_push_properties());
3501 EXPECT_FALSE(child_->needs_push_properties());
3502 EXPECT_FALSE(child_->descendant_needs_push_properties());
3503 EXPECT_FALSE(grandchild1_->needs_push_properties());
3504 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3505 EXPECT_FALSE(grandchild2_->needs_push_properties());
3506 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3507 EXPECT_FALSE(grandchild3_->needs_push_properties());
3508 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3510 layer_tree_host()->SetRootLayer(root_);
3512 EXPECT_TRUE(root_->needs_push_properties());
3513 EXPECT_TRUE(root_->descendant_needs_push_properties());
3514 EXPECT_TRUE(child_->needs_push_properties());
3515 EXPECT_TRUE(child_->descendant_needs_push_properties());
3516 EXPECT_TRUE(grandchild1_->needs_push_properties());
3517 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3518 EXPECT_TRUE(grandchild2_->needs_push_properties());
3519 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3520 EXPECT_TRUE(grandchild3_->needs_push_properties());
3521 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3522 break;
3523 case 1:
3524 EndTest();
3525 break;
3530 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3532 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3533 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3534 protected:
3535 virtual void DidCommitAndDrawFrame() OVERRIDE {
3536 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3537 switch (last_source_frame_number) {
3538 case 0:
3539 layer_tree_host()->SetRootLayer(root_);
3540 break;
3541 case 1:
3542 EXPECT_FALSE(root_->needs_push_properties());
3543 EXPECT_FALSE(root_->descendant_needs_push_properties());
3544 EXPECT_FALSE(child_->needs_push_properties());
3545 EXPECT_FALSE(child_->descendant_needs_push_properties());
3546 EXPECT_FALSE(grandchild1_->needs_push_properties());
3547 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3548 EXPECT_FALSE(grandchild2_->needs_push_properties());
3549 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3550 EXPECT_FALSE(grandchild3_->needs_push_properties());
3551 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3553 grandchild1_->RemoveFromParent();
3554 grandchild1_->SetPosition(gfx::Point(1, 1));
3556 EXPECT_FALSE(root_->needs_push_properties());
3557 EXPECT_FALSE(root_->descendant_needs_push_properties());
3558 EXPECT_FALSE(child_->needs_push_properties());
3559 EXPECT_FALSE(child_->descendant_needs_push_properties());
3560 EXPECT_FALSE(grandchild2_->needs_push_properties());
3561 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3562 EXPECT_FALSE(grandchild3_->needs_push_properties());
3563 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3565 child_->AddChild(grandchild1_);
3567 EXPECT_FALSE(root_->needs_push_properties());
3568 EXPECT_TRUE(root_->descendant_needs_push_properties());
3569 EXPECT_FALSE(child_->needs_push_properties());
3570 EXPECT_TRUE(child_->descendant_needs_push_properties());
3571 EXPECT_TRUE(grandchild1_->needs_push_properties());
3572 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3573 EXPECT_FALSE(grandchild2_->needs_push_properties());
3574 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3575 EXPECT_FALSE(grandchild3_->needs_push_properties());
3576 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3578 grandchild2_->SetPosition(gfx::Point(1, 1));
3580 EXPECT_FALSE(root_->needs_push_properties());
3581 EXPECT_TRUE(root_->descendant_needs_push_properties());
3582 EXPECT_FALSE(child_->needs_push_properties());
3583 EXPECT_TRUE(child_->descendant_needs_push_properties());
3584 EXPECT_TRUE(grandchild1_->needs_push_properties());
3585 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3586 EXPECT_TRUE(grandchild2_->needs_push_properties());
3587 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3588 EXPECT_FALSE(grandchild3_->needs_push_properties());
3589 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3591 // grandchild2_ will still need a push properties.
3592 grandchild1_->RemoveFromParent();
3594 EXPECT_FALSE(root_->needs_push_properties());
3595 EXPECT_TRUE(root_->descendant_needs_push_properties());
3596 EXPECT_FALSE(child_->needs_push_properties());
3597 EXPECT_TRUE(child_->descendant_needs_push_properties());
3599 // grandchild3_ does not need a push properties, so recursing should
3600 // no longer be needed.
3601 grandchild2_->RemoveFromParent();
3603 EXPECT_FALSE(root_->needs_push_properties());
3604 EXPECT_FALSE(root_->descendant_needs_push_properties());
3605 EXPECT_FALSE(child_->needs_push_properties());
3606 EXPECT_FALSE(child_->descendant_needs_push_properties());
3607 EndTest();
3608 break;
3613 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3615 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3616 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3617 protected:
3618 virtual void DidCommitAndDrawFrame() OVERRIDE {
3619 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3620 switch (last_source_frame_number) {
3621 case 0:
3622 layer_tree_host()->SetRootLayer(root_);
3623 grandchild1_->set_persist_needs_push_properties(true);
3624 grandchild2_->set_persist_needs_push_properties(true);
3625 break;
3626 case 1:
3627 EXPECT_FALSE(root_->needs_push_properties());
3628 EXPECT_TRUE(root_->descendant_needs_push_properties());
3629 EXPECT_FALSE(child_->needs_push_properties());
3630 EXPECT_TRUE(child_->descendant_needs_push_properties());
3631 EXPECT_TRUE(grandchild1_->needs_push_properties());
3632 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3633 EXPECT_TRUE(grandchild2_->needs_push_properties());
3634 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3635 EXPECT_FALSE(grandchild3_->needs_push_properties());
3636 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3638 // grandchild2_ will still need a push properties.
3639 grandchild1_->RemoveFromParent();
3641 EXPECT_FALSE(root_->needs_push_properties());
3642 EXPECT_TRUE(root_->descendant_needs_push_properties());
3643 EXPECT_FALSE(child_->needs_push_properties());
3644 EXPECT_TRUE(child_->descendant_needs_push_properties());
3646 // grandchild3_ does not need a push properties, so recursing should
3647 // no longer be needed.
3648 grandchild2_->RemoveFromParent();
3650 EXPECT_FALSE(root_->needs_push_properties());
3651 EXPECT_FALSE(root_->descendant_needs_push_properties());
3652 EXPECT_FALSE(child_->needs_push_properties());
3653 EXPECT_FALSE(child_->descendant_needs_push_properties());
3654 EndTest();
3655 break;
3660 MULTI_THREAD_TEST_F(
3661 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3663 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3664 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3665 protected:
3666 virtual void DidCommitAndDrawFrame() OVERRIDE {
3667 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3668 switch (last_source_frame_number) {
3669 case 0:
3670 layer_tree_host()->SetRootLayer(root_);
3671 break;
3672 case 1:
3673 EXPECT_FALSE(root_->needs_push_properties());
3674 EXPECT_FALSE(root_->descendant_needs_push_properties());
3675 EXPECT_FALSE(child_->needs_push_properties());
3676 EXPECT_FALSE(child_->descendant_needs_push_properties());
3677 EXPECT_FALSE(grandchild1_->needs_push_properties());
3678 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3679 EXPECT_FALSE(grandchild2_->needs_push_properties());
3680 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3681 EXPECT_FALSE(grandchild3_->needs_push_properties());
3682 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3684 // Change grandchildren while their parent is not in the tree.
3685 child_->RemoveFromParent();
3686 grandchild1_->SetPosition(gfx::Point(1, 1));
3687 grandchild2_->SetPosition(gfx::Point(1, 1));
3688 root_->AddChild(child_);
3690 EXPECT_FALSE(root_->needs_push_properties());
3691 EXPECT_TRUE(root_->descendant_needs_push_properties());
3692 EXPECT_TRUE(child_->needs_push_properties());
3693 EXPECT_TRUE(child_->descendant_needs_push_properties());
3694 EXPECT_TRUE(grandchild1_->needs_push_properties());
3695 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3696 EXPECT_TRUE(grandchild2_->needs_push_properties());
3697 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3698 EXPECT_TRUE(grandchild3_->needs_push_properties());
3699 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3701 grandchild1_->RemoveFromParent();
3703 EXPECT_FALSE(root_->needs_push_properties());
3704 EXPECT_TRUE(root_->descendant_needs_push_properties());
3705 EXPECT_TRUE(child_->needs_push_properties());
3706 EXPECT_TRUE(child_->descendant_needs_push_properties());
3708 grandchild2_->RemoveFromParent();
3710 EXPECT_FALSE(root_->needs_push_properties());
3711 EXPECT_TRUE(root_->descendant_needs_push_properties());
3712 EXPECT_TRUE(child_->needs_push_properties());
3713 EXPECT_TRUE(child_->descendant_needs_push_properties());
3715 grandchild3_->RemoveFromParent();
3717 EXPECT_FALSE(root_->needs_push_properties());
3718 EXPECT_TRUE(root_->descendant_needs_push_properties());
3719 EXPECT_TRUE(child_->needs_push_properties());
3720 EXPECT_FALSE(child_->descendant_needs_push_properties());
3722 EndTest();
3723 break;
3728 MULTI_THREAD_TEST_F(
3729 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3731 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3732 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3733 protected:
3734 virtual void DidCommitAndDrawFrame() OVERRIDE {
3735 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3736 switch (last_source_frame_number) {
3737 case 0:
3738 layer_tree_host()->SetRootLayer(root_);
3739 break;
3740 case 1:
3741 EXPECT_FALSE(root_->needs_push_properties());
3742 EXPECT_FALSE(root_->descendant_needs_push_properties());
3743 EXPECT_FALSE(child_->needs_push_properties());
3744 EXPECT_FALSE(child_->descendant_needs_push_properties());
3745 EXPECT_FALSE(grandchild1_->needs_push_properties());
3746 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3747 EXPECT_FALSE(grandchild2_->needs_push_properties());
3748 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3749 EXPECT_FALSE(grandchild3_->needs_push_properties());
3750 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3752 child_->SetPosition(gfx::Point(1, 1));
3753 grandchild1_->SetPosition(gfx::Point(1, 1));
3754 grandchild2_->SetPosition(gfx::Point(1, 1));
3756 EXPECT_FALSE(root_->needs_push_properties());
3757 EXPECT_TRUE(root_->descendant_needs_push_properties());
3758 EXPECT_TRUE(child_->needs_push_properties());
3759 EXPECT_TRUE(child_->descendant_needs_push_properties());
3760 EXPECT_TRUE(grandchild1_->needs_push_properties());
3761 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3762 EXPECT_TRUE(grandchild2_->needs_push_properties());
3763 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3764 EXPECT_FALSE(grandchild3_->needs_push_properties());
3765 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3767 grandchild1_->RemoveFromParent();
3769 EXPECT_FALSE(root_->needs_push_properties());
3770 EXPECT_TRUE(root_->descendant_needs_push_properties());
3771 EXPECT_TRUE(child_->needs_push_properties());
3772 EXPECT_TRUE(child_->descendant_needs_push_properties());
3774 grandchild2_->RemoveFromParent();
3776 EXPECT_FALSE(root_->needs_push_properties());
3777 EXPECT_TRUE(root_->descendant_needs_push_properties());
3778 EXPECT_TRUE(child_->needs_push_properties());
3779 EXPECT_FALSE(child_->descendant_needs_push_properties());
3781 child_->RemoveFromParent();
3783 EXPECT_FALSE(root_->needs_push_properties());
3784 EXPECT_FALSE(root_->descendant_needs_push_properties());
3786 EndTest();
3787 break;
3792 MULTI_THREAD_TEST_F(
3793 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
3795 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
3796 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3797 protected:
3798 virtual void DidCommitAndDrawFrame() OVERRIDE {
3799 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3800 switch (last_source_frame_number) {
3801 case 0:
3802 layer_tree_host()->SetRootLayer(root_);
3803 break;
3804 case 1:
3805 EXPECT_FALSE(root_->needs_push_properties());
3806 EXPECT_FALSE(root_->descendant_needs_push_properties());
3807 EXPECT_FALSE(child_->needs_push_properties());
3808 EXPECT_FALSE(child_->descendant_needs_push_properties());
3809 EXPECT_FALSE(grandchild1_->needs_push_properties());
3810 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3811 EXPECT_FALSE(grandchild2_->needs_push_properties());
3812 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3813 EXPECT_FALSE(grandchild3_->needs_push_properties());
3814 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3816 grandchild1_->SetPosition(gfx::Point(1, 1));
3817 grandchild2_->SetPosition(gfx::Point(1, 1));
3818 child_->SetPosition(gfx::Point(1, 1));
3820 EXPECT_FALSE(root_->needs_push_properties());
3821 EXPECT_TRUE(root_->descendant_needs_push_properties());
3822 EXPECT_TRUE(child_->needs_push_properties());
3823 EXPECT_TRUE(child_->descendant_needs_push_properties());
3824 EXPECT_TRUE(grandchild1_->needs_push_properties());
3825 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3826 EXPECT_TRUE(grandchild2_->needs_push_properties());
3827 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3828 EXPECT_FALSE(grandchild3_->needs_push_properties());
3829 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3831 grandchild1_->RemoveFromParent();
3833 EXPECT_FALSE(root_->needs_push_properties());
3834 EXPECT_TRUE(root_->descendant_needs_push_properties());
3835 EXPECT_TRUE(child_->needs_push_properties());
3836 EXPECT_TRUE(child_->descendant_needs_push_properties());
3838 grandchild2_->RemoveFromParent();
3840 EXPECT_FALSE(root_->needs_push_properties());
3841 EXPECT_TRUE(root_->descendant_needs_push_properties());
3842 EXPECT_TRUE(child_->needs_push_properties());
3843 EXPECT_FALSE(child_->descendant_needs_push_properties());
3845 child_->RemoveFromParent();
3847 EXPECT_FALSE(root_->needs_push_properties());
3848 EXPECT_FALSE(root_->descendant_needs_push_properties());
3850 EndTest();
3851 break;
3856 MULTI_THREAD_TEST_F(
3857 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
3859 // This test verifies that the tree activation callback is invoked correctly.
3860 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
3861 public:
3862 LayerTreeHostTestTreeActivationCallback()
3863 : num_commits_(0), callback_count_(0) {}
3865 virtual void BeginTest() OVERRIDE {
3866 EXPECT_TRUE(HasImplThread());
3867 PostSetNeedsCommitToMainThread();
3870 virtual DrawResult PrepareToDrawOnThread(
3871 LayerTreeHostImpl* host_impl,
3872 LayerTreeHostImpl::FrameData* frame_data,
3873 DrawResult draw_result) OVERRIDE {
3874 ++num_commits_;
3875 switch (num_commits_) {
3876 case 1:
3877 EXPECT_EQ(0, callback_count_);
3878 callback_count_ = 0;
3879 SetCallback(true);
3880 PostSetNeedsCommitToMainThread();
3881 break;
3882 case 2:
3883 EXPECT_EQ(1, callback_count_);
3884 callback_count_ = 0;
3885 SetCallback(false);
3886 PostSetNeedsCommitToMainThread();
3887 break;
3888 case 3:
3889 EXPECT_EQ(0, callback_count_);
3890 callback_count_ = 0;
3891 EndTest();
3892 break;
3893 default:
3894 ADD_FAILURE() << num_commits_;
3895 EndTest();
3896 break;
3898 return LayerTreeHostTest::PrepareToDrawOnThread(
3899 host_impl, frame_data, draw_result);
3902 virtual void AfterTest() OVERRIDE { EXPECT_EQ(3, num_commits_); }
3904 void SetCallback(bool enable) {
3905 output_surface()->SetTreeActivationCallback(
3906 enable
3907 ? base::Bind(
3908 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
3909 base::Unretained(this))
3910 : base::Closure());
3913 void ActivationCallback() { ++callback_count_; }
3915 int num_commits_;
3916 int callback_count_;
3919 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
3920 RunTest(true, false, true);
3923 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
3924 RunTest(true, true, true);
3927 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
3928 public:
3929 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
3931 virtual void BeginTest() OVERRIDE {
3932 ASSERT_TRUE(!!invalidate_layer_)
3933 << "Derived tests must set this in SetupTree";
3935 // One initial commit.
3936 PostSetNeedsCommitToMainThread();
3939 virtual void DidCommitAndDrawFrame() OVERRIDE {
3940 // After commit, invalidate the layer. This should cause a commit.
3941 if (layer_tree_host()->source_frame_number() == 1)
3942 invalidate_layer_->SetNeedsDisplay();
3945 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3946 num_draws_++;
3947 if (impl->active_tree()->source_frame_number() == 1)
3948 EndTest();
3951 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3952 num_commits_++;
3955 virtual void AfterTest() OVERRIDE {
3956 EXPECT_GE(2, num_commits_);
3957 EXPECT_GE(2, num_draws_);
3960 protected:
3961 scoped_refptr<Layer> invalidate_layer_;
3963 private:
3964 int num_commits_;
3965 int num_draws_;
3968 // VideoLayer must support being invalidated and then passing that along
3969 // to the compositor thread, even though no resources are updated in
3970 // response to that invalidation.
3971 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
3972 public:
3973 virtual void SetupTree() OVERRIDE {
3974 LayerTreeHostTest::SetupTree();
3975 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
3976 video_layer->SetBounds(gfx::Size(10, 10));
3977 video_layer->SetIsDrawable(true);
3978 layer_tree_host()->root_layer()->AddChild(video_layer);
3980 invalidate_layer_ = video_layer;
3983 private:
3984 FakeVideoFrameProvider provider_;
3987 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
3989 // IOSurfaceLayer must support being invalidated and then passing that along
3990 // to the compositor thread, even though no resources are updated in
3991 // response to that invalidation.
3992 class LayerTreeHostTestIOSurfaceLayerInvalidate
3993 : public LayerInvalidateCausesDraw {
3994 public:
3995 virtual void SetupTree() OVERRIDE {
3996 LayerTreeHostTest::SetupTree();
3997 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
3998 layer->SetBounds(gfx::Size(10, 10));
3999 uint32_t fake_io_surface_id = 7;
4000 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4001 layer->SetIsDrawable(true);
4002 layer_tree_host()->root_layer()->AddChild(layer);
4004 invalidate_layer_ = layer;
4008 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4009 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4010 LayerTreeHostTestIOSurfaceLayerInvalidate);
4012 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4013 protected:
4014 virtual void SetupTree() OVERRIDE {
4015 root_layer_ = Layer::Create();
4016 root_layer_->SetAnchorPoint(gfx::PointF());
4017 root_layer_->SetPosition(gfx::Point());
4018 root_layer_->SetBounds(gfx::Size(10, 10));
4020 parent_layer_ = SolidColorLayer::Create();
4021 parent_layer_->SetAnchorPoint(gfx::PointF());
4022 parent_layer_->SetPosition(gfx::Point());
4023 parent_layer_->SetBounds(gfx::Size(10, 10));
4024 parent_layer_->SetIsDrawable(true);
4025 root_layer_->AddChild(parent_layer_);
4027 child_layer_ = SolidColorLayer::Create();
4028 child_layer_->SetAnchorPoint(gfx::PointF());
4029 child_layer_->SetPosition(gfx::Point());
4030 child_layer_->SetBounds(gfx::Size(10, 10));
4031 child_layer_->SetIsDrawable(true);
4032 parent_layer_->AddChild(child_layer_);
4034 layer_tree_host()->SetRootLayer(root_layer_);
4035 LayerTreeHostTest::SetupTree();
4038 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4040 virtual void DidCommitAndDrawFrame() OVERRIDE {
4041 switch (layer_tree_host()->source_frame_number()) {
4042 case 1:
4043 // The layer type used does not need to push properties every frame.
4044 EXPECT_FALSE(child_layer_->needs_push_properties());
4046 // Change the bounds of the child layer, but make it skipped
4047 // by CalculateDrawProperties.
4048 parent_layer_->SetOpacity(0.f);
4049 child_layer_->SetBounds(gfx::Size(5, 5));
4050 break;
4051 case 2:
4052 // The bounds of the child layer were pushed to the impl side.
4053 EXPECT_FALSE(child_layer_->needs_push_properties());
4055 EndTest();
4056 break;
4060 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4061 LayerImpl* root = impl->active_tree()->root_layer();
4062 LayerImpl* parent = root->children()[0];
4063 LayerImpl* child = parent->children()[0];
4065 switch (impl->active_tree()->source_frame_number()) {
4066 case 1:
4067 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4068 break;
4072 virtual void AfterTest() OVERRIDE {}
4074 scoped_refptr<Layer> root_layer_;
4075 scoped_refptr<SolidColorLayer> parent_layer_;
4076 scoped_refptr<SolidColorLayer> child_layer_;
4079 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4081 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4082 protected:
4083 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4084 settings->impl_side_painting = true;
4087 virtual void SetupTree() OVERRIDE {
4088 root_layer_ = FakePictureLayer::Create(&client_);
4089 root_layer_->SetAnchorPoint(gfx::PointF());
4090 root_layer_->SetBounds(gfx::Size(10, 10));
4092 layer_tree_host()->SetRootLayer(root_layer_);
4093 LayerTreeHostTest::SetupTree();
4096 virtual void BeginTest() OVERRIDE {
4097 // The viewport is empty, but we still need to update layers on the main
4098 // thread.
4099 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4100 PostSetNeedsCommitToMainThread();
4103 virtual void DidCommit() OVERRIDE {
4104 // The layer should be updated even though the viewport is empty, so we
4105 // are capable of drawing it on the impl tree.
4106 EXPECT_GT(root_layer_->update_count(), 0u);
4107 EndTest();
4110 virtual void AfterTest() OVERRIDE {}
4112 FakeContentLayerClient client_;
4113 scoped_refptr<FakePictureLayer> root_layer_;
4116 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4118 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4119 public:
4120 LayerTreeHostTestAbortEvictedTextures()
4121 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4123 protected:
4124 virtual void SetupTree() OVERRIDE {
4125 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4126 root_layer->SetBounds(gfx::Size(200, 200));
4127 root_layer->SetIsDrawable(true);
4129 layer_tree_host()->SetRootLayer(root_layer);
4130 LayerTreeHostTest::SetupTree();
4133 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4135 virtual void WillBeginMainFrame() OVERRIDE {
4136 num_will_begin_main_frames_++;
4137 switch (num_will_begin_main_frames_) {
4138 case 2:
4139 // Send a redraw to the compositor thread. This will (wrongly) be
4140 // ignored unless aborting resets the texture state.
4141 layer_tree_host()->SetNeedsRedraw();
4142 break;
4146 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4147 num_impl_commits_++;
4150 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4151 switch (impl->SourceAnimationFrameNumber()) {
4152 case 1:
4153 // Prevent draws until commit.
4154 impl->active_tree()->SetContentsTexturesPurged();
4155 EXPECT_FALSE(impl->CanDraw());
4156 // Trigger an abortable commit.
4157 impl->SetNeedsCommit();
4158 break;
4159 case 2:
4160 EndTest();
4161 break;
4165 virtual void AfterTest() OVERRIDE {
4166 // Ensure that the commit was truly aborted.
4167 EXPECT_EQ(2, num_will_begin_main_frames_);
4168 EXPECT_EQ(1, num_impl_commits_);
4171 private:
4172 int num_will_begin_main_frames_;
4173 int num_impl_commits_;
4176 // Commits can only be aborted when using the thread proxy.
4177 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4179 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4180 protected:
4181 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4182 settings->impl_side_painting = true;
4185 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
4186 OVERRIDE {
4187 scoped_refptr<TestContextProvider> context_provider =
4188 TestContextProvider::Create();
4189 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
4190 if (delegating_renderer())
4191 return FakeOutputSurface::CreateDelegating3d(context_provider);
4192 else
4193 return FakeOutputSurface::Create3d(context_provider);
4196 virtual void SetupTree() OVERRIDE {
4197 scoped_refptr<FakePictureLayer> root_layer =
4198 FakePictureLayer::Create(&client_);
4199 root_layer->SetBounds(gfx::Size(6000, 6000));
4200 root_layer->SetIsDrawable(true);
4202 layer_tree_host()->SetRootLayer(root_layer);
4203 LayerTreeHostTest::SetupTree();
4206 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4208 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4209 TestWebGraphicsContext3D* context = TestContext();
4211 // Expect that the transfer buffer memory used is equal to the
4212 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4213 EXPECT_EQ(1024 * 1024u, context->GetTransferBufferMemoryUsedBytes());
4214 EndTest();
4217 virtual void AfterTest() OVERRIDE {}
4219 private:
4220 FakeContentLayerClient client_;
4223 // Impl-side painting is a multi-threaded compositor feature.
4224 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4226 // Test ensuring that memory limits are sent to the prioritized resource
4227 // manager.
4228 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4229 public:
4230 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4232 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4234 virtual void WillCommit() OVERRIDE {
4235 // Some commits are aborted, so increment number of attempted commits here.
4236 num_commits_++;
4239 virtual void DidCommit() OVERRIDE {
4240 switch (num_commits_) {
4241 case 1:
4242 // Verify default values.
4243 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4244 layer_tree_host()
4245 ->contents_texture_manager()
4246 ->MaxMemoryLimitBytes());
4247 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4248 layer_tree_host()
4249 ->contents_texture_manager()
4250 ->ExternalPriorityCutoff());
4251 PostSetNeedsCommitToMainThread();
4252 break;
4253 case 2:
4254 // The values should remain the same until the commit after the policy
4255 // is changed.
4256 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4257 layer_tree_host()
4258 ->contents_texture_manager()
4259 ->MaxMemoryLimitBytes());
4260 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4261 layer_tree_host()
4262 ->contents_texture_manager()
4263 ->ExternalPriorityCutoff());
4264 break;
4265 case 3:
4266 // Verify values were correctly passed.
4267 EXPECT_EQ(16u * 1024u * 1024u,
4268 layer_tree_host()
4269 ->contents_texture_manager()
4270 ->MaxMemoryLimitBytes());
4271 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4272 layer_tree_host()
4273 ->contents_texture_manager()
4274 ->ExternalPriorityCutoff());
4275 EndTest();
4276 break;
4277 case 4:
4278 // Make sure no extra commits happen.
4279 NOTREACHED();
4280 break;
4284 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4285 switch (num_commits_) {
4286 case 1:
4287 break;
4288 case 2:
4289 // This will trigger a commit because the priority cutoff has changed.
4290 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4291 16u * 1024u * 1024u,
4292 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4293 1000));
4294 break;
4295 case 3:
4296 // This will not trigger a commit because the priority cutoff has not
4297 // changed, and there is already enough memory for all allocations.
4298 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4299 32u * 1024u * 1024u,
4300 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4301 1000));
4302 break;
4303 case 4:
4304 NOTREACHED();
4305 break;
4309 virtual void AfterTest() OVERRIDE {}
4311 private:
4312 int num_commits_;
4315 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4317 } // namespace
4319 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4320 : public LayerTreeHostTest {
4321 protected:
4322 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4323 : first_output_surface_memory_limit_(4321234),
4324 second_output_surface_memory_limit_(1234321) {}
4326 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
4327 OVERRIDE {
4328 if (!first_context_provider_) {
4329 first_context_provider_ = TestContextProvider::Create();
4330 } else {
4331 EXPECT_FALSE(second_context_provider_);
4332 second_context_provider_ = TestContextProvider::Create();
4335 scoped_refptr<TestContextProvider> provider(second_context_provider_
4336 ? second_context_provider_
4337 : first_context_provider_);
4338 scoped_ptr<FakeOutputSurface> output_surface;
4339 if (delegating_renderer())
4340 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4341 else
4342 output_surface = FakeOutputSurface::Create3d(provider);
4343 output_surface->SetMemoryPolicyToSetAtBind(
4344 make_scoped_ptr(new ManagedMemoryPolicy(
4345 second_context_provider_ ? second_output_surface_memory_limit_
4346 : first_output_surface_memory_limit_,
4347 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4348 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4349 return output_surface.Pass();
4352 virtual void SetupTree() OVERRIDE {
4353 root_ = FakeContentLayer::Create(&client_);
4354 root_->SetBounds(gfx::Size(20, 20));
4355 layer_tree_host()->SetRootLayer(root_);
4356 LayerTreeHostTest::SetupTree();
4359 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4361 virtual void DidCommitAndDrawFrame() OVERRIDE {
4362 // Lost context sometimes takes two frames to recreate. The third frame
4363 // is sometimes aborted, so wait until the fourth frame to verify that
4364 // the memory has been set, and the fifth frame to end the test.
4365 if (layer_tree_host()->source_frame_number() < 5) {
4366 layer_tree_host()->SetNeedsCommit();
4367 } else if (layer_tree_host()->source_frame_number() == 5) {
4368 EndTest();
4372 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
4373 bool result) OVERRIDE {
4374 switch (impl->active_tree()->source_frame_number()) {
4375 case 1:
4376 EXPECT_EQ(first_output_surface_memory_limit_,
4377 impl->memory_allocation_limit_bytes());
4378 // Lose the output surface.
4379 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4380 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4381 break;
4382 case 4:
4383 EXPECT_EQ(second_output_surface_memory_limit_,
4384 impl->memory_allocation_limit_bytes());
4385 break;
4389 virtual void AfterTest() OVERRIDE {}
4391 scoped_refptr<TestContextProvider> first_context_provider_;
4392 scoped_refptr<TestContextProvider> second_context_provider_;
4393 size_t first_output_surface_memory_limit_;
4394 size_t second_output_surface_memory_limit_;
4395 FakeContentLayerClient client_;
4396 scoped_refptr<FakeContentLayer> root_;
4399 // No output to copy for delegated renderers.
4400 SINGLE_AND_MULTI_THREAD_TEST_F(
4401 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4403 struct TestSwapPromiseResult {
4404 TestSwapPromiseResult()
4405 : did_swap_called(false),
4406 did_not_swap_called(false),
4407 dtor_called(false),
4408 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4410 bool did_swap_called;
4411 bool did_not_swap_called;
4412 bool dtor_called;
4413 SwapPromise::DidNotSwapReason reason;
4414 base::Lock lock;
4417 class TestSwapPromise : public SwapPromise {
4418 public:
4419 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4421 virtual ~TestSwapPromise() {
4422 base::AutoLock lock(result_->lock);
4423 result_->dtor_called = true;
4426 virtual void DidSwap(CompositorFrameMetadata* metadata) OVERRIDE {
4427 base::AutoLock lock(result_->lock);
4428 EXPECT_FALSE(result_->did_swap_called);
4429 EXPECT_FALSE(result_->did_not_swap_called);
4430 result_->did_swap_called = true;
4433 virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE {
4434 base::AutoLock lock(result_->lock);
4435 EXPECT_FALSE(result_->did_swap_called);
4436 EXPECT_FALSE(result_->did_not_swap_called);
4437 result_->did_not_swap_called = true;
4438 result_->reason = reason;
4441 private:
4442 // Not owned.
4443 TestSwapPromiseResult* result_;
4446 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4447 protected:
4448 LayerTreeHostTestBreakSwapPromise()
4449 : commit_count_(0), commit_complete_count_(0) {}
4451 virtual void WillBeginMainFrame() OVERRIDE {
4452 ASSERT_LE(commit_count_, 2);
4453 scoped_ptr<SwapPromise> swap_promise(
4454 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4455 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4458 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4460 virtual void DidCommit() OVERRIDE {
4461 commit_count_++;
4462 if (commit_count_ == 2) {
4463 // This commit will finish.
4464 layer_tree_host()->SetNeedsCommit();
4468 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4469 commit_complete_count_++;
4470 if (commit_complete_count_ == 1) {
4471 // This commit will be aborted because no actual update.
4472 PostSetNeedsUpdateLayersToMainThread();
4473 } else {
4474 EndTest();
4478 virtual void AfterTest() OVERRIDE {
4479 // 3 commits are scheduled. 2 completes. 1 is aborted.
4480 EXPECT_EQ(commit_count_, 3);
4481 EXPECT_EQ(commit_complete_count_, 2);
4484 // The first commit completes and causes swap buffer which finishes
4485 // the promise.
4486 base::AutoLock lock(swap_promise_result_[0].lock);
4487 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4488 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4489 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4493 // The second commit aborts.
4494 base::AutoLock lock(swap_promise_result_[1].lock);
4495 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4496 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4497 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_[1].reason);
4498 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4502 // The last commit completes but it does not cause swap buffer because
4503 // there is no damage in the frame data.
4504 base::AutoLock lock(swap_promise_result_[2].lock);
4505 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4506 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4507 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4508 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4512 int commit_count_;
4513 int commit_complete_count_;
4514 TestSwapPromiseResult swap_promise_result_[3];
4517 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4519 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
4520 public:
4521 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
4522 LayerTreeHostImpl* layer_tree_host_impl,
4523 int* set_needs_commit_count,
4524 int* set_needs_redraw_count)
4525 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
4526 set_needs_commit_count_(set_needs_commit_count),
4527 set_needs_redraw_count_(set_needs_redraw_count) {}
4529 virtual ~SimpleSwapPromiseMonitor() {}
4531 virtual void OnSetNeedsCommitOnMain() OVERRIDE {
4532 (*set_needs_commit_count_)++;
4535 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE {
4536 (*set_needs_redraw_count_)++;
4539 private:
4540 int* set_needs_commit_count_;
4541 int* set_needs_redraw_count_;
4544 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
4545 public:
4546 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4548 virtual void WillBeginMainFrame() OVERRIDE {
4549 int set_needs_commit_count = 0;
4550 int set_needs_redraw_count = 0;
4553 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4554 new SimpleSwapPromiseMonitor(layer_tree_host(),
4555 NULL,
4556 &set_needs_commit_count,
4557 &set_needs_redraw_count));
4558 layer_tree_host()->SetNeedsCommit();
4559 EXPECT_EQ(1, set_needs_commit_count);
4560 EXPECT_EQ(0, set_needs_redraw_count);
4563 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
4564 // monitored.
4565 layer_tree_host()->SetNeedsCommit();
4566 EXPECT_EQ(1, set_needs_commit_count);
4567 EXPECT_EQ(0, set_needs_redraw_count);
4570 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4571 new SimpleSwapPromiseMonitor(layer_tree_host(),
4572 NULL,
4573 &set_needs_commit_count,
4574 &set_needs_redraw_count));
4575 layer_tree_host()->SetNeedsUpdateLayers();
4576 EXPECT_EQ(2, set_needs_commit_count);
4577 EXPECT_EQ(0, set_needs_redraw_count);
4581 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4582 new SimpleSwapPromiseMonitor(layer_tree_host(),
4583 NULL,
4584 &set_needs_commit_count,
4585 &set_needs_redraw_count));
4586 layer_tree_host()->SetNeedsAnimate();
4587 EXPECT_EQ(3, set_needs_commit_count);
4588 EXPECT_EQ(0, set_needs_redraw_count);
4591 EndTest();
4594 virtual void AfterTest() OVERRIDE {}
4597 MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
4599 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
4600 : public LayerTreeHostTest {
4601 protected:
4602 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4603 settings->impl_side_painting = true;
4606 virtual void SetupTree() OVERRIDE {
4607 LayerTreeHostTest::SetupTree();
4608 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
4611 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4613 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4614 host_impl->EvictAllUIResources();
4615 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
4616 // mode. Active tree should require high-res to draw after entering this
4617 // mode to ensure that high-res tiles are also required for a pending tree
4618 // to be activated.
4619 EXPECT_TRUE(host_impl->active_tree()->RequiresHighResToDraw());
4622 virtual void DidCommit() OVERRIDE {
4623 int frame = layer_tree_host()->source_frame_number();
4624 switch (frame) {
4625 case 1:
4626 PostSetNeedsCommitToMainThread();
4627 break;
4628 case 2:
4629 ui_resource_.reset();
4630 EndTest();
4631 break;
4635 virtual void AfterTest() OVERRIDE {}
4637 FakeContentLayerClient client_;
4638 scoped_ptr<FakeScopedUIResource> ui_resource_;
4641 MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources);
4643 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
4644 protected:
4645 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4646 settings->impl_side_painting = true;
4648 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4649 EXPECT_FALSE(settings->gpu_rasterization_forced);
4652 virtual void SetupTree() OVERRIDE {
4653 LayerTreeHostTest::SetupTree();
4655 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4656 layer->SetBounds(gfx::Size(10, 10));
4657 layer->SetIsDrawable(true);
4658 layer_tree_host()->root_layer()->AddChild(layer);
4661 virtual void BeginTest() OVERRIDE {
4662 Layer* root = layer_tree_host()->root_layer();
4663 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4664 PicturePile* pile = layer->GetPicturePileForTesting();
4666 // Verify default values.
4667 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4668 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4669 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4670 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4671 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4673 // Setting gpu rasterization trigger does not enable gpu rasterization.
4674 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4675 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4676 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4678 PostSetNeedsCommitToMainThread();
4681 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4682 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4683 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4686 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4687 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4688 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4689 EndTest();
4692 virtual void AfterTest() OVERRIDE {}
4694 FakeContentLayerClient layer_client_;
4697 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
4699 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
4700 protected:
4701 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4702 settings->impl_side_painting = true;
4704 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4705 settings->gpu_rasterization_enabled = true;
4708 virtual void SetupTree() OVERRIDE {
4709 LayerTreeHostTest::SetupTree();
4711 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4712 layer->SetBounds(gfx::Size(10, 10));
4713 layer->SetIsDrawable(true);
4714 layer_tree_host()->root_layer()->AddChild(layer);
4717 virtual void BeginTest() OVERRIDE {
4718 Layer* root = layer_tree_host()->root_layer();
4719 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4720 PicturePile* pile = layer->GetPicturePileForTesting();
4722 // Verify default values.
4723 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4724 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4725 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4726 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4727 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4729 // Gpu rasterization trigger is relevant.
4730 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4731 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4732 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4734 // Content-based veto is relevant as well.
4735 pile->SetUnsuitableForGpuRasterizationForTesting();
4736 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
4737 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4738 // Veto will take effect when layers are updated.
4739 // The results will be verified after commit is completed below.
4740 // Since we are manually marking picture pile as unsuitable,
4741 // make sure that the layer gets a chance to update.
4742 layer->SetNeedsDisplay();
4743 PostSetNeedsCommitToMainThread();
4746 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4747 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4748 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4751 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4752 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4753 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4754 EndTest();
4757 virtual void AfterTest() OVERRIDE {}
4759 FakeContentLayerClient layer_client_;
4762 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
4764 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
4765 protected:
4766 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4767 settings->impl_side_painting = true;
4769 EXPECT_FALSE(settings->gpu_rasterization_forced);
4770 settings->gpu_rasterization_forced = true;
4773 virtual void SetupTree() OVERRIDE {
4774 LayerTreeHostTest::SetupTree();
4776 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4777 layer->SetBounds(gfx::Size(10, 10));
4778 layer->SetIsDrawable(true);
4779 layer_tree_host()->root_layer()->AddChild(layer);
4782 virtual void BeginTest() OVERRIDE {
4783 Layer* root = layer_tree_host()->root_layer();
4784 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4785 PicturePile* pile = layer->GetPicturePileForTesting();
4787 // Verify default values.
4788 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4789 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4790 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4791 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4793 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
4794 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4795 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4796 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4797 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4799 // Content-based veto is irrelevant as well.
4800 pile->SetUnsuitableForGpuRasterizationForTesting();
4801 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
4802 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4803 // Veto will take effect when layers are updated.
4804 // The results will be verified after commit is completed below.
4805 // Since we are manually marking picture pile as unsuitable,
4806 // make sure that the layer gets a chance to update.
4807 layer->SetNeedsDisplay();
4808 PostSetNeedsCommitToMainThread();
4811 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4812 EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
4813 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4816 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4817 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
4818 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4819 EndTest();
4822 virtual void AfterTest() OVERRIDE {}
4824 FakeContentLayerClient layer_client_;
4827 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
4829 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
4830 public:
4831 LayerTreeHostTestContinuousPainting()
4832 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
4834 protected:
4835 enum { kExpectedNumCommits = 10 };
4837 virtual void SetupTree() OVERRIDE {
4838 scoped_refptr<Layer> root_layer = Layer::Create();
4839 root_layer->SetBounds(bounds_);
4841 if (layer_tree_host()->settings().impl_side_painting) {
4842 picture_layer_ = FakePictureLayer::Create(&client_);
4843 child_layer_ = picture_layer_.get();
4844 } else {
4845 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
4846 child_layer_ = content_layer_.get();
4848 child_layer_->SetBounds(bounds_);
4849 child_layer_->SetIsDrawable(true);
4850 root_layer->AddChild(child_layer_);
4852 layer_tree_host()->SetRootLayer(root_layer);
4853 layer_tree_host()->SetViewportSize(bounds_);
4854 LayerTreeHostTest::SetupTree();
4857 virtual void BeginTest() OVERRIDE {
4858 // Wait 50x longer than expected.
4859 double milliseconds_per_frame =
4860 1000 / layer_tree_host()->settings().refresh_rate;
4861 EndTestAfterDelay(50 * kExpectedNumCommits * milliseconds_per_frame);
4862 MainThreadTaskRunner()->PostTask(
4863 FROM_HERE,
4864 base::Bind(
4865 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
4866 base::Unretained(this)));
4869 virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE {
4870 child_layer_->SetNeedsDisplay();
4873 virtual void AfterTest() OVERRIDE {
4874 EXPECT_LE(kExpectedNumCommits, num_commits_);
4875 EXPECT_LE(kExpectedNumCommits, num_draws_);
4876 int update_count = content_layer_ ? content_layer_->PaintContentsCount()
4877 : picture_layer_->update_count();
4878 EXPECT_LE(kExpectedNumCommits, update_count);
4881 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4882 if (++num_draws_ == kExpectedNumCommits)
4883 EndTest();
4886 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4887 ++num_commits_;
4890 private:
4891 void EnableContinuousPainting() {
4892 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
4893 debug_state.continuous_painting = true;
4894 layer_tree_host()->SetDebugState(debug_state);
4897 int num_commits_;
4898 int num_draws_;
4899 const gfx::Size bounds_;
4900 FakeContentLayerClient client_;
4901 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
4902 scoped_refptr<FakePictureLayer> picture_layer_;
4903 Layer* child_layer_;
4906 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
4908 } // namespace cc