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/test/layer_tree_test.h"
6
7 #include <memory>
8 #include <string>
9
10 #include "base/bind.h"
11 #include "base/cfi_buildflags.h"
12 #include "base/command_line.h"
13 #include "base/location.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/run_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/time/time.h"
19 #include "build/build_config.h"
20 #include "cc/animation/animation.h"
21 #include "cc/animation/animation_host.h"
22 #include "cc/animation/keyframe_effect.h"
23 #include "cc/animation/keyframe_model.h"
24 #include "cc/animation/timing_function.h"
25 #include "cc/base/switches.h"
26 #include "cc/input/input_handler.h"
27 #include "cc/layers/layer.h"
28 #include "cc/layers/layer_impl.h"
29 #include "cc/metrics/begin_main_frame_metrics.h"
30 #include "cc/metrics/compositor_timing_history.h"
31 #include "cc/test/animation_test_common.h"
32 #include "cc/test/fake_compositor_frame_reporting_controller.h"
33 #include "cc/test/fake_layer_tree_host_client.h"
34 #include "cc/test/test_layer_tree_frame_sink.h"
35 #include "cc/test/test_ukm_recorder_factory.h"
36 #include "cc/trees/layer_tree_host_client.h"
37 #include "cc/trees/layer_tree_host_impl.h"
38 #include "cc/trees/layer_tree_host_single_thread_client.h"
39 #include "cc/trees/layer_tree_impl.h"
40 #include "cc/trees/proxy_impl.h"
41 #include "cc/trees/proxy_main.h"
42 #include "cc/trees/single_thread_proxy.h"
43 #include "components/ukm/test_ukm_recorder.h"
44 #include "components/viz/common/frame_timing_details.h"
45 #include "components/viz/service/display/display_compositor_memory_and_task_controller.h"
46 #include "components/viz/service/display/skia_output_surface.h"
47 #include "components/viz/test/begin_frame_args_test.h"
48 #include "components/viz/test/fake_output_surface.h"
49 #include "components/viz/test/fake_skia_output_surface.h"
50 #include "components/viz/test/test_context_provider.h"
51 #include "gpu/command_buffer/service/gpu_switches.h"
52 #include "gpu/config/gpu_finch_features.h"
53 #include "testing/gmock/include/gmock/gmock.h"
54 #include "ui/base/ui_base_features.h"
55 #include "ui/gfx/geometry/size_conversions.h"
56 #include "ui/gl/gl_switches.h"
57
58 namespace cc {
59 namespace {
60
61 class SynchronousLayerTreeFrameSink : public TestLayerTreeFrameSink {
62 public:
SynchronousLayerTreeFrameSink(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,scoped_refptr<base::SingleThreadTaskRunner> task_runner,double refresh_rate,viz::BeginFrameSource * begin_frame_source,bool use_software_renderer)63 SynchronousLayerTreeFrameSink(
64 scoped_refptr<viz::ContextProvider> compositor_context_provider,
65 scoped_refptr<viz::RasterContextProvider> worker_context_provider,
66 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
67 const viz::RendererSettings& renderer_settings,
68 const viz::DebugRendererSettings* const debug_settings,
69 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
70 double refresh_rate,
71 viz::BeginFrameSource* begin_frame_source,
72 bool use_software_renderer)
73 : TestLayerTreeFrameSink(std::move(compositor_context_provider),
74 std::move(worker_context_provider),
75 gpu_memory_buffer_manager,
76 renderer_settings,
77 debug_settings,
78 task_runner,
79 false,
80 false,
81 refresh_rate,
82 begin_frame_source),
83 use_software_renderer_(use_software_renderer),
84 task_runner_(std::move(task_runner)) {}
85 ~SynchronousLayerTreeFrameSink() override = default;
86
set_viewport(const gfx::Rect & viewport)87 void set_viewport(const gfx::Rect& viewport) { viewport_ = viewport; }
88
BindToClient(LayerTreeFrameSinkClient * client)89 bool BindToClient(LayerTreeFrameSinkClient* client) override {
90 if (!TestLayerTreeFrameSink::BindToClient(client))
91 return false;
92 client_ = client;
93 return true;
94 }
DetachFromClient()95 void DetachFromClient() override {
96 client_ = nullptr;
97 weak_factory_.InvalidateWeakPtrs();
98 TestLayerTreeFrameSink::DetachFromClient();
99 }
Invalidate(bool needs_draw)100 void Invalidate(bool needs_draw) override {
101 if (frame_request_pending_)
102 return;
103 frame_request_pending_ = true;
104 InvalidateIfPossible();
105 }
SubmitCompositorFrame(viz::CompositorFrame frame,bool hit_test_data_changed,bool show_hit_test_borders)106 void SubmitCompositorFrame(viz::CompositorFrame frame,
107 bool hit_test_data_changed,
108 bool show_hit_test_borders) override {
109 frame_ack_pending_ = true;
110 TestLayerTreeFrameSink::SubmitCompositorFrame(
111 std::move(frame), hit_test_data_changed, show_hit_test_borders);
112 }
DidReceiveCompositorFrameAck(const std::vector<viz::ReturnedResource> & resources)113 void DidReceiveCompositorFrameAck(
114 const std::vector<viz::ReturnedResource>& resources) override {
115 DCHECK(frame_ack_pending_);
116 frame_ack_pending_ = false;
117 TestLayerTreeFrameSink::DidReceiveCompositorFrameAck(resources);
118 InvalidateIfPossible();
119 }
120
121 private:
InvalidateIfPossible()122 void InvalidateIfPossible() {
123 if (!frame_request_pending_ || frame_ack_pending_)
124 return;
125 task_runner_->PostTask(
126 FROM_HERE,
127 base::BindOnce(&SynchronousLayerTreeFrameSink::DispatchInvalidation,
128 weak_factory_.GetWeakPtr()));
129 }
DispatchInvalidation()130 void DispatchInvalidation() {
131 frame_request_pending_ = false;
132 client_->OnDraw(gfx::Transform(SkMatrix::I()), viewport_,
133 use_software_renderer_, false);
134 }
135
136 bool frame_request_pending_ = false;
137 bool frame_ack_pending_ = false;
138 LayerTreeFrameSinkClient* client_ = nullptr;
139 gfx::Rect viewport_;
140 const bool use_software_renderer_;
141 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
142 base::WeakPtrFactory<SynchronousLayerTreeFrameSink> weak_factory_{this};
143 };
144
145 } // namespace
146
147 // Adapts LayerTreeHostImpl for test. Runs real code, then invokes test hooks.
148 class LayerTreeHostImplForTesting : public LayerTreeHostImpl {
149 public:
Create(TestHooks * test_hooks,const LayerTreeSettings & settings,LayerTreeHostImplClient * host_impl_client,LayerTreeHostSchedulingClient * scheduling_client,TaskRunnerProvider * task_runner_provider,TaskGraphRunner * task_graph_runner,RenderingStatsInstrumentation * stats_instrumentation,scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner)150 static std::unique_ptr<LayerTreeHostImplForTesting> Create(
151 TestHooks* test_hooks,
152 const LayerTreeSettings& settings,
153 LayerTreeHostImplClient* host_impl_client,
154 LayerTreeHostSchedulingClient* scheduling_client,
155 TaskRunnerProvider* task_runner_provider,
156 TaskGraphRunner* task_graph_runner,
157 RenderingStatsInstrumentation* stats_instrumentation,
158 scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner) {
159 return base::WrapUnique(new LayerTreeHostImplForTesting(
160 test_hooks, settings, host_impl_client, scheduling_client,
161 task_runner_provider, task_graph_runner, stats_instrumentation,
162 std::move(image_worker_task_runner)));
163 }
164
165 protected:
LayerTreeHostImplForTesting(TestHooks * test_hooks,const LayerTreeSettings & settings,LayerTreeHostImplClient * host_impl_client,LayerTreeHostSchedulingClient * scheduling_client,TaskRunnerProvider * task_runner_provider,TaskGraphRunner * task_graph_runner,RenderingStatsInstrumentation * stats_instrumentation,scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner)166 LayerTreeHostImplForTesting(
167 TestHooks* test_hooks,
168 const LayerTreeSettings& settings,
169 LayerTreeHostImplClient* host_impl_client,
170 LayerTreeHostSchedulingClient* scheduling_client,
171 TaskRunnerProvider* task_runner_provider,
172 TaskGraphRunner* task_graph_runner,
173 RenderingStatsInstrumentation* stats_instrumentation,
174 scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner)
175 : LayerTreeHostImpl(settings,
176 host_impl_client,
177 task_runner_provider,
178 stats_instrumentation,
179 task_graph_runner,
180 AnimationHost::CreateForTesting(ThreadInstance::IMPL),
181 nullptr,
182 0,
183 std::move(image_worker_task_runner),
184 scheduling_client),
185 test_hooks_(test_hooks) {}
186
CreateRasterBufferProvider()187 std::unique_ptr<RasterBufferProvider> CreateRasterBufferProvider() override {
188 return test_hooks_->CreateRasterBufferProvider(this);
189 }
190
WillBeginImplFrame(const viz::BeginFrameArgs & args)191 bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override {
192 bool has_damage = LayerTreeHostImpl::WillBeginImplFrame(args);
193 test_hooks_->WillBeginImplFrameOnThread(this, args);
194 return has_damage;
195 }
196
DidFinishImplFrame(const viz::BeginFrameArgs & main_args)197 void DidFinishImplFrame(const viz::BeginFrameArgs& main_args) override {
198 LayerTreeHostImpl::DidFinishImplFrame(main_args);
199 test_hooks_->DidFinishImplFrameOnThread(this);
200 }
201
WillSendBeginMainFrame()202 void WillSendBeginMainFrame() override {
203 LayerTreeHostImpl::WillSendBeginMainFrame();
204 test_hooks_->WillSendBeginMainFrameOnThread(this);
205 }
206
DidSendBeginMainFrame(const viz::BeginFrameArgs & args)207 void DidSendBeginMainFrame(const viz::BeginFrameArgs& args) override {
208 LayerTreeHostImpl::DidSendBeginMainFrame(args);
209 test_hooks_->DidSendBeginMainFrameOnThread(this);
210 }
211
BeginMainFrameAborted(CommitEarlyOutReason reason,std::vector<std::unique_ptr<SwapPromise>> swap_promises,const viz::BeginFrameArgs & args)212 void BeginMainFrameAborted(
213 CommitEarlyOutReason reason,
214 std::vector<std::unique_ptr<SwapPromise>> swap_promises,
215 const viz::BeginFrameArgs& args) override {
216 LayerTreeHostImpl::BeginMainFrameAborted(reason, std::move(swap_promises),
217 args);
218 test_hooks_->BeginMainFrameAbortedOnThread(this, reason);
219 }
220
ReadyToCommit(const viz::BeginFrameArgs & commit_args,const BeginMainFrameMetrics * begin_main_frame_metrics)221 void ReadyToCommit(
222 const viz::BeginFrameArgs& commit_args,
223 const BeginMainFrameMetrics* begin_main_frame_metrics) override {
224 LayerTreeHostImpl::ReadyToCommit(commit_args, begin_main_frame_metrics);
225 test_hooks_->ReadyToCommitOnThread(this);
226 }
227
BeginCommit()228 void BeginCommit() override {
229 LayerTreeHostImpl::BeginCommit();
230 test_hooks_->BeginCommitOnThread(this);
231 }
232
CommitComplete()233 void CommitComplete() override {
234 test_hooks_->WillCommitCompleteOnThread(this);
235 LayerTreeHostImpl::CommitComplete();
236 test_hooks_->CommitCompleteOnThread(this);
237 }
238
PrepareTiles()239 bool PrepareTiles() override {
240 test_hooks_->WillPrepareTilesOnThread(this);
241 return LayerTreeHostImpl::PrepareTiles();
242 }
243
PrepareToDraw(FrameData * frame)244 DrawResult PrepareToDraw(FrameData* frame) override {
245 test_hooks_->WillPrepareToDrawOnThread(this);
246 DrawResult draw_result = LayerTreeHostImpl::PrepareToDraw(frame);
247 return test_hooks_->PrepareToDrawOnThread(this, frame, draw_result);
248 }
249
DrawLayers(FrameData * frame)250 bool DrawLayers(FrameData* frame) override {
251 bool r = LayerTreeHostImpl::DrawLayers(frame);
252 test_hooks_->DrawLayersOnThread(this);
253 return r;
254 }
255
NotifyReadyToActivate()256 void NotifyReadyToActivate() override {
257 if (block_notify_ready_to_activate_for_testing_) {
258 notify_ready_to_activate_was_blocked_ = true;
259 } else {
260 test_hooks_->WillNotifyReadyToActivateOnThread(this);
261 LayerTreeHostImpl::NotifyReadyToActivate();
262 test_hooks_->NotifyReadyToActivateOnThread(this);
263 }
264 }
265
NotifyReadyToDraw()266 void NotifyReadyToDraw() override {
267 LayerTreeHostImpl::NotifyReadyToDraw();
268 test_hooks_->NotifyReadyToDrawOnThread(this);
269 }
270
NotifyAllTileTasksCompleted()271 void NotifyAllTileTasksCompleted() override {
272 LayerTreeHostImpl::NotifyAllTileTasksCompleted();
273 test_hooks_->NotifyAllTileTasksCompleted(this);
274 }
275
BlockNotifyReadyToActivateForTesting(bool block)276 void BlockNotifyReadyToActivateForTesting(bool block) override {
277 CHECK(task_runner_provider()->ImplThreadTaskRunner())
278 << "Not supported for single-threaded mode.";
279 block_notify_ready_to_activate_for_testing_ = block;
280 if (!block && notify_ready_to_activate_was_blocked_) {
281 task_runner_provider_->ImplThreadTaskRunner()->PostTask(
282 FROM_HERE,
283 base::BindOnce(&LayerTreeHostImplForTesting::NotifyReadyToActivate,
284 base::Unretained(this)));
285 notify_ready_to_activate_was_blocked_ = false;
286 }
287 }
288
BlockImplSideInvalidationRequestsForTesting(bool block)289 void BlockImplSideInvalidationRequestsForTesting(bool block) override {
290 block_impl_side_invalidation_ = block;
291 if (!block_impl_side_invalidation_ && impl_side_invalidation_was_blocked_) {
292 RequestImplSideInvalidationForCheckerImagedTiles();
293 impl_side_invalidation_was_blocked_ = false;
294 }
295 }
296
ActivateSyncTree()297 void ActivateSyncTree() override {
298 test_hooks_->WillActivateTreeOnThread(this);
299 LayerTreeHostImpl::ActivateSyncTree();
300 DCHECK(!pending_tree());
301 test_hooks_->DidActivateTreeOnThread(this);
302 }
303
InitializeFrameSink(LayerTreeFrameSink * layer_tree_frame_sink)304 bool InitializeFrameSink(LayerTreeFrameSink* layer_tree_frame_sink) override {
305 bool success =
306 LayerTreeHostImpl::InitializeFrameSink(layer_tree_frame_sink);
307 test_hooks_->InitializedRendererOnThread(this, success);
308 return success;
309 }
310
SetVisible(bool visible)311 void SetVisible(bool visible) override {
312 LayerTreeHostImpl::SetVisible(visible);
313 test_hooks_->DidSetVisibleOnImplTree(this, visible);
314 }
315
AnimateLayers(base::TimeTicks monotonic_time,bool is_active_tree)316 bool AnimateLayers(base::TimeTicks monotonic_time,
317 bool is_active_tree) override {
318 test_hooks_->WillAnimateLayers(this, monotonic_time);
319 bool result =
320 LayerTreeHostImpl::AnimateLayers(monotonic_time, is_active_tree);
321 test_hooks_->AnimateLayers(this, monotonic_time);
322 return result;
323 }
324
UpdateAnimationState(bool start_ready_animations)325 void UpdateAnimationState(bool start_ready_animations) override {
326 LayerTreeHostImpl::UpdateAnimationState(start_ready_animations);
327 bool has_unfinished_animation = false;
328 for (const auto& it : animation_host()->ticking_animations_for_testing()) {
329 if (it->keyframe_effect()->HasTickingKeyframeModel()) {
330 has_unfinished_animation = true;
331 break;
332 }
333 }
334 test_hooks_->UpdateAnimationState(this, has_unfinished_animation);
335 }
336
NotifyTileStateChanged(const Tile * tile)337 void NotifyTileStateChanged(const Tile* tile) override {
338 LayerTreeHostImpl::NotifyTileStateChanged(tile);
339 test_hooks_->NotifyTileStateChangedOnThread(this, tile);
340 }
341
InvalidateContentOnImplSide()342 void InvalidateContentOnImplSide() override {
343 LayerTreeHostImpl::InvalidateContentOnImplSide();
344 test_hooks_->DidInvalidateContentOnImplSide(this);
345 }
346
InvalidateLayerTreeFrameSink(bool needs_redraw)347 void InvalidateLayerTreeFrameSink(bool needs_redraw) override {
348 LayerTreeHostImpl::InvalidateLayerTreeFrameSink(needs_redraw);
349 test_hooks_->DidInvalidateLayerTreeFrameSink(this);
350 }
351
RequestImplSideInvalidationForCheckerImagedTiles()352 void RequestImplSideInvalidationForCheckerImagedTiles() override {
353 test_hooks_->DidReceiveImplSideInvalidationRequest(this);
354 if (block_impl_side_invalidation_) {
355 impl_side_invalidation_was_blocked_ = true;
356 return;
357 }
358
359 impl_side_invalidation_was_blocked_ = false;
360 LayerTreeHostImpl::RequestImplSideInvalidationForCheckerImagedTiles();
361 test_hooks_->DidRequestImplSideInvalidation(this);
362 }
363
DidReceiveCompositorFrameAck()364 void DidReceiveCompositorFrameAck() override {
365 test_hooks_->WillReceiveCompositorFrameAckOnThread(this);
366 LayerTreeHostImpl::DidReceiveCompositorFrameAck();
367 test_hooks_->DidReceiveCompositorFrameAckOnThread(this);
368 }
369
DidPresentCompositorFrame(uint32_t presentation_token,const viz::FrameTimingDetails & details)370 void DidPresentCompositorFrame(
371 uint32_t presentation_token,
372 const viz::FrameTimingDetails& details) override {
373 LayerTreeHostImpl::DidPresentCompositorFrame(presentation_token, details);
374 test_hooks_->DidReceivePresentationTimeOnThread(
375 this, presentation_token, details.presentation_feedback);
376 }
animation_host() const377 AnimationHost* animation_host() const {
378 return static_cast<AnimationHost*>(mutator_host());
379 }
380
381 private:
382 TestHooks* test_hooks_;
383 bool block_notify_ready_to_activate_for_testing_ = false;
384 bool notify_ready_to_activate_was_blocked_ = false;
385
386 bool block_impl_side_invalidation_ = false;
387 bool impl_side_invalidation_was_blocked_ = false;
388 };
389
390 // Implementation of LayerTreeHost callback interface.
391 class LayerTreeHostClientForTesting : public LayerTreeHostClient,
392 public LayerTreeHostSchedulingClient,
393 public LayerTreeHostSingleThreadClient {
394 public:
Create(TestHooks * test_hooks)395 static std::unique_ptr<LayerTreeHostClientForTesting> Create(
396 TestHooks* test_hooks) {
397 return base::WrapUnique(new LayerTreeHostClientForTesting(test_hooks));
398 }
399 ~LayerTreeHostClientForTesting() override = default;
400
WillBeginMainFrame()401 void WillBeginMainFrame() override { test_hooks_->WillBeginMainFrame(); }
402
DidBeginMainFrame()403 void DidBeginMainFrame() override { test_hooks_->DidBeginMainFrame(); }
404
WillUpdateLayers()405 void WillUpdateLayers() override {}
DidUpdateLayers()406 void DidUpdateLayers() override {}
407
BeginMainFrame(const viz::BeginFrameArgs & args)408 void BeginMainFrame(const viz::BeginFrameArgs& args) override {
409 test_hooks_->BeginMainFrame(args);
410 }
411
OnDeferMainFrameUpdatesChanged(bool)412 void OnDeferMainFrameUpdatesChanged(bool) override {}
OnDeferCommitsChanged(bool)413 void OnDeferCommitsChanged(bool) override {}
414
RecordStartOfFrameMetrics()415 void RecordStartOfFrameMetrics() override {}
RecordEndOfFrameMetrics(base::TimeTicks,ActiveFrameSequenceTrackers)416 void RecordEndOfFrameMetrics(base::TimeTicks,
417 ActiveFrameSequenceTrackers) override {}
GetBeginMainFrameMetrics()418 std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() override {
419 return nullptr;
420 }
NotifyThroughputTrackerResults(CustomTrackerResults results)421 void NotifyThroughputTrackerResults(CustomTrackerResults results) override {
422 test_hooks_->NotifyThroughputTrackerResults(std::move(results));
423 }
424
UpdateLayerTreeHost()425 void UpdateLayerTreeHost() override { test_hooks_->UpdateLayerTreeHost(); }
426
ApplyViewportChanges(const ApplyViewportChangesArgs & args)427 void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
428 test_hooks_->ApplyViewportChanges(args);
429 }
430
DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay,base::TimeTicks first_scroll_timestamp)431 void DidObserveFirstScrollDelay(
432 base::TimeDelta first_scroll_delay,
433 base::TimeTicks first_scroll_timestamp) override {}
434
RecordManipulationTypeCounts(ManipulationInfo info)435 void RecordManipulationTypeCounts(ManipulationInfo info) override {}
436
SendOverscrollEventFromImplSide(const gfx::Vector2dF & overscroll_delta,ElementId scroll_latched_element_id)437 void SendOverscrollEventFromImplSide(
438 const gfx::Vector2dF& overscroll_delta,
439 ElementId scroll_latched_element_id) override {}
440
SendScrollEndEventFromImplSide(ElementId scroll_latched_element_id)441 void SendScrollEndEventFromImplSide(
442 ElementId scroll_latched_element_id) override {}
443
RequestNewLayerTreeFrameSink()444 void RequestNewLayerTreeFrameSink() override {
445 test_hooks_->RequestNewLayerTreeFrameSink();
446 }
447
DidInitializeLayerTreeFrameSink()448 void DidInitializeLayerTreeFrameSink() override {
449 test_hooks_->DidInitializeLayerTreeFrameSink();
450 }
451
DidFailToInitializeLayerTreeFrameSink()452 void DidFailToInitializeLayerTreeFrameSink() override {
453 test_hooks_->DidFailToInitializeLayerTreeFrameSink();
454 RequestNewLayerTreeFrameSink();
455 }
456
WillCommit()457 void WillCommit() override { test_hooks_->WillCommit(); }
458
DidCommit(const base::TimeTicks)459 void DidCommit(const base::TimeTicks) override { test_hooks_->DidCommit(); }
460
DidCommitAndDrawFrame()461 void DidCommitAndDrawFrame() override {
462 test_hooks_->DidCommitAndDrawFrame();
463 }
464
DidReceiveCompositorFrameAck()465 void DidReceiveCompositorFrameAck() override {
466 test_hooks_->DidReceiveCompositorFrameAck();
467 }
468
DidScheduleBeginMainFrame()469 void DidScheduleBeginMainFrame() override {
470 test_hooks_->DidScheduleBeginMainFrame();
471 }
DidRunBeginMainFrame()472 void DidRunBeginMainFrame() override { test_hooks_->DidRunBeginMainFrame(); }
473
DidSubmitCompositorFrame()474 void DidSubmitCompositorFrame() override {}
DidLoseLayerTreeFrameSink()475 void DidLoseLayerTreeFrameSink() override {}
RequestScheduleComposite()476 void RequestScheduleComposite() override { test_hooks_->ScheduleComposite(); }
DidCompletePageScaleAnimation()477 void DidCompletePageScaleAnimation() override {}
BeginMainFrameNotExpectedSoon()478 void BeginMainFrameNotExpectedSoon() override {
479 test_hooks_->BeginMainFrameNotExpectedSoon();
480 }
BeginMainFrameNotExpectedUntil(base::TimeTicks time)481 void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override {}
DidPresentCompositorFrame(uint32_t frame_token,const gfx::PresentationFeedback & feedback)482 void DidPresentCompositorFrame(
483 uint32_t frame_token,
484 const gfx::PresentationFeedback& feedback) override {}
485
486 private:
LayerTreeHostClientForTesting(TestHooks * test_hooks)487 explicit LayerTreeHostClientForTesting(TestHooks* test_hooks)
488 : test_hooks_(test_hooks) {}
489
490 TestHooks* test_hooks_;
491 };
492
493 // Adapts LayerTreeHost for test. Injects LayerTreeHostImplForTesting.
494 class LayerTreeHostForTesting : public LayerTreeHost {
495 public:
Create(TestHooks * test_hooks,CompositorMode mode,LayerTreeHostClient * client,LayerTreeHostSchedulingClient * scheduling_client,LayerTreeHostSingleThreadClient * single_thread_client,TaskGraphRunner * task_graph_runner,const LayerTreeSettings & settings,scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,MutatorHost * mutator_host)496 static std::unique_ptr<LayerTreeHostForTesting> Create(
497 TestHooks* test_hooks,
498 CompositorMode mode,
499 LayerTreeHostClient* client,
500 LayerTreeHostSchedulingClient* scheduling_client,
501 LayerTreeHostSingleThreadClient* single_thread_client,
502 TaskGraphRunner* task_graph_runner,
503 const LayerTreeSettings& settings,
504 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
505 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
506 scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
507 MutatorHost* mutator_host) {
508 LayerTreeHost::InitParams params;
509 params.client = client;
510 params.scheduling_client = scheduling_client;
511 params.task_graph_runner = task_graph_runner;
512 params.settings = &settings;
513 params.mutator_host = mutator_host;
514 params.image_worker_task_runner = std::move(image_worker_task_runner);
515 params.ukm_recorder_factory = std::make_unique<TestUkmRecorderFactory>();
516
517 auto layer_tree_host = base::WrapUnique(
518 new LayerTreeHostForTesting(test_hooks, std::move(params), mode));
519 std::unique_ptr<TaskRunnerProvider> task_runner_provider =
520 TaskRunnerProvider::Create(main_task_runner, impl_task_runner);
521 std::unique_ptr<Proxy> proxy;
522 switch (mode) {
523 case CompositorMode::SINGLE_THREADED:
524 proxy = SingleThreadProxy::Create(layer_tree_host.get(),
525 single_thread_client,
526 task_runner_provider.get());
527 break;
528 case CompositorMode::THREADED:
529 DCHECK(impl_task_runner.get());
530 proxy = std::make_unique<ProxyMain>(layer_tree_host.get(),
531 task_runner_provider.get());
532 break;
533 }
534 layer_tree_host->InitializeForTesting(std::move(task_runner_provider),
535 std::move(proxy));
536 return layer_tree_host;
537 }
538
CreateLayerTreeHostImpl(LayerTreeHostImplClient * host_impl_client)539 std::unique_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl(
540 LayerTreeHostImplClient* host_impl_client) override {
541 std::unique_ptr<LayerTreeHostImpl> host_impl =
542 LayerTreeHostImplForTesting::Create(
543 test_hooks_, GetSettings(), host_impl_client, scheduling_client(),
544 GetTaskRunnerProvider(), task_graph_runner(),
545 rendering_stats_instrumentation(), image_worker_task_runner_);
546
547 host_impl->InitializeUkm(ukm_recorder_factory_->CreateRecorder());
548 compositor_delegate_weak_ptr_ = host_impl->AsWeakPtr();
549
550 // Many tests using this class are specifically meant as input tests so
551 // we'll need an input handler. Ideally these would be split out into a
552 // separate test harness.
553 InputHandler::Create(*compositor_delegate_weak_ptr_);
554
555 return host_impl;
556 }
557
SetNeedsCommit()558 void SetNeedsCommit() override {
559 if (!test_started_)
560 return;
561 LayerTreeHost::SetNeedsCommit();
562 }
563
SetNeedsUpdateLayers()564 void SetNeedsUpdateLayers() override {
565 if (!test_started_)
566 return;
567 LayerTreeHost::SetNeedsUpdateLayers();
568 }
569
set_test_started(bool started)570 void set_test_started(bool started) { test_started_ = started; }
571
572 private:
LayerTreeHostForTesting(TestHooks * test_hooks,LayerTreeHost::InitParams params,CompositorMode mode)573 LayerTreeHostForTesting(TestHooks* test_hooks,
574 LayerTreeHost::InitParams params,
575 CompositorMode mode)
576 : LayerTreeHost(std::move(params), mode), test_hooks_(test_hooks) {}
577
578 TestHooks* test_hooks_;
579 bool test_started_ = false;
580 };
581
582 class LayerTreeTestLayerTreeFrameSinkClient
583 : public TestLayerTreeFrameSinkClient {
584 public:
LayerTreeTestLayerTreeFrameSinkClient(TestHooks * hooks)585 explicit LayerTreeTestLayerTreeFrameSinkClient(TestHooks* hooks)
586 : hooks_(hooks) {}
587
588 // TestLayerTreeFrameSinkClient implementation.
589 std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
CreateDisplayController()590 CreateDisplayController() override {
591 return hooks_->CreateDisplayControllerOnThread();
592 }
CreateDisplaySkiaOutputSurface(viz::DisplayCompositorMemoryAndTaskController * display_controller)593 std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface(
594 viz::DisplayCompositorMemoryAndTaskController* display_controller)
595 override {
596 return hooks_->CreateDisplaySkiaOutputSurfaceOnThread(display_controller);
597 }
598
CreateDisplayOutputSurface(scoped_refptr<viz::ContextProvider> compositor_context_provider)599 std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
600 scoped_refptr<viz::ContextProvider> compositor_context_provider)
601 override {
602 return hooks_->CreateDisplayOutputSurfaceOnThread(
603 std::move(compositor_context_provider));
604 }
DisplayReceivedLocalSurfaceId(const viz::LocalSurfaceId & local_surface_id)605 void DisplayReceivedLocalSurfaceId(
606 const viz::LocalSurfaceId& local_surface_id) override {
607 hooks_->DisplayReceivedLocalSurfaceIdOnThread(local_surface_id);
608 }
DisplayReceivedCompositorFrame(const viz::CompositorFrame & frame)609 void DisplayReceivedCompositorFrame(
610 const viz::CompositorFrame& frame) override {
611 hooks_->DisplayReceivedCompositorFrameOnThread(frame);
612 }
DisplayWillDrawAndSwap(bool will_draw_and_swap,viz::AggregatedRenderPassList * render_passes)613 void DisplayWillDrawAndSwap(
614 bool will_draw_and_swap,
615 viz::AggregatedRenderPassList* render_passes) override {
616 hooks_->DisplayWillDrawAndSwapOnThread(will_draw_and_swap, *render_passes);
617 }
DisplayDidDrawAndSwap()618 void DisplayDidDrawAndSwap() override {
619 hooks_->DisplayDidDrawAndSwapOnThread();
620 }
621
622 private:
623 TestHooks* hooks_;
624 };
625
LayerTreeTest(viz::RendererType renderer_type)626 LayerTreeTest::LayerTreeTest(viz::RendererType renderer_type)
627 : renderer_type_(renderer_type),
628 initial_root_bounds_(1, 1),
629 layer_tree_frame_sink_client_(
630 new LayerTreeTestLayerTreeFrameSinkClient(this)) {
631 main_thread_weak_ptr_ = weak_factory_.GetWeakPtr();
632
633 // Tests should timeout quickly unless --cc-layer-tree-test-no-timeout was
634 // specified (for running in a debugger).
635 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
636 if (!command_line->HasSwitch(switches::kCCLayerTreeTestNoTimeout)) {
637 timeout_seconds_ = 10;
638 #if defined(THREAD_SANITIZER)
639 // SwiftShader is a multi-threaded renderer and TSAN takes a lot longer to
640 // run tests when using SwiftShader
641 timeout_seconds_ = 35;
642 #elif defined(OS_WIN) && defined(_DEBUG)
643 // Debug builds on Windows are much slower than on other platforms, possibly
644 // because Windows uses separate debug versions of the C Run-Time Library
645 // for debug builds, whereas other platforms use the same system libraries
646 // for debug and release builds.
647 timeout_seconds_ = 25;
648 #elif defined(MEMORY_SANITIZER)
649 // MSAN is slower than uninstrumented code
650 timeout_seconds_ = 20;
651 #elif BUILDFLAG(CFI_CAST_CHECK) || BUILDFLAG(CFI_ICALL_CHECK) || \
652 BUILDFLAG(CFI_ENFORCEMENT_DIAGNOSTIC) || BUILDFLAG(CFI_ENFORCEMENT_TRAP)
653 // CFI is slow as well.
654 timeout_seconds_ = 20;
655 #elif defined(ADDRESS_SANITIZER) || defined(_DEBUG)
656 // ASAN and Debug builds are slower than release builds, as expected.
657 timeout_seconds_ = 30;
658 #elif defined(USE_OZONE)
659 // Ozone builds go through a slower path than regular Linux builds.
660 // TODO(https://crbug.com/1096425): This special case of having both Ozone
661 // and X11 enabled that will be removed when Ozone is the default. Until
662 // then, we only need to use the slower Ozone timeout when the Ozone
663 // platform is being used. Remove this condition once it is not needed.
664 if (features::IsUsingOzonePlatform())
665 timeout_seconds_ = 30;
666 #endif
667 }
668
669 if (command_line->HasSwitch(switches::kCCLayerTreeTestLongTimeout))
670 timeout_seconds_ = 5 * 60;
671
672 // Check if the graphics backend needs to initialize Vulkan.
673 bool init_vulkan = false;
674 if (renderer_type_ == viz::RendererType::kSkiaVk) {
675 scoped_feature_list_.InitAndEnableFeature(features::kVulkan);
676 init_vulkan = true;
677 } else if (renderer_type_ == viz::RendererType::kSkiaDawn) {
678 scoped_feature_list_.InitAndEnableFeature(features::kSkiaDawn);
679 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
680 init_vulkan = true;
681 #elif defined(OS_WIN)
682 // TODO(sgilhuly): Initialize D3D12 for Windows.
683 #else
684 NOTREACHED();
685 #endif
686 }
687
688 if (init_vulkan) {
689 bool use_gpu = command_line->HasSwitch(::switches::kUseGpuInTests);
690 command_line->AppendSwitchASCII(
691 ::switches::kUseVulkan,
692 use_gpu ? ::switches::kVulkanImplementationNameNative
693 : ::switches::kVulkanImplementationNameSwiftshader);
694 }
695 }
696
~LayerTreeTest()697 LayerTreeTest::~LayerTreeTest() {
698 if (animation_host_)
699 animation_host_->SetMutatorHostClient(nullptr);
700 }
701
EndTest()702 void LayerTreeTest::EndTest() {
703 {
704 base::AutoLock hold(test_ended_lock_);
705 if (ended_)
706 return;
707 ended_ = true;
708 }
709
710 // For the case where we EndTest during BeginTest(), set a flag to indicate
711 // that the test should end the second BeginTest regains control.
712 if (beginning_) {
713 end_when_begin_returns_ = true;
714 } else {
715 main_task_runner_->PostTask(
716 FROM_HERE,
717 base::BindOnce(&LayerTreeTest::RealEndTest, main_thread_weak_ptr_));
718 }
719 }
720
EndTestAfterDelayMs(int delay_milliseconds)721 void LayerTreeTest::EndTestAfterDelayMs(int delay_milliseconds) {
722 main_task_runner_->PostDelayedTask(
723 FROM_HERE, base::BindOnce(&LayerTreeTest::EndTest, main_thread_weak_ptr_),
724 base::TimeDelta::FromMilliseconds(delay_milliseconds));
725 }
726
PostAddNoDamageAnimationToMainThread(Animation * animation_to_receive_animation)727 void LayerTreeTest::PostAddNoDamageAnimationToMainThread(
728 Animation* animation_to_receive_animation) {
729 main_task_runner_->PostTask(
730 FROM_HERE,
731 base::BindOnce(&LayerTreeTest::DispatchAddNoDamageAnimation,
732 main_thread_weak_ptr_,
733 base::Unretained(animation_to_receive_animation), 1.0));
734 }
735
PostAddOpacityAnimationToMainThread(Animation * animation_to_receive_animation)736 void LayerTreeTest::PostAddOpacityAnimationToMainThread(
737 Animation* animation_to_receive_animation) {
738 main_task_runner_->PostTask(
739 FROM_HERE,
740 base::BindOnce(
741 &LayerTreeTest::DispatchAddOpacityAnimation, main_thread_weak_ptr_,
742 base::Unretained(animation_to_receive_animation), 0.000004));
743 }
744
PostAddOpacityAnimationToMainThreadInstantly(Animation * animation_to_receive_animation)745 void LayerTreeTest::PostAddOpacityAnimationToMainThreadInstantly(
746 Animation* animation_to_receive_animation) {
747 main_task_runner_->PostTask(
748 FROM_HERE,
749 base::BindOnce(&LayerTreeTest::DispatchAddOpacityAnimation,
750 main_thread_weak_ptr_,
751 base::Unretained(animation_to_receive_animation), 0.0));
752 }
753
PostAddOpacityAnimationToMainThreadDelayed(Animation * animation_to_receive_animation)754 void LayerTreeTest::PostAddOpacityAnimationToMainThreadDelayed(
755 Animation* animation_to_receive_animation) {
756 main_task_runner_->PostTask(
757 FROM_HERE,
758 base::BindOnce(&LayerTreeTest::DispatchAddOpacityAnimation,
759 main_thread_weak_ptr_,
760 base::Unretained(animation_to_receive_animation), 1.0));
761 }
762
PostSetLocalSurfaceIdToMainThread(const viz::LocalSurfaceId & local_surface_id)763 void LayerTreeTest::PostSetLocalSurfaceIdToMainThread(
764 const viz::LocalSurfaceId& local_surface_id) {
765 main_task_runner_->PostTask(
766 FROM_HERE, base::BindOnce(&LayerTreeTest::DispatchSetLocalSurfaceId,
767 main_thread_weak_ptr_, local_surface_id));
768 }
769
PostRequestNewLocalSurfaceIdToMainThread()770 void LayerTreeTest::PostRequestNewLocalSurfaceIdToMainThread() {
771 main_task_runner_->PostTask(
772 FROM_HERE,
773 base::BindOnce(&LayerTreeTest::DispatchRequestNewLocalSurfaceId,
774 main_thread_weak_ptr_));
775 }
776
PostGetDeferMainFrameUpdateToMainThread(std::unique_ptr<ScopedDeferMainFrameUpdate> * scoped_defer_main_frame_update)777 void LayerTreeTest::PostGetDeferMainFrameUpdateToMainThread(
778 std::unique_ptr<ScopedDeferMainFrameUpdate>*
779 scoped_defer_main_frame_update) {
780 main_task_runner_->PostTask(
781 FROM_HERE,
782 base::BindOnce(&LayerTreeTest::DispatchGetDeferMainFrameUpdate,
783 main_thread_weak_ptr_,
784 base::Unretained(scoped_defer_main_frame_update)));
785 }
786
PostReturnDeferMainFrameUpdateToMainThread(std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update)787 void LayerTreeTest::PostReturnDeferMainFrameUpdateToMainThread(
788 std::unique_ptr<ScopedDeferMainFrameUpdate>
789 scoped_defer_main_frame_update) {
790 main_task_runner_->PostTask(
791 FROM_HERE,
792 base::BindOnce(&LayerTreeTest::DispatchReturnDeferMainFrameUpdate,
793 main_thread_weak_ptr_,
794 std::move(scoped_defer_main_frame_update)));
795 }
796
PostSetNeedsCommitToMainThread()797 void LayerTreeTest::PostSetNeedsCommitToMainThread() {
798 main_task_runner_->PostTask(
799 FROM_HERE, base::BindOnce(&LayerTreeTest::DispatchSetNeedsCommit,
800 main_thread_weak_ptr_));
801 }
802
PostSetNeedsUpdateLayersToMainThread()803 void LayerTreeTest::PostSetNeedsUpdateLayersToMainThread() {
804 main_task_runner_->PostTask(
805 FROM_HERE, base::BindOnce(&LayerTreeTest::DispatchSetNeedsUpdateLayers,
806 main_thread_weak_ptr_));
807 }
808
PostSetNeedsRedrawToMainThread()809 void LayerTreeTest::PostSetNeedsRedrawToMainThread() {
810 main_task_runner_->PostTask(
811 FROM_HERE, base::BindOnce(&LayerTreeTest::DispatchSetNeedsRedraw,
812 main_thread_weak_ptr_));
813 }
814
PostSetNeedsRedrawRectToMainThread(const gfx::Rect & damage_rect)815 void LayerTreeTest::PostSetNeedsRedrawRectToMainThread(
816 const gfx::Rect& damage_rect) {
817 main_task_runner_->PostTask(
818 FROM_HERE, base::BindOnce(&LayerTreeTest::DispatchSetNeedsRedrawRect,
819 main_thread_weak_ptr_, damage_rect));
820 }
821
PostSetVisibleToMainThread(bool visible)822 void LayerTreeTest::PostSetVisibleToMainThread(bool visible) {
823 main_task_runner_->PostTask(FROM_HERE,
824 base::BindOnce(&LayerTreeTest::DispatchSetVisible,
825 main_thread_weak_ptr_, visible));
826 }
827
PostSetNeedsCommitWithForcedRedrawToMainThread()828 void LayerTreeTest::PostSetNeedsCommitWithForcedRedrawToMainThread() {
829 main_task_runner_->PostTask(
830 FROM_HERE,
831 base::BindOnce(&LayerTreeTest::DispatchSetNeedsCommitWithForcedRedraw,
832 main_thread_weak_ptr_));
833 }
834
PostCompositeImmediatelyToMainThread()835 void LayerTreeTest::PostCompositeImmediatelyToMainThread() {
836 main_task_runner_->PostTask(
837 FROM_HERE, base::BindOnce(&LayerTreeTest::DispatchCompositeImmediately,
838 main_thread_weak_ptr_));
839 }
840
PostNextCommitWaitsForActivationToMainThread()841 void LayerTreeTest::PostNextCommitWaitsForActivationToMainThread() {
842 main_task_runner_->PostTask(
843 FROM_HERE,
844 base::BindOnce(&LayerTreeTest::DispatchNextCommitWaitsForActivation,
845 main_thread_weak_ptr_));
846 }
847
848 std::unique_ptr<LayerTreeFrameSink>
ReleaseLayerTreeFrameSinkOnLayerTreeHost()849 LayerTreeTest::ReleaseLayerTreeFrameSinkOnLayerTreeHost() {
850 return layer_tree_host_->ReleaseLayerTreeFrameSink();
851 }
852
SetVisibleOnLayerTreeHost(bool visible)853 void LayerTreeTest::SetVisibleOnLayerTreeHost(bool visible) {
854 layer_tree_host_->SetVisible(visible);
855 }
856
WillBeginTest()857 void LayerTreeTest::WillBeginTest() {
858 SetVisibleOnLayerTreeHost(true);
859 }
860
DoBeginTest()861 void LayerTreeTest::DoBeginTest() {
862 client_ = LayerTreeHostClientForTesting::Create(this);
863
864 DCHECK(!impl_thread_ || impl_thread_->task_runner().get());
865
866 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner =
867 base::ThreadTaskRunnerHandle::Get();
868 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner =
869 impl_thread_ ? impl_thread_->task_runner() : nullptr;
870 LayerTreeHostSchedulingClient* scheduling_client =
871 impl_thread_ ? client_.get() : nullptr;
872
873 animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
874
875 layer_tree_host_ = LayerTreeHostForTesting::Create(
876 this, mode_, client_.get(), scheduling_client, client_.get(),
877 task_graph_runner_.get(), settings_, main_task_runner, impl_task_runner,
878 image_worker_->task_runner(), animation_host_.get());
879 ASSERT_TRUE(layer_tree_host_);
880
881 main_task_runner_ =
882 layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner();
883 impl_task_runner_ =
884 layer_tree_host_->GetTaskRunnerProvider()->ImplThreadTaskRunner();
885 if (!impl_task_runner_) {
886 // For tests, if there's no impl thread, make things easier by just giving
887 // the main thread task runner.
888 impl_task_runner_ = main_task_runner_;
889 }
890
891 if (timeout_seconds_) {
892 timeout_.Reset(
893 base::BindOnce(&LayerTreeTest::Timeout, base::Unretained(this)));
894 main_task_runner_->PostDelayedTask(
895 FROM_HERE, timeout_.callback(),
896 base::TimeDelta::FromSeconds(timeout_seconds_));
897 }
898
899 started_ = true;
900 beginning_ = true;
901 SetupTree();
902 WillBeginTest();
903 if (!skip_allocate_initial_local_surface_id_)
904 GenerateNewLocalSurfaceId();
905 BeginTest();
906 if (!skip_allocate_initial_local_surface_id_) {
907 PostSetLocalSurfaceIdToMainThread(GetCurrentLocalSurfaceId());
908 }
909 beginning_ = false;
910 if (end_when_begin_returns_)
911 RealEndTest();
912
913 // Allow commits to happen once BeginTest() has had a chance to post tasks
914 // so that those tasks will happen before the first commit.
915 if (layer_tree_host_) {
916 static_cast<LayerTreeHostForTesting*>(layer_tree_host_.get())
917 ->set_test_started(true);
918 }
919 }
920
SkipAllocateInitialLocalSurfaceId()921 void LayerTreeTest::SkipAllocateInitialLocalSurfaceId() {
922 skip_allocate_initial_local_surface_id_ = true;
923 }
924
GetCurrentLocalSurfaceId() const925 const viz::LocalSurfaceId& LayerTreeTest::GetCurrentLocalSurfaceId() const {
926 return allocator_.GetCurrentLocalSurfaceId();
927 }
928
GenerateNewLocalSurfaceId()929 void LayerTreeTest::GenerateNewLocalSurfaceId() {
930 allocator_.GenerateId();
931 }
932
SetupTree()933 void LayerTreeTest::SetupTree() {
934 if (!layer_tree_host()->root_layer()) {
935 layer_tree_host()->SetRootLayer(Layer::Create());
936 layer_tree_host()->root_layer()->SetBounds(initial_root_bounds_);
937 }
938
939 Layer* root_layer = layer_tree_host()->root_layer();
940 gfx::Size root_bounds = root_layer->bounds();
941 gfx::Size device_root_bounds =
942 gfx::ScaleToCeiledSize(root_bounds, initial_device_scale_factor_);
943 layer_tree_host()->SetViewportRectAndScale(gfx::Rect(device_root_bounds),
944 initial_device_scale_factor_,
945 viz::LocalSurfaceId());
946 root_layer->SetIsDrawable(true);
947 root_layer->SetHitTestable(true);
948 layer_tree_host()->SetElementIdsForTesting();
949
950 if (layer_tree_host()->IsUsingLayerLists())
951 SetupRootProperties(root_layer);
952 }
953
Timeout()954 void LayerTreeTest::Timeout() {
955 timed_out_ = true;
956 EndTest();
957 }
958
RealEndTest()959 void LayerTreeTest::RealEndTest() {
960 // TODO(mithro): Make this method only end when not inside an impl frame.
961 bool main_frame_will_happen =
962 layer_tree_host_
963 ? layer_tree_host_->proxy()->MainFrameWillHappenForTesting()
964 : false;
965
966 if (main_frame_will_happen && !timed_out_) {
967 main_task_runner_->PostTask(
968 FROM_HERE,
969 base::BindOnce(&LayerTreeTest::RealEndTest, main_thread_weak_ptr_));
970 return;
971 }
972
973 base::RunLoop::QuitCurrentWhenIdleDeprecated();
974 }
975
DispatchAddNoDamageAnimation(Animation * animation_to_receive_animation,double animation_duration)976 void LayerTreeTest::DispatchAddNoDamageAnimation(
977 Animation* animation_to_receive_animation,
978 double animation_duration) {
979 DCHECK(main_task_runner_->BelongsToCurrentThread());
980
981 if (animation_to_receive_animation) {
982 AddOpacityTransitionToAnimation(animation_to_receive_animation,
983 animation_duration, 0, 0, true);
984 }
985 }
986
DispatchAddOpacityAnimation(Animation * animation_to_receive_animation,double animation_duration)987 void LayerTreeTest::DispatchAddOpacityAnimation(
988 Animation* animation_to_receive_animation,
989 double animation_duration) {
990 DCHECK(main_task_runner_->BelongsToCurrentThread());
991
992 if (animation_to_receive_animation) {
993 AddOpacityTransitionToAnimation(animation_to_receive_animation,
994 animation_duration, 0, 0.5, true);
995 }
996 }
997
DispatchSetLocalSurfaceId(const viz::LocalSurfaceId & local_surface_id)998 void LayerTreeTest::DispatchSetLocalSurfaceId(
999 const viz::LocalSurfaceId& local_surface_id) {
1000 DCHECK(main_task_runner_->BelongsToCurrentThread());
1001 if (layer_tree_host_) {
1002 layer_tree_host_->SetLocalSurfaceIdFromParent(local_surface_id);
1003 }
1004 }
1005
DispatchRequestNewLocalSurfaceId()1006 void LayerTreeTest::DispatchRequestNewLocalSurfaceId() {
1007 DCHECK(main_task_runner_->BelongsToCurrentThread());
1008 if (layer_tree_host_)
1009 layer_tree_host_->RequestNewLocalSurfaceId();
1010 }
1011
DispatchGetDeferMainFrameUpdate(std::unique_ptr<ScopedDeferMainFrameUpdate> * scoped_defer_main_frame_update)1012 void LayerTreeTest::DispatchGetDeferMainFrameUpdate(
1013 std::unique_ptr<ScopedDeferMainFrameUpdate>*
1014 scoped_defer_main_frame_update) {
1015 DCHECK(main_task_runner_->BelongsToCurrentThread());
1016 if (layer_tree_host_)
1017 *scoped_defer_main_frame_update = layer_tree_host_->DeferMainFrameUpdate();
1018 }
1019
DispatchReturnDeferMainFrameUpdate(std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update)1020 void LayerTreeTest::DispatchReturnDeferMainFrameUpdate(
1021 std::unique_ptr<ScopedDeferMainFrameUpdate>
1022 scoped_defer_main_frame_update) {
1023 DCHECK(main_task_runner_->BelongsToCurrentThread());
1024 // Just let |scoped_defer_main_frame_update| go out of scope.
1025 }
1026
DispatchSetNeedsCommit()1027 void LayerTreeTest::DispatchSetNeedsCommit() {
1028 DCHECK(main_task_runner_->BelongsToCurrentThread());
1029 if (layer_tree_host_)
1030 layer_tree_host_->SetNeedsCommit();
1031 }
1032
DispatchSetNeedsUpdateLayers()1033 void LayerTreeTest::DispatchSetNeedsUpdateLayers() {
1034 DCHECK(main_task_runner_->BelongsToCurrentThread());
1035 if (layer_tree_host_)
1036 layer_tree_host_->SetNeedsUpdateLayers();
1037 }
1038
DispatchSetNeedsRedraw()1039 void LayerTreeTest::DispatchSetNeedsRedraw() {
1040 DCHECK(main_task_runner_->BelongsToCurrentThread());
1041 if (layer_tree_host_)
1042 DispatchSetNeedsRedrawRect(layer_tree_host_->device_viewport_rect());
1043 }
1044
DispatchSetNeedsRedrawRect(const gfx::Rect & damage_rect)1045 void LayerTreeTest::DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect) {
1046 DCHECK(main_task_runner_->BelongsToCurrentThread());
1047 if (layer_tree_host_)
1048 layer_tree_host_->SetNeedsRedrawRect(damage_rect);
1049 }
1050
DispatchSetVisible(bool visible)1051 void LayerTreeTest::DispatchSetVisible(bool visible) {
1052 DCHECK(main_task_runner_->BelongsToCurrentThread());
1053 if (layer_tree_host_)
1054 SetVisibleOnLayerTreeHost(visible);
1055 }
1056
DispatchSetNeedsCommitWithForcedRedraw()1057 void LayerTreeTest::DispatchSetNeedsCommitWithForcedRedraw() {
1058 DCHECK(main_task_runner_->BelongsToCurrentThread());
1059 if (layer_tree_host_)
1060 layer_tree_host_->SetNeedsCommitWithForcedRedraw();
1061 }
1062
DispatchCompositeImmediately()1063 void LayerTreeTest::DispatchCompositeImmediately() {
1064 DCHECK(main_task_runner_->BelongsToCurrentThread());
1065 if (layer_tree_host_)
1066 layer_tree_host_->CompositeForTest(base::TimeTicks::Now(), true);
1067 }
1068
DispatchNextCommitWaitsForActivation()1069 void LayerTreeTest::DispatchNextCommitWaitsForActivation() {
1070 DCHECK(main_task_runner_->BelongsToCurrentThread());
1071 if (layer_tree_host_)
1072 layer_tree_host_->SetNextCommitWaitsForActivation();
1073 }
1074
RunTest(CompositorMode mode)1075 void LayerTreeTest::RunTest(CompositorMode mode) {
1076 mode_ = mode;
1077 if (mode_ == CompositorMode::THREADED) {
1078 impl_thread_.reset(new base::Thread("Compositor"));
1079 ASSERT_TRUE(impl_thread_->Start());
1080 }
1081
1082 image_worker_ = std::make_unique<base::Thread>("ImageWorker");
1083 ASSERT_TRUE(image_worker_->Start());
1084
1085 gpu_memory_buffer_manager_ =
1086 std::make_unique<viz::TestGpuMemoryBufferManager>();
1087 task_graph_runner_.reset(new TestTaskGraphRunner);
1088
1089 if (mode == CompositorMode::THREADED) {
1090 settings_.commit_to_active_tree = false;
1091 settings_.single_thread_proxy_scheduler = false;
1092 }
1093 // Disable latency recovery to make the scheduler more predictable in its
1094 // actions and less dependent on timings to make decisions.
1095 settings_.enable_impl_latency_recovery = false;
1096 settings_.enable_main_latency_recovery = false;
1097 InitializeSettings(&settings_);
1098
1099 base::ThreadTaskRunnerHandle::Get()->PostTask(
1100 FROM_HERE,
1101 base::BindOnce(&LayerTreeTest::DoBeginTest, base::Unretained(this)));
1102
1103 base::RunLoop().Run();
1104 DestroyLayerTreeHost();
1105
1106 timeout_.Cancel();
1107
1108 ASSERT_FALSE(layer_tree_host_.get());
1109 client_ = nullptr;
1110 if (timed_out_) {
1111 FAIL() << "Test timed out";
1112 return;
1113 }
1114 AfterTest();
1115 }
1116
RequestNewLayerTreeFrameSink()1117 void LayerTreeTest::RequestNewLayerTreeFrameSink() {
1118 scoped_refptr<viz::TestContextProvider> shared_context_provider =
1119 use_software_renderer() ? nullptr : viz::TestContextProvider::Create();
1120 scoped_refptr<viz::TestContextProvider> worker_context_provider =
1121 use_software_renderer() ? nullptr
1122 : viz::TestContextProvider::CreateWorker();
1123
1124 if (!use_software_renderer()) {
1125 SetUpUnboundContextProviders(shared_context_provider.get(),
1126 worker_context_provider.get());
1127 }
1128
1129 viz::RendererSettings renderer_settings;
1130 // Spend less time waiting for BeginFrame because the output is
1131 // mocked out.
1132 constexpr double refresh_rate = 200.0;
1133 renderer_settings.use_skia_renderer = use_skia_renderer();
1134 auto layer_tree_frame_sink = CreateLayerTreeFrameSink(
1135 renderer_settings, refresh_rate, std::move(shared_context_provider),
1136 std::move(worker_context_provider));
1137 layer_tree_frame_sink->SetClient(layer_tree_frame_sink_client_.get());
1138 layer_tree_host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
1139 }
1140
SetUpUnboundContextProviders(viz::TestContextProvider * context_provider,viz::TestContextProvider * worker_context_provider)1141 void LayerTreeTest::SetUpUnboundContextProviders(
1142 viz::TestContextProvider* context_provider,
1143 viz::TestContextProvider* worker_context_provider) {}
1144
CreateLayerTreeFrameSink(const viz::RendererSettings & renderer_settings,double refresh_rate,scoped_refptr<viz::ContextProvider> compositor_context_provider,scoped_refptr<viz::RasterContextProvider> worker_context_provider)1145 std::unique_ptr<TestLayerTreeFrameSink> LayerTreeTest::CreateLayerTreeFrameSink(
1146 const viz::RendererSettings& renderer_settings,
1147 double refresh_rate,
1148 scoped_refptr<viz::ContextProvider> compositor_context_provider,
1149 scoped_refptr<viz::RasterContextProvider> worker_context_provider) {
1150 constexpr bool disable_display_vsync = false;
1151 bool synchronous_composite =
1152 !HasImplThread() &&
1153 !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
1154
1155 DCHECK(
1156 !synchronous_composite ||
1157 !layer_tree_host()->GetSettings().using_synchronous_renderer_compositor);
1158 if (layer_tree_host()->GetSettings().using_synchronous_renderer_compositor) {
1159 return std::make_unique<SynchronousLayerTreeFrameSink>(
1160 compositor_context_provider, std::move(worker_context_provider),
1161 gpu_memory_buffer_manager(), renderer_settings, &debug_settings_,
1162 impl_task_runner_, refresh_rate, begin_frame_source_,
1163 use_software_renderer());
1164 }
1165
1166 return std::make_unique<TestLayerTreeFrameSink>(
1167 compositor_context_provider, std::move(worker_context_provider),
1168 gpu_memory_buffer_manager(), renderer_settings, &debug_settings_,
1169 impl_task_runner_, synchronous_composite, disable_display_vsync,
1170 refresh_rate, begin_frame_source_);
1171 }
1172
1173 std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
CreateDisplayControllerOnThread()1174 LayerTreeTest::CreateDisplayControllerOnThread() {
1175 // In this implementation, none of the output surface has a real gpu thread,
1176 // and there is no overlay support.
1177 return nullptr;
1178 }
1179
1180 std::unique_ptr<viz::SkiaOutputSurface>
CreateDisplaySkiaOutputSurfaceOnThread(viz::DisplayCompositorMemoryAndTaskController *)1181 LayerTreeTest::CreateDisplaySkiaOutputSurfaceOnThread(
1182 viz::DisplayCompositorMemoryAndTaskController*) {
1183 return viz::FakeSkiaOutputSurface::Create3d();
1184 }
1185
1186 std::unique_ptr<viz::OutputSurface>
CreateDisplayOutputSurfaceOnThread(scoped_refptr<viz::ContextProvider> compositor_context_provider)1187 LayerTreeTest::CreateDisplayOutputSurfaceOnThread(
1188 scoped_refptr<viz::ContextProvider> compositor_context_provider) {
1189 // By default the Display shares a context with the LayerTreeHostImpl.
1190 if (use_software_renderer()) {
1191 return viz::FakeOutputSurface::CreateSoftware(
1192 std::make_unique<viz::SoftwareOutputDevice>());
1193 }
1194 return viz::FakeOutputSurface::Create3d(
1195 std::move(compositor_context_provider));
1196 }
1197
DestroyLayerTreeHost()1198 void LayerTreeTest::DestroyLayerTreeHost() {
1199 if (layer_tree_host_ && layer_tree_host_->root_layer())
1200 layer_tree_host_->root_layer()->SetLayerTreeHost(nullptr);
1201 layer_tree_host_ = nullptr;
1202 }
1203
task_runner_provider() const1204 TaskRunnerProvider* LayerTreeTest::task_runner_provider() const {
1205 LayerTreeHost* host = layer_tree_host_.get();
1206
1207 // If this fails, the test has ended and there is no task runners to find
1208 // anymore.
1209 DCHECK(host);
1210
1211 return host->GetTaskRunnerProvider();
1212 }
1213
layer_tree_host() const1214 LayerTreeHost* LayerTreeTest::layer_tree_host() const {
1215 DCHECK(task_runner_provider()->IsMainThread() ||
1216 task_runner_provider()->IsMainThreadBlocked());
1217 return layer_tree_host_.get();
1218 }
1219
proxy()1220 Proxy* LayerTreeTest::proxy() {
1221 return layer_tree_host() ? layer_tree_host()->proxy() : nullptr;
1222 }
1223
1224 } // namespace cc
1225