blob: cefc0748ad15f6f6cac702a1d4f006ebc82747b7 [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
revemand180dfc32015-09-24 00:19:43152void SingleThreadProxy::ReleaseOutputSurface() {
sieverse83e41d2015-09-18 23:33:26153 // |layer_tree_host_| should already be aware of this.
154 DCHECK(layer_tree_host_->output_surface_lost());
155
sohan.jyoti3a33d872015-09-18 22:32:55156 if (scheduler_on_impl_thread_)
157 scheduler_on_impl_thread_->DidLoseOutputSurface();
158 return layer_tree_host_impl_->ReleaseOutputSurface();
159}
160
revemand180dfc32015-09-24 00:19:43161void SingleThreadProxy::SetOutputSurface(OutputSurface* output_surface) {
enne2097cab2014-09-25 20:16:31162 DCHECK(Proxy::IsMainThread());
163 DCHECK(layer_tree_host_->output_surface_lost());
enne5232fbb2015-01-27 21:22:41164 DCHECK(output_surface_creation_requested_);
[email protected]da8e3b72b2014-04-25 02:33:45165 renderer_capabilities_for_main_thread_ = RendererCapabilities();
166
enne7f8fdde2014-12-10 21:32:09167 bool success;
168 {
[email protected]819b9f52013-09-22 23:29:51169 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06170 DebugScopedSetImplThread impl(this);
revemand180dfc32015-09-24 00:19:43171 success = layer_tree_host_impl_->InitializeRenderer(output_surface);
[email protected]04049fc2013-05-01 03:13:20172 }
173
[email protected]aeeedad2014-08-22 18:16:22174 if (success) {
enne7f8fdde2014-12-10 21:32:09175 layer_tree_host_->DidInitializeOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22176 if (scheduler_on_impl_thread_)
177 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
jbauman399aec1a2014-10-25 02:33:32178 else if (!inside_synchronous_composite_)
179 SetNeedsCommit();
enne5232fbb2015-01-27 21:22:41180 output_surface_creation_requested_ = false;
enne7f8fdde2014-12-10 21:32:09181 } else {
enne5232fbb2015-01-27 21:22:41182 // DidFailToInitializeOutputSurface is treated as a RequestNewOutputSurface,
183 // and so output_surface_creation_requested remains true.
enne7f8fdde2014-12-10 21:32:09184 layer_tree_host_->DidFailToInitializeOutputSurface();
[email protected]04049fc2013-05-01 03:13:20185 }
[email protected]94f206c12012-08-25 00:09:14186}
187
[email protected]a8a049c2013-03-11 23:27:06188const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20189 DCHECK(Proxy::IsMainThread());
190 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06191 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14192}
193
[email protected]8b9e52b2014-01-17 16:35:31194void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20195 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
[email protected]c5134172013-12-11 06:19:48196 DCHECK(Proxy::IsMainThread());
[email protected]06cbc31b2014-01-17 06:43:20197 client_->ScheduleAnimation();
brianderson49e101d22015-04-29 00:05:33198 if (animate_requested_)
199 return;
200 animate_requested_ = true;
201 DebugScopedSetImplThread impl(this);
202 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01203 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]c5134172013-12-11 06:19:48204}
205
[email protected]8b9e52b2014-01-17 16:35:31206void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20207 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
[email protected]8b9e52b2014-01-17 16:35:31208 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22209 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31210}
211
enne98f3a6c2014-10-09 20:09:44212void SingleThreadProxy::DoCommit() {
[email protected]ccc08dc2014-01-30 07:33:20213 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
[email protected]a8a049c2013-03-11 23:27:06214 DCHECK(Proxy::IsMainThread());
enne98f3a6c2014-10-09 20:09:44215
robliao27728e62015-03-21 07:39:34216 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
217 // fixed.
218 tracked_objects::ScopedTracker tracking_profile1(
219 FROM_HERE_WITH_EXPLICIT_FUNCTION("461509 SingleThreadProxy::DoCommit1"));
[email protected]aeeedad2014-08-22 18:16:22220 layer_tree_host_->WillCommit();
caseq7d2f4c92015-02-04 16:43:27221 devtools_instrumentation::ScopedCommitTrace commit_task(
222 layer_tree_host_->id());
[email protected]aeeedad2014-08-22 18:16:22223
[email protected]a8a049c2013-03-11 23:27:06224 // Commit immediately.
225 {
robliao27728e62015-03-21 07:39:34226 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
227 // is fixed.
228 tracked_objects::ScopedTracker tracking_profile2(
229 FROM_HERE_WITH_EXPLICIT_FUNCTION(
230 "461509 SingleThreadProxy::DoCommit2"));
[email protected]819b9f52013-09-22 23:29:51231 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46232 DebugScopedSetImplThread impl(this);
233
[email protected]9794fb32013-08-29 09:49:59234 // This CapturePostTasks should be destroyed before CommitComplete() is
235 // called since that goes out to the embedder, and we want the embedder
236 // to receive its callbacks before that.
enne98f3a6c2014-10-09 20:09:44237 commit_blocking_task_runner_.reset(new BlockingTaskRunner::CapturePostTasks(
238 blocking_main_thread_task_runner()));
[email protected]9794fb32013-08-29 09:49:59239
[email protected]c1bb5af2013-03-13 19:06:27240 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14241
robliao27728e62015-03-21 07:39:34242 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
243 // is fixed.
robliao27728e62015-03-21 07:39:34244 tracked_objects::ScopedTracker tracking_profile6(
245 FROM_HERE_WITH_EXPLICIT_FUNCTION(
246 "461509 SingleThreadProxy::DoCommit6"));
[email protected]127bdc1a2013-09-11 01:44:48247 if (layer_tree_host_impl_->EvictedUIResourcesExist())
248 layer_tree_host_->RecreateUIResources();
249
robliao27728e62015-03-21 07:39:34250 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
251 // is fixed.
252 tracked_objects::ScopedTracker tracking_profile7(
253 FROM_HERE_WITH_EXPLICIT_FUNCTION(
254 "461509 SingleThreadProxy::DoCommit7"));
[email protected]804c8982013-03-13 16:32:21255 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14256
danakje649f572015-01-08 23:35:58257#if DCHECK_IS_ON()
[email protected]3519b872013-07-30 07:17:50258 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06259 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29260 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27261 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29262 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50263 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14264#endif
enne98f3a6c2014-10-09 20:09:44265
danakj3c3973b2015-08-25 21:50:18266 if (scheduler_on_impl_thread_)
267 scheduler_on_impl_thread_->DidCommit();
268
269 layer_tree_host_impl_->CommitComplete();
270
danakj68803fc2015-06-19 20:55:53271 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
272 // is fixed.
273 tracked_objects::ScopedTracker tracking_profile8(
274 FROM_HERE_WITH_EXPLICIT_FUNCTION(
275 "461509 SingleThreadProxy::DoCommit8"));
276 // Commit goes directly to the active tree, but we need to synchronously
277 // "activate" the tree still during commit to satisfy any potential
278 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
279 // might not be ready to draw, so DidActivateSyncTree must set
280 // the flag to force the tree to not draw until textures are ready.
281 NotifyReadyToActivate();
enne98f3a6c2014-10-09 20:09:44282 }
283}
284
285void SingleThreadProxy::CommitComplete() {
danakj3c3973b2015-08-25 21:50:18286 // Commit complete happens on the main side after activate to satisfy any
287 // SetNextCommitWaitsForActivation calls.
enne98f3a6c2014-10-09 20:09:44288 DCHECK(!layer_tree_host_impl_->pending_tree())
289 << "Activation is expected to have synchronously occurred by now.";
290 DCHECK(commit_blocking_task_runner_);
291
292 DebugScopedSetMainThread main(this);
293 commit_blocking_task_runner_.reset();
[email protected]804c8982013-03-13 16:32:21294 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22295 layer_tree_host_->DidBeginMainFrame();
[email protected]aeeedad2014-08-22 18:16:22296
[email protected]a8a049c2013-03-11 23:27:06297 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14298}
299
[email protected]a8a049c2013-03-11 23:27:06300void SingleThreadProxy::SetNeedsCommit() {
301 DCHECK(Proxy::IsMainThread());
[email protected]943528e2013-11-07 05:01:32302 client_->ScheduleComposite();
danakjfcdaba122015-04-24 21:41:52303 if (commit_requested_)
304 return;
brianderson49e101d22015-04-29 00:05:33305 commit_requested_ = true;
danakjfcdaba122015-04-24 21:41:52306 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22307 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01308 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]94f206c12012-08-25 00:09:14309}
310
[email protected]0023fc72014-01-10 20:05:06311void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20312 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
[email protected]aeeedad2014-08-22 18:16:22313 DCHECK(Proxy::IsMainThread());
314 DebugScopedSetImplThread impl(this);
[email protected]2decdd782014-08-13 22:36:06315 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22316 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14317}
318
[email protected]74b43cc2013-08-30 06:29:27319void SingleThreadProxy::SetNextCommitWaitsForActivation() {
enne98f3a6c2014-10-09 20:09:44320 // Activation always forced in commit, so nothing to do.
[email protected]aeeedad2014-08-22 18:16:22321 DCHECK(Proxy::IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27322}
323
[email protected]a8a049c2013-03-11 23:27:06324void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
[email protected]aeeedad2014-08-22 18:16:22325 DCHECK(Proxy::IsMainThread());
326 // Deferring commits only makes sense if there's a scheduler.
327 if (!scheduler_on_impl_thread_)
328 return;
329 if (defer_commits_ == defer_commits)
330 return;
331
332 if (defer_commits)
333 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
334 else
335 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
336
337 defer_commits_ = defer_commits;
simonhongc6309f792015-01-31 15:47:15338 scheduler_on_impl_thread_->SetDeferCommits(defer_commits);
[email protected]6b16679e2012-10-27 00:44:28339}
340
[email protected]174c6d42014-08-12 01:43:06341bool SingleThreadProxy::CommitRequested() const {
[email protected]aeeedad2014-08-22 18:16:22342 DCHECK(Proxy::IsMainThread());
343 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06344}
[email protected]a8a049c2013-03-11 23:27:06345
[email protected]174c6d42014-08-12 01:43:06346bool SingleThreadProxy::BeginMainFrameRequested() const {
[email protected]aeeedad2014-08-22 18:16:22347 DCHECK(Proxy::IsMainThread());
348 // If there is no scheduler, then there can be no pending begin frame,
349 // as all frames are all manually initiated by the embedder of cc.
350 if (!scheduler_on_impl_thread_)
351 return false;
352 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06353}
[email protected]971728d2013-10-26 10:39:31354
[email protected]a8a049c2013-03-11 23:27:06355void SingleThreadProxy::Stop() {
356 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
357 DCHECK(Proxy::IsMainThread());
358 {
[email protected]819b9f52013-09-22 23:29:51359 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06360 DebugScopedSetImplThread impl(this);
361
skyostil3976a3f2014-09-04 22:07:23362 BlockingTaskRunner::CapturePostTasks blocked(
363 blocking_main_thread_task_runner());
danakjf446a072014-09-27 21:55:48364 scheduler_on_impl_thread_ = nullptr;
365 layer_tree_host_impl_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06366 }
[email protected]7aba6662013-03-12 10:17:34367 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06368}
369
[email protected]3d9f7432013-04-06 00:35:18370void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
[email protected]ccc08dc2014-01-30 07:33:20371 TRACE_EVENT1(
372 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
[email protected]3d9f7432013-04-06 00:35:18373 DCHECK(Proxy::IsImplThread());
[email protected]aeeedad2014-08-22 18:16:22374 if (scheduler_on_impl_thread_)
375 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18376}
377
[email protected]4f48f6e2013-08-27 06:33:38378void SingleThreadProxy::NotifyReadyToActivate() {
enne98f3a6c2014-10-09 20:09:44379 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
380 DebugScopedSetImplThread impl(this);
381 if (scheduler_on_impl_thread_)
382 scheduler_on_impl_thread_->NotifyReadyToActivate();
[email protected]4f48f6e2013-08-27 06:33:38383}
384
ernstmdfac03e2014-11-11 20:18:05385void SingleThreadProxy::NotifyReadyToDraw() {
weiliangc8dac5a62015-04-02 06:12:35386 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToDraw");
387 DebugScopedSetImplThread impl(this);
388 if (scheduler_on_impl_thread_)
389 scheduler_on_impl_thread_->NotifyReadyToDraw();
ernstmdfac03e2014-11-11 20:18:05390}
391
[email protected]c1bb5af2013-03-13 19:06:27392void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]943528e2013-11-07 05:01:32393 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22394 if (scheduler_on_impl_thread_)
395 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06396}
397
[email protected]43b8f982014-04-30 21:24:33398void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
mithro719bf6792014-11-10 15:36:47399 client_->ScheduleComposite();
400 if (scheduler_on_impl_thread_)
401 scheduler_on_impl_thread_->SetNeedsAnimate();
[email protected]43b8f982014-04-30 21:24:33402}
403
vmiura59ea9b4042014-12-09 20:50:39404void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
405 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
enne98f3a6c2014-10-09 20:09:44406 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39407 scheduler_on_impl_thread_->SetNeedsPrepareTiles();
[email protected]c48536a52013-09-14 00:02:08408}
409
[email protected]0023fc72014-01-10 20:05:06410void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
411 const gfx::Rect& damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03412 layer_tree_host_impl_->SetViewportDamage(damage_rect);
[email protected]aeeedad2014-08-22 18:16:22413 SetNeedsRedrawOnImplThread();
[email protected]1cd9f5552013-04-26 04:22:03414}
415
[email protected]c1bb5af2013-03-13 19:06:27416void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]943528e2013-11-07 05:01:32417 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22418 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01419 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]a8a049c2013-03-11 23:27:06420}
421
sunnyps7d073dc2015-04-16 23:29:12422void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
423 TRACE_EVENT1("cc", "SingleThreadProxy::SetVideoNeedsBeginFrames",
424 "needs_begin_frames", needs_begin_frames);
425 // In tests the layer tree is destroyed after the scheduler is.
426 if (scheduler_on_impl_thread_)
427 scheduler_on_impl_thread_->SetVideoNeedsBeginFrames(needs_begin_frames);
428}
429
[email protected]c1bb5af2013-03-13 19:06:27430void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]85b57502014-03-11 15:37:48431 scoped_ptr<AnimationEventsVector> events) {
[email protected]ccc08dc2014-01-30 07:33:20432 TRACE_EVENT0(
433 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
[email protected]a8a049c2013-03-11 23:27:06434 DCHECK(Proxy::IsImplThread());
435 DebugScopedSetMainThread main(this);
[email protected]85b57502014-03-11 15:37:48436 layer_tree_host_->SetAnimationEvents(events.Pass());
[email protected]a8a049c2013-03-11 23:27:06437}
438
[email protected]c1bb5af2013-03-13 19:06:27439bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06440
enne98f3a6c2014-10-09 20:09:44441void SingleThreadProxy::DidActivateSyncTree() {
danakj68803fc2015-06-19 20:55:53442 // Synchronously call to CommitComplete. Resetting
443 // |commit_blocking_task_runner| would make sure all tasks posted during
444 // commit/activation before CommitComplete.
445 CommitComplete();
enne98f3a6c2014-10-09 20:09:44446}
447
brianderson68749812015-07-07 22:39:39448void SingleThreadProxy::WillPrepareTiles() {
449 DCHECK(Proxy::IsImplThread());
450 if (scheduler_on_impl_thread_)
451 scheduler_on_impl_thread_->WillPrepareTiles();
452}
453
vmiura59ea9b4042014-12-09 20:50:39454void SingleThreadProxy::DidPrepareTiles() {
enne98f3a6c2014-10-09 20:09:44455 DCHECK(Proxy::IsImplThread());
456 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39457 scheduler_on_impl_thread_->DidPrepareTiles();
enne98f3a6c2014-10-09 20:09:44458}
459
rouslanf7ebd8832015-01-22 01:54:14460void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
461 layer_tree_host_->DidCompletePageScaleAnimation();
462}
463
[email protected]fa339032014-02-18 22:11:59464void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
465 DCHECK(IsImplThread());
466 renderer_capabilities_for_main_thread_ =
467 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
468}
469
[email protected]c1bb5af2013-03-13 19:06:27470void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20471 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22472 {
473 DebugScopedSetMainThread main(this);
474 // This must happen before we notify the scheduler as it may try to recreate
475 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
476 layer_tree_host_->DidLoseOutputSurface();
477 }
[email protected]4d7e46a2013-11-08 05:33:40478 client_->DidAbortSwapBuffers();
[email protected]aeeedad2014-08-22 18:16:22479 if (scheduler_on_impl_thread_)
480 scheduler_on_impl_thread_->DidLoseOutputSurface();
[email protected]4d7e46a2013-11-08 05:33:40481}
482
weiliangcaf17af42014-12-15 22:17:02483void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
484 base::TimeDelta interval) {
485 if (scheduler_on_impl_thread_)
486 scheduler_on_impl_thread_->CommitVSyncParameters(timebase, interval);
487}
488
jbauman93a5a902015-03-13 22:16:55489void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
490 if (scheduler_on_impl_thread_)
491 scheduler_on_impl_thread_->SetEstimatedParentDrawTime(draw_time);
492}
493
alexst346f30c2015-03-25 13:24:05494void SingleThreadProxy::SetMaxSwapsPendingOnImplThread(int max) {
495 if (scheduler_on_impl_thread_)
496 scheduler_on_impl_thread_->SetMaxSwapsPending(max);
497}
498
[email protected]4d7e46a2013-11-08 05:33:40499void SingleThreadProxy::DidSwapBuffersOnImplThread() {
[email protected]aeeedad2014-08-22 18:16:22500 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
501 if (scheduler_on_impl_thread_)
502 scheduler_on_impl_thread_->DidSwapBuffers();
[email protected]4d7e46a2013-11-08 05:33:40503 client_->DidPostSwapBuffers();
504}
505
[email protected]c14902662014-04-18 05:06:11506void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
miletusfed8c43b2015-01-26 20:04:52507 TRACE_EVENT0("cc,benchmark",
508 "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22509 if (scheduler_on_impl_thread_)
510 scheduler_on_impl_thread_->DidSwapBuffersComplete();
511 layer_tree_host_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10512}
513
sunnypseab5ac92015-04-02 20:26:13514void SingleThreadProxy::OnDrawForOutputSurface() {
515 NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
516}
517
mpbed24c2c2015-06-05 20:57:13518void SingleThreadProxy::PostFrameTimingEventsOnImplThread(
519 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
520 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
521 layer_tree_host_->RecordFrameTimingEvents(composite_events.Pass(),
522 main_frame_events.Pass());
523}
524
wangxianzhu67d1fae2015-06-30 22:15:53525void SingleThreadProxy::LayoutAndUpdateLayers() {
526 if (layer_tree_host_->output_surface_lost()) {
527 RequestNewOutputSurface();
528 // RequestNewOutputSurface could have synchronously created an output
529 // surface, so check again before returning.
530 if (layer_tree_host_->output_surface_lost())
531 return;
532 }
533
534 layer_tree_host_->Layout();
535 layer_tree_host_->UpdateLayers();
536}
537
[email protected]f0c2a242013-03-15 19:34:52538void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
miletusfed8c43b2015-01-26 20:04:52539 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
[email protected]51f81da2014-05-16 21:29:26540 DCHECK(Proxy::IsMainThread());
mithro51693e382015-05-07 23:52:41541#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13542 DCHECK(!inside_impl_frame_);
mithro51693e382015-05-07 23:52:41543#endif
jbauman399aec1a2014-10-25 02:33:32544 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
545
546 if (layer_tree_host_->output_surface_lost()) {
547 RequestNewOutputSurface();
548 // RequestNewOutputSurface could have synchronously created an output
549 // surface, so check again before returning.
550 if (layer_tree_host_->output_surface_lost())
551 return;
552 }
[email protected]51f81da2014-05-16 21:29:26553
mithroc76d70312015-05-04 23:51:13554 BeginFrameArgs begin_frame_args(BeginFrameArgs::Create(
555 BEGINFRAME_FROM_HERE, frame_begin_time, base::TimeTicks(),
556 BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL));
557
558 // Start the impl frame.
enne98f3a6c2014-10-09 20:09:44559 {
mithroc76d70312015-05-04 23:51:13560 DebugScopedSetImplThread impl(this);
561 WillBeginImplFrame(begin_frame_args);
562 }
563
564 // Run the "main thread" and get it to commit.
565 {
mithro51693e382015-05-07 23:52:41566#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13567 DCHECK(inside_impl_frame_);
mithro51693e382015-05-07 23:52:41568#endif
enne98f3a6c2014-10-09 20:09:44569 DoBeginMainFrame(begin_frame_args);
570 DoCommit();
[email protected]e0341352013-04-06 05:01:20571
enne98f3a6c2014-10-09 20:09:44572 DCHECK_EQ(0u, layer_tree_host_->num_queued_swap_promises())
573 << "Commit should always succeed and transfer promises.";
574 }
575
mithroc76d70312015-05-04 23:51:13576 // Finish the impl frame.
enne98f3a6c2014-10-09 20:09:44577 {
mithroc76d70312015-05-04 23:51:13578 DebugScopedSetImplThread impl(this);
danakj68803fc2015-06-19 20:55:53579 layer_tree_host_impl_->ActivateSyncTree();
580 DCHECK(
581 !layer_tree_host_impl_->active_tree()->needs_update_draw_properties());
582 layer_tree_host_impl_->PrepareTiles();
583 layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
enne69277cb2014-10-29 23:03:40584
danakj12e2f6e2015-08-19 22:25:44585 // TODO(danakj): Don't do this last... we prepared the wrong things. D:
586 layer_tree_host_impl_->Animate();
mithro719bf6792014-11-10 15:36:47587
enne98f3a6c2014-10-09 20:09:44588 LayerTreeHostImpl::FrameData frame;
mithro248d1722015-05-05 05:23:45589 DoComposite(&frame);
enne98f3a6c2014-10-09 20:09:44590
591 // DoComposite could abort, but because this is a synchronous composite
592 // another draw will never be scheduled, so break remaining promises.
593 layer_tree_host_impl_->active_tree()->BreakSwapPromises(
594 SwapPromise::SWAP_FAILS);
mithroc76d70312015-05-04 23:51:13595
mithro51693e382015-05-07 23:52:41596 DidFinishImplFrame();
enne98f3a6c2014-10-09 20:09:44597 }
[email protected]74d9063c2013-01-18 03:14:47598}
599
[email protected]5d8bec72014-07-03 03:03:11600bool SingleThreadProxy::SupportsImplScrolling() const {
601 return false;
602}
603
[email protected]3d9f7432013-04-06 00:35:18604bool SingleThreadProxy::ShouldComposite() const {
605 DCHECK(Proxy::IsImplThread());
606 return layer_tree_host_impl_->visible() &&
607 layer_tree_host_impl_->CanDraw();
608}
609
jbauman8ab0f9e2014-10-15 02:30:34610void SingleThreadProxy::ScheduleRequestNewOutputSurface() {
611 if (output_surface_creation_callback_.IsCancelled() &&
612 !output_surface_creation_requested_) {
613 output_surface_creation_callback_.Reset(
614 base::Bind(&SingleThreadProxy::RequestNewOutputSurface,
615 weak_factory_.GetWeakPtr()));
616 MainThreadTaskRunner()->PostTask(
617 FROM_HERE, output_surface_creation_callback_.callback());
618 }
619}
620
mithro248d1722015-05-05 05:23:45621DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20622 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20623 DCHECK(!layer_tree_host_->output_surface_lost());
624
enne98f3a6c2014-10-09 20:09:44625 DrawResult draw_result;
626 bool draw_frame;
[email protected]a8a049c2013-03-11 23:27:06627 {
628 DebugScopedSetImplThread impl(this);
629 base::AutoReset<bool> mark_inside(&inside_draw_, true);
630
robliao27728e62015-03-21 07:39:34631 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
632 // is fixed.
633 tracked_objects::ScopedTracker tracking_profile1(
634 FROM_HERE_WITH_EXPLICIT_FUNCTION(
635 "461509 SingleThreadProxy::DoComposite1"));
636
[email protected]3d9f7432013-04-06 00:35:18637 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
638 // frame, so can only be used when such a frame is possible. Since
639 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
640 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50641 if (!ShouldComposite()) {
[email protected]aeeedad2014-08-22 18:16:22642 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18643 }
[email protected]a8a049c2013-03-11 23:27:06644
robliao27728e62015-03-21 07:39:34645 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
646 // is fixed.
647 tracked_objects::ScopedTracker tracking_profile2(
648 FROM_HERE_WITH_EXPLICIT_FUNCTION(
649 "461509 SingleThreadProxy::DoComposite2"));
enne98f3a6c2014-10-09 20:09:44650 draw_result = layer_tree_host_impl_->PrepareToDraw(frame);
651 draw_frame = draw_result == DRAW_SUCCESS;
robliao27728e62015-03-21 07:39:34652 if (draw_frame) {
653 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
654 // is fixed.
655 tracked_objects::ScopedTracker tracking_profile3(
656 FROM_HERE_WITH_EXPLICIT_FUNCTION(
657 "461509 SingleThreadProxy::DoComposite3"));
mithro248d1722015-05-05 05:23:45658 layer_tree_host_impl_->DrawLayers(frame);
robliao27728e62015-03-21 07:39:34659 }
660 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
661 // is fixed.
662 tracked_objects::ScopedTracker tracking_profile4(
663 FROM_HERE_WITH_EXPLICIT_FUNCTION(
664 "461509 SingleThreadProxy::DoComposite4"));
dnetob71e30c2014-08-25 23:27:20665 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06666
enne98f3a6c2014-10-09 20:09:44667 bool start_ready_animations = draw_frame;
robliao27728e62015-03-21 07:39:34668 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
669 // is fixed.
670 tracked_objects::ScopedTracker tracking_profile5(
671 FROM_HERE_WITH_EXPLICIT_FUNCTION(
672 "461509 SingleThreadProxy::DoComposite5"));
[email protected]3d9f7432013-04-06 00:35:18673 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]aeeedad2014-08-22 18:16:22674
robliao27728e62015-03-21 07:39:34675 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
676 // is fixed.
677 tracked_objects::ScopedTracker tracking_profile7(
678 FROM_HERE_WITH_EXPLICIT_FUNCTION(
679 "461509 SingleThreadProxy::DoComposite7"));
[email protected]a8a049c2013-03-11 23:27:06680 }
681
enne98f3a6c2014-10-09 20:09:44682 if (draw_frame) {
[email protected]aeeedad2014-08-22 18:16:22683 DebugScopedSetImplThread impl(this);
[email protected]174c6d42014-08-12 01:43:06684
dnetob71e30c2014-08-25 23:27:20685 // This CapturePostTasks should be destroyed before
686 // DidCommitAndDrawFrame() is called since that goes out to the
687 // embedder,
688 // and we want the embedder to receive its callbacks before that.
689 // NOTE: This maintains consistent ordering with the ThreadProxy since
690 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
691 // there as the main thread is not blocked, so any posted tasks inside
692 // the swap buffers will execute first.
693 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]aeeedad2014-08-22 18:16:22694
skyostil3976a3f2014-09-04 22:07:23695 BlockingTaskRunner::CapturePostTasks blocked(
696 blocking_main_thread_task_runner());
robliao27728e62015-03-21 07:39:34697 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
698 // is fixed.
699 tracked_objects::ScopedTracker tracking_profile8(
700 FROM_HERE_WITH_EXPLICIT_FUNCTION(
701 "461509 SingleThreadProxy::DoComposite8"));
dnetob71e30c2014-08-25 23:27:20702 layer_tree_host_impl_->SwapBuffers(*frame);
[email protected]aeeedad2014-08-22 18:16:22703 }
robliao27728e62015-03-21 07:39:34704 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
705 // fixed.
706 tracked_objects::ScopedTracker tracking_profile9(
707 FROM_HERE_WITH_EXPLICIT_FUNCTION(
708 "461509 SingleThreadProxy::DoComposite9"));
[email protected]aeeedad2014-08-22 18:16:22709 DidCommitAndDrawFrame();
710
enne98f3a6c2014-10-09 20:09:44711 return draw_result;
[email protected]a8a049c2013-03-11 23:27:06712}
713
[email protected]aeeedad2014-08-22 18:16:22714void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06715 if (next_frame_is_newly_committed_frame_) {
[email protected]aeeedad2014-08-22 18:16:22716 DebugScopedSetMainThread main(this);
[email protected]a8a049c2013-03-11 23:27:06717 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21718 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06719 }
720}
721
[email protected]4ea293f72014-08-13 03:03:17722bool SingleThreadProxy::MainFrameWillHappenForTesting() {
danakjfcdaba122015-04-24 21:41:52723 if (layer_tree_host_->output_surface_lost())
724 return false;
725 if (!scheduler_on_impl_thread_)
726 return false;
727 return scheduler_on_impl_thread_->MainFrameForTestingWillHappen();
[email protected]4ea293f72014-08-13 03:03:17728}
[email protected]a8a049c2013-03-11 23:27:06729
simonhongd3d5f7f2014-11-21 16:38:03730void SingleThreadProxy::SetChildrenNeedBeginFrames(
731 bool children_need_begin_frames) {
732 scheduler_on_impl_thread_->SetChildrenNeedBeginFrames(
733 children_need_begin_frames);
734}
735
simonhong298590fe2015-03-25 06:51:13736void SingleThreadProxy::SetAuthoritativeVSyncInterval(
737 const base::TimeDelta& interval) {
738 scheduler_on_impl_thread_->SetAuthoritativeVSyncInterval(interval);
739}
740
[email protected]aeeedad2014-08-22 18:16:22741void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
mithro51693e382015-05-07 23:52:41742#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02743 DCHECK(!inside_impl_frame_)
744 << "WillBeginImplFrame called while already inside an impl frame!";
745 inside_impl_frame_ = true;
mithro51693e382015-05-07 23:52:41746#endif
[email protected]aeeedad2014-08-22 18:16:22747 layer_tree_host_impl_->WillBeginImplFrame(args);
748}
749
750void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
751 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
752 // Although this proxy is single-threaded, it's problematic to synchronously
753 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
754 // could cause a commit to occur in between a series of SetNeedsCommit calls
755 // (i.e. property modifications) causing some to fall on one frame and some to
756 // fall on the next. Doing it asynchronously instead matches the semantics of
757 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
758 // synchronous commit.
mithro51693e382015-05-07 23:52:41759#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02760 DCHECK(inside_impl_frame_)
761 << "BeginMainFrame should only be sent inside a BeginImplFrame";
mithro51693e382015-05-07 23:52:41762#endif
mithro69fd3bb52015-05-01 03:45:02763 const BeginFrameArgs& begin_frame_args =
764 layer_tree_host_impl_->CurrentBeginFrameArgs();
765
[email protected]aeeedad2014-08-22 18:16:22766 MainThreadTaskRunner()->PostTask(
mithro69fd3bb52015-05-01 03:45:02767 FROM_HERE, base::Bind(&SingleThreadProxy::BeginMainFrame,
768 weak_factory_.GetWeakPtr(), begin_frame_args));
[email protected]aeeedad2014-08-22 18:16:22769}
770
rmcilroy0a19362a2015-02-18 12:34:25771void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
772 layer_tree_host_->BeginMainFrameNotExpectedSoon();
773}
774
mithro69fd3bb52015-05-01 03:45:02775void SingleThreadProxy::BeginMainFrame(const BeginFrameArgs& begin_frame_args) {
danakjfcdaba122015-04-24 21:41:52776 commit_requested_ = false;
brianderson49e101d22015-04-29 00:05:33777 animate_requested_ = false;
danakjfcdaba122015-04-24 21:41:52778
[email protected]aeeedad2014-08-22 18:16:22779 if (defer_commits_) {
simonhongc6309f792015-01-31 15:47:15780 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
781 TRACE_EVENT_SCOPE_THREAD);
782 BeginMainFrameAbortedOnImplThread(
783 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
[email protected]aeeedad2014-08-22 18:16:22784 return;
785 }
786
enne98f3a6c2014-10-09 20:09:44787 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
788 // commit.
[email protected]aeeedad2014-08-22 18:16:22789 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
790
791 if (!layer_tree_host_->visible()) {
792 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48793 BeginMainFrameAbortedOnImplThread(
794 CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
[email protected]aeeedad2014-08-22 18:16:22795 return;
796 }
797
798 if (layer_tree_host_->output_surface_lost()) {
799 TRACE_EVENT_INSTANT0(
800 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48801 BeginMainFrameAbortedOnImplThread(
802 CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST);
[email protected]aeeedad2014-08-22 18:16:22803 return;
804 }
805
danakjfcdaba122015-04-24 21:41:52806 // Prevent new commits from being requested inside DoBeginMainFrame.
brianderson49e101d22015-04-29 00:05:33807 // Note: We do not want to prevent SetNeedsAnimate from requesting
808 // a commit here.
danakjfcdaba122015-04-24 21:41:52809 commit_requested_ = true;
810
enne98f3a6c2014-10-09 20:09:44811 DoBeginMainFrame(begin_frame_args);
812}
813
814void SingleThreadProxy::DoBeginMainFrame(
815 const BeginFrameArgs& begin_frame_args) {
816 layer_tree_host_->WillBeginMainFrame();
817 layer_tree_host_->BeginMainFrame(begin_frame_args);
818 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
819 layer_tree_host_->Layout();
820
danakjfcdaba122015-04-24 21:41:52821 // New commits requested inside UpdateLayers should be respected.
822 commit_requested_ = false;
823
danakj5f46636a2015-06-19 00:01:40824 layer_tree_host_->UpdateLayers();
enne98f3a6c2014-10-09 20:09:44825
mithrof7a21502014-12-17 03:24:48826 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
827 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
828 // thread_proxy.cc
enne98f3a6c2014-10-09 20:09:44829 if (scheduler_on_impl_thread_) {
830 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
831 scheduler_on_impl_thread_->NotifyReadyToCommit();
832 }
[email protected]aeeedad2014-08-22 18:16:22833}
834
mithrof7a21502014-12-17 03:24:48835void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
836 CommitEarlyOutReason reason) {
[email protected]aeeedad2014-08-22 18:16:22837 DebugScopedSetImplThread impl(this);
838 DCHECK(scheduler_on_impl_thread_->CommitPending());
839 DCHECK(!layer_tree_host_impl_->pending_tree());
840
mithrof7a21502014-12-17 03:24:48841 layer_tree_host_impl_->BeginMainFrameAborted(reason);
842 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
[email protected]aeeedad2014-08-22 18:16:22843}
844
845DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
846 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22847 LayerTreeHostImpl::FrameData frame;
mithro248d1722015-05-05 05:23:45848 return DoComposite(&frame);
[email protected]aeeedad2014-08-22 18:16:22849}
850
851DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
852 NOTREACHED();
853 return INVALID_RESULT;
854}
855
856void SingleThreadProxy::ScheduledActionCommit() {
857 DebugScopedSetMainThread main(this);
enne98f3a6c2014-10-09 20:09:44858 DoCommit();
[email protected]aeeedad2014-08-22 18:16:22859}
860
861void SingleThreadProxy::ScheduledActionAnimate() {
862 TRACE_EVENT0("cc", "ScheduledActionAnimate");
mithro719bf6792014-11-10 15:36:47863 DebugScopedSetImplThread impl(this);
danakj12e2f6e2015-08-19 22:25:44864 layer_tree_host_impl_->Animate();
[email protected]aeeedad2014-08-22 18:16:22865}
866
[email protected]aeeedad2014-08-22 18:16:22867void SingleThreadProxy::ScheduledActionActivateSyncTree() {
enne98f3a6c2014-10-09 20:09:44868 DebugScopedSetImplThread impl(this);
869 layer_tree_host_impl_->ActivateSyncTree();
[email protected]aeeedad2014-08-22 18:16:22870}
871
872void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
873 DebugScopedSetMainThread main(this);
874 DCHECK(scheduler_on_impl_thread_);
875 // If possible, create the output surface in a post task. Synchronously
876 // creating the output surface makes tests more awkward since this differs
877 // from the ThreadProxy behavior. However, sometimes there is no
878 // task runner.
879 if (Proxy::MainThreadTaskRunner()) {
jbauman8ab0f9e2014-10-15 02:30:34880 ScheduleRequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22881 } else {
enne2097cab2014-09-25 20:16:31882 RequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22883 }
884}
885
vmiura59ea9b4042014-12-09 20:50:39886void SingleThreadProxy::ScheduledActionPrepareTiles() {
887 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
enne98f3a6c2014-10-09 20:09:44888 DebugScopedSetImplThread impl(this);
vmiura59ea9b4042014-12-09 20:50:39889 layer_tree_host_impl_->PrepareTiles();
[email protected]aeeedad2014-08-22 18:16:22890}
891
sunnypseab5ac92015-04-02 20:26:13892void SingleThreadProxy::ScheduledActionInvalidateOutputSurface() {
893 NOTREACHED();
894}
895
mithro51693e382015-05-07 23:52:41896void SingleThreadProxy::DidFinishImplFrame() {
897 layer_tree_host_impl_->DidFinishImplFrame();
898#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02899 DCHECK(inside_impl_frame_)
mithro51693e382015-05-07 23:52:41900 << "DidFinishImplFrame called while not inside an impl frame!";
mithro69fd3bb52015-05-01 03:45:02901 inside_impl_frame_ = false;
mithro51693e382015-05-07 23:52:41902#endif
[email protected]aeeedad2014-08-22 18:16:22903}
904
simonhongd3d5f7f2014-11-21 16:38:03905void SingleThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) {
906 layer_tree_host_->SendBeginFramesToChildren(args);
907}
908
[email protected]bc5e77c2012-11-05 20:00:49909} // namespace cc