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