blob: 21e0bd8dea997c968a7078458a734353bb1e57a0 [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"
Xida Chend5ee5052019-01-03 13:27:5114#include "cc/paint/paint_worklet_layer_painter.h"
khushalsagar8ec07402016-09-10 03:13:1915#include "cc/resources/ui_resource_manager.h"
mithrof7a21502014-12-17 03:24:4816#include "cc/scheduler/commit_earlyout_reason.h"
briandersonc9f50352015-06-24 03:38:5817#include "cc/scheduler/compositor_timing_history.h"
18#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"
jaydasika13c05062016-04-01 18:12:2722#include "cc/trees/layer_tree_host_common.h"
[email protected]943528e2013-11-07 05:01:3223#include "cc/trees/layer_tree_host_single_thread_client.h"
[email protected]556fd292013-03-18 08:03:0424#include "cc/trees/layer_tree_impl.h"
loysoc601b7b82016-11-10 02:56:4425#include "cc/trees/mutator_host.h"
jonrossa2ff4f82018-02-16 17:27:4626#include "cc/trees/render_frame_metadata_observer.h"
[email protected]aeeedad2014-08-22 18:16:2227#include "cc/trees/scoped_abort_remaining_swap_promises.h"
Fady Samuelc645ffe2017-07-24 17:28:2028#include "components/viz/common/frame_sinks/delay_based_time_source.h"
Xu Xing32549162017-07-17 22:25:4329#include "components/viz/common/gpu/context_provider.h"
[email protected]94f206c12012-08-25 00:09:1430
[email protected]9c88e562012-09-14 22:21:3031namespace cc {
[email protected]94f206c12012-08-25 00:09:1432
danakj60bc3bc2016-04-09 00:24:4833std::unique_ptr<Proxy> SingleThreadProxy::Create(
khushalsagare0e4486e2017-01-25 03:15:0334 LayerTreeHost* layer_tree_host,
[email protected]27e6a212014-07-18 15:51:2735 LayerTreeHostSingleThreadClient* client,
khushalsagar767dd522015-12-16 05:14:0536 TaskRunnerProvider* task_runner_provider) {
danakj60bc3bc2016-04-09 00:24:4837 return base::WrapUnique(
khushalsagar767dd522015-12-16 05:14:0538 new SingleThreadProxy(layer_tree_host, client, task_runner_provider));
[email protected]94f206c12012-08-25 00:09:1439}
40
khushalsagare0e4486e2017-01-25 03:15:0341SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
khushalsagar767dd522015-12-16 05:14:0542 LayerTreeHostSingleThreadClient* client,
43 TaskRunnerProvider* task_runner_provider)
khushalsagarb7db1fe2015-11-12 00:51:2744 : layer_tree_host_(layer_tree_host),
danakj6c872fc02016-10-22 04:29:4945 single_thread_client_(client),
khushalsagarb7db1fe2015-11-12 00:51:2746 task_runner_provider_(task_runner_provider),
[email protected]a8a049c2013-03-11 23:27:0647 next_frame_is_newly_committed_frame_(false),
mithro51693e382015-05-07 23:52:4148#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:0249 inside_impl_frame_(false),
mithro51693e382015-05-07 23:52:4150#endif
[email protected]aeeedad2014-08-22 18:16:2251 inside_draw_(false),
Stephen Chenney6d3f5ce2018-11-14 02:08:0552 defer_main_frame_update_(false),
Stephen Chenney0c8cc37e2019-01-29 21:32:3953 defer_commits_(false),
brianderson49e101d22015-04-29 00:05:3354 animate_requested_(false),
[email protected]aeeedad2014-08-22 18:16:2255 commit_requested_(false),
jbauman399aec1a2014-10-25 02:33:3256 inside_synchronous_composite_(false),
David Bokaneaa5cc82018-10-12 15:50:4057 needs_impl_frame_(false),
danakjc7afae52017-06-20 21:12:4158 layer_tree_frame_sink_creation_requested_(false),
59 layer_tree_frame_sink_lost_(true),
samans44b6dfc2017-04-19 16:50:5360 frame_sink_bound_weak_factory_(this),
[email protected]aeeedad2014-08-22 18:16:2261 weak_factory_(this) {
[email protected]a8a049c2013-03-11 23:27:0662 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
khushalsagarb7db1fe2015-11-12 00:51:2763 DCHECK(task_runner_provider_);
64 DCHECK(task_runner_provider_->IsMainThread());
[email protected]a8a049c2013-03-11 23:27:0665 DCHECK(layer_tree_host);
khushalsagar767dd522015-12-16 05:14:0566}
danakjfcdaba122015-04-24 21:41:5267
enne2b0ad682016-09-21 01:44:4768void SingleThreadProxy::Start() {
khushalsagar767dd522015-12-16 05:14:0569 DebugScopedSetImplThread impl(task_runner_provider_);
khushalsagar767dd522015-12-16 05:14:0570
khushalsagarcebe4942016-09-07 23:27:0171 const LayerTreeSettings& settings = layer_tree_host_->GetSettings();
khushalsagar6dc91d02017-02-28 05:10:0772 DCHECK(settings.single_thread_proxy_scheduler ||
73 !settings.enable_checker_imaging)
74 << "Checker-imaging is not supported in synchronous single threaded mode";
khushalsagarcebe4942016-09-07 23:27:0175 if (settings.single_thread_proxy_scheduler && !scheduler_on_impl_thread_) {
76 SchedulerSettings scheduler_settings(settings.ToSchedulerSettings());
danakj5f2e92de2015-06-20 00:25:5877 scheduler_settings.commit_to_active_tree = CommitToActiveTree();
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,
khushalsagar767dd522015-12-16 05:14:0583 layer_tree_host_->rendering_stats_instrumentation()));
enne2b0ad682016-09-21 01:44:4784 scheduler_on_impl_thread_.reset(
85 new Scheduler(this, scheduler_settings, layer_tree_host_->GetId(),
86 task_runner_provider_->MainThreadTaskRunner(),
87 std::move(compositor_timing_history)));
danakjfcdaba122015-04-24 21:41:5288 }
[email protected]94f206c12012-08-25 00:09:1489
Walter Kormanaa326e42017-08-22 23:04:4390 host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]a8a049c2013-03-11 23:27:0691}
92
93SingleThreadProxy::~SingleThreadProxy() {
94 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
khushalsagarb7db1fe2015-11-12 00:51:2795 DCHECK(task_runner_provider_->IsMainThread());
[email protected]04049fc2013-05-01 03:13:2096 // Make sure Stop() got called or never Started.
Walter Kormanaa326e42017-08-22 23:04:4397 DCHECK(!host_impl_);
[email protected]a8a049c2013-03-11 23:27:0698}
99
[email protected]a8a049c2013-03-11 23:27:06100bool SingleThreadProxy::IsStarted() const {
khushalsagarb7db1fe2015-11-12 00:51:27101 DCHECK(task_runner_provider_->IsMainThread());
Walter Kormanaa326e42017-08-22 23:04:43102 return !!host_impl_;
[email protected]94f206c12012-08-25 00:09:14103}
104
danakj009cdfdf2015-02-17 22:35:14105bool SingleThreadProxy::CommitToActiveTree() const {
106 // With SingleThreadProxy we skip the pending tree and commit directly to the
107 // active tree.
108 return true;
109}
110
[email protected]a8a049c2013-03-11 23:27:06111void SingleThreadProxy::SetVisible(bool visible) {
mithro46adf5a2014-11-19 14:52:40112 TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible);
khushalsagarb7db1fe2015-11-12 00:51:27113 DebugScopedSetImplThread impl(task_runner_provider_);
sunnypsc3f6e0c2015-07-25 01:00:59114
Walter Kormanaa326e42017-08-22 23:04:43115 host_impl_->SetVisible(visible);
sunnypsc3f6e0c2015-07-25 01:00:59116
[email protected]aeeedad2014-08-22 18:16:22117 if (scheduler_on_impl_thread_)
Walter Kormanaa326e42017-08-22 23:04:43118 scheduler_on_impl_thread_->SetVisible(host_impl_->visible());
[email protected]a8a049c2013-03-11 23:27:06119}
120
danakjc7afae52017-06-20 21:12:41121void SingleThreadProxy::RequestNewLayerTreeFrameSink() {
khushalsagarb7db1fe2015-11-12 00:51:27122 DCHECK(task_runner_provider_->IsMainThread());
danakjc7afae52017-06-20 21:12:41123 layer_tree_frame_sink_creation_callback_.Cancel();
124 if (layer_tree_frame_sink_creation_requested_)
jbauman8ab0f9e2014-10-15 02:30:34125 return;
danakjc7afae52017-06-20 21:12:41126 layer_tree_frame_sink_creation_requested_ = true;
127 layer_tree_host_->RequestNewLayerTreeFrameSink();
enne2097cab2014-09-25 20:16:31128}
[email protected]94f206c12012-08-25 00:09:14129
danakjc7afae52017-06-20 21:12:41130void SingleThreadProxy::ReleaseLayerTreeFrameSink() {
131 layer_tree_frame_sink_lost_ = true;
samans44b6dfc2017-04-19 16:50:53132 frame_sink_bound_weak_factory_.InvalidateWeakPtrs();
sohan.jyoti3a33d872015-09-18 22:32:55133 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41134 scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink();
Walter Kormanaa326e42017-08-22 23:04:43135 return host_impl_->ReleaseLayerTreeFrameSink();
sohan.jyoti3a33d872015-09-18 22:32:55136}
137
danakjc7afae52017-06-20 21:12:41138void SingleThreadProxy::SetLayerTreeFrameSink(
139 LayerTreeFrameSink* layer_tree_frame_sink) {
khushalsagarb7db1fe2015-11-12 00:51:27140 DCHECK(task_runner_provider_->IsMainThread());
danakjc7afae52017-06-20 21:12:41141 DCHECK(layer_tree_frame_sink_creation_requested_);
[email protected]da8e3b72b2014-04-25 02:33:45142
enne7f8fdde2014-12-10 21:32:09143 bool success;
144 {
khushalsagarb7db1fe2015-11-12 00:51:27145 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
146 DebugScopedSetImplThread impl(task_runner_provider_);
Xu Xing31616b92018-06-28 00:24:27147 success = host_impl_->InitializeFrameSink(layer_tree_frame_sink);
[email protected]04049fc2013-05-01 03:13:20148 }
149
[email protected]aeeedad2014-08-22 18:16:22150 if (success) {
samans44b6dfc2017-04-19 16:50:53151 frame_sink_bound_weak_ptr_ = frame_sink_bound_weak_factory_.GetWeakPtr();
danakjc7afae52017-06-20 21:12:41152 layer_tree_host_->DidInitializeLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22153 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41154 scheduler_on_impl_thread_->DidCreateAndInitializeLayerTreeFrameSink();
jbauman399aec1a2014-10-25 02:33:32155 else if (!inside_synchronous_composite_)
156 SetNeedsCommit();
danakjc7afae52017-06-20 21:12:41157 layer_tree_frame_sink_creation_requested_ = false;
158 layer_tree_frame_sink_lost_ = false;
enne7f8fdde2014-12-10 21:32:09159 } else {
danakjc7afae52017-06-20 21:12:41160 // DidFailToInitializeLayerTreeFrameSink is treated as a
161 // RequestNewLayerTreeFrameSink, and so
162 // layer_tree_frame_sink_creation_requested remains true.
163 layer_tree_host_->DidFailToInitializeLayerTreeFrameSink();
[email protected]04049fc2013-05-01 03:13:20164 }
[email protected]94f206c12012-08-25 00:09:14165}
166
[email protected]8b9e52b2014-01-17 16:35:31167void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20168 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
khushalsagarb7db1fe2015-11-12 00:51:27169 DCHECK(task_runner_provider_->IsMainThread());
brianderson49e101d22015-04-29 00:05:33170 if (animate_requested_)
171 return;
172 animate_requested_ = true;
khushalsagarb7db1fe2015-11-12 00:51:27173 DebugScopedSetImplThread impl(task_runner_provider_);
brianderson49e101d22015-04-29 00:05:33174 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01175 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]c5134172013-12-11 06:19:48176}
177
[email protected]8b9e52b2014-01-17 16:35:31178void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20179 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
khushalsagarb7db1fe2015-11-12 00:51:27180 DCHECK(task_runner_provider_->IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22181 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31182}
183
enne98f3a6c2014-10-09 20:09:44184void SingleThreadProxy::DoCommit() {
[email protected]ccc08dc2014-01-30 07:33:20185 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
khushalsagarb7db1fe2015-11-12 00:51:27186 DCHECK(task_runner_provider_->IsMainThread());
enne98f3a6c2014-10-09 20:09:44187
[email protected]aeeedad2014-08-22 18:16:22188 layer_tree_host_->WillCommit();
caseq7d2f4c92015-02-04 16:43:27189 devtools_instrumentation::ScopedCommitTrace commit_task(
khushalsagarcebe4942016-09-07 23:27:01190 layer_tree_host_->GetId());
[email protected]aeeedad2014-08-22 18:16:22191
[email protected]a8a049c2013-03-11 23:27:06192 // Commit immediately.
193 {
khushalsagarb7db1fe2015-11-12 00:51:27194 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
195 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]f7c01c82013-07-02 22:58:46196
Walter Kormanaa326e42017-08-22 23:04:43197 host_impl_->ReadyToCommit();
198 host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14199
Walter Kormanaa326e42017-08-22 23:04:43200 if (host_impl_->EvictedUIResourcesExist())
khushalsagar8ec07402016-09-10 03:13:19201 layer_tree_host_->GetUIResourceManager()->RecreateUIResources();
[email protected]127bdc1a2013-09-11 01:44:48202
Walter Kormanaa326e42017-08-22 23:04:43203 layer_tree_host_->FinishCommitOnImplThread(host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14204
danakj3c3973b2015-08-25 21:50:18205 if (scheduler_on_impl_thread_)
206 scheduler_on_impl_thread_->DidCommit();
207
vmpstra840c6a2017-06-01 21:50:39208 IssueImageDecodeFinishedCallbacks();
Walter Kormanaa326e42017-08-22 23:04:43209 host_impl_->CommitComplete();
danakj3c3973b2015-08-25 21:50:18210
danakj68803fc2015-06-19 20:55:53211 // Commit goes directly to the active tree, but we need to synchronously
212 // "activate" the tree still during commit to satisfy any potential
213 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
214 // might not be ready to draw, so DidActivateSyncTree must set
215 // the flag to force the tree to not draw until textures are ready.
216 NotifyReadyToActivate();
enne98f3a6c2014-10-09 20:09:44217 }
218}
219
vmpstra840c6a2017-06-01 21:50:39220void SingleThreadProxy::IssueImageDecodeFinishedCallbacks() {
221 DCHECK(task_runner_provider_->IsImplThread());
222
Vladimir Levinbed5b372017-10-26 23:46:31223 layer_tree_host_->ImageDecodesFinished(
224 host_impl_->TakeCompletedImageDecodeRequests());
vmpstra840c6a2017-06-01 21:50:39225}
226
enne98f3a6c2014-10-09 20:09:44227void SingleThreadProxy::CommitComplete() {
danakj3c3973b2015-08-25 21:50:18228 // Commit complete happens on the main side after activate to satisfy any
229 // SetNextCommitWaitsForActivation calls.
Walter Kormanaa326e42017-08-22 23:04:43230 DCHECK(!host_impl_->pending_tree())
enne98f3a6c2014-10-09 20:09:44231 << "Activation is expected to have synchronously occurred by now.";
enne98f3a6c2014-10-09 20:09:44232
khushalsagarb7db1fe2015-11-12 00:51:27233 DebugScopedSetMainThread main(task_runner_provider_);
Christian Dullweber59cd28c22019-02-20 12:28:00234 layer_tree_host_->DidBeginMainFrame();
Stefan Zager148248c2019-02-20 23:24:08235 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22236
[email protected]a8a049c2013-03-11 23:27:06237 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14238}
239
[email protected]a8a049c2013-03-11 23:27:06240void SingleThreadProxy::SetNeedsCommit() {
khushalsagarb7db1fe2015-11-12 00:51:27241 DCHECK(task_runner_provider_->IsMainThread());
danakj6c872fc02016-10-22 04:29:49242 single_thread_client_->RequestScheduleComposite();
danakjfcdaba122015-04-24 21:41:52243 if (commit_requested_)
244 return;
brianderson49e101d22015-04-29 00:05:33245 commit_requested_ = true;
khushalsagarb7db1fe2015-11-12 00:51:27246 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22247 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01248 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]94f206c12012-08-25 00:09:14249}
250
[email protected]0023fc72014-01-10 20:05:06251void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20252 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
khushalsagarb7db1fe2015-11-12 00:51:27253 DCHECK(task_runner_provider_->IsMainThread());
254 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43255 host_impl_->SetViewportDamage(damage_rect);
danakje41d978a2016-09-19 21:09:28256 SetNeedsRedrawOnImplThread();
[email protected]94f206c12012-08-25 00:09:14257}
258
[email protected]74b43cc2013-08-30 06:29:27259void SingleThreadProxy::SetNextCommitWaitsForActivation() {
enne98f3a6c2014-10-09 20:09:44260 // Activation always forced in commit, so nothing to do.
khushalsagarb7db1fe2015-11-12 00:51:27261 DCHECK(task_runner_provider_->IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27262}
263
danakje6da4f12018-07-04 17:41:30264bool SingleThreadProxy::RequestedAnimatePending() {
David Bokaneaa5cc82018-10-12 15:50:40265 return animate_requested_ || commit_requested_ || needs_impl_frame_;
danakje6da4f12018-07-04 17:41:30266}
267
Stephen Chenney6d3f5ce2018-11-14 02:08:05268void SingleThreadProxy::SetDeferMainFrameUpdate(bool defer_main_frame_update) {
khushalsagarb7db1fe2015-11-12 00:51:27269 DCHECK(task_runner_provider_->IsMainThread());
Stephen Chenney0c8cc37e2019-01-29 21:32:39270 // Deferring main frame updates only makes sense if there's a scheduler.
[email protected]aeeedad2014-08-22 18:16:22271 if (!scheduler_on_impl_thread_)
272 return;
Stephen Chenney6d3f5ce2018-11-14 02:08:05273 if (defer_main_frame_update_ == defer_main_frame_update)
[email protected]aeeedad2014-08-22 18:16:22274 return;
275
Stephen Chenney6d3f5ce2018-11-14 02:08:05276 if (defer_main_frame_update)
277 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate",
278 this);
[email protected]aeeedad2014-08-22 18:16:22279 else
Stephen Chenney6d3f5ce2018-11-14 02:08:05280 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate",
281 this);
[email protected]aeeedad2014-08-22 18:16:22282
Stephen Chenney6d3f5ce2018-11-14 02:08:05283 defer_main_frame_update_ = defer_main_frame_update;
Stephen Chenney0c8cc37e2019-01-29 21:32:39284
Stephen Chenney0f241862019-02-06 01:07:47285 // The scheduler needs to know that it should not issue BeginMainFrame.
286 scheduler_on_impl_thread_->SetDeferBeginMainFrame(defer_main_frame_update_);
Stephen Chenney0c8cc37e2019-01-29 21:32:39287}
288
289void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
290 DCHECK(task_runner_provider_->IsMainThread());
Stephen Chenney0f241862019-02-06 01:07:47291
Stephen Chenney0c8cc37e2019-01-29 21:32:39292 if (defer_commits_ == defer_commits)
293 return;
294
295 if (defer_commits)
296 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
297 else
298 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
299
300 defer_commits_ = defer_commits;
[email protected]6b16679e2012-10-27 00:44:28301}
302
[email protected]174c6d42014-08-12 01:43:06303bool SingleThreadProxy::CommitRequested() const {
khushalsagarb7db1fe2015-11-12 00:51:27304 DCHECK(task_runner_provider_->IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22305 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06306}
[email protected]a8a049c2013-03-11 23:27:06307
[email protected]a8a049c2013-03-11 23:27:06308void SingleThreadProxy::Stop() {
309 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
khushalsagarb7db1fe2015-11-12 00:51:27310 DCHECK(task_runner_provider_->IsMainThread());
[email protected]a8a049c2013-03-11 23:27:06311 {
khushalsagarb7db1fe2015-11-12 00:51:27312 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
313 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06314
sunnypsda928f0a2016-10-08 00:32:53315 // Prevent the scheduler from performing actions while we're in an
316 // inconsistent state.
317 if (scheduler_on_impl_thread_)
318 scheduler_on_impl_thread_->Stop();
danakjc7afae52017-06-20 21:12:41319 // Take away the LayerTreeFrameSink before destroying things so it doesn't
danakj1120f4c2016-09-15 02:05:32320 // try to call into its client mid-shutdown.
Walter Kormanaa326e42017-08-22 23:04:43321 host_impl_->ReleaseLayerTreeFrameSink();
Khushal7899efd2018-01-08 18:01:16322
323 // It is important to destroy LTHI before the Scheduler since it can make
324 // callbacks that access it during destruction cleanup.
Walter Kormanaa326e42017-08-22 23:04:43325 host_impl_ = nullptr;
Khushal7899efd2018-01-08 18:01:16326 scheduler_on_impl_thread_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06327 }
sunnypsda928f0a2016-10-08 00:32:53328 layer_tree_host_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06329}
330
flackrf54e9b42016-05-31 15:20:10331void SingleThreadProxy::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) {
332 DCHECK(task_runner_provider_->IsMainThread());
333 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43334 host_impl_->SetLayerTreeMutator(std::move(mutator));
flackrf54e9b42016-05-31 15:20:10335}
336
Xida Chend5ee5052019-01-03 13:27:51337void SingleThreadProxy::SetPaintWorkletLayerPainter(
338 std::unique_ptr<PaintWorkletLayerPainter> painter) {
339 NOTREACHED();
340}
341
[email protected]3d9f7432013-04-06 00:35:18342void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
sunnypsad3235e2016-08-09 04:57:52343 TRACE_EVENT1("cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw",
344 can_draw);
khushalsagarb7db1fe2015-11-12 00:51:27345 DCHECK(task_runner_provider_->IsImplThread());
[email protected]aeeedad2014-08-22 18:16:22346 if (scheduler_on_impl_thread_)
347 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18348}
349
[email protected]4f48f6e2013-08-27 06:33:38350void SingleThreadProxy::NotifyReadyToActivate() {
enne98f3a6c2014-10-09 20:09:44351 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
khushalsagarb7db1fe2015-11-12 00:51:27352 DebugScopedSetImplThread impl(task_runner_provider_);
rogerm8aeea932017-04-19 21:26:57353 if (scheduler_on_impl_thread_)
354 scheduler_on_impl_thread_->NotifyReadyToActivate();
[email protected]4f48f6e2013-08-27 06:33:38355}
356
ernstmdfac03e2014-11-11 20:18:05357void SingleThreadProxy::NotifyReadyToDraw() {
weiliangc8dac5a62015-04-02 06:12:35358 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToDraw");
khushalsagarb7db1fe2015-11-12 00:51:27359 DebugScopedSetImplThread impl(task_runner_provider_);
weiliangc8dac5a62015-04-02 06:12:35360 if (scheduler_on_impl_thread_)
361 scheduler_on_impl_thread_->NotifyReadyToDraw();
ernstmdfac03e2014-11-11 20:18:05362}
363
[email protected]c1bb5af2013-03-13 19:06:27364void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
danakj6c872fc02016-10-22 04:29:49365 single_thread_client_->RequestScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22366 if (scheduler_on_impl_thread_)
367 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06368}
369
danakja18e826a2015-12-03 00:27:03370void SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread() {
371 TRACE_EVENT0("cc",
372 "SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread");
danakj6c872fc02016-10-22 04:29:49373 single_thread_client_->RequestScheduleComposite();
mithro719bf6792014-11-10 15:36:47374 if (scheduler_on_impl_thread_)
danakja18e826a2015-12-03 00:27:03375 scheduler_on_impl_thread_->SetNeedsOneBeginImplFrame();
David Bokaneaa5cc82018-10-12 15:50:40376 needs_impl_frame_ = true;
[email protected]43b8f982014-04-30 21:24:33377}
378
vmiura59ea9b4042014-12-09 20:50:39379void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
380 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
enne98f3a6c2014-10-09 20:09:44381 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39382 scheduler_on_impl_thread_->SetNeedsPrepareTiles();
[email protected]c48536a52013-09-14 00:02:08383}
384
[email protected]c1bb5af2013-03-13 19:06:27385void SingleThreadProxy::SetNeedsCommitOnImplThread() {
danakj6c872fc02016-10-22 04:29:49386 single_thread_client_->RequestScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22387 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01388 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
David Bokaneaa5cc82018-10-12 15:50:40389 commit_requested_ = true;
[email protected]a8a049c2013-03-11 23:27:06390}
391
sunnyps7d073dc2015-04-16 23:29:12392void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
393 TRACE_EVENT1("cc", "SingleThreadProxy::SetVideoNeedsBeginFrames",
394 "needs_begin_frames", needs_begin_frames);
395 // In tests the layer tree is destroyed after the scheduler is.
396 if (scheduler_on_impl_thread_)
397 scheduler_on_impl_thread_->SetVideoNeedsBeginFrames(needs_begin_frames);
398}
399
[email protected]c1bb5af2013-03-13 19:06:27400void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
loysoc601b7b82016-11-10 02:56:44401 std::unique_ptr<MutatorEvents> events) {
[email protected]ccc08dc2014-01-30 07:33:20402 TRACE_EVENT0(
403 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
khushalsagarb7db1fe2015-11-12 00:51:27404 DCHECK(task_runner_provider_->IsImplThread());
405 DebugScopedSetMainThread main(task_runner_provider_);
danakja04855a2015-11-18 20:39:10406 layer_tree_host_->SetAnimationEvents(std::move(events));
[email protected]a8a049c2013-03-11 23:27:06407}
408
Xida Chend8bb3b22017-10-26 17:14:52409size_t SingleThreadProxy::CompositedAnimationsCount() const {
410 return 0;
411}
412
413size_t SingleThreadProxy::MainThreadAnimationsCount() const {
414 return 0;
415}
416
Stephen McGruer1619b422018-02-20 18:46:55417bool SingleThreadProxy::CurrentFrameHadRAF() const {
418 return false;
419}
420
421bool SingleThreadProxy::NextFrameHasPendingRAF() const {
422 return false;
423}
424
sunnypsad3235e2016-08-09 04:57:52425bool SingleThreadProxy::IsInsideDraw() {
426 return inside_draw_;
427}
[email protected]a8a049c2013-03-11 23:27:06428
enne98f3a6c2014-10-09 20:09:44429void SingleThreadProxy::DidActivateSyncTree() {
danakj68803fc2015-06-19 20:55:53430 CommitComplete();
enne98f3a6c2014-10-09 20:09:44431}
432
brianderson68749812015-07-07 22:39:39433void SingleThreadProxy::WillPrepareTiles() {
khushalsagarb7db1fe2015-11-12 00:51:27434 DCHECK(task_runner_provider_->IsImplThread());
brianderson68749812015-07-07 22:39:39435 if (scheduler_on_impl_thread_)
436 scheduler_on_impl_thread_->WillPrepareTiles();
437}
438
vmiura59ea9b4042014-12-09 20:50:39439void SingleThreadProxy::DidPrepareTiles() {
khushalsagarb7db1fe2015-11-12 00:51:27440 DCHECK(task_runner_provider_->IsImplThread());
enne98f3a6c2014-10-09 20:09:44441 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39442 scheduler_on_impl_thread_->DidPrepareTiles();
enne98f3a6c2014-10-09 20:09:44443}
444
rouslanf7ebd8832015-01-22 01:54:14445void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
446 layer_tree_host_->DidCompletePageScaleAnimation();
447}
448
danakjc7afae52017-06-20 21:12:41449void SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread() {
danakj1120f4c2016-09-15 02:05:32450 TRACE_EVENT0("cc",
danakjc7afae52017-06-20 21:12:41451 "SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22452 {
khushalsagarb7db1fe2015-11-12 00:51:27453 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22454 // This must happen before we notify the scheduler as it may try to recreate
455 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
danakjc7afae52017-06-20 21:12:41456 layer_tree_host_->DidLoseLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22457 }
danakjc7afae52017-06-20 21:12:41458 single_thread_client_->DidLoseLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22459 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41460 scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink();
461 layer_tree_frame_sink_lost_ = true;
[email protected]4d7e46a2013-11-08 05:33:40462}
463
Fady Samuelc645ffe2017-07-24 17:28:20464void SingleThreadProxy::SetBeginFrameSource(viz::BeginFrameSource* source) {
enne19c108582016-04-14 03:35:32465 if (scheduler_on_impl_thread_)
466 scheduler_on_impl_thread_->SetBeginFrameSource(source);
467}
468
danakj9d124422016-10-14 03:15:08469void SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread() {
miletusfed8c43b2015-01-26 20:04:52470 TRACE_EVENT0("cc,benchmark",
danakj9d124422016-10-14 03:15:08471 "SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22472 if (scheduler_on_impl_thread_)
danakj9d124422016-10-14 03:15:08473 scheduler_on_impl_thread_->DidReceiveCompositorFrameAck();
Karolina Soltys4d60b402018-10-01 19:28:20474 if (layer_tree_host_->GetSettings().send_compositor_frame_ack) {
475 // We do a PostTask here because freeing resources in some cases (such as in
476 // TextureLayer) is PostTasked and we want to make sure ack is received
477 // after resources are returned.
478 task_runner_provider_->MainThreadTaskRunner()->PostTask(
kylechar4bb144d2019-01-11 20:42:07479 FROM_HERE,
480 base::BindOnce(&SingleThreadProxy::DidReceiveCompositorFrameAck,
481 frame_sink_bound_weak_ptr_));
Karolina Soltys4d60b402018-10-01 19:28:20482 }
[email protected]493067512012-09-19 23:34:10483}
484
danakjc7afae52017-06-20 21:12:41485void SingleThreadProxy::OnDrawForLayerTreeFrameSink(
James Wallace-Leefbb0e3362018-06-18 23:57:47486 bool resourceless_software_draw,
487 bool skip_draw) {
sunnypseab5ac92015-04-02 20:26:13488 NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
489}
490
Khushal8360fc92017-07-26 01:53:25491void SingleThreadProxy::NeedsImplSideInvalidation(
492 bool needs_first_draw_on_activation) {
Khushal4b6c41882018-02-16 09:02:10493 if (scheduler_on_impl_thread_) {
494 scheduler_on_impl_thread_->SetNeedsImplSideInvalidation(
495 needs_first_draw_on_activation);
496 }
khushalsagard3b8827d2017-02-18 18:42:54497}
498
vmpstra840c6a2017-06-01 21:50:39499void SingleThreadProxy::NotifyImageDecodeRequestFinished() {
500 // If we don't have a scheduler, then just issue the callbacks here.
501 // Otherwise, schedule a commit.
502 if (!scheduler_on_impl_thread_) {
503 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
504 DebugScopedSetImplThread impl(task_runner_provider_);
505
506 IssueImageDecodeFinishedCallbacks();
507 return;
508 }
509 SetNeedsCommitOnImplThread();
510}
511
Scott Violete979c012017-12-08 00:18:16512void SingleThreadProxy::DidPresentCompositorFrameOnImplThread(
Sadrul Habib Chowdhury3d4df2e82018-06-02 05:18:00513 uint32_t frame_token,
514 std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
Sadrul Habib Chowdhuryb62a97302018-06-06 03:33:48515 const gfx::PresentationFeedback& feedback) {
Sadrul Habib Chowdhury3d4df2e82018-06-02 05:18:00516 layer_tree_host_->DidPresentCompositorFrame(frame_token, std::move(callbacks),
Sadrul Habib Chowdhuryb62a97302018-06-06 03:33:48517 feedback);
Scott Violete979c012017-12-08 00:18:16518}
519
Scott Violet7a340f42019-01-23 20:11:20520void SingleThreadProxy::DidGenerateLocalSurfaceIdAllocationOnImplThread(
521 const viz::LocalSurfaceIdAllocation& allocation) {
Scott Violet39db70b2019-02-04 23:35:20522 DebugScopedSetMainThread main(task_runner_provider_);
Scott Violet7a340f42019-01-23 20:11:20523 layer_tree_host_->DidGenerateLocalSurfaceIdAllocation(allocation);
524}
525
Kevin Ellis8272ed22019-03-01 21:03:18526void SingleThreadProxy::NotifyAnimationWorkletStateChange(
527 AnimationWorkletMutationState state,
528 ElementListType element_list_type) {
529 layer_tree_host_->NotifyAnimationWorkletStateChange(state, element_list_type);
530}
531
Scott Violet39db70b2019-02-04 23:35:20532uint32_t SingleThreadProxy::GenerateChildSurfaceSequenceNumberSync() {
533 DebugScopedSetImplThread impl(task_runner_provider_);
534 return host_impl_->GenerateChildSurfaceSequenceNumberSync();
535}
536
Dan Elphick95929fd52017-06-13 09:15:07537void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
538 if (scheduler_on_impl_thread_) {
539 scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected(
540 new_state);
541 }
542}
543
Khushal4b6c41882018-02-16 09:02:10544void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time,
545 bool raster) {
miletusfed8c43b2015-01-26 20:04:52546 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
khushalsagarb7db1fe2015-11-12 00:51:27547 DCHECK(task_runner_provider_->IsMainThread());
mithro51693e382015-05-07 23:52:41548#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13549 DCHECK(!inside_impl_frame_);
mithro51693e382015-05-07 23:52:41550#endif
jbauman399aec1a2014-10-25 02:33:32551 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
552
danakjc7afae52017-06-20 21:12:41553 if (layer_tree_frame_sink_lost_) {
554 RequestNewLayerTreeFrameSink();
555 // RequestNewLayerTreeFrameSink could have synchronously created an output
jbauman399aec1a2014-10-25 02:33:32556 // surface, so check again before returning.
danakjc7afae52017-06-20 21:12:41557 if (layer_tree_frame_sink_lost_)
jbauman399aec1a2014-10-25 02:33:32558 return;
559 }
[email protected]51f81da2014-05-16 21:29:26560
Fady Samuelc296f5fb2017-07-21 04:02:19561 viz::BeginFrameArgs begin_frame_args(viz::BeginFrameArgs::Create(
562 BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
563 frame_begin_time, base::TimeTicks(),
564 viz::BeginFrameArgs::DefaultInterval(), viz::BeginFrameArgs::NORMAL));
mithroc76d70312015-05-04 23:51:13565
566 // Start the impl frame.
enne98f3a6c2014-10-09 20:09:44567 {
khushalsagarb7db1fe2015-11-12 00:51:27568 DebugScopedSetImplThread impl(task_runner_provider_);
mithroc76d70312015-05-04 23:51:13569 WillBeginImplFrame(begin_frame_args);
570 }
571
572 // Run the "main thread" and get it to commit.
573 {
mithro51693e382015-05-07 23:52:41574#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13575 DCHECK(inside_impl_frame_);
mithro51693e382015-05-07 23:52:41576#endif
danakje6da4f12018-07-04 17:41:30577 animate_requested_ = false;
David Bokaneaa5cc82018-10-12 15:50:40578 needs_impl_frame_ = false;
danakje6da4f12018-07-04 17:41:30579 // Prevent new commits from being requested inside DoBeginMainFrame.
580 // Note: We do not want to prevent SetNeedsAnimate from requesting
581 // a commit here.
582 commit_requested_ = true;
enne98f3a6c2014-10-09 20:09:44583 DoBeginMainFrame(begin_frame_args);
danakje6da4f12018-07-04 17:41:30584 commit_requested_ = false;
danakj97660d92017-03-27 14:11:49585 DoPainting();
enne98f3a6c2014-10-09 20:09:44586 DoCommit();
[email protected]e0341352013-04-06 05:01:20587
khushalsagar8297ae992016-09-14 20:51:23588 DCHECK_EQ(
589 0u,
590 layer_tree_host_->GetSwapPromiseManager()->num_queued_swap_promises())
enne98f3a6c2014-10-09 20:09:44591 << "Commit should always succeed and transfer promises.";
592 }
593
mithroc76d70312015-05-04 23:51:13594 // Finish the impl frame.
enne98f3a6c2014-10-09 20:09:44595 {
khushalsagarb7db1fe2015-11-12 00:51:27596 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43597 host_impl_->ActivateSyncTree();
Khushal4b6c41882018-02-16 09:02:10598 if (raster) {
599 host_impl_->PrepareTiles();
600 host_impl_->SynchronouslyInitializeAllTiles();
601 }
enne69277cb2014-10-29 23:03:40602
danakj12e2f6e2015-08-19 22:25:44603 // TODO(danakj): Don't do this last... we prepared the wrong things. D:
Walter Kormanaa326e42017-08-22 23:04:43604 host_impl_->Animate();
mithro719bf6792014-11-10 15:36:47605
Khushal4b6c41882018-02-16 09:02:10606 if (raster) {
607 LayerTreeHostImpl::FrameData frame;
Sadrul Habib Chowdhury4a7940b2018-06-22 16:45:14608 frame.begin_frame_ack = viz::BeginFrameAck(begin_frame_args, true);
Khushal4b6c41882018-02-16 09:02:10609 DoComposite(&frame);
610 }
enne98f3a6c2014-10-09 20:09:44611
612 // DoComposite could abort, but because this is a synchronous composite
613 // another draw will never be scheduled, so break remaining promises.
Walter Kormanaa326e42017-08-22 23:04:43614 host_impl_->active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS);
mithroc76d70312015-05-04 23:51:13615
mithro51693e382015-05-07 23:52:41616 DidFinishImplFrame();
enne98f3a6c2014-10-09 20:09:44617 }
[email protected]74d9063c2013-01-18 03:14:47618}
619
[email protected]5d8bec72014-07-03 03:03:11620bool SingleThreadProxy::SupportsImplScrolling() const {
621 return false;
622}
623
[email protected]3d9f7432013-04-06 00:35:18624bool SingleThreadProxy::ShouldComposite() const {
khushalsagarb7db1fe2015-11-12 00:51:27625 DCHECK(task_runner_provider_->IsImplThread());
Walter Kormanaa326e42017-08-22 23:04:43626 return host_impl_->visible() && host_impl_->CanDraw();
[email protected]3d9f7432013-04-06 00:35:18627}
628
danakjc7afae52017-06-20 21:12:41629void SingleThreadProxy::ScheduleRequestNewLayerTreeFrameSink() {
630 if (layer_tree_frame_sink_creation_callback_.IsCancelled() &&
631 !layer_tree_frame_sink_creation_requested_) {
632 layer_tree_frame_sink_creation_callback_.Reset(
kylechar3ef69ec2019-01-16 21:07:15633 base::BindOnce(&SingleThreadProxy::RequestNewLayerTreeFrameSink,
634 weak_factory_.GetWeakPtr()));
khushalsagarb7db1fe2015-11-12 00:51:27635 task_runner_provider_->MainThreadTaskRunner()->PostTask(
danakjc7afae52017-06-20 21:12:41636 FROM_HERE, layer_tree_frame_sink_creation_callback_.callback());
jbauman8ab0f9e2014-10-15 02:30:34637 }
638}
639
mithro248d1722015-05-05 05:23:45640DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20641 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20642
enne98f3a6c2014-10-09 20:09:44643 DrawResult draw_result;
644 bool draw_frame;
[email protected]a8a049c2013-03-11 23:27:06645 {
khushalsagarb7db1fe2015-11-12 00:51:27646 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06647 base::AutoReset<bool> mark_inside(&inside_draw_, true);
648
[email protected]3d9f7432013-04-06 00:35:18649 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
650 // frame, so can only be used when such a frame is possible. Since
651 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
652 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50653 if (!ShouldComposite()) {
[email protected]aeeedad2014-08-22 18:16:22654 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18655 }
[email protected]a8a049c2013-03-11 23:27:06656
danakj097919e72016-09-07 19:50:55657 // This CapturePostTasks should be destroyed before
658 // DidCommitAndDrawFrame() is called since that goes out to the
659 // embedder, and we want the embedder to receive its callbacks before that.
660 // NOTE: This maintains consistent ordering with the ThreadProxy since
661 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
662 // there as the main thread is not blocked, so any posted tasks inside
663 // the swap buffers will execute first.
664 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
danakj097919e72016-09-07 19:50:55665
Walter Kormanaa326e42017-08-22 23:04:43666 draw_result = host_impl_->PrepareToDraw(frame);
enne98f3a6c2014-10-09 20:09:44667 draw_frame = draw_result == DRAW_SUCCESS;
robliao27728e62015-03-21 07:39:34668 if (draw_frame) {
Walter Kormanaa326e42017-08-22 23:04:43669 if (host_impl_->DrawLayers(frame)) {
danakj097919e72016-09-07 19:50:55670 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41671 // Drawing implies we submitted a frame to the LayerTreeFrameSink.
danakj9d124422016-10-14 03:15:08672 scheduler_on_impl_thread_->DidSubmitCompositorFrame();
danakj6c872fc02016-10-22 04:29:49673 single_thread_client_->DidSubmitCompositorFrame();
danakj097919e72016-09-07 19:50:55674 }
robliao27728e62015-03-21 07:39:34675 }
Walter Kormanaa326e42017-08-22 23:04:43676 host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06677
danakj097919e72016-09-07 19:50:55678 bool start_ready_animations = draw_frame;
Walter Kormanaa326e42017-08-22 23:04:43679 host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]aeeedad2014-08-22 18:16:22680 }
681 DidCommitAndDrawFrame();
682
enne98f3a6c2014-10-09 20:09:44683 return draw_result;
[email protected]a8a049c2013-03-11 23:27:06684}
685
[email protected]aeeedad2014-08-22 18:16:22686void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06687 if (next_frame_is_newly_committed_frame_) {
khushalsagarb7db1fe2015-11-12 00:51:27688 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06689 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21690 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06691 }
692}
693
[email protected]4ea293f72014-08-13 03:03:17694bool SingleThreadProxy::MainFrameWillHappenForTesting() {
danakjfcdaba122015-04-24 21:41:52695 if (!scheduler_on_impl_thread_)
696 return false;
697 return scheduler_on_impl_thread_->MainFrameForTestingWillHappen();
[email protected]4ea293f72014-08-13 03:03:17698}
[email protected]a8a049c2013-03-11 23:27:06699
Fady Samueld26f7fb2018-06-19 04:13:37700void SingleThreadProxy::ClearHistory() {
Khushal2f9cdf22018-01-08 21:47:08701 DCHECK(task_runner_provider_->IsImplThread());
702 if (scheduler_on_impl_thread_)
Fady Samueld26f7fb2018-06-19 04:13:37703 scheduler_on_impl_thread_->ClearHistory();
Khushal2f9cdf22018-01-08 21:47:08704}
705
jonrossa2ff4f82018-02-16 17:27:46706void SingleThreadProxy::SetRenderFrameObserver(
707 std::unique_ptr<RenderFrameMetadataObserver> observer) {
jonrossc1877d6d2018-02-21 00:07:31708 host_impl_->SetRenderFrameObserver(std::move(observer));
jonrossa2ff4f82018-02-16 17:27:46709}
710
David Bokan1e37ebf2018-10-16 13:53:37711void SingleThreadProxy::UpdateBrowserControlsState(
712 BrowserControlsState constraints,
713 BrowserControlsState current,
714 bool animate) {
715 host_impl_->browser_controls_manager()->UpdateBrowserControlsState(
716 constraints, current, animate);
717}
718
James Wallace-Leee71cf582018-01-29 22:24:23719bool SingleThreadProxy::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
danakja18e826a2015-12-03 00:27:03720 DebugScopedSetImplThread impl(task_runner_provider_);
mithro51693e382015-05-07 23:52:41721#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02722 DCHECK(!inside_impl_frame_)
723 << "WillBeginImplFrame called while already inside an impl frame!";
724 inside_impl_frame_ = true;
mithro51693e382015-05-07 23:52:41725#endif
James Wallace-Leee71cf582018-01-29 22:24:23726 return host_impl_->WillBeginImplFrame(args);
[email protected]aeeedad2014-08-22 18:16:22727}
728
brianderson266dc3a2015-11-12 03:16:40729void SingleThreadProxy::ScheduledActionSendBeginMainFrame(
Fady Samuelc296f5fb2017-07-21 04:02:19730 const viz::BeginFrameArgs& begin_frame_args) {
[email protected]aeeedad2014-08-22 18:16:22731 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
sunnypsad3235e2016-08-09 04:57:52732#if DCHECK_IS_ON()
[email protected]aeeedad2014-08-22 18:16:22733 // Although this proxy is single-threaded, it's problematic to synchronously
734 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
735 // could cause a commit to occur in between a series of SetNeedsCommit calls
736 // (i.e. property modifications) causing some to fall on one frame and some to
737 // fall on the next. Doing it asynchronously instead matches the semantics of
738 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
739 // synchronous commit.
mithro69fd3bb52015-05-01 03:45:02740 DCHECK(inside_impl_frame_)
741 << "BeginMainFrame should only be sent inside a BeginImplFrame";
mithro51693e382015-05-07 23:52:41742#endif
mithro69fd3bb52015-05-01 03:45:02743
Zhenyao Mo5b30cf32018-12-01 00:31:25744 host_impl_->WillSendBeginMainFrame();
khushalsagarb7db1fe2015-11-12 00:51:27745 task_runner_provider_->MainThreadTaskRunner()->PostTask(
tzik4604bb52017-04-13 21:50:22746 FROM_HERE, base::BindOnce(&SingleThreadProxy::BeginMainFrame,
747 weak_factory_.GetWeakPtr(), begin_frame_args));
Walter Kormanaa326e42017-08-22 23:04:43748 host_impl_->DidSendBeginMainFrame();
[email protected]aeeedad2014-08-22 18:16:22749}
750
kylechard96169b2018-11-02 00:55:00751void SingleThreadProxy::FrameIntervalUpdated(base::TimeDelta interval) {
752 DebugScopedSetMainThread main(task_runner_provider_);
753 single_thread_client_->FrameIntervalUpdated(interval);
754}
755
rmcilroy0a19362a2015-02-18 12:34:25756void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
757 layer_tree_host_->BeginMainFrameNotExpectedSoon();
758}
759
delphick9db74aa2017-05-05 10:20:49760void SingleThreadProxy::ScheduledActionBeginMainFrameNotExpectedUntil(
761 base::TimeTicks time) {
762 layer_tree_host_->BeginMainFrameNotExpectedUntil(time);
763}
764
Fady Samuelc296f5fb2017-07-21 04:02:19765void SingleThreadProxy::BeginMainFrame(
766 const viz::BeginFrameArgs& begin_frame_args) {
Brian Anderson242b9b02017-12-06 21:06:26767 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
768 // commit.
769 ScopedAbortRemainingSwapPromises swap_promise_checker(
770 layer_tree_host_->GetSwapPromiseManager());
771
brianderson21aef162015-11-11 05:12:23772 if (scheduler_on_impl_thread_) {
773 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(
774 base::TimeTicks::Now());
775 }
776
danakjfcdaba122015-04-24 21:41:52777 commit_requested_ = false;
David Bokaneaa5cc82018-10-12 15:50:40778 needs_impl_frame_ = false;
brianderson49e101d22015-04-29 00:05:33779 animate_requested_ = false;
danakjfcdaba122015-04-24 21:41:52780
Stephen Chenney6d3f5ce2018-11-14 02:08:05781 if (defer_main_frame_update_) {
Stephen Chenney0c8cc37e2019-01-29 21:32:39782 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferBeginMainFrame",
simonhongc6309f792015-01-31 15:47:15783 TRACE_EVENT_SCOPE_THREAD);
784 BeginMainFrameAbortedOnImplThread(
Stephen Chenney0c8cc37e2019-01-29 21:32:39785 CommitEarlyOutReason::ABORTED_DEFERRED_MAIN_FRAME_UPDATE);
[email protected]aeeedad2014-08-22 18:16:22786 return;
787 }
788
khushalsagarcebe4942016-09-07 23:27:01789 if (!layer_tree_host_->IsVisible()) {
[email protected]aeeedad2014-08-22 18:16:22790 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48791 BeginMainFrameAbortedOnImplThread(
792 CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
[email protected]aeeedad2014-08-22 18:16:22793 return;
794 }
795
danakjfcdaba122015-04-24 21:41:52796 // Prevent new commits from being requested inside DoBeginMainFrame.
brianderson49e101d22015-04-29 00:05:33797 // Note: We do not want to prevent SetNeedsAnimate from requesting
798 // a commit here.
danakjfcdaba122015-04-24 21:41:52799 commit_requested_ = true;
800
enne98f3a6c2014-10-09 20:09:44801 DoBeginMainFrame(begin_frame_args);
danakj97660d92017-03-27 14:11:49802
803 // New commits requested inside UpdateLayers should be respected.
804 commit_requested_ = false;
805
806 // At this point the main frame may have deferred commits to avoid committing
807 // right now.
Stephen Chenney0c8cc37e2019-01-29 21:32:39808 if (defer_main_frame_update_ || defer_commits_ ||
809 begin_frame_args.animate_only) {
danakj97660d92017-03-27 14:11:49810 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
811 TRACE_EVENT_SCOPE_THREAD);
812 BeginMainFrameAbortedOnImplThread(
813 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
814 layer_tree_host_->DidBeginMainFrame();
815 return;
816 }
817
Brian Anderson242b9b02017-12-06 21:06:26818 // Queue the LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT swap promise only once we
819 // know we will commit since QueueSwapPromise itself requests a commit.
820 ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
821 new_latency_info.AddLatencyNumberWithTimestamp(
Sadrul Habib Chowdhury41154dc02018-06-09 04:25:01822 ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, begin_frame_args.frame_time,
Navid Zolghadr5870ee112018-05-18 19:08:30823 1);
Brian Anderson242b9b02017-12-06 21:06:26824 layer_tree_host_->QueueSwapPromise(
825 std::make_unique<LatencyInfoSwapPromise>(new_latency_info));
826
danakj97660d92017-03-27 14:11:49827 DoPainting();
enne98f3a6c2014-10-09 20:09:44828}
829
830void SingleThreadProxy::DoBeginMainFrame(
Fady Samuelc296f5fb2017-07-21 04:02:19831 const viz::BeginFrameArgs& begin_frame_args) {
Khushal4b6c41882018-02-16 09:02:10832 // The impl-side scroll deltas may be manipulated directly via the
833 // InputHandler on the UI thread and the scale deltas may change when they are
834 // clamped on the impl thread.
tapted4b70c522016-08-13 09:09:32835 std::unique_ptr<ScrollAndScaleSet> scroll_info =
Walter Kormanaa326e42017-08-22 23:04:43836 host_impl_->ProcessScrollDeltas();
tapted4b70c522016-08-13 09:09:32837 layer_tree_host_->ApplyScrollAndScale(scroll_info.get());
838
enne98f3a6c2014-10-09 20:09:44839 layer_tree_host_->WillBeginMainFrame();
840 layer_tree_host_->BeginMainFrame(begin_frame_args);
841 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
Stephen Chenneyd56b5382019-01-29 00:37:02842 layer_tree_host_->RequestMainFrameUpdate();
danakj97660d92017-03-27 14:11:49843}
enne98f3a6c2014-10-09 20:09:44844
danakj97660d92017-03-27 14:11:49845void SingleThreadProxy::DoPainting() {
danakj5f46636a2015-06-19 00:01:40846 layer_tree_host_->UpdateLayers();
enne98f3a6c2014-10-09 20:09:44847
mithrof7a21502014-12-17 03:24:48848 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
849 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
850 // thread_proxy.cc
brianderson21aef162015-11-11 05:12:23851 if (scheduler_on_impl_thread_)
enne98f3a6c2014-10-09 20:09:44852 scheduler_on_impl_thread_->NotifyReadyToCommit();
[email protected]aeeedad2014-08-22 18:16:22853}
854
mithrof7a21502014-12-17 03:24:48855void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
856 CommitEarlyOutReason reason) {
khushalsagarb7db1fe2015-11-12 00:51:27857 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22858 DCHECK(scheduler_on_impl_thread_->CommitPending());
Walter Kormanaa326e42017-08-22 23:04:43859 DCHECK(!host_impl_->pending_tree());
[email protected]aeeedad2014-08-22 18:16:22860
sunnypsad3235e2016-08-09 04:57:52861 std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
Walter Kormanaa326e42017-08-22 23:04:43862 host_impl_->BeginMainFrameAborted(reason, std::move(empty_swap_promises));
mithrof7a21502014-12-17 03:24:48863 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
[email protected]aeeedad2014-08-22 18:16:22864}
865
danakj9d124422016-10-14 03:15:08866DrawResult SingleThreadProxy::ScheduledActionDrawIfPossible() {
khushalsagarb7db1fe2015-11-12 00:51:27867 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22868 LayerTreeHostImpl::FrameData frame;
esecklerdde665f2017-03-07 20:19:27869 frame.begin_frame_ack =
870 scheduler_on_impl_thread_->CurrentBeginFrameAckForActiveTree();
mithro248d1722015-05-05 05:23:45871 return DoComposite(&frame);
[email protected]aeeedad2014-08-22 18:16:22872}
873
danakj9d124422016-10-14 03:15:08874DrawResult SingleThreadProxy::ScheduledActionDrawForced() {
[email protected]aeeedad2014-08-22 18:16:22875 NOTREACHED();
876 return INVALID_RESULT;
877}
878
879void SingleThreadProxy::ScheduledActionCommit() {
khushalsagarb7db1fe2015-11-12 00:51:27880 DebugScopedSetMainThread main(task_runner_provider_);
enne98f3a6c2014-10-09 20:09:44881 DoCommit();
[email protected]aeeedad2014-08-22 18:16:22882}
883
[email protected]aeeedad2014-08-22 18:16:22884void SingleThreadProxy::ScheduledActionActivateSyncTree() {
khushalsagarb7db1fe2015-11-12 00:51:27885 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43886 host_impl_->ActivateSyncTree();
[email protected]aeeedad2014-08-22 18:16:22887}
888
danakjc7afae52017-06-20 21:12:41889void SingleThreadProxy::ScheduledActionBeginLayerTreeFrameSinkCreation() {
khushalsagarb7db1fe2015-11-12 00:51:27890 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22891 DCHECK(scheduler_on_impl_thread_);
892 // If possible, create the output surface in a post task. Synchronously
893 // creating the output surface makes tests more awkward since this differs
894 // from the ThreadProxy behavior. However, sometimes there is no
895 // task runner.
khushalsagarb7db1fe2015-11-12 00:51:27896 if (task_runner_provider_->MainThreadTaskRunner()) {
danakjc7afae52017-06-20 21:12:41897 ScheduleRequestNewLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22898 } else {
danakjc7afae52017-06-20 21:12:41899 RequestNewLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22900 }
901}
902
vmiura59ea9b4042014-12-09 20:50:39903void SingleThreadProxy::ScheduledActionPrepareTiles() {
904 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
khushalsagarb7db1fe2015-11-12 00:51:27905 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43906 host_impl_->PrepareTiles();
[email protected]aeeedad2014-08-22 18:16:22907}
908
James Wallace-Leefbb0e3362018-06-18 23:57:47909void SingleThreadProxy::ScheduledActionInvalidateLayerTreeFrameSink(
910 bool needs_redraw) {
danakja5df53792018-04-26 18:36:39911 // This is an Android WebView codepath, which only uses multi-thread
912 // compositor. So this should not occur in single-thread mode.
913 NOTREACHED() << "Android Webview use-case, so multi-thread only";
sunnypseab5ac92015-04-02 20:26:13914}
915
khushalsagarab73d502017-02-24 02:26:46916void SingleThreadProxy::ScheduledActionPerformImplSideInvalidation() {
khushalsagar6dc91d02017-02-28 05:10:07917 DCHECK(scheduler_on_impl_thread_);
918
919 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43920 host_impl_->InvalidateContentOnImplSide();
khushalsagar6dc91d02017-02-28 05:10:07921
922 // Invalidations go directly to the active tree, so we synchronously call
923 // NotifyReadyToActivate to update the scheduler and LTHI state correctly.
924 // Since in single-threaded mode the scheduler will wait for a ready to draw
925 // signal from LTHI, the draw will remain blocked till the invalidated tiles
926 // are ready.
927 NotifyReadyToActivate();
khushalsagarab73d502017-02-24 02:26:46928}
929
mithro51693e382015-05-07 23:52:41930void SingleThreadProxy::DidFinishImplFrame() {
Walter Kormanaa326e42017-08-22 23:04:43931 host_impl_->DidFinishImplFrame();
mithro51693e382015-05-07 23:52:41932#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02933 DCHECK(inside_impl_frame_)
mithro51693e382015-05-07 23:52:41934 << "DidFinishImplFrame called while not inside an impl frame!";
mithro69fd3bb52015-05-01 03:45:02935 inside_impl_frame_ = false;
mithro51693e382015-05-07 23:52:41936#endif
[email protected]aeeedad2014-08-22 18:16:22937}
938
Fady Samuelc296f5fb2017-07-21 04:02:19939void SingleThreadProxy::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
eseckler9404a232017-05-22 14:49:43940 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43941 host_impl_->DidNotProduceFrame(ack);
eseckler9404a232017-05-22 14:49:43942}
943
yiyix807099e2018-11-09 05:24:28944void SingleThreadProxy::WillNotReceiveBeginFrame() {
945 host_impl_->DidNotNeedBeginFrame();
946}
947
samans44b6dfc2017-04-19 16:50:53948void SingleThreadProxy::DidReceiveCompositorFrameAck() {
949 layer_tree_host_->DidReceiveCompositorFrameAck();
950}
951
[email protected]bc5e77c2012-11-05 20:00:49952} // namespace cc