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