blob: 2a235b6dd900cb2f7f4550e6d6318eafe34a007e [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// 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
[email protected]556fd292013-03-18 08:03:045#include "cc/trees/single_thread_proxy.h"
[email protected]94f206c12012-08-25 00:09:146
[email protected]74d9063c2013-01-18 03:14:477#include "base/auto_reset.h"
Sebastien Marchand6d0558fd2019-01-25 16:49:378#include "base/bind.h"
danakj60bc3bc2016-04-09 00:24:489#include "base/memory/ptr_util.h"
primianoc06e2382015-01-28 04:21:4910#include "base/trace_event/trace_event.h"
chrishtr82b5d9502017-03-20 18:25:3311#include "cc/base/devtools_instrumentation.h"
12#include "cc/benchmarks/benchmark_instrumentation.h"
David Bokan1e37ebf2018-10-16 13:53:3713#include "cc/input/browser_controls_offset_manager.h"
behdad5fb48ea22019-08-12 18:15:3614#include "cc/metrics/compositor_timing_history.h"
Xida Chend5ee5052019-01-03 13:27:5115#include "cc/paint/paint_worklet_layer_painter.h"
khushalsagar8ec07402016-09-10 03:13:1916#include "cc/resources/ui_resource_manager.h"
mithrof7a21502014-12-17 03:24:4817#include "cc/scheduler/commit_earlyout_reason.h"
briandersonc9f50352015-06-24 03:38:5818#include "cc/scheduler/scheduler.h"
Brian Anderson242b9b02017-12-06 21:06:2619#include "cc/trees/latency_info_swap_promise.h"
danakjba65a0912017-09-21 16:38:4220#include "cc/trees/layer_tree_frame_sink.h"
khushalsagare0e4486e2017-01-25 03:15:0321#include "cc/trees/layer_tree_host.h"
[email protected]943528e2013-11-07 05:01:3222#include "cc/trees/layer_tree_host_single_thread_client.h"
[email protected]556fd292013-03-18 08:03:0423#include "cc/trees/layer_tree_impl.h"
loysoc601b7b82016-11-10 02:56:4424#include "cc/trees/mutator_host.h"
jonrossa2ff4f82018-02-16 17:27:4625#include "cc/trees/render_frame_metadata_observer.h"
[email protected]aeeedad2014-08-22 18:16:2226#include "cc/trees/scoped_abort_remaining_swap_promises.h"
Xianzhu Wang66e13e02019-09-18 20:39:1227#include "cc/trees/scroll_and_scale_set.h"
Fady Samuelc645ffe2017-07-24 17:28:2028#include "components/viz/common/frame_sinks/delay_based_time_source.h"
Nathan Zabriskie12b7d892019-09-11 19:16:1729#include "components/viz/common/frame_timing_details.h"
Xu Xing32549162017-07-17 22:25:4330#include "components/viz/common/gpu/context_provider.h"
[email protected]94f206c12012-08-25 00:09:1431
[email protected]9c88e562012-09-14 22:21:3032namespace cc {
[email protected]94f206c12012-08-25 00:09:1433
danakj60bc3bc2016-04-09 00:24:4834std::unique_ptr<Proxy> SingleThreadProxy::Create(
khushalsagare0e4486e2017-01-25 03:15:0335 LayerTreeHost* layer_tree_host,
[email protected]27e6a212014-07-18 15:51:2736 LayerTreeHostSingleThreadClient* client,
khushalsagar767dd522015-12-16 05:14:0537 TaskRunnerProvider* task_runner_provider) {
danakj60bc3bc2016-04-09 00:24:4838 return base::WrapUnique(
khushalsagar767dd522015-12-16 05:14:0539 new SingleThreadProxy(layer_tree_host, client, task_runner_provider));
[email protected]94f206c12012-08-25 00:09:1440}
41
khushalsagare0e4486e2017-01-25 03:15:0342SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
khushalsagar767dd522015-12-16 05:14:0543 LayerTreeHostSingleThreadClient* client,
44 TaskRunnerProvider* task_runner_provider)
khushalsagarb7db1fe2015-11-12 00:51:2745 : layer_tree_host_(layer_tree_host),
danakj6c872fc02016-10-22 04:29:4946 single_thread_client_(client),
khushalsagarb7db1fe2015-11-12 00:51:2747 task_runner_provider_(task_runner_provider),
[email protected]a8a049c2013-03-11 23:27:0648 next_frame_is_newly_committed_frame_(false),
mithro51693e382015-05-07 23:52:4149#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:0250 inside_impl_frame_(false),
mithro51693e382015-05-07 23:52:4151#endif
[email protected]aeeedad2014-08-22 18:16:2252 inside_draw_(false),
Stephen Chenney6d3f5ce2018-11-14 02:08:0553 defer_main_frame_update_(false),
Stephen Chenney1b197822019-09-04 14:25:4854 defer_commits_(false),
brianderson49e101d22015-04-29 00:05:3355 animate_requested_(false),
[email protected]aeeedad2014-08-22 18:16:2256 commit_requested_(false),
jbauman399aec1a2014-10-25 02:33:3257 inside_synchronous_composite_(false),
David Bokaneaa5cc82018-10-12 15:50:4058 needs_impl_frame_(false),
danakjc7afae52017-06-20 21:12:4159 layer_tree_frame_sink_creation_requested_(false),
Jeremy Roman31f36b72019-07-09 16:33:4160 layer_tree_frame_sink_lost_(true) {
[email protected]a8a049c2013-03-11 23:27:0661 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
khushalsagarb7db1fe2015-11-12 00:51:2762 DCHECK(task_runner_provider_);
63 DCHECK(task_runner_provider_->IsMainThread());
[email protected]a8a049c2013-03-11 23:27:0664 DCHECK(layer_tree_host);
khushalsagar767dd522015-12-16 05:14:0565}
danakjfcdaba122015-04-24 21:41:5266
enne2b0ad682016-09-21 01:44:4767void SingleThreadProxy::Start() {
khushalsagar767dd522015-12-16 05:14:0568 DebugScopedSetImplThread impl(task_runner_provider_);
khushalsagar767dd522015-12-16 05:14:0569
khushalsagarcebe4942016-09-07 23:27:0170 const LayerTreeSettings& settings = layer_tree_host_->GetSettings();
khushalsagar6dc91d02017-02-28 05:10:0771 DCHECK(settings.single_thread_proxy_scheduler ||
72 !settings.enable_checker_imaging)
73 << "Checker-imaging is not supported in synchronous single threaded mode";
Kaan Alsana27ebc152019-04-17 15:56:5874 host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
khushalsagarcebe4942016-09-07 23:27:0175 if (settings.single_thread_proxy_scheduler && !scheduler_on_impl_thread_) {
76 SchedulerSettings scheduler_settings(settings.ToSchedulerSettings());
Sadrul Habib Chowdhury2f79f002019-07-19 01:07:3677 scheduler_settings.commit_to_active_tree = true;
briandersonc9f50352015-06-24 03:38:5878
danakj60bc3bc2016-04-09 00:24:4879 std::unique_ptr<CompositorTimingHistory> compositor_timing_history(
briandersonc9f50352015-06-24 03:38:5880 new CompositorTimingHistory(
briandersonbb917dd2016-02-20 05:21:1481 scheduler_settings.using_synchronous_renderer_compositor,
briandersonc68220f2015-07-20 20:08:3582 CompositorTimingHistory::BROWSER_UMA,
Kaan Alsana27ebc152019-04-17 15:56:5883 layer_tree_host_->rendering_stats_instrumentation(),
84 host_impl_->compositor_frame_reporting_controller()));
enne2b0ad682016-09-21 01:44:4785 scheduler_on_impl_thread_.reset(
86 new Scheduler(this, scheduler_settings, layer_tree_host_->GetId(),
87 task_runner_provider_->MainThreadTaskRunner(),
88 std::move(compositor_timing_history)));
danakjfcdaba122015-04-24 21:41:5289 }
[email protected]a8a049c2013-03-11 23:27:0690}
91
92SingleThreadProxy::~SingleThreadProxy() {
93 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
khushalsagarb7db1fe2015-11-12 00:51:2794 DCHECK(task_runner_provider_->IsMainThread());
[email protected]04049fc2013-05-01 03:13:2095 // Make sure Stop() got called or never Started.
Walter Kormanaa326e42017-08-22 23:04:4396 DCHECK(!host_impl_);
[email protected]a8a049c2013-03-11 23:27:0697}
98
[email protected]a8a049c2013-03-11 23:27:0699bool SingleThreadProxy::IsStarted() const {
khushalsagarb7db1fe2015-11-12 00:51:27100 DCHECK(task_runner_provider_->IsMainThread());
Walter Kormanaa326e42017-08-22 23:04:43101 return !!host_impl_;
[email protected]94f206c12012-08-25 00:09:14102}
103
[email protected]a8a049c2013-03-11 23:27:06104void SingleThreadProxy::SetVisible(bool visible) {
mithro46adf5a2014-11-19 14:52:40105 TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible);
khushalsagarb7db1fe2015-11-12 00:51:27106 DebugScopedSetImplThread impl(task_runner_provider_);
sunnypsc3f6e0c2015-07-25 01:00:59107
Walter Kormanaa326e42017-08-22 23:04:43108 host_impl_->SetVisible(visible);
sunnypsc3f6e0c2015-07-25 01:00:59109
[email protected]aeeedad2014-08-22 18:16:22110 if (scheduler_on_impl_thread_)
Walter Kormanaa326e42017-08-22 23:04:43111 scheduler_on_impl_thread_->SetVisible(host_impl_->visible());
[email protected]a8a049c2013-03-11 23:27:06112}
113
danakjc7afae52017-06-20 21:12:41114void SingleThreadProxy::RequestNewLayerTreeFrameSink() {
khushalsagarb7db1fe2015-11-12 00:51:27115 DCHECK(task_runner_provider_->IsMainThread());
danakjc7afae52017-06-20 21:12:41116 layer_tree_frame_sink_creation_callback_.Cancel();
117 if (layer_tree_frame_sink_creation_requested_)
jbauman8ab0f9e2014-10-15 02:30:34118 return;
danakjc7afae52017-06-20 21:12:41119 layer_tree_frame_sink_creation_requested_ = true;
120 layer_tree_host_->RequestNewLayerTreeFrameSink();
enne2097cab2014-09-25 20:16:31121}
[email protected]94f206c12012-08-25 00:09:14122
danakjc7afae52017-06-20 21:12:41123void SingleThreadProxy::ReleaseLayerTreeFrameSink() {
124 layer_tree_frame_sink_lost_ = true;
samans44b6dfc2017-04-19 16:50:53125 frame_sink_bound_weak_factory_.InvalidateWeakPtrs();
sohan.jyoti3a33d872015-09-18 22:32:55126 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41127 scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink();
Walter Kormanaa326e42017-08-22 23:04:43128 return host_impl_->ReleaseLayerTreeFrameSink();
sohan.jyoti3a33d872015-09-18 22:32:55129}
130
danakjc7afae52017-06-20 21:12:41131void SingleThreadProxy::SetLayerTreeFrameSink(
132 LayerTreeFrameSink* layer_tree_frame_sink) {
khushalsagarb7db1fe2015-11-12 00:51:27133 DCHECK(task_runner_provider_->IsMainThread());
danakjc7afae52017-06-20 21:12:41134 DCHECK(layer_tree_frame_sink_creation_requested_);
[email protected]da8e3b72b2014-04-25 02:33:45135
enne7f8fdde2014-12-10 21:32:09136 bool success;
137 {
khushalsagarb7db1fe2015-11-12 00:51:27138 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
139 DebugScopedSetImplThread impl(task_runner_provider_);
Xu Xing31616b92018-06-28 00:24:27140 success = host_impl_->InitializeFrameSink(layer_tree_frame_sink);
[email protected]04049fc2013-05-01 03:13:20141 }
142
[email protected]aeeedad2014-08-22 18:16:22143 if (success) {
samans44b6dfc2017-04-19 16:50:53144 frame_sink_bound_weak_ptr_ = frame_sink_bound_weak_factory_.GetWeakPtr();
danakjc7afae52017-06-20 21:12:41145 layer_tree_host_->DidInitializeLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22146 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41147 scheduler_on_impl_thread_->DidCreateAndInitializeLayerTreeFrameSink();
jbauman399aec1a2014-10-25 02:33:32148 else if (!inside_synchronous_composite_)
149 SetNeedsCommit();
danakjc7afae52017-06-20 21:12:41150 layer_tree_frame_sink_creation_requested_ = false;
151 layer_tree_frame_sink_lost_ = false;
enne7f8fdde2014-12-10 21:32:09152 } else {
danakjc7afae52017-06-20 21:12:41153 // DidFailToInitializeLayerTreeFrameSink is treated as a
154 // RequestNewLayerTreeFrameSink, and so
155 // layer_tree_frame_sink_creation_requested remains true.
156 layer_tree_host_->DidFailToInitializeLayerTreeFrameSink();
[email protected]04049fc2013-05-01 03:13:20157 }
[email protected]94f206c12012-08-25 00:09:14158}
159
[email protected]8b9e52b2014-01-17 16:35:31160void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20161 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
khushalsagarb7db1fe2015-11-12 00:51:27162 DCHECK(task_runner_provider_->IsMainThread());
brianderson49e101d22015-04-29 00:05:33163 if (animate_requested_)
164 return;
165 animate_requested_ = true;
khushalsagarb7db1fe2015-11-12 00:51:27166 DebugScopedSetImplThread impl(task_runner_provider_);
brianderson49e101d22015-04-29 00:05:33167 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01168 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]c5134172013-12-11 06:19:48169}
170
[email protected]8b9e52b2014-01-17 16:35:31171void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20172 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
khushalsagarb7db1fe2015-11-12 00:51:27173 DCHECK(task_runner_provider_->IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22174 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31175}
176
enne98f3a6c2014-10-09 20:09:44177void SingleThreadProxy::DoCommit() {
[email protected]ccc08dc2014-01-30 07:33:20178 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
khushalsagarb7db1fe2015-11-12 00:51:27179 DCHECK(task_runner_provider_->IsMainThread());
enne98f3a6c2014-10-09 20:09:44180
[email protected]aeeedad2014-08-22 18:16:22181 layer_tree_host_->WillCommit();
caseq7d2f4c92015-02-04 16:43:27182 devtools_instrumentation::ScopedCommitTrace commit_task(
khushalsagarcebe4942016-09-07 23:27:01183 layer_tree_host_->GetId());
[email protected]aeeedad2014-08-22 18:16:22184
[email protected]a8a049c2013-03-11 23:27:06185 // Commit immediately.
186 {
khushalsagarb7db1fe2015-11-12 00:51:27187 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
188 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]f7c01c82013-07-02 22:58:46189
Walter Kormanaa326e42017-08-22 23:04:43190 host_impl_->ReadyToCommit();
191 host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14192
Walter Kormanaa326e42017-08-22 23:04:43193 if (host_impl_->EvictedUIResourcesExist())
khushalsagar8ec07402016-09-10 03:13:19194 layer_tree_host_->GetUIResourceManager()->RecreateUIResources();
[email protected]127bdc1a2013-09-11 01:44:48195
Walter Kormanaa326e42017-08-22 23:04:43196 layer_tree_host_->FinishCommitOnImplThread(host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14197
Stephen Chenneybd1e3902019-11-05 20:47:30198 if (scheduler_on_impl_thread_) {
danakj3c3973b2015-08-25 21:50:18199 scheduler_on_impl_thread_->DidCommit();
Stephen Chenneybd1e3902019-11-05 20:47:30200 }
danakj3c3973b2015-08-25 21:50:18201
vmpstra840c6a2017-06-01 21:50:39202 IssueImageDecodeFinishedCallbacks();
Walter Kormanaa326e42017-08-22 23:04:43203 host_impl_->CommitComplete();
danakj3c3973b2015-08-25 21:50:18204
danakj68803fc2015-06-19 20:55:53205 // Commit goes directly to the active tree, but we need to synchronously
206 // "activate" the tree still during commit to satisfy any potential
207 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
208 // might not be ready to draw, so DidActivateSyncTree must set
209 // the flag to force the tree to not draw until textures are ready.
210 NotifyReadyToActivate();
enne98f3a6c2014-10-09 20:09:44211 }
212}
213
vmpstra840c6a2017-06-01 21:50:39214void SingleThreadProxy::IssueImageDecodeFinishedCallbacks() {
215 DCHECK(task_runner_provider_->IsImplThread());
216
Vladimir Levinbed5b372017-10-26 23:46:31217 layer_tree_host_->ImageDecodesFinished(
218 host_impl_->TakeCompletedImageDecodeRequests());
vmpstra840c6a2017-06-01 21:50:39219}
220
enne98f3a6c2014-10-09 20:09:44221void SingleThreadProxy::CommitComplete() {
danakj3c3973b2015-08-25 21:50:18222 // Commit complete happens on the main side after activate to satisfy any
223 // SetNextCommitWaitsForActivation calls.
Walter Kormanaa326e42017-08-22 23:04:43224 DCHECK(!host_impl_->pending_tree())
enne98f3a6c2014-10-09 20:09:44225 << "Activation is expected to have synchronously occurred by now.";
enne98f3a6c2014-10-09 20:09:44226
khushalsagarb7db1fe2015-11-12 00:51:27227 DebugScopedSetMainThread main(task_runner_provider_);
Stefan Zager148248c2019-02-20 23:24:08228 layer_tree_host_->CommitComplete();
Chris Harrelson1fd01012019-04-27 01:20:33229 layer_tree_host_->DidBeginMainFrame();
[email protected]aeeedad2014-08-22 18:16:22230
[email protected]a8a049c2013-03-11 23:27:06231 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14232}
233
[email protected]a8a049c2013-03-11 23:27:06234void SingleThreadProxy::SetNeedsCommit() {
khushalsagarb7db1fe2015-11-12 00:51:27235 DCHECK(task_runner_provider_->IsMainThread());
danakj6c872fc02016-10-22 04:29:49236 single_thread_client_->RequestScheduleComposite();
danakjfcdaba122015-04-24 21:41:52237 if (commit_requested_)
238 return;
brianderson49e101d22015-04-29 00:05:33239 commit_requested_ = true;
khushalsagarb7db1fe2015-11-12 00:51:27240 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22241 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01242 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]94f206c12012-08-25 00:09:14243}
244
[email protected]0023fc72014-01-10 20:05:06245void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20246 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
khushalsagarb7db1fe2015-11-12 00:51:27247 DCHECK(task_runner_provider_->IsMainThread());
248 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43249 host_impl_->SetViewportDamage(damage_rect);
danakje41d978a2016-09-19 21:09:28250 SetNeedsRedrawOnImplThread();
[email protected]94f206c12012-08-25 00:09:14251}
252
[email protected]74b43cc2013-08-30 06:29:27253void SingleThreadProxy::SetNextCommitWaitsForActivation() {
enne98f3a6c2014-10-09 20:09:44254 // Activation always forced in commit, so nothing to do.
khushalsagarb7db1fe2015-11-12 00:51:27255 DCHECK(task_runner_provider_->IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27256}
257
danakje6da4f12018-07-04 17:41:30258bool SingleThreadProxy::RequestedAnimatePending() {
David Bokaneaa5cc82018-10-12 15:50:40259 return animate_requested_ || commit_requested_ || needs_impl_frame_;
danakje6da4f12018-07-04 17:41:30260}
261
Stephen Chenney6d3f5ce2018-11-14 02:08:05262void SingleThreadProxy::SetDeferMainFrameUpdate(bool defer_main_frame_update) {
khushalsagarb7db1fe2015-11-12 00:51:27263 DCHECK(task_runner_provider_->IsMainThread());
Stephen Chenney0c8cc37e2019-01-29 21:32:39264 // Deferring main frame updates only makes sense if there's a scheduler.
[email protected]aeeedad2014-08-22 18:16:22265 if (!scheduler_on_impl_thread_)
266 return;
Stephen Chenney6d3f5ce2018-11-14 02:08:05267 if (defer_main_frame_update_ == defer_main_frame_update)
[email protected]aeeedad2014-08-22 18:16:22268 return;
269
Stephen Chenney1b197822019-09-04 14:25:48270 if (defer_main_frame_update) {
Stephen Chenney6d3f5ce2018-11-14 02:08:05271 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate",
272 this);
Stephen Chenney1b197822019-09-04 14:25:48273 } else {
Stephen Chenney6d3f5ce2018-11-14 02:08:05274 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate",
275 this);
Stephen Chenney1b197822019-09-04 14:25:48276 }
[email protected]aeeedad2014-08-22 18:16:22277
Stephen Chenney6d3f5ce2018-11-14 02:08:05278 defer_main_frame_update_ = defer_main_frame_update;
Stephen Chenney0c8cc37e2019-01-29 21:32:39279
Stephen Chenney1b197822019-09-04 14:25:48280 // Notify dependent systems that the deferral status has changed.
281 layer_tree_host_->OnDeferMainFrameUpdatesChanged(defer_main_frame_update_);
282
Stephen Chenney0f241862019-02-06 01:07:47283 // The scheduler needs to know that it should not issue BeginMainFrame.
284 scheduler_on_impl_thread_->SetDeferBeginMainFrame(defer_main_frame_update_);
Stephen Chenney0c8cc37e2019-01-29 21:32:39285}
286
Stephen Chenney931aa842019-03-06 02:27:39287void SingleThreadProxy::StartDeferringCommits(base::TimeDelta timeout) {
Stephen Chenney0c8cc37e2019-01-29 21:32:39288 DCHECK(task_runner_provider_->IsMainThread());
Stephen Chenney0f241862019-02-06 01:07:47289
Stephen Chenney931aa842019-03-06 02:27:39290 // Do nothing if already deferring. The timeout remains as it was from when
291 // we most recently began deferring.
292 if (defer_commits_)
Stephen Chenney0c8cc37e2019-01-29 21:32:39293 return;
294
Stephen Chenney931aa842019-03-06 02:27:39295 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
Stephen Chenney0c8cc37e2019-01-29 21:32:39296
Stephen Chenney931aa842019-03-06 02:27:39297 defer_commits_ = true;
298 commits_restart_time_ = base::TimeTicks::Now() + timeout;
Stephen Chenney1b197822019-09-04 14:25:48299
300 // Notify dependent systems that the deferral status has changed.
301 layer_tree_host_->OnDeferCommitsChanged(defer_commits_);
Stephen Chenney931aa842019-03-06 02:27:39302}
303
Stephen Chenneya4125562019-05-29 23:59:15304void SingleThreadProxy::StopDeferringCommits(
305 PaintHoldingCommitTrigger trigger) {
Stephen Chenney931aa842019-03-06 02:27:39306 if (!defer_commits_)
307 return;
308 defer_commits_ = false;
309 commits_restart_time_ = base::TimeTicks();
Stephen Chenney5dbeb2d2019-07-31 18:41:09310 UMA_HISTOGRAM_ENUMERATION("PaintHolding.CommitTrigger2", trigger);
Stephen Chenney931aa842019-03-06 02:27:39311 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
Stephen Chenney1b197822019-09-04 14:25:48312
313 // Notify dependent systems that the deferral status has changed.
314 layer_tree_host_->OnDeferCommitsChanged(defer_commits_);
[email protected]6b16679e2012-10-27 00:44:28315}
316
[email protected]174c6d42014-08-12 01:43:06317bool SingleThreadProxy::CommitRequested() const {
khushalsagarb7db1fe2015-11-12 00:51:27318 DCHECK(task_runner_provider_->IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22319 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06320}
[email protected]a8a049c2013-03-11 23:27:06321
[email protected]a8a049c2013-03-11 23:27:06322void SingleThreadProxy::Stop() {
323 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
khushalsagarb7db1fe2015-11-12 00:51:27324 DCHECK(task_runner_provider_->IsMainThread());
[email protected]a8a049c2013-03-11 23:27:06325 {
khushalsagarb7db1fe2015-11-12 00:51:27326 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
327 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06328
sunnypsda928f0a2016-10-08 00:32:53329 // Prevent the scheduler from performing actions while we're in an
330 // inconsistent state.
331 if (scheduler_on_impl_thread_)
332 scheduler_on_impl_thread_->Stop();
danakjc7afae52017-06-20 21:12:41333 // Take away the LayerTreeFrameSink before destroying things so it doesn't
danakj1120f4c2016-09-15 02:05:32334 // try to call into its client mid-shutdown.
Walter Kormanaa326e42017-08-22 23:04:43335 host_impl_->ReleaseLayerTreeFrameSink();
Khushal7899efd2018-01-08 18:01:16336
337 // It is important to destroy LTHI before the Scheduler since it can make
338 // callbacks that access it during destruction cleanup.
Walter Kormanaa326e42017-08-22 23:04:43339 host_impl_ = nullptr;
Khushal7899efd2018-01-08 18:01:16340 scheduler_on_impl_thread_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06341 }
sunnypsda928f0a2016-10-08 00:32:53342 layer_tree_host_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06343}
344
flackrf54e9b42016-05-31 15:20:10345void SingleThreadProxy::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) {
346 DCHECK(task_runner_provider_->IsMainThread());
347 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43348 host_impl_->SetLayerTreeMutator(std::move(mutator));
flackrf54e9b42016-05-31 15:20:10349}
350
Xida Chend5ee5052019-01-03 13:27:51351void SingleThreadProxy::SetPaintWorkletLayerPainter(
352 std::unique_ptr<PaintWorkletLayerPainter> painter) {
353 NOTREACHED();
354}
355
[email protected]3d9f7432013-04-06 00:35:18356void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
sunnypsad3235e2016-08-09 04:57:52357 TRACE_EVENT1("cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw",
358 can_draw);
khushalsagarb7db1fe2015-11-12 00:51:27359 DCHECK(task_runner_provider_->IsImplThread());
[email protected]aeeedad2014-08-22 18:16:22360 if (scheduler_on_impl_thread_)
361 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18362}
363
[email protected]4f48f6e2013-08-27 06:33:38364void SingleThreadProxy::NotifyReadyToActivate() {
enne98f3a6c2014-10-09 20:09:44365 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
khushalsagarb7db1fe2015-11-12 00:51:27366 DebugScopedSetImplThread impl(task_runner_provider_);
rogerm8aeea932017-04-19 21:26:57367 if (scheduler_on_impl_thread_)
368 scheduler_on_impl_thread_->NotifyReadyToActivate();
[email protected]4f48f6e2013-08-27 06:33:38369}
370
ernstmdfac03e2014-11-11 20:18:05371void SingleThreadProxy::NotifyReadyToDraw() {
weiliangc8dac5a62015-04-02 06:12:35372 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToDraw");
khushalsagarb7db1fe2015-11-12 00:51:27373 DebugScopedSetImplThread impl(task_runner_provider_);
weiliangc8dac5a62015-04-02 06:12:35374 if (scheduler_on_impl_thread_)
375 scheduler_on_impl_thread_->NotifyReadyToDraw();
ernstmdfac03e2014-11-11 20:18:05376}
377
[email protected]c1bb5af2013-03-13 19:06:27378void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
danakj6c872fc02016-10-22 04:29:49379 single_thread_client_->RequestScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22380 if (scheduler_on_impl_thread_)
381 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06382}
383
danakja18e826a2015-12-03 00:27:03384void SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread() {
385 TRACE_EVENT0("cc",
386 "SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread");
danakj6c872fc02016-10-22 04:29:49387 single_thread_client_->RequestScheduleComposite();
mithro719bf6792014-11-10 15:36:47388 if (scheduler_on_impl_thread_)
danakja18e826a2015-12-03 00:27:03389 scheduler_on_impl_thread_->SetNeedsOneBeginImplFrame();
David Bokaneaa5cc82018-10-12 15:50:40390 needs_impl_frame_ = true;
[email protected]43b8f982014-04-30 21:24:33391}
392
vmiura59ea9b4042014-12-09 20:50:39393void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
394 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
enne98f3a6c2014-10-09 20:09:44395 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39396 scheduler_on_impl_thread_->SetNeedsPrepareTiles();
[email protected]c48536a52013-09-14 00:02:08397}
398
[email protected]c1bb5af2013-03-13 19:06:27399void SingleThreadProxy::SetNeedsCommitOnImplThread() {
danakj6c872fc02016-10-22 04:29:49400 single_thread_client_->RequestScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22401 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01402 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
David Bokaneaa5cc82018-10-12 15:50:40403 commit_requested_ = true;
[email protected]a8a049c2013-03-11 23:27:06404}
405
sunnyps7d073dc2015-04-16 23:29:12406void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
407 TRACE_EVENT1("cc", "SingleThreadProxy::SetVideoNeedsBeginFrames",
408 "needs_begin_frames", needs_begin_frames);
409 // In tests the layer tree is destroyed after the scheduler is.
410 if (scheduler_on_impl_thread_)
411 scheduler_on_impl_thread_->SetVideoNeedsBeginFrames(needs_begin_frames);
412}
413
[email protected]c1bb5af2013-03-13 19:06:27414void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
loysoc601b7b82016-11-10 02:56:44415 std::unique_ptr<MutatorEvents> events) {
[email protected]ccc08dc2014-01-30 07:33:20416 TRACE_EVENT0(
417 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
khushalsagarb7db1fe2015-11-12 00:51:27418 DCHECK(task_runner_provider_->IsImplThread());
419 DebugScopedSetMainThread main(task_runner_provider_);
danakja04855a2015-11-18 20:39:10420 layer_tree_host_->SetAnimationEvents(std::move(events));
[email protected]a8a049c2013-03-11 23:27:06421}
422
Xida Chend8bb3b22017-10-26 17:14:52423size_t SingleThreadProxy::CompositedAnimationsCount() const {
424 return 0;
425}
426
427size_t SingleThreadProxy::MainThreadAnimationsCount() const {
428 return 0;
429}
430
Xida Chen63843ab2019-10-17 01:53:59431bool SingleThreadProxy::HasCustomPropertyAnimations() const {
432 return false;
433}
434
Stephen McGruer1619b422018-02-20 18:46:55435bool SingleThreadProxy::CurrentFrameHadRAF() const {
436 return false;
437}
438
439bool SingleThreadProxy::NextFrameHasPendingRAF() const {
440 return false;
441}
442
sunnypsad3235e2016-08-09 04:57:52443bool SingleThreadProxy::IsInsideDraw() {
444 return inside_draw_;
445}
[email protected]a8a049c2013-03-11 23:27:06446
Sadrul Habib Chowdhuryab4d350f2019-07-13 00:17:37447bool SingleThreadProxy::IsBeginMainFrameExpected() {
448 return true;
449}
450
enne98f3a6c2014-10-09 20:09:44451void SingleThreadProxy::DidActivateSyncTree() {
danakj68803fc2015-06-19 20:55:53452 CommitComplete();
enne98f3a6c2014-10-09 20:09:44453}
454
brianderson68749812015-07-07 22:39:39455void SingleThreadProxy::WillPrepareTiles() {
khushalsagarb7db1fe2015-11-12 00:51:27456 DCHECK(task_runner_provider_->IsImplThread());
brianderson68749812015-07-07 22:39:39457 if (scheduler_on_impl_thread_)
458 scheduler_on_impl_thread_->WillPrepareTiles();
459}
460
vmiura59ea9b4042014-12-09 20:50:39461void SingleThreadProxy::DidPrepareTiles() {
khushalsagarb7db1fe2015-11-12 00:51:27462 DCHECK(task_runner_provider_->IsImplThread());
enne98f3a6c2014-10-09 20:09:44463 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39464 scheduler_on_impl_thread_->DidPrepareTiles();
enne98f3a6c2014-10-09 20:09:44465}
466
rouslanf7ebd8832015-01-22 01:54:14467void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
468 layer_tree_host_->DidCompletePageScaleAnimation();
469}
470
danakjc7afae52017-06-20 21:12:41471void SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread() {
danakj1120f4c2016-09-15 02:05:32472 TRACE_EVENT0("cc",
danakjc7afae52017-06-20 21:12:41473 "SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22474 {
khushalsagarb7db1fe2015-11-12 00:51:27475 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22476 // This must happen before we notify the scheduler as it may try to recreate
477 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
danakjc7afae52017-06-20 21:12:41478 layer_tree_host_->DidLoseLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22479 }
danakjc7afae52017-06-20 21:12:41480 single_thread_client_->DidLoseLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22481 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41482 scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink();
483 layer_tree_frame_sink_lost_ = true;
[email protected]4d7e46a2013-11-08 05:33:40484}
485
Fady Samuelc645ffe2017-07-24 17:28:20486void SingleThreadProxy::SetBeginFrameSource(viz::BeginFrameSource* source) {
enne19c108582016-04-14 03:35:32487 if (scheduler_on_impl_thread_)
488 scheduler_on_impl_thread_->SetBeginFrameSource(source);
489}
490
danakj9d124422016-10-14 03:15:08491void SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread() {
miletusfed8c43b2015-01-26 20:04:52492 TRACE_EVENT0("cc,benchmark",
danakj9d124422016-10-14 03:15:08493 "SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22494 if (scheduler_on_impl_thread_)
danakj9d124422016-10-14 03:15:08495 scheduler_on_impl_thread_->DidReceiveCompositorFrameAck();
Karolina Soltys4d60b402018-10-01 19:28:20496 if (layer_tree_host_->GetSettings().send_compositor_frame_ack) {
497 // We do a PostTask here because freeing resources in some cases (such as in
498 // TextureLayer) is PostTasked and we want to make sure ack is received
499 // after resources are returned.
500 task_runner_provider_->MainThreadTaskRunner()->PostTask(
kylechar4bb144d2019-01-11 20:42:07501 FROM_HERE,
502 base::BindOnce(&SingleThreadProxy::DidReceiveCompositorFrameAck,
503 frame_sink_bound_weak_ptr_));
Karolina Soltys4d60b402018-10-01 19:28:20504 }
[email protected]493067512012-09-19 23:34:10505}
506
danakjc7afae52017-06-20 21:12:41507void SingleThreadProxy::OnDrawForLayerTreeFrameSink(
James Wallace-Leefbb0e3362018-06-18 23:57:47508 bool resourceless_software_draw,
509 bool skip_draw) {
sunnypseab5ac92015-04-02 20:26:13510 NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
511}
512
Khushal8360fc92017-07-26 01:53:25513void SingleThreadProxy::NeedsImplSideInvalidation(
514 bool needs_first_draw_on_activation) {
Khushal4b6c41882018-02-16 09:02:10515 if (scheduler_on_impl_thread_) {
516 scheduler_on_impl_thread_->SetNeedsImplSideInvalidation(
517 needs_first_draw_on_activation);
518 }
khushalsagard3b8827d2017-02-18 18:42:54519}
520
vmpstra840c6a2017-06-01 21:50:39521void SingleThreadProxy::NotifyImageDecodeRequestFinished() {
522 // If we don't have a scheduler, then just issue the callbacks here.
523 // Otherwise, schedule a commit.
524 if (!scheduler_on_impl_thread_) {
525 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
526 DebugScopedSetImplThread impl(task_runner_provider_);
527
528 IssueImageDecodeFinishedCallbacks();
529 return;
530 }
531 SetNeedsCommitOnImplThread();
532}
533
Scott Violete979c012017-12-08 00:18:16534void SingleThreadProxy::DidPresentCompositorFrameOnImplThread(
Sadrul Habib Chowdhury3d4df2e82018-06-02 05:18:00535 uint32_t frame_token,
536 std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
Nathan Zabriskie12b7d892019-09-11 19:16:17537 const viz::FrameTimingDetails& details) {
Sadrul Habib Chowdhury3d4df2e82018-06-02 05:18:00538 layer_tree_host_->DidPresentCompositorFrame(frame_token, std::move(callbacks),
Nathan Zabriskie12b7d892019-09-11 19:16:17539 details.presentation_feedback);
behdad2b3c65c2019-07-12 19:15:42540
541 if (scheduler_on_impl_thread_) {
Nathan Zabriskie12b7d892019-09-11 19:16:17542 scheduler_on_impl_thread_->DidPresentCompositorFrame(frame_token, details);
behdad2b3c65c2019-07-12 19:15:42543 }
Scott Violete979c012017-12-08 00:18:16544}
545
Kevin Ellis8272ed22019-03-01 21:03:18546void SingleThreadProxy::NotifyAnimationWorkletStateChange(
547 AnimationWorkletMutationState state,
548 ElementListType element_list_type) {
549 layer_tree_host_->NotifyAnimationWorkletStateChange(state, element_list_type);
550}
551
Stephen McGruerfe312c92019-06-14 03:18:07552void SingleThreadProxy::NotifyPaintWorkletStateChange(
553 Scheduler::PaintWorkletState state) {
554 // Off-Thread PaintWorklet is only supported on the threaded compositor.
555 NOTREACHED();
556}
557
Dan Elphick95929fd52017-06-13 09:15:07558void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
559 if (scheduler_on_impl_thread_) {
560 scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected(
561 new_state);
562 }
563}
564
Khushal4b6c41882018-02-16 09:02:10565void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time,
566 bool raster) {
miletusfed8c43b2015-01-26 20:04:52567 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
khushalsagarb7db1fe2015-11-12 00:51:27568 DCHECK(task_runner_provider_->IsMainThread());
mithro51693e382015-05-07 23:52:41569#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13570 DCHECK(!inside_impl_frame_);
mithro51693e382015-05-07 23:52:41571#endif
jbauman399aec1a2014-10-25 02:33:32572 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
573
danakjc7afae52017-06-20 21:12:41574 if (layer_tree_frame_sink_lost_) {
575 RequestNewLayerTreeFrameSink();
576 // RequestNewLayerTreeFrameSink could have synchronously created an output
jbauman399aec1a2014-10-25 02:33:32577 // surface, so check again before returning.
danakjc7afae52017-06-20 21:12:41578 if (layer_tree_frame_sink_lost_)
jbauman399aec1a2014-10-25 02:33:32579 return;
580 }
[email protected]51f81da2014-05-16 21:29:26581
Fady Samuelc296f5fb2017-07-21 04:02:19582 viz::BeginFrameArgs begin_frame_args(viz::BeginFrameArgs::Create(
Xida Chen0b269a602019-09-11 02:54:54583 BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId,
584 begin_frame_sequence_number_++, frame_begin_time, base::TimeTicks(),
Fady Samuelc296f5fb2017-07-21 04:02:19585 viz::BeginFrameArgs::DefaultInterval(), viz::BeginFrameArgs::NORMAL));
mithroc76d70312015-05-04 23:51:13586
587 // Start the impl frame.
enne98f3a6c2014-10-09 20:09:44588 {
khushalsagarb7db1fe2015-11-12 00:51:27589 DebugScopedSetImplThread impl(task_runner_provider_);
mithroc76d70312015-05-04 23:51:13590 WillBeginImplFrame(begin_frame_args);
591 }
592
593 // Run the "main thread" and get it to commit.
594 {
mithro51693e382015-05-07 23:52:41595#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13596 DCHECK(inside_impl_frame_);
mithro51693e382015-05-07 23:52:41597#endif
danakje6da4f12018-07-04 17:41:30598 animate_requested_ = false;
David Bokaneaa5cc82018-10-12 15:50:40599 needs_impl_frame_ = false;
danakje6da4f12018-07-04 17:41:30600 // Prevent new commits from being requested inside DoBeginMainFrame.
601 // Note: We do not want to prevent SetNeedsAnimate from requesting
602 // a commit here.
603 commit_requested_ = true;
enne98f3a6c2014-10-09 20:09:44604 DoBeginMainFrame(begin_frame_args);
danakje6da4f12018-07-04 17:41:30605 commit_requested_ = false;
danakj97660d92017-03-27 14:11:49606 DoPainting();
enne98f3a6c2014-10-09 20:09:44607 DoCommit();
[email protected]e0341352013-04-06 05:01:20608
khushalsagar8297ae992016-09-14 20:51:23609 DCHECK_EQ(
610 0u,
611 layer_tree_host_->GetSwapPromiseManager()->num_queued_swap_promises())
enne98f3a6c2014-10-09 20:09:44612 << "Commit should always succeed and transfer promises.";
613 }
614
mithroc76d70312015-05-04 23:51:13615 // Finish the impl frame.
enne98f3a6c2014-10-09 20:09:44616 {
khushalsagarb7db1fe2015-11-12 00:51:27617 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43618 host_impl_->ActivateSyncTree();
Khushal4b6c41882018-02-16 09:02:10619 if (raster) {
620 host_impl_->PrepareTiles();
621 host_impl_->SynchronouslyInitializeAllTiles();
622 }
enne69277cb2014-10-29 23:03:40623
danakj12e2f6e2015-08-19 22:25:44624 // TODO(danakj): Don't do this last... we prepared the wrong things. D:
Walter Kormanaa326e42017-08-22 23:04:43625 host_impl_->Animate();
mithro719bf6792014-11-10 15:36:47626
Khushal4b6c41882018-02-16 09:02:10627 if (raster) {
628 LayerTreeHostImpl::FrameData frame;
Sadrul Habib Chowdhury4a7940b2018-06-22 16:45:14629 frame.begin_frame_ack = viz::BeginFrameAck(begin_frame_args, true);
Sadrul Habib Chowdhury0d7cff6ae2019-07-08 21:19:33630 frame.origin_begin_main_frame_args = begin_frame_args;
Khushal4b6c41882018-02-16 09:02:10631 DoComposite(&frame);
632 }
enne98f3a6c2014-10-09 20:09:44633
634 // DoComposite could abort, but because this is a synchronous composite
635 // another draw will never be scheduled, so break remaining promises.
Walter Kormanaa326e42017-08-22 23:04:43636 host_impl_->active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS);
mithroc76d70312015-05-04 23:51:13637
mithro51693e382015-05-07 23:52:41638 DidFinishImplFrame();
enne98f3a6c2014-10-09 20:09:44639 }
[email protected]74d9063c2013-01-18 03:14:47640}
641
[email protected]5d8bec72014-07-03 03:03:11642bool SingleThreadProxy::SupportsImplScrolling() const {
643 return false;
644}
645
[email protected]3d9f7432013-04-06 00:35:18646bool SingleThreadProxy::ShouldComposite() const {
khushalsagarb7db1fe2015-11-12 00:51:27647 DCHECK(task_runner_provider_->IsImplThread());
Walter Kormanaa326e42017-08-22 23:04:43648 return host_impl_->visible() && host_impl_->CanDraw();
[email protected]3d9f7432013-04-06 00:35:18649}
650
danakjc7afae52017-06-20 21:12:41651void SingleThreadProxy::ScheduleRequestNewLayerTreeFrameSink() {
652 if (layer_tree_frame_sink_creation_callback_.IsCancelled() &&
653 !layer_tree_frame_sink_creation_requested_) {
654 layer_tree_frame_sink_creation_callback_.Reset(
kylechar3ef69ec2019-01-16 21:07:15655 base::BindOnce(&SingleThreadProxy::RequestNewLayerTreeFrameSink,
656 weak_factory_.GetWeakPtr()));
khushalsagarb7db1fe2015-11-12 00:51:27657 task_runner_provider_->MainThreadTaskRunner()->PostTask(
danakjc7afae52017-06-20 21:12:41658 FROM_HERE, layer_tree_frame_sink_creation_callback_.callback());
jbauman8ab0f9e2014-10-15 02:30:34659 }
660}
661
mithro248d1722015-05-05 05:23:45662DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20663 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20664
enne98f3a6c2014-10-09 20:09:44665 DrawResult draw_result;
666 bool draw_frame;
[email protected]a8a049c2013-03-11 23:27:06667 {
khushalsagarb7db1fe2015-11-12 00:51:27668 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06669 base::AutoReset<bool> mark_inside(&inside_draw_, true);
670
[email protected]3d9f7432013-04-06 00:35:18671 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
672 // frame, so can only be used when such a frame is possible. Since
673 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
674 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50675 if (!ShouldComposite()) {
[email protected]aeeedad2014-08-22 18:16:22676 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18677 }
[email protected]a8a049c2013-03-11 23:27:06678
danakj097919e72016-09-07 19:50:55679 // This CapturePostTasks should be destroyed before
680 // DidCommitAndDrawFrame() is called since that goes out to the
681 // embedder, and we want the embedder to receive its callbacks before that.
682 // NOTE: This maintains consistent ordering with the ThreadProxy since
683 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
684 // there as the main thread is not blocked, so any posted tasks inside
685 // the swap buffers will execute first.
686 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
danakj097919e72016-09-07 19:50:55687
Walter Kormanaa326e42017-08-22 23:04:43688 draw_result = host_impl_->PrepareToDraw(frame);
enne98f3a6c2014-10-09 20:09:44689 draw_frame = draw_result == DRAW_SUCCESS;
robliao27728e62015-03-21 07:39:34690 if (draw_frame) {
Walter Kormanaa326e42017-08-22 23:04:43691 if (host_impl_->DrawLayers(frame)) {
behdad2b3c65c2019-07-12 19:15:42692 if (scheduler_on_impl_thread_) {
danakjc7afae52017-06-20 21:12:41693 // Drawing implies we submitted a frame to the LayerTreeFrameSink.
behdad2b3c65c2019-07-12 19:15:42694 scheduler_on_impl_thread_->DidSubmitCompositorFrame(
695 frame->frame_token);
696 }
danakj6c872fc02016-10-22 04:29:49697 single_thread_client_->DidSubmitCompositorFrame();
danakj097919e72016-09-07 19:50:55698 }
robliao27728e62015-03-21 07:39:34699 }
Walter Kormanaa326e42017-08-22 23:04:43700 host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06701
danakj097919e72016-09-07 19:50:55702 bool start_ready_animations = draw_frame;
Walter Kormanaa326e42017-08-22 23:04:43703 host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]aeeedad2014-08-22 18:16:22704 }
705 DidCommitAndDrawFrame();
706
enne98f3a6c2014-10-09 20:09:44707 return draw_result;
[email protected]a8a049c2013-03-11 23:27:06708}
709
[email protected]aeeedad2014-08-22 18:16:22710void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06711 if (next_frame_is_newly_committed_frame_) {
khushalsagarb7db1fe2015-11-12 00:51:27712 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06713 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21714 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06715 }
716}
717
[email protected]4ea293f72014-08-13 03:03:17718bool SingleThreadProxy::MainFrameWillHappenForTesting() {
danakjfcdaba122015-04-24 21:41:52719 if (!scheduler_on_impl_thread_)
720 return false;
721 return scheduler_on_impl_thread_->MainFrameForTestingWillHappen();
[email protected]4ea293f72014-08-13 03:03:17722}
[email protected]a8a049c2013-03-11 23:27:06723
Fady Samueld26f7fb2018-06-19 04:13:37724void SingleThreadProxy::ClearHistory() {
Khushal2f9cdf22018-01-08 21:47:08725 DCHECK(task_runner_provider_->IsImplThread());
726 if (scheduler_on_impl_thread_)
Fady Samueld26f7fb2018-06-19 04:13:37727 scheduler_on_impl_thread_->ClearHistory();
Khushal2f9cdf22018-01-08 21:47:08728}
729
jonrossa2ff4f82018-02-16 17:27:46730void SingleThreadProxy::SetRenderFrameObserver(
731 std::unique_ptr<RenderFrameMetadataObserver> observer) {
jonrossc1877d6d2018-02-21 00:07:31732 host_impl_->SetRenderFrameObserver(std::move(observer));
jonrossa2ff4f82018-02-16 17:27:46733}
734
David Bokan1e37ebf2018-10-16 13:53:37735void SingleThreadProxy::UpdateBrowserControlsState(
736 BrowserControlsState constraints,
737 BrowserControlsState current,
738 bool animate) {
739 host_impl_->browser_controls_manager()->UpdateBrowserControlsState(
740 constraints, current, animate);
741}
742
James Wallace-Leee71cf582018-01-29 22:24:23743bool SingleThreadProxy::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
danakja18e826a2015-12-03 00:27:03744 DebugScopedSetImplThread impl(task_runner_provider_);
mithro51693e382015-05-07 23:52:41745#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02746 DCHECK(!inside_impl_frame_)
747 << "WillBeginImplFrame called while already inside an impl frame!";
748 inside_impl_frame_ = true;
mithro51693e382015-05-07 23:52:41749#endif
James Wallace-Leee71cf582018-01-29 22:24:23750 return host_impl_->WillBeginImplFrame(args);
[email protected]aeeedad2014-08-22 18:16:22751}
752
brianderson266dc3a2015-11-12 03:16:40753void SingleThreadProxy::ScheduledActionSendBeginMainFrame(
Fady Samuelc296f5fb2017-07-21 04:02:19754 const viz::BeginFrameArgs& begin_frame_args) {
[email protected]aeeedad2014-08-22 18:16:22755 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
sunnypsad3235e2016-08-09 04:57:52756#if DCHECK_IS_ON()
[email protected]aeeedad2014-08-22 18:16:22757 // Although this proxy is single-threaded, it's problematic to synchronously
758 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
759 // could cause a commit to occur in between a series of SetNeedsCommit calls
760 // (i.e. property modifications) causing some to fall on one frame and some to
761 // fall on the next. Doing it asynchronously instead matches the semantics of
762 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
763 // synchronous commit.
mithro69fd3bb52015-05-01 03:45:02764 DCHECK(inside_impl_frame_)
765 << "BeginMainFrame should only be sent inside a BeginImplFrame";
mithro51693e382015-05-07 23:52:41766#endif
mithro69fd3bb52015-05-01 03:45:02767
Zhenyao Mo5b30cf32018-12-01 00:31:25768 host_impl_->WillSendBeginMainFrame();
khushalsagarb7db1fe2015-11-12 00:51:27769 task_runner_provider_->MainThreadTaskRunner()->PostTask(
tzik4604bb52017-04-13 21:50:22770 FROM_HERE, base::BindOnce(&SingleThreadProxy::BeginMainFrame,
771 weak_factory_.GetWeakPtr(), begin_frame_args));
Sadrul Habib Chowdhury0d7cff6ae2019-07-08 21:19:33772 host_impl_->DidSendBeginMainFrame(begin_frame_args);
[email protected]aeeedad2014-08-22 18:16:22773}
774
kylechard96169b2018-11-02 00:55:00775void SingleThreadProxy::FrameIntervalUpdated(base::TimeDelta interval) {
776 DebugScopedSetMainThread main(task_runner_provider_);
777 single_thread_client_->FrameIntervalUpdated(interval);
778}
779
rmcilroy0a19362a2015-02-18 12:34:25780void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
781 layer_tree_host_->BeginMainFrameNotExpectedSoon();
782}
783
delphick9db74aa2017-05-05 10:20:49784void SingleThreadProxy::ScheduledActionBeginMainFrameNotExpectedUntil(
785 base::TimeTicks time) {
786 layer_tree_host_->BeginMainFrameNotExpectedUntil(time);
787}
788
Fady Samuelc296f5fb2017-07-21 04:02:19789void SingleThreadProxy::BeginMainFrame(
790 const viz::BeginFrameArgs& begin_frame_args) {
Brian Anderson242b9b02017-12-06 21:06:26791 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
792 // commit.
793 ScopedAbortRemainingSwapPromises swap_promise_checker(
794 layer_tree_host_->GetSwapPromiseManager());
795
brianderson21aef162015-11-11 05:12:23796 if (scheduler_on_impl_thread_) {
797 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(
798 base::TimeTicks::Now());
799 }
800
danakjfcdaba122015-04-24 21:41:52801 commit_requested_ = false;
David Bokaneaa5cc82018-10-12 15:50:40802 needs_impl_frame_ = false;
brianderson49e101d22015-04-29 00:05:33803 animate_requested_ = false;
danakjfcdaba122015-04-24 21:41:52804
Stephen Chenney6d3f5ce2018-11-14 02:08:05805 if (defer_main_frame_update_) {
Stephen Chenney0c8cc37e2019-01-29 21:32:39806 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferBeginMainFrame",
simonhongc6309f792015-01-31 15:47:15807 TRACE_EVENT_SCOPE_THREAD);
808 BeginMainFrameAbortedOnImplThread(
Stephen Chenney0c8cc37e2019-01-29 21:32:39809 CommitEarlyOutReason::ABORTED_DEFERRED_MAIN_FRAME_UPDATE);
[email protected]aeeedad2014-08-22 18:16:22810 return;
811 }
812
khushalsagarcebe4942016-09-07 23:27:01813 if (!layer_tree_host_->IsVisible()) {
[email protected]aeeedad2014-08-22 18:16:22814 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48815 BeginMainFrameAbortedOnImplThread(
816 CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
[email protected]aeeedad2014-08-22 18:16:22817 return;
818 }
819
danakjfcdaba122015-04-24 21:41:52820 // Prevent new commits from being requested inside DoBeginMainFrame.
brianderson49e101d22015-04-29 00:05:33821 // Note: We do not want to prevent SetNeedsAnimate from requesting
822 // a commit here.
danakjfcdaba122015-04-24 21:41:52823 commit_requested_ = true;
824
Stephen Chenney1b197822019-09-04 14:25:48825 // Check now if we should stop deferring commits. Do this before
826 // DoBeginMainFrame because the latter updates scroll offsets, which
827 // we should avoid if deferring commits.
828 if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_)
829 StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout);
830
enne98f3a6c2014-10-09 20:09:44831 DoBeginMainFrame(begin_frame_args);
danakj97660d92017-03-27 14:11:49832
833 // New commits requested inside UpdateLayers should be respected.
834 commit_requested_ = false;
835
danakj97660d92017-03-27 14:11:49836 // At this point the main frame may have deferred commits to avoid committing
837 // right now.
Stephen Chenney0c8cc37e2019-01-29 21:32:39838 if (defer_main_frame_update_ || defer_commits_ ||
839 begin_frame_args.animate_only) {
danakj97660d92017-03-27 14:11:49840 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
841 TRACE_EVENT_SCOPE_THREAD);
842 BeginMainFrameAbortedOnImplThread(
843 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
844 layer_tree_host_->DidBeginMainFrame();
845 return;
846 }
847
danakj97660d92017-03-27 14:11:49848 DoPainting();
enne98f3a6c2014-10-09 20:09:44849}
850
851void SingleThreadProxy::DoBeginMainFrame(
Fady Samuelc296f5fb2017-07-21 04:02:19852 const viz::BeginFrameArgs& begin_frame_args) {
Stephen Chenney1b197822019-09-04 14:25:48853 // Only update scroll deltas if we are going to commit the frame, otherwise
854 // scroll offsets get confused.
855 if (!defer_commits_) {
856 // The impl-side scroll deltas may be manipulated directly via the
857 // InputHandler on the UI thread and the scale deltas may change when they
858 // are clamped on the impl thread.
859 std::unique_ptr<ScrollAndScaleSet> scroll_info =
860 host_impl_->ProcessScrollDeltas();
861 layer_tree_host_->ApplyScrollAndScale(scroll_info.get());
862 }
tapted4b70c522016-08-13 09:09:32863
enne98f3a6c2014-10-09 20:09:44864 layer_tree_host_->WillBeginMainFrame();
865 layer_tree_host_->BeginMainFrame(begin_frame_args);
866 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
Stephen Chenney329976d2019-09-27 16:47:35867 layer_tree_host_->RequestMainFrameUpdate(false /* record_cc_metrics */);
danakj97660d92017-03-27 14:11:49868}
enne98f3a6c2014-10-09 20:09:44869
danakj97660d92017-03-27 14:11:49870void SingleThreadProxy::DoPainting() {
danakj5f46636a2015-06-19 00:01:40871 layer_tree_host_->UpdateLayers();
enne98f3a6c2014-10-09 20:09:44872
mithrof7a21502014-12-17 03:24:48873 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
874 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
875 // thread_proxy.cc
Stephen Chenneybd1e3902019-11-05 20:47:30876 if (scheduler_on_impl_thread_) {
877 scheduler_on_impl_thread_->NotifyReadyToCommit(
878 layer_tree_host_->begin_main_frame_metrics());
879 }
[email protected]aeeedad2014-08-22 18:16:22880}
881
mithrof7a21502014-12-17 03:24:48882void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
883 CommitEarlyOutReason reason) {
khushalsagarb7db1fe2015-11-12 00:51:27884 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22885 DCHECK(scheduler_on_impl_thread_->CommitPending());
Walter Kormanaa326e42017-08-22 23:04:43886 DCHECK(!host_impl_->pending_tree());
[email protected]aeeedad2014-08-22 18:16:22887
sunnypsad3235e2016-08-09 04:57:52888 std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
Sadrul Habib Chowdhury0d7cff6ae2019-07-08 21:19:33889 host_impl_->BeginMainFrameAborted(
890 reason, std::move(empty_swap_promises),
891 scheduler_on_impl_thread_->last_dispatched_begin_main_frame_args());
mithrof7a21502014-12-17 03:24:48892 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
[email protected]aeeedad2014-08-22 18:16:22893}
894
danakj9d124422016-10-14 03:15:08895DrawResult SingleThreadProxy::ScheduledActionDrawIfPossible() {
khushalsagarb7db1fe2015-11-12 00:51:27896 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22897 LayerTreeHostImpl::FrameData frame;
esecklerdde665f2017-03-07 20:19:27898 frame.begin_frame_ack =
899 scheduler_on_impl_thread_->CurrentBeginFrameAckForActiveTree();
Sadrul Habib Chowdhury0d7cff6ae2019-07-08 21:19:33900 frame.origin_begin_main_frame_args =
901 scheduler_on_impl_thread_->last_activate_origin_frame_args();
mithro248d1722015-05-05 05:23:45902 return DoComposite(&frame);
[email protected]aeeedad2014-08-22 18:16:22903}
904
danakj9d124422016-10-14 03:15:08905DrawResult SingleThreadProxy::ScheduledActionDrawForced() {
[email protected]aeeedad2014-08-22 18:16:22906 NOTREACHED();
907 return INVALID_RESULT;
908}
909
910void SingleThreadProxy::ScheduledActionCommit() {
khushalsagarb7db1fe2015-11-12 00:51:27911 DebugScopedSetMainThread main(task_runner_provider_);
enne98f3a6c2014-10-09 20:09:44912 DoCommit();
[email protected]aeeedad2014-08-22 18:16:22913}
914
[email protected]aeeedad2014-08-22 18:16:22915void SingleThreadProxy::ScheduledActionActivateSyncTree() {
khushalsagarb7db1fe2015-11-12 00:51:27916 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43917 host_impl_->ActivateSyncTree();
[email protected]aeeedad2014-08-22 18:16:22918}
919
danakjc7afae52017-06-20 21:12:41920void SingleThreadProxy::ScheduledActionBeginLayerTreeFrameSinkCreation() {
khushalsagarb7db1fe2015-11-12 00:51:27921 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22922 DCHECK(scheduler_on_impl_thread_);
923 // If possible, create the output surface in a post task. Synchronously
924 // creating the output surface makes tests more awkward since this differs
925 // from the ThreadProxy behavior. However, sometimes there is no
926 // task runner.
khushalsagarb7db1fe2015-11-12 00:51:27927 if (task_runner_provider_->MainThreadTaskRunner()) {
danakjc7afae52017-06-20 21:12:41928 ScheduleRequestNewLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22929 } else {
danakjc7afae52017-06-20 21:12:41930 RequestNewLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22931 }
932}
933
vmiura59ea9b4042014-12-09 20:50:39934void SingleThreadProxy::ScheduledActionPrepareTiles() {
935 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
khushalsagarb7db1fe2015-11-12 00:51:27936 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43937 host_impl_->PrepareTiles();
[email protected]aeeedad2014-08-22 18:16:22938}
939
James Wallace-Leefbb0e3362018-06-18 23:57:47940void SingleThreadProxy::ScheduledActionInvalidateLayerTreeFrameSink(
941 bool needs_redraw) {
danakja5df53792018-04-26 18:36:39942 // This is an Android WebView codepath, which only uses multi-thread
943 // compositor. So this should not occur in single-thread mode.
944 NOTREACHED() << "Android Webview use-case, so multi-thread only";
sunnypseab5ac92015-04-02 20:26:13945}
946
khushalsagarab73d502017-02-24 02:26:46947void SingleThreadProxy::ScheduledActionPerformImplSideInvalidation() {
khushalsagar6dc91d02017-02-28 05:10:07948 DCHECK(scheduler_on_impl_thread_);
949
950 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43951 host_impl_->InvalidateContentOnImplSide();
khushalsagar6dc91d02017-02-28 05:10:07952
953 // Invalidations go directly to the active tree, so we synchronously call
954 // NotifyReadyToActivate to update the scheduler and LTHI state correctly.
955 // Since in single-threaded mode the scheduler will wait for a ready to draw
956 // signal from LTHI, the draw will remain blocked till the invalidated tiles
957 // are ready.
958 NotifyReadyToActivate();
khushalsagarab73d502017-02-24 02:26:46959}
960
mithro51693e382015-05-07 23:52:41961void SingleThreadProxy::DidFinishImplFrame() {
Walter Kormanaa326e42017-08-22 23:04:43962 host_impl_->DidFinishImplFrame();
mithro51693e382015-05-07 23:52:41963#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02964 DCHECK(inside_impl_frame_)
mithro51693e382015-05-07 23:52:41965 << "DidFinishImplFrame called while not inside an impl frame!";
mithro69fd3bb52015-05-01 03:45:02966 inside_impl_frame_ = false;
mithro51693e382015-05-07 23:52:41967#endif
[email protected]aeeedad2014-08-22 18:16:22968}
969
Fady Samuelc296f5fb2017-07-21 04:02:19970void SingleThreadProxy::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
eseckler9404a232017-05-22 14:49:43971 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43972 host_impl_->DidNotProduceFrame(ack);
eseckler9404a232017-05-22 14:49:43973}
974
yiyix807099e2018-11-09 05:24:28975void SingleThreadProxy::WillNotReceiveBeginFrame() {
976 host_impl_->DidNotNeedBeginFrame();
977}
978
samans44b6dfc2017-04-19 16:50:53979void SingleThreadProxy::DidReceiveCompositorFrameAck() {
980 layer_tree_host_->DidReceiveCompositorFrameAck();
981}
982
[email protected]bc5e77c2012-11-05 20:00:49983} // namespace cc