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 #ifndef CC_TREES_SINGLE_THREAD_PROXY_H_
6 #define CC_TREES_SINGLE_THREAD_PROXY_H_
7 
8 #include <limits>
9 #include <memory>
10 #include <vector>
11 
12 #include "base/cancelable_callback.h"
13 #include "base/time/time.h"
14 #include "cc/scheduler/scheduler.h"
15 #include "cc/trees/layer_tree_host_impl.h"
16 #include "cc/trees/proxy.h"
17 #include "cc/trees/task_runner_provider.h"
18 #include "components/viz/common/frame_sinks/begin_frame_args.h"
19 
20 namespace viz {
21 class BeginFrameSource;
22 struct FrameTimingDetails;
23 }
24 
25 namespace cc {
26 
27 class LayerTreeHost;
28 class LayerTreeHostSingleThreadClient;
29 class RenderFrameMetadataObserver;
30 
31 class CC_EXPORT SingleThreadProxy : public Proxy,
32                                     LayerTreeHostImplClient,
33                                     public SchedulerClient {
34  public:
35   static std::unique_ptr<Proxy> Create(
36       LayerTreeHost* layer_tree_host,
37       LayerTreeHostSingleThreadClient* client,
38       TaskRunnerProvider* task_runner_provider);
39   SingleThreadProxy(const SingleThreadProxy&) = delete;
40   ~SingleThreadProxy() override;
41 
42   SingleThreadProxy& operator=(const SingleThreadProxy&) = delete;
43 
44   // Proxy implementation
45   bool IsStarted() const override;
46   void SetLayerTreeFrameSink(
47       LayerTreeFrameSink* layer_tree_frame_sink) override;
48   void ReleaseLayerTreeFrameSink() override;
49   void SetVisible(bool visible) override;
50   void SetNeedsAnimate() override;
51   void SetNeedsUpdateLayers() override;
52   void SetNeedsCommit() override;
53   void SetNeedsRedraw(const gfx::Rect& damage_rect) override;
54   void SetNextCommitWaitsForActivation() override;
55   bool RequestedAnimatePending() override;
56   void SetDeferMainFrameUpdate(bool defer_main_frame_update) override;
57   void StartDeferringCommits(base::TimeDelta timeout) override;
58   void StopDeferringCommits(PaintHoldingCommitTrigger) override;
59   bool CommitRequested() const override;
60   void Start() override;
61   void Stop() override;
62   void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) override;
63   void SetPaintWorkletLayerPainter(
64       std::unique_ptr<PaintWorkletLayerPainter> painter) override;
65   bool SupportsImplScrolling() const override;
66   bool MainFrameWillHappenForTesting() override;
SetSourceURL(ukm::SourceId source_id,const GURL & url)67   void SetSourceURL(ukm::SourceId source_id, const GURL& url) override {
68     // Single-threaded mode is only for browser compositing and for renderers in
69     // layout tests. This will still get called in the latter case, but we don't
70     // need to record UKM in that case.
71   }
SetUkmSmoothnessDestination(base::WritableSharedMemoryMapping ukm_smoothness_data)72   void SetUkmSmoothnessDestination(
73       base::WritableSharedMemoryMapping ukm_smoothness_data) override {}
74   void ClearHistory() override;
75   void SetRenderFrameObserver(
76       std::unique_ptr<RenderFrameMetadataObserver> observer) override;
SetEnableFrameRateThrottling(bool enable_frame_rate_throttling)77   void SetEnableFrameRateThrottling(
78       bool enable_frame_rate_throttling) override {}
79 
80   void UpdateBrowserControlsState(BrowserControlsState constraints,
81                                   BrowserControlsState current,
82                                   bool animate) override;
83 
84   // SchedulerClient implementation
85   bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override;
86   void DidFinishImplFrame(
87       const viz::BeginFrameArgs& last_activated_args) override;
88   void DidNotProduceFrame(const viz::BeginFrameAck& ack,
89                           FrameSkippedReason reason) override;
90   void WillNotReceiveBeginFrame() override;
91   void ScheduledActionSendBeginMainFrame(
92       const viz::BeginFrameArgs& args) override;
93   DrawResult ScheduledActionDrawIfPossible() override;
94   DrawResult ScheduledActionDrawForced() override;
95   void ScheduledActionCommit() override;
96   void ScheduledActionActivateSyncTree() override;
97   void ScheduledActionBeginLayerTreeFrameSinkCreation() override;
98   void ScheduledActionPrepareTiles() override;
99   void ScheduledActionInvalidateLayerTreeFrameSink(bool needs_redraw) override;
100   void ScheduledActionPerformImplSideInvalidation() override;
101   void SendBeginMainFrameNotExpectedSoon() override;
102   void ScheduledActionBeginMainFrameNotExpectedUntil(
103       base::TimeTicks time) override;
104   void FrameIntervalUpdated(base::TimeDelta interval) override;
105   bool HasCustomPropertyAnimations() const override;
106 
107   // LayerTreeHostImplClient implementation
108   void DidLoseLayerTreeFrameSinkOnImplThread() override;
109   void SetBeginFrameSource(viz::BeginFrameSource* source) override;
110   void DidReceiveCompositorFrameAckOnImplThread() override;
111   void OnCanDrawStateChanged(bool can_draw) override;
112   void NotifyReadyToActivate() override;
113   void NotifyReadyToDraw() override;
114   void SetNeedsRedrawOnImplThread() override;
115   void SetNeedsOneBeginImplFrameOnImplThread() override;
116   void SetNeedsPrepareTilesOnImplThread() override;
117   void SetNeedsCommitOnImplThread() override;
118   void SetVideoNeedsBeginFrames(bool needs_begin_frames) override;
119   bool IsInsideDraw() override;
120   bool IsBeginMainFrameExpected() override;
RenewTreePriority()121   void RenewTreePriority() override {}
PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,base::TimeDelta delay)122   void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
123                                             base::TimeDelta delay) override {}
124   void DidActivateSyncTree() override;
125   void WillPrepareTiles() override;
126   void DidPrepareTiles() override;
127   void DidCompletePageScaleAnimationOnImplThread() override;
128   void OnDrawForLayerTreeFrameSink(bool resourceless_software_draw,
129                                    bool skip_draw) override;
130   void NeedsImplSideInvalidation(bool needs_first_draw_on_activation) override;
131   void RequestBeginMainFrameNotExpected(bool new_state) override;
132   void NotifyImageDecodeRequestFinished() override;
133   void DidPresentCompositorFrameOnImplThread(
134       uint32_t frame_token,
135       std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
136       const viz::FrameTimingDetails& details) override;
137   void NotifyAnimationWorkletStateChange(
138       AnimationWorkletMutationState state,
139       ElementListType element_list_type) override;
140   void NotifyPaintWorkletStateChange(
141       Scheduler::PaintWorkletState state) override;
142   void NotifyThroughputTrackerResults(CustomTrackerResults results) override;
143   bool IsInSynchronousComposite() const override;
144 
145   void RequestNewLayerTreeFrameSink();
146 
DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay,base::TimeTicks first_scroll_timestamp)147   void DidObserveFirstScrollDelay(
148       base::TimeDelta first_scroll_delay,
149       base::TimeTicks first_scroll_timestamp) override {
150     // Single-threaded mode is only for browser compositing and for renderers in
151     // layout tests. This will still get called in the latter case, but we don't
152     // need to record UKM in that case.
153   }
154 
155   // Called by the legacy path where RenderWidget does the scheduling.
156   // Rasterization of tiles is only performed when |raster| is true.
157   void CompositeImmediatelyForTest(base::TimeTicks frame_begin_time,
158                                    bool raster);
159 
160  protected:
161   SingleThreadProxy(LayerTreeHost* layer_tree_host,
162                     LayerTreeHostSingleThreadClient* client,
163                     TaskRunnerProvider* task_runner_provider);
164 
165  private:
166   void BeginMainFrame(const viz::BeginFrameArgs& begin_frame_args);
167   void BeginMainFrameAbortedOnImplThread(CommitEarlyOutReason reason);
168   void DoBeginMainFrame(const viz::BeginFrameArgs& begin_frame_args);
169   void DoPainting();
170   void DoCommit(const viz::BeginFrameArgs& commit_args);
171   DrawResult DoComposite(LayerTreeHostImpl::FrameData* frame);
172   void DoSwap();
173   void DidCommitAndDrawFrame();
174   void CommitComplete();
175 
176   bool ShouldComposite() const;
177   void ScheduleRequestNewLayerTreeFrameSink();
178   void IssueImageDecodeFinishedCallbacks();
179 
180   void DidReceiveCompositorFrameAck();
181 
182   // Accessed on main thread only.
183   LayerTreeHost* layer_tree_host_;
184   LayerTreeHostSingleThreadClient* single_thread_client_;
185 
186   TaskRunnerProvider* task_runner_provider_;
187 
188   // Used on the Thread, but checked on main thread during
189   // initialization/shutdown.
190   std::unique_ptr<LayerTreeHostImpl> host_impl_;
191 
192   // Accessed from both threads.
193   std::unique_ptr<Scheduler> scheduler_on_impl_thread_;
194 
195   // Only used when defer_commits_ is active and must be set in such cases.
196   base::TimeTicks commits_restart_time_;
197 
198   bool next_frame_is_newly_committed_frame_;
199 
200 #if DCHECK_IS_ON()
201   bool inside_impl_frame_;
202 #endif
203   bool inside_draw_;
204   bool defer_main_frame_update_;
205   bool defer_commits_;
206   bool animate_requested_;
207   bool update_layers_requested_;
208   bool commit_requested_;
209   bool inside_synchronous_composite_;
210   bool needs_impl_frame_;
211 
212   // True if a request to the LayerTreeHostClient to create an output surface
213   // is still outstanding.
214   bool layer_tree_frame_sink_creation_requested_;
215   // When output surface is lost, is set to true until a new output surface is
216   // initialized.
217   bool layer_tree_frame_sink_lost_;
218 
219   // A number that kept incrementing in CompositeImmediately, which indicates a
220   // new impl frame.
221   uint64_t begin_frame_sequence_number_ = 1u;
222 
223   // This is the callback for the scheduled RequestNewLayerTreeFrameSink.
224   base::CancelableOnceClosure layer_tree_frame_sink_creation_callback_;
225 
226   base::WeakPtr<SingleThreadProxy> frame_sink_bound_weak_ptr_;
227 
228   // WeakPtrs generated by this factory will be invalidated when
229   // LayerTreeFrameSink is released.
230   base::WeakPtrFactory<SingleThreadProxy> frame_sink_bound_weak_factory_{this};
231 
232   base::WeakPtrFactory<SingleThreadProxy> weak_factory_{this};
233 };
234 
235 // For use in the single-threaded case. In debug builds, it pretends that the
236 // code is running on the impl thread to satisfy assertion checks.
237 class DebugScopedSetImplThread {
238  public:
239 #if DCHECK_IS_ON()
DebugScopedSetImplThread(TaskRunnerProvider * task_runner_provider)240   explicit DebugScopedSetImplThread(TaskRunnerProvider* task_runner_provider)
241       : task_runner_provider_(task_runner_provider) {
242     previous_value_ = task_runner_provider_->impl_thread_is_overridden_;
243     task_runner_provider_->SetCurrentThreadIsImplThread(true);
244   }
245 #else
246   explicit DebugScopedSetImplThread(TaskRunnerProvider* task_runner_provider) {}
247 #endif
248 
249   DebugScopedSetImplThread(const DebugScopedSetImplThread&) = delete;
250 
~DebugScopedSetImplThread()251   ~DebugScopedSetImplThread() {
252 #if DCHECK_IS_ON()
253     task_runner_provider_->SetCurrentThreadIsImplThread(previous_value_);
254 #endif
255   }
256 
257   DebugScopedSetImplThread& operator=(const DebugScopedSetImplThread&) = delete;
258 
259 #if DCHECK_IS_ON()
260 
261  private:
262   bool previous_value_;
263   TaskRunnerProvider* task_runner_provider_;
264 #endif
265 };
266 
267 // For use in the single-threaded case. In debug builds, it pretends that the
268 // code is running on the main thread to satisfy assertion checks.
269 class DebugScopedSetMainThread {
270  public:
271 #if DCHECK_IS_ON()
DebugScopedSetMainThread(TaskRunnerProvider * task_runner_provider)272   explicit DebugScopedSetMainThread(TaskRunnerProvider* task_runner_provider)
273       : task_runner_provider_(task_runner_provider) {
274     previous_value_ = task_runner_provider_->impl_thread_is_overridden_;
275     task_runner_provider_->SetCurrentThreadIsImplThread(false);
276   }
277 #else
278   explicit DebugScopedSetMainThread(TaskRunnerProvider* task_runner_provider) {}
279 #endif
280 
281   DebugScopedSetMainThread(const DebugScopedSetMainThread&) = delete;
282 
~DebugScopedSetMainThread()283   ~DebugScopedSetMainThread() {
284 #if DCHECK_IS_ON()
285     task_runner_provider_->SetCurrentThreadIsImplThread(previous_value_);
286 #endif
287   }
288 
289   DebugScopedSetMainThread& operator=(const DebugScopedSetMainThread&) = delete;
290 
291 #if DCHECK_IS_ON()
292 
293  private:
294   bool previous_value_;
295   TaskRunnerProvider* task_runner_provider_;
296 #endif
297 };
298 
299 // For use in the single-threaded case. In debug builds, it pretends that the
300 // code is running on the impl thread and that the main thread is blocked to
301 // satisfy assertion checks
302 class DebugScopedSetImplThreadAndMainThreadBlocked {
303  public:
DebugScopedSetImplThreadAndMainThreadBlocked(TaskRunnerProvider * task_runner_provider)304   explicit DebugScopedSetImplThreadAndMainThreadBlocked(
305       TaskRunnerProvider* task_runner_provider)
306       : impl_thread_(task_runner_provider),
307         main_thread_blocked_(task_runner_provider) {}
308   DebugScopedSetImplThreadAndMainThreadBlocked(
309       const DebugScopedSetImplThreadAndMainThreadBlocked&) = delete;
310   DebugScopedSetImplThreadAndMainThreadBlocked& operator=(
311       const DebugScopedSetImplThreadAndMainThreadBlocked&) = delete;
312 
313  private:
314   DebugScopedSetImplThread impl_thread_;
315   DebugScopedSetMainThreadBlocked main_thread_blocked_;
316 };
317 
318 }  // namespace cc
319 
320 #endif  // CC_TREES_SINGLE_THREAD_PROXY_H_
321