Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: cc/trees/layer_tree_host_unittest.cc

Issue 1057283003: Remove parts of //cc we aren't using (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/debug/frame_rate_counter.h"
13 #include "cc/layers/content_layer.h"
14 #include "cc/layers/content_layer_client.h"
15 #include "cc/layers/io_surface_layer.h"
16 #include "cc/layers/layer_impl.h"
17 #include "cc/layers/painted_scrollbar_layer.h"
18 #include "cc/layers/picture_layer.h"
19 #include "cc/layers/solid_color_layer.h"
20 #include "cc/output/begin_frame_args.h"
21 #include "cc/output/compositor_frame_ack.h"
22 #include "cc/output/copy_output_request.h"
23 #include "cc/output/copy_output_result.h"
24 #include "cc/output/output_surface.h"
25 #include "cc/output/swap_promise.h"
26 #include "cc/quads/draw_quad.h"
27 #include "cc/quads/io_surface_draw_quad.h"
28 #include "cc/quads/tile_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_picture_pile.h"
41 #include "cc/test/fake_proxy.h"
42 #include "cc/test/fake_scoped_ui_resource.h"
43 #include "cc/test/geometry_test_utils.h"
44 #include "cc/test/impl_side_painting_settings.h"
45 #include "cc/test/layer_tree_test.h"
46 #include "cc/test/test_shared_bitmap_manager.h"
47 #include "cc/test/test_web_graphics_context_3d.h"
48 #include "cc/trees/layer_tree_host_impl.h"
49 #include "cc/trees/layer_tree_impl.h"
50 #include "cc/trees/single_thread_proxy.h"
51 #include "cc/trees/thread_proxy.h"
52 #include "gpu/GLES2/gl2extchromium.h"
53 #include "skia/ext/refptr.h"
54 #include "testing/gmock/include/gmock/gmock.h"
55 #include "third_party/khronos/GLES2/gl2.h"
56 #include "third_party/khronos/GLES2/gl2ext.h"
57 #include "third_party/skia/include/core/SkPicture.h"
58 #include "ui/gfx/frame_time.h"
59 #include "ui/gfx/geometry/point_conversions.h"
60 #include "ui/gfx/geometry/size_conversions.h"
61 #include "ui/gfx/geometry/vector2d_conversions.h"
62
63 using testing::_;
64 using testing::AnyNumber;
65 using testing::AtLeast;
66 using testing::Mock;
67
68 namespace cc {
69 namespace {
70
71 class LayerTreeHostTest : public LayerTreeTest {
72 public:
73 LayerTreeHostTest() : contents_texture_manager_(nullptr) {}
74
75 void DidInitializeOutputSurface() override {
76 contents_texture_manager_ = layer_tree_host()->contents_texture_manager();
77 }
78
79 protected:
80 PrioritizedResourceManager* contents_texture_manager_;
81 };
82
83 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
84 // when no raster tasks get scheduled.
85 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
86 public:
87 LayerTreeHostTestReadyToActivateEmpty()
88 : did_notify_ready_to_activate_(false),
89 all_tiles_required_for_activation_are_ready_to_draw_(false),
90 required_for_activation_count_(0) {}
91
92 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
93
94 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
95 const std::vector<PictureLayerImpl*>& layers =
96 impl->sync_tree()->picture_layers();
97 required_for_activation_count_ = 0;
98 for (const auto& layer : layers) {
99 FakePictureLayerImpl* fake_layer =
100 static_cast<FakePictureLayerImpl*>(layer);
101 required_for_activation_count_ +=
102 fake_layer->CountTilesRequiredForActivation();
103 }
104 }
105
106 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
107 did_notify_ready_to_activate_ = true;
108 all_tiles_required_for_activation_are_ready_to_draw_ =
109 impl->tile_manager()->IsReadyToActivate();
110 EndTest();
111 }
112
113 void AfterTest() override {
114 EXPECT_TRUE(did_notify_ready_to_activate_);
115 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
116 EXPECT_EQ(size_t(0), required_for_activation_count_);
117 }
118
119 protected:
120 bool did_notify_ready_to_activate_;
121 bool all_tiles_required_for_activation_are_ready_to_draw_;
122 size_t required_for_activation_count_;
123 };
124
125 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
126
127 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
128 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
129 class LayerTreeHostTestReadyToActivateNonEmpty
130 : public LayerTreeHostTestReadyToActivateEmpty {
131 public:
132 void SetupTree() override {
133 client_.set_fill_with_nonsolid_color(true);
134 scoped_refptr<FakePictureLayer> root_layer =
135 FakePictureLayer::Create(&client_);
136 root_layer->SetBounds(gfx::Size(1024, 1024));
137 root_layer->SetIsDrawable(true);
138
139 layer_tree_host()->SetRootLayer(root_layer);
140 LayerTreeHostTest::SetupTree();
141 }
142
143 void AfterTest() override {
144 EXPECT_TRUE(did_notify_ready_to_activate_);
145 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
146 EXPECT_LE(size_t(1), required_for_activation_count_);
147 }
148
149 private:
150 FakeContentLayerClient client_;
151 };
152
153 // Multi-thread only because in single thread the commit goes directly to the
154 // active tree, so notify ready to activate is skipped.
155 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
156
157 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
158 // no raster tasks get scheduled.
159 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
160 public:
161 LayerTreeHostTestReadyToDrawEmpty()
162 : did_notify_ready_to_draw_(false),
163 all_tiles_required_for_draw_are_ready_to_draw_(false),
164 required_for_draw_count_(0) {}
165
166 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
167
168 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
169 did_notify_ready_to_draw_ = true;
170 const std::vector<PictureLayerImpl*>& layers =
171 impl->active_tree()->picture_layers();
172 all_tiles_required_for_draw_are_ready_to_draw_ =
173 impl->tile_manager()->IsReadyToDraw();
174 for (const auto& layer : layers) {
175 FakePictureLayerImpl* fake_layer =
176 static_cast<FakePictureLayerImpl*>(layer);
177 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw();
178 }
179
180 EndTest();
181 }
182
183 void AfterTest() override {
184 EXPECT_TRUE(did_notify_ready_to_draw_);
185 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
186 EXPECT_EQ(size_t(0), required_for_draw_count_);
187 }
188
189 protected:
190 bool did_notify_ready_to_draw_;
191 bool all_tiles_required_for_draw_are_ready_to_draw_;
192 size_t required_for_draw_count_;
193 };
194
195 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
196
197 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
198 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
199 class LayerTreeHostTestReadyToDrawNonEmpty
200 : public LayerTreeHostTestReadyToDrawEmpty {
201 public:
202 void SetupTree() override {
203 client_.set_fill_with_nonsolid_color(true);
204 scoped_refptr<FakePictureLayer> root_layer =
205 FakePictureLayer::Create(&client_);
206 root_layer->SetBounds(gfx::Size(1024, 1024));
207 root_layer->SetIsDrawable(true);
208
209 layer_tree_host()->SetRootLayer(root_layer);
210 LayerTreeHostTest::SetupTree();
211 }
212
213 void AfterTest() override {
214 EXPECT_TRUE(did_notify_ready_to_draw_);
215 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
216 EXPECT_LE(size_t(1), required_for_draw_count_);
217 }
218
219 private:
220 FakeContentLayerClient client_;
221 };
222
223 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
224 // single threaded mode.
225 SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
226
227 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
228 // draw with frame 0.
229 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
230 public:
231 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
232
233 void BeginTest() override {
234 PostSetNeedsCommitToMainThread();
235 PostSetNeedsCommitToMainThread();
236 }
237
238 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
239 num_draws_++;
240 if (!impl->active_tree()->source_frame_number())
241 EndTest();
242 }
243
244 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
245 num_commits_++;
246 }
247
248 void AfterTest() override {
249 EXPECT_LE(1, num_commits_);
250 EXPECT_LE(1, num_draws_);
251 }
252
253 private:
254 int num_commits_;
255 int num_draws_;
256 };
257
258 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
259
260 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
261 // first committed frame draws should lead to another commit.
262 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
263 public:
264 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
265
266 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
267
268 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
269
270 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
271 ++num_commits_;
272 switch (num_commits_) {
273 case 1:
274 PostSetNeedsCommitToMainThread();
275 break;
276 case 2:
277 EndTest();
278 break;
279 default:
280 NOTREACHED();
281 }
282 }
283
284 void AfterTest() override {
285 EXPECT_EQ(2, num_commits_);
286 EXPECT_LE(1, num_draws_);
287 }
288
289 private:
290 int num_commits_;
291 int num_draws_;
292 };
293
294 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
295
296 // Verify that we pass property values in PushPropertiesTo.
297 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
298 protected:
299 void SetupTree() override {
300 scoped_refptr<Layer> root = Layer::Create();
301 root->CreateRenderSurface();
302 root->SetBounds(gfx::Size(10, 10));
303 layer_tree_host()->SetRootLayer(root);
304 LayerTreeHostTest::SetupTree();
305 }
306
307 enum Properties {
308 STARTUP,
309 BOUNDS,
310 HIDE_LAYER_AND_SUBTREE,
311 DRAWS_CONTENT,
312 DONE,
313 };
314
315 void BeginTest() override {
316 index_ = STARTUP;
317 PostSetNeedsCommitToMainThread();
318 }
319
320 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
321 VerifyAfterValues(impl->active_tree()->root_layer());
322 }
323
324 void DidCommitAndDrawFrame() override {
325 SetBeforeValues(layer_tree_host()->root_layer());
326 VerifyBeforeValues(layer_tree_host()->root_layer());
327
328 ++index_;
329 if (index_ == DONE) {
330 EndTest();
331 return;
332 }
333
334 SetAfterValues(layer_tree_host()->root_layer());
335 }
336
337 void AfterTest() override {}
338
339 void VerifyBeforeValues(Layer* layer) {
340 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
341 EXPECT_FALSE(layer->hide_layer_and_subtree());
342 EXPECT_FALSE(layer->DrawsContent());
343 }
344
345 void SetBeforeValues(Layer* layer) {
346 layer->SetBounds(gfx::Size(10, 10));
347 layer->SetHideLayerAndSubtree(false);
348 layer->SetIsDrawable(false);
349 }
350
351 void VerifyAfterValues(LayerImpl* layer) {
352 switch (static_cast<Properties>(index_)) {
353 case STARTUP:
354 case DONE:
355 break;
356 case BOUNDS:
357 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
358 break;
359 case HIDE_LAYER_AND_SUBTREE:
360 EXPECT_TRUE(layer->hide_layer_and_subtree());
361 break;
362 case DRAWS_CONTENT:
363 EXPECT_TRUE(layer->DrawsContent());
364 break;
365 }
366 }
367
368 void SetAfterValues(Layer* layer) {
369 switch (static_cast<Properties>(index_)) {
370 case STARTUP:
371 case DONE:
372 break;
373 case BOUNDS:
374 layer->SetBounds(gfx::Size(20, 20));
375 break;
376 case HIDE_LAYER_AND_SUBTREE:
377 layer->SetHideLayerAndSubtree(true);
378 break;
379 case DRAWS_CONTENT:
380 layer->SetIsDrawable(true);
381 break;
382 }
383 }
384
385 int index_;
386 };
387
388 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
389
390 // 1 setNeedsRedraw after the first commit has completed should lead to 1
391 // additional draw.
392 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
393 public:
394 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
395
396 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
397
398 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
399 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
400 if (!num_draws_) {
401 // Redraw again to verify that the second redraw doesn't commit.
402 PostSetNeedsRedrawToMainThread();
403 } else {
404 EndTest();
405 }
406 num_draws_++;
407 }
408
409 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
410 EXPECT_EQ(0, num_draws_);
411 num_commits_++;
412 }
413
414 void AfterTest() override {
415 EXPECT_GE(2, num_draws_);
416 EXPECT_EQ(1, num_commits_);
417 }
418
419 private:
420 int num_commits_;
421 int num_draws_;
422 };
423
424 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
425
426 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
427 // must contain invalid_rect.
428 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
429 public:
430 LayerTreeHostTestSetNeedsRedrawRect()
431 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
432
433 void BeginTest() override {
434 if (layer_tree_host()->settings().impl_side_painting)
435 root_layer_ = FakePictureLayer::Create(&client_);
436 else
437 root_layer_ = ContentLayer::Create(&client_);
438 root_layer_->SetIsDrawable(true);
439 root_layer_->SetBounds(bounds_);
440 layer_tree_host()->SetRootLayer(root_layer_);
441 layer_tree_host()->SetViewportSize(bounds_);
442 PostSetNeedsCommitToMainThread();
443 }
444
445 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
446 LayerTreeHostImpl::FrameData* frame_data,
447 DrawResult draw_result) override {
448 EXPECT_EQ(DRAW_SUCCESS, draw_result);
449
450 gfx::RectF root_damage_rect;
451 if (!frame_data->render_passes.empty())
452 root_damage_rect = frame_data->render_passes.back()->damage_rect;
453
454 if (!num_draws_) {
455 // If this is the first frame, expect full frame damage.
456 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_));
457 } else {
458 // Check that invalid_rect_ is indeed repainted.
459 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
460 }
461
462 return draw_result;
463 }
464
465 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
466 if (!num_draws_) {
467 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
468 } else {
469 EndTest();
470 }
471 num_draws_++;
472 }
473
474 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
475
476 private:
477 int num_draws_;
478 const gfx::Size bounds_;
479 const gfx::Rect invalid_rect_;
480 FakeContentLayerClient client_;
481 scoped_refptr<Layer> root_layer_;
482 };
483
484 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
485
486 // Ensure the texture size of the pending and active trees are identical when a
487 // layer is not in the viewport and a resize happens on the viewport
488 class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
489 public:
490 LayerTreeHostTestGpuRasterDeviceSizeChanged()
491 : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {}
492
493 void BeginTest() override {
494 client_.set_fill_with_nonsolid_color(true);
495 root_layer_ = FakePictureLayer::Create(&client_);
496 root_layer_->SetIsDrawable(true);
497 gfx::Transform transform;
498 // Translate the layer out of the viewport to force it to not update its
499 // tile size via PushProperties.
500 transform.Translate(10000.0, 10000.0);
501 root_layer_->SetTransform(transform);
502 root_layer_->SetBounds(bounds_);
503 layer_tree_host()->SetRootLayer(root_layer_);
504 layer_tree_host()->SetViewportSize(bounds_);
505
506 PostSetNeedsCommitToMainThread();
507 }
508
509 void InitializeSettings(LayerTreeSettings* settings) override {
510 settings->gpu_rasterization_enabled = true;
511 settings->gpu_rasterization_forced = true;
512 }
513
514 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
515 // Perform 2 commits.
516 if (!num_draws_) {
517 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
518 } else {
519 EndTest();
520 }
521 num_draws_++;
522 }
523
524 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
525 if (num_draws_ == 2) {
526 auto pending_tree = host_impl->pending_tree();
527 auto pending_layer_impl =
528 static_cast<FakePictureLayerImpl*>(pending_tree->root_layer());
529 EXPECT_NE(pending_layer_impl, nullptr);
530
531 auto active_tree = host_impl->pending_tree();
532 auto active_layer_impl =
533 static_cast<FakePictureLayerImpl*>(active_tree->root_layer());
534 EXPECT_NE(pending_layer_impl, nullptr);
535
536 auto active_tiling_set = active_layer_impl->picture_layer_tiling_set();
537 auto active_tiling = active_tiling_set->tiling_at(0);
538 auto pending_tiling_set = pending_layer_impl->picture_layer_tiling_set();
539 auto pending_tiling = pending_tiling_set->tiling_at(0);
540 EXPECT_EQ(
541 pending_tiling->TilingDataForTesting().max_texture_size().width(),
542 active_tiling->TilingDataForTesting().max_texture_size().width());
543 }
544 }
545
546 void DidCommitAndDrawFrame() override {
547 // On the second commit, resize the viewport.
548 if (num_draws_ == 1) {
549 layer_tree_host()->SetViewportSize(gfx::Size(400, 64));
550 }
551 }
552
553 void AfterTest() override {}
554
555 private:
556 int num_draws_;
557 const gfx::Size bounds_;
558 const gfx::Rect invalid_rect_;
559 FakeContentLayerClient client_;
560 scoped_refptr<FakePictureLayer> root_layer_;
561 };
562
563 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
564 LayerTreeHostTestGpuRasterDeviceSizeChanged);
565
566 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
567 public:
568 void InitializeSettings(LayerTreeSettings* settings) override {
569 settings->layer_transforms_should_scale_layer_contents = true;
570 }
571
572 void SetupTree() override {
573 root_layer_ = Layer::Create();
574 root_layer_->SetBounds(gfx::Size(10, 20));
575 root_layer_->CreateRenderSurface();
576
577 if (layer_tree_host()->settings().impl_side_painting)
578 scaled_layer_ = FakePictureLayer::Create(&client_);
579 else
580 scaled_layer_ = FakeContentLayer::Create(&client_);
581 scaled_layer_->SetBounds(gfx::Size(1, 1));
582 root_layer_->AddChild(scaled_layer_);
583
584 layer_tree_host()->SetRootLayer(root_layer_);
585 LayerTreeHostTest::SetupTree();
586 }
587
588 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
589
590 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
591 if (host_impl->active_tree()->source_frame_number() == 1)
592 EndTest();
593 }
594
595 void DidCommit() override {
596 switch (layer_tree_host()->source_frame_number()) {
597 case 1:
598 // SetBounds grows the layer and exposes new content.
599 if (layer_tree_host()->settings().impl_side_painting) {
600 scaled_layer_->SetBounds(gfx::Size(4, 4));
601 } else {
602 // Changing the device scale factor causes a commit. It also changes
603 // the content bounds of |scaled_layer_|, which should not generate
604 // a second commit as a result.
605 layer_tree_host()->SetDeviceScaleFactor(4.f);
606 }
607 break;
608 default:
609 // No extra commits.
610 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
611 }
612 }
613
614 void AfterTest() override {
615 EXPECT_EQ(gfx::Size(4, 4).ToString(),
616 scaled_layer_->content_bounds().ToString());
617 }
618
619 private:
620 FakeContentLayerClient client_;
621 scoped_refptr<Layer> root_layer_;
622 scoped_refptr<Layer> scaled_layer_;
623 };
624
625 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
626
627 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
628 : public LayerTreeHostTest {
629 public:
630 void InitializeSettings(LayerTreeSettings* settings) override {
631 settings->layer_transforms_should_scale_layer_contents = true;
632 }
633
634 void SetupTree() override {
635 root_layer_ = Layer::Create();
636 root_layer_->SetBounds(gfx::Size(10, 20));
637 root_layer_->CreateRenderSurface();
638
639 bool paint_scrollbar = true;
640 bool has_thumb = false;
641 scrollbar_ = FakePaintedScrollbarLayer::Create(
642 paint_scrollbar, has_thumb, root_layer_->id());
643 scrollbar_->SetPosition(gfx::Point(0, 10));
644 scrollbar_->SetBounds(gfx::Size(10, 10));
645
646 root_layer_->AddChild(scrollbar_);
647
648 layer_tree_host()->SetRootLayer(root_layer_);
649 LayerTreeHostTest::SetupTree();
650 }
651
652 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
653
654 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
655 if (host_impl->active_tree()->source_frame_number() == 1)
656 EndTest();
657 }
658
659 void DidCommit() override {
660 switch (layer_tree_host()->source_frame_number()) {
661 case 1:
662 // Changing the device scale factor causes a commit. It also changes
663 // the content bounds of |scrollbar_|, which should not generate
664 // a second commit as a result.
665 layer_tree_host()->SetDeviceScaleFactor(4.f);
666 break;
667 default:
668 // No extra commits.
669 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
670 }
671 }
672
673 void AfterTest() override {
674 EXPECT_EQ(gfx::Size(40, 40).ToString(),
675 scrollbar_->internal_content_bounds().ToString());
676 }
677
678 private:
679 FakeContentLayerClient client_;
680 scoped_refptr<Layer> root_layer_;
681 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
682 };
683
684 SINGLE_AND_MULTI_THREAD_TEST_F(
685 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
686
687 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
688 public:
689 LayerTreeHostTestSetNextCommitForcesRedraw()
690 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
691
692 void BeginTest() override {
693 if (layer_tree_host()->settings().impl_side_painting)
694 root_layer_ = FakePictureLayer::Create(&client_);
695 else
696 root_layer_ = ContentLayer::Create(&client_);
697 root_layer_->SetIsDrawable(true);
698 root_layer_->SetBounds(bounds_);
699 layer_tree_host()->SetRootLayer(root_layer_);
700 layer_tree_host()->SetViewportSize(bounds_);
701 PostSetNeedsCommitToMainThread();
702 }
703
704 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
705 if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
706 host_impl->SetNeedsRedrawRect(invalid_rect_);
707 }
708
709 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
710 LayerTreeHostImpl::FrameData* frame_data,
711 DrawResult draw_result) override {
712 EXPECT_EQ(DRAW_SUCCESS, draw_result);
713
714 gfx::RectF root_damage_rect;
715 if (!frame_data->render_passes.empty())
716 root_damage_rect = frame_data->render_passes.back()->damage_rect;
717
718 switch (num_draws_) {
719 case 0:
720 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
721 break;
722 case 1:
723 case 2:
724 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
725 break;
726 case 3:
727 EXPECT_EQ(invalid_rect_, root_damage_rect);
728 break;
729 case 4:
730 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
731 break;
732 default:
733 NOTREACHED();
734 }
735
736 return draw_result;
737 }
738
739 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
740 switch (num_draws_) {
741 case 0:
742 case 1:
743 // Cycle through a couple of empty commits to ensure we're observing the
744 // right behavior
745 PostSetNeedsCommitToMainThread();
746 break;
747 case 2:
748 // Should force full frame damage on the next commit
749 PostSetNextCommitForcesRedrawToMainThread();
750 PostSetNeedsCommitToMainThread();
751 if (host_impl->settings().impl_side_painting)
752 host_impl->BlockNotifyReadyToActivateForTesting(true);
753 else
754 num_draws_++;
755 break;
756 case 3:
757 host_impl->BlockNotifyReadyToActivateForTesting(false);
758 break;
759 default:
760 EndTest();
761 break;
762 }
763 num_draws_++;
764 }
765
766 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
767
768 private:
769 int num_draws_;
770 const gfx::Size bounds_;
771 const gfx::Rect invalid_rect_;
772 FakeContentLayerClient client_;
773 scoped_refptr<Layer> root_layer_;
774 };
775
776 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
777 LayerTreeHostTestSetNextCommitForcesRedraw);
778
779 // Tests that if a layer is not drawn because of some reason in the parent then
780 // its damage is preserved until the next time it is drawn.
781 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
782 public:
783 LayerTreeHostTestUndrawnLayersDamageLater() {}
784
785 void InitializeSettings(LayerTreeSettings* settings) override {
786 // If we don't set the minimum contents scale, it's harder to verify whether
787 // the damage we get is correct. For other scale amounts, please see
788 // LayerTreeHostTestDamageWithScale.
789 settings->minimum_contents_scale = 1.f;
790 }
791
792 void SetupTree() override {
793 if (layer_tree_host()->settings().impl_side_painting)
794 root_layer_ = FakePictureLayer::Create(&client_);
795 else
796 root_layer_ = ContentLayer::Create(&client_);
797 root_layer_->SetIsDrawable(true);
798 root_layer_->SetBounds(gfx::Size(50, 50));
799 layer_tree_host()->SetRootLayer(root_layer_);
800
801 // The initially transparent layer has a larger child layer, which is
802 // not initially drawn because of the this (parent) layer.
803 if (layer_tree_host()->settings().impl_side_painting)
804 parent_layer_ = FakePictureLayer::Create(&client_);
805 else
806 parent_layer_ = FakeContentLayer::Create(&client_);
807 parent_layer_->SetBounds(gfx::Size(15, 15));
808 parent_layer_->SetOpacity(0.0f);
809 root_layer_->AddChild(parent_layer_);
810
811 if (layer_tree_host()->settings().impl_side_painting)
812 child_layer_ = FakePictureLayer::Create(&client_);
813 else
814 child_layer_ = FakeContentLayer::Create(&client_);
815 child_layer_->SetBounds(gfx::Size(25, 25));
816 parent_layer_->AddChild(child_layer_);
817
818 LayerTreeHostTest::SetupTree();
819 }
820
821 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
822
823 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
824 LayerTreeHostImpl::FrameData* frame_data,
825 DrawResult draw_result) override {
826 EXPECT_EQ(DRAW_SUCCESS, draw_result);
827
828 gfx::RectF root_damage_rect;
829 if (!frame_data->render_passes.empty())
830 root_damage_rect = frame_data->render_passes.back()->damage_rect;
831
832 // The first time, the whole view needs be drawn.
833 // Afterwards, just the opacity of surface_layer1 is changed a few times,
834 // and each damage should be the bounding box of it and its child. If this
835 // was working improperly, the damage might not include its childs bounding
836 // box.
837 switch (host_impl->active_tree()->source_frame_number()) {
838 case 0:
839 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
840 break;
841 case 1:
842 case 2:
843 case 3:
844 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
845 break;
846 default:
847 NOTREACHED();
848 }
849
850 return draw_result;
851 }
852
853 void DidCommitAndDrawFrame() override {
854 switch (layer_tree_host()->source_frame_number()) {
855 case 1:
856 // Test not owning the surface.
857 parent_layer_->SetOpacity(1.0f);
858 break;
859 case 2:
860 parent_layer_->SetOpacity(0.0f);
861 break;
862 case 3:
863 // Test owning the surface.
864 parent_layer_->SetOpacity(0.5f);
865 parent_layer_->SetForceRenderSurface(true);
866 break;
867 case 4:
868 EndTest();
869 break;
870 default:
871 NOTREACHED();
872 }
873 }
874
875 void AfterTest() override {}
876
877 private:
878 FakeContentLayerClient client_;
879 scoped_refptr<Layer> root_layer_;
880 scoped_refptr<Layer> parent_layer_;
881 scoped_refptr<Layer> child_layer_;
882 };
883
884 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
885
886 // Tests that if a layer is not drawn because of some reason in the parent then
887 // its damage is preserved until the next time it is drawn.
888 class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest {
889 public:
890 LayerTreeHostTestDamageWithScale() {}
891
892 void SetupTree() override {
893 client_.set_fill_with_nonsolid_color(true);
894
895 scoped_ptr<FakePicturePile> pile(
896 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
897 ImplSidePaintingSettings().default_tile_grid_size));
898 root_layer_ =
899 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
900 root_layer_->SetBounds(gfx::Size(50, 50));
901
902 pile.reset(
903 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
904 ImplSidePaintingSettings().default_tile_grid_size));
905 child_layer_ =
906 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
907 child_layer_->SetBounds(gfx::Size(25, 25));
908 child_layer_->SetIsDrawable(true);
909 child_layer_->SetContentsOpaque(true);
910 root_layer_->AddChild(child_layer_);
911
912 layer_tree_host()->SetRootLayer(root_layer_);
913 LayerTreeHostTest::SetupTree();
914 }
915
916 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
917 // Force the layer to have a tiling at 1.3f scale. Note that if we simply
918 // add tiling, it will be gone by the time we draw because of aggressive
919 // cleanup. AddTilingUntilNextDraw ensures that it remains there during
920 // damage calculation.
921 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
922 host_impl->active_tree()->LayerById(child_layer_->id()));
923 child_layer_impl->AddTilingUntilNextDraw(1.3f);
924 }
925
926 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
927
928 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
929 LayerTreeHostImpl::FrameData* frame_data,
930 DrawResult draw_result) override {
931 EXPECT_EQ(DRAW_SUCCESS, draw_result);
932
933 gfx::RectF root_damage_rect;
934 if (!frame_data->render_passes.empty())
935 root_damage_rect = frame_data->render_passes.back()->damage_rect;
936
937 // The first time, the whole view needs be drawn.
938 // Afterwards, just the opacity of surface_layer1 is changed a few times,
939 // and each damage should be the bounding box of it and its child. If this
940 // was working improperly, the damage might not include its childs bounding
941 // box.
942 switch (host_impl->active_tree()->source_frame_number()) {
943 case 0:
944 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
945 break;
946 case 1: {
947 FakePictureLayerImpl* child_layer_impl =
948 static_cast<FakePictureLayerImpl*>(
949 host_impl->active_tree()->LayerById(child_layer_->id()));
950 // We remove tilings pretty aggressively if they are not ideal. Add this
951 // back in so that we can compare
952 // child_layer_impl->GetEnclosingRectInTargetSpace to the damage.
953 child_layer_impl->AddTilingUntilNextDraw(1.3f);
954
955 EXPECT_EQ(gfx::Rect(26, 26), root_damage_rect);
956 EXPECT_EQ(child_layer_impl->GetEnclosingRectInTargetSpace(),
957 root_damage_rect);
958 EXPECT_TRUE(child_layer_impl->GetEnclosingRectInTargetSpace().Contains(
959 gfx::Rect(child_layer_->bounds())));
960 break;
961 }
962 default:
963 NOTREACHED();
964 }
965
966 return draw_result;
967 }
968
969 void DidCommitAndDrawFrame() override {
970 switch (layer_tree_host()->source_frame_number()) {
971 case 1: {
972 // Test not owning the surface.
973 child_layer_->SetOpacity(0.5f);
974 break;
975 }
976 case 2:
977 EndTest();
978 break;
979 default:
980 NOTREACHED();
981 }
982 }
983
984 void AfterTest() override {}
985
986 private:
987 FakeContentLayerClient client_;
988 scoped_refptr<Layer> root_layer_;
989 scoped_refptr<Layer> child_layer_;
990 };
991
992 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestDamageWithScale);
993
994 // Tests that if a layer is not drawn because of some reason in the parent,
995 // causing its content bounds to not be computed, then when it is later drawn,
996 // its content bounds get pushed.
997 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
998 : public LayerTreeHostTest {
999 public:
1000 LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
1001 : root_layer_(Layer::Create()) {}
1002
1003 void SetupTree() override {
1004 root_layer_->CreateRenderSurface();
1005 root_layer_->SetIsDrawable(true);
1006 root_layer_->SetBounds(gfx::Size(20, 20));
1007 layer_tree_host()->SetRootLayer(root_layer_);
1008
1009 parent_layer_ = Layer::Create();
1010 parent_layer_->SetBounds(gfx::Size(20, 20));
1011 parent_layer_->SetOpacity(0.0f);
1012 root_layer_->AddChild(parent_layer_);
1013
1014 child_layer_ = Layer::Create();
1015 child_layer_->SetBounds(gfx::Size(15, 15));
1016 parent_layer_->AddChild(child_layer_);
1017
1018 LayerTreeHostTest::SetupTree();
1019 }
1020
1021 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1022
1023 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1024 LayerImpl* root = host_impl->active_tree()->root_layer();
1025 LayerImpl* parent = root->children()[0];
1026 LayerImpl* child = parent->children()[0];
1027
1028 switch (host_impl->active_tree()->source_frame_number()) {
1029 case 0:
1030 EXPECT_EQ(0.f, parent->opacity());
1031 EXPECT_EQ(gfx::SizeF(), child->content_bounds());
1032 break;
1033 case 1:
1034 EXPECT_EQ(1.f, parent->opacity());
1035 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
1036 EndTest();
1037 break;
1038 default:
1039 NOTREACHED();
1040 }
1041 }
1042
1043 void DidCommit() override {
1044 switch (layer_tree_host()->source_frame_number()) {
1045 case 1:
1046 parent_layer_->SetOpacity(1.0f);
1047 break;
1048 case 2:
1049 break;
1050 default:
1051 NOTREACHED();
1052 }
1053 }
1054
1055 void AfterTest() override {}
1056
1057 private:
1058 scoped_refptr<Layer> root_layer_;
1059 scoped_refptr<Layer> parent_layer_;
1060 scoped_refptr<Layer> child_layer_;
1061 };
1062
1063 SINGLE_AND_MULTI_THREAD_TEST_F(
1064 LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
1065
1066 // This test verifies that properties on the layer tree host are commited
1067 // to the impl side.
1068 class LayerTreeHostTestCommit : public LayerTreeHostTest {
1069 public:
1070 LayerTreeHostTestCommit() {}
1071
1072 void BeginTest() override {
1073 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1074 layer_tree_host()->set_background_color(SK_ColorGRAY);
1075
1076 PostSetNeedsCommitToMainThread();
1077 }
1078
1079 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1080 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
1081 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
1082
1083 EndTest();
1084 }
1085
1086 void AfterTest() override {}
1087 };
1088
1089 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
1090
1091 // This test verifies that LayerTreeHostImpl's current frame time gets
1092 // updated in consecutive frames when it doesn't draw due to tree
1093 // activation failure.
1094 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
1095 : public LayerTreeHostTest {
1096 public:
1097 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
1098 : frame_count_with_pending_tree_(0) {}
1099
1100 void BeginTest() override {
1101 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1102 layer_tree_host()->set_background_color(SK_ColorGRAY);
1103
1104 PostSetNeedsCommitToMainThread();
1105 }
1106
1107 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
1108 EXPECT_EQ(frame_count_with_pending_tree_, 0);
1109 if (impl->settings().impl_side_painting)
1110 impl->BlockNotifyReadyToActivateForTesting(true);
1111 }
1112
1113 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1114 const BeginFrameArgs& args) override {
1115 if (impl->pending_tree())
1116 frame_count_with_pending_tree_++;
1117
1118 if (frame_count_with_pending_tree_ == 1) {
1119 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
1120 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1121 } else if (frame_count_with_pending_tree_ == 2 &&
1122 impl->settings().impl_side_painting) {
1123 impl->BlockNotifyReadyToActivateForTesting(false);
1124 }
1125 }
1126
1127 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1128 if (frame_count_with_pending_tree_ > 1) {
1129 EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
1130 EXPECT_NE(first_frame_time_.ToInternalValue(),
1131 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
1132 EndTest();
1133 return;
1134 }
1135
1136 EXPECT_FALSE(impl->settings().impl_side_painting);
1137 EndTest();
1138 }
1139 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1140 if (impl->settings().impl_side_painting)
1141 EXPECT_NE(frame_count_with_pending_tree_, 1);
1142 }
1143
1144 void AfterTest() override {}
1145
1146 private:
1147 int frame_count_with_pending_tree_;
1148 base::TimeTicks first_frame_time_;
1149 };
1150
1151 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1152 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
1153
1154 // This test verifies that LayerTreeHostImpl's current frame time gets
1155 // updated in consecutive frames when it draws in each frame.
1156 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
1157 public:
1158 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
1159
1160 void BeginTest() override {
1161 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1162 layer_tree_host()->set_background_color(SK_ColorGRAY);
1163
1164 PostSetNeedsCommitToMainThread();
1165 }
1166
1167 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1168 frame_++;
1169 if (frame_ == 1) {
1170 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
1171 impl->SetNeedsRedraw();
1172
1173 // Since we might use a low-resolution clock on Windows, we need to
1174 // make sure that the clock has incremented past first_frame_time_.
1175 while (first_frame_time_ == gfx::FrameTime::Now()) {
1176 }
1177
1178 return;
1179 }
1180
1181 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
1182 EndTest();
1183 }
1184
1185 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1186 // Ensure there isn't a commit between the two draws, to ensure that a
1187 // commit isn't required for updating the current frame time. We can
1188 // only check for this in the multi-threaded case, since in the single-
1189 // threaded case there will always be a commit between consecutive draws.
1190 if (HasImplThread())
1191 EXPECT_EQ(0, frame_);
1192 }
1193
1194 void AfterTest() override {}
1195
1196 private:
1197 int frame_;
1198 base::TimeTicks first_frame_time_;
1199 };
1200
1201 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1202
1203 // Verifies that StartPageScaleAnimation events propagate correctly
1204 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1205 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
1206 public:
1207 LayerTreeHostTestStartPageScaleAnimation() {}
1208
1209 void SetupTree() override {
1210 LayerTreeHostTest::SetupTree();
1211
1212 if (layer_tree_host()->settings().impl_side_painting) {
1213 scoped_refptr<FakePictureLayer> layer =
1214 FakePictureLayer::Create(&client_);
1215 layer->set_always_update_resources(true);
1216 scroll_layer_ = layer;
1217 } else {
1218 scroll_layer_ = FakeContentLayer::Create(&client_);
1219 }
1220
1221 Layer* root_layer = layer_tree_host()->root_layer();
1222 scroll_layer_->SetScrollClipLayerId(root_layer->id());
1223 scroll_layer_->SetIsContainerForFixedPositionLayers(true);
1224 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
1225 2 * root_layer->bounds().height()));
1226 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
1227 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1228 // This test requires the page_scale and inner viewport layers to be
1229 // identified.
1230 layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
1231 scroll_layer_.get(), NULL);
1232 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1233 }
1234
1235 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1236
1237 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
1238 float scale,
1239 float) override {
1240 gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
1241 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset,
1242 scroll_delta));
1243 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1244 }
1245
1246 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1247 // We get one commit before the first draw, and the animation doesn't happen
1248 // until the second draw.
1249 switch (impl->active_tree()->source_frame_number()) {
1250 case 0:
1251 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1252 // We'll start an animation when we get back to the main thread.
1253 break;
1254 case 1:
1255 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
1256 break;
1257 case 2:
1258 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
1259 EndTest();
1260 break;
1261 default:
1262 NOTREACHED();
1263 }
1264 }
1265
1266 void DidCommitAndDrawFrame() override {
1267 switch (layer_tree_host()->source_frame_number()) {
1268 case 1:
1269 layer_tree_host()->StartPageScaleAnimation(
1270 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1271 break;
1272 }
1273 }
1274
1275 void AfterTest() override {}
1276
1277 FakeContentLayerClient client_;
1278 scoped_refptr<Layer> scroll_layer_;
1279 };
1280
1281 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1282
1283 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1284 public:
1285 LayerTreeHostTestSetVisible() : num_draws_(0) {}
1286
1287 void BeginTest() override {
1288 PostSetNeedsCommitToMainThread();
1289 PostSetVisibleToMainThread(false);
1290 // This is suppressed while we're invisible.
1291 PostSetNeedsRedrawToMainThread();
1292 // Triggers the redraw.
1293 PostSetVisibleToMainThread(true);
1294 }
1295
1296 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1297 EXPECT_TRUE(impl->visible());
1298 ++num_draws_;
1299 EndTest();
1300 }
1301
1302 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
1303
1304 private:
1305 int num_draws_;
1306 };
1307
1308 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1309
1310 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1311 public:
1312 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1313
1314 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1315
1316 void PaintContents(SkCanvas* canvas,
1317 const gfx::Rect& clip,
1318 PaintingControlSetting picture_control) override {
1319 // Set layer opacity to 0.
1320 if (test_layer_)
1321 test_layer_->SetOpacity(0.f);
1322 }
1323 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
1324 const gfx::Rect& clip,
1325 PaintingControlSetting picture_control) override {
1326 NOTIMPLEMENTED();
1327 return DisplayItemList::Create();
1328 }
1329 bool FillsBoundsCompletely() const override { return false; }
1330
1331 private:
1332 Layer* test_layer_;
1333 };
1334
1335 class ContentLayerWithUpdateTracking : public ContentLayer {
1336 public:
1337 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1338 ContentLayerClient* client) {
1339 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1340 }
1341
1342 int PaintContentsCount() { return paint_contents_count_; }
1343 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1344
1345 bool Update(ResourceUpdateQueue* queue,
1346 const OcclusionTracker<Layer>* occlusion) override {
1347 bool updated = ContentLayer::Update(queue, occlusion);
1348 paint_contents_count_++;
1349 return updated;
1350 }
1351
1352 private:
1353 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1354 : ContentLayer(client), paint_contents_count_(0) {
1355 SetBounds(gfx::Size(10, 10));
1356 SetIsDrawable(true);
1357 }
1358 ~ContentLayerWithUpdateTracking() override {}
1359
1360 int paint_contents_count_;
1361 };
1362
1363 // Layer opacity change during paint should not prevent compositor resources
1364 // from being updated during commit.
1365 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1366 public:
1367 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {}
1368
1369 void BeginTest() override {
1370 if (layer_tree_host()->settings().impl_side_painting) {
1371 update_check_picture_layer_ =
1372 FakePictureLayer::Create(&test_opacity_change_delegate_);
1373 test_opacity_change_delegate_.SetTestLayer(
1374 update_check_picture_layer_.get());
1375 is_impl_paint_ = true;
1376 } else {
1377 update_check_content_layer_ = ContentLayerWithUpdateTracking::Create(
1378 &test_opacity_change_delegate_);
1379 test_opacity_change_delegate_.SetTestLayer(
1380 update_check_content_layer_.get());
1381 is_impl_paint_ = false;
1382 }
1383 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1384 if (layer_tree_host()->settings().impl_side_painting)
1385 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
1386 else
1387 layer_tree_host()->root_layer()->AddChild(update_check_content_layer_);
1388
1389 PostSetNeedsCommitToMainThread();
1390 }
1391
1392 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
1393
1394 void AfterTest() override {
1395 // Update() should have been called once.
1396 if (is_impl_paint_)
1397 EXPECT_EQ(1u, update_check_picture_layer_->update_count());
1398 else
1399 EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount());
1400 }
1401
1402 private:
1403 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1404 scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_;
1405 scoped_refptr<FakePictureLayer> update_check_picture_layer_;
1406 bool is_impl_paint_;
1407 };
1408
1409 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1410
1411 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1412 : public LayerTreeHostTest {
1413 public:
1414 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {}
1415
1416 void InitializeSettings(LayerTreeSettings* settings) override {
1417 // PictureLayer can only be used with impl side painting enabled.
1418 settings->impl_side_painting = true;
1419 }
1420
1421 void BeginTest() override {
1422 client_.set_fill_with_nonsolid_color(true);
1423 root_layer_ = FakePictureLayer::Create(&client_);
1424 child_layer_ = FakePictureLayer::Create(&client_);
1425
1426 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1427 layer_tree_host()->SetDeviceScaleFactor(1.5);
1428 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1429
1430 root_layer_->AddChild(child_layer_);
1431
1432 root_layer_->SetIsDrawable(true);
1433 root_layer_->SetBounds(gfx::Size(30, 30));
1434
1435 child_layer_->SetIsDrawable(true);
1436 child_layer_->SetPosition(gfx::Point(2, 2));
1437 child_layer_->SetBounds(gfx::Size(10, 10));
1438
1439 layer_tree_host()->SetRootLayer(root_layer_);
1440
1441 PostSetNeedsCommitToMainThread();
1442 }
1443
1444 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1445 // Should only do one commit.
1446 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1447 // Device scale factor should come over to impl.
1448 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1449
1450 // Both layers are on impl.
1451 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1452
1453 // Device viewport is scaled.
1454 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1455
1456 FakePictureLayerImpl* root =
1457 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
1458 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
1459 impl->active_tree()->root_layer()->children()[0]);
1460
1461 // Positions remain in layout pixels.
1462 EXPECT_EQ(gfx::Point(0, 0), root->position());
1463 EXPECT_EQ(gfx::Point(2, 2), child->position());
1464
1465 // Compute all the layer transforms for the frame.
1466 LayerTreeHostImpl::FrameData frame_data;
1467 impl->PrepareToDraw(&frame_data);
1468 impl->DidDrawAllLayers(frame_data);
1469
1470 const LayerImplList& render_surface_layer_list =
1471 *frame_data.render_surface_layer_list;
1472
1473 // Both layers should be drawing into the root render surface.
1474 ASSERT_EQ(1u, render_surface_layer_list.size());
1475 ASSERT_EQ(root->render_surface(),
1476 render_surface_layer_list[0]->render_surface());
1477 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1478
1479 // The root render surface is the size of the viewport.
1480 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect());
1481
1482 // The max tiling scale of the child should be scaled.
1483 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale());
1484
1485 gfx::Transform scale_transform;
1486 scale_transform.Scale(impl->device_scale_factor(),
1487 impl->device_scale_factor());
1488
1489 // The root layer is scaled by 2x.
1490 gfx::Transform root_screen_space_transform = scale_transform;
1491 gfx::Transform root_draw_transform = scale_transform;
1492
1493 EXPECT_EQ(root_draw_transform, root->draw_transform());
1494 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1495
1496 // The child is at position 2,2, which is transformed to 3,3 after the scale
1497 gfx::Transform child_transform;
1498 child_transform.Translate(3.f, 3.f);
1499 child_transform.Scale(child->MaximumTilingContentsScale(),
1500 child->MaximumTilingContentsScale());
1501
1502 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform());
1503 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform,
1504 child->screen_space_transform());
1505
1506 EndTest();
1507 }
1508
1509 void AfterTest() override {}
1510
1511 private:
1512 FakeContentLayerClient client_;
1513 scoped_refptr<FakePictureLayer> root_layer_;
1514 scoped_refptr<FakePictureLayer> child_layer_;
1515 };
1516
1517 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1518
1519 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1520 // Verify atomicity of commits and reuse of textures.
1521 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1522 public:
1523 void InitializeSettings(LayerTreeSettings* settings) override {
1524 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1525 // Make sure partial texture updates are turned off.
1526 settings->max_partial_texture_updates = 0;
1527 // Linear fade animator prevents scrollbars from drawing immediately.
1528 settings->scrollbar_animator = LayerTreeSettings::NO_ANIMATOR;
1529 }
1530
1531 void SetupTree() override {
1532 layer_ = FakeContentLayer::Create(&client_);
1533 layer_->SetBounds(gfx::Size(10, 20));
1534
1535 bool paint_scrollbar = true;
1536 bool has_thumb = false;
1537 scrollbar_ = FakePaintedScrollbarLayer::Create(
1538 paint_scrollbar, has_thumb, layer_->id());
1539 scrollbar_->SetPosition(gfx::Point(0, 10));
1540 scrollbar_->SetBounds(gfx::Size(10, 10));
1541
1542 layer_->AddChild(scrollbar_);
1543
1544 layer_tree_host()->SetRootLayer(layer_);
1545 LayerTreeHostTest::SetupTree();
1546 }
1547
1548 void BeginTest() override {
1549 drew_frame_ = -1;
1550 PostSetNeedsCommitToMainThread();
1551 }
1552
1553 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1554 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
1555
1556 TestWebGraphicsContext3D* context = TestContext();
1557
1558 switch (impl->active_tree()->source_frame_number()) {
1559 case 0:
1560 // Number of textures should be one for each layer
1561 ASSERT_EQ(2u, context->NumTextures());
1562 // Number of textures used for commit should be one for each layer.
1563 EXPECT_EQ(2u, context->NumUsedTextures());
1564 // Verify that used texture is correct.
1565 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1566 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1567
1568 context->ResetUsedTextures();
1569 break;
1570 case 1:
1571 // Number of textures should be one for scrollbar layer since it was
1572 // requested and deleted on the impl-thread, and double for the content
1573 // layer since its first texture is used by impl thread and cannot by
1574 // used for update.
1575 ASSERT_EQ(3u, context->NumTextures());
1576 // Number of textures used for commit should be one for each layer.
1577 EXPECT_EQ(2u, context->NumUsedTextures());
1578 // First textures should not have been used.
1579 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1580 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1581 // New textures should have been used.
1582 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1583 context->ResetUsedTextures();
1584 break;
1585 case 2:
1586 EndTest();
1587 break;
1588 default:
1589 NOTREACHED();
1590 break;
1591 }
1592 }
1593
1594 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1595 TestWebGraphicsContext3D* context = TestContext();
1596
1597 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1598 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1599 return;
1600 }
1601 drew_frame_ = impl->active_tree()->source_frame_number();
1602
1603 // We draw/ship one texture each frame for each layer.
1604 EXPECT_EQ(2u, context->NumUsedTextures());
1605 context->ResetUsedTextures();
1606
1607 if (!TestEnded())
1608 PostSetNeedsCommitToMainThread();
1609 }
1610
1611 void Layout() override {
1612 layer_->SetNeedsDisplay();
1613 scrollbar_->SetNeedsDisplay();
1614 }
1615
1616 void AfterTest() override {}
1617
1618 protected:
1619 FakeContentLayerClient client_;
1620 scoped_refptr<FakeContentLayer> layer_;
1621 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1622 int drew_frame_;
1623 };
1624
1625 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1626 LayerTreeHostTestDirectRendererAtomicCommit);
1627
1628 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1629 class LayerTreeHostTestDelegatingRendererAtomicCommit
1630 : public LayerTreeHostTestDirectRendererAtomicCommit {
1631 public:
1632 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1633 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
1634
1635 TestWebGraphicsContext3D* context = TestContext();
1636
1637 switch (impl->active_tree()->source_frame_number()) {
1638 case 0:
1639 // Number of textures should be one for each layer
1640 ASSERT_EQ(2u, context->NumTextures());
1641 // Number of textures used for commit should be one for each layer.
1642 EXPECT_EQ(2u, context->NumUsedTextures());
1643 // Verify that used texture is correct.
1644 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1645 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1646 break;
1647 case 1:
1648 // Number of textures should be doubled as the first context layer
1649 // texture is being used by the impl-thread and cannot be used for
1650 // update. The scrollbar behavior is different direct renderer because
1651 // UI resource deletion with delegating renderer occurs after tree
1652 // activation.
1653 ASSERT_EQ(4u, context->NumTextures());
1654 // Number of textures used for commit should still be
1655 // one for each layer.
1656 EXPECT_EQ(2u, context->NumUsedTextures());
1657 // First textures should not have been used.
1658 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1659 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1660 // New textures should have been used.
1661 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1662 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1663 break;
1664 case 2:
1665 EndTest();
1666 break;
1667 default:
1668 NOTREACHED();
1669 break;
1670 }
1671 }
1672 };
1673
1674 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1675 LayerTreeHostTestDelegatingRendererAtomicCommit);
1676
1677 static void SetLayerPropertiesForTesting(Layer* layer,
1678 Layer* parent,
1679 const gfx::Transform& transform,
1680 const gfx::Point3F& transform_origin,
1681 const gfx::PointF& position,
1682 const gfx::Size& bounds,
1683 bool opaque) {
1684 layer->RemoveAllChildren();
1685 if (parent)
1686 parent->AddChild(layer);
1687 layer->SetTransform(transform);
1688 layer->SetTransformOrigin(transform_origin);
1689 layer->SetPosition(position);
1690 layer->SetBounds(bounds);
1691 layer->SetContentsOpaque(opaque);
1692 }
1693
1694 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
1695 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1696 : public LayerTreeHostTest {
1697 public:
1698 void InitializeSettings(LayerTreeSettings* settings) override {
1699 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
1700 // Allow one partial texture update.
1701 settings->max_partial_texture_updates = 1;
1702 // No partial updates when impl side painting is enabled.
1703 settings->impl_side_painting = false;
1704 }
1705
1706 void SetupTree() override {
1707 parent_ = FakeContentLayer::Create(&client_);
1708 parent_->SetBounds(gfx::Size(10, 20));
1709
1710 child_ = FakeContentLayer::Create(&client_);
1711 child_->SetPosition(gfx::Point(0, 10));
1712 child_->SetBounds(gfx::Size(3, 10));
1713
1714 parent_->AddChild(child_);
1715
1716 layer_tree_host()->SetRootLayer(parent_);
1717 LayerTreeHostTest::SetupTree();
1718 }
1719
1720 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1721
1722 void DidCommitAndDrawFrame() override {
1723 switch (layer_tree_host()->source_frame_number()) {
1724 case 1:
1725 parent_->SetNeedsDisplay();
1726 child_->SetNeedsDisplay();
1727 break;
1728 case 2:
1729 // Damage part of layers.
1730 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1731 child_->SetNeedsDisplayRect(gfx::Rect(5, 5));
1732 break;
1733 case 3:
1734 child_->SetNeedsDisplay();
1735 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1736 break;
1737 case 4:
1738 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1739 break;
1740 case 5:
1741 EndTest();
1742 break;
1743 default:
1744 NOTREACHED() << layer_tree_host()->source_frame_number();
1745 break;
1746 }
1747 }
1748
1749 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1750 ASSERT_EQ(1u, impl->settings().max_partial_texture_updates);
1751
1752 TestWebGraphicsContext3D* context = TestContext();
1753
1754 switch (impl->active_tree()->source_frame_number()) {
1755 case 0:
1756 // Number of textures should be one for each layer.
1757 ASSERT_EQ(2u, context->NumTextures());
1758 // Number of textures used for commit should be one for each layer.
1759 EXPECT_EQ(2u, context->NumUsedTextures());
1760 // Verify that used textures are correct.
1761 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1762 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1763 context->ResetUsedTextures();
1764 break;
1765 case 1:
1766 if (HasImplThread()) {
1767 // Number of textures should be two for each content layer.
1768 ASSERT_EQ(4u, context->NumTextures());
1769 } else {
1770 // In single thread we can always do partial updates, so the limit has
1771 // no effect.
1772 ASSERT_EQ(2u, context->NumTextures());
1773 }
1774 // Number of textures used for commit should be one for each content
1775 // layer.
1776 EXPECT_EQ(2u, context->NumUsedTextures());
1777
1778 if (HasImplThread()) {
1779 // First content textures should not have been used.
1780 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1781 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1782 // New textures should have been used.
1783 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1784 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1785 } else {
1786 // In single thread we can always do partial updates, so the limit has
1787 // no effect.
1788 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1789 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1790 }
1791
1792 context->ResetUsedTextures();
1793 break;
1794 case 2:
1795 if (HasImplThread()) {
1796 // Number of textures should be two for each content layer.
1797 ASSERT_EQ(4u, context->NumTextures());
1798 } else {
1799 // In single thread we can always do partial updates, so the limit has
1800 // no effect.
1801 ASSERT_EQ(2u, context->NumTextures());
1802 }
1803 // Number of textures used for commit should be one for each content
1804 // layer.
1805 EXPECT_EQ(2u, context->NumUsedTextures());
1806
1807 if (HasImplThread()) {
1808 // One content layer does a partial update also.
1809 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1810 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1811 } else {
1812 // In single thread we can always do partial updates, so the limit has
1813 // no effect.
1814 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1815 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1816 }
1817
1818 context->ResetUsedTextures();
1819 break;
1820 case 3:
1821 // No textures should be used for commit.
1822 EXPECT_EQ(0u, context->NumUsedTextures());
1823
1824 context->ResetUsedTextures();
1825 break;
1826 case 4:
1827 // Number of textures used for commit should be one, for the
1828 // content layer.
1829 EXPECT_EQ(1u, context->NumUsedTextures());
1830
1831 context->ResetUsedTextures();
1832 break;
1833 default:
1834 NOTREACHED();
1835 break;
1836 }
1837 }
1838
1839 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1840 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1841
1842 TestWebGraphicsContext3D* context = TestContext();
1843
1844 // Number of textures used for drawing should one per layer except for
1845 // frame 3 where the viewport only contains one layer.
1846 if (impl->active_tree()->source_frame_number() == 3) {
1847 EXPECT_EQ(1u, context->NumUsedTextures());
1848 } else {
1849 EXPECT_EQ(2u, context->NumUsedTextures())
1850 << "For frame " << impl->active_tree()->source_frame_number();
1851 }
1852
1853 context->ResetUsedTextures();
1854 }
1855
1856 void AfterTest() override {}
1857
1858 private:
1859 FakeContentLayerClient client_;
1860 scoped_refptr<FakeContentLayer> parent_;
1861 scoped_refptr<FakeContentLayer> child_;
1862 };
1863
1864 // Partial updates are not possible with a delegating renderer.
1865 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1866 LayerTreeHostTestAtomicCommitWithPartialUpdate);
1867
1868 // TODO(sohanjg) : Make it work with impl-side painting.
1869 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1870 : public LayerTreeHostTest {
1871 protected:
1872 void SetupTree() override {
1873 root_layer_ = FakeContentLayer::Create(&client_);
1874 root_layer_->SetBounds(gfx::Size(100, 100));
1875
1876 surface_layer1_ = FakeContentLayer::Create(&client_);
1877 surface_layer1_->SetBounds(gfx::Size(100, 100));
1878 surface_layer1_->SetForceRenderSurface(true);
1879 surface_layer1_->SetOpacity(0.5f);
1880 root_layer_->AddChild(surface_layer1_);
1881
1882 surface_layer2_ = FakeContentLayer::Create(&client_);
1883 surface_layer2_->SetBounds(gfx::Size(100, 100));
1884 surface_layer2_->SetForceRenderSurface(true);
1885 surface_layer2_->SetOpacity(0.5f);
1886 surface_layer1_->AddChild(surface_layer2_);
1887
1888 replica_layer1_ = FakeContentLayer::Create(&client_);
1889 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1890
1891 replica_layer2_ = FakeContentLayer::Create(&client_);
1892 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1893
1894 layer_tree_host()->SetRootLayer(root_layer_);
1895 LayerTreeHostTest::SetupTree();
1896 }
1897
1898 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1899
1900 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1901 Renderer* renderer = host_impl->renderer();
1902 RenderPassId surface1_render_pass_id = host_impl->active_tree()
1903 ->root_layer()
1904 ->children()[0]
1905 ->render_surface()
1906 ->GetRenderPassId();
1907 RenderPassId surface2_render_pass_id = host_impl->active_tree()
1908 ->root_layer()
1909 ->children()[0]
1910 ->children()[0]
1911 ->render_surface()
1912 ->GetRenderPassId();
1913
1914 switch (host_impl->active_tree()->source_frame_number()) {
1915 case 0:
1916 EXPECT_TRUE(
1917 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1918 EXPECT_TRUE(
1919 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1920
1921 // Reduce the memory limit to only fit the root layer and one render
1922 // surface. This prevents any contents drawing into surfaces
1923 // from being allocated.
1924 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1925 break;
1926 case 1:
1927 EXPECT_FALSE(
1928 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
1929 EXPECT_FALSE(
1930 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
1931
1932 EndTest();
1933 break;
1934 }
1935 }
1936
1937 void DidCommitAndDrawFrame() override {
1938 if (layer_tree_host()->source_frame_number() < 2)
1939 root_layer_->SetNeedsDisplay();
1940 }
1941
1942 void AfterTest() override {
1943 EXPECT_LE(2u, root_layer_->update_count());
1944 EXPECT_LE(2u, surface_layer1_->update_count());
1945 EXPECT_LE(2u, surface_layer2_->update_count());
1946 }
1947
1948 FakeContentLayerClient client_;
1949 scoped_refptr<FakeContentLayer> root_layer_;
1950 scoped_refptr<FakeContentLayer> surface_layer1_;
1951 scoped_refptr<FakeContentLayer> replica_layer1_;
1952 scoped_refptr<FakeContentLayer> surface_layer2_;
1953 scoped_refptr<FakeContentLayer> replica_layer2_;
1954 };
1955
1956 // Surfaces don't exist with a delegated renderer.
1957 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1958 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1959
1960 class EvictionTestLayer : public Layer {
1961 public:
1962 static scoped_refptr<EvictionTestLayer> Create() {
1963 return make_scoped_refptr(new EvictionTestLayer());
1964 }
1965
1966 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override;
1967 bool DrawsContent() const override { return true; }
1968
1969 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
1970 void PushPropertiesTo(LayerImpl* impl) override;
1971 void SetTexturePriorities(const PriorityCalculator&) override;
1972
1973 bool HaveBackingTexture() const {
1974 return texture_.get() ? texture_->have_backing_texture() : false;
1975 }
1976
1977 private:
1978 EvictionTestLayer() : Layer() {}
1979 ~EvictionTestLayer() override {}
1980
1981 void CreateTextureIfNeeded() {
1982 if (texture_)
1983 return;
1984 texture_ = PrioritizedResource::Create(
1985 layer_tree_host()->contents_texture_manager());
1986 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1987 bitmap_.allocN32Pixels(10, 10);
1988 }
1989
1990 scoped_ptr<PrioritizedResource> texture_;
1991 SkBitmap bitmap_;
1992 };
1993
1994 class EvictionTestLayerImpl : public LayerImpl {
1995 public:
1996 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1997 int id) {
1998 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1999 }
2000 ~EvictionTestLayerImpl() override {}
2001
2002 void AppendQuads(RenderPass* render_pass,
2003 AppendQuadsData* append_quads_data) override {
2004 ASSERT_TRUE(has_texture_);
2005 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
2006 }
2007
2008 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
2009
2010 private:
2011 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
2012 : LayerImpl(tree_impl, id), has_texture_(false) {}
2013
2014 bool has_texture_;
2015 };
2016
2017 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
2018 CreateTextureIfNeeded();
2019 if (!texture_)
2020 return;
2021 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
2022 }
2023
2024 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
2025 const OcclusionTracker<Layer>* occlusion) {
2026 CreateTextureIfNeeded();
2027 if (!texture_)
2028 return false;
2029
2030 gfx::Rect full_rect(0, 0, 10, 10);
2031 ResourceUpdate upload = ResourceUpdate::Create(
2032 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
2033 queue->AppendFullUpload(upload);
2034 return true;
2035 }
2036
2037 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
2038 LayerTreeImpl* tree_impl) {
2039 return EvictionTestLayerImpl::Create(tree_impl, layer_id_);
2040 }
2041
2042 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
2043 Layer::PushPropertiesTo(layer_impl);
2044
2045 EvictionTestLayerImpl* test_layer_impl =
2046 static_cast<EvictionTestLayerImpl*>(layer_impl);
2047 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
2048 }
2049
2050 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
2051 public:
2052 LayerTreeHostTestEvictTextures()
2053 : layer_(EvictionTestLayer::Create()),
2054 impl_for_evict_textures_(0),
2055 num_commits_(0) {}
2056
2057 void BeginTest() override {
2058 layer_tree_host()->SetRootLayer(layer_);
2059 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
2060
2061 gfx::Transform identity_matrix;
2062 SetLayerPropertiesForTesting(layer_.get(),
2063 0,
2064 identity_matrix,
2065 gfx::Point3F(0.f, 0.f, 0.f),
2066 gfx::PointF(0.f, 0.f),
2067 gfx::Size(10, 20),
2068 true);
2069
2070 PostSetNeedsCommitToMainThread();
2071 }
2072
2073 void PostEvictTextures() {
2074 ImplThreadTaskRunner()->PostTask(
2075 FROM_HERE,
2076 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
2077 base::Unretained(this)));
2078 }
2079
2080 void EvictTexturesOnImplThread() {
2081 DCHECK(impl_for_evict_textures_);
2082 impl_for_evict_textures_->EvictTexturesForTesting();
2083 }
2084
2085 // Commit 1: Just commit and draw normally, then post an eviction at the end
2086 // that will trigger a commit.
2087 // Commit 2: Triggered by the eviction, let it go through and then set
2088 // needsCommit.
2089 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
2090 // task, which will be handled before the commit. Don't set needsCommit, it
2091 // should have been posted. A frame should not be drawn (note,
2092 // didCommitAndDrawFrame may be called anyway).
2093 // Commit 4: Triggered by the eviction, let it go through and then set
2094 // needsCommit.
2095 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
2096 // Layout(), a frame should not be drawn but a commit will be posted.
2097 // Commit 6: Triggered by the eviction, post an eviction task in
2098 // Layout(), which will be a noop, letting the commit (which recreates the
2099 // textures) go through and draw a frame, then end the test.
2100 //
2101 // Commits 1+2 test the eviction recovery path where eviction happens outside
2102 // of the beginFrame/commit pair.
2103 // Commits 3+4 test the eviction recovery path where eviction happens inside
2104 // the beginFrame/commit pair.
2105 // Commits 5+6 test the path where an eviction happens during the eviction
2106 // recovery path.
2107 void DidCommit() override {
2108 switch (num_commits_) {
2109 case 1:
2110 EXPECT_TRUE(layer_->HaveBackingTexture());
2111 PostEvictTextures();
2112 break;
2113 case 2:
2114 EXPECT_TRUE(layer_->HaveBackingTexture());
2115 layer_tree_host()->SetNeedsCommit();
2116 break;
2117 case 3:
2118 break;
2119 case 4:
2120 EXPECT_TRUE(layer_->HaveBackingTexture());
2121 layer_tree_host()->SetNeedsCommit();
2122 break;
2123 case 5:
2124 break;
2125 case 6:
2126 EXPECT_TRUE(layer_->HaveBackingTexture());
2127 EndTest();
2128 break;
2129 default:
2130 NOTREACHED();
2131 break;
2132 }
2133 }
2134
2135 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2136 impl_for_evict_textures_ = impl;
2137 }
2138
2139 void Layout() override {
2140 ++num_commits_;
2141 switch (num_commits_) {
2142 case 1:
2143 case 2:
2144 break;
2145 case 3:
2146 PostEvictTextures();
2147 break;
2148 case 4:
2149 // We couldn't check in didCommitAndDrawFrame on commit 3,
2150 // so check here.
2151 EXPECT_FALSE(layer_->HaveBackingTexture());
2152 break;
2153 case 5:
2154 PostEvictTextures();
2155 break;
2156 case 6:
2157 // We couldn't check in didCommitAndDrawFrame on commit 5,
2158 // so check here.
2159 EXPECT_FALSE(layer_->HaveBackingTexture());
2160 PostEvictTextures();
2161 break;
2162 default:
2163 NOTREACHED();
2164 break;
2165 }
2166 }
2167
2168 void AfterTest() override {}
2169
2170 private:
2171 FakeContentLayerClient client_;
2172 scoped_refptr<EvictionTestLayer> layer_;
2173 LayerTreeHostImpl* impl_for_evict_textures_;
2174 int num_commits_;
2175 };
2176
2177 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
2178
2179 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
2180 public:
2181 LayerTreeHostTestContinuousInvalidate()
2182 : num_commit_complete_(0), num_draw_layers_(0) {}
2183
2184 void BeginTest() override {
2185 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2186 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2187
2188 if (layer_tree_host()->settings().impl_side_painting)
2189 layer_ = FakePictureLayer::Create(&client_);
2190 else
2191 layer_ = FakeContentLayer::Create(&client_);
2192
2193 layer_->SetBounds(gfx::Size(10, 10));
2194 layer_->SetPosition(gfx::PointF(0.f, 0.f));
2195 layer_->SetIsDrawable(true);
2196 layer_tree_host()->root_layer()->AddChild(layer_);
2197
2198 PostSetNeedsCommitToMainThread();
2199 }
2200
2201 void DidCommitAndDrawFrame() override {
2202 if (num_draw_layers_ == 2)
2203 return;
2204 layer_->SetNeedsDisplay();
2205 }
2206
2207 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2208 if (num_draw_layers_ == 1)
2209 num_commit_complete_++;
2210 }
2211
2212 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2213 num_draw_layers_++;
2214 if (num_draw_layers_ == 2)
2215 EndTest();
2216 }
2217
2218 void AfterTest() override {
2219 // Check that we didn't commit twice between first and second draw.
2220 EXPECT_EQ(1, num_commit_complete_);
2221 }
2222
2223 private:
2224 FakeContentLayerClient client_;
2225 scoped_refptr<Layer> layer_;
2226 int num_commit_complete_;
2227 int num_draw_layers_;
2228 };
2229
2230 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
2231
2232 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2233 public:
2234 LayerTreeHostTestDeferCommits()
2235 : num_will_begin_impl_frame_(0),
2236 num_send_begin_main_frame_(0) {}
2237
2238 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2239
2240 void WillBeginImplFrame(const BeginFrameArgs& args) override {
2241 num_will_begin_impl_frame_++;
2242 switch (num_will_begin_impl_frame_) {
2243 case 1:
2244 break;
2245 case 2:
2246 PostSetNeedsCommitToMainThread();
2247 break;
2248 case 3:
2249 PostSetDeferCommitsToMainThread(false);
2250 break;
2251 default:
2252 // Sometimes |num_will_begin_impl_frame_| will be greater than 3 if the
2253 // main thread is slow to respond.
2254 break;
2255 }
2256 }
2257
2258 void ScheduledActionSendBeginMainFrame() override {
2259 num_send_begin_main_frame_++;
2260 switch (num_send_begin_main_frame_) {
2261 case 1:
2262 PostSetDeferCommitsToMainThread(true);
2263 break;
2264 case 2:
2265 EndTest();
2266 break;
2267 default:
2268 NOTREACHED();
2269 break;
2270 }
2271 }
2272
2273 void AfterTest() override {
2274 EXPECT_GE(num_will_begin_impl_frame_, 3);
2275 EXPECT_EQ(2, num_send_begin_main_frame_);
2276 }
2277
2278 private:
2279 int num_will_begin_impl_frame_;
2280 int num_send_begin_main_frame_;
2281 };
2282
2283 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2284
2285 class LayerTreeHostWithProxy : public LayerTreeHost {
2286 public:
2287 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2288 const LayerTreeSettings& settings,
2289 scoped_ptr<FakeProxy> proxy)
2290 : LayerTreeHost(client, NULL, NULL, NULL, settings) {
2291 proxy->SetLayerTreeHost(this);
2292 client->SetLayerTreeHost(this);
2293 InitializeForTesting(proxy.Pass());
2294 }
2295 };
2296
2297 TEST(LayerTreeHostTest, LimitPartialUpdates) {
2298 // When partial updates are not allowed, max updates should be 0.
2299 {
2300 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2301
2302 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2303 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2304 proxy->SetMaxPartialTextureUpdates(5);
2305
2306 LayerTreeSettings settings;
2307 settings.impl_side_painting = false;
2308 settings.max_partial_texture_updates = 10;
2309
2310 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2311
2312 EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2313 }
2314
2315 // When partial updates are allowed,
2316 // max updates should be limited by the proxy.
2317 {
2318 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2319
2320 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2321 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2322 proxy->SetMaxPartialTextureUpdates(5);
2323
2324 LayerTreeSettings settings;
2325 settings.impl_side_painting = false;
2326 settings.max_partial_texture_updates = 10;
2327
2328 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2329
2330 EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2331 }
2332
2333 // When partial updates are allowed,
2334 // max updates should also be limited by the settings.
2335 {
2336 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2337
2338 scoped_ptr<FakeProxy> proxy(new FakeProxy);
2339 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2340 proxy->SetMaxPartialTextureUpdates(20);
2341
2342 LayerTreeSettings settings;
2343 settings.impl_side_painting = false;
2344 settings.max_partial_texture_updates = 10;
2345
2346 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2347
2348 EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2349 }
2350 }
2351
2352 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2353 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2354
2355 LayerTreeSettings settings;
2356 settings.max_partial_texture_updates = 4;
2357 settings.single_thread_proxy_scheduler = false;
2358 settings.impl_side_painting = false;
2359
2360 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2361 new TestSharedBitmapManager());
2362 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2363 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2364 base::MessageLoopProxy::current(), nullptr);
2365 client.SetLayerTreeHost(host.get());
2366 host->Composite(base::TimeTicks::Now());
2367
2368 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2369 }
2370
2371 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2372 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2373
2374 LayerTreeSettings settings;
2375 settings.max_partial_texture_updates = 4;
2376 settings.single_thread_proxy_scheduler = false;
2377 settings.impl_side_painting = false;
2378
2379 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2380 new TestSharedBitmapManager());
2381 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2382 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2383 base::MessageLoopProxy::current(), nullptr);
2384 client.SetLayerTreeHost(host.get());
2385 host->Composite(base::TimeTicks::Now());
2386
2387 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2388 }
2389
2390 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2391 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2392
2393 LayerTreeSettings settings;
2394 settings.max_partial_texture_updates = 4;
2395 settings.single_thread_proxy_scheduler = false;
2396 settings.impl_side_painting = false;
2397
2398 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2399 new TestSharedBitmapManager());
2400 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2401 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2402 base::MessageLoopProxy::current(), nullptr);
2403 client.SetLayerTreeHost(host.get());
2404 host->Composite(base::TimeTicks::Now());
2405
2406 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2407 }
2408
2409 TEST(LayerTreeHostTest,
2410 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2411 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2412
2413 LayerTreeSettings settings;
2414 settings.max_partial_texture_updates = 4;
2415 settings.single_thread_proxy_scheduler = false;
2416 settings.impl_side_painting = false;
2417
2418 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2419 new TestSharedBitmapManager());
2420 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
2421 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings,
2422 base::MessageLoopProxy::current(), nullptr);
2423 client.SetLayerTreeHost(host.get());
2424 host->Composite(base::TimeTicks::Now());
2425
2426 EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2427 }
2428
2429 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
2430 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2431 : public LayerTreeHostTest {
2432 public:
2433 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2434 : root_layer_(FakeContentLayer::Create(&client_)),
2435 child_layer1_(FakeContentLayer::Create(&client_)),
2436 child_layer2_(FakeContentLayer::Create(&client_)),
2437 num_commits_(0) {}
2438
2439 void BeginTest() override {
2440 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2441 root_layer_->SetBounds(gfx::Size(100, 100));
2442 child_layer1_->SetBounds(gfx::Size(100, 100));
2443 child_layer2_->SetBounds(gfx::Size(100, 100));
2444 root_layer_->AddChild(child_layer1_);
2445 root_layer_->AddChild(child_layer2_);
2446 layer_tree_host()->SetRootLayer(root_layer_);
2447 PostSetNeedsCommitToMainThread();
2448 }
2449
2450 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2451 bool visible) override {
2452 if (visible) {
2453 // One backing should remain unevicted.
2454 EXPECT_EQ(100u * 100u * 4u * 1u,
2455 contents_texture_manager_->MemoryUseBytes());
2456 } else {
2457 EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes());
2458 }
2459
2460 // Make sure that contents textures are marked as having been
2461 // purged.
2462 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2463 // End the test in this state.
2464 EndTest();
2465 }
2466
2467 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2468 ++num_commits_;
2469 switch (num_commits_) {
2470 case 1:
2471 // All three backings should have memory.
2472 EXPECT_EQ(100u * 100u * 4u * 3u,
2473 contents_texture_manager_->MemoryUseBytes());
2474
2475 // Set a new policy that will kick out 1 of the 3 resources.
2476 // Because a resource was evicted, a commit will be kicked off.
2477 host_impl->SetMemoryPolicy(
2478 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2479 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2480 1000));
2481 break;
2482 case 2:
2483 // Only two backings should have memory.
2484 EXPECT_EQ(100u * 100u * 4u * 2u,
2485 contents_texture_manager_->MemoryUseBytes());
2486 // Become backgrounded, which will cause 1 more resource to be
2487 // evicted.
2488 PostSetVisibleToMainThread(false);
2489 break;
2490 default:
2491 // No further commits should happen because this is not visible
2492 // anymore.
2493 NOTREACHED();
2494 break;
2495 }
2496 }
2497
2498 void AfterTest() override {}
2499
2500 private:
2501 FakeContentLayerClient client_;
2502 scoped_refptr<FakeContentLayer> root_layer_;
2503 scoped_refptr<FakeContentLayer> child_layer1_;
2504 scoped_refptr<FakeContentLayer> child_layer2_;
2505 int num_commits_;
2506 };
2507
2508 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2509 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2510
2511 class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
2512 public:
2513 void SetupTree() override {
2514 num_tiles_rastered_ = 0;
2515
2516 scoped_refptr<Layer> root_layer = PictureLayer::Create(&client_);
2517 client_.set_fill_with_nonsolid_color(true);
2518 root_layer->SetIsDrawable(true);
2519 root_layer->SetBounds(gfx::Size(10, 10));
2520 root_layer->SetContentsOpaque(true);
2521
2522 layer_tree_host()->SetRootLayer(root_layer);
2523
2524 // The expectations are based on the assumption that the default
2525 // LCD settings are:
2526 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2527
2528 LayerTreeHostTest::SetupTree();
2529 }
2530
2531 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2532
2533 void DidCommitAndDrawFrame() override {
2534 switch (layer_tree_host()->source_frame_number()) {
2535 case 1:
2536 PostSetNeedsCommitToMainThread();
2537 break;
2538 case 2:
2539 // Change layer opacity that should trigger lcd change.
2540 layer_tree_host()->root_layer()->SetOpacity(.5f);
2541 break;
2542 case 3:
2543 // Change layer opacity that should not trigger lcd change.
2544 layer_tree_host()->root_layer()->SetOpacity(1.f);
2545 break;
2546 case 4:
2547 EndTest();
2548 break;
2549 }
2550 }
2551
2552 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
2553 const Tile* tile) override {
2554 ++num_tiles_rastered_;
2555 }
2556
2557 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2558 PictureLayerImpl* root_layer =
2559 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer());
2560 bool can_use_lcd_text =
2561 host_impl->active_tree()->root_layer()->can_use_lcd_text();
2562 switch (host_impl->active_tree()->source_frame_number()) {
2563 case 0:
2564 // The first draw.
2565 EXPECT_EQ(1, num_tiles_rastered_);
2566 EXPECT_TRUE(can_use_lcd_text);
2567 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2568 break;
2569 case 1:
2570 // Nothing changed on the layer.
2571 EXPECT_EQ(1, num_tiles_rastered_);
2572 EXPECT_TRUE(can_use_lcd_text);
2573 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText());
2574 break;
2575 case 2:
2576 // LCD text was disabled; it should be re-rastered with LCD text off.
2577 EXPECT_EQ(2, num_tiles_rastered_);
2578 EXPECT_FALSE(can_use_lcd_text);
2579 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2580 break;
2581 case 3:
2582 // LCD text was enabled, but it's sticky and stays off.
2583 EXPECT_EQ(2, num_tiles_rastered_);
2584 EXPECT_TRUE(can_use_lcd_text);
2585 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText());
2586 break;
2587 }
2588 }
2589
2590 void AfterTest() override {}
2591
2592 private:
2593 FakeContentLayerClient client_;
2594 int num_tiles_rastered_;
2595 };
2596
2597 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
2598
2599 // Verify that the BeginFrame notification is used to initiate rendering.
2600 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2601 public:
2602 void InitializeSettings(LayerTreeSettings* settings) override {
2603 settings->use_external_begin_frame_source = true;
2604 }
2605
2606 void BeginTest() override {
2607 // This will trigger a SetNeedsBeginFrame which will trigger a
2608 // BeginFrame.
2609 PostSetNeedsCommitToMainThread();
2610 }
2611
2612 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2613 LayerTreeHostImpl::FrameData* frame,
2614 DrawResult draw_result) override {
2615 EndTest();
2616 return DRAW_SUCCESS;
2617 }
2618
2619 void AfterTest() override {}
2620
2621 private:
2622 base::TimeTicks frame_time_;
2623 };
2624
2625 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2626
2627 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2628 : public LayerTreeHostTest {
2629 public:
2630 void InitializeSettings(LayerTreeSettings* settings) override {
2631 settings->use_external_begin_frame_source = true;
2632 settings->using_synchronous_renderer_compositor = true;
2633 }
2634
2635 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2636
2637 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2638 // The BeginFrame notification is turned off now but will get enabled
2639 // once we return. End test while it's enabled.
2640 ImplThreadTaskRunner()->PostTask(
2641 FROM_HERE,
2642 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2643 base::Unretained(this)));
2644 }
2645
2646 void AfterTest() override {}
2647 };
2648
2649 MULTI_THREAD_TEST_F(
2650 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2651
2652 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2653 protected:
2654 LayerTreeHostTestAbortedCommitDoesntStall()
2655 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
2656
2657 void InitializeSettings(LayerTreeSettings* settings) override {
2658 settings->use_external_begin_frame_source = true;
2659 }
2660
2661 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2662
2663 void DidCommit() override {
2664 commit_count_++;
2665 if (commit_count_ == 4) {
2666 // After two aborted commits, request a real commit now to make sure a
2667 // real commit following an aborted commit will still complete and
2668 // end the test even when the Impl thread is idle.
2669 layer_tree_host()->SetNeedsCommit();
2670 }
2671 }
2672
2673 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
2674 CommitEarlyOutReason reason) override {
2675 commit_abort_count_++;
2676 // Initiate another abortable commit.
2677 host_impl->SetNeedsCommit();
2678 }
2679
2680 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2681 commit_complete_count_++;
2682 if (commit_complete_count_ == 1) {
2683 // Initiate an abortable commit after the first commit.
2684 host_impl->SetNeedsCommit();
2685 } else {
2686 EndTest();
2687 }
2688 }
2689
2690 void AfterTest() override {
2691 EXPECT_EQ(commit_count_, 5);
2692 EXPECT_EQ(commit_abort_count_, 3);
2693 EXPECT_EQ(commit_complete_count_, 2);
2694 }
2695
2696 int commit_count_;
2697 int commit_abort_count_;
2698 int commit_complete_count_;
2699 };
2700
2701 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2702 : public LayerTreeHostTestAbortedCommitDoesntStall {
2703 void InitializeSettings(LayerTreeSettings* settings) override {
2704 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2705 settings->using_synchronous_renderer_compositor = true;
2706 }
2707 };
2708
2709 MULTI_THREAD_TEST_F(
2710 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2711
2712 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2713 : public LayerTreeHostTestAbortedCommitDoesntStall {
2714 void InitializeSettings(LayerTreeSettings* settings) override {
2715 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2716 settings->throttle_frame_production = false;
2717 }
2718 };
2719
2720 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2721
2722 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2723 : public LayerTreeHostTest {
2724 protected:
2725 void InitializeSettings(LayerTreeSettings* settings) override {
2726 settings->impl_side_painting = true;
2727 }
2728
2729 void SetupTree() override {
2730 LayerTreeHostTest::SetupTree();
2731
2732 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2733 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2734 layer->SetBounds(gfx::Size(10, 10));
2735 layer_tree_host()->root_layer()->AddChild(layer);
2736 }
2737
2738 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2739
2740 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2741 EndTest();
2742 }
2743
2744 void AfterTest() override {}
2745
2746 FakeContentLayerClient client_;
2747 };
2748
2749 MULTI_THREAD_TEST_F(
2750 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2751
2752 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2753 : public LayerTreeHostTest {
2754 public:
2755 class SetBoundsClient : public ContentLayerClient {
2756 public:
2757 SetBoundsClient() : layer_(0) {}
2758
2759 void set_layer(Layer* layer) { layer_ = layer; }
2760
2761 void PaintContents(SkCanvas* canvas,
2762 const gfx::Rect& clip,
2763 PaintingControlSetting picture_control) override {
2764 layer_->SetBounds(gfx::Size(2, 2));
2765 }
2766
2767 scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
2768 const gfx::Rect& clip,
2769 PaintingControlSetting picture_control) override {
2770 NOTIMPLEMENTED();
2771 return DisplayItemList::Create();
2772 }
2773
2774 bool FillsBoundsCompletely() const override { return false; }
2775
2776 private:
2777 Layer* layer_;
2778 };
2779
2780 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2781
2782 void SetupTree() override {
2783 if (layer_tree_host()->settings().impl_side_painting) {
2784 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_);
2785 layer_tree_host()->SetRootLayer(root_layer);
2786 } else {
2787 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2788 layer_tree_host()->SetRootLayer(root_layer);
2789 }
2790 Layer* root_layer = layer_tree_host()->root_layer();
2791 root_layer->SetIsDrawable(true);
2792 root_layer->SetBounds(gfx::Size(1, 1));
2793
2794 client_.set_layer(root_layer);
2795
2796 LayerTreeHostTest::SetupTree();
2797 }
2798
2799 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2800 void AfterTest() override {}
2801
2802 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2803 num_commits_++;
2804 if (num_commits_ == 1) {
2805 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2806 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds());
2807 } else {
2808 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2809 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds());
2810 EndTest();
2811 }
2812 }
2813
2814 private:
2815 SetBoundsClient client_;
2816 int num_commits_;
2817 };
2818
2819 SINGLE_AND_MULTI_THREAD_TEST_F(
2820 LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2821
2822 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2823 public:
2824 MockIOSurfaceWebGraphicsContext3D() {
2825 test_capabilities_.gpu.iosurface = true;
2826 test_capabilities_.gpu.texture_rectangle = true;
2827 }
2828
2829 GLuint createTexture() override { return 1; }
2830 MOCK_METHOD1(activeTexture, void(GLenum texture));
2831 MOCK_METHOD2(bindTexture, void(GLenum target,
2832 GLuint texture_id));
2833 MOCK_METHOD3(texParameteri, void(GLenum target,
2834 GLenum pname,
2835 GLint param));
2836 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
2837 GLint width,
2838 GLint height,
2839 GLuint ioSurfaceId,
2840 GLuint plane));
2841 MOCK_METHOD4(drawElements, void(GLenum mode,
2842 GLsizei count,
2843 GLenum type,
2844 GLintptr offset));
2845 MOCK_METHOD1(deleteTexture, void(GLenum texture));
2846 MOCK_METHOD3(produceTextureDirectCHROMIUM,
2847 void(GLuint texture, GLenum target, const GLbyte* mailbox));
2848 };
2849
2850 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2851 protected:
2852 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
2853 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2854 new MockIOSurfaceWebGraphicsContext3D);
2855 mock_context_ = mock_context_owned.get();
2856
2857 if (delegating_renderer())
2858 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass());
2859 else
2860 return FakeOutputSurface::Create3d(mock_context_owned.Pass());
2861 }
2862
2863 void SetupTree() override {
2864 LayerTreeHostTest::SetupTree();
2865
2866 layer_tree_host()->root_layer()->SetIsDrawable(false);
2867
2868 io_surface_id_ = 9;
2869 io_surface_size_ = gfx::Size(6, 7);
2870
2871 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2872 io_surface_layer->SetBounds(gfx::Size(10, 10));
2873 io_surface_layer->SetIsDrawable(true);
2874 io_surface_layer->SetContentsOpaque(true);
2875 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2876 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2877 }
2878
2879 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2880
2881 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
2882 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
2883 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2884
2885 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
2886 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2887 .Times(AtLeast(1));
2888 EXPECT_CALL(*mock_context_,
2889 texParameteri(
2890 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
2891 .Times(1);
2892 EXPECT_CALL(*mock_context_,
2893 texParameteri(
2894 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
2895 .Times(1);
2896 EXPECT_CALL(*mock_context_,
2897 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2898 GL_TEXTURE_POOL_CHROMIUM,
2899 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
2900 EXPECT_CALL(*mock_context_,
2901 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2902 GL_TEXTURE_WRAP_S,
2903 GL_CLAMP_TO_EDGE)).Times(1);
2904 EXPECT_CALL(*mock_context_,
2905 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2906 GL_TEXTURE_WRAP_T,
2907 GL_CLAMP_TO_EDGE)).Times(1);
2908
2909 EXPECT_CALL(*mock_context_,
2910 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
2911 io_surface_size_.width(),
2912 io_surface_size_.height(),
2913 io_surface_id_,
2914 0)).Times(1);
2915
2916 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
2917 }
2918
2919 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2920 LayerTreeHostImpl::FrameData* frame,
2921 DrawResult draw_result) override {
2922 Mock::VerifyAndClearExpectations(&mock_context_);
2923 ResourceProvider* resource_provider = host_impl->resource_provider();
2924 EXPECT_EQ(1u, resource_provider->num_resources());
2925 CHECK_EQ(1u, frame->render_passes.size());
2926 CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
2927 const DrawQuad* quad = frame->render_passes[0]->quad_list.front();
2928 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
2929 const IOSurfaceDrawQuad* io_surface_draw_quad =
2930 IOSurfaceDrawQuad::MaterialCast(quad);
2931 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
2932 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
2933 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
2934 resource_provider->TargetForTesting(
2935 io_surface_draw_quad->io_surface_resource_id));
2936
2937 if (delegating_renderer()) {
2938 // The io surface layer's resource should be sent to the parent.
2939 EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM(
2940 _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
2941 } else {
2942 // The io surface layer's texture is drawn.
2943 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
2944 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2945 .Times(AtLeast(1));
2946 }
2947
2948 return draw_result;
2949 }
2950
2951 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2952 Mock::VerifyAndClearExpectations(&mock_context_);
2953
2954 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
2955 EndTest();
2956 }
2957
2958 void AfterTest() override {}
2959
2960 int io_surface_id_;
2961 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2962 gfx::Size io_surface_size_;
2963 };
2964
2965 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2966
2967 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2968 public:
2969 void BeginTest() override {
2970 frame_ = 0;
2971 PostSetNeedsCommitToMainThread();
2972 }
2973
2974 // Round 1: commit + draw
2975 // Round 2: commit only (no draw/swap)
2976 // Round 3: draw only (no commit)
2977
2978 void DidCommit() override {
2979 int commit = layer_tree_host()->source_frame_number();
2980 switch (commit) {
2981 case 2:
2982 // Round 2 done.
2983 EXPECT_EQ(1, frame_);
2984 layer_tree_host()->SetNeedsRedraw();
2985 break;
2986 }
2987 }
2988
2989 void DidCompleteSwapBuffers() override {
2990 int commit = layer_tree_host()->source_frame_number();
2991 ++frame_;
2992 switch (frame_) {
2993 case 1:
2994 // Round 1 done.
2995 EXPECT_EQ(1, commit);
2996 layer_tree_host()->SetNeedsCommit();
2997 break;
2998 case 2:
2999 // Round 3 done.
3000 EXPECT_EQ(2, commit);
3001 EndTest();
3002 break;
3003 }
3004 }
3005
3006 void AfterTest() override {}
3007
3008 protected:
3009 int frame_;
3010 };
3011
3012 // Flaky on all platforms: http://crbug.com/327498
3013 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
3014 RunTest(true, true, true);
3015 }
3016
3017 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
3018 RunTest(true, false, true);
3019 }
3020
3021 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
3022 public:
3023 void InitializeSettings(LayerTreeSettings* settings) override {
3024 // PictureLayer can only be used with impl side painting enabled.
3025 settings->impl_side_painting = true;
3026 }
3027
3028 void SetupTree() override {
3029 layer_ = FakePictureLayer::Create(&client_);
3030 // Force commits to not be aborted so new frames get drawn, otherwise
3031 // the renderer gets deferred initialized but nothing new needs drawing.
3032 layer_->set_always_update_resources(true);
3033 layer_tree_host()->SetRootLayer(layer_);
3034 LayerTreeHostTest::SetupTree();
3035 }
3036
3037 void BeginTest() override {
3038 did_initialize_gl_ = false;
3039 did_release_gl_ = false;
3040 last_source_frame_number_drawn_ = -1; // Never drawn.
3041 PostSetNeedsCommitToMainThread();
3042 }
3043
3044 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3045 scoped_ptr<TestWebGraphicsContext3D> context3d(
3046 TestWebGraphicsContext3D::Create());
3047
3048 return FakeOutputSurface::CreateDeferredGL(
3049 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
3050 delegating_renderer());
3051 }
3052
3053 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
3054 ASSERT_TRUE(host_impl->RootLayer());
3055 FakePictureLayerImpl* layer_impl =
3056 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
3057
3058 // The same frame can be draw multiple times if new visible tiles are
3059 // rasterized. But we want to make sure we only post DeferredInitialize
3060 // and ReleaseGL once, so early out if the same frame is drawn again.
3061 if (last_source_frame_number_drawn_ ==
3062 host_impl->active_tree()->source_frame_number())
3063 return;
3064
3065 last_source_frame_number_drawn_ =
3066 host_impl->active_tree()->source_frame_number();
3067
3068 if (!did_initialize_gl_) {
3069 EXPECT_LE(1u, layer_impl->append_quads_count());
3070 ImplThreadTaskRunner()->PostTask(
3071 FROM_HERE,
3072 base::Bind(
3073 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3074 base::Unretained(this),
3075 base::Unretained(host_impl)));
3076 } else if (did_initialize_gl_ && !did_release_gl_) {
3077 EXPECT_LE(2u, layer_impl->append_quads_count());
3078 ImplThreadTaskRunner()->PostTask(
3079 FROM_HERE,
3080 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3081 base::Unretained(this),
3082 base::Unretained(host_impl)));
3083 } else if (did_initialize_gl_ && did_release_gl_) {
3084 EXPECT_LE(3u, layer_impl->append_quads_count());
3085 EndTest();
3086 }
3087 }
3088
3089 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
3090 EXPECT_FALSE(did_initialize_gl_);
3091 // SetAndInitializeContext3D calls SetNeedsCommit.
3092 FakeOutputSurface* fake_output_surface =
3093 static_cast<FakeOutputSurface*>(host_impl->output_surface());
3094 scoped_refptr<TestContextProvider> context_provider =
3095 TestContextProvider::Create(); // Not bound to thread.
3096 scoped_refptr<TestContextProvider> worker_context_provider =
3097 TestContextProvider::Create(); // Not bound to thread.
3098 EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d(
3099 context_provider, worker_context_provider));
3100 did_initialize_gl_ = true;
3101 }
3102
3103 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3104 EXPECT_TRUE(did_initialize_gl_);
3105 EXPECT_FALSE(did_release_gl_);
3106 // ReleaseGL calls SetNeedsCommit.
3107 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3108 did_release_gl_ = true;
3109 }
3110
3111 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
3112 ASSERT_TRUE(result);
3113 DelegatedFrameData* delegated_frame_data =
3114 output_surface()->last_sent_frame().delegated_frame_data.get();
3115 if (!delegated_frame_data)
3116 return;
3117
3118 // Return all resources immediately.
3119 TransferableResourceArray resources_to_return =
3120 output_surface()->resources_held_by_parent();
3121
3122 CompositorFrameAck ack;
3123 for (size_t i = 0; i < resources_to_return.size(); ++i)
3124 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
3125 host_impl->ReclaimResources(&ack);
3126 }
3127
3128 void AfterTest() override {
3129 EXPECT_TRUE(did_initialize_gl_);
3130 EXPECT_TRUE(did_release_gl_);
3131 }
3132
3133 private:
3134 FakeContentLayerClient client_;
3135 scoped_refptr<FakePictureLayer> layer_;
3136 bool did_initialize_gl_;
3137 bool did_release_gl_;
3138 int last_source_frame_number_drawn_;
3139 };
3140
3141 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3142
3143 class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest {
3144 public:
3145 void SetupTree() override {
3146 root_layer_ = FakePictureLayer::Create(&client_);
3147 root_layer_->SetIsDrawable(true);
3148 root_layer_->SetBounds(gfx::Size(50, 50));
3149
3150 parent_layer_ = FakePictureLayer::Create(&client_);
3151 parent_layer_->SetIsDrawable(true);
3152 parent_layer_->SetBounds(gfx::Size(50, 50));
3153 parent_layer_->SetForceRenderSurface(true);
3154
3155 child_layer_ = FakePictureLayer::Create(&client_);
3156 child_layer_->SetIsDrawable(true);
3157 child_layer_->SetBounds(gfx::Size(50, 50));
3158
3159 root_layer_->AddChild(parent_layer_);
3160 parent_layer_->AddChild(child_layer_);
3161 layer_tree_host()->SetRootLayer(root_layer_);
3162
3163 LayerTreeHostTest::SetupTree();
3164 }
3165
3166 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
3167 return FakeOutputSurface::CreateDeferredGL(
3168 make_scoped_ptr(new SoftwareOutputDevice), delegating_renderer());
3169 }
3170
3171 void BeginTest() override {
3172 PostSetNeedsCommitToMainThread();
3173 swap_count_ = 0;
3174 }
3175
3176 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3177 LayerTreeHostImpl::FrameData* frame_data,
3178 DrawResult draw_result) override {
3179 if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
3180 EXPECT_EQ(1u, frame_data->render_passes.size());
3181 // Has at least 3 quads for each layer.
3182 RenderPass* render_pass = frame_data->render_passes[0];
3183 EXPECT_GE(render_pass->quad_list.size(), 3u);
3184 } else {
3185 EXPECT_EQ(2u, frame_data->render_passes.size());
3186
3187 // At least root layer quad in root render pass.
3188 EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u);
3189 // At least parent and child layer quads in parent render pass.
3190 EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u);
3191 }
3192 return draw_result;
3193 }
3194
3195 void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3196 swap_count_++;
3197 switch (swap_count_) {
3198 case 1: {
3199 gfx::Transform identity;
3200 gfx::Rect empty_rect;
3201 bool resourceless_software_draw = true;
3202 host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect,
3203 empty_rect, identity,
3204 resourceless_software_draw);
3205 host_impl->SetFullRootLayerDamage();
3206 host_impl->SetNeedsRedraw();
3207 break;
3208 }
3209 case 2:
3210 EndTest();
3211 break;
3212 default:
3213 NOTREACHED();
3214 }
3215 }
3216
3217 void AfterTest() override {}
3218
3219 private:
3220 FakeContentLayerClient client_;
3221 scoped_refptr<Layer> root_layer_;
3222 scoped_refptr<Layer> parent_layer_;
3223 scoped_refptr<Layer> child_layer_;
3224 int swap_count_;
3225 };
3226
3227 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw);
3228
3229 class LayerTreeHostTestDeferredInitializeWithGpuRasterization
3230 : public LayerTreeHostTestDeferredInitialize {
3231 void InitializeSettings(LayerTreeSettings* settings) override {
3232 // PictureLayer can only be used with impl side painting enabled.
3233 settings->impl_side_painting = true;
3234 settings->gpu_rasterization_enabled = true;
3235 settings->gpu_rasterization_forced = true;
3236 }
3237 };
3238
3239 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization);
3240
3241 // Test for UI Resource management.
3242 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3243 public:
3244 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
3245
3246 void InitializeSettings(LayerTreeSettings* settings) override {
3247 settings->renderer_settings.texture_id_allocation_chunk_size = 1;
3248 }
3249
3250 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3251
3252 void DidCommit() override {
3253 int frame = layer_tree_host()->source_frame_number();
3254 switch (frame) {
3255 case 1:
3256 CreateResource();
3257 CreateResource();
3258 PostSetNeedsCommitToMainThread();
3259 break;
3260 case 2:
3261 // Usually ScopedUIResource are deleted from the manager in their
3262 // destructor. Here we just want to test that a direct call to
3263 // DeleteUIResource works.
3264 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3265 PostSetNeedsCommitToMainThread();
3266 break;
3267 case 3:
3268 // DeleteUIResource can be called with an invalid id.
3269 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3270 PostSetNeedsCommitToMainThread();
3271 break;
3272 case 4:
3273 CreateResource();
3274 CreateResource();
3275 PostSetNeedsCommitToMainThread();
3276 break;
3277 case 5:
3278 ClearResources();
3279 EndTest();
3280 break;
3281 }
3282 }
3283
3284 void PerformTest(LayerTreeHostImpl* impl) {
3285 TestWebGraphicsContext3D* context = TestContext();
3286
3287 int frame = impl->active_tree()->source_frame_number();
3288 switch (frame) {
3289 case 0:
3290 ASSERT_EQ(0u, context->NumTextures());
3291 break;
3292 case 1:
3293 // Created two textures.
3294 ASSERT_EQ(2u, context->NumTextures());
3295 break;
3296 case 2:
3297 // One texture left after one deletion.
3298 ASSERT_EQ(1u, context->NumTextures());
3299 break;
3300 case 3:
3301 // Resource manager state should not change when delete is called on an
3302 // invalid id.
3303 ASSERT_EQ(1u, context->NumTextures());
3304 break;
3305 case 4:
3306 // Creation after deletion: two more creates should total up to
3307 // three textures.
3308 ASSERT_EQ(3u, context->NumTextures());
3309 break;
3310 }
3311 }
3312
3313 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3314 if (!impl->settings().impl_side_painting)
3315 PerformTest(impl);
3316 }
3317
3318 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3319 if (impl->settings().impl_side_painting)
3320 PerformTest(impl);
3321 }
3322
3323 void AfterTest() override {}
3324
3325 private:
3326 // Must clear all resources before exiting.
3327 void ClearResources() {
3328 for (int i = 0; i < num_ui_resources_; i++)
3329 ui_resources_[i] = nullptr;
3330 }
3331
3332 void CreateResource() {
3333 ui_resources_[num_ui_resources_++] =
3334 FakeScopedUIResource::Create(layer_tree_host());
3335 }
3336
3337 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3338 int num_ui_resources_;
3339 };
3340
3341 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3342
3343 class PushPropertiesCountingLayerImpl : public LayerImpl {
3344 public:
3345 static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
3346 LayerTreeImpl* tree_impl, int id) {
3347 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
3348 }
3349
3350 ~PushPropertiesCountingLayerImpl() override {}
3351
3352 void PushPropertiesTo(LayerImpl* layer) override {
3353 LayerImpl::PushPropertiesTo(layer);
3354 push_properties_count_++;
3355 // Push state to the active tree because we can only access it from there.
3356 static_cast<PushPropertiesCountingLayerImpl*>(
3357 layer)->push_properties_count_ = push_properties_count_;
3358 }
3359
3360 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3361 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3362 }
3363
3364 size_t push_properties_count() const { return push_properties_count_; }
3365 void reset_push_properties_count() { push_properties_count_ = 0; }
3366
3367 private:
3368 size_t push_properties_count_;
3369
3370 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
3371 : LayerImpl(tree_impl, id),
3372 push_properties_count_(0) {
3373 SetBounds(gfx::Size(1, 1));
3374 }
3375 };
3376
3377 class PushPropertiesCountingLayer : public Layer {
3378 public:
3379 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3380 return new PushPropertiesCountingLayer();
3381 }
3382
3383 void PushPropertiesTo(LayerImpl* layer) override {
3384 Layer::PushPropertiesTo(layer);
3385 push_properties_count_++;
3386 if (persist_needs_push_properties_)
3387 needs_push_properties_ = true;
3388 }
3389
3390 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
3391 return PushPropertiesCountingLayerImpl::Create(tree_impl, id());
3392 }
3393
3394 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); }
3395
3396 size_t push_properties_count() const { return push_properties_count_; }
3397 void reset_push_properties_count() { push_properties_count_ = 0; }
3398
3399 void set_persist_needs_push_properties(bool persist) {
3400 persist_needs_push_properties_ = persist;
3401 }
3402
3403 private:
3404 PushPropertiesCountingLayer()
3405 : push_properties_count_(0), persist_needs_push_properties_(false) {
3406 SetBounds(gfx::Size(1, 1));
3407 }
3408 ~PushPropertiesCountingLayer() override {}
3409
3410 size_t push_properties_count_;
3411 bool persist_needs_push_properties_;
3412 };
3413
3414 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3415 protected:
3416 void BeginTest() override {
3417 num_commits_ = 0;
3418 expected_push_properties_root_ = 0;
3419 expected_push_properties_child_ = 0;
3420 expected_push_properties_grandchild_ = 0;
3421 expected_push_properties_child2_ = 0;
3422 expected_push_properties_other_root_ = 0;
3423 expected_push_properties_leaf_layer_ = 0;
3424 PostSetNeedsCommitToMainThread();
3425 }
3426
3427 void SetupTree() override {
3428 root_ = PushPropertiesCountingLayer::Create();
3429 root_->CreateRenderSurface();
3430 child_ = PushPropertiesCountingLayer::Create();
3431 child2_ = PushPropertiesCountingLayer::Create();
3432 grandchild_ = PushPropertiesCountingLayer::Create();
3433 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3434 leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3435
3436 root_->AddChild(child_);
3437 root_->AddChild(child2_);
3438 child_->AddChild(grandchild_);
3439 child2_->AddChild(leaf_always_pushing_layer_);
3440
3441 other_root_ = PushPropertiesCountingLayer::Create();
3442 other_root_->CreateRenderSurface();
3443
3444 // Don't set the root layer here.
3445 LayerTreeHostTest::SetupTree();
3446 }
3447
3448 void DidCommitAndDrawFrame() override {
3449 ++num_commits_;
3450
3451 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3452 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3453 EXPECT_EQ(expected_push_properties_grandchild_,
3454 grandchild_->push_properties_count());
3455 EXPECT_EQ(expected_push_properties_child2_,
3456 child2_->push_properties_count());
3457 EXPECT_EQ(expected_push_properties_other_root_,
3458 other_root_->push_properties_count());
3459 EXPECT_EQ(expected_push_properties_leaf_layer_,
3460 leaf_always_pushing_layer_->push_properties_count());
3461
3462 // The scrollbar layer always needs to be pushed.
3463 if (root_->layer_tree_host()) {
3464 EXPECT_TRUE(root_->descendant_needs_push_properties());
3465 EXPECT_FALSE(root_->needs_push_properties());
3466 }
3467 if (child2_->layer_tree_host()) {
3468 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3469 EXPECT_FALSE(child2_->needs_push_properties());
3470 }
3471 if (leaf_always_pushing_layer_->layer_tree_host()) {
3472 EXPECT_FALSE(
3473 leaf_always_pushing_layer_->descendant_needs_push_properties());
3474 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3475 }
3476
3477 // child_ and grandchild_ don't persist their need to push properties.
3478 if (child_->layer_tree_host()) {
3479 EXPECT_FALSE(child_->descendant_needs_push_properties());
3480 EXPECT_FALSE(child_->needs_push_properties());
3481 }
3482 if (grandchild_->layer_tree_host()) {
3483 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3484 EXPECT_FALSE(grandchild_->needs_push_properties());
3485 }
3486
3487 if (other_root_->layer_tree_host()) {
3488 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3489 EXPECT_FALSE(other_root_->needs_push_properties());
3490 }
3491
3492 switch (num_commits_) {
3493 case 1:
3494 layer_tree_host()->SetRootLayer(root_);
3495 // Layers added to the tree get committed.
3496 ++expected_push_properties_root_;
3497 ++expected_push_properties_child_;
3498 ++expected_push_properties_grandchild_;
3499 ++expected_push_properties_child2_;
3500 break;
3501 case 2:
3502 layer_tree_host()->SetNeedsCommit();
3503 // No layers need commit.
3504 break;
3505 case 3:
3506 layer_tree_host()->SetRootLayer(other_root_);
3507 // Layers added to the tree get committed.
3508 ++expected_push_properties_other_root_;
3509 break;
3510 case 4:
3511 layer_tree_host()->SetRootLayer(root_);
3512 // Layers added to the tree get committed.
3513 ++expected_push_properties_root_;
3514 ++expected_push_properties_child_;
3515 ++expected_push_properties_grandchild_;
3516 ++expected_push_properties_child2_;
3517 break;
3518 case 5:
3519 layer_tree_host()->SetNeedsCommit();
3520 // No layers need commit.
3521 break;
3522 case 6:
3523 child_->RemoveFromParent();
3524 // No layers need commit.
3525 break;
3526 case 7:
3527 root_->AddChild(child_);
3528 // Layers added to the tree get committed.
3529 ++expected_push_properties_child_;
3530 ++expected_push_properties_grandchild_;
3531 break;
3532 case 8:
3533 grandchild_->RemoveFromParent();
3534 // No layers need commit.
3535 break;
3536 case 9:
3537 child_->AddChild(grandchild_);
3538 // Layers added to the tree get committed.
3539 ++expected_push_properties_grandchild_;
3540 break;
3541 case 10:
3542 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3543 // No layers need commit.
3544 break;
3545 case 11:
3546 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3547 // No layers need commit.
3548 break;
3549 case 12:
3550 child_->SetPosition(gfx::Point(1, 1));
3551 // The modified layer needs commit
3552 ++expected_push_properties_child_;
3553 break;
3554 case 13:
3555 child2_->SetPosition(gfx::Point(1, 1));
3556 // The modified layer needs commit
3557 ++expected_push_properties_child2_;
3558 break;
3559 case 14:
3560 child_->RemoveFromParent();
3561 root_->AddChild(child_);
3562 // Layers added to the tree get committed.
3563 ++expected_push_properties_child_;
3564 ++expected_push_properties_grandchild_;
3565 break;
3566 case 15:
3567 grandchild_->SetPosition(gfx::Point(1, 1));
3568 // The modified layer needs commit
3569 ++expected_push_properties_grandchild_;
3570 break;
3571 case 16:
3572 // SetNeedsDisplay does not always set needs commit (so call it
3573 // explicitly), but is a property change.
3574 child_->SetNeedsDisplay();
3575 ++expected_push_properties_child_;
3576 layer_tree_host()->SetNeedsCommit();
3577 break;
3578 case 17:
3579 EndTest();
3580 break;
3581 }
3582
3583 // The leaf layer always pushes.
3584 if (leaf_always_pushing_layer_->layer_tree_host())
3585 ++expected_push_properties_leaf_layer_;
3586 }
3587
3588 void AfterTest() override {}
3589
3590 int num_commits_;
3591 FakeContentLayerClient client_;
3592 scoped_refptr<PushPropertiesCountingLayer> root_;
3593 scoped_refptr<PushPropertiesCountingLayer> child_;
3594 scoped_refptr<PushPropertiesCountingLayer> child2_;
3595 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3596 scoped_refptr<PushPropertiesCountingLayer> other_root_;
3597 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
3598 size_t expected_push_properties_root_;
3599 size_t expected_push_properties_child_;
3600 size_t expected_push_properties_child2_;
3601 size_t expected_push_properties_grandchild_;
3602 size_t expected_push_properties_other_root_;
3603 size_t expected_push_properties_leaf_layer_;
3604 };
3605
3606 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3607
3608 class LayerTreeHostTestImplLayersPushProperties
3609 : public LayerTreeHostTestLayersPushProperties {
3610 protected:
3611 void BeginTest() override {
3612 expected_push_properties_root_impl_ = 0;
3613 expected_push_properties_child_impl_ = 0;
3614 expected_push_properties_grandchild_impl_ = 0;
3615 expected_push_properties_child2_impl_ = 0;
3616 expected_push_properties_grandchild2_impl_ = 0;
3617 LayerTreeHostTestLayersPushProperties::BeginTest();
3618 }
3619
3620 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3621 // These commits are in response to the changes made in
3622 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
3623 switch (num_commits_) {
3624 case 0:
3625 // Tree hasn't been setup yet don't bother to check anything.
3626 return;
3627 case 1:
3628 // Root gets set up, Everyone is initialized.
3629 ++expected_push_properties_root_impl_;
3630 ++expected_push_properties_child_impl_;
3631 ++expected_push_properties_grandchild_impl_;
3632 ++expected_push_properties_child2_impl_;
3633 ++expected_push_properties_grandchild2_impl_;
3634 break;
3635 case 2:
3636 // Tree doesn't change but the one leaf that always pushes is pushed.
3637 ++expected_push_properties_grandchild2_impl_;
3638 break;
3639 case 3:
3640 // Root is swapped here.
3641 // Clear the expected push properties the tree will be rebuilt.
3642 expected_push_properties_root_impl_ = 0;
3643 expected_push_properties_child_impl_ = 0;
3644 expected_push_properties_grandchild_impl_ = 0;
3645 expected_push_properties_child2_impl_ = 0;
3646 expected_push_properties_grandchild2_impl_ = 0;
3647
3648 // Make sure the new root is pushed.
3649 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
3650 host_impl->RootLayer())->push_properties_count());
3651 return;
3652 case 4:
3653 // Root is swapped back all of the layers in the tree get pushed.
3654 ++expected_push_properties_root_impl_;
3655 ++expected_push_properties_child_impl_;
3656 ++expected_push_properties_grandchild_impl_;
3657 ++expected_push_properties_child2_impl_;
3658 ++expected_push_properties_grandchild2_impl_;
3659 break;
3660 case 5:
3661 // Tree doesn't change but the one leaf that always pushes is pushed.
3662 ++expected_push_properties_grandchild2_impl_;
3663 break;
3664 case 6:
3665 // First child is removed. Structure of the tree changes here so swap
3666 // some of the values. child_impl becomes child2_impl.
3667 expected_push_properties_child_impl_ =
3668 expected_push_properties_child2_impl_;
3669 expected_push_properties_child2_impl_ = 0;
3670 // grandchild_impl becomes grandchild2_impl.
3671 expected_push_properties_grandchild_impl_ =
3672 expected_push_properties_grandchild2_impl_;
3673 expected_push_properties_grandchild2_impl_ = 0;
3674
3675 // grandchild_impl is now the leaf that always pushes. It is pushed.
3676 ++expected_push_properties_grandchild_impl_;
3677 break;
3678 case 7:
3679 // The leaf that always pushes is pushed.
3680 ++expected_push_properties_grandchild_impl_;
3681
3682 // Child is added back. New layers are initialized.
3683 ++expected_push_properties_grandchild2_impl_;
3684 ++expected_push_properties_child2_impl_;
3685 break;
3686 case 8:
3687 // Leaf is removed.
3688 expected_push_properties_grandchild2_impl_ = 0;
3689
3690 // Always pushing.
3691 ++expected_push_properties_grandchild_impl_;
3692 break;
3693 case 9:
3694 // Leaf is added back
3695 ++expected_push_properties_grandchild2_impl_;
3696
3697 // The leaf that always pushes is pushed.
3698 ++expected_push_properties_grandchild_impl_;
3699 break;
3700 case 10:
3701 // The leaf that always pushes is pushed.
3702 ++expected_push_properties_grandchild_impl_;
3703 break;
3704 case 11:
3705 // The leaf that always pushes is pushed.
3706 ++expected_push_properties_grandchild_impl_;
3707 break;
3708 case 12:
3709 // The leaf that always pushes is pushed.
3710 ++expected_push_properties_grandchild_impl_;
3711
3712 // This child position was changed.
3713 ++expected_push_properties_child2_impl_;
3714 break;
3715 case 13:
3716 // The position of this child was changed.
3717 ++expected_push_properties_child_impl_;
3718
3719 // The leaf that always pushes is pushed.
3720 ++expected_push_properties_grandchild_impl_;
3721 break;
3722 case 14:
3723 // Second child is removed from tree. Don't discard counts because
3724 // they are added back before commit.
3725
3726 // The leaf that always pushes is pushed.
3727 ++expected_push_properties_grandchild_impl_;
3728
3729 // Second child added back.
3730 ++expected_push_properties_child2_impl_;
3731 ++expected_push_properties_grandchild2_impl_;
3732
3733 break;
3734 case 15:
3735 // The position of this child was changed.
3736 ++expected_push_properties_grandchild2_impl_;
3737
3738 // The leaf that always pushes is pushed.
3739 ++expected_push_properties_grandchild_impl_;
3740 break;
3741 case 16:
3742 // Second child is invalidated with SetNeedsDisplay
3743 ++expected_push_properties_child2_impl_;
3744
3745 // The leaf that always pushed is pushed.
3746 ++expected_push_properties_grandchild_impl_;
3747 break;
3748 }
3749
3750 PushPropertiesCountingLayerImpl* root_impl_ = NULL;
3751 PushPropertiesCountingLayerImpl* child_impl_ = NULL;
3752 PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
3753 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
3754 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
3755
3756 // Pull the layers that we need from the tree assuming the same structure
3757 // as LayerTreeHostTestLayersPushProperties
3758 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3759 host_impl->RootLayer());
3760
3761 if (root_impl_ && root_impl_->children().size() > 0) {
3762 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3763 root_impl_->children()[0]);
3764
3765 if (child_impl_ && child_impl_->children().size() > 0)
3766 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3767 child_impl_->children()[0]);
3768 }
3769
3770 if (root_impl_ && root_impl_->children().size() > 1) {
3771 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
3772 root_impl_->children()[1]);
3773
3774 if (child2_impl_ && child2_impl_->children().size() > 0)
3775 leaf_always_pushing_layer_impl_ =
3776 static_cast<PushPropertiesCountingLayerImpl*>(
3777 child2_impl_->children()[0]);
3778 }
3779
3780 if (root_impl_)
3781 EXPECT_EQ(expected_push_properties_root_impl_,
3782 root_impl_->push_properties_count());
3783 if (child_impl_)
3784 EXPECT_EQ(expected_push_properties_child_impl_,
3785 child_impl_->push_properties_count());
3786 if (grandchild_impl_)
3787 EXPECT_EQ(expected_push_properties_grandchild_impl_,
3788 grandchild_impl_->push_properties_count());
3789 if (child2_impl_)
3790 EXPECT_EQ(expected_push_properties_child2_impl_,
3791 child2_impl_->push_properties_count());
3792 if (leaf_always_pushing_layer_impl_)
3793 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
3794 leaf_always_pushing_layer_impl_->push_properties_count());
3795 }
3796
3797 size_t expected_push_properties_root_impl_;
3798 size_t expected_push_properties_child_impl_;
3799 size_t expected_push_properties_child2_impl_;
3800 size_t expected_push_properties_grandchild_impl_;
3801 size_t expected_push_properties_grandchild2_impl_;
3802 };
3803
3804 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
3805 RunTestWithImplSidePainting();
3806 }
3807
3808 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3809 : public LayerTreeHostTest {
3810 protected:
3811 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3812
3813 void SetupTree() override {
3814 root_ = Layer::Create();
3815 root_->CreateRenderSurface();
3816 root_->SetBounds(gfx::Size(1, 1));
3817
3818 bool paint_scrollbar = true;
3819 bool has_thumb = false;
3820 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
3821 paint_scrollbar, has_thumb, root_->id());
3822
3823 root_->AddChild(scrollbar_layer_);
3824
3825 layer_tree_host()->SetRootLayer(root_);
3826 LayerTreeHostTest::SetupTree();
3827 }
3828
3829 void DidCommitAndDrawFrame() override {
3830 switch (layer_tree_host()->source_frame_number()) {
3831 case 0:
3832 break;
3833 case 1: {
3834 // During update, the ignore_set_needs_commit_ bit is set to true to
3835 // avoid causing a second commit to be scheduled. If a property change
3836 // is made during this, however, it needs to be pushed in the upcoming
3837 // commit.
3838 scoped_ptr<base::AutoReset<bool>> ignore =
3839 scrollbar_layer_->IgnoreSetNeedsCommit();
3840
3841 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3842
3843 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3844 EXPECT_TRUE(root_->descendant_needs_push_properties());
3845 layer_tree_host()->SetNeedsCommit();
3846
3847 scrollbar_layer_->reset_push_properties_count();
3848 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3849 break;
3850 }
3851 case 2:
3852 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3853 EndTest();
3854 break;
3855 }
3856 }
3857
3858 void AfterTest() override {}
3859
3860 scoped_refptr<Layer> root_;
3861 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
3862 };
3863
3864 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3865
3866 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
3867 protected:
3868 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3869
3870 void SetupTree() override {
3871 root_ = PushPropertiesCountingLayer::Create();
3872 root_->CreateRenderSurface();
3873 child_ = PushPropertiesCountingLayer::Create();
3874 root_->AddChild(child_);
3875
3876 layer_tree_host()->SetRootLayer(root_);
3877 LayerTreeHostTest::SetupTree();
3878 }
3879
3880 void DidCommitAndDrawFrame() override {
3881 switch (layer_tree_host()->source_frame_number()) {
3882 case 0:
3883 break;
3884 case 1: {
3885 // During update, the ignore_set_needs_commit_ bit is set to true to
3886 // avoid causing a second commit to be scheduled. If a property change
3887 // is made during this, however, it needs to be pushed in the upcoming
3888 // commit.
3889 EXPECT_FALSE(root_->needs_push_properties());
3890 EXPECT_FALSE(child_->needs_push_properties());
3891 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
3892 root_->reset_push_properties_count();
3893 child_->reset_push_properties_count();
3894 child_->SetDrawsContent(true);
3895 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
3896 EXPECT_EQ(0u, root_->push_properties_count());
3897 EXPECT_EQ(0u, child_->push_properties_count());
3898 EXPECT_TRUE(root_->needs_push_properties());
3899 EXPECT_TRUE(child_->needs_push_properties());
3900 break;
3901 }
3902 case 2:
3903 EXPECT_EQ(1u, root_->push_properties_count());
3904 EXPECT_EQ(1u, child_->push_properties_count());
3905 EXPECT_FALSE(root_->needs_push_properties());
3906 EXPECT_FALSE(child_->needs_push_properties());
3907 EndTest();
3908 break;
3909 }
3910 }
3911
3912 void AfterTest() override {}
3913
3914 scoped_refptr<PushPropertiesCountingLayer> root_;
3915 scoped_refptr<PushPropertiesCountingLayer> child_;
3916 };
3917
3918 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
3919
3920 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3921 : public LayerTreeHostTest {
3922 protected:
3923 void BeginTest() override {
3924 expected_push_properties_root_ = 0;
3925 expected_push_properties_child_ = 0;
3926 expected_push_properties_grandchild1_ = 0;
3927 expected_push_properties_grandchild2_ = 0;
3928 expected_push_properties_grandchild3_ = 0;
3929 PostSetNeedsCommitToMainThread();
3930 }
3931
3932 void SetupTree() override {
3933 root_ = PushPropertiesCountingLayer::Create();
3934 root_->CreateRenderSurface();
3935 child_ = PushPropertiesCountingLayer::Create();
3936 grandchild1_ = PushPropertiesCountingLayer::Create();
3937 grandchild2_ = PushPropertiesCountingLayer::Create();
3938 grandchild3_ = PushPropertiesCountingLayer::Create();
3939
3940 root_->AddChild(child_);
3941 child_->AddChild(grandchild1_);
3942 child_->AddChild(grandchild2_);
3943 child_->AddChild(grandchild3_);
3944
3945 // Don't set the root layer here.
3946 LayerTreeHostTest::SetupTree();
3947 }
3948
3949 void AfterTest() override {}
3950
3951 FakeContentLayerClient client_;
3952 scoped_refptr<PushPropertiesCountingLayer> root_;
3953 scoped_refptr<PushPropertiesCountingLayer> child_;
3954 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3955 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3956 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3957 size_t expected_push_properties_root_;
3958 size_t expected_push_properties_child_;
3959 size_t expected_push_properties_grandchild1_;
3960 size_t expected_push_properties_grandchild2_;
3961 size_t expected_push_properties_grandchild3_;
3962 };
3963
3964 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3965 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3966 protected:
3967 void DidCommitAndDrawFrame() override {
3968 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
3969 switch (last_source_frame_number) {
3970 case 0:
3971 EXPECT_FALSE(root_->needs_push_properties());
3972 EXPECT_FALSE(root_->descendant_needs_push_properties());
3973 EXPECT_FALSE(child_->needs_push_properties());
3974 EXPECT_FALSE(child_->descendant_needs_push_properties());
3975 EXPECT_FALSE(grandchild1_->needs_push_properties());
3976 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3977 EXPECT_FALSE(grandchild2_->needs_push_properties());
3978 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3979 EXPECT_FALSE(grandchild3_->needs_push_properties());
3980 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3981
3982 layer_tree_host()->SetRootLayer(root_);
3983
3984 EXPECT_TRUE(root_->needs_push_properties());
3985 EXPECT_TRUE(root_->descendant_needs_push_properties());
3986 EXPECT_TRUE(child_->needs_push_properties());
3987 EXPECT_TRUE(child_->descendant_needs_push_properties());
3988 EXPECT_TRUE(grandchild1_->needs_push_properties());
3989 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3990 EXPECT_TRUE(grandchild2_->needs_push_properties());
3991 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3992 EXPECT_TRUE(grandchild3_->needs_push_properties());
3993 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3994 break;
3995 case 1:
3996 EndTest();
3997 break;
3998 }
3999 }
4000 };
4001
4002 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
4003
4004 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
4005 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4006 protected:
4007 void DidCommitAndDrawFrame() override {
4008 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4009 switch (last_source_frame_number) {
4010 case 0:
4011 layer_tree_host()->SetRootLayer(root_);
4012 break;
4013 case 1:
4014 EXPECT_FALSE(root_->needs_push_properties());
4015 EXPECT_FALSE(root_->descendant_needs_push_properties());
4016 EXPECT_FALSE(child_->needs_push_properties());
4017 EXPECT_FALSE(child_->descendant_needs_push_properties());
4018 EXPECT_FALSE(grandchild1_->needs_push_properties());
4019 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4020 EXPECT_FALSE(grandchild2_->needs_push_properties());
4021 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4022 EXPECT_FALSE(grandchild3_->needs_push_properties());
4023 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4024
4025 grandchild1_->RemoveFromParent();
4026 grandchild1_->SetPosition(gfx::Point(1, 1));
4027
4028 EXPECT_FALSE(root_->needs_push_properties());
4029 EXPECT_FALSE(root_->descendant_needs_push_properties());
4030 EXPECT_FALSE(child_->needs_push_properties());
4031 EXPECT_FALSE(child_->descendant_needs_push_properties());
4032 EXPECT_FALSE(grandchild2_->needs_push_properties());
4033 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4034 EXPECT_FALSE(grandchild3_->needs_push_properties());
4035 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4036
4037 child_->AddChild(grandchild1_);
4038
4039 EXPECT_FALSE(root_->needs_push_properties());
4040 EXPECT_TRUE(root_->descendant_needs_push_properties());
4041 EXPECT_FALSE(child_->needs_push_properties());
4042 EXPECT_TRUE(child_->descendant_needs_push_properties());
4043 EXPECT_TRUE(grandchild1_->needs_push_properties());
4044 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4045 EXPECT_FALSE(grandchild2_->needs_push_properties());
4046 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4047 EXPECT_FALSE(grandchild3_->needs_push_properties());
4048 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4049
4050 grandchild2_->SetPosition(gfx::Point(1, 1));
4051
4052 EXPECT_FALSE(root_->needs_push_properties());
4053 EXPECT_TRUE(root_->descendant_needs_push_properties());
4054 EXPECT_FALSE(child_->needs_push_properties());
4055 EXPECT_TRUE(child_->descendant_needs_push_properties());
4056 EXPECT_TRUE(grandchild1_->needs_push_properties());
4057 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4058 EXPECT_TRUE(grandchild2_->needs_push_properties());
4059 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4060 EXPECT_FALSE(grandchild3_->needs_push_properties());
4061 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4062
4063 // grandchild2_ will still need a push properties.
4064 grandchild1_->RemoveFromParent();
4065
4066 EXPECT_FALSE(root_->needs_push_properties());
4067 EXPECT_TRUE(root_->descendant_needs_push_properties());
4068 EXPECT_FALSE(child_->needs_push_properties());
4069 EXPECT_TRUE(child_->descendant_needs_push_properties());
4070
4071 // grandchild3_ does not need a push properties, so recursing should
4072 // no longer be needed.
4073 grandchild2_->RemoveFromParent();
4074
4075 EXPECT_FALSE(root_->needs_push_properties());
4076 EXPECT_FALSE(root_->descendant_needs_push_properties());
4077 EXPECT_FALSE(child_->needs_push_properties());
4078 EXPECT_FALSE(child_->descendant_needs_push_properties());
4079 EndTest();
4080 break;
4081 }
4082 }
4083 };
4084
4085 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
4086
4087 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
4088 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4089 protected:
4090 void DidCommitAndDrawFrame() override {
4091 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4092 switch (last_source_frame_number) {
4093 case 0:
4094 layer_tree_host()->SetRootLayer(root_);
4095 grandchild1_->set_persist_needs_push_properties(true);
4096 grandchild2_->set_persist_needs_push_properties(true);
4097 break;
4098 case 1:
4099 EXPECT_FALSE(root_->needs_push_properties());
4100 EXPECT_TRUE(root_->descendant_needs_push_properties());
4101 EXPECT_FALSE(child_->needs_push_properties());
4102 EXPECT_TRUE(child_->descendant_needs_push_properties());
4103 EXPECT_TRUE(grandchild1_->needs_push_properties());
4104 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4105 EXPECT_TRUE(grandchild2_->needs_push_properties());
4106 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4107 EXPECT_FALSE(grandchild3_->needs_push_properties());
4108 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4109
4110 // grandchild2_ will still need a push properties.
4111 grandchild1_->RemoveFromParent();
4112
4113 EXPECT_FALSE(root_->needs_push_properties());
4114 EXPECT_TRUE(root_->descendant_needs_push_properties());
4115 EXPECT_FALSE(child_->needs_push_properties());
4116 EXPECT_TRUE(child_->descendant_needs_push_properties());
4117
4118 // grandchild3_ does not need a push properties, so recursing should
4119 // no longer be needed.
4120 grandchild2_->RemoveFromParent();
4121
4122 EXPECT_FALSE(root_->needs_push_properties());
4123 EXPECT_FALSE(root_->descendant_needs_push_properties());
4124 EXPECT_FALSE(child_->needs_push_properties());
4125 EXPECT_FALSE(child_->descendant_needs_push_properties());
4126 EndTest();
4127 break;
4128 }
4129 }
4130 };
4131
4132 MULTI_THREAD_TEST_F(
4133 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
4134
4135 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
4136 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4137 protected:
4138 void DidCommitAndDrawFrame() override {
4139 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4140 switch (last_source_frame_number) {
4141 case 0:
4142 layer_tree_host()->SetRootLayer(root_);
4143 break;
4144 case 1:
4145 EXPECT_FALSE(root_->needs_push_properties());
4146 EXPECT_FALSE(root_->descendant_needs_push_properties());
4147 EXPECT_FALSE(child_->needs_push_properties());
4148 EXPECT_FALSE(child_->descendant_needs_push_properties());
4149 EXPECT_FALSE(grandchild1_->needs_push_properties());
4150 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4151 EXPECT_FALSE(grandchild2_->needs_push_properties());
4152 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4153 EXPECT_FALSE(grandchild3_->needs_push_properties());
4154 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4155
4156 // Change grandchildren while their parent is not in the tree.
4157 child_->RemoveFromParent();
4158 grandchild1_->SetPosition(gfx::Point(1, 1));
4159 grandchild2_->SetPosition(gfx::Point(1, 1));
4160 root_->AddChild(child_);
4161
4162 EXPECT_FALSE(root_->needs_push_properties());
4163 EXPECT_TRUE(root_->descendant_needs_push_properties());
4164 EXPECT_TRUE(child_->needs_push_properties());
4165 EXPECT_TRUE(child_->descendant_needs_push_properties());
4166 EXPECT_TRUE(grandchild1_->needs_push_properties());
4167 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4168 EXPECT_TRUE(grandchild2_->needs_push_properties());
4169 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4170 EXPECT_TRUE(grandchild3_->needs_push_properties());
4171 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4172
4173 grandchild1_->RemoveFromParent();
4174
4175 EXPECT_FALSE(root_->needs_push_properties());
4176 EXPECT_TRUE(root_->descendant_needs_push_properties());
4177 EXPECT_TRUE(child_->needs_push_properties());
4178 EXPECT_TRUE(child_->descendant_needs_push_properties());
4179
4180 grandchild2_->RemoveFromParent();
4181
4182 EXPECT_FALSE(root_->needs_push_properties());
4183 EXPECT_TRUE(root_->descendant_needs_push_properties());
4184 EXPECT_TRUE(child_->needs_push_properties());
4185 EXPECT_TRUE(child_->descendant_needs_push_properties());
4186
4187 grandchild3_->RemoveFromParent();
4188
4189 EXPECT_FALSE(root_->needs_push_properties());
4190 EXPECT_TRUE(root_->descendant_needs_push_properties());
4191 EXPECT_TRUE(child_->needs_push_properties());
4192 EXPECT_FALSE(child_->descendant_needs_push_properties());
4193
4194 EndTest();
4195 break;
4196 }
4197 }
4198 };
4199
4200 MULTI_THREAD_TEST_F(
4201 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4202
4203 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4204 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4205 protected:
4206 void DidCommitAndDrawFrame() override {
4207 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4208 switch (last_source_frame_number) {
4209 case 0:
4210 layer_tree_host()->SetRootLayer(root_);
4211 break;
4212 case 1:
4213 EXPECT_FALSE(root_->needs_push_properties());
4214 EXPECT_FALSE(root_->descendant_needs_push_properties());
4215 EXPECT_FALSE(child_->needs_push_properties());
4216 EXPECT_FALSE(child_->descendant_needs_push_properties());
4217 EXPECT_FALSE(grandchild1_->needs_push_properties());
4218 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4219 EXPECT_FALSE(grandchild2_->needs_push_properties());
4220 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4221 EXPECT_FALSE(grandchild3_->needs_push_properties());
4222 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4223
4224 child_->SetPosition(gfx::Point(1, 1));
4225 grandchild1_->SetPosition(gfx::Point(1, 1));
4226 grandchild2_->SetPosition(gfx::Point(1, 1));
4227
4228 EXPECT_FALSE(root_->needs_push_properties());
4229 EXPECT_TRUE(root_->descendant_needs_push_properties());
4230 EXPECT_TRUE(child_->needs_push_properties());
4231 EXPECT_TRUE(child_->descendant_needs_push_properties());
4232 EXPECT_TRUE(grandchild1_->needs_push_properties());
4233 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4234 EXPECT_TRUE(grandchild2_->needs_push_properties());
4235 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4236 EXPECT_FALSE(grandchild3_->needs_push_properties());
4237 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4238
4239 grandchild1_->RemoveFromParent();
4240
4241 EXPECT_FALSE(root_->needs_push_properties());
4242 EXPECT_TRUE(root_->descendant_needs_push_properties());
4243 EXPECT_TRUE(child_->needs_push_properties());
4244 EXPECT_TRUE(child_->descendant_needs_push_properties());
4245
4246 grandchild2_->RemoveFromParent();
4247
4248 EXPECT_FALSE(root_->needs_push_properties());
4249 EXPECT_TRUE(root_->descendant_needs_push_properties());
4250 EXPECT_TRUE(child_->needs_push_properties());
4251 EXPECT_FALSE(child_->descendant_needs_push_properties());
4252
4253 child_->RemoveFromParent();
4254
4255 EXPECT_FALSE(root_->needs_push_properties());
4256 EXPECT_FALSE(root_->descendant_needs_push_properties());
4257
4258 EndTest();
4259 break;
4260 }
4261 }
4262 };
4263
4264 MULTI_THREAD_TEST_F(
4265 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4266
4267 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4268 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4269 protected:
4270 void DidCommitAndDrawFrame() override {
4271 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4272 switch (last_source_frame_number) {
4273 case 0:
4274 layer_tree_host()->SetRootLayer(root_);
4275 break;
4276 case 1:
4277 EXPECT_FALSE(root_->needs_push_properties());
4278 EXPECT_FALSE(root_->descendant_needs_push_properties());
4279 EXPECT_FALSE(child_->needs_push_properties());
4280 EXPECT_FALSE(child_->descendant_needs_push_properties());
4281 EXPECT_FALSE(grandchild1_->needs_push_properties());
4282 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4283 EXPECT_FALSE(grandchild2_->needs_push_properties());
4284 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4285 EXPECT_FALSE(grandchild3_->needs_push_properties());
4286 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4287
4288 grandchild1_->SetPosition(gfx::Point(1, 1));
4289 grandchild2_->SetPosition(gfx::Point(1, 1));
4290 child_->SetPosition(gfx::Point(1, 1));
4291
4292 EXPECT_FALSE(root_->needs_push_properties());
4293 EXPECT_TRUE(root_->descendant_needs_push_properties());
4294 EXPECT_TRUE(child_->needs_push_properties());
4295 EXPECT_TRUE(child_->descendant_needs_push_properties());
4296 EXPECT_TRUE(grandchild1_->needs_push_properties());
4297 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4298 EXPECT_TRUE(grandchild2_->needs_push_properties());
4299 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4300 EXPECT_FALSE(grandchild3_->needs_push_properties());
4301 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4302
4303 grandchild1_->RemoveFromParent();
4304
4305 EXPECT_FALSE(root_->needs_push_properties());
4306 EXPECT_TRUE(root_->descendant_needs_push_properties());
4307 EXPECT_TRUE(child_->needs_push_properties());
4308 EXPECT_TRUE(child_->descendant_needs_push_properties());
4309
4310 grandchild2_->RemoveFromParent();
4311
4312 EXPECT_FALSE(root_->needs_push_properties());
4313 EXPECT_TRUE(root_->descendant_needs_push_properties());
4314 EXPECT_TRUE(child_->needs_push_properties());
4315 EXPECT_FALSE(child_->descendant_needs_push_properties());
4316
4317 child_->RemoveFromParent();
4318
4319 EXPECT_FALSE(root_->needs_push_properties());
4320 EXPECT_FALSE(root_->descendant_needs_push_properties());
4321
4322 EndTest();
4323 break;
4324 }
4325 }
4326 };
4327
4328 MULTI_THREAD_TEST_F(
4329 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4330
4331 // This test verifies that the tree activation callback is invoked correctly.
4332 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4333 public:
4334 LayerTreeHostTestTreeActivationCallback()
4335 : num_commits_(0), callback_count_(0) {}
4336
4337 void BeginTest() override {
4338 EXPECT_TRUE(HasImplThread());
4339 PostSetNeedsCommitToMainThread();
4340 }
4341
4342 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4343 LayerTreeHostImpl::FrameData* frame_data,
4344 DrawResult draw_result) override {
4345 ++num_commits_;
4346 switch (num_commits_) {
4347 case 1:
4348 EXPECT_EQ(0, callback_count_);
4349 callback_count_ = 0;
4350 SetCallback(true);
4351 PostSetNeedsCommitToMainThread();
4352 break;
4353 case 2:
4354 EXPECT_EQ(1, callback_count_);
4355 callback_count_ = 0;
4356 SetCallback(false);
4357 PostSetNeedsCommitToMainThread();
4358 break;
4359 case 3:
4360 EXPECT_EQ(0, callback_count_);
4361 callback_count_ = 0;
4362 EndTest();
4363 break;
4364 default:
4365 ADD_FAILURE() << num_commits_;
4366 EndTest();
4367 break;
4368 }
4369 return LayerTreeHostTest::PrepareToDrawOnThread(
4370 host_impl, frame_data, draw_result);
4371 }
4372
4373 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
4374
4375 void SetCallback(bool enable) {
4376 output_surface()->SetTreeActivationCallback(
4377 enable
4378 ? base::Bind(
4379 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4380 base::Unretained(this))
4381 : base::Closure());
4382 }
4383
4384 void ActivationCallback() { ++callback_count_; }
4385
4386 int num_commits_;
4387 int callback_count_;
4388 };
4389
4390 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4391 RunTest(true, false, true);
4392 }
4393
4394 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4395 RunTest(true, true, true);
4396 }
4397
4398 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4399 public:
4400 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4401
4402 void BeginTest() override {
4403 ASSERT_TRUE(!!invalidate_layer_.get())
4404 << "Derived tests must set this in SetupTree";
4405
4406 // One initial commit.
4407 PostSetNeedsCommitToMainThread();
4408 }
4409
4410 void DidCommitAndDrawFrame() override {
4411 // After commit, invalidate the layer. This should cause a commit.
4412 if (layer_tree_host()->source_frame_number() == 1)
4413 invalidate_layer_->SetNeedsDisplay();
4414 }
4415
4416 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4417 num_draws_++;
4418 if (impl->active_tree()->source_frame_number() == 1)
4419 EndTest();
4420 }
4421
4422 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4423 num_commits_++;
4424 }
4425
4426 void AfterTest() override {
4427 EXPECT_GE(2, num_commits_);
4428 EXPECT_GE(2, num_draws_);
4429 }
4430
4431 protected:
4432 scoped_refptr<Layer> invalidate_layer_;
4433
4434 private:
4435 int num_commits_;
4436 int num_draws_;
4437 };
4438
4439 // IOSurfaceLayer must support being invalidated and then passing that along
4440 // to the compositor thread, even though no resources are updated in
4441 // response to that invalidation.
4442 class LayerTreeHostTestIOSurfaceLayerInvalidate
4443 : public LayerInvalidateCausesDraw {
4444 public:
4445 void SetupTree() override {
4446 LayerTreeHostTest::SetupTree();
4447 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4448 layer->SetBounds(gfx::Size(10, 10));
4449 uint32_t fake_io_surface_id = 7;
4450 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4451 layer->SetIsDrawable(true);
4452 layer_tree_host()->root_layer()->AddChild(layer);
4453
4454 invalidate_layer_ = layer;
4455 }
4456 };
4457
4458 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4459 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4460 LayerTreeHostTestIOSurfaceLayerInvalidate);
4461
4462 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4463 protected:
4464 void SetupTree() override {
4465 root_layer_ = Layer::Create();
4466 root_layer_->CreateRenderSurface();
4467 root_layer_->SetPosition(gfx::Point());
4468 root_layer_->SetBounds(gfx::Size(10, 10));
4469
4470 parent_layer_ = SolidColorLayer::Create();
4471 parent_layer_->SetPosition(gfx::Point());
4472 parent_layer_->SetBounds(gfx::Size(10, 10));
4473 parent_layer_->SetIsDrawable(true);
4474 root_layer_->AddChild(parent_layer_);
4475
4476 child_layer_ = SolidColorLayer::Create();
4477 child_layer_->SetPosition(gfx::Point());
4478 child_layer_->SetBounds(gfx::Size(10, 10));
4479 child_layer_->SetIsDrawable(true);
4480 parent_layer_->AddChild(child_layer_);
4481
4482 layer_tree_host()->SetRootLayer(root_layer_);
4483 LayerTreeHostTest::SetupTree();
4484 }
4485
4486 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4487
4488 void DidCommitAndDrawFrame() override {
4489 switch (layer_tree_host()->source_frame_number()) {
4490 case 1:
4491 // The layer type used does not need to push properties every frame.
4492 EXPECT_FALSE(child_layer_->needs_push_properties());
4493
4494 // Change the bounds of the child layer, but make it skipped
4495 // by CalculateDrawProperties.
4496 parent_layer_->SetOpacity(0.f);
4497 child_layer_->SetBounds(gfx::Size(5, 5));
4498 break;
4499 case 2:
4500 // The bounds of the child layer were pushed to the impl side.
4501 EXPECT_FALSE(child_layer_->needs_push_properties());
4502
4503 EndTest();
4504 break;
4505 }
4506 }
4507
4508 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4509 LayerImpl* root = impl->active_tree()->root_layer();
4510 LayerImpl* parent = root->children()[0];
4511 LayerImpl* child = parent->children()[0];
4512
4513 switch (impl->active_tree()->source_frame_number()) {
4514 case 1:
4515 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4516 break;
4517 }
4518 }
4519
4520 void AfterTest() override {}
4521
4522 scoped_refptr<Layer> root_layer_;
4523 scoped_refptr<SolidColorLayer> parent_layer_;
4524 scoped_refptr<SolidColorLayer> child_layer_;
4525 };
4526
4527 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4528
4529 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4530 protected:
4531 void InitializeSettings(LayerTreeSettings* settings) override {
4532 settings->impl_side_painting = true;
4533 }
4534
4535 void SetupTree() override {
4536 root_layer_ = FakePictureLayer::Create(&client_);
4537 root_layer_->SetBounds(gfx::Size(10, 10));
4538
4539 layer_tree_host()->SetRootLayer(root_layer_);
4540 LayerTreeHostTest::SetupTree();
4541 }
4542
4543 void BeginTest() override {
4544 // The viewport is empty, but we still need to update layers on the main
4545 // thread.
4546 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4547 PostSetNeedsCommitToMainThread();
4548 }
4549
4550 void DidCommit() override {
4551 // The layer should be updated even though the viewport is empty, so we
4552 // are capable of drawing it on the impl tree.
4553 EXPECT_GT(root_layer_->update_count(), 0u);
4554 EndTest();
4555 }
4556
4557 void AfterTest() override {}
4558
4559 FakeContentLayerClient client_;
4560 scoped_refptr<FakePictureLayer> root_layer_;
4561 };
4562
4563 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4564
4565 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4566 public:
4567 LayerTreeHostTestAbortEvictedTextures()
4568 : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4569
4570 protected:
4571 void SetupTree() override {
4572 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4573 root_layer->SetBounds(gfx::Size(200, 200));
4574 root_layer->SetIsDrawable(true);
4575 root_layer->CreateRenderSurface();
4576
4577 layer_tree_host()->SetRootLayer(root_layer);
4578 LayerTreeHostTest::SetupTree();
4579 }
4580
4581 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4582
4583 void WillBeginMainFrame() override {
4584 num_will_begin_main_frames_++;
4585 switch (num_will_begin_main_frames_) {
4586 case 2:
4587 // Send a redraw to the compositor thread. This will (wrongly) be
4588 // ignored unless aborting resets the texture state.
4589 layer_tree_host()->SetNeedsRedraw();
4590 break;
4591 }
4592 }
4593
4594 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
4595 num_impl_commits_++;
4596 }
4597
4598 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
4599 switch (impl->SourceAnimationFrameNumber()) {
4600 case 1:
4601 // Prevent draws until commit.
4602 impl->active_tree()->SetContentsTexturesPurged();
4603 EXPECT_FALSE(impl->CanDraw());
4604 // Trigger an abortable commit.
4605 impl->SetNeedsCommit();
4606 break;
4607 case 2:
4608 EndTest();
4609 break;
4610 }
4611 }
4612
4613 void AfterTest() override {
4614 // Ensure that the commit was truly aborted.
4615 EXPECT_EQ(2, num_will_begin_main_frames_);
4616 EXPECT_EQ(1, num_impl_commits_);
4617 }
4618
4619 private:
4620 int num_will_begin_main_frames_;
4621 int num_impl_commits_;
4622 };
4623
4624 // Commits can only be aborted when using the thread proxy.
4625 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4626
4627 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4628 protected:
4629 void InitializeSettings(LayerTreeSettings* settings) override {
4630 settings->impl_side_painting = true;
4631 settings->use_zero_copy = false;
4632 settings->use_one_copy = false;
4633 }
4634
4635 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4636 scoped_refptr<TestContextProvider> context_provider =
4637 TestContextProvider::Create();
4638 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
4639 if (delegating_renderer())
4640 return FakeOutputSurface::CreateDelegating3d(context_provider);
4641 else
4642 return FakeOutputSurface::Create3d(context_provider);
4643 }
4644
4645 void SetupTree() override {
4646 client_.set_fill_with_nonsolid_color(true);
4647 scoped_refptr<FakePictureLayer> root_layer =
4648 FakePictureLayer::Create(&client_);
4649 root_layer->SetBounds(gfx::Size(1024, 1024));
4650 root_layer->SetIsDrawable(true);
4651
4652 layer_tree_host()->SetRootLayer(root_layer);
4653 LayerTreeHostTest::SetupTree();
4654 }
4655
4656 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4657
4658 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4659 TestWebGraphicsContext3D* context = TestContext();
4660
4661 // Expect that the transfer buffer memory used is equal to the
4662 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4663 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
4664 EndTest();
4665 }
4666
4667 void AfterTest() override {}
4668
4669 private:
4670 FakeContentLayerClient client_;
4671 };
4672
4673 // Impl-side painting is a multi-threaded compositor feature.
4674 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4675
4676 // Test ensuring that memory limits are sent to the prioritized resource
4677 // manager.
4678 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4679 public:
4680 LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4681
4682 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4683
4684 void WillCommit() override {
4685 // Some commits are aborted, so increment number of attempted commits here.
4686 num_commits_++;
4687 }
4688
4689 void DidCommit() override {
4690 switch (num_commits_) {
4691 case 1:
4692 // Verify default values.
4693 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4694 layer_tree_host()
4695 ->contents_texture_manager()
4696 ->MaxMemoryLimitBytes());
4697 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4698 layer_tree_host()
4699 ->contents_texture_manager()
4700 ->ExternalPriorityCutoff());
4701 PostSetNeedsCommitToMainThread();
4702 break;
4703 case 2:
4704 // The values should remain the same until the commit after the policy
4705 // is changed.
4706 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4707 layer_tree_host()
4708 ->contents_texture_manager()
4709 ->MaxMemoryLimitBytes());
4710 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
4711 layer_tree_host()
4712 ->contents_texture_manager()
4713 ->ExternalPriorityCutoff());
4714 break;
4715 case 3:
4716 // Verify values were correctly passed.
4717 EXPECT_EQ(16u * 1024u * 1024u,
4718 layer_tree_host()
4719 ->contents_texture_manager()
4720 ->MaxMemoryLimitBytes());
4721 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4722 layer_tree_host()
4723 ->contents_texture_manager()
4724 ->ExternalPriorityCutoff());
4725 EndTest();
4726 break;
4727 case 4:
4728 // Make sure no extra commits happen.
4729 NOTREACHED();
4730 break;
4731 }
4732 }
4733
4734 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
4735 switch (num_commits_) {
4736 case 1:
4737 break;
4738 case 2:
4739 // This will trigger a commit because the priority cutoff has changed.
4740 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4741 16u * 1024u * 1024u,
4742 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4743 1000));
4744 break;
4745 case 3:
4746 // This will not trigger a commit because the priority cutoff has not
4747 // changed, and there is already enough memory for all allocations.
4748 impl->SetMemoryPolicy(ManagedMemoryPolicy(
4749 32u * 1024u * 1024u,
4750 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4751 1000));
4752 break;
4753 case 4:
4754 NOTREACHED();
4755 break;
4756 }
4757 }
4758
4759 void AfterTest() override {}
4760
4761 private:
4762 int num_commits_;
4763 };
4764
4765 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
4766
4767 } // namespace
4768
4769 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
4770 : public LayerTreeHostTest {
4771 protected:
4772 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
4773 : first_output_surface_memory_limit_(4321234),
4774 second_output_surface_memory_limit_(1234321) {}
4775
4776 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
4777 if (!first_context_provider_.get()) {
4778 first_context_provider_ = TestContextProvider::Create();
4779 } else {
4780 EXPECT_FALSE(second_context_provider_.get());
4781 second_context_provider_ = TestContextProvider::Create();
4782 }
4783
4784 scoped_refptr<TestContextProvider> provider(second_context_provider_.get()
4785 ? second_context_provider_
4786 : first_context_provider_);
4787 scoped_ptr<FakeOutputSurface> output_surface;
4788 if (delegating_renderer())
4789 output_surface = FakeOutputSurface::CreateDelegating3d(provider);
4790 else
4791 output_surface = FakeOutputSurface::Create3d(provider);
4792 output_surface->SetMemoryPolicyToSetAtBind(
4793 make_scoped_ptr(new ManagedMemoryPolicy(
4794 second_context_provider_.get() ? second_output_surface_memory_limit_
4795 : first_output_surface_memory_limit_,
4796 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4797 ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
4798 return output_surface.Pass();
4799 }
4800
4801 void SetupTree() override {
4802 if (layer_tree_host()->settings().impl_side_painting)
4803 root_ = FakePictureLayer::Create(&client_);
4804 else
4805 root_ = FakeContentLayer::Create(&client_);
4806 root_->SetBounds(gfx::Size(20, 20));
4807 layer_tree_host()->SetRootLayer(root_);
4808 LayerTreeHostTest::SetupTree();
4809 }
4810
4811 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4812
4813 void DidCommitAndDrawFrame() override {
4814 // Lost context sometimes takes two frames to recreate. The third frame
4815 // is sometimes aborted, so wait until the fourth frame to verify that
4816 // the memory has been set, and the fifth frame to end the test.
4817 if (layer_tree_host()->source_frame_number() < 5) {
4818 layer_tree_host()->SetNeedsCommit();
4819 } else if (layer_tree_host()->source_frame_number() == 5) {
4820 EndTest();
4821 }
4822 }
4823
4824 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override {
4825 switch (impl->active_tree()->source_frame_number()) {
4826 case 1:
4827 EXPECT_EQ(first_output_surface_memory_limit_,
4828 impl->memory_allocation_limit_bytes());
4829 // Lose the output surface.
4830 first_context_provider_->TestContext3d()->loseContextCHROMIUM(
4831 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
4832 break;
4833 case 4:
4834 EXPECT_EQ(second_output_surface_memory_limit_,
4835 impl->memory_allocation_limit_bytes());
4836 break;
4837 }
4838 }
4839
4840 void AfterTest() override {}
4841
4842 scoped_refptr<TestContextProvider> first_context_provider_;
4843 scoped_refptr<TestContextProvider> second_context_provider_;
4844 size_t first_output_surface_memory_limit_;
4845 size_t second_output_surface_memory_limit_;
4846 FakeContentLayerClient client_;
4847 scoped_refptr<Layer> root_;
4848 };
4849
4850 SINGLE_AND_MULTI_THREAD_TEST_F(
4851 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
4852
4853 struct TestSwapPromiseResult {
4854 TestSwapPromiseResult()
4855 : did_swap_called(false),
4856 did_not_swap_called(false),
4857 dtor_called(false),
4858 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
4859
4860 bool did_swap_called;
4861 bool did_not_swap_called;
4862 bool dtor_called;
4863 SwapPromise::DidNotSwapReason reason;
4864 base::Lock lock;
4865 };
4866
4867 class TestSwapPromise : public SwapPromise {
4868 public:
4869 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
4870
4871 ~TestSwapPromise() override {
4872 base::AutoLock lock(result_->lock);
4873 result_->dtor_called = true;
4874 }
4875
4876 void DidSwap(CompositorFrameMetadata* metadata) override {
4877 base::AutoLock lock(result_->lock);
4878 EXPECT_FALSE(result_->did_swap_called);
4879 EXPECT_FALSE(result_->did_not_swap_called);
4880 result_->did_swap_called = true;
4881 }
4882
4883 void DidNotSwap(DidNotSwapReason reason) override {
4884 base::AutoLock lock(result_->lock);
4885 EXPECT_FALSE(result_->did_swap_called);
4886 EXPECT_FALSE(result_->did_not_swap_called);
4887 result_->did_not_swap_called = true;
4888 result_->reason = reason;
4889 }
4890
4891 int64 TraceId() const override { return 0; }
4892
4893 private:
4894 // Not owned.
4895 TestSwapPromiseResult* result_;
4896 };
4897
4898 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
4899 protected:
4900 LayerTreeHostTestBreakSwapPromise()
4901 : commit_count_(0), commit_complete_count_(0) {}
4902
4903 void WillBeginMainFrame() override {
4904 ASSERT_LE(commit_count_, 2);
4905 scoped_ptr<SwapPromise> swap_promise(
4906 new TestSwapPromise(&swap_promise_result_[commit_count_]));
4907 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
4908 }
4909
4910 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4911
4912 void DidCommit() override {
4913 commit_count_++;
4914 if (commit_count_ == 2) {
4915 // This commit will finish.
4916 layer_tree_host()->SetNeedsCommit();
4917 }
4918 }
4919
4920 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4921 commit_complete_count_++;
4922 if (commit_complete_count_ == 1) {
4923 // This commit will be aborted because no actual update.
4924 PostSetNeedsUpdateLayersToMainThread();
4925 } else {
4926 EndTest();
4927 }
4928 }
4929
4930 void AfterTest() override {
4931 // 3 commits are scheduled. 2 completes. 1 is aborted.
4932 EXPECT_EQ(commit_count_, 3);
4933 EXPECT_EQ(commit_complete_count_, 2);
4934
4935 {
4936 // The first commit completes and causes swap buffer which finishes
4937 // the promise.
4938 base::AutoLock lock(swap_promise_result_[0].lock);
4939 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
4940 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
4941 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
4942 }
4943
4944 {
4945 // The second commit is aborted since it contains no updates.
4946 base::AutoLock lock(swap_promise_result_[1].lock);
4947 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
4948 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
4949 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
4950 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
4951 }
4952
4953 {
4954 // The last commit completes but it does not cause swap buffer because
4955 // there is no damage in the frame data.
4956 base::AutoLock lock(swap_promise_result_[2].lock);
4957 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
4958 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
4959 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
4960 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
4961 }
4962 }
4963
4964 int commit_count_;
4965 int commit_complete_count_;
4966 TestSwapPromiseResult swap_promise_result_[3];
4967 };
4968
4969 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
4970
4971 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
4972 public:
4973 LayerTreeHostTestKeepSwapPromise() {}
4974
4975 void BeginTest() override {
4976 layer_ = SolidColorLayer::Create();
4977 layer_->SetIsDrawable(true);
4978 layer_->SetBounds(gfx::Size(10, 10));
4979 layer_tree_host()->SetRootLayer(layer_);
4980 gfx::Size bounds(100, 100);
4981 layer_tree_host()->SetViewportSize(bounds);
4982 PostSetNeedsCommitToMainThread();
4983 }
4984
4985 void DidCommit() override {
4986 MainThreadTaskRunner()->PostTask(
4987 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
4988 base::Unretained(this)));
4989 }
4990
4991 void ChangeFrame() {
4992 switch (layer_tree_host()->source_frame_number()) {
4993 case 1:
4994 layer_->SetBounds(gfx::Size(10, 11));
4995 layer_tree_host()->QueueSwapPromise(
4996 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_)));
4997 break;
4998 case 2:
4999 break;
5000 default:
5001 NOTREACHED();
5002 break;
5003 }
5004 }
5005
5006 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
5007 EXPECT_TRUE(result);
5008 if (host_impl->active_tree()->source_frame_number() >= 1) {
5009 // The commit changes layers so it should cause a swap.
5010 base::AutoLock lock(swap_promise_result_.lock);
5011 EXPECT_TRUE(swap_promise_result_.did_swap_called);
5012 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5013 EXPECT_TRUE(swap_promise_result_.dtor_called);
5014 EndTest();
5015 }
5016 }
5017
5018 void AfterTest() override {}
5019
5020 private:
5021 scoped_refptr<Layer> layer_;
5022 TestSwapPromiseResult swap_promise_result_;
5023 };
5024
5025 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
5026
5027 class LayerTreeHostTestBreakSwapPromiseForVisibility
5028 : public LayerTreeHostTest {
5029 protected:
5030 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5031
5032 void SetVisibleFalseAndQueueSwapPromise() {
5033 layer_tree_host()->SetVisible(false);
5034 scoped_ptr<SwapPromise> swap_promise(
5035 new TestSwapPromise(&swap_promise_result_));
5036 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5037 }
5038
5039 void ScheduledActionWillSendBeginMainFrame() override {
5040 MainThreadTaskRunner()->PostTask(
5041 FROM_HERE,
5042 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility
5043 ::SetVisibleFalseAndQueueSwapPromise,
5044 base::Unretained(this)));
5045 }
5046
5047 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5048 CommitEarlyOutReason reason) override {
5049 EndTest();
5050 }
5051
5052 void AfterTest() override {
5053 {
5054 base::AutoLock lock(swap_promise_result_.lock);
5055 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5056 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5057 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5058 EXPECT_TRUE(swap_promise_result_.dtor_called);
5059 }
5060 }
5061
5062 TestSwapPromiseResult swap_promise_result_;
5063 };
5064
5065 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
5066
5067 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest {
5068 protected:
5069 LayerTreeHostTestBreakSwapPromiseForContext()
5070 : output_surface_lost_triggered_(false) {
5071 }
5072
5073 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5074
5075 void LoseOutputSurfaceAndQueueSwapPromise() {
5076 layer_tree_host()->DidLoseOutputSurface();
5077 scoped_ptr<SwapPromise> swap_promise(
5078 new TestSwapPromise(&swap_promise_result_));
5079 layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
5080 }
5081
5082 void ScheduledActionWillSendBeginMainFrame() override {
5083 if (output_surface_lost_triggered_)
5084 return;
5085 output_surface_lost_triggered_ = true;
5086
5087 MainThreadTaskRunner()->PostTask(
5088 FROM_HERE,
5089 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext
5090 ::LoseOutputSurfaceAndQueueSwapPromise,
5091 base::Unretained(this)));
5092 }
5093
5094 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5095 CommitEarlyOutReason reason) override {
5096 // This is needed so that the impl-thread state matches main-thread state.
5097 host_impl->DidLoseOutputSurface();
5098 EndTest();
5099 }
5100
5101 void AfterTest() override {
5102 {
5103 base::AutoLock lock(swap_promise_result_.lock);
5104 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5105 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
5106 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
5107 EXPECT_TRUE(swap_promise_result_.dtor_called);
5108 }
5109 }
5110
5111 bool output_surface_lost_triggered_;
5112 TestSwapPromiseResult swap_promise_result_;
5113 };
5114
5115 SINGLE_AND_MULTI_THREAD_TEST_F(
5116 LayerTreeHostTestBreakSwapPromiseForContext);
5117
5118 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
5119 public:
5120 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
5121 LayerTreeHostImpl* layer_tree_host_impl,
5122 int* set_needs_commit_count,
5123 int* set_needs_redraw_count)
5124 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
5125 set_needs_commit_count_(set_needs_commit_count) {}
5126
5127 ~SimpleSwapPromiseMonitor() override {}
5128
5129 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
5130
5131 void OnSetNeedsRedrawOnImpl() override {
5132 ADD_FAILURE() << "Should not get called on main thread.";
5133 }
5134
5135 void OnForwardScrollUpdateToMainThreadOnImpl() override {
5136 ADD_FAILURE() << "Should not get called on main thread.";
5137 }
5138
5139 private:
5140 int* set_needs_commit_count_;
5141 };
5142
5143 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
5144 public:
5145 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5146
5147 void WillBeginMainFrame() override {
5148 if (TestEnded())
5149 return;
5150
5151 int set_needs_commit_count = 0;
5152 int set_needs_redraw_count = 0;
5153
5154 {
5155 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5156 new SimpleSwapPromiseMonitor(layer_tree_host(),
5157 NULL,
5158 &set_needs_commit_count,
5159 &set_needs_redraw_count));
5160 layer_tree_host()->SetNeedsCommit();
5161 EXPECT_EQ(1, set_needs_commit_count);
5162 EXPECT_EQ(0, set_needs_redraw_count);
5163 }
5164
5165 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
5166 // monitored.
5167 layer_tree_host()->SetNeedsCommit();
5168 EXPECT_EQ(1, set_needs_commit_count);
5169 EXPECT_EQ(0, set_needs_redraw_count);
5170
5171 {
5172 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5173 new SimpleSwapPromiseMonitor(layer_tree_host(),
5174 NULL,
5175 &set_needs_commit_count,
5176 &set_needs_redraw_count));
5177 layer_tree_host()->SetNeedsUpdateLayers();
5178 EXPECT_EQ(2, set_needs_commit_count);
5179 EXPECT_EQ(0, set_needs_redraw_count);
5180 }
5181
5182 {
5183 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
5184 new SimpleSwapPromiseMonitor(layer_tree_host(),
5185 NULL,
5186 &set_needs_commit_count,
5187 &set_needs_redraw_count));
5188 layer_tree_host()->SetNeedsAnimate();
5189 EXPECT_EQ(3, set_needs_commit_count);
5190 EXPECT_EQ(0, set_needs_redraw_count);
5191 }
5192
5193 EndTest();
5194 }
5195
5196 void AfterTest() override {}
5197 };
5198
5199 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
5200
5201 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
5202 : public LayerTreeHostTest {
5203 protected:
5204 void InitializeSettings(LayerTreeSettings* settings) override {
5205 settings->impl_side_painting = true;
5206 }
5207
5208 void SetupTree() override {
5209 LayerTreeHostTest::SetupTree();
5210 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
5211 }
5212
5213 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5214
5215 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5216 host_impl->EvictAllUIResources();
5217 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
5218 // mode. Active tree should require high-res to draw after entering this
5219 // mode to ensure that high-res tiles are also required for a pending tree
5220 // to be activated.
5221 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5222 }
5223
5224 void DidCommit() override {
5225 int frame = layer_tree_host()->source_frame_number();
5226 switch (frame) {
5227 case 1:
5228 PostSetNeedsCommitToMainThread();
5229 break;
5230 case 2:
5231 ui_resource_ = nullptr;
5232 EndTest();
5233 break;
5234 }
5235 }
5236
5237 void AfterTest() override {}
5238
5239 FakeContentLayerClient client_;
5240 scoped_ptr<FakeScopedUIResource> ui_resource_;
5241 };
5242
5243 // This test is flaky, see http://crbug.com/386199
5244 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
5245
5246 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
5247 protected:
5248 void InitializeSettings(LayerTreeSettings* settings) override {
5249 settings->impl_side_painting = true;
5250
5251 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5252 EXPECT_FALSE(settings->gpu_rasterization_forced);
5253 }
5254
5255 void SetupTree() override {
5256 LayerTreeHostTest::SetupTree();
5257
5258 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5259 layer->SetBounds(gfx::Size(10, 10));
5260 layer->SetIsDrawable(true);
5261 layer_tree_host()->root_layer()->AddChild(layer);
5262 }
5263
5264 void BeginTest() override {
5265 Layer* root = layer_tree_host()->root_layer();
5266 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5267 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5268
5269 // Verify default values.
5270 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5271 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5272 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5273 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5274 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5275
5276 // Setting gpu rasterization trigger does not enable gpu rasterization.
5277 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5278 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5279 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5280
5281 PostSetNeedsCommitToMainThread();
5282 }
5283
5284 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5285 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5286 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5287 }
5288
5289 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5290 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5291 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5292 EndTest();
5293 }
5294
5295 void AfterTest() override {}
5296
5297 FakeContentLayerClient layer_client_;
5298 };
5299
5300 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
5301
5302 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
5303 protected:
5304 void InitializeSettings(LayerTreeSettings* settings) override {
5305 settings->impl_side_painting = true;
5306
5307 EXPECT_FALSE(settings->gpu_rasterization_enabled);
5308 settings->gpu_rasterization_enabled = true;
5309 }
5310
5311 void SetupTree() override {
5312 LayerTreeHostTest::SetupTree();
5313
5314 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
5315 layer->SetBounds(gfx::Size(10, 10));
5316 layer->SetIsDrawable(true);
5317 layer_tree_host()->root_layer()->AddChild(layer);
5318 }
5319
5320 void BeginTest() override {
5321 Layer* root = layer_tree_host()->root_layer();
5322 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5323 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5324
5325 // Verify default values.
5326 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5327 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5328 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5329 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5330 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
5331
5332 // Gpu rasterization trigger is relevant.
5333 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5334 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5335 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5336
5337 // Content-based veto is relevant as well.
5338 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5339 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5340 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5341 // Veto will take effect when layers are updated.
5342 // The results will be verified after commit is completed below.
5343 // Since we are manually marking picture pile as unsuitable,
5344 // make sure that the layer gets a chance to update.
5345 layer->SetNeedsDisplay();
5346 PostSetNeedsCommitToMainThread();
5347 }
5348
5349 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5350 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
5351 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5352 }
5353
5354 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5355 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
5356 EXPECT_FALSE(host_impl->use_gpu_rasterization());
5357 EndTest();
5358 }
5359
5360 void AfterTest() override {}
5361
5362 FakeContentLayerClient layer_client_;
5363 };
5364
5365 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
5366
5367 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
5368 protected:
5369 void InitializeSettings(LayerTreeSettings* settings) override {
5370 ASSERT_TRUE(settings->impl_side_painting);
5371
5372 EXPECT_FALSE(settings->gpu_rasterization_forced);
5373 settings->gpu_rasterization_forced = true;
5374 }
5375
5376 void SetupTree() override {
5377 LayerTreeHostTest::SetupTree();
5378
5379 scoped_refptr<FakePictureLayer> layer =
5380 FakePictureLayer::Create(&layer_client_);
5381 layer->SetBounds(gfx::Size(10, 10));
5382 layer->SetIsDrawable(true);
5383 layer_tree_host()->root_layer()->AddChild(layer);
5384 }
5385
5386 void BeginTest() override {
5387 Layer* root = layer_tree_host()->root_layer();
5388 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
5389 RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
5390
5391 // Verify default values.
5392 EXPECT_TRUE(root->IsSuitableForGpuRasterization());
5393 EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
5394 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization());
5395 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
5396
5397 // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
5398 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5399 layer_tree_host()->SetHasGpuRasterizationTrigger(true);
5400 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
5401 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
5402
5403 // Content-based veto is irrelevant as well.
5404 recording_source->SetUnsuitableForGpuRasterizationForTesting();
5405 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization());
5406 EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
5407 // Veto will take effect when layers are updated.
5408 // The results will be verified after commit is completed below.
5409 // Since we are manually marking picture pile as unsuitable,
5410 // make sure that the layer gets a chance to update.
5411 layer->SetNeedsDisplay();
5412 PostSetNeedsCommitToMainThread();
5413 }
5414
5415 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5416 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
5417 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5418 }
5419
5420 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5421 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
5422 EXPECT_TRUE(host_impl->use_gpu_rasterization());
5423 EndTest();
5424 }
5425
5426 void AfterTest() override {}
5427
5428 FakeContentLayerClient layer_client_;
5429 };
5430
5431 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
5432
5433 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
5434 public:
5435 LayerTreeHostTestContinuousPainting()
5436 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
5437
5438 protected:
5439 enum { kExpectedNumCommits = 10 };
5440
5441 void SetupTree() override {
5442 scoped_refptr<Layer> root_layer = Layer::Create();
5443 root_layer->SetBounds(bounds_);
5444 root_layer->CreateRenderSurface();
5445
5446 if (layer_tree_host()->settings().impl_side_painting) {
5447 picture_layer_ = FakePictureLayer::Create(&client_);
5448 child_layer_ = picture_layer_.get();
5449 } else {
5450 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
5451 child_layer_ = content_layer_.get();
5452 }
5453 child_layer_->SetBounds(bounds_);
5454 child_layer_->SetIsDrawable(true);
5455 root_layer->AddChild(child_layer_);
5456
5457 layer_tree_host()->SetRootLayer(root_layer);
5458 layer_tree_host()->SetViewportSize(bounds_);
5459 LayerTreeHostTest::SetupTree();
5460 }
5461
5462 void BeginTest() override {
5463 MainThreadTaskRunner()->PostTask(
5464 FROM_HERE,
5465 base::Bind(
5466 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
5467 base::Unretained(this)));
5468 // Wait 50x longer than expected.
5469 double milliseconds_per_frame =
5470 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate;
5471 MainThreadTaskRunner()->PostDelayedTask(
5472 FROM_HERE,
5473 base::Bind(
5474 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting,
5475 base::Unretained(this)),
5476 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits *
5477 milliseconds_per_frame));
5478 }
5479
5480 void BeginMainFrame(const BeginFrameArgs& args) override {
5481 child_layer_->SetNeedsDisplay();
5482 }
5483
5484 void AfterTest() override {
5485 EXPECT_LE(kExpectedNumCommits, num_commits_);
5486 EXPECT_LE(kExpectedNumCommits, num_draws_);
5487 int update_count = content_layer_.get()
5488 ? content_layer_->PaintContentsCount()
5489 : picture_layer_->update_count();
5490 EXPECT_LE(kExpectedNumCommits, update_count);
5491 }
5492
5493 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5494 if (++num_draws_ == kExpectedNumCommits)
5495 EndTest();
5496 }
5497
5498 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5499 ++num_commits_;
5500 }
5501
5502 private:
5503 void EnableContinuousPainting() {
5504 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5505 debug_state.continuous_painting = true;
5506 layer_tree_host()->SetDebugState(debug_state);
5507 }
5508
5509 void DisableContinuousPainting() {
5510 LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
5511 debug_state.continuous_painting = false;
5512 layer_tree_host()->SetDebugState(debug_state);
5513 EndTest();
5514 }
5515
5516 int num_commits_;
5517 int num_draws_;
5518 const gfx::Size bounds_;
5519 FakeContentLayerClient client_;
5520 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
5521 scoped_refptr<FakePictureLayer> picture_layer_;
5522 Layer* child_layer_;
5523 };
5524
5525 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
5526
5527 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest {
5528 public:
5529 LayerTreeHostTestSendBeginFramesToChildren()
5530 : begin_frame_sent_to_children_(false) {
5531 }
5532
5533 void BeginTest() override {
5534 // Kick off the test with a commit.
5535 PostSetNeedsCommitToMainThread();
5536 }
5537
5538 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5539 begin_frame_sent_to_children_ = true;
5540 EndTest();
5541 }
5542
5543 void DidBeginMainFrame() override {
5544 // Children requested BeginFrames.
5545 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5546 }
5547
5548 void AfterTest() override {
5549 // Ensure that BeginFrame message is sent to children during parent
5550 // scheduler handles its BeginFrame.
5551 EXPECT_TRUE(begin_frame_sent_to_children_);
5552 }
5553
5554 private:
5555 bool begin_frame_sent_to_children_;
5556 };
5557
5558 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren);
5559
5560 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS
5561 : public LayerTreeHostTest {
5562 public:
5563 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS()
5564 : begin_frame_sent_to_children_(false) {
5565 }
5566
5567 void InitializeSettings(LayerTreeSettings* settings) override {
5568 settings->use_external_begin_frame_source = true;
5569 }
5570
5571 void BeginTest() override {
5572 // Kick off the test with a commit.
5573 PostSetNeedsCommitToMainThread();
5574 }
5575
5576 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
5577 begin_frame_sent_to_children_ = true;
5578 EndTest();
5579 }
5580
5581 void DidBeginMainFrame() override {
5582 // Children requested BeginFrames.
5583 layer_tree_host()->SetChildrenNeedBeginFrames(true);
5584 }
5585
5586 void AfterTest() override {
5587 // Ensure that BeginFrame message is sent to children during parent
5588 // scheduler handles its BeginFrame.
5589 EXPECT_TRUE(begin_frame_sent_to_children_);
5590 }
5591
5592 private:
5593 bool begin_frame_sent_to_children_;
5594 };
5595
5596 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS);
5597
5598 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
5599 public:
5600 LayerTreeHostTestActivateOnInvisible()
5601 : activation_count_(0), visible_(true) {}
5602
5603 void InitializeSettings(LayerTreeSettings* settings) override {
5604 settings->impl_side_painting = true;
5605 }
5606
5607 void BeginTest() override {
5608 // Kick off the test with a commit.
5609 PostSetNeedsCommitToMainThread();
5610 }
5611
5612 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5613 // Make sure we don't activate using the notify signal from tile manager.
5614 host_impl->BlockNotifyReadyToActivateForTesting(true);
5615 }
5616
5617 void DidCommit() override { layer_tree_host()->SetVisible(false); }
5618
5619 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
5620 bool visible) override {
5621 visible_ = visible;
5622
5623 // Once invisible, we can go visible again.
5624 if (!visible) {
5625 PostSetVisibleToMainThread(true);
5626 } else {
5627 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
5628 EndTest();
5629 }
5630 }
5631
5632 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5633 ++activation_count_;
5634 EXPECT_FALSE(visible_);
5635 }
5636
5637 void AfterTest() override {
5638 // Ensure we activated even though the signal was blocked.
5639 EXPECT_EQ(1, activation_count_);
5640 EXPECT_TRUE(visible_);
5641 }
5642
5643 private:
5644 int activation_count_;
5645 bool visible_;
5646
5647 FakeContentLayerClient client_;
5648 scoped_refptr<FakePictureLayer> picture_layer_;
5649 };
5650
5651 // TODO(vmpstr): Enable with single thread impl-side painting.
5652 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
5653
5654 // Do a synchronous composite and assert that the swap promise succeeds.
5655 class LayerTreeHostTestSynchronousCompositeSwapPromise
5656 : public LayerTreeHostTest {
5657 public:
5658 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {}
5659
5660 void InitializeSettings(LayerTreeSettings* settings) override {
5661 settings->single_thread_proxy_scheduler = false;
5662 }
5663
5664 void BeginTest() override {
5665 // Successful composite.
5666 scoped_ptr<SwapPromise> swap_promise0(
5667 new TestSwapPromise(&swap_promise_result_[0]));
5668 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
5669 layer_tree_host()->Composite(gfx::FrameTime::Now());
5670
5671 // Fail to swap (no damage).
5672 scoped_ptr<SwapPromise> swap_promise1(
5673 new TestSwapPromise(&swap_promise_result_[1]));
5674 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
5675 layer_tree_host()->SetNeedsCommit();
5676 layer_tree_host()->Composite(gfx::FrameTime::Now());
5677
5678 // Fail to draw (not visible).
5679 scoped_ptr<SwapPromise> swap_promise2(
5680 new TestSwapPromise(&swap_promise_result_[2]));
5681 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
5682 layer_tree_host()->SetNeedsDisplayOnAllLayers();
5683 layer_tree_host()->SetVisible(false);
5684 layer_tree_host()->Composite(gfx::FrameTime::Now());
5685
5686 EndTest();
5687 }
5688
5689 void DidCommit() override {
5690 commit_count_++;
5691 ASSERT_LE(commit_count_, 3);
5692 }
5693
5694 void AfterTest() override {
5695 EXPECT_EQ(3, commit_count_);
5696
5697 // Initial swap promise should have succeded.
5698 {
5699 base::AutoLock lock(swap_promise_result_[0].lock);
5700 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5701 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5702 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5703 }
5704
5705 // Second swap promise fails to swap.
5706 {
5707 base::AutoLock lock(swap_promise_result_[1].lock);
5708 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5709 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5710 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
5711 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5712 }
5713
5714 // Third swap promises also fails to swap (and draw).
5715 {
5716 base::AutoLock lock(swap_promise_result_[2].lock);
5717 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5718 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5719 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5720 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5721 }
5722 }
5723
5724 int commit_count_;
5725 TestSwapPromiseResult swap_promise_result_[3];
5726 };
5727
5728 // Impl-side painting is not supported for synchronous compositing.
5729 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
5730
5731 // Make sure page scale and top control deltas are applied to the client even
5732 // when the LayerTreeHost doesn't have a root layer.
5733 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
5734 : public LayerTreeHostTest {
5735 public:
5736 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
5737 : deltas_sent_to_client_(false) {}
5738
5739 void BeginTest() override {
5740 layer_tree_host()->SetRootLayer(nullptr);
5741 info_.page_scale_delta = 3.14f;
5742 info_.top_controls_delta = 2.73f;
5743
5744 PostSetNeedsCommitToMainThread();
5745 }
5746
5747 void BeginMainFrame(const BeginFrameArgs& args) override {
5748 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
5749
5750 layer_tree_host()->ApplyScrollAndScale(&info_);
5751 EndTest();
5752 }
5753
5754 void ApplyViewportDeltas(const gfx::Vector2dF& inner,
5755 const gfx::Vector2dF& outer,
5756 const gfx::Vector2dF& elastic_overscroll_delta,
5757 float scale_delta,
5758 float top_controls_delta) override {
5759 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5760 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5761 deltas_sent_to_client_ = true;
5762 }
5763
5764 void ApplyViewportDeltas(
5765 const gfx::Vector2d& scroll,
5766 float scale_delta,
5767 float top_controls_delta) override {
5768 EXPECT_EQ(info_.page_scale_delta, scale_delta);
5769 EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
5770 deltas_sent_to_client_ = true;
5771 }
5772
5773 void AfterTest() override {
5774 EXPECT_TRUE(deltas_sent_to_client_);
5775 }
5776
5777 ScrollAndScaleSet info_;
5778 bool deltas_sent_to_client_;
5779 };
5780
5781 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5782
5783 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
5784 protected:
5785 LayerTreeHostTestCrispUpAfterPinchEnds()
5786 : playback_allowed_event_(true, true) {}
5787
5788 void SetupTree() override {
5789 frame_ = 1;
5790 posted_ = false;
5791 client_.set_fill_with_nonsolid_color(true);
5792
5793 scoped_refptr<Layer> root = Layer::Create();
5794 root->SetBounds(gfx::Size(500, 500));
5795
5796 scoped_refptr<Layer> pinch = Layer::Create();
5797 pinch->SetBounds(gfx::Size(500, 500));
5798 pinch->SetScrollClipLayerId(root->id());
5799 pinch->SetIsContainerForFixedPositionLayers(true);
5800 root->AddChild(pinch);
5801
5802 scoped_ptr<FakePicturePile> pile(
5803 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
5804 ImplSidePaintingSettings().default_tile_grid_size));
5805 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
5806 scoped_refptr<FakePictureLayer> layer =
5807 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
5808 layer->SetBounds(gfx::Size(500, 500));
5809 layer->SetContentsOpaque(true);
5810 // Avoid LCD text on the layer so we don't cause extra commits when we
5811 // pinch.
5812 layer->disable_lcd_text();
5813 pinch->AddChild(layer);
5814
5815 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
5816 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5817 layer_tree_host()->SetRootLayer(root);
5818 LayerTreeHostTest::SetupTree();
5819 }
5820
5821 // Returns the delta scale of all quads in the frame's root pass from their
5822 // ideal, or 0 if they are not all the same.
5823 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5824 if (frame_data->has_no_damage)
5825 return 0.f;
5826 float frame_scale = 0.f;
5827 RenderPass* root_pass = frame_data->render_passes.back();
5828 for (const auto& draw_quad : root_pass->quad_list) {
5829 // Checkerboards mean an incomplete frame.
5830 if (draw_quad->material != DrawQuad::TILED_CONTENT)
5831 return 0.f;
5832 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
5833 float quad_scale =
5834 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5835 float transform_scale =
5836 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5837 float scale = quad_scale / transform_scale;
5838 if (frame_scale != 0.f && frame_scale != scale)
5839 return 0.f;
5840 frame_scale = scale;
5841 }
5842 return frame_scale;
5843 }
5844
5845 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5846
5847 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5848 LayerTreeHostImpl::FrameData* frame_data,
5849 DrawResult draw_result) override {
5850 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5851 switch (frame_) {
5852 case 1:
5853 // Drew at page scale 1 before any pinching.
5854 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5855 EXPECT_EQ(1.f, quad_scale_delta);
5856 PostNextAfterDraw(host_impl);
5857 break;
5858 case 2:
5859 if (quad_scale_delta != 1.f)
5860 break;
5861 // Drew at page scale 1.5 after pinching in.
5862 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
5863 EXPECT_EQ(1.f, quad_scale_delta);
5864 PostNextAfterDraw(host_impl);
5865 break;
5866 case 3:
5867 // By pinching out, we will create a new tiling and raster it. This may
5868 // cause some additional draws, though we should still be drawing with
5869 // the old 1.5 tiling.
5870 if (frame_data->has_no_damage)
5871 break;
5872 // Drew at page scale 1 with the 1.5 tiling while pinching out.
5873 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5874 EXPECT_EQ(1.5f, quad_scale_delta);
5875 // We don't PostNextAfterDraw here, instead we wait for the new tiling
5876 // to finish rastering so we don't get any noise in further steps.
5877 break;
5878 case 4:
5879 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
5880 // while waiting for texture uploads to complete.
5881 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5882 // This frame will not have any damage, since it's actually the same as
5883 // the last frame, and should contain no incomplete tiles. We just want
5884 // to make sure we drew here at least once after the pinch ended to be
5885 // sure that drawing after pinch doesn't leave us at the wrong scale
5886 EXPECT_TRUE(frame_data->has_no_damage);
5887 PostNextAfterDraw(host_impl);
5888 break;
5889 case 5:
5890 if (quad_scale_delta != 1.f)
5891 break;
5892 // Drew at scale 1 after texture uploads are done.
5893 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
5894 EXPECT_EQ(1.f, quad_scale_delta);
5895 EndTest();
5896 break;
5897 }
5898 return draw_result;
5899 }
5900
5901 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
5902 if (posted_)
5903 return;
5904 posted_ = true;
5905 ImplThreadTaskRunner()->PostDelayedTask(
5906 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
5907 base::Unretained(this), host_impl),
5908 // Use a delay to allow raster/upload to happen in between frames. This
5909 // should cause flakiness if we fail to block raster/upload when
5910 // desired.
5911 base::TimeDelta::FromMilliseconds(16 * 4));
5912 }
5913
5914 void Next(LayerTreeHostImpl* host_impl) {
5915 ++frame_;
5916 posted_ = false;
5917 switch (frame_) {
5918 case 2:
5919 // Pinch zoom in.
5920 host_impl->PinchGestureBegin();
5921 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
5922 host_impl->PinchGestureEnd();
5923 break;
5924 case 3:
5925 // Pinch zoom back to 1.f but don't end it.
5926 host_impl->PinchGestureBegin();
5927 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100));
5928 break;
5929 case 4:
5930 // End the pinch, but delay tile production.
5931 playback_allowed_event_.Reset();
5932 host_impl->PinchGestureEnd();
5933 break;
5934 case 5:
5935 // Let tiles complete.
5936 playback_allowed_event_.Signal();
5937 break;
5938 }
5939 }
5940
5941 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5942 const Tile* tile) override {
5943 if (frame_ == 3) {
5944 // On frame 3, we will have a lower res tile complete for the pinch-out
5945 // gesture even though it's not displayed. We wait for it here to prevent
5946 // flakiness.
5947 EXPECT_EQ(0.75f, tile->contents_scale());
5948 PostNextAfterDraw(host_impl);
5949 }
5950 // On frame_ == 4, we are preventing texture uploads from completing,
5951 // so this verifies they are not completing before frame_ == 5.
5952 // Flaky failures here indicate we're failing to prevent uploads from
5953 // completing.
5954 EXPECT_NE(4, frame_) << tile->contents_scale();
5955 }
5956
5957 void AfterTest() override {}
5958
5959 FakeContentLayerClient client_;
5960 int frame_;
5961 bool posted_;
5962 base::WaitableEvent playback_allowed_event_;
5963 };
5964
5965 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
5966
5967 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
5968 : public LayerTreeHostTestCrispUpAfterPinchEnds {
5969 protected:
5970 void InitializeSettings(LayerTreeSettings* settings) override {
5971 settings->use_one_copy = true;
5972 }
5973
5974 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
5975 scoped_ptr<TestWebGraphicsContext3D> context3d =
5976 TestWebGraphicsContext3D::Create();
5977 context3d->set_support_image(true);
5978 context3d->set_support_sync_query(true);
5979 #if defined(OS_MACOSX)
5980 context3d->set_support_texture_rectangle(true);
5981 #endif
5982
5983 if (delegating_renderer())
5984 return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
5985 else
5986 return FakeOutputSurface::Create3d(context3d.Pass());
5987 }
5988 };
5989
5990 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
5991
5992 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
5993 protected:
5994 RasterizeWithGpuRasterizationCreatesResources() {}
5995
5996 void InitializeSettings(LayerTreeSettings* settings) override {
5997 settings->impl_side_painting = true;
5998 settings->gpu_rasterization_forced = true;
5999 }
6000
6001 void SetupTree() override {
6002 client_.set_fill_with_nonsolid_color(true);
6003
6004 scoped_refptr<Layer> root = Layer::Create();
6005 root->SetBounds(gfx::Size(500, 500));
6006
6007 scoped_ptr<FakePicturePile> pile(
6008 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6009 ImplSidePaintingSettings().default_tile_grid_size));
6010 scoped_refptr<FakePictureLayer> layer =
6011 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6012 layer->SetBounds(gfx::Size(500, 500));
6013 layer->SetContentsOpaque(true);
6014 root->AddChild(layer);
6015
6016 layer_tree_host()->SetRootLayer(root);
6017 LayerTreeHostTest::SetupTree();
6018 }
6019
6020 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6021
6022 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6023 LayerTreeHostImpl::FrameData* frame_data,
6024 DrawResult draw_result) override {
6025 EXPECT_NE(0u, host_impl->resource_provider()->num_resources());
6026 EndTest();
6027 return draw_result;
6028 }
6029 void AfterTest() override {}
6030
6031 FakeContentLayerClient client_;
6032 };
6033
6034 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
6035
6036 class SynchronousGpuRasterizationRasterizesVisibleOnly
6037 : public LayerTreeHostTest {
6038 protected:
6039 SynchronousGpuRasterizationRasterizesVisibleOnly()
6040 : viewport_size_(1024, 2048) {}
6041
6042 void InitializeSettings(LayerTreeSettings* settings) override {
6043 settings->impl_side_painting = true;
6044 settings->gpu_rasterization_enabled = true;
6045 settings->gpu_rasterization_forced = true;
6046 settings->threaded_gpu_rasterization_enabled = false;
6047 }
6048
6049 void SetupTree() override {
6050 client_.set_fill_with_nonsolid_color(true);
6051
6052 scoped_ptr<FakePicturePile> pile(
6053 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6054 ImplSidePaintingSettings().default_tile_grid_size));
6055 scoped_refptr<FakePictureLayer> root =
6056 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6057 root->SetBounds(gfx::Size(viewport_size_.width(), 10000));
6058 root->SetContentsOpaque(true);
6059
6060 layer_tree_host()->SetRootLayer(root);
6061 LayerTreeHostTest::SetupTree();
6062 layer_tree_host()->SetViewportSize(viewport_size_);
6063 }
6064
6065 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6066
6067 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6068 LayerTreeHostImpl::FrameData* frame_data,
6069 DrawResult draw_result) override {
6070 EXPECT_EQ(4u, host_impl->resource_provider()->num_resources());
6071
6072 // Verify which tiles got resources using an eviction iterator, which has to
6073 // return all tiles that have resources.
6074 scoped_ptr<EvictionTilePriorityQueue> eviction_queue(
6075 host_impl->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES));
6076 int tile_count = 0;
6077 for (; !eviction_queue->IsEmpty(); eviction_queue->Pop()) {
6078 Tile* tile = eviction_queue->Top();
6079 // Ensure this tile is within the viewport.
6080 EXPECT_TRUE(tile->content_rect().Intersects(gfx::Rect(viewport_size_)));
6081 // Ensure that the tile is 1/4 of the viewport tall (plus padding).
6082 EXPECT_EQ(tile->content_rect().height(),
6083 (viewport_size_.height() / 4) + 2);
6084 ++tile_count;
6085 }
6086 EXPECT_EQ(4, tile_count);
6087 EndTest();
6088 return draw_result;
6089 }
6090
6091 void AfterTest() override {}
6092
6093 private:
6094 FakeContentLayerClient client_;
6095 gfx::Size viewport_size_;
6096 };
6097
6098 MULTI_THREAD_IMPL_TEST_F(SynchronousGpuRasterizationRasterizesVisibleOnly);
6099
6100 class ThreadedGpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
6101 protected:
6102 ThreadedGpuRasterizationRasterizesBorderTiles()
6103 : viewport_size_(1024, 2048) {}
6104
6105 void InitializeSettings(LayerTreeSettings* settings) override {
6106 settings->impl_side_painting = true;
6107 settings->gpu_rasterization_enabled = true;
6108 settings->gpu_rasterization_forced = true;
6109 settings->threaded_gpu_rasterization_enabled = true;
6110 }
6111
6112 void SetupTree() override {
6113 client_.set_fill_with_nonsolid_color(true);
6114
6115 scoped_ptr<FakePicturePile> pile(
6116 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6117 ImplSidePaintingSettings().default_tile_grid_size));
6118 scoped_refptr<FakePictureLayer> root =
6119 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6120 root->SetBounds(gfx::Size(10000, 10000));
6121 root->SetContentsOpaque(true);
6122
6123 layer_tree_host()->SetRootLayer(root);
6124 LayerTreeHostTest::SetupTree();
6125 layer_tree_host()->SetViewportSize(viewport_size_);
6126 }
6127
6128 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6129
6130 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6131 LayerTreeHostImpl::FrameData* frame_data,
6132 DrawResult draw_result) override {
6133 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources());
6134 EndTest();
6135 return draw_result;
6136 }
6137
6138 void AfterTest() override {}
6139
6140 private:
6141 FakeContentLayerClient client_;
6142 gfx::Size viewport_size_;
6143 };
6144
6145 MULTI_THREAD_IMPL_TEST_F(ThreadedGpuRasterizationRasterizesBorderTiles);
6146
6147 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
6148 : public LayerTreeHostTest {
6149 protected:
6150 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
6151 : playback_allowed_event_(true, true) {}
6152
6153 void InitializeSettings(LayerTreeSettings* settings) override {
6154 settings->impl_side_painting = true;
6155 }
6156
6157 void SetupTree() override {
6158 step_ = 1;
6159 continuous_draws_ = 0;
6160 client_.set_fill_with_nonsolid_color(true);
6161
6162 scoped_refptr<Layer> root = Layer::Create();
6163 root->SetBounds(gfx::Size(500, 500));
6164
6165 scoped_refptr<Layer> pinch = Layer::Create();
6166 pinch->SetBounds(gfx::Size(500, 500));
6167 pinch->SetScrollClipLayerId(root->id());
6168 pinch->SetIsContainerForFixedPositionLayers(true);
6169 root->AddChild(pinch);
6170
6171 scoped_ptr<FakePicturePile> pile(
6172 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
6173 ImplSidePaintingSettings().default_tile_grid_size));
6174 pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
6175 scoped_refptr<FakePictureLayer> layer =
6176 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
6177 layer->SetBounds(gfx::Size(500, 500));
6178 layer->SetContentsOpaque(true);
6179 // Avoid LCD text on the layer so we don't cause extra commits when we
6180 // pinch.
6181 layer->disable_lcd_text();
6182 pinch->AddChild(layer);
6183
6184 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch);
6185 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6186 layer_tree_host()->SetRootLayer(root);
6187 LayerTreeHostTest::SetupTree();
6188 }
6189
6190 // Returns the delta scale of all quads in the frame's root pass from their
6191 // ideal, or 0 if they are not all the same.
6192 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6193 if (frame_data->has_no_damage)
6194 return 0.f;
6195 float frame_scale = 0.f;
6196 RenderPass* root_pass = frame_data->render_passes.back();
6197 for (const auto& draw_quad : root_pass->quad_list) {
6198 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
6199 float quad_scale =
6200 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6201 float transform_scale =
6202 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
6203 float scale = quad_scale / transform_scale;
6204 if (frame_scale != 0.f && frame_scale != scale)
6205 return 0.f;
6206 frame_scale = scale;
6207 }
6208 return frame_scale;
6209 }
6210
6211 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6212
6213 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6214 LayerTreeHostImpl::FrameData* frame_data,
6215 DrawResult draw_result) override {
6216 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6217 switch (step_) {
6218 case 1:
6219 // Drew at scale 1 before any pinching.
6220 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6221 EXPECT_EQ(1.f, quad_scale_delta);
6222 break;
6223 case 2:
6224 if (quad_scale_delta != 1.f / 1.5f)
6225 break;
6226 // Drew at scale 1 still though the ideal is 1.5.
6227 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6228 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6229 break;
6230 case 3:
6231 // Continuous draws are attempted.
6232 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6233 if (!frame_data->has_no_damage)
6234 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
6235 break;
6236 case 4:
6237 if (quad_scale_delta != 1.f)
6238 break;
6239 // Drew at scale 1.5 when all the tiles completed.
6240 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6241 EXPECT_EQ(1.f, quad_scale_delta);
6242 break;
6243 case 5:
6244 // TODO(danakj): We get more draws before the NotifyReadyToDraw
6245 // because it is asynchronous from the previous draw and happens late.
6246 break;
6247 case 6:
6248 // NotifyReadyToDraw happened. If we were already inside a frame, we may
6249 // try to draw once more.
6250 break;
6251 case 7:
6252 NOTREACHED() << "No draws should happen once we have a complete frame.";
6253 break;
6254 }
6255 return draw_result;
6256 }
6257
6258 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6259 switch (step_) {
6260 case 1:
6261 // Delay tile production.
6262 playback_allowed_event_.Reset();
6263 // Pinch zoom in to cause new tiles to be required.
6264 host_impl->PinchGestureBegin();
6265 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
6266 host_impl->PinchGestureEnd();
6267 ++step_;
6268 break;
6269 case 2:
6270 ++step_;
6271 break;
6272 case 3:
6273 // We should continue to try draw while there are incomplete visible
6274 // tiles.
6275 if (++continuous_draws_ > 5) {
6276 // Allow the tiles to complete.
6277 playback_allowed_event_.Signal();
6278 ++step_;
6279 }
6280 break;
6281 case 4:
6282 ++step_;
6283 break;
6284 case 5:
6285 // Waiting for NotifyReadyToDraw.
6286 break;
6287 case 6:
6288 // NotifyReadyToDraw happened.
6289 ++step_;
6290 break;
6291 }
6292 }
6293
6294 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
6295 if (step_ == 5) {
6296 ++step_;
6297 // NotifyReadyToDraw has happened, we may draw once more, but should not
6298 // get any more draws after that. End the test after a timeout to watch
6299 // for any extraneous draws.
6300 // TODO(brianderson): We could remove this delay and instead wait until
6301 // the BeginFrameSource decides it doesn't need to send frames anymore,
6302 // or test that it already doesn't here.
6303 EndTestAfterDelayMs(16 * 4);
6304 }
6305 }
6306
6307 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
6308 const Tile* tile) override {
6309 // On step_ == 2, we are preventing texture uploads from completing,
6310 // so this verifies they are not completing before step_ == 3.
6311 // Flaky failures here indicate we're failing to prevent uploads from
6312 // completing.
6313 EXPECT_NE(2, step_);
6314 }
6315
6316 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
6317
6318 FakeContentLayerClient client_;
6319 int step_;
6320 int continuous_draws_;
6321 base::WaitableEvent playback_allowed_event_;
6322 };
6323
6324 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
6325
6326 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
6327 public:
6328 LayerTreeHostTestOneActivatePerPrepareTiles()
6329 : notify_ready_to_activate_count_(0u),
6330 scheduled_prepare_tiles_count_(0) {}
6331
6332 void SetupTree() override {
6333 client_.set_fill_with_nonsolid_color(true);
6334 scoped_refptr<FakePictureLayer> root_layer =
6335 FakePictureLayer::Create(&client_);
6336 root_layer->SetBounds(gfx::Size(1500, 1500));
6337 root_layer->SetIsDrawable(true);
6338
6339 layer_tree_host()->SetRootLayer(root_layer);
6340 LayerTreeHostTest::SetupTree();
6341 }
6342
6343 void BeginTest() override {
6344 layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
6345 PostSetNeedsCommitToMainThread();
6346 }
6347
6348 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
6349 bool success) override {
6350 ASSERT_TRUE(success);
6351 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
6352 }
6353
6354 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6355 ++notify_ready_to_activate_count_;
6356 EndTestAfterDelayMs(100);
6357 }
6358
6359 void ScheduledActionPrepareTiles() override {
6360 ++scheduled_prepare_tiles_count_;
6361 }
6362
6363 void AfterTest() override {
6364 // Expect at most a notification for each scheduled prepare tiles, plus one
6365 // for the initial commit (which doesn't go through scheduled actions).
6366 // The reason this is not an equality is because depending on timing, we
6367 // might get a prepare tiles but not yet get a notification that we're
6368 // ready to activate. The intent of a test is to ensure that we don't
6369 // get more than one notification per prepare tiles, so this is OK.
6370 EXPECT_LE(notify_ready_to_activate_count_,
6371 1u + scheduled_prepare_tiles_count_);
6372 }
6373
6374 protected:
6375 FakeContentLayerClient client_;
6376 size_t notify_ready_to_activate_count_;
6377 size_t scheduled_prepare_tiles_count_;
6378 };
6379
6380 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
6381
6382 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
6383 : public LayerTreeHostTest {
6384 public:
6385 LayerTreeHostTestFrameTimingRequestsSaveTimestamps()
6386 : check_results_on_commit_(false) {}
6387
6388 void SetupTree() override {
6389 scoped_refptr<FakePictureLayer> root_layer =
6390 FakePictureLayer::Create(&client_);
6391 root_layer->SetBounds(gfx::Size(200, 200));
6392 root_layer->SetIsDrawable(true);
6393
6394 scoped_refptr<FakePictureLayer> child_layer =
6395 FakePictureLayer::Create(&client_);
6396 child_layer->SetBounds(gfx::Size(1500, 1500));
6397 child_layer->SetIsDrawable(true);
6398
6399 std::vector<FrameTimingRequest> requests;
6400 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100)));
6401 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100)));
6402 child_layer->SetFrameTimingRequests(requests);
6403
6404 root_layer->AddChild(child_layer);
6405 layer_tree_host()->SetRootLayer(root_layer);
6406 LayerTreeHostTest::SetupTree();
6407 }
6408
6409 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6410
6411 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
6412 if (!check_results_on_commit_)
6413 return;
6414
6415 // Since in reality, the events will be read by LayerTreeHost during commit,
6416 // we check the requests here to ensure that they are correct at the next
6417 // commit time (as opposed to checking in DrawLayers for instance).
6418 // TODO(vmpstr): Change this to read things from the main thread when this
6419 // information is propagated to the main thread (not yet implemented).
6420 FrameTimingTracker* tracker = host_impl->frame_timing_tracker();
6421 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set =
6422 tracker->GroupCountsByRectId();
6423 EXPECT_EQ(1u, timing_set->size());
6424 auto rect_1_it = timing_set->find(1);
6425 EXPECT_TRUE(rect_1_it != timing_set->end());
6426 const auto& timing_events = rect_1_it->second;
6427 EXPECT_EQ(1u, timing_events.size());
6428 EXPECT_EQ(host_impl->active_tree()->source_frame_number(),
6429 timing_events[0].frame_id);
6430 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks());
6431
6432 EndTest();
6433 }
6434
6435 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
6436 check_results_on_commit_ = true;
6437 PostSetNeedsCommitToMainThread();
6438 }
6439
6440 void AfterTest() override {}
6441
6442 private:
6443 FakeContentLayerClient client_;
6444 bool check_results_on_commit_;
6445 };
6446
6447 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
6448
6449 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
6450 public:
6451 LayerTreeHostTestActivationCausesPrepareTiles()
6452 : scheduled_prepare_tiles_count_(0) {}
6453
6454 void SetupTree() override {
6455 client_.set_fill_with_nonsolid_color(true);
6456 scoped_refptr<FakePictureLayer> root_layer =
6457 FakePictureLayer::Create(&client_);
6458 root_layer->SetBounds(gfx::Size(150, 150));
6459 root_layer->SetIsDrawable(true);
6460
6461 layer_tree_host()->SetRootLayer(root_layer);
6462 LayerTreeHostTest::SetupTree();
6463 }
6464
6465 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6466
6467 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
6468 // Ensure we've already activated.
6469 EXPECT_FALSE(impl->pending_tree());
6470
6471 // After activating, we either need to prepare tiles, or we've already
6472 // called a scheduled prepare tiles. This is done because activation might
6473 // cause us to have to memory available (old active tree is gone), so we
6474 // need to ensure we will get a PrepareTiles call.
6475 if (!impl->prepare_tiles_needed())
6476 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
6477 EndTest();
6478 }
6479
6480 void ScheduledActionPrepareTiles() override {
6481 ++scheduled_prepare_tiles_count_;
6482 }
6483
6484 void AfterTest() override {}
6485
6486 protected:
6487 FakeContentLayerClient client_;
6488 int scheduled_prepare_tiles_count_;
6489 };
6490
6491 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
6492
6493 // This tests an assertion that DidCommit and WillCommit happen in the same
6494 // stack frame with no tasks that run between them. Various embedders of
6495 // cc depend on this logic. ui::Compositor holds a compositor lock between
6496 // these events and the inspector timeline wants begin/end CompositeLayers
6497 // to be properly nested with other begin/end events.
6498 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
6499 : public LayerTreeHostTest {
6500 public:
6501 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
6502
6503 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6504
6505 void WillCommit() override {
6506 MainThreadTaskRunner()->PostTask(
6507 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
6508 EndTestShouldRunAfterDidCommit,
6509 base::Unretained(this)));
6510 }
6511
6512 void EndTestShouldRunAfterDidCommit() {
6513 EXPECT_TRUE(did_commit_);
6514 EndTest();
6515 }
6516
6517 void DidCommit() override {
6518 EXPECT_FALSE(did_commit_);
6519 did_commit_ = true;
6520 }
6521
6522 void AfterTest() override { EXPECT_TRUE(did_commit_); }
6523
6524 private:
6525 bool did_commit_;
6526 };
6527
6528 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
6529
6530 // Verify that if a LayerImpl holds onto a copy request for multiple
6531 // frames that it will continue to have a render surface through
6532 // multiple commits, even though the Layer itself has no reason
6533 // to have a render surface.
6534 class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest {
6535 protected:
6536 void SetupTree() override {
6537 scoped_refptr<Layer> root = Layer::Create();
6538 root->CreateRenderSurface();
6539 root->SetBounds(gfx::Size(10, 10));
6540 child_ = Layer::Create();
6541 child_->SetBounds(gfx::Size(20, 20));
6542 root->AddChild(child_);
6543
6544 layer_tree_host()->SetRootLayer(root);
6545 LayerTreeHostTest::SetupTree();
6546 }
6547
6548 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
6549
6550 void BeginTest() override {
6551 child_->RequestCopyOfOutput(
6552 CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback)));
6553 EXPECT_TRUE(child_->HasCopyRequest());
6554 PostSetNeedsCommitToMainThread();
6555 }
6556
6557 void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); }
6558
6559 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6560 LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id());
6561
6562 switch (host_impl->sync_tree()->source_frame_number()) {
6563 case 0:
6564 EXPECT_TRUE(child_impl->HasCopyRequest());
6565 EXPECT_TRUE(child_impl->render_surface());
6566 break;
6567 case 1:
6568 if (host_impl->proxy()->CommitToActiveTree()) {
6569 EXPECT_TRUE(child_impl->HasCopyRequest());
6570 EXPECT_TRUE(child_impl->render_surface());
6571 } else {
6572 EXPECT_FALSE(child_impl->HasCopyRequest());
6573 EXPECT_FALSE(child_impl->render_surface());
6574 }
6575 break;
6576 default:
6577 NOTREACHED();
6578 break;
6579 }
6580 }
6581
6582 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6583 LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id());
6584 EXPECT_TRUE(child_impl->HasCopyRequest());
6585 EXPECT_TRUE(child_impl->render_surface());
6586
6587 switch (host_impl->active_tree()->source_frame_number()) {
6588 case 0:
6589 // Lose output surface to prevent drawing and cause another commit.
6590 host_impl->DidLoseOutputSurface();
6591 break;
6592 case 1:
6593 EndTest();
6594 break;
6595 default:
6596 NOTREACHED();
6597 break;
6598 }
6599 }
6600
6601 void AfterTest() override {}
6602
6603 private:
6604 scoped_refptr<Layer> child_;
6605 };
6606
6607 SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests);
6608
6609 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/layer_tree_host_single_thread_client.h ('k') | cc/trees/layer_tree_host_unittest_animation.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698