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