blob: 44ea7ca779261c813b134fe4eeb7fd55e053edba [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"
[email protected]e12dd0e2013-03-18 08:24:4015#include "cc/resources/prioritized_resource_manager.h"
mithrof7a21502014-12-17 03:24:4816#include "cc/scheduler/commit_earlyout_reason.h"
[email protected]556fd292013-03-18 08:03:0417#include "cc/trees/layer_tree_host.h"
[email protected]943528e2013-11-07 05:01:3218#include "cc/trees/layer_tree_host_single_thread_client.h"
[email protected]556fd292013-03-18 08:03:0419#include "cc/trees/layer_tree_impl.h"
[email protected]aeeedad2014-08-22 18:16:2220#include "cc/trees/scoped_abort_remaining_swap_promises.h"
[email protected]94f206c12012-08-25 00:09:1421
[email protected]9c88e562012-09-14 22:21:3022namespace cc {
[email protected]94f206c12012-08-25 00:09:1423
[email protected]943528e2013-11-07 05:01:3224scoped_ptr<Proxy> SingleThreadProxy::Create(
25 LayerTreeHost* layer_tree_host,
[email protected]27e6a212014-07-18 15:51:2726 LayerTreeHostSingleThreadClient* client,
simonhonga7e3ac42014-11-11 20:50:2227 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
28 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
29 return make_scoped_ptr(new SingleThreadProxy(
30 layer_tree_host,
31 client,
32 main_task_runner,
33 external_begin_frame_source.Pass()));
[email protected]94f206c12012-08-25 00:09:1434}
35
[email protected]27e6a212014-07-18 15:51:2736SingleThreadProxy::SingleThreadProxy(
37 LayerTreeHost* layer_tree_host,
38 LayerTreeHostSingleThreadClient* client,
simonhonga7e3ac42014-11-11 20:50:2239 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
40 scoped_ptr<BeginFrameSource> external_begin_frame_source)
[email protected]27e6a212014-07-18 15:51:2741 : Proxy(main_task_runner, NULL),
[email protected]a8a049c2013-03-11 23:27:0642 layer_tree_host_(layer_tree_host),
[email protected]943528e2013-11-07 05:01:3243 client_(client),
[email protected]aeeedad2014-08-22 18:16:2244 timing_history_(layer_tree_host->rendering_stats_instrumentation()),
[email protected]a8a049c2013-03-11 23:27:0645 next_frame_is_newly_committed_frame_(false),
mithro51693e382015-05-07 23:52:4146#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:0247 inside_impl_frame_(false),
mithro51693e382015-05-07 23:52:4148#endif
[email protected]aeeedad2014-08-22 18:16:2249 inside_draw_(false),
50 defer_commits_(false),
brianderson49e101d22015-04-29 00:05:3351 animate_requested_(false),
[email protected]aeeedad2014-08-22 18:16:2252 commit_requested_(false),
jbauman399aec1a2014-10-25 02:33:3253 inside_synchronous_composite_(false),
jbauman8ab0f9e2014-10-15 02:30:3454 output_surface_creation_requested_(false),
[email protected]aeeedad2014-08-22 18:16:2255 weak_factory_(this) {
[email protected]a8a049c2013-03-11 23:27:0656 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
57 DCHECK(Proxy::IsMainThread());
58 DCHECK(layer_tree_host);
danakjfcdaba122015-04-24 21:41:5259
60 if (layer_tree_host->settings().single_thread_proxy_scheduler &&
61 !scheduler_on_impl_thread_) {
62 SchedulerSettings scheduler_settings(
63 layer_tree_host->settings().ToSchedulerSettings());
64 // SingleThreadProxy should run in main thread low latency mode.
65 scheduler_settings.main_thread_should_always_be_low_latency = true;
66 scheduler_on_impl_thread_ = Scheduler::Create(
67 this, scheduler_settings, layer_tree_host_->id(),
68 MainThreadTaskRunner(), external_begin_frame_source.Pass());
69 }
[email protected]94f206c12012-08-25 00:09:1470}
71
[email protected]e96e3432013-12-19 18:56:0772void SingleThreadProxy::Start() {
[email protected]a8a049c2013-03-11 23:27:0673 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:2174 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]a8a049c2013-03-11 23:27:0675}
76
77SingleThreadProxy::~SingleThreadProxy() {
78 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
79 DCHECK(Proxy::IsMainThread());
[email protected]04049fc2013-05-01 03:13:2080 // Make sure Stop() got called or never Started.
81 DCHECK(!layer_tree_host_impl_);
[email protected]a8a049c2013-03-11 23:27:0682}
83
[email protected]a8a049c2013-03-11 23:27:0684void SingleThreadProxy::FinishAllRendering() {
[email protected]ccc08dc2014-01-30 07:33:2085 TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering");
[email protected]a8a049c2013-03-11 23:27:0686 DCHECK(Proxy::IsMainThread());
87 {
[email protected]61de5812012-11-08 07:03:4488 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2789 layer_tree_host_impl_->FinishAllRendering();
[email protected]a8a049c2013-03-11 23:27:0690 }
[email protected]94f206c12012-08-25 00:09:1491}
92
[email protected]a8a049c2013-03-11 23:27:0693bool SingleThreadProxy::IsStarted() const {
94 DCHECK(Proxy::IsMainThread());
[email protected]3209161d2013-03-29 19:17:3495 return layer_tree_host_impl_;
[email protected]94f206c12012-08-25 00:09:1496}
97
danakj009cdfdf2015-02-17 22:35:1498bool SingleThreadProxy::CommitToActiveTree() const {
99 // With SingleThreadProxy we skip the pending tree and commit directly to the
100 // active tree.
101 return true;
102}
103
[email protected]14bd5542013-05-08 21:51:30104void SingleThreadProxy::SetLayerTreeHostClientReady() {
[email protected]ccc08dc2014-01-30 07:33:20105 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
[email protected]a8a049c2013-03-11 23:27:06106 // Scheduling is controlled by the embedder in the single thread case, so
107 // nothing to do.
[email protected]aeeedad2014-08-22 18:16:22108 DCHECK(Proxy::IsMainThread());
109 DebugScopedSetImplThread impl(this);
danakjfcdaba122015-04-24 21:41:52110 if (scheduler_on_impl_thread_) {
[email protected]aeeedad2014-08-22 18:16:22111 scheduler_on_impl_thread_->SetCanStart();
112 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
113 }
[email protected]a8a049c2013-03-11 23:27:06114}
115
116void SingleThreadProxy::SetVisible(bool visible) {
mithro46adf5a2014-11-19 14:52:40117 TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible);
[email protected]f7c01c82013-07-02 22:58:46118 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:27119 layer_tree_host_impl_->SetVisible(visible);
[email protected]aeeedad2014-08-22 18:16:22120 if (scheduler_on_impl_thread_)
121 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
[email protected]8ea875b2013-08-07 00:32:12122 // Changing visibility could change ShouldComposite().
[email protected]a8a049c2013-03-11 23:27:06123}
124
bajones274110612015-01-06 20:53:59125void SingleThreadProxy::SetThrottleFrameProduction(bool throttle) {
126 TRACE_EVENT1("cc", "SingleThreadProxy::SetThrottleFrameProduction",
127 "throttle", throttle);
128 DebugScopedSetImplThread impl(this);
129 if (scheduler_on_impl_thread_)
130 scheduler_on_impl_thread_->SetThrottleFrameProduction(throttle);
131}
132
enne2097cab2014-09-25 20:16:31133void SingleThreadProxy::RequestNewOutputSurface() {
[email protected]a8a049c2013-03-11 23:27:06134 DCHECK(Proxy::IsMainThread());
[email protected]497edf82014-05-20 21:53:15135 DCHECK(layer_tree_host_->output_surface_lost());
jbauman8ab0f9e2014-10-15 02:30:34136 output_surface_creation_callback_.Cancel();
137 if (output_surface_creation_requested_)
138 return;
139 output_surface_creation_requested_ = true;
enne2097cab2014-09-25 20:16:31140 layer_tree_host_->RequestNewOutputSurface();
141}
[email protected]94f206c12012-08-25 00:09:14142
enne2097cab2014-09-25 20:16:31143void SingleThreadProxy::SetOutputSurface(
144 scoped_ptr<OutputSurface> output_surface) {
145 DCHECK(Proxy::IsMainThread());
146 DCHECK(layer_tree_host_->output_surface_lost());
enne5232fbb2015-01-27 21:22:41147 DCHECK(output_surface_creation_requested_);
[email protected]da8e3b72b2014-04-25 02:33:45148 renderer_capabilities_for_main_thread_ = RendererCapabilities();
149
enne7f8fdde2014-12-10 21:32:09150 bool success;
151 {
[email protected]819b9f52013-09-22 23:29:51152 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06153 DebugScopedSetImplThread impl(this);
[email protected]da8e3b72b2014-04-25 02:33:45154 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]04049fc2013-05-01 03:13:20155 }
156
[email protected]aeeedad2014-08-22 18:16:22157 if (success) {
enne7f8fdde2014-12-10 21:32:09158 layer_tree_host_->DidInitializeOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22159 if (scheduler_on_impl_thread_)
160 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
jbauman399aec1a2014-10-25 02:33:32161 else if (!inside_synchronous_composite_)
162 SetNeedsCommit();
enne5232fbb2015-01-27 21:22:41163 output_surface_creation_requested_ = false;
enne7f8fdde2014-12-10 21:32:09164 } else {
enne5232fbb2015-01-27 21:22:41165 // DidFailToInitializeOutputSurface is treated as a RequestNewOutputSurface,
166 // and so output_surface_creation_requested remains true.
enne7f8fdde2014-12-10 21:32:09167 layer_tree_host_->DidFailToInitializeOutputSurface();
[email protected]04049fc2013-05-01 03:13:20168 }
[email protected]94f206c12012-08-25 00:09:14169}
170
[email protected]a8a049c2013-03-11 23:27:06171const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20172 DCHECK(Proxy::IsMainThread());
173 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06174 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14175}
176
[email protected]8b9e52b2014-01-17 16:35:31177void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20178 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
[email protected]c5134172013-12-11 06:19:48179 DCHECK(Proxy::IsMainThread());
[email protected]06cbc31b2014-01-17 06:43:20180 client_->ScheduleAnimation();
brianderson49e101d22015-04-29 00:05:33181 if (animate_requested_)
182 return;
183 animate_requested_ = true;
184 DebugScopedSetImplThread impl(this);
185 if (scheduler_on_impl_thread_)
186 scheduler_on_impl_thread_->SetNeedsCommit();
[email protected]c5134172013-12-11 06:19:48187}
188
[email protected]8b9e52b2014-01-17 16:35:31189void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20190 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
[email protected]8b9e52b2014-01-17 16:35:31191 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22192 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31193}
194
mithro719bf6792014-11-10 15:36:47195void SingleThreadProxy::DoAnimate() {
196 // Don't animate if there is no root layer.
197 // TODO(mithro): Both Animate and UpdateAnimationState already have a
198 // "!active_tree_->root_layer()" check?
199 if (!layer_tree_host_impl_->active_tree()->root_layer()) {
200 return;
201 }
202
203 layer_tree_host_impl_->Animate(
204 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
205
206 // If animations are not visible, update the animation state now as it
207 // won't happen in DoComposite.
208 if (!layer_tree_host_impl_->AnimationsAreVisible()) {
209 layer_tree_host_impl_->UpdateAnimationState(true);
210 }
211}
212
enne98f3a6c2014-10-09 20:09:44213void SingleThreadProxy::DoCommit() {
[email protected]ccc08dc2014-01-30 07:33:20214 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
[email protected]a8a049c2013-03-11 23:27:06215 DCHECK(Proxy::IsMainThread());
enne98f3a6c2014-10-09 20:09:44216
robliao27728e62015-03-21 07:39:34217 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
218 // fixed.
219 tracked_objects::ScopedTracker tracking_profile1(
220 FROM_HERE_WITH_EXPLICIT_FUNCTION("461509 SingleThreadProxy::DoCommit1"));
[email protected]aeeedad2014-08-22 18:16:22221 layer_tree_host_->WillCommit();
caseq7d2f4c92015-02-04 16:43:27222 devtools_instrumentation::ScopedCommitTrace commit_task(
223 layer_tree_host_->id());
[email protected]aeeedad2014-08-22 18:16:22224
[email protected]a8a049c2013-03-11 23:27:06225 // Commit immediately.
226 {
robliao27728e62015-03-21 07:39:34227 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
228 // is fixed.
229 tracked_objects::ScopedTracker tracking_profile2(
230 FROM_HERE_WITH_EXPLICIT_FUNCTION(
231 "461509 SingleThreadProxy::DoCommit2"));
[email protected]819b9f52013-09-22 23:29:51232 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46233 DebugScopedSetImplThread impl(this);
234
[email protected]9794fb32013-08-29 09:49:59235 // This CapturePostTasks should be destroyed before CommitComplete() is
236 // called since that goes out to the embedder, and we want the embedder
237 // to receive its callbacks before that.
enne98f3a6c2014-10-09 20:09:44238 commit_blocking_task_runner_.reset(new BlockingTaskRunner::CapturePostTasks(
239 blocking_main_thread_task_runner()));
[email protected]9794fb32013-08-29 09:49:59240
[email protected]c1bb5af2013-03-13 19:06:27241 layer_tree_host_impl_->BeginCommit();
[email protected]804c8982013-03-13 16:32:21242 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14243
robliao27728e62015-03-21 07:39:34244 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
245 // is fixed.
robliao27728e62015-03-21 07:39:34246 tracked_objects::ScopedTracker tracking_profile6(
247 FROM_HERE_WITH_EXPLICIT_FUNCTION(
248 "461509 SingleThreadProxy::DoCommit6"));
[email protected]127bdc1a2013-09-11 01:44:48249 if (layer_tree_host_impl_->EvictedUIResourcesExist())
250 layer_tree_host_->RecreateUIResources();
251
robliao27728e62015-03-21 07:39:34252 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
253 // is fixed.
254 tracked_objects::ScopedTracker tracking_profile7(
255 FROM_HERE_WITH_EXPLICIT_FUNCTION(
256 "461509 SingleThreadProxy::DoCommit7"));
[email protected]804c8982013-03-13 16:32:21257 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14258
danakje649f572015-01-08 23:35:58259#if DCHECK_IS_ON()
[email protected]3519b872013-07-30 07:17:50260 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06261 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29262 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27263 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29264 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50265 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14266#endif
enne98f3a6c2014-10-09 20:09:44267
danakj68803fc2015-06-19 20:55:53268 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
269 // is fixed.
270 tracked_objects::ScopedTracker tracking_profile8(
271 FROM_HERE_WITH_EXPLICIT_FUNCTION(
272 "461509 SingleThreadProxy::DoCommit8"));
273 // Commit goes directly to the active tree, but we need to synchronously
274 // "activate" the tree still during commit to satisfy any potential
275 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
276 // might not be ready to draw, so DidActivateSyncTree must set
277 // the flag to force the tree to not draw until textures are ready.
278 NotifyReadyToActivate();
enne98f3a6c2014-10-09 20:09:44279 }
280}
281
282void SingleThreadProxy::CommitComplete() {
283 DCHECK(!layer_tree_host_impl_->pending_tree())
284 << "Activation is expected to have synchronously occurred by now.";
285 DCHECK(commit_blocking_task_runner_);
286
danakj009cdfdf2015-02-17 22:35:14287 // Notify commit complete on the impl side after activate to satisfy any
288 // SetNextCommitWaitsForActivation calls.
289 layer_tree_host_impl_->CommitComplete();
290
enne98f3a6c2014-10-09 20:09:44291 DebugScopedSetMainThread main(this);
292 commit_blocking_task_runner_.reset();
[email protected]804c8982013-03-13 16:32:21293 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22294 layer_tree_host_->DidBeginMainFrame();
295 timing_history_.DidCommit();
296
[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_)
308 scheduler_on_impl_thread_->SetNeedsCommit();
[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_)
419 scheduler_on_impl_thread_->SetNeedsCommit();
[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 // This is required because NotifyReadyToActivate gets called immediately
443 // after commit since single thread commits directly to the active tree.
444 if (scheduler_on_impl_thread_)
445 scheduler_on_impl_thread_->SetWaitForReadyToDraw();
enne98f3a6c2014-10-09 20:09:44446
danakj68803fc2015-06-19 20:55:53447 // Synchronously call to CommitComplete. Resetting
448 // |commit_blocking_task_runner| would make sure all tasks posted during
449 // commit/activation before CommitComplete.
450 CommitComplete();
enne98f3a6c2014-10-09 20:09:44451
enne98f3a6c2014-10-09 20:09:44452 timing_history_.DidActivateSyncTree();
453}
454
vmiura59ea9b4042014-12-09 20:50:39455void SingleThreadProxy::DidPrepareTiles() {
enne98f3a6c2014-10-09 20:09:44456 DCHECK(Proxy::IsImplThread());
457 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39458 scheduler_on_impl_thread_->DidPrepareTiles();
enne98f3a6c2014-10-09 20:09:44459}
460
rouslanf7ebd8832015-01-22 01:54:14461void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
462 layer_tree_host_->DidCompletePageScaleAnimation();
463}
464
[email protected]fa339032014-02-18 22:11:59465void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
466 DCHECK(IsImplThread());
467 renderer_capabilities_for_main_thread_ =
468 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
469}
470
[email protected]c1bb5af2013-03-13 19:06:27471void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20472 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22473 {
474 DebugScopedSetMainThread main(this);
475 // This must happen before we notify the scheduler as it may try to recreate
476 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
477 layer_tree_host_->DidLoseOutputSurface();
478 }
[email protected]4d7e46a2013-11-08 05:33:40479 client_->DidAbortSwapBuffers();
[email protected]aeeedad2014-08-22 18:16:22480 if (scheduler_on_impl_thread_)
481 scheduler_on_impl_thread_->DidLoseOutputSurface();
[email protected]4d7e46a2013-11-08 05:33:40482}
483
weiliangcaf17af42014-12-15 22:17:02484void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
485 base::TimeDelta interval) {
486 if (scheduler_on_impl_thread_)
487 scheduler_on_impl_thread_->CommitVSyncParameters(timebase, interval);
488}
489
jbauman93a5a902015-03-13 22:16:55490void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
491 if (scheduler_on_impl_thread_)
492 scheduler_on_impl_thread_->SetEstimatedParentDrawTime(draw_time);
493}
494
alexst346f30c2015-03-25 13:24:05495void SingleThreadProxy::SetMaxSwapsPendingOnImplThread(int max) {
496 if (scheduler_on_impl_thread_)
497 scheduler_on_impl_thread_->SetMaxSwapsPending(max);
498}
499
[email protected]4d7e46a2013-11-08 05:33:40500void SingleThreadProxy::DidSwapBuffersOnImplThread() {
[email protected]aeeedad2014-08-22 18:16:22501 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
502 if (scheduler_on_impl_thread_)
503 scheduler_on_impl_thread_->DidSwapBuffers();
[email protected]4d7e46a2013-11-08 05:33:40504 client_->DidPostSwapBuffers();
505}
506
[email protected]c14902662014-04-18 05:06:11507void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
miletusfed8c43b2015-01-26 20:04:52508 TRACE_EVENT0("cc,benchmark",
509 "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22510 if (scheduler_on_impl_thread_)
511 scheduler_on_impl_thread_->DidSwapBuffersComplete();
512 layer_tree_host_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10513}
514
sunnypseab5ac92015-04-02 20:26:13515void SingleThreadProxy::OnDrawForOutputSurface() {
516 NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
517}
518
mpbed24c2c2015-06-05 20:57:13519void SingleThreadProxy::PostFrameTimingEventsOnImplThread(
520 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
521 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
522 layer_tree_host_->RecordFrameTimingEvents(composite_events.Pass(),
523 main_frame_events.Pass());
524}
525
[email protected]f0c2a242013-03-15 19:34:52526void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
miletusfed8c43b2015-01-26 20:04:52527 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
[email protected]51f81da2014-05-16 21:29:26528 DCHECK(Proxy::IsMainThread());
mithro51693e382015-05-07 23:52:41529#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13530 DCHECK(!inside_impl_frame_);
mithro51693e382015-05-07 23:52:41531#endif
jbauman399aec1a2014-10-25 02:33:32532 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
533
534 if (layer_tree_host_->output_surface_lost()) {
535 RequestNewOutputSurface();
536 // RequestNewOutputSurface could have synchronously created an output
537 // surface, so check again before returning.
538 if (layer_tree_host_->output_surface_lost())
539 return;
540 }
[email protected]51f81da2014-05-16 21:29:26541
mithroc76d70312015-05-04 23:51:13542 BeginFrameArgs begin_frame_args(BeginFrameArgs::Create(
543 BEGINFRAME_FROM_HERE, frame_begin_time, base::TimeTicks(),
544 BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL));
545
546 // Start the impl frame.
enne98f3a6c2014-10-09 20:09:44547 {
mithroc76d70312015-05-04 23:51:13548 DebugScopedSetImplThread impl(this);
549 WillBeginImplFrame(begin_frame_args);
550 }
551
552 // Run the "main thread" and get it to commit.
553 {
mithro51693e382015-05-07 23:52:41554#if DCHECK_IS_ON()
mithroc76d70312015-05-04 23:51:13555 DCHECK(inside_impl_frame_);
mithro51693e382015-05-07 23:52:41556#endif
enne98f3a6c2014-10-09 20:09:44557 DoBeginMainFrame(begin_frame_args);
558 DoCommit();
[email protected]e0341352013-04-06 05:01:20559
enne98f3a6c2014-10-09 20:09:44560 DCHECK_EQ(0u, layer_tree_host_->num_queued_swap_promises())
561 << "Commit should always succeed and transfer promises.";
562 }
563
mithroc76d70312015-05-04 23:51:13564 // Finish the impl frame.
enne98f3a6c2014-10-09 20:09:44565 {
mithroc76d70312015-05-04 23:51:13566 DebugScopedSetImplThread impl(this);
danakj68803fc2015-06-19 20:55:53567 layer_tree_host_impl_->ActivateSyncTree();
568 DCHECK(
569 !layer_tree_host_impl_->active_tree()->needs_update_draw_properties());
570 layer_tree_host_impl_->PrepareTiles();
571 layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
enne69277cb2014-10-29 23:03:40572
mithro719bf6792014-11-10 15:36:47573 DoAnimate();
574
enne98f3a6c2014-10-09 20:09:44575 LayerTreeHostImpl::FrameData frame;
mithro248d1722015-05-05 05:23:45576 DoComposite(&frame);
enne98f3a6c2014-10-09 20:09:44577
578 // DoComposite could abort, but because this is a synchronous composite
579 // another draw will never be scheduled, so break remaining promises.
580 layer_tree_host_impl_->active_tree()->BreakSwapPromises(
581 SwapPromise::SWAP_FAILS);
mithroc76d70312015-05-04 23:51:13582
mithro51693e382015-05-07 23:52:41583 DidFinishImplFrame();
enne98f3a6c2014-10-09 20:09:44584 }
[email protected]74d9063c2013-01-18 03:14:47585}
586
[email protected]a8a049c2013-03-11 23:27:06587void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
588 {
589 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20590 if (layer_tree_host_impl_->renderer()) {
591 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06592 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20593 }
[email protected]a8a049c2013-03-11 23:27:06594 }
[email protected]8947cbe2012-11-28 05:27:43595}
596
[email protected]5d8bec72014-07-03 03:03:11597bool SingleThreadProxy::SupportsImplScrolling() const {
598 return false;
599}
600
[email protected]3d9f7432013-04-06 00:35:18601bool SingleThreadProxy::ShouldComposite() const {
602 DCHECK(Proxy::IsImplThread());
603 return layer_tree_host_impl_->visible() &&
604 layer_tree_host_impl_->CanDraw();
605}
606
jbauman8ab0f9e2014-10-15 02:30:34607void SingleThreadProxy::ScheduleRequestNewOutputSurface() {
608 if (output_surface_creation_callback_.IsCancelled() &&
609 !output_surface_creation_requested_) {
610 output_surface_creation_callback_.Reset(
611 base::Bind(&SingleThreadProxy::RequestNewOutputSurface,
612 weak_factory_.GetWeakPtr()));
613 MainThreadTaskRunner()->PostTask(
614 FROM_HERE, output_surface_creation_callback_.callback());
615 }
616}
617
mithro248d1722015-05-05 05:23:45618DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20619 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20620 DCHECK(!layer_tree_host_->output_surface_lost());
621
enne98f3a6c2014-10-09 20:09:44622 DrawResult draw_result;
623 bool draw_frame;
[email protected]a8a049c2013-03-11 23:27:06624 {
625 DebugScopedSetImplThread impl(this);
626 base::AutoReset<bool> mark_inside(&inside_draw_, true);
627
robliao27728e62015-03-21 07:39:34628 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
629 // is fixed.
630 tracked_objects::ScopedTracker tracking_profile1(
631 FROM_HERE_WITH_EXPLICIT_FUNCTION(
632 "461509 SingleThreadProxy::DoComposite1"));
633
[email protected]3d9f7432013-04-06 00:35:18634 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
635 // frame, so can only be used when such a frame is possible. Since
636 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
637 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50638 if (!ShouldComposite()) {
[email protected]aeeedad2014-08-22 18:16:22639 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18640 }
[email protected]a8a049c2013-03-11 23:27:06641
[email protected]aeeedad2014-08-22 18:16:22642 timing_history_.DidStartDrawing();
643
robliao27728e62015-03-21 07:39:34644 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
645 // is fixed.
646 tracked_objects::ScopedTracker tracking_profile2(
647 FROM_HERE_WITH_EXPLICIT_FUNCTION(
648 "461509 SingleThreadProxy::DoComposite2"));
enne98f3a6c2014-10-09 20:09:44649 draw_result = layer_tree_host_impl_->PrepareToDraw(frame);
650 draw_frame = draw_result == DRAW_SUCCESS;
robliao27728e62015-03-21 07:39:34651 if (draw_frame) {
652 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
653 // is fixed.
654 tracked_objects::ScopedTracker tracking_profile3(
655 FROM_HERE_WITH_EXPLICIT_FUNCTION(
656 "461509 SingleThreadProxy::DoComposite3"));
mithro248d1722015-05-05 05:23:45657 layer_tree_host_impl_->DrawLayers(frame);
robliao27728e62015-03-21 07:39:34658 }
659 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
660 // is fixed.
661 tracked_objects::ScopedTracker tracking_profile4(
662 FROM_HERE_WITH_EXPLICIT_FUNCTION(
663 "461509 SingleThreadProxy::DoComposite4"));
dnetob71e30c2014-08-25 23:27:20664 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06665
enne98f3a6c2014-10-09 20:09:44666 bool start_ready_animations = draw_frame;
robliao27728e62015-03-21 07:39:34667 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
668 // is fixed.
669 tracked_objects::ScopedTracker tracking_profile5(
670 FROM_HERE_WITH_EXPLICIT_FUNCTION(
671 "461509 SingleThreadProxy::DoComposite5"));
[email protected]3d9f7432013-04-06 00:35:18672 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]aeeedad2014-08-22 18:16:22673
robliao27728e62015-03-21 07:39:34674 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
675 // is fixed.
676 tracked_objects::ScopedTracker tracking_profile7(
677 FROM_HERE_WITH_EXPLICIT_FUNCTION(
678 "461509 SingleThreadProxy::DoComposite7"));
[email protected]aeeedad2014-08-22 18:16:22679 timing_history_.DidFinishDrawing();
[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
[email protected]aeeedad2014-08-22 18:16:22826 timing_history_.DidBeginMainFrame();
827
mithrof7a21502014-12-17 03:24:48828 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
829 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
830 // thread_proxy.cc
enne98f3a6c2014-10-09 20:09:44831 if (scheduler_on_impl_thread_) {
832 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
833 scheduler_on_impl_thread_->NotifyReadyToCommit();
834 }
[email protected]aeeedad2014-08-22 18:16:22835}
836
mithrof7a21502014-12-17 03:24:48837void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
838 CommitEarlyOutReason reason) {
[email protected]aeeedad2014-08-22 18:16:22839 DebugScopedSetImplThread impl(this);
840 DCHECK(scheduler_on_impl_thread_->CommitPending());
841 DCHECK(!layer_tree_host_impl_->pending_tree());
842
mithrof7a21502014-12-17 03:24:48843 layer_tree_host_impl_->BeginMainFrameAborted(reason);
844 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
[email protected]aeeedad2014-08-22 18:16:22845}
846
847DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
848 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22849 LayerTreeHostImpl::FrameData frame;
mithro248d1722015-05-05 05:23:45850 return DoComposite(&frame);
[email protected]aeeedad2014-08-22 18:16:22851}
852
853DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
854 NOTREACHED();
855 return INVALID_RESULT;
856}
857
858void SingleThreadProxy::ScheduledActionCommit() {
859 DebugScopedSetMainThread main(this);
enne98f3a6c2014-10-09 20:09:44860 DoCommit();
[email protected]aeeedad2014-08-22 18:16:22861}
862
863void SingleThreadProxy::ScheduledActionAnimate() {
864 TRACE_EVENT0("cc", "ScheduledActionAnimate");
mithro719bf6792014-11-10 15:36:47865 DebugScopedSetImplThread impl(this);
866 DoAnimate();
[email protected]aeeedad2014-08-22 18:16:22867}
868
[email protected]aeeedad2014-08-22 18:16:22869void SingleThreadProxy::ScheduledActionActivateSyncTree() {
enne98f3a6c2014-10-09 20:09:44870 DebugScopedSetImplThread impl(this);
871 layer_tree_host_impl_->ActivateSyncTree();
[email protected]aeeedad2014-08-22 18:16:22872}
873
874void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
875 DebugScopedSetMainThread main(this);
876 DCHECK(scheduler_on_impl_thread_);
877 // If possible, create the output surface in a post task. Synchronously
878 // creating the output surface makes tests more awkward since this differs
879 // from the ThreadProxy behavior. However, sometimes there is no
880 // task runner.
881 if (Proxy::MainThreadTaskRunner()) {
jbauman8ab0f9e2014-10-15 02:30:34882 ScheduleRequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22883 } else {
enne2097cab2014-09-25 20:16:31884 RequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22885 }
886}
887
vmiura59ea9b4042014-12-09 20:50:39888void SingleThreadProxy::ScheduledActionPrepareTiles() {
889 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
enne98f3a6c2014-10-09 20:09:44890 DebugScopedSetImplThread impl(this);
vmiura59ea9b4042014-12-09 20:50:39891 layer_tree_host_impl_->PrepareTiles();
[email protected]aeeedad2014-08-22 18:16:22892}
893
sunnypseab5ac92015-04-02 20:26:13894void SingleThreadProxy::ScheduledActionInvalidateOutputSurface() {
895 NOTREACHED();
896}
897
[email protected]aeeedad2014-08-22 18:16:22898base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
899 return timing_history_.DrawDurationEstimate();
900}
901
902base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
903 return timing_history_.BeginMainFrameToCommitDurationEstimate();
904}
905
906base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
907 return timing_history_.CommitToActivateDurationEstimate();
908}
909
mithro51693e382015-05-07 23:52:41910void SingleThreadProxy::DidFinishImplFrame() {
911 layer_tree_host_impl_->DidFinishImplFrame();
912#if DCHECK_IS_ON()
mithro69fd3bb52015-05-01 03:45:02913 DCHECK(inside_impl_frame_)
mithro51693e382015-05-07 23:52:41914 << "DidFinishImplFrame called while not inside an impl frame!";
mithro69fd3bb52015-05-01 03:45:02915 inside_impl_frame_ = false;
mithro51693e382015-05-07 23:52:41916#endif
[email protected]aeeedad2014-08-22 18:16:22917}
918
simonhongd3d5f7f2014-11-21 16:38:03919void SingleThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) {
920 layer_tree_host_->SendBeginFramesToChildren(args);
921}
922
[email protected]bc5e77c2012-11-05 20:00:49923} // namespace cc