Move prefs::kLastPolicyStatisticsUpdate to the policy component.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob0cb69f5c3ed687b93b94e62bfa7f0ce61f90c6f4
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/debug/frame_rate_counter.h"
13 #include "cc/debug/test_web_graphics_context_3d.h"
14 #include "cc/layers/content_layer.h"
15 #include "cc/layers/content_layer_client.h"
16 #include "cc/layers/io_surface_layer.h"
17 #include "cc/layers/layer_impl.h"
18 #include "cc/layers/painted_scrollbar_layer.h"
19 #include "cc/layers/picture_layer.h"
20 #include "cc/layers/solid_color_layer.h"
21 #include "cc/layers/video_layer.h"
22 #include "cc/output/begin_frame_args.h"
23 #include "cc/output/copy_output_request.h"
24 #include "cc/output/copy_output_result.h"
25 #include "cc/output/output_surface.h"
26 #include "cc/resources/prioritized_resource.h"
27 #include "cc/resources/prioritized_resource_manager.h"
28 #include "cc/resources/resource_update_queue.h"
29 #include "cc/scheduler/frame_rate_controller.h"
30 #include "cc/test/fake_content_layer.h"
31 #include "cc/test/fake_content_layer_client.h"
32 #include "cc/test/fake_layer_tree_host_client.h"
33 #include "cc/test/fake_output_surface.h"
34 #include "cc/test/fake_painted_scrollbar_layer.h"
35 #include "cc/test/fake_picture_layer.h"
36 #include "cc/test/fake_picture_layer_impl.h"
37 #include "cc/test/fake_proxy.h"
38 #include "cc/test/fake_scoped_ui_resource.h"
39 #include "cc/test/fake_video_frame_provider.h"
40 #include "cc/test/geometry_test_utils.h"
41 #include "cc/test/layer_tree_test.h"
42 #include "cc/test/occlusion_tracker_test_common.h"
43 #include "cc/trees/layer_tree_host_impl.h"
44 #include "cc/trees/layer_tree_impl.h"
45 #include "cc/trees/single_thread_proxy.h"
46 #include "cc/trees/thread_proxy.h"
47 #include "gpu/GLES2/gl2extchromium.h"
48 #include "skia/ext/refptr.h"
49 #include "testing/gmock/include/gmock/gmock.h"
50 #include "third_party/khronos/GLES2/gl2.h"
51 #include "third_party/khronos/GLES2/gl2ext.h"
52 #include "third_party/skia/include/core/SkPicture.h"
53 #include "ui/gfx/point_conversions.h"
54 #include "ui/gfx/size_conversions.h"
55 #include "ui/gfx/vector2d_conversions.h"
57 using testing::_;
58 using testing::AnyNumber;
59 using testing::AtLeast;
60 using testing::Mock;
62 namespace cc {
63 namespace {
65 class LayerTreeHostTest : public LayerTreeTest {
68 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
69 // draw with frame 0.
70 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
71 public:
72 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
74 virtual void BeginTest() OVERRIDE {
75 PostSetNeedsCommitToMainThread();
76 PostSetNeedsCommitToMainThread();
79 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
80 num_draws_++;
81 if (!impl->active_tree()->source_frame_number())
82 EndTest();
85 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
86 num_commits_++;
89 virtual void AfterTest() OVERRIDE {
90 EXPECT_GE(1, num_commits_);
91 EXPECT_GE(1, num_draws_);
94 private:
95 int num_commits_;
96 int num_draws_;
99 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
101 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
102 // first committed frame draws should lead to another commit.
103 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
104 public:
105 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
107 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
109 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
110 ++num_draws_;
113 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
114 ++num_commits_;
115 switch (num_commits_) {
116 case 1:
117 PostSetNeedsCommitToMainThread();
118 break;
119 case 2:
120 EndTest();
121 break;
122 default:
123 NOTREACHED();
127 virtual void AfterTest() OVERRIDE {
128 EXPECT_EQ(2, num_commits_);
129 EXPECT_LE(1, num_draws_);
132 private:
133 int num_commits_;
134 int num_draws_;
137 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
139 // Verify that we pass property values in PushPropertiesTo.
140 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
141 protected:
142 virtual void SetupTree() OVERRIDE {
143 scoped_refptr<Layer> root = Layer::Create();
144 root->SetBounds(gfx::Size(10, 10));
145 layer_tree_host()->SetRootLayer(root);
146 LayerTreeHostTest::SetupTree();
149 enum Properties {
150 STARTUP,
151 BOUNDS,
152 HIDE_LAYER_AND_SUBTREE,
153 DRAWS_CONTENT,
154 DONE,
157 virtual void BeginTest() OVERRIDE {
158 index_ = STARTUP;
159 PostSetNeedsCommitToMainThread();
162 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
163 VerifyAfterValues(impl->active_tree()->root_layer());
166 virtual void DidCommitAndDrawFrame() OVERRIDE {
167 SetBeforeValues(layer_tree_host()->root_layer());
168 VerifyBeforeValues(layer_tree_host()->root_layer());
170 ++index_;
171 if (index_ == DONE) {
172 EndTest();
173 return;
176 SetAfterValues(layer_tree_host()->root_layer());
179 virtual void AfterTest() OVERRIDE {}
181 void VerifyBeforeValues(Layer* layer) {
182 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
183 EXPECT_FALSE(layer->hide_layer_and_subtree());
184 EXPECT_FALSE(layer->DrawsContent());
187 void SetBeforeValues(Layer* layer) {
188 layer->SetBounds(gfx::Size(10, 10));
189 layer->SetHideLayerAndSubtree(false);
190 layer->SetIsDrawable(false);
193 void VerifyAfterValues(LayerImpl* layer) {
194 switch (static_cast<Properties>(index_)) {
195 case STARTUP:
196 case DONE:
197 break;
198 case BOUNDS:
199 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
200 break;
201 case HIDE_LAYER_AND_SUBTREE:
202 EXPECT_TRUE(layer->hide_layer_and_subtree());
203 break;
204 case DRAWS_CONTENT:
205 EXPECT_TRUE(layer->DrawsContent());
206 break;
210 void SetAfterValues(Layer* layer) {
211 switch (static_cast<Properties>(index_)) {
212 case STARTUP:
213 case DONE:
214 break;
215 case BOUNDS:
216 layer->SetBounds(gfx::Size(20, 20));
217 break;
218 case HIDE_LAYER_AND_SUBTREE:
219 layer->SetHideLayerAndSubtree(true);
220 break;
221 case DRAWS_CONTENT:
222 layer->SetIsDrawable(true);
223 break;
227 int index_;
230 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
232 // 1 setNeedsRedraw after the first commit has completed should lead to 1
233 // additional draw.
234 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
235 public:
236 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
238 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
240 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
241 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
242 if (!num_draws_) {
243 // Redraw again to verify that the second redraw doesn't commit.
244 PostSetNeedsRedrawToMainThread();
245 } else {
246 EndTest();
248 num_draws_++;
251 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
252 EXPECT_EQ(0, num_draws_);
253 num_commits_++;
256 virtual void AfterTest() OVERRIDE {
257 EXPECT_GE(2, num_draws_);
258 EXPECT_EQ(1, num_commits_);
261 private:
262 int num_commits_;
263 int num_draws_;
266 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
268 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
269 // must contain invalid_rect.
270 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
271 public:
272 LayerTreeHostTestSetNeedsRedrawRect()
273 : num_draws_(0),
274 bounds_(50, 50),
275 invalid_rect_(10, 10, 20, 20),
276 root_layer_(ContentLayer::Create(&client_)) {
279 virtual void BeginTest() OVERRIDE {
280 root_layer_->SetIsDrawable(true);
281 root_layer_->SetBounds(bounds_);
282 layer_tree_host()->SetRootLayer(root_layer_);
283 layer_tree_host()->SetViewportSize(bounds_);
284 PostSetNeedsCommitToMainThread();
287 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
288 LayerTreeHostImpl::FrameData* frame_data,
289 bool result) OVERRIDE {
290 EXPECT_TRUE(result);
292 gfx::RectF root_damage_rect;
293 if (!frame_data->render_passes.empty())
294 root_damage_rect = frame_data->render_passes.back()->damage_rect;
296 if (!num_draws_) {
297 // If this is the first frame, expect full frame damage.
298 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
299 } else {
300 // Check that invalid_rect_ is indeed repainted.
301 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
304 return result;
307 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
308 if (!num_draws_) {
309 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
310 } else {
311 EndTest();
313 num_draws_++;
316 virtual void AfterTest() OVERRIDE {
317 EXPECT_EQ(2, num_draws_);
320 private:
321 int num_draws_;
322 const gfx::Size bounds_;
323 const gfx::Rect invalid_rect_;
324 FakeContentLayerClient client_;
325 scoped_refptr<ContentLayer> root_layer_;
328 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
330 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
331 public:
332 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
333 settings->layer_transforms_should_scale_layer_contents = true;
336 virtual void SetupTree() OVERRIDE {
337 root_layer_ = Layer::Create();
338 root_layer_->SetBounds(gfx::Size(10, 20));
340 scaled_layer_ = FakeContentLayer::Create(&client_);
341 scaled_layer_->SetBounds(gfx::Size(1, 1));
342 root_layer_->AddChild(scaled_layer_);
344 layer_tree_host()->SetRootLayer(root_layer_);
345 LayerTreeHostTest::SetupTree();
348 virtual void BeginTest() OVERRIDE {
349 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 {
409 PostSetNeedsCommitToMainThread();
412 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
413 if (host_impl->active_tree()->source_frame_number() == 1)
414 EndTest();
417 virtual void DidCommit() OVERRIDE {
418 switch (layer_tree_host()->source_frame_number()) {
419 case 1:
420 // Changing the device scale factor causes a commit. It also changes
421 // the content bounds of |scrollbar_|, which should not generate
422 // a second commit as a result.
423 layer_tree_host()->SetDeviceScaleFactor(4.f);
424 break;
425 default:
426 // No extra commits.
427 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
431 virtual void AfterTest() OVERRIDE {
432 EXPECT_EQ(gfx::Size(40, 40).ToString(),
433 scrollbar_->content_bounds().ToString());
436 private:
437 FakeContentLayerClient client_;
438 scoped_refptr<Layer> root_layer_;
439 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
442 SINGLE_AND_MULTI_THREAD_TEST_F(
443 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
445 class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
446 public:
447 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
449 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
451 virtual void DidCommit() OVERRIDE {
452 num_commits_++;
453 if (num_commits_ == 1) {
454 char pixels[4];
455 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
456 } else if (num_commits_ == 2) {
457 // This is inside the readback. We should get another commit after it.
458 } else if (num_commits_ == 3) {
459 EndTest();
460 } else {
461 NOTREACHED();
465 virtual void AfterTest() OVERRIDE {}
467 private:
468 int num_commits_;
471 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback);
473 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
474 : public LayerTreeHostTest {
475 public:
476 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
477 : num_commits_(0) {}
479 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
481 virtual void DidCommit() OVERRIDE {
482 num_commits_++;
483 if (num_commits_ == 1) {
484 layer_tree_host()->SetNeedsCommit();
485 } else if (num_commits_ == 2) {
486 char pixels[4];
487 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
488 } else if (num_commits_ == 3) {
489 // This is inside the readback. We should get another commit after it.
490 } else if (num_commits_ == 4) {
491 EndTest();
492 } else {
493 NOTREACHED();
497 virtual void AfterTest() OVERRIDE {}
499 private:
500 int num_commits_;
503 MULTI_THREAD_TEST_F(
504 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws);
506 class LayerTreeHostTestCompositeAndReadbackDuringForcedDraw
507 : public LayerTreeHostTest {
508 protected:
509 static const int kFirstCommitSourceFrameNumber = 0;
510 static const int kReadbackSourceFrameNumber = 1;
511 static const int kReadbackReplacementAndForcedDrawSourceFrameNumber = 2;
513 LayerTreeHostTestCompositeAndReadbackDuringForcedDraw()
514 : did_post_readback_(false) {}
516 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
517 // This enables forced draws after a single prepare to draw failure.
518 settings->timeout_and_draw_when_animation_checkerboards = true;
519 settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
522 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
524 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
525 LayerTreeHostImpl::FrameData* frame_data,
526 bool result) OVERRIDE {
527 int sfn = host_impl->active_tree()->source_frame_number();
528 EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
529 sfn == kReadbackSourceFrameNumber ||
530 sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
531 << sfn;
533 // Before we react to the failed draw by initiating the forced draw
534 // sequence, start a readback on the main thread.
535 if (sfn == kFirstCommitSourceFrameNumber && !did_post_readback_) {
536 did_post_readback_ = true;
537 PostReadbackToMainThread();
540 // Returning false will result in a forced draw.
541 return false;
544 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
545 // We should only draw for the readback and the forced draw.
546 int sfn = host_impl->active_tree()->source_frame_number();
547 EXPECT_TRUE(sfn == kReadbackSourceFrameNumber ||
548 sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
549 << sfn;
552 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
553 bool result) OVERRIDE {
554 // We should only swap for the forced draw.
555 int sfn = host_impl->active_tree()->source_frame_number();
556 EXPECT_TRUE(sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
557 << sfn;
558 EndTest();
561 virtual void AfterTest() OVERRIDE {}
563 bool did_post_readback_;
566 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackDuringForcedDraw);
568 class LayerTreeHostTestCompositeAndReadbackAfterForcedDraw
569 : public LayerTreeHostTest {
570 protected:
571 static const int kFirstCommitSourceFrameNumber = 0;
572 static const int kForcedDrawSourceFrameNumber = 1;
573 static const int kReadbackSourceFrameNumber = 2;
574 static const int kReadbackReplacementSourceFrameNumber = 3;
576 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
577 // This enables forced draws after a single prepare to draw failure.
578 settings->timeout_and_draw_when_animation_checkerboards = true;
579 settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
582 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
584 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
585 LayerTreeHostImpl::FrameData* frame_data,
586 bool result) OVERRIDE {
587 int sfn = host_impl->active_tree()->source_frame_number();
588 EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
589 sfn == kForcedDrawSourceFrameNumber ||
590 sfn == kReadbackSourceFrameNumber ||
591 sfn == kReadbackReplacementSourceFrameNumber)
592 << sfn;
594 // Returning false will result in a forced draw.
595 return false;
598 virtual void DidCommit() OVERRIDE {
599 if (layer_tree_host()->source_frame_number() ==
600 kForcedDrawSourceFrameNumber) {
601 // Avoid aborting the forced draw commit so source_frame_number
602 // increments.
603 layer_tree_host()->SetNeedsCommit();
604 } else if (layer_tree_host()->source_frame_number() ==
605 kReadbackSourceFrameNumber) {
606 // Perform a readback immediately after the forced draw's commit.
607 char pixels[4];
608 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
612 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
613 // We should only draw for the the forced draw, readback, and
614 // replacement commit.
615 int sfn = host_impl->active_tree()->source_frame_number();
616 EXPECT_TRUE(sfn == kForcedDrawSourceFrameNumber ||
617 sfn == kReadbackSourceFrameNumber ||
618 sfn == kReadbackReplacementSourceFrameNumber)
619 << sfn;
622 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
623 bool result) OVERRIDE {
624 // We should only swap for the forced draw and replacement commit.
625 int sfn = host_impl->active_tree()->source_frame_number();
626 EXPECT_TRUE(sfn == kForcedDrawSourceFrameNumber ||
627 sfn == kReadbackReplacementSourceFrameNumber)
628 << sfn;
630 if (sfn == kReadbackReplacementSourceFrameNumber)
631 EndTest();
634 virtual void AfterTest() OVERRIDE {}
637 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackAfterForcedDraw);
639 // If the layerTreeHost says it can't draw, Then we should not try to draw.
640 class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
641 public:
642 LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
644 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
646 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
647 if (done_)
648 return;
649 // Only the initial draw should bring us here.
650 EXPECT_TRUE(impl->CanDraw());
651 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
654 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
655 if (done_)
656 return;
657 if (num_commits_ >= 1) {
658 // After the first commit, we should not be able to draw.
659 EXPECT_FALSE(impl->CanDraw());
663 virtual void DidCommit() OVERRIDE {
664 num_commits_++;
665 if (num_commits_ == 1) {
666 // Make the viewport empty so the host says it can't draw.
667 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
668 } else if (num_commits_ == 2) {
669 char pixels[4];
670 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
671 } else if (num_commits_ == 3) {
672 // Let it draw so we go idle and end the test.
673 layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
674 done_ = true;
675 EndTest();
679 virtual void AfterTest() OVERRIDE {}
681 private:
682 int num_commits_;
683 bool done_;
686 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
688 // beginLayerWrite should prevent draws from executing until a commit occurs
689 class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
690 public:
691 LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
693 virtual void BeginTest() OVERRIDE {
694 PostAcquireLayerTextures();
695 PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
696 PostSetNeedsCommitToMainThread();
699 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
700 num_draws_++;
701 EXPECT_EQ(num_draws_, num_commits_);
704 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
705 num_commits_++;
706 EndTest();
709 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
711 private:
712 int num_commits_;
713 int num_draws_;
716 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw);
718 // Verify that when resuming visibility, Requesting layer write permission
719 // will not deadlock the main thread even though there are not yet any
720 // scheduled redraws. This behavior is critical for reliably surviving tab
721 // switching. There are no failure conditions to this test, it just passes
722 // by not timing out.
723 class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
724 public:
725 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
727 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
729 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
730 num_commits_++;
731 if (num_commits_ == 2)
732 EndTest();
733 else if (num_commits_ < 2) {
734 PostSetVisibleToMainThread(false);
735 PostSetVisibleToMainThread(true);
736 PostAcquireLayerTextures();
737 PostSetNeedsCommitToMainThread();
741 virtual void AfterTest() OVERRIDE {}
743 private:
744 int num_commits_;
747 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
749 // A compositeAndReadback while invisible should force a normal commit without
750 // assertion.
751 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
752 : public LayerTreeHostTest {
753 public:
754 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
756 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
758 virtual void DidCommitAndDrawFrame() OVERRIDE {
759 num_commits_++;
760 if (num_commits_ == 1) {
761 layer_tree_host()->SetVisible(false);
762 layer_tree_host()->SetNeedsCommit();
763 layer_tree_host()->SetNeedsCommit();
764 char pixels[4];
765 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
766 } else {
767 EndTest();
771 virtual void AfterTest() OVERRIDE {}
773 private:
774 int num_commits_;
777 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible);
779 class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
780 public:
781 LayerTreeHostTestAbortFrameWhenInvisible() {}
783 virtual void BeginTest() OVERRIDE {
784 // Request a commit (from the main thread), Which will trigger the commit
785 // flow from the impl side.
786 layer_tree_host()->SetNeedsCommit();
787 // Then mark ourselves as not visible before processing any more messages
788 // on the main thread.
789 layer_tree_host()->SetVisible(false);
790 // If we make it without kicking a frame, we pass!
791 EndTestAfterDelay(1);
794 virtual void Layout() OVERRIDE {
795 ASSERT_FALSE(true);
796 EndTest();
799 virtual void AfterTest() OVERRIDE {}
802 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
804 // This test verifies that properties on the layer tree host are commited
805 // to the impl side.
806 class LayerTreeHostTestCommit : public LayerTreeHostTest {
807 public:
808 LayerTreeHostTestCommit() {}
810 virtual void BeginTest() OVERRIDE {
811 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
812 layer_tree_host()->set_background_color(SK_ColorGRAY);
814 PostSetNeedsCommitToMainThread();
817 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
818 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
819 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
821 EndTest();
824 virtual void AfterTest() OVERRIDE {}
827 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
829 // This test verifies that LayerTreeHostImpl's current frame time gets
830 // updated in consecutive frames when it doesn't draw due to tree
831 // activation failure.
832 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
833 : public LayerTreeHostTest {
834 public:
835 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
836 : frame_count_with_pending_tree_(0) {}
838 virtual void BeginTest() OVERRIDE {
839 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
840 layer_tree_host()->set_background_color(SK_ColorGRAY);
842 PostSetNeedsCommitToMainThread();
845 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
846 const BeginFrameArgs& args) OVERRIDE {
847 if (host_impl->pending_tree())
848 frame_count_with_pending_tree_++;
849 host_impl->BlockNotifyReadyToActivateForTesting(
850 frame_count_with_pending_tree_ <= 1);
853 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
854 if (frame_count_with_pending_tree_ > 1) {
855 EXPECT_NE(first_frame_time_.ToInternalValue(),
856 impl->CurrentFrameTimeTicks().ToInternalValue());
857 EndTest();
858 return;
861 EXPECT_FALSE(impl->settings().impl_side_painting);
862 EndTest();
864 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
865 if (impl->settings().impl_side_painting)
866 EXPECT_NE(frame_count_with_pending_tree_, 1);
869 virtual void AfterTest() OVERRIDE {}
871 private:
872 int frame_count_with_pending_tree_;
873 base::TimeTicks first_frame_time_;
876 SINGLE_AND_MULTI_THREAD_TEST_F(
877 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
879 // This test verifies that LayerTreeHostImpl's current frame time gets
880 // updated in consecutive frames when it draws in each frame.
881 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
882 public:
883 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
885 virtual void BeginTest() OVERRIDE {
886 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
887 layer_tree_host()->set_background_color(SK_ColorGRAY);
889 PostSetNeedsCommitToMainThread();
892 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
893 frame_++;
894 if (frame_ == 1) {
895 first_frame_time_ = impl->CurrentFrameTimeTicks();
896 impl->SetNeedsRedraw();
898 // Since base::TimeTicks::Now() uses a low-resolution clock on
899 // Windows, we need to make sure that the clock has incremented past
900 // first_frame_time_.
901 while (first_frame_time_ == base::TimeTicks::Now()) {}
903 return;
906 EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
907 EndTest();
910 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
911 // Ensure there isn't a commit between the two draws, to ensure that a
912 // commit isn't required for updating the current frame time. We can
913 // only check for this in the multi-threaded case, since in the single-
914 // threaded case there will always be a commit between consecutive draws.
915 if (HasImplThread())
916 EXPECT_EQ(0, frame_);
919 virtual void AfterTest() OVERRIDE {}
921 private:
922 int frame_;
923 base::TimeTicks first_frame_time_;
926 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
928 // Verifies that StartPageScaleAnimation events propagate correctly
929 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
930 class DISABLED_LayerTreeHostTestStartPageScaleAnimation
931 : public LayerTreeHostTest {
932 public:
933 DISABLED_LayerTreeHostTestStartPageScaleAnimation() {}
935 virtual void SetupTree() OVERRIDE {
936 LayerTreeHostTest::SetupTree();
938 scroll_layer_ = FakeContentLayer::Create(&client_);
939 scroll_layer_->SetScrollable(true);
940 scroll_layer_->SetScrollOffset(gfx::Vector2d());
941 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
944 virtual void BeginTest() OVERRIDE {
945 PostSetNeedsCommitToMainThread();
948 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float scale)
949 OVERRIDE {
950 gfx::Vector2d offset = scroll_layer_->scroll_offset();
951 scroll_layer_->SetScrollOffset(offset + scroll_delta);
952 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
955 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
956 impl->ProcessScrollDeltas();
957 // We get one commit before the first draw, and the animation doesn't happen
958 // until the second draw.
959 switch (impl->active_tree()->source_frame_number()) {
960 case 0:
961 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
962 // We'll start an animation when we get back to the main thread.
963 break;
964 case 1:
965 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
966 PostSetNeedsRedrawToMainThread();
967 break;
968 case 2:
969 EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
970 EndTest();
971 break;
972 default:
973 NOTREACHED();
977 virtual void DidCommitAndDrawFrame() OVERRIDE {
978 switch (layer_tree_host()->source_frame_number()) {
979 case 1:
980 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
981 layer_tree_host()->StartPageScaleAnimation(
982 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
983 break;
987 virtual void AfterTest() OVERRIDE {}
989 FakeContentLayerClient client_;
990 scoped_refptr<FakeContentLayer> scroll_layer_;
993 // Disabled. See: crbug.com/280508
994 MULTI_THREAD_TEST_F(DISABLED_LayerTreeHostTestStartPageScaleAnimation);
996 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
997 public:
998 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1000 virtual void BeginTest() OVERRIDE {
1001 PostSetNeedsCommitToMainThread();
1002 PostSetVisibleToMainThread(false);
1003 // This is suppressed while we're invisible.
1004 PostSetNeedsRedrawToMainThread();
1005 // Triggers the redraw.
1006 PostSetVisibleToMainThread(true);
1009 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1010 EXPECT_TRUE(impl->visible());
1011 ++num_draws_;
1012 EndTest();
1015 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
1017 private:
1018 int num_draws_;
1021 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1023 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1024 public:
1025 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1027 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1029 virtual void PaintContents(SkCanvas*, gfx::Rect, gfx::RectF*) OVERRIDE {
1030 // Set layer opacity to 0.
1031 if (test_layer_)
1032 test_layer_->SetOpacity(0.f);
1034 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
1036 private:
1037 Layer* test_layer_;
1040 class ContentLayerWithUpdateTracking : public ContentLayer {
1041 public:
1042 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1043 ContentLayerClient* client) {
1044 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1047 int PaintContentsCount() { return paint_contents_count_; }
1048 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1050 virtual bool Update(ResourceUpdateQueue* queue,
1051 const OcclusionTracker* occlusion) OVERRIDE {
1052 bool updated = ContentLayer::Update(queue, occlusion);
1053 paint_contents_count_++;
1054 return updated;
1057 private:
1058 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1059 : ContentLayer(client), paint_contents_count_(0) {
1060 SetAnchorPoint(gfx::PointF(0.f, 0.f));
1061 SetBounds(gfx::Size(10, 10));
1062 SetIsDrawable(true);
1064 virtual ~ContentLayerWithUpdateTracking() {}
1066 int paint_contents_count_;
1069 // Layer opacity change during paint should not prevent compositor resources
1070 // from being updated during commit.
1071 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1072 public:
1073 LayerTreeHostTestOpacityChange()
1074 : test_opacity_change_delegate_(),
1075 update_check_layer_(ContentLayerWithUpdateTracking::Create(
1076 &test_opacity_change_delegate_)) {
1077 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
1080 virtual void BeginTest() OVERRIDE {
1081 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1082 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
1084 PostSetNeedsCommitToMainThread();
1087 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1088 EndTest();
1091 virtual void AfterTest() OVERRIDE {
1092 // Update() should have been called once.
1093 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
1096 private:
1097 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1098 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
1101 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1103 class NoScaleContentLayer : public ContentLayer {
1104 public:
1105 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
1106 return make_scoped_refptr(new NoScaleContentLayer(client));
1109 virtual void CalculateContentsScale(float ideal_contents_scale,
1110 float device_scale_factor,
1111 float page_scale_factor,
1112 bool animating_transform_to_screen,
1113 float* contents_scale_x,
1114 float* contents_scale_y,
1115 gfx::Size* contentBounds) OVERRIDE {
1116 // Skip over the ContentLayer's method to the base Layer class.
1117 Layer::CalculateContentsScale(ideal_contents_scale,
1118 device_scale_factor,
1119 page_scale_factor,
1120 animating_transform_to_screen,
1121 contents_scale_x,
1122 contents_scale_y,
1123 contentBounds);
1126 private:
1127 explicit NoScaleContentLayer(ContentLayerClient* client)
1128 : ContentLayer(client) {}
1129 virtual ~NoScaleContentLayer() {}
1132 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1133 : public LayerTreeHostTest {
1134 public:
1135 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1136 : root_layer_(NoScaleContentLayer::Create(&client_)),
1137 child_layer_(ContentLayer::Create(&client_)) {}
1139 virtual void BeginTest() OVERRIDE {
1140 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1141 layer_tree_host()->SetDeviceScaleFactor(1.5);
1142 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1144 root_layer_->AddChild(child_layer_);
1146 root_layer_->SetIsDrawable(true);
1147 root_layer_->SetBounds(gfx::Size(30, 30));
1148 root_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1150 child_layer_->SetIsDrawable(true);
1151 child_layer_->SetPosition(gfx::Point(2, 2));
1152 child_layer_->SetBounds(gfx::Size(10, 10));
1153 child_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1155 layer_tree_host()->SetRootLayer(root_layer_);
1157 PostSetNeedsCommitToMainThread();
1160 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1161 // Should only do one commit.
1162 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1163 // Device scale factor should come over to impl.
1164 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1166 // Both layers are on impl.
1167 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1169 // Device viewport is scaled.
1170 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1172 LayerImpl* root = impl->active_tree()->root_layer();
1173 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1175 // Positions remain in layout pixels.
1176 EXPECT_EQ(gfx::Point(0, 0), root->position());
1177 EXPECT_EQ(gfx::Point(2, 2), child->position());
1179 // Compute all the layer transforms for the frame.
1180 LayerTreeHostImpl::FrameData frame_data;
1181 impl->PrepareToDraw(&frame_data, gfx::Rect());
1182 impl->DidDrawAllLayers(frame_data);
1184 const LayerImplList& render_surface_layer_list =
1185 *frame_data.render_surface_layer_list;
1187 // Both layers should be drawing into the root render surface.
1188 ASSERT_EQ(1u, render_surface_layer_list.size());
1189 ASSERT_EQ(root->render_surface(),
1190 render_surface_layer_list[0]->render_surface());
1191 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1193 // The root render surface is the size of the viewport.
1194 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1195 root->render_surface()->content_rect());
1197 // The content bounds of the child should be scaled.
1198 gfx::Size child_bounds_scaled =
1199 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1200 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1202 gfx::Transform scale_transform;
1203 scale_transform.Scale(impl->device_scale_factor(),
1204 impl->device_scale_factor());
1206 // The root layer is scaled by 2x.
1207 gfx::Transform root_screen_space_transform = scale_transform;
1208 gfx::Transform root_draw_transform = scale_transform;
1210 EXPECT_EQ(root_draw_transform, root->draw_transform());
1211 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1213 // The child is at position 2,2, which is transformed to 3,3 after the scale
1214 gfx::Transform child_screen_space_transform;
1215 child_screen_space_transform.Translate(3.f, 3.f);
1216 gfx::Transform child_draw_transform = child_screen_space_transform;
1218 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1219 child->draw_transform());
1220 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1221 child->screen_space_transform());
1223 EndTest();
1226 virtual void AfterTest() OVERRIDE {}
1228 private:
1229 FakeContentLayerClient client_;
1230 scoped_refptr<NoScaleContentLayer> root_layer_;
1231 scoped_refptr<ContentLayer> child_layer_;
1234 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1236 // Verify atomicity of commits and reuse of textures.
1237 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1238 public:
1239 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1240 // Make sure partial texture updates are turned off.
1241 settings->max_partial_texture_updates = 0;
1242 // Linear fade animator prevents scrollbars from drawing immediately.
1243 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1246 virtual void SetupTree() OVERRIDE {
1247 layer_ = FakeContentLayer::Create(&client_);
1248 layer_->SetBounds(gfx::Size(10, 20));
1250 bool paint_scrollbar = true;
1251 bool has_thumb = false;
1252 scrollbar_ = FakePaintedScrollbarLayer::Create(
1253 paint_scrollbar, has_thumb, layer_->id());
1254 scrollbar_->SetPosition(gfx::Point(0, 10));
1255 scrollbar_->SetBounds(gfx::Size(10, 10));
1257 layer_->AddChild(scrollbar_);
1259 layer_tree_host()->SetRootLayer(layer_);
1260 LayerTreeHostTest::SetupTree();
1263 virtual void BeginTest() OVERRIDE {
1264 drew_frame_ = -1;
1265 PostSetNeedsCommitToMainThread();
1268 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1269 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1271 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1272 impl->output_surface()->context_provider()->Context3d());
1274 switch (impl->active_tree()->source_frame_number()) {
1275 case 0:
1276 // Number of textures should be one for each layer
1277 ASSERT_EQ(2u, context->NumTextures());
1278 // Number of textures used for commit should be one for each layer.
1279 EXPECT_EQ(2u, context->NumUsedTextures());
1280 // Verify that used texture is correct.
1281 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1282 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1284 context->ResetUsedTextures();
1285 PostSetNeedsCommitToMainThread();
1286 break;
1287 case 1:
1288 // Number of textures should be one for scrollbar layer since it was
1289 // requested and deleted on the impl-thread, and double for the content
1290 // layer since its first texture is used by impl thread and cannot by
1291 // used for update.
1292 ASSERT_EQ(3u, context->NumTextures());
1293 // Number of textures used for commit should be one for each layer.
1294 EXPECT_EQ(2u, context->NumUsedTextures());
1295 // First textures should not have been used.
1296 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1297 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1298 // New textures should have been used.
1299 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1300 context->ResetUsedTextures();
1301 PostSetNeedsCommitToMainThread();
1302 break;
1303 case 2:
1304 EndTest();
1305 break;
1306 default:
1307 NOTREACHED();
1308 break;
1312 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1313 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1314 impl->output_surface()->context_provider()->Context3d());
1316 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1317 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1318 return;
1320 drew_frame_ = impl->active_tree()->source_frame_number();
1322 // We draw/ship one texture each frame for each layer.
1323 EXPECT_EQ(2u, context->NumUsedTextures());
1324 context->ResetUsedTextures();
1327 virtual void Layout() OVERRIDE {
1328 layer_->SetNeedsDisplay();
1329 scrollbar_->SetNeedsDisplay();
1332 virtual void AfterTest() OVERRIDE {}
1334 protected:
1335 FakeContentLayerClient client_;
1336 scoped_refptr<FakeContentLayer> layer_;
1337 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1338 int drew_frame_;
1341 MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1342 LayerTreeHostTestDirectRendererAtomicCommit);
1344 class LayerTreeHostTestDelegatingRendererAtomicCommit
1345 : public LayerTreeHostTestDirectRendererAtomicCommit {
1346 public:
1347 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1348 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1350 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1351 impl->output_surface()->context_provider()->Context3d());
1353 switch (impl->active_tree()->source_frame_number()) {
1354 case 0:
1355 // Number of textures should be one for each layer
1356 ASSERT_EQ(2u, context->NumTextures());
1357 // Number of textures used for commit should be one for each layer.
1358 EXPECT_EQ(2u, context->NumUsedTextures());
1359 // Verify that used texture is correct.
1360 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1361 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1362 context->ResetUsedTextures();
1363 PostSetNeedsCommitToMainThread();
1364 break;
1365 case 1:
1366 // Number of textures should be doubled as the first context layer
1367 // texture is being used by the impl-thread and cannot be used for
1368 // update. The scrollbar behavior is different direct renderer because
1369 // UI resource deletion with delegating renderer occurs after tree
1370 // activation.
1371 ASSERT_EQ(4u, context->NumTextures());
1372 // Number of textures used for commit should still be
1373 // one for each layer.
1374 EXPECT_EQ(2u, context->NumUsedTextures());
1375 // First textures should not have been used.
1376 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1377 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1378 // New textures should have been used.
1379 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1380 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1381 context->ResetUsedTextures();
1382 PostSetNeedsCommitToMainThread();
1383 break;
1384 case 2:
1385 EndTest();
1386 break;
1387 default:
1388 NOTREACHED();
1389 break;
1394 MULTI_THREAD_DELEGATING_RENDERER_TEST_F(
1395 LayerTreeHostTestDelegatingRendererAtomicCommit);
1397 static void SetLayerPropertiesForTesting(Layer* layer,
1398 Layer* parent,
1399 const gfx::Transform& transform,
1400 gfx::PointF anchor,
1401 gfx::PointF position,
1402 gfx::Size bounds,
1403 bool opaque) {
1404 layer->RemoveAllChildren();
1405 if (parent)
1406 parent->AddChild(layer);
1407 layer->SetTransform(transform);
1408 layer->SetAnchorPoint(anchor);
1409 layer->SetPosition(position);
1410 layer->SetBounds(bounds);
1411 layer->SetContentsOpaque(opaque);
1414 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1415 : public LayerTreeHostTest {
1416 public:
1417 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1418 // Allow one partial texture update.
1419 settings->max_partial_texture_updates = 1;
1420 // No partial updates when impl side painting is enabled.
1421 settings->impl_side_painting = false;
1424 virtual void SetupTree() OVERRIDE {
1425 parent_ = FakeContentLayer::Create(&client_);
1426 parent_->SetBounds(gfx::Size(10, 20));
1428 child_ = FakeContentLayer::Create(&client_);
1429 child_->SetPosition(gfx::Point(0, 10));
1430 child_->SetBounds(gfx::Size(3, 10));
1432 parent_->AddChild(child_);
1434 layer_tree_host()->SetRootLayer(parent_);
1435 LayerTreeHostTest::SetupTree();
1438 virtual void BeginTest() OVERRIDE {
1439 PostSetNeedsCommitToMainThread();
1442 virtual void DidCommitAndDrawFrame() OVERRIDE {
1443 switch (layer_tree_host()->source_frame_number()) {
1444 case 1:
1445 parent_->SetNeedsDisplay();
1446 child_->SetNeedsDisplay();
1447 break;
1448 case 2:
1449 // Damage part of layers.
1450 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1451 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1452 break;
1453 case 3:
1454 child_->SetNeedsDisplay();
1455 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1456 break;
1457 case 4:
1458 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1459 break;
1460 case 5:
1461 EndTest();
1462 break;
1463 default:
1464 NOTREACHED() << layer_tree_host()->source_frame_number();
1465 break;
1469 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1470 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1472 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1473 impl->output_surface()->context_provider()->Context3d());
1475 switch (impl->active_tree()->source_frame_number()) {
1476 case 0:
1477 // Number of textures should be one for each layer.
1478 ASSERT_EQ(2u, context->NumTextures());
1479 // Number of textures used for commit should be one for each layer.
1480 EXPECT_EQ(2u, context->NumUsedTextures());
1481 // Verify that used textures are correct.
1482 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1483 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1484 context->ResetUsedTextures();
1485 break;
1486 case 1:
1487 // Number of textures should be two for each content layer.
1488 ASSERT_EQ(4u, context->NumTextures());
1489 // Number of textures used for commit should be one for each content
1490 // layer.
1491 EXPECT_EQ(2u, context->NumUsedTextures());
1493 // First content textures should not have been used.
1494 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1495 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1496 // New textures should have been used.
1497 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1498 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1500 context->ResetUsedTextures();
1501 break;
1502 case 2:
1503 // Number of textures should be two for each content layer.
1504 ASSERT_EQ(4u, context->NumTextures());
1505 // Number of textures used for commit should be one for each content
1506 // layer.
1507 EXPECT_EQ(2u, context->NumUsedTextures());
1509 // One content layer does a partial update also.
1510 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1511 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1513 context->ResetUsedTextures();
1514 break;
1515 case 3:
1516 // No textures should be used for commit.
1517 EXPECT_EQ(0u, context->NumUsedTextures());
1519 context->ResetUsedTextures();
1520 break;
1521 case 4:
1522 // Number of textures used for commit should be one, for the
1523 // content layer.
1524 EXPECT_EQ(1u, context->NumUsedTextures());
1526 context->ResetUsedTextures();
1527 break;
1528 default:
1529 NOTREACHED();
1530 break;
1534 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1535 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1537 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1538 impl->output_surface()->context_provider()->Context3d());
1540 // Number of textures used for drawing should one per layer except for
1541 // frame 3 where the viewport only contains one layer.
1542 if (impl->active_tree()->source_frame_number() == 3) {
1543 EXPECT_EQ(1u, context->NumUsedTextures());
1544 } else {
1545 EXPECT_EQ(2u, context->NumUsedTextures()) <<
1546 "For frame " << impl->active_tree()->source_frame_number();
1549 context->ResetUsedTextures();
1552 virtual void AfterTest() OVERRIDE {}
1554 private:
1555 FakeContentLayerClient client_;
1556 scoped_refptr<FakeContentLayer> parent_;
1557 scoped_refptr<FakeContentLayer> child_;
1560 // Partial updates are not possible with a delegating renderer.
1561 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1562 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1564 class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
1565 public:
1566 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1568 virtual void BeginTest() OVERRIDE {
1569 layer_tree_host()->SetNeedsRedraw();
1570 PostSetNeedsCommitToMainThread();
1573 virtual void DidCommitAndDrawFrame() OVERRIDE {
1574 if (once_)
1575 return;
1576 once_ = true;
1577 layer_tree_host()->SetNeedsRedraw();
1578 layer_tree_host()->AcquireLayerTextures();
1580 base::AutoLock lock(lock_);
1581 draw_count_ = 0;
1583 layer_tree_host()->FinishAllRendering();
1585 base::AutoLock lock(lock_);
1586 EXPECT_EQ(0, draw_count_);
1588 EndTest();
1591 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1592 base::AutoLock lock(lock_);
1593 ++draw_count_;
1596 virtual void AfterTest() OVERRIDE {}
1598 private:
1599 bool once_;
1600 base::Lock lock_;
1601 int draw_count_;
1604 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering);
1606 class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
1607 public:
1608 virtual void BeginTest() OVERRIDE {
1609 Layer* root_layer = layer_tree_host()->root_layer();
1611 char pixels[4];
1612 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
1613 gfx::Rect(0, 0, 1, 1));
1614 EXPECT_FALSE(root_layer->render_surface());
1616 EndTest();
1619 virtual void AfterTest() OVERRIDE {}
1622 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup);
1624 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1625 : public LayerTreeHostTest {
1626 protected:
1627 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1628 settings->cache_render_pass_contents = true;
1631 virtual void SetupTree() OVERRIDE {
1632 root_layer_ = FakeContentLayer::Create(&client_);
1633 root_layer_->SetBounds(gfx::Size(100, 100));
1635 surface_layer1_ = FakeContentLayer::Create(&client_);
1636 surface_layer1_->SetBounds(gfx::Size(100, 100));
1637 surface_layer1_->SetForceRenderSurface(true);
1638 surface_layer1_->SetOpacity(0.5f);
1639 root_layer_->AddChild(surface_layer1_);
1641 surface_layer2_ = FakeContentLayer::Create(&client_);
1642 surface_layer2_->SetBounds(gfx::Size(100, 100));
1643 surface_layer2_->SetForceRenderSurface(true);
1644 surface_layer2_->SetOpacity(0.5f);
1645 surface_layer1_->AddChild(surface_layer2_);
1647 replica_layer1_ = FakeContentLayer::Create(&client_);
1648 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1650 replica_layer2_ = FakeContentLayer::Create(&client_);
1651 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1653 layer_tree_host()->SetRootLayer(root_layer_);
1654 LayerTreeHostTest::SetupTree();
1657 virtual void BeginTest() OVERRIDE {
1658 PostSetNeedsCommitToMainThread();
1661 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1662 Renderer* renderer = host_impl->renderer();
1663 RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1664 ->root_layer()->children()[0]->render_surface()->RenderPassId();
1665 RenderPass::Id surface2_render_pass_id =
1666 host_impl->active_tree()->root_layer()->children()[0]->children()[0]
1667 ->render_surface()->RenderPassId();
1669 switch (host_impl->active_tree()->source_frame_number()) {
1670 case 0:
1671 EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
1672 surface1_render_pass_id));
1673 EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
1674 surface2_render_pass_id));
1676 // Reduce the memory limit to only fit the root layer and one render
1677 // surface. This prevents any contents drawing into surfaces
1678 // from being allocated.
1679 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1680 host_impl->SetDiscardBackBufferWhenNotVisible(true);
1681 break;
1682 case 1:
1683 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1684 surface1_render_pass_id));
1685 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1686 surface2_render_pass_id));
1688 EndTest();
1689 break;
1693 virtual void DidCommitAndDrawFrame() OVERRIDE {
1694 if (layer_tree_host()->source_frame_number() < 2)
1695 root_layer_->SetNeedsDisplay();
1698 virtual void AfterTest() OVERRIDE {
1699 EXPECT_LE(2u, root_layer_->update_count());
1700 EXPECT_LE(2u, surface_layer1_->update_count());
1701 EXPECT_LE(2u, surface_layer2_->update_count());
1704 FakeContentLayerClient client_;
1705 scoped_refptr<FakeContentLayer> root_layer_;
1706 scoped_refptr<FakeContentLayer> surface_layer1_;
1707 scoped_refptr<FakeContentLayer> replica_layer1_;
1708 scoped_refptr<FakeContentLayer> surface_layer2_;
1709 scoped_refptr<FakeContentLayer> replica_layer2_;
1712 // Surfaces don't exist with a delegated renderer.
1713 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1714 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1716 class EvictionTestLayer : public Layer {
1717 public:
1718 static scoped_refptr<EvictionTestLayer> Create() {
1719 return make_scoped_refptr(new EvictionTestLayer());
1722 virtual bool Update(ResourceUpdateQueue*,
1723 const OcclusionTracker*) OVERRIDE;
1724 virtual bool DrawsContent() const OVERRIDE { return true; }
1726 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1727 OVERRIDE;
1728 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1729 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1731 bool HaveBackingTexture() const {
1732 return texture_.get() ? texture_->have_backing_texture() : false;
1735 private:
1736 EvictionTestLayer() : Layer() {}
1737 virtual ~EvictionTestLayer() {}
1739 void CreateTextureIfNeeded() {
1740 if (texture_)
1741 return;
1742 texture_ = PrioritizedResource::Create(
1743 layer_tree_host()->contents_texture_manager());
1744 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1745 bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
1748 scoped_ptr<PrioritizedResource> texture_;
1749 SkBitmap bitmap_;
1752 class EvictionTestLayerImpl : public LayerImpl {
1753 public:
1754 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1755 int id) {
1756 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1758 virtual ~EvictionTestLayerImpl() {}
1760 virtual void AppendQuads(QuadSink* quad_sink,
1761 AppendQuadsData* append_quads_data) OVERRIDE {
1762 ASSERT_TRUE(has_texture_);
1763 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1766 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1768 private:
1769 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1770 : LayerImpl(tree_impl, id), has_texture_(false) {}
1772 bool has_texture_;
1775 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1776 CreateTextureIfNeeded();
1777 if (!texture_)
1778 return;
1779 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1782 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1783 const OcclusionTracker*) {
1784 CreateTextureIfNeeded();
1785 if (!texture_)
1786 return false;
1788 gfx::Rect full_rect(0, 0, 10, 10);
1789 ResourceUpdate upload = ResourceUpdate::Create(
1790 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1791 queue->AppendFullUpload(upload);
1792 return true;
1795 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1796 LayerTreeImpl* tree_impl) {
1797 return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
1798 .PassAs<LayerImpl>();
1801 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1802 Layer::PushPropertiesTo(layer_impl);
1804 EvictionTestLayerImpl* test_layer_impl =
1805 static_cast<EvictionTestLayerImpl*>(layer_impl);
1806 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1809 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1810 public:
1811 LayerTreeHostTestEvictTextures()
1812 : layer_(EvictionTestLayer::Create()),
1813 impl_for_evict_textures_(0),
1814 num_commits_(0) {}
1816 virtual void BeginTest() OVERRIDE {
1817 layer_tree_host()->SetRootLayer(layer_);
1818 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1820 gfx::Transform identity_matrix;
1821 SetLayerPropertiesForTesting(layer_.get(),
1823 identity_matrix,
1824 gfx::PointF(0.f, 0.f),
1825 gfx::PointF(0.f, 0.f),
1826 gfx::Size(10, 20),
1827 true);
1829 PostSetNeedsCommitToMainThread();
1832 void PostEvictTextures() {
1833 DCHECK(HasImplThread());
1834 ImplThreadTaskRunner()->PostTask(
1835 FROM_HERE,
1836 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1837 base::Unretained(this)));
1840 void EvictTexturesOnImplThread() {
1841 DCHECK(impl_for_evict_textures_);
1842 impl_for_evict_textures_->EvictTexturesForTesting();
1845 // Commit 1: Just commit and draw normally, then post an eviction at the end
1846 // that will trigger a commit.
1847 // Commit 2: Triggered by the eviction, let it go through and then set
1848 // needsCommit.
1849 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1850 // task, which will be handled before the commit. Don't set needsCommit, it
1851 // should have been posted. A frame should not be drawn (note,
1852 // didCommitAndDrawFrame may be called anyway).
1853 // Commit 4: Triggered by the eviction, let it go through and then set
1854 // needsCommit.
1855 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1856 // Layout(), a frame should not be drawn but a commit will be posted.
1857 // Commit 6: Triggered by the eviction, post an eviction task in
1858 // Layout(), which will be a noop, letting the commit (which recreates the
1859 // textures) go through and draw a frame, then end the test.
1861 // Commits 1+2 test the eviction recovery path where eviction happens outside
1862 // of the beginFrame/commit pair.
1863 // Commits 3+4 test the eviction recovery path where eviction happens inside
1864 // the beginFrame/commit pair.
1865 // Commits 5+6 test the path where an eviction happens during the eviction
1866 // recovery path.
1867 virtual void DidCommit() OVERRIDE {
1868 switch (num_commits_) {
1869 case 1:
1870 EXPECT_TRUE(layer_->HaveBackingTexture());
1871 PostEvictTextures();
1872 break;
1873 case 2:
1874 EXPECT_TRUE(layer_->HaveBackingTexture());
1875 layer_tree_host()->SetNeedsCommit();
1876 break;
1877 case 3:
1878 break;
1879 case 4:
1880 EXPECT_TRUE(layer_->HaveBackingTexture());
1881 layer_tree_host()->SetNeedsCommit();
1882 break;
1883 case 5:
1884 break;
1885 case 6:
1886 EXPECT_TRUE(layer_->HaveBackingTexture());
1887 EndTest();
1888 break;
1889 default:
1890 NOTREACHED();
1891 break;
1895 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1896 impl_for_evict_textures_ = impl;
1899 virtual void Layout() OVERRIDE {
1900 ++num_commits_;
1901 switch (num_commits_) {
1902 case 1:
1903 case 2:
1904 break;
1905 case 3:
1906 PostEvictTextures();
1907 break;
1908 case 4:
1909 // We couldn't check in didCommitAndDrawFrame on commit 3,
1910 // so check here.
1911 EXPECT_FALSE(layer_->HaveBackingTexture());
1912 break;
1913 case 5:
1914 PostEvictTextures();
1915 break;
1916 case 6:
1917 // We couldn't check in didCommitAndDrawFrame on commit 5,
1918 // so check here.
1919 EXPECT_FALSE(layer_->HaveBackingTexture());
1920 PostEvictTextures();
1921 break;
1922 default:
1923 NOTREACHED();
1924 break;
1928 virtual void AfterTest() OVERRIDE {}
1930 private:
1931 FakeContentLayerClient client_;
1932 scoped_refptr<EvictionTestLayer> layer_;
1933 LayerTreeHostImpl* impl_for_evict_textures_;
1934 int num_commits_;
1937 MULTI_THREAD_TEST_F(LayerTreeHostTestEvictTextures);
1939 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
1940 public:
1941 LayerTreeHostTestContinuousCommit()
1942 : num_commit_complete_(0), num_draw_layers_(0) {}
1944 virtual void BeginTest() OVERRIDE {
1945 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1946 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1948 PostSetNeedsCommitToMainThread();
1951 virtual void DidCommit() OVERRIDE {
1952 if (num_draw_layers_ == 2)
1953 return;
1954 layer_tree_host()->SetNeedsCommit();
1957 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1958 if (num_draw_layers_ == 1)
1959 num_commit_complete_++;
1962 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1963 num_draw_layers_++;
1964 if (num_draw_layers_ == 2)
1965 EndTest();
1968 virtual void AfterTest() OVERRIDE {
1969 // Check that we didn't commit twice between first and second draw.
1970 EXPECT_EQ(1, num_commit_complete_);
1973 private:
1974 int num_commit_complete_;
1975 int num_draw_layers_;
1978 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
1980 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1981 public:
1982 LayerTreeHostTestContinuousInvalidate()
1983 : num_commit_complete_(0), num_draw_layers_(0) {}
1985 virtual void BeginTest() OVERRIDE {
1986 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1987 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1989 content_layer_ = ContentLayer::Create(&client_);
1990 content_layer_->SetBounds(gfx::Size(10, 10));
1991 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
1992 content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1993 content_layer_->SetIsDrawable(true);
1994 layer_tree_host()->root_layer()->AddChild(content_layer_);
1996 PostSetNeedsCommitToMainThread();
1999 virtual void DidCommitAndDrawFrame() OVERRIDE {
2000 if (num_draw_layers_ == 2)
2001 return;
2002 content_layer_->SetNeedsDisplay();
2005 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2006 if (num_draw_layers_ == 1)
2007 num_commit_complete_++;
2010 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2011 num_draw_layers_++;
2012 if (num_draw_layers_ == 2)
2013 EndTest();
2016 virtual void AfterTest() OVERRIDE {
2017 // Check that we didn't commit twice between first and second draw.
2018 EXPECT_EQ(1, num_commit_complete_);
2021 private:
2022 FakeContentLayerClient client_;
2023 scoped_refptr<Layer> content_layer_;
2024 int num_commit_complete_;
2025 int num_draw_layers_;
2028 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
2030 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2031 public:
2032 LayerTreeHostTestDeferCommits()
2033 : num_commits_deferred_(0), num_complete_commits_(0) {}
2035 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2037 virtual void DidDeferCommit() OVERRIDE {
2038 num_commits_deferred_++;
2039 layer_tree_host()->SetDeferCommits(false);
2042 virtual void DidCommit() OVERRIDE {
2043 num_complete_commits_++;
2044 switch (num_complete_commits_) {
2045 case 1:
2046 EXPECT_EQ(0, num_commits_deferred_);
2047 layer_tree_host()->SetDeferCommits(true);
2048 PostSetNeedsCommitToMainThread();
2049 break;
2050 case 2:
2051 EndTest();
2052 break;
2053 default:
2054 NOTREACHED();
2055 break;
2059 virtual void AfterTest() OVERRIDE {
2060 EXPECT_EQ(1, num_commits_deferred_);
2061 EXPECT_EQ(2, num_complete_commits_);
2064 private:
2065 int num_commits_deferred_;
2066 int num_complete_commits_;
2069 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2071 class LayerTreeHostWithProxy : public LayerTreeHost {
2072 public:
2073 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2074 const LayerTreeSettings& settings,
2075 scoped_ptr<FakeProxy> proxy)
2076 : LayerTreeHost(client, settings) {
2077 proxy->SetLayerTreeHost(this);
2078 EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>()));
2082 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2083 // When partial updates are not allowed, max updates should be 0.
2085 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2087 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2088 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2089 proxy->SetMaxPartialTextureUpdates(5);
2091 LayerTreeSettings settings;
2092 settings.max_partial_texture_updates = 10;
2094 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2095 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2097 EXPECT_EQ(0u, host.settings().max_partial_texture_updates);
2100 // When partial updates are allowed,
2101 // max updates should be limited by the proxy.
2103 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2105 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2106 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2107 proxy->SetMaxPartialTextureUpdates(5);
2109 LayerTreeSettings settings;
2110 settings.max_partial_texture_updates = 10;
2112 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2113 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2115 EXPECT_EQ(5u, host.settings().max_partial_texture_updates);
2118 // When partial updates are allowed,
2119 // max updates should also be limited by the settings.
2121 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2123 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2124 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2125 proxy->SetMaxPartialTextureUpdates(20);
2127 LayerTreeSettings settings;
2128 settings.max_partial_texture_updates = 10;
2130 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2131 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2133 EXPECT_EQ(10u, host.settings().max_partial_texture_updates);
2137 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2138 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2140 LayerTreeSettings settings;
2141 settings.max_partial_texture_updates = 4;
2143 scoped_ptr<LayerTreeHost> host =
2144 LayerTreeHost::Create(&client, settings, NULL);
2145 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2146 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2149 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2150 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2152 LayerTreeSettings settings;
2153 settings.max_partial_texture_updates = 4;
2155 scoped_ptr<LayerTreeHost> host =
2156 LayerTreeHost::Create(&client, settings, NULL);
2157 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2158 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2161 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2162 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2164 LayerTreeSettings settings;
2165 settings.max_partial_texture_updates = 4;
2167 scoped_ptr<LayerTreeHost> host =
2168 LayerTreeHost::Create(&client, settings, NULL);
2169 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2170 EXPECT_EQ(0u, host->settings().max_partial_texture_updates);
2173 TEST(LayerTreeHostTest,
2174 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2175 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2177 LayerTreeSettings settings;
2178 settings.max_partial_texture_updates = 4;
2180 scoped_ptr<LayerTreeHost> host =
2181 LayerTreeHost::Create(&client, settings, NULL);
2182 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2183 EXPECT_EQ(0u, host->settings().max_partial_texture_updates);
2186 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2187 : public LayerTreeHostTest {
2188 public:
2189 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2190 : root_layer_(FakeContentLayer::Create(&client_)),
2191 child_layer1_(FakeContentLayer::Create(&client_)),
2192 child_layer2_(FakeContentLayer::Create(&client_)),
2193 num_commits_(0) {}
2195 virtual void BeginTest() OVERRIDE {
2196 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2197 root_layer_->SetBounds(gfx::Size(100, 100));
2198 child_layer1_->SetBounds(gfx::Size(100, 100));
2199 child_layer2_->SetBounds(gfx::Size(100, 100));
2200 root_layer_->AddChild(child_layer1_);
2201 root_layer_->AddChild(child_layer2_);
2202 layer_tree_host()->SetRootLayer(root_layer_);
2203 PostSetNeedsCommitToMainThread();
2206 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2207 bool visible) OVERRIDE {
2208 // One backing should remain unevicted.
2209 EXPECT_EQ(100u * 100u * 4u * 1u,
2210 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2211 // Make sure that contents textures are marked as having been
2212 // purged.
2213 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2214 // End the test in this state.
2215 EndTest();
2218 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2219 ++num_commits_;
2220 switch (num_commits_) {
2221 case 1:
2222 // All three backings should have memory.
2223 EXPECT_EQ(
2224 100u * 100u * 4u * 3u,
2225 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2226 // Set a new policy that will kick out 1 of the 3 resources.
2227 // Because a resource was evicted, a commit will be kicked off.
2228 host_impl->SetMemoryPolicy(
2229 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2230 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
2231 100 * 100 * 4 * 1,
2232 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
2233 1000));
2234 host_impl->SetDiscardBackBufferWhenNotVisible(true);
2235 break;
2236 case 2:
2237 // Only two backings should have memory.
2238 EXPECT_EQ(
2239 100u * 100u * 4u * 2u,
2240 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2241 // Become backgrounded, which will cause 1 more resource to be
2242 // evicted.
2243 PostSetVisibleToMainThread(false);
2244 break;
2245 default:
2246 // No further commits should happen because this is not visible
2247 // anymore.
2248 NOTREACHED();
2249 break;
2253 virtual void AfterTest() OVERRIDE {}
2255 private:
2256 FakeContentLayerClient client_;
2257 scoped_refptr<FakeContentLayer> root_layer_;
2258 scoped_refptr<FakeContentLayer> child_layer1_;
2259 scoped_refptr<FakeContentLayer> child_layer2_;
2260 int num_commits_;
2263 SINGLE_AND_MULTI_THREAD_TEST_F(
2264 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2266 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2267 public:
2268 class NotificationClient : public ContentLayerClient {
2269 public:
2270 NotificationClient()
2271 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2273 void set_layer(Layer* layer) { layer_ = layer; }
2274 int paint_count() const { return paint_count_; }
2275 int lcd_notification_count() const { return lcd_notification_count_; }
2277 virtual void PaintContents(SkCanvas* canvas,
2278 gfx::Rect clip,
2279 gfx::RectF* opaque) OVERRIDE {
2280 ++paint_count_;
2282 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2283 ++lcd_notification_count_;
2284 layer_->SetNeedsDisplay();
2287 private:
2288 Layer* layer_;
2289 int paint_count_;
2290 int lcd_notification_count_;
2293 virtual void SetupTree() OVERRIDE {
2294 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2295 root_layer->SetIsDrawable(true);
2296 root_layer->SetBounds(gfx::Size(1, 1));
2298 layer_tree_host()->SetRootLayer(root_layer);
2299 client_.set_layer(root_layer.get());
2301 // The expecations are based on the assumption that the default
2302 // LCD settings are:
2303 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2304 EXPECT_FALSE(root_layer->can_use_lcd_text());
2306 LayerTreeHostTest::SetupTree();
2309 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2310 virtual void AfterTest() OVERRIDE {}
2312 virtual void DidCommit() OVERRIDE {
2313 switch (layer_tree_host()->source_frame_number()) {
2314 case 1:
2315 // The first update consists one LCD notification and one paint.
2316 EXPECT_EQ(1, client_.lcd_notification_count());
2317 EXPECT_EQ(1, client_.paint_count());
2318 // LCD text must have been enabled on the layer.
2319 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2320 PostSetNeedsCommitToMainThread();
2321 break;
2322 case 2:
2323 // Since nothing changed on layer, there should be no notification
2324 // or paint on the second update.
2325 EXPECT_EQ(1, client_.lcd_notification_count());
2326 EXPECT_EQ(1, client_.paint_count());
2327 // LCD text must not have changed.
2328 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2329 // Change layer opacity that should trigger lcd notification.
2330 layer_tree_host()->root_layer()->SetOpacity(.5f);
2331 // No need to request a commit - setting opacity will do it.
2332 break;
2333 default:
2334 // Verify that there is not extra commit due to layer invalidation.
2335 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
2336 // LCD notification count should have incremented due to
2337 // change in layer opacity.
2338 EXPECT_EQ(2, client_.lcd_notification_count());
2339 // Paint count should be incremented due to invalidation.
2340 EXPECT_EQ(2, client_.paint_count());
2341 // LCD text must have been disabled on the layer due to opacity.
2342 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2343 EndTest();
2344 break;
2348 private:
2349 NotificationClient client_;
2352 SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2354 // Verify that the BeginFrame notification is used to initiate rendering.
2355 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2356 public:
2357 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2358 settings->begin_frame_scheduling_enabled = true;
2361 virtual void BeginTest() OVERRIDE {
2362 // This will trigger a SetNeedsBeginFrame which will trigger a BeginFrame.
2363 PostSetNeedsCommitToMainThread();
2366 virtual bool PrepareToDrawOnThread(
2367 LayerTreeHostImpl* host_impl,
2368 LayerTreeHostImpl::FrameData* frame,
2369 bool result) OVERRIDE {
2370 EndTest();
2371 return true;
2374 virtual void AfterTest() OVERRIDE {}
2376 private:
2377 base::TimeTicks frame_time_;
2380 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2382 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2383 : public LayerTreeHostTest {
2384 public:
2385 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2386 settings->begin_frame_scheduling_enabled = true;
2387 settings->using_synchronous_renderer_compositor = true;
2390 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2392 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2393 // The BeginFrame notification is turned off now but will get enabled
2394 // once we return. End test while it's enabled.
2395 ImplThreadTaskRunner()->PostTask(
2396 FROM_HERE,
2397 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2398 base::Unretained(this)));
2401 virtual void AfterTest() OVERRIDE {}
2404 MULTI_THREAD_TEST_F(
2405 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2407 class LayerTreeHostTestAbortedCommitDoesntStallNextCommitWhenIdle
2408 : public LayerTreeHostTest {
2409 protected:
2410 LayerTreeHostTestAbortedCommitDoesntStallNextCommitWhenIdle()
2411 : commit_count_(0), commit_complete_count_(0) {}
2413 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2414 settings->begin_frame_scheduling_enabled = true;
2415 settings->using_synchronous_renderer_compositor = true;
2418 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2420 virtual void DidCommit() OVERRIDE {
2421 commit_count_++;
2422 if (commit_count_ == 2) {
2423 // A commit was just aborted, request a real commit now to make sure a
2424 // real commit following an aborted commit will still complete and
2425 // end the test even when the Impl thread is idle.
2426 layer_tree_host()->SetNeedsCommit();
2430 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2431 commit_complete_count_++;
2432 if (commit_complete_count_ == 1) {
2433 // Initiate an aborted commit after the first commit.
2434 host_impl->SetNeedsCommit();
2435 } else {
2436 EndTest();
2440 virtual void AfterTest() OVERRIDE {
2441 EXPECT_EQ(commit_count_, 3);
2442 EXPECT_EQ(commit_complete_count_, 2);
2445 int commit_count_;
2446 int commit_complete_count_;
2449 MULTI_THREAD_TEST_F(
2450 LayerTreeHostTestAbortedCommitDoesntStallNextCommitWhenIdle);
2452 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2453 : public LayerTreeHostTest {
2454 protected:
2455 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2456 settings->impl_side_painting = true;
2459 virtual void SetupTree() OVERRIDE {
2460 LayerTreeHostTest::SetupTree();
2462 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2463 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2464 layer->SetBounds(gfx::Size(10, 10));
2465 layer_tree_host()->root_layer()->AddChild(layer);
2468 virtual void BeginTest() OVERRIDE {
2469 PostSetNeedsCommitToMainThread();
2472 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2473 EndTest();
2476 virtual void AfterTest() OVERRIDE {
2479 FakeContentLayerClient client_;
2482 MULTI_THREAD_TEST_F(
2483 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2485 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2486 : public LayerTreeHostTest {
2487 public:
2488 class SetBoundsClient : public ContentLayerClient {
2489 public:
2490 SetBoundsClient() : layer_(0) {}
2492 void set_layer(Layer* layer) { layer_ = layer; }
2494 virtual void PaintContents(SkCanvas* canvas,
2495 gfx::Rect clip,
2496 gfx::RectF* opaque) OVERRIDE {
2497 layer_->SetBounds(gfx::Size(2, 2));
2500 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2502 private:
2503 Layer* layer_;
2506 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2508 virtual void SetupTree() OVERRIDE {
2509 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2510 root_layer->SetIsDrawable(true);
2511 root_layer->SetBounds(gfx::Size(1, 1));
2513 layer_tree_host()->SetRootLayer(root_layer);
2514 client_.set_layer(root_layer.get());
2516 LayerTreeHostTest::SetupTree();
2519 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2520 virtual void AfterTest() OVERRIDE {}
2522 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2523 num_commits_++;
2524 if (num_commits_ == 1) {
2525 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2526 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2527 } else {
2528 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2529 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2530 EndTest();
2534 private:
2535 SetBoundsClient client_;
2536 int num_commits_;
2539 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2541 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2542 public:
2543 MockIOSurfaceWebGraphicsContext3D() {
2544 test_capabilities_.iosurface = true;
2545 test_capabilities_.texture_rectangle = true;
2548 virtual WebKit::WebGLId createTexture() OVERRIDE {
2549 return 1;
2552 MOCK_METHOD1(activeTexture, void(WebKit::WGC3Denum texture));
2553 MOCK_METHOD2(bindTexture, void(WebKit::WGC3Denum target,
2554 WebKit::WebGLId texture_id));
2555 MOCK_METHOD3(texParameteri, void(WebKit::WGC3Denum target,
2556 WebKit::WGC3Denum pname,
2557 WebKit::WGC3Dint param));
2558 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(WebKit::WGC3Denum target,
2559 WebKit::WGC3Dint width,
2560 WebKit::WGC3Dint height,
2561 WebKit::WGC3Duint ioSurfaceId,
2562 WebKit::WGC3Duint plane));
2563 MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
2564 WebKit::WGC3Dsizei count,
2565 WebKit::WGC3Denum type,
2566 WebKit::WGC3Dintptr offset));
2567 MOCK_METHOD1(deleteTexture, void(WebKit::WGC3Denum texture));
2571 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2572 protected:
2573 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
2574 OVERRIDE {
2575 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2576 new MockIOSurfaceWebGraphicsContext3D);
2577 mock_context_ = mock_context_owned.get();
2579 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
2580 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
2581 return output_surface.Pass();
2584 virtual void SetupTree() OVERRIDE {
2585 LayerTreeHostTest::SetupTree();
2587 layer_tree_host()->root_layer()->SetIsDrawable(false);
2589 io_surface_id_ = 9;
2590 io_surface_size_ = gfx::Size(6, 7);
2592 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2593 io_surface_layer->SetBounds(gfx::Size(10, 10));
2594 io_surface_layer->SetAnchorPoint(gfx::PointF());
2595 io_surface_layer->SetIsDrawable(true);
2596 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2597 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2600 virtual void BeginTest() OVERRIDE {
2601 PostSetNeedsCommitToMainThread();
2604 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2605 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2607 EXPECT_CALL(*mock_context_, activeTexture(_))
2608 .Times(0);
2609 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2610 .Times(AtLeast(1));
2611 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2612 GL_TEXTURE_MIN_FILTER,
2613 GL_LINEAR))
2614 .Times(1);
2615 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2616 GL_TEXTURE_MAG_FILTER,
2617 GL_LINEAR))
2618 .Times(1);
2619 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2620 GL_TEXTURE_WRAP_S,
2621 GL_CLAMP_TO_EDGE))
2622 .Times(1);
2623 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2624 GL_TEXTURE_WRAP_T,
2625 GL_CLAMP_TO_EDGE))
2626 .Times(1);
2628 EXPECT_CALL(*mock_context_, texImageIOSurface2DCHROMIUM(
2629 GL_TEXTURE_RECTANGLE_ARB,
2630 io_surface_size_.width(),
2631 io_surface_size_.height(),
2632 io_surface_id_,
2634 .Times(1);
2636 EXPECT_CALL(*mock_context_, bindTexture(_, 0))
2637 .Times(AnyNumber());
2640 virtual bool PrepareToDrawOnThread(
2641 LayerTreeHostImpl* host_impl,
2642 LayerTreeHostImpl::FrameData* frame,
2643 bool result) OVERRIDE {
2644 Mock::VerifyAndClearExpectations(&mock_context_);
2646 // The io surface layer's texture is drawn.
2647 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0))
2648 .Times(AtLeast(1));
2649 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2650 .Times(1);
2651 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2652 .Times(AtLeast(1));
2654 return result;
2657 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2658 Mock::VerifyAndClearExpectations(&mock_context_);
2660 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(1);
2661 EndTest();
2664 virtual void AfterTest() OVERRIDE {}
2666 int io_surface_id_;
2667 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2668 gfx::Size io_surface_size_;
2671 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
2672 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2673 LayerTreeHostTestIOSurfaceDrawing);
2675 class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
2676 protected:
2677 virtual void SetupTree() OVERRIDE {
2678 root = FakeContentLayer::Create(&client_);
2679 root->SetBounds(gfx::Size(20, 20));
2681 child = FakeContentLayer::Create(&client_);
2682 child->SetBounds(gfx::Size(10, 10));
2683 root->AddChild(child);
2685 layer_tree_host()->SetRootLayer(root);
2686 LayerTreeHostTest::SetupTree();
2689 virtual void BeginTest() OVERRIDE {
2690 PostSetNeedsCommitToMainThread();
2693 virtual void DidCommitAndDrawFrame() OVERRIDE {
2694 WaitForCallback();
2697 void WaitForCallback() {
2698 base::MessageLoop::current()->PostTask(
2699 FROM_HERE,
2700 base::Bind(
2701 &LayerTreeHostTestAsyncReadback::NextStep,
2702 base::Unretained(this)));
2705 void NextStep() {
2706 int frame = layer_tree_host()->source_frame_number();
2707 switch (frame) {
2708 case 1:
2709 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2710 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2711 base::Unretained(this))));
2712 EXPECT_EQ(0u, callbacks_.size());
2713 break;
2714 case 2:
2715 if (callbacks_.size() < 1u) {
2716 WaitForCallback();
2717 return;
2719 EXPECT_EQ(1u, callbacks_.size());
2720 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
2722 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2723 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2724 base::Unretained(this))));
2725 root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2726 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2727 base::Unretained(this))));
2728 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2729 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2730 base::Unretained(this))));
2731 EXPECT_EQ(1u, callbacks_.size());
2732 break;
2733 case 3:
2734 if (callbacks_.size() < 4u) {
2735 WaitForCallback();
2736 return;
2738 EXPECT_EQ(4u, callbacks_.size());
2739 // The child was copied to a bitmap and passed back twice.
2740 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
2741 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
2742 // The root was copied to a bitmap and passed back also.
2743 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
2744 EndTest();
2745 break;
2749 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2750 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2751 EXPECT_TRUE(result->HasBitmap());
2752 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
2753 EXPECT_EQ(result->size().ToString(),
2754 gfx::Size(bitmap->width(), bitmap->height()).ToString());
2755 callbacks_.push_back(result->size());
2758 virtual void AfterTest() OVERRIDE {
2759 EXPECT_EQ(4u, callbacks_.size());
2762 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
2763 OVERRIDE {
2764 scoped_ptr<FakeOutputSurface> output_surface;
2765 if (use_gl_renderer_) {
2766 output_surface = FakeOutputSurface::Create3d().Pass();
2767 } else {
2768 output_surface = FakeOutputSurface::CreateSoftware(
2769 make_scoped_ptr(new SoftwareOutputDevice)).Pass();
2771 return output_surface.PassAs<OutputSurface>();
2774 bool use_gl_renderer_;
2775 std::vector<gfx::Size> callbacks_;
2776 FakeContentLayerClient client_;
2777 scoped_refptr<FakeContentLayer> root;
2778 scoped_refptr<FakeContentLayer> child;
2781 // Readback can't be done with a delegating renderer.
2782 TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
2783 use_gl_renderer_ = true;
2784 RunTest(false, false, false);
2787 TEST_F(LayerTreeHostTestAsyncReadback,
2788 GLRenderer_RunMultiThread_MainThreadPainting) {
2789 use_gl_renderer_ = true;
2790 RunTest(true, false, false);
2793 TEST_F(LayerTreeHostTestAsyncReadback,
2794 GLRenderer_RunMultiThread_ImplSidePainting) {
2795 use_gl_renderer_ = true;
2796 RunTest(true, false, true);
2799 TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
2800 use_gl_renderer_ = false;
2801 RunTest(false, false, false);
2804 TEST_F(LayerTreeHostTestAsyncReadback,
2805 SoftwareRenderer_RunMultiThread_MainThreadPainting) {
2806 use_gl_renderer_ = false;
2807 RunTest(true, false, false);
2810 TEST_F(LayerTreeHostTestAsyncReadback,
2811 SoftwareRenderer_RunMultiThread_ImplSidePainting) {
2812 use_gl_renderer_ = false;
2813 RunTest(true, false, true);
2816 class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
2817 protected:
2818 virtual void SetupTree() OVERRIDE {
2819 root_ = FakeContentLayer::Create(&client_);
2820 root_->SetBounds(gfx::Size(20, 20));
2822 main_destroyed_ = FakeContentLayer::Create(&client_);
2823 main_destroyed_->SetBounds(gfx::Size(15, 15));
2824 root_->AddChild(main_destroyed_);
2826 impl_destroyed_ = FakeContentLayer::Create(&client_);
2827 impl_destroyed_->SetBounds(gfx::Size(10, 10));
2828 root_->AddChild(impl_destroyed_);
2830 layer_tree_host()->SetRootLayer(root_);
2831 LayerTreeHostTest::SetupTree();
2834 virtual void BeginTest() OVERRIDE {
2835 callback_count_ = 0;
2836 PostSetNeedsCommitToMainThread();
2839 virtual void DidCommit() OVERRIDE {
2840 int frame = layer_tree_host()->source_frame_number();
2841 switch (frame) {
2842 case 1:
2843 main_destroyed_->RequestCopyOfOutput(
2844 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2845 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
2846 CopyOutputCallback,
2847 base::Unretained(this))));
2848 impl_destroyed_->RequestCopyOfOutput(
2849 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2850 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
2851 CopyOutputCallback,
2852 base::Unretained(this))));
2853 EXPECT_EQ(0, callback_count_);
2855 // Destroy the main thread layer right away.
2856 main_destroyed_->RemoveFromParent();
2857 main_destroyed_ = NULL;
2859 // Should callback with a NULL bitmap.
2860 EXPECT_EQ(1, callback_count_);
2862 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
2863 layer_tree_host()->SetViewportSize(gfx::Size());
2864 break;
2865 case 2:
2866 // Flush the message loops and make sure the callbacks run.
2867 layer_tree_host()->SetNeedsCommit();
2868 break;
2869 case 3:
2870 // No drawing means no readback yet.
2871 EXPECT_EQ(1, callback_count_);
2873 // Destroy the impl thread layer.
2874 impl_destroyed_->RemoveFromParent();
2875 impl_destroyed_ = NULL;
2877 // No callback yet because it's on the impl side.
2878 EXPECT_EQ(1, callback_count_);
2879 break;
2880 case 4:
2881 // Flush the message loops and make sure the callbacks run.
2882 layer_tree_host()->SetNeedsCommit();
2883 break;
2884 case 5:
2885 // We should get another callback with a NULL bitmap.
2886 EXPECT_EQ(2, callback_count_);
2887 EndTest();
2888 break;
2892 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2893 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2894 EXPECT_TRUE(result->IsEmpty());
2895 ++callback_count_;
2898 virtual void AfterTest() OVERRIDE {}
2900 int callback_count_;
2901 FakeContentLayerClient client_;
2902 scoped_refptr<FakeContentLayer> root_;
2903 scoped_refptr<FakeContentLayer> main_destroyed_;
2904 scoped_refptr<FakeContentLayer> impl_destroyed_;
2907 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed);
2909 class LayerTreeHostTestAsyncReadbackInHiddenSubtree : public LayerTreeHostTest {
2910 protected:
2911 virtual void SetupTree() OVERRIDE {
2912 root_ = FakeContentLayer::Create(&client_);
2913 root_->SetBounds(gfx::Size(20, 20));
2915 grand_parent_layer_ = FakeContentLayer::Create(&client_);
2916 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
2917 root_->AddChild(grand_parent_layer_);
2919 // parent_layer_ owns a render surface.
2920 parent_layer_ = FakeContentLayer::Create(&client_);
2921 parent_layer_->SetBounds(gfx::Size(15, 15));
2922 parent_layer_->SetForceRenderSurface(true);
2923 grand_parent_layer_->AddChild(parent_layer_);
2925 copy_layer_ = FakeContentLayer::Create(&client_);
2926 copy_layer_->SetBounds(gfx::Size(10, 10));
2927 parent_layer_->AddChild(copy_layer_);
2929 layer_tree_host()->SetRootLayer(root_);
2930 LayerTreeHostTest::SetupTree();
2933 void AddCopyRequest(Layer* layer) {
2934 layer->RequestCopyOfOutput(
2935 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2936 &LayerTreeHostTestAsyncReadbackInHiddenSubtree::CopyOutputCallback,
2937 base::Unretained(this))));
2940 virtual void BeginTest() OVERRIDE {
2941 callback_count_ = 0;
2942 PostSetNeedsCommitToMainThread();
2944 AddCopyRequest(copy_layer_.get());
2947 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2948 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2949 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
2950 ++callback_count_;
2952 switch (callback_count_) {
2953 case 1:
2954 // Hide the copy request layer.
2955 grand_parent_layer_->SetHideLayerAndSubtree(false);
2956 parent_layer_->SetHideLayerAndSubtree(false);
2957 copy_layer_->SetHideLayerAndSubtree(true);
2958 AddCopyRequest(copy_layer_.get());
2959 break;
2960 case 2:
2961 // Hide the copy request layer's parent only.
2962 grand_parent_layer_->SetHideLayerAndSubtree(false);
2963 parent_layer_->SetHideLayerAndSubtree(true);
2964 copy_layer_->SetHideLayerAndSubtree(false);
2965 AddCopyRequest(copy_layer_.get());
2966 break;
2967 case 3:
2968 // Hide the copy request layer's grand parent only.
2969 grand_parent_layer_->SetHideLayerAndSubtree(true);
2970 parent_layer_->SetHideLayerAndSubtree(false);
2971 copy_layer_->SetHideLayerAndSubtree(false);
2972 AddCopyRequest(copy_layer_.get());
2973 break;
2974 case 4:
2975 // Hide the copy request layer's parent and grandparent.
2976 grand_parent_layer_->SetHideLayerAndSubtree(true);
2977 parent_layer_->SetHideLayerAndSubtree(true);
2978 copy_layer_->SetHideLayerAndSubtree(false);
2979 AddCopyRequest(copy_layer_.get());
2980 break;
2981 case 5:
2982 // Hide the copy request layer as well as its parent and grandparent.
2983 grand_parent_layer_->SetHideLayerAndSubtree(true);
2984 parent_layer_->SetHideLayerAndSubtree(true);
2985 copy_layer_->SetHideLayerAndSubtree(true);
2986 AddCopyRequest(copy_layer_.get());
2987 break;
2988 case 6:
2989 EndTest();
2990 break;
2994 virtual void AfterTest() OVERRIDE {}
2996 int callback_count_;
2997 FakeContentLayerClient client_;
2998 scoped_refptr<FakeContentLayer> root_;
2999 scoped_refptr<FakeContentLayer> grand_parent_layer_;
3000 scoped_refptr<FakeContentLayer> parent_layer_;
3001 scoped_refptr<FakeContentLayer> copy_layer_;
3004 // No output to copy for delegated renderers.
3005 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3006 LayerTreeHostTestAsyncReadbackInHiddenSubtree);
3008 class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
3009 : public LayerTreeHostTest {
3010 protected:
3011 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3012 settings->cache_render_pass_contents = true;
3015 virtual void SetupTree() OVERRIDE {
3016 root_ = FakeContentLayer::Create(&client_);
3017 root_->SetBounds(gfx::Size(20, 20));
3019 grand_parent_layer_ = FakeContentLayer::Create(&client_);
3020 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
3021 grand_parent_layer_->SetHideLayerAndSubtree(true);
3022 root_->AddChild(grand_parent_layer_);
3024 // parent_layer_ owns a render surface.
3025 parent_layer_ = FakeContentLayer::Create(&client_);
3026 parent_layer_->SetBounds(gfx::Size(15, 15));
3027 parent_layer_->SetForceRenderSurface(true);
3028 grand_parent_layer_->AddChild(parent_layer_);
3030 copy_layer_ = FakeContentLayer::Create(&client_);
3031 copy_layer_->SetBounds(gfx::Size(10, 10));
3032 parent_layer_->AddChild(copy_layer_);
3034 layer_tree_host()->SetRootLayer(root_);
3035 LayerTreeHostTest::SetupTree();
3038 virtual void BeginTest() OVERRIDE {
3039 did_draw_ = false;
3040 PostSetNeedsCommitToMainThread();
3042 copy_layer_->RequestCopyOfOutput(
3043 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3044 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
3045 CopyOutputCallback,
3046 base::Unretained(this))));
3049 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3050 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3051 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3052 EndTest();
3055 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3056 Renderer* renderer = host_impl->renderer();
3058 LayerImpl* root = host_impl->active_tree()->root_layer();
3059 LayerImpl* grand_parent = root->children()[0];
3060 LayerImpl* parent = grand_parent->children()[0];
3061 LayerImpl* copy_layer = parent->children()[0];
3063 // |parent| owns a surface, but it was hidden and not part of the copy
3064 // request so it should not allocate any resource.
3065 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
3066 parent->render_surface()->RenderPassId()));
3068 // |copy_layer| should have been rendered to a texture since it was needed
3069 // for a copy request.
3070 EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
3071 copy_layer->render_surface()->RenderPassId()));
3073 did_draw_ = true;
3076 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
3078 FakeContentLayerClient client_;
3079 bool did_draw_;
3080 scoped_refptr<FakeContentLayer> root_;
3081 scoped_refptr<FakeContentLayer> grand_parent_layer_;
3082 scoped_refptr<FakeContentLayer> parent_layer_;
3083 scoped_refptr<FakeContentLayer> copy_layer_;
3086 // No output to copy for delegated renderers.
3087 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3088 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
3090 class LayerTreeHostTestAsyncReadbackClippedOut : public LayerTreeHostTest {
3091 protected:
3092 virtual void SetupTree() OVERRIDE {
3093 root_ = FakeContentLayer::Create(&client_);
3094 root_->SetBounds(gfx::Size(20, 20));
3096 parent_layer_ = FakeContentLayer::Create(&client_);
3097 parent_layer_->SetBounds(gfx::Size(15, 15));
3098 parent_layer_->SetMasksToBounds(true);
3099 root_->AddChild(parent_layer_);
3101 copy_layer_ = FakeContentLayer::Create(&client_);
3102 copy_layer_->SetPosition(gfx::Point(15, 15));
3103 copy_layer_->SetBounds(gfx::Size(10, 10));
3104 parent_layer_->AddChild(copy_layer_);
3106 layer_tree_host()->SetRootLayer(root_);
3107 LayerTreeHostTest::SetupTree();
3110 virtual void BeginTest() OVERRIDE {
3111 PostSetNeedsCommitToMainThread();
3113 copy_layer_->RequestCopyOfOutput(
3114 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3115 &LayerTreeHostTestAsyncReadbackClippedOut::CopyOutputCallback,
3116 base::Unretained(this))));
3119 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3120 // We should still get a callback with no output if the copy requested layer
3121 // was completely clipped away.
3122 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3123 EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
3124 EndTest();
3127 virtual void AfterTest() OVERRIDE {}
3129 FakeContentLayerClient client_;
3130 scoped_refptr<FakeContentLayer> root_;
3131 scoped_refptr<FakeContentLayer> parent_layer_;
3132 scoped_refptr<FakeContentLayer> copy_layer_;
3135 // No output to copy for delegated renderers.
3136 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3137 LayerTreeHostTestAsyncReadbackClippedOut);
3139 class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostTest {
3140 protected:
3141 virtual void SetupTree() OVERRIDE {
3142 root_ = FakeContentLayer::Create(&client_);
3143 root_->SetBounds(gfx::Size(20, 20));
3145 copy_layer_ = FakeContentLayer::Create(&client_);
3146 copy_layer_->SetBounds(gfx::Size(10, 10));
3147 root_->AddChild(copy_layer_);
3149 layer_tree_host()->SetRootLayer(root_);
3150 LayerTreeHostTest::SetupTree();
3153 void AddCopyRequest(Layer* layer) {
3154 layer->RequestCopyOfOutput(
3155 CopyOutputRequest::CreateBitmapRequest(base::Bind(
3156 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
3157 base::Unretained(this))));
3160 virtual void BeginTest() OVERRIDE {
3161 saw_copy_request_ = false;
3162 callback_count_ = 0;
3163 PostSetNeedsCommitToMainThread();
3165 // Prevent drawing.
3166 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
3168 AddCopyRequest(copy_layer_.get());
3171 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3172 if (impl->active_tree()->source_frame_number() == 0) {
3173 LayerImpl* root = impl->active_tree()->root_layer();
3174 EXPECT_TRUE(root->children()[0]->HasCopyRequest());
3175 saw_copy_request_ = true;
3179 virtual void DidCommit() OVERRIDE {
3180 if (layer_tree_host()->source_frame_number() == 1) {
3181 // Allow drawing.
3182 layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
3184 AddCopyRequest(copy_layer_.get());
3188 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3189 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3190 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3191 ++callback_count_;
3193 if (callback_count_ == 2)
3194 EndTest();
3197 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
3199 bool saw_copy_request_;
3200 int callback_count_;
3201 FakeContentLayerClient client_;
3202 scoped_refptr<FakeContentLayer> root_;
3203 scoped_refptr<FakeContentLayer> copy_layer_;
3206 // No output to copy for delegated renderers.
3207 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3208 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
3210 class LayerTreeHostTestAsyncReadbackLostOutputSurface
3211 : public LayerTreeHostTest {
3212 protected:
3213 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3214 OVERRIDE {
3215 if (!first_context_provider_.get()) {
3216 first_context_provider_ = TestContextProvider::Create();
3217 return FakeOutputSurface::Create3d(first_context_provider_)
3218 .PassAs<OutputSurface>();
3221 EXPECT_FALSE(second_context_provider_.get());
3222 second_context_provider_ = TestContextProvider::Create();
3223 return FakeOutputSurface::Create3d(second_context_provider_)
3224 .PassAs<OutputSurface>();
3227 virtual void SetupTree() OVERRIDE {
3228 root_ = FakeContentLayer::Create(&client_);
3229 root_->SetBounds(gfx::Size(20, 20));
3231 copy_layer_ = FakeContentLayer::Create(&client_);
3232 copy_layer_->SetBounds(gfx::Size(10, 10));
3233 root_->AddChild(copy_layer_);
3235 layer_tree_host()->SetRootLayer(root_);
3236 LayerTreeHostTest::SetupTree();
3239 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3241 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3242 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3243 EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString());
3244 EXPECT_TRUE(result->HasTexture());
3246 // Save the result for later.
3247 EXPECT_FALSE(result_);
3248 result_ = result.Pass();
3250 // Post a commit to lose the output surface.
3251 layer_tree_host()->SetNeedsCommit();
3254 virtual void DidCommitAndDrawFrame() OVERRIDE {
3255 switch (layer_tree_host()->source_frame_number()) {
3256 case 1:
3257 // The layers have been pushed to the impl side. The layer textures have
3258 // been allocated.
3260 // Request a copy of the layer. This will use another texture.
3261 copy_layer_->RequestCopyOfOutput(
3262 CopyOutputRequest::CreateRequest(base::Bind(
3263 &LayerTreeHostTestAsyncReadbackLostOutputSurface::
3264 CopyOutputCallback,
3265 base::Unretained(this))));
3266 break;
3267 case 4:
3268 // With SingleThreadProxy it takes two commits to finally swap after a
3269 // context loss.
3270 case 5:
3271 // Now destroy the CopyOutputResult, releasing the texture inside back
3272 // to the compositor.
3273 EXPECT_TRUE(result_);
3274 result_.reset();
3276 // Check that it is released.
3277 base::SingleThreadTaskRunner* task_runner =
3278 HasImplThread() ? ImplThreadTaskRunner()
3279 : base::MessageLoopProxy::current();
3280 task_runner->PostTask(
3281 FROM_HERE,
3282 base::Bind(&LayerTreeHostTestAsyncReadbackLostOutputSurface::
3283 CheckNumTextures,
3284 base::Unretained(this),
3285 num_textures_after_loss_ - 1));
3286 break;
3290 virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result)
3291 OVERRIDE {
3292 switch (impl->active_tree()->source_frame_number()) {
3293 case 0:
3294 // The layers have been drawn, so their textures have been allocated.
3295 EXPECT_FALSE(result_);
3296 num_textures_without_readback_ =
3297 first_context_provider_->TestContext3d()->NumTextures();
3298 break;
3299 case 1:
3300 // We did a readback, so there will be a readback texture around now.
3301 EXPECT_LT(num_textures_without_readback_,
3302 first_context_provider_->TestContext3d()->NumTextures());
3303 break;
3304 case 2:
3305 // The readback texture is collected.
3306 EXPECT_TRUE(result_);
3308 // Lose the output surface.
3309 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
3310 GL_GUILTY_CONTEXT_RESET_ARB,
3311 GL_INNOCENT_CONTEXT_RESET_ARB);
3312 break;
3313 case 3:
3314 // With SingleThreadProxy it takes two commits to finally swap after a
3315 // context loss.
3316 case 4:
3317 // The output surface has been recreated.
3318 EXPECT_TRUE(second_context_provider_.get());
3320 num_textures_after_loss_ =
3321 first_context_provider_->TestContext3d()->NumTextures();
3322 break;
3326 void CheckNumTextures(size_t expected_num_textures) {
3327 EXPECT_EQ(expected_num_textures,
3328 first_context_provider_->TestContext3d()->NumTextures());
3329 EndTest();
3332 virtual void AfterTest() OVERRIDE {}
3334 scoped_refptr<TestContextProvider> first_context_provider_;
3335 scoped_refptr<TestContextProvider> second_context_provider_;
3336 size_t num_textures_without_readback_;
3337 size_t num_textures_after_loss_;
3338 FakeContentLayerClient client_;
3339 scoped_refptr<FakeContentLayer> root_;
3340 scoped_refptr<FakeContentLayer> copy_layer_;
3341 scoped_ptr<CopyOutputResult> result_;
3344 // No output to copy for delegated renderers.
3345 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3346 LayerTreeHostTestAsyncReadbackLostOutputSurface);
3348 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
3349 public:
3350 virtual void BeginTest() OVERRIDE {
3351 frame_ = 0;
3352 PostSetNeedsCommitToMainThread();
3355 // Round 1: commit + draw
3356 // Round 2: commit only (no draw/swap)
3357 // Round 3: draw only (no commit)
3358 // Round 4: composite & readback (2 commits, no draw/swap)
3359 // Round 5: commit + draw
3361 virtual void DidCommit() OVERRIDE {
3362 int commit = layer_tree_host()->source_frame_number();
3363 switch (commit) {
3364 case 2:
3365 // Round 2 done.
3366 EXPECT_EQ(1, frame_);
3367 layer_tree_host()->SetNeedsRedraw();
3368 break;
3369 case 3:
3370 // CompositeAndReadback in Round 4, first commit.
3371 EXPECT_EQ(2, frame_);
3372 break;
3373 case 4:
3374 // Round 4 done.
3375 EXPECT_EQ(2, frame_);
3376 layer_tree_host()->SetNeedsCommit();
3377 layer_tree_host()->SetNeedsRedraw();
3378 break;
3382 virtual void DidCompleteSwapBuffers() OVERRIDE {
3383 int commit = layer_tree_host()->source_frame_number();
3384 ++frame_;
3385 char pixels[4] = {0};
3386 switch (frame_) {
3387 case 1:
3388 // Round 1 done.
3389 EXPECT_EQ(1, commit);
3390 layer_tree_host()->SetNeedsCommit();
3391 break;
3392 case 2:
3393 // Round 3 done.
3394 EXPECT_EQ(2, commit);
3395 layer_tree_host()->CompositeAndReadback(pixels, gfx::Rect(0, 0, 1, 1));
3396 break;
3397 case 3:
3398 // Round 5 done.
3399 EXPECT_EQ(5, commit);
3400 EndTest();
3401 break;
3405 virtual void AfterTest() OVERRIDE {}
3407 protected:
3408 int frame_;
3411 TEST_F(LayerTreeHostTestNumFramesPending, DelegatingRenderer) {
3412 RunTest(true, true, true);
3415 TEST_F(LayerTreeHostTestNumFramesPending, GLRenderer) {
3416 RunTest(true, false, true);
3419 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
3420 public:
3421 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3422 // PictureLayer can only be used with impl side painting enabled.
3423 settings->impl_side_painting = true;
3424 settings->solid_color_scrollbars = true;
3427 virtual void SetupTree() OVERRIDE {
3428 layer_ = FakePictureLayer::Create(&client_);
3429 // Force commits to not be aborted so new frames get drawn, otherwise
3430 // the renderer gets deferred initialized but nothing new needs drawing.
3431 layer_->set_always_update_resources(true);
3432 layer_tree_host()->SetRootLayer(layer_);
3433 LayerTreeHostTest::SetupTree();
3436 virtual void BeginTest() OVERRIDE {
3437 did_initialize_gl_ = false;
3438 did_release_gl_ = false;
3439 last_source_frame_number_drawn_ = -1; // Never drawn.
3440 PostSetNeedsCommitToMainThread();
3443 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3444 OVERRIDE {
3445 scoped_ptr<TestWebGraphicsContext3D> context3d(
3446 TestWebGraphicsContext3D::Create());
3447 context3d->set_support_swapbuffers_complete_callback(false);
3449 return FakeOutputSurface::CreateDeferredGL(
3450 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice))
3451 .PassAs<OutputSurface>();
3454 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3455 ASSERT_TRUE(host_impl->RootLayer());
3456 FakePictureLayerImpl* layer_impl =
3457 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
3459 // The same frame can be draw multiple times if new visible tiles are
3460 // rasterized. But we want to make sure we only post DeferredInitialize
3461 // and ReleaseGL once, so early out if the same frame is drawn again.
3462 if (last_source_frame_number_drawn_ ==
3463 host_impl->active_tree()->source_frame_number())
3464 return;
3466 last_source_frame_number_drawn_ =
3467 host_impl->active_tree()->source_frame_number();
3469 if (!did_initialize_gl_) {
3470 EXPECT_LE(1u, layer_impl->append_quads_count());
3471 ImplThreadTaskRunner()->PostTask(
3472 FROM_HERE,
3473 base::Bind(
3474 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3475 base::Unretained(this),
3476 base::Unretained(host_impl)));
3477 } else if (did_initialize_gl_ && !did_release_gl_) {
3478 EXPECT_LE(2u, layer_impl->append_quads_count());
3479 ImplThreadTaskRunner()->PostTask(
3480 FROM_HERE,
3481 base::Bind(
3482 &LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3483 base::Unretained(this),
3484 base::Unretained(host_impl)));
3485 } else if (did_initialize_gl_ && did_release_gl_) {
3486 EXPECT_LE(3u, layer_impl->append_quads_count());
3487 EndTest();
3491 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
3492 EXPECT_FALSE(did_initialize_gl_);
3493 // SetAndInitializeContext3D calls SetNeedsCommit.
3494 FakeOutputSurface* fake_output_surface =
3495 static_cast<FakeOutputSurface*>(host_impl->output_surface());
3496 scoped_refptr<TestContextProvider> context_provider =
3497 TestContextProvider::Create(); // Not bound to thread.
3498 EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d(
3499 context_provider, NULL));
3500 did_initialize_gl_ = true;
3503 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3504 EXPECT_TRUE(did_initialize_gl_);
3505 EXPECT_FALSE(did_release_gl_);
3506 // ReleaseGL calls SetNeedsCommit.
3507 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3508 did_release_gl_ = true;
3511 virtual void AfterTest() OVERRIDE {
3512 EXPECT_TRUE(did_initialize_gl_);
3513 EXPECT_TRUE(did_release_gl_);
3516 private:
3517 FakeContentLayerClient client_;
3518 scoped_refptr<FakePictureLayer> layer_;
3519 bool did_initialize_gl_;
3520 bool did_release_gl_;
3521 int last_source_frame_number_drawn_;
3524 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3526 // Test for UI Resource management.
3527 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3528 public:
3529 LayerTreeHostTestUIResource() : num_ui_resources_(0), num_commits_(0) {}
3531 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3533 virtual void DidCommit() OVERRIDE {
3534 int frame = num_commits_;
3535 switch (frame) {
3536 case 1:
3537 CreateResource();
3538 CreateResource();
3539 PostSetNeedsCommitToMainThread();
3540 break;
3541 case 2:
3542 // Usually ScopedUIResource are deleted from the manager in their
3543 // destructor. Here we just want to test that a direct call to
3544 // DeleteUIResource works.
3545 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3546 PostSetNeedsCommitToMainThread();
3547 break;
3548 case 3:
3549 // DeleteUIResource can be called with an invalid id.
3550 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3551 PostSetNeedsCommitToMainThread();
3552 break;
3553 case 4:
3554 CreateResource();
3555 CreateResource();
3556 PostSetNeedsCommitToMainThread();
3557 break;
3558 case 5:
3559 ClearResources();
3560 EndTest();
3561 break;
3565 void PerformTest(LayerTreeHostImpl* impl) {
3566 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
3567 impl->output_surface()->context_provider()->Context3d());
3569 int frame = num_commits_;
3570 switch (frame) {
3571 case 1:
3572 ASSERT_EQ(0u, context->NumTextures());
3573 break;
3574 case 2:
3575 // Created two textures.
3576 ASSERT_EQ(2u, context->NumTextures());
3577 break;
3578 case 3:
3579 // One texture left after one deletion.
3580 ASSERT_EQ(1u, context->NumTextures());
3581 break;
3582 case 4:
3583 // Resource manager state should not change when delete is called on an
3584 // invalid id.
3585 ASSERT_EQ(1u, context->NumTextures());
3586 break;
3587 case 5:
3588 // Creation after deletion: two more creates should total up to
3589 // three textures.
3590 ASSERT_EQ(3u, context->NumTextures());
3591 break;
3595 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3596 ++num_commits_;
3597 if (!layer_tree_host()->settings().impl_side_painting)
3598 PerformTest(impl);
3601 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3602 if (layer_tree_host()->settings().impl_side_painting)
3603 PerformTest(impl);
3606 virtual void AfterTest() OVERRIDE {}
3608 private:
3609 // Must clear all resources before exiting.
3610 void ClearResources() {
3611 for (int i = 0; i < num_ui_resources_; i++)
3612 ui_resources_[i].reset();
3615 void CreateResource() {
3616 ui_resources_[num_ui_resources_++] =
3617 FakeScopedUIResource::Create(layer_tree_host());
3620 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3621 int num_ui_resources_;
3622 int num_commits_;
3625 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3627 class PushPropertiesCountingLayer : public Layer {
3628 public:
3629 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3630 return new PushPropertiesCountingLayer();
3633 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
3634 Layer::PushPropertiesTo(layer);
3635 push_properties_count_++;
3636 if (persist_needs_push_properties_)
3637 needs_push_properties_ = true;
3640 size_t push_properties_count() const { return push_properties_count_; }
3641 void reset_push_properties_count() { push_properties_count_ = 0; }
3643 void set_persist_needs_push_properties(bool persist) {
3644 persist_needs_push_properties_ = persist;
3647 private:
3648 PushPropertiesCountingLayer()
3649 : push_properties_count_(0),
3650 persist_needs_push_properties_(false) {
3651 SetAnchorPoint(gfx::PointF());
3652 SetBounds(gfx::Size(1, 1));
3653 SetIsDrawable(true);
3655 virtual ~PushPropertiesCountingLayer() {}
3657 size_t push_properties_count_;
3658 bool persist_needs_push_properties_;
3661 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3662 protected:
3663 virtual void BeginTest() OVERRIDE {
3664 num_commits_ = 0;
3665 expected_push_properties_root_ = 0;
3666 expected_push_properties_child_ = 0;
3667 expected_push_properties_grandchild_ = 0;
3668 expected_push_properties_child2_ = 0;
3669 expected_push_properties_other_root_ = 0;
3670 expected_push_properties_leaf_layer_ = 0;
3671 PostSetNeedsCommitToMainThread();
3674 virtual void SetupTree() OVERRIDE {
3675 root_ = PushPropertiesCountingLayer::Create();
3676 child_ = PushPropertiesCountingLayer::Create();
3677 child2_ = PushPropertiesCountingLayer::Create();
3678 grandchild_ = PushPropertiesCountingLayer::Create();
3679 leaf_scrollbar_layer_ =
3680 FakePaintedScrollbarLayer::Create(false, false, root_->id());
3682 root_->AddChild(child_);
3683 root_->AddChild(child2_);
3684 child_->AddChild(grandchild_);
3685 child2_->AddChild(leaf_scrollbar_layer_);
3687 other_root_ = PushPropertiesCountingLayer::Create();
3689 // Don't set the root layer here.
3690 LayerTreeHostTest::SetupTree();
3693 virtual void DidCommitAndDrawFrame() OVERRIDE {
3694 ++num_commits_;
3696 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3697 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3698 EXPECT_EQ(expected_push_properties_grandchild_,
3699 grandchild_->push_properties_count());
3700 EXPECT_EQ(expected_push_properties_child2_,
3701 child2_->push_properties_count());
3702 EXPECT_EQ(expected_push_properties_other_root_,
3703 other_root_->push_properties_count());
3704 EXPECT_EQ(expected_push_properties_leaf_layer_,
3705 leaf_scrollbar_layer_->push_properties_count());
3707 // The scrollbar layer always needs to be pushed.
3708 if (root_->layer_tree_host()) {
3709 EXPECT_TRUE(root_->descendant_needs_push_properties());
3710 EXPECT_FALSE(root_->needs_push_properties());
3712 if (child2_->layer_tree_host()) {
3713 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3714 EXPECT_FALSE(child2_->needs_push_properties());
3716 if (leaf_scrollbar_layer_->layer_tree_host()) {
3717 EXPECT_FALSE(leaf_scrollbar_layer_->descendant_needs_push_properties());
3718 EXPECT_TRUE(leaf_scrollbar_layer_->needs_push_properties());
3721 // child_ and grandchild_ don't persist their need to push properties.
3722 if (child_->layer_tree_host()) {
3723 EXPECT_FALSE(child_->descendant_needs_push_properties());
3724 EXPECT_FALSE(child_->needs_push_properties());
3726 if (grandchild_->layer_tree_host()) {
3727 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3728 EXPECT_FALSE(grandchild_->needs_push_properties());
3731 if (other_root_->layer_tree_host()) {
3732 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3733 EXPECT_FALSE(other_root_->needs_push_properties());
3736 switch (num_commits_) {
3737 case 1:
3738 layer_tree_host()->SetRootLayer(root_);
3739 // Layers added to the tree get committed.
3740 ++expected_push_properties_root_;
3741 ++expected_push_properties_child_;
3742 ++expected_push_properties_grandchild_;
3743 ++expected_push_properties_child2_;
3744 break;
3745 case 2:
3746 layer_tree_host()->SetNeedsCommit();
3747 // No layers need commit.
3748 break;
3749 case 3:
3750 layer_tree_host()->SetRootLayer(other_root_);
3751 // Layers added to the tree get committed.
3752 ++expected_push_properties_other_root_;
3753 break;
3754 case 4:
3755 layer_tree_host()->SetRootLayer(root_);
3756 // Layers added to the tree get committed.
3757 ++expected_push_properties_root_;
3758 ++expected_push_properties_child_;
3759 ++expected_push_properties_grandchild_;
3760 ++expected_push_properties_child2_;
3761 break;
3762 case 5:
3763 layer_tree_host()->SetNeedsCommit();
3764 // No layers need commit.
3765 break;
3766 case 6:
3767 child_->RemoveFromParent();
3768 // No layers need commit.
3769 break;
3770 case 7:
3771 root_->AddChild(child_);
3772 // Layers added to the tree get committed.
3773 ++expected_push_properties_child_;
3774 ++expected_push_properties_grandchild_;
3775 break;
3776 case 8:
3777 grandchild_->RemoveFromParent();
3778 // No layers need commit.
3779 break;
3780 case 9:
3781 child_->AddChild(grandchild_);
3782 // Layers added to the tree get committed.
3783 ++expected_push_properties_grandchild_;
3784 break;
3785 case 10:
3786 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3787 // No layers need commit.
3788 break;
3789 case 11:
3790 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3791 // No layers need commit.
3792 break;
3793 case 12:
3794 child_->SetPosition(gfx::Point(1, 1));
3795 // The modified layer needs commit
3796 ++expected_push_properties_child_;
3797 break;
3798 case 13:
3799 child2_->SetPosition(gfx::Point(1, 1));
3800 // The modified layer needs commit
3801 ++expected_push_properties_child2_;
3802 break;
3803 case 14:
3804 child_->RemoveFromParent();
3805 root_->AddChild(child_);
3806 // Layers added to the tree get committed.
3807 ++expected_push_properties_child_;
3808 ++expected_push_properties_grandchild_;
3809 break;
3810 case 15:
3811 grandchild_->SetPosition(gfx::Point(1, 1));
3812 // The modified layer needs commit
3813 ++expected_push_properties_grandchild_;
3814 break;
3815 case 16:
3816 // SetNeedsDisplay does not always set needs commit (so call it
3817 // explicitly), but is a property change.
3818 child_->SetNeedsDisplay();
3819 ++expected_push_properties_child_;
3820 layer_tree_host()->SetNeedsCommit();
3821 break;
3822 case 17:
3823 EndTest();
3824 break;
3827 // Content/Picture layers require PushProperties every commit that they are
3828 // in the tree.
3829 if (leaf_scrollbar_layer_->layer_tree_host())
3830 ++expected_push_properties_leaf_layer_;
3833 virtual void AfterTest() OVERRIDE {}
3835 int num_commits_;
3836 FakeContentLayerClient client_;
3837 scoped_refptr<PushPropertiesCountingLayer> root_;
3838 scoped_refptr<PushPropertiesCountingLayer> child_;
3839 scoped_refptr<PushPropertiesCountingLayer> child2_;
3840 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3841 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3842 scoped_refptr<FakePaintedScrollbarLayer> leaf_scrollbar_layer_;
3843 size_t expected_push_properties_root_;
3844 size_t expected_push_properties_child_;
3845 size_t expected_push_properties_child2_;
3846 size_t expected_push_properties_grandchild_;
3847 size_t expected_push_properties_other_root_;
3848 size_t expected_push_properties_leaf_layer_;
3851 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3853 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3854 : public LayerTreeHostTest {
3855 protected:
3856 virtual void BeginTest() OVERRIDE {
3857 PostSetNeedsCommitToMainThread();
3860 virtual void SetupTree() OVERRIDE {
3861 root_ = Layer::Create();
3862 root_->SetBounds(gfx::Size(1, 1));
3864 bool paint_scrollbar = true;
3865 bool has_thumb = false;
3866 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3867 paint_scrollbar, has_thumb, root_->id());
3869 root_->AddChild(scrollbar_layer_);
3871 layer_tree_host()->SetRootLayer(root_);
3872 LayerTreeHostTest::SetupTree();
3875 virtual void DidCommitAndDrawFrame() OVERRIDE {
3876 switch (layer_tree_host()->source_frame_number()) {
3877 case 0:
3878 break;
3879 case 1: {
3880 // During update, the ignore_set_needs_commit_ bit is set to true to
3881 // avoid causing a second commit to be scheduled. If a property change
3882 // is made during this, however, it needs to be pushed in the upcoming
3883 // commit.
3884 scoped_ptr<base::AutoReset<bool> > ignore =
3885 scrollbar_layer_->IgnoreSetNeedsCommit();
3887 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3889 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3890 EXPECT_TRUE(root_->descendant_needs_push_properties());
3891 layer_tree_host()->SetNeedsCommit();
3893 scrollbar_layer_->reset_push_properties_count();
3894 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3895 break;
3897 case 2:
3898 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3899 EndTest();
3900 break;
3904 virtual void AfterTest() OVERRIDE {}
3906 scoped_refptr<Layer> root_;
3907 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3910 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3912 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3913 : public LayerTreeHostTest {
3914 protected:
3915 virtual void BeginTest() OVERRIDE {
3916 expected_push_properties_root_ = 0;
3917 expected_push_properties_child_ = 0;
3918 expected_push_properties_grandchild1_ = 0;
3919 expected_push_properties_grandchild2_ = 0;
3920 expected_push_properties_grandchild3_ = 0;
3921 PostSetNeedsCommitToMainThread();
3924 virtual void SetupTree() OVERRIDE {
3925 root_ = PushPropertiesCountingLayer::Create();
3926 child_ = PushPropertiesCountingLayer::Create();
3927 grandchild1_ = PushPropertiesCountingLayer::Create();
3928 grandchild2_ = PushPropertiesCountingLayer::Create();
3929 grandchild3_ = PushPropertiesCountingLayer::Create();
3931 root_->AddChild(child_);
3932 child_->AddChild(grandchild1_);
3933 child_->AddChild(grandchild2_);
3934 child_->AddChild(grandchild3_);
3936 // Don't set the root layer here.
3937 LayerTreeHostTest::SetupTree();
3940 virtual void AfterTest() OVERRIDE {}
3942 FakeContentLayerClient client_;
3943 scoped_refptr<PushPropertiesCountingLayer> root_;
3944 scoped_refptr<PushPropertiesCountingLayer> child_;
3945 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3946 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3947 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3948 size_t expected_push_properties_root_;
3949 size_t expected_push_properties_child_;
3950 size_t expected_push_properties_grandchild1_;
3951 size_t expected_push_properties_grandchild2_;
3952 size_t expected_push_properties_grandchild3_;
3955 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3956 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3957 protected:
3958 virtual void DidCommitAndDrawFrame() OVERRIDE {
3959 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3960 switch (last_source_frame_number) {
3961 case 0:
3962 EXPECT_FALSE(root_->needs_push_properties());
3963 EXPECT_FALSE(root_->descendant_needs_push_properties());
3964 EXPECT_FALSE(child_->needs_push_properties());
3965 EXPECT_FALSE(child_->descendant_needs_push_properties());
3966 EXPECT_FALSE(grandchild1_->needs_push_properties());
3967 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3968 EXPECT_FALSE(grandchild2_->needs_push_properties());
3969 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3970 EXPECT_FALSE(grandchild3_->needs_push_properties());
3971 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3973 layer_tree_host()->SetRootLayer(root_);
3975 EXPECT_TRUE(root_->needs_push_properties());
3976 EXPECT_TRUE(root_->descendant_needs_push_properties());
3977 EXPECT_TRUE(child_->needs_push_properties());
3978 EXPECT_TRUE(child_->descendant_needs_push_properties());
3979 EXPECT_TRUE(grandchild1_->needs_push_properties());
3980 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3981 EXPECT_TRUE(grandchild2_->needs_push_properties());
3982 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3983 EXPECT_TRUE(grandchild3_->needs_push_properties());
3984 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3985 break;
3986 case 1:
3987 EndTest();
3988 break;
3993 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3995 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3996 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3997 protected:
3998 virtual void DidCommitAndDrawFrame() OVERRIDE {
3999 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4000 switch (last_source_frame_number) {
4001 case 0:
4002 layer_tree_host()->SetRootLayer(root_);
4003 break;
4004 case 1:
4005 EXPECT_FALSE(root_->needs_push_properties());
4006 EXPECT_FALSE(root_->descendant_needs_push_properties());
4007 EXPECT_FALSE(child_->needs_push_properties());
4008 EXPECT_FALSE(child_->descendant_needs_push_properties());
4009 EXPECT_FALSE(grandchild1_->needs_push_properties());
4010 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4011 EXPECT_FALSE(grandchild2_->needs_push_properties());
4012 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4013 EXPECT_FALSE(grandchild3_->needs_push_properties());
4014 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4016 grandchild1_->RemoveFromParent();
4017 grandchild1_->SetPosition(gfx::Point(1, 1));
4019 EXPECT_FALSE(root_->needs_push_properties());
4020 EXPECT_FALSE(root_->descendant_needs_push_properties());
4021 EXPECT_FALSE(child_->needs_push_properties());
4022 EXPECT_FALSE(child_->descendant_needs_push_properties());
4023 EXPECT_FALSE(grandchild2_->needs_push_properties());
4024 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4025 EXPECT_FALSE(grandchild3_->needs_push_properties());
4026 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4028 child_->AddChild(grandchild1_);
4030 EXPECT_FALSE(root_->needs_push_properties());
4031 EXPECT_TRUE(root_->descendant_needs_push_properties());
4032 EXPECT_FALSE(child_->needs_push_properties());
4033 EXPECT_TRUE(child_->descendant_needs_push_properties());
4034 EXPECT_TRUE(grandchild1_->needs_push_properties());
4035 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4036 EXPECT_FALSE(grandchild2_->needs_push_properties());
4037 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4038 EXPECT_FALSE(grandchild3_->needs_push_properties());
4039 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4041 grandchild2_->SetPosition(gfx::Point(1, 1));
4043 EXPECT_FALSE(root_->needs_push_properties());
4044 EXPECT_TRUE(root_->descendant_needs_push_properties());
4045 EXPECT_FALSE(child_->needs_push_properties());
4046 EXPECT_TRUE(child_->descendant_needs_push_properties());
4047 EXPECT_TRUE(grandchild1_->needs_push_properties());
4048 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4049 EXPECT_TRUE(grandchild2_->needs_push_properties());
4050 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4051 EXPECT_FALSE(grandchild3_->needs_push_properties());
4052 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4054 // grandchild2_ will still need a push properties.
4055 grandchild1_->RemoveFromParent();
4057 EXPECT_FALSE(root_->needs_push_properties());
4058 EXPECT_TRUE(root_->descendant_needs_push_properties());
4059 EXPECT_FALSE(child_->needs_push_properties());
4060 EXPECT_TRUE(child_->descendant_needs_push_properties());
4062 // grandchild3_ does not need a push properties, so recursing should
4063 // no longer be needed.
4064 grandchild2_->RemoveFromParent();
4066 EXPECT_FALSE(root_->needs_push_properties());
4067 EXPECT_FALSE(root_->descendant_needs_push_properties());
4068 EXPECT_FALSE(child_->needs_push_properties());
4069 EXPECT_FALSE(child_->descendant_needs_push_properties());
4070 EndTest();
4071 break;
4076 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
4078 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
4079 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4080 protected:
4081 virtual void DidCommitAndDrawFrame() OVERRIDE {
4082 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4083 switch (last_source_frame_number) {
4084 case 0:
4085 layer_tree_host()->SetRootLayer(root_);
4086 grandchild1_->set_persist_needs_push_properties(true);
4087 grandchild2_->set_persist_needs_push_properties(true);
4088 break;
4089 case 1:
4090 EXPECT_FALSE(root_->needs_push_properties());
4091 EXPECT_TRUE(root_->descendant_needs_push_properties());
4092 EXPECT_FALSE(child_->needs_push_properties());
4093 EXPECT_TRUE(child_->descendant_needs_push_properties());
4094 EXPECT_TRUE(grandchild1_->needs_push_properties());
4095 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4096 EXPECT_TRUE(grandchild2_->needs_push_properties());
4097 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4098 EXPECT_FALSE(grandchild3_->needs_push_properties());
4099 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4101 // grandchild2_ will still need a push properties.
4102 grandchild1_->RemoveFromParent();
4104 EXPECT_FALSE(root_->needs_push_properties());
4105 EXPECT_TRUE(root_->descendant_needs_push_properties());
4106 EXPECT_FALSE(child_->needs_push_properties());
4107 EXPECT_TRUE(child_->descendant_needs_push_properties());
4109 // grandchild3_ does not need a push properties, so recursing should
4110 // no longer be needed.
4111 grandchild2_->RemoveFromParent();
4113 EXPECT_FALSE(root_->needs_push_properties());
4114 EXPECT_FALSE(root_->descendant_needs_push_properties());
4115 EXPECT_FALSE(child_->needs_push_properties());
4116 EXPECT_FALSE(child_->descendant_needs_push_properties());
4117 EndTest();
4118 break;
4123 MULTI_THREAD_TEST_F(
4124 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
4126 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
4127 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4128 protected:
4129 virtual void DidCommitAndDrawFrame() OVERRIDE {
4130 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4131 switch (last_source_frame_number) {
4132 case 0:
4133 layer_tree_host()->SetRootLayer(root_);
4134 break;
4135 case 1:
4136 EXPECT_FALSE(root_->needs_push_properties());
4137 EXPECT_FALSE(root_->descendant_needs_push_properties());
4138 EXPECT_FALSE(child_->needs_push_properties());
4139 EXPECT_FALSE(child_->descendant_needs_push_properties());
4140 EXPECT_FALSE(grandchild1_->needs_push_properties());
4141 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4142 EXPECT_FALSE(grandchild2_->needs_push_properties());
4143 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4144 EXPECT_FALSE(grandchild3_->needs_push_properties());
4145 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4147 // Change grandchildren while their parent is not in the tree.
4148 child_->RemoveFromParent();
4149 grandchild1_->SetPosition(gfx::Point(1, 1));
4150 grandchild2_->SetPosition(gfx::Point(1, 1));
4151 root_->AddChild(child_);
4153 EXPECT_FALSE(root_->needs_push_properties());
4154 EXPECT_TRUE(root_->descendant_needs_push_properties());
4155 EXPECT_TRUE(child_->needs_push_properties());
4156 EXPECT_TRUE(child_->descendant_needs_push_properties());
4157 EXPECT_TRUE(grandchild1_->needs_push_properties());
4158 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4159 EXPECT_TRUE(grandchild2_->needs_push_properties());
4160 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4161 EXPECT_TRUE(grandchild3_->needs_push_properties());
4162 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4164 grandchild1_->RemoveFromParent();
4166 EXPECT_FALSE(root_->needs_push_properties());
4167 EXPECT_TRUE(root_->descendant_needs_push_properties());
4168 EXPECT_TRUE(child_->needs_push_properties());
4169 EXPECT_TRUE(child_->descendant_needs_push_properties());
4171 grandchild2_->RemoveFromParent();
4173 EXPECT_FALSE(root_->needs_push_properties());
4174 EXPECT_TRUE(root_->descendant_needs_push_properties());
4175 EXPECT_TRUE(child_->needs_push_properties());
4176 EXPECT_TRUE(child_->descendant_needs_push_properties());
4178 grandchild3_->RemoveFromParent();
4180 EXPECT_FALSE(root_->needs_push_properties());
4181 EXPECT_TRUE(root_->descendant_needs_push_properties());
4182 EXPECT_TRUE(child_->needs_push_properties());
4183 EXPECT_FALSE(child_->descendant_needs_push_properties());
4185 EndTest();
4186 break;
4191 MULTI_THREAD_TEST_F(
4192 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4194 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4195 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4196 protected:
4197 virtual void DidCommitAndDrawFrame() OVERRIDE {
4198 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4199 switch (last_source_frame_number) {
4200 case 0:
4201 layer_tree_host()->SetRootLayer(root_);
4202 break;
4203 case 1:
4204 EXPECT_FALSE(root_->needs_push_properties());
4205 EXPECT_FALSE(root_->descendant_needs_push_properties());
4206 EXPECT_FALSE(child_->needs_push_properties());
4207 EXPECT_FALSE(child_->descendant_needs_push_properties());
4208 EXPECT_FALSE(grandchild1_->needs_push_properties());
4209 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4210 EXPECT_FALSE(grandchild2_->needs_push_properties());
4211 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4212 EXPECT_FALSE(grandchild3_->needs_push_properties());
4213 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4215 child_->SetPosition(gfx::Point(1, 1));
4216 grandchild1_->SetPosition(gfx::Point(1, 1));
4217 grandchild2_->SetPosition(gfx::Point(1, 1));
4219 EXPECT_FALSE(root_->needs_push_properties());
4220 EXPECT_TRUE(root_->descendant_needs_push_properties());
4221 EXPECT_TRUE(child_->needs_push_properties());
4222 EXPECT_TRUE(child_->descendant_needs_push_properties());
4223 EXPECT_TRUE(grandchild1_->needs_push_properties());
4224 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4225 EXPECT_TRUE(grandchild2_->needs_push_properties());
4226 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4227 EXPECT_FALSE(grandchild3_->needs_push_properties());
4228 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4230 grandchild1_->RemoveFromParent();
4232 EXPECT_FALSE(root_->needs_push_properties());
4233 EXPECT_TRUE(root_->descendant_needs_push_properties());
4234 EXPECT_TRUE(child_->needs_push_properties());
4235 EXPECT_TRUE(child_->descendant_needs_push_properties());
4237 grandchild2_->RemoveFromParent();
4239 EXPECT_FALSE(root_->needs_push_properties());
4240 EXPECT_TRUE(root_->descendant_needs_push_properties());
4241 EXPECT_TRUE(child_->needs_push_properties());
4242 EXPECT_FALSE(child_->descendant_needs_push_properties());
4244 child_->RemoveFromParent();
4246 EXPECT_FALSE(root_->needs_push_properties());
4247 EXPECT_FALSE(root_->descendant_needs_push_properties());
4249 EndTest();
4250 break;
4255 MULTI_THREAD_TEST_F(
4256 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4258 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4259 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4260 protected:
4261 virtual void DidCommitAndDrawFrame() OVERRIDE {
4262 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4263 switch (last_source_frame_number) {
4264 case 0:
4265 layer_tree_host()->SetRootLayer(root_);
4266 break;
4267 case 1:
4268 EXPECT_FALSE(root_->needs_push_properties());
4269 EXPECT_FALSE(root_->descendant_needs_push_properties());
4270 EXPECT_FALSE(child_->needs_push_properties());
4271 EXPECT_FALSE(child_->descendant_needs_push_properties());
4272 EXPECT_FALSE(grandchild1_->needs_push_properties());
4273 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4274 EXPECT_FALSE(grandchild2_->needs_push_properties());
4275 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4276 EXPECT_FALSE(grandchild3_->needs_push_properties());
4277 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4279 grandchild1_->SetPosition(gfx::Point(1, 1));
4280 grandchild2_->SetPosition(gfx::Point(1, 1));
4281 child_->SetPosition(gfx::Point(1, 1));
4283 EXPECT_FALSE(root_->needs_push_properties());
4284 EXPECT_TRUE(root_->descendant_needs_push_properties());
4285 EXPECT_TRUE(child_->needs_push_properties());
4286 EXPECT_TRUE(child_->descendant_needs_push_properties());
4287 EXPECT_TRUE(grandchild1_->needs_push_properties());
4288 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4289 EXPECT_TRUE(grandchild2_->needs_push_properties());
4290 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4291 EXPECT_FALSE(grandchild3_->needs_push_properties());
4292 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4294 grandchild1_->RemoveFromParent();
4296 EXPECT_FALSE(root_->needs_push_properties());
4297 EXPECT_TRUE(root_->descendant_needs_push_properties());
4298 EXPECT_TRUE(child_->needs_push_properties());
4299 EXPECT_TRUE(child_->descendant_needs_push_properties());
4301 grandchild2_->RemoveFromParent();
4303 EXPECT_FALSE(root_->needs_push_properties());
4304 EXPECT_TRUE(root_->descendant_needs_push_properties());
4305 EXPECT_TRUE(child_->needs_push_properties());
4306 EXPECT_FALSE(child_->descendant_needs_push_properties());
4308 child_->RemoveFromParent();
4310 EXPECT_FALSE(root_->needs_push_properties());
4311 EXPECT_FALSE(root_->descendant_needs_push_properties());
4313 EndTest();
4314 break;
4319 MULTI_THREAD_TEST_F(
4320 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4322 // This test verifies that the tree activation callback is invoked correctly.
4323 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4324 public:
4325 LayerTreeHostTestTreeActivationCallback()
4326 : num_commits_(0), callback_count_(0) {}
4328 virtual void BeginTest() OVERRIDE {
4329 EXPECT_TRUE(HasImplThread());
4330 PostSetNeedsCommitToMainThread();
4333 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4334 LayerTreeHostImpl::FrameData* frame_data,
4335 bool result) OVERRIDE {
4336 ++num_commits_;
4337 switch (num_commits_) {
4338 case 1:
4339 EXPECT_EQ(0, callback_count_);
4340 callback_count_ = 0;
4341 SetCallback(true);
4342 PostSetNeedsCommitToMainThread();
4343 break;
4344 case 2:
4345 EXPECT_EQ(1, callback_count_);
4346 callback_count_ = 0;
4347 SetCallback(false);
4348 PostSetNeedsCommitToMainThread();
4349 break;
4350 case 3:
4351 EXPECT_EQ(0, callback_count_);
4352 callback_count_ = 0;
4353 EndTest();
4354 break;
4355 default:
4356 ADD_FAILURE() << num_commits_;
4357 EndTest();
4358 break;
4360 return LayerTreeHostTest::PrepareToDrawOnThread(host_impl, frame_data,
4361 result);
4364 virtual void AfterTest() OVERRIDE {
4365 EXPECT_EQ(3, num_commits_);
4368 void SetCallback(bool enable) {
4369 output_surface()->SetTreeActivationCallback(enable ?
4370 base::Bind(&LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4371 base::Unretained(this)) :
4372 base::Closure());
4375 void ActivationCallback() {
4376 ++callback_count_;
4379 int num_commits_;
4380 int callback_count_;
4383 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4384 RunTest(true, false, true);
4387 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4388 RunTest(true, true, true);
4391 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4392 public:
4393 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4395 virtual void BeginTest() OVERRIDE {
4396 ASSERT_TRUE(!!invalidate_layer_)
4397 << "Derived tests must set this in SetupTree";
4399 // One initial commit.
4400 PostSetNeedsCommitToMainThread();
4403 virtual void DidCommitAndDrawFrame() OVERRIDE {
4404 // After commit, invalidate the layer. This should cause a commit.
4405 if (layer_tree_host()->source_frame_number() == 1)
4406 invalidate_layer_->SetNeedsDisplay();
4409 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4410 num_draws_++;
4411 if (impl->active_tree()->source_frame_number() == 1)
4412 EndTest();
4415 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4416 num_commits_++;
4419 virtual void AfterTest() OVERRIDE {
4420 EXPECT_GE(2, num_commits_);
4421 EXPECT_GE(2, num_draws_);
4424 protected:
4425 scoped_refptr<Layer> invalidate_layer_;
4427 private:
4428 int num_commits_;
4429 int num_draws_;
4432 // VideoLayer must support being invalidated and then passing that along
4433 // to the compositor thread, even though no resources are updated in
4434 // response to that invalidation.
4435 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4436 public:
4437 virtual void SetupTree() OVERRIDE {
4438 LayerTreeHostTest::SetupTree();
4439 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
4440 video_layer->SetBounds(gfx::Size(10, 10));
4441 video_layer->SetIsDrawable(true);
4442 layer_tree_host()->root_layer()->AddChild(video_layer);
4444 invalidate_layer_ = video_layer;
4447 private:
4448 FakeVideoFrameProvider provider_;
4451 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4453 // IOSurfaceLayer must support being invalidated and then passing that along
4454 // to the compositor thread, even though no resources are updated in
4455 // response to that invalidation.
4456 class LayerTreeHostTestIOSurfaceLayerInvalidate
4457 : public LayerInvalidateCausesDraw {
4458 public:
4459 virtual void SetupTree() OVERRIDE {
4460 LayerTreeHostTest::SetupTree();
4461 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4462 layer->SetBounds(gfx::Size(10, 10));
4463 uint32_t fake_io_surface_id = 7;
4464 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4465 layer->SetIsDrawable(true);
4466 layer_tree_host()->root_layer()->AddChild(layer);
4468 invalidate_layer_ = layer;
4472 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4473 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4474 LayerTreeHostTestIOSurfaceLayerInvalidate);
4476 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4477 protected:
4478 virtual void SetupTree() OVERRIDE {
4479 root_layer_ = Layer::Create();
4480 root_layer_->SetAnchorPoint(gfx::PointF());
4481 root_layer_->SetPosition(gfx::Point());
4482 root_layer_->SetBounds(gfx::Size(10, 10));
4484 parent_layer_ = SolidColorLayer::Create();
4485 parent_layer_->SetAnchorPoint(gfx::PointF());
4486 parent_layer_->SetPosition(gfx::Point());
4487 parent_layer_->SetBounds(gfx::Size(10, 10));
4488 parent_layer_->SetIsDrawable(true);
4489 root_layer_->AddChild(parent_layer_);
4491 child_layer_ = SolidColorLayer::Create();
4492 child_layer_->SetAnchorPoint(gfx::PointF());
4493 child_layer_->SetPosition(gfx::Point());
4494 child_layer_->SetBounds(gfx::Size(10, 10));
4495 child_layer_->SetIsDrawable(true);
4496 parent_layer_->AddChild(child_layer_);
4498 layer_tree_host()->SetRootLayer(root_layer_);
4499 LayerTreeHostTest::SetupTree();
4502 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4504 virtual void DidCommitAndDrawFrame() OVERRIDE {
4505 switch (layer_tree_host()->source_frame_number()) {
4506 case 1:
4507 // The layer type used does not need to push properties every frame.
4508 EXPECT_FALSE(child_layer_->needs_push_properties());
4510 // Change the bounds of the child layer, but make it skipped
4511 // by CalculateDrawProperties.
4512 parent_layer_->SetOpacity(0.f);
4513 child_layer_->SetBounds(gfx::Size(5, 5));
4514 break;
4515 case 2:
4516 // The bounds of the child layer were pushed to the impl side.
4517 EXPECT_FALSE(child_layer_->needs_push_properties());
4519 EndTest();
4520 break;
4524 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4525 LayerImpl* root = impl->active_tree()->root_layer();
4526 LayerImpl* parent = root->children()[0];
4527 LayerImpl* child = parent->children()[0];
4529 switch (impl->active_tree()->source_frame_number()) {
4530 case 1:
4531 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4532 break;
4536 virtual void AfterTest() OVERRIDE {}
4538 scoped_refptr<Layer> root_layer_;
4539 scoped_refptr<SolidColorLayer> parent_layer_;
4540 scoped_refptr<SolidColorLayer> child_layer_;
4543 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4545 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4546 protected:
4547 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4548 settings->impl_side_painting = true;
4551 virtual void SetupTree() OVERRIDE {
4552 root_layer_ = FakePictureLayer::Create(&client_);
4553 root_layer_->SetAnchorPoint(gfx::PointF());
4554 root_layer_->SetBounds(gfx::Size(10, 10));
4556 layer_tree_host()->SetRootLayer(root_layer_);
4557 LayerTreeHostTest::SetupTree();
4560 virtual void BeginTest() OVERRIDE {
4561 // The viewport is empty, but we still need to update layers on the main
4562 // thread.
4563 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4564 PostSetNeedsCommitToMainThread();
4567 virtual void DidCommit() OVERRIDE {
4568 // The layer should be updated even though the viewport is empty, so we
4569 // are capable of drawing it on the impl tree.
4570 EXPECT_GT(root_layer_->update_count(), 0u);
4571 EndTest();
4574 virtual void AfterTest() OVERRIDE {}
4576 FakeContentLayerClient client_;
4577 scoped_refptr<FakePictureLayer> root_layer_;
4580 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4582 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4583 public:
4584 LayerTreeHostTestAbortEvictedTextures()
4585 : num_will_begin_frames_(0), num_impl_commits_(0) {}
4587 protected:
4588 virtual void SetupTree() OVERRIDE {
4589 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4590 root_layer->SetBounds(gfx::Size(200, 200));
4591 root_layer->SetIsDrawable(true);
4593 layer_tree_host()->SetRootLayer(root_layer);
4594 LayerTreeHostTest::SetupTree();
4597 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4599 virtual void WillBeginFrame() OVERRIDE {
4600 num_will_begin_frames_++;
4601 switch (num_will_begin_frames_) {
4602 case 2:
4603 // Send a redraw to the compositor thread. This will (wrongly) be
4604 // ignored unless aborting resets the texture state.
4605 layer_tree_host()->SetNeedsRedraw();
4606 break;
4610 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4611 num_impl_commits_++;
4614 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4615 switch (impl->SourceAnimationFrameNumber()) {
4616 case 1:
4617 // Prevent draws until commit.
4618 impl->active_tree()->SetContentsTexturesPurged();
4619 EXPECT_FALSE(impl->CanDraw());
4620 // Trigger an abortable commit.
4621 impl->SetNeedsCommit();
4622 break;
4623 case 2:
4624 EndTest();
4625 break;
4629 virtual void AfterTest() OVERRIDE {
4630 // Ensure that the commit was truly aborted.
4631 EXPECT_EQ(2, num_will_begin_frames_);
4632 EXPECT_EQ(1, num_impl_commits_);
4635 private:
4636 int num_will_begin_frames_;
4637 int num_impl_commits_;
4640 // Commits can only be aborted when using the thread proxy.
4641 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4643 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4644 protected:
4645 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4646 settings->impl_side_painting = true;
4649 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
4650 OVERRIDE {
4651 scoped_refptr<TestContextProvider> context_provider =
4652 TestContextProvider::Create();
4653 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
4654 return FakeOutputSurface::Create3d(context_provider)
4655 .PassAs<OutputSurface>();
4658 virtual void SetupTree() OVERRIDE {
4659 scoped_refptr<FakePictureLayer> root_layer =
4660 FakePictureLayer::Create(&client_);
4661 root_layer->SetBounds(gfx::Size(6000, 6000));
4662 root_layer->SetIsDrawable(true);
4664 layer_tree_host()->SetRootLayer(root_layer);
4665 LayerTreeHostTest::SetupTree();
4668 virtual void BeginTest() OVERRIDE {
4669 PostSetNeedsCommitToMainThread();
4672 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4673 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
4674 impl->output_surface()->context_provider()->Context3d());
4676 // Expect that the transfer buffer memory used is equal to the
4677 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4678 EXPECT_EQ(1024 * 1024u,
4679 context->GetTransferBufferMemoryUsedBytes());
4680 EndTest();
4683 virtual void AfterTest() OVERRIDE {}
4685 private:
4686 FakeContentLayerClient client_;
4689 // Impl-side painting is a multi-threaded compositor feature.
4690 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4692 } // namespace
4694 } // namespace cc