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 <stddef.h>
8 #include <stdint.h>
9
10 #include <algorithm>
11
12 #include "base/auto_reset.h"
13 #include "base/bind.h"
14 #include "base/callback_helpers.h"
15 #include "base/location.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/stl_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/synchronization/lock.h"
20 #include "base/threading/thread_task_runner_handle.h"
21 #include "base/time/time.h"
22 #include "build/build_config.h"
23 #include "cc/animation/animation_host.h"
24 #include "cc/animation/timing_function.h"
25 #include "cc/input/scroll_elasticity_helper.h"
26 #include "cc/layers/content_layer_client.h"
27 #include "cc/layers/heads_up_display_layer.h"
28 #include "cc/layers/layer_impl.h"
29 #include "cc/layers/painted_scrollbar_layer.h"
30 #include "cc/layers/picture_layer.h"
31 #include "cc/layers/solid_color_layer.h"
32 #include "cc/layers/video_layer.h"
33 #include "cc/metrics/events_metrics_manager.h"
34 #include "cc/metrics/ukm_smoothness_data.h"
35 #include "cc/paint/image_animation_count.h"
36 #include "cc/resources/ui_resource_manager.h"
37 #include "cc/test/fake_content_layer_client.h"
38 #include "cc/test/fake_layer_tree_host_client.h"
39 #include "cc/test/fake_paint_image_generator.h"
40 #include "cc/test/fake_painted_scrollbar_layer.h"
41 #include "cc/test/fake_picture_layer.h"
42 #include "cc/test/fake_picture_layer_impl.h"
43 #include "cc/test/fake_proxy.h"
44 #include "cc/test/fake_recording_source.h"
45 #include "cc/test/fake_scoped_ui_resource.h"
46 #include "cc/test/fake_video_frame_provider.h"
47 #include "cc/test/geometry_test_utils.h"
48 #include "cc/test/layer_test_common.h"
49 #include "cc/test/layer_tree_test.h"
50 #include "cc/test/push_properties_counting_layer.h"
51 #include "cc/test/push_properties_counting_layer_impl.h"
52 #include "cc/test/render_pass_test_utils.h"
53 #include "cc/test/skia_common.h"
54 #include "cc/test/test_layer_tree_frame_sink.h"
55 #include "cc/trees/clip_node.h"
56 #include "cc/trees/compositor_commit_data.h"
57 #include "cc/trees/effect_node.h"
58 #include "cc/trees/layer_tree_host_impl.h"
59 #include "cc/trees/layer_tree_impl.h"
60 #include "cc/trees/scroll_node.h"
61 #include "cc/trees/single_thread_proxy.h"
62 #include "cc/trees/swap_promise.h"
63 #include "cc/trees/swap_promise_manager.h"
64 #include "cc/trees/transform_node.h"
65 #include "components/ukm/test_ukm_recorder.h"
66 #include "components/viz/common/frame_sinks/begin_frame_args.h"
67 #include "components/viz/common/frame_sinks/copy_output_request.h"
68 #include "components/viz/common/frame_sinks/copy_output_result.h"
69 #include "components/viz/common/quads/compositor_render_pass_draw_quad.h"
70 #include "components/viz/common/quads/draw_quad.h"
71 #include "components/viz/common/quads/tile_draw_quad.h"
72 #include "components/viz/service/display/output_surface.h"
73 #include "components/viz/test/begin_frame_args_test.h"
74 #include "components/viz/test/fake_output_surface.h"
75 #include "components/viz/test/test_gles2_interface.h"
76 #include "gpu/GLES2/gl2extchromium.h"
77 #include "testing/gmock/include/gmock/gmock.h"
78 #include "third_party/khronos/GLES2/gl2.h"
79 #include "third_party/khronos/GLES2/gl2ext.h"
80 #include "third_party/skia/include/core/SkPicture.h"
81 #include "third_party/skia/include/gpu/GrDirectContext.h"
82 #include "ui/gfx/geometry/point_conversions.h"
83 #include "ui/gfx/geometry/size_conversions.h"
84 #include "ui/gfx/geometry/vector2d_conversions.h"
85
86 #define EXPECT_SCOPED(statements) \
87 { \
88 SCOPED_TRACE(""); \
89 statements; \
90 }
91
92 using testing::_;
93 using testing::AnyNumber;
94 using testing::AtLeast;
95 using testing::Mock;
96
97 namespace cc {
98 namespace {
99 const char kUserInteraction[] = "Compositor.UserInteraction";
100 const char kCheckerboardArea[] = "CheckerboardedContentArea";
101 const char kCheckerboardAreaRatio[] = "CheckerboardedContentAreaRatio";
102 const char kMissingTiles[] = "NumMissingTiles";
103
LayerSubtreeHasCopyRequest(Layer * layer)104 bool LayerSubtreeHasCopyRequest(Layer* layer) {
105 LayerTreeHost* host = layer->layer_tree_host();
106 int index = layer->effect_tree_index();
107 auto* node = host->property_trees()->effect_tree.Node(index);
108 return node->subtree_has_copy_request;
109 }
110
111 using LayerTreeHostTest = LayerTreeTest;
112
113 class LayerTreeHostTestHasImplThreadTest : public LayerTreeHostTest {
114 public:
LayerTreeHostTestHasImplThreadTest()115 LayerTreeHostTestHasImplThreadTest() : single_threaded_(false) {}
116
RunTest(CompositorMode mode)117 void RunTest(CompositorMode mode) override {
118 single_threaded_ = mode == CompositorMode::SINGLE_THREADED;
119 LayerTreeHostTest::RunTest(mode);
120 }
121
BeginTest()122 void BeginTest() override {
123 EXPECT_EQ(single_threaded_, !HasImplThread());
124 EndTest();
125 }
126
AfterTest()127 void AfterTest() override { EXPECT_EQ(single_threaded_, !HasImplThread()); }
128
129 private:
130 bool single_threaded_;
131 };
132
133 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHasImplThreadTest);
134
135 class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest {
136 protected:
BeginTest()137 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
138
UpdateLayerTreeHost()139 void UpdateLayerTreeHost() override {
140 // This shouldn't cause a second commit to happen.
141 layer_tree_host()->SetNeedsCommit();
142 }
143
DidCommit()144 void DidCommit() override {
145 EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber());
146 EndTest();
147 }
148 };
149
150 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommitInsideLayout);
151
152 class LayerTreeHostTestFrameOrdering : public LayerTreeHostTest {
153 protected:
154 enum MainOrder : int {
155 MAIN_START = 1,
156 MAIN_LAYOUT,
157 MAIN_COMMIT_COMPLETE,
158 MAIN_DID_BEGIN_FRAME,
159 MAIN_END,
160 };
161
162 enum ImplOrder : int {
163 IMPL_START = 1,
164 IMPL_READY_TO_COMMIT,
165 IMPL_COMMIT,
166 IMPL_COMMIT_COMPLETE,
167 IMPL_ACTIVATE,
168 IMPL_DRAW,
169 IMPL_END,
170 };
171
172 template <typename T>
CheckStep(T next,T * var)173 bool CheckStep(T next, T* var) {
174 int expected = next - 1;
175 EXPECT_EQ(expected, *var);
176 bool correct = expected == *var;
177 *var = next;
178 return correct;
179 }
180
BeginTest()181 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
182
UpdateLayerTreeHost()183 void UpdateLayerTreeHost() override {
184 EXPECT_TRUE(CheckStep(MAIN_LAYOUT, &main_));
185 }
186
DidCommit()187 void DidCommit() override {
188 EXPECT_TRUE(CheckStep(MAIN_COMMIT_COMPLETE, &main_));
189 }
190
DidBeginMainFrame()191 void DidBeginMainFrame() override {
192 EXPECT_TRUE(CheckStep(MAIN_DID_BEGIN_FRAME, &main_));
193 }
194
ReadyToCommitOnThread(LayerTreeHostImpl * impl)195 void ReadyToCommitOnThread(LayerTreeHostImpl* impl) override {
196 EXPECT_TRUE(CheckStep(IMPL_READY_TO_COMMIT, &impl_));
197 }
198
BeginCommitOnThread(LayerTreeHostImpl * impl)199 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
200 EXPECT_TRUE(CheckStep(IMPL_COMMIT, &impl_));
201 }
202
CommitCompleteOnThread(LayerTreeHostImpl * impl)203 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
204 EXPECT_TRUE(CheckStep(IMPL_COMMIT_COMPLETE, &impl_));
205 }
206
WillActivateTreeOnThread(LayerTreeHostImpl * impl)207 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
208 EXPECT_TRUE(CheckStep(IMPL_ACTIVATE, &impl_));
209 }
210
DrawLayersOnThread(LayerTreeHostImpl * impl)211 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
212 EXPECT_TRUE(CheckStep(IMPL_DRAW, &impl_));
213 EndTest();
214 }
215
AfterTest()216 void AfterTest() override {
217 EXPECT_TRUE(CheckStep(MAIN_END, &main_));
218 EXPECT_TRUE(CheckStep(IMPL_END, &impl_));
219 }
220
221 MainOrder main_ = MAIN_START;
222 ImplOrder impl_ = IMPL_START;
223 };
224
225 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameOrdering);
226
227 class LayerTreeHostTestRequestedMainFrame : public LayerTreeHostTest {
228 public:
BeginTest()229 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
230
WillBeginMainFrame()231 void WillBeginMainFrame() override {
232 // Post NextStep() so it happens after the MainFrame completes.
233 MainThreadTaskRunner()->PostTask(
234 FROM_HERE,
235 base::BindOnce(&LayerTreeHostTestRequestedMainFrame::NextStep,
236 base::Unretained(this)));
237 }
238
NextStep()239 void NextStep() {
240 // The MainFrame request is cleared once a MainFrame happens.
241 EXPECT_FALSE(layer_tree_host()->RequestedMainFramePendingForTesting());
242 switch (layer_tree_host()->SourceFrameNumber()) {
243 case 0:
244 ADD_FAILURE()
245 << "Case 0 is the initial commit used to send the test here";
246 FALLTHROUGH;
247 case 1:
248 layer_tree_host()->SetNeedsAnimate();
249 break;
250 case 2:
251 layer_tree_host()->SetNeedsUpdateLayers();
252 break;
253 case 3:
254 layer_tree_host()->SetNeedsCommit();
255 break;
256 case 4:
257 EndTest();
258 return;
259 }
260 // SetNeeds{Animate,UpdateLayers,Commit}() will mean a MainFrame is pending.
261 EXPECT_TRUE(layer_tree_host()->RequestedMainFramePendingForTesting());
262 }
263 };
264
265 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestedMainFrame);
266
267 class LayerTreeHostTestSchedulingClient : public LayerTreeHostTest {
268 public:
BeginTest()269 void BeginTest() override {
270 PostSetNeedsCommitToMainThread();
271 EXPECT_EQ(0, main_frame_scheduled_count_);
272 EXPECT_EQ(0, main_frame_run_count_);
273 }
274
DidScheduleBeginMainFrame()275 void DidScheduleBeginMainFrame() override { main_frame_scheduled_count_++; }
DidRunBeginMainFrame()276 void DidRunBeginMainFrame() override { main_frame_run_count_++; }
277
DidBeginMainFrame()278 void DidBeginMainFrame() override {
279 EXPECT_EQ(1, main_frame_scheduled_count_);
280 EXPECT_EQ(1, main_frame_run_count_);
281 EndTest();
282 }
283
AfterTest()284 void AfterTest() override {}
285
286 private:
287 int main_frame_scheduled_count_ = 0;
288 int main_frame_run_count_ = 0;
289 };
290
291 MULTI_THREAD_TEST_F(LayerTreeHostTestSchedulingClient);
292
293 class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest {
294 protected:
BeginTest()295 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
296
UpdateLayerTreeHost()297 void UpdateLayerTreeHost() override {
298 // This shouldn't cause a second commit to happen.
299 layer_tree_host()->SetNeedsUpdateLayers();
300 }
301
DidCommit()302 void DidCommit() override {
303 EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber());
304 EndTest();
305 }
306 };
307
308 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsUpdateInsideLayout);
309
310 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
311 // when no raster tasks get scheduled.
312 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
313 public:
LayerTreeHostTestReadyToActivateEmpty()314 LayerTreeHostTestReadyToActivateEmpty()
315 : did_notify_ready_to_activate_(false),
316 all_tiles_required_for_activation_are_ready_to_draw_(false),
317 required_for_activation_count_(0) {}
318
BeginTest()319 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
320
CommitCompleteOnThread(LayerTreeHostImpl * impl)321 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
322 const std::vector<PictureLayerImpl*>& layers =
323 impl->sync_tree()->picture_layers();
324 required_for_activation_count_ = 0;
325 for (auto* layer : layers) {
326 FakePictureLayerImpl* fake_layer =
327 static_cast<FakePictureLayerImpl*>(layer);
328 required_for_activation_count_ +=
329 fake_layer->CountTilesRequiredForActivation();
330 }
331 }
332
NotifyReadyToActivateOnThread(LayerTreeHostImpl * impl)333 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
334 did_notify_ready_to_activate_ = true;
335 all_tiles_required_for_activation_are_ready_to_draw_ =
336 impl->tile_manager()->IsReadyToActivate();
337 EndTest();
338 }
339
AfterTest()340 void AfterTest() override {
341 EXPECT_TRUE(did_notify_ready_to_activate_);
342 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
343 EXPECT_EQ(size_t(0), required_for_activation_count_);
344 }
345
346 protected:
347 bool did_notify_ready_to_activate_;
348 bool all_tiles_required_for_activation_are_ready_to_draw_;
349 size_t required_for_activation_count_;
350 };
351
352 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
353
354 // Test if the LTHI receives ReadyToActivate notifications from the TileManager
355 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
356 class LayerTreeHostTestReadyToActivateNonEmpty
357 : public LayerTreeHostTestReadyToActivateEmpty {
358 public:
SetupTree()359 void SetupTree() override {
360 client_.set_fill_with_nonsolid_color(true);
361 scoped_refptr<FakePictureLayer> root_layer =
362 FakePictureLayer::Create(&client_);
363 root_layer->SetBounds(gfx::Size(1024, 1024));
364 root_layer->SetIsDrawable(true);
365
366 layer_tree_host()->SetRootLayer(root_layer);
367 LayerTreeHostTest::SetupTree();
368 client_.set_bounds(root_layer->bounds());
369 }
370
AfterTest()371 void AfterTest() override {
372 EXPECT_TRUE(did_notify_ready_to_activate_);
373 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_);
374 EXPECT_LE(size_t(1), required_for_activation_count_);
375 }
376
377 private:
378 FakeContentLayerClient client_;
379 };
380
381 // No single thread test because the commit goes directly to the active tree in
382 // single thread mode, so notify ready to activate is skipped.
383 // Flaky: https://crbug.com/947673
384 // MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
385
386 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
387 // no raster tasks get scheduled.
388 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
389 public:
LayerTreeHostTestReadyToDrawEmpty()390 LayerTreeHostTestReadyToDrawEmpty()
391 : did_notify_ready_to_draw_(false),
392 all_tiles_required_for_draw_are_ready_to_draw_(false),
393 required_for_draw_count_(0) {}
394
BeginTest()395 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
396
NotifyReadyToDrawOnThread(LayerTreeHostImpl * impl)397 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override {
398 did_notify_ready_to_draw_ = true;
399 const std::vector<PictureLayerImpl*>& layers =
400 impl->active_tree()->picture_layers();
401 all_tiles_required_for_draw_are_ready_to_draw_ =
402 impl->tile_manager()->IsReadyToDraw();
403 for (auto* layer : layers) {
404 FakePictureLayerImpl* fake_layer =
405 static_cast<FakePictureLayerImpl*>(layer);
406 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw();
407 }
408
409 EndTest();
410 }
411
AfterTest()412 void AfterTest() override {
413 EXPECT_TRUE(did_notify_ready_to_draw_);
414 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
415 EXPECT_EQ(size_t(0), required_for_draw_count_);
416 }
417
418 protected:
419 bool did_notify_ready_to_draw_;
420 bool all_tiles_required_for_draw_are_ready_to_draw_;
421 size_t required_for_draw_count_;
422 };
423
424 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
425
426 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when
427 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
428 class LayerTreeHostTestReadyToDrawNonEmpty
429 : public LayerTreeHostTestReadyToDrawEmpty {
430 public:
SetupTree()431 void SetupTree() override {
432 client_.set_fill_with_nonsolid_color(true);
433 scoped_refptr<FakePictureLayer> root_layer =
434 FakePictureLayer::Create(&client_);
435 root_layer->SetBounds(gfx::Size(1024, 1024));
436 root_layer->SetIsDrawable(true);
437
438 layer_tree_host()->SetRootLayer(root_layer);
439 LayerTreeHostTest::SetupTree();
440 client_.set_bounds(root_layer->bounds());
441 }
442
AfterTest()443 void AfterTest() override {
444 EXPECT_TRUE(did_notify_ready_to_draw_);
445 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_);
446 EXPECT_LE(size_t(1), required_for_draw_count_);
447 }
448
449 private:
450 FakeContentLayerClient client_;
451 };
452
453 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
454 // single threaded mode.
455 SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
456
457 // This tests if we get the READY_TO_DRAW signal and draw if we become invisible
458 // and then become visible again.
459 class LayerTreeHostTestReadyToDrawVisibility : public LayerTreeHostTest {
460 public:
LayerTreeHostTestReadyToDrawVisibility()461 LayerTreeHostTestReadyToDrawVisibility()
462 : LayerTreeHostTest(),
463 toggled_visibility_(false),
464 did_notify_ready_to_draw_(false),
465 did_draw_(false) {}
466
BeginTest()467 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
468
SetupTree()469 void SetupTree() override {
470 client_.set_fill_with_nonsolid_color(true);
471 scoped_refptr<FakePictureLayer> root_layer =
472 FakePictureLayer::Create(&client_);
473 root_layer->SetBounds(gfx::Size(1024, 1024));
474 client_.set_bounds(root_layer->bounds());
475 root_layer->SetIsDrawable(true);
476
477 layer_tree_host()->SetRootLayer(root_layer);
478 LayerTreeHostTest::SetupTree();
479 }
480
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)481 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
482 if (!toggled_visibility_) {
483 {
484 DebugScopedSetMainThread main(task_runner_provider());
485 layer_tree_host()->SetVisible(false);
486 }
487 toggled_visibility_ = true;
488 EXPECT_FALSE(host_impl->visible());
489 }
490 }
491
NotifyReadyToDrawOnThread(LayerTreeHostImpl * host_impl)492 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
493 // Sometimes the worker thread posts NotifyReadyToDraw in the extremely
494 // short duration of time between PrepareTiles and SetVisible(false) so we
495 // might get two NotifyReadyToDraw signals for this test.
496 did_notify_ready_to_draw_ = true;
497 }
498
DrawLayersOnThread(LayerTreeHostImpl * host_impl)499 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
500 EXPECT_FALSE(did_draw_);
501 did_draw_ = true;
502 EndTest();
503 }
504
DidFinishImplFrameOnThread(LayerTreeHostImpl * host_impl)505 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
506 if (!host_impl->visible()) {
507 {
508 DebugScopedSetMainThread main(task_runner_provider());
509 layer_tree_host()->SetVisible(true);
510 }
511 EXPECT_TRUE(host_impl->visible());
512 }
513 }
514
AfterTest()515 void AfterTest() override {
516 EXPECT_TRUE(did_notify_ready_to_draw_);
517 EXPECT_TRUE(did_draw_);
518 }
519
520 private:
521 FakeContentLayerClient client_;
522 bool toggled_visibility_;
523 bool did_notify_ready_to_draw_;
524 bool did_draw_;
525 };
526
527 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
528 // single threaded mode.
529 SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawVisibility);
530
531 class LayerTreeHostContextCacheTest : public LayerTreeHostTest {
532 public:
CreateLayerTreeFrameSink(const viz::RendererSettings & renderer_settings,double refresh_rate,scoped_refptr<viz::ContextProvider> compositor_context_provider,scoped_refptr<viz::RasterContextProvider> worker_context_provider)533 std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
534 const viz::RendererSettings& renderer_settings,
535 double refresh_rate,
536 scoped_refptr<viz::ContextProvider> compositor_context_provider,
537 scoped_refptr<viz::RasterContextProvider> worker_context_provider)
538 override {
539 // Create the main viz::ContextProvider with a MockContextSupport.
540 auto main_support = std::make_unique<MockContextSupport>();
541 mock_main_context_support_ = main_support.get();
542 auto test_main_context_provider =
543 viz::TestContextProvider::Create(std::move(main_support));
544
545 // Create the main viz::ContextProvider with a MockContextSupport.
546 auto worker_support = std::make_unique<MockContextSupport>();
547 mock_worker_context_support_ = worker_support.get();
548 auto test_worker_context_provider =
549 viz::TestContextProvider::CreateWorker(std::move(worker_support));
550
551 // At init, visibility is set to true, so SetAggressivelyFreeResources will
552 // be disabled.
553 EXPECT_CALL(*mock_main_context_support_,
554 SetAggressivelyFreeResources(false));
555 EXPECT_CALL(*mock_worker_context_support_,
556 SetAggressivelyFreeResources(false));
557
558 return LayerTreeHostTest::CreateLayerTreeFrameSink(
559 renderer_settings, refresh_rate, std::move(test_main_context_provider),
560 std::move(test_worker_context_provider));
561 }
562
BeginTest()563 void BeginTest() override {}
564
565 protected:
566 class MockContextSupport : public viz::TestContextSupport {
567 public:
568 MockContextSupport() = default;
569 MOCK_METHOD1(SetAggressivelyFreeResources,
570 void(bool aggressively_free_resources));
571 };
572
573 MockContextSupport* mock_main_context_support_;
574 MockContextSupport* mock_worker_context_support_;
575 };
576
577 // Test if the LTH successfully frees resources on the main/worker
578 // ContextSupport when visibility is set to false.
579 class LayerTreeHostFreesContextResourcesOnInvisible
580 : public LayerTreeHostContextCacheTest {
581 public:
InitializedRendererOnThread(LayerTreeHostImpl * host_impl,bool success)582 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
583 bool success) override {
584 // Ensure that our initialization expectations have completed.
585 Mock::VerifyAndClearExpectations(mock_main_context_support_);
586 Mock::VerifyAndClearExpectations(mock_worker_context_support_);
587
588 // Update visibility and make sure resources are freed.
589 EXPECT_CALL(*mock_main_context_support_,
590 SetAggressivelyFreeResources(true));
591 EXPECT_CALL(*mock_worker_context_support_,
592 SetAggressivelyFreeResources(true))
593 .WillOnce(testing::Invoke([this](bool is_visible) { EndTest(); }));
594 PostSetVisibleToMainThread(false);
595 }
596 };
597
598 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostFreesContextResourcesOnInvisible);
599
600 // Test if the LTH successfully frees worker context resources when the hard
601 // memory limit is set to zero.
602 class LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimit
603 : public LayerTreeHostContextCacheTest {
604 public:
InitializedRendererOnThread(LayerTreeHostImpl * host_impl,bool success)605 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
606 bool success) override {
607 // Ensure that our initialization expectations have completed.
608 Mock::VerifyAndClearExpectations(mock_worker_context_support_);
609
610 // Worker context support should start freeing resources when hard memory
611 // limit is zeroed.
612 EXPECT_CALL(*mock_worker_context_support_,
613 SetAggressivelyFreeResources(true))
614 .WillOnce(testing::Invoke([this](bool is_visible) {
615 // Main context is unchanged. It will start freeing on destruction.
616 EXPECT_CALL(*mock_main_context_support_,
617 SetAggressivelyFreeResources(true));
618 EndTest();
619 }));
620 ManagedMemoryPolicy zero_policy(
621 0, gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING, 0);
622 host_impl->SetMemoryPolicy(zero_policy);
623 }
624 };
625
626 SINGLE_AND_MULTI_THREAD_TEST_F(
627 LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimit);
628
629 // Test if the LTH successfully frees worker context resources when hard memory
630 // limit is set to zero while using a synchronous compositor (Android WebView).
631 class LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimitSynchronous
632 : public LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimit {
633 public:
InitializeSettings(LayerTreeSettings * settings)634 void InitializeSettings(LayerTreeSettings* settings) override {
635 LayerTreeHostContextCacheTest::InitializeSettings(settings);
636 settings->using_synchronous_renderer_compositor = true;
637 }
638 };
639
640 // Android Webview only runs in multi-threaded compositing mode.
641 MULTI_THREAD_TEST_F(
642 LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimitSynchronous);
643
644 // Test if the LTH successfully frees main and worker resources when the
645 // OutputSurface is destroyed.
646 class LayerTreeHostFreeContextResourcesOnDestroy
647 : public LayerTreeHostContextCacheTest {
648 public:
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)649 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
650 const viz::BeginFrameArgs& args) override {
651 if (!first_will_begin_impl_frame_)
652 return;
653
654 first_will_begin_impl_frame_ = false;
655
656 // Ensure that our initialization expectations have completed.
657 Mock::VerifyAndClearExpectations(mock_main_context_support_);
658 Mock::VerifyAndClearExpectations(mock_worker_context_support_);
659
660 // We leave the LTHI visible, so it start freeing resources on destruction.
661 EXPECT_CALL(*mock_worker_context_support_,
662 SetAggressivelyFreeResources(true));
663 EXPECT_CALL(*mock_main_context_support_,
664 SetAggressivelyFreeResources(true));
665 EndTest();
666 }
667
668 private:
669 bool first_will_begin_impl_frame_ = true;
670 };
671
672 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostFreeContextResourcesOnDestroy);
673
674 // Test if the LTH successfully frees and stops freeing context resources
675 // when the LayerTreeFrameSink is lost and recreated.
676 class LayerTreeHostCacheBehaviorOnLayerTreeFrameSinkRecreated
677 : public LayerTreeHostContextCacheTest {
678 public:
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)679 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
680 const viz::BeginFrameArgs& args) override {
681 // This code is run once, to trigger recreation of our LayerTreeFrameSink.
682 if (test_state_ != TestState::INIT)
683 return;
684
685 // Ensure that our initialization expectations have completed.
686 Mock::VerifyAndClearExpectations(mock_main_context_support_);
687 Mock::VerifyAndClearExpectations(mock_worker_context_support_);
688
689 // LayerTreeFrameSink lost expectations.
690 EXPECT_CALL(*mock_worker_context_support_,
691 SetAggressivelyFreeResources(true));
692 EXPECT_CALL(*mock_main_context_support_,
693 SetAggressivelyFreeResources(true));
694 host_impl->DidLoseLayerTreeFrameSink();
695 test_state_ = TestState::RECREATED;
696 }
697
InitializedRendererOnThread(LayerTreeHostImpl * host_impl,bool success)698 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
699 bool success) override {
700 // This is run after we have recreated our LayerTreeFrameSink.
701 if (test_state_ != TestState::RECREATED)
702 return;
703
704 // Ensure that our expectations have completed.
705 Mock::VerifyAndClearExpectations(mock_main_context_support_);
706 Mock::VerifyAndClearExpectations(mock_worker_context_support_);
707
708 // Destruction exptectations.
709 EXPECT_CALL(*mock_worker_context_support_,
710 SetAggressivelyFreeResources(true));
711 EXPECT_CALL(*mock_main_context_support_,
712 SetAggressivelyFreeResources(true));
713 EndTest();
714 test_state_ = TestState::DONE;
715 }
716
717 private:
718 enum class TestState { INIT, RECREATED, DONE };
719 TestState test_state_ = TestState::INIT;
720 };
721
722 SINGLE_AND_MULTI_THREAD_TEST_F(
723 LayerTreeHostCacheBehaviorOnLayerTreeFrameSinkRecreated);
724
725 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
726 // draw with frame 0.
727 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
728 public:
LayerTreeHostTestSetNeedsCommit1()729 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
730
BeginTest()731 void BeginTest() override {
732 PostSetNeedsCommitToMainThread();
733 PostSetNeedsCommitToMainThread();
734 }
735
DrawLayersOnThread(LayerTreeHostImpl * impl)736 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
737 num_draws_++;
738 if (!impl->active_tree()->source_frame_number())
739 EndTest();
740 }
741
CommitCompleteOnThread(LayerTreeHostImpl * impl)742 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
743 num_commits_++;
744 }
745
AfterTest()746 void AfterTest() override {
747 EXPECT_LE(1, num_commits_);
748 EXPECT_LE(1, num_draws_);
749 }
750
751 private:
752 int num_commits_;
753 int num_draws_;
754 };
755
756 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
757
758 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
759 // first committed frame draws should lead to another commit.
760 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
761 public:
LayerTreeHostTestSetNeedsCommit2()762 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
763
BeginTest()764 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
765
DrawLayersOnThread(LayerTreeHostImpl * impl)766 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; }
767
CommitCompleteOnThread(LayerTreeHostImpl * impl)768 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
769 ++num_commits_;
770 switch (num_commits_) {
771 case 1:
772 PostSetNeedsCommitToMainThread();
773 break;
774 case 2:
775 EndTest();
776 break;
777 default:
778 NOTREACHED();
779 }
780 }
781
AfterTest()782 void AfterTest() override {
783 EXPECT_EQ(2, num_commits_);
784 EXPECT_LE(1, num_draws_);
785 }
786
787 private:
788 int num_commits_;
789 int num_draws_;
790 };
791
792 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
793
794 // Verify that we pass property values in PushPropertiesTo.
795 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
796 protected:
SetupTree()797 void SetupTree() override {
798 SetInitialRootBounds(gfx::Size(10, 10));
799 LayerTreeHostTest::SetupTree();
800 }
801
802 enum Properties {
803 STARTUP,
804 BOUNDS,
805 HIDE_LAYER_AND_SUBTREE,
806 DRAWS_CONTENT,
807 DONE,
808 };
809
BeginTest()810 void BeginTest() override {
811 index_ = STARTUP;
812 PostSetNeedsCommitToMainThread();
813 }
814
DrawLayersOnThread(LayerTreeHostImpl * impl)815 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
816 VerifyAfterValues(impl->active_tree()->root_layer());
817 }
818
DidCommitAndDrawFrame()819 void DidCommitAndDrawFrame() override {
820 SetBeforeValues(layer_tree_host()->root_layer());
821 VerifyBeforeValues(layer_tree_host()->root_layer());
822
823 ++index_;
824 if (index_ == DONE) {
825 EndTest();
826 return;
827 }
828
829 SetAfterValues(layer_tree_host()->root_layer());
830 }
831
VerifyBeforeValues(Layer * layer)832 void VerifyBeforeValues(Layer* layer) {
833 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
834 EXPECT_FALSE(layer->hide_layer_and_subtree());
835 EXPECT_FALSE(layer->DrawsContent());
836 }
837
SetBeforeValues(Layer * layer)838 void SetBeforeValues(Layer* layer) {
839 layer->SetBounds(gfx::Size(10, 10));
840 layer->SetHideLayerAndSubtree(false);
841 layer->SetIsDrawable(false);
842 }
843
VerifyAfterValues(LayerImpl * layer)844 void VerifyAfterValues(LayerImpl* layer) {
845 EffectTree& tree = layer->layer_tree_impl()->property_trees()->effect_tree;
846 EffectNode* node = tree.Node(layer->effect_tree_index());
847 switch (static_cast<Properties>(index_)) {
848 case STARTUP:
849 case DONE:
850 break;
851 case BOUNDS:
852 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
853 break;
854 case HIDE_LAYER_AND_SUBTREE:
855 EXPECT_EQ(tree.EffectiveOpacity(node), 0.f);
856 break;
857 case DRAWS_CONTENT:
858 EXPECT_TRUE(layer->DrawsContent());
859 break;
860 }
861 }
862
SetAfterValues(Layer * layer)863 void SetAfterValues(Layer* layer) {
864 switch (static_cast<Properties>(index_)) {
865 case STARTUP:
866 case DONE:
867 break;
868 case BOUNDS:
869 layer->SetBounds(gfx::Size(20, 20));
870 break;
871 case HIDE_LAYER_AND_SUBTREE:
872 layer->SetHideLayerAndSubtree(true);
873 break;
874 case DRAWS_CONTENT:
875 layer->SetIsDrawable(true);
876 break;
877 }
878 }
879
880 int index_;
881 };
882
883 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
884
885 // Verify that invisible render passes are excluded in CompositorFrame.
886 class LayerTreeHostTestInvisibleLayersSkipRenderPass
887 : public LayerTreeHostTest {
888 protected:
889 enum Step {
890 kAllInvisible,
891 kOneVisible,
892 kAllVisible,
893 kAllInvisibleAgain,
894 kDone,
895 };
896
SetupTree()897 void SetupTree() override {
898 SetInitialRootBounds(gfx::Size(10, 10));
899 LayerTreeHostTest::SetupTree();
900 auto* root = layer_tree_host()->root_layer();
901 child1_ = CreateChild(root);
902 child2_ = CreateChild(root);
903 }
904
CreateChild(scoped_refptr<Layer> root)905 scoped_refptr<Layer> CreateChild(scoped_refptr<Layer> root) {
906 auto child = Layer::Create();
907 // Initially hidden.
908 child->SetHideLayerAndSubtree(true);
909 AddBackgroundBlurFilter(child.get());
910 root->AddChild(child.get());
911 return child;
912 }
913
AddBackgroundBlurFilter(Layer * layer)914 void AddBackgroundBlurFilter(Layer* layer) {
915 FilterOperations filters;
916 filters.Append(FilterOperation::CreateBlurFilter(
917 30, SkBlurImageFilter::kClamp_TileMode));
918 layer->SetBackdropFilters(filters);
919 }
920
BeginTest()921 void BeginTest() override {
922 index_ = kAllInvisible;
923 PostSetNeedsCommitToMainThread();
924 }
925
DidCommitAndDrawFrame()926 void DidCommitAndDrawFrame() override {
927 ++index_;
928 switch (index_) {
929 case kAllInvisible:
930 NOTREACHED();
931 break;
932 case kOneVisible:
933 child1_->SetHideLayerAndSubtree(false);
934 break;
935 case kAllVisible:
936 child2_->SetHideLayerAndSubtree(false);
937 break;
938 case kAllInvisibleAgain:
939 child1_->SetHideLayerAndSubtree(true);
940 child2_->SetHideLayerAndSubtree(true);
941 break;
942 case kDone:
943 EndTest();
944 break;
945 }
946 }
947
DisplayReceivedCompositorFrameOnThread(const viz::CompositorFrame & frame)948 void DisplayReceivedCompositorFrameOnThread(
949 const viz::CompositorFrame& frame) override {
950 size_t num_render_passes = frame.render_pass_list.size();
951 switch (index_) {
952 case kAllInvisible:
953 // There is only a root render pass.
954 EXPECT_EQ(1u, num_render_passes);
955 break;
956 case kOneVisible:
957 EXPECT_EQ(2u, num_render_passes);
958 break;
959 case kAllVisible:
960 EXPECT_EQ(3u, num_render_passes);
961 break;
962 case kAllInvisibleAgain:
963 EXPECT_EQ(1u, num_render_passes);
964 break;
965 case kDone:
966 EndTest();
967 break;
968 }
969 }
970
971 int index_ = kAllInvisible;
972 scoped_refptr<Layer> child1_;
973 scoped_refptr<Layer> child2_;
974 };
975
976 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestInvisibleLayersSkipRenderPass);
977
978 class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest {
979 protected:
SetupTree()980 void SetupTree() override {
981 root_ = Layer::Create();
982 child_ = Layer::Create();
983 root_->AddChild(child_);
984 layer_tree_host()->SetRootLayer(root_);
985 LayerTreeHostTest::SetupTree();
986 }
987
BeginTest()988 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
989
DidCommit()990 void DidCommit() override {
991 switch (layer_tree_host()->SourceFrameNumber()) {
992 case 1:
993 // child_ should create transform, effect node.
994 child_->SetForceRenderSurfaceForTesting(true);
995 break;
996 case 2:
997 // child_ should create a scroll node.
998 child_->SetScrollable(gfx::Size(1, 1));
999 break;
1000 case 3:
1001 // child_ should create a clip node.
1002 child_->SetMasksToBounds(true);
1003 break;
1004 case 4:
1005 // child_ should only create the scroll-related nodes.
1006 child_->SetMasksToBounds(false);
1007 child_->SetForceRenderSurfaceForTesting(false);
1008 // Should have no effect because empty bounds do not prevent scrolling.
1009 child_->SetScrollable(gfx::Size(0, 0));
1010 }
1011 }
1012
CommitCompleteOnThread(LayerTreeHostImpl * impl)1013 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1014 PropertyTrees* property_trees = impl->sync_tree()->property_trees();
1015 const TransformNode* root_transform_node =
1016 property_trees->transform_tree.Node(root_->transform_tree_index());
1017 const TransformNode* child_transform_node =
1018 property_trees->transform_tree.Node(child_->transform_tree_index());
1019 const EffectNode* root_effect_node =
1020 property_trees->effect_tree.Node(root_->effect_tree_index());
1021 const EffectNode* child_effect_node =
1022 property_trees->effect_tree.Node(child_->effect_tree_index());
1023 const ClipNode* root_clip_node =
1024 property_trees->clip_tree.Node(root_->clip_tree_index());
1025 const ClipNode* child_clip_node =
1026 property_trees->clip_tree.Node(child_->clip_tree_index());
1027 const ScrollNode* root_scroll_node =
1028 property_trees->scroll_tree.Node(root_->scroll_tree_index());
1029 const ScrollNode* child_scroll_node =
1030 property_trees->scroll_tree.Node(child_->scroll_tree_index());
1031 switch (impl->sync_tree()->source_frame_number()) {
1032 case 0:
1033 // root_ should create transform, scroll and effect tree nodes but not
1034 // a clip node.
1035 EXPECT_NE(nullptr, root_transform_node);
1036 EXPECT_NE(nullptr, root_effect_node);
1037 EXPECT_NE(nullptr, root_scroll_node);
1038 EXPECT_NE(nullptr, root_clip_node);
1039 EXPECT_EQ(root_transform_node, child_transform_node);
1040 EXPECT_EQ(child_effect_node, root_effect_node);
1041 EXPECT_EQ(root_clip_node, child_clip_node);
1042 EXPECT_EQ(root_scroll_node, child_scroll_node);
1043
1044 break;
1045 case 1:
1046 // child_ should create a transfrom, effect nodes but not a scroll, clip
1047 // node.
1048 EXPECT_NE(root_transform_node, child_transform_node);
1049 EXPECT_NE(child_effect_node, root_effect_node);
1050 EXPECT_EQ(root_clip_node, child_clip_node);
1051 EXPECT_EQ(root_scroll_node, child_scroll_node);
1052
1053 break;
1054 case 2:
1055 // child_ should create a scroll node.
1056 EXPECT_NE(root_scroll_node, child_scroll_node);
1057 break;
1058 case 3:
1059 // child_ should create a clip node.
1060 EXPECT_NE(root_clip_node, child_clip_node);
1061 break;
1062 case 4:
1063 // child_ should only create the scroll-related nodes.
1064 EXPECT_EQ(child_transform_node->id, child_scroll_node->transform_id);
1065 EXPECT_EQ(child_effect_node, root_effect_node);
1066 EXPECT_EQ(root_clip_node, child_clip_node);
1067 EXPECT_NE(root_scroll_node, child_scroll_node);
1068 EndTest();
1069 break;
1070 }
1071 }
1072
1073 private:
1074 scoped_refptr<Layer> root_;
1075 scoped_refptr<Layer> child_;
1076 };
1077
1078 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushNodeOwnerToNodeIdMap);
1079
1080 class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest {
1081 protected:
SetupTree()1082 void SetupTree() override {
1083 root_ = Layer::Create();
1084 child_ = Layer::Create();
1085 root_->AddChild(child_);
1086 layer_tree_host()->SetRootLayer(root_);
1087 LayerTreeHostTest::SetupTree();
1088 }
1089
BeginTest()1090 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1091
DidCommit()1092 void DidCommit() override {
1093 switch (layer_tree_host()->SourceFrameNumber()) {
1094 case 1:
1095 child_->SetForceRenderSurfaceForTesting(true);
1096 // Add a non-fast region to ensure a scroll node is created.
1097 child_->SetNonFastScrollableRegion(Region(gfx::Rect(50, 50, 50, 50)));
1098 break;
1099 case 2:
1100 child_->SetForceRenderSurfaceForTesting(false);
1101 // Remove the non-fast region to ensure a scroll node is removed.
1102 child_->SetNonFastScrollableRegion(Region());
1103 break;
1104 }
1105 }
1106
CommitCompleteOnThread(LayerTreeHostImpl * impl)1107 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1108 PropertyTrees* property_trees = impl->sync_tree()->property_trees();
1109 LayerImpl* child_impl_ = impl->sync_tree()->LayerById(child_->id());
1110 switch (impl->sync_tree()->source_frame_number()) {
1111 case 0:
1112 EXPECT_EQ(2U, child_impl_->layer_tree_impl()
1113 ->property_trees()
1114 ->transform_tree.size());
1115 EXPECT_EQ(2U, child_impl_->layer_tree_impl()
1116 ->property_trees()
1117 ->effect_tree.size());
1118 EXPECT_EQ(2U, child_impl_->layer_tree_impl()
1119 ->property_trees()
1120 ->scroll_tree.size());
1121 EXPECT_TRUE(property_trees->element_id_to_transform_node_index.find(
1122 child_->element_id()) ==
1123 property_trees->element_id_to_transform_node_index.end());
1124 EXPECT_TRUE(property_trees->element_id_to_effect_node_index.find(
1125 child_->element_id()) ==
1126 property_trees->element_id_to_effect_node_index.end());
1127 EXPECT_TRUE(property_trees->element_id_to_scroll_node_index.find(
1128 child_->element_id()) ==
1129 property_trees->element_id_to_scroll_node_index.end());
1130 break;
1131 case 1:
1132 EXPECT_EQ(3U, child_impl_->layer_tree_impl()
1133 ->property_trees()
1134 ->transform_tree.size());
1135 EXPECT_EQ(3U, child_impl_->layer_tree_impl()
1136 ->property_trees()
1137 ->effect_tree.size());
1138 EXPECT_EQ(3U, child_impl_->layer_tree_impl()
1139 ->property_trees()
1140 ->scroll_tree.size());
1141 EXPECT_EQ(
1142 2, property_trees
1143 ->element_id_to_transform_node_index[child_->element_id()]);
1144 EXPECT_EQ(2,
1145 property_trees
1146 ->element_id_to_effect_node_index[child_->element_id()]);
1147 EXPECT_EQ(2,
1148 property_trees
1149 ->element_id_to_scroll_node_index[child_->element_id()]);
1150 break;
1151 case 2:
1152 EXPECT_EQ(2U, child_impl_->layer_tree_impl()
1153 ->property_trees()
1154 ->transform_tree.size());
1155 EXPECT_EQ(2U, child_impl_->layer_tree_impl()
1156 ->property_trees()
1157 ->effect_tree.size());
1158 EXPECT_TRUE(property_trees->element_id_to_transform_node_index.find(
1159 child_->element_id()) ==
1160 property_trees->element_id_to_transform_node_index.end());
1161 EXPECT_TRUE(property_trees->element_id_to_effect_node_index.find(
1162 child_->element_id()) ==
1163 property_trees->element_id_to_effect_node_index.end());
1164 EXPECT_TRUE(property_trees->element_id_to_scroll_node_index.find(
1165 child_->element_id()) ==
1166 property_trees->element_id_to_scroll_node_index.end());
1167 break;
1168 }
1169 EndTest();
1170 }
1171
1172 private:
1173 scoped_refptr<Layer> root_;
1174 scoped_refptr<Layer> child_;
1175 };
1176
1177 // Validates that, for a layer with a compositor element id set on it, mappings
1178 // from compositor element id to transform/effect node indexes are created as
1179 // part of building a layer's property tree and are present on the impl thread.
1180 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushElementIdToNodeIdMap);
1181
1182 class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest {
1183 protected:
SetupTree()1184 void SetupTree() override {
1185 root_ = Layer::Create();
1186 child_ = Layer::Create();
1187 grand_child_ = Layer::Create();
1188
1189 layer_tree_host()->SetRootLayer(root_);
1190 root_->AddChild(child_);
1191 child_->AddChild(grand_child_);
1192
1193 root_->SetBounds(gfx::Size(50, 50));
1194 root_->SetMasksToBounds(true);
1195 child_->SetForceRenderSurfaceForTesting(true);
1196
1197 LayerTreeHostTest::SetupTree();
1198 }
1199
BeginTest()1200 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1201
DidCommit()1202 void DidCommit() override {
1203 switch (layer_tree_host()->SourceFrameNumber()) {
1204 case 1:
1205 grand_child_->SetOpacity(0.9f);
1206 break;
1207 case 2:
1208 root_->SetBounds(gfx::Size(20, 20));
1209 break;
1210 case 3:
1211 child_->SetOpacity(0.8f);
1212 break;
1213 }
1214 }
1215
PrepareToDrawOnThread(LayerTreeHostImpl * impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)1216 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl,
1217 LayerTreeHostImpl::FrameData* frame_data,
1218 DrawResult draw_result) override {
1219 LayerImpl* root_impl = impl->active_tree()->LayerById(root_->id());
1220 LayerImpl* child_impl = impl->active_tree()->LayerById(child_->id());
1221 switch (impl->active_tree()->source_frame_number()) {
1222 case 0:
1223 EXPECT_TRUE(GetRenderSurface(root_impl)->AncestorPropertyChanged());
1224 EXPECT_TRUE(GetRenderSurface(child_impl)->AncestorPropertyChanged());
1225 PostSetNeedsCommitToMainThread();
1226 break;
1227 case 1:
1228 EXPECT_FALSE(GetRenderSurface(root_impl)->AncestorPropertyChanged());
1229 EXPECT_FALSE(GetRenderSurface(child_impl)->AncestorPropertyChanged());
1230 PostSetNeedsCommitToMainThread();
1231 break;
1232 case 2:
1233 EXPECT_TRUE(GetRenderSurface(root_impl)->AncestorPropertyChanged());
1234 EXPECT_TRUE(GetRenderSurface(child_impl)->AncestorPropertyChanged());
1235 PostSetNeedsCommitToMainThread();
1236 break;
1237 case 3:
1238 EXPECT_FALSE(GetRenderSurface(root_impl)->AncestorPropertyChanged());
1239 EXPECT_TRUE(GetRenderSurface(child_impl)->AncestorPropertyChanged());
1240 PostSetNeedsCommitToMainThread();
1241 break;
1242 case 4:
1243 EXPECT_FALSE(GetRenderSurface(root_impl)->AncestorPropertyChanged());
1244 EXPECT_FALSE(GetRenderSurface(child_impl)->AncestorPropertyChanged());
1245 EndTest();
1246 break;
1247 }
1248
1249 return draw_result;
1250 }
1251
1252 private:
1253 scoped_refptr<Layer> root_;
1254 scoped_refptr<Layer> child_;
1255 scoped_refptr<Layer> grand_child_;
1256 };
1257
1258 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage);
1259
1260 class LayerTreeHostTestLayerListSurfaceDamage : public LayerTreeHostTest {
1261 protected:
LayerTreeHostTestLayerListSurfaceDamage()1262 LayerTreeHostTestLayerListSurfaceDamage() { SetUseLayerLists(); }
1263
SetupTree()1264 void SetupTree() override {
1265 SetInitialRootBounds(gfx::Size(50, 50));
1266 LayerTreeHostTest::SetupTree();
1267 root_ = layer_tree_host()->root_layer();
1268
1269 child_a_ = Layer::Create();
1270 child_a_->SetBounds(gfx::Size(10, 20));
1271 child_a_->SetIsDrawable(true);
1272 CopyProperties(root_, child_a_.get());
1273 auto& effect_a = CreateEffectNode(child_a_.get());
1274 effect_a.render_surface_reason = RenderSurfaceReason::kTest;
1275 root_->AddChild(child_a_);
1276
1277 child_b_ = Layer::Create();
1278 child_b_->SetBounds(gfx::Size(20, 10));
1279 child_b_->SetIsDrawable(true);
1280 CopyProperties(root_, child_b_.get());
1281 auto& effect_b = CreateEffectNode(child_b_.get());
1282 effect_b.render_surface_reason = RenderSurfaceReason::kTest;
1283 root_->AddChild(child_b_);
1284
1285 child_c_ = Layer::Create();
1286 child_c_->SetBounds(gfx::Size(15, 15));
1287 child_c_->SetIsDrawable(true);
1288 CopyProperties(root_, child_c_.get());
1289 auto& effect_c = CreateEffectNode(child_c_.get());
1290 effect_c.render_surface_reason = RenderSurfaceReason::kTest;
1291 root_->AddChild(child_c_);
1292 }
1293
BeginTest()1294 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1295
DidCommit()1296 void DidCommit() override {
1297 switch (layer_tree_host()->SourceFrameNumber()) {
1298 case 1:
1299 // Push an unchanged list. This should cause no damage.
1300 {
1301 LayerList same_list = root_->children();
1302 root_->SetChildLayerList(same_list);
1303 }
1304 break;
1305 case 2:
1306 // Reverse the last two layers so the order becomes: [a, c, b]. This
1307 // should only damage the 'b' layer.
1308 {
1309 LayerList last_two_reversed;
1310 last_two_reversed.push_back(child_a_);
1311 last_two_reversed.push_back(child_c_);
1312 last_two_reversed.push_back(child_b_);
1313 root_->SetChildLayerList(last_two_reversed);
1314 }
1315 break;
1316 case 3:
1317 // Reverse the first two layers so the order becomes: [c, a, b]. This
1318 // should damage the last two layers, 'a' and 'b'.
1319 {
1320 LayerList last_pair_reversed;
1321 last_pair_reversed.push_back(child_c_);
1322 last_pair_reversed.push_back(child_a_);
1323 last_pair_reversed.push_back(child_b_);
1324 root_->SetChildLayerList(last_pair_reversed);
1325 }
1326 break;
1327 case 4:
1328 // Remove the first layer, 'c', so the order becomes: ['a', 'b']. This
1329 // should not damage 'a' or 'b'.
1330 {
1331 LayerList first_removed = root_->children();
1332 first_removed.erase(first_removed.begin());
1333 root_->SetChildLayerList(first_removed);
1334 }
1335 break;
1336 case 5:
1337 // Add a new layer, 'c', so the order becomes: ['a', 'b', 'c']. This
1338 // should only damage 'c'.
1339 {
1340 LayerList existing_plus_new_child = root_->children();
1341 existing_plus_new_child.push_back(child_c_);
1342 root_->SetChildLayerList(existing_plus_new_child);
1343 }
1344 break;
1345 }
1346 }
1347
PrepareToDrawOnThread(LayerTreeHostImpl * impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)1348 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl,
1349 LayerTreeHostImpl::FrameData* frame_data,
1350 DrawResult draw_result) override {
1351 LayerImpl* child_a_impl = impl->active_tree()->LayerById(child_a_->id());
1352 LayerImpl* child_b_impl = impl->active_tree()->LayerById(child_b_->id());
1353 LayerImpl* child_c_impl = impl->active_tree()->LayerById(child_c_->id());
1354 switch (impl->active_tree()->source_frame_number()) {
1355 case 0:
1356 // Full damage on first frame.
1357 EXPECT_EQ(GetRenderSurface(child_a_impl)->GetDamageRect(),
1358 gfx::Rect(0, 0, 10, 20));
1359 EXPECT_EQ(GetRenderSurface(child_b_impl)->GetDamageRect(),
1360 gfx::Rect(0, 0, 20, 10));
1361 EXPECT_EQ(GetRenderSurface(child_c_impl)->GetDamageRect(),
1362 gfx::Rect(0, 0, 15, 15));
1363 PostSetNeedsCommitToMainThread();
1364 break;
1365 case 1:
1366 // No damage after pushing the same list.
1367 EXPECT_TRUE(GetRenderSurface(child_a_impl)->GetDamageRect().IsEmpty());
1368 EXPECT_TRUE(GetRenderSurface(child_b_impl)->GetDamageRect().IsEmpty());
1369 EXPECT_TRUE(GetRenderSurface(child_c_impl)->GetDamageRect().IsEmpty());
1370 PostSetNeedsCommitToMainThread();
1371 break;
1372 case 2:
1373 // Only 'b' damaged after reversing the last two layers.
1374 EXPECT_TRUE(GetRenderSurface(child_a_impl)->GetDamageRect().IsEmpty());
1375 EXPECT_EQ(GetRenderSurface(child_b_impl)->GetDamageRect(),
1376 gfx::Rect(0, 0, 20, 10));
1377 EXPECT_TRUE(GetRenderSurface(child_c_impl)->GetDamageRect().IsEmpty());
1378 PostSetNeedsCommitToMainThread();
1379 break;
1380 case 3:
1381 // 'a' and 'b' damaged after reversing the first two layers.
1382 EXPECT_EQ(GetRenderSurface(child_a_impl)->GetDamageRect(),
1383 gfx::Rect(0, 0, 10, 20));
1384 EXPECT_EQ(GetRenderSurface(child_b_impl)->GetDamageRect(),
1385 gfx::Rect(0, 0, 20, 10));
1386 EXPECT_TRUE(GetRenderSurface(child_c_impl)->GetDamageRect().IsEmpty());
1387 PostSetNeedsCommitToMainThread();
1388 break;
1389 case 4:
1390 // When the first layer, 'c', is removed, 'a' and 'b' should not be
1391 // damaged.
1392 EXPECT_TRUE(GetRenderSurface(child_a_impl)->GetDamageRect().IsEmpty());
1393 EXPECT_TRUE(GetRenderSurface(child_b_impl)->GetDamageRect().IsEmpty());
1394 PostSetNeedsCommitToMainThread();
1395 break;
1396 case 5:
1397 // When 'c' is added, 'a' and 'b' should not be damaged.
1398 EXPECT_TRUE(GetRenderSurface(child_a_impl)->GetDamageRect().IsEmpty());
1399 EXPECT_TRUE(GetRenderSurface(child_b_impl)->GetDamageRect().IsEmpty());
1400 EXPECT_EQ(GetRenderSurface(child_c_impl)->GetDamageRect(),
1401 gfx::Rect(0, 0, 15, 15));
1402 EndTest();
1403 break;
1404 }
1405
1406 return draw_result;
1407 }
1408
1409 private:
1410 Layer* root_;
1411 scoped_refptr<Layer> child_a_;
1412 scoped_refptr<Layer> child_b_;
1413 scoped_refptr<Layer> child_c_;
1414 };
1415
1416 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLayerListSurfaceDamage);
1417
1418 // When settings->enable_early_damage_check is true, verify that invalidate is
1419 // not called when changes to a layer don't cause visible damage.
1420 class LayerTreeHostTestNoDamageCausesNoInvalidate : public LayerTreeHostTest {
InitializeSettings(LayerTreeSettings * settings)1421 void InitializeSettings(LayerTreeSettings* settings) override {
1422 settings->using_synchronous_renderer_compositor = true;
1423 settings->enable_early_damage_check = true;
1424 }
1425
1426 protected:
SetupTree()1427 void SetupTree() override {
1428 scoped_refptr<Layer> root = Layer::Create();
1429 layer_ = Layer::Create();
1430 root->AddChild(layer_);
1431
1432 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
1433 viz::LocalSurfaceId());
1434 layer_tree_host()->SetRootLayer(root);
1435
1436 // Translate the root layer past the viewport.
1437 gfx::Transform translation;
1438 translation.Translate(100, 100);
1439 layer_->SetTransform(translation);
1440
1441 root->SetBounds(gfx::Size(50, 50));
1442 layer_->SetBounds(gfx::Size(50, 50));
1443
1444 LayerTreeHostTest::SetupTree();
1445 }
1446
BeginTest()1447 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1448
DidCommit()1449 void DidCommit() override {
1450 // This does not damage the frame because the root layer is outside the
1451 // viewport.
1452 if (layer_tree_host()->SourceFrameNumber() == 2)
1453 layer_->SetOpacity(0.9f);
1454 }
1455
PrepareToDrawOnThread(LayerTreeHostImpl * impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)1456 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl,
1457 LayerTreeHostImpl::FrameData* frame_data,
1458 DrawResult draw_result) override {
1459 PostSetNeedsCommitToMainThread();
1460 return draw_result;
1461 }
1462
CommitCompleteOnThread(LayerTreeHostImpl * impl)1463 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1464 switch (impl->active_tree()->source_frame_number()) {
1465 // This gives us some assurance that invalidates happen before this call,
1466 // so invalidating on frame 2 will cause a failure before the test ends.
1467 case 0:
1468 EXPECT_TRUE(first_frame_invalidate_before_commit_);
1469 break;
1470 case 2:
1471 EndTest();
1472 break;
1473 }
1474 }
1475
DidInvalidateLayerTreeFrameSink(LayerTreeHostImpl * impl)1476 void DidInvalidateLayerTreeFrameSink(LayerTreeHostImpl* impl) override {
1477 int source_frame_number = impl->active_tree()->source_frame_number();
1478 if (source_frame_number == 0) {
1479 // Be sure that invalidates happen before commits, so the below failure
1480 // works.
1481 first_frame_invalidate_before_commit_ = true;
1482 } else if (source_frame_number > 0) {
1483 // The first frame (frame number 0) has damage because it's the first
1484 // frame. All subsequent frames in this test are set up to have no damage.
1485 // The early damage check will prevent further invalidates without damage
1486 // after 2 consecutive invalidates without damage. So check there is no
1487 // more than 2.
1488 invalidate_without_damage_count_++;
1489 EXPECT_LT(invalidate_without_damage_count_, 2);
1490 }
1491 }
1492
1493 private:
1494 scoped_refptr<Layer> layer_;
1495 bool first_frame_invalidate_before_commit_ = false;
1496 int invalidate_without_damage_count_ = 0;
1497 };
1498
1499 // This behavior is specific to Android WebView, which only uses
1500 // multi-threaded compositor.
1501 MULTI_THREAD_TEST_F(LayerTreeHostTestNoDamageCausesNoInvalidate);
1502
1503 // When settings->enable_early_damage_check is true, verify that the early
1504 // damage check is turned off after |settings->damaged_frame_limit| frames
1505 // have consecutive damage.
1506 // The test verifies that frames come in as follows:
1507 // 0: visible damage as the root appears; invalidated
1508 // 1: no visible damage; invalidate because all previous frames had damage
1509 // 2: no visible damage; check early since frame 1 had no damage; no invalidate
1510 // 3: visible damage
1511 // ... (visible damage)
1512 // 3 + damaged_frame_limit - 1: visible damage
1513 // 3 + damaged_frame_limit: no visible damage, but invalidate because all of
1514 // the last |damaged_frame_limit| frames had damage.
1515 class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest {
InitializeSettings(LayerTreeSettings * settings)1516 void InitializeSettings(LayerTreeSettings* settings) override {
1517 settings->using_synchronous_renderer_compositor = true;
1518 settings->enable_early_damage_check = true;
1519 damaged_frame_limit_ = settings->damaged_frame_limit;
1520 }
1521
1522 protected:
SetupTree()1523 void SetupTree() override {
1524 root_ = Layer::Create();
1525 child_ = Layer::Create();
1526 root_->AddChild(child_);
1527
1528 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(100, 100), 1.f,
1529 viz::LocalSurfaceId());
1530
1531 layer_tree_host()->SetRootLayer(root_);
1532 root_->SetBounds(gfx::Size(50, 50));
1533 child_->SetBounds(gfx::Size(50, 50));
1534
1535 // Translate the child layer past the viewport.
1536 gfx::Transform translation;
1537 translation.Translate(200, 200);
1538 child_->SetTransform(translation);
1539
1540 LayerTreeHostTest::SetupTree();
1541 }
1542
BeginTest()1543 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1544
WillBeginMainFrame()1545 void WillBeginMainFrame() override {
1546 int frame = layer_tree_host()->SourceFrameNumber();
1547 // Change the child layer each frame. Since the child layer is translated
1548 // past the viewport, it should not cause damage, but webview will still
1549 // invalidate if the frame doesn't check for damage early.
1550 child_->SetOpacity(1.0f / (frame + 1));
1551
1552 // For |damaged_frame_limit| consecutive frames, cause actual damage.
1553 if (frame >= 3 && frame < (damaged_frame_limit_ + 3)) {
1554 root_->SetOpacity(1.0f / frame);
1555 }
1556 }
1557
DidActivateTreeOnThread(LayerTreeHostImpl * impl)1558 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
1559 PostSetNeedsCommitToMainThread();
1560 }
1561
DidInvalidateLayerTreeFrameSink(LayerTreeHostImpl * impl)1562 void DidInvalidateLayerTreeFrameSink(LayerTreeHostImpl* impl) override {
1563 int frame_number = impl->active_tree()->source_frame_number();
1564 // Frames 0 and 1 invalidate because the early damage check is not enabled
1565 // during this setup. But frames 1 and 2 are not damaged, so the early
1566 // check should prevent frame 2 from invalidating.
1567 if (frame_number == 2) {
1568 ADD_FAILURE();
1569 } else if (frame_number > 2) {
1570 invalidate_count_++;
1571 }
1572
1573 // Frame number |damaged_frame_limit_ + 3| was not damaged, but it should
1574 // invalidate since the previous |damaged_frame_limit_| frames had damage
1575 // and should have turned off the early damage check.
1576 if (frame_number == damaged_frame_limit_ + 3) {
1577 EndTest();
1578 return;
1579 }
1580 }
1581
AfterTest()1582 void AfterTest() override {
1583 // We should invalidate |damaged_frame_limit_| frames that had actual damage
1584 // and one additional frame after, since the early check is disabled.
1585 EXPECT_EQ(invalidate_count_, damaged_frame_limit_ + 1);
1586 }
1587
1588 private:
1589 scoped_refptr<Layer> root_;
1590 scoped_refptr<Layer> child_;
1591 int invalidate_count_ = 0;
1592 int damaged_frame_limit_;
1593 };
1594
1595 // This behavior is specific to Android WebView, which only uses
1596 // multi-threaded compositor.
1597 // TODO(crbug.com/1043900): Disabled because test is flaky on Mac10.13.
1598 // MULTI_THREAD_TEST_F(LayerTreeHostTestEarlyDamageCheckStops);
1599
1600 // When settings->enable_early_damage_check is true, verifies that PrepareTiles
1601 // need not cause a draw when there is no visible damage. Here, a child layer is
1602 // translated outside of the viewport. After two draws, the early damage check
1603 // should prevent further draws, but preventing further draws should not prevent
1604 // PrepareTiles.
1605 class LayerTreeHostTestPrepareTilesWithoutDraw : public LayerTreeHostTest {
InitializeSettings(LayerTreeSettings * settings)1606 void InitializeSettings(LayerTreeSettings* settings) override {
1607 settings->using_synchronous_renderer_compositor = true;
1608 settings->enable_early_damage_check = true;
1609 }
1610
1611 protected:
SetupTree()1612 void SetupTree() override {
1613 LayerTreeHostTest::SetupTree();
1614 child_layer_ = Layer::Create();
1615 layer_tree_host()->root_layer()->AddChild(child_layer_);
1616
1617 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
1618 viz::LocalSurfaceId());
1619
1620 layer_tree_host()->root_layer()->SetBounds(gfx::Size(50, 50));
1621 child_layer_->SetBounds(gfx::Size(50, 50));
1622
1623 // Translate the child layer past the viewport.
1624 gfx::Transform translation;
1625 translation.Translate(100, 100);
1626 child_layer_->SetTransform(translation);
1627 child_layer_->SetBounds(gfx::Size(50, 50));
1628 }
1629
BeginTest()1630 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1631
DidCommit()1632 void DidCommit() override {
1633 int frame_number = layer_tree_host()->SourceFrameNumber();
1634 if (frame_number > 3) {
1635 EndTest();
1636 return;
1637 }
1638
1639 // Modify the child layer each frame.
1640 float new_opacity = 0.9f / (frame_number + 1);
1641 child_layer_->SetOpacity(new_opacity);
1642 PostSetNeedsCommitToMainThread();
1643 }
1644
WillPrepareTilesOnThread(LayerTreeHostImpl * impl)1645 void WillPrepareTilesOnThread(LayerTreeHostImpl* impl) override {
1646 if (impl->active_tree()->source_frame_number() >= 0)
1647 prepare_tiles_count_++;
1648
1649 switch (impl->active_tree()->source_frame_number()) {
1650 case 0:
1651 EXPECT_EQ(1, prepare_tiles_count_);
1652 break;
1653 case 1:
1654 EXPECT_EQ(2, prepare_tiles_count_);
1655 break;
1656 case 2:
1657 EXPECT_EQ(3, prepare_tiles_count_);
1658 break;
1659 }
1660 }
1661
DrawLayersOnThread(LayerTreeHostImpl * impl)1662 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
1663 draw_count_++;
1664
1665 switch (impl->active_tree()->source_frame_number()) {
1666 case 0:
1667 // There is actual damage as the layers are set up.
1668 EXPECT_EQ(1, draw_count_);
1669 break;
1670 case 1:
1671 // There is no damage, but draw because the early damage check
1672 // didn't occur.
1673 EXPECT_EQ(2, draw_count_);
1674 break;
1675 default:
1676 // After the first two draws, the early damage check should kick
1677 // in and prevent further draws.
1678 ADD_FAILURE();
1679 }
1680 }
1681
AfterTest()1682 void AfterTest() override { EXPECT_EQ(2, draw_count_); }
1683
1684 private:
1685 scoped_refptr<Layer> child_layer_;
1686 int prepare_tiles_count_ = 0;
1687 int draw_count_ = 0;
1688 };
1689
1690 // This behavior is specific to Android WebView, which only uses
1691 // multi-threaded compositor.
1692 // Flaky: https://crbug.com/947673
1693 // MULTI_THREAD_TEST_F(LayerTreeHostTestPrepareTilesWithoutDraw);
1694
1695 // Verify CanDraw() is false until first commit.
1696 class LayerTreeHostTestCantDrawBeforeCommit : public LayerTreeHostTest {
1697 protected:
BeginTest()1698 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1699
ReadyToCommitOnThread(LayerTreeHostImpl * host_impl)1700 void ReadyToCommitOnThread(LayerTreeHostImpl* host_impl) override {
1701 EXPECT_FALSE(host_impl->CanDraw());
1702 }
1703
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)1704 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1705 EXPECT_TRUE(host_impl->CanDraw());
1706 EndTest();
1707 }
1708 };
1709
1710 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCantDrawBeforeCommit);
1711
1712 // Verify CanDraw() is false until first commit+activate.
1713 class LayerTreeHostTestCantDrawBeforeCommitActivate : public LayerTreeHostTest {
1714 protected:
BeginTest()1715 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1716
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)1717 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1718 EXPECT_FALSE(host_impl->CanDraw());
1719 }
1720
WillActivateTreeOnThread(LayerTreeHostImpl * host_impl)1721 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1722 EXPECT_FALSE(host_impl->CanDraw());
1723 }
1724
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)1725 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
1726 EXPECT_TRUE(host_impl->CanDraw());
1727 EndTest();
1728 }
1729 };
1730
1731 // Single thread mode commits directly to the active tree, so CanDraw()
1732 // is true by the time WillActivateTreeOnThread is called.
1733 MULTI_THREAD_TEST_F(LayerTreeHostTestCantDrawBeforeCommitActivate);
1734
1735 // Verify damage status of property trees is preserved after commit.
1736 class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest {
1737 protected:
SetupTree()1738 void SetupTree() override {
1739 root_ = Layer::Create();
1740 child_ = Layer::Create();
1741 // This is to force the child to create a transform and effect node.
1742 child_->SetForceRenderSurfaceForTesting(true);
1743 root_->AddChild(child_);
1744 layer_tree_host()->SetRootLayer(root_);
1745 LayerTreeHostTest::SetupTree();
1746 }
1747
1748 enum Animations {
1749 OPACITY,
1750 TRANSFORM,
1751 FILTER,
1752 END,
1753 };
1754
BeginTest()1755 void BeginTest() override {
1756 index_ = OPACITY;
1757 PostSetNeedsCommitToMainThread();
1758 }
1759
DidCommit()1760 void DidCommit() override {
1761 switch (layer_tree_host()->SourceFrameNumber()) {
1762 case 2:
1763 // We rebuild property trees for this case to test the code path of
1764 // damage status synchronization when property trees are different.
1765 layer_tree_host()->property_trees()->needs_rebuild = true;
1766 break;
1767 default:
1768 EXPECT_FALSE(layer_tree_host()->property_trees()->needs_rebuild);
1769 }
1770 }
1771
CommitCompleteOnThread(LayerTreeHostImpl * impl)1772 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
1773 gfx::Transform transform;
1774 FilterOperations filters;
1775 LayerImpl* root = impl->active_tree()->root_layer();
1776 switch (static_cast<Animations>(index_)) {
1777 case OPACITY:
1778 index_++;
1779 impl->active_tree()->ResetAllChangeTracking();
1780 impl->active_tree()->SetOpacityMutated(root->element_id(), 0.5f);
1781 PostSetNeedsCommitToMainThread();
1782 break;
1783 case TRANSFORM:
1784 index_++;
1785 EXPECT_TRUE(impl->active_tree()
1786 ->LayerById(root_->id())
1787 ->LayerPropertyChanged());
1788 impl->active_tree()->ResetAllChangeTracking();
1789 EXPECT_FALSE(impl->active_tree()
1790 ->LayerById(root_->id())
1791 ->LayerPropertyChanged());
1792 EXPECT_FALSE(impl->active_tree()
1793 ->LayerById(child_->id())
1794 ->LayerPropertyChanged());
1795 transform.Translate(10, 10);
1796 impl->active_tree()->SetTransformMutated(root->element_id(), transform);
1797 PostSetNeedsCommitToMainThread();
1798 break;
1799 case FILTER:
1800 index_++;
1801 EXPECT_TRUE(root->LayerPropertyChanged());
1802 EXPECT_TRUE(impl->active_tree()
1803 ->LayerById(child_->id())
1804 ->LayerPropertyChanged());
1805 impl->active_tree()->ResetAllChangeTracking();
1806 EXPECT_FALSE(root->LayerPropertyChanged());
1807 EXPECT_FALSE(impl->active_tree()
1808 ->LayerById(child_->id())
1809 ->LayerPropertyChanged());
1810 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1811 impl->active_tree()->SetFilterMutated(root->element_id(), filters);
1812 PostSetNeedsCommitToMainThread();
1813 break;
1814 case END:
1815 EXPECT_TRUE(root->LayerPropertyChanged());
1816 EndTest();
1817 break;
1818 }
1819 }
1820
1821 private:
1822 int index_;
1823 scoped_refptr<Layer> root_;
1824 scoped_refptr<Layer> child_;
1825 };
1826
1827 SINGLE_THREAD_TEST_F(LayerTreeHostTestPropertyTreesChangedSync);
1828
1829 class LayerTreeHostTestAnimationOpacityMutatedNotUsingLayerLists
1830 : public LayerTreeHostTest {
1831 protected:
BeginTest()1832 void BeginTest() override {
1833 Layer* root = layer_tree_host()->root_layer();
1834 EXPECT_EQ(1.0f, root->opacity());
1835 layer_tree_host()->SetElementOpacityMutated(root->element_id(),
1836 ElementListType::ACTIVE, 0.3f);
1837 // When not using layer lists, opacity is stored on the layer.
1838 EXPECT_EQ(0.3f, root->opacity());
1839 EndTest();
1840 }
1841 };
1842
1843 SINGLE_THREAD_TEST_F(
1844 LayerTreeHostTestAnimationOpacityMutatedNotUsingLayerLists);
1845
1846 class LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists
1847 : public LayerTreeHostTest {
1848 public:
LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists()1849 LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists() {
1850 SetUseLayerLists();
1851 }
1852
1853 protected:
BeginTest()1854 void BeginTest() override {
1855 Layer* root = layer_tree_host()->root_layer();
1856 EXPECT_EQ(1.0f, layer_tree_host()
1857 ->property_trees()
1858 ->effect_tree.FindNodeFromElementId(root->element_id())
1859 ->opacity);
1860
1861 layer_tree_host()->SetElementOpacityMutated(root->element_id(),
1862 ElementListType::ACTIVE, 0.3f);
1863
1864 // The opacity should have been set directly on the effect node instead.
1865 EXPECT_EQ(0.3f, layer_tree_host()
1866 ->property_trees()
1867 ->effect_tree.FindNodeFromElementId(root->element_id())
1868 ->opacity);
1869 EndTest();
1870 }
1871 };
1872
1873 SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists);
1874
1875 class LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists
1876 : public LayerTreeHostTest {
1877 protected:
SetupTree()1878 void SetupTree() override {
1879 root_ = Layer::Create();
1880 child_ = Layer::Create();
1881 root_->AddChild(child_);
1882 layer_tree_host()->SetRootLayer(root_);
1883 LayerTreeHostTest::SetupTree();
1884 }
1885
BeginTest()1886 void BeginTest() override {
1887 EXPECT_EQ(gfx::Transform(), child_->transform());
1888 gfx::Transform expected_transform;
1889 expected_transform.Translate(42, 42);
1890 layer_tree_host()->SetElementTransformMutated(
1891 child_->element_id(), ElementListType::ACTIVE, expected_transform);
1892 // When not using layer lists, transform is stored on the layer.
1893 EXPECT_EQ(expected_transform, child_->transform());
1894 EndTest();
1895 }
1896
1897 private:
1898 scoped_refptr<Layer> root_;
1899 scoped_refptr<Layer> child_;
1900 };
1901
1902 SINGLE_THREAD_TEST_F(
1903 LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists);
1904
1905 class LayerTreeHostTestAnimationTransformMutatedUsingLayerLists
1906 : public LayerTreeHostTest {
1907 public:
LayerTreeHostTestAnimationTransformMutatedUsingLayerLists()1908 LayerTreeHostTestAnimationTransformMutatedUsingLayerLists() {
1909 SetUseLayerLists();
1910 }
1911
1912 protected:
BeginTest()1913 void BeginTest() override {
1914 Layer* root = layer_tree_host()->root_layer();
1915 EXPECT_EQ(gfx::Transform(),
1916 layer_tree_host()
1917 ->property_trees()
1918 ->transform_tree.FindNodeFromElementId(root->element_id())
1919 ->local);
1920
1921 gfx::Transform expected_transform;
1922 expected_transform.Translate(42, 42);
1923 layer_tree_host()->SetElementTransformMutated(
1924 root->element_id(), ElementListType::ACTIVE, expected_transform);
1925
1926 // The transform should have been set directly on the transform node
1927 // instead.
1928 EXPECT_EQ(expected_transform,
1929 layer_tree_host()
1930 ->property_trees()
1931 ->transform_tree.FindNodeFromElementId(root->element_id())
1932 ->local);
1933 EndTest();
1934 }
1935 };
1936
1937 SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationTransformMutatedUsingLayerLists);
1938
1939 class LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists
1940 : public LayerTreeHostTest {
1941 protected:
BeginTest()1942 void BeginTest() override {
1943 Layer* root = layer_tree_host()->root_layer();
1944 FilterOperations filters;
1945 EXPECT_EQ(FilterOperations(), root->filters());
1946 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1947 layer_tree_host()->SetElementFilterMutated(
1948 root->element_id(), ElementListType::ACTIVE, filters);
1949 // When not using layer lists, filters are just stored directly on the
1950 // layer.
1951 EXPECT_EQ(filters, root->filters());
1952 EndTest();
1953 }
1954 };
1955
1956 SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists);
1957
1958 class LayerTreeHostTestAnimationFilterMutatedUsingLayerLists
1959 : public LayerTreeHostTest {
1960 public:
LayerTreeHostTestAnimationFilterMutatedUsingLayerLists()1961 LayerTreeHostTestAnimationFilterMutatedUsingLayerLists() {
1962 SetUseLayerLists();
1963 }
1964
1965 protected:
BeginTest()1966 void BeginTest() override {
1967 Layer* root = layer_tree_host()->root_layer();
1968 EXPECT_EQ(FilterOperations(),
1969 layer_tree_host()
1970 ->property_trees()
1971 ->effect_tree.FindNodeFromElementId(root->element_id())
1972 ->filters);
1973
1974 FilterOperations filters;
1975 filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
1976 layer_tree_host()->SetElementFilterMutated(
1977 root->element_id(), ElementListType::ACTIVE, filters);
1978
1979 // The filter should have been set directly on the effect node instead.
1980 EXPECT_EQ(filters,
1981 layer_tree_host()
1982 ->property_trees()
1983 ->effect_tree.FindNodeFromElementId(root->element_id())
1984 ->filters);
1985 EndTest();
1986 }
1987 };
1988
1989 SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationFilterMutatedUsingLayerLists);
1990
1991 class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest {
1992 protected:
SetupTree()1993 void SetupTree() override {
1994 root_ = Layer::Create();
1995 layer_tree_host()->SetRootLayer(root_);
1996 blur_filter_.Append(FilterOperation::CreateBlurFilter(0.5f));
1997 brightness_filter_.Append(FilterOperation::CreateBrightnessFilter(0.25f));
1998 sepia_filter_.Append(FilterOperation::CreateSepiaFilter(0.75f));
1999 LayerTreeHostTest::SetupTree();
2000 }
2001
BeginTest()2002 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2003
DidCommit()2004 void DidCommit() override {
2005 EffectTree& effect_tree = layer_tree_host()->property_trees()->effect_tree;
2006 EffectNode* node = effect_tree.Node(root_->effect_tree_index());
2007 switch (layer_tree_host()->SourceFrameNumber()) {
2008 case 1:
2009 node->opacity = 0.5f;
2010 node->is_currently_animating_opacity = true;
2011 break;
2012 case 2:
2013 node->is_currently_animating_opacity = true;
2014 break;
2015 case 3:
2016 node->is_currently_animating_opacity = false;
2017 break;
2018 case 4:
2019 node->opacity = 0.25f;
2020 node->is_currently_animating_opacity = true;
2021 break;
2022 case 5:
2023 node->filters = blur_filter_;
2024 node->is_currently_animating_filter = true;
2025 break;
2026 case 6:
2027 node->is_currently_animating_filter = true;
2028 break;
2029 case 7:
2030 node->is_currently_animating_filter = false;
2031 break;
2032 case 8:
2033 node->filters = sepia_filter_;
2034 node->is_currently_animating_filter = true;
2035 break;
2036 }
2037 }
2038
CommitCompleteOnThread(LayerTreeHostImpl * impl)2039 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2040 EffectTree& effect_tree = impl->sync_tree()->property_trees()->effect_tree;
2041 LayerImpl* root = impl->sync_tree()->root_layer();
2042 EffectNode* node = effect_tree.Node(root->effect_tree_index());
2043 switch (impl->sync_tree()->source_frame_number()) {
2044 case 0:
2045 impl->sync_tree()->SetOpacityMutated(root->element_id(), 0.75f);
2046 PostSetNeedsCommitToMainThread();
2047 break;
2048 case 1:
2049 EXPECT_EQ(node->opacity, 0.75f);
2050 PostSetNeedsCommitToMainThread();
2051 break;
2052 case 2:
2053 EXPECT_EQ(node->opacity, 0.75f);
2054 impl->sync_tree()->SetOpacityMutated(root->element_id(), 0.75f);
2055 PostSetNeedsCommitToMainThread();
2056 break;
2057 case 3:
2058 EXPECT_EQ(node->opacity, 0.5f);
2059 PostSetNeedsCommitToMainThread();
2060 break;
2061 case 4:
2062 EXPECT_EQ(node->opacity, 0.25f);
2063 impl->sync_tree()->SetFilterMutated(root->element_id(),
2064 brightness_filter_);
2065 PostSetNeedsCommitToMainThread();
2066 break;
2067 case 5:
2068 EXPECT_EQ(node->filters, brightness_filter_);
2069 PostSetNeedsCommitToMainThread();
2070 break;
2071 case 6:
2072 EXPECT_EQ(node->filters, brightness_filter_);
2073 impl->sync_tree()->SetFilterMutated(root->element_id(),
2074 brightness_filter_);
2075 PostSetNeedsCommitToMainThread();
2076 break;
2077 case 7:
2078 EXPECT_EQ(node->filters, blur_filter_);
2079 PostSetNeedsCommitToMainThread();
2080 break;
2081 case 8:
2082 EXPECT_EQ(node->filters, sepia_filter_);
2083 EndTest();
2084 break;
2085 }
2086 }
2087
2088 private:
2089 scoped_refptr<Layer> root_;
2090 FilterOperations blur_filter_;
2091 FilterOperations brightness_filter_;
2092 FilterOperations sepia_filter_;
2093 };
2094
2095 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestEffectTreeSync);
2096
2097 class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest {
2098 protected:
SetupTree()2099 void SetupTree() override {
2100 scoped_refptr<Layer> root = Layer::Create();
2101 layer_ = Layer::Create();
2102 // Force a transform node for the layer.
2103 gfx::Transform rotate5;
2104 rotate5.Rotate(5.f);
2105 layer_->SetTransform(rotate5);
2106 root->AddChild(layer_);
2107 layer_tree_host()->SetRootLayer(root);
2108 LayerTreeHostTest::SetupTree();
2109 }
2110
BeginTest()2111 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2112
DidCommit()2113 void DidCommit() override {
2114 TransformTree& transform_tree =
2115 layer_tree_host()->property_trees()->transform_tree;
2116 TransformNode* node = transform_tree.Node(layer_->transform_tree_index());
2117 gfx::Transform rotate10;
2118 rotate10.Rotate(10.f);
2119 switch (layer_tree_host()->SourceFrameNumber()) {
2120 case 1:
2121 node->local = rotate10;
2122 node->is_currently_animating = true;
2123 break;
2124 case 2:
2125 node->is_currently_animating = true;
2126 break;
2127 case 3:
2128 node->is_currently_animating = false;
2129 break;
2130 case 4:
2131 node->local = gfx::Transform();
2132 node->is_currently_animating = true;
2133 break;
2134 }
2135 }
2136
CommitCompleteOnThread(LayerTreeHostImpl * impl)2137 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2138 TransformTree& transform_tree =
2139 impl->sync_tree()->property_trees()->transform_tree;
2140 const LayerImpl* layer = impl->sync_tree()->LayerById(layer_->id());
2141 const TransformNode* node =
2142 transform_tree.Node(layer->transform_tree_index());
2143 gfx::Transform rotate10;
2144 rotate10.Rotate(10.f);
2145 gfx::Transform rotate20;
2146 rotate20.Rotate(20.f);
2147 switch (impl->sync_tree()->source_frame_number()) {
2148 case 0:
2149 impl->sync_tree()->SetTransformMutated(layer->element_id(), rotate20);
2150 PostSetNeedsCommitToMainThread();
2151 break;
2152 case 1:
2153 EXPECT_EQ(node->local, rotate20);
2154 PostSetNeedsCommitToMainThread();
2155 break;
2156 case 2:
2157 EXPECT_EQ(node->local, rotate20);
2158 impl->sync_tree()->SetTransformMutated(layer->element_id(), rotate20);
2159 PostSetNeedsCommitToMainThread();
2160 break;
2161 case 3:
2162 EXPECT_EQ(node->local, rotate10);
2163 PostSetNeedsCommitToMainThread();
2164 break;
2165 case 4:
2166 EXPECT_EQ(node->local, gfx::Transform());
2167 EndTest();
2168 }
2169 }
2170
2171 private:
2172 scoped_refptr<Layer> layer_;
2173 };
2174
2175 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTransformTreeSync);
2176
2177 // Verify damage status is updated even when the transform tree doesn't need
2178 // to be updated at draw time.
2179 class LayerTreeHostTestTransformTreeDamageIsUpdated : public LayerTreeHostTest {
2180 protected:
SetupTree()2181 void SetupTree() override {
2182 root_ = Layer::Create();
2183 child_ = Layer::Create();
2184 grand_child_ = Layer::Create();
2185
2186 root_->SetBounds(gfx::Size(50, 50));
2187
2188 // Make sure child is registered for animation.
2189 child_->SetElementId(ElementId(2));
2190
2191 // Make sure child and grand_child have transform nodes.
2192 gfx::Transform rotation;
2193 rotation.RotateAboutZAxis(45.0);
2194 child_->SetTransform(rotation);
2195 grand_child_->SetTransform(rotation);
2196
2197 root_->AddChild(child_);
2198 child_->AddChild(grand_child_);
2199 layer_tree_host()->SetRootLayer(root_);
2200 LayerTreeHostTest::SetupTree();
2201 }
2202
BeginTest()2203 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2204
DidCommit()2205 void DidCommit() override {
2206 if (layer_tree_host()->SourceFrameNumber() == 1) {
2207 gfx::Transform scale;
2208 scale.Scale(2.0, 2.0);
2209 layer_tree_host()->SetElementTransformMutated(
2210 child_->element_id(), ElementListType::ACTIVE, scale);
2211 }
2212 }
2213
CommitCompleteOnThread(LayerTreeHostImpl * impl)2214 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2215 if (impl->sync_tree()->source_frame_number() == 0)
2216 PostSetNeedsCommitToMainThread();
2217 }
2218
PrepareToDrawOnThread(LayerTreeHostImpl * impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)2219 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl,
2220 LayerTreeHostImpl::FrameData* frame_data,
2221 DrawResult draw_result) override {
2222 if (impl->active_tree()->source_frame_number() == 1) {
2223 EXPECT_FALSE(
2224 impl->active_tree()->LayerById(root_->id())->LayerPropertyChanged());
2225 EXPECT_TRUE(
2226 impl->active_tree()->LayerById(child_->id())->LayerPropertyChanged());
2227 EXPECT_TRUE(impl->active_tree()
2228 ->LayerById(grand_child_->id())
2229 ->LayerPropertyChanged());
2230 EndTest();
2231 }
2232
2233 return draw_result;
2234 }
2235
DrawLayersOnThread(LayerTreeHostImpl * impl)2236 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2237 if (impl->active_tree()->source_frame_number() == 0) {
2238 gfx::Transform scale;
2239 scale.Scale(2.0, 2.0);
2240 impl->active_tree()->SetTransformMutated(child_->element_id(), scale);
2241 }
2242 }
2243
2244 private:
2245 scoped_refptr<Layer> root_;
2246 scoped_refptr<Layer> child_;
2247 scoped_refptr<Layer> grand_child_;
2248 };
2249
2250 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTransformTreeDamageIsUpdated);
2251
2252 class UpdateCountingLayer : public PictureLayer {
2253 public:
UpdateCountingLayer(ContentLayerClient * client)2254 explicit UpdateCountingLayer(ContentLayerClient* client)
2255 : PictureLayer(client) {}
2256
Update()2257 bool Update() override {
2258 update_count_++;
2259 return false;
2260 }
2261
update_count() const2262 int update_count() const { return update_count_; }
2263
2264 private:
2265 ~UpdateCountingLayer() override = default;
2266
2267 int update_count_ = 0;
2268 };
2269
2270 // Test that when mask layers switches layers, this gets pushed onto impl.
2271 // Also test that mask layer is in the layer update list even if its owning
2272 // layer isn't.
2273 class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest {
2274 protected:
SetupTree()2275 void SetupTree() override {
2276 scoped_refptr<Layer> root = Layer::Create();
2277 root->SetBounds(gfx::Size(10, 10));
2278 // child_layer_ is not drawable.
2279 child_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_);
2280 child_layer_->SetBounds(gfx::Size(10, 10));
2281 mask_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_);
2282 mask_layer_->SetBounds(gfx::Size(10, 10));
2283 mask_layer_->SetIsDrawable(true);
2284 child_layer_->SetMaskLayer(mask_layer_);
2285 root->AddChild(child_layer_);
2286 layer_tree_host()->SetRootLayer(root);
2287 LayerTreeHostTest::SetupTree();
2288 }
2289
BeginTest()2290 void BeginTest() override {
2291 index_ = 0;
2292 PostSetNeedsCommitToMainThread();
2293 }
2294
DidCommit()2295 void DidCommit() override {
2296 switch (layer_tree_host()->SourceFrameNumber()) {
2297 case 1:
2298 // Root and mask layer should have the same source frame number as they
2299 // will be in the layer update list but the child is not as it doesn't
2300 // draw content.
2301 EXPECT_EQ(mask_layer_->update_count(), 1);
2302 EXPECT_EQ(child_layer_->update_count(), 0);
2303
2304 layer_tree_host()->root_layer()->RemoveAllChildren();
2305 layer_tree_host()->root_layer()->SetMaskLayer(mask_layer_);
2306 break;
2307 }
2308 }
2309
CommitCompleteOnThread(LayerTreeHostImpl * impl)2310 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2311 auto* mask_surface =
2312 GetRenderSurface(impl->sync_tree()->LayerById(mask_layer_->id()));
2313 auto* root_surface = GetRenderSurface(impl->sync_tree()->root_layer());
2314 ASSERT_TRUE(mask_surface);
2315 switch (index_) {
2316 case 0: {
2317 index_++;
2318 auto* child_surface =
2319 GetRenderSurface(impl->sync_tree()->LayerById(child_layer_->id()));
2320 EXPECT_EQ(child_surface, mask_surface->render_target());
2321 EXPECT_NE(child_surface, root_surface);
2322 break;
2323 }
2324 case 1:
2325 EXPECT_EQ(mask_surface->render_target(), root_surface);
2326 EndTest();
2327 break;
2328 }
2329 }
2330
2331 FakeContentLayerClient client_;
2332 scoped_refptr<UpdateCountingLayer> mask_layer_;
2333 scoped_refptr<UpdateCountingLayer> child_layer_;
2334 int index_;
2335 };
2336
2337 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSwitchMaskLayer);
2338
2339 // 1 setNeedsRedraw after the first commit has completed should lead to 1
2340 // additional draw.
2341 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
2342 public:
LayerTreeHostTestSetNeedsRedraw()2343 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
2344
BeginTest()2345 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2346
DrawLayersOnThread(LayerTreeHostImpl * impl)2347 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2348 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
2349 if (!num_draws_) {
2350 // Redraw again to verify that the second redraw doesn't commit.
2351 PostSetNeedsRedrawToMainThread();
2352 } else {
2353 EndTest();
2354 }
2355 num_draws_++;
2356 }
2357
CommitCompleteOnThread(LayerTreeHostImpl * impl)2358 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
2359 EXPECT_EQ(0, num_draws_);
2360 num_commits_++;
2361 }
2362
AfterTest()2363 void AfterTest() override {
2364 EXPECT_GE(2, num_draws_);
2365 EXPECT_EQ(1, num_commits_);
2366 }
2367
2368 private:
2369 int num_commits_;
2370 int num_draws_;
2371 };
2372
2373 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
2374
2375 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
2376 // must contain invalid_rect.
2377 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
2378 public:
LayerTreeHostTestSetNeedsRedrawRect()2379 LayerTreeHostTestSetNeedsRedrawRect()
2380 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
2381
BeginTest()2382 void BeginTest() override {
2383 root_layer_ = FakePictureLayer::Create(&client_);
2384 root_layer_->SetIsDrawable(true);
2385 root_layer_->SetBounds(bounds_);
2386 layer_tree_host()->SetRootLayer(root_layer_);
2387 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds_), 1.f,
2388 viz::LocalSurfaceId());
2389 PostSetNeedsCommitToMainThread();
2390 client_.set_bounds(root_layer_->bounds());
2391 }
2392
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)2393 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2394 LayerTreeHostImpl::FrameData* frame_data,
2395 DrawResult draw_result) override {
2396 EXPECT_EQ(DRAW_SUCCESS, draw_result);
2397
2398 gfx::Rect root_damage_rect;
2399 if (!frame_data->render_passes.empty())
2400 root_damage_rect = frame_data->render_passes.back()->damage_rect;
2401
2402 if (!num_draws_) {
2403 // If this is the first frame, expect full frame damage.
2404 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_));
2405 } else {
2406 // Check that invalid_rect_ is indeed repainted.
2407 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
2408 }
2409
2410 return draw_result;
2411 }
2412
DrawLayersOnThread(LayerTreeHostImpl * impl)2413 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
2414 if (!num_draws_) {
2415 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
2416 } else {
2417 EndTest();
2418 }
2419 num_draws_++;
2420 }
2421
AfterTest()2422 void AfterTest() override { EXPECT_EQ(2, num_draws_); }
2423
2424 private:
2425 int num_draws_;
2426 const gfx::Size bounds_;
2427 const gfx::Rect invalid_rect_;
2428 FakeContentLayerClient client_;
2429 scoped_refptr<FakePictureLayer> root_layer_;
2430 };
2431
2432 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
2433
2434 // Ensure the texture size of the pending and active trees are identical when a
2435 // layer is not in the viewport and a resize happens on the viewport
2436 class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
2437 public:
LayerTreeHostTestGpuRasterDeviceSizeChanged()2438 LayerTreeHostTestGpuRasterDeviceSizeChanged()
2439 : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {}
2440
BeginTest()2441 void BeginTest() override {
2442 client_.set_fill_with_nonsolid_color(true);
2443 scoped_refptr<Layer> root = Layer::Create();
2444 layer_ = FakePictureLayer::Create(&client_);
2445 root->AddChild(layer_);
2446 layer_->SetIsDrawable(true);
2447 gfx::Transform transform;
2448 // Translate the layer out of the viewport to force it to not update its
2449 // tile size via PushProperties.
2450 transform.Translate(10000.0, 10000.0);
2451 layer_->SetTransform(transform);
2452 root->SetBounds(bounds_);
2453 layer_->SetBounds(bounds_);
2454 layer_tree_host()->SetRootLayer(root);
2455 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds_), 1.f,
2456 GetCurrentLocalSurfaceId());
2457
2458 PostSetNeedsCommitToMainThread();
2459 client_.set_bounds(layer_->bounds());
2460 }
2461
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_provider)2462 void SetUpUnboundContextProviders(
2463 viz::TestContextProvider* context_provider,
2464 viz::TestContextProvider* worker_provider) override {
2465 context_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
2466 worker_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
2467 }
2468
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)2469 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2470 if (num_draws_ == 2) {
2471 auto* pending_tree = host_impl->pending_tree();
2472 auto* pending_layer_impl = static_cast<FakePictureLayerImpl*>(
2473 pending_tree->LayerById(layer_->id()));
2474 EXPECT_NE(pending_layer_impl, nullptr);
2475
2476 auto* active_tree = host_impl->pending_tree();
2477 auto* active_layer_impl = static_cast<FakePictureLayerImpl*>(
2478 active_tree->LayerById(layer_->id()));
2479 EXPECT_NE(pending_layer_impl, nullptr);
2480
2481 auto* active_tiling_set = active_layer_impl->picture_layer_tiling_set();
2482 auto* active_tiling = active_tiling_set->tiling_at(0);
2483 auto* pending_tiling_set = pending_layer_impl->picture_layer_tiling_set();
2484 auto* pending_tiling = pending_tiling_set->tiling_at(0);
2485 EXPECT_EQ(
2486 pending_tiling->TilingDataForTesting().max_texture_size().width(),
2487 active_tiling->TilingDataForTesting().max_texture_size().width());
2488 }
2489 }
2490
DidCommitAndDrawFrame()2491 void DidCommitAndDrawFrame() override {
2492 // On the second commit, resize the viewport.
2493 if (num_draws_ == 1) {
2494 GenerateNewLocalSurfaceId();
2495 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(400, 64), 1.f,
2496 GetCurrentLocalSurfaceId());
2497 }
2498 if (num_draws_ < 2) {
2499 layer_tree_host()->SetNeedsRedrawRect(invalid_rect_);
2500 layer_tree_host()->SetNeedsCommit();
2501 num_draws_++;
2502 } else {
2503 EndTest();
2504 }
2505 }
2506
2507 private:
2508 int num_draws_;
2509 const gfx::Size bounds_;
2510 const gfx::Rect invalid_rect_;
2511 FakeContentLayerClient client_;
2512 scoped_refptr<FakePictureLayer> layer_;
2513 };
2514
2515 // As there's no pending tree in single-threaded case, this test should run
2516 // only for multi-threaded case.
2517 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterDeviceSizeChanged);
2518
2519 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
2520 public:
SetupTree()2521 void SetupTree() override {
2522 root_layer_ = Layer::Create();
2523 root_layer_->SetBounds(gfx::Size(10, 20));
2524
2525 scaled_layer_ = FakePictureLayer::Create(&client_);
2526 scaled_layer_->SetBounds(gfx::Size(1, 1));
2527 root_layer_->AddChild(scaled_layer_);
2528
2529 layer_tree_host()->SetRootLayer(root_layer_);
2530 LayerTreeHostTest::SetupTree();
2531 client_.set_bounds(root_layer_->bounds());
2532 }
2533
BeginTest()2534 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2535
DrawLayersOnThread(LayerTreeHostImpl * host_impl)2536 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2537 if (host_impl->active_tree()->source_frame_number() == 1)
2538 EndTest();
2539 }
2540
DidCommit()2541 void DidCommit() override {
2542 switch (layer_tree_host()->SourceFrameNumber()) {
2543 case 1:
2544 // SetBounds grows the layer and exposes new content.
2545 scaled_layer_->SetBounds(gfx::Size(4, 4));
2546 break;
2547 default:
2548 // No extra commits.
2549 EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber());
2550 }
2551 }
2552
AfterTest()2553 void AfterTest() override {
2554 EXPECT_EQ(gfx::Size(4, 4).ToString(), scaled_layer_->bounds().ToString());
2555 }
2556
2557 private:
2558 FakeContentLayerClient client_;
2559 scoped_refptr<Layer> root_layer_;
2560 scoped_refptr<Layer> scaled_layer_;
2561 };
2562
2563 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
2564
2565 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
2566 : public LayerTreeHostTest {
2567 public:
SetupTree()2568 void SetupTree() override {
2569 root_layer_ = Layer::Create();
2570 root_layer_->SetBounds(gfx::Size(10, 20));
2571
2572 bool paint_scrollbar = true;
2573 bool has_thumb = false;
2574 scrollbar_ = FakePaintedScrollbarLayer::Create(paint_scrollbar, has_thumb,
2575 root_layer_->element_id());
2576 scrollbar_->SetPosition(gfx::PointF(0.f, 10.f));
2577 scrollbar_->SetBounds(gfx::Size(10, 10));
2578
2579 root_layer_->AddChild(scrollbar_);
2580
2581 layer_tree_host()->SetRootLayer(root_layer_);
2582 LayerTreeHostTest::SetupTree();
2583 client_.set_bounds(root_layer_->bounds());
2584 }
2585
BeginTest()2586 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2587
DrawLayersOnThread(LayerTreeHostImpl * host_impl)2588 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2589 if (host_impl->active_tree()->source_frame_number() == 1)
2590 EndTest();
2591 }
2592
DidCommit()2593 void DidCommit() override {
2594 switch (layer_tree_host()->SourceFrameNumber()) {
2595 case 1:
2596 // Changing the device scale factor causes a commit. It also changes
2597 // the content bounds of |scrollbar_|, which should not generate
2598 // a second commit as a result.
2599 layer_tree_host()->SetViewportRectAndScale(
2600 layer_tree_host()->device_viewport_rect(), 4.f,
2601 layer_tree_host()->local_surface_id_from_parent());
2602 break;
2603 default:
2604 // No extra commits.
2605 EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber());
2606 break;
2607 }
2608 }
2609
2610 private:
2611 FakeContentLayerClient client_;
2612 scoped_refptr<Layer> root_layer_;
2613 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
2614 };
2615
2616 SINGLE_AND_MULTI_THREAD_TEST_F(
2617 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
2618
2619 class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest {
2620 public:
SetupTree()2621 void SetupTree() override {
2622 root_layer_ = Layer::Create();
2623 root_layer_->SetBounds(gfx::Size(10, 20));
2624
2625 child_layer_ = FakePictureLayer::Create(&client_);
2626 child_layer_->SetBounds(gfx::Size(10, 10));
2627 root_layer_->AddChild(child_layer_);
2628
2629 layer_tree_host()->SetRootLayer(root_layer_);
2630 LayerTreeHostTest::SetupTree();
2631 client_.set_bounds(root_layer_->bounds());
2632 }
2633
BeginTest()2634 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2635
DidCommit()2636 void DidCommit() override {
2637 if (layer_tree_host()->SourceFrameNumber() == 1) {
2638 layer_tree_host()->SetViewportRectAndScale(
2639 layer_tree_host()->device_viewport_rect(), 4.f,
2640 layer_tree_host()->local_surface_id_from_parent());
2641 }
2642 }
2643
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)2644 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2645 if (host_impl->sync_tree()->source_frame_number() == 1) {
2646 EXPECT_EQ(4.f, host_impl->sync_tree()->device_scale_factor());
2647 if (host_impl->pending_tree()) {
2648 // The active tree's device scale factor shouldn't change until
2649 // activation.
2650 EXPECT_EQ(1.f, host_impl->active_tree()->device_scale_factor());
2651 }
2652 }
2653 }
2654
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)2655 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2656 LayerTreeHostImpl::FrameData* frame_data,
2657 DrawResult draw_result) override {
2658 if (host_impl->active_tree()->source_frame_number() == 0) {
2659 EXPECT_EQ(1.f, host_impl->active_tree()->device_scale_factor());
2660 } else {
2661 gfx::Rect root_damage_rect =
2662 frame_data->render_passes.back()->damage_rect;
2663 EXPECT_EQ(gfx::Rect(host_impl->active_tree()->root_layer()->bounds()),
2664 root_damage_rect);
2665 EXPECT_EQ(4.f, host_impl->active_tree()->device_scale_factor());
2666 EndTest();
2667 }
2668
2669 return draw_result;
2670 }
2671
2672 private:
2673 FakeContentLayerClient client_;
2674 scoped_refptr<Layer> root_layer_;
2675 scoped_refptr<Layer> child_layer_;
2676 };
2677
2678 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorChange);
2679
2680 class LayerTreeHostTestRasterColorSpaceChange : public LayerTreeHostTest {
2681 public:
SetupTree()2682 void SetupTree() override {
2683 space1_ = gfx::DisplayColorSpaces(gfx::ColorSpace::CreateXYZD50());
2684 space2_ = gfx::DisplayColorSpaces(gfx::ColorSpace::CreateSRGB());
2685
2686 root_layer_ = Layer::Create();
2687 root_layer_->SetBounds(gfx::Size(10, 20));
2688
2689 child_layer_ = FakePictureLayer::Create(&client_);
2690 child_layer_->SetBounds(gfx::Size(10, 10));
2691 root_layer_->AddChild(child_layer_);
2692
2693 layer_tree_host()->SetRootLayer(root_layer_);
2694 layer_tree_host()->SetDisplayColorSpaces(space1_);
2695 LayerTreeHostTest::SetupTree();
2696 client_.set_bounds(root_layer_->bounds());
2697 }
2698
BeginTest()2699 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2700
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)2701 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2702 LayerTreeHostImpl::FrameData* frame_data,
2703 DrawResult draw_result) override {
2704 EXPECT_EQ(DRAW_SUCCESS, draw_result);
2705
2706 int source_frame = host_impl->active_tree()->source_frame_number();
2707 switch (source_frame) {
2708 case 0:
2709 // The first frame will have full damage, and should be in the initial
2710 // color space.
2711 EXPECT_FALSE(frame_data->has_no_damage);
2712 EXPECT_TRUE(space1_ ==
2713 host_impl->active_tree()->display_color_spaces());
2714 break;
2715 case 1:
2716 // Empty commit.
2717 EXPECT_TRUE(frame_data->has_no_damage);
2718 EXPECT_TRUE(space1_ ==
2719 host_impl->active_tree()->display_color_spaces());
2720 break;
2721 case 2:
2722 // The change from space1 to space2 should cause full damage.
2723 EXPECT_FALSE(frame_data->has_no_damage);
2724 EXPECT_TRUE(space2_ ==
2725 host_impl->active_tree()->display_color_spaces());
2726 break;
2727 case 3:
2728 // Empty commit with the color space set to space2 redundantly.
2729 EXPECT_TRUE(frame_data->has_no_damage);
2730 EXPECT_TRUE(space2_ ==
2731 host_impl->active_tree()->display_color_spaces());
2732 break;
2733 case 4:
2734 // The change from space2 to space1 should cause full damage.
2735 EXPECT_FALSE(frame_data->has_no_damage);
2736 EXPECT_TRUE(space1_ ==
2737 host_impl->active_tree()->display_color_spaces());
2738 break;
2739 case 5:
2740 // Empty commit.
2741 EXPECT_TRUE(frame_data->has_no_damage);
2742 EXPECT_TRUE(space1_ ==
2743 host_impl->active_tree()->display_color_spaces());
2744 EndTest();
2745 break;
2746 default:
2747 NOTREACHED();
2748 break;
2749 }
2750
2751 if (!frame_data->has_no_damage) {
2752 gfx::Rect root_damage_rect =
2753 frame_data->render_passes.back()->damage_rect;
2754 EXPECT_EQ(gfx::Rect(host_impl->active_tree()->root_layer()->bounds()),
2755 root_damage_rect);
2756 }
2757
2758 return draw_result;
2759 }
2760
DidCommit()2761 void DidCommit() override {
2762 switch (layer_tree_host()->SourceFrameNumber()) {
2763 case 1:
2764 PostSetNeedsCommitToMainThread();
2765 break;
2766 case 2:
2767 EXPECT_TRUE(child_layer_->update_rect().IsEmpty());
2768 layer_tree_host()->SetDisplayColorSpaces(space2_);
2769 EXPECT_FALSE(child_layer_->update_rect().IsEmpty());
2770 break;
2771 case 3:
2772 // The redundant SetRasterColorSpace should cause no commit and no
2773 // damage. Force a commit for the test to continue.
2774 layer_tree_host()->SetDisplayColorSpaces(space2_);
2775 PostSetNeedsCommitToMainThread();
2776 EXPECT_TRUE(child_layer_->update_rect().IsEmpty());
2777 break;
2778 case 4:
2779 EXPECT_TRUE(child_layer_->update_rect().IsEmpty());
2780 layer_tree_host()->SetDisplayColorSpaces(space1_);
2781 EXPECT_FALSE(child_layer_->update_rect().IsEmpty());
2782 break;
2783 case 5:
2784 EXPECT_TRUE(child_layer_->update_rect().IsEmpty());
2785 PostSetNeedsCommitToMainThread();
2786 break;
2787 case 6:
2788 break;
2789 default:
2790 NOTREACHED();
2791 break;
2792 }
2793 }
2794
2795 private:
2796 gfx::DisplayColorSpaces space1_;
2797 gfx::DisplayColorSpaces space2_;
2798 FakeContentLayerClient client_;
2799 scoped_refptr<Layer> root_layer_;
2800 scoped_refptr<Layer> child_layer_;
2801 };
2802
2803 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRasterColorSpaceChange);
2804
2805 class LayerTreeHostTestSetNeedsCommitWithForcedRedraw
2806 : public LayerTreeHostTest {
2807 public:
LayerTreeHostTestSetNeedsCommitWithForcedRedraw()2808 LayerTreeHostTestSetNeedsCommitWithForcedRedraw()
2809 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
2810
BeginTest()2811 void BeginTest() override {
2812 root_layer_ = FakePictureLayer::Create(&client_);
2813 root_layer_->SetIsDrawable(true);
2814 root_layer_->SetBounds(bounds_);
2815 layer_tree_host()->SetRootLayer(root_layer_);
2816 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds_), 1.f,
2817 viz::LocalSurfaceId());
2818 PostSetNeedsCommitToMainThread();
2819 client_.set_bounds(root_layer_->bounds());
2820 }
2821
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)2822 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
2823 if (num_draws_ == 3) {
2824 host_impl->SetViewportDamage(invalid_rect_);
2825 host_impl->SetNeedsRedraw();
2826 }
2827 }
2828
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)2829 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2830 LayerTreeHostImpl::FrameData* frame_data,
2831 DrawResult draw_result) override {
2832 EXPECT_EQ(DRAW_SUCCESS, draw_result);
2833
2834 gfx::Rect root_damage_rect;
2835 if (!frame_data->render_passes.empty())
2836 root_damage_rect = frame_data->render_passes.back()->damage_rect;
2837
2838 switch (num_draws_) {
2839 case 0:
2840 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
2841 break;
2842 case 1:
2843 case 2:
2844 EXPECT_EQ(gfx::Rect(), root_damage_rect);
2845 break;
2846 case 3:
2847 EXPECT_EQ(invalid_rect_, root_damage_rect);
2848 break;
2849 case 4:
2850 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect);
2851 break;
2852 default:
2853 NOTREACHED();
2854 }
2855
2856 return draw_result;
2857 }
2858
DrawLayersOnThread(LayerTreeHostImpl * host_impl)2859 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
2860 switch (num_draws_) {
2861 case 0:
2862 case 1:
2863 // Cycle through a couple of empty commits to ensure we're observing the
2864 // right behavior
2865 PostSetNeedsCommitToMainThread();
2866 break;
2867 case 2:
2868 // Should force full frame damage on the next commit
2869 PostSetNeedsCommitWithForcedRedrawToMainThread();
2870 host_impl->BlockNotifyReadyToActivateForTesting(true);
2871 break;
2872 case 3:
2873 host_impl->BlockNotifyReadyToActivateForTesting(false);
2874 break;
2875 default:
2876 EndTest();
2877 break;
2878 }
2879 num_draws_++;
2880 }
2881
AfterTest()2882 void AfterTest() override { EXPECT_EQ(5, num_draws_); }
2883
2884 private:
2885 int num_draws_;
2886 const gfx::Size bounds_;
2887 const gfx::Rect invalid_rect_;
2888 FakeContentLayerClient client_;
2889 scoped_refptr<FakePictureLayer> root_layer_;
2890 };
2891
2892 // This test blocks activation which is not supported for single thread mode.
2893 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
2894 LayerTreeHostTestSetNeedsCommitWithForcedRedraw);
2895
2896 // Tests that if a layer is not drawn because of some reason in the parent then
2897 // its damage is preserved until the next time it is drawn.
2898 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
2899 public:
SetupTree()2900 void SetupTree() override {
2901 root_layer_ = FakePictureLayer::Create(&client_);
2902 root_layer_->SetIsDrawable(true);
2903 root_layer_->SetBounds(gfx::Size(50, 50));
2904 layer_tree_host()->SetRootLayer(root_layer_);
2905
2906 // The initially transparent layer has a larger child layer, which is
2907 // not initially drawn because of the this (parent) layer.
2908 parent_layer_ = FakePictureLayer::Create(&client_);
2909 parent_layer_->SetBounds(gfx::Size(15, 15));
2910 parent_layer_->SetOpacity(0.0f);
2911 root_layer_->AddChild(parent_layer_);
2912
2913 child_layer_ = FakePictureLayer::Create(&client_);
2914 child_layer_->SetBounds(gfx::Size(25, 25));
2915 parent_layer_->AddChild(child_layer_);
2916 client_.set_bounds(root_layer_->bounds());
2917
2918 LayerTreeHostTest::SetupTree();
2919 }
2920
BeginTest()2921 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
2922
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)2923 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
2924 LayerTreeHostImpl::FrameData* frame_data,
2925 DrawResult draw_result) override {
2926 EXPECT_EQ(DRAW_SUCCESS, draw_result);
2927
2928 gfx::Rect root_damage_rect;
2929 if (!frame_data->render_passes.empty())
2930 root_damage_rect = frame_data->render_passes.back()->damage_rect;
2931
2932 // The first time, the whole view needs be drawn.
2933 // Afterwards, just the opacity of surface_layer1 is changed a few times,
2934 // and each damage should be the bounding box of it and its child. If this
2935 // was working improperly, the damage might not include its childs bounding
2936 // box.
2937 switch (host_impl->active_tree()->source_frame_number()) {
2938 case 0:
2939 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
2940 break;
2941 case 1:
2942 case 2:
2943 case 3:
2944 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
2945 break;
2946 default:
2947 NOTREACHED();
2948 }
2949
2950 return draw_result;
2951 }
2952
DidCommitAndDrawFrame()2953 void DidCommitAndDrawFrame() override {
2954 switch (layer_tree_host()->SourceFrameNumber()) {
2955 case 1:
2956 // Test not owning the surface.
2957 parent_layer_->SetOpacity(1.0f);
2958 break;
2959 case 2:
2960 parent_layer_->SetOpacity(0.0f);
2961 break;
2962 case 3:
2963 // Test owning the surface.
2964 parent_layer_->SetOpacity(0.5f);
2965 parent_layer_->SetForceRenderSurfaceForTesting(true);
2966 break;
2967 case 4:
2968 EndTest();
2969 break;
2970 default:
2971 NOTREACHED();
2972 }
2973 }
2974
2975 private:
2976 FakeContentLayerClient client_;
2977 scoped_refptr<FakePictureLayer> root_layer_;
2978 scoped_refptr<FakePictureLayer> parent_layer_;
2979 scoped_refptr<FakePictureLayer> child_layer_;
2980 };
2981
2982 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
2983
2984 // Tests that if a layer is not drawn because of some reason in the parent then
2985 // its damage is preserved until the next time it is drawn.
2986 class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest {
2987 public:
2988 LayerTreeHostTestDamageWithScale() = default;
2989
SetupTree()2990 void SetupTree() override {
2991 client_.set_fill_with_nonsolid_color(true);
2992
2993 std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource);
2994 root_layer_ = FakePictureLayer::CreateWithRecordingSource(
2995 &client_, std::move(recording));
2996 root_layer_->SetBounds(gfx::Size(50, 50));
2997
2998 recording.reset(new FakeRecordingSource);
2999 child_layer_ = FakePictureLayer::CreateWithRecordingSource(
3000 &client_, std::move(recording));
3001 child_layer_->SetBounds(gfx::Size(25, 25));
3002 child_layer_->SetIsDrawable(true);
3003 child_layer_->SetContentsOpaque(true);
3004 root_layer_->AddChild(child_layer_);
3005
3006 layer_tree_host()->SetRootLayer(root_layer_);
3007 LayerTreeHostTest::SetupTree();
3008 client_.set_bounds(root_layer_->bounds());
3009 }
3010
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)3011 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
3012 // Force the layer to have a tiling at 1.3f scale. Note that if we simply
3013 // add tiling, it will be gone by the time we draw because of aggressive
3014 // cleanup. AddTilingUntilNextDraw ensures that it remains there during
3015 // damage calculation.
3016 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
3017 host_impl->active_tree()->LayerById(child_layer_->id()));
3018 child_layer_impl->AddTilingUntilNextDraw(1.3f);
3019 }
3020
BeginTest()3021 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3022
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)3023 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3024 LayerTreeHostImpl::FrameData* frame_data,
3025 DrawResult draw_result) override {
3026 EXPECT_EQ(DRAW_SUCCESS, draw_result);
3027
3028 gfx::Rect root_damage_rect;
3029 if (!frame_data->render_passes.empty())
3030 root_damage_rect = frame_data->render_passes.back()->damage_rect;
3031
3032 // The first time, the whole view needs be drawn.
3033 // Afterwards, just the opacity of surface_layer1 is changed a few times,
3034 // and each damage should be the bounding box of it and its child. If this
3035 // was working improperly, the damage might not include its childs bounding
3036 // box.
3037 switch (host_impl->active_tree()->source_frame_number()) {
3038 case 0:
3039 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
3040 break;
3041 case 1: {
3042 FakePictureLayerImpl* child_layer_impl =
3043 static_cast<FakePictureLayerImpl*>(
3044 host_impl->active_tree()->LayerById(child_layer_->id()));
3045 // We remove tilings pretty aggressively if they are not ideal. Add this
3046 // back in so that we can compare
3047 // child_layer_impl->visible_drawable_content_rect() to the damage.
3048 child_layer_impl->AddTilingUntilNextDraw(1.3f);
3049
3050 EXPECT_EQ(gfx::Rect(25, 25), root_damage_rect);
3051 EXPECT_EQ(child_layer_impl->visible_drawable_content_rect(),
3052 root_damage_rect);
3053 EXPECT_TRUE(child_layer_impl->visible_drawable_content_rect().Contains(
3054 gfx::Rect(child_layer_->bounds())));
3055 break;
3056 }
3057 default:
3058 NOTREACHED();
3059 }
3060
3061 return draw_result;
3062 }
3063
DidCommitAndDrawFrame()3064 void DidCommitAndDrawFrame() override {
3065 switch (layer_tree_host()->SourceFrameNumber()) {
3066 case 1: {
3067 // Test not owning the surface.
3068 child_layer_->SetOpacity(0.5f);
3069 break;
3070 }
3071 case 2:
3072 EndTest();
3073 break;
3074 default:
3075 NOTREACHED();
3076 }
3077 }
3078
3079 private:
3080 FakeContentLayerClient client_;
3081 scoped_refptr<Layer> root_layer_;
3082 scoped_refptr<Layer> child_layer_;
3083 };
3084
3085 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDamageWithScale);
3086
3087 // This test verifies that properties on the layer tree host are commited
3088 // to the impl side.
3089 class LayerTreeHostTestCommit : public LayerTreeHostTest {
3090 public:
3091 LayerTreeHostTestCommit() = default;
3092
BeginTest()3093 void BeginTest() override {
3094 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(20, 20), 1.f,
3095 viz::LocalSurfaceId());
3096 layer_tree_host()->set_background_color(SK_ColorGRAY);
3097 layer_tree_host()->SetEventListenerProperties(
3098 EventListenerClass::kMouseWheel, EventListenerProperties::kPassive);
3099 layer_tree_host()->SetEventListenerProperties(
3100 EventListenerClass::kTouchStartOrMove,
3101 EventListenerProperties::kBlocking);
3102 layer_tree_host()->SetEventListenerProperties(
3103 EventListenerClass::kTouchEndOrCancel,
3104 EventListenerProperties::kBlockingAndPassive);
3105 layer_tree_host()->SetHaveScrollEventHandlers(true);
3106
3107 PostSetNeedsCommitToMainThread();
3108 }
3109
DidActivateTreeOnThread(LayerTreeHostImpl * impl)3110 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3111 EXPECT_EQ(gfx::Rect(20, 20), impl->active_tree()->GetDeviceViewport());
3112 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
3113 EXPECT_EQ(EventListenerProperties::kPassive,
3114 impl->active_tree()->event_listener_properties(
3115 EventListenerClass::kMouseWheel));
3116 EXPECT_EQ(EventListenerProperties::kBlocking,
3117 impl->active_tree()->event_listener_properties(
3118 EventListenerClass::kTouchStartOrMove));
3119 EXPECT_EQ(EventListenerProperties::kBlockingAndPassive,
3120 impl->active_tree()->event_listener_properties(
3121 EventListenerClass::kTouchEndOrCancel));
3122 EXPECT_TRUE(impl->active_tree()->have_scroll_event_handlers());
3123
3124 EndTest();
3125 }
3126 };
3127
3128 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
3129
3130 // This test verifies that LayerTreeHostImpl's current frame time gets
3131 // updated in consecutive frames when it doesn't draw due to tree
3132 // activation failure.
3133 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
3134 : public LayerTreeHostTest {
3135 public:
LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()3136 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
3137 : frame_count_with_pending_tree_(0) {}
3138
BeginTest()3139 void BeginTest() override {
3140 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(20, 20), 1.f,
3141 viz::LocalSurfaceId());
3142 layer_tree_host()->set_background_color(SK_ColorGRAY);
3143
3144 PostSetNeedsCommitToMainThread();
3145 }
3146
BeginCommitOnThread(LayerTreeHostImpl * impl)3147 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
3148 EXPECT_EQ(frame_count_with_pending_tree_, 0);
3149 impl->BlockNotifyReadyToActivateForTesting(true);
3150 }
3151
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const viz::BeginFrameArgs & args)3152 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
3153 const viz::BeginFrameArgs& args) override {
3154 if (impl->pending_tree())
3155 frame_count_with_pending_tree_++;
3156
3157 if (frame_count_with_pending_tree_ == 1) {
3158 EXPECT_EQ(base::TimeTicks(), first_frame_time_);
3159 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
3160 } else if (frame_count_with_pending_tree_ == 2) {
3161 impl->BlockNotifyReadyToActivateForTesting(false);
3162 }
3163 }
3164
DrawLayersOnThread(LayerTreeHostImpl * impl)3165 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
3166 EXPECT_GT(frame_count_with_pending_tree_, 1);
3167 EXPECT_NE(base::TimeTicks(), first_frame_time_);
3168 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
3169 EndTest();
3170 }
3171
DidActivateTreeOnThread(LayerTreeHostImpl * impl)3172 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3173 EXPECT_GT(frame_count_with_pending_tree_, 1);
3174 }
3175
3176 private:
3177 int frame_count_with_pending_tree_;
3178 base::TimeTicks first_frame_time_;
3179 };
3180
3181 // This test blocks activation which is not supported for single thread mode.
3182 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
3183 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
3184
3185 // This test verifies that LayerTreeHostImpl's current frame time gets
3186 // updated in consecutive frames when it draws in each frame.
3187 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
3188 public:
LayerTreeHostTestFrameTimeUpdatesAfterDraw()3189 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
3190
BeginTest()3191 void BeginTest() override {
3192 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(20, 20), 1.f,
3193 viz::LocalSurfaceId());
3194 layer_tree_host()->set_background_color(SK_ColorGRAY);
3195
3196 PostSetNeedsCommitToMainThread();
3197 }
3198
DrawLayersOnThread(LayerTreeHostImpl * impl)3199 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
3200 frame_++;
3201 if (frame_ == 1) {
3202 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
3203 impl->SetNeedsRedraw();
3204
3205 // Since we might use a low-resolution clock on Windows, we need to
3206 // make sure that the clock has incremented past first_frame_time_.
3207 while (first_frame_time_ == base::TimeTicks::Now()) {
3208 }
3209
3210 return;
3211 }
3212
3213 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
3214 EndTest();
3215 }
3216
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)3217 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3218 // Ensure there isn't a commit between the two draws, to ensure that a
3219 // commit isn't required for updating the current frame time. We can
3220 // only check for this in the multi-threaded case, since in the single-
3221 // threaded case there will always be a commit between consecutive draws.
3222 if (HasImplThread())
3223 EXPECT_EQ(0, frame_);
3224 }
3225
3226 private:
3227 int frame_;
3228 base::TimeTicks first_frame_time_;
3229 };
3230
3231 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
3232
3233 // Verifies that StartPageScaleAnimation events propagate correctly
3234 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
3235 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
3236 public:
LayerTreeHostTestStartPageScaleAnimation()3237 LayerTreeHostTestStartPageScaleAnimation() { SetUseLayerLists(); }
3238
SetupTree()3239 void SetupTree() override {
3240 LayerTreeHostTest::SetupTree();
3241
3242 Layer* root_layer = layer_tree_host()->root_layer();
3243
3244 scroll_layer_ = FakePictureLayer::Create(&client_);
3245 scroll_layer_->set_always_update_resources(true);
3246
3247 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
3248 2 * root_layer->bounds().height()));
3249 scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
3250
3251 SetupViewport(root_layer, scroll_layer_, root_layer->bounds());
3252
3253 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
3254 client_.set_bounds(root_layer->bounds());
3255 }
3256
BeginTest()3257 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3258
ApplyViewportChanges(const ApplyViewportChangesArgs & args)3259 void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
3260 gfx::ScrollOffset offset = CurrentScrollOffset(scroll_layer_.get());
3261 SetScrollOffset(scroll_layer_.get(), offset + args.inner_delta);
3262 layer_tree_host()->SetPageScaleFactorAndLimits(args.page_scale_delta, 0.5f,
3263 2.f);
3264 }
3265
DidActivateTreeOnThread(LayerTreeHostImpl * impl)3266 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3267 // We get one commit before the first draw, and the animation doesn't happen
3268 // until the second draw.
3269 switch (impl->active_tree()->source_frame_number()) {
3270 case 0:
3271 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
3272 // We'll start an animation when we get back to the main thread.
3273 break;
3274 case 1:
3275 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
3276 // Once the animation starts, an ImplFrame will be requested. However,
3277 // main frames may be happening in the mean-time due to high-latency
3278 // mode. If one happens before the next impl frame, then the source
3279 // frame number may increment twice instead of just once.
3280 break;
3281 case 2:
3282 case 3:
3283 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
3284 EndTest();
3285 break;
3286 }
3287 }
3288
DidCommitAndDrawFrame()3289 void DidCommitAndDrawFrame() override {
3290 switch (layer_tree_host()->SourceFrameNumber()) {
3291 case 1:
3292 layer_tree_host()->StartPageScaleAnimation(gfx::Vector2d(), false,
3293 1.25f, base::TimeDelta());
3294 break;
3295 }
3296 }
3297
3298 FakeContentLayerClient client_;
3299 scoped_refptr<FakePictureLayer> scroll_layer_;
3300 };
3301
3302 // Single thread proxy does not support impl-side page scale changes.
3303 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
3304
3305 class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest,
3306 public ScrollCallbacks {
3307 protected:
ViewportDeltasAppliedDuringPinch()3308 ViewportDeltasAppliedDuringPinch() : sent_gesture_(false) {
3309 SetUseLayerLists();
3310 }
3311
SetupTree()3312 void SetupTree() override {
3313 SetInitialRootBounds(gfx::Size(200, 200));
3314 LayerTreeHostTest::SetupTree();
3315 Layer* root = layer_tree_host()->root_layer();
3316 SetupViewport(root, gfx::Size(500, 500), gfx::Size(500, 500));
3317 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
3318 layer_tree_host()->property_trees()->scroll_tree.SetScrollCallbacks(
3319 weak_ptr_factory_.GetWeakPtr());
3320 }
3321
BeginTest()3322 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3323
DrawLayersOnThread(LayerTreeHostImpl * host_impl)3324 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
3325 if (!sent_gesture_) {
3326 host_impl->GetInputHandler().PinchGestureBegin();
3327 host_impl->GetInputHandler().PinchGestureUpdate(2, gfx::Point(100, 100));
3328 host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100), true);
3329 sent_gesture_ = true;
3330 }
3331 }
3332
ApplyViewportChanges(const ApplyViewportChangesArgs & args)3333 void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
3334 EXPECT_TRUE(sent_gesture_);
3335 EXPECT_EQ(gfx::ScrollOffset(50, 50), args.inner_delta);
3336 EXPECT_EQ(2, args.page_scale_delta);
3337
3338 auto* scroll_layer =
3339 layer_tree_host()->InnerViewportScrollLayerForTesting();
3340 EXPECT_EQ(scroll_layer->element_id(), last_scrolled_element_id_);
3341 EXPECT_EQ(gfx::ScrollOffset(50, 50), last_scrolled_offset_);
3342 // The scroll offset in the scroll tree is typically updated from blink
3343 // which doesn't exist in this test. Because we preemptively apply the
3344 // scroll offset in LayerTreeHost::UpdateScrollOffsetFromImpl, the current
3345 // scroll offset will still be updated.
3346 EXPECT_EQ(gfx::ScrollOffset(50, 50), CurrentScrollOffset(scroll_layer));
3347 EndTest();
3348 }
3349
AfterTest()3350 void AfterTest() override { EXPECT_TRUE(sent_gesture_); }
3351
3352 // ScrollCallbacks
DidScroll(ElementId element_id,const gfx::ScrollOffset & scroll_offset,const base::Optional<TargetSnapAreaElementIds> & snap_target_ids)3353 void DidScroll(ElementId element_id,
3354 const gfx::ScrollOffset& scroll_offset,
3355 const base::Optional<TargetSnapAreaElementIds>&
3356 snap_target_ids) override {
3357 last_scrolled_element_id_ = element_id;
3358 last_scrolled_offset_ = scroll_offset;
3359 }
DidChangeScrollbarsHidden(ElementId,bool)3360 void DidChangeScrollbarsHidden(ElementId, bool) override {}
3361
3362 private:
3363 bool sent_gesture_;
3364 ElementId last_scrolled_element_id_;
3365 gfx::ScrollOffset last_scrolled_offset_;
3366 base::WeakPtrFactory<ViewportDeltasAppliedDuringPinch> weak_ptr_factory_{
3367 this};
3368 };
3369
3370 MULTI_THREAD_TEST_F(ViewportDeltasAppliedDuringPinch);
3371
3372 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
3373 public:
LayerTreeHostTestSetVisible()3374 LayerTreeHostTestSetVisible() : num_draws_(0) {}
3375
BeginTest()3376 void BeginTest() override {
3377 PostSetNeedsCommitToMainThread();
3378 }
3379
WillCommit()3380 void WillCommit() override {
3381 PostSetVisibleToMainThread(false);
3382 // This is suppressed while we're invisible.
3383 PostSetNeedsRedrawToMainThread();
3384 // Triggers the redraw.
3385 PostSetVisibleToMainThread(true);
3386 }
3387
DrawLayersOnThread(LayerTreeHostImpl * impl)3388 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
3389 EXPECT_TRUE(impl->visible());
3390 ++num_draws_;
3391 EndTest();
3392 }
3393
AfterTest()3394 void AfterTest() override { EXPECT_EQ(1, num_draws_); }
3395
3396 private:
3397 int num_draws_;
3398 };
3399
3400 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
3401
3402 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
3403 : public LayerTreeHostTest {
3404 public:
3405 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() = default;
3406
BeginTest()3407 void BeginTest() override {
3408 client_.set_fill_with_nonsolid_color(true);
3409 root_layer_ = FakePictureLayer::Create(&client_);
3410 child_layer_ = FakePictureLayer::Create(&client_);
3411
3412 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(60, 60), 1.5f,
3413 viz::LocalSurfaceId());
3414 EXPECT_EQ(gfx::Size(60, 60),
3415 layer_tree_host()->device_viewport_rect().size());
3416
3417 root_layer_->AddChild(child_layer_);
3418
3419 root_layer_->SetIsDrawable(true);
3420 root_layer_->SetBounds(gfx::Size(30, 30));
3421
3422 child_layer_->SetIsDrawable(true);
3423 child_layer_->SetPosition(gfx::PointF(2.f, 2.f));
3424 child_layer_->SetBounds(gfx::Size(10, 10));
3425 client_.set_bounds(gfx::Size(10, 10));
3426
3427 layer_tree_host()->SetRootLayer(root_layer_);
3428
3429 PostSetNeedsCommitToMainThread();
3430 client_.set_bounds(root_layer_->bounds());
3431 }
3432
DidActivateTreeOnThread(LayerTreeHostImpl * impl)3433 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
3434 // Should only do one commit.
3435 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
3436 // Device scale factor should come over to impl.
3437 EXPECT_NEAR(impl->active_tree()->device_scale_factor(), 1.5f, 0.00001f);
3438
3439 // Device viewport is scaled.
3440 EXPECT_EQ(gfx::Rect(60, 60), impl->active_tree()->GetDeviceViewport());
3441
3442 FakePictureLayerImpl* root =
3443 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
3444 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>(
3445 impl->active_tree()->LayerById(child_layer_->id()));
3446
3447 // Compute all the layer transforms for the frame.
3448 LayerTreeHostImpl::FrameData frame_data;
3449 impl->PrepareToDraw(&frame_data);
3450 impl->DidDrawAllLayers(frame_data);
3451
3452 const RenderSurfaceList& render_surface_list =
3453 *frame_data.render_surface_list;
3454
3455 // Both layers should be drawing into the root render surface.
3456 ASSERT_EQ(1u, render_surface_list.size());
3457 ASSERT_EQ(GetRenderSurface(root), render_surface_list[0]);
3458 ASSERT_EQ(2, GetRenderSurface(root)->num_contributors());
3459
3460 // The root render surface is the size of the viewport.
3461 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), GetRenderSurface(root)->content_rect());
3462
3463 // The max tiling scale of the child should be scaled.
3464 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale());
3465
3466 gfx::Transform scale_transform;
3467 scale_transform.Scale(impl->active_tree()->device_scale_factor(),
3468 impl->active_tree()->device_scale_factor());
3469
3470 // The root layer is scaled by 2x.
3471 gfx::Transform root_screen_space_transform = scale_transform;
3472 gfx::Transform root_draw_transform = scale_transform;
3473
3474 EXPECT_EQ(root_draw_transform, root->DrawTransform());
3475 EXPECT_EQ(root_screen_space_transform, root->ScreenSpaceTransform());
3476
3477 // The child is at position 2,2, which is transformed to 3,3 after the scale
3478 gfx::Transform child_transform;
3479 child_transform.Translate(3.f, 3.f);
3480 child_transform.Scale(child->MaximumTilingContentsScale(),
3481 child->MaximumTilingContentsScale());
3482
3483 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->DrawTransform());
3484 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform,
3485 child->ScreenSpaceTransform());
3486
3487 EndTest();
3488 }
3489
3490 private:
3491 FakeContentLayerClient client_;
3492 scoped_refptr<FakePictureLayer> root_layer_;
3493 scoped_refptr<FakePictureLayer> child_layer_;
3494 };
3495
3496 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
3497
3498 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
3499 public:
LayerTreeHostTestContinuousInvalidate()3500 LayerTreeHostTestContinuousInvalidate()
3501 : num_commit_complete_(0), num_draw_layers_(0) {}
3502
BeginTest()3503 void BeginTest() override {
3504 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
3505 viz::LocalSurfaceId());
3506 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
3507
3508 layer_ = FakePictureLayer::Create(&client_);
3509 layer_->SetBounds(gfx::Size(10, 10));
3510 layer_->SetPosition(gfx::PointF(0.f, 0.f));
3511 layer_->SetIsDrawable(true);
3512 layer_tree_host()->root_layer()->AddChild(layer_);
3513
3514 PostSetNeedsCommitToMainThread();
3515 client_.set_bounds(layer_->bounds());
3516 }
3517
DidCommitAndDrawFrame()3518 void DidCommitAndDrawFrame() override {
3519 if (num_draw_layers_ == 2)
3520 return;
3521 layer_->SetNeedsDisplay();
3522 }
3523
CommitCompleteOnThread(LayerTreeHostImpl * impl)3524 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
3525 if (num_draw_layers_ == 1)
3526 num_commit_complete_++;
3527 }
3528
DrawLayersOnThread(LayerTreeHostImpl * impl)3529 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
3530 num_draw_layers_++;
3531 if (num_draw_layers_ == 2)
3532 EndTest();
3533 }
3534
AfterTest()3535 void AfterTest() override {
3536 // Check that we didn't commit twice between first and second draw.
3537 EXPECT_EQ(1, num_commit_complete_);
3538 }
3539
3540 private:
3541 FakeContentLayerClient client_;
3542 scoped_refptr<Layer> layer_;
3543 int num_commit_complete_;
3544 int num_draw_layers_;
3545 };
3546
3547 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
3548
3549 class LayerTreeHostTestDeferMainFrameUpdate : public LayerTreeHostTest {
3550 public:
3551 LayerTreeHostTestDeferMainFrameUpdate() = default;
3552
BeginTest()3553 void BeginTest() override {
3554 // Start with commits deferred.
3555 PostGetDeferMainFrameUpdateToMainThread(&scoped_defer_main_frame_update_);
3556 PostSetNeedsCommitToMainThread();
3557 }
3558
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)3559 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
3560 const viz::BeginFrameArgs& args) override {
3561 // Impl frames happen while commits are deferred.
3562 num_will_begin_impl_frame_++;
3563 switch (num_will_begin_impl_frame_) {
3564 case 1:
3565 case 2:
3566 case 3:
3567 case 4:
3568 // Post a number of frames to increase the chance that, if there exist
3569 // bugs, an unexpected BeginMainFrame will be issued.
3570 PostSetNeedsCommitToMainThread();
3571 PostSetNeedsRedrawToMainThread();
3572 break;
3573 case 5:
3574 MainThreadTaskRunner()->PostTask(
3575 FROM_HERE,
3576 // Unretained because the test should not end before allowing
3577 // commits via this running.
3578 base::BindOnce(&LayerTreeHostTestDeferMainFrameUpdate::AllowCommits,
3579 base::Unretained(this)));
3580 break;
3581 default:
3582 // Sometimes |num_will_begin_impl_frame_| will be greater than 5 if the
3583 // main thread is slow to respond.
3584 break;
3585 }
3586 }
3587
WillBeginMainFrame()3588 void WillBeginMainFrame() override {
3589 EXPECT_FALSE(scoped_defer_main_frame_update_);
3590 EXPECT_TRUE(IsCommitAllowed());
3591 num_send_begin_main_frame_++;
3592 EndTest();
3593 }
3594
AfterTest()3595 void AfterTest() override {
3596 EXPECT_GE(num_will_begin_impl_frame_, 5);
3597 EXPECT_EQ(1, num_send_begin_main_frame_);
3598 }
3599
AllowCommits()3600 virtual void AllowCommits() {
3601 allow_commits_ = true;
3602 scoped_defer_main_frame_update_.reset();
3603 }
3604
IsCommitAllowed() const3605 virtual bool IsCommitAllowed() const { return allow_commits_; }
3606
3607 private:
3608 std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
3609 bool allow_commits_ = false;
3610 int num_will_begin_impl_frame_ = 0;
3611 int num_send_begin_main_frame_ = 0;
3612 };
3613
3614 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferMainFrameUpdate);
3615
3616 // This verifies that changing the size of a LayerTreeHost without providing a
3617 // LocalSurfaceId defers commits.
3618 class LayerTreeHostInvalidLocalSurfaceIdDefersCommit
3619 : public LayerTreeHostTestDeferMainFrameUpdate {
3620 public:
LayerTreeHostInvalidLocalSurfaceIdDefersCommit()3621 LayerTreeHostInvalidLocalSurfaceIdDefersCommit() {
3622 SkipAllocateInitialLocalSurfaceId();
3623 }
BeginTest()3624 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3625
AllowCommits()3626 void AllowCommits() override {
3627 GenerateNewLocalSurfaceId();
3628 PostSetLocalSurfaceIdToMainThread(GetCurrentLocalSurfaceId());
3629 }
3630
IsCommitAllowed() const3631 bool IsCommitAllowed() const override {
3632 return GetCurrentLocalSurfaceId().is_valid();
3633 }
3634 };
3635
3636 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostInvalidLocalSurfaceIdDefersCommit);
3637
3638 // This verifies that we can abort a commit inside the main frame, and
3639 // we don't leave any weird states around if we never allow the commit
3640 // to happen.
3641 class LayerTreeHostTestDeferMainFrameUpdateInsideBeginMainFrame
3642 : public LayerTreeHostTest {
3643 public:
3644 LayerTreeHostTestDeferMainFrameUpdateInsideBeginMainFrame() = default;
3645
BeginTest()3646 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3647
WillBeginMainFrame()3648 void WillBeginMainFrame() override {
3649 ++begin_main_frame_count_;
3650
3651 // This should prevent the commit from happening.
3652 scoped_defer_main_frame_update_ = layer_tree_host()->DeferMainFrameUpdate();
3653 // Wait to see if the commit happens. It's possible the deferred
3654 // commit happens when it shouldn't but takes long enough that
3655 // this passes. But it won't fail when it shouldn't.
3656 MainThreadTaskRunner()->PostDelayedTask(
3657 FROM_HERE,
3658 // Unretained because the test doesn't end before this runs.
3659 base::BindOnce(&LayerTreeTest::EndTest, base::Unretained(this)),
3660 base::TimeDelta::FromMilliseconds(100));
3661 }
3662
DidCommit()3663 void DidCommit() override { ++commit_count_; }
3664
AfterTest()3665 void AfterTest() override {
3666 EXPECT_EQ(0, commit_count_);
3667 EXPECT_EQ(1, begin_main_frame_count_);
3668 }
3669
3670 private:
3671 std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
3672 int commit_count_ = 0;
3673 int begin_main_frame_count_ = 0;
3674 };
3675
3676 SINGLE_AND_MULTI_THREAD_TEST_F(
3677 LayerTreeHostTestDeferMainFrameUpdateInsideBeginMainFrame);
3678
3679 // This verifies that we can abort a commit inside the main frame, and
3680 // we will finish the commit once it is allowed.
3681 class LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter
3682 : public LayerTreeHostTest {
3683 public:
3684 LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter() = default;
3685
BeginTest()3686 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3687
WillBeginMainFrame()3688 void WillBeginMainFrame() override {
3689 ++begin_main_frame_count_;
3690 if (allow_commits_)
3691 return;
3692
3693 // This should prevent the commit from happening.
3694 scoped_defer_main_frame_update_ = layer_tree_host()->DeferMainFrameUpdate();
3695 // Wait to see if the commit happens. It's possible the deferred
3696 // commit happens when it shouldn't but takes long enough that
3697 // this passes. But it won't fail when it shouldn't.
3698 MainThreadTaskRunner()->PostDelayedTask(
3699 FROM_HERE,
3700 // Unretained because the test doesn't end before this runs.
3701 base::BindOnce(
3702 &LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter::
3703 AllowCommits,
3704 base::Unretained(this)),
3705 base::TimeDelta::FromMilliseconds(100));
3706 }
3707
AllowCommits()3708 void AllowCommits() {
3709 // Once we've waited and seen that commit did not happen, we
3710 // allow commits and should see this one go through.
3711 allow_commits_ = true;
3712 scoped_defer_main_frame_update_.reset();
3713 }
3714
DidCommit()3715 void DidCommit() override {
3716 ++commit_count_;
3717 EXPECT_TRUE(allow_commits_);
3718 EndTest();
3719 }
3720
AfterTest()3721 void AfterTest() override {
3722 EXPECT_EQ(1, commit_count_);
3723 EXPECT_EQ(2, begin_main_frame_count_);
3724 // The commit should not have been aborted.
3725 EXPECT_EQ(1, ready_to_commit_count_);
3726 }
3727
ReadyToCommitOnThread(LayerTreeHostImpl * host_impl)3728 void ReadyToCommitOnThread(LayerTreeHostImpl* host_impl) override {
3729 ++ready_to_commit_count_;
3730 }
3731
3732 private:
3733 std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
3734 bool allow_commits_ = false;
3735 int commit_count_ = 0;
3736 int begin_main_frame_count_ = 0;
3737 int ready_to_commit_count_ = 0;
3738 };
3739
3740 SINGLE_AND_MULTI_THREAD_TEST_F(
3741 LayerTreeHostTestDeferInsideBeginMainFrameWithCommitAfter);
3742
3743 // This verifies that animate_only BeginFrames only run animation/layout
3744 // updates, i.e. abort commits after the paint stage and only request layer
3745 // tree updates for layout.
3746 //
3747 // The tests sends five Begin(Main)Frames in sequence: four animate_only
3748 // Begin(Main)Frames followed by a normal Begin(Main)Frame. The first frame
3749 // has animate_only force to false by CompositorFrameSinkSupport, since it
3750 // needs a complete frame to assure surface activation. Frames 2-4 should
3751 // result in aborted commits, whereas the last one should complete the
3752 // previously aborted commits.
3753 //
3754 // Between BeginMainFrames 3 and 4, the client also requests a new commit
3755 // (SetNeedsCommit), but not between BeginMainFrames 1-3. In multi-threaded
3756 // mode, ProxyMain will run the animate pipeline stage only for BeginMainFrames
3757 // 2 and 4, as no new commit was requested between 2 and 3.
3758 //
3759 // The test uses the full-pipeline mode to ensure that each BeginFrame also
3760 // incurs a BeginMainFrame.
3761 class LayerTreeHostTestAnimateOnlyBeginFrames
3762 : public LayerTreeHostTest,
3763 public viz::ExternalBeginFrameSourceClient {
3764 public:
LayerTreeHostTestAnimateOnlyBeginFrames()3765 LayerTreeHostTestAnimateOnlyBeginFrames()
3766 : external_begin_frame_source_(this) {
3767 UseBeginFrameSource(&external_begin_frame_source_);
3768 }
3769
IssueBeginFrame(bool animate_only)3770 void IssueBeginFrame(bool animate_only) {
3771 ++begin_frame_count_;
3772
3773 last_begin_frame_time_ += viz::BeginFrameArgs::DefaultInterval();
3774 uint64_t sequence_number = next_begin_frame_sequence_number_++;
3775
3776 auto args = viz::BeginFrameArgs::Create(
3777 BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId,
3778 sequence_number, last_begin_frame_time_,
3779 last_begin_frame_time_ + viz::BeginFrameArgs::DefaultInterval(),
3780 viz::BeginFrameArgs::DefaultInterval(), viz::BeginFrameArgs::NORMAL);
3781 args.animate_only = animate_only;
3782
3783 external_begin_frame_source_.OnBeginFrame(args);
3784 }
3785
PostIssueBeginFrame(bool animate_only)3786 void PostIssueBeginFrame(bool animate_only) {
3787 // Post a new task so that BeginFrame is not issued within same callstack.
3788 ImplThreadTaskRunner()->PostTask(
3789 FROM_HERE,
3790 base::BindOnce(
3791 &LayerTreeHostTestAnimateOnlyBeginFrames::IssueBeginFrame,
3792 base::Unretained(this), animate_only));
3793 }
3794
3795 // viz::ExternalBeginFrameSourceClient implementation:
OnNeedsBeginFrames(bool needs_begin_frames)3796 void OnNeedsBeginFrames(bool needs_begin_frames) override {
3797 if (needs_begin_frames) {
3798 EXPECT_EQ(0, begin_frame_count_);
3799 // Send a first animation_only BeginFrame.
3800 PostIssueBeginFrame(true);
3801 }
3802 }
3803
3804 // LayerTreeHostTest implementation:
BeginTest()3805 void BeginTest() override {
3806 PostSetNeedsCommitToMainThread();
3807 // OnNeedsBeginFrames(true) will be called during tree initialization.
3808 }
3809
WillBeginMainFrame()3810 void WillBeginMainFrame() override { ++will_begin_main_frame_count_; }
3811
DidSendBeginMainFrameOnThread(LayerTreeHostImpl * host_impl)3812 void DidSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) override {
3813 ++sent_begin_main_frame_count_;
3814 EXPECT_GE(begin_frame_count_, sent_begin_main_frame_count_);
3815 }
3816
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)3817 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
3818 const viz::BeginFrameArgs& args) override {
3819 EXPECT_EQ(args.animate_only,
3820 (begin_frame_count_ >= 2 && begin_frame_count_ <= 4));
3821 }
3822
DidFinishImplFrameOnThread(LayerTreeHostImpl * host_impl)3823 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
3824 EXPECT_LE(sent_begin_main_frame_count_, begin_frame_count_);
3825 if (begin_frame_count_ < 3) {
3826 // Send another animation_only BeginFrame.
3827 PostIssueBeginFrame(true);
3828 } else if (begin_frame_count_ == 3) {
3829 MainThreadTaskRunner()->PostTaskAndReply(
3830 FROM_HERE,
3831 base::BindOnce(&LayerTreeHostTestAnimateOnlyBeginFrames::
3832 SetNeedsCommitOnMainThread,
3833 base::Unretained(this)),
3834 base::BindOnce(
3835 &LayerTreeHostTestAnimateOnlyBeginFrames::PostIssueBeginFrame,
3836 base::Unretained(this), true));
3837 } else if (begin_frame_count_ == 4) {
3838 PostIssueBeginFrame(false);
3839 }
3840 }
3841
SetNeedsCommitOnMainThread()3842 void SetNeedsCommitOnMainThread() { layer_tree_host()->SetNeedsCommit(); }
3843
UpdateLayerTreeHost()3844 void UpdateLayerTreeHost() override { ++update_layer_tree_host_count_; }
3845
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)3846 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3847 if (begin_frame_count_ == 1)
3848 host_impl->NotifyReadyToDraw();
3849
3850 ++commit_count_;
3851
3852 // First commit is due to first frame having animate_only forced to false
3853 // in ordser to create the surface.
3854 if (commit_count_ == 1)
3855 return;
3856
3857 // Fourth BeginMainFrame should lead to commit.
3858 EXPECT_EQ(5, begin_frame_count_);
3859 EXPECT_EQ(3, sent_begin_main_frame_count_);
3860
3861 EndTest();
3862 }
3863
ReadyToCommitOnThread(LayerTreeHostImpl * host_impl)3864 void ReadyToCommitOnThread(LayerTreeHostImpl* host_impl) override {
3865 ++ready_to_commit_count_;
3866 }
3867
AfterTest()3868 void AfterTest() override {
3869 EXPECT_EQ(2, commit_count_);
3870 EXPECT_EQ(5, begin_frame_count_);
3871 EXPECT_EQ(3, sent_begin_main_frame_count_);
3872
3873 EXPECT_EQ(3, will_begin_main_frame_count_);
3874 EXPECT_EQ(3, update_layer_tree_host_count_);
3875
3876 // The final commit should not have been aborted.
3877 EXPECT_EQ(2, ready_to_commit_count_);
3878 }
3879
3880 protected:
InitializeSettings(LayerTreeSettings * settings)3881 void InitializeSettings(LayerTreeSettings* settings) override {
3882 // Use full-pipeline mode to make BeginFrame handling deterministic.
3883 EXPECT_FALSE(settings->wait_for_all_pipeline_stages_before_draw);
3884 settings->wait_for_all_pipeline_stages_before_draw = true;
3885 }
3886
3887 private:
3888 viz::ExternalBeginFrameSource external_begin_frame_source_;
3889
3890 base::TimeTicks last_begin_frame_time_ = base::TimeTicks::Now();
3891 uint64_t next_begin_frame_sequence_number_ =
3892 viz::BeginFrameArgs::kStartingFrameNumber;
3893 int commit_count_ = 0;
3894 int begin_frame_count_ = 0;
3895 int sent_begin_main_frame_count_ = 0;
3896 int will_begin_main_frame_count_ = 0;
3897 int update_layer_tree_host_count_ = 0;
3898 int ready_to_commit_count_ = 0;
3899 };
3900
3901 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAnimateOnlyBeginFrames);
3902
3903 class LayerTreeHostTestCompositeImmediatelyStateTransitions
3904 : public LayerTreeHostTest {
3905 public:
3906 enum {
3907 kInvalid,
3908 kStartedTest,
3909 kStartedImplFrame,
3910 kStartedMainFrame,
3911 kStartedCommit,
3912 kCompletedCommit,
3913 kCompletedMainFrame,
3914 kCompletedImplFrame,
3915 };
3916
LayerTreeHostTestCompositeImmediatelyStateTransitions()3917 LayerTreeHostTestCompositeImmediatelyStateTransitions()
3918 : current_state_(kInvalid), current_begin_frame_args_() {}
3919
InitializeSettings(LayerTreeSettings * settings)3920 void InitializeSettings(LayerTreeSettings* settings) override {
3921 settings->single_thread_proxy_scheduler = false;
3922 settings->use_zero_copy = true;
3923 }
3924
BeginTest()3925 void BeginTest() override {
3926 current_state_ = kStartedTest;
3927 PostCompositeImmediatelyToMainThread();
3928 }
3929
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)3930 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
3931 const viz::BeginFrameArgs& args) override {
3932 EXPECT_EQ(current_state_, kStartedTest);
3933 current_state_ = kStartedImplFrame;
3934
3935 EXPECT_FALSE(current_begin_frame_args_.IsValid());
3936 EXPECT_TRUE(args.IsValid());
3937 current_begin_frame_args_ = args;
3938 }
WillBeginMainFrame()3939 void WillBeginMainFrame() override {
3940 EXPECT_EQ(current_state_, kStartedImplFrame);
3941 current_state_ = kStartedMainFrame;
3942 }
BeginMainFrame(const viz::BeginFrameArgs & args)3943 void BeginMainFrame(const viz::BeginFrameArgs& args) override {
3944 EXPECT_EQ(current_state_, kStartedMainFrame);
3945 EXPECT_EQ(args.frame_time, current_begin_frame_args_.frame_time);
3946 }
BeginCommitOnThread(LayerTreeHostImpl * host_impl)3947 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
3948 EXPECT_EQ(current_state_, kStartedMainFrame);
3949 current_state_ = kStartedCommit;
3950 }
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)3951 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3952 EXPECT_EQ(current_state_, kStartedCommit);
3953 current_state_ = kCompletedCommit;
3954 }
DidBeginMainFrame()3955 void DidBeginMainFrame() override {
3956 EXPECT_EQ(current_state_, kCompletedCommit);
3957 current_state_ = kCompletedMainFrame;
3958 }
DidFinishImplFrameOnThread(LayerTreeHostImpl * host_impl)3959 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
3960 EXPECT_EQ(current_state_, kCompletedMainFrame);
3961 current_state_ = kCompletedImplFrame;
3962 EndTest();
3963 }
AfterTest()3964 void AfterTest() override { EXPECT_EQ(current_state_, kCompletedImplFrame); }
3965
3966 private:
3967 int current_state_;
3968 viz::BeginFrameArgs current_begin_frame_args_;
3969 };
3970
3971 SINGLE_THREAD_TEST_F(LayerTreeHostTestCompositeImmediatelyStateTransitions);
3972
3973 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
3974 : public LayerTreeHostTest {
3975 public:
InitializeSettings(LayerTreeSettings * settings)3976 void InitializeSettings(LayerTreeSettings* settings) override {
3977 settings->using_synchronous_renderer_compositor = true;
3978 }
3979
BeginTest()3980 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
3981
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)3982 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
3983 // The BeginFrame notification is turned off now but will get enabled
3984 // once we return. End test while it's enabled.
3985 ImplThreadTaskRunner()->PostTask(
3986 FROM_HERE,
3987 base::BindOnce(&LayerTreeHostTest::EndTest, base::Unretained(this)));
3988 }
3989 };
3990
3991 MULTI_THREAD_TEST_F(
3992 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
3993
3994 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
3995 protected:
LayerTreeHostTestAbortedCommitDoesntStall()3996 LayerTreeHostTestAbortedCommitDoesntStall()
3997 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
3998
BeginTest()3999 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4000
DidCommit()4001 void DidCommit() override {
4002 commit_count_++;
4003 if (commit_count_ == 4) {
4004 // After two aborted commits, request a real commit now to make sure a
4005 // real commit following an aborted commit will still complete and
4006 // end the test even when the Impl thread is idle.
4007 layer_tree_host()->SetNeedsCommit();
4008 }
4009 }
4010
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,CommitEarlyOutReason reason)4011 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
4012 CommitEarlyOutReason reason) override {
4013 commit_abort_count_++;
4014 // Initiate another abortable commit.
4015 host_impl->SetNeedsCommit();
4016 }
4017
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)4018 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
4019 commit_complete_count_++;
4020 if (commit_complete_count_ == 1) {
4021 // Initiate an abortable commit after the first commit.
4022 host_impl->SetNeedsCommit();
4023 } else {
4024 EndTest();
4025 }
4026 }
4027
AfterTest()4028 void AfterTest() override {
4029 EXPECT_EQ(commit_count_, 5);
4030 EXPECT_EQ(commit_abort_count_, 3);
4031 EXPECT_EQ(commit_complete_count_, 2);
4032 }
4033
4034 int commit_count_;
4035 int commit_abort_count_;
4036 int commit_complete_count_;
4037 };
4038
4039 class OnDrawLayerTreeFrameSink : public TestLayerTreeFrameSink {
4040 public:
OnDrawLayerTreeFrameSink(scoped_refptr<viz::ContextProvider> compositor_context_provider,scoped_refptr<viz::RasterContextProvider> worker_context_provider,gpu::GpuMemoryBufferManager * gpu_memory_buffer_manager,const viz::RendererSettings & renderer_settings,const viz::DebugRendererSettings * const debug_settings,base::SingleThreadTaskRunner * task_runner,bool synchronous_composite,double refresh_rate,base::RepeatingClosure invalidate_callback)4041 OnDrawLayerTreeFrameSink(
4042 scoped_refptr<viz::ContextProvider> compositor_context_provider,
4043 scoped_refptr<viz::RasterContextProvider> worker_context_provider,
4044 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
4045 const viz::RendererSettings& renderer_settings,
4046 const viz::DebugRendererSettings* const debug_settings,
4047 base::SingleThreadTaskRunner* task_runner,
4048 bool synchronous_composite,
4049 double refresh_rate,
4050 base::RepeatingClosure invalidate_callback)
4051 : TestLayerTreeFrameSink(std::move(compositor_context_provider),
4052 std::move(worker_context_provider),
4053 gpu_memory_buffer_manager,
4054 renderer_settings,
4055 debug_settings,
4056 task_runner,
4057 synchronous_composite,
4058 false /* disable_display_vsync */,
4059 refresh_rate),
4060 invalidate_callback_(std::move(invalidate_callback)) {}
4061
4062 // TestLayerTreeFrameSink overrides.
Invalidate(bool needs_draw)4063 void Invalidate(bool needs_draw) override { invalidate_callback_.Run(); }
4064
OnDraw(bool resourceless_software_draw)4065 void OnDraw(bool resourceless_software_draw) {
4066 gfx::Transform identity;
4067 gfx::Rect empty_rect;
4068 client_->OnDraw(identity, empty_rect, resourceless_software_draw, false);
4069 }
4070
4071 private:
4072 const base::RepeatingClosure invalidate_callback_;
4073 };
4074
4075 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
4076 : public LayerTreeHostTestAbortedCommitDoesntStall {
4077 protected:
InitializeSettings(LayerTreeSettings * settings)4078 void InitializeSettings(LayerTreeSettings* settings) override {
4079 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
4080 settings->using_synchronous_renderer_compositor = true;
4081 }
4082
CreateLayerTreeFrameSink(const viz::RendererSettings & renderer_settings,double refresh_rate,scoped_refptr<viz::ContextProvider> compositor_context_provider,scoped_refptr<viz::RasterContextProvider> worker_context_provider)4083 std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
4084 const viz::RendererSettings& renderer_settings,
4085 double refresh_rate,
4086 scoped_refptr<viz::ContextProvider> compositor_context_provider,
4087 scoped_refptr<viz::RasterContextProvider> worker_context_provider)
4088 override {
4089 auto on_draw_callback = base::BindRepeating(
4090 &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor::
4091 CallOnDraw,
4092 base::Unretained(this));
4093 auto frame_sink = std::make_unique<OnDrawLayerTreeFrameSink>(
4094 compositor_context_provider, std::move(worker_context_provider),
4095 gpu_memory_buffer_manager(), renderer_settings, &debug_settings_,
4096 ImplThreadTaskRunner(), false /* synchronous_composite */, refresh_rate,
4097 std::move(on_draw_callback));
4098 layer_tree_frame_sink_ = frame_sink.get();
4099 return std::move(frame_sink);
4100 }
4101
CallOnDraw()4102 void CallOnDraw() {
4103 if (!TestEnded()) {
4104 // Synchronous compositor does not draw unless told to do so by the output
4105 // surface. But it needs to be done on a new stack frame.
4106 bool resourceless_software_draw = false;
4107 ImplThreadTaskRunner()->PostTask(
4108 FROM_HERE, base::BindOnce(&OnDrawLayerTreeFrameSink::OnDraw,
4109 base::Unretained(layer_tree_frame_sink_),
4110 resourceless_software_draw));
4111 }
4112 }
4113
4114 OnDrawLayerTreeFrameSink* layer_tree_frame_sink_ = nullptr;
4115 };
4116
4117 // TODO(crbug.com/1121690): Test is flaky.
4118 // MULTI_THREAD_TEST_F(
4119 // LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
4120
4121 class LayerTreeHostTestSynchronousCompositorActivateWithoutDraw
4122 : public LayerTreeHostTest {
4123 protected:
InitializeSettings(LayerTreeSettings * settings)4124 void InitializeSettings(LayerTreeSettings* settings) override {
4125 settings->using_synchronous_renderer_compositor = true;
4126 }
4127
CreateLayerTreeFrameSink(const viz::RendererSettings & renderer_settings,double refresh_rate,scoped_refptr<viz::ContextProvider> compositor_context_provider,scoped_refptr<viz::RasterContextProvider> worker_context_provider)4128 std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
4129 const viz::RendererSettings& renderer_settings,
4130 double refresh_rate,
4131 scoped_refptr<viz::ContextProvider> compositor_context_provider,
4132 scoped_refptr<viz::RasterContextProvider> worker_context_provider)
4133 override {
4134 // Make |invalidate_callback| do nothing so there is no draw.
4135 auto frame_sink = std::make_unique<OnDrawLayerTreeFrameSink>(
4136 compositor_context_provider, std::move(worker_context_provider),
4137 gpu_memory_buffer_manager(), renderer_settings, &debug_settings_,
4138 ImplThreadTaskRunner(),
4139 /*synchronous_composite=*/false, refresh_rate,
4140 /*invalidate_callback=*/base::DoNothing());
4141 return std::move(frame_sink);
4142 }
4143
BeginTest()4144 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4145
DidCommit()4146 void DidCommit() override { commit_count_++; }
4147
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)4148 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4149 activate_count_++;
4150 if (activate_count_ == 1) {
4151 PostSetNeedsCommitToMainThread();
4152 } else if (activate_count_ == 2) {
4153 EndTest();
4154 } else {
4155 NOTREACHED();
4156 }
4157 }
4158
DrawLayersOnThread(LayerTreeHostImpl * host_impl)4159 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
4160 // This test specifically tests that two commit-activate cycles without
4161 // draw in between them.
4162 ADD_FAILURE();
4163 }
4164
AfterTest()4165 void AfterTest() override {
4166 // There should be two commits and activations without any draw.
4167 EXPECT_EQ(commit_count_, 2);
4168 EXPECT_EQ(activate_count_, 2);
4169 }
4170
4171 private:
4172 int commit_count_ = 0;
4173 int activate_count_ = 0;
4174 };
4175
4176 MULTI_THREAD_TEST_F(LayerTreeHostTestSynchronousCompositorActivateWithoutDraw);
4177
4178 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
4179 : public LayerTreeHostTest {
4180 protected:
SetupTree()4181 void SetupTree() override {
4182 LayerTreeHostTest::SetupTree();
4183
4184 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
4185 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
4186 layer->SetBounds(gfx::Size(10, 10));
4187 layer_tree_host()->root_layer()->AddChild(layer);
4188 client_.set_bounds(layer->bounds());
4189 }
4190
BeginTest()4191 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4192
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)4193 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4194 EndTest();
4195 }
4196
4197 FakeContentLayerClient client_;
4198 };
4199
4200 SINGLE_AND_MULTI_THREAD_TEST_F(
4201 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
4202
4203 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
4204 public:
BeginTest()4205 void BeginTest() override {
4206 frame_ = 0;
4207 PostSetNeedsCommitToMainThread();
4208 }
4209
4210 // Round 1: commit + draw
4211 // Round 2: commit only (no draw/swap)
4212 // Round 3: draw only (no commit)
4213
DidCommit()4214 void DidCommit() override {
4215 int commit = layer_tree_host()->SourceFrameNumber();
4216 switch (commit) {
4217 case 2:
4218 // Round 2 done.
4219 EXPECT_EQ(1, frame_);
4220 layer_tree_host()->SetNeedsRedrawRect(
4221 layer_tree_host()->device_viewport_rect());
4222 break;
4223 }
4224 }
4225
DidReceiveCompositorFrameAck()4226 void DidReceiveCompositorFrameAck() override {
4227 int commit = layer_tree_host()->SourceFrameNumber();
4228 ++frame_;
4229 switch (frame_) {
4230 case 1:
4231 // Round 1 done.
4232 EXPECT_EQ(1, commit);
4233 layer_tree_host()->SetNeedsCommit();
4234 break;
4235 case 2:
4236 // Round 3 done.
4237 EXPECT_EQ(2, commit);
4238 EndTest();
4239 break;
4240 }
4241 }
4242
4243 protected:
4244 int frame_;
4245 };
4246
4247 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNumFramesPending);
4248
4249 // Test for UI Resource management.
4250 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
4251 public:
LayerTreeHostTestUIResource()4252 LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
4253
BeginTest()4254 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4255
DidCommit()4256 void DidCommit() override {
4257 int frame = layer_tree_host()->SourceFrameNumber();
4258 switch (frame) {
4259 case 1:
4260 CreateResource();
4261 CreateResource();
4262 PostSetNeedsCommitToMainThread();
4263 break;
4264 case 2:
4265 // Usually ScopedUIResource are deleted from the manager in their
4266 // destructor. Here we just want to test that a direct call to
4267 // DeleteUIResource works.
4268 layer_tree_host()->GetUIResourceManager()->DeleteUIResource(
4269 ui_resources_[0]->id());
4270 PostSetNeedsCommitToMainThread();
4271 break;
4272 case 3:
4273 // DeleteUIResource can be called with an invalid id.
4274 layer_tree_host()->GetUIResourceManager()->DeleteUIResource(
4275 ui_resources_[0]->id());
4276 PostSetNeedsCommitToMainThread();
4277 break;
4278 case 4:
4279 CreateResource();
4280 CreateResource();
4281 PostSetNeedsCommitToMainThread();
4282 break;
4283 case 5:
4284 ClearResources();
4285 EndTest();
4286 break;
4287 }
4288 }
4289
DidActivateTreeOnThread(LayerTreeHostImpl * impl)4290 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4291 auto* sii = static_cast<viz::TestContextProvider*>(
4292 impl->layer_tree_frame_sink()->context_provider())
4293 ->SharedImageInterface();
4294
4295 int frame = impl->active_tree()->source_frame_number();
4296 switch (frame) {
4297 case 0:
4298 ASSERT_EQ(0u, sii->shared_image_count());
4299 break;
4300 case 1:
4301 // Created two textures.
4302 ASSERT_EQ(2u, sii->shared_image_count());
4303 break;
4304 case 2:
4305 // One texture left after one deletion.
4306 ASSERT_EQ(1u, sii->shared_image_count());
4307 break;
4308 case 3:
4309 // Resource manager state should not change when delete is called on an
4310 // invalid id.
4311 ASSERT_EQ(1u, sii->shared_image_count());
4312 break;
4313 case 4:
4314 // Creation after deletion: two more creates should total up to
4315 // three textures.
4316 ASSERT_EQ(3u, sii->shared_image_count());
4317 break;
4318 }
4319 }
4320
4321 private:
4322 // Must clear all resources before exiting.
ClearResources()4323 void ClearResources() {
4324 for (int i = 0; i < num_ui_resources_; i++)
4325 ui_resources_[i] = nullptr;
4326 }
4327
CreateResource()4328 void CreateResource() {
4329 ui_resources_[num_ui_resources_++] =
4330 FakeScopedUIResource::Create(layer_tree_host()->GetUIResourceManager());
4331 }
4332
4333 std::unique_ptr<FakeScopedUIResource> ui_resources_[5];
4334 int num_ui_resources_;
4335 };
4336
4337 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
4338
4339 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
4340 protected:
BeginTest()4341 void BeginTest() override {
4342 num_commits_ = 0;
4343 expected_push_properties_root_ = 0;
4344 expected_push_properties_child_ = 0;
4345 expected_push_properties_grandchild_ = 0;
4346 expected_push_properties_child2_ = 0;
4347 expected_push_properties_other_root_ = 0;
4348 expected_push_properties_leaf_layer_ = 0;
4349 PostSetNeedsCommitToMainThread();
4350 }
4351
SetupTree()4352 void SetupTree() override {
4353 root_ = PushPropertiesCountingLayer::Create();
4354 child_ = PushPropertiesCountingLayer::Create();
4355 child2_ = PushPropertiesCountingLayer::Create();
4356 grandchild_ = PushPropertiesCountingLayer::Create();
4357 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
4358
4359 root_->AddChild(child_);
4360 root_->AddChild(child2_);
4361 child_->AddChild(grandchild_);
4362 child2_->AddChild(leaf_always_pushing_layer_);
4363
4364 other_root_ = PushPropertiesCountingLayer::Create();
4365
4366 // Don't set the root layer here.
4367 LayerTreeHostTest::SetupTree();
4368 client_.set_bounds(root_->bounds());
4369 }
4370
DidCommitAndDrawFrame()4371 void DidCommitAndDrawFrame() override {
4372 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count())
4373 << "num_commits: " << num_commits_;
4374 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count())
4375 << "num_commits: " << num_commits_;
4376 EXPECT_EQ(expected_push_properties_grandchild_,
4377 grandchild_->push_properties_count())
4378 << "num_commits: " << num_commits_;
4379 EXPECT_EQ(expected_push_properties_child2_,
4380 child2_->push_properties_count())
4381 << "num_commits: " << num_commits_;
4382 EXPECT_EQ(expected_push_properties_other_root_,
4383 other_root_->push_properties_count())
4384 << "num_commits: " << num_commits_;
4385 EXPECT_EQ(expected_push_properties_leaf_layer_,
4386 leaf_always_pushing_layer_->push_properties_count())
4387 << "num_commits: " << num_commits_;
4388
4389 ++num_commits_;
4390
4391 // The scrollbar layer always needs to be pushed.
4392 if (root_->layer_tree_host()) {
4393 EXPECT_FALSE(base::Contains(
4394 root_->layer_tree_host()->LayersThatShouldPushProperties(),
4395 root_.get()));
4396 }
4397 if (child2_->layer_tree_host()) {
4398 EXPECT_FALSE(base::Contains(
4399 child2_->layer_tree_host()->LayersThatShouldPushProperties(),
4400 child2_.get()));
4401 }
4402 if (leaf_always_pushing_layer_->layer_tree_host()) {
4403 leaf_always_pushing_layer_->SetNeedsPushProperties();
4404 EXPECT_TRUE(base::Contains(leaf_always_pushing_layer_->layer_tree_host()
4405 ->LayersThatShouldPushProperties(),
4406 leaf_always_pushing_layer_.get()));
4407 }
4408
4409 // child_ and grandchild_ don't persist their need to push properties.
4410 if (child_->layer_tree_host()) {
4411 EXPECT_FALSE(base::Contains(
4412 child_->layer_tree_host()->LayersThatShouldPushProperties(),
4413 child_.get()));
4414 }
4415 if (grandchild_->layer_tree_host()) {
4416 EXPECT_FALSE(base::Contains(
4417 grandchild_->layer_tree_host()->LayersThatShouldPushProperties(),
4418 grandchild_.get()));
4419 }
4420
4421 if (other_root_->layer_tree_host()) {
4422 EXPECT_FALSE(base::Contains(
4423 other_root_->layer_tree_host()->LayersThatShouldPushProperties(),
4424 other_root_.get()));
4425 }
4426
4427 switch (num_commits_) {
4428 case 1:
4429 layer_tree_host()->SetRootLayer(root_);
4430 // Layers added to the tree get committed.
4431 ++expected_push_properties_root_;
4432 ++expected_push_properties_child_;
4433 ++expected_push_properties_grandchild_;
4434 ++expected_push_properties_child2_;
4435 break;
4436 case 2:
4437 layer_tree_host()->SetNeedsCommit();
4438 // No layers need commit.
4439 break;
4440 case 3:
4441 layer_tree_host()->SetRootLayer(other_root_);
4442 // Layers added to the tree get committed.
4443 ++expected_push_properties_other_root_;
4444 break;
4445 case 4:
4446 layer_tree_host()->SetRootLayer(root_);
4447 // Layers added to the tree get committed.
4448 ++expected_push_properties_root_;
4449 ++expected_push_properties_child_;
4450 ++expected_push_properties_grandchild_;
4451 ++expected_push_properties_child2_;
4452 break;
4453 case 5:
4454 layer_tree_host()->SetNeedsCommit();
4455 // No layers need commit.
4456 break;
4457 case 6:
4458 child_->RemoveFromParent();
4459 // No layers need commit.
4460 break;
4461 case 7:
4462 root_->AddChild(child_);
4463 // Layers added to the tree get committed.
4464 ++expected_push_properties_child_;
4465 ++expected_push_properties_grandchild_;
4466 break;
4467 case 8:
4468 grandchild_->RemoveFromParent();
4469 // No layers need commit.
4470 break;
4471 case 9:
4472 child_->AddChild(grandchild_);
4473 // Layers added to the tree get committed.
4474 ++expected_push_properties_grandchild_;
4475 break;
4476 case 10:
4477 GenerateNewLocalSurfaceId();
4478 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(20, 20), 1.f,
4479 GetCurrentLocalSurfaceId());
4480 // No layers need commit.
4481 break;
4482 case 11:
4483 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
4484 // No layers need commit.
4485 break;
4486 case 12:
4487 child_->MakePushProperties();
4488 // The modified layer needs commit
4489 ++expected_push_properties_child_;
4490 ++expected_push_properties_grandchild_;
4491 break;
4492 case 13:
4493 child2_->MakePushProperties();
4494 // The modified layer needs commit
4495 ++expected_push_properties_child2_;
4496 break;
4497 case 14:
4498 child_->RemoveFromParent();
4499 root_->AddChild(child_);
4500 // Layers added to the tree get committed.
4501 ++expected_push_properties_child_;
4502 ++expected_push_properties_grandchild_;
4503 break;
4504 case 15:
4505 grandchild_->MakePushProperties();
4506 // The modified layer needs commit
4507 ++expected_push_properties_grandchild_;
4508 break;
4509 case 16:
4510 // SetNeedsDisplay does not always set needs commit (so call it
4511 // explicitly), but is a property change.
4512 child_->SetNeedsDisplay();
4513 ++expected_push_properties_child_;
4514 layer_tree_host()->SetNeedsCommit();
4515 break;
4516 case 17:
4517 EndTest();
4518 break;
4519 }
4520
4521 // The leaf layer always pushes.
4522 if (leaf_always_pushing_layer_->layer_tree_host())
4523 ++expected_push_properties_leaf_layer_;
4524 }
4525
4526 int num_commits_;
4527 FakeContentLayerClient client_;
4528 scoped_refptr<PushPropertiesCountingLayer> root_;
4529 scoped_refptr<PushPropertiesCountingLayer> child_;
4530 scoped_refptr<PushPropertiesCountingLayer> child2_;
4531 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
4532 scoped_refptr<PushPropertiesCountingLayer> other_root_;
4533 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
4534 size_t expected_push_properties_root_;
4535 size_t expected_push_properties_child_;
4536 size_t expected_push_properties_child2_;
4537 size_t expected_push_properties_grandchild_;
4538 size_t expected_push_properties_other_root_;
4539 size_t expected_push_properties_leaf_layer_;
4540 };
4541
4542 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
4543
4544 class LayerTreeHostTestImplLayersPushProperties
4545 : public LayerTreeHostTestLayersPushProperties {
4546 protected:
BeginTest()4547 void BeginTest() override {
4548 expected_push_properties_root_impl_ = 0;
4549 expected_push_properties_child_impl_ = 0;
4550 expected_push_properties_grandchild_impl_ = 0;
4551 expected_push_properties_child2_impl_ = 0;
4552 expected_push_properties_grandchild2_impl_ = 0;
4553 LayerTreeHostTestLayersPushProperties::BeginTest();
4554 }
4555
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)4556 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
4557 // These commits are in response to the changes made in
4558 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
4559 switch (num_commits_) {
4560 case 0:
4561 // Tree hasn't been setup yet don't bother to check anything.
4562 return;
4563 case 1:
4564 // Root gets set up, Everyone is initialized.
4565 ++expected_push_properties_root_impl_;
4566 ++expected_push_properties_child_impl_;
4567 ++expected_push_properties_grandchild_impl_;
4568 ++expected_push_properties_child2_impl_;
4569 ++expected_push_properties_grandchild2_impl_;
4570 break;
4571 case 2:
4572 // Tree doesn't change but the one leaf that always pushes is pushed.
4573 ++expected_push_properties_grandchild2_impl_;
4574 break;
4575 case 3:
4576 // Root is swapped here.
4577 // Clear the expected push properties the tree will be rebuilt.
4578 expected_push_properties_root_impl_ = 0;
4579 expected_push_properties_child_impl_ = 0;
4580 expected_push_properties_grandchild_impl_ = 0;
4581 expected_push_properties_child2_impl_ = 0;
4582 expected_push_properties_grandchild2_impl_ = 0;
4583
4584 // Make sure the new root is pushed.
4585 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
4586 host_impl->active_tree()->root_layer())
4587 ->push_properties_count());
4588 return;
4589 case 4:
4590 // Root is swapped back all of the layers in the tree get pushed.
4591 ++expected_push_properties_root_impl_;
4592 ++expected_push_properties_child_impl_;
4593 ++expected_push_properties_grandchild_impl_;
4594 ++expected_push_properties_child2_impl_;
4595 ++expected_push_properties_grandchild2_impl_;
4596 break;
4597 case 5:
4598 // Tree doesn't change but the one leaf that always pushes is pushed.
4599 ++expected_push_properties_grandchild2_impl_;
4600 break;
4601 case 6:
4602 // First child is removed. Structure of the tree changes.
4603 expected_push_properties_child_impl_ = 0;
4604 expected_push_properties_grandchild_impl_ = 0;
4605
4606 // The leaf that always pushes is pushed.
4607 ++expected_push_properties_grandchild2_impl_;
4608 break;
4609 case 7:
4610 // The leaf that always pushes is pushed.
4611 ++expected_push_properties_grandchild2_impl_;
4612
4613 // Child is added back. New layers are initialized.
4614 ++expected_push_properties_grandchild_impl_;
4615 ++expected_push_properties_child_impl_;
4616 break;
4617 case 8:
4618 // Leaf is removed.
4619 expected_push_properties_grandchild_impl_ = 0;
4620
4621 // Always pushing.
4622 ++expected_push_properties_grandchild2_impl_;
4623 break;
4624 case 9:
4625 // Leaf is added back
4626 ++expected_push_properties_grandchild_impl_;
4627
4628 // The leaf that always pushes is pushed.
4629 ++expected_push_properties_grandchild2_impl_;
4630 break;
4631 case 10:
4632 // The leaf that always pushes is pushed.
4633 ++expected_push_properties_grandchild2_impl_;
4634 break;
4635 case 11:
4636 // The leaf that always pushes is pushed.
4637 ++expected_push_properties_grandchild2_impl_;
4638 break;
4639 case 12:
4640 // The leaf that always pushes is pushed.
4641 ++expected_push_properties_grandchild2_impl_;
4642
4643 // This child position was changed. So the subtree needs to push
4644 // properties.
4645 ++expected_push_properties_child_impl_;
4646 ++expected_push_properties_grandchild_impl_;
4647 break;
4648 case 13:
4649 // The position of this child was changed.
4650 ++expected_push_properties_child2_impl_;
4651
4652 // The leaf that always pushes is pushed.
4653 ++expected_push_properties_grandchild2_impl_;
4654 break;
4655 case 14:
4656 // Second child is removed from tree. Don't discard counts because
4657 // they are added back before commit.
4658
4659 // The leaf that always pushes is pushed.
4660 ++expected_push_properties_grandchild2_impl_;
4661
4662 // Second child added back.
4663 ++expected_push_properties_child_impl_;
4664 ++expected_push_properties_grandchild_impl_;
4665
4666 break;
4667 case 15:
4668 // The position of this child was changed.
4669 ++expected_push_properties_grandchild_impl_;
4670
4671 // The leaf that always pushes is pushed.
4672 ++expected_push_properties_grandchild2_impl_;
4673 break;
4674 case 16:
4675 // Second child is invalidated with SetNeedsDisplay
4676 ++expected_push_properties_child_impl_;
4677
4678 // The leaf that always pushed is pushed.
4679 ++expected_push_properties_grandchild2_impl_;
4680 break;
4681 }
4682
4683 PushPropertiesCountingLayerImpl* root_impl_ = nullptr;
4684 PushPropertiesCountingLayerImpl* child_impl_ = nullptr;
4685 PushPropertiesCountingLayerImpl* child2_impl_ = nullptr;
4686 PushPropertiesCountingLayerImpl* grandchild_impl_ = nullptr;
4687 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = nullptr;
4688
4689 // Pull the layers that we need from the tree assuming the same structure
4690 // as LayerTreeHostTestLayersPushProperties
4691 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
4692 host_impl->active_tree()->root_layer());
4693
4694 LayerTreeImpl* impl = root_impl_->layer_tree_impl();
4695 if (impl->LayerById(child_->id())) {
4696 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
4697 impl->LayerById(child_->id()));
4698
4699 if (impl->LayerById(grandchild_->id()))
4700 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
4701 impl->LayerById(grandchild_->id()));
4702 }
4703
4704 if (impl->LayerById(child2_->id())) {
4705 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
4706 impl->LayerById(child2_->id()));
4707
4708 if (impl->LayerById(leaf_always_pushing_layer_->id()))
4709 leaf_always_pushing_layer_impl_ =
4710 static_cast<PushPropertiesCountingLayerImpl*>(
4711 impl->LayerById(leaf_always_pushing_layer_->id()));
4712 }
4713
4714 if (root_impl_)
4715 EXPECT_EQ(expected_push_properties_root_impl_,
4716 root_impl_->push_properties_count());
4717 if (child_impl_)
4718 EXPECT_EQ(expected_push_properties_child_impl_,
4719 child_impl_->push_properties_count());
4720 if (grandchild_impl_)
4721 EXPECT_EQ(expected_push_properties_grandchild_impl_,
4722 grandchild_impl_->push_properties_count());
4723 if (child2_impl_)
4724 EXPECT_EQ(expected_push_properties_child2_impl_,
4725 child2_impl_->push_properties_count());
4726 if (leaf_always_pushing_layer_impl_)
4727 EXPECT_EQ(expected_push_properties_grandchild2_impl_,
4728 leaf_always_pushing_layer_impl_->push_properties_count());
4729 }
4730
4731 size_t expected_push_properties_root_impl_;
4732 size_t expected_push_properties_child_impl_;
4733 size_t expected_push_properties_child2_impl_;
4734 size_t expected_push_properties_grandchild_impl_;
4735 size_t expected_push_properties_grandchild2_impl_;
4736 };
4737
4738 MULTI_THREAD_TEST_F(LayerTreeHostTestImplLayersPushProperties);
4739
4740 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
4741 : public LayerTreeHostTest {
4742 protected:
BeginTest()4743 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4744
SetupTree()4745 void SetupTree() override {
4746 root_ = Layer::Create();
4747 root_->SetBounds(gfx::Size(1, 1));
4748
4749 bool paint_scrollbar = true;
4750 bool has_thumb = false;
4751 scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
4752 paint_scrollbar, has_thumb, root_->element_id());
4753
4754 root_->AddChild(scrollbar_layer_);
4755
4756 layer_tree_host()->SetRootLayer(root_);
4757 LayerTreeHostTest::SetupTree();
4758 }
4759
DidCommitAndDrawFrame()4760 void DidCommitAndDrawFrame() override {
4761 switch (layer_tree_host()->SourceFrameNumber()) {
4762 case 0:
4763 break;
4764 case 1: {
4765 // During update, the ignore_set_needs_commit_ bit is set to true to
4766 // avoid causing a second commit to be scheduled. If a property change
4767 // is made during this, however, it needs to be pushed in the upcoming
4768 // commit.
4769 auto ignore = scrollbar_layer_->IgnoreSetNeedsCommit();
4770
4771 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
4772
4773 EXPECT_TRUE(
4774 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4775 scrollbar_layer_.get()));
4776 layer_tree_host()->SetNeedsCommit();
4777
4778 scrollbar_layer_->reset_push_properties_count();
4779 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
4780 break;
4781 }
4782 case 2:
4783 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
4784 EndTest();
4785 break;
4786 }
4787 }
4788
4789 scoped_refptr<Layer> root_;
4790 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
4791 };
4792
4793 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
4794
4795 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
4796 protected:
BeginTest()4797 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4798
SetupTree()4799 void SetupTree() override {
4800 root_ = PushPropertiesCountingLayer::Create();
4801 child_ = PushPropertiesCountingLayer::Create();
4802 root_->AddChild(child_);
4803
4804 layer_tree_host()->SetRootLayer(root_);
4805 LayerTreeHostTest::SetupTree();
4806 }
4807
DidCommitAndDrawFrame()4808 void DidCommitAndDrawFrame() override {
4809 switch (layer_tree_host()->SourceFrameNumber()) {
4810 case 0:
4811 break;
4812 case 1: {
4813 // During update, the ignore_set_needs_commit_ bit is set to true to
4814 // avoid causing a second commit to be scheduled. If a property change
4815 // is made during this, however, it needs to be pushed in the upcoming
4816 // commit.
4817 EXPECT_FALSE(base::Contains(
4818 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
4819 EXPECT_FALSE(base::Contains(
4820 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
4821 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
4822 root_->reset_push_properties_count();
4823 child_->reset_push_properties_count();
4824 child_->SetIsDrawable(true);
4825 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
4826 EXPECT_EQ(0u, root_->push_properties_count());
4827 EXPECT_EQ(0u, child_->push_properties_count());
4828 EXPECT_TRUE(base::Contains(
4829 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
4830 EXPECT_TRUE(base::Contains(
4831 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
4832 break;
4833 }
4834 case 2:
4835 EXPECT_EQ(1u, root_->push_properties_count());
4836 EXPECT_EQ(1u, child_->push_properties_count());
4837 EXPECT_FALSE(base::Contains(
4838 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
4839 EXPECT_FALSE(base::Contains(
4840 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
4841 EndTest();
4842 break;
4843 }
4844 }
4845
4846 scoped_refptr<PushPropertiesCountingLayer> root_;
4847 scoped_refptr<PushPropertiesCountingLayer> child_;
4848 };
4849
4850 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit);
4851
4852 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
4853 : public LayerTreeHostTest {
4854 protected:
BeginTest()4855 void BeginTest() override {
4856 expected_push_properties_root_ = 0;
4857 expected_push_properties_child_ = 0;
4858 expected_push_properties_grandchild1_ = 0;
4859 expected_push_properties_grandchild2_ = 0;
4860 expected_push_properties_grandchild3_ = 0;
4861 PostSetNeedsCommitToMainThread();
4862 }
4863
SetupTree()4864 void SetupTree() override {
4865 root_ = PushPropertiesCountingLayer::Create();
4866 child_ = PushPropertiesCountingLayer::Create();
4867 grandchild1_ = PushPropertiesCountingLayer::Create();
4868 grandchild2_ = PushPropertiesCountingLayer::Create();
4869 grandchild3_ = PushPropertiesCountingLayer::Create();
4870
4871 root_->AddChild(child_);
4872 child_->AddChild(grandchild1_);
4873 child_->AddChild(grandchild2_);
4874 child_->AddChild(grandchild3_);
4875
4876 // Don't set the root layer here.
4877 LayerTreeHostTest::SetupTree();
4878 client_.set_bounds(root_->bounds());
4879 }
4880
4881 FakeContentLayerClient client_;
4882 scoped_refptr<PushPropertiesCountingLayer> root_;
4883 scoped_refptr<PushPropertiesCountingLayer> child_;
4884 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
4885 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
4886 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
4887 size_t expected_push_properties_root_;
4888 size_t expected_push_properties_child_;
4889 size_t expected_push_properties_grandchild1_;
4890 size_t expected_push_properties_grandchild2_;
4891 size_t expected_push_properties_grandchild3_;
4892 };
4893
4894 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
4895 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4896 protected:
DidCommitAndDrawFrame()4897 void DidCommitAndDrawFrame() override {
4898 int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
4899 switch (last_source_frame_number) {
4900 case 0:
4901 // All layers will need push properties as we set their layer tree host
4902 layer_tree_host()->SetRootLayer(root_);
4903 EXPECT_TRUE(base::Contains(
4904 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
4905 EXPECT_TRUE(base::Contains(
4906 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
4907 EXPECT_TRUE(
4908 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4909 grandchild1_.get()));
4910 EXPECT_TRUE(
4911 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4912 grandchild2_.get()));
4913 EXPECT_TRUE(
4914 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4915 grandchild3_.get()));
4916 break;
4917 case 1:
4918 EndTest();
4919 break;
4920 }
4921 }
4922 };
4923
4924 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
4925
4926 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
4927 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4928 protected:
DidCommitAndDrawFrame()4929 void DidCommitAndDrawFrame() override {
4930 int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
4931 switch (last_source_frame_number) {
4932 case 0:
4933 layer_tree_host()->SetRootLayer(root_);
4934 break;
4935 case 1:
4936 EXPECT_FALSE(base::Contains(
4937 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
4938 EXPECT_FALSE(base::Contains(
4939 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
4940 EXPECT_FALSE(
4941 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4942 grandchild1_.get()));
4943 EXPECT_FALSE(
4944 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4945 grandchild2_.get()));
4946 EXPECT_FALSE(
4947 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4948 grandchild3_.get()));
4949
4950 grandchild1_->RemoveFromParent();
4951 grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
4952
4953 EXPECT_FALSE(base::Contains(
4954 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
4955 EXPECT_FALSE(base::Contains(
4956 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
4957 EXPECT_FALSE(
4958 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4959 grandchild2_.get()));
4960 EXPECT_FALSE(
4961 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4962 grandchild3_.get()));
4963
4964 child_->AddChild(grandchild1_);
4965
4966 EXPECT_FALSE(base::Contains(
4967 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
4968 EXPECT_FALSE(base::Contains(
4969 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
4970 EXPECT_TRUE(
4971 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4972 grandchild1_.get()));
4973 EXPECT_FALSE(
4974 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4975 grandchild2_.get()));
4976 EXPECT_FALSE(
4977 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4978 grandchild3_.get()));
4979
4980 grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
4981
4982 EXPECT_FALSE(base::Contains(
4983 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
4984 EXPECT_FALSE(base::Contains(
4985 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
4986 EXPECT_TRUE(
4987 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4988 grandchild1_.get()));
4989 EXPECT_TRUE(
4990 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4991 grandchild2_.get()));
4992 EXPECT_FALSE(
4993 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
4994 grandchild3_.get()));
4995
4996 // grandchild2_ will still need a push properties.
4997 grandchild1_->RemoveFromParent();
4998
4999 EXPECT_FALSE(base::Contains(
5000 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5001 EXPECT_FALSE(base::Contains(
5002 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5003
5004 // grandchild3_ does not need a push properties, so recursing should
5005 // no longer be needed.
5006 grandchild2_->RemoveFromParent();
5007
5008 EXPECT_FALSE(base::Contains(
5009 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5010 EXPECT_FALSE(base::Contains(
5011 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5012 EndTest();
5013 break;
5014 }
5015 }
5016 };
5017
5018 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
5019
5020 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
5021 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
5022 protected:
DidCommitAndDrawFrame()5023 void DidCommitAndDrawFrame() override {
5024 // The grand children are set to need push properties, to verify the impact
5025 // on their ancestors.
5026 grandchild1_->SetNeedsPushProperties();
5027 grandchild2_->SetNeedsPushProperties();
5028
5029 int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
5030 switch (last_source_frame_number) {
5031 case 0:
5032 layer_tree_host()->SetRootLayer(root_);
5033 break;
5034 case 1:
5035 EXPECT_FALSE(base::Contains(
5036 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5037 EXPECT_FALSE(base::Contains(
5038 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5039 EXPECT_TRUE(
5040 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5041 grandchild1_.get()));
5042 EXPECT_TRUE(
5043 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5044 grandchild2_.get()));
5045 EXPECT_FALSE(
5046 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5047 grandchild3_.get()));
5048
5049 // grandchild2_ will still need a push properties.
5050 grandchild1_->RemoveFromParent();
5051
5052 EXPECT_FALSE(base::Contains(
5053 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5054 EXPECT_FALSE(base::Contains(
5055 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5056
5057 // grandchild3_ does not need a push properties, so recursing should
5058 // no longer be needed.
5059 grandchild2_->RemoveFromParent();
5060
5061 EXPECT_FALSE(base::Contains(
5062 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5063 EXPECT_FALSE(base::Contains(
5064 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5065 EndTest();
5066 break;
5067 }
5068 }
5069 };
5070
5071 MULTI_THREAD_TEST_F(
5072 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
5073
5074 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
5075 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
5076 protected:
DidCommitAndDrawFrame()5077 void DidCommitAndDrawFrame() override {
5078 int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
5079 switch (last_source_frame_number) {
5080 case 0:
5081 layer_tree_host()->SetRootLayer(root_);
5082 break;
5083 case 1:
5084 EXPECT_FALSE(base::Contains(
5085 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5086 EXPECT_FALSE(base::Contains(
5087 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5088 EXPECT_FALSE(
5089 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5090 grandchild1_.get()));
5091 EXPECT_FALSE(
5092 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5093 grandchild2_.get()));
5094 EXPECT_FALSE(
5095 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5096 grandchild3_.get()));
5097
5098 // Change grandchildren while their parent is not in the tree.
5099 child_->RemoveFromParent();
5100 grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
5101 grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
5102 root_->AddChild(child_);
5103
5104 EXPECT_FALSE(base::Contains(
5105 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5106 EXPECT_TRUE(base::Contains(
5107 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5108 EXPECT_TRUE(
5109 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5110 grandchild1_.get()));
5111 EXPECT_TRUE(
5112 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5113 grandchild2_.get()));
5114 EXPECT_TRUE(
5115 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5116 grandchild3_.get()));
5117
5118 grandchild1_->RemoveFromParent();
5119
5120 EXPECT_FALSE(base::Contains(
5121 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5122 EXPECT_TRUE(base::Contains(
5123 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5124
5125 grandchild2_->RemoveFromParent();
5126
5127 EXPECT_FALSE(base::Contains(
5128 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5129 EXPECT_TRUE(base::Contains(
5130 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5131
5132 grandchild3_->RemoveFromParent();
5133
5134 EXPECT_FALSE(base::Contains(
5135 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5136 EXPECT_TRUE(base::Contains(
5137 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5138
5139 EndTest();
5140 break;
5141 }
5142 }
5143 };
5144
5145 MULTI_THREAD_TEST_F(
5146 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
5147
5148 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
5149 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
5150 protected:
DidCommitAndDrawFrame()5151 void DidCommitAndDrawFrame() override {
5152 int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
5153 switch (last_source_frame_number) {
5154 case 0:
5155 layer_tree_host()->SetRootLayer(root_);
5156 break;
5157 case 1:
5158 EXPECT_FALSE(base::Contains(
5159 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5160 EXPECT_FALSE(base::Contains(
5161 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5162 EXPECT_FALSE(
5163 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5164 grandchild1_.get()));
5165 EXPECT_FALSE(
5166 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5167 grandchild2_.get()));
5168 EXPECT_FALSE(
5169 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5170 grandchild3_.get()));
5171
5172 child_->SetPosition(gfx::PointF(1.f, 1.f));
5173 grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
5174 grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
5175
5176 EXPECT_FALSE(base::Contains(
5177 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5178 EXPECT_TRUE(base::Contains(
5179 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5180 EXPECT_TRUE(
5181 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5182 grandchild1_.get()));
5183 EXPECT_TRUE(
5184 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5185 grandchild2_.get()));
5186 EXPECT_FALSE(
5187 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5188 grandchild3_.get()));
5189
5190 grandchild1_->RemoveFromParent();
5191
5192 EXPECT_FALSE(base::Contains(
5193 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5194 EXPECT_TRUE(base::Contains(
5195 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5196
5197 grandchild2_->RemoveFromParent();
5198
5199 EXPECT_FALSE(base::Contains(
5200 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5201 EXPECT_TRUE(base::Contains(
5202 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5203
5204 child_->RemoveFromParent();
5205
5206 EXPECT_FALSE(base::Contains(
5207 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5208
5209 EndTest();
5210 break;
5211 }
5212 }
5213 };
5214
5215 MULTI_THREAD_TEST_F(
5216 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
5217
5218 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
5219 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
5220 protected:
DidCommitAndDrawFrame()5221 void DidCommitAndDrawFrame() override {
5222 int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
5223 switch (last_source_frame_number) {
5224 case 0:
5225 layer_tree_host()->SetRootLayer(root_);
5226 break;
5227 case 1:
5228 EXPECT_FALSE(base::Contains(
5229 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5230 EXPECT_FALSE(base::Contains(
5231 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5232 EXPECT_FALSE(
5233 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5234 grandchild1_.get()));
5235 EXPECT_FALSE(
5236 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5237 grandchild2_.get()));
5238 EXPECT_FALSE(
5239 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5240 grandchild3_.get()));
5241
5242 grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
5243 grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
5244 child_->SetPosition(gfx::PointF(1.f, 1.f));
5245
5246 EXPECT_FALSE(base::Contains(
5247 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5248 EXPECT_TRUE(base::Contains(
5249 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5250 EXPECT_TRUE(
5251 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5252 grandchild1_.get()));
5253 EXPECT_TRUE(
5254 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5255 grandchild2_.get()));
5256 EXPECT_FALSE(
5257 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5258 grandchild3_.get()));
5259
5260 grandchild1_->RemoveFromParent();
5261
5262 EXPECT_FALSE(base::Contains(
5263 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5264 EXPECT_TRUE(base::Contains(
5265 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5266
5267 grandchild2_->RemoveFromParent();
5268
5269 EXPECT_FALSE(base::Contains(
5270 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5271 EXPECT_TRUE(base::Contains(
5272 layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
5273
5274 child_->RemoveFromParent();
5275
5276 EXPECT_FALSE(base::Contains(
5277 layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
5278
5279 EndTest();
5280 break;
5281 }
5282 }
5283 };
5284
5285 MULTI_THREAD_TEST_F(
5286 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
5287
5288 // This test verifies that the tree activation callback is invoked correctly.
5289 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
5290 public:
LayerTreeHostTestTreeActivationCallback()5291 LayerTreeHostTestTreeActivationCallback()
5292 : num_commits_(0), callback_count_(0) {}
5293
BeginTest()5294 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5295
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)5296 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5297 LayerTreeHostImpl::FrameData* frame_data,
5298 DrawResult draw_result) override {
5299 ++num_commits_;
5300 switch (num_commits_) {
5301 case 1:
5302 EXPECT_EQ(0, callback_count_);
5303 callback_count_ = 0;
5304 SetCallback(host_impl, true);
5305 PostSetNeedsCommitToMainThread();
5306 break;
5307 case 2:
5308 EXPECT_EQ(1, callback_count_);
5309 callback_count_ = 0;
5310 SetCallback(host_impl, false);
5311 PostSetNeedsCommitToMainThread();
5312 break;
5313 case 3:
5314 EXPECT_EQ(0, callback_count_);
5315 callback_count_ = 0;
5316 EndTest();
5317 break;
5318 default:
5319 ADD_FAILURE() << num_commits_;
5320 EndTest();
5321 break;
5322 }
5323 return LayerTreeHostTest::PrepareToDrawOnThread(host_impl, frame_data,
5324 draw_result);
5325 }
5326
AfterTest()5327 void AfterTest() override { EXPECT_EQ(3, num_commits_); }
5328
SetCallback(LayerTreeHostImpl * host_impl,bool enable)5329 void SetCallback(LayerTreeHostImpl* host_impl, bool enable) {
5330 host_impl->SetTreeActivationCallback(
5331 enable
5332 ? base::BindRepeating(
5333 &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
5334 base::Unretained(this))
5335 : base::RepeatingClosure());
5336 }
5337
ActivationCallback()5338 void ActivationCallback() { ++callback_count_; }
5339
5340 int num_commits_;
5341 int callback_count_;
5342 };
5343
5344 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTreeActivationCallback);
5345
5346 class LayerInvalidateCausesDraw : public LayerTreeHostTest {
5347 public:
LayerInvalidateCausesDraw()5348 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
5349
BeginTest()5350 void BeginTest() override {
5351 ASSERT_TRUE(invalidate_layer_)
5352 << "Derived tests must set this in SetupTree";
5353
5354 // One initial commit.
5355 PostSetNeedsCommitToMainThread();
5356 }
5357
DidCommitAndDrawFrame()5358 void DidCommitAndDrawFrame() override {
5359 // After commit, invalidate the layer. This should cause a commit.
5360 if (layer_tree_host()->SourceFrameNumber() == 1)
5361 invalidate_layer_->SetNeedsDisplay();
5362 }
5363
DrawLayersOnThread(LayerTreeHostImpl * impl)5364 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
5365 num_draws_++;
5366 if (impl->active_tree()->source_frame_number() == 1)
5367 EndTest();
5368 }
5369
CommitCompleteOnThread(LayerTreeHostImpl * impl)5370 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
5371 num_commits_++;
5372 }
5373
AfterTest()5374 void AfterTest() override {
5375 EXPECT_GE(2, num_commits_);
5376 EXPECT_GE(2, num_draws_);
5377 }
5378
5379 protected:
5380 scoped_refptr<Layer> invalidate_layer_;
5381
5382 private:
5383 int num_commits_;
5384 int num_draws_;
5385 };
5386
5387 // VideoLayer must support being invalidated and then passing that along
5388 // to the compositor thread, even though no resources are updated in
5389 // response to that invalidation.
5390 class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
5391 public:
SetupTree()5392 void SetupTree() override {
5393 LayerTreeHostTest::SetupTree();
5394 scoped_refptr<VideoLayer> video_layer =
5395 VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
5396 video_layer->SetBounds(gfx::Size(10, 10));
5397 video_layer->SetIsDrawable(true);
5398 layer_tree_host()->root_layer()->AddChild(video_layer);
5399
5400 invalidate_layer_ = video_layer;
5401 }
5402
5403 private:
5404 FakeVideoFrameProvider provider_;
5405 };
5406
5407 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
5408
5409 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
5410 protected:
SetupTree()5411 void SetupTree() override {
5412 root_layer_ = Layer::Create();
5413 root_layer_->SetPosition(gfx::PointF());
5414 root_layer_->SetBounds(gfx::Size(10, 10));
5415
5416 parent_layer_ = SolidColorLayer::Create();
5417 parent_layer_->SetPosition(gfx::PointF());
5418 parent_layer_->SetBounds(gfx::Size(10, 10));
5419 parent_layer_->SetIsDrawable(true);
5420 root_layer_->AddChild(parent_layer_);
5421
5422 child_layer_ = SolidColorLayer::Create();
5423 child_layer_->SetPosition(gfx::PointF());
5424 child_layer_->SetBounds(gfx::Size(10, 10));
5425 child_layer_->SetIsDrawable(true);
5426 parent_layer_->AddChild(child_layer_);
5427
5428 layer_tree_host()->SetRootLayer(root_layer_);
5429 LayerTreeHostTest::SetupTree();
5430 }
5431
BeginTest()5432 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5433
DidCommitAndDrawFrame()5434 void DidCommitAndDrawFrame() override {
5435 switch (layer_tree_host()->SourceFrameNumber()) {
5436 case 1:
5437 // The layer type used does not need to push properties every frame.
5438 EXPECT_FALSE(
5439 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5440 child_layer_.get()));
5441
5442 // Change the bounds of the child layer, but make it skipped
5443 // by CalculateDrawProperties.
5444 parent_layer_->SetOpacity(0.f);
5445 child_layer_->SetBounds(gfx::Size(5, 5));
5446 break;
5447 case 2:
5448 // The bounds of the child layer were pushed to the impl side.
5449 EXPECT_FALSE(
5450 base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
5451 child_layer_.get()));
5452
5453 EndTest();
5454 break;
5455 }
5456 }
5457
DidActivateTreeOnThread(LayerTreeHostImpl * impl)5458 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
5459 LayerImpl* child = impl->active_tree()->LayerById(child_layer_->id());
5460
5461 switch (impl->active_tree()->source_frame_number()) {
5462 case 1:
5463 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
5464 break;
5465 }
5466 }
5467
5468 scoped_refptr<Layer> root_layer_;
5469 scoped_refptr<SolidColorLayer> parent_layer_;
5470 scoped_refptr<SolidColorLayer> child_layer_;
5471 };
5472
5473 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
5474
5475 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
5476 protected:
SetupTree()5477 void SetupTree() override {
5478 root_layer_ = FakePictureLayer::Create(&client_);
5479 root_layer_->SetBounds(gfx::Size(10, 10));
5480
5481 layer_tree_host()->SetRootLayer(root_layer_);
5482 LayerTreeHostTest::SetupTree();
5483 client_.set_bounds(root_layer_->bounds());
5484 }
5485
BeginTest()5486 void BeginTest() override {
5487 // The viewport is empty, but we still need to update layers on the main
5488 // thread.
5489 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(0, 0), 1.f,
5490 viz::LocalSurfaceId());
5491 PostSetNeedsCommitToMainThread();
5492 }
5493
DidCommit()5494 void DidCommit() override {
5495 // The layer should be updated even though the viewport is empty, so we
5496 // are capable of drawing it on the impl tree.
5497 EXPECT_GT(root_layer_->update_count(), 0);
5498 EndTest();
5499 }
5500
5501 FakeContentLayerClient client_;
5502 scoped_refptr<FakePictureLayer> root_layer_;
5503 };
5504
5505 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
5506
5507 class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest {
5508 public:
LayerTreeHostTestElasticOverscroll()5509 LayerTreeHostTestElasticOverscroll()
5510 : scroll_elasticity_helper_(nullptr), num_draws_(0) {
5511 SetUseLayerLists();
5512 }
5513
InitializeSettings(LayerTreeSettings * settings)5514 void InitializeSettings(LayerTreeSettings* settings) override {
5515 settings->enable_elastic_overscroll = true;
5516 }
5517
SetupTree()5518 void SetupTree() override {
5519 LayerTreeHostTest::SetupTree();
5520 root_layer_ = layer_tree_host()->root_layer();
5521 SetupViewport(root_layer_, root_layer_->bounds(), root_layer_->bounds());
5522
5523 scoped_refptr<Layer> content_layer = FakePictureLayer::Create(&client_);
5524 content_layer_id_ = content_layer->id();
5525 content_layer->SetBounds(gfx::Size(10, 10));
5526 CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(),
5527 content_layer.get());
5528 root_layer_->AddChild(content_layer);
5529
5530 client_.set_bounds(content_layer->bounds());
5531 }
5532
BeginTest()5533 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5534
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)5535 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5536 if (host_impl->sync_tree()->source_frame_number() == 0) {
5537 scroll_elasticity_helper_ =
5538 host_impl->GetInputHandler().CreateScrollElasticityHelper();
5539 }
5540 }
5541
DrawLayersOnThread(LayerTreeHostImpl * host_impl)5542 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
5543 num_draws_++;
5544 LayerImpl* content_layer_impl =
5545 host_impl->active_tree()->LayerById(content_layer_id_);
5546 gfx::Transform expected_draw_transform;
5547 switch (num_draws_) {
5548 case 1:
5549 // Initially, there's no overscroll.
5550 EXPECT_EQ(expected_draw_transform, content_layer_impl->DrawTransform());
5551
5552 // Begin overscrolling. This should be reflected in the draw transform
5553 // the next time we draw.
5554 scroll_elasticity_helper_->SetStretchAmount(gfx::Vector2dF(5.f, 6.f));
5555 break;
5556 case 2:
5557 expected_draw_transform.Translate(-5.0, -6.0);
5558 EXPECT_EQ(expected_draw_transform, content_layer_impl->DrawTransform());
5559
5560 scroll_elasticity_helper_->SetStretchAmount(gfx::Vector2dF(3.f, 2.f));
5561 break;
5562 case 3:
5563 expected_draw_transform.Translate(-3.0, -2.0);
5564 EXPECT_EQ(expected_draw_transform, content_layer_impl->DrawTransform());
5565
5566 scroll_elasticity_helper_->SetStretchAmount(gfx::Vector2dF());
5567 break;
5568 case 4:
5569 EXPECT_EQ(expected_draw_transform, content_layer_impl->DrawTransform());
5570 EndTest();
5571 break;
5572 default:
5573 NOTREACHED();
5574 }
5575 }
5576
5577 private:
5578 FakeContentLayerClient client_;
5579 Layer* root_layer_;
5580 ScrollElasticityHelper* scroll_elasticity_helper_;
5581 int content_layer_id_;
5582 int num_draws_;
5583 };
5584
5585 MULTI_THREAD_TEST_F(LayerTreeHostTestElasticOverscroll);
5586
5587 struct TestSwapPromiseResult {
TestSwapPromiseResultcc::__anon887f63680111::TestSwapPromiseResult5588 TestSwapPromiseResult()
5589 : did_activate_called(false),
5590 did_swap_called(false),
5591 did_not_swap_called(false),
5592 dtor_called(false),
5593 reason(SwapPromise::COMMIT_FAILS) {}
5594
5595 bool did_activate_called;
5596 bool did_swap_called;
5597 bool did_not_swap_called;
5598 bool dtor_called;
5599 SwapPromise::DidNotSwapReason reason;
5600 base::Lock lock;
5601 };
5602
5603 class TestSwapPromise : public SwapPromise {
5604 public:
TestSwapPromise(TestSwapPromiseResult * result)5605 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
5606
~TestSwapPromise()5607 ~TestSwapPromise() override {
5608 base::AutoLock lock(result_->lock);
5609 result_->dtor_called = true;
5610 }
5611
DidActivate()5612 void DidActivate() override {
5613 base::AutoLock lock(result_->lock);
5614 EXPECT_FALSE(result_->did_activate_called);
5615 EXPECT_FALSE(result_->did_swap_called);
5616 EXPECT_TRUE(!result_->did_not_swap_called ||
5617 action_ == SwapPromise::DidNotSwapAction::KEEP_ACTIVE);
5618 result_->did_activate_called = true;
5619 }
5620
WillSwap(viz::CompositorFrameMetadata * metadata)5621 void WillSwap(viz::CompositorFrameMetadata* metadata) override {
5622 base::AutoLock lock(result_->lock);
5623 EXPECT_FALSE(result_->did_swap_called);
5624 EXPECT_TRUE(!result_->did_not_swap_called ||
5625 action_ == SwapPromise::DidNotSwapAction::KEEP_ACTIVE);
5626 result_->did_swap_called = true;
5627 }
5628
DidSwap()5629 void DidSwap() override {}
5630
DidNotSwap(DidNotSwapReason reason)5631 DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
5632 base::AutoLock lock(result_->lock);
5633 EXPECT_FALSE(result_->did_swap_called);
5634 EXPECT_FALSE(result_->did_not_swap_called);
5635 EXPECT_FALSE(result_->did_activate_called &&
5636 reason != DidNotSwapReason::SWAP_FAILS);
5637 result_->did_not_swap_called = true;
5638 result_->reason = reason;
5639 return action_;
5640 }
5641
set_action(DidNotSwapAction action)5642 void set_action(DidNotSwapAction action) { action_ = action; }
5643
TraceId() const5644 int64_t TraceId() const override { return 0; }
5645
5646 private:
5647 // Not owned.
5648 TestSwapPromiseResult* result_;
5649 DidNotSwapAction action_ = DidNotSwapAction::BREAK_PROMISE;
5650 };
5651
5652 class PinnedLayerTreeSwapPromise : public LayerTreeHostTest {
5653 protected:
BeginTest()5654 void BeginTest() override {
5655 layer_tree_host()->SetNeedsCommitWithForcedRedraw();
5656 }
5657
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)5658 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5659 int frame = host_impl->active_tree()->source_frame_number();
5660 if (frame == -1) {
5661 host_impl->active_tree()->QueuePinnedSwapPromise(
5662 std::make_unique<TestSwapPromise>(
5663 &pinned_active_swap_promise_result_));
5664 host_impl->pending_tree()->QueueSwapPromise(
5665 std::make_unique<TestSwapPromise>(&pending_swap_promise_result_));
5666 host_impl->active_tree()->QueueSwapPromise(
5667 std::make_unique<TestSwapPromise>(&active_swap_promise_result_));
5668 }
5669 }
5670
DisplayDidDrawAndSwapOnThread()5671 void DisplayDidDrawAndSwapOnThread() override { EndTest(); }
5672
AfterTest()5673 void AfterTest() override {
5674 // The pending swap promise should activate and swap.
5675 EXPECT_TRUE(pending_swap_promise_result_.did_activate_called);
5676 EXPECT_TRUE(pending_swap_promise_result_.did_swap_called);
5677
5678 // The active swap promise should fail to swap (it is cancelled by
5679 // the activation of a new frame).
5680 EXPECT_FALSE(active_swap_promise_result_.did_activate_called);
5681 EXPECT_FALSE(active_swap_promise_result_.did_swap_called);
5682 EXPECT_TRUE(active_swap_promise_result_.did_not_swap_called);
5683 EXPECT_EQ(active_swap_promise_result_.reason, SwapPromise::SWAP_FAILS);
5684
5685 // The pinned active swap promise should not activate, but should swap.
5686 EXPECT_FALSE(pinned_active_swap_promise_result_.did_activate_called);
5687 EXPECT_TRUE(pinned_active_swap_promise_result_.did_swap_called);
5688 }
5689
5690 TestSwapPromiseResult pending_swap_promise_result_;
5691 TestSwapPromiseResult active_swap_promise_result_;
5692 TestSwapPromiseResult pinned_active_swap_promise_result_;
5693 };
5694
5695 MULTI_THREAD_TEST_F(PinnedLayerTreeSwapPromise);
5696
5697 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
5698 protected:
LayerTreeHostTestBreakSwapPromise()5699 LayerTreeHostTestBreakSwapPromise()
5700 : commit_count_(0), commit_complete_count_(0) {}
5701
WillBeginMainFrame()5702 void WillBeginMainFrame() override {
5703 ASSERT_LE(commit_count_, 2);
5704 std::unique_ptr<SwapPromise> swap_promise(
5705 new TestSwapPromise(&swap_promise_result_[commit_count_]));
5706 layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
5707 std::move(swap_promise));
5708 }
5709
BeginTest()5710 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5711
DidCommit()5712 void DidCommit() override {
5713 commit_count_++;
5714 if (commit_count_ == 2) {
5715 // This commit will finish.
5716 layer_tree_host()->SetNeedsCommit();
5717 }
5718 }
5719
WillActivateTreeOnThread(LayerTreeHostImpl * host_impl)5720 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5721 if (host_impl->pending_tree()) {
5722 int frame = host_impl->pending_tree()->source_frame_number();
5723 base::AutoLock lock(swap_promise_result_[frame].lock);
5724 EXPECT_FALSE(swap_promise_result_[frame].did_activate_called);
5725 EXPECT_FALSE(swap_promise_result_[frame].did_swap_called);
5726 }
5727 }
5728
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)5729 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5730 int frame = host_impl->active_tree()->source_frame_number();
5731 base::AutoLock lock(swap_promise_result_[frame].lock);
5732 EXPECT_TRUE(swap_promise_result_[frame].did_activate_called);
5733 EXPECT_FALSE(swap_promise_result_[frame].did_swap_called);
5734 }
5735
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)5736 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
5737 commit_complete_count_++;
5738 if (commit_complete_count_ == 1) {
5739 // This commit will be aborted because no actual update.
5740 PostSetNeedsUpdateLayersToMainThread();
5741 }
5742 }
5743
DrawLayersOnThread(LayerTreeHostImpl * host_impl)5744 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
5745 int frame = host_impl->active_tree()->source_frame_number();
5746 if (frame == 2) {
5747 EndTest();
5748 }
5749 }
5750
AfterTest()5751 void AfterTest() override {
5752 // 3 commits are scheduled. 2 completes. 1 is aborted.
5753 EXPECT_EQ(commit_count_, 3);
5754 EXPECT_EQ(commit_complete_count_, 2);
5755
5756 {
5757 // The first commit completes and causes swap buffer which finishes
5758 // the promise.
5759 base::AutoLock lock(swap_promise_result_[0].lock);
5760 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
5761 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
5762 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
5763 }
5764
5765 {
5766 // The second commit is aborted since it contains no updates.
5767 base::AutoLock lock(swap_promise_result_[1].lock);
5768 EXPECT_FALSE(swap_promise_result_[1].did_activate_called);
5769 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
5770 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
5771 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason);
5772 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
5773 }
5774
5775 {
5776 // The last commit completes but it does not cause swap buffer because
5777 // there is no damage in the frame data.
5778 base::AutoLock lock(swap_promise_result_[2].lock);
5779 EXPECT_TRUE(swap_promise_result_[2].did_activate_called);
5780 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
5781 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
5782 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
5783 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
5784 }
5785 }
5786
5787 int commit_count_;
5788 int commit_complete_count_;
5789 TestSwapPromiseResult swap_promise_result_[3];
5790 };
5791
5792 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
5793
5794 class LayerTreeHostTestKeepSwapPromise : public LayerTreeHostTest {
5795 public:
5796 LayerTreeHostTestKeepSwapPromise() = default;
5797
BeginTest()5798 void BeginTest() override {
5799 layer_ = SolidColorLayer::Create();
5800 layer_->SetIsDrawable(true);
5801 layer_->SetBounds(gfx::Size(10, 10));
5802 layer_tree_host()->SetRootLayer(layer_);
5803 gfx::Size bounds(100, 100);
5804 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds), 1.f,
5805 viz::LocalSurfaceId());
5806 PostSetNeedsCommitToMainThread();
5807 }
5808
DidCommit()5809 void DidCommit() override {
5810 MainThreadTaskRunner()->PostTask(
5811 FROM_HERE,
5812 base::BindOnce(&LayerTreeHostTestKeepSwapPromise::ChangeFrame,
5813 base::Unretained(this)));
5814 }
5815
ChangeFrame()5816 void ChangeFrame() {
5817 switch (layer_tree_host()->SourceFrameNumber()) {
5818 case 1:
5819 layer_->SetBounds(gfx::Size(10, 11));
5820 layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
5821 std::make_unique<TestSwapPromise>(&swap_promise_result_));
5822 break;
5823 case 2:
5824 break;
5825 default:
5826 NOTREACHED();
5827 break;
5828 }
5829 }
5830
WillActivateTreeOnThread(LayerTreeHostImpl * host_impl)5831 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5832 if (host_impl->pending_tree()) {
5833 if (host_impl->pending_tree()->source_frame_number() == 1) {
5834 base::AutoLock lock(swap_promise_result_.lock);
5835 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5836 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5837 SetCallback(host_impl, true);
5838 } else {
5839 SetCallback(host_impl, false);
5840 }
5841 }
5842 }
5843
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)5844 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5845 if (host_impl->active_tree()->source_frame_number() == 1) {
5846 base::AutoLock lock(swap_promise_result_.lock);
5847 EXPECT_TRUE(swap_promise_result_.did_activate_called);
5848 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5849 }
5850 }
5851
ActivationCallback()5852 void ActivationCallback() {
5853 // DidActivate needs to happen before the tree activation callback.
5854 base::AutoLock lock(swap_promise_result_.lock);
5855 EXPECT_TRUE(swap_promise_result_.did_activate_called);
5856 }
5857
SetCallback(LayerTreeHostImpl * host_impl,bool enable)5858 void SetCallback(LayerTreeHostImpl* host_impl, bool enable) {
5859 host_impl->SetTreeActivationCallback(
5860 enable ? base::BindRepeating(
5861 &LayerTreeHostTestKeepSwapPromise::ActivationCallback,
5862 base::Unretained(this))
5863 : base::RepeatingClosure());
5864 }
5865
DisplayDidDrawAndSwapOnThread()5866 void DisplayDidDrawAndSwapOnThread() override {
5867 if (num_swaps_++ >= 1) {
5868 // The commit changes layers so it should cause a swap.
5869 base::AutoLock lock(swap_promise_result_.lock);
5870 EXPECT_TRUE(swap_promise_result_.did_swap_called);
5871 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5872 EXPECT_TRUE(swap_promise_result_.dtor_called);
5873 EndTest();
5874 }
5875 }
5876
5877 private:
5878 int num_swaps_ = 0;
5879 scoped_refptr<Layer> layer_;
5880 TestSwapPromiseResult swap_promise_result_;
5881 };
5882
5883 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise);
5884
5885 class LayerTreeHostTestKeepSwapPromiseMFBA : public LayerTreeHostTest {
5886 public:
5887 LayerTreeHostTestKeepSwapPromiseMFBA() = default;
5888
InitializeSettings(LayerTreeSettings * settings)5889 void InitializeSettings(LayerTreeSettings* settings) override {
5890 settings->main_frame_before_activation_enabled = true;
5891 }
5892
BeginTest()5893 void BeginTest() override {
5894 layer_ = SolidColorLayer::Create();
5895 layer_->SetIsDrawable(true);
5896 layer_->SetBounds(gfx::Size(10, 10));
5897 layer_tree_host()->SetRootLayer(layer_);
5898 gfx::Size bounds(100, 100);
5899 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(bounds), 1.f,
5900 viz::LocalSurfaceId());
5901 PostSetNeedsCommitToMainThread();
5902 }
5903
BeginCommitOnThread(LayerTreeHostImpl * host_impl)5904 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
5905 // Safe to check frame number here because main thread is blocked.
5906 if (layer_tree_host()->SourceFrameNumber() == 0) {
5907 host_impl->BlockNotifyReadyToActivateForTesting(true);
5908 } else {
5909 NOTREACHED();
5910 }
5911 }
5912
DidCommit()5913 void DidCommit() override {
5914 MainThreadTaskRunner()->PostTask(
5915 FROM_HERE,
5916 base::BindOnce(&LayerTreeHostTestKeepSwapPromiseMFBA::ChangeFrame,
5917 base::Unretained(this)));
5918 }
5919
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,CommitEarlyOutReason reason)5920 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
5921 CommitEarlyOutReason reason) override {
5922 base::AutoLock lock(swap_promise_result_.lock);
5923 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5924 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5925 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5926 host_impl->BlockNotifyReadyToActivateForTesting(false);
5927 }
5928
ChangeFrame()5929 void ChangeFrame() {
5930 switch (layer_tree_host()->SourceFrameNumber()) {
5931 case 1:
5932 // Make no changes so that we abort the next commit caused by queuing
5933 // the swap promise.
5934 layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
5935 std::make_unique<TestSwapPromise>(&swap_promise_result_));
5936 layer_tree_host()->SetNeedsUpdateLayers();
5937 break;
5938 case 2:
5939 break;
5940 default:
5941 NOTREACHED();
5942 break;
5943 }
5944 }
5945
WillActivateTreeOnThread(LayerTreeHostImpl * host_impl)5946 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5947 if (host_impl->pending_tree()) {
5948 if (host_impl->pending_tree()->source_frame_number() == 1) {
5949 base::AutoLock lock(swap_promise_result_.lock);
5950 EXPECT_FALSE(swap_promise_result_.did_activate_called);
5951 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5952 SetCallback(host_impl, true);
5953 } else {
5954 SetCallback(host_impl, false);
5955 }
5956 }
5957 }
5958
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)5959 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
5960 if (host_impl->active_tree()->source_frame_number() == 1) {
5961 base::AutoLock lock(swap_promise_result_.lock);
5962 EXPECT_TRUE(swap_promise_result_.did_activate_called);
5963 EXPECT_FALSE(swap_promise_result_.did_swap_called);
5964 }
5965 }
5966
ActivationCallback()5967 void ActivationCallback() {
5968 // DidActivate needs to happen before the tree activation callback.
5969 base::AutoLock lock(swap_promise_result_.lock);
5970 EXPECT_TRUE(swap_promise_result_.did_activate_called);
5971 }
5972
SetCallback(LayerTreeHostImpl * host_impl,bool enable)5973 void SetCallback(LayerTreeHostImpl* host_impl, bool enable) {
5974 host_impl->SetTreeActivationCallback(
5975 enable ? base::BindRepeating(
5976 &LayerTreeHostTestKeepSwapPromiseMFBA::ActivationCallback,
5977 base::Unretained(this))
5978 : base::RepeatingClosure());
5979 }
5980
DisplayDidDrawAndSwapOnThread()5981 void DisplayDidDrawAndSwapOnThread() override {
5982 num_swaps_++;
5983 base::AutoLock lock(swap_promise_result_.lock);
5984 EXPECT_TRUE(swap_promise_result_.did_swap_called);
5985 EXPECT_FALSE(swap_promise_result_.did_not_swap_called);
5986 EXPECT_TRUE(swap_promise_result_.dtor_called);
5987 EndTest();
5988 }
5989
AfterTest()5990 void AfterTest() override { EXPECT_EQ(1, num_swaps_); }
5991
5992 private:
5993 int num_swaps_ = 0;
5994 scoped_refptr<Layer> layer_;
5995 TestSwapPromiseResult swap_promise_result_;
5996 };
5997
5998 MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromiseMFBA);
5999
6000 class LayerTreeHostTestDeferSwapPromiseForVisibility
6001 : public LayerTreeHostTest {
6002 protected:
BeginTest()6003 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6004
SetVisibleFalseAndQueueSwapPromise()6005 void SetVisibleFalseAndQueueSwapPromise() {
6006 layer_tree_host()->SetVisible(false);
6007 auto swap_promise =
6008 std::make_unique<TestSwapPromise>(&swap_promise_result_);
6009 swap_promise->set_action(SwapPromise::DidNotSwapAction::KEEP_ACTIVE);
6010 layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
6011 std::move(swap_promise));
6012 }
6013
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const viz::BeginFrameArgs & args)6014 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
6015 const viz::BeginFrameArgs& args) override {
6016 if (!sent_queue_request_) {
6017 sent_queue_request_ = true;
6018 MainThreadTaskRunner()->PostTask(
6019 FROM_HERE,
6020 base::BindOnce(&LayerTreeHostTestDeferSwapPromiseForVisibility::
6021 SetVisibleFalseAndQueueSwapPromise,
6022 base::Unretained(this)));
6023 }
6024 }
6025
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,CommitEarlyOutReason reason)6026 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
6027 CommitEarlyOutReason reason) override {
6028 MainThreadTaskRunner()->PostTask(
6029 FROM_HERE,
6030 base::BindOnce(&LayerTreeHostTestDeferSwapPromiseForVisibility::
6031 CheckSwapPromiseNotCalled,
6032 base::Unretained(this)));
6033 }
6034
CheckSwapPromiseNotCalled()6035 void CheckSwapPromiseNotCalled() {
6036 {
6037 base::AutoLock lock(swap_promise_result_.lock);
6038 EXPECT_FALSE(swap_promise_result_.did_activate_called);
6039 EXPECT_FALSE(swap_promise_result_.did_swap_called);
6040 EXPECT_TRUE(swap_promise_result_.did_not_swap_called);
6041 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason);
6042 EXPECT_FALSE(swap_promise_result_.dtor_called);
6043 }
6044 layer_tree_host()->SetVisible(true);
6045 }
6046
DidCommitAndDrawFrame()6047 void DidCommitAndDrawFrame() override {
6048 {
6049 base::AutoLock lock(swap_promise_result_.lock);
6050 EXPECT_TRUE(swap_promise_result_.did_activate_called);
6051 EXPECT_TRUE(swap_promise_result_.did_swap_called);
6052 EXPECT_TRUE(swap_promise_result_.dtor_called);
6053 }
6054 EndTest();
6055 }
6056
6057 TestSwapPromiseResult swap_promise_result_;
6058 bool sent_queue_request_ = false;
6059 };
6060
6061 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferSwapPromiseForVisibility);
6062
6063 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
6064 public:
SimpleSwapPromiseMonitor(LayerTreeHost * layer_tree_host,int * set_needs_commit_count,int * set_needs_redraw_count)6065 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
6066 int* set_needs_commit_count,
6067 int* set_needs_redraw_count)
6068 : SwapPromiseMonitor(layer_tree_host
6069 ? layer_tree_host->GetSwapPromiseManager()
6070 : nullptr),
6071 set_needs_commit_count_(set_needs_commit_count) {}
6072
6073 ~SimpleSwapPromiseMonitor() override = default;
6074
OnSetNeedsCommitOnMain()6075 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
6076
OnSetNeedsRedrawOnImpl()6077 void OnSetNeedsRedrawOnImpl() override {
6078 ADD_FAILURE() << "Should not get called on main thread.";
6079 }
6080
6081 private:
6082 int* set_needs_commit_count_;
6083 };
6084
6085 class LayerTreeHostTestSwapPromiseDuringCommit : public LayerTreeHostTest {
6086 protected:
6087 LayerTreeHostTestSwapPromiseDuringCommit() = default;
6088
WillBeginMainFrame()6089 void WillBeginMainFrame() override {
6090 if (TestEnded())
6091 return;
6092
6093 std::unique_ptr<SwapPromise> swap_promise(
6094 new TestSwapPromise(&swap_promise_result_[0]));
6095 int set_needs_commit_count = 0;
6096 int set_needs_redraw_count = 0;
6097
6098 {
6099 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
6100 new SimpleSwapPromiseMonitor(layer_tree_host(),
6101 &set_needs_commit_count,
6102 &set_needs_redraw_count));
6103 layer_tree_host()->QueueSwapPromise(std::move(swap_promise));
6104 // Queueing a swap promise from WillBeginMainFrame should not cause
6105 // another commit to be scheduled.
6106 EXPECT_EQ(0, set_needs_commit_count);
6107 }
6108 }
6109
BeginTest()6110 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6111
DidBeginMainFrame()6112 void DidBeginMainFrame() override {
6113 if (TestEnded())
6114 return;
6115
6116 std::unique_ptr<SwapPromise> swap_promise(
6117 new TestSwapPromise(&swap_promise_result_[1]));
6118 int set_needs_commit_count = 0;
6119 int set_needs_redraw_count = 0;
6120
6121 {
6122 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
6123 new SimpleSwapPromiseMonitor(layer_tree_host(),
6124 &set_needs_commit_count,
6125 &set_needs_redraw_count));
6126 layer_tree_host()->QueueSwapPromise(std::move(swap_promise));
6127 // Queueing a swap promise from DidBeginMainFrame should not cause a
6128 // subsequent main frame to be scheduled.
6129 EXPECT_EQ(0, set_needs_commit_count);
6130 }
6131
6132 EndTest();
6133 }
6134
6135 TestSwapPromiseResult swap_promise_result_[2];
6136 };
6137
6138 MULTI_THREAD_TEST_F(LayerTreeHostTestSwapPromiseDuringCommit);
6139
6140 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
6141 public:
BeginTest()6142 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6143
WillBeginMainFrame()6144 void WillBeginMainFrame() override {
6145 if (TestEnded())
6146 return;
6147
6148 int set_needs_commit_count = 0;
6149 int set_needs_redraw_count = 0;
6150
6151 {
6152 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
6153 new SimpleSwapPromiseMonitor(layer_tree_host(),
6154 &set_needs_commit_count,
6155 &set_needs_redraw_count));
6156 layer_tree_host()->SetNeedsCommit();
6157 EXPECT_EQ(1, set_needs_commit_count);
6158 EXPECT_EQ(0, set_needs_redraw_count);
6159 }
6160
6161 // Now the monitor is destroyed, SetNeedsCommit() is no longer being
6162 // monitored.
6163 layer_tree_host()->SetNeedsCommit();
6164 EXPECT_EQ(1, set_needs_commit_count);
6165 EXPECT_EQ(0, set_needs_redraw_count);
6166
6167 {
6168 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
6169 new SimpleSwapPromiseMonitor(layer_tree_host(),
6170 &set_needs_commit_count,
6171 &set_needs_redraw_count));
6172 layer_tree_host()->SetNeedsUpdateLayers();
6173 EXPECT_EQ(2, set_needs_commit_count);
6174 EXPECT_EQ(0, set_needs_redraw_count);
6175 }
6176
6177 {
6178 std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
6179 new SimpleSwapPromiseMonitor(layer_tree_host(),
6180 &set_needs_commit_count,
6181 &set_needs_redraw_count));
6182 layer_tree_host()->SetNeedsAnimate();
6183 EXPECT_EQ(3, set_needs_commit_count);
6184 EXPECT_EQ(0, set_needs_redraw_count);
6185 }
6186
6187 EndTest();
6188 }
6189 };
6190
6191 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
6192
6193 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
6194 : public LayerTreeHostTest {
6195 protected:
SetupTree()6196 void SetupTree() override {
6197 LayerTreeHostTest::SetupTree();
6198 ui_resource_ =
6199 FakeScopedUIResource::Create(layer_tree_host()->GetUIResourceManager());
6200 }
6201
BeginTest()6202 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6203
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)6204 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6205 if (TestEnded())
6206 return;
6207
6208 host_impl->EvictAllUIResources();
6209 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
6210 // mode. Active tree should require high-res to draw after entering this
6211 // mode to ensure that high-res tiles are also required for a pending tree
6212 // to be activated.
6213 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
6214
6215 MainThreadTaskRunner()->PostTask(
6216 FROM_HERE,
6217 base::BindOnce(
6218 &LayerTreeHostTestHighResRequiredAfterEvictingUIResources::
6219 DeleteResourceAndEndTest,
6220 base::Unretained(this)));
6221 }
6222
DeleteResourceAndEndTest()6223 void DeleteResourceAndEndTest() {
6224 // This must be destroyed before the test ends and tears down the
6225 // LayerTreeHost. It causes another commit+activation though, which
6226 // may run before the test exits.
6227 ui_resource_ = nullptr;
6228 EndTest();
6229 }
6230
6231 std::unique_ptr<FakeScopedUIResource> ui_resource_;
6232 };
6233
6234 MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources);
6235
6236 class LayerTreeHostTestGpuRasterizationDisabled : public LayerTreeHostTest {
6237 protected:
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_provider)6238 void SetUpUnboundContextProviders(
6239 viz::TestContextProvider* context_provider,
6240 viz::TestContextProvider* worker_provider) override {
6241 // The test contexts have gpu raster disabled by default.
6242 gpu::Capabilities caps =
6243 context_provider->UnboundTestContextGL()->test_capabilities();
6244 EXPECT_FALSE(caps.gpu_rasterization);
6245 gpu::Capabilities worker_caps =
6246 context_provider->UnboundTestContextGL()->test_capabilities();
6247 EXPECT_FALSE(worker_caps.gpu_rasterization);
6248 }
6249
SetupTree()6250 void SetupTree() override {
6251 LayerTreeHostTest::SetupTree();
6252
6253 std::unique_ptr<FakeRecordingSource> recording_source(
6254 new FakeRecordingSource);
6255 recording_source_ = recording_source.get();
6256
6257 scoped_refptr<FakePictureLayer> layer =
6258 FakePictureLayer::CreateWithRecordingSource(
6259 &layer_client_, std::move(recording_source));
6260 layer_ = layer.get();
6261 layer->SetBounds(gfx::Size(10, 10));
6262 layer->SetIsDrawable(true);
6263 layer_tree_host()->root_layer()->AddChild(layer);
6264 layer_client_.set_bounds(layer_->bounds());
6265 }
6266
BeginTest()6267 void BeginTest() override {
6268 PostSetNeedsCommitToMainThread();
6269 }
6270
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)6271 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6272 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
6273 EXPECT_FALSE(host_impl->use_gpu_rasterization());
6274 }
6275
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)6276 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6277 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
6278 EXPECT_FALSE(host_impl->use_gpu_rasterization());
6279 EndTest();
6280 }
6281
6282 FakeContentLayerClient layer_client_;
6283 FakePictureLayer* layer_;
6284 FakeRecordingSource* recording_source_;
6285 };
6286
6287 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDisabled);
6288
6289 class LayerTreeHostTestGpuRasterizationSupportedButDisabled
6290 : public LayerTreeTest {
6291 protected:
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_provider)6292 void SetUpUnboundContextProviders(
6293 viz::TestContextProvider* context_provider,
6294 viz::TestContextProvider* worker_provider) override {
6295 context_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
6296 worker_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
6297 }
6298
InitializeSettings(LayerTreeSettings * settings)6299 void InitializeSettings(LayerTreeSettings* settings) override {
6300 settings->gpu_rasterization_disabled = true;
6301 }
6302
SetupTree()6303 void SetupTree() override {
6304 LayerTreeHostTest::SetupTree();
6305
6306 std::unique_ptr<FakeRecordingSource> recording_source(
6307 new FakeRecordingSource);
6308 recording_source_ = recording_source.get();
6309
6310 scoped_refptr<FakePictureLayer> layer =
6311 FakePictureLayer::CreateWithRecordingSource(
6312 &layer_client_, std::move(recording_source));
6313 layer_ = layer.get();
6314
6315 layer->SetBounds(gfx::Size(10, 10));
6316 layer->SetIsDrawable(true);
6317 layer_tree_host()->root_layer()->AddChild(layer);
6318 layer_client_.set_bounds(layer_->bounds());
6319 }
6320
BeginTest()6321 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6322
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)6323 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6324 EXPECT_FALSE(host_impl->sync_tree()->use_gpu_rasterization());
6325 EXPECT_FALSE(host_impl->use_gpu_rasterization());
6326 }
6327
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)6328 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6329 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
6330 EXPECT_FALSE(host_impl->use_gpu_rasterization());
6331 EndTest();
6332 }
6333
6334 FakeContentLayerClient layer_client_;
6335 FakePictureLayer* layer_;
6336 FakeRecordingSource* recording_source_;
6337 };
6338
6339 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationSupportedButDisabled);
6340
6341 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
6342 protected:
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_provider)6343 void SetUpUnboundContextProviders(
6344 viz::TestContextProvider* context_provider,
6345 viz::TestContextProvider* worker_provider) override {
6346 context_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
6347 worker_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
6348 }
6349
SetupTree()6350 void SetupTree() override {
6351 LayerTreeHostTest::SetupTree();
6352
6353 std::unique_ptr<FakeRecordingSource> recording_source(
6354 new FakeRecordingSource);
6355 recording_source_ = recording_source.get();
6356
6357 scoped_refptr<FakePictureLayer> layer =
6358 FakePictureLayer::CreateWithRecordingSource(
6359 &layer_client_, std::move(recording_source));
6360 layer_ = layer.get();
6361
6362 layer->SetBounds(gfx::Size(10, 10));
6363 layer->SetIsDrawable(true);
6364 layer_tree_host()->root_layer()->AddChild(layer);
6365 layer_client_.set_bounds(layer_->bounds());
6366 }
6367
BeginTest()6368 void BeginTest() override {
6369 PostSetNeedsCommitToMainThread();
6370 }
6371
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)6372 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6373 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
6374 EXPECT_TRUE(host_impl->use_gpu_rasterization());
6375 }
6376
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)6377 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6378 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
6379 EXPECT_TRUE(host_impl->use_gpu_rasterization());
6380 EndTest();
6381 }
6382
6383 FakeContentLayerClient layer_client_;
6384 FakePictureLayer* layer_;
6385 FakeRecordingSource* recording_source_;
6386 };
6387
6388 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
6389
6390 class LayerTreeHostTestGpuRasterizationEnabledWithMSAA : public LayerTreeTest {
6391 protected:
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_provider)6392 void SetUpUnboundContextProviders(
6393 viz::TestContextProvider* context_provider,
6394 viz::TestContextProvider* worker_provider) override {
6395 viz::TestGLES2Interface* gl = context_provider->UnboundTestContextGL();
6396 gl->set_gpu_rasterization(true);
6397 gl->set_support_multisample_compatibility(false);
6398 gl->SetMaxSamples(4);
6399 viz::TestGLES2Interface* worker = worker_provider->UnboundTestContextGL();
6400 worker->set_gpu_rasterization(true);
6401 worker->set_support_multisample_compatibility(false);
6402 worker->SetMaxSamples(4);
6403 }
6404
InitializeSettings(LayerTreeSettings * settings)6405 void InitializeSettings(LayerTreeSettings* settings) override {
6406 // GetMSAASampleCountForRaster() will return this value if there are too
6407 // many slow paths.
6408 settings->gpu_rasterization_msaa_sample_count = 4;
6409 }
6410
SetupTree()6411 void SetupTree() override {
6412 LayerTreeHostTest::SetupTree();
6413
6414 auto recording_source = std::make_unique<FakeRecordingSource>();
6415 recording_source_ = recording_source.get();
6416
6417 scoped_refptr<FakePictureLayer> layer =
6418 FakePictureLayer::CreateWithRecordingSource(
6419 &layer_client_, std::move(recording_source));
6420 layer_ = layer.get();
6421 layer->SetBounds(gfx::Size(10, 10));
6422 layer->SetIsDrawable(true);
6423 layer_tree_host()->root_layer()->AddChild(layer);
6424 layer_client_.set_bounds(layer_->bounds());
6425 }
6426
BeginTest()6427 void BeginTest() override {
6428 // Content-based MSAA trigger.
6429 layer_client_.set_contains_slow_paths(true);
6430 // MSAA trigger will take effect when layers are updated.
6431 // The results will be verified after commit is completed below.
6432 // Since we are manually marking the source as containing slow paths,
6433 // make sure that the layer gets a chance to update.
6434 layer_->SetNeedsDisplay();
6435
6436 PostSetNeedsCommitToMainThread();
6437 }
6438
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)6439 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6440 auto* raster_source = static_cast<PictureLayerImpl*>(
6441 host_impl->sync_tree()->LayerById(layer_->id()))
6442 ->GetRasterSource();
6443 EXPECT_GT(host_impl->GetMSAASampleCountForRaster(
6444 raster_source->GetDisplayItemList()),
6445 0);
6446 EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
6447 EXPECT_TRUE(host_impl->use_gpu_rasterization());
6448 EndTest();
6449 }
6450
6451 FakeContentLayerClient layer_client_;
6452 FakePictureLayer* layer_;
6453 FakeRecordingSource* recording_source_;
6454 };
6455
6456 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabledWithMSAA);
6457
6458 class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
6459 : public LayerTreeHostTest {
6460 public:
6461 enum { kExpectedNumImplFrames = 10 };
6462
LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame()6463 LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame()
6464 : will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {}
6465
BeginTest()6466 void BeginTest() override {
6467 PostSetNeedsCommitToMainThread();
6468 }
6469
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)6470 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
6471 const viz::BeginFrameArgs& args) override {
6472 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
6473 EXPECT_FALSE(TestEnded());
6474 will_begin_impl_frame_count_++;
6475 }
6476
DidFinishImplFrameOnThread(LayerTreeHostImpl * host_impl)6477 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
6478 did_finish_impl_frame_count_++;
6479 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
6480
6481 // Trigger a new impl frame until we are done testing.
6482 if (did_finish_impl_frame_count_ < kExpectedNumImplFrames)
6483 PostSetNeedsRedrawToMainThread();
6484 else
6485 EndTest();
6486 }
6487
AfterTest()6488 void AfterTest() override {
6489 EXPECT_GT(will_begin_impl_frame_count_, 0);
6490 EXPECT_GT(did_finish_impl_frame_count_, 0);
6491 EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
6492
6493 EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
6494 EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
6495 }
6496
6497 private:
6498 int will_begin_impl_frame_count_;
6499 int did_finish_impl_frame_count_;
6500 };
6501
6502 // TODO(crbug.com/842038): Disabled as flaky.
6503 // SINGLE_AND_MULTI_THREAD_TEST_F(
6504 // LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame);
6505
AssertFrameTimeContained(const char * haystack_expr,const char * needle_expr,const std::vector<viz::BeginFrameArgs> haystack,const viz::BeginFrameArgs needle)6506 ::testing::AssertionResult AssertFrameTimeContained(
6507 const char* haystack_expr,
6508 const char* needle_expr,
6509 const std::vector<viz::BeginFrameArgs> haystack,
6510 const viz::BeginFrameArgs needle) {
6511 auto failure = ::testing::AssertionFailure()
6512 << needle.frame_time << " (" << needle_expr
6513 << ") not found in " << haystack_expr;
6514
6515 if (haystack.size() == 0) {
6516 failure << " which is empty.";
6517 } else {
6518 failure << " which contains:\n";
6519 for (size_t i = 0; i < haystack.size(); i++) {
6520 if (haystack[i].frame_time == needle.frame_time)
6521 return ::testing::AssertionSuccess();
6522 failure << " [" << i << "]: " << haystack[i].frame_time << "\n";
6523 }
6524 }
6525
6526 return failure;
6527 }
6528
6529 class LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime
6530 : public LayerTreeHostTest {
6531 public:
LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime()6532 LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime()
6533 : impl_frame_args_(), will_begin_impl_frame_count_(0) {}
6534
BeginTest()6535 void BeginTest() override {
6536 // Test terminates when a main frame is no longer expected so request that
6537 // this message is actually sent.
6538 layer_tree_host()->RequestBeginMainFrameNotExpected(true);
6539 // Kick off the test with a commit.
6540 PostSetNeedsCommitToMainThread();
6541 }
6542
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const viz::BeginFrameArgs & args)6543 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
6544 const viz::BeginFrameArgs& args) override {
6545 impl_frame_args_.push_back(args);
6546
6547 will_begin_impl_frame_count_++;
6548 if (will_begin_impl_frame_count_ < 10)
6549 PostSetNeedsCommitToMainThread();
6550 }
6551
BeginMainFrame(const viz::BeginFrameArgs & args)6552 void BeginMainFrame(const viz::BeginFrameArgs& args) override {
6553 ASSERT_GT(impl_frame_args_.size(), 0U)
6554 << "BeginMainFrame called before BeginImplFrame called!";
6555 EXPECT_PRED_FORMAT2(AssertFrameTimeContained, impl_frame_args_, args);
6556 }
6557
BeginMainFrameNotExpectedSoon()6558 void BeginMainFrameNotExpectedSoon() override { EndTest(); }
6559
AfterTest()6560 void AfterTest() override {
6561 EXPECT_GT(impl_frame_args_.size(), 0U);
6562 EXPECT_GE(will_begin_impl_frame_count_, 10);
6563 }
6564
6565 private:
6566 std::vector<viz::BeginFrameArgs> impl_frame_args_;
6567 int will_begin_impl_frame_count_;
6568 };
6569
6570 // TODO(mithro): Re-enable the multi-threaded version of this test
6571 // http://crbug.com/537621
6572 // SINGLE_AND_MULTI_THREAD_TEST_F(
6573 // LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime);
6574 SINGLE_THREAD_TEST_F(LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime);
6575
6576 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
6577 public:
LayerTreeHostTestActivateOnInvisible()6578 LayerTreeHostTestActivateOnInvisible()
6579 : activation_count_(0), visible_(true) {}
6580
BeginTest()6581 void BeginTest() override {
6582 // Kick off the test with a commit.
6583 PostSetNeedsCommitToMainThread();
6584 }
6585
BeginCommitOnThread(LayerTreeHostImpl * host_impl)6586 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
6587 // Make sure we don't activate using the notify signal from tile manager.
6588 host_impl->BlockNotifyReadyToActivateForTesting(true);
6589 }
6590
DidCommit()6591 void DidCommit() override { layer_tree_host()->SetVisible(false); }
6592
DidSetVisibleOnImplTree(LayerTreeHostImpl * host_impl,bool visible)6593 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
6594 bool visible) override {
6595 visible_ = visible;
6596
6597 // Once invisible, we can go visible again.
6598 if (!visible) {
6599 PostSetVisibleToMainThread(true);
6600 } else if (activation_count_) {
6601 EXPECT_TRUE(host_impl->RequiresHighResToDraw());
6602 EndTest();
6603 }
6604 }
6605
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)6606 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6607 ++activation_count_;
6608 EXPECT_FALSE(visible_);
6609 }
6610
AfterTest()6611 void AfterTest() override {
6612 // Ensure we activated even though the signal was blocked.
6613 EXPECT_EQ(1, activation_count_);
6614 EXPECT_TRUE(visible_);
6615 }
6616
6617 private:
6618 int activation_count_;
6619 bool visible_;
6620 };
6621
6622 // TODO(vmpstr): Enable with single thread impl-side painting.
6623 // This test blocks activation which is not supported for single thread mode.
6624 MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestActivateOnInvisible);
6625
6626 class LayerTreeHostTestRenderSurfaceEffectTreeIndex : public LayerTreeHostTest {
6627 public:
6628 LayerTreeHostTestRenderSurfaceEffectTreeIndex() = default;
6629
BeginTest()6630 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6631
SetupTree()6632 void SetupTree() override {
6633 root_ = Layer::Create();
6634 child_ = Layer::Create();
6635 grand_child_ = Layer::Create();
6636
6637 layer_tree_host()->SetRootLayer(root_);
6638 root_->AddChild(child_);
6639 child_->AddChild(grand_child_);
6640
6641 root_->SetBounds(gfx::Size(50, 50));
6642 child_->SetBounds(gfx::Size(50, 50));
6643 grand_child_->SetBounds(gfx::Size(50, 50));
6644 child_->SetForceRenderSurfaceForTesting(true);
6645 grand_child_->SetForceRenderSurfaceForTesting(true);
6646
6647 LayerTreeHostTest::SetupTree();
6648 }
6649
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)6650 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
6651 if (host_impl->sync_tree()->source_frame_number() >= 1) {
6652 LayerImpl* grand_child_impl =
6653 host_impl->sync_tree()->LayerById(grand_child_->id());
6654 EXPECT_EQ(grand_child_impl->effect_tree_index(),
6655 GetRenderSurface(grand_child_impl)->EffectTreeIndex());
6656 }
6657 }
6658
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)6659 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
6660 LayerImpl* grand_child_impl =
6661 host_impl->active_tree()->LayerById(grand_child_->id());
6662 switch (host_impl->active_tree()->source_frame_number()) {
6663 case 0:
6664 PostSetNeedsCommitToMainThread();
6665 break;
6666 case 1:
6667 case 2:
6668 EXPECT_EQ(grand_child_impl->effect_tree_index(),
6669 GetRenderSurface(grand_child_impl)->EffectTreeIndex());
6670 PostSetNeedsCommitToMainThread();
6671 break;
6672 case 3:
6673 EXPECT_EQ(grand_child_impl->effect_tree_index(),
6674 GetRenderSurface(grand_child_impl)->EffectTreeIndex());
6675 EndTest();
6676 }
6677 }
6678
DidCommit()6679 void DidCommit() override {
6680 switch (layer_tree_host()->SourceFrameNumber()) {
6681 case 2:
6682 // Setting an empty viewport causes draws to get skipped, so the active
6683 // tree won't update draw properties.
6684 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(), 1.f,
6685 GetCurrentLocalSurfaceId());
6686 child_->SetForceRenderSurfaceForTesting(false);
6687 break;
6688 case 3:
6689 layer_tree_host()->SetViewportRectAndScale(
6690 gfx::Rect(root_->bounds()), 1.f, GetCurrentLocalSurfaceId());
6691 }
6692 }
6693
6694 private:
6695 scoped_refptr<Layer> root_;
6696 scoped_refptr<Layer> child_;
6697 scoped_refptr<Layer> grand_child_;
6698 };
6699
6700 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRenderSurfaceEffectTreeIndex);
6701
6702 // Do a synchronous composite and assert that the swap promise succeeds.
6703 class LayerTreeHostTestSynchronousCompositeSwapPromise
6704 : public LayerTreeHostTest {
6705 public:
6706 LayerTreeHostTestSynchronousCompositeSwapPromise() = default;
6707
InitializeSettings(LayerTreeSettings * settings)6708 void InitializeSettings(LayerTreeSettings* settings) override {
6709 settings->single_thread_proxy_scheduler = false;
6710 settings->use_zero_copy = true;
6711 }
6712
CreateLayerTreeFrameSink(const viz::RendererSettings & renderer_settings,double refresh_rate,scoped_refptr<viz::ContextProvider> compositor_context_provider,scoped_refptr<viz::RasterContextProvider> worker_context_provider)6713 std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
6714 const viz::RendererSettings& renderer_settings,
6715 double refresh_rate,
6716 scoped_refptr<viz::ContextProvider> compositor_context_provider,
6717 scoped_refptr<viz::RasterContextProvider> worker_context_provider)
6718 override {
6719 constexpr bool disable_display_vsync = false;
6720 bool synchronous_composite =
6721 !HasImplThread() &&
6722 !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
6723 return std::make_unique<TestLayerTreeFrameSink>(
6724 compositor_context_provider, std::move(worker_context_provider),
6725 gpu_memory_buffer_manager(), renderer_settings, &debug_settings_,
6726 ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
6727 refresh_rate);
6728 }
6729
BeginTest()6730 void BeginTest() override {
6731 // Successful composite.
6732 const bool raster = true;
6733 std::unique_ptr<SwapPromise> swap_promise0(
6734 new TestSwapPromise(&swap_promise_result_[0]));
6735 layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
6736 std::move(swap_promise0));
6737 layer_tree_host()->CompositeForTest(base::TimeTicks::Now(), raster);
6738
6739 // Fail to swap (no damage) if not reclaiming resources from the Display.
6740 std::unique_ptr<SwapPromise> swap_promise1(
6741 new TestSwapPromise(&swap_promise_result_[1]));
6742 layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
6743 std::move(swap_promise1));
6744 layer_tree_host()->SetNeedsCommit();
6745 layer_tree_host()->CompositeForTest(base::TimeTicks::Now(), raster);
6746
6747 // Fail to draw (not visible).
6748 std::unique_ptr<SwapPromise> swap_promise2(
6749 new TestSwapPromise(&swap_promise_result_[2]));
6750 layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
6751 std::move(swap_promise2));
6752 layer_tree_host()->SetNeedsDisplayOnAllLayers();
6753 layer_tree_host()->SetVisible(false);
6754 layer_tree_host()->CompositeForTest(base::TimeTicks::Now(), raster);
6755
6756 EndTest();
6757 }
6758
DidCommit()6759 void DidCommit() override {
6760 commit_count_++;
6761 ASSERT_LE(commit_count_, 3);
6762 }
6763
AfterTest()6764 void AfterTest() override {
6765 EXPECT_EQ(3, commit_count_);
6766
6767 // Initial swap promise should have succeded.
6768 {
6769 base::AutoLock lock(swap_promise_result_[0].lock);
6770 EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
6771 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
6772 EXPECT_TRUE(swap_promise_result_[0].dtor_called);
6773 }
6774
6775 // Second swap promise fails to swap.
6776 {
6777 base::AutoLock lock(swap_promise_result_[1].lock);
6778 EXPECT_TRUE(swap_promise_result_[1].did_activate_called);
6779 EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
6780 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
6781 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason);
6782 EXPECT_TRUE(swap_promise_result_[1].dtor_called);
6783 }
6784
6785 // Third swap promises also fails to swap (and draw).
6786 {
6787 base::AutoLock lock(swap_promise_result_[2].lock);
6788 EXPECT_TRUE(swap_promise_result_[2].did_activate_called);
6789 EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
6790 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
6791 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
6792 EXPECT_TRUE(swap_promise_result_[2].dtor_called);
6793 }
6794 }
6795
6796 int commit_count_ = 0;
6797 TestSwapPromiseResult swap_promise_result_[3];
6798 };
6799
6800 // Synchronous composite is a single-threaded only feature.
6801 SINGLE_THREAD_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
6802
6803 // Make sure page scale and top control deltas are applied to the client even
6804 // when the LayerTreeHost doesn't have a root layer.
6805 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
6806 : public LayerTreeHostTest {
6807 public:
LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()6808 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer()
6809 : deltas_sent_to_client_(false) {}
6810
BeginTest()6811 void BeginTest() override {
6812 layer_tree_host()->SetRootLayer(nullptr);
6813 commit_data_.page_scale_delta = 3.14f;
6814 commit_data_.top_controls_delta = 2.73f;
6815
6816 PostSetNeedsCommitToMainThread();
6817 }
6818
BeginMainFrame(const viz::BeginFrameArgs & args)6819 void BeginMainFrame(const viz::BeginFrameArgs& args) override {
6820 EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
6821
6822 layer_tree_host()->ApplyCompositorChanges(&commit_data_);
6823 EndTest();
6824 }
6825
ApplyViewportChanges(const ApplyViewportChangesArgs & args)6826 void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
6827 EXPECT_EQ(commit_data_.page_scale_delta, args.page_scale_delta);
6828 EXPECT_EQ(commit_data_.top_controls_delta, args.top_controls_delta);
6829 EXPECT_EQ(commit_data_.browser_controls_constraint,
6830 args.browser_controls_constraint);
6831 deltas_sent_to_client_ = true;
6832 }
6833
AfterTest()6834 void AfterTest() override { EXPECT_TRUE(deltas_sent_to_client_); }
6835
6836 CompositorCommitData commit_data_;
6837 bool deltas_sent_to_client_;
6838 };
6839
6840 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
6841
6842 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
6843 protected:
LayerTreeHostTestCrispUpAfterPinchEnds()6844 LayerTreeHostTestCrispUpAfterPinchEnds()
6845 : playback_allowed_event_(base::WaitableEvent::ResetPolicy::MANUAL,
6846 base::WaitableEvent::InitialState::SIGNALED) {
6847 SetUseLayerLists();
6848 }
6849
SetupTree()6850 void SetupTree() override {
6851 frame_ = 1;
6852 posted_ = false;
6853 client_.set_fill_with_nonsolid_color(true);
6854
6855 SetInitialRootBounds(gfx::Size(500, 500));
6856 LayerTreeHostTest::SetupTree();
6857 Layer* root = layer_tree_host()->root_layer();
6858 SetupViewport(root, root->bounds(), root->bounds());
6859
6860 std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource);
6861 recording->SetPlaybackAllowedEvent(&playback_allowed_event_);
6862 scoped_refptr<FakePictureLayer> layer =
6863 FakePictureLayer::CreateWithRecordingSource(&client_,
6864 std::move(recording));
6865 layer->SetBounds(gfx::Size(500, 500));
6866 layer->SetContentsOpaque(true);
6867 // Avoid LCD text on the layer so we don't cause extra commits when we
6868 // pinch.
6869 CopyProperties(layer_tree_host()->InnerViewportScrollLayerForTesting(),
6870 layer.get());
6871 root->AddChild(layer);
6872
6873 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
6874 client_.set_bounds(root->bounds());
6875 }
6876
6877 // Returns the delta scale of all quads in the frame's root pass from their
6878 // ideal, or 0 if they are not all the same.
FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData * frame_data)6879 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
6880 if (frame_data->has_no_damage)
6881 return 0.f;
6882 float frame_scale = 0.f;
6883 viz::CompositorRenderPass* root_pass =
6884 frame_data->render_passes.back().get();
6885 for (auto* draw_quad : root_pass->quad_list) {
6886 // Checkerboards mean an incomplete frame.
6887 if (draw_quad->material != viz::DrawQuad::Material::kTiledContent)
6888 return 0.f;
6889 const viz::TileDrawQuad* quad =
6890 viz::TileDrawQuad::MaterialCast(draw_quad);
6891 float quad_scale =
6892 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
6893 float transform_scale = SkScalarToFloat(
6894 quad->shared_quad_state->quad_to_target_transform.matrix().get(0, 0));
6895 float scale = quad_scale / transform_scale;
6896 if (frame_scale != 0.f && frame_scale != scale)
6897 return 0.f;
6898 frame_scale = scale;
6899 }
6900 return frame_scale;
6901 }
6902
BeginTest()6903 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
6904
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)6905 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
6906 LayerTreeHostImpl::FrameData* frame_data,
6907 DrawResult draw_result) override {
6908 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
6909 switch (frame_) {
6910 case 1:
6911 // Drew at page scale 1 before any pinching.
6912 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6913 EXPECT_EQ(1.f, quad_scale_delta);
6914 PostNextAfterDraw(host_impl);
6915 break;
6916 case 2:
6917 if (quad_scale_delta != 1.f)
6918 break;
6919 // Drew at page scale 1.5 after pinching in.
6920 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
6921 EXPECT_EQ(1.f, quad_scale_delta);
6922 PostNextAfterDraw(host_impl);
6923 break;
6924 case 3:
6925 // By pinching out, we will create a new tiling and raster it. This may
6926 // cause some additional draws, though we should still be drawing with
6927 // the old 1.5 tiling.
6928 if (frame_data->has_no_damage)
6929 break;
6930 // Drew at page scale 1 with the 1.5 tiling while pinching out.
6931 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6932 EXPECT_EQ(1.5f, quad_scale_delta);
6933 // We don't PostNextAfterDraw here, instead we wait for the new tiling
6934 // to finish rastering so we don't get any noise in further steps.
6935 break;
6936 case 4:
6937 // Drew at page scale 1 with the 1.5 tiling after pinching out completed
6938 // while waiting for texture uploads to complete.
6939 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6940 // This frame will not have any damage, since it's actually the same as
6941 // the last frame, and should contain no incomplete tiles. We just want
6942 // to make sure we drew here at least once after the pinch ended to be
6943 // sure that drawing after pinch doesn't leave us at the wrong scale
6944 EXPECT_TRUE(frame_data->has_no_damage);
6945 PostNextAfterDraw(host_impl);
6946 break;
6947 case 5:
6948 if (quad_scale_delta != 1.f)
6949 break;
6950 // Drew at scale 1 after texture uploads are done.
6951 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
6952 EXPECT_EQ(1.f, quad_scale_delta);
6953 EndTest();
6954 break;
6955 }
6956 return draw_result;
6957 }
6958
PostNextAfterDraw(LayerTreeHostImpl * host_impl)6959 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
6960 if (posted_)
6961 return;
6962 posted_ = true;
6963 ImplThreadTaskRunner()->PostDelayedTask(
6964 FROM_HERE,
6965 base::BindOnce(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
6966 base::Unretained(this), host_impl),
6967 // Use a delay to allow raster/upload to happen in between frames. This
6968 // should cause flakiness if we fail to block raster/upload when
6969 // desired.
6970 base::TimeDelta::FromMilliseconds(16 * 4));
6971 }
6972
Next(LayerTreeHostImpl * host_impl)6973 void Next(LayerTreeHostImpl* host_impl) {
6974 ++frame_;
6975 posted_ = false;
6976 switch (frame_) {
6977 case 2:
6978 // Pinch zoom in.
6979 host_impl->GetInputHandler().PinchGestureBegin();
6980 host_impl->GetInputHandler().PinchGestureUpdate(1.5f,
6981 gfx::Point(100, 100));
6982 host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100),
6983 true);
6984 break;
6985 case 3:
6986 // Pinch zoom back to 1.f but don't end it.
6987 host_impl->GetInputHandler().PinchGestureBegin();
6988 host_impl->GetInputHandler().PinchGestureUpdate(1.f / 1.5f,
6989 gfx::Point(100, 100));
6990 break;
6991 case 4:
6992 // End the pinch, but delay tile production.
6993 playback_allowed_event_.Reset();
6994 host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100),
6995 true);
6996 break;
6997 case 5:
6998 // Let tiles complete.
6999 playback_allowed_event_.Signal();
7000 break;
7001 }
7002 }
7003
NotifyTileStateChangedOnThread(LayerTreeHostImpl * host_impl,const Tile * tile)7004 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
7005 const Tile* tile) override {
7006 if (frame_ == 3) {
7007 // On frame 3, we will have a lower res tile complete for the pinch-out
7008 // gesture even though it's not displayed. We wait for it here to prevent
7009 // flakiness.
7010 EXPECT_EQ(gfx::AxisTransform2d(0.75f, gfx::Vector2dF()),
7011 tile->raster_transform());
7012 PostNextAfterDraw(host_impl);
7013 }
7014 // On frame_ == 4, we are preventing texture uploads from completing,
7015 // so this verifies they are not completing before frame_ == 5.
7016 // Flaky failures here indicate we're failing to prevent uploads from
7017 // completing.
7018 EXPECT_NE(4, frame_) << tile->contents_scale_key();
7019 }
7020
7021 FakeContentLayerClient client_;
7022 int frame_;
7023 bool posted_;
7024 base::WaitableEvent playback_allowed_event_;
7025 };
7026
7027 // This test does pinching on the impl side which is not supported in single
7028 // thread.
7029 MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
7030
7031 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
7032 : public LayerTreeHostTestCrispUpAfterPinchEnds {
7033 protected:
CreateDisplayOutputSurfaceOnThread(scoped_refptr<viz::ContextProvider> compositor_context_provider)7034 std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
7035 scoped_refptr<viz::ContextProvider> compositor_context_provider)
7036 override {
7037 scoped_refptr<viz::TestContextProvider> display_context_provider =
7038 viz::TestContextProvider::Create();
7039 viz::TestGLES2Interface* gl =
7040 display_context_provider->UnboundTestContextGL();
7041 gl->set_support_sync_query(true);
7042 #if defined(OS_MAC)
7043 gl->set_support_texture_rectangle(true);
7044 #endif
7045 display_context_provider->BindToCurrentThread();
7046 return LayerTreeTest::CreateDisplayOutputSurfaceOnThread(
7047 std::move(display_context_provider));
7048 }
7049 };
7050
7051 // This test does pinching on the impl side which is not supported in single
7052 // thread.
7053 MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
7054
7055 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
7056 protected:
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_provider)7057 void SetUpUnboundContextProviders(
7058 viz::TestContextProvider* context_provider,
7059 viz::TestContextProvider* worker_provider) override {
7060 context_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
7061 worker_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
7062 }
7063
SetupTree()7064 void SetupTree() override {
7065 client_.set_fill_with_nonsolid_color(true);
7066
7067 scoped_refptr<Layer> root = Layer::Create();
7068 root->SetBounds(gfx::Size(500, 500));
7069 client_.set_bounds(root->bounds());
7070
7071 std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource);
7072 scoped_refptr<FakePictureLayer> layer =
7073 FakePictureLayer::CreateWithRecordingSource(&client_,
7074 std::move(recording));
7075 layer->SetBounds(gfx::Size(500, 500));
7076 layer->SetContentsOpaque(true);
7077 root->AddChild(layer);
7078
7079 layer_tree_host()->SetRootLayer(root);
7080 LayerTreeHostTest::SetupTree();
7081 client_.set_bounds(root->bounds());
7082 }
7083
BeginTest()7084 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7085
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7086 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7087 LayerTreeHostImpl::FrameData* frame_data,
7088 DrawResult draw_result) override {
7089 EXPECT_NE(0u, host_impl->resource_pool()->resource_count());
7090 EndTest();
7091 return draw_result;
7092 }
7093
7094 FakeContentLayerClient client_;
7095 };
7096
7097 SINGLE_AND_MULTI_THREAD_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
7098
7099 class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
7100 protected:
GpuRasterizationRasterizesBorderTiles()7101 GpuRasterizationRasterizesBorderTiles() : viewport_size_(1024, 2048) {}
7102
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_provider)7103 void SetUpUnboundContextProviders(
7104 viz::TestContextProvider* context_provider,
7105 viz::TestContextProvider* worker_provider) override {
7106 context_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
7107 worker_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
7108 }
7109
SetupTree()7110 void SetupTree() override {
7111 client_.set_fill_with_nonsolid_color(true);
7112
7113 std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource);
7114 scoped_refptr<FakePictureLayer> root =
7115 FakePictureLayer::CreateWithRecordingSource(&client_,
7116 std::move(recording));
7117 root->SetBounds(gfx::Size(10000, 10000));
7118 client_.set_bounds(root->bounds());
7119 root->SetContentsOpaque(true);
7120
7121 layer_tree_host()->SetRootLayer(root);
7122 LayerTreeHostTest::SetupTree();
7123 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(viewport_size_), 1.f,
7124 viz::LocalSurfaceId());
7125 client_.set_bounds(root->bounds());
7126 }
7127
BeginTest()7128 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7129
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7130 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7131 LayerTreeHostImpl::FrameData* frame_data,
7132 DrawResult draw_result) override {
7133 EXPECT_EQ(15u, host_impl->resource_pool()->resource_count());
7134 EndTest();
7135 return draw_result;
7136 }
7137
7138 private:
7139 FakeContentLayerClient client_;
7140 gfx::Size viewport_size_;
7141 };
7142
7143 SINGLE_AND_MULTI_THREAD_TEST_F(GpuRasterizationRasterizesBorderTiles);
7144
7145 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
7146 : public LayerTreeHostTest {
7147 protected:
LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()7148 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
7149 : playback_allowed_event_(base::WaitableEvent::ResetPolicy::MANUAL,
7150 base::WaitableEvent::InitialState::SIGNALED) {
7151 SetUseLayerLists();
7152 }
7153
SetupTree()7154 void SetupTree() override {
7155 step_ = 1;
7156 continuous_draws_ = 0;
7157 client_.set_fill_with_nonsolid_color(true);
7158
7159 SetInitialRootBounds(gfx::Size(500, 500));
7160 LayerTreeHostTest::SetupTree();
7161
7162 Layer* root = layer_tree_host()->root_layer();
7163 SetupViewport(root, root->bounds(), root->bounds());
7164
7165 std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource);
7166 recording->SetPlaybackAllowedEvent(&playback_allowed_event_);
7167 scoped_refptr<FakePictureLayer> layer =
7168 FakePictureLayer::CreateWithRecordingSource(&client_,
7169 std::move(recording));
7170 layer->SetBounds(gfx::Size(500, 500));
7171 layer->SetContentsOpaque(true);
7172 CopyProperties(layer_tree_host()->InnerViewportScrollLayerForTesting(),
7173 layer.get());
7174 root->AddChild(layer);
7175
7176 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
7177 client_.set_bounds(root->bounds());
7178 }
7179
7180 // Returns the delta scale of all quads in the frame's root pass from their
7181 // ideal, or 0 if they are not all the same.
FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData * frame_data)7182 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
7183 if (frame_data->has_no_damage)
7184 return 0.f;
7185 float frame_scale = 0.f;
7186 viz::CompositorRenderPass* root_pass =
7187 frame_data->render_passes.back().get();
7188 for (auto* draw_quad : root_pass->quad_list) {
7189 const viz::TileDrawQuad* quad =
7190 viz::TileDrawQuad::MaterialCast(draw_quad);
7191 float quad_scale =
7192 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
7193 float transform_scale = SkScalarToFloat(
7194 quad->shared_quad_state->quad_to_target_transform.matrix().get(0, 0));
7195 float scale = quad_scale / transform_scale;
7196 if (frame_scale != 0.f && frame_scale != scale)
7197 return 0.f;
7198 frame_scale = scale;
7199 }
7200 return frame_scale;
7201 }
7202
BeginTest()7203 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7204
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7205 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7206 LayerTreeHostImpl::FrameData* frame_data,
7207 DrawResult draw_result) override {
7208 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
7209 switch (step_) {
7210 case 1:
7211 // Drew at scale 1 before any pinching.
7212 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
7213 EXPECT_EQ(1.f, quad_scale_delta);
7214 break;
7215 case 2:
7216 if (quad_scale_delta != 1.f / 1.5f)
7217 break;
7218 // Drew at scale 1 still though the ideal is 1.5.
7219 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
7220 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
7221 break;
7222 case 3:
7223 // Continuous draws are attempted.
7224 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
7225 if (!frame_data->has_no_damage)
7226 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
7227 break;
7228 case 4:
7229 if (quad_scale_delta != 1.f)
7230 break;
7231 // Drew at scale 1.5 when all the tiles completed.
7232 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
7233 EXPECT_EQ(1.f, quad_scale_delta);
7234 break;
7235 case 5:
7236 // TODO(danakj): We get more draws before the NotifyReadyToDraw
7237 // because it is asynchronous from the previous draw and happens late.
7238 break;
7239 case 6:
7240 // NotifyReadyToDraw happened. If we were already inside a frame, we may
7241 // try to draw once more.
7242 break;
7243 case 7:
7244 NOTREACHED() << "No draws should happen once we have a complete frame.";
7245 break;
7246 }
7247 return draw_result;
7248 }
7249
DrawLayersOnThread(LayerTreeHostImpl * host_impl)7250 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
7251 switch (step_) {
7252 case 1:
7253 // Delay tile production.
7254 playback_allowed_event_.Reset();
7255 // Pinch zoom in to cause new tiles to be required.
7256 host_impl->GetInputHandler().PinchGestureBegin();
7257 host_impl->GetInputHandler().PinchGestureUpdate(1.5f,
7258 gfx::Point(100, 100));
7259 host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(100, 100),
7260 true);
7261 ++step_;
7262 break;
7263 case 2:
7264 ++step_;
7265 break;
7266 case 3:
7267 // We should continue to try draw while there are incomplete visible
7268 // tiles.
7269 if (++continuous_draws_ > 5) {
7270 // Allow the tiles to complete.
7271 playback_allowed_event_.Signal();
7272 ++step_;
7273 }
7274 break;
7275 case 4:
7276 ++step_;
7277 break;
7278 case 5:
7279 // Waiting for NotifyReadyToDraw.
7280 break;
7281 case 6:
7282 // NotifyReadyToDraw happened.
7283 ++step_;
7284 break;
7285 }
7286 }
7287
NotifyReadyToDrawOnThread(LayerTreeHostImpl * host_impl)7288 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override {
7289 if (step_ == 5) {
7290 ++step_;
7291 // NotifyReadyToDraw has happened, we may draw once more, but should not
7292 // get any more draws after that. End the test after a timeout to watch
7293 // for any extraneous draws.
7294 // TODO(brianderson): We could remove this delay and instead wait until
7295 // the viz::BeginFrameSource decides it doesn't need to send frames
7296 // anymore, or test that it already doesn't here.
7297 EndTestAfterDelayMs(16 * 4);
7298 }
7299 }
7300
NotifyTileStateChangedOnThread(LayerTreeHostImpl * host_impl,const Tile * tile)7301 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
7302 const Tile* tile) override {
7303 // On step_ == 2, we are preventing texture uploads from completing,
7304 // so this verifies they are not completing before step_ == 3.
7305 // Flaky failures here indicate we're failing to prevent uploads from
7306 // completing.
7307 EXPECT_NE(2, step_);
7308 }
7309
AfterTest()7310 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
7311
7312 FakeContentLayerClient client_;
7313 int step_;
7314 int continuous_draws_;
7315 base::WaitableEvent playback_allowed_event_;
7316 };
7317
7318 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
7319
7320 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
7321 public:
LayerTreeHostTestOneActivatePerPrepareTiles()7322 LayerTreeHostTestOneActivatePerPrepareTiles()
7323 : notify_ready_to_activate_count_(0u),
7324 scheduled_prepare_tiles_count_(0) {}
7325
SetupTree()7326 void SetupTree() override {
7327 client_.set_fill_with_nonsolid_color(true);
7328 scoped_refptr<FakePictureLayer> root_layer =
7329 FakePictureLayer::Create(&client_);
7330 root_layer->SetBounds(gfx::Size(1500, 1500));
7331 root_layer->SetIsDrawable(true);
7332
7333 layer_tree_host()->SetRootLayer(root_layer);
7334 LayerTreeHostTest::SetupTree();
7335 client_.set_bounds(root_layer->bounds());
7336 }
7337
BeginTest()7338 void BeginTest() override {
7339 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(16, 16), 1.f,
7340 viz::LocalSurfaceId());
7341 PostSetNeedsCommitToMainThread();
7342 }
7343
InitializedRendererOnThread(LayerTreeHostImpl * host_impl,bool success)7344 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
7345 bool success) override {
7346 ASSERT_TRUE(success);
7347 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1);
7348 }
7349
NotifyReadyToActivateOnThread(LayerTreeHostImpl * impl)7350 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
7351 ++notify_ready_to_activate_count_;
7352 EndTestAfterDelayMs(100);
7353 }
7354
WillPrepareTilesOnThread(LayerTreeHostImpl * impl)7355 void WillPrepareTilesOnThread(LayerTreeHostImpl* impl) override {
7356 ++scheduled_prepare_tiles_count_;
7357 }
7358
AfterTest()7359 void AfterTest() override {
7360 // Expect at most a notification for each scheduled prepare tiles, plus one
7361 // for the initial commit (which doesn't go through scheduled actions).
7362 // The reason this is not an equality is because depending on timing, we
7363 // might get a prepare tiles but not yet get a notification that we're
7364 // ready to activate. The intent of a test is to ensure that we don't
7365 // get more than one notification per prepare tiles, so this is OK.
7366 EXPECT_LE(notify_ready_to_activate_count_,
7367 1u + scheduled_prepare_tiles_count_);
7368 }
7369
7370 protected:
7371 FakeContentLayerClient client_;
7372 size_t notify_ready_to_activate_count_;
7373 size_t scheduled_prepare_tiles_count_;
7374 };
7375
7376 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
7377
7378 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
7379 public:
LayerTreeHostTestActivationCausesPrepareTiles()7380 LayerTreeHostTestActivationCausesPrepareTiles()
7381 : scheduled_prepare_tiles_count_(0) {}
7382
SetupTree()7383 void SetupTree() override {
7384 client_.set_fill_with_nonsolid_color(true);
7385 scoped_refptr<FakePictureLayer> root_layer =
7386 FakePictureLayer::Create(&client_);
7387 root_layer->SetBounds(gfx::Size(150, 150));
7388 root_layer->SetIsDrawable(true);
7389
7390 layer_tree_host()->SetRootLayer(root_layer);
7391 LayerTreeHostTest::SetupTree();
7392 client_.set_bounds(root_layer->bounds());
7393 }
7394
BeginTest()7395 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7396
NotifyReadyToActivateOnThread(LayerTreeHostImpl * impl)7397 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override {
7398 // Ensure we've already activated.
7399 EXPECT_FALSE(impl->pending_tree());
7400
7401 // After activating, we either need to prepare tiles, or we've already
7402 // called a scheduled prepare tiles. This is done because activation might
7403 // cause us to have to memory available (old active tree is gone), so we
7404 // need to ensure we will get a PrepareTiles call.
7405 if (!impl->prepare_tiles_needed())
7406 EXPECT_GE(scheduled_prepare_tiles_count_, 1);
7407 EndTest();
7408 }
7409
WillPrepareTilesOnThread(LayerTreeHostImpl * impl)7410 void WillPrepareTilesOnThread(LayerTreeHostImpl* impl) override {
7411 ++scheduled_prepare_tiles_count_;
7412 }
7413
7414 protected:
7415 FakeContentLayerClient client_;
7416 int scheduled_prepare_tiles_count_;
7417 };
7418
7419 // This test is testing activation from a pending tree and doesn't make sense
7420 // with single thread commit-to-active.
7421 MULTI_THREAD_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
7422
7423 // This tests an assertion that DidCommit and WillCommit happen in the same
7424 // stack frame with no tasks that run between them. Various embedders of
7425 // cc depend on this logic. ui::Compositor holds a compositor lock between
7426 // these events and the inspector timeline wants begin/end CompositeLayers
7427 // to be properly nested with other begin/end events.
7428 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
7429 : public LayerTreeHostTest {
7430 public:
LayerTreeHostTestNoTasksBetweenWillAndDidCommit()7431 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {}
7432
BeginTest()7433 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7434
WillCommit()7435 void WillCommit() override {
7436 MainThreadTaskRunner()->PostTask(
7437 FROM_HERE,
7438 base::BindOnce(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit::
7439 EndTestShouldRunAfterDidCommit,
7440 base::Unretained(this)));
7441 }
7442
EndTestShouldRunAfterDidCommit()7443 void EndTestShouldRunAfterDidCommit() {
7444 EXPECT_TRUE(did_commit_);
7445 EndTest();
7446 }
7447
DidCommit()7448 void DidCommit() override {
7449 EXPECT_FALSE(did_commit_);
7450 did_commit_ = true;
7451 }
7452
AfterTest()7453 void AfterTest() override { EXPECT_TRUE(did_commit_); }
7454
7455 private:
7456 bool did_commit_;
7457 };
7458
7459 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
7460
7461 class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
7462 protected:
SetupTree()7463 void SetupTree() override {
7464 root = Layer::Create();
7465 child = Layer::Create();
7466 root->AddChild(child);
7467 layer_tree_host()->SetRootLayer(root);
7468 LayerTreeHostTest::SetupTree();
7469 }
7470
BeginTest()7471 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7472
WillCommit()7473 void WillCommit() override {
7474 switch (layer_tree_host()->SourceFrameNumber()) {
7475 case 1:
7476 EXPECT_TRUE(LayerSubtreeHasCopyRequest(root.get()));
7477 break;
7478 }
7479 }
7480
DidCommit()7481 void DidCommit() override {
7482 gfx::Transform transform;
7483 switch (layer_tree_host()->SourceFrameNumber()) {
7484 case 1:
7485 child->RequestCopyOfOutput(
7486 viz::CopyOutputRequest::CreateStubForTesting());
7487 transform.Scale(2.0, 2.0);
7488 child->SetTransform(transform);
7489 break;
7490 case 2:
7491 // By changing the scale of a layer which already owns a transform node,
7492 // a commit will be triggered but a property tree rebuild will not, this
7493 // is used to test sure that clearing copy requestts does trigger a
7494 // rebuild whenever next commit happens.
7495 transform.Scale(1.5, 1.5);
7496 child->SetTransform(transform);
7497 break;
7498 case 3:
7499 EXPECT_FALSE(LayerSubtreeHasCopyRequest(root.get()));
7500 EndTest();
7501 break;
7502 }
7503 }
7504
7505 private:
7506 scoped_refptr<Layer> root;
7507 scoped_refptr<Layer> child;
7508 };
7509
7510 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
7511
7512 class LayerTreeTestPageScaleFlags : public LayerTreeTest {
7513 public:
LayerTreeTestPageScaleFlags()7514 LayerTreeTestPageScaleFlags() { SetUseLayerLists(); }
7515
7516 protected:
SetupTree()7517 void SetupTree() override {
7518 // -root
7519 // -pre page scale
7520 // -viewport layers
7521 // -post page scale
7522
7523 LayerTreeTest::SetupTree();
7524 Layer* root = layer_tree_host()->root_layer();
7525
7526 scoped_refptr<Layer> pre_page_scale = Layer::Create();
7527 CopyProperties(root, pre_page_scale.get());
7528 root->AddChild(pre_page_scale);
7529
7530 SetupViewport(root, root->bounds(), root->bounds());
7531
7532 scoped_refptr<Layer> post_page_scale = Layer::Create();
7533 CopyProperties(root, post_page_scale.get());
7534 root->AddChild(post_page_scale);
7535
7536 affected_by_page_scale_.push_back(
7537 layer_tree_host()->InnerViewportScrollLayerForTesting()->id());
7538 affected_by_page_scale_.push_back(
7539 layer_tree_host()->OuterViewportScrollLayerForTesting()->id());
7540
7541 not_affected_by_page_scale_.push_back(root->id());
7542 not_affected_by_page_scale_.push_back(pre_page_scale->id());
7543 not_affected_by_page_scale_.push_back(post_page_scale->id());
7544 }
7545
BeginTest()7546 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7547
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)7548 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
7549 for (auto* layer : *host_impl->sync_tree()) {
7550 const std::vector<int>& list = layer->IsAffectedByPageScale()
7551 ? this->affected_by_page_scale_
7552 : this->not_affected_by_page_scale_;
7553 EXPECT_TRUE(base::Contains(list, layer->id()));
7554 }
7555
7556 EndTest();
7557 }
7558
7559 std::vector<int> affected_by_page_scale_;
7560 std::vector<int> not_affected_by_page_scale_;
7561 };
7562
7563 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestPageScaleFlags);
7564
7565 class LayerTreeHostTestDestroyWhileInitializingOutputSurface
7566 : public LayerTreeHostTest {
7567 protected:
BeginTest()7568 void BeginTest() override {
7569 // By ending the test immediately we start initialization of an output
7570 // surface but destroy the LTH before it completes. This test verifies
7571 // that this works correctly and the output surface is destroyed on
7572 // the correct thread.
7573 EndTest();
7574 }
7575 };
7576
7577 MULTI_THREAD_TEST_F(LayerTreeHostTestDestroyWhileInitializingOutputSurface);
7578
7579 // Makes sure that painted_device_scale_factor is propagated to the
7580 // frame's metadata.
7581 class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest {
7582 protected:
InitializeSettings(LayerTreeSettings * settings)7583 void InitializeSettings(LayerTreeSettings* settings) override {
7584 settings->use_painted_device_scale_factor = true;
7585 LayerTreeHostTest::InitializeSettings(settings);
7586 }
7587
SetupTree()7588 void SetupTree() override {
7589 SetInitialDeviceScaleFactor(2.f);
7590 LayerTreeHostTest::SetupTree();
7591 }
7592
BeginTest()7593 void BeginTest() override {
7594 EXPECT_EQ(1.0f, layer_tree_host()->device_scale_factor());
7595 PostSetNeedsCommitToMainThread();
7596 }
7597
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7598 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7599 LayerTreeHostImpl::FrameData* frame_data,
7600 DrawResult draw_result) override {
7601 EXPECT_EQ(DRAW_SUCCESS, draw_result);
7602 EXPECT_EQ(2.0f, host_impl->active_tree()->painted_device_scale_factor());
7603 EXPECT_EQ(1.0f, host_impl->active_tree()->device_scale_factor());
7604 return draw_result;
7605 }
7606
DisplayReceivedCompositorFrameOnThread(const viz::CompositorFrame & frame)7607 void DisplayReceivedCompositorFrameOnThread(
7608 const viz::CompositorFrame& frame) override {
7609 EXPECT_EQ(2.0f, frame.metadata.device_scale_factor);
7610 EndTest();
7611 }
7612 };
7613 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor);
7614
7615 // Tests that a presentation-timestamps are received for a frame.
7616 class LayerTreeHostTestPresentationTime : public LayerTreeHostTest {
7617 protected:
BeginTest()7618 void BeginTest() override {
7619 PostSetNeedsCommitToMainThread();
7620 }
7621
DisplayReceivedCompositorFrameOnThread(const viz::CompositorFrame & frame)7622 void DisplayReceivedCompositorFrameOnThread(
7623 const viz::CompositorFrame& frame) override {
7624 frame_token_ = frame.metadata.frame_token;
7625 }
7626
DidReceivePresentationTimeOnThread(LayerTreeHostImpl * host_impl,uint32_t frame_token,const gfx::PresentationFeedback & feedback)7627 void DidReceivePresentationTimeOnThread(
7628 LayerTreeHostImpl* host_impl,
7629 uint32_t frame_token,
7630 const gfx::PresentationFeedback& feedback) override {
7631 EXPECT_EQ(frame_token_, frame_token);
7632 EndTest();
7633 }
7634
AfterTest()7635 void AfterTest() override { ASSERT_GT(frame_token_, 0u); }
7636
7637 private:
7638 uint32_t frame_token_ = 0;
7639 };
7640 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPresentationTime);
7641
7642 // Makes sure that viz::LocalSurfaceId is propagated to the LayerTreeFrameSink.
7643 class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
7644 protected:
BeginTest()7645 void BeginTest() override {}
7646
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7647 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7648 LayerTreeHostImpl::FrameData* frame_data,
7649 DrawResult draw_result) override {
7650 EXPECT_EQ(DRAW_SUCCESS, draw_result);
7651 EXPECT_EQ(GetCurrentLocalSurfaceId(),
7652 host_impl->active_tree()->local_surface_id_from_parent());
7653 return draw_result;
7654 }
7655
DisplayReceivedLocalSurfaceIdOnThread(const viz::LocalSurfaceId & local_surface_id)7656 void DisplayReceivedLocalSurfaceIdOnThread(
7657 const viz::LocalSurfaceId& local_surface_id) override {
7658 EXPECT_EQ(GetCurrentLocalSurfaceId(), local_surface_id);
7659 EndTest();
7660 }
7661 };
7662 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId);
7663
7664 // Makes sure that LayerTreeHost does not pick up changes to
7665 // viz::LocalSurfaceIds that only involve the child sequence number.
7666 class LayerTreeHostTestLocalSurfaceIdSkipChildNum : public LayerTreeHostTest {
7667 protected:
BeginTest()7668 void BeginTest() override {
7669 EXPECT_TRUE(child_allocator_.UpdateFromParent(GetCurrentLocalSurfaceId()));
7670 }
7671
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7672 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7673 LayerTreeHostImpl::FrameData* frame_data,
7674 DrawResult draw_result) override {
7675 EXPECT_EQ(DRAW_SUCCESS, draw_result);
7676 // We should not be picking up the newer |child_local_surface_id_|.
7677 EXPECT_EQ(GetCurrentLocalSurfaceId(),
7678 host_impl->active_tree()->local_surface_id_from_parent());
7679
7680 // This initial test setup triggers a commit and subsequent draw. Upon the
7681 // first draw, enqueue the second portion of the test. The newly pushed id,
7682 // with an advanced child sequence number, but no change in parent sequence,
7683 // should not trigger a commit. If it does, then PrepareToDrawOnThread will
7684 // be called a second time, and the expectation upon viz::LocalSurfaceId
7685 // will fail. We do not assert on frame number, as that interferes with
7686 // returning from this method. We do not just have an expectation either,
7687 // as then we would continuously increment that child sequence until the
7688 // test times out.
7689 if (!host_impl->active_tree()->source_frame_number()) {
7690 child_allocator_.GenerateId();
7691 child_local_surface_id_ = child_allocator_.GetCurrentLocalSurfaceId();
7692 EXPECT_NE(GetCurrentLocalSurfaceId(), child_local_surface_id_);
7693 PostSetLocalSurfaceIdToMainThread(child_local_surface_id_);
7694 }
7695
7696 return draw_result;
7697 }
7698
DisplayReceivedLocalSurfaceIdOnThread(const viz::LocalSurfaceId & local_surface_id)7699 void DisplayReceivedLocalSurfaceIdOnThread(
7700 const viz::LocalSurfaceId& local_surface_id) override {
7701 EXPECT_EQ(GetCurrentLocalSurfaceId(), local_surface_id);
7702 EndTest();
7703 }
7704
7705 viz::LocalSurfaceId child_local_surface_id_;
7706 viz::ChildLocalSurfaceIdAllocator child_allocator_;
7707 };
7708 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceIdSkipChildNum);
7709
7710 // Makes sure that viz::LocalSurfaceId allocation requests propagate all the way
7711 // to LayerTreeFrameSink.
7712 class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest {
7713 protected:
BeginTest()7714 void BeginTest() override {
7715 PostRequestNewLocalSurfaceIdToMainThread();
7716 }
7717
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7718 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7719 LayerTreeHostImpl::FrameData* frame_data,
7720 DrawResult draw_result) override {
7721 EXPECT_EQ(DRAW_SUCCESS, draw_result);
7722 EXPECT_EQ(GetCurrentLocalSurfaceId(),
7723 host_impl->active_tree()->local_surface_id_from_parent());
7724 return draw_result;
7725 }
7726
DisplayReceivedLocalSurfaceIdOnThread(const viz::LocalSurfaceId & local_surface_id)7727 void DisplayReceivedLocalSurfaceIdOnThread(
7728 const viz::LocalSurfaceId& local_surface_id) override {
7729 const viz::LocalSurfaceId& expected_parent_local_surface_id =
7730 GetCurrentLocalSurfaceId();
7731 viz::LocalSurfaceId child_local_surface_id(
7732 expected_parent_local_surface_id.parent_sequence_number(),
7733 expected_parent_local_surface_id.child_sequence_number() + 1,
7734 expected_parent_local_surface_id.embed_token());
7735 EXPECT_NE(expected_parent_local_surface_id, local_surface_id);
7736 EXPECT_EQ(child_local_surface_id, local_surface_id);
7737 }
7738
7739 // This gets called after DispllayReceivedLocalSurfaceIdOnThread.
DrawLayersOnThread(LayerTreeHostImpl * host_impl)7740 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
7741 // Verify that the request bit doesn't stick after we submit a frame.
7742 EXPECT_FALSE(
7743 host_impl->active_tree()->new_local_surface_id_request_for_testing());
7744 EndTest();
7745 }
7746 };
7747 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestNewLocalSurfaceId);
7748
7749 // The GPU image decode controller hands images off to Skia for rasterization.
7750 // When used with large images, the images in question could be deleted before
7751 // Skia was done with them, causing a crash. This test performs an end-to-end
7752 // check of large image rasterization to ensure we do not hit this crash.
7753 // Note that this code path won't always hit the crash, even when incorrect
7754 // behavior occurs, so this is more of a sanity check.
7755 // TODO(ericrk): We should improve this so that we can reliably detect the
7756 // crash.
7757 class GpuRasterizationSucceedsWithLargeImage : public LayerTreeHostTest {
7758 protected:
GpuRasterizationSucceedsWithLargeImage()7759 GpuRasterizationSucceedsWithLargeImage()
7760 : viewport_size_(1024, 2048), large_image_size_(20000, 10) {}
7761
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_provider)7762 void SetUpUnboundContextProviders(
7763 viz::TestContextProvider* context_provider,
7764 viz::TestContextProvider* worker_provider) override {
7765 context_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
7766 worker_provider->UnboundTestContextGL()->set_gpu_rasterization(true);
7767 }
7768
InitializeSettings(LayerTreeSettings * settings)7769 void InitializeSettings(LayerTreeSettings* settings) override {
7770 // Set to 0 to force at-raster GPU image decode.
7771 settings->decoded_image_working_set_budget_bytes = 0;
7772 }
7773
SetupTree()7774 void SetupTree() override {
7775 client_.set_fill_with_nonsolid_color(true);
7776
7777 std::unique_ptr<FakeRecordingSource> recording =
7778 FakeRecordingSource::CreateFilledRecordingSource(
7779 gfx::Size(10000, 10000));
7780
7781 recording->add_draw_image(CreateDiscardablePaintImage(large_image_size_),
7782 gfx::Point(0, 0));
7783 recording->Rerecord();
7784
7785 scoped_refptr<FakePictureLayer> root =
7786 FakePictureLayer::CreateWithRecordingSource(&client_,
7787 std::move(recording));
7788 root->SetBounds(gfx::Size(10000, 10000));
7789 client_.set_bounds(root->bounds());
7790 root->SetContentsOpaque(true);
7791
7792 layer_tree_host()->SetRootLayer(root);
7793 LayerTreeHostTest::SetupTree();
7794 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(viewport_size_), 1.f,
7795 viz::LocalSurfaceId());
7796 client_.set_bounds(root->bounds());
7797 }
7798
InitializedRendererOnThread(LayerTreeHostImpl * host_impl,bool success)7799 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
7800 bool success) override {
7801 // Check that our large_image_size_ is greater than max texture size. We do
7802 // this here to ensure that our otuput surface exists.
7803
7804 // Retrieve max texture size from Skia.
7805 viz::ContextProvider* context_provider =
7806 host_impl->layer_tree_frame_sink()->context_provider();
7807 ASSERT_TRUE(context_provider);
7808
7809 auto* gr_context = context_provider->GrContext();
7810 ASSERT_TRUE(gr_context);
7811 const uint32_t max_texture_size = gr_context->maxTextureSize();
7812 ASSERT_GT(static_cast<uint32_t>(large_image_size_.width()),
7813 max_texture_size);
7814 }
7815
BeginTest()7816 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7817
DidCommit()7818 void DidCommit() override { EndTest(); }
7819
7820 private:
7821 FakeContentLayerClient client_;
7822 const gfx::Size viewport_size_;
7823 const gfx::Size large_image_size_;
7824 };
7825
7826 SINGLE_AND_MULTI_THREAD_TEST_F(GpuRasterizationSucceedsWithLargeImage);
7827
7828 class LayerTreeHostTestSubmitFrameMetadata : public LayerTreeHostTest {
7829 protected:
BeginTest()7830 void BeginTest() override {
7831 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
7832 PostSetNeedsCommitToMainThread();
7833 }
7834
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7835 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7836 LayerTreeHostImpl::FrameData* frame_data,
7837 DrawResult draw_result) override {
7838 EXPECT_EQ(DRAW_SUCCESS, draw_result);
7839 EXPECT_EQ(0, num_swaps_);
7840 drawn_viewport_ = host_impl->active_tree()->GetDeviceViewport();
7841 return draw_result;
7842 }
7843
DisplayReceivedCompositorFrameOnThread(const viz::CompositorFrame & frame)7844 void DisplayReceivedCompositorFrameOnThread(
7845 const viz::CompositorFrame& frame) override {
7846 EXPECT_EQ(1, ++num_swaps_);
7847
7848 EXPECT_EQ(drawn_viewport_, frame.render_pass_list.back()->output_rect);
7849 EXPECT_EQ(0.5f, frame.metadata.min_page_scale_factor);
7850 EXPECT_EQ(0u, frame.resource_list.size());
7851 EXPECT_EQ(1u, frame.render_pass_list.size());
7852
7853 EndTest();
7854 }
7855
7856 int num_swaps_ = 0;
7857 gfx::Rect drawn_viewport_;
7858 };
7859
7860 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSubmitFrameMetadata);
7861
7862 class LayerTreeHostTestSubmitFrameResources : public LayerTreeHostTest {
7863 protected:
CreateLayerTreeFrameSink(const viz::RendererSettings & renderer_settings,double refresh_rate,scoped_refptr<viz::ContextProvider> compositor_context_provider,scoped_refptr<viz::RasterContextProvider> worker_context_provider)7864 std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
7865 const viz::RendererSettings& renderer_settings,
7866 double refresh_rate,
7867 scoped_refptr<viz::ContextProvider> compositor_context_provider,
7868 scoped_refptr<viz::RasterContextProvider> worker_context_provider)
7869 override {
7870 auto gl = std::make_unique<viz::TestGLES2Interface>();
7871 gl->set_have_extension_egl_image(true);
7872 auto provider = viz::TestContextProvider::Create(std::move(gl));
7873 return LayerTreeTest::CreateLayerTreeFrameSink(
7874 renderer_settings, refresh_rate, std::move(provider),
7875 std::move(worker_context_provider));
7876 }
7877
BeginTest()7878 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7879
PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame,DrawResult draw_result)7880 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
7881 LayerTreeHostImpl::FrameData* frame,
7882 DrawResult draw_result) override {
7883 frame->render_passes.clear();
7884
7885 viz::CompositorRenderPass* child_pass = AddRenderPass(
7886 &frame->render_passes, viz::CompositorRenderPassId{2},
7887 gfx::Rect(3, 3, 10, 10), gfx::Transform(), FilterOperations());
7888 std::vector<viz::ResourceId> child_resources =
7889 AddOneOfEveryQuadType(child_pass, host_impl->resource_provider(),
7890 viz::CompositorRenderPassId{0});
7891
7892 viz::CompositorRenderPass* pass = AddRenderPass(
7893 &frame->render_passes, viz::CompositorRenderPassId{1},
7894 gfx::Rect(3, 3, 10, 10), gfx::Transform(), FilterOperations());
7895 std::vector<viz::ResourceId> root_resources = AddOneOfEveryQuadType(
7896 pass, host_impl->resource_provider(), child_pass->id);
7897
7898 auto append = [](std::vector<viz::ResourceId>* to,
7899 std::vector<viz::ResourceId> from) {
7900 to->insert(to->end(), from.begin(), from.end());
7901 };
7902 append(&resources_, child_resources);
7903 append(&resources_, root_resources);
7904
7905 return draw_result;
7906 }
7907
DrawLayersOnThread(LayerTreeHostImpl * host_impl)7908 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
7909 // The resources have been submitted to the display compositor by now, we
7910 // can remove them from cc now, so that they are not leaked.
7911 for (viz::ResourceId id : resources_)
7912 host_impl->resource_provider()->RemoveImportedResource(id);
7913 }
7914
DisplayReceivedCompositorFrameOnThread(const viz::CompositorFrame & frame)7915 void DisplayReceivedCompositorFrameOnThread(
7916 const viz::CompositorFrame& frame) override {
7917 EXPECT_EQ(2u, frame.render_pass_list.size());
7918 // Each render pass has 10 resources in it. And the root render pass has a
7919 // mask resource used when drawing the child render pass. The number 10 may
7920 // change if AppendOneOfEveryQuadType() is updated, and the value here
7921 // should be updated accordingly.
7922 EXPECT_EQ(21u, frame.resource_list.size());
7923
7924 EndTest();
7925 }
7926
7927 std::vector<viz::ResourceId> resources_;
7928 };
7929
7930 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSubmitFrameResources);
7931
7932 class LayerTreeHostTestBeginFrameAcks : public LayerTreeHostTest {
7933 protected:
BeginTest()7934 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7935
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const viz::BeginFrameArgs & args)7936 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
7937 const viz::BeginFrameArgs& args) override {
7938 EXPECT_TRUE(args.IsValid());
7939 current_begin_frame_args_ = args;
7940 }
7941
PrepareToDrawOnThread(LayerTreeHostImpl * impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)7942 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl,
7943 LayerTreeHostImpl::FrameData* frame_data,
7944 DrawResult draw_result) override {
7945 frame_data_ = frame_data;
7946 return draw_result;
7947 }
7948
DisplayReceivedCompositorFrameOnThread(const viz::CompositorFrame & frame)7949 void DisplayReceivedCompositorFrameOnThread(
7950 const viz::CompositorFrame& frame) override {
7951 if (compositor_frame_submitted_)
7952 return;
7953 compositor_frame_submitted_ = true;
7954
7955 EXPECT_EQ(viz::BeginFrameAck(current_begin_frame_args_, true),
7956 frame.metadata.begin_frame_ack);
7957 }
7958
DrawLayersOnThread(LayerTreeHostImpl * impl)7959 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
7960 if (layers_drawn_)
7961 return;
7962 layers_drawn_ = true;
7963
7964 EXPECT_TRUE(frame_data_);
7965 EXPECT_TRUE(compositor_frame_submitted_);
7966 EXPECT_EQ(viz::BeginFrameAck(current_begin_frame_args_, true),
7967 frame_data_->begin_frame_ack);
7968 EndTest();
7969 }
7970
AfterTest()7971 void AfterTest() override { EXPECT_TRUE(layers_drawn_); }
7972
7973 private:
7974 bool compositor_frame_submitted_ = false;
7975 bool layers_drawn_ = false;
7976 viz::BeginFrameArgs current_begin_frame_args_;
7977 LayerTreeHostImpl::FrameData* frame_data_;
7978 };
7979
7980 MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestBeginFrameAcks);
7981
7982 class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest {
7983 protected:
BeginTest()7984 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
7985
InitializeSettings(LayerTreeSettings * settings)7986 void InitializeSettings(LayerTreeSettings* settings) override {
7987 settings->enable_checker_imaging = true;
7988 settings->min_image_bytes_to_checker = 512 * 1024;
7989 }
7990
WillBeginMainFrame()7991 void WillBeginMainFrame() override {
7992 if (!first_)
7993 return;
7994 first_ = false;
7995
7996 image_ = DrawImage(CreateDiscardablePaintImage(gfx::Size(400, 400)), false,
7997 SkIRect::MakeWH(400, 400), kNone_SkFilterQuality,
7998 SkMatrix::I(), PaintImage::kDefaultFrameIndex,
7999 gfx::ColorSpace());
8000 auto callback = base::BindRepeating(
8001 &LayerTreeHostTestQueueImageDecode::ImageDecodeFinished,
8002 base::Unretained(this));
8003 // Schedule the decode twice for the same image.
8004 layer_tree_host()->QueueImageDecode(image_.paint_image(), callback);
8005 layer_tree_host()->QueueImageDecode(image_.paint_image(), callback);
8006 }
8007
ReadyToCommitOnThread(LayerTreeHostImpl * impl)8008 void ReadyToCommitOnThread(LayerTreeHostImpl* impl) override {
8009 if (one_commit_done_)
8010 return;
8011 EXPECT_FALSE(
8012 impl->tile_manager()->checker_image_tracker().ShouldCheckerImage(
8013 image_, WhichTree::PENDING_TREE));
8014 }
8015
CommitCompleteOnThread(LayerTreeHostImpl * impl)8016 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
8017 one_commit_done_ = true;
8018 EXPECT_FALSE(
8019 impl->tile_manager()->checker_image_tracker().ShouldCheckerImage(
8020 image_, WhichTree::PENDING_TREE));
8021 }
8022
ImageDecodeFinished(bool decode_succeeded)8023 void ImageDecodeFinished(bool decode_succeeded) {
8024 EXPECT_TRUE(decode_succeeded);
8025 ++finished_decode_count_;
8026 EXPECT_LE(finished_decode_count_, 2);
8027 if (finished_decode_count_ == 2)
8028 EndTest();
8029 }
8030
8031 private:
8032 bool first_ = true;
8033 bool one_commit_done_ = false;
8034 int finished_decode_count_ = 0;
8035 DrawImage image_;
8036 };
8037
8038 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestQueueImageDecode);
8039
8040 class LayerTreeHostTestQueueImageDecodeNonLazy : public LayerTreeHostTest {
8041 protected:
BeginTest()8042 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8043
WillBeginMainFrame()8044 void WillBeginMainFrame() override {
8045 if (!first_)
8046 return;
8047 first_ = false;
8048
8049 bitmap_.allocN32Pixels(10, 10);
8050 PaintImage image = PaintImageBuilder::WithDefault()
8051 .set_id(PaintImage::GetNextId())
8052 .set_image(SkImage::MakeFromBitmap(bitmap_),
8053 PaintImage::GetNextContentId())
8054 .TakePaintImage();
8055 auto callback = base::BindOnce(
8056 &LayerTreeHostTestQueueImageDecodeNonLazy::ImageDecodeFinished,
8057 base::Unretained(this));
8058 layer_tree_host()->QueueImageDecode(image, std::move(callback));
8059 }
8060
ImageDecodeFinished(bool decode_succeeded)8061 void ImageDecodeFinished(bool decode_succeeded) {
8062 EXPECT_TRUE(decode_succeeded);
8063 EndTest();
8064 }
8065
8066 private:
8067 bool first_ = true;
8068 SkBitmap bitmap_;
8069 };
8070
8071 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestQueueImageDecodeNonLazy);
8072
8073 class LayerTreeHostTestHudLayerWithLayerLists : public LayerTreeHostTest {
8074 public:
LayerTreeHostTestHudLayerWithLayerLists()8075 LayerTreeHostTestHudLayerWithLayerLists() { SetUseLayerLists(); }
8076
InitializeSettings(LayerTreeSettings * settings)8077 void InitializeSettings(LayerTreeSettings* settings) override {
8078 settings->initial_debug_state.show_paint_rects = true;
8079 }
8080
BeginTest()8081 void BeginTest() override {
8082 // The HUD layer should not have been setup.
8083 DCHECK_EQ(layer_tree_host()->hud_layer(), nullptr);
8084 PostSetNeedsCommitToMainThread();
8085 }
8086
DrawLayersOnThread(LayerTreeHostImpl * host_impl)8087 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { EndTest(); }
8088
DidCommit()8089 void DidCommit() override {
8090 auto* hud = layer_tree_host()->hud_layer();
8091 DCHECK(hud);
8092 auto* root_layer = layer_tree_host()->root_layer();
8093 DCHECK_EQ(hud->transform_tree_index(), root_layer->transform_tree_index());
8094 DCHECK_EQ(hud->clip_tree_index(), root_layer->clip_tree_index());
8095 DCHECK_EQ(hud->effect_tree_index(), root_layer->effect_tree_index());
8096 DCHECK_EQ(hud->scroll_tree_index(), root_layer->scroll_tree_index());
8097 }
8098 };
8099
8100 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHudLayerWithLayerLists);
8101
8102 // Verifies that LayerTreeHostClient does not receive frame acks from a released
8103 // LayerTreeFrameSink.
8104 class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest {
8105 protected:
SetupTree()8106 void SetupTree() override {
8107 scoped_refptr<Layer> root = Layer::Create();
8108 root->SetBounds(gfx::Size(10, 10));
8109 layer_tree_host()->SetRootLayer(std::move(root));
8110 LayerTreeHostTest::SetupTree();
8111 }
8112
BeginTest()8113 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8114
WillReceiveCompositorFrameAckOnThread(LayerTreeHostImpl * host_impl)8115 void WillReceiveCompositorFrameAckOnThread(
8116 LayerTreeHostImpl* host_impl) override {
8117 // This method is called before ack is posted to main thread. This ensures
8118 // that WillReceiveCompositorFrameAck which we PostTask below will be called
8119 // before DidReceiveCompositorFrameAck.
8120 MainThreadTaskRunner()->PostTask(
8121 FROM_HERE, base::BindOnce(&LayerTreeHostTestDiscardAckAfterRelease::
8122 WillReceiveCompositorFrameAck,
8123 base::Unretained(this)));
8124 }
8125
WillReceiveCompositorFrameAck()8126 void WillReceiveCompositorFrameAck() {
8127 switch (layer_tree_host()->SourceFrameNumber()) {
8128 case 1:
8129 // For the first commit, don't release the LayerTreeFrameSink. We must
8130 // receive the ack later on.
8131 break;
8132 case 2:
8133 // Release the LayerTreeFrameSink for the second commit. We'll later
8134 // check that the ack is discarded.
8135 layer_tree_host()->SetVisible(false);
8136 layer_tree_host()->ReleaseLayerTreeFrameSink();
8137 break;
8138 default:
8139 NOTREACHED();
8140 }
8141 }
8142
DidReceiveCompositorFrameAckOnThread(LayerTreeHostImpl * host_impl)8143 void DidReceiveCompositorFrameAckOnThread(
8144 LayerTreeHostImpl* host_impl) override {
8145 // Since this method is called after ack is posted to main thread, we can be
8146 // sure that if the ack is not discarded, it will be definitely received
8147 // before we are in CheckFrameAck.
8148 MainThreadTaskRunner()->PostTask(
8149 FROM_HERE,
8150 base::BindOnce(&LayerTreeHostTestDiscardAckAfterRelease::CheckFrameAck,
8151 base::Unretained(this)));
8152 }
8153
DidReceiveCompositorFrameAck()8154 void DidReceiveCompositorFrameAck() override { received_ack_ = true; }
8155
CheckFrameAck()8156 void CheckFrameAck() {
8157 switch (layer_tree_host()->SourceFrameNumber()) {
8158 case 1:
8159 // LayerTreeFrameSink was not released. We must receive the ack.
8160 EXPECT_TRUE(received_ack_);
8161 // Cause damage so that we draw and swap.
8162 layer_tree_host()->root_layer()->SetBackgroundColor(SK_ColorGREEN);
8163 break;
8164 case 2:
8165 // LayerTreeFrameSink was released. The ack must be discarded.
8166 EXPECT_FALSE(received_ack_);
8167 EndTest();
8168 break;
8169 default:
8170 NOTREACHED();
8171 }
8172 received_ack_ = false;
8173 }
8174
8175 private:
8176 bool received_ack_ = false;
8177 };
8178
8179 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDiscardAckAfterRelease);
8180
8181 class LayerTreeHostTestImageAnimation : public LayerTreeHostTest {
8182 public:
LayerTreeHostTestImageAnimation(viz::RendererType type=viz::RendererType::kGL)8183 explicit LayerTreeHostTestImageAnimation(
8184 viz::RendererType type = viz::RendererType::kGL)
8185 : LayerTreeHostTest(type) {}
8186
BeginTest()8187 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8188
8189 virtual void AddImageOp(const PaintImage& image) = 0;
8190
SetupTree()8191 void SetupTree() override {
8192 gfx::Size layer_size(1000, 500);
8193 content_layer_client_.set_bounds(layer_size);
8194 content_layer_client_.set_fill_with_nonsolid_color(true);
8195 std::vector<FrameMetadata> frames = {
8196 FrameMetadata(true, base::TimeDelta::FromSeconds(1)),
8197 FrameMetadata(true, base::TimeDelta::FromSeconds(1)),
8198 FrameMetadata(true, base::TimeDelta::FromSeconds(1))};
8199 generator_ = sk_make_sp<FakePaintImageGenerator>(
8200 SkImageInfo::MakeN32Premul(500, 500, SkColorSpace::MakeSRGB()), frames);
8201 PaintImage image =
8202 PaintImageBuilder::WithDefault()
8203 .set_id(PaintImage::GetNextId())
8204 .set_paint_image_generator(generator_)
8205 .set_animation_type(PaintImage::AnimationType::ANIMATED)
8206 .set_repetition_count(kAnimationLoopOnce)
8207 .TakePaintImage();
8208 AddImageOp(image);
8209
8210 layer_tree_host()->SetRootLayer(
8211 FakePictureLayer::Create(&content_layer_client_));
8212 layer_tree_host()->root_layer()->SetBounds(layer_size);
8213 LayerTreeTest::SetupTree();
8214 }
8215
WillPrepareToDrawOnThread(LayerTreeHostImpl * host_impl)8216 void WillPrepareToDrawOnThread(LayerTreeHostImpl* host_impl) override {
8217 gfx::Rect image_rect(-1, -1, 502, 502);
8218 auto* layer =
8219 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer());
8220 switch (++draw_count_) {
8221 case 1:
8222 // First draw, everything is invalid. layer->update_rect() doesn't
8223 // matter because a new layer always causes surface damage.
8224 EXPECT_EQ(layer->InvalidationForTesting().bounds(),
8225 gfx::Rect(layer->bounds()));
8226 EXPECT_EQ(generator_->frames_decoded().size(), 1u);
8227 EXPECT_EQ(generator_->frames_decoded().count(0u), 1u);
8228 break;
8229 case 2:
8230 // Every frame after the first one should invalidate only the image.
8231 EXPECT_EQ(layer->InvalidationForTesting().bounds(), image_rect);
8232 EXPECT_EQ(layer->update_rect(), image_rect);
8233 EXPECT_EQ(generator_->frames_decoded().size(), 2u);
8234 EXPECT_EQ(generator_->frames_decoded().count(1u), 1u);
8235 break;
8236 case 3:
8237 EXPECT_EQ(layer->InvalidationForTesting().bounds(), image_rect);
8238 EXPECT_EQ(layer->update_rect(), image_rect);
8239 EXPECT_EQ(generator_->frames_decoded().size(), 3u);
8240 EXPECT_EQ(generator_->frames_decoded().count(2u), 1u);
8241 break;
8242 default:
8243 // Only 3 draws should happen for 3 frames of the animate image.
8244 NOTREACHED();
8245 }
8246
8247 if (draw_count_ == 3)
8248 EndTest();
8249 }
8250
AfterTest()8251 void AfterTest() override {
8252 EXPECT_EQ(generator_->frames_decoded().size(), 3u);
8253 }
8254
8255 protected:
8256 FakeContentLayerClient content_layer_client_;
8257 sk_sp<FakePaintImageGenerator> generator_;
8258 int draw_count_ = 0;
8259 };
8260
8261 class LayerTreeHostTestImageAnimationDrawImage
8262 : public LayerTreeHostTestImageAnimation {
8263 public:
LayerTreeHostTestImageAnimationDrawImage(viz::RendererType type=viz::RendererType::kGL)8264 explicit LayerTreeHostTestImageAnimationDrawImage(
8265 viz::RendererType type = viz::RendererType::kGL)
8266 : LayerTreeHostTestImageAnimation(type) {}
8267
8268 private:
AddImageOp(const PaintImage & image)8269 void AddImageOp(const PaintImage& image) override {
8270 content_layer_client_.add_draw_image(image, gfx::Point(0, 0), PaintFlags());
8271 }
8272 };
8273
8274 MULTI_THREAD_TEST_F(LayerTreeHostTestImageAnimationDrawImage);
8275
8276 class LayerTreeHostTestImageAnimationDrawImageShader
8277 : public LayerTreeHostTestImageAnimation {
AddImageOp(const PaintImage & image)8278 void AddImageOp(const PaintImage& image) override {
8279 PaintFlags flags;
8280 flags.setShader(PaintShader::MakeImage(image, SkTileMode::kRepeat,
8281 SkTileMode::kRepeat, nullptr));
8282 content_layer_client_.add_draw_rect(gfx::Rect(500, 500), flags);
8283 }
8284 };
8285
8286 MULTI_THREAD_TEST_F(LayerTreeHostTestImageAnimationDrawImageShader);
8287
8288 class LayerTreeHostTestImageAnimationDrawRecordShader
8289 : public LayerTreeHostTestImageAnimation {
AddImageOp(const PaintImage & image)8290 void AddImageOp(const PaintImage& image) override {
8291 auto record = sk_make_sp<PaintOpBuffer>();
8292 record->push<DrawImageOp>(image, 0.f, 0.f, nullptr);
8293 PaintFlags flags;
8294 flags.setShader(PaintShader::MakePaintRecord(
8295 record, SkRect::MakeWH(500, 500), SkTileMode::kClamp,
8296 SkTileMode::kClamp, nullptr));
8297 content_layer_client_.add_draw_rect(gfx::Rect(500, 500), flags);
8298 }
8299 };
8300
8301 MULTI_THREAD_TEST_F(LayerTreeHostTestImageAnimationDrawRecordShader);
8302
8303 class LayerTreeHostTestImageAnimationPaintFilter
8304 : public LayerTreeHostTestImageAnimation {
AddImageOp(const PaintImage & image)8305 void AddImageOp(const PaintImage& image) override {
8306 auto record = sk_make_sp<PaintOpBuffer>();
8307 record->push<DrawImageOp>(image, 0.f, 0.f, nullptr);
8308 PaintFlags flags;
8309 flags.setImageFilter(
8310 sk_make_sp<RecordPaintFilter>(record, SkRect::MakeWH(500, 500)));
8311 content_layer_client_.add_draw_rect(gfx::Rect(500, 500), flags);
8312 }
8313 };
8314
8315 MULTI_THREAD_TEST_F(LayerTreeHostTestImageAnimationPaintFilter);
8316
8317 class LayerTreeHostTestImageAnimationSynchronousScheduling
8318 : public LayerTreeHostTestImageAnimationDrawImage {
8319 public:
LayerTreeHostTestImageAnimationSynchronousScheduling(viz::RendererType type=viz::RendererType::kGL)8320 explicit LayerTreeHostTestImageAnimationSynchronousScheduling(
8321 viz::RendererType type = viz::RendererType::kGL)
8322 : LayerTreeHostTestImageAnimationDrawImage(type) {}
8323
InitializeSettings(LayerTreeSettings * settings)8324 void InitializeSettings(LayerTreeSettings* settings) override {
8325 LayerTreeHostTestImageAnimation::InitializeSettings(settings);
8326 settings->using_synchronous_renderer_compositor = true;
8327 }
8328 };
8329
8330 MULTI_THREAD_TEST_F(LayerTreeHostTestImageAnimationSynchronousScheduling);
8331
8332 class LayerTreeHostTestImageAnimationSynchronousSchedulingSoftwareDraw
8333 : public LayerTreeHostTestImageAnimationSynchronousScheduling {
8334 public:
LayerTreeHostTestImageAnimationSynchronousSchedulingSoftwareDraw()8335 LayerTreeHostTestImageAnimationSynchronousSchedulingSoftwareDraw()
8336 : LayerTreeHostTestImageAnimationSynchronousScheduling(
8337 viz::RendererType::kSoftware) {}
8338
AfterTest()8339 void AfterTest() override {
8340 LayerTreeHostTestImageAnimationSynchronousScheduling::AfterTest();
8341 // 3 frames decoded twice, once during tile raster and once during raster
8342 // for PictureDrawQuad.
8343 for (size_t i = 0u; i < 3u; ++i) {
8344 EXPECT_EQ(generator_->frames_decoded().find(i)->second, 2);
8345 }
8346 }
8347 };
8348
8349 MULTI_THREAD_TEST_F(
8350 LayerTreeHostTestImageAnimationSynchronousSchedulingSoftwareDraw);
8351
8352 class LayerTreeHostTestImageDecodingHints : public LayerTreeHostTest {
8353 public:
InitializeSettings(LayerTreeSettings * settings)8354 void InitializeSettings(LayerTreeSettings* settings) override {
8355 LayerTreeHostTest::InitializeSettings(settings);
8356 settings->enable_checker_imaging = true;
8357 }
8358
BeginTest()8359 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8360
SetupTree()8361 void SetupTree() override {
8362 gfx::Size layer_size(100, 100);
8363 content_layer_client_.set_bounds(layer_size);
8364 content_layer_client_.set_fill_with_nonsolid_color(true);
8365 PaintImage async_image =
8366 PaintImageBuilder::WithCopy(
8367 CreateDiscardablePaintImage(gfx::Size(10, 10)))
8368 .set_id(1)
8369 .set_decoding_mode(PaintImage::DecodingMode::kAsync)
8370 .TakePaintImage();
8371 PaintImage sync_image =
8372 PaintImageBuilder::WithCopy(
8373 CreateDiscardablePaintImage(gfx::Size(10, 10)))
8374 .set_id(2)
8375 .set_decoding_mode(PaintImage::DecodingMode::kSync)
8376 .TakePaintImage();
8377 PaintImage unspecified_image =
8378 PaintImageBuilder::WithCopy(
8379 CreateDiscardablePaintImage(gfx::Size(10, 10)))
8380 .set_id(3)
8381 .set_decoding_mode(PaintImage::DecodingMode::kUnspecified)
8382 .TakePaintImage();
8383 content_layer_client_.add_draw_image(async_image, gfx::Point(0, 0),
8384 PaintFlags());
8385 content_layer_client_.add_draw_image(sync_image, gfx::Point(1, 2),
8386 PaintFlags());
8387 content_layer_client_.add_draw_image(unspecified_image, gfx::Point(3, 4),
8388 PaintFlags());
8389
8390 layer_tree_host()->SetRootLayer(
8391 FakePictureLayer::Create(&content_layer_client_));
8392 layer_tree_host()->root_layer()->SetBounds(layer_size);
8393 LayerTreeTest::SetupTree();
8394 }
8395
WillPrepareToDrawOnThread(LayerTreeHostImpl * host_impl)8396 void WillPrepareToDrawOnThread(LayerTreeHostImpl* host_impl) override {
8397 auto& tracker = host_impl->tile_manager()->checker_image_tracker();
8398 EXPECT_EQ(tracker.get_decoding_mode_hint_for_testing(1),
8399 PaintImage::DecodingMode::kAsync);
8400 EXPECT_EQ(tracker.get_decoding_mode_hint_for_testing(2),
8401 PaintImage::DecodingMode::kSync);
8402 EXPECT_EQ(tracker.get_decoding_mode_hint_for_testing(3),
8403 PaintImage::DecodingMode::kUnspecified);
8404 EndTest();
8405 }
8406
8407 private:
8408 FakeContentLayerClient content_layer_client_;
8409 };
8410
8411 MULTI_THREAD_TEST_F(LayerTreeHostTestImageDecodingHints);
8412
8413 class LayerTreeHostTestCheckerboardUkm : public LayerTreeHostTest {
8414 public:
LayerTreeHostTestCheckerboardUkm()8415 LayerTreeHostTestCheckerboardUkm() : url_(GURL("https://example.com")),
8416 ukm_source_id_(123) {}
BeginTest()8417 void BeginTest() override {
8418 PostSetNeedsCommitToMainThread();
8419 layer_tree_host()->SetSourceURL(ukm_source_id_, url_);
8420 }
8421
SetupTree()8422 void SetupTree() override {
8423 gfx::Size layer_size(100, 100);
8424 content_layer_client_.set_bounds(layer_size);
8425 content_layer_client_.set_fill_with_nonsolid_color(true);
8426 layer_tree_host()->SetRootLayer(
8427 FakePictureLayer::Create(&content_layer_client_));
8428 layer_tree_host()->root_layer()->SetBounds(layer_size);
8429 LayerTreeTest::SetupTree();
8430 }
8431
DidActivateTreeOnThread(LayerTreeHostImpl * impl)8432 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
8433 if (impl->active_tree()->source_frame_number() != 0)
8434 return;
8435
8436 // We have an active tree. Start a pinch gesture so we start recording
8437 // stats.
8438 impl->GetInputHandler().PinchGestureBegin();
8439 }
8440
DrawLayersOnThread(LayerTreeHostImpl * impl)8441 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
8442 if (!impl->GetInputHandler().pinch_gesture_active())
8443 return;
8444
8445 // We just drew a frame, stats for it should have been recorded. End the
8446 // gesture so they are flushed to the recorder.
8447 impl->GetInputHandler().PinchGestureEnd(gfx::Point(50, 50), false);
8448
8449 // RenewTreePriority will run when the smoothness expiration timer fires.
8450 // Synthetically do it here so the UkmManager is notified.
8451 impl->RenewTreePriorityForTesting();
8452
8453 auto* recorder = static_cast<ukm::TestUkmRecorder*>(
8454 impl->ukm_manager()->recorder_for_testing());
8455 // Tie the source id to the URL. In production, this is already done in
8456 // Document, and the source id is passed down to cc.
8457 recorder->UpdateSourceURL(ukm_source_id_, url_);
8458
8459 const auto& entries = recorder->GetEntriesByName(kUserInteraction);
8460 EXPECT_EQ(1u, entries.size());
8461 for (const auto* entry : entries) {
8462 recorder->ExpectEntrySourceHasUrl(entry, url_);
8463 recorder->ExpectEntryMetric(entry, kCheckerboardArea, 0);
8464 recorder->ExpectEntryMetric(entry, kMissingTiles, 0);
8465 recorder->ExpectEntryMetric(entry, kCheckerboardAreaRatio, 0);
8466 }
8467
8468 EndTest();
8469 }
8470
8471 private:
8472 const GURL url_;
8473 const ukm::SourceId ukm_source_id_;
8474 FakeContentLayerClient content_layer_client_;
8475 };
8476
8477 // Only multi-thread mode needs to record UKMs.
8478 MULTI_THREAD_TEST_F(LayerTreeHostTestCheckerboardUkm);
8479
8480 class DontUpdateLayersWithEmptyBounds : public LayerTreeTest {
8481 protected:
SetupTree()8482 void SetupTree() override {
8483 auto root = FakePictureLayer::Create(&root_client_);
8484 child_ = FakePictureLayer::Create(&child_client_);
8485 mask_ = FakePictureLayer::Create(&mask_client_);
8486
8487 // Add a lot of draw ops, to make sure the recording source
8488 // hits the early out and avoids being detected as solid color even
8489 // though it is empty. This ensures we hit later code paths that would
8490 // early out if solid color in CanHaveTilings().
8491 PaintFlags flags;
8492 flags.setColor(SK_ColorRED);
8493 for (int i = 0; i < 100; ++i) {
8494 child_client_.add_draw_rect(gfx::Rect(3, 3), flags);
8495 mask_client_.add_draw_rect(gfx::Rect(2, 2), flags);
8496 }
8497
8498 root_client_.set_bounds(gfx::Size(10, 10));
8499 root->SetBounds(gfx::Size(10, 10));
8500
8501 child_client_.set_bounds(gfx::Size(9, 9));
8502 child_->SetBounds(gfx::Size(9, 9));
8503 mask_client_.set_bounds(gfx::Size(9, 9));
8504 mask_->SetBounds(gfx::Size(9, 9));
8505
8506 child_->SetMaskLayer(mask_);
8507 root->AddChild(child_);
8508 layer_tree_host()->SetRootLayer(std::move(root));
8509 LayerTreeTest::SetupTree();
8510 }
8511
BeginTest()8512 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8513
DidCommit()8514 void DidCommit() override {
8515 switch (layer_tree_host()->SourceFrameNumber()) {
8516 case 1:
8517 // The child and mask are updated when they have non-empty bounds.
8518 EXPECT_EQ(1, child_->update_count());
8519 EXPECT_EQ(1, mask_->update_count());
8520
8521 // The child and mask become empty bounds.
8522 child_client_.set_bounds(gfx::Size());
8523 child_->SetBounds(gfx::Size());
8524 mask_client_.set_bounds(gfx::Size());
8525 mask_->SetBounds(gfx::Size());
8526 break;
8527 case 2: {
8528 scoped_refptr<RasterSource> child_raster =
8529 child_->GetRecordingSourceForTesting()->CreateRasterSource();
8530 EXPECT_FALSE(child_raster->IsSolidColor());
8531 scoped_refptr<RasterSource> mask_raster =
8532 mask_->GetRecordingSourceForTesting()->CreateRasterSource();
8533 EXPECT_FALSE(mask_raster->IsSolidColor());
8534 }
8535
8536 // The child and mask are not updated when they have empty bounds.
8537 EXPECT_EQ(1, child_->update_count());
8538 EXPECT_EQ(1, mask_->update_count());
8539 EndTest();
8540 break;
8541 default:
8542 ADD_FAILURE() << layer_tree_host()->SourceFrameNumber();
8543 }
8544 }
8545
8546 scoped_refptr<FakePictureLayer> child_;
8547 scoped_refptr<FakePictureLayer> mask_;
8548 FakeContentLayerClient root_client_;
8549 FakeContentLayerClient child_client_;
8550 FakeContentLayerClient mask_client_;
8551 };
8552
8553 SINGLE_AND_MULTI_THREAD_TEST_F(DontUpdateLayersWithEmptyBounds);
8554
8555 // Verifies that if we have a new LocalSurfaceId we submit a CompositorFrame
8556 // even if there is no damage.
8557 class LayerTreeHostTestNewLocalSurfaceIdForcesDraw : public LayerTreeHostTest {
8558 public:
LayerTreeHostTestNewLocalSurfaceIdForcesDraw()8559 LayerTreeHostTestNewLocalSurfaceIdForcesDraw() {}
8560
BeginTest()8561 void BeginTest() override {
8562 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
8563 viz::LocalSurfaceId());
8564 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
8565 }
8566
DidReceiveCompositorFrameAck()8567 void DidReceiveCompositorFrameAck() override {
8568 switch (layer_tree_host()->SourceFrameNumber()) {
8569 case 1:
8570 GenerateNewLocalSurfaceId();
8571 PostSetLocalSurfaceIdToMainThread(GetCurrentLocalSurfaceId());
8572 break;
8573 case 2:
8574 EndTest();
8575 break;
8576 default:
8577 NOTREACHED();
8578 }
8579 }
8580 };
8581
8582 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNewLocalSurfaceIdForcesDraw);
8583
8584 // Verifies that DidReceiveCompositorFrameAck does not get sent with PostTask
8585 // when not needed.
8586 class DidReceiveCompositorFrameAckNotSentWhenNotNeeded
8587 : public LayerTreeHostTest {
8588 public:
DidReceiveCompositorFrameAckNotSentWhenNotNeeded()8589 DidReceiveCompositorFrameAckNotSentWhenNotNeeded() {}
8590
InitializeSettings(LayerTreeSettings * settings)8591 void InitializeSettings(LayerTreeSettings* settings) override {
8592 settings->send_compositor_frame_ack = false;
8593 }
8594
BeginTest()8595 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8596
DidReceiveCompositorFrameAck()8597 void DidReceiveCompositorFrameAck() override { ADD_FAILURE(); }
8598
8599 // DrawLayersOnThread gets called after the conditional call to
8600 // DidReceiveCompositorFrameAck, so we wait for it to end the test.
DrawLayersOnThread(LayerTreeHostImpl * impl)8601 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
8602 if (!received_first_frame_) {
8603 received_first_frame_ = true;
8604 PostSetNeedsCommitToMainThread();
8605 } else {
8606 EndTest();
8607 }
8608 }
8609
8610 private:
8611 bool received_first_frame_ = false;
8612 };
8613
8614 SINGLE_AND_MULTI_THREAD_TEST_F(
8615 DidReceiveCompositorFrameAckNotSentWhenNotNeeded);
8616
8617 // Confirms that requests to force send RFM are forwarded once (and exactly
8618 // once) to the RFM observer. Does this by drawing 3 frames and requesting
8619 // force send from only the second then validating the request.
8620 class LayerTreeHostTestRequestForceSendMetadata
8621 : public LayerTreeHostTest,
8622 public RenderFrameMetadataObserver {
8623 public:
8624 // Provides a wrapper which can be passed to LayerTreeHost, but just forwards
8625 // to the test class.
8626 class ForwardingRenderFrameMetadataObserver
8627 : public RenderFrameMetadataObserver {
8628 public:
ForwardingRenderFrameMetadataObserver(RenderFrameMetadataObserver * target)8629 explicit ForwardingRenderFrameMetadataObserver(
8630 RenderFrameMetadataObserver* target)
8631 : target_(target) {}
8632
8633 // RenderFrameMetadataObserver implementation.
BindToCurrentThread()8634 void BindToCurrentThread() override { target_->BindToCurrentThread(); }
OnRenderFrameSubmission(const RenderFrameMetadata & render_frame_metadata,viz::CompositorFrameMetadata * compositor_frame_metadata,bool force_send)8635 void OnRenderFrameSubmission(
8636 const RenderFrameMetadata& render_frame_metadata,
8637 viz::CompositorFrameMetadata* compositor_frame_metadata,
8638 bool force_send) override {
8639 target_->OnRenderFrameSubmission(render_frame_metadata,
8640 compositor_frame_metadata, force_send);
8641 }
8642
8643 private:
8644 RenderFrameMetadataObserver* target_ = nullptr;
8645 };
8646
8647 LayerTreeHostTestRequestForceSendMetadata() = default;
8648
BeginTest()8649 void BeginTest() override {
8650 // Just set up a basic frame which can be repeatedly re-drawn.
8651 layer_tree_host()->SetRenderFrameObserver(
8652 std::make_unique<ForwardingRenderFrameMetadataObserver>(this));
8653 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
8654 viz::LocalSurfaceId());
8655 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
8656
8657 layer_ = FakePictureLayer::Create(&client_);
8658 layer_->SetBounds(gfx::Size(10, 10));
8659 layer_->SetPosition(gfx::PointF(0.f, 0.f));
8660 layer_->SetIsDrawable(true);
8661 layer_tree_host()->root_layer()->AddChild(layer_);
8662
8663 PostSetNeedsCommitToMainThread();
8664 client_.set_bounds(layer_->bounds());
8665 }
8666
DidCommitAndDrawFrame()8667 void DidCommitAndDrawFrame() override {
8668 // Draw three frames, sending a request to force send metadata on the
8669 // middle (second) frame.
8670 if (num_draw_layers_ == 3)
8671 return;
8672 if (num_draw_layers_ == 2)
8673 layer_tree_host()->RequestForceSendMetadata();
8674 layer_->SetNeedsDisplay();
8675 }
8676
DrawLayersOnThread(LayerTreeHostImpl * impl)8677 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
8678 num_draw_layers_++;
8679 if (num_draw_layers_ == 3)
8680 EndTest();
8681 }
8682
AfterTest()8683 void AfterTest() override { EXPECT_EQ(1, num_force_sends_); }
8684
8685 // RenderFrameMetadataObserver implementation. Called on thread.
BindToCurrentThread()8686 void BindToCurrentThread() override {}
OnRenderFrameSubmission(const RenderFrameMetadata & render_frame_metadata,viz::CompositorFrameMetadata * compositor_frame_metadata,bool force_send)8687 void OnRenderFrameSubmission(
8688 const RenderFrameMetadata& render_frame_metadata,
8689 viz::CompositorFrameMetadata* compositor_frame_metadata,
8690 bool force_send) override {
8691 if (force_send)
8692 num_force_sends_++;
8693 }
8694
8695 private:
8696 FakeContentLayerClient client_;
8697 scoped_refptr<Layer> layer_;
8698 int num_draw_layers_ = 0;
8699 int num_force_sends_ = 0;
8700 };
8701
8702 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestForceSendMetadata);
8703
8704 class LayerTreeHostTestPartialTileDamage : public LayerTreeHostTest {
8705 public:
LayerTreeHostTestPartialTileDamage()8706 LayerTreeHostTestPartialTileDamage()
8707 : partial_damage_(20, 20, 45, 60), layer_size_(512, 512) {}
8708
BeginTest()8709 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8710
InitializeSettings(LayerTreeSettings * settings)8711 void InitializeSettings(LayerTreeSettings* settings) override {
8712 settings->default_tile_size = gfx::Size(256, 256);
8713 }
8714
SetupTree()8715 void SetupTree() override {
8716 content_layer_client_.set_bounds(layer_size_);
8717 content_layer_client_.set_fill_with_nonsolid_color(true);
8718 layer_tree_host()->SetRootLayer(
8719 FakePictureLayer::Create(&content_layer_client_));
8720 layer_tree_host()->root_layer()->SetBounds(layer_size_);
8721 LayerTreeTest::SetupTree();
8722 }
8723
DoPartialTileInvalidation()8724 void DoPartialTileInvalidation() {
8725 layer_tree_host()->root_layer()->SetNeedsDisplayRect(partial_damage_);
8726 }
8727
DisplayReceivedCompositorFrameOnThread(const viz::CompositorFrame & frame)8728 void DisplayReceivedCompositorFrameOnThread(
8729 const viz::CompositorFrame& frame) override {
8730 frame_count_on_impl_thread_++;
8731 gfx::Rect frame_damage = frame.render_pass_list.back()->damage_rect;
8732
8733 switch (frame_count_on_impl_thread_) {
8734 case 1:
8735 // We have the first frame, which should damage everything. Schedule
8736 // another which partially damages one of tiles.
8737 MainThreadTaskRunner()->PostTask(
8738 FROM_HERE,
8739 base::BindOnce(
8740 &LayerTreeHostTestPartialTileDamage::DoPartialTileInvalidation,
8741 base::Unretained(this)));
8742 EXPECT_EQ(frame_damage, gfx::Rect(layer_size_));
8743 break;
8744 case 2:
8745 EXPECT_EQ(frame_damage, partial_damage_);
8746 EndTest();
8747 }
8748 }
8749
8750 protected:
8751 const gfx::Rect partial_damage_;
8752 const gfx::Size layer_size_;
8753
8754 // Main thread.
8755 FakeContentLayerClient content_layer_client_;
8756
8757 // Impl thread.
8758 int frame_count_on_impl_thread_ = 0;
8759 };
8760
8761 MULTI_THREAD_TEST_F(LayerTreeHostTestPartialTileDamage);
8762
8763 // Make sure that a change in top controls shown ratio causes an update to the
8764 // pending tree's viewports.
8765 class LayerTreeHostTopControlsDeltaTriggersViewportUpdate
8766 : public LayerTreeHostTest {
8767 public:
LayerTreeHostTopControlsDeltaTriggersViewportUpdate()8768 LayerTreeHostTopControlsDeltaTriggersViewportUpdate() { SetUseLayerLists(); }
8769
BeginTest()8770 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8771
SetupTree()8772 void SetupTree() override {
8773 LayerTreeHostTest::SetupTree();
8774 Layer* root_layer = layer_tree_host()->root_layer();
8775 // Set up scrollable root.
8776 root_layer->SetBounds(gfx::Size(100, 100));
8777 SetupViewport(root_layer, gfx::Size(50, 50), root_layer->bounds());
8778 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f);
8779 // Set browser controls to be partially shown.
8780 layer_tree_host()->SetBrowserControlsParams(
8781 {kTopControlsHeight, 0, kBottomControlsHeight, 0, false /* animate */,
8782 true /* shrink */});
8783 layer_tree_host()->SetBrowserControlsShownRatio(kTopControlsShownRatio,
8784 kBottomControlsShownRatio);
8785 }
8786
BeginCommitOnThread(LayerTreeHostImpl * impl)8787 void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
8788 // Before commit the inner_viewport_container_bounds_delta() value should
8789 // not reflect the partially shown top controls.
8790 float bounds_delta = impl->pending_tree()
8791 ->property_trees()
8792 ->inner_viewport_container_bounds_delta()
8793 .y();
8794 EXPECT_EQ(bounds_delta, 0.0f);
8795 }
8796
CommitCompleteOnThread(LayerTreeHostImpl * impl)8797 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
8798 // After commit the inner_viewport_container_bounds_delta() value should
8799 // reflect the partially shown top controls.
8800 float bounds_delta = impl->pending_tree()
8801 ->property_trees()
8802 ->inner_viewport_container_bounds_delta()
8803 .y();
8804 EXPECT_EQ(bounds_delta,
8805 kTopControlsHeight - kTopControlsHeight * kTopControlsShownRatio);
8806 EndTest();
8807 }
8808
8809 static constexpr float kTopControlsHeight = 10.0f;
8810 static constexpr float kTopControlsShownRatio = 0.3f;
8811 static constexpr float kBottomControlsHeight = 10.0f;
8812 static constexpr float kBottomControlsShownRatio = 1.f;
8813 };
8814
8815 MULTI_THREAD_TEST_F(LayerTreeHostTopControlsDeltaTriggersViewportUpdate);
8816
8817 // Tests that custom sequence throughput tracking result is reported to
8818 // LayerTreeHostClient.
8819 constexpr MutatorHost::TrackedAnimationSequenceId kSequenceId = 1u;
8820 class LayerTreeHostCustomThrougputTrackerTest : public LayerTreeHostTest {
8821 public:
BeginTest()8822 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8823
DidCommit()8824 void DidCommit() override {
8825 // FrameSequenceTracker typically sees the following sequence:
8826 // e(2,2)b(3)B(0,3)E(3)s(3)S(3)e(3,3)P(3)b(4)B(3,4)E(4)s(4)S(4)e(4,4)P(4)
8827 switch (layer_tree_host()->SourceFrameNumber()) {
8828 case 1:
8829 animation_host()->StartThroughputTracking(kSequenceId);
8830 break;
8831 case 3:
8832 animation_host()->StopThroughputTracking(kSequenceId);
8833 break;
8834 default:
8835 break;
8836 }
8837
8838 if (!TestEnded())
8839 PostSetNeedsCommitWithForcedRedrawToMainThread();
8840 }
8841
NotifyThroughputTrackerResults(CustomTrackerResults results)8842 void NotifyThroughputTrackerResults(CustomTrackerResults results) override {
8843 // Check that data for kSequenceId is captured. Ideally, we should get
8844 // 2 frame_expected and 2 frame_produced. But on slow bots, it is difficult
8845 // to infer the correct numbers. Both frame_expected and frame_produced
8846 // could drop to 1 (or even below). So no sanity check on data itself.
8847 ASSERT_TRUE(base::Contains(results, kSequenceId));
8848
8849 EndTest();
8850 }
8851 };
8852
8853 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCustomThrougputTrackerTest);
8854
8855 // Confirm that DelegatedInkMetadata set on the LTH propagates to the
8856 // CompositorFrameMetadata and RenderFrameMetadata, and then both are correctly
8857 // reset when another frame is drawn without DelegatedInkMetadata.
8858 class LayerTreeHostTestDelegatedInkMetadataOnAndOff
8859 : public LayerTreeHostTest,
8860 public RenderFrameMetadataObserver {
8861 public:
8862 // Provides a wrapper which can be passed to LayerTreeHost, but just forwards
8863 // to the test class.
8864 class ForwardingRenderFrameMetadataObserver
8865 : public RenderFrameMetadataObserver {
8866 public:
ForwardingRenderFrameMetadataObserver(RenderFrameMetadataObserver * target)8867 explicit ForwardingRenderFrameMetadataObserver(
8868 RenderFrameMetadataObserver* target)
8869 : target_(target) {}
8870
8871 // RenderFrameMetadataObserver implementation.
BindToCurrentThread()8872 void BindToCurrentThread() override { target_->BindToCurrentThread(); }
OnRenderFrameSubmission(const RenderFrameMetadata & render_frame_metadata,viz::CompositorFrameMetadata * compositor_frame_metadata,bool force_send)8873 void OnRenderFrameSubmission(
8874 const RenderFrameMetadata& render_frame_metadata,
8875 viz::CompositorFrameMetadata* compositor_frame_metadata,
8876 bool force_send) override {
8877 target_->OnRenderFrameSubmission(render_frame_metadata,
8878 compositor_frame_metadata, force_send);
8879 }
8880
8881 private:
8882 RenderFrameMetadataObserver* target_ = nullptr;
8883 };
8884
BeginTest()8885 void BeginTest() override {
8886 // Set up a basic render frame observer for the LTH/LTHI to forward to.
8887 layer_tree_host()->SetRenderFrameObserver(
8888 std::make_unique<ForwardingRenderFrameMetadataObserver>(this));
8889
8890 // Setting up a basic frame that can be redrawn.
8891 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
8892 viz::LocalSurfaceId());
8893 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
8894 layer_ = FakePictureLayer::Create(&client_);
8895 layer_tree_host()->root_layer()->AddChild(layer_);
8896 client_.set_bounds(layer_->bounds());
8897
8898 // Values chosen arbitrarily
8899 SkColor color = SK_ColorDKGRAY;
8900 double diameter = 1.000002;
8901 gfx::PointF point = gfx::PointF(135, 45);
8902 gfx::RectF area = gfx::RectF(173, 438);
8903 base::TimeTicks timestamp = base::TimeTicks::Now();
8904
8905 expected_metadata_ =
8906 viz::DelegatedInkMetadata(point, diameter, color, timestamp, area);
8907 layer_tree_host()->SetDelegatedInkMetadata(
8908 std::make_unique<viz::DelegatedInkMetadata>(
8909 expected_metadata_.value()));
8910 }
8911
DidCommitAndDrawFrame()8912 void DidCommitAndDrawFrame() override {
8913 // Cause a redraw to occur.
8914 if (set_needs_display_) {
8915 layer_->SetNeedsDisplay();
8916 set_needs_display_ = false;
8917 }
8918 }
8919
DrawLayersOnThread(LayerTreeHostImpl * impl)8920 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
8921 if (expected_metadata_.has_value()) {
8922 EXPECT_EQ(metadata_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
8923 // Now try again with no metadata to confirm everything is cleared out.
8924 expected_metadata_.reset();
8925 }
8926 }
8927
ExpectMetadata(bool had_delegated_ink_metadata,viz::DelegatedInkMetadata * actual_metadata)8928 void ExpectMetadata(bool had_delegated_ink_metadata,
8929 viz::DelegatedInkMetadata* actual_metadata) {
8930 if (expected_metadata_.has_value()) {
8931 EXPECT_TRUE(had_delegated_ink_metadata);
8932 EXPECT_TRUE(actual_metadata);
8933 EXPECT_EQ(expected_metadata_->point(), actual_metadata->point());
8934 EXPECT_EQ(expected_metadata_->color(), actual_metadata->color());
8935 EXPECT_EQ(expected_metadata_->diameter(), actual_metadata->diameter());
8936 EXPECT_EQ(expected_metadata_->presentation_area(),
8937 actual_metadata->presentation_area());
8938 EXPECT_EQ(expected_metadata_->timestamp(), actual_metadata->timestamp());
8939
8940 // Record the frame time from the metadata so we can confirm that it
8941 // matches the LayerTreeHostImpl's frame time in DrawLayersOnThread.
8942 EXPECT_GT(actual_metadata->frame_time(), base::TimeTicks::Min());
8943 metadata_frame_time_ = actual_metadata->frame_time();
8944 } else {
8945 EXPECT_FALSE(had_delegated_ink_metadata);
8946 EXPECT_FALSE(actual_metadata);
8947 EndTest();
8948 }
8949 }
8950
8951 // RenderFrameMetadataObserver implementation.
BindToCurrentThread()8952 void BindToCurrentThread() override {}
OnRenderFrameSubmission(const RenderFrameMetadata & render_frame_metadata,viz::CompositorFrameMetadata * compositor_frame_metadata,bool force_send)8953 void OnRenderFrameSubmission(
8954 const RenderFrameMetadata& render_frame_metadata,
8955 viz::CompositorFrameMetadata* compositor_frame_metadata,
8956 bool force_send) override {
8957 ExpectMetadata(render_frame_metadata.has_delegated_ink_metadata,
8958 compositor_frame_metadata->delegated_ink_metadata.get());
8959 }
8960
8961 private:
8962 base::Optional<viz::DelegatedInkMetadata> expected_metadata_;
8963 FakeContentLayerClient client_;
8964 scoped_refptr<Layer> layer_;
8965 bool set_needs_display_ = true;
8966 base::TimeTicks metadata_frame_time_;
8967 };
8968
8969 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDelegatedInkMetadataOnAndOff);
8970
8971 // Base class for EventMetrics-related tests.
8972 class LayerTreeHostTestEventsMetrics : public LayerTreeHostTest {
8973 protected:
BeginTest()8974 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
8975
8976 // Simulate an event being handled on the main thread.
PostSimulateEvent()8977 void PostSimulateEvent() {
8978 MainThreadTaskRunner()->PostTask(
8979 FROM_HERE,
8980 base::BindOnce(&LayerTreeHostTestEventsMetrics::SimulateEventOnMain,
8981 base::Unretained(this)));
8982 }
8983
8984 // Verifies the number of saved events metrics on the main thread.
PostVerifyMainSavedEventsMetricsCount(size_t count) const8985 void PostVerifyMainSavedEventsMetricsCount(size_t count) const {
8986 MainThreadTaskRunner()->PostTask(
8987 FROM_HERE, base::BindOnce(&LayerTreeHostTestEventsMetrics::
8988 VerifyMainSavedEventsMetricsCountOnMain,
8989 base::Unretained(this), count));
8990 }
8991
8992 // Verifies the number of events metrics copied from the main thread to the
8993 // impl thread.
VerifyImplEventsMetricsFromMainCount(LayerTreeHostImpl * impl,size_t count) const8994 void VerifyImplEventsMetricsFromMainCount(LayerTreeHostImpl* impl,
8995 size_t count) const {
8996 EXPECT_EQ(count, impl->active_tree()
8997 ->events_metrics_from_main_thread_count_for_testing());
8998 }
8999
9000 private:
SimulateEventOnMain()9001 void SimulateEventOnMain() {
9002 std::unique_ptr<EventMetrics> metrics = EventMetrics::Create(
9003 ui::ET_GESTURE_SCROLL_UPDATE,
9004 EventMetrics::ScrollUpdateType::kContinued, base::TimeTicks::Now(),
9005 ui::ScrollInputType::kWheel);
9006 {
9007 auto done_callback = base::BindOnce(
9008 [](std::unique_ptr<EventMetrics> metrics, bool handled) {
9009 std::unique_ptr<EventMetrics> result =
9010 handled ? std::move(metrics) : nullptr;
9011 return result;
9012 },
9013 std::move(metrics));
9014 auto scoped_event_monitor =
9015 layer_tree_host()->GetScopedEventMetricsMonitor(
9016 std::move(done_callback));
9017 layer_tree_host()->SetNeedsAnimate();
9018 }
9019 EXPECT_SCOPED(VerifyMainSavedEventsMetricsCountOnMain(1));
9020 }
9021
VerifyMainSavedEventsMetricsCountOnMain(size_t count) const9022 void VerifyMainSavedEventsMetricsCountOnMain(size_t count) const {
9023 EXPECT_EQ(count,
9024 layer_tree_host()->saved_events_metrics_count_for_testing());
9025 }
9026 };
9027
9028 // Verifies that if the commit is aborted (deferred) due to LayerTreeHost being
9029 // hidden, events metrics are not thrown away to be used when it becomes
9030 // visible.
9031 class LayerTreeHostTestKeepEventsMetricsForVisibility
9032 : public LayerTreeHostTestEventsMetrics {
9033 protected:
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const viz::BeginFrameArgs & args)9034 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
9035 const viz::BeginFrameArgs& args) override {
9036 // Skip if we have already received a begin-impl-frame and acted on it.
9037 if (received_will_begin_impl_frame_)
9038 return;
9039 received_will_begin_impl_frame_ = true;
9040
9041 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 0));
9042
9043 // Simulate an event being handled on the main thread. Since the main frame
9044 // is not yet scheduled, we will have events metrics when the main frame is
9045 // processed.
9046 PostSimulateEvent();
9047
9048 // Hide layer tree host. Since the main frame is not yet scheduled, layer
9049 // tree host will be hidden when the main frame is processed, causing it to
9050 // abort.
9051 PostSetLayerTreeHostVisible(false);
9052 }
9053
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * impl,CommitEarlyOutReason reason)9054 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* impl,
9055 CommitEarlyOutReason reason) override {
9056 EXPECT_EQ(reason, CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
9057
9058 // Since the main frame is aborted due to invisibility, events metrics
9059 // should not have been thrown away.
9060 PostVerifyMainSavedEventsMetricsCount(1);
9061
9062 // Make layer tree host visible so that the deferred commit is completed,
9063 // causing events metrics being passed to the impl thread.
9064 PostSetLayerTreeHostVisible(true);
9065 }
9066
DidActivateTreeOnThread(LayerTreeHostImpl * impl)9067 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
9068 // Now that a commit is completed and activated, events metrics from main
9069 // thread should have been moved to the impl thread.
9070 PostVerifyMainSavedEventsMetricsCount(0);
9071 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 1));
9072
9073 EndTest();
9074 }
9075
9076 private:
SetLayerTreeHostVisibleOnMain(bool visible)9077 void SetLayerTreeHostVisibleOnMain(bool visible) {
9078 layer_tree_host()->SetVisible(visible);
9079 }
9080
PostSetLayerTreeHostVisible(bool visible)9081 void PostSetLayerTreeHostVisible(bool visible) {
9082 MainThreadTaskRunner()->PostTask(
9083 FROM_HERE,
9084 base::BindOnce(&LayerTreeHostTestKeepEventsMetricsForVisibility::
9085 SetLayerTreeHostVisibleOnMain,
9086 base::Unretained(this), visible));
9087 }
9088
9089 bool received_will_begin_impl_frame_ = false;
9090 };
9091
9092 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepEventsMetricsForVisibility);
9093
9094 // Verifies that if the commit is aborted due to main frame update being
9095 // deferred, events metrics are not thrown away to be used when the actual
9096 // commit happens.
9097 class LayerTreeHostTestKeepEventsMetricsForDeferredMainFrameUpdate
9098 : public LayerTreeHostTestEventsMetrics {
9099 protected:
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const viz::BeginFrameArgs & args)9100 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
9101 const viz::BeginFrameArgs& args) override {
9102 // Skip if we have already received a begin-impl-frame and acted on it.
9103 if (received_will_begin_impl_frame_)
9104 return;
9105 received_will_begin_impl_frame_ = true;
9106
9107 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 0));
9108
9109 // Simulate an event being handled on the main thread. Since the main frame
9110 // is not yet scheduled, we will have events metrics when the main frame is
9111 // processed.
9112 PostSimulateEvent();
9113
9114 // Defer main frame updates. Since the main frame is not yet scheduled, main
9115 // frame updates will be deferred when the main frame is processed, causing
9116 // it to abort.
9117 PostDeferMainFrameUpdate();
9118 }
9119
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * impl,CommitEarlyOutReason reason)9120 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* impl,
9121 CommitEarlyOutReason reason) override {
9122 EXPECT_EQ(reason, CommitEarlyOutReason::ABORTED_DEFERRED_MAIN_FRAME_UPDATE);
9123
9124 // Since the main frame is aborted due to deferred main frame updates,
9125 // events metrics should not have been thrown away.
9126 PostVerifyMainSavedEventsMetricsCount(1);
9127
9128 // Stop deferring main frame updates so that the deferred commit is
9129 // completed, causing events metrics being passed to the impl thread.
9130 PostStopDeferringMainFrameUpdate();
9131 }
9132
DidActivateTreeOnThread(LayerTreeHostImpl * impl)9133 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
9134 // Now that a commit is completed and activated, events metrics from main
9135 // thread should have been moved to the impl thread.
9136 PostVerifyMainSavedEventsMetricsCount(0);
9137 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 1));
9138
9139 EndTest();
9140 }
9141
9142 private:
DeferMainFrameUpdateOnMain()9143 void DeferMainFrameUpdateOnMain() {
9144 scoped_defer_main_frame_update_ = layer_tree_host()->DeferMainFrameUpdate();
9145 }
9146
PostDeferMainFrameUpdate()9147 void PostDeferMainFrameUpdate() {
9148 MainThreadTaskRunner()->PostTask(
9149 FROM_HERE,
9150 base::BindOnce(
9151 &LayerTreeHostTestKeepEventsMetricsForDeferredMainFrameUpdate::
9152 DeferMainFrameUpdateOnMain,
9153 base::Unretained(this)));
9154 }
9155
StopDeferringMainFrameUpdateOnMain()9156 void StopDeferringMainFrameUpdateOnMain() {
9157 scoped_defer_main_frame_update_.reset();
9158 }
9159
PostStopDeferringMainFrameUpdate()9160 void PostStopDeferringMainFrameUpdate() {
9161 MainThreadTaskRunner()->PostTask(
9162 FROM_HERE,
9163 base::BindOnce(
9164 &LayerTreeHostTestKeepEventsMetricsForDeferredMainFrameUpdate::
9165 StopDeferringMainFrameUpdateOnMain,
9166 base::Unretained(this)));
9167 }
9168
9169 bool received_will_begin_impl_frame_ = false;
9170 std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
9171 };
9172
9173 SINGLE_AND_MULTI_THREAD_TEST_F(
9174 LayerTreeHostTestKeepEventsMetricsForDeferredMainFrameUpdate);
9175
9176 // Verifies that if the commit is aborted (deferred), events metrics are not
9177 // thrown away to be used when the actual commit happens.
9178 class LayerTreeHostTestKeepEventsMetricsForDeferredCommit
9179 : public LayerTreeHostTestEventsMetrics {
9180 protected:
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const viz::BeginFrameArgs & args)9181 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
9182 const viz::BeginFrameArgs& args) override {
9183 // Skip if we have already received a begin-impl-frame and acted on it.
9184 if (received_will_begin_impl_frame_)
9185 return;
9186 received_will_begin_impl_frame_ = true;
9187
9188 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 0));
9189
9190 // Simulate an event being handled on the main thread. Since the main frame
9191 // is not yet scheduled, we will have events metrics when the main frame is
9192 // processed.
9193 PostSimulateEvent();
9194
9195 // Defer commits. Since the main frame is not yet scheduled, commits will be
9196 // deferred when the main frame is processed, causing it to abort.
9197 PostDeferCommit();
9198 }
9199
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * impl,CommitEarlyOutReason reason)9200 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* impl,
9201 CommitEarlyOutReason reason) override {
9202 EXPECT_EQ(reason, CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
9203
9204 // Since the main frame is aborted due to deferred commits, events metrics
9205 // should not have been thrown away.
9206 PostVerifyMainSavedEventsMetricsCount(1);
9207
9208 // Stop deferring commits so that the deferred commit is completed, causing
9209 // events metrics being passed to the impl thread.
9210 PostStopDeferringCommit();
9211 }
9212
DidActivateTreeOnThread(LayerTreeHostImpl * impl)9213 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
9214 // Now that a commit is completed and activated, events metrics from main
9215 // thread should have been moved to the impl thread.
9216 PostVerifyMainSavedEventsMetricsCount(0);
9217 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 1));
9218
9219 EndTest();
9220 }
9221
9222 private:
DeferCommitOnMain()9223 void DeferCommitOnMain() {
9224 layer_tree_host()->StartDeferringCommits(base::TimeDelta::FromDays(1));
9225 }
9226
PostDeferCommit()9227 void PostDeferCommit() {
9228 MainThreadTaskRunner()->PostTask(
9229 FROM_HERE,
9230 base::BindOnce(&LayerTreeHostTestKeepEventsMetricsForDeferredCommit::
9231 DeferCommitOnMain,
9232 base::Unretained(this)));
9233 }
9234
StopDeferringCommitOnMain()9235 void StopDeferringCommitOnMain() {
9236 layer_tree_host()->StopDeferringCommits(
9237 PaintHoldingCommitTrigger::kFirstContentfulPaint);
9238 }
9239
PostStopDeferringCommit()9240 void PostStopDeferringCommit() {
9241 MainThreadTaskRunner()->PostTask(
9242 FROM_HERE,
9243 base::BindOnce(&LayerTreeHostTestKeepEventsMetricsForDeferredCommit::
9244 StopDeferringCommitOnMain,
9245 base::Unretained(this)));
9246 }
9247
9248 bool received_will_begin_impl_frame_ = false;
9249 };
9250
9251 SINGLE_AND_MULTI_THREAD_TEST_F(
9252 LayerTreeHostTestKeepEventsMetricsForDeferredCommit);
9253
9254 // Verifies that if the commit is aborted due to no damage, events metrics are
9255 // thrown away, so there is nothing to report in the next commit.
9256 class LayerTreeHostTestIgnoreEventsMetricsForNoUpdate
9257 : public LayerTreeHostTestEventsMetrics {
9258 protected:
WillBeginImplFrameOnThread(LayerTreeHostImpl * impl,const viz::BeginFrameArgs & args)9259 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
9260 const viz::BeginFrameArgs& args) override {
9261 // Continue only if we are waiting for the second frame's being-impl-frame.
9262 // The first frame will end up in a commit which is not what we want.
9263 if (state_ != State::kWaitingForSecondFrameBeginImpl)
9264 return;
9265 state_ = State::kReceivedSecondFrameBeginImpl;
9266
9267 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 0));
9268
9269 // Simulate an event being handled on the main thread. Since the main frame
9270 // is not yet scheduled, we will have events metrics when the main frame is
9271 // processed.
9272 PostSimulateEvent();
9273 }
9274
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * impl,CommitEarlyOutReason reason)9275 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* impl,
9276 CommitEarlyOutReason reason) override {
9277 EXPECT_EQ(reason, CommitEarlyOutReason::FINISHED_NO_UPDATES);
9278
9279 // We should reach here only for the second frame.
9280 EXPECT_EQ(state_, State::kReceivedSecondFrameBeginImpl);
9281 state_ = State::kWaitingForThirdFrameActivation;
9282
9283 // Since the main frame is aborted due to no updates, events metrics should
9284 // have been thrown away.
9285 PostVerifyMainSavedEventsMetricsCount(0);
9286
9287 // Request another commit to make sure no events metrics is passed to the
9288 // impl thread when it is complete.
9289 PostSetNeedsCommitToMainThread();
9290 }
9291
DidActivateTreeOnThread(LayerTreeHostImpl * impl)9292 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
9293 switch (state_) {
9294 case State::kWaitingForFirstFrameActivation:
9295 // Now that the first frame's commit is completed and activated, request
9296 // another begin-main-frame without requesting a full commit so that it
9297 // aborts with no updates.
9298 state_ = State::kWaitingForSecondFrameBeginImpl;
9299 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 0));
9300 PostSetNeedsUpdateLayersToMainThread();
9301 break;
9302 case State::kWaitingForThirdFrameActivation:
9303 // Now that the third frame's commit is completed and activated there
9304 // should be no events metrics on the main or impl thread as the events
9305 // metrics were thrown away after second frame was aborted with no
9306 // updates.
9307 EXPECT_SCOPED(VerifyImplEventsMetricsFromMainCount(impl, 0));
9308 PostVerifyMainSavedEventsMetricsCount(0);
9309 EndTest();
9310 break;
9311 default:
9312 NOTREACHED();
9313 }
9314 }
9315
9316 private:
9317 enum class State {
9318 kWaitingForFirstFrameActivation,
9319 kWaitingForSecondFrameBeginImpl,
9320 kReceivedSecondFrameBeginImpl,
9321 kWaitingForThirdFrameActivation,
9322 };
9323
9324 State state_ = State::kWaitingForFirstFrameActivation;
9325 };
9326
9327 MULTI_THREAD_TEST_F(LayerTreeHostTestIgnoreEventsMetricsForNoUpdate);
9328
9329 class LayerTreeHostUkmSmoothnessMetric : public LayerTreeTest {
9330 public:
9331 LayerTreeHostUkmSmoothnessMetric() = default;
9332 ~LayerTreeHostUkmSmoothnessMetric() override = default;
9333
InitializeSettings(LayerTreeSettings * settings)9334 void InitializeSettings(LayerTreeSettings* settings) override {
9335 settings->commit_to_active_tree = false;
9336 }
9337
SetupTree()9338 void SetupTree() override {
9339 LayerTreeTest::SetupTree();
9340 shmem_region_ = layer_tree_host()->CreateSharedMemoryForSmoothnessUkm();
9341 }
9342
BeginTest()9343 void BeginTest() override {
9344 // Start with requesting main-frames.
9345 PostSetNeedsCommitToMainThread();
9346 }
9347
AfterTest()9348 void AfterTest() override {
9349 ASSERT_TRUE(shmem_region_.IsValid());
9350 auto mapping = shmem_region_.Map();
9351 auto* smoothness = mapping.GetMemoryAs<UkmSmoothnessDataShared>();
9352 ASSERT_TRUE(smoothness);
9353 // It is not always possible to guarantee an exact number of dropped frames.
9354 // So validate that there are non-zero dropped frames.
9355 EXPECT_GT(smoothness->data.avg_smoothness, 0);
9356 }
9357
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)9358 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
9359 const viz::BeginFrameArgs& args) override {
9360 host_impl->dropped_frame_counter()->OnFcpReceived();
9361 }
9362
DidFinishImplFrameOnThread(LayerTreeHostImpl * host_impl)9363 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
9364 if (TestEnded())
9365 return;
9366
9367 if (frames_counter_ == 0) {
9368 EndTest();
9369 return;
9370 }
9371
9372 // Mark every frame as a dropped frame affecting smoothness.
9373 host_impl->dropped_frame_counter()->OnEndFrame(viz::BeginFrameArgs(), true);
9374 host_impl->SetNeedsRedraw();
9375 --frames_counter_;
9376 }
9377
9378 private:
9379 const uint32_t kTotalFramesForTest = 5;
9380 uint32_t frames_counter_ = kTotalFramesForTest;
9381 base::ReadOnlySharedMemoryRegion shmem_region_;
9382 };
9383
9384 MULTI_THREAD_TEST_F(LayerTreeHostUkmSmoothnessMetric);
9385
9386 class LayerTreeHostUkmSmoothnessMemoryOwnership : public LayerTreeTest {
9387 public:
9388 LayerTreeHostUkmSmoothnessMemoryOwnership() = default;
9389 ~LayerTreeHostUkmSmoothnessMemoryOwnership() override = default;
9390
InitializeSettings(LayerTreeSettings * settings)9391 void InitializeSettings(LayerTreeSettings* settings) override {
9392 settings->commit_to_active_tree = false;
9393 }
9394
BeginTest()9395 void BeginTest() override {
9396 // Start with requesting main-frames.
9397 PostSetNeedsCommitToMainThread();
9398 }
9399
AfterTest()9400 void AfterTest() override {
9401 }
9402
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)9403 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
9404 const viz::BeginFrameArgs& args) override {
9405 host_impl->dropped_frame_counter()->OnFcpReceived();
9406 host_impl->SetNeedsCommit();
9407 }
9408
DidFinishImplFrameOnThread(LayerTreeHostImpl * host_impl)9409 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
9410 if (TestEnded())
9411 return;
9412
9413 if (frames_counter_ == 0) {
9414 EndTest();
9415 return;
9416 }
9417
9418 // Mark every frame as a dropped frame affecting smoothness.
9419 host_impl->dropped_frame_counter()->OnEndFrame(viz::BeginFrameArgs(), true);
9420 host_impl->SetNeedsRedraw();
9421 --frames_counter_;
9422 }
9423
DidBeginMainFrame()9424 void DidBeginMainFrame() override {
9425 // Re-request the shared memory region in each frame.
9426 shmem_region_ = layer_tree_host()->CreateSharedMemoryForSmoothnessUkm();
9427 }
9428
9429 private:
9430 const uint32_t kTotalFramesForTest = 50;
9431 uint32_t frames_counter_ = kTotalFramesForTest;
9432 base::ReadOnlySharedMemoryRegion shmem_region_;
9433 };
9434
9435 MULTI_THREAD_TEST_F(LayerTreeHostUkmSmoothnessMemoryOwnership);
9436
9437 } // namespace
9438 } // namespace cc
9439