blob: 8193758812327d2bd2408cdedd8c5fa6a9335665 [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
enne2097cab2014-09-25 20:16:31152void SingleThreadProxy::SetOutputSurface(
153 scoped_ptr<OutputSurface> output_surface) {
154 DCHECK(Proxy::IsMainThread());
155 DCHECK(layer_tree_host_->output_surface_lost());
enne5232fbb2015-01-27 21:22:41156 DCHECK(output_surface_creation_requested_);
[email protected]da8e3b72b2014-04-25 02:33:45157 renderer_capabilities_for_main_thread_ = RendererCapabilities();
158
enne7f8fdde2014-12-10 21:32:09159 bool success;
160 {
[email protected]819b9f52013-09-22 23:29:51161 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06162 DebugScopedSetImplThread impl(this);
[email protected]da8e3b72b2014-04-25 02:33:45163 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]04049fc2013-05-01 03:13:20164 }
165
[email protected]aeeedad2014-08-22 18:16:22166 if (success) {
enne7f8fdde2014-12-10 21:32:09167 layer_tree_host_->DidInitializeOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22168 if (scheduler_on_impl_thread_)
169 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
jbauman399aec1a2014-10-25 02:33:32170 else if (!inside_synchronous_composite_)
171 SetNeedsCommit();
enne5232fbb2015-01-27 21:22:41172 output_surface_creation_requested_ = false;
enne7f8fdde2014-12-10 21:32:09173 } else {
enne5232fbb2015-01-27 21:22:41174 // DidFailToInitializeOutputSurface is treated as a RequestNewOutputSurface,
175 // and so output_surface_creation_requested remains true.
enne7f8fdde2014-12-10 21:32:09176 layer_tree_host_->DidFailToInitializeOutputSurface();
[email protected]04049fc2013-05-01 03:13:20177 }
[email protected]94f206c12012-08-25 00:09:14178}
179
[email protected]a8a049c2013-03-11 23:27:06180const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20181 DCHECK(Proxy::IsMainThread());
182 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06183 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14184}
185
[email protected]8b9e52b2014-01-17 16:35:31186void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20187 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
[email protected]c5134172013-12-11 06:19:48188 DCHECK(Proxy::IsMainThread());
[email protected]06cbc31b2014-01-17 06:43:20189 client_->ScheduleAnimation();
brianderson49e101d22015-04-29 00:05:33190 if (animate_requested_)
191 return;
192 animate_requested_ = true;
193 DebugScopedSetImplThread impl(this);
194 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01195 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]c5134172013-12-11 06:19:48196}
197
[email protected]8b9e52b2014-01-17 16:35:31198void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20199 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
[email protected]8b9e52b2014-01-17 16:35:31200 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22201 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31202}
203
enne98f3a6c2014-10-09 20:09:44204void SingleThreadProxy::DoCommit() {
[email protected]ccc08dc2014-01-30 07:33:20205 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
[email protected]a8a049c2013-03-11 23:27:06206 DCHECK(Proxy::IsMainThread());
enne98f3a6c2014-10-09 20:09:44207
robliao27728e62015-03-21 07:39:34208 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
209 // fixed.
210 tracked_objects::ScopedTracker tracking_profile1(
211 FROM_HERE_WITH_EXPLICIT_FUNCTION("461509 SingleThreadProxy::DoCommit1"));
[email protected]aeeedad2014-08-22 18:16:22212 layer_tree_host_->WillCommit();
caseq7d2f4c92015-02-04 16:43:27213 devtools_instrumentation::ScopedCommitTrace commit_task(
214 layer_tree_host_->id());
[email protected]aeeedad2014-08-22 18:16:22215
[email protected]a8a049c2013-03-11 23:27:06216 // Commit immediately.
217 {
robliao27728e62015-03-21 07:39:34218 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
219 // is fixed.
220 tracked_objects::ScopedTracker tracking_profile2(
221 FROM_HERE_WITH_EXPLICIT_FUNCTION(
222 "461509 SingleThreadProxy::DoCommit2"));
[email protected]819b9f52013-09-22 23:29:51223 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46224 DebugScopedSetImplThread impl(this);
225
[email protected]9794fb32013-08-29 09:49:59226 // This CapturePostTasks should be destroyed before CommitComplete() is
227 // called since that goes out to the embedder, and we want the embedder
228 // to receive its callbacks before that.
enne98f3a6c2014-10-09 20:09:44229 commit_blocking_task_runner_.reset(new BlockingTaskRunner::CapturePostTasks(
230 blocking_main_thread_task_runner()));
[email protected]9794fb32013-08-29 09:49:59231
[email protected]c1bb5af2013-03-13 19:06:27232 layer_tree_host_impl_->BeginCommit();
[email protected]804c8982013-03-13 16:32:21233 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14234
robliao27728e62015-03-21 07:39:34235 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
236 // is fixed.
robliao27728e62015-03-21 07:39:34237 tracked_objects::ScopedTracker tracking_profile6(
238 FROM_HERE_WITH_EXPLICIT_FUNCTION(
239 "461509 SingleThreadProxy::DoCommit6"));
[email protected]127bdc1a2013-09-11 01:44:48240 if (layer_tree_host_impl_->EvictedUIResourcesExist())
241 layer_tree_host_->RecreateUIResources();
242
robliao27728e62015-03-21 07:39:34243 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
244 // is fixed.
245 tracked_objects::ScopedTracker tracking_profile7(
246 FROM_HERE_WITH_EXPLICIT_FUNCTION(
247 "461509 SingleThreadProxy::DoCommit7"));
[email protected]804c8982013-03-13 16:32:21248 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14249
danakje649f572015-01-08 23:35:58250#if DCHECK_IS_ON()
[email protected]3519b872013-07-30 07:17:50251 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06252 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29253 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27254 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29255 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50256 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14257#endif
enne98f3a6c2014-10-09 20:09:44258
danakj3c3973b2015-08-25 21:50:18259 if (scheduler_on_impl_thread_)
260 scheduler_on_impl_thread_->DidCommit();
261
262 layer_tree_host_impl_->CommitComplete();
263
danakj68803fc2015-06-19 20:55:53264 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
265 // is fixed.
266 tracked_objects::ScopedTracker tracking_profile8(
267 FROM_HERE_WITH_EXPLICIT_FUNCTION(
268 "461509 SingleThreadProxy::DoCommit8"));
269 // Commit goes directly to the active tree, but we need to synchronously
270 // "activate" the tree still during commit to satisfy any potential
271 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
272 // might not be ready to draw, so DidActivateSyncTree must set
273 // the flag to force the tree to not draw until textures are ready.
274 NotifyReadyToActivate();
enne98f3a6c2014-10-09 20:09:44275 }
276}
277
278void SingleThreadProxy::CommitComplete() {
danakj3c3973b2015-08-25 21:50:18279 // Commit complete happens on the main side after activate to satisfy any
280 // SetNextCommitWaitsForActivation calls.
enne98f3a6c2014-10-09 20:09:44281 DCHECK(!layer_tree_host_impl_->pending_tree())
282 << "Activation is expected to have synchronously occurred by now.";
283 DCHECK(commit_blocking_task_runner_);
284
285 DebugScopedSetMainThread main(this);
286 commit_blocking_task_runner_.reset();
[email protected]804c8982013-03-13 16:32:21287 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22288 layer_tree_host_->DidBeginMainFrame();
[email protected]aeeedad2014-08-22 18:16:22289
[email protected]a8a049c2013-03-11 23:27:06290 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14291}
292
[email protected]a8a049c2013-03-11 23:27:06293void SingleThreadProxy::SetNeedsCommit() {
294 DCHECK(Proxy::IsMainThread());
[email protected]943528e2013-11-07 05:01:32295 client_->ScheduleComposite();
danakjfcdaba122015-04-24 21:41:52296 if (commit_requested_)
297 return;
brianderson49e101d22015-04-29 00:05:33298 commit_requested_ = true;
danakjfcdaba122015-04-24 21:41:52299 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22300 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01301 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]94f206c12012-08-25 00:09:14302}
303
[email protected]0023fc72014-01-10 20:05:06304void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20305 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
[email protected]aeeedad2014-08-22 18:16:22306 DCHECK(Proxy::IsMainThread());
307 DebugScopedSetImplThread impl(this);
[email protected]2decdd782014-08-13 22:36:06308 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22309 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14310}
311
[email protected]74b43cc2013-08-30 06:29:27312void SingleThreadProxy::SetNextCommitWaitsForActivation() {
enne98f3a6c2014-10-09 20:09:44313 // Activation always forced in commit, so nothing to do.
[email protected]aeeedad2014-08-22 18:16:22314 DCHECK(Proxy::IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27315}
316
[email protected]a8a049c2013-03-11 23:27:06317void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
[email protected]aeeedad2014-08-22 18:16:22318 DCHECK(Proxy::IsMainThread());
319 // Deferring commits only makes sense if there's a scheduler.
320 if (!scheduler_on_impl_thread_)
321 return;
322 if (defer_commits_ == defer_commits)
323 return;
324
325 if (defer_commits)
326 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
327 else
328 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
329
330 defer_commits_ = defer_commits;
simonhongc6309f792015-01-31 15:47:15331 scheduler_on_impl_thread_->SetDeferCommits(defer_commits);
[email protected]6b16679e2012-10-27 00:44:28332}
333
[email protected]174c6d42014-08-12 01:43:06334bool SingleThreadProxy::CommitRequested() const {
[email protected]aeeedad2014-08-22 18:16:22335 DCHECK(Proxy::IsMainThread());
336 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06337}
[email protected]a8a049c2013-03-11 23:27:06338
[email protected]174c6d42014-08-12 01:43:06339bool SingleThreadProxy::BeginMainFrameRequested() const {
[email protected]aeeedad2014-08-22 18:16:22340 DCHECK(Proxy::IsMainThread());
341 // If there is no scheduler, then there can be no pending begin frame,
342 // as all frames are all manually initiated by the embedder of cc.
343 if (!scheduler_on_impl_thread_)
344 return false;
345 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06346}
[email protected]971728d2013-10-26 10:39:31347
[email protected]a8a049c2013-03-11 23:27:06348void SingleThreadProxy::Stop() {
349 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
350 DCHECK(Proxy::IsMainThread());
351 {
[email protected]819b9f52013-09-22 23:29:51352 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06353 DebugScopedSetImplThread impl(this);
354
skyostil3976a3f2014-09-04 22:07:23355 BlockingTaskRunner::CapturePostTasks blocked(
356 blocking_main_thread_task_runner());
danakjf446a072014-09-27 21:55:48357 scheduler_on_impl_thread_ = nullptr;
358 layer_tree_host_impl_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06359 }
[email protected]7aba6662013-03-12 10:17:34360 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06361}
362
[email protected]3d9f7432013-04-06 00:35:18363void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
[email protected]ccc08dc2014-01-30 07:33:20364 TRACE_EVENT1(
365 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
[email protected]3d9f7432013-04-06 00:35:18366 DCHECK(Proxy::IsImplThread());
[email protected]aeeedad2014-08-22 18:16:22367 if (scheduler_on_impl_thread_)
368 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18369}
370
[email protected]4f48f6e2013-08-27 06:33:38371void SingleThreadProxy::NotifyReadyToActivate() {
enne98f3a6c2014-10-09 20:09:44372 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
373 DebugScopedSetImplThread impl(this);
374 if (scheduler_on_impl_thread_)
375 scheduler_on_impl_thread_->NotifyReadyToActivate();
[email protected]4f48f6e2013-08-27 06:33:38376}
377
ernstmdfac03e2014-11-11 20:18:05378void SingleThreadProxy::NotifyReadyToDraw() {
weiliangc8dac5a62015-04-02 06:12:35379 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToDraw");
380 DebugScopedSetImplThread impl(this);
381 if (scheduler_on_impl_thread_)
382 scheduler_on_impl_thread_->NotifyReadyToDraw();
ernstmdfac03e2014-11-11 20:18:05383}
384
[email protected]c1bb5af2013-03-13 19:06:27385void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]943528e2013-11-07 05:01:32386 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22387 if (scheduler_on_impl_thread_)
388 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06389}
390
[email protected]43b8f982014-04-30 21:24:33391void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
mithro719bf6792014-11-10 15:36:47392 client_->ScheduleComposite();
393 if (scheduler_on_impl_thread_)
394 scheduler_on_impl_thread_->SetNeedsAnimate();
[email protected]43b8f982014-04-30 21:24:33395}
396
vmiura59ea9b4042014-12-09 20:50:39397void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
398 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
enne98f3a6c2014-10-09 20:09:44399 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39400 scheduler_on_impl_thread_->SetNeedsPrepareTiles();
[email protected]c48536a52013-09-14 00:02:08401}
402
[email protected]0023fc72014-01-10 20:05:06403void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
404 const gfx::Rect& damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03405 layer_tree_host_impl_->SetViewportDamage(damage_rect);
[email protected]aeeedad2014-08-22 18:16:22406 SetNeedsRedrawOnImplThread();
[email protected]1cd9f5552013-04-26 04:22:03407}
408
[email protected]c1bb5af2013-03-13 19:06:27409void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]943528e2013-11-07 05:01:32410 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22411 if (scheduler_on_impl_thread_)
mithroe77254b32015-07-22 09:36:01412 scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
[email protected]a8a049c2013-03-11 23:27:06413}
414
sunnyps7d073dc2015-04-16 23:29:12415void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
416 TRACE_EVENT1("cc", "SingleThreadProxy::SetVideoNeedsBeginFrames",
417 "needs_begin_frames", needs_begin_frames);
418 // In tests the layer tree is destroyed after the scheduler is.
419 if (scheduler_on_impl_thread_)
420 scheduler_on_impl_thread_->SetVideoNeedsBeginFrames(needs_begin_frames);
421}
422
[email protected]c1bb5af2013-03-13 19:06:27423void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]85b57502014-03-11 15:37:48424 scoped_ptr<AnimationEventsVector> events) {
[email protected]ccc08dc2014-01-30 07:33:20425 TRACE_EVENT0(
426 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
[email protected]a8a049c2013-03-11 23:27:06427 DCHECK(Proxy::IsImplThread());
428 DebugScopedSetMainThread main(this);
[email protected]85b57502014-03-11 15:37:48429 layer_tree_host_->SetAnimationEvents(events.Pass());
[email protected]a8a049c2013-03-11 23:27:06430}
431
[email protected]c1bb5af2013-03-13 19:06:27432bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06433
enne98f3a6c2014-10-09 20:09:44434void SingleThreadProxy::DidActivateSyncTree() {
danakj68803fc2015-06-19 20:55:53435 // Synchronously call to CommitComplete. Resetting
436 // |commit_blocking_task_runner| would make sure all tasks posted during
437 // commit/activation before CommitComplete.
438 CommitComplete();
enne98f3a6c2014-10-09 20:09:44439}
440
brianderson68749812015-07-07 22:39:39441void SingleThreadProxy::WillPrepareTiles() {
442 DCHECK(Proxy::IsImplThread());
443 if (scheduler_on_impl_thread_)
444 scheduler_on_impl_thread_->WillPrepareTiles();
445}
446
vmiura59ea9b4042014-12-09 20:50:39447void SingleThreadProxy::DidPrepareTiles() {
enne98f3a6c2014-10-09 20:09:44448 DCHECK(Proxy::IsImplThread());
449 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39450 scheduler_on_impl_thread_->DidPrepareTiles();
enne98f3a6c2014-10-09 20:09:44451}
452
rouslanf7ebd8832015-01-22 01:54:14453void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
454 layer_tree_host_->DidCompletePageScaleAnimation();
455}
456
[email protected]fa339032014-02-18 22:11:59457void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
458 DCHECK(IsImplThread());
459 renderer_capabilities_for_main_thread_ =
460 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
461}
462
[email protected]c1bb5af2013-03-13 19:06:27463void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20464 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22465 {
466 DebugScopedSetMainThread main(this);
467 // This must happen before we notify the scheduler as it may try to recreate
468 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
469 layer_tree_host_->DidLoseOutputSurface();
470 }
[email protected]4d7e46a2013-11-08 05:33:40471 client_->DidAbortSwapBuffers();
[email protected]aeeedad2014-08-22 18:16:22472 if (scheduler_on_impl_thread_)
473 scheduler_on_impl_thread_->DidLoseOutputSurface();
[email protected]4d7e46a2013-11-08 05:33:40474}
475
weiliangcaf17af42014-12-15 22:17:02476void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
477 base::TimeDelta interval) {
478 if (scheduler_on_impl_thread_)
479 scheduler_on_impl_thread_->CommitVSyncParameters(timebase, interval);
480}
481
jbauman93a5a902015-03-13 22:16:55482void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
483 if (scheduler_on_impl_thread_)
484 scheduler_on_impl_thread_->SetEstimatedParentDrawTime(draw_time);
485}
486
alexst346f30c2015-03-25 13:24:05487void SingleThreadProxy::SetMaxSwapsPendingOnImplThread(int max) {
488 if (scheduler_on_impl_thread_)
489 scheduler_on_impl_thread_->SetMaxSwapsPending(max);
490}
491
[email protected]4d7e46a2013-11-08 05:33:40492void SingleThreadProxy::DidSwapBuffersOnImplThread() {
[email protected]aeeedad2014-08-22 18:16:22493 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
494 if (scheduler_on_impl_thread_)
495 scheduler_on_impl_thread_->DidSwapBuffers();
[email protected]4d7e46a2013-11-08 05:33:40496 client_->DidPostSwapBuffers();
497}
498
[email protected]c14902662014-04-18 05:06:11499void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
miletusfed8c43b2015-01-26 20:04:52500 TRACE_EVENT0("cc,benchmark",
501 "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22502 if (scheduler_on_impl_thread_)
503 scheduler_on_impl_thread_->DidSwapBuffersComplete();
504 layer_tree_host_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10505}
506
sunnypseab5ac92015-04-02 20:26:13507void SingleThreadProxy::OnDrawForOutputSurface() {
508 NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
509}
510
mpbed24c2c2015-06-05 20:57:13511void SingleThreadProxy::PostFrameTimingEventsOnImplThread(
512 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
513 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
514 layer_tree_host_->RecordFrameTimingEvents(composite_events.Pass(),
515 main_frame_events.Pass());
516}
517
wangxianzhu67d1fae2015-06-30 22:15:53518void SingleThreadProxy::LayoutAndUpdateLayers() {
519 if (layer_tree_host_->output_surface_lost()) {
520 RequestNewOutputSurface();
521 // RequestNewOutputSurface could have synchronously created an output
522 // surface, so check again before returning.
523 if (layer_tree_host_->output_surface_lost())
524 return;
525 }
526
527 layer_tree_host_->Layout();
528 layer_tree_host_->UpdateLayers();
529}
530
[email protected]f0c2a242013-03-15 19:34:52531void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
miletusfed8c43b2015-01-26 20:04:52532 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
[email protected]51f81da2014-05-16 21:29:26533 DCHECK(Proxy::IsMainThread());
mithro51693e382015-05-07 23:52:41534#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13535 DCHECK(!inside_impl_frame_);
mithro51693e382015-05-07 23:52:41536#endif
jbauman399aec1a2014-10-25 02:33:32537 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
538
539 if (layer_tree_host_->output_surface_lost()) {
540 RequestNewOutputSurface();
541 // RequestNewOutputSurface could have synchronously created an output
542 // surface, so check again before returning.
543 if (layer_tree_host_->output_surface_lost())
544 return;
545 }
[email protected]51f81da2014-05-16 21:29:26546
mithroc76d70312015-05-04 23:51:13547 BeginFrameArgs begin_frame_args(BeginFrameArgs::Create(
548 BEGINFRAME_FROM_HERE, frame_begin_time, base::TimeTicks(),
549 BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL));
550
551 // Start the impl frame.
enne98f3a6c2014-10-09 20:09:44552 {
mithroc76d70312015-05-04 23:51:13553 DebugScopedSetImplThread impl(this);
554 WillBeginImplFrame(begin_frame_args);
555 }
556
557 // Run the "main thread" and get it to commit.
558 {
mithro51693e382015-05-07 23:52:41559#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13560 DCHECK(inside_impl_frame_);
mithro51693e382015-05-07 23:52:41561#endif
enne98f3a6c2014-10-09 20:09:44562 DoBeginMainFrame(begin_frame_args);
563 DoCommit();
[email protected]e0341352013-04-06 05:01:20564
enne98f3a6c2014-10-09 20:09:44565 DCHECK_EQ(0u, layer_tree_host_->num_queued_swap_promises())
566 << "Commit should always succeed and transfer promises.";
567 }
568
mithroc76d70312015-05-04 23:51:13569 // Finish the impl frame.
enne98f3a6c2014-10-09 20:09:44570 {
mithroc76d70312015-05-04 23:51:13571 DebugScopedSetImplThread impl(this);
danakj68803fc2015-06-19 20:55:53572 layer_tree_host_impl_->ActivateSyncTree();
573 DCHECK(
574 !layer_tree_host_impl_->active_tree()->needs_update_draw_properties());
575 layer_tree_host_impl_->PrepareTiles();
576 layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
enne69277cb2014-10-29 23:03:40577
danakj12e2f6e2015-08-19 22:25:44578 // TODO(danakj): Don't do this last... we prepared the wrong things. D:
579 layer_tree_host_impl_->Animate();
mithro719bf6792014-11-10 15:36:47580
enne98f3a6c2014-10-09 20:09:44581 LayerTreeHostImpl::FrameData frame;
mithro248d1722015-05-05 05:23:45582 DoComposite(&frame);
enne98f3a6c2014-10-09 20:09:44583
584 // DoComposite could abort, but because this is a synchronous composite
585 // another draw will never be scheduled, so break remaining promises.
586 layer_tree_host_impl_->active_tree()->BreakSwapPromises(
587 SwapPromise::SWAP_FAILS);
mithroc76d70312015-05-04 23:51:13588
mithro51693e382015-05-07 23:52:41589 DidFinishImplFrame();
enne98f3a6c2014-10-09 20:09:44590 }
[email protected]74d9063c2013-01-18 03:14:47591}
592
[email protected]a8a049c2013-03-11 23:27:06593void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
594 {
595 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20596 if (layer_tree_host_impl_->renderer()) {
597 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06598 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20599 }
[email protected]a8a049c2013-03-11 23:27:06600 }
[email protected]8947cbe2012-11-28 05:27:43601}
602
[email protected]5d8bec72014-07-03 03:03:11603bool SingleThreadProxy::SupportsImplScrolling() const {
604 return false;
605}
606
[email protected]3d9f7432013-04-06 00:35:18607bool SingleThreadProxy::ShouldComposite() const {
608 DCHECK(Proxy::IsImplThread());
609 return layer_tree_host_impl_->visible() &&
610 layer_tree_host_impl_->CanDraw();
611}
612
jbauman8ab0f9e2014-10-15 02:30:34613void SingleThreadProxy::ScheduleRequestNewOutputSurface() {
614 if (output_surface_creation_callback_.IsCancelled() &&
615 !output_surface_creation_requested_) {
616 output_surface_creation_callback_.Reset(
617 base::Bind(&SingleThreadProxy::RequestNewOutputSurface,
618 weak_factory_.GetWeakPtr()));
619 MainThreadTaskRunner()->PostTask(
620 FROM_HERE, output_surface_creation_callback_.callback());
621 }
622}
623
mithro248d1722015-05-05 05:23:45624DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20625 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20626 DCHECK(!layer_tree_host_->output_surface_lost());
627
enne98f3a6c2014-10-09 20:09:44628 DrawResult draw_result;
629 bool draw_frame;
[email protected]a8a049c2013-03-11 23:27:06630 {
631 DebugScopedSetImplThread impl(this);
632 base::AutoReset<bool> mark_inside(&inside_draw_, true);
633
robliao27728e62015-03-21 07:39:34634 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
635 // is fixed.
636 tracked_objects::ScopedTracker tracking_profile1(
637 FROM_HERE_WITH_EXPLICIT_FUNCTION(
638 "461509 SingleThreadProxy::DoComposite1"));
639
[email protected]3d9f7432013-04-06 00:35:18640 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
641 // frame, so can only be used when such a frame is possible. Since
642 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
643 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50644 if (!ShouldComposite()) {
[email protected]aeeedad2014-08-22 18:16:22645 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18646 }
[email protected]a8a049c2013-03-11 23:27:06647
robliao27728e62015-03-21 07:39:34648 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
649 // is fixed.
650 tracked_objects::ScopedTracker tracking_profile2(
651 FROM_HERE_WITH_EXPLICIT_FUNCTION(
652 "461509 SingleThreadProxy::DoComposite2"));
enne98f3a6c2014-10-09 20:09:44653 draw_result = layer_tree_host_impl_->PrepareToDraw(frame);
654 draw_frame = draw_result == DRAW_SUCCESS;
robliao27728e62015-03-21 07:39:34655 if (draw_frame) {
656 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
657 // is fixed.
658 tracked_objects::ScopedTracker tracking_profile3(
659 FROM_HERE_WITH_EXPLICIT_FUNCTION(
660 "461509 SingleThreadProxy::DoComposite3"));
mithro248d1722015-05-05 05:23:45661 layer_tree_host_impl_->DrawLayers(frame);
robliao27728e62015-03-21 07:39:34662 }
663 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
664 // is fixed.
665 tracked_objects::ScopedTracker tracking_profile4(
666 FROM_HERE_WITH_EXPLICIT_FUNCTION(
667 "461509 SingleThreadProxy::DoComposite4"));
dnetob71e30c2014-08-25 23:27:20668 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06669
enne98f3a6c2014-10-09 20:09:44670 bool start_ready_animations = draw_frame;
robliao27728e62015-03-21 07:39:34671 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
672 // is fixed.
673 tracked_objects::ScopedTracker tracking_profile5(
674 FROM_HERE_WITH_EXPLICIT_FUNCTION(
675 "461509 SingleThreadProxy::DoComposite5"));
[email protected]3d9f7432013-04-06 00:35:18676 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]aeeedad2014-08-22 18:16:22677
robliao27728e62015-03-21 07:39:34678 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
679 // is fixed.
680 tracked_objects::ScopedTracker tracking_profile7(
681 FROM_HERE_WITH_EXPLICIT_FUNCTION(
682 "461509 SingleThreadProxy::DoComposite7"));
[email protected]a8a049c2013-03-11 23:27:06683 }
684
enne98f3a6c2014-10-09 20:09:44685 if (draw_frame) {
[email protected]aeeedad2014-08-22 18:16:22686 DebugScopedSetImplThread impl(this);
[email protected]174c6d42014-08-12 01:43:06687
dnetob71e30c2014-08-25 23:27:20688 // This CapturePostTasks should be destroyed before
689 // DidCommitAndDrawFrame() is called since that goes out to the
690 // embedder,
691 // and we want the embedder to receive its callbacks before that.
692 // NOTE: This maintains consistent ordering with the ThreadProxy since
693 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
694 // there as the main thread is not blocked, so any posted tasks inside
695 // the swap buffers will execute first.
696 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]aeeedad2014-08-22 18:16:22697
skyostil3976a3f2014-09-04 22:07:23698 BlockingTaskRunner::CapturePostTasks blocked(
699 blocking_main_thread_task_runner());
robliao27728e62015-03-21 07:39:34700 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
701 // is fixed.
702 tracked_objects::ScopedTracker tracking_profile8(
703 FROM_HERE_WITH_EXPLICIT_FUNCTION(
704 "461509 SingleThreadProxy::DoComposite8"));
dnetob71e30c2014-08-25 23:27:20705 layer_tree_host_impl_->SwapBuffers(*frame);
[email protected]aeeedad2014-08-22 18:16:22706 }
robliao27728e62015-03-21 07:39:34707 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
708 // fixed.
709 tracked_objects::ScopedTracker tracking_profile9(
710 FROM_HERE_WITH_EXPLICIT_FUNCTION(
711 "461509 SingleThreadProxy::DoComposite9"));
[email protected]aeeedad2014-08-22 18:16:22712 DidCommitAndDrawFrame();
713
enne98f3a6c2014-10-09 20:09:44714 return draw_result;
[email protected]a8a049c2013-03-11 23:27:06715}
716
[email protected]aeeedad2014-08-22 18:16:22717void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06718 if (next_frame_is_newly_committed_frame_) {
[email protected]aeeedad2014-08-22 18:16:22719 DebugScopedSetMainThread main(this);
[email protected]a8a049c2013-03-11 23:27:06720 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21721 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06722 }
723}
724
[email protected]4ea293f72014-08-13 03:03:17725bool SingleThreadProxy::MainFrameWillHappenForTesting() {
danakjfcdaba122015-04-24 21:41:52726 if (layer_tree_host_->output_surface_lost())
727 return false;
728 if (!scheduler_on_impl_thread_)
729 return false;
730 return scheduler_on_impl_thread_->MainFrameForTestingWillHappen();
[email protected]4ea293f72014-08-13 03:03:17731}
[email protected]a8a049c2013-03-11 23:27:06732
simonhongd3d5f7f2014-11-21 16:38:03733void SingleThreadProxy::SetChildrenNeedBeginFrames(
734 bool children_need_begin_frames) {
735 scheduler_on_impl_thread_->SetChildrenNeedBeginFrames(
736 children_need_begin_frames);
737}
738
simonhong298590fe2015-03-25 06:51:13739void SingleThreadProxy::SetAuthoritativeVSyncInterval(
740 const base::TimeDelta& interval) {
741 scheduler_on_impl_thread_->SetAuthoritativeVSyncInterval(interval);
742}
743
[email protected]aeeedad2014-08-22 18:16:22744void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
mithro51693e382015-05-07 23:52:41745#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02746 DCHECK(!inside_impl_frame_)
747 << "WillBeginImplFrame called while already inside an impl frame!";
748 inside_impl_frame_ = true;
mithro51693e382015-05-07 23:52:41749#endif
[email protected]aeeedad2014-08-22 18:16:22750 layer_tree_host_impl_->WillBeginImplFrame(args);
751}
752
753void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
754 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
755 // Although this proxy is single-threaded, it's problematic to synchronously
756 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
757 // could cause a commit to occur in between a series of SetNeedsCommit calls
758 // (i.e. property modifications) causing some to fall on one frame and some to
759 // fall on the next. Doing it asynchronously instead matches the semantics of
760 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
761 // synchronous commit.
mithro51693e382015-05-07 23:52:41762#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02763 DCHECK(inside_impl_frame_)
764 << "BeginMainFrame should only be sent inside a BeginImplFrame";
mithro51693e382015-05-07 23:52:41765#endif
mithro69fd3bb52015-05-01 03:45:02766 const BeginFrameArgs& begin_frame_args =
767 layer_tree_host_impl_->CurrentBeginFrameArgs();
768
[email protected]aeeedad2014-08-22 18:16:22769 MainThreadTaskRunner()->PostTask(
mithro69fd3bb52015-05-01 03:45:02770 FROM_HERE, base::Bind(&SingleThreadProxy::BeginMainFrame,
771 weak_factory_.GetWeakPtr(), begin_frame_args));
[email protected]aeeedad2014-08-22 18:16:22772}
773
rmcilroy0a19362a2015-02-18 12:34:25774void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
775 layer_tree_host_->BeginMainFrameNotExpectedSoon();
776}
777
mithro69fd3bb52015-05-01 03:45:02778void SingleThreadProxy::BeginMainFrame(const BeginFrameArgs& begin_frame_args) {
danakjfcdaba122015-04-24 21:41:52779 commit_requested_ = false;
brianderson49e101d22015-04-29 00:05:33780 animate_requested_ = false;
danakjfcdaba122015-04-24 21:41:52781
[email protected]aeeedad2014-08-22 18:16:22782 if (defer_commits_) {
simonhongc6309f792015-01-31 15:47:15783 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
784 TRACE_EVENT_SCOPE_THREAD);
785 BeginMainFrameAbortedOnImplThread(
786 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
[email protected]aeeedad2014-08-22 18:16:22787 return;
788 }
789
enne98f3a6c2014-10-09 20:09:44790 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
791 // commit.
[email protected]aeeedad2014-08-22 18:16:22792 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
793
794 if (!layer_tree_host_->visible()) {
795 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48796 BeginMainFrameAbortedOnImplThread(
797 CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
[email protected]aeeedad2014-08-22 18:16:22798 return;
799 }
800
801 if (layer_tree_host_->output_surface_lost()) {
802 TRACE_EVENT_INSTANT0(
803 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48804 BeginMainFrameAbortedOnImplThread(
805 CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST);
[email protected]aeeedad2014-08-22 18:16:22806 return;
807 }
808
danakjfcdaba122015-04-24 21:41:52809 // Prevent new commits from being requested inside DoBeginMainFrame.
brianderson49e101d22015-04-29 00:05:33810 // Note: We do not want to prevent SetNeedsAnimate from requesting
811 // a commit here.
danakjfcdaba122015-04-24 21:41:52812 commit_requested_ = true;
813
enne98f3a6c2014-10-09 20:09:44814 DoBeginMainFrame(begin_frame_args);
815}
816
817void SingleThreadProxy::DoBeginMainFrame(
818 const BeginFrameArgs& begin_frame_args) {
819 layer_tree_host_->WillBeginMainFrame();
820 layer_tree_host_->BeginMainFrame(begin_frame_args);
821 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
822 layer_tree_host_->Layout();
823
danakjfcdaba122015-04-24 21:41:52824 // New commits requested inside UpdateLayers should be respected.
825 commit_requested_ = false;
826
danakj5f46636a2015-06-19 00:01:40827 layer_tree_host_->UpdateLayers();
enne98f3a6c2014-10-09 20:09:44828
mithrof7a21502014-12-17 03:24:48829 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
830 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
831 // thread_proxy.cc
enne98f3a6c2014-10-09 20:09:44832 if (scheduler_on_impl_thread_) {
833 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
834 scheduler_on_impl_thread_->NotifyReadyToCommit();
835 }
[email protected]aeeedad2014-08-22 18:16:22836}
837
mithrof7a21502014-12-17 03:24:48838void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
839 CommitEarlyOutReason reason) {
[email protected]aeeedad2014-08-22 18:16:22840 DebugScopedSetImplThread impl(this);
841 DCHECK(scheduler_on_impl_thread_->CommitPending());
842 DCHECK(!layer_tree_host_impl_->pending_tree());
843
mithrof7a21502014-12-17 03:24:48844 layer_tree_host_impl_->BeginMainFrameAborted(reason);
845 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
[email protected]aeeedad2014-08-22 18:16:22846}
847
848DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
849 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22850 LayerTreeHostImpl::FrameData frame;
mithro248d1722015-05-05 05:23:45851 return DoComposite(&frame);
[email protected]aeeedad2014-08-22 18:16:22852}
853
854DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
855 NOTREACHED();
856 return INVALID_RESULT;
857}
858
859void SingleThreadProxy::ScheduledActionCommit() {
860 DebugScopedSetMainThread main(this);
enne98f3a6c2014-10-09 20:09:44861 DoCommit();
[email protected]aeeedad2014-08-22 18:16:22862}
863
864void SingleThreadProxy::ScheduledActionAnimate() {
865 TRACE_EVENT0("cc", "ScheduledActionAnimate");
mithro719bf6792014-11-10 15:36:47866 DebugScopedSetImplThread impl(this);
danakj12e2f6e2015-08-19 22:25:44867 layer_tree_host_impl_->Animate();
[email protected]aeeedad2014-08-22 18:16:22868}
869
[email protected]aeeedad2014-08-22 18:16:22870void SingleThreadProxy::ScheduledActionActivateSyncTree() {
enne98f3a6c2014-10-09 20:09:44871 DebugScopedSetImplThread impl(this);
872 layer_tree_host_impl_->ActivateSyncTree();
[email protected]aeeedad2014-08-22 18:16:22873}
874
875void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
876 DebugScopedSetMainThread main(this);
877 DCHECK(scheduler_on_impl_thread_);
878 // If possible, create the output surface in a post task. Synchronously
879 // creating the output surface makes tests more awkward since this differs
880 // from the ThreadProxy behavior. However, sometimes there is no
881 // task runner.
882 if (Proxy::MainThreadTaskRunner()) {
jbauman8ab0f9e2014-10-15 02:30:34883 ScheduleRequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22884 } else {
enne2097cab2014-09-25 20:16:31885 RequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22886 }
887}
888
vmiura59ea9b4042014-12-09 20:50:39889void SingleThreadProxy::ScheduledActionPrepareTiles() {
890 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
enne98f3a6c2014-10-09 20:09:44891 DebugScopedSetImplThread impl(this);
vmiura59ea9b4042014-12-09 20:50:39892 layer_tree_host_impl_->PrepareTiles();
[email protected]aeeedad2014-08-22 18:16:22893}
894
sunnypseab5ac92015-04-02 20:26:13895void SingleThreadProxy::ScheduledActionInvalidateOutputSurface() {
896 NOTREACHED();
897}
898
mithro51693e382015-05-07 23:52:41899void SingleThreadProxy::DidFinishImplFrame() {
900 layer_tree_host_impl_->DidFinishImplFrame();
901#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02902 DCHECK(inside_impl_frame_)
mithro51693e382015-05-07 23:52:41903 << "DidFinishImplFrame called while not inside an impl frame!";
mithro69fd3bb52015-05-01 03:45:02904 inside_impl_frame_ = false;
mithro51693e382015-05-07 23:52:41905#endif
[email protected]aeeedad2014-08-22 18:16:22906}
907
simonhongd3d5f7f2014-11-21 16:38:03908void SingleThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) {
909 layer_tree_host_->SendBeginFramesToChildren(args);
910}
911
[email protected]bc5e77c2012-11-05 20:00:49912} // namespace cc