blob: ccc800a61a3e0c7fd5161acdaf69e1a71cd8aaf6 [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"
danakj60bc3bc2016-04-09 00:24:488#include "base/memory/ptr_util.h"
primianoc06e2382015-01-28 04:21:499#include "base/trace_event/trace_event.h"
chrishtr82b5d9502017-03-20 18:25:3310#include "cc/base/devtools_instrumentation.h"
11#include "cc/benchmarks/benchmark_instrumentation.h"
khushalsagar8ec07402016-09-10 03:13:1912#include "cc/resources/ui_resource_manager.h"
mithrof7a21502014-12-17 03:24:4813#include "cc/scheduler/commit_earlyout_reason.h"
briandersonc9f50352015-06-24 03:38:5814#include "cc/scheduler/compositor_timing_history.h"
15#include "cc/scheduler/scheduler.h"
Brian Anderson242b9b02017-12-06 21:06:2616#include "cc/trees/latency_info_swap_promise.h"
danakjba65a0912017-09-21 16:38:4217#include "cc/trees/layer_tree_frame_sink.h"
khushalsagare0e4486e2017-01-25 03:15:0318#include "cc/trees/layer_tree_host.h"
jaydasika13c05062016-04-01 18:12:2719#include "cc/trees/layer_tree_host_common.h"
[email protected]943528e2013-11-07 05:01:3220#include "cc/trees/layer_tree_host_single_thread_client.h"
[email protected]556fd292013-03-18 08:03:0421#include "cc/trees/layer_tree_impl.h"
loysoc601b7b82016-11-10 02:56:4422#include "cc/trees/mutator_host.h"
jonrossa2ff4f82018-02-16 17:27:4623#include "cc/trees/render_frame_metadata_observer.h"
[email protected]aeeedad2014-08-22 18:16:2224#include "cc/trees/scoped_abort_remaining_swap_promises.h"
Fady Samuelc645ffe2017-07-24 17:28:2025#include "components/viz/common/frame_sinks/delay_based_time_source.h"
Xu Xing32549162017-07-17 22:25:4326#include "components/viz/common/gpu/context_provider.h"
[email protected]94f206c12012-08-25 00:09:1427
[email protected]9c88e562012-09-14 22:21:3028namespace cc {
[email protected]94f206c12012-08-25 00:09:1429
danakj60bc3bc2016-04-09 00:24:4830std::unique_ptr<Proxy> SingleThreadProxy::Create(
khushalsagare0e4486e2017-01-25 03:15:0331 LayerTreeHost* layer_tree_host,
[email protected]27e6a212014-07-18 15:51:2732 LayerTreeHostSingleThreadClient* client,
khushalsagar767dd522015-12-16 05:14:0533 TaskRunnerProvider* task_runner_provider) {
danakj60bc3bc2016-04-09 00:24:4834 return base::WrapUnique(
khushalsagar767dd522015-12-16 05:14:0535 new SingleThreadProxy(layer_tree_host, client, task_runner_provider));
[email protected]94f206c12012-08-25 00:09:1436}
37
khushalsagare0e4486e2017-01-25 03:15:0338SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
khushalsagar767dd522015-12-16 05:14:0539 LayerTreeHostSingleThreadClient* client,
40 TaskRunnerProvider* task_runner_provider)
khushalsagarb7db1fe2015-11-12 00:51:2741 : layer_tree_host_(layer_tree_host),
danakj6c872fc02016-10-22 04:29:4942 single_thread_client_(client),
khushalsagarb7db1fe2015-11-12 00:51:2743 task_runner_provider_(task_runner_provider),
[email protected]a8a049c2013-03-11 23:27:0644 next_frame_is_newly_committed_frame_(false),
mithro51693e382015-05-07 23:52:4145#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:0246 inside_impl_frame_(false),
mithro51693e382015-05-07 23:52:4147#endif
[email protected]aeeedad2014-08-22 18:16:2248 inside_draw_(false),
49 defer_commits_(false),
brianderson49e101d22015-04-29 00:05:3350 animate_requested_(false),
[email protected]aeeedad2014-08-22 18:16:2251 commit_requested_(false),
jbauman399aec1a2014-10-25 02:33:3252 inside_synchronous_composite_(false),
danakjc7afae52017-06-20 21:12:4153 layer_tree_frame_sink_creation_requested_(false),
54 layer_tree_frame_sink_lost_(true),
samans44b6dfc2017-04-19 16:50:5355 frame_sink_bound_weak_factory_(this),
[email protected]aeeedad2014-08-22 18:16:2256 weak_factory_(this) {
[email protected]a8a049c2013-03-11 23:27:0657 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
khushalsagarb7db1fe2015-11-12 00:51:2758 DCHECK(task_runner_provider_);
59 DCHECK(task_runner_provider_->IsMainThread());
[email protected]a8a049c2013-03-11 23:27:0660 DCHECK(layer_tree_host);
khushalsagar767dd522015-12-16 05:14:0561}
danakjfcdaba122015-04-24 21:41:5262
enne2b0ad682016-09-21 01:44:4763void SingleThreadProxy::Start() {
khushalsagar767dd522015-12-16 05:14:0564 DebugScopedSetImplThread impl(task_runner_provider_);
khushalsagar767dd522015-12-16 05:14:0565
khushalsagarcebe4942016-09-07 23:27:0166 const LayerTreeSettings& settings = layer_tree_host_->GetSettings();
khushalsagar6dc91d02017-02-28 05:10:0767 DCHECK(settings.single_thread_proxy_scheduler ||
68 !settings.enable_checker_imaging)
69 << "Checker-imaging is not supported in synchronous single threaded mode";
khushalsagarcebe4942016-09-07 23:27:0170 if (settings.single_thread_proxy_scheduler && !scheduler_on_impl_thread_) {
71 SchedulerSettings scheduler_settings(settings.ToSchedulerSettings());
danakj5f2e92de2015-06-20 00:25:5872 scheduler_settings.commit_to_active_tree = CommitToActiveTree();
briandersonc9f50352015-06-24 03:38:5873
danakj60bc3bc2016-04-09 00:24:4874 std::unique_ptr<CompositorTimingHistory> compositor_timing_history(
briandersonc9f50352015-06-24 03:38:5875 new CompositorTimingHistory(
briandersonbb917dd2016-02-20 05:21:1476 scheduler_settings.using_synchronous_renderer_compositor,
briandersonc68220f2015-07-20 20:08:3577 CompositorTimingHistory::BROWSER_UMA,
khushalsagar767dd522015-12-16 05:14:0578 layer_tree_host_->rendering_stats_instrumentation()));
enne2b0ad682016-09-21 01:44:4779 scheduler_on_impl_thread_.reset(
80 new Scheduler(this, scheduler_settings, layer_tree_host_->GetId(),
81 task_runner_provider_->MainThreadTaskRunner(),
82 std::move(compositor_timing_history)));
danakjfcdaba122015-04-24 21:41:5283 }
[email protected]94f206c12012-08-25 00:09:1484
Walter Kormanaa326e42017-08-22 23:04:4385 host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]a8a049c2013-03-11 23:27:0686}
87
88SingleThreadProxy::~SingleThreadProxy() {
89 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
khushalsagarb7db1fe2015-11-12 00:51:2790 DCHECK(task_runner_provider_->IsMainThread());
[email protected]04049fc2013-05-01 03:13:2091 // Make sure Stop() got called or never Started.
Walter Kormanaa326e42017-08-22 23:04:4392 DCHECK(!host_impl_);
[email protected]a8a049c2013-03-11 23:27:0693}
94
[email protected]a8a049c2013-03-11 23:27:0695bool SingleThreadProxy::IsStarted() const {
khushalsagarb7db1fe2015-11-12 00:51:2796 DCHECK(task_runner_provider_->IsMainThread());
Walter Kormanaa326e42017-08-22 23:04:4397 return !!host_impl_;
[email protected]94f206c12012-08-25 00:09:1498}
99
danakj009cdfdf2015-02-17 22:35:14100bool SingleThreadProxy::CommitToActiveTree() const {
101 // With SingleThreadProxy we skip the pending tree and commit directly to the
102 // active tree.
103 return true;
104}
105
[email protected]a8a049c2013-03-11 23:27:06106void SingleThreadProxy::SetVisible(bool visible) {
mithro46adf5a2014-11-19 14:52:40107 TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible);
khushalsagarb7db1fe2015-11-12 00:51:27108 DebugScopedSetImplThread impl(task_runner_provider_);
sunnypsc3f6e0c2015-07-25 01:00:59109
Walter Kormanaa326e42017-08-22 23:04:43110 host_impl_->SetVisible(visible);
sunnypsc3f6e0c2015-07-25 01:00:59111
[email protected]aeeedad2014-08-22 18:16:22112 if (scheduler_on_impl_thread_)
Walter Kormanaa326e42017-08-22 23:04:43113 scheduler_on_impl_thread_->SetVisible(host_impl_->visible());
[email protected]a8a049c2013-03-11 23:27:06114}
115
danakjc7afae52017-06-20 21:12:41116void SingleThreadProxy::RequestNewLayerTreeFrameSink() {
khushalsagarb7db1fe2015-11-12 00:51:27117 DCHECK(task_runner_provider_->IsMainThread());
danakjc7afae52017-06-20 21:12:41118 layer_tree_frame_sink_creation_callback_.Cancel();
119 if (layer_tree_frame_sink_creation_requested_)
jbauman8ab0f9e2014-10-15 02:30:34120 return;
danakjc7afae52017-06-20 21:12:41121 layer_tree_frame_sink_creation_requested_ = true;
122 layer_tree_host_->RequestNewLayerTreeFrameSink();
enne2097cab2014-09-25 20:16:31123}
[email protected]94f206c12012-08-25 00:09:14124
danakjc7afae52017-06-20 21:12:41125void SingleThreadProxy::ReleaseLayerTreeFrameSink() {
126 layer_tree_frame_sink_lost_ = true;
samans44b6dfc2017-04-19 16:50:53127 frame_sink_bound_weak_factory_.InvalidateWeakPtrs();
sohan.jyoti3a33d872015-09-18 22:32:55128 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41129 scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink();
Walter Kormanaa326e42017-08-22 23:04:43130 return host_impl_->ReleaseLayerTreeFrameSink();
sohan.jyoti3a33d872015-09-18 22:32:55131}
132
danakjc7afae52017-06-20 21:12:41133void SingleThreadProxy::SetLayerTreeFrameSink(
134 LayerTreeFrameSink* layer_tree_frame_sink) {
khushalsagarb7db1fe2015-11-12 00:51:27135 DCHECK(task_runner_provider_->IsMainThread());
danakjc7afae52017-06-20 21:12:41136 DCHECK(layer_tree_frame_sink_creation_requested_);
[email protected]da8e3b72b2014-04-25 02:33:45137
enne7f8fdde2014-12-10 21:32:09138 bool success;
139 {
khushalsagarb7db1fe2015-11-12 00:51:27140 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
141 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43142 success = host_impl_->InitializeRenderer(layer_tree_frame_sink);
[email protected]04049fc2013-05-01 03:13:20143 }
144
[email protected]aeeedad2014-08-22 18:16:22145 if (success) {
samans44b6dfc2017-04-19 16:50:53146 frame_sink_bound_weak_ptr_ = frame_sink_bound_weak_factory_.GetWeakPtr();
danakjc7afae52017-06-20 21:12:41147 layer_tree_host_->DidInitializeLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22148 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41149 scheduler_on_impl_thread_->DidCreateAndInitializeLayerTreeFrameSink();
jbauman399aec1a2014-10-25 02:33:32150 else if (!inside_synchronous_composite_)
151 SetNeedsCommit();
danakjc7afae52017-06-20 21:12:41152 layer_tree_frame_sink_creation_requested_ = false;
153 layer_tree_frame_sink_lost_ = false;
enne7f8fdde2014-12-10 21:32:09154 } else {
danakjc7afae52017-06-20 21:12:41155 // DidFailToInitializeLayerTreeFrameSink is treated as a
156 // RequestNewLayerTreeFrameSink, and so
157 // layer_tree_frame_sink_creation_requested remains true.
158 layer_tree_host_->DidFailToInitializeLayerTreeFrameSink();
[email protected]04049fc2013-05-01 03:13:20159 }
[email protected]94f206c12012-08-25 00:09:14160}
161
[email protected]8b9e52b2014-01-17 16:35:31162void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20163 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
khushalsagarb7db1fe2015-11-12 00:51:27164 DCHECK(task_runner_provider_->IsMainThread());
danakj6c872fc02016-10-22 04:29:49165 single_thread_client_->RequestScheduleAnimation();
brianderson49e101d22015-04-29 00:05:33166 if (animate_requested_)
167 return;
168 animate_requested_ = true;
khushalsagarb7db1fe2015-11-12 00:51:27169 DebugScopedSetImplThread impl(task_runner_provider_);
brianderson49e101d22015-04-29 00:05:33170 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01171 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]c5134172013-12-11 06:19:48172}
173
[email protected]8b9e52b2014-01-17 16:35:31174void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20175 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
khushalsagarb7db1fe2015-11-12 00:51:27176 DCHECK(task_runner_provider_->IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22177 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31178}
179
enne98f3a6c2014-10-09 20:09:44180void SingleThreadProxy::DoCommit() {
[email protected]ccc08dc2014-01-30 07:33:20181 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
khushalsagarb7db1fe2015-11-12 00:51:27182 DCHECK(task_runner_provider_->IsMainThread());
enne98f3a6c2014-10-09 20:09:44183
[email protected]aeeedad2014-08-22 18:16:22184 layer_tree_host_->WillCommit();
caseq7d2f4c92015-02-04 16:43:27185 devtools_instrumentation::ScopedCommitTrace commit_task(
khushalsagarcebe4942016-09-07 23:27:01186 layer_tree_host_->GetId());
[email protected]aeeedad2014-08-22 18:16:22187
[email protected]a8a049c2013-03-11 23:27:06188 // Commit immediately.
189 {
khushalsagarb7db1fe2015-11-12 00:51:27190 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
191 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]f7c01c82013-07-02 22:58:46192
Walter Kormanaa326e42017-08-22 23:04:43193 host_impl_->ReadyToCommit();
194 host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14195
Walter Kormanaa326e42017-08-22 23:04:43196 if (host_impl_->EvictedUIResourcesExist())
khushalsagar8ec07402016-09-10 03:13:19197 layer_tree_host_->GetUIResourceManager()->RecreateUIResources();
[email protected]127bdc1a2013-09-11 01:44:48198
Walter Kormanaa326e42017-08-22 23:04:43199 layer_tree_host_->FinishCommitOnImplThread(host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14200
danakj3c3973b2015-08-25 21:50:18201 if (scheduler_on_impl_thread_)
202 scheduler_on_impl_thread_->DidCommit();
203
vmpstra840c6a2017-06-01 21:50:39204 IssueImageDecodeFinishedCallbacks();
Walter Kormanaa326e42017-08-22 23:04:43205 host_impl_->CommitComplete();
danakj3c3973b2015-08-25 21:50:18206
danakj68803fc2015-06-19 20:55:53207 // Commit goes directly to the active tree, but we need to synchronously
208 // "activate" the tree still during commit to satisfy any potential
209 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
210 // might not be ready to draw, so DidActivateSyncTree must set
211 // the flag to force the tree to not draw until textures are ready.
212 NotifyReadyToActivate();
enne98f3a6c2014-10-09 20:09:44213 }
214}
215
vmpstra840c6a2017-06-01 21:50:39216void SingleThreadProxy::IssueImageDecodeFinishedCallbacks() {
217 DCHECK(task_runner_provider_->IsImplThread());
218
Vladimir Levinbed5b372017-10-26 23:46:31219 layer_tree_host_->ImageDecodesFinished(
220 host_impl_->TakeCompletedImageDecodeRequests());
vmpstra840c6a2017-06-01 21:50:39221}
222
enne98f3a6c2014-10-09 20:09:44223void SingleThreadProxy::CommitComplete() {
danakj3c3973b2015-08-25 21:50:18224 // Commit complete happens on the main side after activate to satisfy any
225 // SetNextCommitWaitsForActivation calls.
Walter Kormanaa326e42017-08-22 23:04:43226 DCHECK(!host_impl_->pending_tree())
enne98f3a6c2014-10-09 20:09:44227 << "Activation is expected to have synchronously occurred by now.";
enne98f3a6c2014-10-09 20:09:44228
khushalsagarb7db1fe2015-11-12 00:51:27229 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]804c8982013-03-13 16:32:21230 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22231 layer_tree_host_->DidBeginMainFrame();
[email protected]aeeedad2014-08-22 18:16:22232
[email protected]a8a049c2013-03-11 23:27:06233 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14234}
235
[email protected]a8a049c2013-03-11 23:27:06236void SingleThreadProxy::SetNeedsCommit() {
khushalsagarb7db1fe2015-11-12 00:51:27237 DCHECK(task_runner_provider_->IsMainThread());
danakj6c872fc02016-10-22 04:29:49238 single_thread_client_->RequestScheduleComposite();
danakjfcdaba122015-04-24 21:41:52239 if (commit_requested_)
240 return;
brianderson49e101d22015-04-29 00:05:33241 commit_requested_ = true;
khushalsagarb7db1fe2015-11-12 00:51:27242 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22243 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01244 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]94f206c12012-08-25 00:09:14245}
246
[email protected]0023fc72014-01-10 20:05:06247void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20248 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
khushalsagarb7db1fe2015-11-12 00:51:27249 DCHECK(task_runner_provider_->IsMainThread());
250 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43251 host_impl_->SetViewportDamage(damage_rect);
danakje41d978a2016-09-19 21:09:28252 SetNeedsRedrawOnImplThread();
[email protected]94f206c12012-08-25 00:09:14253}
254
[email protected]74b43cc2013-08-30 06:29:27255void SingleThreadProxy::SetNextCommitWaitsForActivation() {
enne98f3a6c2014-10-09 20:09:44256 // Activation always forced in commit, so nothing to do.
khushalsagarb7db1fe2015-11-12 00:51:27257 DCHECK(task_runner_provider_->IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27258}
259
[email protected]a8a049c2013-03-11 23:27:06260void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
khushalsagarb7db1fe2015-11-12 00:51:27261 DCHECK(task_runner_provider_->IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22262 // Deferring commits only makes sense if there's a scheduler.
263 if (!scheduler_on_impl_thread_)
264 return;
265 if (defer_commits_ == defer_commits)
266 return;
267
268 if (defer_commits)
269 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
270 else
271 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
272
273 defer_commits_ = defer_commits;
simonhongc6309f792015-01-31 15:47:15274 scheduler_on_impl_thread_->SetDeferCommits(defer_commits);
[email protected]6b16679e2012-10-27 00:44:28275}
276
[email protected]174c6d42014-08-12 01:43:06277bool SingleThreadProxy::CommitRequested() const {
khushalsagarb7db1fe2015-11-12 00:51:27278 DCHECK(task_runner_provider_->IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22279 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06280}
[email protected]a8a049c2013-03-11 23:27:06281
[email protected]a8a049c2013-03-11 23:27:06282void SingleThreadProxy::Stop() {
283 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
khushalsagarb7db1fe2015-11-12 00:51:27284 DCHECK(task_runner_provider_->IsMainThread());
[email protected]a8a049c2013-03-11 23:27:06285 {
khushalsagarb7db1fe2015-11-12 00:51:27286 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
287 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06288
sunnypsda928f0a2016-10-08 00:32:53289 // Prevent the scheduler from performing actions while we're in an
290 // inconsistent state.
291 if (scheduler_on_impl_thread_)
292 scheduler_on_impl_thread_->Stop();
danakjc7afae52017-06-20 21:12:41293 // Take away the LayerTreeFrameSink before destroying things so it doesn't
danakj1120f4c2016-09-15 02:05:32294 // try to call into its client mid-shutdown.
Walter Kormanaa326e42017-08-22 23:04:43295 host_impl_->ReleaseLayerTreeFrameSink();
Khushal7899efd2018-01-08 18:01:16296
297 // It is important to destroy LTHI before the Scheduler since it can make
298 // callbacks that access it during destruction cleanup.
Walter Kormanaa326e42017-08-22 23:04:43299 host_impl_ = nullptr;
Khushal7899efd2018-01-08 18:01:16300 scheduler_on_impl_thread_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06301 }
sunnypsda928f0a2016-10-08 00:32:53302 layer_tree_host_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06303}
304
flackrf54e9b42016-05-31 15:20:10305void SingleThreadProxy::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) {
306 DCHECK(task_runner_provider_->IsMainThread());
307 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43308 host_impl_->SetLayerTreeMutator(std::move(mutator));
flackrf54e9b42016-05-31 15:20:10309}
310
[email protected]3d9f7432013-04-06 00:35:18311void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
sunnypsad3235e2016-08-09 04:57:52312 TRACE_EVENT1("cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw",
313 can_draw);
khushalsagarb7db1fe2015-11-12 00:51:27314 DCHECK(task_runner_provider_->IsImplThread());
[email protected]aeeedad2014-08-22 18:16:22315 if (scheduler_on_impl_thread_)
316 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18317}
318
[email protected]4f48f6e2013-08-27 06:33:38319void SingleThreadProxy::NotifyReadyToActivate() {
enne98f3a6c2014-10-09 20:09:44320 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
khushalsagarb7db1fe2015-11-12 00:51:27321 DebugScopedSetImplThread impl(task_runner_provider_);
rogerm8aeea932017-04-19 21:26:57322 if (scheduler_on_impl_thread_)
323 scheduler_on_impl_thread_->NotifyReadyToActivate();
[email protected]4f48f6e2013-08-27 06:33:38324}
325
ernstmdfac03e2014-11-11 20:18:05326void SingleThreadProxy::NotifyReadyToDraw() {
weiliangc8dac5a62015-04-02 06:12:35327 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToDraw");
khushalsagarb7db1fe2015-11-12 00:51:27328 DebugScopedSetImplThread impl(task_runner_provider_);
weiliangc8dac5a62015-04-02 06:12:35329 if (scheduler_on_impl_thread_)
330 scheduler_on_impl_thread_->NotifyReadyToDraw();
ernstmdfac03e2014-11-11 20:18:05331}
332
[email protected]c1bb5af2013-03-13 19:06:27333void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
danakj6c872fc02016-10-22 04:29:49334 single_thread_client_->RequestScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22335 if (scheduler_on_impl_thread_)
336 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06337}
338
danakja18e826a2015-12-03 00:27:03339void SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread() {
340 TRACE_EVENT0("cc",
341 "SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread");
danakj6c872fc02016-10-22 04:29:49342 single_thread_client_->RequestScheduleComposite();
mithro719bf6792014-11-10 15:36:47343 if (scheduler_on_impl_thread_)
danakja18e826a2015-12-03 00:27:03344 scheduler_on_impl_thread_->SetNeedsOneBeginImplFrame();
[email protected]43b8f982014-04-30 21:24:33345}
346
vmiura59ea9b4042014-12-09 20:50:39347void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
348 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
enne98f3a6c2014-10-09 20:09:44349 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39350 scheduler_on_impl_thread_->SetNeedsPrepareTiles();
[email protected]c48536a52013-09-14 00:02:08351}
352
[email protected]c1bb5af2013-03-13 19:06:27353void SingleThreadProxy::SetNeedsCommitOnImplThread() {
danakj6c872fc02016-10-22 04:29:49354 single_thread_client_->RequestScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22355 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01356 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]a8a049c2013-03-11 23:27:06357}
358
sunnyps7d073dc2015-04-16 23:29:12359void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
360 TRACE_EVENT1("cc", "SingleThreadProxy::SetVideoNeedsBeginFrames",
361 "needs_begin_frames", needs_begin_frames);
362 // In tests the layer tree is destroyed after the scheduler is.
363 if (scheduler_on_impl_thread_)
364 scheduler_on_impl_thread_->SetVideoNeedsBeginFrames(needs_begin_frames);
365}
366
[email protected]c1bb5af2013-03-13 19:06:27367void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
loysoc601b7b82016-11-10 02:56:44368 std::unique_ptr<MutatorEvents> events) {
[email protected]ccc08dc2014-01-30 07:33:20369 TRACE_EVENT0(
370 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
khushalsagarb7db1fe2015-11-12 00:51:27371 DCHECK(task_runner_provider_->IsImplThread());
372 DebugScopedSetMainThread main(task_runner_provider_);
danakja04855a2015-11-18 20:39:10373 layer_tree_host_->SetAnimationEvents(std::move(events));
[email protected]a8a049c2013-03-11 23:27:06374}
375
Xida Chend8bb3b22017-10-26 17:14:52376size_t SingleThreadProxy::CompositedAnimationsCount() const {
377 return 0;
378}
379
380size_t SingleThreadProxy::MainThreadAnimationsCount() const {
381 return 0;
382}
383
384size_t SingleThreadProxy::MainThreadCompositableAnimationsCount() const {
385 return 0;
386}
387
sunnypsad3235e2016-08-09 04:57:52388bool SingleThreadProxy::IsInsideDraw() {
389 return inside_draw_;
390}
[email protected]a8a049c2013-03-11 23:27:06391
enne98f3a6c2014-10-09 20:09:44392void SingleThreadProxy::DidActivateSyncTree() {
danakj68803fc2015-06-19 20:55:53393 CommitComplete();
enne98f3a6c2014-10-09 20:09:44394}
395
brianderson68749812015-07-07 22:39:39396void SingleThreadProxy::WillPrepareTiles() {
khushalsagarb7db1fe2015-11-12 00:51:27397 DCHECK(task_runner_provider_->IsImplThread());
brianderson68749812015-07-07 22:39:39398 if (scheduler_on_impl_thread_)
399 scheduler_on_impl_thread_->WillPrepareTiles();
400}
401
vmiura59ea9b4042014-12-09 20:50:39402void SingleThreadProxy::DidPrepareTiles() {
khushalsagarb7db1fe2015-11-12 00:51:27403 DCHECK(task_runner_provider_->IsImplThread());
enne98f3a6c2014-10-09 20:09:44404 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39405 scheduler_on_impl_thread_->DidPrepareTiles();
enne98f3a6c2014-10-09 20:09:44406}
407
rouslanf7ebd8832015-01-22 01:54:14408void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
409 layer_tree_host_->DidCompletePageScaleAnimation();
410}
411
danakjc7afae52017-06-20 21:12:41412void SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread() {
danakj1120f4c2016-09-15 02:05:32413 TRACE_EVENT0("cc",
danakjc7afae52017-06-20 21:12:41414 "SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22415 {
khushalsagarb7db1fe2015-11-12 00:51:27416 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22417 // This must happen before we notify the scheduler as it may try to recreate
418 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
danakjc7afae52017-06-20 21:12:41419 layer_tree_host_->DidLoseLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22420 }
danakjc7afae52017-06-20 21:12:41421 single_thread_client_->DidLoseLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22422 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41423 scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink();
424 layer_tree_frame_sink_lost_ = true;
[email protected]4d7e46a2013-11-08 05:33:40425}
426
Fady Samuelc645ffe2017-07-24 17:28:20427void SingleThreadProxy::SetBeginFrameSource(viz::BeginFrameSource* source) {
enne19c108582016-04-14 03:35:32428 if (scheduler_on_impl_thread_)
429 scheduler_on_impl_thread_->SetBeginFrameSource(source);
430}
431
danakj9d124422016-10-14 03:15:08432void SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread() {
miletusfed8c43b2015-01-26 20:04:52433 TRACE_EVENT0("cc,benchmark",
danakj9d124422016-10-14 03:15:08434 "SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22435 if (scheduler_on_impl_thread_)
danakj9d124422016-10-14 03:15:08436 scheduler_on_impl_thread_->DidReceiveCompositorFrameAck();
samans44b6dfc2017-04-19 16:50:53437 // We do a PostTask here because freeing resources in some cases (such as in
438 // TextureLayer) is PostTasked and we want to make sure ack is received after
439 // resources are returned.
440 task_runner_provider_->MainThreadTaskRunner()->PostTask(
441 FROM_HERE, base::Bind(&SingleThreadProxy::DidReceiveCompositorFrameAck,
442 frame_sink_bound_weak_ptr_));
[email protected]493067512012-09-19 23:34:10443}
444
danakjc7afae52017-06-20 21:12:41445void SingleThreadProxy::OnDrawForLayerTreeFrameSink(
boliu7097ee5b2015-12-17 03:16:09446 bool resourceless_software_draw) {
sunnypseab5ac92015-04-02 20:26:13447 NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
448}
449
Khushal8360fc92017-07-26 01:53:25450void SingleThreadProxy::NeedsImplSideInvalidation(
451 bool needs_first_draw_on_activation) {
Khushal4b6c41882018-02-16 09:02:10452 if (scheduler_on_impl_thread_) {
453 scheduler_on_impl_thread_->SetNeedsImplSideInvalidation(
454 needs_first_draw_on_activation);
455 }
khushalsagard3b8827d2017-02-18 18:42:54456}
457
vmpstra840c6a2017-06-01 21:50:39458void SingleThreadProxy::NotifyImageDecodeRequestFinished() {
459 // If we don't have a scheduler, then just issue the callbacks here.
460 // Otherwise, schedule a commit.
461 if (!scheduler_on_impl_thread_) {
462 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
463 DebugScopedSetImplThread impl(task_runner_provider_);
464
465 IssueImageDecodeFinishedCallbacks();
466 return;
467 }
468 SetNeedsCommitOnImplThread();
469}
470
Scott Violete979c012017-12-08 00:18:16471void SingleThreadProxy::DidPresentCompositorFrameOnImplThread(
472 const std::vector<int>& source_frames,
473 base::TimeTicks time,
474 base::TimeDelta refresh,
475 uint32_t flags) {
476 layer_tree_host_->DidPresentCompositorFrame(source_frames, time, refresh,
477 flags);
478}
479
Dan Elphick95929fd52017-06-13 09:15:07480void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
481 if (scheduler_on_impl_thread_) {
482 scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected(
483 new_state);
484 }
485}
486
Khushal4b6c41882018-02-16 09:02:10487void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time,
488 bool raster) {
miletusfed8c43b2015-01-26 20:04:52489 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
khushalsagarb7db1fe2015-11-12 00:51:27490 DCHECK(task_runner_provider_->IsMainThread());
mithro51693e382015-05-07 23:52:41491#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13492 DCHECK(!inside_impl_frame_);
mithro51693e382015-05-07 23:52:41493#endif
jbauman399aec1a2014-10-25 02:33:32494 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
495
danakjc7afae52017-06-20 21:12:41496 if (layer_tree_frame_sink_lost_) {
497 RequestNewLayerTreeFrameSink();
498 // RequestNewLayerTreeFrameSink could have synchronously created an output
jbauman399aec1a2014-10-25 02:33:32499 // surface, so check again before returning.
danakjc7afae52017-06-20 21:12:41500 if (layer_tree_frame_sink_lost_)
jbauman399aec1a2014-10-25 02:33:32501 return;
502 }
[email protected]51f81da2014-05-16 21:29:26503
Fady Samuelc296f5fb2017-07-21 04:02:19504 viz::BeginFrameArgs begin_frame_args(viz::BeginFrameArgs::Create(
505 BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
506 frame_begin_time, base::TimeTicks(),
507 viz::BeginFrameArgs::DefaultInterval(), viz::BeginFrameArgs::NORMAL));
mithroc76d70312015-05-04 23:51:13508
509 // Start the impl frame.
enne98f3a6c2014-10-09 20:09:44510 {
khushalsagarb7db1fe2015-11-12 00:51:27511 DebugScopedSetImplThread impl(task_runner_provider_);
mithroc76d70312015-05-04 23:51:13512 WillBeginImplFrame(begin_frame_args);
513 }
514
515 // Run the "main thread" and get it to commit.
516 {
mithro51693e382015-05-07 23:52:41517#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13518 DCHECK(inside_impl_frame_);
mithro51693e382015-05-07 23:52:41519#endif
enne98f3a6c2014-10-09 20:09:44520 DoBeginMainFrame(begin_frame_args);
danakj97660d92017-03-27 14:11:49521 DoPainting();
enne98f3a6c2014-10-09 20:09:44522 DoCommit();
[email protected]e0341352013-04-06 05:01:20523
khushalsagar8297ae992016-09-14 20:51:23524 DCHECK_EQ(
525 0u,
526 layer_tree_host_->GetSwapPromiseManager()->num_queued_swap_promises())
enne98f3a6c2014-10-09 20:09:44527 << "Commit should always succeed and transfer promises.";
528 }
529
mithroc76d70312015-05-04 23:51:13530 // Finish the impl frame.
enne98f3a6c2014-10-09 20:09:44531 {
khushalsagarb7db1fe2015-11-12 00:51:27532 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43533 host_impl_->ActivateSyncTree();
Khushal4b6c41882018-02-16 09:02:10534 if (raster) {
535 host_impl_->PrepareTiles();
536 host_impl_->SynchronouslyInitializeAllTiles();
537 }
enne69277cb2014-10-29 23:03:40538
danakj12e2f6e2015-08-19 22:25:44539 // TODO(danakj): Don't do this last... we prepared the wrong things. D:
Walter Kormanaa326e42017-08-22 23:04:43540 host_impl_->Animate();
mithro719bf6792014-11-10 15:36:47541
Khushal4b6c41882018-02-16 09:02:10542 if (raster) {
543 LayerTreeHostImpl::FrameData frame;
544 frame.begin_frame_ack = viz::BeginFrameAck(
545 begin_frame_args.source_id, begin_frame_args.sequence_number, true);
546 DoComposite(&frame);
547 }
enne98f3a6c2014-10-09 20:09:44548
549 // DoComposite could abort, but because this is a synchronous composite
550 // another draw will never be scheduled, so break remaining promises.
Walter Kormanaa326e42017-08-22 23:04:43551 host_impl_->active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS);
mithroc76d70312015-05-04 23:51:13552
mithro51693e382015-05-07 23:52:41553 DidFinishImplFrame();
enne98f3a6c2014-10-09 20:09:44554 }
[email protected]74d9063c2013-01-18 03:14:47555}
556
[email protected]5d8bec72014-07-03 03:03:11557bool SingleThreadProxy::SupportsImplScrolling() const {
558 return false;
559}
560
[email protected]3d9f7432013-04-06 00:35:18561bool SingleThreadProxy::ShouldComposite() const {
khushalsagarb7db1fe2015-11-12 00:51:27562 DCHECK(task_runner_provider_->IsImplThread());
Walter Kormanaa326e42017-08-22 23:04:43563 return host_impl_->visible() && host_impl_->CanDraw();
[email protected]3d9f7432013-04-06 00:35:18564}
565
danakjc7afae52017-06-20 21:12:41566void SingleThreadProxy::ScheduleRequestNewLayerTreeFrameSink() {
567 if (layer_tree_frame_sink_creation_callback_.IsCancelled() &&
568 !layer_tree_frame_sink_creation_requested_) {
569 layer_tree_frame_sink_creation_callback_.Reset(
570 base::Bind(&SingleThreadProxy::RequestNewLayerTreeFrameSink,
jbauman8ab0f9e2014-10-15 02:30:34571 weak_factory_.GetWeakPtr()));
khushalsagarb7db1fe2015-11-12 00:51:27572 task_runner_provider_->MainThreadTaskRunner()->PostTask(
danakjc7afae52017-06-20 21:12:41573 FROM_HERE, layer_tree_frame_sink_creation_callback_.callback());
jbauman8ab0f9e2014-10-15 02:30:34574 }
575}
576
mithro248d1722015-05-05 05:23:45577DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20578 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20579
enne98f3a6c2014-10-09 20:09:44580 DrawResult draw_result;
581 bool draw_frame;
[email protected]a8a049c2013-03-11 23:27:06582 {
khushalsagarb7db1fe2015-11-12 00:51:27583 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06584 base::AutoReset<bool> mark_inside(&inside_draw_, true);
585
[email protected]3d9f7432013-04-06 00:35:18586 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
587 // frame, so can only be used when such a frame is possible. Since
588 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
589 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50590 if (!ShouldComposite()) {
[email protected]aeeedad2014-08-22 18:16:22591 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18592 }
[email protected]a8a049c2013-03-11 23:27:06593
danakj097919e72016-09-07 19:50:55594 // This CapturePostTasks should be destroyed before
595 // DidCommitAndDrawFrame() is called since that goes out to the
596 // embedder, and we want the embedder to receive its callbacks before that.
597 // NOTE: This maintains consistent ordering with the ThreadProxy since
598 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
599 // there as the main thread is not blocked, so any posted tasks inside
600 // the swap buffers will execute first.
601 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
danakj097919e72016-09-07 19:50:55602
Walter Kormanaa326e42017-08-22 23:04:43603 draw_result = host_impl_->PrepareToDraw(frame);
enne98f3a6c2014-10-09 20:09:44604 draw_frame = draw_result == DRAW_SUCCESS;
robliao27728e62015-03-21 07:39:34605 if (draw_frame) {
Walter Kormanaa326e42017-08-22 23:04:43606 if (host_impl_->DrawLayers(frame)) {
danakj097919e72016-09-07 19:50:55607 if (scheduler_on_impl_thread_)
danakjc7afae52017-06-20 21:12:41608 // Drawing implies we submitted a frame to the LayerTreeFrameSink.
danakj9d124422016-10-14 03:15:08609 scheduler_on_impl_thread_->DidSubmitCompositorFrame();
danakj6c872fc02016-10-22 04:29:49610 single_thread_client_->DidSubmitCompositorFrame();
danakj097919e72016-09-07 19:50:55611 }
robliao27728e62015-03-21 07:39:34612 }
Walter Kormanaa326e42017-08-22 23:04:43613 host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06614
danakj097919e72016-09-07 19:50:55615 bool start_ready_animations = draw_frame;
Walter Kormanaa326e42017-08-22 23:04:43616 host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]aeeedad2014-08-22 18:16:22617 }
618 DidCommitAndDrawFrame();
619
enne98f3a6c2014-10-09 20:09:44620 return draw_result;
[email protected]a8a049c2013-03-11 23:27:06621}
622
[email protected]aeeedad2014-08-22 18:16:22623void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06624 if (next_frame_is_newly_committed_frame_) {
khushalsagarb7db1fe2015-11-12 00:51:27625 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]a8a049c2013-03-11 23:27:06626 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21627 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06628 }
629}
630
[email protected]4ea293f72014-08-13 03:03:17631bool SingleThreadProxy::MainFrameWillHappenForTesting() {
danakjfcdaba122015-04-24 21:41:52632 if (!scheduler_on_impl_thread_)
633 return false;
634 return scheduler_on_impl_thread_->MainFrameForTestingWillHappen();
[email protected]4ea293f72014-08-13 03:03:17635}
[email protected]a8a049c2013-03-11 23:27:06636
Khushal2f9cdf22018-01-08 21:47:08637void SingleThreadProxy::ClearHistoryOnNavigation() {
638 DCHECK(task_runner_provider_->IsImplThread());
639 if (scheduler_on_impl_thread_)
640 scheduler_on_impl_thread_->ClearHistoryOnNavigation();
641}
642
jonrossa2ff4f82018-02-16 17:27:46643void SingleThreadProxy::SetRenderFrameObserver(
644 std::unique_ptr<RenderFrameMetadataObserver> observer) {
645 // TODO(jonross): this is used in some tests. Find a way to not attempt to
646 // create/set the RenderFrameMetadataObserver while in those tests.
647 // The browser does not produce RenderFrameMetadata.
648 NOTIMPLEMENTED();
649}
650
James Wallace-Leee71cf582018-01-29 22:24:23651bool SingleThreadProxy::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
danakja18e826a2015-12-03 00:27:03652 DebugScopedSetImplThread impl(task_runner_provider_);
mithro51693e382015-05-07 23:52:41653#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02654 DCHECK(!inside_impl_frame_)
655 << "WillBeginImplFrame called while already inside an impl frame!";
656 inside_impl_frame_ = true;
mithro51693e382015-05-07 23:52:41657#endif
James Wallace-Leee71cf582018-01-29 22:24:23658 return host_impl_->WillBeginImplFrame(args);
[email protected]aeeedad2014-08-22 18:16:22659}
660
brianderson266dc3a2015-11-12 03:16:40661void SingleThreadProxy::ScheduledActionSendBeginMainFrame(
Fady Samuelc296f5fb2017-07-21 04:02:19662 const viz::BeginFrameArgs& begin_frame_args) {
[email protected]aeeedad2014-08-22 18:16:22663 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
sunnypsad3235e2016-08-09 04:57:52664#if DCHECK_IS_ON()
[email protected]aeeedad2014-08-22 18:16:22665 // Although this proxy is single-threaded, it's problematic to synchronously
666 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
667 // could cause a commit to occur in between a series of SetNeedsCommit calls
668 // (i.e. property modifications) causing some to fall on one frame and some to
669 // fall on the next. Doing it asynchronously instead matches the semantics of
670 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
671 // synchronous commit.
mithro69fd3bb52015-05-01 03:45:02672 DCHECK(inside_impl_frame_)
673 << "BeginMainFrame should only be sent inside a BeginImplFrame";
mithro51693e382015-05-07 23:52:41674#endif
mithro69fd3bb52015-05-01 03:45:02675
khushalsagarb7db1fe2015-11-12 00:51:27676 task_runner_provider_->MainThreadTaskRunner()->PostTask(
tzik4604bb52017-04-13 21:50:22677 FROM_HERE, base::BindOnce(&SingleThreadProxy::BeginMainFrame,
678 weak_factory_.GetWeakPtr(), begin_frame_args));
Walter Kormanaa326e42017-08-22 23:04:43679 host_impl_->DidSendBeginMainFrame();
[email protected]aeeedad2014-08-22 18:16:22680}
681
rmcilroy0a19362a2015-02-18 12:34:25682void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
683 layer_tree_host_->BeginMainFrameNotExpectedSoon();
684}
685
delphick9db74aa2017-05-05 10:20:49686void SingleThreadProxy::ScheduledActionBeginMainFrameNotExpectedUntil(
687 base::TimeTicks time) {
688 layer_tree_host_->BeginMainFrameNotExpectedUntil(time);
689}
690
Fady Samuelc296f5fb2017-07-21 04:02:19691void SingleThreadProxy::BeginMainFrame(
692 const viz::BeginFrameArgs& begin_frame_args) {
Brian Anderson242b9b02017-12-06 21:06:26693 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
694 // commit.
695 ScopedAbortRemainingSwapPromises swap_promise_checker(
696 layer_tree_host_->GetSwapPromiseManager());
697
brianderson21aef162015-11-11 05:12:23698 if (scheduler_on_impl_thread_) {
699 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(
700 base::TimeTicks::Now());
701 }
702
danakjfcdaba122015-04-24 21:41:52703 commit_requested_ = false;
brianderson49e101d22015-04-29 00:05:33704 animate_requested_ = false;
danakjfcdaba122015-04-24 21:41:52705
[email protected]aeeedad2014-08-22 18:16:22706 if (defer_commits_) {
simonhongc6309f792015-01-31 15:47:15707 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
708 TRACE_EVENT_SCOPE_THREAD);
709 BeginMainFrameAbortedOnImplThread(
710 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
[email protected]aeeedad2014-08-22 18:16:22711 return;
712 }
713
khushalsagarcebe4942016-09-07 23:27:01714 if (!layer_tree_host_->IsVisible()) {
[email protected]aeeedad2014-08-22 18:16:22715 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48716 BeginMainFrameAbortedOnImplThread(
717 CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
[email protected]aeeedad2014-08-22 18:16:22718 return;
719 }
720
danakjfcdaba122015-04-24 21:41:52721 // Prevent new commits from being requested inside DoBeginMainFrame.
brianderson49e101d22015-04-29 00:05:33722 // Note: We do not want to prevent SetNeedsAnimate from requesting
723 // a commit here.
danakjfcdaba122015-04-24 21:41:52724 commit_requested_ = true;
725
enne98f3a6c2014-10-09 20:09:44726 DoBeginMainFrame(begin_frame_args);
danakj97660d92017-03-27 14:11:49727
728 // New commits requested inside UpdateLayers should be respected.
729 commit_requested_ = false;
730
731 // At this point the main frame may have deferred commits to avoid committing
732 // right now.
Eric Seckler8af8c0e52018-01-17 23:45:53733 if (defer_commits_ || begin_frame_args.animate_only) {
danakj97660d92017-03-27 14:11:49734 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
735 TRACE_EVENT_SCOPE_THREAD);
736 BeginMainFrameAbortedOnImplThread(
737 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
738 layer_tree_host_->DidBeginMainFrame();
739 return;
740 }
741
Brian Anderson242b9b02017-12-06 21:06:26742 // Queue the LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT swap promise only once we
743 // know we will commit since QueueSwapPromise itself requests a commit.
744 ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
745 new_latency_info.AddLatencyNumberWithTimestamp(
746 ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, 0, 0,
747 begin_frame_args.frame_time, 1);
748 layer_tree_host_->QueueSwapPromise(
749 std::make_unique<LatencyInfoSwapPromise>(new_latency_info));
750
danakj97660d92017-03-27 14:11:49751 DoPainting();
enne98f3a6c2014-10-09 20:09:44752}
753
754void SingleThreadProxy::DoBeginMainFrame(
Fady Samuelc296f5fb2017-07-21 04:02:19755 const viz::BeginFrameArgs& begin_frame_args) {
Khushal4b6c41882018-02-16 09:02:10756 // The impl-side scroll deltas may be manipulated directly via the
757 // InputHandler on the UI thread and the scale deltas may change when they are
758 // clamped on the impl thread.
tapted4b70c522016-08-13 09:09:32759 std::unique_ptr<ScrollAndScaleSet> scroll_info =
Walter Kormanaa326e42017-08-22 23:04:43760 host_impl_->ProcessScrollDeltas();
tapted4b70c522016-08-13 09:09:32761 layer_tree_host_->ApplyScrollAndScale(scroll_info.get());
762
enne98f3a6c2014-10-09 20:09:44763 layer_tree_host_->WillBeginMainFrame();
764 layer_tree_host_->BeginMainFrame(begin_frame_args);
765 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
Eric Seckler8af8c0e52018-01-17 23:45:53766 layer_tree_host_->RequestMainFrameUpdate(
767 begin_frame_args.animate_only
768 ? LayerTreeHost::VisualStateUpdate::kPrePaint
769 : LayerTreeHost::VisualStateUpdate::kAll);
danakj97660d92017-03-27 14:11:49770}
enne98f3a6c2014-10-09 20:09:44771
danakj97660d92017-03-27 14:11:49772void SingleThreadProxy::DoPainting() {
danakj5f46636a2015-06-19 00:01:40773 layer_tree_host_->UpdateLayers();
enne98f3a6c2014-10-09 20:09:44774
mithrof7a21502014-12-17 03:24:48775 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
776 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
777 // thread_proxy.cc
brianderson21aef162015-11-11 05:12:23778 if (scheduler_on_impl_thread_)
enne98f3a6c2014-10-09 20:09:44779 scheduler_on_impl_thread_->NotifyReadyToCommit();
[email protected]aeeedad2014-08-22 18:16:22780}
781
mithrof7a21502014-12-17 03:24:48782void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
783 CommitEarlyOutReason reason) {
khushalsagarb7db1fe2015-11-12 00:51:27784 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22785 DCHECK(scheduler_on_impl_thread_->CommitPending());
Walter Kormanaa326e42017-08-22 23:04:43786 DCHECK(!host_impl_->pending_tree());
[email protected]aeeedad2014-08-22 18:16:22787
sunnypsad3235e2016-08-09 04:57:52788 std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
Walter Kormanaa326e42017-08-22 23:04:43789 host_impl_->BeginMainFrameAborted(reason, std::move(empty_swap_promises));
mithrof7a21502014-12-17 03:24:48790 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
[email protected]aeeedad2014-08-22 18:16:22791}
792
danakj9d124422016-10-14 03:15:08793DrawResult SingleThreadProxy::ScheduledActionDrawIfPossible() {
khushalsagarb7db1fe2015-11-12 00:51:27794 DebugScopedSetImplThread impl(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22795 LayerTreeHostImpl::FrameData frame;
esecklerdde665f2017-03-07 20:19:27796 frame.begin_frame_ack =
797 scheduler_on_impl_thread_->CurrentBeginFrameAckForActiveTree();
mithro248d1722015-05-05 05:23:45798 return DoComposite(&frame);
[email protected]aeeedad2014-08-22 18:16:22799}
800
danakj9d124422016-10-14 03:15:08801DrawResult SingleThreadProxy::ScheduledActionDrawForced() {
[email protected]aeeedad2014-08-22 18:16:22802 NOTREACHED();
803 return INVALID_RESULT;
804}
805
806void SingleThreadProxy::ScheduledActionCommit() {
khushalsagarb7db1fe2015-11-12 00:51:27807 DebugScopedSetMainThread main(task_runner_provider_);
enne98f3a6c2014-10-09 20:09:44808 DoCommit();
[email protected]aeeedad2014-08-22 18:16:22809}
810
[email protected]aeeedad2014-08-22 18:16:22811void SingleThreadProxy::ScheduledActionActivateSyncTree() {
khushalsagarb7db1fe2015-11-12 00:51:27812 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43813 host_impl_->ActivateSyncTree();
[email protected]aeeedad2014-08-22 18:16:22814}
815
danakjc7afae52017-06-20 21:12:41816void SingleThreadProxy::ScheduledActionBeginLayerTreeFrameSinkCreation() {
khushalsagarb7db1fe2015-11-12 00:51:27817 DebugScopedSetMainThread main(task_runner_provider_);
[email protected]aeeedad2014-08-22 18:16:22818 DCHECK(scheduler_on_impl_thread_);
819 // If possible, create the output surface in a post task. Synchronously
820 // creating the output surface makes tests more awkward since this differs
821 // from the ThreadProxy behavior. However, sometimes there is no
822 // task runner.
khushalsagarb7db1fe2015-11-12 00:51:27823 if (task_runner_provider_->MainThreadTaskRunner()) {
danakjc7afae52017-06-20 21:12:41824 ScheduleRequestNewLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22825 } else {
danakjc7afae52017-06-20 21:12:41826 RequestNewLayerTreeFrameSink();
[email protected]aeeedad2014-08-22 18:16:22827 }
828}
829
vmiura59ea9b4042014-12-09 20:50:39830void SingleThreadProxy::ScheduledActionPrepareTiles() {
831 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
khushalsagarb7db1fe2015-11-12 00:51:27832 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43833 host_impl_->PrepareTiles();
[email protected]aeeedad2014-08-22 18:16:22834}
835
danakjc7afae52017-06-20 21:12:41836void SingleThreadProxy::ScheduledActionInvalidateLayerTreeFrameSink() {
sunnypseab5ac92015-04-02 20:26:13837 NOTREACHED();
838}
839
khushalsagarab73d502017-02-24 02:26:46840void SingleThreadProxy::ScheduledActionPerformImplSideInvalidation() {
khushalsagar6dc91d02017-02-28 05:10:07841 DCHECK(scheduler_on_impl_thread_);
842
843 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43844 host_impl_->InvalidateContentOnImplSide();
khushalsagar6dc91d02017-02-28 05:10:07845
846 // Invalidations go directly to the active tree, so we synchronously call
847 // NotifyReadyToActivate to update the scheduler and LTHI state correctly.
848 // Since in single-threaded mode the scheduler will wait for a ready to draw
849 // signal from LTHI, the draw will remain blocked till the invalidated tiles
850 // are ready.
851 NotifyReadyToActivate();
khushalsagarab73d502017-02-24 02:26:46852}
853
mithro51693e382015-05-07 23:52:41854void SingleThreadProxy::DidFinishImplFrame() {
Walter Kormanaa326e42017-08-22 23:04:43855 host_impl_->DidFinishImplFrame();
mithro51693e382015-05-07 23:52:41856#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02857 DCHECK(inside_impl_frame_)
mithro51693e382015-05-07 23:52:41858 << "DidFinishImplFrame called while not inside an impl frame!";
mithro69fd3bb52015-05-01 03:45:02859 inside_impl_frame_ = false;
mithro51693e382015-05-07 23:52:41860#endif
[email protected]aeeedad2014-08-22 18:16:22861}
862
Fady Samuelc296f5fb2017-07-21 04:02:19863void SingleThreadProxy::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
eseckler9404a232017-05-22 14:49:43864 DebugScopedSetImplThread impl(task_runner_provider_);
Walter Kormanaa326e42017-08-22 23:04:43865 host_impl_->DidNotProduceFrame(ack);
eseckler9404a232017-05-22 14:49:43866}
867
samans44b6dfc2017-04-19 16:50:53868void SingleThreadProxy::DidReceiveCompositorFrameAck() {
869 layer_tree_host_->DidReceiveCompositorFrameAck();
870}
871
[email protected]bc5e77c2012-11-05 20:00:49872} // namespace cc