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.
4
5 #include "cc/trees/layer_tree_host.h"
6
7 #include <algorithm>
8
9 #include "base/auto_reset.h"
10 #include "base/synchronization/lock.h"
11 #include "cc/animation/timing_function.h"
12 #include "cc/base/swap_promise.h"
13 #include "cc/debug/frame_rate_counter.h"
14 #include "cc/layers/content_layer.h"
15 #include "cc/layers/content_layer_client.h"
16 #include "cc/layers/io_surface_layer.h"
17 #include "cc/layers/layer_impl.h"
18 #include "cc/layers/painted_scrollbar_layer.h"
19 #include "cc/layers/picture_layer.h"
20 #include "cc/layers/solid_color_layer.h"
21 #include "cc/layers/video_layer.h"
22 #include "cc/output/begin_frame_args.h"
23 #include "cc/output/compositor_frame_ack.h"
24 #include "cc/output/copy_output_request.h"
25 #include "cc/output/copy_output_result.h"
26 #include "cc/output/output_surface.h"
27 #include "cc/quads/draw_quad.h"
28 #include "cc/quads/io_surface_draw_quad.h"
29 #include "cc/resources/prioritized_resource.h"
30 #include "cc/resources/prioritized_resource_manager.h"
31 #include "cc/resources/resource_update_queue.h"
32 #include "cc/test/fake_content_layer.h"
33 #include "cc/test/fake_content_layer_client.h"
34 #include "cc/test/fake_content_layer_impl.h"
35 #include "cc/test/fake_layer_tree_host_client.h"
36 #include "cc/test/fake_output_surface.h"
37 #include "cc/test/fake_painted_scrollbar_layer.h"
38 #include "cc/test/fake_picture_layer.h"
39 #include "cc/test/fake_picture_layer_impl.h"
40 #include "cc/test/fake_proxy.h"
41 #include "cc/test/fake_scoped_ui_resource.h"
42 #include "cc/test/fake_video_frame_provider.h"
43 #include "cc/test/geometry_test_utils.h"
44 #include "cc/test/layer_tree_test.h"
45 #include "cc/test/test_shared_bitmap_manager.h"
46 #include "cc/test/test_web_graphics_context_3d.h"
47 #include "cc/trees/layer_tree_host_impl.h"
48 #include "cc/trees/layer_tree_impl.h"
49 #include "cc/trees/single_thread_proxy.h"
50 #include "cc/trees/thread_proxy.h"
51 #include "gpu/GLES2/gl2extchromium.h"
52 #include "skia/ext/refptr.h"
53 #include "testing/gmock/include/gmock/gmock.h"
54 #include "third_party/khronos/GLES2/gl2.h"
55 #include "third_party/khronos/GLES2/gl2ext.h"
56 #include "third_party/skia/include/core/SkPicture.h"
57 #include "ui/gfx/frame_time.h"
58 #include "ui/gfx/point_conversions.h"
59 #include "ui/gfx/size_conversions.h"
60 #include "ui/gfx/vector2d_conversions.h"
61
62 using testing::_;
63 using testing::AnyNumber;
64 using testing::AtLeast;
65 using testing::Mock;
66
67 namespace cc {
68 namespace {
69
70 class LayerTreeHostTest : public LayerTreeTest {};
71
72 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
73 // draw with frame 0.
74 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
75 public:
LayerTreeHostTestSetNeedsCommit1()76 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
77
BeginTest()78 virtual void BeginTest() OVERRIDE {
79 PostSetNeedsCommitToMainThread();
80 PostSetNeedsCommitToMainThread();
81 }
82
DrawLayersOnThread(LayerTreeHostImpl * impl)83 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
84 num_draws_++;
85 if (!impl->active_tree()->source_frame_number())
86 EndTest();
87 }
88
CommitCompleteOnThread(LayerTreeHostImpl * impl)89 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
90 num_commits_++;
91 }
92
AfterTest()93 virtual void AfterTest() OVERRIDE {
94 EXPECT_LE(1, num_commits_);
95 EXPECT_LE(1, num_draws_);
96 }
97
98 private:
99 int num_commits_;
100 int num_draws_;
101 };
102
103 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
104
105 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
106 // first committed frame draws should lead to another commit.
107 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
108 public:
LayerTreeHostTestSetNeedsCommit2()109 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
110
BeginTest()111 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
112
DrawLayersOnThread(LayerTreeHostImpl * impl)113 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
114 ++num_draws_;
115 }
116
CommitCompleteOnThread(LayerTreeHostImpl * impl)117 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
118 ++num_commits_;
119 switch (num_commits_) {
120 case 1:
121 PostSetNeedsCommitToMainThread();
122 break;
123 case 2:
124 EndTest();
125 break;
126 default:
127 NOTREACHED();
128 }
129 }
130
AfterTest()131 virtual void AfterTest() OVERRIDE {
132 EXPECT_EQ(2, num_commits_);
133 EXPECT_LE(1, num_draws_);
134 }
135
136 private:
137 int num_commits_;
138 int num_draws_;
139 };
140
141 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
142
143 // Verify that we pass property values in PushPropertiesTo.
144 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
145 protected:
SetupTree()146 virtual void SetupTree() OVERRIDE {
147 scoped_refptr<Layer> root = Layer::Create();
148 root->SetBounds(gfx::Size(10, 10));
149 layer_tree_host()->SetRootLayer(root);
150 LayerTreeHostTest::SetupTree();
151 }
152
153 enum Properties {
154 STARTUP,
155 BOUNDS,
156 HIDE_LAYER_AND_SUBTREE,
157 DRAWS_CONTENT,
158 DONE,
159 };
160
BeginTest()161 virtual void BeginTest() OVERRIDE {
162 index_ = STARTUP;
163 PostSetNeedsCommitToMainThread();
164 }
165
DrawLayersOnThread(LayerTreeHostImpl * impl)166 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
167 VerifyAfterValues(impl->active_tree()->root_layer());
168 }
169
DidCommitAndDrawFrame()170 virtual void DidCommitAndDrawFrame() OVERRIDE {
171 SetBeforeValues(layer_tree_host()->root_layer());
172 VerifyBeforeValues(layer_tree_host()->root_layer());
173
174 ++index_;
175 if (index_ == DONE) {
176 EndTest();
177 return;
178 }
179
180 SetAfterValues(layer_tree_host()->root_layer());
181 }
182
AfterTest()183 virtual void AfterTest() OVERRIDE {}
184
VerifyBeforeValues(Layer * layer)185 void VerifyBeforeValues(Layer* layer) {
186 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
187 EXPECT_FALSE(layer->hide_layer_and_subtree());
188 EXPECT_FALSE(layer->DrawsContent());
189 }
190
SetBeforeValues(Layer * layer)191 void SetBeforeValues(Layer* layer) {
192 layer->SetBounds(gfx::Size(10, 10));
193 layer->SetHideLayerAndSubtree(false);
194 layer->SetIsDrawable(false);
195 }
196
VerifyAfterValues(LayerImpl * layer)197 void VerifyAfterValues(LayerImpl* layer) {
198 switch (static_cast<Properties>(index_)) {
199 case STARTUP:
200 case DONE:
201 break;
202 case BOUNDS:
203 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
204 break;
205 case HIDE_LAYER_AND_SUBTREE:
206 EXPECT_TRUE(layer->hide_layer_and_subtree());
207 break;
208 case DRAWS_CONTENT:
209 EXPECT_TRUE(layer->DrawsContent());
210 break;
211 }
212 }
213
SetAfterValues(Layer * layer)214 void SetAfterValues(Layer* layer) {
215 switch (static_cast<Properties>(index_)) {
216 case STARTUP:
217 case DONE:
218 break;
219 case BOUNDS:
220 layer->SetBounds(gfx::Size(20, 20));
221 break;
222 case HIDE_LAYER_AND_SUBTREE:
223 layer->SetHideLayerAndSubtree(true);
224 break;
225 case DRAWS_CONTENT:
226 layer->SetIsDrawable(true);
227 break;
228 }
229 }
230
231 int index_;
232 };
233
234 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
235
236 // 1 setNeedsRedraw after the first commit has completed should lead to 1
237 // additional draw.
238 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
239 public:
LayerTreeHostTestSetNeedsRedraw()240 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
241
BeginTest()242 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
243
DrawLayersOnThread(LayerTreeHostImpl * impl)244 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
245 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
246 if (!num_draws_) {
247 // Redraw again to verify that the second redraw doesn't commit.
248 PostSetNeedsRedrawToMainThread();
249 } else {
250 EndTest();
251 }
252 num_draws_++;
253 }
254
CommitCompleteOnThread(LayerTreeHostImpl * impl)255 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
256 EXPECT_EQ(0, num_draws_);
257 num_commits_++;
258 }
259
AfterTest()260 virtual void AfterTest() OVERRIDE {
261 EXPECT_GE(2, num_draws_);
262 EXPECT_EQ(1, num_commits_);
263 }
264
265 private:
266 int num_commits_;
267 int num_draws_;
268 };
269
270 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
271
272 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
273 // must contain invalid_rect.
274 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
275 public:
LayerTreeHostTestSetNeedsRedrawRect()276 LayerTreeHostTestSetNeedsRedrawRect()
277 : num_draws_(0),
278 bounds_(50, 50),
279 invalid_rect_(10, 10, 20, 20),
280 root_layer_(ContentLayer::Create(&client_)) {}
281
BeginTest()282 virtual void BeginTest() OVERRIDE {
283 root_layer_->SetIsDrawable(true);
284 root_layer_->SetBounds(bounds_);
285 layer_tree_host()->SetRootLayer(root_layer_);
286 layer_tree_host()->SetViewportSize(bounds_);
287 PostSetNeedsCommitToMainThread();
288 }
289
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)290 virtual DrawResult PrepareToDrawOnThread(
291 LayerTreeHostImpl* host_impl,
292 LayerTreeHostImpl::FrameData* frame_data,
293 DrawResult draw_result) OVERRIDE {
294 EXPECT_EQ(DRAW_SUCCESS, draw_result);
295
296 gfx::RectF root_damage_rect;
297 if (!frame_data->render_passes.empty())
298 root_damage_rect = frame_data->render_passes.back()->damage_rect;
299
300 if (!num_draws_) {
301 // If this is the first frame, expect full frame damage.
302 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
303 } else {
304 // Check that invalid_rect_ is indeed repainted.
305 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
306 }
307
308 return draw_result;
309 }
310
DrawLayersOnThread(LayerTreeHostImpl * impl)311 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
312 if (!num_draws_) {
313 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
314 } else {
315 EndTest();
316 }
317 num_draws_++;
318 }
319
AfterTest()320 virtual void AfterTest() OVERRIDE { EXPECT_EQ(2, num_draws_); }
321
322 private:
323 int num_draws_;
324 const gfx::Size bounds_;
325 const gfx::Rect invalid_rect_;
326 FakeContentLayerClient client_;
327 scoped_refptr<ContentLayer> root_layer_;
328 };
329
330 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
331
332 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
333 public:
InitializeSettings(LayerTreeSettings * settings)334 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
335 settings->layer_transforms_should_scale_layer_contents = true;
336 }
337
SetupTree()338 virtual void SetupTree() OVERRIDE {
339 root_layer_ = Layer::Create();
340 root_layer_->SetBounds(gfx::Size(10, 20));
341
342 scaled_layer_ = FakeContentLayer::Create(&client_);
343 scaled_layer_->SetBounds(gfx::Size(1, 1));
344 root_layer_->AddChild(scaled_layer_);
345
346 layer_tree_host()->SetRootLayer(root_layer_);
347 LayerTreeHostTest::SetupTree();
348 }
349
BeginTest()350 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
351
DrawLayersOnThread(LayerTreeHostImpl * host_impl)352 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
353 if (host_impl->active_tree()->source_frame_number() == 1)
354 EndTest();
355 }
356
DidCommit()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());
368 }
369 }
370
AfterTest()371 virtual void AfterTest() OVERRIDE {
372 EXPECT_EQ(gfx::Size(4, 4).ToString(),
373 scaled_layer_->content_bounds().ToString());
374 }
375
376 private:
377 FakeContentLayerClient client_;
378 scoped_refptr<Layer> root_layer_;
379 scoped_refptr<FakeContentLayer> scaled_layer_;
380 };
381
382 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
383
384 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
385 : public LayerTreeHostTest {
386 public:
InitializeSettings(LayerTreeSettings * settings)387 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
388 settings->layer_transforms_should_scale_layer_contents = true;
389 }
390
SetupTree()391 virtual void SetupTree() OVERRIDE {
392 root_layer_ = Layer::Create();
393 root_layer_->SetBounds(gfx::Size(10, 20));
394
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));
401
402 root_layer_->AddChild(scrollbar_);
403
404 layer_tree_host()->SetRootLayer(root_layer_);
405 LayerTreeHostTest::SetupTree();
406 }
407
BeginTest()408 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
409
DrawLayersOnThread(LayerTreeHostImpl * host_impl)410 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
411 if (host_impl->active_tree()->source_frame_number() == 1)
412 EndTest();
413 }
414
DidCommit()415 virtual void DidCommit() OVERRIDE {
416 switch (layer_tree_host()->source_frame_number()) {
417 case 1:
418 // Changing the device scale factor causes a commit. It also changes
419 // the content bounds of |scrollbar_|, which should not generate
420 // a second commit as a result.
421 layer_tree_host()->SetDeviceScaleFactor(4.f);
422 break;
423 default:
424 // No extra commits.
425 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
426 }
427 }
428
AfterTest()429 virtual void AfterTest() OVERRIDE {
430 EXPECT_EQ(gfx::Size(40, 40).ToString(),
431 scrollbar_->content_bounds().ToString());
432 }
433
434 private:
435 FakeContentLayerClient client_;
436 scoped_refptr<Layer> root_layer_;
437 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
438 };
439
440 SINGLE_AND_MULTI_THREAD_TEST_F(
441 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
442
443 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
444 public:
LayerTreeHostTestSetNextCommitForcesRedraw()445 LayerTreeHostTestSetNextCommitForcesRedraw()
446 : num_draws_(0),
447 bounds_(50, 50),
448 invalid_rect_(10, 10, 20, 20),
449 root_layer_(ContentLayer::Create(&client_)) {}
450
BeginTest()451 virtual void BeginTest() OVERRIDE {
452 root_layer_->SetIsDrawable(true);
453 root_layer_->SetBounds(bounds_);
454 layer_tree_host()->SetRootLayer(root_layer_);
455 layer_tree_host()->SetViewportSize(bounds_);
456 PostSetNeedsCommitToMainThread();
457 }
458
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)459 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
460 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
461 host_impl->SetNeedsRedrawRect(invalid_rect_);
462 }
463
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)464 virtual DrawResult PrepareToDrawOnThread(
465 LayerTreeHostImpl* host_impl,
466 LayerTreeHostImpl::FrameData* frame_data,
467 DrawResult draw_result) OVERRIDE {
468 EXPECT_EQ(DRAW_SUCCESS, draw_result);
469
470 gfx::RectF root_damage_rect;
471 if (!frame_data->render_passes.empty())
472 root_damage_rect = frame_data->render_passes.back()->damage_rect;
473
474 switch (num_draws_) {
475 case 0:
476 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
477 break;
478 case 1:
479 case 2:
480 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
481 break;
482 case 3:
483 EXPECT_RECT_EQ(invalid_rect_, root_damage_rect);
484 break;
485 case 4:
486 EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
487 break;
488 default:
489 NOTREACHED();
490 }
491
492 return draw_result;
493 }
494
DrawLayersOnThread(LayerTreeHostImpl * host_impl)495 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
496 switch (num_draws_) {
497 case 0:
498 case 1:
499 // Cycle through a couple of empty commits to ensure we're observing the
500 // right behavior
501 PostSetNeedsCommitToMainThread();
502 break;
503 case 2:
504 // Should force full frame damage on the next commit
505 PostSetNextCommitForcesRedrawToMainThread();
506 PostSetNeedsCommitToMainThread();
507 if (host_impl->settings().impl_side_painting)
508 host_impl->BlockNotifyReadyToActivateForTesting(true);
509 else
510 num_draws_++;
511 break;
512 case 3:
513 host_impl->BlockNotifyReadyToActivateForTesting(false);
514 break;
515 default:
516 EndTest();
517 break;
518 }
519 num_draws_++;
520 }
521
AfterTest()522 virtual void AfterTest() OVERRIDE { EXPECT_EQ(5, num_draws_); }
523
524 private:
525 int num_draws_;
526 const gfx::Size bounds_;
527 const gfx::Rect invalid_rect_;
528 FakeContentLayerClient client_;
529 scoped_refptr<ContentLayer> root_layer_;
530 };
531
532 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw);
533
534 // Tests that if a layer is not drawn because of some reason in the parent then
535 // its damage is preserved until the next time it is drawn.
536 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
537 public:
LayerTreeHostTestUndrawnLayersDamageLater()538 LayerTreeHostTestUndrawnLayersDamageLater()
539 : root_layer_(ContentLayer::Create(&client_)) {}
540
SetupTree()541 virtual void SetupTree() OVERRIDE {
542 root_layer_->SetIsDrawable(true);
543 root_layer_->SetBounds(gfx::Size(50, 50));
544 layer_tree_host()->SetRootLayer(root_layer_);
545
546 // The initially transparent layer has a larger child layer, which is
547 // not initially drawn because of the this (parent) layer.
548 parent_layer_ = FakeContentLayer::Create(&client_);
549 parent_layer_->SetBounds(gfx::Size(15, 15));
550 parent_layer_->SetOpacity(0.0f);
551 root_layer_->AddChild(parent_layer_);
552
553 child_layer_ = FakeContentLayer::Create(&client_);
554 child_layer_->SetBounds(gfx::Size(25, 25));
555 parent_layer_->AddChild(child_layer_);
556
557 LayerTreeHostTest::SetupTree();
558 }
559
BeginTest()560 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
561
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)562 virtual DrawResult PrepareToDrawOnThread(
563 LayerTreeHostImpl* host_impl,
564 LayerTreeHostImpl::FrameData* frame_data,
565 DrawResult draw_result) OVERRIDE {
566 EXPECT_EQ(DRAW_SUCCESS, draw_result);
567
568 gfx::RectF root_damage_rect;
569 if (!frame_data->render_passes.empty())
570 root_damage_rect = frame_data->render_passes.back()->damage_rect;
571
572 // The first time, the whole view needs be drawn.
573 // Afterwards, just the opacity of surface_layer1 is changed a few times,
574 // and each damage should be the bounding box of it and its child. If this
575 // was working improperly, the damage might not include its childs bounding
576 // box.
577 switch (host_impl->active_tree()->source_frame_number()) {
578 case 0:
579 EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
580 break;
581 case 1:
582 case 2:
583 case 3:
584 EXPECT_RECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
585 break;
586 default:
587 NOTREACHED();
588 }
589
590 return draw_result;
591 }
592
DidCommitAndDrawFrame()593 virtual void DidCommitAndDrawFrame() OVERRIDE {
594 switch (layer_tree_host()->source_frame_number()) {
595 case 1:
596 // Test not owning the surface.
597 parent_layer_->SetOpacity(1.0f);
598 break;
599 case 2:
600 parent_layer_->SetOpacity(0.0f);
601 break;
602 case 3:
603 // Test owning the surface.
604 parent_layer_->SetOpacity(0.5f);
605 parent_layer_->SetForceRenderSurface(true);
606 break;
607 case 4:
608 EndTest();
609 break;
610 default:
611 NOTREACHED();
612 }
613 }
614
AfterTest()615 virtual void AfterTest() OVERRIDE {}
616
617 private:
618 FakeContentLayerClient client_;
619 scoped_refptr<ContentLayer> root_layer_;
620 scoped_refptr<FakeContentLayer> parent_layer_;
621 scoped_refptr<FakeContentLayer> child_layer_;
622 };
623
624 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
625
626 // Tests that if a layer is not drawn because of some reason in the parent,
627 // causing its content bounds to not be computed, then when it is later drawn,
628 // its content bounds get pushed.
629 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
630 : public LayerTreeHostTest {
631 public:
LayerTreeHostTestUndrawnLayersPushContentBoundsLater()632 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
633 : root_layer_(Layer::Create()) {}
634
SetupTree()635 virtual void SetupTree() OVERRIDE {
636 root_layer_->SetIsDrawable(true);
637 root_layer_->SetBounds(gfx::Size(20, 20));
638 layer_tree_host()->SetRootLayer(root_layer_);
639
640 parent_layer_ = Layer::Create();
641 parent_layer_->SetBounds(gfx::Size(20, 20));
642 parent_layer_->SetOpacity(0.0f);
643 root_layer_->AddChild(parent_layer_);
644
645 child_layer_ = Layer::Create();
646 child_layer_->SetBounds(gfx::Size(15, 15));
647 parent_layer_->AddChild(child_layer_);
648
649 LayerTreeHostTest::SetupTree();
650 }
651
BeginTest()652 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
653
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)654 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
655 LayerImpl* root = host_impl->active_tree()->root_layer();
656 LayerImpl* parent = root->children()[0];
657 LayerImpl* child = parent->children()[0];
658
659 switch (host_impl->active_tree()->source_frame_number()) {
660 case 0:
661 EXPECT_EQ(0.f, parent->opacity());
662 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
663 break;
664 case 1:
665 EXPECT_EQ(1.f, parent->opacity());
666 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
667 EndTest();
668 break;
669 default:
670 NOTREACHED();
671 }
672 }
673
DidCommit()674 virtual void DidCommit() OVERRIDE {
675 switch (layer_tree_host()->source_frame_number()) {
676 case 1:
677 parent_layer_->SetOpacity(1.0f);
678 break;
679 case 2:
680 break;
681 default:
682 NOTREACHED();
683 }
684 }
685
AfterTest()686 virtual void AfterTest() OVERRIDE {}
687
688 private:
689 scoped_refptr<Layer> root_layer_;
690 scoped_refptr<Layer> parent_layer_;
691 scoped_refptr<Layer> child_layer_;
692 };
693
694 SINGLE_AND_MULTI_THREAD_TEST_F(
695 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
696
697 // This test verifies that properties on the layer tree host are commited
698 // to the impl side.
699 class LayerTreeHostTestCommit : public LayerTreeHostTest {
700 public:
LayerTreeHostTestCommit()701 LayerTreeHostTestCommit() {}
702
BeginTest()703 virtual void BeginTest() OVERRIDE {
704 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
705 layer_tree_host()->set_background_color(SK_ColorGRAY);
706
707 PostSetNeedsCommitToMainThread();
708 }
709
DidActivateTreeOnThread(LayerTreeHostImpl * impl)710 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
711 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
712 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
713
714 EndTest();
715 }
716
AfterTest()717 virtual void AfterTest() OVERRIDE {}
718 };
719
720 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
721
722 // This test verifies that LayerTreeHostImpl's current frame time gets
723 // updated in consecutive frames when it doesn't draw due to tree
724 // activation failure.
725 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
726 : public LayerTreeHostTest {
727 public:
LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()728 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
729 : frame_count_with_pending_tree_(0) {}
730
BeginTest()731 virtual void BeginTest() OVERRIDE {
732 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
733 layer_tree_host()->set_background_color(SK_ColorGRAY);
734
735 PostSetNeedsCommitToMainThread();
736 }
737
BeginCommitOnThread(LayerTreeHostImpl * impl)738 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
739 EXPECT_EQ(frame_count_with_pending_tree_, 0);
740 impl->BlockNotifyReadyToActivateForTesting(true);
741 }
742
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const BeginFrameArgs & args)743 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
744 const BeginFrameArgs& args) OVERRIDE {
745 if (impl->pending_tree())
746 frame_count_with_pending_tree_++;
747
748 if (frame_count_with_pending_tree_ == 1) {
749 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
750 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
751 } else if (frame_count_with_pending_tree_ == 2) {
752 impl->BlockNotifyReadyToActivateForTesting(false);
753 }
754 }
755
DrawLayersOnThread(LayerTreeHostImpl * impl)756 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
757 if (frame_count_with_pending_tree_ > 1) {
758 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
759 EXPECT_NE(first_frame_time_.ToInternalValue(),
760 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
761 EndTest();
762 return;
763 }
764
765 EXPECT_FALSE(impl->settings().impl_side_painting);
766 EndTest();
767 }
DidActivateTreeOnThread(LayerTreeHostImpl * impl)768 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
769 if (impl->settings().impl_side_painting)
770 EXPECT_NE(frame_count_with_pending_tree_, 1);
771 }
772
AfterTest()773 virtual void AfterTest() OVERRIDE {}
774
775 private:
776 int frame_count_with_pending_tree_;
777 base::TimeTicks first_frame_time_;
778 };
779
780 SINGLE_AND_MULTI_THREAD_TEST_F(
781 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
782
783 // This test verifies that LayerTreeHostImpl's current frame time gets
784 // updated in consecutive frames when it draws in each frame.
785 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
786 public:
LayerTreeHostTestFrameTimeUpdatesAfterDraw()787 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
788
BeginTest()789 virtual void BeginTest() OVERRIDE {
790 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
791 layer_tree_host()->set_background_color(SK_ColorGRAY);
792
793 PostSetNeedsCommitToMainThread();
794 }
795
DrawLayersOnThread(LayerTreeHostImpl * impl)796 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
797 frame_++;
798 if (frame_ == 1) {
799 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
800 impl->SetNeedsRedraw();
801
802 // Since we might use a low-resolution clock on Windows, we need to
803 // make sure that the clock has incremented past first_frame_time_.
804 while (first_frame_time_ == gfx::FrameTime::Now()) {
805 }
806
807 return;
808 }
809
810 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
811 EndTest();
812 }
813
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)814 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
815 // Ensure there isn't a commit between the two draws, to ensure that a
816 // commit isn't required for updating the current frame time. We can
817 // only check for this in the multi-threaded case, since in the single-
818 // threaded case there will always be a commit between consecutive draws.
819 if (HasImplThread())
820 EXPECT_EQ(0, frame_);
821 }
822
AfterTest()823 virtual void AfterTest() OVERRIDE {}
824
825 private:
826 int frame_;
827 base::TimeTicks first_frame_time_;
828 };
829
830 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
831
832 // Verifies that StartPageScaleAnimation events propagate correctly
833 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
834 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
835 public:
LayerTreeHostTestStartPageScaleAnimation()836 LayerTreeHostTestStartPageScaleAnimation() {}
837
SetupTree()838 virtual void SetupTree() OVERRIDE {
839 LayerTreeHostTest::SetupTree();
840
841 if (layer_tree_host()->settings().impl_side_painting) {
842 scoped_refptr<FakePictureLayer> layer =
843 FakePictureLayer::Create(&client_);
844 layer->set_always_update_resources(true);
845 scroll_layer_ = layer;
846 } else {
847 scroll_layer_ = FakeContentLayer::Create(&client_);
848 }
849
850 Layer* root_layer = layer_tree_host()->root_layer();
851 scroll_layer_->SetScrollClipLayerId(root_layer->id());
852 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
853 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
854 2 * root_layer->bounds().height()));
855 scroll_layer_->SetScrollOffset(gfx::Vector2d());
856 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
857 // This test requires the page_scale and inner viewport layers to be
858 // identified.
859 layer_tree_host()->RegisterViewportLayers(
860 root_layer, scroll_layer_.get(), NULL);
861 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
862 }
863
BeginTest()864 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
865
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float scale,float)866 virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
867 float scale,
868 float) OVERRIDE {
869 gfx::Vector2d offset = scroll_layer_->scroll_offset();
870 scroll_layer_->SetScrollOffset(offset + scroll_delta);
871 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
872 }
873
DidActivateTreeOnThread(LayerTreeHostImpl * impl)874 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
875 // We get one commit before the first draw, and the animation doesn't happen
876 // until the second draw.
877 switch (impl->active_tree()->source_frame_number()) {
878 case 0:
879 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
880 // We'll start an animation when we get back to the main thread.
881 break;
882 case 1:
883 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
884 break;
885 case 2:
886 EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
887 EndTest();
888 break;
889 default:
890 NOTREACHED();
891 }
892 }
893
DidCommitAndDrawFrame()894 virtual void DidCommitAndDrawFrame() OVERRIDE {
895 switch (layer_tree_host()->source_frame_number()) {
896 case 1:
897 layer_tree_host()->StartPageScaleAnimation(
898 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
899 break;
900 }
901 }
902
AfterTest()903 virtual void AfterTest() OVERRIDE {}
904
905 FakeContentLayerClient client_;
906 scoped_refptr<Layer> scroll_layer_;
907 };
908
909 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
910
911 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
912 public:
LayerTreeHostTestSetVisible()913 LayerTreeHostTestSetVisible() : num_draws_(0) {}
914
BeginTest()915 virtual void BeginTest() OVERRIDE {
916 PostSetNeedsCommitToMainThread();
917 PostSetVisibleToMainThread(false);
918 // This is suppressed while we're invisible.
919 PostSetNeedsRedrawToMainThread();
920 // Triggers the redraw.
921 PostSetVisibleToMainThread(true);
922 }
923
DrawLayersOnThread(LayerTreeHostImpl * impl)924 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
925 EXPECT_TRUE(impl->visible());
926 ++num_draws_;
927 EndTest();
928 }
929
AfterTest()930 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
931
932 private:
933 int num_draws_;
934 };
935
936 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
937
938 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
939 public:
TestOpacityChangeLayerDelegate()940 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
941
SetTestLayer(Layer * test_layer)942 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
943
PaintContents(SkCanvas * canvas,const gfx::Rect & clip,ContentLayerClient::GraphicsContextStatus gc_status)944 virtual void PaintContents(
945 SkCanvas* canvas,
946 const gfx::Rect& clip,
947 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
948 // Set layer opacity to 0.
949 if (test_layer_)
950 test_layer_->SetOpacity(0.f);
951 }
DidChangeLayerCanUseLCDText()952 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
FillsBoundsCompletely() const953 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
954
955 private:
956 Layer* test_layer_;
957 };
958
959 class ContentLayerWithUpdateTracking : public ContentLayer {
960 public:
Create(ContentLayerClient * client)961 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
962 ContentLayerClient* client) {
963 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
964 }
965
PaintContentsCount()966 int PaintContentsCount() { return paint_contents_count_; }
ResetPaintContentsCount()967 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
968
Update(ResourceUpdateQueue * queue,const OcclusionTracker<Layer> * occlusion)969 virtual bool Update(ResourceUpdateQueue* queue,
970 const OcclusionTracker<Layer>* occlusion) OVERRIDE {
971 bool updated = ContentLayer::Update(queue, occlusion);
972 paint_contents_count_++;
973 return updated;
974 }
975
976 private:
ContentLayerWithUpdateTracking(ContentLayerClient * client)977 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
978 : ContentLayer(client), paint_contents_count_(0) {
979 SetBounds(gfx::Size(10, 10));
980 SetIsDrawable(true);
981 }
~ContentLayerWithUpdateTracking()982 virtual ~ContentLayerWithUpdateTracking() {}
983
984 int paint_contents_count_;
985 };
986
987 // Layer opacity change during paint should not prevent compositor resources
988 // from being updated during commit.
989 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
990 public:
LayerTreeHostTestOpacityChange()991 LayerTreeHostTestOpacityChange()
992 : test_opacity_change_delegate_(),
993 update_check_layer_(ContentLayerWithUpdateTracking::Create(
994 &test_opacity_change_delegate_)) {
995 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
996 }
997
BeginTest()998 virtual void BeginTest() OVERRIDE {
999 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1000 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
1001
1002 PostSetNeedsCommitToMainThread();
1003 }
1004
CommitCompleteOnThread(LayerTreeHostImpl * impl)1005 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1006 EndTest();
1007 }
1008
AfterTest()1009 virtual void AfterTest() OVERRIDE {
1010 // Update() should have been called once.
1011 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
1012 }
1013
1014 private:
1015 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1016 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
1017 };
1018
1019 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1020
1021 class NoScaleContentLayer : public ContentLayer {
1022 public:
Create(ContentLayerClient * client)1023 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
1024 return make_scoped_refptr(new NoScaleContentLayer(client));
1025 }
1026
CalculateContentsScale(float ideal_contents_scale,float * contents_scale_x,float * contents_scale_y,gfx::Size * contentBounds)1027 virtual void CalculateContentsScale(float ideal_contents_scale,
1028 float* contents_scale_x,
1029 float* contents_scale_y,
1030 gfx::Size* contentBounds) OVERRIDE {
1031 // Skip over the ContentLayer's method to the base Layer class.
1032 Layer::CalculateContentsScale(ideal_contents_scale,
1033 contents_scale_x,
1034 contents_scale_y,
1035 contentBounds);
1036 }
1037
1038 private:
NoScaleContentLayer(ContentLayerClient * client)1039 explicit NoScaleContentLayer(ContentLayerClient* client)
1040 : ContentLayer(client) {}
~NoScaleContentLayer()1041 virtual ~NoScaleContentLayer() {}
1042 };
1043
1044 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1045 : public LayerTreeHostTest {
1046 public:
LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()1047 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1048 : root_layer_(NoScaleContentLayer::Create(&client_)),
1049 child_layer_(ContentLayer::Create(&client_)) {}
1050
BeginTest()1051 virtual void BeginTest() OVERRIDE {
1052 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1053 layer_tree_host()->SetDeviceScaleFactor(1.5);
1054 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1055
1056 root_layer_->AddChild(child_layer_);
1057
1058 root_layer_->SetIsDrawable(true);
1059 root_layer_->SetBounds(gfx::Size(30, 30));
1060
1061 child_layer_->SetIsDrawable(true);
1062 child_layer_->SetPosition(gfx::Point(2, 2));
1063 child_layer_->SetBounds(gfx::Size(10, 10));
1064
1065 layer_tree_host()->SetRootLayer(root_layer_);
1066
1067 PostSetNeedsCommitToMainThread();
1068 }
1069
DidActivateTreeOnThread(LayerTreeHostImpl * impl)1070 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1071 // Should only do one commit.
1072 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1073 // Device scale factor should come over to impl.
1074 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1075
1076 // Both layers are on impl.
1077 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1078
1079 // Device viewport is scaled.
1080 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1081
1082 LayerImpl* root = impl->active_tree()->root_layer();
1083 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1084
1085 // Positions remain in layout pixels.
1086 EXPECT_EQ(gfx::Point(0, 0), root->position());
1087 EXPECT_EQ(gfx::Point(2, 2), child->position());
1088
1089 // Compute all the layer transforms for the frame.
1090 LayerTreeHostImpl::FrameData frame_data;
1091 impl->PrepareToDraw(&frame_data);
1092 impl->DidDrawAllLayers(frame_data);
1093
1094 const LayerImplList& render_surface_layer_list =
1095 *frame_data.render_surface_layer_list;
1096
1097 // Both layers should be drawing into the root render surface.
1098 ASSERT_EQ(1u, render_surface_layer_list.size());
1099 ASSERT_EQ(root->render_surface(),
1100 render_surface_layer_list[0]->render_surface());
1101 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1102
1103 // The root render surface is the size of the viewport.
1104 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1105 root->render_surface()->content_rect());
1106
1107 // The content bounds of the child should be scaled.
1108 gfx::Size child_bounds_scaled =
1109 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1110 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1111
1112 gfx::Transform scale_transform;
1113 scale_transform.Scale(impl->device_scale_factor(),
1114 impl->device_scale_factor());
1115
1116 // The root layer is scaled by 2x.
1117 gfx::Transform root_screen_space_transform = scale_transform;
1118 gfx::Transform root_draw_transform = scale_transform;
1119
1120 EXPECT_EQ(root_draw_transform, root->draw_transform());
1121 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1122
1123 // The child is at position 2,2, which is transformed to 3,3 after the scale
1124 gfx::Transform child_screen_space_transform;
1125 child_screen_space_transform.Translate(3.f, 3.f);
1126 gfx::Transform child_draw_transform = child_screen_space_transform;
1127
1128 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1129 child->draw_transform());
1130 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1131 child->screen_space_transform());
1132
1133 EndTest();
1134 }
1135
AfterTest()1136 virtual void AfterTest() OVERRIDE {}
1137
1138 private:
1139 FakeContentLayerClient client_;
1140 scoped_refptr<NoScaleContentLayer> root_layer_;
1141 scoped_refptr<ContentLayer> child_layer_;
1142 };
1143
1144 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1145
1146 // Verify atomicity of commits and reuse of textures.
1147 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1148 public:
InitializeSettings(LayerTreeSettings * settings)1149 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1150 settings->texture_id_allocation_chunk_size = 1;
1151 // Make sure partial texture updates are turned off.
1152 settings->max_partial_texture_updates = 0;
1153 // Linear fade animator prevents scrollbars from drawing immediately.
1154 settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1155 }
1156
SetupTree()1157 virtual void SetupTree() OVERRIDE {
1158 layer_ = FakeContentLayer::Create(&client_);
1159 layer_->SetBounds(gfx::Size(10, 20));
1160
1161 bool paint_scrollbar = true;
1162 bool has_thumb = false;
1163 scrollbar_ = FakePaintedScrollbarLayer::Create(
1164 paint_scrollbar, has_thumb, layer_->id());
1165 scrollbar_->SetPosition(gfx::Point(0, 10));
1166 scrollbar_->SetBounds(gfx::Size(10, 10));
1167
1168 layer_->AddChild(scrollbar_);
1169
1170 layer_tree_host()->SetRootLayer(layer_);
1171 LayerTreeHostTest::SetupTree();
1172 }
1173
BeginTest()1174 virtual void BeginTest() OVERRIDE {
1175 drew_frame_ = -1;
1176 PostSetNeedsCommitToMainThread();
1177 }
1178
DidActivateTreeOnThread(LayerTreeHostImpl * impl)1179 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1180 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1181
1182 TestWebGraphicsContext3D* context = TestContext();
1183
1184 switch (impl->active_tree()->source_frame_number()) {
1185 case 0:
1186 // Number of textures should be one for each layer
1187 ASSERT_EQ(2u, context->NumTextures());
1188 // Number of textures used for commit should be one for each layer.
1189 EXPECT_EQ(2u, context->NumUsedTextures());
1190 // Verify that used texture is correct.
1191 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1192 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1193
1194 context->ResetUsedTextures();
1195 break;
1196 case 1:
1197 // Number of textures should be one for scrollbar layer since it was
1198 // requested and deleted on the impl-thread, and double for the content
1199 // layer since its first texture is used by impl thread and cannot by
1200 // used for update.
1201 ASSERT_EQ(3u, context->NumTextures());
1202 // Number of textures used for commit should be one for each layer.
1203 EXPECT_EQ(2u, context->NumUsedTextures());
1204 // First textures should not have been used.
1205 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1206 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1207 // New textures should have been used.
1208 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1209 context->ResetUsedTextures();
1210 break;
1211 case 2:
1212 EndTest();
1213 break;
1214 default:
1215 NOTREACHED();
1216 break;
1217 }
1218 }
1219
DrawLayersOnThread(LayerTreeHostImpl * impl)1220 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1221 TestWebGraphicsContext3D* context = TestContext();
1222
1223 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1224 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1225 return;
1226 }
1227 drew_frame_ = impl->active_tree()->source_frame_number();
1228
1229 // We draw/ship one texture each frame for each layer.
1230 EXPECT_EQ(2u, context->NumUsedTextures());
1231 context->ResetUsedTextures();
1232
1233 if (!TestEnded())
1234 PostSetNeedsCommitToMainThread();
1235 }
1236
Layout()1237 virtual void Layout() OVERRIDE {
1238 layer_->SetNeedsDisplay();
1239 scrollbar_->SetNeedsDisplay();
1240 }
1241
AfterTest()1242 virtual void AfterTest() OVERRIDE {}
1243
1244 protected:
1245 FakeContentLayerClient client_;
1246 scoped_refptr<FakeContentLayer> layer_;
1247 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1248 int drew_frame_;
1249 };
1250
1251 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1252 LayerTreeHostTestDirectRendererAtomicCommit);
1253
1254 class LayerTreeHostTestDelegatingRendererAtomicCommit
1255 : public LayerTreeHostTestDirectRendererAtomicCommit {
1256 public:
DidActivateTreeOnThread(LayerTreeHostImpl * impl)1257 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1258 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1259
1260 TestWebGraphicsContext3D* context = TestContext();
1261
1262 switch (impl->active_tree()->source_frame_number()) {
1263 case 0:
1264 // Number of textures should be one for each layer
1265 ASSERT_EQ(2u, context->NumTextures());
1266 // Number of textures used for commit should be one for each layer.
1267 EXPECT_EQ(2u, context->NumUsedTextures());
1268 // Verify that used texture is correct.
1269 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1270 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1271 context->ResetUsedTextures();
1272 break;
1273 case 1:
1274 // Number of textures should be doubled as the first context layer
1275 // texture is being used by the impl-thread and cannot be used for
1276 // update. The scrollbar behavior is different direct renderer because
1277 // UI resource deletion with delegating renderer occurs after tree
1278 // activation.
1279 ASSERT_EQ(4u, context->NumTextures());
1280 // Number of textures used for commit should still be
1281 // one for each layer.
1282 EXPECT_EQ(2u, context->NumUsedTextures());
1283 // First textures should not have been used.
1284 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1285 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1286 // New textures should have been used.
1287 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1288 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1289 context->ResetUsedTextures();
1290 break;
1291 case 2:
1292 EndTest();
1293 break;
1294 default:
1295 NOTREACHED();
1296 break;
1297 }
1298 }
1299 };
1300
1301 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1302 LayerTreeHostTestDelegatingRendererAtomicCommit);
1303
SetLayerPropertiesForTesting(Layer * layer,Layer * parent,const gfx::Transform & transform,const gfx::Point3F & transform_origin,const gfx::PointF & position,const gfx::Size & bounds,bool opaque)1304 static void SetLayerPropertiesForTesting(Layer* layer,
1305 Layer* parent,
1306 const gfx::Transform& transform,
1307 const gfx::Point3F& transform_origin,
1308 const gfx::PointF& position,
1309 const gfx::Size& bounds,
1310 bool opaque) {
1311 layer->RemoveAllChildren();
1312 if (parent)
1313 parent->AddChild(layer);
1314 layer->SetTransform(transform);
1315 layer->SetTransformOrigin(transform_origin);
1316 layer->SetPosition(position);
1317 layer->SetBounds(bounds);
1318 layer->SetContentsOpaque(opaque);
1319 }
1320
1321 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1322 : public LayerTreeHostTest {
1323 public:
InitializeSettings(LayerTreeSettings * settings)1324 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1325 settings->texture_id_allocation_chunk_size = 1;
1326 // Allow one partial texture update.
1327 settings->max_partial_texture_updates = 1;
1328 // No partial updates when impl side painting is enabled.
1329 settings->impl_side_painting = false;
1330 }
1331
SetupTree()1332 virtual void SetupTree() OVERRIDE {
1333 parent_ = FakeContentLayer::Create(&client_);
1334 parent_->SetBounds(gfx::Size(10, 20));
1335
1336 child_ = FakeContentLayer::Create(&client_);
1337 child_->SetPosition(gfx::Point(0, 10));
1338 child_->SetBounds(gfx::Size(3, 10));
1339
1340 parent_->AddChild(child_);
1341
1342 layer_tree_host()->SetRootLayer(parent_);
1343 LayerTreeHostTest::SetupTree();
1344 }
1345
BeginTest()1346 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1347
DidCommitAndDrawFrame()1348 virtual void DidCommitAndDrawFrame() OVERRIDE {
1349 switch (layer_tree_host()->source_frame_number()) {
1350 case 1:
1351 parent_->SetNeedsDisplay();
1352 child_->SetNeedsDisplay();
1353 break;
1354 case 2:
1355 // Damage part of layers.
1356 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1357 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1358 break;
1359 case 3:
1360 child_->SetNeedsDisplay();
1361 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1362 break;
1363 case 4:
1364 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1365 break;
1366 case 5:
1367 EndTest();
1368 break;
1369 default:
1370 NOTREACHED() << layer_tree_host()->source_frame_number();
1371 break;
1372 }
1373 }
1374
CommitCompleteOnThread(LayerTreeHostImpl * impl)1375 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1376 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1377
1378 TestWebGraphicsContext3D* context = TestContext();
1379
1380 switch (impl->active_tree()->source_frame_number()) {
1381 case 0:
1382 // Number of textures should be one for each layer.
1383 ASSERT_EQ(2u, context->NumTextures());
1384 // Number of textures used for commit should be one for each layer.
1385 EXPECT_EQ(2u, context->NumUsedTextures());
1386 // Verify that used textures are correct.
1387 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1388 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1389 context->ResetUsedTextures();
1390 break;
1391 case 1:
1392 if (HasImplThread()) {
1393 // Number of textures should be two for each content layer.
1394 ASSERT_EQ(4u, context->NumTextures());
1395 } else {
1396 // In single thread we can always do partial updates, so the limit has
1397 // no effect.
1398 ASSERT_EQ(2u, context->NumTextures());
1399 }
1400 // Number of textures used for commit should be one for each content
1401 // layer.
1402 EXPECT_EQ(2u, context->NumUsedTextures());
1403
1404 if (HasImplThread()) {
1405 // First content textures should not have been used.
1406 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1407 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1408 // New textures should have been used.
1409 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1410 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1411 } else {
1412 // In single thread we can always do partial updates, so the limit has
1413 // no effect.
1414 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1415 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1416 }
1417
1418 context->ResetUsedTextures();
1419 break;
1420 case 2:
1421 if (HasImplThread()) {
1422 // Number of textures should be two for each content layer.
1423 ASSERT_EQ(4u, context->NumTextures());
1424 } else {
1425 // In single thread we can always do partial updates, so the limit has
1426 // no effect.
1427 ASSERT_EQ(2u, context->NumTextures());
1428 }
1429 // Number of textures used for commit should be one for each content
1430 // layer.
1431 EXPECT_EQ(2u, context->NumUsedTextures());
1432
1433 if (HasImplThread()) {
1434 // One content layer does a partial update also.
1435 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1436 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1437 } else {
1438 // In single thread we can always do partial updates, so the limit has
1439 // no effect.
1440 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1441 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1442 }
1443
1444 context->ResetUsedTextures();
1445 break;
1446 case 3:
1447 // No textures should be used for commit.
1448 EXPECT_EQ(0u, context->NumUsedTextures());
1449
1450 context->ResetUsedTextures();
1451 break;
1452 case 4:
1453 // Number of textures used for commit should be one, for the
1454 // content layer.
1455 EXPECT_EQ(1u, context->NumUsedTextures());
1456
1457 context->ResetUsedTextures();
1458 break;
1459 default:
1460 NOTREACHED();
1461 break;
1462 }
1463 }
1464
DrawLayersOnThread(LayerTreeHostImpl * impl)1465 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1466 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1467
1468 TestWebGraphicsContext3D* context = TestContext();
1469
1470 // Number of textures used for drawing should one per layer except for
1471 // frame 3 where the viewport only contains one layer.
1472 if (impl->active_tree()->source_frame_number() == 3) {
1473 EXPECT_EQ(1u, context->NumUsedTextures());
1474 } else {
1475 EXPECT_EQ(2u, context->NumUsedTextures())
1476 << "For frame " << impl->active_tree()->source_frame_number();
1477 }
1478
1479 context->ResetUsedTextures();
1480 }
1481
AfterTest()1482 virtual void AfterTest() OVERRIDE {}
1483
1484 private:
1485 FakeContentLayerClient client_;
1486 scoped_refptr<FakeContentLayer> parent_;
1487 scoped_refptr<FakeContentLayer> child_;
1488 };
1489
1490 // Partial updates are not possible with a delegating renderer.
1491 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1492 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1493
1494 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1495 : public LayerTreeHostTest {
1496 protected:
SetupTree()1497 virtual void SetupTree() OVERRIDE {
1498 root_layer_ = FakeContentLayer::Create(&client_);
1499 root_layer_->SetBounds(gfx::Size(100, 100));
1500
1501 surface_layer1_ = FakeContentLayer::Create(&client_);
1502 surface_layer1_->SetBounds(gfx::Size(100, 100));
1503 surface_layer1_->SetForceRenderSurface(true);
1504 surface_layer1_->SetOpacity(0.5f);
1505 root_layer_->AddChild(surface_layer1_);
1506
1507 surface_layer2_ = FakeContentLayer::Create(&client_);
1508 surface_layer2_->SetBounds(gfx::Size(100, 100));
1509 surface_layer2_->SetForceRenderSurface(true);
1510 surface_layer2_->SetOpacity(0.5f);
1511 surface_layer1_->AddChild(surface_layer2_);
1512
1513 replica_layer1_ = FakeContentLayer::Create(&client_);
1514 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1515
1516 replica_layer2_ = FakeContentLayer::Create(&client_);
1517 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1518
1519 layer_tree_host()->SetRootLayer(root_layer_);
1520 LayerTreeHostTest::SetupTree();
1521 }
1522
BeginTest()1523 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1524
DrawLayersOnThread(LayerTreeHostImpl * host_impl)1525 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1526 Renderer* renderer = host_impl->renderer();
1527 RenderPassId surface1_render_pass_id = host_impl->active_tree()
1528 ->root_layer()
1529 ->children()[0]
1530 ->render_surface()
1531 ->GetRenderPassId();
1532 RenderPassId surface2_render_pass_id = host_impl->active_tree()
1533 ->root_layer()
1534 ->children()[0]
1535 ->children()[0]
1536 ->render_surface()
1537 ->GetRenderPassId();
1538
1539 switch (host_impl->active_tree()->source_frame_number()) {
1540 case 0:
1541 EXPECT_TRUE(
1542 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1543 EXPECT_TRUE(
1544 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1545
1546 // Reduce the memory limit to only fit the root layer and one render
1547 // surface. This prevents any contents drawing into surfaces
1548 // from being allocated.
1549 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1550 break;
1551 case 1:
1552 EXPECT_FALSE(
1553 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1554 EXPECT_FALSE(
1555 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1556
1557 EndTest();
1558 break;
1559 }
1560 }
1561
DidCommitAndDrawFrame()1562 virtual void DidCommitAndDrawFrame() OVERRIDE {
1563 if (layer_tree_host()->source_frame_number() < 2)
1564 root_layer_->SetNeedsDisplay();
1565 }
1566
AfterTest()1567 virtual void AfterTest() OVERRIDE {
1568 EXPECT_LE(2u, root_layer_->update_count());
1569 EXPECT_LE(2u, surface_layer1_->update_count());
1570 EXPECT_LE(2u, surface_layer2_->update_count());
1571 }
1572
1573 FakeContentLayerClient client_;
1574 scoped_refptr<FakeContentLayer> root_layer_;
1575 scoped_refptr<FakeContentLayer> surface_layer1_;
1576 scoped_refptr<FakeContentLayer> replica_layer1_;
1577 scoped_refptr<FakeContentLayer> surface_layer2_;
1578 scoped_refptr<FakeContentLayer> replica_layer2_;
1579 };
1580
1581 // Surfaces don't exist with a delegated renderer.
1582 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1583 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1584
1585 class EvictionTestLayer : public Layer {
1586 public:
Create()1587 static scoped_refptr<EvictionTestLayer> Create() {
1588 return make_scoped_refptr(new EvictionTestLayer());
1589 }
1590
1591 virtual bool Update(ResourceUpdateQueue*,
1592 const OcclusionTracker<Layer>*) OVERRIDE;
DrawsContent() const1593 virtual bool DrawsContent() const OVERRIDE { return true; }
1594
1595 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1596 OVERRIDE;
1597 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1598 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1599
HaveBackingTexture() const1600 bool HaveBackingTexture() const {
1601 return texture_.get() ? texture_->have_backing_texture() : false;
1602 }
1603
1604 private:
EvictionTestLayer()1605 EvictionTestLayer() : Layer() {}
~EvictionTestLayer()1606 virtual ~EvictionTestLayer() {}
1607
CreateTextureIfNeeded()1608 void CreateTextureIfNeeded() {
1609 if (texture_)
1610 return;
1611 texture_ = PrioritizedResource::Create(
1612 layer_tree_host()->contents_texture_manager());
1613 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1614 bitmap_.allocN32Pixels(10, 10);
1615 }
1616
1617 scoped_ptr<PrioritizedResource> texture_;
1618 SkBitmap bitmap_;
1619 };
1620
1621 class EvictionTestLayerImpl : public LayerImpl {
1622 public:
Create(LayerTreeImpl * tree_impl,int id)1623 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1624 int id) {
1625 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1626 }
~EvictionTestLayerImpl()1627 virtual ~EvictionTestLayerImpl() {}
1628
AppendQuads(RenderPass * render_pass,const OcclusionTracker<LayerImpl> & occlusion_tracker,AppendQuadsData * append_quads_data)1629 virtual void AppendQuads(RenderPass* render_pass,
1630 const OcclusionTracker<LayerImpl>& occlusion_tracker,
1631 AppendQuadsData* append_quads_data) OVERRIDE {
1632 ASSERT_TRUE(has_texture_);
1633 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1634 }
1635
SetHasTexture(bool has_texture)1636 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1637
1638 private:
EvictionTestLayerImpl(LayerTreeImpl * tree_impl,int id)1639 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1640 : LayerImpl(tree_impl, id), has_texture_(false) {}
1641
1642 bool has_texture_;
1643 };
1644
SetTexturePriorities(const PriorityCalculator &)1645 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1646 CreateTextureIfNeeded();
1647 if (!texture_)
1648 return;
1649 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1650 }
1651
Update(ResourceUpdateQueue * queue,const OcclusionTracker<Layer> * occlusion)1652 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1653 const OcclusionTracker<Layer>* occlusion) {
1654 CreateTextureIfNeeded();
1655 if (!texture_)
1656 return false;
1657
1658 gfx::Rect full_rect(0, 0, 10, 10);
1659 ResourceUpdate upload = ResourceUpdate::Create(
1660 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1661 queue->AppendFullUpload(upload);
1662 return true;
1663 }
1664
CreateLayerImpl(LayerTreeImpl * tree_impl)1665 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1666 LayerTreeImpl* tree_impl) {
1667 return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
1668 .PassAs<LayerImpl>();
1669 }
1670
PushPropertiesTo(LayerImpl * layer_impl)1671 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1672 Layer::PushPropertiesTo(layer_impl);
1673
1674 EvictionTestLayerImpl* test_layer_impl =
1675 static_cast<EvictionTestLayerImpl*>(layer_impl);
1676 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1677 }
1678
1679 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1680 public:
LayerTreeHostTestEvictTextures()1681 LayerTreeHostTestEvictTextures()
1682 : layer_(EvictionTestLayer::Create()),
1683 impl_for_evict_textures_(0),
1684 num_commits_(0) {}
1685
BeginTest()1686 virtual void BeginTest() OVERRIDE {
1687 layer_tree_host()->SetRootLayer(layer_);
1688 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1689
1690 gfx::Transform identity_matrix;
1691 SetLayerPropertiesForTesting(layer_.get(),
1692 0,
1693 identity_matrix,
1694 gfx::Point3F(0.f, 0.f, 0.f),
1695 gfx::PointF(0.f, 0.f),
1696 gfx::Size(10, 20),
1697 true);
1698
1699 PostSetNeedsCommitToMainThread();
1700 }
1701
PostEvictTextures()1702 void PostEvictTextures() {
1703 ImplThreadTaskRunner()->PostTask(
1704 FROM_HERE,
1705 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1706 base::Unretained(this)));
1707 }
1708
EvictTexturesOnImplThread()1709 void EvictTexturesOnImplThread() {
1710 DCHECK(impl_for_evict_textures_);
1711 impl_for_evict_textures_->EvictTexturesForTesting();
1712 }
1713
1714 // Commit 1: Just commit and draw normally, then post an eviction at the end
1715 // that will trigger a commit.
1716 // Commit 2: Triggered by the eviction, let it go through and then set
1717 // needsCommit.
1718 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1719 // task, which will be handled before the commit. Don't set needsCommit, it
1720 // should have been posted. A frame should not be drawn (note,
1721 // didCommitAndDrawFrame may be called anyway).
1722 // Commit 4: Triggered by the eviction, let it go through and then set
1723 // needsCommit.
1724 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1725 // Layout(), a frame should not be drawn but a commit will be posted.
1726 // Commit 6: Triggered by the eviction, post an eviction task in
1727 // Layout(), which will be a noop, letting the commit (which recreates the
1728 // textures) go through and draw a frame, then end the test.
1729 //
1730 // Commits 1+2 test the eviction recovery path where eviction happens outside
1731 // of the beginFrame/commit pair.
1732 // Commits 3+4 test the eviction recovery path where eviction happens inside
1733 // the beginFrame/commit pair.
1734 // Commits 5+6 test the path where an eviction happens during the eviction
1735 // recovery path.
DidCommit()1736 virtual void DidCommit() OVERRIDE {
1737 switch (num_commits_) {
1738 case 1:
1739 EXPECT_TRUE(layer_->HaveBackingTexture());
1740 PostEvictTextures();
1741 break;
1742 case 2:
1743 EXPECT_TRUE(layer_->HaveBackingTexture());
1744 layer_tree_host()->SetNeedsCommit();
1745 break;
1746 case 3:
1747 break;
1748 case 4:
1749 EXPECT_TRUE(layer_->HaveBackingTexture());
1750 layer_tree_host()->SetNeedsCommit();
1751 break;
1752 case 5:
1753 break;
1754 case 6:
1755 EXPECT_TRUE(layer_->HaveBackingTexture());
1756 EndTest();
1757 break;
1758 default:
1759 NOTREACHED();
1760 break;
1761 }
1762 }
1763
CommitCompleteOnThread(LayerTreeHostImpl * impl)1764 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1765 impl_for_evict_textures_ = impl;
1766 }
1767
Layout()1768 virtual void Layout() OVERRIDE {
1769 ++num_commits_;
1770 switch (num_commits_) {
1771 case 1:
1772 case 2:
1773 break;
1774 case 3:
1775 PostEvictTextures();
1776 break;
1777 case 4:
1778 // We couldn't check in didCommitAndDrawFrame on commit 3,
1779 // so check here.
1780 EXPECT_FALSE(layer_->HaveBackingTexture());
1781 break;
1782 case 5:
1783 PostEvictTextures();
1784 break;
1785 case 6:
1786 // We couldn't check in didCommitAndDrawFrame on commit 5,
1787 // so check here.
1788 EXPECT_FALSE(layer_->HaveBackingTexture());
1789 PostEvictTextures();
1790 break;
1791 default:
1792 NOTREACHED();
1793 break;
1794 }
1795 }
1796
AfterTest()1797 virtual void AfterTest() OVERRIDE {}
1798
1799 private:
1800 FakeContentLayerClient client_;
1801 scoped_refptr<EvictionTestLayer> layer_;
1802 LayerTreeHostImpl* impl_for_evict_textures_;
1803 int num_commits_;
1804 };
1805
1806 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
1807
1808 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1809 public:
LayerTreeHostTestContinuousInvalidate()1810 LayerTreeHostTestContinuousInvalidate()
1811 : num_commit_complete_(0), num_draw_layers_(0) {}
1812
BeginTest()1813 virtual void BeginTest() OVERRIDE {
1814 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1815 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1816
1817 content_layer_ = ContentLayer::Create(&client_);
1818 content_layer_->SetBounds(gfx::Size(10, 10));
1819 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
1820 content_layer_->SetIsDrawable(true);
1821 layer_tree_host()->root_layer()->AddChild(content_layer_);
1822
1823 PostSetNeedsCommitToMainThread();
1824 }
1825
DidCommitAndDrawFrame()1826 virtual void DidCommitAndDrawFrame() OVERRIDE {
1827 if (num_draw_layers_ == 2)
1828 return;
1829 content_layer_->SetNeedsDisplay();
1830 }
1831
CommitCompleteOnThread(LayerTreeHostImpl * impl)1832 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1833 if (num_draw_layers_ == 1)
1834 num_commit_complete_++;
1835 }
1836
DrawLayersOnThread(LayerTreeHostImpl * impl)1837 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1838 num_draw_layers_++;
1839 if (num_draw_layers_ == 2)
1840 EndTest();
1841 }
1842
AfterTest()1843 virtual void AfterTest() OVERRIDE {
1844 // Check that we didn't commit twice between first and second draw.
1845 EXPECT_EQ(1, num_commit_complete_);
1846 }
1847
1848 private:
1849 FakeContentLayerClient client_;
1850 scoped_refptr<Layer> content_layer_;
1851 int num_commit_complete_;
1852 int num_draw_layers_;
1853 };
1854
1855 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestContinuousInvalidate);
1856
1857 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
1858 public:
LayerTreeHostTestDeferCommits()1859 LayerTreeHostTestDeferCommits()
1860 : num_commits_deferred_(0), num_complete_commits_(0) {}
1861
BeginTest()1862 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1863
DidDeferCommit()1864 virtual void DidDeferCommit() OVERRIDE {
1865 num_commits_deferred_++;
1866 layer_tree_host()->SetDeferCommits(false);
1867 }
1868
DidCommit()1869 virtual void DidCommit() OVERRIDE {
1870 num_complete_commits_++;
1871 switch (num_complete_commits_) {
1872 case 1:
1873 EXPECT_EQ(0, num_commits_deferred_);
1874 layer_tree_host()->SetDeferCommits(true);
1875 PostSetNeedsCommitToMainThread();
1876 break;
1877 case 2:
1878 EndTest();
1879 break;
1880 default:
1881 NOTREACHED();
1882 break;
1883 }
1884 }
1885
AfterTest()1886 virtual void AfterTest() OVERRIDE {
1887 EXPECT_EQ(1, num_commits_deferred_);
1888 EXPECT_EQ(2, num_complete_commits_);
1889 }
1890
1891 private:
1892 int num_commits_deferred_;
1893 int num_complete_commits_;
1894 };
1895
1896 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
1897
1898 class LayerTreeHostWithProxy : public LayerTreeHost {
1899 public:
LayerTreeHostWithProxy(FakeLayerTreeHostClient * client,const LayerTreeSettings & settings,scoped_ptr<FakeProxy> proxy)1900 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
1901 const LayerTreeSettings& settings,
1902 scoped_ptr<FakeProxy> proxy)
1903 : LayerTreeHost(client, NULL, settings) {
1904 proxy->SetLayerTreeHost(this);
1905 client->SetLayerTreeHost(this);
1906 InitializeForTesting(proxy.PassAs<Proxy>());
1907 }
1908 };
1909
TEST(LayerTreeHostTest,LimitPartialUpdates)1910 TEST(LayerTreeHostTest, LimitPartialUpdates) {
1911 // When partial updates are not allowed, max updates should be 0.
1912 {
1913 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1914
1915 scoped_ptr<FakeProxy> proxy(new FakeProxy);
1916 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
1917 proxy->SetMaxPartialTextureUpdates(5);
1918
1919 LayerTreeSettings settings;
1920 settings.max_partial_texture_updates = 10;
1921
1922 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1923 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
1924
1925 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
1926 }
1927
1928 // When partial updates are allowed,
1929 // max updates should be limited by the proxy.
1930 {
1931 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1932
1933 scoped_ptr<FakeProxy> proxy(new FakeProxy);
1934 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1935 proxy->SetMaxPartialTextureUpdates(5);
1936
1937 LayerTreeSettings settings;
1938 settings.max_partial_texture_updates = 10;
1939
1940 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1941 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
1942
1943 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
1944 }
1945
1946 // When partial updates are allowed,
1947 // max updates should also be limited by the settings.
1948 {
1949 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1950
1951 scoped_ptr<FakeProxy> proxy(new FakeProxy);
1952 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1953 proxy->SetMaxPartialTextureUpdates(20);
1954
1955 LayerTreeSettings settings;
1956 settings.max_partial_texture_updates = 10;
1957
1958 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1959 host.OnCreateAndInitializeOutputSurfaceAttempted(true);
1960
1961 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
1962 }
1963 }
1964
TEST(LayerTreeHostTest,PartialUpdatesWithGLRenderer)1965 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
1966 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1967
1968 LayerTreeSettings settings;
1969 settings.max_partial_texture_updates = 4;
1970 settings.single_thread_proxy_scheduler = false;
1971
1972 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1973 new TestSharedBitmapManager());
1974 scoped_ptr<LayerTreeHost> host =
1975 LayerTreeHost::CreateSingleThreaded(&client,
1976 &client,
1977 shared_bitmap_manager.get(),
1978 settings,
1979 base::MessageLoopProxy::current());
1980 client.SetLayerTreeHost(host.get());
1981 host->Composite(base::TimeTicks::Now());
1982
1983 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
1984 }
1985
TEST(LayerTreeHostTest,PartialUpdatesWithSoftwareRenderer)1986 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
1987 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
1988
1989 LayerTreeSettings settings;
1990 settings.max_partial_texture_updates = 4;
1991 settings.single_thread_proxy_scheduler = false;
1992
1993 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1994 new TestSharedBitmapManager());
1995 scoped_ptr<LayerTreeHost> host =
1996 LayerTreeHost::CreateSingleThreaded(&client,
1997 &client,
1998 shared_bitmap_manager.get(),
1999 settings,
2000 base::MessageLoopProxy::current());
2001 client.SetLayerTreeHost(host.get());
2002 host->Composite(base::TimeTicks::Now());
2003
2004 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2005 }
2006
TEST(LayerTreeHostTest,PartialUpdatesWithDelegatingRendererAndGLContent)2007 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2008 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2009
2010 LayerTreeSettings settings;
2011 settings.max_partial_texture_updates = 4;
2012 settings.single_thread_proxy_scheduler = false;
2013
2014 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2015 new TestSharedBitmapManager());
2016 scoped_ptr<LayerTreeHost> host =
2017 LayerTreeHost::CreateSingleThreaded(&client,
2018 &client,
2019 shared_bitmap_manager.get(),
2020 settings,
2021 base::MessageLoopProxy::current());
2022 client.SetLayerTreeHost(host.get());
2023 host->Composite(base::TimeTicks::Now());
2024
2025 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2026 }
2027
TEST(LayerTreeHostTest,PartialUpdatesWithDelegatingRendererAndSoftwareContent)2028 TEST(LayerTreeHostTest,
2029 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2030 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2031
2032 LayerTreeSettings settings;
2033 settings.max_partial_texture_updates = 4;
2034 settings.single_thread_proxy_scheduler = false;
2035
2036 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2037 new TestSharedBitmapManager());
2038 scoped_ptr<LayerTreeHost> host =
2039 LayerTreeHost::CreateSingleThreaded(&client,
2040 &client,
2041 shared_bitmap_manager.get(),
2042 settings,
2043 base::MessageLoopProxy::current());
2044 client.SetLayerTreeHost(host.get());
2045 host->Composite(base::TimeTicks::Now());
2046
2047 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2048 }
2049
2050 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2051 : public LayerTreeHostTest {
2052 public:
LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()2053 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2054 : root_layer_(FakeContentLayer::Create(&client_)),
2055 child_layer1_(FakeContentLayer::Create(&client_)),
2056 child_layer2_(FakeContentLayer::Create(&client_)),
2057 num_commits_(0) {}
2058
BeginTest()2059 virtual void BeginTest() OVERRIDE {
2060 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2061 root_layer_->SetBounds(gfx::Size(100, 100));
2062 child_layer1_->SetBounds(gfx::Size(100, 100));
2063 child_layer2_->SetBounds(gfx::Size(100, 100));
2064 root_layer_->AddChild(child_layer1_);
2065 root_layer_->AddChild(child_layer2_);
2066 layer_tree_host()->SetRootLayer(root_layer_);
2067 PostSetNeedsCommitToMainThread();
2068 }
2069
DidSetVisibleOnImplTree(LayerTreeHostImpl * host_impl,bool visible)2070 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2071 bool visible) OVERRIDE {
2072 if (visible) {
2073 // One backing should remain unevicted.
2074 EXPECT_EQ(
2075 100u * 100u * 4u * 1u,
2076 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2077 } else {
2078 EXPECT_EQ(
2079 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2080 }
2081
2082 // Make sure that contents textures are marked as having been
2083 // purged.
2084 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2085 // End the test in this state.
2086 EndTest();
2087 }
2088
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)2089 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2090 ++num_commits_;
2091 switch (num_commits_) {
2092 case 1:
2093 // All three backings should have memory.
2094 EXPECT_EQ(
2095 100u * 100u * 4u * 3u,
2096 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2097 // Set a new policy that will kick out 1 of the 3 resources.
2098 // Because a resource was evicted, a commit will be kicked off.
2099 host_impl->SetMemoryPolicy(
2100 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2101 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2102 1000));
2103 break;
2104 case 2:
2105 // Only two backings should have memory.
2106 EXPECT_EQ(
2107 100u * 100u * 4u * 2u,
2108 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2109 // Become backgrounded, which will cause 1 more resource to be
2110 // evicted.
2111 PostSetVisibleToMainThread(false);
2112 break;
2113 default:
2114 // No further commits should happen because this is not visible
2115 // anymore.
2116 NOTREACHED();
2117 break;
2118 }
2119 }
2120
AfterTest()2121 virtual void AfterTest() OVERRIDE {}
2122
2123 private:
2124 FakeContentLayerClient client_;
2125 scoped_refptr<FakeContentLayer> root_layer_;
2126 scoped_refptr<FakeContentLayer> child_layer1_;
2127 scoped_refptr<FakeContentLayer> child_layer2_;
2128 int num_commits_;
2129 };
2130
2131 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2132 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2133
2134 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2135 public:
2136 class NotificationClient : public ContentLayerClient {
2137 public:
NotificationClient()2138 NotificationClient()
2139 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2140
set_layer(Layer * layer)2141 void set_layer(Layer* layer) { layer_ = layer; }
paint_count() const2142 int paint_count() const { return paint_count_; }
lcd_notification_count() const2143 int lcd_notification_count() const { return lcd_notification_count_; }
2144
PaintContents(SkCanvas * canvas,const gfx::Rect & clip,ContentLayerClient::GraphicsContextStatus gc_status)2145 virtual void PaintContents(
2146 SkCanvas* canvas,
2147 const gfx::Rect& clip,
2148 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
2149 ++paint_count_;
2150 }
DidChangeLayerCanUseLCDText()2151 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2152 ++lcd_notification_count_;
2153 layer_->SetNeedsDisplay();
2154 }
FillsBoundsCompletely() const2155 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
2156
2157 private:
2158 Layer* layer_;
2159 int paint_count_;
2160 int lcd_notification_count_;
2161 };
2162
SetupTree()2163 virtual void SetupTree() OVERRIDE {
2164 scoped_refptr<Layer> root_layer;
2165 if (layer_tree_host()->settings().impl_side_painting)
2166 root_layer = PictureLayer::Create(&client_);
2167 else
2168 root_layer = ContentLayer::Create(&client_);
2169 root_layer->SetIsDrawable(true);
2170 root_layer->SetBounds(gfx::Size(1, 1));
2171
2172 layer_tree_host()->SetRootLayer(root_layer);
2173 client_.set_layer(root_layer.get());
2174
2175 // The expecations are based on the assumption that the default
2176 // LCD settings are:
2177 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2178 EXPECT_FALSE(root_layer->can_use_lcd_text());
2179
2180 LayerTreeHostTest::SetupTree();
2181 }
2182
BeginTest()2183 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
AfterTest()2184 virtual void AfterTest() OVERRIDE {}
2185
DidCommit()2186 virtual void DidCommit() OVERRIDE {
2187 switch (layer_tree_host()->source_frame_number()) {
2188 case 1:
2189 // The first update consists of one LCD notification and one paint.
2190 EXPECT_EQ(1, client_.lcd_notification_count());
2191 EXPECT_EQ(1, client_.paint_count());
2192 // LCD text must have been enabled on the layer.
2193 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2194 PostSetNeedsCommitToMainThread();
2195 break;
2196 case 2:
2197 // Since nothing changed on layer, there should be no notification
2198 // or paint on the second update.
2199 EXPECT_EQ(1, client_.lcd_notification_count());
2200 EXPECT_EQ(1, client_.paint_count());
2201 // LCD text must not have changed.
2202 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2203 // Change layer opacity that should trigger lcd notification.
2204 layer_tree_host()->root_layer()->SetOpacity(.5f);
2205 // No need to request a commit - setting opacity will do it.
2206 break;
2207 default:
2208 // Verify that there is no extra commit due to layer invalidation.
2209 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
2210 // LCD notification count should have incremented due to
2211 // change in layer opacity.
2212 EXPECT_EQ(2, client_.lcd_notification_count());
2213 // Paint count should be incremented due to invalidation.
2214 EXPECT_EQ(2, client_.paint_count());
2215 // LCD text must have been disabled on the layer due to opacity.
2216 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2217 EndTest();
2218 break;
2219 }
2220 }
2221
2222 private:
2223 NotificationClient client_;
2224 };
2225
2226 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2227
2228 // Verify that the BeginFrame notification is used to initiate rendering.
2229 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2230 public:
InitializeSettings(LayerTreeSettings * settings)2231 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2232 settings->begin_frame_scheduling_enabled = true;
2233 }
2234
BeginTest()2235 virtual void BeginTest() OVERRIDE {
2236 // This will trigger a SetNeedsBeginFrame which will trigger a
2237 // BeginFrame.
2238 PostSetNeedsCommitToMainThread();
2239 }
2240
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame,DrawResult draw_result)2241 virtual DrawResult PrepareToDrawOnThread(
2242 LayerTreeHostImpl* host_impl,
2243 LayerTreeHostImpl::FrameData* frame,
2244 DrawResult draw_result) OVERRIDE {
2245 EndTest();
2246 return DRAW_SUCCESS;
2247 }
2248
AfterTest()2249 virtual void AfterTest() OVERRIDE {}
2250
2251 private:
2252 base::TimeTicks frame_time_;
2253 };
2254
2255 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2256
2257 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2258 : public LayerTreeHostTest {
2259 public:
InitializeSettings(LayerTreeSettings * settings)2260 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2261 settings->begin_frame_scheduling_enabled = true;
2262 settings->using_synchronous_renderer_compositor = true;
2263 }
2264
BeginTest()2265 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2266
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)2267 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2268 // The BeginFrame notification is turned off now but will get enabled
2269 // once we return. End test while it's enabled.
2270 ImplThreadTaskRunner()->PostTask(
2271 FROM_HERE,
2272 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2273 base::Unretained(this)));
2274 }
2275
AfterTest()2276 virtual void AfterTest() OVERRIDE {}
2277 };
2278
2279 MULTI_THREAD_TEST_F(
2280 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2281
2282 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2283 protected:
LayerTreeHostTestAbortedCommitDoesntStall()2284 LayerTreeHostTestAbortedCommitDoesntStall()
2285 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2286
InitializeSettings(LayerTreeSettings * settings)2287 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2288 settings->begin_frame_scheduling_enabled = true;
2289 }
2290
BeginTest()2291 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2292
DidCommit()2293 virtual void DidCommit() OVERRIDE {
2294 commit_count_++;
2295 if (commit_count_ == 4) {
2296 // After two aborted commits, request a real commit now to make sure a
2297 // real commit following an aborted commit will still complete and
2298 // end the test even when the Impl thread is idle.
2299 layer_tree_host()->SetNeedsCommit();
2300 }
2301 }
2302
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,bool did_handle)2303 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2304 bool did_handle) OVERRIDE {
2305 commit_abort_count_++;
2306 // Initiate another abortable commit.
2307 host_impl->SetNeedsCommit();
2308 }
2309
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)2310 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2311 commit_complete_count_++;
2312 if (commit_complete_count_ == 1) {
2313 // Initiate an abortable commit after the first commit.
2314 host_impl->SetNeedsCommit();
2315 } else {
2316 EndTest();
2317 }
2318 }
2319
AfterTest()2320 virtual void AfterTest() OVERRIDE {
2321 EXPECT_EQ(commit_count_, 5);
2322 EXPECT_EQ(commit_abort_count_, 3);
2323 EXPECT_EQ(commit_complete_count_, 2);
2324 }
2325
2326 int commit_count_;
2327 int commit_abort_count_;
2328 int commit_complete_count_;
2329 };
2330
2331 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2332 : public LayerTreeHostTestAbortedCommitDoesntStall {
InitializeSettings(LayerTreeSettings * settings)2333 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2334 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2335 settings->using_synchronous_renderer_compositor = true;
2336 }
2337 };
2338
2339 MULTI_THREAD_TEST_F(
2340 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2341
2342 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2343 : public LayerTreeHostTestAbortedCommitDoesntStall {
InitializeSettings(LayerTreeSettings * settings)2344 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2345 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2346 settings->throttle_frame_production = false;
2347 }
2348 };
2349
2350 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2351
2352 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2353 : public LayerTreeHostTest {
2354 protected:
InitializeSettings(LayerTreeSettings * settings)2355 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2356 settings->impl_side_painting = true;
2357 }
2358
SetupTree()2359 virtual void SetupTree() OVERRIDE {
2360 LayerTreeHostTest::SetupTree();
2361
2362 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2363 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2364 layer->SetBounds(gfx::Size(10, 10));
2365 layer_tree_host()->root_layer()->AddChild(layer);
2366 }
2367
BeginTest()2368 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2369
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)2370 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2371 EndTest();
2372 }
2373
AfterTest()2374 virtual void AfterTest() OVERRIDE {}
2375
2376 FakeContentLayerClient client_;
2377 };
2378
2379 MULTI_THREAD_TEST_F(
2380 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2381
2382 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2383 : public LayerTreeHostTest {
2384 public:
2385 class SetBoundsClient : public ContentLayerClient {
2386 public:
SetBoundsClient()2387 SetBoundsClient() : layer_(0) {}
2388
set_layer(Layer * layer)2389 void set_layer(Layer* layer) { layer_ = layer; }
2390
PaintContents(SkCanvas * canvas,const gfx::Rect & clip,ContentLayerClient::GraphicsContextStatus gc_status)2391 virtual void PaintContents(
2392 SkCanvas* canvas,
2393 const gfx::Rect& clip,
2394 ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
2395 layer_->SetBounds(gfx::Size(2, 2));
2396 }
2397
DidChangeLayerCanUseLCDText()2398 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2399
FillsBoundsCompletely() const2400 virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
2401
2402 private:
2403 Layer* layer_;
2404 };
2405
LayerTreeHostTestChangeLayerPropertiesInPaintContents()2406 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2407
SetupTree()2408 virtual void SetupTree() OVERRIDE {
2409 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2410 root_layer->SetIsDrawable(true);
2411 root_layer->SetBounds(gfx::Size(1, 1));
2412
2413 layer_tree_host()->SetRootLayer(root_layer);
2414 client_.set_layer(root_layer.get());
2415
2416 LayerTreeHostTest::SetupTree();
2417 }
2418
BeginTest()2419 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
AfterTest()2420 virtual void AfterTest() OVERRIDE {}
2421
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)2422 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2423 num_commits_++;
2424 if (num_commits_ == 1) {
2425 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2426 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2427 } else {
2428 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2429 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2430 EndTest();
2431 }
2432 }
2433
2434 private:
2435 SetBoundsClient client_;
2436 int num_commits_;
2437 };
2438
2439 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2440
2441 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2442 public:
MockIOSurfaceWebGraphicsContext3D()2443 MockIOSurfaceWebGraphicsContext3D() {
2444 test_capabilities_.gpu.iosurface = true;
2445 test_capabilities_.gpu.texture_rectangle = true;
2446 }
2447
createTexture()2448 virtual GLuint createTexture() OVERRIDE {
2449 return 1;
2450 }
2451 MOCK_METHOD1(activeTexture, void(GLenum texture));
2452 MOCK_METHOD2(bindTexture, void(GLenum target,
2453 GLuint texture_id));
2454 MOCK_METHOD3(texParameteri, void(GLenum target,
2455 GLenum pname,
2456 GLint param));
2457 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2458 GLint width,
2459 GLint height,
2460 GLuint ioSurfaceId,
2461 GLuint plane));
2462 MOCK_METHOD4(drawElements, void(GLenum mode,
2463 GLsizei count,
2464 GLenum type,
2465 GLintptr offset));
2466 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2467 MOCK_METHOD2(produceTextureCHROMIUM,
2468 void(GLenum target, const GLbyte* mailbox));
2469 };
2470
2471 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2472 protected:
CreateFakeOutputSurface(bool fallback)2473 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
2474 OVERRIDE {
2475 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2476 new MockIOSurfaceWebGraphicsContext3D);
2477 mock_context_ = mock_context_owned.get();
2478
2479 if (delegating_renderer()) {
2480 return FakeOutputSurface::CreateDelegating3d(
2481 mock_context_owned.PassAs<TestWebGraphicsContext3D>());
2482 } else {
2483 return FakeOutputSurface::Create3d(
2484 mock_context_owned.PassAs<TestWebGraphicsContext3D>());
2485 }
2486 }
2487
SetupTree()2488 virtual void SetupTree() OVERRIDE {
2489 LayerTreeHostTest::SetupTree();
2490
2491 layer_tree_host()->root_layer()->SetIsDrawable(false);
2492
2493 io_surface_id_ = 9;
2494 io_surface_size_ = gfx::Size(6, 7);
2495
2496 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2497 io_surface_layer->SetBounds(gfx::Size(10, 10));
2498 io_surface_layer->SetIsDrawable(true);
2499 io_surface_layer->SetContentsOpaque(true);
2500 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2501 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2502 }
2503
BeginTest()2504 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2505
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)2506 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2507 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2508 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2509
2510 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2511 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2512 .Times(AtLeast(1));
2513 EXPECT_CALL(*mock_context_,
2514 texParameteri(
2515 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2516 .Times(1);
2517 EXPECT_CALL(*mock_context_,
2518 texParameteri(
2519 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2520 .Times(1);
2521 EXPECT_CALL(*mock_context_,
2522 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2523 GL_TEXTURE_POOL_CHROMIUM,
2524 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2525 EXPECT_CALL(*mock_context_,
2526 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2527 GL_TEXTURE_WRAP_S,
2528 GL_CLAMP_TO_EDGE)).Times(1);
2529 EXPECT_CALL(*mock_context_,
2530 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2531 GL_TEXTURE_WRAP_T,
2532 GL_CLAMP_TO_EDGE)).Times(1);
2533
2534 EXPECT_CALL(*mock_context_,
2535 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2536 io_surface_size_.width(),
2537 io_surface_size_.height(),
2538 io_surface_id_,
2539 0)).Times(1);
2540
2541 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2542 }
2543
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame,DrawResult draw_result)2544 virtual DrawResult PrepareToDrawOnThread(
2545 LayerTreeHostImpl* host_impl,
2546 LayerTreeHostImpl::FrameData* frame,
2547 DrawResult draw_result) OVERRIDE {
2548 Mock::VerifyAndClearExpectations(&mock_context_);
2549 ResourceProvider* resource_provider = host_impl->resource_provider();
2550 EXPECT_EQ(1u, resource_provider->num_resources());
2551 CHECK_EQ(1u, frame->render_passes.size());
2552 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2553 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
2554 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2555 const IOSurfaceDrawQuad* io_surface_draw_quad =
2556 IOSurfaceDrawQuad::MaterialCast(quad);
2557 EXPECT_SIZE_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2558 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
2559 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2560 resource_provider->TargetForTesting(
2561 io_surface_draw_quad->io_surface_resource_id));
2562
2563 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2564 .Times(1);
2565 if (delegating_renderer()) {
2566 // The io surface layer's resource should be sent to the parent.
2567 EXPECT_CALL(*mock_context_,
2568 produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2569 } else {
2570 // The io surface layer's texture is drawn.
2571 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2572 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2573 .Times(AtLeast(1));
2574 }
2575
2576 return draw_result;
2577 }
2578
DrawLayersOnThread(LayerTreeHostImpl * host_impl)2579 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2580 Mock::VerifyAndClearExpectations(&mock_context_);
2581
2582 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2583 EndTest();
2584 }
2585
AfterTest()2586 virtual void AfterTest() OVERRIDE {}
2587
2588 int io_surface_id_;
2589 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2590 gfx::Size io_surface_size_;
2591 };
2592
2593 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2594
2595 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2596 public:
BeginTest()2597 virtual void BeginTest() OVERRIDE {
2598 frame_ = 0;
2599 PostSetNeedsCommitToMainThread();
2600 }
2601
2602 // Round 1: commit + draw
2603 // Round 2: commit only (no draw/swap)
2604 // Round 3: draw only (no commit)
2605
DidCommit()2606 virtual void DidCommit() OVERRIDE {
2607 int commit = layer_tree_host()->source_frame_number();
2608 switch (commit) {
2609 case 2:
2610 // Round 2 done.
2611 EXPECT_EQ(1, frame_);
2612 layer_tree_host()->SetNeedsRedraw();
2613 break;
2614 }
2615 }
2616
DidCompleteSwapBuffers()2617 virtual void DidCompleteSwapBuffers() OVERRIDE {
2618 int commit = layer_tree_host()->source_frame_number();
2619 ++frame_;
2620 switch (frame_) {
2621 case 1:
2622 // Round 1 done.
2623 EXPECT_EQ(1, commit);
2624 layer_tree_host()->SetNeedsCommit();
2625 break;
2626 case 2:
2627 // Round 3 done.
2628 EXPECT_EQ(2, commit);
2629 EndTest();
2630 break;
2631 }
2632 }
2633
AfterTest()2634 virtual void AfterTest() OVERRIDE {}
2635
2636 protected:
2637 int frame_;
2638 };
2639
2640 // Flaky on all platforms: http://crbug.com/327498
TEST_F(LayerTreeHostTestNumFramesPending,DISABLED_DelegatingRenderer)2641 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
2642 RunTest(true, true, true);
2643 }
2644
TEST_F(LayerTreeHostTestNumFramesPending,DISABLED_GLRenderer)2645 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
2646 RunTest(true, false, true);
2647 }
2648
2649 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
2650 public:
InitializeSettings(LayerTreeSettings * settings)2651 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2652 // PictureLayer can only be used with impl side painting enabled.
2653 settings->impl_side_painting = true;
2654 }
2655
SetupTree()2656 virtual void SetupTree() OVERRIDE {
2657 layer_ = FakePictureLayer::Create(&client_);
2658 // Force commits to not be aborted so new frames get drawn, otherwise
2659 // the renderer gets deferred initialized but nothing new needs drawing.
2660 layer_->set_always_update_resources(true);
2661 layer_tree_host()->SetRootLayer(layer_);
2662 LayerTreeHostTest::SetupTree();
2663 }
2664
BeginTest()2665 virtual void BeginTest() OVERRIDE {
2666 did_initialize_gl_ = false;
2667 did_release_gl_ = false;
2668 last_source_frame_number_drawn_ = -1; // Never drawn.
2669 PostSetNeedsCommitToMainThread();
2670 }
2671
CreateFakeOutputSurface(bool fallback)2672 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
2673 OVERRIDE {
2674 scoped_ptr<TestWebGraphicsContext3D> context3d(
2675 TestWebGraphicsContext3D::Create());
2676
2677 return FakeOutputSurface::CreateDeferredGL(
2678 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
2679 delegating_renderer());
2680 }
2681
DrawLayersOnThread(LayerTreeHostImpl * host_impl)2682 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2683 ASSERT_TRUE(host_impl->RootLayer());
2684 FakePictureLayerImpl* layer_impl =
2685 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
2686
2687 // The same frame can be draw multiple times if new visible tiles are
2688 // rasterized. But we want to make sure we only post DeferredInitialize
2689 // and ReleaseGL once, so early out if the same frame is drawn again.
2690 if (last_source_frame_number_drawn_ ==
2691 host_impl->active_tree()->source_frame_number())
2692 return;
2693
2694 last_source_frame_number_drawn_ =
2695 host_impl->active_tree()->source_frame_number();
2696
2697 if (!did_initialize_gl_) {
2698 EXPECT_LE(1u, layer_impl->append_quads_count());
2699 ImplThreadTaskRunner()->PostTask(
2700 FROM_HERE,
2701 base::Bind(
2702 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
2703 base::Unretained(this),
2704 base::Unretained(host_impl)));
2705 } else if (did_initialize_gl_ && !did_release_gl_) {
2706 EXPECT_LE(2u, layer_impl->append_quads_count());
2707 ImplThreadTaskRunner()->PostTask(
2708 FROM_HERE,
2709 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
2710 base::Unretained(this),
2711 base::Unretained(host_impl)));
2712 } else if (did_initialize_gl_ && did_release_gl_) {
2713 EXPECT_LE(3u, layer_impl->append_quads_count());
2714 EndTest();
2715 }
2716 }
2717
DeferredInitializeAndRedraw(LayerTreeHostImpl * host_impl)2718 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
2719 EXPECT_FALSE(did_initialize_gl_);
2720 // SetAndInitializeContext3D calls SetNeedsCommit.
2721 FakeOutputSurface* fake_output_surface =
2722 static_cast<FakeOutputSurface*>(host_impl->output_surface());
2723 scoped_refptr<TestContextProvider> context_provider =
2724 TestContextProvider::Create(); // Not bound to thread.
2725 EXPECT_TRUE(
2726 fake_output_surface->InitializeAndSetContext3d(context_provider));
2727 did_initialize_gl_ = true;
2728 }
2729
ReleaseGLAndRedraw(LayerTreeHostImpl * host_impl)2730 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
2731 EXPECT_TRUE(did_initialize_gl_);
2732 EXPECT_FALSE(did_release_gl_);
2733 // ReleaseGL calls SetNeedsCommit.
2734 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
2735 did_release_gl_ = true;
2736 }
2737
SwapBuffersOnThread(LayerTreeHostImpl * host_impl,bool result)2738 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
2739 bool result) OVERRIDE {
2740 ASSERT_TRUE(result);
2741 DelegatedFrameData* delegated_frame_data =
2742 output_surface()->last_sent_frame().delegated_frame_data.get();
2743 if (!delegated_frame_data)
2744 return;
2745
2746 // Return all resources immediately.
2747 TransferableResourceArray resources_to_return =
2748 output_surface()->resources_held_by_parent();
2749
2750 CompositorFrameAck ack;
2751 for (size_t i = 0; i < resources_to_return.size(); ++i)
2752 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
2753 host_impl->ReclaimResources(&ack);
2754 }
2755
AfterTest()2756 virtual void AfterTest() OVERRIDE {
2757 EXPECT_TRUE(did_initialize_gl_);
2758 EXPECT_TRUE(did_release_gl_);
2759 }
2760
2761 private:
2762 FakeContentLayerClient client_;
2763 scoped_refptr<FakePictureLayer> layer_;
2764 bool did_initialize_gl_;
2765 bool did_release_gl_;
2766 int last_source_frame_number_drawn_;
2767 };
2768
2769 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
2770
2771 class LayerTreeHostTestDeferredInitializeWithGpuRasterization
2772 : public LayerTreeHostTestDeferredInitialize {
InitializeSettings(LayerTreeSettings * settings)2773 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2774 // PictureLayer can only be used with impl side painting enabled.
2775 settings->impl_side_painting = true;
2776 settings->gpu_rasterization_enabled = true;
2777 settings->gpu_rasterization_forced = true;
2778 }
2779 };
2780
2781 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization);
2782
2783 // Test for UI Resource management.
2784 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
2785 public:
LayerTreeHostTestUIResource()2786 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
2787
InitializeSettings(LayerTreeSettings * settings)2788 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2789 settings->texture_id_allocation_chunk_size = 1;
2790 }
2791
BeginTest()2792 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2793
DidCommit()2794 virtual void DidCommit() OVERRIDE {
2795 int frame = layer_tree_host()->source_frame_number();
2796 switch (frame) {
2797 case 1:
2798 CreateResource();
2799 CreateResource();
2800 PostSetNeedsCommitToMainThread();
2801 break;
2802 case 2:
2803 // Usually ScopedUIResource are deleted from the manager in their
2804 // destructor. Here we just want to test that a direct call to
2805 // DeleteUIResource works.
2806 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
2807 PostSetNeedsCommitToMainThread();
2808 break;
2809 case 3:
2810 // DeleteUIResource can be called with an invalid id.
2811 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
2812 PostSetNeedsCommitToMainThread();
2813 break;
2814 case 4:
2815 CreateResource();
2816 CreateResource();
2817 PostSetNeedsCommitToMainThread();
2818 break;
2819 case 5:
2820 ClearResources();
2821 EndTest();
2822 break;
2823 }
2824 }
2825
PerformTest(LayerTreeHostImpl * impl)2826 void PerformTest(LayerTreeHostImpl* impl) {
2827 TestWebGraphicsContext3D* context = TestContext();
2828
2829 int frame = impl->active_tree()->source_frame_number();
2830 switch (frame) {
2831 case 0:
2832 ASSERT_EQ(0u, context->NumTextures());
2833 break;
2834 case 1:
2835 // Created two textures.
2836 ASSERT_EQ(2u, context->NumTextures());
2837 break;
2838 case 2:
2839 // One texture left after one deletion.
2840 ASSERT_EQ(1u, context->NumTextures());
2841 break;
2842 case 3:
2843 // Resource manager state should not change when delete is called on an
2844 // invalid id.
2845 ASSERT_EQ(1u, context->NumTextures());
2846 break;
2847 case 4:
2848 // Creation after deletion: two more creates should total up to
2849 // three textures.
2850 ASSERT_EQ(3u, context->NumTextures());
2851 break;
2852 }
2853 }
2854
CommitCompleteOnThread(LayerTreeHostImpl * impl)2855 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2856 if (!layer_tree_host()->settings().impl_side_painting)
2857 PerformTest(impl);
2858 }
2859
DidActivateTreeOnThread(LayerTreeHostImpl * impl)2860 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2861 if (layer_tree_host()->settings().impl_side_painting)
2862 PerformTest(impl);
2863 }
2864
AfterTest()2865 virtual void AfterTest() OVERRIDE {}
2866
2867 private:
2868 // Must clear all resources before exiting.
ClearResources()2869 void ClearResources() {
2870 for (int i = 0; i < num_ui_resources_; i++)
2871 ui_resources_[i].reset();
2872 }
2873
CreateResource()2874 void CreateResource() {
2875 ui_resources_[num_ui_resources_++] =
2876 FakeScopedUIResource::Create(layer_tree_host());
2877 }
2878
2879 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
2880 int num_ui_resources_;
2881 };
2882
2883 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
2884
2885 class PushPropertiesCountingLayerImpl : public LayerImpl {
2886 public:
Create(LayerTreeImpl * tree_impl,int id)2887 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
2888 LayerTreeImpl* tree_impl, int id) {
2889 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
2890 }
2891
~PushPropertiesCountingLayerImpl()2892 virtual ~PushPropertiesCountingLayerImpl() {}
2893
PushPropertiesTo(LayerImpl * layer)2894 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
2895 LayerImpl::PushPropertiesTo(layer);
2896 push_properties_count_++;
2897 // Push state to the active tree because we can only access it from there.
2898 static_cast<PushPropertiesCountingLayerImpl*>(
2899 layer)->push_properties_count_ = push_properties_count_;
2900 }
2901
CreateLayerImpl(LayerTreeImpl * tree_impl)2902 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
2903 OVERRIDE {
2904 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
2905 PassAs<LayerImpl>();
2906 }
2907
push_properties_count() const2908 size_t push_properties_count() const { return push_properties_count_; }
reset_push_properties_count()2909 void reset_push_properties_count() { push_properties_count_ = 0; }
2910
2911 private:
2912 size_t push_properties_count_;
2913
PushPropertiesCountingLayerImpl(LayerTreeImpl * tree_impl,int id)2914 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
2915 : LayerImpl(tree_impl, id),
2916 push_properties_count_(0) {
2917 SetBounds(gfx::Size(1, 1));
2918 }
2919 };
2920
2921 class PushPropertiesCountingLayer : public Layer {
2922 public:
Create()2923 static scoped_refptr<PushPropertiesCountingLayer> Create() {
2924 return new PushPropertiesCountingLayer();
2925 }
2926
PushPropertiesTo(LayerImpl * layer)2927 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
2928 Layer::PushPropertiesTo(layer);
2929 push_properties_count_++;
2930 if (persist_needs_push_properties_)
2931 needs_push_properties_ = true;
2932 }
2933
CreateLayerImpl(LayerTreeImpl * tree_impl)2934 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
2935 OVERRIDE {
2936 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
2937 PassAs<LayerImpl>();
2938 }
2939
SetDrawsContent(bool draws_content)2940 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
2941
push_properties_count() const2942 size_t push_properties_count() const { return push_properties_count_; }
reset_push_properties_count()2943 void reset_push_properties_count() { push_properties_count_ = 0; }
2944
set_persist_needs_push_properties(bool persist)2945 void set_persist_needs_push_properties(bool persist) {
2946 persist_needs_push_properties_ = persist;
2947 }
2948
2949 private:
PushPropertiesCountingLayer()2950 PushPropertiesCountingLayer()
2951 : push_properties_count_(0), persist_needs_push_properties_(false) {
2952 SetBounds(gfx::Size(1, 1));
2953 }
~PushPropertiesCountingLayer()2954 virtual ~PushPropertiesCountingLayer() {}
2955
2956 size_t push_properties_count_;
2957 bool persist_needs_push_properties_;
2958 };
2959
2960 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
2961 protected:
BeginTest()2962 virtual void BeginTest() OVERRIDE {
2963 num_commits_ = 0;
2964 expected_push_properties_root_ = 0;
2965 expected_push_properties_child_ = 0;
2966 expected_push_properties_grandchild_ = 0;
2967 expected_push_properties_child2_ = 0;
2968 expected_push_properties_other_root_ = 0;
2969 expected_push_properties_leaf_layer_ = 0;
2970 PostSetNeedsCommitToMainThread();
2971 }
2972
SetupTree()2973 virtual void SetupTree() OVERRIDE {
2974 root_ = PushPropertiesCountingLayer::Create();
2975 child_ = PushPropertiesCountingLayer::Create();
2976 child2_ = PushPropertiesCountingLayer::Create();
2977 grandchild_ = PushPropertiesCountingLayer::Create();
2978 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
2979 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
2980
2981 root_->AddChild(child_);
2982 root_->AddChild(child2_);
2983 child_->AddChild(grandchild_);
2984 child2_->AddChild(leaf_always_pushing_layer_);
2985
2986 other_root_ = PushPropertiesCountingLayer::Create();
2987
2988 // Don't set the root layer here.
2989 LayerTreeHostTest::SetupTree();
2990 }
2991
DidCommitAndDrawFrame()2992 virtual void DidCommitAndDrawFrame() OVERRIDE {
2993 ++num_commits_;
2994
2995 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
2996 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
2997 EXPECT_EQ(expected_push_properties_grandchild_,
2998 grandchild_->push_properties_count());
2999 EXPECT_EQ(expected_push_properties_child2_,
3000 child2_->push_properties_count());
3001 EXPECT_EQ(expected_push_properties_other_root_,
3002 other_root_->push_properties_count());
3003 EXPECT_EQ(expected_push_properties_leaf_layer_,
3004 leaf_always_pushing_layer_->push_properties_count());
3005
3006 // The scrollbar layer always needs to be pushed.
3007 if (root_->layer_tree_host()) {
3008 EXPECT_TRUE(root_->descendant_needs_push_properties());
3009 EXPECT_FALSE(root_->needs_push_properties());
3010 }
3011 if (child2_->layer_tree_host()) {
3012 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3013 EXPECT_FALSE(child2_->needs_push_properties());
3014 }
3015 if (leaf_always_pushing_layer_->layer_tree_host()) {
3016 EXPECT_FALSE(
3017 leaf_always_pushing_layer_->descendant_needs_push_properties());
3018 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3019 }
3020
3021 // child_ and grandchild_ don't persist their need to push properties.
3022 if (child_->layer_tree_host()) {
3023 EXPECT_FALSE(child_->descendant_needs_push_properties());
3024 EXPECT_FALSE(child_->needs_push_properties());
3025 }
3026 if (grandchild_->layer_tree_host()) {
3027 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3028 EXPECT_FALSE(grandchild_->needs_push_properties());
3029 }
3030
3031 if (other_root_->layer_tree_host()) {
3032 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3033 EXPECT_FALSE(other_root_->needs_push_properties());
3034 }
3035
3036 switch (num_commits_) {
3037 case 1:
3038 layer_tree_host()->SetRootLayer(root_);
3039 // Layers added to the tree get committed.
3040 ++expected_push_properties_root_;
3041 ++expected_push_properties_child_;
3042 ++expected_push_properties_grandchild_;
3043 ++expected_push_properties_child2_;
3044 break;
3045 case 2:
3046 layer_tree_host()->SetNeedsCommit();
3047 // No layers need commit.
3048 break;
3049 case 3:
3050 layer_tree_host()->SetRootLayer(other_root_);
3051 // Layers added to the tree get committed.
3052 ++expected_push_properties_other_root_;
3053 break;
3054 case 4:
3055 layer_tree_host()->SetRootLayer(root_);
3056 // Layers added to the tree get committed.
3057 ++expected_push_properties_root_;
3058 ++expected_push_properties_child_;
3059 ++expected_push_properties_grandchild_;
3060 ++expected_push_properties_child2_;
3061 break;
3062 case 5:
3063 layer_tree_host()->SetNeedsCommit();
3064 // No layers need commit.
3065 break;
3066 case 6:
3067 child_->RemoveFromParent();
3068 // No layers need commit.
3069 break;
3070 case 7:
3071 root_->AddChild(child_);
3072 // Layers added to the tree get committed.
3073 ++expected_push_properties_child_;
3074 ++expected_push_properties_grandchild_;
3075 break;
3076 case 8:
3077 grandchild_->RemoveFromParent();
3078 // No layers need commit.
3079 break;
3080 case 9:
3081 child_->AddChild(grandchild_);
3082 // Layers added to the tree get committed.
3083 ++expected_push_properties_grandchild_;
3084 break;
3085 case 10:
3086 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3087 // No layers need commit.
3088 break;
3089 case 11:
3090 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3091 // No layers need commit.
3092 break;
3093 case 12:
3094 child_->SetPosition(gfx::Point(1, 1));
3095 // The modified layer needs commit
3096 ++expected_push_properties_child_;
3097 break;
3098 case 13:
3099 child2_->SetPosition(gfx::Point(1, 1));
3100 // The modified layer needs commit
3101 ++expected_push_properties_child2_;
3102 break;
3103 case 14:
3104 child_->RemoveFromParent();
3105 root_->AddChild(child_);
3106 // Layers added to the tree get committed.
3107 ++expected_push_properties_child_;
3108 ++expected_push_properties_grandchild_;
3109 break;
3110 case 15:
3111 grandchild_->SetPosition(gfx::Point(1, 1));
3112 // The modified layer needs commit
3113 ++expected_push_properties_grandchild_;
3114 break;
3115 case 16:
3116 // SetNeedsDisplay does not always set needs commit (so call it
3117 // explicitly), but is a property change.
3118 child_->SetNeedsDisplay();
3119 ++expected_push_properties_child_;
3120 layer_tree_host()->SetNeedsCommit();
3121 break;
3122 case 17:
3123 EndTest();
3124 break;
3125 }
3126
3127 // The leaf layer always pushes.
3128 if (leaf_always_pushing_layer_->layer_tree_host())
3129 ++expected_push_properties_leaf_layer_;
3130 }
3131
AfterTest()3132 virtual void AfterTest() OVERRIDE {}
3133
3134 int num_commits_;
3135 FakeContentLayerClient client_;
3136 scoped_refptr<PushPropertiesCountingLayer> root_;
3137 scoped_refptr<PushPropertiesCountingLayer> child_;
3138 scoped_refptr<PushPropertiesCountingLayer> child2_;
3139 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3140 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3141 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3142 size_t expected_push_properties_root_;
3143 size_t expected_push_properties_child_;
3144 size_t expected_push_properties_child2_;
3145 size_t expected_push_properties_grandchild_;
3146 size_t expected_push_properties_other_root_;
3147 size_t expected_push_properties_leaf_layer_;
3148 };
3149
3150 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3151
3152 class LayerTreeHostTestImplLayersPushProperties
3153 : public LayerTreeHostTestLayersPushProperties {
3154 protected:
BeginTest()3155 virtual void BeginTest() OVERRIDE {
3156 expected_push_properties_root_impl_ = 0;
3157 expected_push_properties_child_impl_ = 0;
3158 expected_push_properties_grandchild_impl_ = 0;
3159 expected_push_properties_child2_impl_ = 0;
3160 expected_push_properties_grandchild2_impl_ = 0;
3161 LayerTreeHostTestLayersPushProperties::BeginTest();
3162 }
3163
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)3164 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3165 // These commits are in response to the changes made in
3166 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3167 switch (num_commits_) {
3168 case 0:
3169 // Tree hasn't been setup yet don't bother to check anything.
3170 return;
3171 case 1:
3172 // Root gets set up, Everyone is initialized.
3173 ++expected_push_properties_root_impl_;
3174 ++expected_push_properties_child_impl_;
3175 ++expected_push_properties_grandchild_impl_;
3176 ++expected_push_properties_child2_impl_;
3177 ++expected_push_properties_grandchild2_impl_;
3178 break;
3179 case 2:
3180 // Tree doesn't change but the one leaf that always pushes is pushed.
3181 ++expected_push_properties_grandchild2_impl_;
3182 break;
3183 case 3:
3184 // Root is swapped here.
3185 // Clear the expected push properties the tree will be rebuilt.
3186 expected_push_properties_root_impl_ = 0;
3187 expected_push_properties_child_impl_ = 0;
3188 expected_push_properties_grandchild_impl_ = 0;
3189 expected_push_properties_child2_impl_ = 0;
3190 expected_push_properties_grandchild2_impl_ = 0;
3191
3192 // Make sure the new root is pushed.
3193 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3194 host_impl->RootLayer())->push_properties_count());
3195 return;
3196 case 4:
3197 // Root is swapped back all of the layers in the tree get pushed.
3198 ++expected_push_properties_root_impl_;
3199 ++expected_push_properties_child_impl_;
3200 ++expected_push_properties_grandchild_impl_;
3201 ++expected_push_properties_child2_impl_;
3202 ++expected_push_properties_grandchild2_impl_;
3203 break;
3204 case 5:
3205 // Tree doesn't change but the one leaf that always pushes is pushed.
3206 ++expected_push_properties_grandchild2_impl_;
3207 break;
3208 case 6:
3209 // First child is removed. Structure of the tree changes here so swap
3210 // some of the values. child_impl becomes child2_impl.
3211 expected_push_properties_child_impl_ =
3212 expected_push_properties_child2_impl_;
3213 expected_push_properties_child2_impl_ = 0;
3214 // grandchild_impl becomes grandchild2_impl.
3215 expected_push_properties_grandchild_impl_ =
3216 expected_push_properties_grandchild2_impl_;
3217 expected_push_properties_grandchild2_impl_ = 0;
3218
3219 // grandchild_impl is now the leaf that always pushes. It is pushed.
3220 ++expected_push_properties_grandchild_impl_;
3221 break;
3222 case 7:
3223 // The leaf that always pushes is pushed.
3224 ++expected_push_properties_grandchild_impl_;
3225
3226 // Child is added back. New layers are initialized.
3227 ++expected_push_properties_grandchild2_impl_;
3228 ++expected_push_properties_child2_impl_;
3229 break;
3230 case 8:
3231 // Leaf is removed.
3232 expected_push_properties_grandchild2_impl_ = 0;
3233
3234 // Always pushing.
3235 ++expected_push_properties_grandchild_impl_;
3236 break;
3237 case 9:
3238 // Leaf is added back
3239 ++expected_push_properties_grandchild2_impl_;
3240
3241 // The leaf that always pushes is pushed.
3242 ++expected_push_properties_grandchild_impl_;
3243 break;
3244 case 10:
3245 // The leaf that always pushes is pushed.
3246 ++expected_push_properties_grandchild_impl_;
3247 break;
3248 case 11:
3249 // The leaf that always pushes is pushed.
3250 ++expected_push_properties_grandchild_impl_;
3251 break;
3252 case 12:
3253 // The leaf that always pushes is pushed.
3254 ++expected_push_properties_grandchild_impl_;
3255
3256 // This child position was changed.
3257 ++expected_push_properties_child2_impl_;
3258 break;
3259 case 13:
3260 // The position of this child was changed.
3261 ++expected_push_properties_child_impl_;
3262
3263 // The leaf that always pushes is pushed.
3264 ++expected_push_properties_grandchild_impl_;
3265 break;
3266 case 14:
3267 // Second child is removed from tree. Don't discard counts because
3268 // they are added back before commit.
3269
3270 // The leaf that always pushes is pushed.
3271 ++expected_push_properties_grandchild_impl_;
3272
3273 // Second child added back.
3274 ++expected_push_properties_child2_impl_;
3275 ++expected_push_properties_grandchild2_impl_;
3276
3277 break;
3278 case 15:
3279 // The position of this child was changed.
3280 ++expected_push_properties_grandchild2_impl_;
3281
3282 // The leaf that always pushes is pushed.
3283 ++expected_push_properties_grandchild_impl_;
3284 break;
3285 case 16:
3286 // Second child is invalidated with SetNeedsDisplay
3287 ++expected_push_properties_child2_impl_;
3288
3289 // The leaf that always pushed is pushed.
3290 ++expected_push_properties_grandchild_impl_;
3291 break;
3292 }
3293
3294 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3295 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3296 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3297 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3298 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3299
3300 // Pull the layers that we need from the tree assuming the same structure
3301 // as LayerTreeHostTestLayersPushProperties
3302 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3303 host_impl->RootLayer());
3304
3305 if (root_impl_ && root_impl_->children().size() > 0) {
3306 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3307 root_impl_->children()[0]);
3308
3309 if (child_impl_ && child_impl_->children().size() > 0)
3310 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3311 child_impl_->children()[0]);
3312 }
3313
3314 if (root_impl_ && root_impl_->children().size() > 1) {
3315 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3316 root_impl_->children()[1]);
3317
3318 if (child2_impl_ && child2_impl_->children().size() > 0)
3319 leaf_always_pushing_layer_impl_ =
3320 static_cast<PushPropertiesCountingLayerImpl*>(
3321 child2_impl_->children()[0]);
3322 }
3323
3324 if (root_impl_)
3325 EXPECT_EQ(expected_push_properties_root_impl_,
3326 root_impl_->push_properties_count());
3327 if (child_impl_)
3328 EXPECT_EQ(expected_push_properties_child_impl_,
3329 child_impl_->push_properties_count());
3330 if (grandchild_impl_)
3331 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3332 grandchild_impl_->push_properties_count());
3333 if (child2_impl_)
3334 EXPECT_EQ(expected_push_properties_child2_impl_,
3335 child2_impl_->push_properties_count());
3336 if (leaf_always_pushing_layer_impl_)
3337 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3338 leaf_always_pushing_layer_impl_->push_properties_count());
3339 }
3340
3341 size_t expected_push_properties_root_impl_;
3342 size_t expected_push_properties_child_impl_;
3343 size_t expected_push_properties_child2_impl_;
3344 size_t expected_push_properties_grandchild_impl_;
3345 size_t expected_push_properties_grandchild2_impl_;
3346 };
3347
TEST_F(LayerTreeHostTestImplLayersPushProperties,DelegatingRenderer)3348 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3349 RunTestWithImplSidePainting();
3350 }
3351
3352 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3353 : public LayerTreeHostTest {
3354 protected:
BeginTest()3355 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3356
SetupTree()3357 virtual void SetupTree() OVERRIDE {
3358 root_ = Layer::Create();
3359 root_->SetBounds(gfx::Size(1, 1));
3360
3361 bool paint_scrollbar = true;
3362 bool has_thumb = false;
3363 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3364 paint_scrollbar, has_thumb, root_->id());
3365
3366 root_->AddChild(scrollbar_layer_);
3367
3368 layer_tree_host()->SetRootLayer(root_);
3369 LayerTreeHostTest::SetupTree();
3370 }
3371
DidCommitAndDrawFrame()3372 virtual void DidCommitAndDrawFrame() OVERRIDE {
3373 switch (layer_tree_host()->source_frame_number()) {
3374 case 0:
3375 break;
3376 case 1: {
3377 // During update, the ignore_set_needs_commit_ bit is set to true to
3378 // avoid causing a second commit to be scheduled. If a property change
3379 // is made during this, however, it needs to be pushed in the upcoming
3380 // commit.
3381 scoped_ptr<base::AutoReset<bool> > ignore =
3382 scrollbar_layer_->IgnoreSetNeedsCommit();
3383
3384 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3385
3386 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3387 EXPECT_TRUE(root_->descendant_needs_push_properties());
3388 layer_tree_host()->SetNeedsCommit();
3389
3390 scrollbar_layer_->reset_push_properties_count();
3391 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3392 break;
3393 }
3394 case 2:
3395 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3396 EndTest();
3397 break;
3398 }
3399 }
3400
AfterTest()3401 virtual void AfterTest() OVERRIDE {}
3402
3403 scoped_refptr<Layer> root_;
3404 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3405 };
3406
3407 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3408
3409 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3410 protected:
BeginTest()3411 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3412
SetupTree()3413 virtual void SetupTree() OVERRIDE {
3414 root_ = PushPropertiesCountingLayer::Create();
3415 child_ = PushPropertiesCountingLayer::Create();
3416 root_->AddChild(child_);
3417
3418 layer_tree_host()->SetRootLayer(root_);
3419 LayerTreeHostTest::SetupTree();
3420 }
3421
DidCommitAndDrawFrame()3422 virtual void DidCommitAndDrawFrame() OVERRIDE {
3423 switch (layer_tree_host()->source_frame_number()) {
3424 case 0:
3425 break;
3426 case 1: {
3427 // During update, the ignore_set_needs_commit_ bit is set to true to
3428 // avoid causing a second commit to be scheduled. If a property change
3429 // is made during this, however, it needs to be pushed in the upcoming
3430 // commit.
3431 EXPECT_FALSE(root_->needs_push_properties());
3432 EXPECT_FALSE(child_->needs_push_properties());
3433 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3434 root_->reset_push_properties_count();
3435 child_->reset_push_properties_count();
3436 child_->SetDrawsContent(true);
3437 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3438 EXPECT_EQ(0u, root_->push_properties_count());
3439 EXPECT_EQ(0u, child_->push_properties_count());
3440 EXPECT_TRUE(root_->needs_push_properties());
3441 EXPECT_TRUE(child_->needs_push_properties());
3442 break;
3443 }
3444 case 2:
3445 EXPECT_EQ(1u, root_->push_properties_count());
3446 EXPECT_EQ(1u, child_->push_properties_count());
3447 EXPECT_FALSE(root_->needs_push_properties());
3448 EXPECT_FALSE(child_->needs_push_properties());
3449 EndTest();
3450 break;
3451 }
3452 }
3453
AfterTest()3454 virtual void AfterTest() OVERRIDE {}
3455
3456 scoped_refptr<PushPropertiesCountingLayer> root_;
3457 scoped_refptr<PushPropertiesCountingLayer> child_;
3458 };
3459
3460 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3461
3462 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3463 : public LayerTreeHostTest {
3464 protected:
BeginTest()3465 virtual void BeginTest() OVERRIDE {
3466 expected_push_properties_root_ = 0;
3467 expected_push_properties_child_ = 0;
3468 expected_push_properties_grandchild1_ = 0;
3469 expected_push_properties_grandchild2_ = 0;
3470 expected_push_properties_grandchild3_ = 0;
3471 PostSetNeedsCommitToMainThread();
3472 }
3473
SetupTree()3474 virtual void SetupTree() OVERRIDE {
3475 root_ = PushPropertiesCountingLayer::Create();
3476 child_ = PushPropertiesCountingLayer::Create();
3477 grandchild1_ = PushPropertiesCountingLayer::Create();
3478 grandchild2_ = PushPropertiesCountingLayer::Create();
3479 grandchild3_ = PushPropertiesCountingLayer::Create();
3480
3481 root_->AddChild(child_);
3482 child_->AddChild(grandchild1_);
3483 child_->AddChild(grandchild2_);
3484 child_->AddChild(grandchild3_);
3485
3486 // Don't set the root layer here.
3487 LayerTreeHostTest::SetupTree();
3488 }
3489
AfterTest()3490 virtual void AfterTest() OVERRIDE {}
3491
3492 FakeContentLayerClient client_;
3493 scoped_refptr<PushPropertiesCountingLayer> root_;
3494 scoped_refptr<PushPropertiesCountingLayer> child_;
3495 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3496 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3497 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3498 size_t expected_push_properties_root_;
3499 size_t expected_push_properties_child_;
3500 size_t expected_push_properties_grandchild1_;
3501 size_t expected_push_properties_grandchild2_;
3502 size_t expected_push_properties_grandchild3_;
3503 };
3504
3505 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3506 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3507 protected:
DidCommitAndDrawFrame()3508 virtual void DidCommitAndDrawFrame() OVERRIDE {
3509 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3510 switch (last_source_frame_number) {
3511 case 0:
3512 EXPECT_FALSE(root_->needs_push_properties());
3513 EXPECT_FALSE(root_->descendant_needs_push_properties());
3514 EXPECT_FALSE(child_->needs_push_properties());
3515 EXPECT_FALSE(child_->descendant_needs_push_properties());
3516 EXPECT_FALSE(grandchild1_->needs_push_properties());
3517 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3518 EXPECT_FALSE(grandchild2_->needs_push_properties());
3519 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3520 EXPECT_FALSE(grandchild3_->needs_push_properties());
3521 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3522
3523 layer_tree_host()->SetRootLayer(root_);
3524
3525 EXPECT_TRUE(root_->needs_push_properties());
3526 EXPECT_TRUE(root_->descendant_needs_push_properties());
3527 EXPECT_TRUE(child_->needs_push_properties());
3528 EXPECT_TRUE(child_->descendant_needs_push_properties());
3529 EXPECT_TRUE(grandchild1_->needs_push_properties());
3530 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3531 EXPECT_TRUE(grandchild2_->needs_push_properties());
3532 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3533 EXPECT_TRUE(grandchild3_->needs_push_properties());
3534 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3535 break;
3536 case 1:
3537 EndTest();
3538 break;
3539 }
3540 }
3541 };
3542
3543 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3544
3545 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3546 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3547 protected:
DidCommitAndDrawFrame()3548 virtual void DidCommitAndDrawFrame() OVERRIDE {
3549 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3550 switch (last_source_frame_number) {
3551 case 0:
3552 layer_tree_host()->SetRootLayer(root_);
3553 break;
3554 case 1:
3555 EXPECT_FALSE(root_->needs_push_properties());
3556 EXPECT_FALSE(root_->descendant_needs_push_properties());
3557 EXPECT_FALSE(child_->needs_push_properties());
3558 EXPECT_FALSE(child_->descendant_needs_push_properties());
3559 EXPECT_FALSE(grandchild1_->needs_push_properties());
3560 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3561 EXPECT_FALSE(grandchild2_->needs_push_properties());
3562 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3563 EXPECT_FALSE(grandchild3_->needs_push_properties());
3564 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3565
3566 grandchild1_->RemoveFromParent();
3567 grandchild1_->SetPosition(gfx::Point(1, 1));
3568
3569 EXPECT_FALSE(root_->needs_push_properties());
3570 EXPECT_FALSE(root_->descendant_needs_push_properties());
3571 EXPECT_FALSE(child_->needs_push_properties());
3572 EXPECT_FALSE(child_->descendant_needs_push_properties());
3573 EXPECT_FALSE(grandchild2_->needs_push_properties());
3574 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3575 EXPECT_FALSE(grandchild3_->needs_push_properties());
3576 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3577
3578 child_->AddChild(grandchild1_);
3579
3580 EXPECT_FALSE(root_->needs_push_properties());
3581 EXPECT_TRUE(root_->descendant_needs_push_properties());
3582 EXPECT_FALSE(child_->needs_push_properties());
3583 EXPECT_TRUE(child_->descendant_needs_push_properties());
3584 EXPECT_TRUE(grandchild1_->needs_push_properties());
3585 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3586 EXPECT_FALSE(grandchild2_->needs_push_properties());
3587 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3588 EXPECT_FALSE(grandchild3_->needs_push_properties());
3589 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3590
3591 grandchild2_->SetPosition(gfx::Point(1, 1));
3592
3593 EXPECT_FALSE(root_->needs_push_properties());
3594 EXPECT_TRUE(root_->descendant_needs_push_properties());
3595 EXPECT_FALSE(child_->needs_push_properties());
3596 EXPECT_TRUE(child_->descendant_needs_push_properties());
3597 EXPECT_TRUE(grandchild1_->needs_push_properties());
3598 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3599 EXPECT_TRUE(grandchild2_->needs_push_properties());
3600 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3601 EXPECT_FALSE(grandchild3_->needs_push_properties());
3602 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3603
3604 // grandchild2_ will still need a push properties.
3605 grandchild1_->RemoveFromParent();
3606
3607 EXPECT_FALSE(root_->needs_push_properties());
3608 EXPECT_TRUE(root_->descendant_needs_push_properties());
3609 EXPECT_FALSE(child_->needs_push_properties());
3610 EXPECT_TRUE(child_->descendant_needs_push_properties());
3611
3612 // grandchild3_ does not need a push properties, so recursing should
3613 // no longer be needed.
3614 grandchild2_->RemoveFromParent();
3615
3616 EXPECT_FALSE(root_->needs_push_properties());
3617 EXPECT_FALSE(root_->descendant_needs_push_properties());
3618 EXPECT_FALSE(child_->needs_push_properties());
3619 EXPECT_FALSE(child_->descendant_needs_push_properties());
3620 EndTest();
3621 break;
3622 }
3623 }
3624 };
3625
3626 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3627
3628 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3629 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3630 protected:
DidCommitAndDrawFrame()3631 virtual void DidCommitAndDrawFrame() OVERRIDE {
3632 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3633 switch (last_source_frame_number) {
3634 case 0:
3635 layer_tree_host()->SetRootLayer(root_);
3636 grandchild1_->set_persist_needs_push_properties(true);
3637 grandchild2_->set_persist_needs_push_properties(true);
3638 break;
3639 case 1:
3640 EXPECT_FALSE(root_->needs_push_properties());
3641 EXPECT_TRUE(root_->descendant_needs_push_properties());
3642 EXPECT_FALSE(child_->needs_push_properties());
3643 EXPECT_TRUE(child_->descendant_needs_push_properties());
3644 EXPECT_TRUE(grandchild1_->needs_push_properties());
3645 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3646 EXPECT_TRUE(grandchild2_->needs_push_properties());
3647 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3648 EXPECT_FALSE(grandchild3_->needs_push_properties());
3649 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3650
3651 // grandchild2_ will still need a push properties.
3652 grandchild1_->RemoveFromParent();
3653
3654 EXPECT_FALSE(root_->needs_push_properties());
3655 EXPECT_TRUE(root_->descendant_needs_push_properties());
3656 EXPECT_FALSE(child_->needs_push_properties());
3657 EXPECT_TRUE(child_->descendant_needs_push_properties());
3658
3659 // grandchild3_ does not need a push properties, so recursing should
3660 // no longer be needed.
3661 grandchild2_->RemoveFromParent();
3662
3663 EXPECT_FALSE(root_->needs_push_properties());
3664 EXPECT_FALSE(root_->descendant_needs_push_properties());
3665 EXPECT_FALSE(child_->needs_push_properties());
3666 EXPECT_FALSE(child_->descendant_needs_push_properties());
3667 EndTest();
3668 break;
3669 }
3670 }
3671 };
3672
3673 MULTI_THREAD_TEST_F(
3674 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3675
3676 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3677 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3678 protected:
DidCommitAndDrawFrame()3679 virtual void DidCommitAndDrawFrame() OVERRIDE {
3680 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3681 switch (last_source_frame_number) {
3682 case 0:
3683 layer_tree_host()->SetRootLayer(root_);
3684 break;
3685 case 1:
3686 EXPECT_FALSE(root_->needs_push_properties());
3687 EXPECT_FALSE(root_->descendant_needs_push_properties());
3688 EXPECT_FALSE(child_->needs_push_properties());
3689 EXPECT_FALSE(child_->descendant_needs_push_properties());
3690 EXPECT_FALSE(grandchild1_->needs_push_properties());
3691 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3692 EXPECT_FALSE(grandchild2_->needs_push_properties());
3693 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3694 EXPECT_FALSE(grandchild3_->needs_push_properties());
3695 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3696
3697 // Change grandchildren while their parent is not in the tree.
3698 child_->RemoveFromParent();
3699 grandchild1_->SetPosition(gfx::Point(1, 1));
3700 grandchild2_->SetPosition(gfx::Point(1, 1));
3701 root_->AddChild(child_);
3702
3703 EXPECT_FALSE(root_->needs_push_properties());
3704 EXPECT_TRUE(root_->descendant_needs_push_properties());
3705 EXPECT_TRUE(child_->needs_push_properties());
3706 EXPECT_TRUE(child_->descendant_needs_push_properties());
3707 EXPECT_TRUE(grandchild1_->needs_push_properties());
3708 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3709 EXPECT_TRUE(grandchild2_->needs_push_properties());
3710 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3711 EXPECT_TRUE(grandchild3_->needs_push_properties());
3712 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3713
3714 grandchild1_->RemoveFromParent();
3715
3716 EXPECT_FALSE(root_->needs_push_properties());
3717 EXPECT_TRUE(root_->descendant_needs_push_properties());
3718 EXPECT_TRUE(child_->needs_push_properties());
3719 EXPECT_TRUE(child_->descendant_needs_push_properties());
3720
3721 grandchild2_->RemoveFromParent();
3722
3723 EXPECT_FALSE(root_->needs_push_properties());
3724 EXPECT_TRUE(root_->descendant_needs_push_properties());
3725 EXPECT_TRUE(child_->needs_push_properties());
3726 EXPECT_TRUE(child_->descendant_needs_push_properties());
3727
3728 grandchild3_->RemoveFromParent();
3729
3730 EXPECT_FALSE(root_->needs_push_properties());
3731 EXPECT_TRUE(root_->descendant_needs_push_properties());
3732 EXPECT_TRUE(child_->needs_push_properties());
3733 EXPECT_FALSE(child_->descendant_needs_push_properties());
3734
3735 EndTest();
3736 break;
3737 }
3738 }
3739 };
3740
3741 MULTI_THREAD_TEST_F(
3742 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3743
3744 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3745 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3746 protected:
DidCommitAndDrawFrame()3747 virtual void DidCommitAndDrawFrame() OVERRIDE {
3748 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3749 switch (last_source_frame_number) {
3750 case 0:
3751 layer_tree_host()->SetRootLayer(root_);
3752 break;
3753 case 1:
3754 EXPECT_FALSE(root_->needs_push_properties());
3755 EXPECT_FALSE(root_->descendant_needs_push_properties());
3756 EXPECT_FALSE(child_->needs_push_properties());
3757 EXPECT_FALSE(child_->descendant_needs_push_properties());
3758 EXPECT_FALSE(grandchild1_->needs_push_properties());
3759 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3760 EXPECT_FALSE(grandchild2_->needs_push_properties());
3761 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3762 EXPECT_FALSE(grandchild3_->needs_push_properties());
3763 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3764
3765 child_->SetPosition(gfx::Point(1, 1));
3766 grandchild1_->SetPosition(gfx::Point(1, 1));
3767 grandchild2_->SetPosition(gfx::Point(1, 1));
3768
3769 EXPECT_FALSE(root_->needs_push_properties());
3770 EXPECT_TRUE(root_->descendant_needs_push_properties());
3771 EXPECT_TRUE(child_->needs_push_properties());
3772 EXPECT_TRUE(child_->descendant_needs_push_properties());
3773 EXPECT_TRUE(grandchild1_->needs_push_properties());
3774 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3775 EXPECT_TRUE(grandchild2_->needs_push_properties());
3776 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3777 EXPECT_FALSE(grandchild3_->needs_push_properties());
3778 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3779
3780 grandchild1_->RemoveFromParent();
3781
3782 EXPECT_FALSE(root_->needs_push_properties());
3783 EXPECT_TRUE(root_->descendant_needs_push_properties());
3784 EXPECT_TRUE(child_->needs_push_properties());
3785 EXPECT_TRUE(child_->descendant_needs_push_properties());
3786
3787 grandchild2_->RemoveFromParent();
3788
3789 EXPECT_FALSE(root_->needs_push_properties());
3790 EXPECT_TRUE(root_->descendant_needs_push_properties());
3791 EXPECT_TRUE(child_->needs_push_properties());
3792 EXPECT_FALSE(child_->descendant_needs_push_properties());
3793
3794 child_->RemoveFromParent();
3795
3796 EXPECT_FALSE(root_->needs_push_properties());
3797 EXPECT_FALSE(root_->descendant_needs_push_properties());
3798
3799 EndTest();
3800 break;
3801 }
3802 }
3803 };
3804
3805 MULTI_THREAD_TEST_F(
3806 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
3807
3808 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
3809 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3810 protected:
DidCommitAndDrawFrame()3811 virtual void DidCommitAndDrawFrame() OVERRIDE {
3812 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3813 switch (last_source_frame_number) {
3814 case 0:
3815 layer_tree_host()->SetRootLayer(root_);
3816 break;
3817 case 1:
3818 EXPECT_FALSE(root_->needs_push_properties());
3819 EXPECT_FALSE(root_->descendant_needs_push_properties());
3820 EXPECT_FALSE(child_->needs_push_properties());
3821 EXPECT_FALSE(child_->descendant_needs_push_properties());
3822 EXPECT_FALSE(grandchild1_->needs_push_properties());
3823 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3824 EXPECT_FALSE(grandchild2_->needs_push_properties());
3825 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3826 EXPECT_FALSE(grandchild3_->needs_push_properties());
3827 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3828
3829 grandchild1_->SetPosition(gfx::Point(1, 1));
3830 grandchild2_->SetPosition(gfx::Point(1, 1));
3831 child_->SetPosition(gfx::Point(1, 1));
3832
3833 EXPECT_FALSE(root_->needs_push_properties());
3834 EXPECT_TRUE(root_->descendant_needs_push_properties());
3835 EXPECT_TRUE(child_->needs_push_properties());
3836 EXPECT_TRUE(child_->descendant_needs_push_properties());
3837 EXPECT_TRUE(grandchild1_->needs_push_properties());
3838 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3839 EXPECT_TRUE(grandchild2_->needs_push_properties());
3840 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3841 EXPECT_FALSE(grandchild3_->needs_push_properties());
3842 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3843
3844 grandchild1_->RemoveFromParent();
3845
3846 EXPECT_FALSE(root_->needs_push_properties());
3847 EXPECT_TRUE(root_->descendant_needs_push_properties());
3848 EXPECT_TRUE(child_->needs_push_properties());
3849 EXPECT_TRUE(child_->descendant_needs_push_properties());
3850
3851 grandchild2_->RemoveFromParent();
3852
3853 EXPECT_FALSE(root_->needs_push_properties());
3854 EXPECT_TRUE(root_->descendant_needs_push_properties());
3855 EXPECT_TRUE(child_->needs_push_properties());
3856 EXPECT_FALSE(child_->descendant_needs_push_properties());
3857
3858 child_->RemoveFromParent();
3859
3860 EXPECT_FALSE(root_->needs_push_properties());
3861 EXPECT_FALSE(root_->descendant_needs_push_properties());
3862
3863 EndTest();
3864 break;
3865 }
3866 }
3867 };
3868
3869 MULTI_THREAD_TEST_F(
3870 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
3871
3872 // This test verifies that the tree activation callback is invoked correctly.
3873 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
3874 public:
LayerTreeHostTestTreeActivationCallback()3875 LayerTreeHostTestTreeActivationCallback()
3876 : num_commits_(0), callback_count_(0) {}
3877
BeginTest()3878 virtual void BeginTest() OVERRIDE {
3879 EXPECT_TRUE(HasImplThread());
3880 PostSetNeedsCommitToMainThread();
3881 }
3882
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)3883 virtual DrawResult PrepareToDrawOnThread(
3884 LayerTreeHostImpl* host_impl,
3885 LayerTreeHostImpl::FrameData* frame_data,
3886 DrawResult draw_result) OVERRIDE {
3887 ++num_commits_;
3888 switch (num_commits_) {
3889 case 1:
3890 EXPECT_EQ(0, callback_count_);
3891 callback_count_ = 0;
3892 SetCallback(true);
3893 PostSetNeedsCommitToMainThread();
3894 break;
3895 case 2:
3896 EXPECT_EQ(1, callback_count_);
3897 callback_count_ = 0;
3898 SetCallback(false);
3899 PostSetNeedsCommitToMainThread();
3900 break;
3901 case 3:
3902 EXPECT_EQ(0, callback_count_);
3903 callback_count_ = 0;
3904 EndTest();
3905 break;
3906 default:
3907 ADD_FAILURE() << num_commits_;
3908 EndTest();
3909 break;
3910 }
3911 return LayerTreeHostTest::PrepareToDrawOnThread(
3912 host_impl, frame_data, draw_result);
3913 }
3914
AfterTest()3915 virtual void AfterTest() OVERRIDE { EXPECT_EQ(3, num_commits_); }
3916
SetCallback(bool enable)3917 void SetCallback(bool enable) {
3918 output_surface()->SetTreeActivationCallback(
3919 enable
3920 ? base::Bind(
3921 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
3922 base::Unretained(this))
3923 : base::Closure());
3924 }
3925
ActivationCallback()3926 void ActivationCallback() { ++callback_count_; }
3927
3928 int num_commits_;
3929 int callback_count_;
3930 };
3931
TEST_F(LayerTreeHostTestTreeActivationCallback,DirectRenderer)3932 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
3933 RunTest(true, false, true);
3934 }
3935
TEST_F(LayerTreeHostTestTreeActivationCallback,DelegatingRenderer)3936 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
3937 RunTest(true, true, true);
3938 }
3939
3940 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
3941 public:
LayerInvalidateCausesDraw()3942 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
3943
BeginTest()3944 virtual void BeginTest() OVERRIDE {
3945 ASSERT_TRUE(!!invalidate_layer_.get())
3946 << "Derived tests must set this in SetupTree";
3947
3948 // One initial commit.
3949 PostSetNeedsCommitToMainThread();
3950 }
3951
DidCommitAndDrawFrame()3952 virtual void DidCommitAndDrawFrame() OVERRIDE {
3953 // After commit, invalidate the layer. This should cause a commit.
3954 if (layer_tree_host()->source_frame_number() == 1)
3955 invalidate_layer_->SetNeedsDisplay();
3956 }
3957
DrawLayersOnThread(LayerTreeHostImpl * impl)3958 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3959 num_draws_++;
3960 if (impl->active_tree()->source_frame_number() == 1)
3961 EndTest();
3962 }
3963
CommitCompleteOnThread(LayerTreeHostImpl * impl)3964 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3965 num_commits_++;
3966 }
3967
AfterTest()3968 virtual void AfterTest() OVERRIDE {
3969 EXPECT_GE(2, num_commits_);
3970 EXPECT_GE(2, num_draws_);
3971 }
3972
3973 protected:
3974 scoped_refptr<Layer> invalidate_layer_;
3975
3976 private:
3977 int num_commits_;
3978 int num_draws_;
3979 };
3980
3981 // VideoLayer must support being invalidated and then passing that along
3982 // to the compositor thread, even though no resources are updated in
3983 // response to that invalidation.
3984 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
3985 public:
SetupTree()3986 virtual void SetupTree() OVERRIDE {
3987 LayerTreeHostTest::SetupTree();
3988 scoped_refptr<VideoLayer> video_layer =
3989 VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
3990 video_layer->SetBounds(gfx::Size(10, 10));
3991 video_layer->SetIsDrawable(true);
3992 layer_tree_host()->root_layer()->AddChild(video_layer);
3993
3994 invalidate_layer_ = video_layer;
3995 }
3996
3997 private:
3998 FakeVideoFrameProvider provider_;
3999 };
4000
4001 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4002
4003 // IOSurfaceLayer must support being invalidated and then passing that along
4004 // to the compositor thread, even though no resources are updated in
4005 // response to that invalidation.
4006 class LayerTreeHostTestIOSurfaceLayerInvalidate
4007 : public LayerInvalidateCausesDraw {
4008 public:
SetupTree()4009 virtual void SetupTree() OVERRIDE {
4010 LayerTreeHostTest::SetupTree();
4011 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4012 layer->SetBounds(gfx::Size(10, 10));
4013 uint32_t fake_io_surface_id = 7;
4014 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4015 layer->SetIsDrawable(true);
4016 layer_tree_host()->root_layer()->AddChild(layer);
4017
4018 invalidate_layer_ = layer;
4019 }
4020 };
4021
4022 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4023 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4024 LayerTreeHostTestIOSurfaceLayerInvalidate);
4025
4026 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4027 protected:
SetupTree()4028 virtual void SetupTree() OVERRIDE {
4029 root_layer_ = Layer::Create();
4030 root_layer_->SetPosition(gfx::Point());
4031 root_layer_->SetBounds(gfx::Size(10, 10));
4032
4033 parent_layer_ = SolidColorLayer::Create();
4034 parent_layer_->SetPosition(gfx::Point());
4035 parent_layer_->SetBounds(gfx::Size(10, 10));
4036 parent_layer_->SetIsDrawable(true);
4037 root_layer_->AddChild(parent_layer_);
4038
4039 child_layer_ = SolidColorLayer::Create();
4040 child_layer_->SetPosition(gfx::Point());
4041 child_layer_->SetBounds(gfx::Size(10, 10));
4042 child_layer_->SetIsDrawable(true);
4043 parent_layer_->AddChild(child_layer_);
4044
4045 layer_tree_host()->SetRootLayer(root_layer_);
4046 LayerTreeHostTest::SetupTree();
4047 }
4048
BeginTest()4049 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4050
DidCommitAndDrawFrame()4051 virtual void DidCommitAndDrawFrame() OVERRIDE {
4052 switch (layer_tree_host()->source_frame_number()) {
4053 case 1:
4054 // The layer type used does not need to push properties every frame.
4055 EXPECT_FALSE(child_layer_->needs_push_properties());
4056
4057 // Change the bounds of the child layer, but make it skipped
4058 // by CalculateDrawProperties.
4059 parent_layer_->SetOpacity(0.f);
4060 child_layer_->SetBounds(gfx::Size(5, 5));
4061 break;
4062 case 2:
4063 // The bounds of the child layer were pushed to the impl side.
4064 EXPECT_FALSE(child_layer_->needs_push_properties());
4065
4066 EndTest();
4067 break;
4068 }
4069 }
4070
DidActivateTreeOnThread(LayerTreeHostImpl * impl)4071 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4072 LayerImpl* root = impl->active_tree()->root_layer();
4073 LayerImpl* parent = root->children()[0];
4074 LayerImpl* child = parent->children()[0];
4075
4076 switch (impl->active_tree()->source_frame_number()) {
4077 case 1:
4078 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4079 break;
4080 }
4081 }
4082
AfterTest()4083 virtual void AfterTest() OVERRIDE {}
4084
4085 scoped_refptr<Layer> root_layer_;
4086 scoped_refptr<SolidColorLayer> parent_layer_;
4087 scoped_refptr<SolidColorLayer> child_layer_;
4088 };
4089
4090 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4091
4092 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4093 protected:
InitializeSettings(LayerTreeSettings * settings)4094 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4095 settings->impl_side_painting = true;
4096 }
4097
SetupTree()4098 virtual void SetupTree() OVERRIDE {
4099 root_layer_ = FakePictureLayer::Create(&client_);
4100 root_layer_->SetBounds(gfx::Size(10, 10));
4101
4102 layer_tree_host()->SetRootLayer(root_layer_);
4103 LayerTreeHostTest::SetupTree();
4104 }
4105
BeginTest()4106 virtual void BeginTest() OVERRIDE {
4107 // The viewport is empty, but we still need to update layers on the main
4108 // thread.
4109 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4110 PostSetNeedsCommitToMainThread();
4111 }
4112
DidCommit()4113 virtual void DidCommit() OVERRIDE {
4114 // The layer should be updated even though the viewport is empty, so we
4115 // are capable of drawing it on the impl tree.
4116 EXPECT_GT(root_layer_->update_count(), 0u);
4117 EndTest();
4118 }
4119
AfterTest()4120 virtual void AfterTest() OVERRIDE {}
4121
4122 FakeContentLayerClient client_;
4123 scoped_refptr<FakePictureLayer> root_layer_;
4124 };
4125
4126 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4127
4128 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4129 public:
LayerTreeHostTestAbortEvictedTextures()4130 LayerTreeHostTestAbortEvictedTextures()
4131 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4132
4133 protected:
SetupTree()4134 virtual void SetupTree() OVERRIDE {
4135 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4136 root_layer->SetBounds(gfx::Size(200, 200));
4137 root_layer->SetIsDrawable(true);
4138
4139 layer_tree_host()->SetRootLayer(root_layer);
4140 LayerTreeHostTest::SetupTree();
4141 }
4142
BeginTest()4143 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4144
WillBeginMainFrame()4145 virtual void WillBeginMainFrame() OVERRIDE {
4146 num_will_begin_main_frames_++;
4147 switch (num_will_begin_main_frames_) {
4148 case 2:
4149 // Send a redraw to the compositor thread. This will (wrongly) be
4150 // ignored unless aborting resets the texture state.
4151 layer_tree_host()->SetNeedsRedraw();
4152 break;
4153 }
4154 }
4155
BeginCommitOnThread(LayerTreeHostImpl * impl)4156 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4157 num_impl_commits_++;
4158 }
4159
DrawLayersOnThread(LayerTreeHostImpl * impl)4160 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4161 switch (impl->SourceAnimationFrameNumber()) {
4162 case 1:
4163 // Prevent draws until commit.
4164 impl->active_tree()->SetContentsTexturesPurged();
4165 EXPECT_FALSE(impl->CanDraw());
4166 // Trigger an abortable commit.
4167 impl->SetNeedsCommit();
4168 break;
4169 case 2:
4170 EndTest();
4171 break;
4172 }
4173 }
4174
AfterTest()4175 virtual void AfterTest() OVERRIDE {
4176 // Ensure that the commit was truly aborted.
4177 EXPECT_EQ(2, num_will_begin_main_frames_);
4178 EXPECT_EQ(1, num_impl_commits_);
4179 }
4180
4181 private:
4182 int num_will_begin_main_frames_;
4183 int num_impl_commits_;
4184 };
4185
4186 // Commits can only be aborted when using the thread proxy.
4187 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4188
4189 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4190 protected:
InitializeSettings(LayerTreeSettings * settings)4191 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4192 settings->impl_side_painting = true;
4193 }
4194
CreateFakeOutputSurface(bool fallback)4195 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
4196 OVERRIDE {
4197 scoped_refptr<TestContextProvider> context_provider =
4198 TestContextProvider::Create();
4199 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
4200 if (delegating_renderer())
4201 return FakeOutputSurface::CreateDelegating3d(context_provider);
4202 else
4203 return FakeOutputSurface::Create3d(context_provider);
4204 }
4205
SetupTree()4206 virtual void SetupTree() OVERRIDE {
4207 client_.set_fill_with_nonsolid_color(true);
4208 scoped_refptr<FakePictureLayer> root_layer =
4209 FakePictureLayer::Create(&client_);
4210 root_layer->SetBounds(gfx::Size(6000, 6000));
4211 root_layer->SetIsDrawable(true);
4212
4213 layer_tree_host()->SetRootLayer(root_layer);
4214 LayerTreeHostTest::SetupTree();
4215 }
4216
BeginTest()4217 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4218
DidActivateTreeOnThread(LayerTreeHostImpl * impl)4219 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4220 TestWebGraphicsContext3D* context = TestContext();
4221
4222 // Expect that the transfer buffer memory used is equal to the
4223 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4224 EXPECT_EQ(1024 * 1024u, context->max_used_transfer_buffer_usage_bytes());
4225 EndTest();
4226 }
4227
AfterTest()4228 virtual void AfterTest() OVERRIDE {}
4229
4230 private:
4231 FakeContentLayerClient client_;
4232 };
4233
4234 // Impl-side painting is a multi-threaded compositor feature.
4235 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4236
4237 // Test ensuring that memory limits are sent to the prioritized resource
4238 // manager.
4239 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4240 public:
LayerTreeHostTestMemoryLimits()4241 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4242
BeginTest()4243 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4244
WillCommit()4245 virtual void WillCommit() OVERRIDE {
4246 // Some commits are aborted, so increment number of attempted commits here.
4247 num_commits_++;
4248 }
4249
DidCommit()4250 virtual void DidCommit() OVERRIDE {
4251 switch (num_commits_) {
4252 case 1:
4253 // Verify default values.
4254 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4255 layer_tree_host()
4256 ->contents_texture_manager()
4257 ->MaxMemoryLimitBytes());
4258 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4259 layer_tree_host()
4260 ->contents_texture_manager()
4261 ->ExternalPriorityCutoff());
4262 PostSetNeedsCommitToMainThread();
4263 break;
4264 case 2:
4265 // The values should remain the same until the commit after the policy
4266 // is changed.
4267 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4268 layer_tree_host()
4269 ->contents_texture_manager()
4270 ->MaxMemoryLimitBytes());
4271 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4272 layer_tree_host()
4273 ->contents_texture_manager()
4274 ->ExternalPriorityCutoff());
4275 break;
4276 case 3:
4277 // Verify values were correctly passed.
4278 EXPECT_EQ(16u * 1024u * 1024u,
4279 layer_tree_host()
4280 ->contents_texture_manager()
4281 ->MaxMemoryLimitBytes());
4282 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4283 layer_tree_host()
4284 ->contents_texture_manager()
4285 ->ExternalPriorityCutoff());
4286 EndTest();
4287 break;
4288 case 4:
4289 // Make sure no extra commits happen.
4290 NOTREACHED();
4291 break;
4292 }
4293 }
4294
CommitCompleteOnThread(LayerTreeHostImpl * impl)4295 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4296 switch (num_commits_) {
4297 case 1:
4298 break;
4299 case 2:
4300 // This will trigger a commit because the priority cutoff has changed.
4301 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4302 16u * 1024u * 1024u,
4303 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4304 1000));
4305 break;
4306 case 3:
4307 // This will not trigger a commit because the priority cutoff has not
4308 // changed, and there is already enough memory for all allocations.
4309 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4310 32u * 1024u * 1024u,
4311 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4312 1000));
4313 break;
4314 case 4:
4315 NOTREACHED();
4316 break;
4317 }
4318 }
4319
AfterTest()4320 virtual void AfterTest() OVERRIDE {}
4321
4322 private:
4323 int num_commits_;
4324 };
4325
4326 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4327
4328 } // namespace
4329
4330 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4331 : public LayerTreeHostTest {
4332 protected:
LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()4333 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4334 : first_output_surface_memory_limit_(4321234),
4335 second_output_surface_memory_limit_(1234321) {}
4336
CreateFakeOutputSurface(bool fallback)4337 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
4338 OVERRIDE {
4339 if (!first_context_provider_.get()) {
4340 first_context_provider_ = TestContextProvider::Create();
4341 } else {
4342 EXPECT_FALSE(second_context_provider_.get());
4343 second_context_provider_ = TestContextProvider::Create();
4344 }
4345
4346 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4347 ? second_context_provider_
4348 : first_context_provider_);
4349 scoped_ptr<FakeOutputSurface> output_surface;
4350 if (delegating_renderer())
4351 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4352 else
4353 output_surface = FakeOutputSurface::Create3d(provider);
4354 output_surface->SetMemoryPolicyToSetAtBind(
4355 make_scoped_ptr(new ManagedMemoryPolicy(
4356 second_context_provider_.get() ? second_output_surface_memory_limit_
4357 : first_output_surface_memory_limit_,
4358 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4359 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4360 return output_surface.Pass();
4361 }
4362
SetupTree()4363 virtual void SetupTree() OVERRIDE {
4364 root_ = FakeContentLayer::Create(&client_);
4365 root_->SetBounds(gfx::Size(20, 20));
4366 layer_tree_host()->SetRootLayer(root_);
4367 LayerTreeHostTest::SetupTree();
4368 }
4369
BeginTest()4370 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4371
DidCommitAndDrawFrame()4372 virtual void DidCommitAndDrawFrame() OVERRIDE {
4373 // Lost context sometimes takes two frames to recreate. The third frame
4374 // is sometimes aborted, so wait until the fourth frame to verify that
4375 // the memory has been set, and the fifth frame to end the test.
4376 if (layer_tree_host()->source_frame_number() < 5) {
4377 layer_tree_host()->SetNeedsCommit();
4378 } else if (layer_tree_host()->source_frame_number() == 5) {
4379 EndTest();
4380 }
4381 }
4382
SwapBuffersOnThread(LayerTreeHostImpl * impl,bool result)4383 virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
4384 bool result) OVERRIDE {
4385 switch (impl->active_tree()->source_frame_number()) {
4386 case 1:
4387 EXPECT_EQ(first_output_surface_memory_limit_,
4388 impl->memory_allocation_limit_bytes());
4389 // Lose the output surface.
4390 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4391 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4392 break;
4393 case 4:
4394 EXPECT_EQ(second_output_surface_memory_limit_,
4395 impl->memory_allocation_limit_bytes());
4396 break;
4397 }
4398 }
4399
AfterTest()4400 virtual void AfterTest() OVERRIDE {}
4401
4402 scoped_refptr<TestContextProvider> first_context_provider_;
4403 scoped_refptr<TestContextProvider> second_context_provider_;
4404 size_t first_output_surface_memory_limit_;
4405 size_t second_output_surface_memory_limit_;
4406 FakeContentLayerClient client_;
4407 scoped_refptr<FakeContentLayer> root_;
4408 };
4409
4410 // No output to copy for delegated renderers.
4411 SINGLE_AND_MULTI_THREAD_TEST_F(
4412 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4413
4414 struct TestSwapPromiseResult {
TestSwapPromiseResultcc::TestSwapPromiseResult4415 TestSwapPromiseResult()
4416 : did_swap_called(false),
4417 did_not_swap_called(false),
4418 dtor_called(false),
4419 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4420
4421 bool did_swap_called;
4422 bool did_not_swap_called;
4423 bool dtor_called;
4424 SwapPromise::DidNotSwapReason reason;
4425 base::Lock lock;
4426 };
4427
4428 class TestSwapPromise : public SwapPromise {
4429 public:
TestSwapPromise(TestSwapPromiseResult * result)4430 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4431
~TestSwapPromise()4432 virtual ~TestSwapPromise() {
4433 base::AutoLock lock(result_->lock);
4434 result_->dtor_called = true;
4435 }
4436
DidSwap(CompositorFrameMetadata * metadata)4437 virtual void DidSwap(CompositorFrameMetadata* metadata) OVERRIDE {
4438 base::AutoLock lock(result_->lock);
4439 EXPECT_FALSE(result_->did_swap_called);
4440 EXPECT_FALSE(result_->did_not_swap_called);
4441 result_->did_swap_called = true;
4442 }
4443
DidNotSwap(DidNotSwapReason reason)4444 virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE {
4445 base::AutoLock lock(result_->lock);
4446 EXPECT_FALSE(result_->did_swap_called);
4447 EXPECT_FALSE(result_->did_not_swap_called);
4448 result_->did_not_swap_called = true;
4449 result_->reason = reason;
4450 }
4451
TraceId() const4452 virtual int64 TraceId() const OVERRIDE { return 0; }
4453
4454 private:
4455 // Not owned.
4456 TestSwapPromiseResult* result_;
4457 };
4458
4459 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4460 protected:
LayerTreeHostTestBreakSwapPromise()4461 LayerTreeHostTestBreakSwapPromise()
4462 : commit_count_(0), commit_complete_count_(0) {}
4463
WillBeginMainFrame()4464 virtual void WillBeginMainFrame() OVERRIDE {
4465 ASSERT_LE(commit_count_, 2);
4466 scoped_ptr<SwapPromise> swap_promise(
4467 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4468 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4469 }
4470
BeginTest()4471 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4472
DidCommit()4473 virtual void DidCommit() OVERRIDE {
4474 commit_count_++;
4475 if (commit_count_ == 2) {
4476 // This commit will finish.
4477 layer_tree_host()->SetNeedsCommit();
4478 }
4479 }
4480
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)4481 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4482 commit_complete_count_++;
4483 if (commit_complete_count_ == 1) {
4484 // This commit will be aborted because no actual update.
4485 PostSetNeedsUpdateLayersToMainThread();
4486 } else {
4487 EndTest();
4488 }
4489 }
4490
AfterTest()4491 virtual void AfterTest() OVERRIDE {
4492 // 3 commits are scheduled. 2 completes. 1 is aborted.
4493 EXPECT_EQ(commit_count_, 3);
4494 EXPECT_EQ(commit_complete_count_, 2);
4495
4496 {
4497 // The first commit completes and causes swap buffer which finishes
4498 // the promise.
4499 base::AutoLock lock(swap_promise_result_[0].lock);
4500 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4501 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4502 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4503 }
4504
4505 {
4506 // The second commit is aborted since it contains no updates.
4507 base::AutoLock lock(swap_promise_result_[1].lock);
4508 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4509 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4510 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
4511 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4512 }
4513
4514 {
4515 // The last commit completes but it does not cause swap buffer because
4516 // there is no damage in the frame data.
4517 base::AutoLock lock(swap_promise_result_[2].lock);
4518 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4519 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4520 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4521 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4522 }
4523 }
4524
4525 int commit_count_;
4526 int commit_complete_count_;
4527 TestSwapPromiseResult swap_promise_result_[3];
4528 };
4529
4530 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4531
4532 class LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit
4533 : public LayerTreeHostTest {
4534 protected:
BeginTest()4535 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4536
DidCommit()4537 virtual void DidCommit() OVERRIDE {
4538 layer_tree_host()->SetDeferCommits(true);
4539 layer_tree_host()->SetNeedsCommit();
4540 }
4541
DidDeferCommit()4542 virtual void DidDeferCommit() OVERRIDE {
4543 layer_tree_host()->SetVisible(false);
4544 scoped_ptr<SwapPromise> swap_promise(
4545 new TestSwapPromise(&swap_promise_result_));
4546 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4547 layer_tree_host()->SetDeferCommits(false);
4548 }
4549
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,bool did_handle)4550 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4551 bool did_handle) OVERRIDE {
4552 EndTest();
4553 }
4554
AfterTest()4555 virtual void AfterTest() OVERRIDE {
4556 {
4557 base::AutoLock lock(swap_promise_result_.lock);
4558 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4559 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4560 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4561 EXPECT_TRUE(swap_promise_result_.dtor_called);
4562 }
4563 }
4564
4565 TestSwapPromiseResult swap_promise_result_;
4566 };
4567
4568 SINGLE_AND_MULTI_THREAD_TEST_F(
4569 LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit);
4570
4571 class LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit
4572 : public LayerTreeHostTest {
4573 protected:
BeginTest()4574 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4575
DidCommit()4576 virtual void DidCommit() OVERRIDE {
4577 if (TestEnded())
4578 return;
4579 layer_tree_host()->SetDeferCommits(true);
4580 layer_tree_host()->SetNeedsCommit();
4581 }
4582
DidDeferCommit()4583 virtual void DidDeferCommit() OVERRIDE {
4584 layer_tree_host()->DidLoseOutputSurface();
4585 scoped_ptr<SwapPromise> swap_promise(
4586 new TestSwapPromise(&swap_promise_result_));
4587 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4588 layer_tree_host()->SetDeferCommits(false);
4589 }
4590
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,bool did_handle)4591 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4592 bool did_handle) OVERRIDE {
4593 EndTest();
4594 // This lets the test finally commit and exit.
4595 MainThreadTaskRunner()->PostTask(
4596 FROM_HERE,
4597 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit::
4598 FindOutputSurface,
4599 base::Unretained(this)));
4600 }
4601
FindOutputSurface()4602 void FindOutputSurface() {
4603 layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(true);
4604 }
4605
AfterTest()4606 virtual void AfterTest() OVERRIDE {
4607 {
4608 base::AutoLock lock(swap_promise_result_.lock);
4609 EXPECT_FALSE(swap_promise_result_.did_swap_called);
4610 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
4611 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
4612 EXPECT_TRUE(swap_promise_result_.dtor_called);
4613 }
4614 }
4615
4616 TestSwapPromiseResult swap_promise_result_;
4617 };
4618
4619 SINGLE_AND_MULTI_THREAD_TEST_F(
4620 LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit);
4621
4622 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
4623 public:
SimpleSwapPromiseMonitor(LayerTreeHost * layer_tree_host,LayerTreeHostImpl * layer_tree_host_impl,int * set_needs_commit_count,int * set_needs_redraw_count)4624 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
4625 LayerTreeHostImpl* layer_tree_host_impl,
4626 int* set_needs_commit_count,
4627 int* set_needs_redraw_count)
4628 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
4629 set_needs_commit_count_(set_needs_commit_count) {}
4630
~SimpleSwapPromiseMonitor()4631 virtual ~SimpleSwapPromiseMonitor() {}
4632
OnSetNeedsCommitOnMain()4633 virtual void OnSetNeedsCommitOnMain() OVERRIDE {
4634 (*set_needs_commit_count_)++;
4635 }
4636
OnSetNeedsRedrawOnImpl()4637 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE {
4638 ADD_FAILURE() << "Should not get called on main thread.";
4639 }
4640
OnForwardScrollUpdateToMainThreadOnImpl()4641 virtual void OnForwardScrollUpdateToMainThreadOnImpl() OVERRIDE {
4642 ADD_FAILURE() << "Should not get called on main thread.";
4643 }
4644
4645 private:
4646 int* set_needs_commit_count_;
4647 };
4648
4649 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
4650 public:
BeginTest()4651 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4652
WillBeginMainFrame()4653 virtual void WillBeginMainFrame() OVERRIDE {
4654 if (TestEnded())
4655 return;
4656
4657 int set_needs_commit_count = 0;
4658 int set_needs_redraw_count = 0;
4659
4660 {
4661 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4662 new SimpleSwapPromiseMonitor(layer_tree_host(),
4663 NULL,
4664 &set_needs_commit_count,
4665 &set_needs_redraw_count));
4666 layer_tree_host()->SetNeedsCommit();
4667 EXPECT_EQ(1, set_needs_commit_count);
4668 EXPECT_EQ(0, set_needs_redraw_count);
4669 }
4670
4671 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
4672 // monitored.
4673 layer_tree_host()->SetNeedsCommit();
4674 EXPECT_EQ(1, set_needs_commit_count);
4675 EXPECT_EQ(0, set_needs_redraw_count);
4676
4677 {
4678 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4679 new SimpleSwapPromiseMonitor(layer_tree_host(),
4680 NULL,
4681 &set_needs_commit_count,
4682 &set_needs_redraw_count));
4683 layer_tree_host()->SetNeedsUpdateLayers();
4684 EXPECT_EQ(2, set_needs_commit_count);
4685 EXPECT_EQ(0, set_needs_redraw_count);
4686 }
4687
4688 {
4689 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
4690 new SimpleSwapPromiseMonitor(layer_tree_host(),
4691 NULL,
4692 &set_needs_commit_count,
4693 &set_needs_redraw_count));
4694 layer_tree_host()->SetNeedsAnimate();
4695 EXPECT_EQ(3, set_needs_commit_count);
4696 EXPECT_EQ(0, set_needs_redraw_count);
4697 }
4698
4699 EndTest();
4700 }
4701
AfterTest()4702 virtual void AfterTest() OVERRIDE {}
4703 };
4704
4705 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
4706
4707 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
4708 : public LayerTreeHostTest {
4709 protected:
InitializeSettings(LayerTreeSettings * settings)4710 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4711 settings->impl_side_painting = true;
4712 }
4713
SetupTree()4714 virtual void SetupTree() OVERRIDE {
4715 LayerTreeHostTest::SetupTree();
4716 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
4717 }
4718
BeginTest()4719 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4720
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)4721 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4722 host_impl->EvictAllUIResources();
4723 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
4724 // mode. Active tree should require high-res to draw after entering this
4725 // mode to ensure that high-res tiles are also required for a pending tree
4726 // to be activated.
4727 EXPECT_TRUE(host_impl->active_tree()->RequiresHighResToDraw());
4728 }
4729
DidCommit()4730 virtual void DidCommit() OVERRIDE {
4731 int frame = layer_tree_host()->source_frame_number();
4732 switch (frame) {
4733 case 1:
4734 PostSetNeedsCommitToMainThread();
4735 break;
4736 case 2:
4737 ui_resource_.reset();
4738 EndTest();
4739 break;
4740 }
4741 }
4742
AfterTest()4743 virtual void AfterTest() OVERRIDE {}
4744
4745 FakeContentLayerClient client_;
4746 scoped_ptr<FakeScopedUIResource> ui_resource_;
4747 };
4748
4749 // This test is flaky, see http://crbug.com/386199
4750 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
4751
4752 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
4753 protected:
InitializeSettings(LayerTreeSettings * settings)4754 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4755 settings->impl_side_painting = true;
4756
4757 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4758 EXPECT_FALSE(settings->gpu_rasterization_forced);
4759 }
4760
SetupTree()4761 virtual void SetupTree() OVERRIDE {
4762 LayerTreeHostTest::SetupTree();
4763
4764 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4765 layer->SetBounds(gfx::Size(10, 10));
4766 layer->SetIsDrawable(true);
4767 layer_tree_host()->root_layer()->AddChild(layer);
4768 }
4769
BeginTest()4770 virtual void BeginTest() OVERRIDE {
4771 Layer* root = layer_tree_host()->root_layer();
4772 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4773 PicturePile* pile = layer->GetPicturePileForTesting();
4774
4775 // Verify default values.
4776 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4777 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4778 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4779 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4780 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4781
4782 // Setting gpu rasterization trigger does not enable gpu rasterization.
4783 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4784 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4785 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4786
4787 PostSetNeedsCommitToMainThread();
4788 }
4789
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)4790 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4791 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4792 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4793 }
4794
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)4795 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4796 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4797 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4798 EndTest();
4799 }
4800
AfterTest()4801 virtual void AfterTest() OVERRIDE {}
4802
4803 FakeContentLayerClient layer_client_;
4804 };
4805
4806 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
4807
4808 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
4809 protected:
InitializeSettings(LayerTreeSettings * settings)4810 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4811 settings->impl_side_painting = true;
4812
4813 EXPECT_FALSE(settings->gpu_rasterization_enabled);
4814 settings->gpu_rasterization_enabled = true;
4815 }
4816
SetupTree()4817 virtual void SetupTree() OVERRIDE {
4818 LayerTreeHostTest::SetupTree();
4819
4820 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4821 layer->SetBounds(gfx::Size(10, 10));
4822 layer->SetIsDrawable(true);
4823 layer_tree_host()->root_layer()->AddChild(layer);
4824 }
4825
BeginTest()4826 virtual void BeginTest() OVERRIDE {
4827 Layer* root = layer_tree_host()->root_layer();
4828 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4829 PicturePile* pile = layer->GetPicturePileForTesting();
4830
4831 // Verify default values.
4832 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4833 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4834 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4835 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4836 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
4837
4838 // Gpu rasterization trigger is relevant.
4839 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4840 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4841 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4842
4843 // Content-based veto is relevant as well.
4844 pile->SetUnsuitableForGpuRasterizationForTesting();
4845 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
4846 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4847 // Veto will take effect when layers are updated.
4848 // The results will be verified after commit is completed below.
4849 // Since we are manually marking picture pile as unsuitable,
4850 // make sure that the layer gets a chance to update.
4851 layer->SetNeedsDisplay();
4852 PostSetNeedsCommitToMainThread();
4853 }
4854
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)4855 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4856 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
4857 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4858 }
4859
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)4860 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4861 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
4862 EXPECT_FALSE(host_impl->use_gpu_rasterization());
4863 EndTest();
4864 }
4865
AfterTest()4866 virtual void AfterTest() OVERRIDE {}
4867
4868 FakeContentLayerClient layer_client_;
4869 };
4870
4871 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
4872
4873 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
4874 protected:
InitializeSettings(LayerTreeSettings * settings)4875 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4876 settings->impl_side_painting = true;
4877
4878 EXPECT_FALSE(settings->gpu_rasterization_forced);
4879 settings->gpu_rasterization_forced = true;
4880 }
4881
SetupTree()4882 virtual void SetupTree() OVERRIDE {
4883 LayerTreeHostTest::SetupTree();
4884
4885 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
4886 layer->SetBounds(gfx::Size(10, 10));
4887 layer->SetIsDrawable(true);
4888 layer_tree_host()->root_layer()->AddChild(layer);
4889 }
4890
BeginTest()4891 virtual void BeginTest() OVERRIDE {
4892 Layer* root = layer_tree_host()->root_layer();
4893 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
4894 PicturePile* pile = layer->GetPicturePileForTesting();
4895
4896 // Verify default values.
4897 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
4898 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
4899 EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
4900 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
4901
4902 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
4903 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4904 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
4905 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
4906 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
4907
4908 // Content-based veto is irrelevant as well.
4909 pile->SetUnsuitableForGpuRasterizationForTesting();
4910 EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
4911 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
4912 // Veto will take effect when layers are updated.
4913 // The results will be verified after commit is completed below.
4914 // Since we are manually marking picture pile as unsuitable,
4915 // make sure that the layer gets a chance to update.
4916 layer->SetNeedsDisplay();
4917 PostSetNeedsCommitToMainThread();
4918 }
4919
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)4920 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4921 EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
4922 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4923 }
4924
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)4925 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
4926 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
4927 EXPECT_TRUE(host_impl->use_gpu_rasterization());
4928 EndTest();
4929 }
4930
AfterTest()4931 virtual void AfterTest() OVERRIDE {}
4932
4933 FakeContentLayerClient layer_client_;
4934 };
4935
4936 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
4937
4938 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
4939 public:
LayerTreeHostTestContinuousPainting()4940 LayerTreeHostTestContinuousPainting()
4941 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
4942
4943 protected:
4944 enum { kExpectedNumCommits = 10 };
4945
SetupTree()4946 virtual void SetupTree() OVERRIDE {
4947 scoped_refptr<Layer> root_layer = Layer::Create();
4948 root_layer->SetBounds(bounds_);
4949
4950 if (layer_tree_host()->settings().impl_side_painting) {
4951 picture_layer_ = FakePictureLayer::Create(&client_);
4952 child_layer_ = picture_layer_.get();
4953 } else {
4954 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
4955 child_layer_ = content_layer_.get();
4956 }
4957 child_layer_->SetBounds(bounds_);
4958 child_layer_->SetIsDrawable(true);
4959 root_layer->AddChild(child_layer_);
4960
4961 layer_tree_host()->SetRootLayer(root_layer);
4962 layer_tree_host()->SetViewportSize(bounds_);
4963 LayerTreeHostTest::SetupTree();
4964 }
4965
BeginTest()4966 virtual void BeginTest() OVERRIDE {
4967 MainThreadTaskRunner()->PostTask(
4968 FROM_HERE,
4969 base::Bind(
4970 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
4971 base::Unretained(this)));
4972 // Wait 50x longer than expected.
4973 double milliseconds_per_frame =
4974 1000.0 / layer_tree_host()->settings().refresh_rate;
4975 MainThreadTaskRunner()->PostDelayedTask(
4976 FROM_HERE,
4977 base::Bind(
4978 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
4979 base::Unretained(this)),
4980 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
4981 milliseconds_per_frame));
4982 }
4983
BeginMainFrame(const BeginFrameArgs & args)4984 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
4985 child_layer_->SetNeedsDisplay();
4986 }
4987
AfterTest()4988 virtual void AfterTest() OVERRIDE {
4989 EXPECT_LE(kExpectedNumCommits, num_commits_);
4990 EXPECT_LE(kExpectedNumCommits, num_draws_);
4991 int update_count = content_layer_.get()
4992 ? content_layer_->PaintContentsCount()
4993 : picture_layer_->update_count();
4994 EXPECT_LE(kExpectedNumCommits, update_count);
4995 }
4996
DrawLayersOnThread(LayerTreeHostImpl * impl)4997 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4998 if (++num_draws_ == kExpectedNumCommits)
4999 EndTest();
5000 }
5001
CommitCompleteOnThread(LayerTreeHostImpl * impl)5002 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
5003 ++num_commits_;
5004 }
5005
5006 private:
EnableContinuousPainting()5007 void EnableContinuousPainting() {
5008 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5009 debug_state.continuous_painting = true;
5010 layer_tree_host()->SetDebugState(debug_state);
5011 }
5012
DisableContinuousPainting()5013 void DisableContinuousPainting() {
5014 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5015 debug_state.continuous_painting = false;
5016 layer_tree_host()->SetDebugState(debug_state);
5017 EndTest();
5018 }
5019
5020 int num_commits_;
5021 int num_draws_;
5022 const gfx::Size bounds_;
5023 FakeContentLayerClient client_;
5024 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5025 scoped_refptr<FakePictureLayer> picture_layer_;
5026 Layer* child_layer_;
5027 };
5028
5029 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5030
5031 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5032 public:
LayerTreeHostTestActivateOnInvisible()5033 LayerTreeHostTestActivateOnInvisible()
5034 : activation_count_(0), visible_(true) {}
5035
InitializeSettings(LayerTreeSettings * settings)5036 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
5037 settings->impl_side_painting = true;
5038 }
5039
BeginTest()5040 virtual void BeginTest() OVERRIDE {
5041 // Kick off the test with a commit.
5042 PostSetNeedsCommitToMainThread();
5043 }
5044
BeginCommitOnThread(LayerTreeHostImpl * host_impl)5045 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
5046 // Make sure we don't activate using the notify signal from tile manager.
5047 host_impl->BlockNotifyReadyToActivateForTesting(true);
5048 }
5049
DidCommit()5050 virtual void DidCommit() OVERRIDE { layer_tree_host()->SetVisible(false); }
5051
DidSetVisibleOnImplTree(LayerTreeHostImpl * host_impl,bool visible)5052 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5053 bool visible) OVERRIDE {
5054 visible_ = visible;
5055
5056 // Once invisible, we can go visible again.
5057 if (!visible) {
5058 PostSetVisibleToMainThread(true);
5059 } else {
5060 EXPECT_TRUE(host_impl->active_tree()->RequiresHighResToDraw());
5061 EndTest();
5062 }
5063 }
5064
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)5065 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
5066 ++activation_count_;
5067 EXPECT_FALSE(visible_);
5068 }
5069
AfterTest()5070 virtual void AfterTest() OVERRIDE {
5071 // Ensure we activated even though the signal was blocked.
5072 EXPECT_EQ(1, activation_count_);
5073 EXPECT_TRUE(visible_);
5074 }
5075
5076 private:
5077 int activation_count_;
5078 bool visible_;
5079
5080 FakeContentLayerClient client_;
5081 scoped_refptr<FakePictureLayer> picture_layer_;
5082 };
5083
5084 // TODO(vmpstr): Enable with single thread impl-side painting.
5085 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5086
5087 // Make sure page scale and top control deltas are applied to the client even
5088 // when the LayerTreeHost doesn't have a root layer.
5089 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
5090 : public LayerTreeHostTest {
5091 public:
LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()5092 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
5093 : deltas_sent_to_client_(false) {}
5094
BeginTest()5095 virtual void BeginTest() OVERRIDE {
5096 layer_tree_host()->SetRootLayer(nullptr);
5097 info_.page_scale_delta = 3.14f;
5098 info_.top_controls_delta = 2.73f;
5099
5100 PostSetNeedsCommitToMainThread();
5101 }
5102
BeginMainFrame(const BeginFrameArgs & args)5103 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
5104 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
5105
5106 layer_tree_host()->ApplyScrollAndScale(&info_);
5107 EndTest();
5108 }
5109
ApplyViewportDeltas(const gfx::Vector2d & scroll,float scale_delta,float top_controls_delta)5110 virtual void ApplyViewportDeltas(
5111 const gfx::Vector2d& scroll,
5112 float scale_delta,
5113 float top_controls_delta) OVERRIDE {
5114 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5115 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5116 deltas_sent_to_client_ = true;
5117 }
5118
AfterTest()5119 virtual void AfterTest() OVERRIDE {
5120 EXPECT_TRUE(deltas_sent_to_client_);
5121 }
5122
5123 ScrollAndScaleSet info_;
5124 bool deltas_sent_to_client_;
5125 };
5126
5127 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5128 } // namespace cc
5129