blob: b97b3ce889cb35186764c513476da9d17fbf1215 [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"
16#include "cc/resources/resource_update_controller.h"
mithrof7a21502014-12-17 03:24:4817#include "cc/scheduler/commit_earlyout_reason.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]de2cf8c2013-10-25 19:46:4622#include "ui/gfx/frame_time.h"
[email protected]94f206c12012-08-25 00:09:1423
[email protected]9c88e562012-09-14 22:21:3024namespace cc {
[email protected]94f206c12012-08-25 00:09:1425
[email protected]943528e2013-11-07 05:01:3226scoped_ptr<Proxy> SingleThreadProxy::Create(
27 LayerTreeHost* layer_tree_host,
[email protected]27e6a212014-07-18 15:51:2728 LayerTreeHostSingleThreadClient* client,
simonhonga7e3ac42014-11-11 20:50:2229 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
30 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
31 return make_scoped_ptr(new SingleThreadProxy(
32 layer_tree_host,
33 client,
34 main_task_runner,
35 external_begin_frame_source.Pass()));
[email protected]94f206c12012-08-25 00:09:1436}
37
[email protected]27e6a212014-07-18 15:51:2738SingleThreadProxy::SingleThreadProxy(
39 LayerTreeHost* layer_tree_host,
40 LayerTreeHostSingleThreadClient* client,
simonhonga7e3ac42014-11-11 20:50:2241 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
42 scoped_ptr<BeginFrameSource> external_begin_frame_source)
[email protected]27e6a212014-07-18 15:51:2743 : Proxy(main_task_runner, NULL),
[email protected]a8a049c2013-03-11 23:27:0644 layer_tree_host_(layer_tree_host),
[email protected]943528e2013-11-07 05:01:3245 client_(client),
[email protected]aeeedad2014-08-22 18:16:2246 timing_history_(layer_tree_host->rendering_stats_instrumentation()),
[email protected]a8a049c2013-03-11 23:27:0647 next_frame_is_newly_committed_frame_(false),
mithro69fd3bb52015-05-01 03:45:0248 inside_impl_frame_(false),
[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]804c8982013-03-13 16:32:21154 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27155 layer_tree_host_impl_->resource_provider());
[email protected]da8e3b72b2014-04-25 02:33:45156 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]04049fc2013-05-01 03:13:20157 }
158
[email protected]aeeedad2014-08-22 18:16:22159 if (success) {
enne7f8fdde2014-12-10 21:32:09160 layer_tree_host_->DidInitializeOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22161 if (scheduler_on_impl_thread_)
162 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
jbauman399aec1a2014-10-25 02:33:32163 else if (!inside_synchronous_composite_)
164 SetNeedsCommit();
enne5232fbb2015-01-27 21:22:41165 output_surface_creation_requested_ = false;
enne7f8fdde2014-12-10 21:32:09166 } else {
enne5232fbb2015-01-27 21:22:41167 // DidFailToInitializeOutputSurface is treated as a RequestNewOutputSurface,
168 // and so output_surface_creation_requested remains true.
enne7f8fdde2014-12-10 21:32:09169 layer_tree_host_->DidFailToInitializeOutputSurface();
[email protected]04049fc2013-05-01 03:13:20170 }
[email protected]94f206c12012-08-25 00:09:14171}
172
[email protected]a8a049c2013-03-11 23:27:06173const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20174 DCHECK(Proxy::IsMainThread());
175 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06176 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14177}
178
[email protected]8b9e52b2014-01-17 16:35:31179void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20180 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
[email protected]c5134172013-12-11 06:19:48181 DCHECK(Proxy::IsMainThread());
[email protected]06cbc31b2014-01-17 06:43:20182 client_->ScheduleAnimation();
brianderson49e101d22015-04-29 00:05:33183 if (animate_requested_)
184 return;
185 animate_requested_ = true;
186 DebugScopedSetImplThread impl(this);
187 if (scheduler_on_impl_thread_)
188 scheduler_on_impl_thread_->SetNeedsCommit();
[email protected]c5134172013-12-11 06:19:48189}
190
[email protected]8b9e52b2014-01-17 16:35:31191void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20192 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
[email protected]8b9e52b2014-01-17 16:35:31193 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22194 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31195}
196
mithro719bf6792014-11-10 15:36:47197void SingleThreadProxy::DoAnimate() {
198 // Don't animate if there is no root layer.
199 // TODO(mithro): Both Animate and UpdateAnimationState already have a
200 // "!active_tree_->root_layer()" check?
201 if (!layer_tree_host_impl_->active_tree()->root_layer()) {
202 return;
203 }
204
205 layer_tree_host_impl_->Animate(
206 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
207
208 // If animations are not visible, update the animation state now as it
209 // won't happen in DoComposite.
210 if (!layer_tree_host_impl_->AnimationsAreVisible()) {
211 layer_tree_host_impl_->UpdateAnimationState(true);
212 }
213}
214
enne98f3a6c2014-10-09 20:09:44215void SingleThreadProxy::DoCommit() {
[email protected]ccc08dc2014-01-30 07:33:20216 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
[email protected]a8a049c2013-03-11 23:27:06217 DCHECK(Proxy::IsMainThread());
enne98f3a6c2014-10-09 20:09:44218
robliao27728e62015-03-21 07:39:34219 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
220 // fixed.
221 tracked_objects::ScopedTracker tracking_profile1(
222 FROM_HERE_WITH_EXPLICIT_FUNCTION("461509 SingleThreadProxy::DoCommit1"));
[email protected]aeeedad2014-08-22 18:16:22223 layer_tree_host_->WillCommit();
caseq7d2f4c92015-02-04 16:43:27224 devtools_instrumentation::ScopedCommitTrace commit_task(
225 layer_tree_host_->id());
[email protected]aeeedad2014-08-22 18:16:22226
[email protected]a8a049c2013-03-11 23:27:06227 // Commit immediately.
228 {
robliao27728e62015-03-21 07:39:34229 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
230 // is fixed.
231 tracked_objects::ScopedTracker tracking_profile2(
232 FROM_HERE_WITH_EXPLICIT_FUNCTION(
233 "461509 SingleThreadProxy::DoCommit2"));
[email protected]819b9f52013-09-22 23:29:51234 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46235 DebugScopedSetImplThread impl(this);
236
[email protected]9794fb32013-08-29 09:49:59237 // This CapturePostTasks should be destroyed before CommitComplete() is
238 // called since that goes out to the embedder, and we want the embedder
239 // to receive its callbacks before that.
enne98f3a6c2014-10-09 20:09:44240 commit_blocking_task_runner_.reset(new BlockingTaskRunner::CapturePostTasks(
241 blocking_main_thread_task_runner()));
[email protected]9794fb32013-08-29 09:49:59242
[email protected]c1bb5af2013-03-13 19:06:27243 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14244
[email protected]5d2fec02013-11-28 20:08:33245 if (PrioritizedResourceManager* contents_texture_manager =
246 layer_tree_host_->contents_texture_manager()) {
robliao27728e62015-03-21 07:39:34247 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
248 // is fixed.
249 tracked_objects::ScopedTracker tracking_profile3(
250 FROM_HERE_WITH_EXPLICIT_FUNCTION(
251 "461509 SingleThreadProxy::DoCommit3"));
[email protected]5d2fec02013-11-28 20:08:33252 contents_texture_manager->PushTexturePrioritiesToBackings();
[email protected]6e8c54922013-06-02 19:17:35253 }
[email protected]804c8982013-03-13 16:32:21254 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14255
robliao27728e62015-03-21 07:39:34256 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
257 // is fixed.
258 tracked_objects::ScopedTracker tracking_profile4(
259 FROM_HERE_WITH_EXPLICIT_FUNCTION(
260 "461509 SingleThreadProxy::DoCommit4"));
[email protected]ed511b8d2013-03-25 03:29:29261 scoped_ptr<ResourceUpdateController> update_controller =
[email protected]a8a049c2013-03-11 23:27:06262 ResourceUpdateController::Create(
263 NULL,
[email protected]aeeedad2014-08-22 18:16:22264 MainThreadTaskRunner(),
enne98f3a6c2014-10-09 20:09:44265 queue_for_commit_.Pass(),
[email protected]c1bb5af2013-03-13 19:06:27266 layer_tree_host_impl_->resource_provider());
robliao27728e62015-03-21 07:39:34267
268 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
269 // is fixed.
270 tracked_objects::ScopedTracker tracking_profile5(
271 FROM_HERE_WITH_EXPLICIT_FUNCTION(
272 "461509 SingleThreadProxy::DoCommit5"));
[email protected]ed511b8d2013-03-25 03:29:29273 update_controller->Finalize();
[email protected]94f206c12012-08-25 00:09:14274
robliao27728e62015-03-21 07:39:34275 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
276 // is fixed.
277 tracked_objects::ScopedTracker tracking_profile6(
278 FROM_HERE_WITH_EXPLICIT_FUNCTION(
279 "461509 SingleThreadProxy::DoCommit6"));
[email protected]127bdc1a2013-09-11 01:44:48280 if (layer_tree_host_impl_->EvictedUIResourcesExist())
281 layer_tree_host_->RecreateUIResources();
282
robliao27728e62015-03-21 07:39:34283 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
284 // is fixed.
285 tracked_objects::ScopedTracker tracking_profile7(
286 FROM_HERE_WITH_EXPLICIT_FUNCTION(
287 "461509 SingleThreadProxy::DoCommit7"));
[email protected]804c8982013-03-13 16:32:21288 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14289
danakje649f572015-01-08 23:35:58290#if DCHECK_IS_ON()
[email protected]3519b872013-07-30 07:17:50291 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06292 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29293 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27294 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29295 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50296 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14297#endif
enne98f3a6c2014-10-09 20:09:44298
danakj009cdfdf2015-02-17 22:35:14299 if (layer_tree_host_->settings().impl_side_painting) {
robliao27728e62015-03-21 07:39:34300 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
301 // is fixed.
302 tracked_objects::ScopedTracker tracking_profile8(
303 FROM_HERE_WITH_EXPLICIT_FUNCTION(
304 "461509 SingleThreadProxy::DoCommit8"));
danakj009cdfdf2015-02-17 22:35:14305 // Commit goes directly to the active tree, but we need to synchronously
306 // "activate" the tree still during commit to satisfy any potential
307 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
308 // might not be ready to draw, so DidActivateSyncTree must set
309 // the flag to force the tree to not draw until textures are ready.
310 NotifyReadyToActivate();
311 } else {
robliao27728e62015-03-21 07:39:34312 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
313 // is fixed.
314 tracked_objects::ScopedTracker tracking_profile9(
315 FROM_HERE_WITH_EXPLICIT_FUNCTION(
316 "461509 SingleThreadProxy::DoCommit9"));
danakj009cdfdf2015-02-17 22:35:14317 CommitComplete();
318 }
enne98f3a6c2014-10-09 20:09:44319 }
320}
321
322void SingleThreadProxy::CommitComplete() {
323 DCHECK(!layer_tree_host_impl_->pending_tree())
324 << "Activation is expected to have synchronously occurred by now.";
325 DCHECK(commit_blocking_task_runner_);
326
danakj009cdfdf2015-02-17 22:35:14327 // Notify commit complete on the impl side after activate to satisfy any
328 // SetNextCommitWaitsForActivation calls.
329 layer_tree_host_impl_->CommitComplete();
330
enne98f3a6c2014-10-09 20:09:44331 DebugScopedSetMainThread main(this);
332 commit_blocking_task_runner_.reset();
[email protected]804c8982013-03-13 16:32:21333 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22334 layer_tree_host_->DidBeginMainFrame();
335 timing_history_.DidCommit();
336
[email protected]a8a049c2013-03-11 23:27:06337 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14338}
339
[email protected]a8a049c2013-03-11 23:27:06340void SingleThreadProxy::SetNeedsCommit() {
341 DCHECK(Proxy::IsMainThread());
[email protected]943528e2013-11-07 05:01:32342 client_->ScheduleComposite();
danakjfcdaba122015-04-24 21:41:52343 if (commit_requested_)
344 return;
brianderson49e101d22015-04-29 00:05:33345 commit_requested_ = true;
danakjfcdaba122015-04-24 21:41:52346 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22347 if (scheduler_on_impl_thread_)
348 scheduler_on_impl_thread_->SetNeedsCommit();
[email protected]94f206c12012-08-25 00:09:14349}
350
[email protected]0023fc72014-01-10 20:05:06351void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20352 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
[email protected]aeeedad2014-08-22 18:16:22353 DCHECK(Proxy::IsMainThread());
354 DebugScopedSetImplThread impl(this);
[email protected]2decdd782014-08-13 22:36:06355 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22356 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14357}
358
[email protected]74b43cc2013-08-30 06:29:27359void SingleThreadProxy::SetNextCommitWaitsForActivation() {
enne98f3a6c2014-10-09 20:09:44360 // Activation always forced in commit, so nothing to do.
[email protected]aeeedad2014-08-22 18:16:22361 DCHECK(Proxy::IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27362}
363
[email protected]a8a049c2013-03-11 23:27:06364void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
[email protected]aeeedad2014-08-22 18:16:22365 DCHECK(Proxy::IsMainThread());
366 // Deferring commits only makes sense if there's a scheduler.
367 if (!scheduler_on_impl_thread_)
368 return;
369 if (defer_commits_ == defer_commits)
370 return;
371
372 if (defer_commits)
373 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
374 else
375 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
376
377 defer_commits_ = defer_commits;
simonhongc6309f792015-01-31 15:47:15378 scheduler_on_impl_thread_->SetDeferCommits(defer_commits);
[email protected]6b16679e2012-10-27 00:44:28379}
380
[email protected]174c6d42014-08-12 01:43:06381bool SingleThreadProxy::CommitRequested() const {
[email protected]aeeedad2014-08-22 18:16:22382 DCHECK(Proxy::IsMainThread());
383 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06384}
[email protected]a8a049c2013-03-11 23:27:06385
[email protected]174c6d42014-08-12 01:43:06386bool SingleThreadProxy::BeginMainFrameRequested() const {
[email protected]aeeedad2014-08-22 18:16:22387 DCHECK(Proxy::IsMainThread());
388 // If there is no scheduler, then there can be no pending begin frame,
389 // as all frames are all manually initiated by the embedder of cc.
390 if (!scheduler_on_impl_thread_)
391 return false;
392 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06393}
[email protected]971728d2013-10-26 10:39:31394
[email protected]a8a049c2013-03-11 23:27:06395size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
396 return std::numeric_limits<size_t>::max();
397}
398
399void SingleThreadProxy::Stop() {
400 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
401 DCHECK(Proxy::IsMainThread());
402 {
[email protected]819b9f52013-09-22 23:29:51403 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06404 DebugScopedSetImplThread impl(this);
405
skyostil3976a3f2014-09-04 22:07:23406 BlockingTaskRunner::CapturePostTasks blocked(
407 blocking_main_thread_task_runner());
[email protected]804c8982013-03-13 16:32:21408 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27409 layer_tree_host_impl_->resource_provider());
danakjf446a072014-09-27 21:55:48410 scheduler_on_impl_thread_ = nullptr;
411 layer_tree_host_impl_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06412 }
[email protected]7aba6662013-03-12 10:17:34413 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06414}
415
[email protected]3d9f7432013-04-06 00:35:18416void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
[email protected]ccc08dc2014-01-30 07:33:20417 TRACE_EVENT1(
418 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
[email protected]3d9f7432013-04-06 00:35:18419 DCHECK(Proxy::IsImplThread());
[email protected]aeeedad2014-08-22 18:16:22420 if (scheduler_on_impl_thread_)
421 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18422}
423
[email protected]4f48f6e2013-08-27 06:33:38424void SingleThreadProxy::NotifyReadyToActivate() {
enne98f3a6c2014-10-09 20:09:44425 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
426 DebugScopedSetImplThread impl(this);
427 if (scheduler_on_impl_thread_)
428 scheduler_on_impl_thread_->NotifyReadyToActivate();
[email protected]4f48f6e2013-08-27 06:33:38429}
430
ernstmdfac03e2014-11-11 20:18:05431void SingleThreadProxy::NotifyReadyToDraw() {
weiliangc8dac5a62015-04-02 06:12:35432 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToDraw");
433 DebugScopedSetImplThread impl(this);
434 if (scheduler_on_impl_thread_)
435 scheduler_on_impl_thread_->NotifyReadyToDraw();
ernstmdfac03e2014-11-11 20:18:05436}
437
[email protected]c1bb5af2013-03-13 19:06:27438void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]943528e2013-11-07 05:01:32439 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22440 if (scheduler_on_impl_thread_)
441 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06442}
443
[email protected]43b8f982014-04-30 21:24:33444void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
mithro719bf6792014-11-10 15:36:47445 client_->ScheduleComposite();
446 if (scheduler_on_impl_thread_)
447 scheduler_on_impl_thread_->SetNeedsAnimate();
[email protected]43b8f982014-04-30 21:24:33448}
449
vmiura59ea9b4042014-12-09 20:50:39450void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
451 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
enne98f3a6c2014-10-09 20:09:44452 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39453 scheduler_on_impl_thread_->SetNeedsPrepareTiles();
[email protected]c48536a52013-09-14 00:02:08454}
455
[email protected]0023fc72014-01-10 20:05:06456void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
457 const gfx::Rect& damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03458 layer_tree_host_impl_->SetViewportDamage(damage_rect);
[email protected]aeeedad2014-08-22 18:16:22459 SetNeedsRedrawOnImplThread();
[email protected]1cd9f5552013-04-26 04:22:03460}
461
[email protected]c1bb5af2013-03-13 19:06:27462void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]943528e2013-11-07 05:01:32463 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22464 if (scheduler_on_impl_thread_)
465 scheduler_on_impl_thread_->SetNeedsCommit();
[email protected]a8a049c2013-03-11 23:27:06466}
467
sunnyps7d073dc2015-04-16 23:29:12468void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
469 TRACE_EVENT1("cc", "SingleThreadProxy::SetVideoNeedsBeginFrames",
470 "needs_begin_frames", needs_begin_frames);
471 // In tests the layer tree is destroyed after the scheduler is.
472 if (scheduler_on_impl_thread_)
473 scheduler_on_impl_thread_->SetVideoNeedsBeginFrames(needs_begin_frames);
474}
475
[email protected]c1bb5af2013-03-13 19:06:27476void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]85b57502014-03-11 15:37:48477 scoped_ptr<AnimationEventsVector> events) {
[email protected]ccc08dc2014-01-30 07:33:20478 TRACE_EVENT0(
479 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
[email protected]a8a049c2013-03-11 23:27:06480 DCHECK(Proxy::IsImplThread());
481 DebugScopedSetMainThread main(this);
[email protected]85b57502014-03-11 15:37:48482 layer_tree_host_->SetAnimationEvents(events.Pass());
[email protected]a8a049c2013-03-11 23:27:06483}
484
[email protected]c1bb5af2013-03-13 19:06:27485bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06486 size_t limit_bytes,
487 int priority_cutoff) {
488 DCHECK(IsImplThread());
[email protected]5d2fec02013-11-28 20:08:33489 PrioritizedResourceManager* contents_texture_manager =
490 layer_tree_host_->contents_texture_manager();
491
492 ResourceProvider* resource_provider =
493 layer_tree_host_impl_->resource_provider();
494
495 if (!contents_texture_manager || !resource_provider)
[email protected]e7595ead2013-10-10 10:10:07496 return false;
[email protected]a8a049c2013-03-11 23:27:06497
[email protected]5d2fec02013-11-28 20:08:33498 return contents_texture_manager->ReduceMemoryOnImplThread(
499 limit_bytes, priority_cutoff, resource_provider);
[email protected]94f206c12012-08-25 00:09:14500}
501
[email protected]c1bb5af2013-03-13 19:06:27502bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06503
enne98f3a6c2014-10-09 20:09:44504void SingleThreadProxy::DidActivateSyncTree() {
505 // Non-impl-side painting finishes commit in DoCommit. Impl-side painting
506 // defers until here to simulate SetNextCommitWaitsForActivation.
507 if (layer_tree_host_impl_->settings().impl_side_painting) {
danakj009cdfdf2015-02-17 22:35:14508 // This is required because NotifyReadyToActivate gets called immediately
509 // after commit since single thread commits directly to the active tree.
weiliangc8dac5a62015-04-02 06:12:35510 if (scheduler_on_impl_thread_)
511 scheduler_on_impl_thread_->SetWaitForReadyToDraw();
enne98f3a6c2014-10-09 20:09:44512
weiliangc5efa0a12015-01-29 19:56:46513 // Synchronously call to CommitComplete. Resetting
514 // |commit_blocking_task_runner| would make sure all tasks posted during
515 // commit/activation before CommitComplete.
enne5bea30e72014-12-18 00:36:17516 CommitComplete();
enne98f3a6c2014-10-09 20:09:44517 }
518
enne98f3a6c2014-10-09 20:09:44519 timing_history_.DidActivateSyncTree();
520}
521
vmiura59ea9b4042014-12-09 20:50:39522void SingleThreadProxy::DidPrepareTiles() {
enne98f3a6c2014-10-09 20:09:44523 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
524 DCHECK(Proxy::IsImplThread());
525 if (scheduler_on_impl_thread_)
vmiura59ea9b4042014-12-09 20:50:39526 scheduler_on_impl_thread_->DidPrepareTiles();
enne98f3a6c2014-10-09 20:09:44527}
528
rouslanf7ebd8832015-01-22 01:54:14529void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
530 layer_tree_host_->DidCompletePageScaleAnimation();
531}
532
[email protected]fa339032014-02-18 22:11:59533void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
534 DCHECK(IsImplThread());
535 renderer_capabilities_for_main_thread_ =
536 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
537}
538
[email protected]c1bb5af2013-03-13 19:06:27539void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20540 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22541 {
542 DebugScopedSetMainThread main(this);
543 // This must happen before we notify the scheduler as it may try to recreate
544 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
545 layer_tree_host_->DidLoseOutputSurface();
546 }
[email protected]4d7e46a2013-11-08 05:33:40547 client_->DidAbortSwapBuffers();
[email protected]aeeedad2014-08-22 18:16:22548 if (scheduler_on_impl_thread_)
549 scheduler_on_impl_thread_->DidLoseOutputSurface();
[email protected]4d7e46a2013-11-08 05:33:40550}
551
weiliangcaf17af42014-12-15 22:17:02552void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
553 base::TimeDelta interval) {
554 if (scheduler_on_impl_thread_)
555 scheduler_on_impl_thread_->CommitVSyncParameters(timebase, interval);
556}
557
jbauman93a5a902015-03-13 22:16:55558void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
559 if (scheduler_on_impl_thread_)
560 scheduler_on_impl_thread_->SetEstimatedParentDrawTime(draw_time);
561}
562
alexst346f30c2015-03-25 13:24:05563void SingleThreadProxy::SetMaxSwapsPendingOnImplThread(int max) {
564 if (scheduler_on_impl_thread_)
565 scheduler_on_impl_thread_->SetMaxSwapsPending(max);
566}
567
[email protected]4d7e46a2013-11-08 05:33:40568void SingleThreadProxy::DidSwapBuffersOnImplThread() {
[email protected]aeeedad2014-08-22 18:16:22569 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
570 if (scheduler_on_impl_thread_)
571 scheduler_on_impl_thread_->DidSwapBuffers();
[email protected]4d7e46a2013-11-08 05:33:40572 client_->DidPostSwapBuffers();
573}
574
[email protected]c14902662014-04-18 05:06:11575void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
miletusfed8c43b2015-01-26 20:04:52576 TRACE_EVENT0("cc,benchmark",
577 "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22578 if (scheduler_on_impl_thread_)
579 scheduler_on_impl_thread_->DidSwapBuffersComplete();
580 layer_tree_host_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10581}
582
sunnypseab5ac92015-04-02 20:26:13583void SingleThreadProxy::OnDrawForOutputSurface() {
584 NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
585}
586
[email protected]f0c2a242013-03-15 19:34:52587void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
miletusfed8c43b2015-01-26 20:04:52588 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
[email protected]51f81da2014-05-16 21:29:26589 DCHECK(Proxy::IsMainThread());
mithroc76d70312015-05-04 23:51:13590 DCHECK(!inside_impl_frame_);
jbauman399aec1a2014-10-25 02:33:32591 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
592
593 if (layer_tree_host_->output_surface_lost()) {
594 RequestNewOutputSurface();
595 // RequestNewOutputSurface could have synchronously created an output
596 // surface, so check again before returning.
597 if (layer_tree_host_->output_surface_lost())
598 return;
599 }
[email protected]51f81da2014-05-16 21:29:26600
mithroc76d70312015-05-04 23:51:13601 BeginFrameArgs begin_frame_args(BeginFrameArgs::Create(
602 BEGINFRAME_FROM_HERE, frame_begin_time, base::TimeTicks(),
603 BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL));
604
605 // Start the impl frame.
enne98f3a6c2014-10-09 20:09:44606 {
mithroc76d70312015-05-04 23:51:13607 DebugScopedSetImplThread impl(this);
608 WillBeginImplFrame(begin_frame_args);
609 }
610
611 // Run the "main thread" and get it to commit.
612 {
613 DCHECK(inside_impl_frame_);
enne98f3a6c2014-10-09 20:09:44614 DoBeginMainFrame(begin_frame_args);
615 DoCommit();
[email protected]e0341352013-04-06 05:01:20616
enne98f3a6c2014-10-09 20:09:44617 DCHECK_EQ(0u, layer_tree_host_->num_queued_swap_promises())
618 << "Commit should always succeed and transfer promises.";
619 }
620
mithroc76d70312015-05-04 23:51:13621 // Finish the impl frame.
enne98f3a6c2014-10-09 20:09:44622 {
mithroc76d70312015-05-04 23:51:13623 DebugScopedSetImplThread impl(this);
enne69277cb2014-10-29 23:03:40624 if (layer_tree_host_impl_->settings().impl_side_painting) {
625 layer_tree_host_impl_->ActivateSyncTree();
enne0acea6ae2015-02-19 20:01:51626 DCHECK(!layer_tree_host_impl_->active_tree()
627 ->needs_update_draw_properties());
vmiura59ea9b4042014-12-09 20:50:39628 layer_tree_host_impl_->PrepareTiles();
enne69277cb2014-10-29 23:03:40629 layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
630 }
631
mithro719bf6792014-11-10 15:36:47632 DoAnimate();
633
enne98f3a6c2014-10-09 20:09:44634 LayerTreeHostImpl::FrameData frame;
635 DoComposite(frame_begin_time, &frame);
636
637 // DoComposite could abort, but because this is a synchronous composite
638 // another draw will never be scheduled, so break remaining promises.
639 layer_tree_host_impl_->active_tree()->BreakSwapPromises(
640 SwapPromise::SWAP_FAILS);
mithroc76d70312015-05-04 23:51:13641
642 DidBeginImplFrameDeadline();
enne98f3a6c2014-10-09 20:09:44643 }
[email protected]74d9063c2013-01-18 03:14:47644}
645
[email protected]a8a049c2013-03-11 23:27:06646void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
647 {
648 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20649 if (layer_tree_host_impl_->renderer()) {
650 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06651 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20652 }
[email protected]a8a049c2013-03-11 23:27:06653 }
[email protected]8947cbe2012-11-28 05:27:43654}
655
[email protected]5d8bec72014-07-03 03:03:11656bool SingleThreadProxy::SupportsImplScrolling() const {
657 return false;
658}
659
[email protected]3d9f7432013-04-06 00:35:18660bool SingleThreadProxy::ShouldComposite() const {
661 DCHECK(Proxy::IsImplThread());
662 return layer_tree_host_impl_->visible() &&
663 layer_tree_host_impl_->CanDraw();
664}
665
jbauman8ab0f9e2014-10-15 02:30:34666void SingleThreadProxy::ScheduleRequestNewOutputSurface() {
667 if (output_surface_creation_callback_.IsCancelled() &&
668 !output_surface_creation_requested_) {
669 output_surface_creation_callback_.Reset(
670 base::Bind(&SingleThreadProxy::RequestNewOutputSurface,
671 weak_factory_.GetWeakPtr()));
672 MainThreadTaskRunner()->PostTask(
673 FROM_HERE, output_surface_creation_callback_.callback());
674 }
675}
676
[email protected]aeeedad2014-08-22 18:16:22677DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time,
678 LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20679 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20680 DCHECK(!layer_tree_host_->output_surface_lost());
681
enne98f3a6c2014-10-09 20:09:44682 DrawResult draw_result;
683 bool draw_frame;
[email protected]a8a049c2013-03-11 23:27:06684 {
685 DebugScopedSetImplThread impl(this);
686 base::AutoReset<bool> mark_inside(&inside_draw_, true);
687
robliao27728e62015-03-21 07:39:34688 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
689 // is fixed.
690 tracked_objects::ScopedTracker tracking_profile1(
691 FROM_HERE_WITH_EXPLICIT_FUNCTION(
692 "461509 SingleThreadProxy::DoComposite1"));
693
[email protected]3d9f7432013-04-06 00:35:18694 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
695 // frame, so can only be used when such a frame is possible. Since
696 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
697 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50698 if (!ShouldComposite()) {
[email protected]aeeedad2014-08-22 18:16:22699 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18700 }
[email protected]a8a049c2013-03-11 23:27:06701
[email protected]aeeedad2014-08-22 18:16:22702 timing_history_.DidStartDrawing();
703
robliao27728e62015-03-21 07:39:34704 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
705 // is fixed.
706 tracked_objects::ScopedTracker tracking_profile2(
707 FROM_HERE_WITH_EXPLICIT_FUNCTION(
708 "461509 SingleThreadProxy::DoComposite2"));
enne98f3a6c2014-10-09 20:09:44709 draw_result = layer_tree_host_impl_->PrepareToDraw(frame);
710 draw_frame = draw_result == DRAW_SUCCESS;
robliao27728e62015-03-21 07:39:34711 if (draw_frame) {
712 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
713 // is fixed.
714 tracked_objects::ScopedTracker tracking_profile3(
715 FROM_HERE_WITH_EXPLICIT_FUNCTION(
716 "461509 SingleThreadProxy::DoComposite3"));
enne98f3a6c2014-10-09 20:09:44717 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
robliao27728e62015-03-21 07:39:34718 }
719 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
720 // is fixed.
721 tracked_objects::ScopedTracker tracking_profile4(
722 FROM_HERE_WITH_EXPLICIT_FUNCTION(
723 "461509 SingleThreadProxy::DoComposite4"));
dnetob71e30c2014-08-25 23:27:20724 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06725
enne98f3a6c2014-10-09 20:09:44726 bool start_ready_animations = draw_frame;
robliao27728e62015-03-21 07:39:34727 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
728 // is fixed.
729 tracked_objects::ScopedTracker tracking_profile5(
730 FROM_HERE_WITH_EXPLICIT_FUNCTION(
731 "461509 SingleThreadProxy::DoComposite5"));
[email protected]3d9f7432013-04-06 00:35:18732 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
[email protected]aeeedad2014-08-22 18:16:22733
robliao27728e62015-03-21 07:39:34734 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
735 // is fixed.
736 tracked_objects::ScopedTracker tracking_profile7(
737 FROM_HERE_WITH_EXPLICIT_FUNCTION(
738 "461509 SingleThreadProxy::DoComposite7"));
[email protected]aeeedad2014-08-22 18:16:22739 timing_history_.DidFinishDrawing();
[email protected]a8a049c2013-03-11 23:27:06740 }
741
enne98f3a6c2014-10-09 20:09:44742 if (draw_frame) {
[email protected]aeeedad2014-08-22 18:16:22743 DebugScopedSetImplThread impl(this);
[email protected]174c6d42014-08-12 01:43:06744
dnetob71e30c2014-08-25 23:27:20745 // This CapturePostTasks should be destroyed before
746 // DidCommitAndDrawFrame() is called since that goes out to the
747 // embedder,
748 // and we want the embedder to receive its callbacks before that.
749 // NOTE: This maintains consistent ordering with the ThreadProxy since
750 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
751 // there as the main thread is not blocked, so any posted tasks inside
752 // the swap buffers will execute first.
753 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]aeeedad2014-08-22 18:16:22754
skyostil3976a3f2014-09-04 22:07:23755 BlockingTaskRunner::CapturePostTasks blocked(
756 blocking_main_thread_task_runner());
robliao27728e62015-03-21 07:39:34757 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
758 // is fixed.
759 tracked_objects::ScopedTracker tracking_profile8(
760 FROM_HERE_WITH_EXPLICIT_FUNCTION(
761 "461509 SingleThreadProxy::DoComposite8"));
dnetob71e30c2014-08-25 23:27:20762 layer_tree_host_impl_->SwapBuffers(*frame);
[email protected]aeeedad2014-08-22 18:16:22763 }
robliao27728e62015-03-21 07:39:34764 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
765 // fixed.
766 tracked_objects::ScopedTracker tracking_profile9(
767 FROM_HERE_WITH_EXPLICIT_FUNCTION(
768 "461509 SingleThreadProxy::DoComposite9"));
[email protected]aeeedad2014-08-22 18:16:22769 DidCommitAndDrawFrame();
770
enne98f3a6c2014-10-09 20:09:44771 return draw_result;
[email protected]a8a049c2013-03-11 23:27:06772}
773
[email protected]aeeedad2014-08-22 18:16:22774void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06775 if (next_frame_is_newly_committed_frame_) {
[email protected]aeeedad2014-08-22 18:16:22776 DebugScopedSetMainThread main(this);
[email protected]a8a049c2013-03-11 23:27:06777 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21778 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06779 }
780}
781
[email protected]4ea293f72014-08-13 03:03:17782bool SingleThreadProxy::MainFrameWillHappenForTesting() {
danakjfcdaba122015-04-24 21:41:52783 if (layer_tree_host_->output_surface_lost())
784 return false;
785 if (!scheduler_on_impl_thread_)
786 return false;
787 return scheduler_on_impl_thread_->MainFrameForTestingWillHappen();
[email protected]4ea293f72014-08-13 03:03:17788}
[email protected]a8a049c2013-03-11 23:27:06789
simonhongd3d5f7f2014-11-21 16:38:03790void SingleThreadProxy::SetChildrenNeedBeginFrames(
791 bool children_need_begin_frames) {
792 scheduler_on_impl_thread_->SetChildrenNeedBeginFrames(
793 children_need_begin_frames);
794}
795
simonhong298590fe2015-03-25 06:51:13796void SingleThreadProxy::SetAuthoritativeVSyncInterval(
797 const base::TimeDelta& interval) {
798 scheduler_on_impl_thread_->SetAuthoritativeVSyncInterval(interval);
799}
800
[email protected]aeeedad2014-08-22 18:16:22801void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
mithro69fd3bb52015-05-01 03:45:02802 DCHECK(!inside_impl_frame_)
803 << "WillBeginImplFrame called while already inside an impl frame!";
804 inside_impl_frame_ = true;
[email protected]aeeedad2014-08-22 18:16:22805 layer_tree_host_impl_->WillBeginImplFrame(args);
806}
807
808void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
809 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
810 // Although this proxy is single-threaded, it's problematic to synchronously
811 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
812 // could cause a commit to occur in between a series of SetNeedsCommit calls
813 // (i.e. property modifications) causing some to fall on one frame and some to
814 // fall on the next. Doing it asynchronously instead matches the semantics of
815 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
816 // synchronous commit.
mithro69fd3bb52015-05-01 03:45:02817 DCHECK(inside_impl_frame_)
818 << "BeginMainFrame should only be sent inside a BeginImplFrame";
819 const BeginFrameArgs& begin_frame_args =
820 layer_tree_host_impl_->CurrentBeginFrameArgs();
821
[email protected]aeeedad2014-08-22 18:16:22822 MainThreadTaskRunner()->PostTask(
mithro69fd3bb52015-05-01 03:45:02823 FROM_HERE, base::Bind(&SingleThreadProxy::BeginMainFrame,
824 weak_factory_.GetWeakPtr(), begin_frame_args));
[email protected]aeeedad2014-08-22 18:16:22825}
826
rmcilroy0a19362a2015-02-18 12:34:25827void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
828 layer_tree_host_->BeginMainFrameNotExpectedSoon();
829}
830
mithro69fd3bb52015-05-01 03:45:02831void SingleThreadProxy::BeginMainFrame(const BeginFrameArgs& begin_frame_args) {
danakjfcdaba122015-04-24 21:41:52832 commit_requested_ = false;
brianderson49e101d22015-04-29 00:05:33833 animate_requested_ = false;
danakjfcdaba122015-04-24 21:41:52834
[email protected]aeeedad2014-08-22 18:16:22835 if (defer_commits_) {
simonhongc6309f792015-01-31 15:47:15836 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
837 TRACE_EVENT_SCOPE_THREAD);
838 BeginMainFrameAbortedOnImplThread(
839 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
[email protected]aeeedad2014-08-22 18:16:22840 return;
841 }
842
enne98f3a6c2014-10-09 20:09:44843 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
844 // commit.
[email protected]aeeedad2014-08-22 18:16:22845 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
846
847 if (!layer_tree_host_->visible()) {
848 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48849 BeginMainFrameAbortedOnImplThread(
850 CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
[email protected]aeeedad2014-08-22 18:16:22851 return;
852 }
853
854 if (layer_tree_host_->output_surface_lost()) {
855 TRACE_EVENT_INSTANT0(
856 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
mithrof7a21502014-12-17 03:24:48857 BeginMainFrameAbortedOnImplThread(
858 CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST);
[email protected]aeeedad2014-08-22 18:16:22859 return;
860 }
861
danakjfcdaba122015-04-24 21:41:52862 // Prevent new commits from being requested inside DoBeginMainFrame.
brianderson49e101d22015-04-29 00:05:33863 // Note: We do not want to prevent SetNeedsAnimate from requesting
864 // a commit here.
danakjfcdaba122015-04-24 21:41:52865 commit_requested_ = true;
866
enne98f3a6c2014-10-09 20:09:44867 DoBeginMainFrame(begin_frame_args);
868}
869
870void SingleThreadProxy::DoBeginMainFrame(
871 const BeginFrameArgs& begin_frame_args) {
872 layer_tree_host_->WillBeginMainFrame();
873 layer_tree_host_->BeginMainFrame(begin_frame_args);
874 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
875 layer_tree_host_->Layout();
876
877 if (PrioritizedResourceManager* contents_texture_manager =
878 layer_tree_host_->contents_texture_manager()) {
879 contents_texture_manager->UnlinkAndClearEvictedBackings();
880 contents_texture_manager->SetMaxMemoryLimitBytes(
881 layer_tree_host_impl_->memory_allocation_limit_bytes());
882 contents_texture_manager->SetExternalPriorityCutoff(
883 layer_tree_host_impl_->memory_allocation_priority_cutoff());
884 }
885
886 DCHECK(!queue_for_commit_);
887 queue_for_commit_ = make_scoped_ptr(new ResourceUpdateQueue);
888
danakjfcdaba122015-04-24 21:41:52889 // New commits requested inside UpdateLayers should be respected.
890 commit_requested_ = false;
891
enne98f3a6c2014-10-09 20:09:44892 layer_tree_host_->UpdateLayers(queue_for_commit_.get());
893
[email protected]aeeedad2014-08-22 18:16:22894 timing_history_.DidBeginMainFrame();
895
mithrof7a21502014-12-17 03:24:48896 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
897 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
898 // thread_proxy.cc
enne98f3a6c2014-10-09 20:09:44899 if (scheduler_on_impl_thread_) {
900 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
901 scheduler_on_impl_thread_->NotifyReadyToCommit();
902 }
[email protected]aeeedad2014-08-22 18:16:22903}
904
mithrof7a21502014-12-17 03:24:48905void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
906 CommitEarlyOutReason reason) {
[email protected]aeeedad2014-08-22 18:16:22907 DebugScopedSetImplThread impl(this);
908 DCHECK(scheduler_on_impl_thread_->CommitPending());
909 DCHECK(!layer_tree_host_impl_->pending_tree());
910
mithrof7a21502014-12-17 03:24:48911 layer_tree_host_impl_->BeginMainFrameAborted(reason);
912 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
[email protected]aeeedad2014-08-22 18:16:22913}
914
915DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
916 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22917 LayerTreeHostImpl::FrameData frame;
918 return DoComposite(layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time,
919 &frame);
920}
921
922DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
923 NOTREACHED();
924 return INVALID_RESULT;
925}
926
927void SingleThreadProxy::ScheduledActionCommit() {
928 DebugScopedSetMainThread main(this);
enne98f3a6c2014-10-09 20:09:44929 DoCommit();
[email protected]aeeedad2014-08-22 18:16:22930}
931
932void SingleThreadProxy::ScheduledActionAnimate() {
933 TRACE_EVENT0("cc", "ScheduledActionAnimate");
mithro719bf6792014-11-10 15:36:47934 DebugScopedSetImplThread impl(this);
935 DoAnimate();
[email protected]aeeedad2014-08-22 18:16:22936}
937
[email protected]aeeedad2014-08-22 18:16:22938void SingleThreadProxy::ScheduledActionActivateSyncTree() {
enne98f3a6c2014-10-09 20:09:44939 DebugScopedSetImplThread impl(this);
940 layer_tree_host_impl_->ActivateSyncTree();
[email protected]aeeedad2014-08-22 18:16:22941}
942
943void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
944 DebugScopedSetMainThread main(this);
945 DCHECK(scheduler_on_impl_thread_);
946 // If possible, create the output surface in a post task. Synchronously
947 // creating the output surface makes tests more awkward since this differs
948 // from the ThreadProxy behavior. However, sometimes there is no
949 // task runner.
950 if (Proxy::MainThreadTaskRunner()) {
jbauman8ab0f9e2014-10-15 02:30:34951 ScheduleRequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22952 } else {
enne2097cab2014-09-25 20:16:31953 RequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22954 }
955}
956
vmiura59ea9b4042014-12-09 20:50:39957void SingleThreadProxy::ScheduledActionPrepareTiles() {
958 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
enne98f3a6c2014-10-09 20:09:44959 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
960 DebugScopedSetImplThread impl(this);
vmiura59ea9b4042014-12-09 20:50:39961 layer_tree_host_impl_->PrepareTiles();
[email protected]aeeedad2014-08-22 18:16:22962}
963
sunnypseab5ac92015-04-02 20:26:13964void SingleThreadProxy::ScheduledActionInvalidateOutputSurface() {
965 NOTREACHED();
966}
967
[email protected]aeeedad2014-08-22 18:16:22968void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
969}
970
971base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
972 return timing_history_.DrawDurationEstimate();
973}
974
975base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
976 return timing_history_.BeginMainFrameToCommitDurationEstimate();
977}
978
979base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
980 return timing_history_.CommitToActivateDurationEstimate();
981}
982
983void SingleThreadProxy::DidBeginImplFrameDeadline() {
984 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
mithro69fd3bb52015-05-01 03:45:02985 DCHECK(inside_impl_frame_)
986 << "DidBeginImplFrameDeadline called while not inside an impl frame!";
987 inside_impl_frame_ = false;
[email protected]aeeedad2014-08-22 18:16:22988}
989
simonhongd3d5f7f2014-11-21 16:38:03990void SingleThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) {
991 layer_tree_host_->SendBeginFramesToChildren(args);
992}
993
[email protected]bc5e77c2012-11-05 20:00:49994} // namespace cc