blob: bcda921ff86dc86bf20feb23499c812330c2107d [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"
robliao27728e62015-03-21 07:39:348#include "base/profiler/scoped_tracker.h"
primianoc06e2382015-01-28 04:21:499#include "base/trace_event/trace_event.h"
[email protected]adbe30f2013-10-11 21:12:3310#include "cc/debug/benchmark_instrumentation.h"
caseq7d2f4c92015-02-04 16:43:2711#include "cc/debug/devtools_instrumentation.h"
[email protected]7f0d825f2013-03-18 07:24:3012#include "cc/output/context_provider.h"
13#include "cc/output/output_surface.h"
[email protected]89e82672013-03-18 07:50:5614#include "cc/quads/draw_quad.h"
mithrof7a21502014-12-17 03:24:4815#include "cc/scheduler/commit_earlyout_reason.h"
briandersonc9f50352015-06-24 03:38:5816#include "cc/scheduler/compositor_timing_history.h"
17#include "cc/scheduler/scheduler.h"
[email protected]556fd292013-03-18 08:03:0418#include "cc/trees/layer_tree_host.h"
[email protected]943528e2013-11-07 05:01:3219#include "cc/trees/layer_tree_host_single_thread_client.h"
[email protected]556fd292013-03-18 08:03:0420#include "cc/trees/layer_tree_impl.h"
[email protected]aeeedad2014-08-22 18:16:2221#include "cc/trees/scoped_abort_remaining_swap_promises.h"
[email protected]94f206c12012-08-25 00:09:1422
[email protected]9c88e562012-09-14 22:21:3023namespace cc {
[email protected]94f206c12012-08-25 00:09:1424
[email protected]943528e2013-11-07 05:01:3225scoped_ptr<Proxy> SingleThreadProxy::Create(
26 LayerTreeHost* layer_tree_host,
[email protected]27e6a212014-07-18 15:51:2727 LayerTreeHostSingleThreadClient* client,
simonhonga7e3ac42014-11-11 20:50:2228 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
29 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
30 return make_scoped_ptr(new SingleThreadProxy(
31 layer_tree_host,
32 client,
33 main_task_runner,
34 external_begin_frame_source.Pass()));
[email protected]94f206c12012-08-25 00:09:1435}
36
[email protected]27e6a212014-07-18 15:51:2737SingleThreadProxy::SingleThreadProxy(
38 LayerTreeHost* layer_tree_host,
39 LayerTreeHostSingleThreadClient* client,
simonhonga7e3ac42014-11-11 20:50:2240 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
41 scoped_ptr<BeginFrameSource> external_begin_frame_source)
[email protected]27e6a212014-07-18 15:51:2742 : Proxy(main_task_runner, NULL),
[email protected]a8a049c2013-03-11 23:27:0643 layer_tree_host_(layer_tree_host),
[email protected]943528e2013-11-07 05:01:3244 client_(client),
sunnypsf381ede2015-06-23 01:46:5345 external_begin_frame_source_(external_begin_frame_source.Pass()),
[email protected]a8a049c2013-03-11 23:27:0646 next_frame_is_newly_committed_frame_(false),
mithro51693e382015-05-07 23:52:4147#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:0248 inside_impl_frame_(false),
mithro51693e382015-05-07 23:52:4149#endif
[email protected]aeeedad2014-08-22 18:16:2250 inside_draw_(false),
51 defer_commits_(false),
brianderson49e101d22015-04-29 00:05:3352 animate_requested_(false),
[email protected]aeeedad2014-08-22 18:16:2253 commit_requested_(false),
jbauman399aec1a2014-10-25 02:33:3254 inside_synchronous_composite_(false),
jbauman8ab0f9e2014-10-15 02:30:3455 output_surface_creation_requested_(false),
[email protected]aeeedad2014-08-22 18:16:2256 weak_factory_(this) {
[email protected]a8a049c2013-03-11 23:27:0657 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
58 DCHECK(Proxy::IsMainThread());
59 DCHECK(layer_tree_host);
danakjfcdaba122015-04-24 21:41:5260
61 if (layer_tree_host->settings().single_thread_proxy_scheduler &&
62 !scheduler_on_impl_thread_) {
63 SchedulerSettings scheduler_settings(
64 layer_tree_host->settings().ToSchedulerSettings());
danakj5f2e92de2015-06-20 00:25:5865 scheduler_settings.commit_to_active_tree = CommitToActiveTree();
briandersonc9f50352015-06-24 03:38:5866
67 scoped_ptr<CompositorTimingHistory> compositor_timing_history(
68 new CompositorTimingHistory(
briandersonc68220f2015-07-20 20:08:3569 CompositorTimingHistory::BROWSER_UMA,
briandersonc9f50352015-06-24 03:38:5870 layer_tree_host->rendering_stats_instrumentation()));
71
danakjfcdaba122015-04-24 21:41:5272 scheduler_on_impl_thread_ = Scheduler::Create(
73 this, scheduler_settings, layer_tree_host_->id(),
briandersonc9f50352015-06-24 03:38:5874 MainThreadTaskRunner(), external_begin_frame_source_.get(),
75 compositor_timing_history.Pass());
danakjfcdaba122015-04-24 21:41:5276 }
[email protected]94f206c12012-08-25 00:09:1477}
78
[email protected]e96e3432013-12-19 18:56:0779void SingleThreadProxy::Start() {
[email protected]a8a049c2013-03-11 23:27:0680 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:2181 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]a8a049c2013-03-11 23:27:0682}
83
84SingleThreadProxy::~SingleThreadProxy() {
85 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
86 DCHECK(Proxy::IsMainThread());
[email protected]04049fc2013-05-01 03:13:2087 // Make sure Stop() got called or never Started.
88 DCHECK(!layer_tree_host_impl_);
[email protected]a8a049c2013-03-11 23:27:0689}
90
[email protected]a8a049c2013-03-11 23:27:0691void SingleThreadProxy::FinishAllRendering() {
[email protected]ccc08dc2014-01-30 07:33:2092 TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering");
[email protected]a8a049c2013-03-11 23:27:0693 DCHECK(Proxy::IsMainThread());
94 {
[email protected]61de5812012-11-08 07:03:4495 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2796 layer_tree_host_impl_->FinishAllRendering();
[email protected]a8a049c2013-03-11 23:27:0697 }
[email protected]94f206c12012-08-25 00:09:1498}
99
[email protected]a8a049c2013-03-11 23:27:06100bool SingleThreadProxy::IsStarted() const {
101 DCHECK(Proxy::IsMainThread());
[email protected]3209161d2013-03-29 19:17:34102 return layer_tree_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]14bd5542013-05-08 21:51:30111void SingleThreadProxy::SetLayerTreeHostClientReady() {
[email protected]ccc08dc2014-01-30 07:33:20112 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
[email protected]a8a049c2013-03-11 23:27:06113 // Scheduling is controlled by the embedder in the single thread case, so
114 // nothing to do.
[email protected]aeeedad2014-08-22 18:16:22115 DCHECK(Proxy::IsMainThread());
116 DebugScopedSetImplThread impl(this);
danakjfcdaba122015-04-24 21:41:52117 if (scheduler_on_impl_thread_) {
[email protected]aeeedad2014-08-22 18:16:22118 scheduler_on_impl_thread_->SetCanStart();
119 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
120 }
[email protected]a8a049c2013-03-11 23:27:06121}
122
123void SingleThreadProxy::SetVisible(bool visible) {
mithro46adf5a2014-11-19 14:52:40124 TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible);
[email protected]f7c01c82013-07-02 22:58:46125 DebugScopedSetImplThread impl(this);
sunnypsc3f6e0c2015-07-25 01:00:59126
[email protected]c1bb5af2013-03-13 19:06:27127 layer_tree_host_impl_->SetVisible(visible);
sunnypsc3f6e0c2015-07-25 01:00:59128
[email protected]aeeedad2014-08-22 18:16:22129 if (scheduler_on_impl_thread_)
130 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
[email protected]8ea875b2013-08-07 00:32:12131 // Changing visibility could change ShouldComposite().
[email protected]a8a049c2013-03-11 23:27:06132}
133
bajones274110612015-01-06 20:53:59134void SingleThreadProxy::SetThrottleFrameProduction(bool throttle) {
135 TRACE_EVENT1("cc", "SingleThreadProxy::SetThrottleFrameProduction",
136 "throttle", throttle);
137 DebugScopedSetImplThread impl(this);
138 if (scheduler_on_impl_thread_)
139 scheduler_on_impl_thread_->SetThrottleFrameProduction(throttle);
140}
141
enne2097cab2014-09-25 20:16:31142void SingleThreadProxy::RequestNewOutputSurface() {
[email protected]a8a049c2013-03-11 23:27:06143 DCHECK(Proxy::IsMainThread());
[email protected]497edf82014-05-20 21:53:15144 DCHECK(layer_tree_host_->output_surface_lost());
jbauman8ab0f9e2014-10-15 02:30:34145 output_surface_creation_callback_.Cancel();
146 if (output_surface_creation_requested_)
147 return;
148 output_surface_creation_requested_ = true;
enne2097cab2014-09-25 20:16:31149 layer_tree_host_->RequestNewOutputSurface();
150}
[email protected]94f206c12012-08-25 00:09:14151
sohan.jyoti3a33d872015-09-18 22:32:55152scoped_ptr<OutputSurface> SingleThreadProxy::ReleaseOutputSurface() {
153 if (scheduler_on_impl_thread_)
154 scheduler_on_impl_thread_->DidLoseOutputSurface();
155 return layer_tree_host_impl_->ReleaseOutputSurface();
156}
157
kbrd29c27832015-09-17 01:43:02158void SingleThreadProxy::SetOutputSurface(
159 scoped_ptr<OutputSurface> output_surface) {
enne2097cab2014-09-25 20:16:31160 DCHECK(Proxy::IsMainThread());
161 DCHECK(layer_tree_host_->output_surface_lost());
enne5232fbb2015-01-27 21:22:41162 DCHECK(output_surface_creation_requested_);
[email protected]da8e3b72b2014-04-25 02:33:45163 renderer_capabilities_for_main_thread_ = RendererCapabilities();
164
enne7f8fdde2014-12-10 21:32:09165 bool success;
166 {
[email protected]819b9f52013-09-22 23:29:51167 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06168 DebugScopedSetImplThread impl(this);
kbrd29c27832015-09-17 01:43:02169 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]04049fc2013-05-01 03:13:20170 }
171
[email protected]aeeedad2014-08-22 18:16:22172 if (success) {
enne7f8fdde2014-12-10 21:32:09173 layer_tree_host_->DidInitializeOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22174 if (scheduler_on_impl_thread_)
175 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
jbauman399aec1a2014-10-25 02:33:32176 else if (!inside_synchronous_composite_)
177 SetNeedsCommit();
enne5232fbb2015-01-27 21:22:41178 output_surface_creation_requested_ = false;
enne7f8fdde2014-12-10 21:32:09179 } else {
enne5232fbb2015-01-27 21:22:41180 // DidFailToInitializeOutputSurface is treated as a RequestNewOutputSurface,
181 // and so output_surface_creation_requested remains true.
enne7f8fdde2014-12-10 21:32:09182 layer_tree_host_->DidFailToInitializeOutputSurface();
[email protected]04049fc2013-05-01 03:13:20183 }
[email protected]94f206c12012-08-25 00:09:14184}
185
[email protected]a8a049c2013-03-11 23:27:06186const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20187 DCHECK(Proxy::IsMainThread());
188 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06189 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14190}
191
[email protected]8b9e52b2014-01-17 16:35:31192void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20193 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
[email protected]c5134172013-12-11 06:19:48194 DCHECK(Proxy::IsMainThread());
[email protected]06cbc31b2014-01-17 06:43:20195 client_->ScheduleAnimation();
brianderson49e101d22015-04-29 00:05:33196 if (animate_requested_)
197 return;
198 animate_requested_ = true;
199 DebugScopedSetImplThread impl(this);
200 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01201 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]c5134172013-12-11 06:19:48202}
203
[email protected]8b9e52b2014-01-17 16:35:31204void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20205 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
[email protected]8b9e52b2014-01-17 16:35:31206 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22207 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31208}
209
enne98f3a6c2014-10-09 20:09:44210void SingleThreadProxy::DoCommit() {
[email protected]ccc08dc2014-01-30 07:33:20211 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
[email protected]a8a049c2013-03-11 23:27:06212 DCHECK(Proxy::IsMainThread());
enne98f3a6c2014-10-09 20:09:44213
robliao27728e62015-03-21 07:39:34214 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
215 // fixed.
216 tracked_objects::ScopedTracker tracking_profile1(
217 FROM_HERE_WITH_EXPLICIT_FUNCTION("461509 SingleThreadProxy::DoCommit1"));
[email protected]aeeedad2014-08-22 18:16:22218 layer_tree_host_->WillCommit();
caseq7d2f4c92015-02-04 16:43:27219 devtools_instrumentation::ScopedCommitTrace commit_task(
220 layer_tree_host_->id());
[email protected]aeeedad2014-08-22 18:16:22221
[email protected]a8a049c2013-03-11 23:27:06222 // Commit immediately.
223 {
robliao27728e62015-03-21 07:39:34224 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
225 // is fixed.
226 tracked_objects::ScopedTracker tracking_profile2(
227 FROM_HERE_WITH_EXPLICIT_FUNCTION(
228 "461509 SingleThreadProxy::DoCommit2"));
[email protected]819b9f52013-09-22 23:29:51229 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46230 DebugScopedSetImplThread impl(this);
231
[email protected]9794fb32013-08-29 09:49:59232 // This CapturePostTasks should be destroyed before CommitComplete() is
233 // called since that goes out to the embedder, and we want the embedder
234 // to receive its callbacks before that.
enne98f3a6c2014-10-09 20:09:44235 commit_blocking_task_runner_.reset(new BlockingTaskRunner::CapturePostTasks(
236 blocking_main_thread_task_runner()));
[email protected]9794fb32013-08-29 09:49:59237
[email protected]c1bb5af2013-03-13 19:06:27238 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14239
robliao27728e62015-03-21 07:39:34240 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
241 // is fixed.
robliao27728e62015-03-21 07:39:34242 tracked_objects::ScopedTracker tracking_profile6(
243 FROM_HERE_WITH_EXPLICIT_FUNCTION(
244 "461509 SingleThreadProxy::DoCommit6"));
[email protected]127bdc1a2013-09-11 01:44:48245 if (layer_tree_host_impl_->EvictedUIResourcesExist())
246 layer_tree_host_->RecreateUIResources();
247
robliao27728e62015-03-21 07:39:34248 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
249 // is fixed.
250 tracked_objects::ScopedTracker tracking_profile7(
251 FROM_HERE_WITH_EXPLICIT_FUNCTION(
252 "461509 SingleThreadProxy::DoCommit7"));
[email protected]804c8982013-03-13 16:32:21253 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14254
danakje649f572015-01-08 23:35:58255#if DCHECK_IS_ON()
[email protected]3519b872013-07-30 07:17:50256 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06257 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29258 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27259 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29260 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50261 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14262#endif
enne98f3a6c2014-10-09 20:09:44263
danakj3c3973b2015-08-25 21:50:18264 if (scheduler_on_impl_thread_)
265 scheduler_on_impl_thread_->DidCommit();
266
267 layer_tree_host_impl_->CommitComplete();
268
danakj68803fc2015-06-19 20:55:53269 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
270 // is fixed.
271 tracked_objects::ScopedTracker tracking_profile8(
272 FROM_HERE_WITH_EXPLICIT_FUNCTION(
273 "461509 SingleThreadProxy::DoCommit8"));
274 // Commit goes directly to the active tree, but we need to synchronously
275 // "activate" the tree still during commit to satisfy any potential
276 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
277 // might not be ready to draw, so DidActivateSyncTree must set
278 // the flag to force the tree to not draw until textures are ready.
279 NotifyReadyToActivate();
enne98f3a6c2014-10-09 20:09:44280 }
281}
282
283void SingleThreadProxy::CommitComplete() {
danakj3c3973b2015-08-25 21:50:18284 // Commit complete happens on the main side after activate to satisfy any
285 // SetNextCommitWaitsForActivation calls.
enne98f3a6c2014-10-09 20:09:44286 DCHECK(!layer_tree_host_impl_->pending_tree())
287 << "Activation is expected to have synchronously occurred by now.";
288 DCHECK(commit_blocking_task_runner_);
289
290 DebugScopedSetMainThread main(this);
291 commit_blocking_task_runner_.reset();
[email protected]804c8982013-03-13 16:32:21292 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22293 layer_tree_host_->DidBeginMainFrame();
[email protected]aeeedad2014-08-22 18:16:22294
[email protected]a8a049c2013-03-11 23:27:06295 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14296}
297
[email protected]a8a049c2013-03-11 23:27:06298void SingleThreadProxy::SetNeedsCommit() {
299 DCHECK(Proxy::IsMainThread());
[email protected]943528e2013-11-07 05:01:32300 client_->ScheduleComposite();
danakjfcdaba122015-04-24 21:41:52301 if (commit_requested_)
302 return;
brianderson49e101d22015-04-29 00:05:33303 commit_requested_ = true;
danakjfcdaba122015-04-24 21:41:52304 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22305 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01306 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]94f206c12012-08-25 00:09:14307}
308
[email protected]0023fc72014-01-10 20:05:06309void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20310 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
[email protected]aeeedad2014-08-22 18:16:22311 DCHECK(Proxy::IsMainThread());
312 DebugScopedSetImplThread impl(this);
[email protected]2decdd782014-08-13 22:36:06313 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22314 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14315}
316
[email protected]74b43cc2013-08-30 06:29:27317void SingleThreadProxy::SetNextCommitWaitsForActivation() {
enne98f3a6c2014-10-09 20:09:44318 // Activation always forced in commit, so nothing to do.
[email protected]aeeedad2014-08-22 18:16:22319 DCHECK(Proxy::IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27320}
321
[email protected]a8a049c2013-03-11 23:27:06322void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
[email protected]aeeedad2014-08-22 18:16:22323 DCHECK(Proxy::IsMainThread());
324 // Deferring commits only makes sense if there's a scheduler.
325 if (!scheduler_on_impl_thread_)
326 return;
327 if (defer_commits_ == defer_commits)
328 return;
329
330 if (defer_commits)
331 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
332 else
333 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
334
335 defer_commits_ = defer_commits;
simonhongc6309f792015-01-31 15:47:15336 scheduler_on_impl_thread_->SetDeferCommits(defer_commits);
[email protected]6b16679e2012-10-27 00:44:28337}
338
[email protected]174c6d42014-08-12 01:43:06339bool SingleThreadProxy::CommitRequested() const {
[email protected]aeeedad2014-08-22 18:16:22340 DCHECK(Proxy::IsMainThread());
341 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06342}
[email protected]a8a049c2013-03-11 23:27:06343
[email protected]174c6d42014-08-12 01:43:06344bool SingleThreadProxy::BeginMainFrameRequested() const {
[email protected]aeeedad2014-08-22 18:16:22345 DCHECK(Proxy::IsMainThread());
346 // If there is no scheduler, then there can be no pending begin frame,
347 // as all frames are all manually initiated by the embedder of cc.
348 if (!scheduler_on_impl_thread_)
349 return false;
350 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06351}
[email protected]971728d2013-10-26 10:39:31352
[email protected]a8a049c2013-03-11 23:27:06353void SingleThreadProxy::Stop() {
354 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
355 DCHECK(Proxy::IsMainThread());
356 {
[email protected]819b9f52013-09-22 23:29:51357 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06358 DebugScopedSetImplThread impl(this);
359
skyostil3976a3f2014-09-04 22:07:23360 BlockingTaskRunner::CapturePostTasks blocked(
361 blocking_main_thread_task_runner());
danakjf446a072014-09-27 21:55:48362 scheduler_on_impl_thread_ = nullptr;
363 layer_tree_host_impl_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06364 }
[email protected]7aba6662013-03-12 10:17:34365 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06366}
367
[email protected]3d9f7432013-04-06 00:35:18368void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
[email protected]ccc08dc2014-01-30 07:33:20369 TRACE_EVENT1(
370 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
[email protected]3d9f7432013-04-06 00:35:18371 DCHECK(Proxy::IsImplThread());
[email protected]aeeedad2014-08-22 18:16:22372 if (scheduler_on_impl_thread_)
373 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18374}
375
[email protected]4f48f6e2013-08-27 06:33:38376void SingleThreadProxy::NotifyReadyToActivate() {
enne98f3a6c2014-10-09 20:09:44377 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
378 DebugScopedSetImplThread impl(this);
379 if (scheduler_on_impl_thread_)
380 scheduler_on_impl_thread_->NotifyReadyToActivate();
[email protected]4f48f6e2013-08-27 06:33:38381}
382
ernstmdfac03e2014-11-11 20:18:05383void SingleThreadProxy::NotifyReadyToDraw() {
weiliangc8dac5a62015-04-02 06:12:35384 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToDraw");
385 DebugScopedSetImplThread impl(this);
386 if (scheduler_on_impl_thread_)
387 scheduler_on_impl_thread_->NotifyReadyToDraw();
ernstmdfac03e2014-11-11 20:18:05388}
389
[email protected]c1bb5af2013-03-13 19:06:27390void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]943528e2013-11-07 05:01:32391 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22392 if (scheduler_on_impl_thread_)
393 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06394}
395
[email protected]43b8f982014-04-30 21:24:33396void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
mithro719bf6792014-11-10 15:36:47397 client_->ScheduleComposite();
398 if (scheduler_on_impl_thread_)
399 scheduler_on_impl_thread_->SetNeedsAnimate();
[email protected]43b8f982014-04-30 21:24:33400}
401
vmiura59ea9b4042014-12-09 20:50:39402void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
403 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
enne98f3a6c2014-10-09 20:09:44404 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39405 scheduler_on_impl_thread_->SetNeedsPrepareTiles();
[email protected]c48536a52013-09-14 00:02:08406}
407
[email protected]0023fc72014-01-10 20:05:06408void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
409 const gfx::Rect& damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03410 layer_tree_host_impl_->SetViewportDamage(damage_rect);
[email protected]aeeedad2014-08-22 18:16:22411 SetNeedsRedrawOnImplThread();
[email protected]1cd9f5552013-04-26 04:22:03412}
413
[email protected]c1bb5af2013-03-13 19:06:27414void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]943528e2013-11-07 05:01:32415 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22416 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01417 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]a8a049c2013-03-11 23:27:06418}
419
sunnyps7d073dc2015-04-16 23:29:12420void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
421 TRACE_EVENT1("cc", "SingleThreadProxy::SetVideoNeedsBeginFrames",
422 "needs_begin_frames", needs_begin_frames);
423 // In tests the layer tree is destroyed after the scheduler is.
424 if (scheduler_on_impl_thread_)
425 scheduler_on_impl_thread_->SetVideoNeedsBeginFrames(needs_begin_frames);
426}
427
[email protected]c1bb5af2013-03-13 19:06:27428void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]85b57502014-03-11 15:37:48429 scoped_ptr<AnimationEventsVector> events) {
[email protected]ccc08dc2014-01-30 07:33:20430 TRACE_EVENT0(
431 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
[email protected]a8a049c2013-03-11 23:27:06432 DCHECK(Proxy::IsImplThread());
433 DebugScopedSetMainThread main(this);
[email protected]85b57502014-03-11 15:37:48434 layer_tree_host_->SetAnimationEvents(events.Pass());
[email protected]a8a049c2013-03-11 23:27:06435}
436
[email protected]c1bb5af2013-03-13 19:06:27437bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06438
enne98f3a6c2014-10-09 20:09:44439void SingleThreadProxy::DidActivateSyncTree() {
danakj68803fc2015-06-19 20:55:53440 // Synchronously call to CommitComplete. Resetting
441 // |commit_blocking_task_runner| would make sure all tasks posted during
442 // commit/activation before CommitComplete.
443 CommitComplete();
enne98f3a6c2014-10-09 20:09:44444}
445
brianderson68749812015-07-07 22:39:39446void SingleThreadProxy::WillPrepareTiles() {
447 DCHECK(Proxy::IsImplThread());
448 if (scheduler_on_impl_thread_)
449 scheduler_on_impl_thread_->WillPrepareTiles();
450}
451
vmiura59ea9b4042014-12-09 20:50:39452void SingleThreadProxy::DidPrepareTiles() {
enne98f3a6c2014-10-09 20:09:44453 DCHECK(Proxy::IsImplThread());
454 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39455 scheduler_on_impl_thread_->DidPrepareTiles();
enne98f3a6c2014-10-09 20:09:44456}
457
rouslanf7ebd8832015-01-22 01:54:14458void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
459 layer_tree_host_->DidCompletePageScaleAnimation();
460}
461
[email protected]fa339032014-02-18 22:11:59462void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
463 DCHECK(IsImplThread());
464 renderer_capabilities_for_main_thread_ =
465 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
466}
467
[email protected]c1bb5af2013-03-13 19:06:27468void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20469 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22470 {
471 DebugScopedSetMainThread main(this);
472 // This must happen before we notify the scheduler as it may try to recreate
473 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
474 layer_tree_host_->DidLoseOutputSurface();
475 }
[email protected]4d7e46a2013-11-08 05:33:40476 client_->DidAbortSwapBuffers();
[email protected]aeeedad2014-08-22 18:16:22477 if (scheduler_on_impl_thread_)
478 scheduler_on_impl_thread_->DidLoseOutputSurface();
[email protected]4d7e46a2013-11-08 05:33:40479}
480
weiliangcaf17af42014-12-15 22:17:02481void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
482 base::TimeDelta interval) {
483 if (scheduler_on_impl_thread_)
484 scheduler_on_impl_thread_->CommitVSyncParameters(timebase, interval);
485}
486
jbauman93a5a902015-03-13 22:16:55487void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
488 if (scheduler_on_impl_thread_)
489 scheduler_on_impl_thread_->SetEstimatedParentDrawTime(draw_time);
490}
491
alexst346f30c2015-03-25 13:24:05492void SingleThreadProxy::SetMaxSwapsPendingOnImplThread(int max) {
493 if (scheduler_on_impl_thread_)
494 scheduler_on_impl_thread_->SetMaxSwapsPending(max);
495}
496
[email protected]4d7e46a2013-11-08 05:33:40497void SingleThreadProxy::DidSwapBuffersOnImplThread() {
[email protected]aeeedad2014-08-22 18:16:22498 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
499 if (scheduler_on_impl_thread_)
500 scheduler_on_impl_thread_->DidSwapBuffers();
[email protected]4d7e46a2013-11-08 05:33:40501 client_->DidPostSwapBuffers();
502}
503
[email protected]c14902662014-04-18 05:06:11504void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
miletusfed8c43b2015-01-26 20:04:52505 TRACE_EVENT0("cc,benchmark",
506 "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22507 if (scheduler_on_impl_thread_)
508 scheduler_on_impl_thread_->DidSwapBuffersComplete();
509 layer_tree_host_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10510}
511
sunnypseab5ac92015-04-02 20:26:13512void SingleThreadProxy::OnDrawForOutputSurface() {
513 NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
514}
515
mpbed24c2c2015-06-05 20:57:13516void SingleThreadProxy::PostFrameTimingEventsOnImplThread(
517 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
518 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
519 layer_tree_host_->RecordFrameTimingEvents(composite_events.Pass(),
520 main_frame_events.Pass());
521}
522
wangxianzhu67d1fae2015-06-30 22:15:53523void SingleThreadProxy::LayoutAndUpdateLayers() {
524 if (layer_tree_host_->output_surface_lost()) {
525 RequestNewOutputSurface();
526 // RequestNewOutputSurface could have synchronously created an output
527 // surface, so check again before returning.
528 if (layer_tree_host_->output_surface_lost())
529 return;
530 }
531
532 layer_tree_host_->Layout();
533 layer_tree_host_->UpdateLayers();
534}
535
[email protected]f0c2a242013-03-15 19:34:52536void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
miletusfed8c43b2015-01-26 20:04:52537 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
[email protected]51f81da2014-05-16 21:29:26538 DCHECK(Proxy::IsMainThread());
mithro51693e382015-05-07 23:52:41539#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13540 DCHECK(!inside_impl_frame_);
mithro51693e382015-05-07 23:52:41541#endif
jbauman399aec1a2014-10-25 02:33:32542 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
543
544 if (layer_tree_host_->output_surface_lost()) {
545 RequestNewOutputSurface();
546 // RequestNewOutputSurface could have synchronously created an output
547 // surface, so check again before returning.
548 if (layer_tree_host_->output_surface_lost())
549 return;
550 }
[email protected]51f81da2014-05-16 21:29:26551
mithroc76d70312015-05-04 23:51:13552 BeginFrameArgs begin_frame_args(BeginFrameArgs::Create(
553 BEGINFRAME_FROM_HERE, frame_begin_time, base::TimeTicks(),
554 BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL));
555
556 // Start the impl frame.
enne98f3a6c2014-10-09 20:09:44557 {
mithroc76d70312015-05-04 23:51:13558 DebugScopedSetImplThread impl(this);
559 WillBeginImplFrame(begin_frame_args);
560 }
561
562 // Run the "main thread" and get it to commit.
563 {
mithro51693e382015-05-07 23:52:41564#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13565 DCHECK(inside_impl_frame_);
mithro51693e382015-05-07 23:52:41566#endif
enne98f3a6c2014-10-09 20:09:44567 DoBeginMainFrame(begin_frame_args);
568 DoCommit();
[email protected]e0341352013-04-06 05:01:20569
enne98f3a6c2014-10-09 20:09:44570 DCHECK_EQ(0u, layer_tree_host_->num_queued_swap_promises())
571 << "Commit should always succeed and transfer promises.";
572 }
573
mithroc76d70312015-05-04 23:51:13574 // Finish the impl frame.
enne98f3a6c2014-10-09 20:09:44575 {
mithroc76d70312015-05-04 23:51:13576 DebugScopedSetImplThread impl(this);
danakj68803fc2015-06-19 20:55:53577 layer_tree_host_impl_->ActivateSyncTree();
578 DCHECK(
579 !layer_tree_host_impl_->active_tree()->needs_update_draw_properties());
580 layer_tree_host_impl_->PrepareTiles();
581 layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
enne69277cb2014-10-29 23:03:40582
danakj12e2f6e2015-08-19 22:25:44583 // TODO(danakj): Don't do this last... we prepared the wrong things. D:
584 layer_tree_host_impl_->Animate();
mithro719bf6792014-11-10 15:36:47585
enne98f3a6c2014-10-09 20:09:44586 LayerTreeHostImpl::FrameData frame;
mithro248d1722015-05-05 05:23:45587 DoComposite(&frame);
enne98f3a6c2014-10-09 20:09:44588
589 // DoComposite could abort, but because this is a synchronous composite
590 // another draw will never be scheduled, so break remaining promises.
591 layer_tree_host_impl_->active_tree()->BreakSwapPromises(
592 SwapPromise::SWAP_FAILS);
mithroc76d70312015-05-04 23:51:13593
mithro51693e382015-05-07 23:52:41594 DidFinishImplFrame();
enne98f3a6c2014-10-09 20:09:44595 }
[email protected]74d9063c2013-01-18 03:14:47596}
597
[email protected]a8a049c2013-03-11 23:27:06598void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
599 {
600 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20601 if (layer_tree_host_impl_->renderer()) {
602 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06603 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20604 }
[email protected]a8a049c2013-03-11 23:27:06605 }
[email protected]8947cbe2012-11-28 05:27:43606}
607
[email protected]5d8bec72014-07-03 03:03:11608bool SingleThreadProxy::SupportsImplScrolling() const {
609 return false;
610}
611
[email protected]3d9f7432013-04-06 00:35:18612bool SingleThreadProxy::ShouldComposite() const {
613 DCHECK(Proxy::IsImplThread());
614 return layer_tree_host_impl_->visible() &&
615 layer_tree_host_impl_->CanDraw();
616}
617
jbauman8ab0f9e2014-10-15 02:30:34618void SingleThreadProxy::ScheduleRequestNewOutputSurface() {
619 if (output_surface_creation_callback_.IsCancelled() &&
620 !output_surface_creation_requested_) {
621 output_surface_creation_callback_.Reset(
622 base::Bind(&SingleThreadProxy::RequestNewOutputSurface,
623 weak_factory_.GetWeakPtr()));
624 MainThreadTaskRunner()->PostTask(
625 FROM_HERE, output_surface_creation_callback_.callback());
626 }
627}
628
mithro248d1722015-05-05 05:23:45629DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20630 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20631 DCHECK(!layer_tree_host_->output_surface_lost());
632
enne98f3a6c2014-10-09 20:09:44633 DrawResult draw_result;
634 bool draw_frame;
[email protected]a8a049c2013-03-11 23:27:06635 {
636 DebugScopedSetImplThread impl(this);
637 base::AutoReset<bool> mark_inside(&inside_draw_, true);
638
robliao27728e62015-03-21 07:39:34639 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
640 // is fixed.
641 tracked_objects::ScopedTracker tracking_profile1(
642 FROM_HERE_WITH_EXPLICIT_FUNCTION(
643 "461509 SingleThreadProxy::DoComposite1"));
644
[email protected]3d9f7432013-04-06 00:35:18645 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
646 // frame, so can only be used when such a frame is possible. Since
647 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
648 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50649 if (!ShouldComposite()) {
[email protected]aeeedad2014-08-22 18:16:22650 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18651 }
[email protected]a8a049c2013-03-11 23:27:06652
robliao27728e62015-03-21 07:39:34653 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
654 // is fixed.
655 tracked_objects::ScopedTracker tracking_profile2(
656 FROM_HERE_WITH_EXPLICIT_FUNCTION(
657 "461509 SingleThreadProxy::DoComposite2"));
enne98f3a6c2014-10-09 20:09:44658 draw_result = layer_tree_host_impl_->PrepareToDraw(frame);
659 draw_frame = draw_result == DRAW_SUCCESS;
robliao27728e62015-03-21 07:39:34660 if (draw_frame) {
661 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
662 // is fixed.
663 tracked_objects::ScopedTracker tracking_profile3(
664 FROM_HERE_WITH_EXPLICIT_FUNCTION(
665 "461509 SingleThreadProxy::DoComposite3"));
mithro248d1722015-05-05 05:23:45666 layer_tree_host_impl_->DrawLayers(frame);
robliao27728e62015-03-21 07:39:34667 }
668 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
669 // is fixed.
670 tracked_objects::ScopedTracker tracking_profile4(
671 FROM_HERE_WITH_EXPLICIT_FUNCTION(
672 "461509 SingleThreadProxy::DoComposite4"));
dnetob71e30c2014-08-25 23:27:20673 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06674
enne98f3a6c2014-10-09 20:09:44675 bool start_ready_animations = draw_frame;
robliao27728e62015-03-21 07:39:34676 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
677 // is fixed.
678 tracked_objects::ScopedTracker tracking_profile5(
679 FROM_HERE_WITH_EXPLICIT_FUNCTION(
680 "461509 SingleThreadProxy::DoComposite5"));
[email protected]3d9f7432013-04-06 00:35:18681 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]aeeedad2014-08-22 18:16:22682
robliao27728e62015-03-21 07:39:34683 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
684 // is fixed.
685 tracked_objects::ScopedTracker tracking_profile7(
686 FROM_HERE_WITH_EXPLICIT_FUNCTION(
687 "461509 SingleThreadProxy::DoComposite7"));
[email protected]a8a049c2013-03-11 23:27:06688 }
689
enne98f3a6c2014-10-09 20:09:44690 if (draw_frame) {
[email protected]aeeedad2014-08-22 18:16:22691 DebugScopedSetImplThread impl(this);
[email protected]174c6d42014-08-12 01:43:06692
dnetob71e30c2014-08-25 23:27:20693 // This CapturePostTasks should be destroyed before
694 // DidCommitAndDrawFrame() is called since that goes out to the
695 // embedder,
696 // and we want the embedder to receive its callbacks before that.
697 // NOTE: This maintains consistent ordering with the ThreadProxy since
698 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
699 // there as the main thread is not blocked, so any posted tasks inside
700 // the swap buffers will execute first.
701 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]aeeedad2014-08-22 18:16:22702
skyostil3976a3f2014-09-04 22:07:23703 BlockingTaskRunner::CapturePostTasks blocked(
704 blocking_main_thread_task_runner());
robliao27728e62015-03-21 07:39:34705 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
706 // is fixed.
707 tracked_objects::ScopedTracker tracking_profile8(
708 FROM_HERE_WITH_EXPLICIT_FUNCTION(
709 "461509 SingleThreadProxy::DoComposite8"));
dnetob71e30c2014-08-25 23:27:20710 layer_tree_host_impl_->SwapBuffers(*frame);
[email protected]aeeedad2014-08-22 18:16:22711 }
robliao27728e62015-03-21 07:39:34712 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
713 // fixed.
714 tracked_objects::ScopedTracker tracking_profile9(
715 FROM_HERE_WITH_EXPLICIT_FUNCTION(
716 "461509 SingleThreadProxy::DoComposite9"));
[email protected]aeeedad2014-08-22 18:16:22717 DidCommitAndDrawFrame();
718
enne98f3a6c2014-10-09 20:09:44719 return draw_result;
[email protected]a8a049c2013-03-11 23:27:06720}
721
[email protected]aeeedad2014-08-22 18:16:22722void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06723 if (next_frame_is_newly_committed_frame_) {
[email protected]aeeedad2014-08-22 18:16:22724 DebugScopedSetMainThread main(this);
[email protected]a8a049c2013-03-11 23:27:06725 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21726 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06727 }
728}
729
[email protected]4ea293f72014-08-13 03:03:17730bool SingleThreadProxy::MainFrameWillHappenForTesting() {
danakjfcdaba122015-04-24 21:41:52731 if (layer_tree_host_->output_surface_lost())
732 return false;
733 if (!scheduler_on_impl_thread_)
734 return false;
735 return scheduler_on_impl_thread_->MainFrameForTestingWillHappen();
[email protected]4ea293f72014-08-13 03:03:17736}
[email protected]a8a049c2013-03-11 23:27:06737
simonhongd3d5f7f2014-11-21 16:38:03738void SingleThreadProxy::SetChildrenNeedBeginFrames(
739 bool children_need_begin_frames) {
740 scheduler_on_impl_thread_->SetChildrenNeedBeginFrames(
741 children_need_begin_frames);
742}
743
simonhong298590fe2015-03-25 06:51:13744void SingleThreadProxy::SetAuthoritativeVSyncInterval(
745 const base::TimeDelta& interval) {
746 scheduler_on_impl_thread_->SetAuthoritativeVSyncInterval(interval);
747}
748
[email protected]aeeedad2014-08-22 18:16:22749void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
mithro51693e382015-05-07 23:52:41750#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02751 DCHECK(!inside_impl_frame_)
752 << "WillBeginImplFrame called while already inside an impl frame!";
753 inside_impl_frame_ = true;
mithro51693e382015-05-07 23:52:41754#endif
[email protected]aeeedad2014-08-22 18:16:22755 layer_tree_host_impl_->WillBeginImplFrame(args);
756}
757
758void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
759 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
760 // Although this proxy is single-threaded, it's problematic to synchronously
761 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
762 // could cause a commit to occur in between a series of SetNeedsCommit calls
763 // (i.e. property modifications) causing some to fall on one frame and some to
764 // fall on the next. Doing it asynchronously instead matches the semantics of
765 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
766 // synchronous commit.
mithro51693e382015-05-07 23:52:41767#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02768 DCHECK(inside_impl_frame_)
769 << "BeginMainFrame should only be sent inside a BeginImplFrame";
mithro51693e382015-05-07 23:52:41770#endif
mithro69fd3bb52015-05-01 03:45:02771 const BeginFrameArgs& begin_frame_args =
772 layer_tree_host_impl_->CurrentBeginFrameArgs();
773
[email protected]aeeedad2014-08-22 18:16:22774 MainThreadTaskRunner()->PostTask(
mithro69fd3bb52015-05-01 03:45:02775 FROM_HERE, base::Bind(&SingleThreadProxy::BeginMainFrame,
776 weak_factory_.GetWeakPtr(), begin_frame_args));
[email protected]aeeedad2014-08-22 18:16:22777}
778
rmcilroy0a19362a2015-02-18 12:34:25779void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
780 layer_tree_host_->BeginMainFrameNotExpectedSoon();
781}
782
mithro69fd3bb52015-05-01 03:45:02783void SingleThreadProxy::BeginMainFrame(const BeginFrameArgs& begin_frame_args) {
danakjfcdaba122015-04-24 21:41:52784 commit_requested_ = false;
brianderson49e101d22015-04-29 00:05:33785 animate_requested_ = false;
danakjfcdaba122015-04-24 21:41:52786
[email protected]aeeedad2014-08-22 18:16:22787 if (defer_commits_) {
simonhongc6309f792015-01-31 15:47:15788 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
789 TRACE_EVENT_SCOPE_THREAD);
790 BeginMainFrameAbortedOnImplThread(
791 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
[email protected]aeeedad2014-08-22 18:16:22792 return;
793 }
794
enne98f3a6c2014-10-09 20:09:44795 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
796 // commit.
[email protected]aeeedad2014-08-22 18:16:22797 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
798
799 if (!layer_tree_host_->visible()) {
800 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48801 BeginMainFrameAbortedOnImplThread(
802 CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
[email protected]aeeedad2014-08-22 18:16:22803 return;
804 }
805
806 if (layer_tree_host_->output_surface_lost()) {
807 TRACE_EVENT_INSTANT0(
808 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48809 BeginMainFrameAbortedOnImplThread(
810 CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST);
[email protected]aeeedad2014-08-22 18:16:22811 return;
812 }
813
danakjfcdaba122015-04-24 21:41:52814 // Prevent new commits from being requested inside DoBeginMainFrame.
brianderson49e101d22015-04-29 00:05:33815 // Note: We do not want to prevent SetNeedsAnimate from requesting
816 // a commit here.
danakjfcdaba122015-04-24 21:41:52817 commit_requested_ = true;
818
enne98f3a6c2014-10-09 20:09:44819 DoBeginMainFrame(begin_frame_args);
820}
821
822void SingleThreadProxy::DoBeginMainFrame(
823 const BeginFrameArgs& begin_frame_args) {
824 layer_tree_host_->WillBeginMainFrame();
825 layer_tree_host_->BeginMainFrame(begin_frame_args);
826 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
827 layer_tree_host_->Layout();
828
danakjfcdaba122015-04-24 21:41:52829 // New commits requested inside UpdateLayers should be respected.
830 commit_requested_ = false;
831
danakj5f46636a2015-06-19 00:01:40832 layer_tree_host_->UpdateLayers();
enne98f3a6c2014-10-09 20:09:44833
mithrof7a21502014-12-17 03:24:48834 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
835 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
836 // thread_proxy.cc
enne98f3a6c2014-10-09 20:09:44837 if (scheduler_on_impl_thread_) {
838 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
839 scheduler_on_impl_thread_->NotifyReadyToCommit();
840 }
[email protected]aeeedad2014-08-22 18:16:22841}
842
mithrof7a21502014-12-17 03:24:48843void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
844 CommitEarlyOutReason reason) {
[email protected]aeeedad2014-08-22 18:16:22845 DebugScopedSetImplThread impl(this);
846 DCHECK(scheduler_on_impl_thread_->CommitPending());
847 DCHECK(!layer_tree_host_impl_->pending_tree());
848
mithrof7a21502014-12-17 03:24:48849 layer_tree_host_impl_->BeginMainFrameAborted(reason);
850 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
[email protected]aeeedad2014-08-22 18:16:22851}
852
853DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
854 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22855 LayerTreeHostImpl::FrameData frame;
mithro248d1722015-05-05 05:23:45856 return DoComposite(&frame);
[email protected]aeeedad2014-08-22 18:16:22857}
858
859DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
860 NOTREACHED();
861 return INVALID_RESULT;
862}
863
864void SingleThreadProxy::ScheduledActionCommit() {
865 DebugScopedSetMainThread main(this);
enne98f3a6c2014-10-09 20:09:44866 DoCommit();
[email protected]aeeedad2014-08-22 18:16:22867}
868
869void SingleThreadProxy::ScheduledActionAnimate() {
870 TRACE_EVENT0("cc", "ScheduledActionAnimate");
mithro719bf6792014-11-10 15:36:47871 DebugScopedSetImplThread impl(this);
danakj12e2f6e2015-08-19 22:25:44872 layer_tree_host_impl_->Animate();
[email protected]aeeedad2014-08-22 18:16:22873}
874
[email protected]aeeedad2014-08-22 18:16:22875void SingleThreadProxy::ScheduledActionActivateSyncTree() {
enne98f3a6c2014-10-09 20:09:44876 DebugScopedSetImplThread impl(this);
877 layer_tree_host_impl_->ActivateSyncTree();
[email protected]aeeedad2014-08-22 18:16:22878}
879
880void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
881 DebugScopedSetMainThread main(this);
882 DCHECK(scheduler_on_impl_thread_);
883 // If possible, create the output surface in a post task. Synchronously
884 // creating the output surface makes tests more awkward since this differs
885 // from the ThreadProxy behavior. However, sometimes there is no
886 // task runner.
887 if (Proxy::MainThreadTaskRunner()) {
jbauman8ab0f9e2014-10-15 02:30:34888 ScheduleRequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22889 } else {
enne2097cab2014-09-25 20:16:31890 RequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22891 }
892}
893
vmiura59ea9b4042014-12-09 20:50:39894void SingleThreadProxy::ScheduledActionPrepareTiles() {
895 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
enne98f3a6c2014-10-09 20:09:44896 DebugScopedSetImplThread impl(this);
vmiura59ea9b4042014-12-09 20:50:39897 layer_tree_host_impl_->PrepareTiles();
[email protected]aeeedad2014-08-22 18:16:22898}
899
sunnypseab5ac92015-04-02 20:26:13900void SingleThreadProxy::ScheduledActionInvalidateOutputSurface() {
901 NOTREACHED();
902}
903
mithro51693e382015-05-07 23:52:41904void SingleThreadProxy::DidFinishImplFrame() {
905 layer_tree_host_impl_->DidFinishImplFrame();
906#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02907 DCHECK(inside_impl_frame_)
mithro51693e382015-05-07 23:52:41908 << "DidFinishImplFrame called while not inside an impl frame!";
mithro69fd3bb52015-05-01 03:45:02909 inside_impl_frame_ = false;
mithro51693e382015-05-07 23:52:41910#endif
[email protected]aeeedad2014-08-22 18:16:22911}
912
simonhongd3d5f7f2014-11-21 16:38:03913void SingleThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) {
914 layer_tree_host_->SendBeginFramesToChildren(args);
915}
916
[email protected]bc5e77c2012-11-05 20:00:49917} // namespace cc