This sets up API to release OutputSurface from LTHClient.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_picture.cc
blob646b3a039afacae164c7c04e1b46f5f21627a3cc
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(layer_settings());
21 root->SetBounds(size);
23 root_picture_layer_ = FakePictureLayer::Create(layer_settings(), &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(layer_settings(), &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());
112 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
113 LayerImpl* active_root_impl = impl->active_tree()->root_layer();
114 if (active_root_impl->children().empty()) {
115 EXPECT_EQ(2, activates_);
116 } else {
117 FakePictureLayerImpl* active_picture_impl =
118 static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]);
119 EXPECT_EQ(nullptr, active_picture_impl->GetPendingOrActiveTwinLayer());
122 ++activates_;
125 void AfterTest() override { EXPECT_EQ(5, activates_); }
127 int activates_;
130 // There is no pending layers in single thread mode.
131 MULTI_THREAD_TEST_F(LayerTreeHostPictureTestTwinLayer);
133 class LayerTreeHostPictureTestResizeViewportWithGpuRaster
134 : public LayerTreeHostPictureTest {
135 void InitializeSettings(LayerTreeSettings* settings) override {
136 settings->gpu_rasterization_forced = true;
139 void SetupTree() override {
140 scoped_refptr<Layer> root = Layer::Create(layer_settings());
141 root->SetBounds(gfx::Size(768, 960));
143 client_.set_fill_with_nonsolid_color(true);
144 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
145 picture_->SetBounds(gfx::Size(768, 960));
146 root->AddChild(picture_);
148 layer_tree_host()->SetRootLayer(root);
149 LayerTreeHostPictureTest::SetupTree();
152 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
154 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
155 LayerImpl* child = impl->sync_tree()->root_layer()->children()[0];
156 FakePictureLayerImpl* picture_impl =
157 static_cast<FakePictureLayerImpl*>(child);
158 gfx::Size tile_size =
159 picture_impl->HighResTiling()->TileAt(0, 0)->content_rect().size();
161 switch (impl->sync_tree()->source_frame_number()) {
162 case 0:
163 tile_size_ = tile_size;
164 // GPU Raster picks a tile size based on the viewport size.
165 EXPECT_EQ(gfx::Size(768, 256), tile_size);
166 break;
167 case 1:
168 // When the viewport changed size, the new frame's tiles should change
169 // along with it.
170 EXPECT_NE(gfx::Size(768, 256), tile_size);
174 void DidCommit() override {
175 switch (layer_tree_host()->source_frame_number()) {
176 case 1:
177 // Change the picture layer's size along with the viewport, so it will
178 // consider picking a new tile size.
179 picture_->SetBounds(gfx::Size(768, 1056));
180 layer_tree_host()->SetViewportSize(gfx::Size(768, 1056));
181 break;
182 case 2:
183 EndTest();
187 void AfterTest() override {}
189 gfx::Size tile_size_;
190 FakeContentLayerClient client_;
191 scoped_refptr<FakePictureLayer> picture_;
194 SINGLE_AND_MULTI_THREAD_TEST_F(
195 LayerTreeHostPictureTestResizeViewportWithGpuRaster);
197 class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
198 : public LayerTreeHostPictureTest {
199 void SetupTree() override {
200 frame_ = 0;
201 did_post_commit_ = false;
203 scoped_refptr<Layer> root = Layer::Create(layer_settings());
204 root->SetBounds(gfx::Size(100, 100));
206 // The layer is big enough that the live tiles rect won't cover the full
207 // layer.
208 client_.set_fill_with_nonsolid_color(true);
209 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
210 picture_->SetBounds(gfx::Size(100, 100000));
211 root->AddChild(picture_);
213 // picture_'s transform is going to be changing on the compositor thread, so
214 // force it to have a transform node by making it scrollable.
215 picture_->SetScrollClipLayerId(root->id());
217 layer_tree_host()->SetRootLayer(root);
218 LayerTreeHostPictureTest::SetupTree();
221 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
223 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
224 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
225 FakePictureLayerImpl* picture_impl =
226 static_cast<FakePictureLayerImpl*>(child);
227 switch (++frame_) {
228 case 1: {
229 PictureLayerTiling* tiling = picture_impl->HighResTiling();
230 int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
232 // There should be tiles at the top of the picture layer but not at the
233 // bottom.
234 EXPECT_TRUE(tiling->TileAt(0, 0));
235 EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
237 // Make the bottom of the layer visible.
238 gfx::Transform transform;
239 transform.Translate(0.f, -100000.f + 100.f);
240 picture_impl->SetTransform(transform);
241 picture_impl->UpdatePropertyTreeTransform();
242 impl->SetNeedsRedraw();
243 break;
245 case 2: {
246 PictureLayerTiling* tiling = picture_impl->HighResTiling();
248 // There not be tiles at the top of the layer now.
249 EXPECT_FALSE(tiling->TileAt(0, 0));
251 // Make the top of the layer visible again.
252 picture_impl->SetTransform(gfx::Transform());
253 picture_impl->UpdatePropertyTreeTransform();
254 impl->SetNeedsRedraw();
255 break;
257 case 3: {
258 PictureLayerTiling* tiling = picture_impl->HighResTiling();
259 int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
261 // There should be tiles at the top of the picture layer again.
262 EXPECT_TRUE(tiling->TileAt(0, 0));
263 EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
265 // Make a new main frame without changing the picture layer at all, so
266 // it won't need to update or push properties.
267 did_post_commit_ = true;
268 PostSetNeedsCommitToMainThread();
269 break;
274 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
275 LayerImpl* child = impl->sync_tree()->root_layer()->children()[0];
276 FakePictureLayerImpl* picture_impl =
277 static_cast<FakePictureLayerImpl*>(child);
278 PictureLayerTiling* tiling = picture_impl->HighResTiling();
279 int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
281 if (!impl->active_tree()->root_layer()) {
282 // If active tree doesn't have the layer, then pending tree should have
283 // all needed tiles.
284 EXPECT_TRUE(tiling->TileAt(0, 0));
285 } else {
286 // Since there was no invalidation, the pending tree shouldn't have any
287 // tiles.
288 EXPECT_FALSE(tiling->TileAt(0, 0));
290 EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
292 if (did_post_commit_)
293 EndTest();
296 void AfterTest() override {}
298 int frame_;
299 bool did_post_commit_;
300 FakeContentLayerClient client_;
301 scoped_refptr<FakePictureLayer> picture_;
304 // Multi-thread only since there is no recycle tree in single thread.
305 MULTI_THREAD_TEST_F(LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree);
307 class LayerTreeHostPictureTestRSLLMembership : public LayerTreeHostPictureTest {
308 void SetupTree() override {
309 scoped_refptr<Layer> root = Layer::Create(layer_settings());
310 root->SetBounds(gfx::Size(100, 100));
312 child_ = Layer::Create(layer_settings());
313 root->AddChild(child_);
315 // Don't be solid color so the layer has tilings/tiles.
316 client_.set_fill_with_nonsolid_color(true);
317 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
318 picture_->SetBounds(gfx::Size(100, 100));
319 child_->AddChild(picture_);
321 layer_tree_host()->SetRootLayer(root);
322 LayerTreeHostPictureTest::SetupTree();
325 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
327 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
328 LayerImpl* root = impl->sync_tree()->root_layer();
329 LayerImpl* child = root->children()[0];
330 LayerImpl* gchild = child->children()[0];
331 FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
333 switch (impl->sync_tree()->source_frame_number()) {
334 case 0:
335 // On 1st commit the layer has tilings.
336 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
337 break;
338 case 1:
339 // On 2nd commit, the layer is transparent, but its tilings are left
340 // there.
341 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
342 break;
343 case 2:
344 // On 3rd commit, the layer is visible again, so has tilings.
345 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
349 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
350 LayerImpl* root = impl->active_tree()->root_layer();
351 LayerImpl* child = root->children()[0];
352 LayerImpl* gchild = child->children()[0];
353 FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
355 switch (impl->active_tree()->source_frame_number()) {
356 case 0:
357 // On 1st commit the layer has tilings.
358 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
359 break;
360 case 1:
361 // On 2nd commit, the layer is transparent, but its tilings are left
362 // there.
363 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
364 break;
365 case 2:
366 // On 3rd commit, the layer is visible again, so has tilings.
367 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
368 EndTest();
372 void DidCommit() override {
373 switch (layer_tree_host()->source_frame_number()) {
374 case 1:
375 // For the 2nd commit, change opacity to 0 so that the layer will not be
376 // part of the visible frame.
377 child_->SetOpacity(0.f);
378 break;
379 case 2:
380 // For the 3rd commit, change opacity to 1 so that the layer will again
381 // be part of the visible frame.
382 child_->SetOpacity(1.f);
386 void AfterTest() override {}
388 FakeContentLayerClient client_;
389 scoped_refptr<Layer> child_;
390 scoped_refptr<FakePictureLayer> picture_;
393 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembership);
395 class LayerTreeHostPictureTestRSLLMembershipWithScale
396 : public LayerTreeHostPictureTest {
397 void SetupTree() override {
398 scoped_refptr<Layer> root = Layer::Create(layer_settings());
399 root->SetBounds(gfx::Size(100, 100));
401 pinch_ = Layer::Create(layer_settings());
402 pinch_->SetBounds(gfx::Size(500, 500));
403 pinch_->SetScrollClipLayerId(root->id());
404 pinch_->SetIsContainerForFixedPositionLayers(true);
405 root->AddChild(pinch_);
407 // Don't be solid color so the layer has tilings/tiles.
408 client_.set_fill_with_nonsolid_color(true);
409 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
410 picture_->SetBounds(gfx::Size(100, 100));
411 pinch_->AddChild(picture_);
413 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch_, pinch_);
414 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
415 layer_tree_host()->SetRootLayer(root);
416 LayerTreeHostPictureTest::SetupTree();
419 void InitializeSettings(LayerTreeSettings* settings) override {
420 settings->layer_transforms_should_scale_layer_contents = true;
423 void BeginTest() override {
424 frame_ = 0;
425 draws_in_frame_ = 0;
426 last_frame_drawn_ = -1;
427 ready_to_draw_ = false;
428 PostSetNeedsCommitToMainThread();
431 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
432 LayerImpl* root = impl->sync_tree()->root_layer();
433 LayerImpl* pinch = root->children()[0];
434 LayerImpl* gchild = pinch->children()[0];
435 FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
436 ready_to_draw_ = false;
438 switch (frame_) {
439 case 0:
440 // On 1st commit the pending layer has tilings.
441 ASSERT_EQ(1u, picture->tilings()->num_tilings());
442 EXPECT_EQ(1.f, picture->tilings()->tiling_at(0)->contents_scale());
443 break;
444 case 1:
445 // On 2nd commit, the pending layer is transparent, so has a stale
446 // value.
447 ASSERT_EQ(1u, picture->tilings()->num_tilings());
448 EXPECT_EQ(1.f, picture->tilings()->tiling_at(0)->contents_scale());
449 break;
450 case 2:
451 // On 3rd commit, the pending layer is visible again, so has tilings and
452 // is updated for the pinch.
453 ASSERT_EQ(1u, picture->tilings()->num_tilings());
454 EXPECT_EQ(2.f, picture->tilings()->tiling_at(0)->contents_scale());
458 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
459 LayerImpl* root = impl->active_tree()->root_layer();
460 LayerImpl* pinch = root->children()[0];
461 LayerImpl* gchild = pinch->children()[0];
462 FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
464 if (frame_ != last_frame_drawn_)
465 draws_in_frame_ = 0;
466 ++draws_in_frame_;
467 last_frame_drawn_ = frame_;
469 switch (frame_) {
470 case 0:
471 if (draws_in_frame_ == 1) {
472 // On 1st commit the layer has tilings.
473 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
474 EXPECT_EQ(1.f, picture->HighResTiling()->contents_scale());
476 // Pinch zoom in to change the scale on the active tree.
477 impl->PinchGestureBegin();
478 impl->PinchGestureUpdate(2.f, gfx::Point(1, 1));
479 impl->PinchGestureEnd();
480 } else if (picture->tilings()->num_tilings() == 1) {
481 // If the pinch gesture caused a commit we could get here with a
482 // pending tree.
483 EXPECT_FALSE(impl->pending_tree());
484 EXPECT_EQ(2.f, picture->HighResTiling()->contents_scale());
486 // Need to wait for ready to draw here so that the pinch is
487 // entirely complete, otherwise another draw might come in before
488 // the commit occurs.
489 if (ready_to_draw_) {
490 ++frame_;
491 MainThreadTaskRunner()->PostTask(
492 FROM_HERE,
493 base::Bind(
494 &LayerTreeHostPictureTestRSLLMembershipWithScale::NextStep,
495 base::Unretained(this)));
498 break;
499 case 1:
500 EXPECT_EQ(1, draws_in_frame_);
501 // On 2nd commit, this active layer is transparent, so does not update
502 // tilings. It has the high res scale=2 from the previous frame, and
503 // also a scale=1 copied from the pending layer's stale value during
504 // activation.
505 EXPECT_EQ(2u, picture->picture_layer_tiling_set()->num_tilings());
507 ++frame_;
508 MainThreadTaskRunner()->PostTask(
509 FROM_HERE,
510 base::Bind(
511 &LayerTreeHostPictureTestRSLLMembershipWithScale::NextStep,
512 base::Unretained(this)));
513 break;
514 case 2:
515 EXPECT_EQ(1, draws_in_frame_);
516 // On 3rd commit, the layer is visible again, so has tilings.
517 EXPECT_GT(picture->tilings()->num_tilings(), 0u);
518 EndTest();
522 void NextStep() {
523 switch (frame_) {
524 case 1:
525 // For the 2nd commit, change opacity to 0 so that the layer will not be
526 // part of the visible frame.
527 pinch_->SetOpacity(0.f);
528 break;
529 case 2:
530 // For the 3rd commit, change opacity to 1 so that the layer will again
531 // be part of the visible frame.
532 pinch_->SetOpacity(1.f);
533 break;
537 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
538 ready_to_draw_ = true;
539 if (frame_ == 0) {
540 // The ready to draw can race with a draw in which everything is
541 // actually ready. Therefore, just issue one more extra draw
542 // here to force notify->draw ordering.
543 impl->SetNeedsRedraw();
547 void AfterTest() override {}
549 FakeContentLayerClient client_;
550 scoped_refptr<Layer> pinch_;
551 scoped_refptr<FakePictureLayer> picture_;
552 int frame_;
553 int draws_in_frame_;
554 int last_frame_drawn_;
555 bool ready_to_draw_;
558 // Multi-thread only because in single thread you can't pinch zoom on the
559 // compositor thread.
560 MULTI_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembershipWithScale);
562 } // namespace
563 } // namespace cc