Disable blink_perf.events on x64.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_picture.cc
blob6f222f71e719e47a6b44c3675b6e545cface7c8b
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include "cc/test/fake_content_layer_client.h"
8 #include "cc/test/fake_picture_layer.h"
9 #include "cc/test/fake_picture_layer_impl.h"
10 #include "cc/test/layer_tree_test.h"
11 #include "cc/trees/layer_tree_impl.h"
13 namespace cc {
14 namespace {
16 // These tests deal with picture layers.
17 class LayerTreeHostPictureTest : public LayerTreeTest {
18 protected:
19 void SetupTreeWithSinglePictureLayer(const gfx::Size& size) {
20 scoped_refptr<Layer> root = Layer::Create();
21 root->SetBounds(size);
23 root_picture_layer_ = FakePictureLayer::Create(&client_);
24 root_picture_layer_->SetBounds(size);
25 root->AddChild(root_picture_layer_);
27 layer_tree_host()->SetRootLayer(root);
30 scoped_refptr<FakePictureLayer> root_picture_layer_;
31 FakeContentLayerClient client_;
34 class LayerTreeHostPictureTestTwinLayer
35 : public LayerTreeHostPictureTest {
36 void SetupTree() override {
37 SetupTreeWithSinglePictureLayer(gfx::Size(1, 1));
40 void BeginTest() override {
41 activates_ = 0;
42 PostSetNeedsCommitToMainThread();
45 void DidCommit() override {
46 switch (layer_tree_host()->source_frame_number()) {
47 case 1:
48 // Activate while there are pending and active twins in place.
49 layer_tree_host()->SetNeedsCommit();
50 break;
51 case 2:
52 // Drop the picture layer from the tree so the activate will have an
53 // active layer without a pending twin.
54 layer_tree_host()->root_layer()->children()[0]->RemoveFromParent();
55 break;
56 case 3: {
57 // Add a new picture layer so the activate will have a pending layer
58 // without an active twin.
59 scoped_refptr<FakePictureLayer> picture =
60 FakePictureLayer::Create(&client_);
61 layer_tree_host()->root_layer()->AddChild(picture);
62 break;
64 case 4:
65 // Active while there are pending and active twins again.
66 layer_tree_host()->SetNeedsCommit();
67 break;
68 case 5:
69 EndTest();
70 break;
74 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
75 LayerImpl* pending_root_impl = impl->pending_tree()->root_layer();
76 LayerImpl* active_root_impl = impl->active_tree()->root_layer();
78 if (pending_root_impl->children().empty()) {
79 EXPECT_EQ(2, activates_);
80 return;
83 FakePictureLayerImpl* pending_picture_impl =
84 static_cast<FakePictureLayerImpl*>(pending_root_impl->children()[0]);
86 if (!active_root_impl) {
87 EXPECT_EQ(0, activates_);
88 EXPECT_EQ(nullptr, pending_picture_impl->GetPendingOrActiveTwinLayer());
89 return;
92 if (active_root_impl->children().empty()) {
93 EXPECT_EQ(3, activates_);
94 EXPECT_EQ(nullptr, pending_picture_impl->GetPendingOrActiveTwinLayer());
95 return;
98 FakePictureLayerImpl* active_picture_impl =
99 static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]);
101 // After the first activation, when we commit again, we'll have a pending
102 // and active layer. Then we recreate a picture layer in the 4th activate
103 // and the next commit will have a pending and active twin again.
104 EXPECT_TRUE(activates_ == 1 || activates_ == 4) << activates_;
106 EXPECT_EQ(pending_picture_impl,
107 active_picture_impl->GetPendingOrActiveTwinLayer());
108 EXPECT_EQ(active_picture_impl,
109 pending_picture_impl->GetPendingOrActiveTwinLayer());
110 EXPECT_EQ(nullptr, active_picture_impl->GetRecycledTwinLayer());
113 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
114 LayerImpl* active_root_impl = impl->active_tree()->root_layer();
115 LayerImpl* recycle_root_impl = impl->recycle_tree()->root_layer();
117 if (active_root_impl->children().empty()) {
118 EXPECT_EQ(2, activates_);
119 } else {
120 FakePictureLayerImpl* active_picture_impl =
121 static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]);
122 FakePictureLayerImpl* recycle_picture_impl =
123 static_cast<FakePictureLayerImpl*>(recycle_root_impl->children()[0]);
125 EXPECT_EQ(nullptr, active_picture_impl->GetPendingOrActiveTwinLayer());
126 EXPECT_EQ(recycle_picture_impl,
127 active_picture_impl->GetRecycledTwinLayer());
130 ++activates_;
133 void AfterTest() override { EXPECT_EQ(5, activates_); }
135 int activates_;
138 // There is no pending layers in single thread mode.
139 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestTwinLayer);
141 class LayerTreeHostPictureTestResizeViewportWithGpuRaster
142 : public LayerTreeHostPictureTest {
143 void InitializeSettings(LayerTreeSettings* settings) override {
144 settings->gpu_rasterization_forced = true;
147 void SetupTree() override {
148 scoped_refptr<Layer> root = Layer::Create();
149 root->SetBounds(gfx::Size(768, 960));
151 client_.set_fill_with_nonsolid_color(true);
152 picture_ = FakePictureLayer::Create(&client_);
153 picture_->SetBounds(gfx::Size(768, 960));
154 root->AddChild(picture_);
156 layer_tree_host()->SetRootLayer(root);
157 LayerTreeHostPictureTest::SetupTree();
160 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
162 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
163 LayerImpl* child = impl->sync_tree()->root_layer()->children()[0];
164 FakePictureLayerImpl* picture_impl =
165 static_cast<FakePictureLayerImpl*>(child);
166 gfx::Size tile_size =
167 picture_impl->HighResTiling()->TileAt(0, 0)->content_rect().size();
169 switch (impl->sync_tree()->source_frame_number()) {
170 case 0:
171 tile_size_ = tile_size;
172 // GPU Raster picks a tile size based on the viewport size.
173 EXPECT_EQ(gfx::Size(768, 256), tile_size);
174 break;
175 case 1:
176 // When the viewport changed size, the new frame's tiles should change
177 // along with it.
178 EXPECT_NE(gfx::Size(768, 256), tile_size);
182 void DidCommit() override {
183 switch (layer_tree_host()->source_frame_number()) {
184 case 1:
185 // Change the picture layer's size along with the viewport, so it will
186 // consider picking a new tile size.
187 picture_->SetBounds(gfx::Size(768, 1056));
188 layer_tree_host()->SetViewportSize(gfx::Size(768, 1056));
189 break;
190 case 2:
191 EndTest();
195 void AfterTest() override {}
197 gfx::Size tile_size_;
198 FakeContentLayerClient client_;
199 scoped_refptr<FakePictureLayer> picture_;
202 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
203 LayerTreeHostPictureTestResizeViewportWithGpuRaster);
205 class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
206 : public LayerTreeHostPictureTest {
207 void SetupTree() override {
208 frame_ = 0;
209 did_post_commit_ = false;
211 scoped_refptr<Layer> root = Layer::Create();
212 root->SetBounds(gfx::Size(100, 100));
214 // The layer is big enough that the live tiles rect won't cover the full
215 // layer.
216 client_.set_fill_with_nonsolid_color(true);
217 picture_ = FakePictureLayer::Create(&client_);
218 picture_->SetBounds(gfx::Size(100, 100000));
219 root->AddChild(picture_);
221 layer_tree_host()->SetRootLayer(root);
222 LayerTreeHostPictureTest::SetupTree();
225 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
227 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
228 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
229 FakePictureLayerImpl* picture_impl =
230 static_cast<FakePictureLayerImpl*>(child);
231 FakePictureLayerImpl* recycled_impl = static_cast<FakePictureLayerImpl*>(
232 picture_impl->GetRecycledTwinLayer());
234 switch (++frame_) {
235 case 1: {
236 PictureLayerTiling* tiling = picture_impl->HighResTiling();
237 PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
238 int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
240 // There should be tiles at the top of the picture layer but not at the
241 // bottom.
242 EXPECT_TRUE(tiling->TileAt(0, 0));
243 EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
245 // The recycled tiling has no tiles.
246 EXPECT_FALSE(recycled_tiling->TileAt(0, 0));
247 EXPECT_FALSE(recycled_tiling->TileAt(0, num_tiles_y));
249 // The live tiles rect matches on the recycled tree.
250 EXPECT_EQ(tiling->live_tiles_rect(),
251 recycled_tiling->live_tiles_rect());
253 // Make the bottom of the layer visible.
254 picture_impl->SetPosition(gfx::PointF(0.f, -100000.f + 100.f));
255 impl->SetNeedsRedraw();
256 break;
258 case 2: {
259 PictureLayerTiling* tiling = picture_impl->HighResTiling();
260 PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
262 // There not be tiles at the top of the layer now.
263 EXPECT_FALSE(tiling->TileAt(0, 0));
265 // The recycled twin tiling should not have unshared tiles at the top
266 // either.
267 EXPECT_FALSE(recycled_tiling->TileAt(0, 0));
269 // Make the top of the layer visible again.
270 picture_impl->SetPosition(gfx::PointF());
271 impl->SetNeedsRedraw();
272 break;
274 case 3: {
275 PictureLayerTiling* tiling = picture_impl->HighResTiling();
276 PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
277 int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
279 // There should be tiles at the top of the picture layer again.
280 EXPECT_TRUE(tiling->TileAt(0, 0));
281 EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
283 // The recycled tiling should have no tiles.
284 EXPECT_FALSE(recycled_tiling->TileAt(0, 0));
285 EXPECT_FALSE(recycled_tiling->TileAt(0, num_tiles_y));
287 // The live tiles rect matches on the recycled tree.
288 EXPECT_EQ(tiling->live_tiles_rect(),
289 recycled_tiling->live_tiles_rect());
291 // Make a new main frame without changing the picture layer at all, so
292 // it won't need to update or push properties.
293 did_post_commit_ = true;
294 PostSetNeedsCommitToMainThread();
295 break;
300 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
301 LayerImpl* child = impl->sync_tree()->root_layer()->children()[0];
302 FakePictureLayerImpl* picture_impl =
303 static_cast<FakePictureLayerImpl*>(child);
304 PictureLayerTiling* tiling = picture_impl->HighResTiling();
305 int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
307 if (!impl->active_tree()->root_layer()) {
308 // If active tree doesn't have the layer, then pending tree should have
309 // all needed tiles.
310 EXPECT_TRUE(tiling->TileAt(0, 0));
311 } else {
312 // Since there was no invalidation, the pending tree shouldn't have any
313 // tiles.
314 EXPECT_FALSE(tiling->TileAt(0, 0));
316 EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
318 if (did_post_commit_)
319 EndTest();
322 void AfterTest() override {}
324 int frame_;
325 bool did_post_commit_;
326 FakeContentLayerClient client_;
327 scoped_refptr<FakePictureLayer> picture_;
330 // Multi-thread only since there is no recycle tree in single thread.
331 MULTI_THREAD_IMPL_TEST_F(
332 LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree);
334 class LayerTreeHostPictureTestRSLLMembership : public LayerTreeHostPictureTest {
335 void SetupTree() override {
336 scoped_refptr<Layer> root = Layer::Create();
337 root->SetBounds(gfx::Size(100, 100));
339 child_ = Layer::Create();
340 root->AddChild(child_);
342 // Don't be solid color so the layer has tilings/tiles.
343 client_.set_fill_with_nonsolid_color(true);
344 picture_ = FakePictureLayer::Create(&client_);
345 picture_->SetBounds(gfx::Size(100, 100));
346 child_->AddChild(picture_);
348 layer_tree_host()->SetRootLayer(root);
349 LayerTreeHostPictureTest::SetupTree();
352 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
354 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
355 LayerImpl* root = impl->sync_tree()->root_layer();
356 LayerImpl* child = root->children()[0];
357 LayerImpl* gchild = child->children()[0];
358 FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
360 switch (impl->sync_tree()->source_frame_number()) {
361 case 0:
362 // On 1st commit the layer has tilings.
363 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
364 break;
365 case 1:
366 // On 2nd commit, the layer is transparent, but its tilings are left
367 // there.
368 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
369 break;
370 case 2:
371 // On 3rd commit, the layer is visible again, so has tilings.
372 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
376 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
377 LayerImpl* root = impl->active_tree()->root_layer();
378 LayerImpl* child = root->children()[0];
379 LayerImpl* gchild = child->children()[0];
380 FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
382 switch (impl->active_tree()->source_frame_number()) {
383 case 0:
384 // On 1st commit the layer has tilings.
385 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
386 break;
387 case 1:
388 // On 2nd commit, the layer is transparent, but its tilings are left
389 // there.
390 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
391 break;
392 case 2:
393 // On 3rd commit, the layer is visible again, so has tilings.
394 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
395 EndTest();
399 void DidCommit() override {
400 switch (layer_tree_host()->source_frame_number()) {
401 case 1:
402 // For the 2nd commit, change opacity to 0 so that the layer will not be
403 // part of the visible frame.
404 child_->SetOpacity(0.f);
405 break;
406 case 2:
407 // For the 3rd commit, change opacity to 1 so that the layer will again
408 // be part of the visible frame.
409 child_->SetOpacity(1.f);
413 void AfterTest() override {}
415 FakeContentLayerClient client_;
416 scoped_refptr<Layer> child_;
417 scoped_refptr<FakePictureLayer> picture_;
420 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestRSLLMembership);
422 class LayerTreeHostPictureTestRSLLMembershipWithScale
423 : public LayerTreeHostPictureTest {
424 void SetupTree() override {
425 scoped_refptr<Layer> root = Layer::Create();
426 root->SetBounds(gfx::Size(100, 100));
428 pinch_ = Layer::Create();
429 pinch_->SetBounds(gfx::Size(500, 500));
430 pinch_->SetScrollClipLayerId(root->id());
431 pinch_->SetIsContainerForFixedPositionLayers(true);
432 root->AddChild(pinch_);
434 // Don't be solid color so the layer has tilings/tiles.
435 client_.set_fill_with_nonsolid_color(true);
436 picture_ = FakePictureLayer::Create(&client_);
437 picture_->SetBounds(gfx::Size(100, 100));
438 pinch_->AddChild(picture_);
440 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch_, pinch_);
441 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
442 layer_tree_host()->SetRootLayer(root);
443 LayerTreeHostPictureTest::SetupTree();
446 void InitializeSettings(LayerTreeSettings* settings) override {
447 settings->layer_transforms_should_scale_layer_contents = true;
450 void BeginTest() override {
451 frame_ = 0;
452 draws_in_frame_ = 0;
453 last_frame_drawn_ = -1;
454 PostSetNeedsCommitToMainThread();
457 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
458 LayerImpl* root = impl->sync_tree()->root_layer();
459 LayerImpl* pinch = root->children()[0];
460 LayerImpl* gchild = pinch->children()[0];
461 FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
463 switch (frame_) {
464 case 0:
465 // On 1st commit the layer has tilings.
466 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
467 break;
468 case 1:
469 // On 2nd commit, the layer is transparent, so does not have tilings.
470 EXPECT_EQ(0u, picture->tilings()->num_tilings());
471 break;
472 case 2:
473 // On 3rd commit, the layer is visible again, so has tilings.
474 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
478 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
479 LayerImpl* root = impl->active_tree()->root_layer();
480 LayerImpl* pinch = root->children()[0];
481 LayerImpl* gchild = pinch->children()[0];
482 FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
484 if (frame_ != last_frame_drawn_)
485 draws_in_frame_ = 0;
486 ++draws_in_frame_;
487 last_frame_drawn_ = frame_;
489 switch (frame_) {
490 case 0:
491 if (draws_in_frame_ == 1) {
492 // On 1st commit the layer has tilings.
493 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
494 EXPECT_EQ(1.f, picture->HighResTiling()->contents_scale());
496 // Pinch zoom in to change the scale on the active tree.
497 impl->PinchGestureBegin();
498 impl->PinchGestureUpdate(2.f, gfx::Point(1, 1));
499 impl->PinchGestureEnd();
500 } else if (picture->tilings()->num_tilings() == 1) {
501 // If the pinch gesture caused a commit we could get here with a
502 // pending tree.
503 EXPECT_FALSE(impl->pending_tree());
504 // The active layer now has only a 2.f scale tiling, which means the
505 // recycled layer's tiling is destroyed.
506 EXPECT_EQ(2.f, picture->HighResTiling()->contents_scale());
507 EXPECT_EQ(0u, picture->GetRecycledTwinLayer()
508 ->picture_layer_tiling_set()
509 ->num_tilings());
511 ++frame_;
512 MainThreadTaskRunner()->PostTask(
513 FROM_HERE,
514 base::Bind(
515 &LayerTreeHostPictureTestRSLLMembershipWithScale::NextStep,
516 base::Unretained(this)));
518 break;
519 case 1:
520 EXPECT_EQ(1, draws_in_frame_);
521 // On 2nd commit, the layer is transparent, so does not create
522 // tilings. Since the 1.f tiling was destroyed in the recycle tree, it
523 // has no tilings left. This is propogated to the active tree.
524 EXPECT_EQ(0u, picture->picture_layer_tiling_set()->num_tilings());
525 EXPECT_EQ(0u, picture->GetRecycledTwinLayer()
526 ->picture_layer_tiling_set()
527 ->num_tilings());
528 ++frame_;
529 MainThreadTaskRunner()->PostTask(
530 FROM_HERE,
531 base::Bind(
532 &LayerTreeHostPictureTestRSLLMembershipWithScale::NextStep,
533 base::Unretained(this)));
534 break;
535 case 2:
536 EXPECT_EQ(1, draws_in_frame_);
537 // On 3rd commit, the layer is visible again, so has tilings.
538 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
539 EndTest();
543 void NextStep() {
544 switch (frame_) {
545 case 1:
546 // For the 2nd commit, change opacity to 0 so that the layer will not be
547 // part of the visible frame.
548 pinch_->SetOpacity(0.f);
549 break;
550 case 2:
551 // For the 3rd commit, change opacity to 1 so that the layer will again
552 // be part of the visible frame.
553 pinch_->SetOpacity(1.f);
554 break;
558 void AfterTest() override {}
560 FakeContentLayerClient client_;
561 scoped_refptr<Layer> pinch_;
562 scoped_refptr<FakePictureLayer> picture_;
563 int frame_;
564 int draws_in_frame_;
565 int last_frame_drawn_;
568 // Multi-thread only because in single thread you can't pinch zoom on the
569 // compositor thread.
570 // Disabled due to flakiness. See http://crbug.com/460581
571 // MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestRSLLMembershipWithScale);
573 } // namespace
574 } // namespace cc