blob: 1ccbdb9dc628dadd307d48c19628373a53b7c623 [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"
[email protected]6331a1172012-10-18 11:35:138#include "base/debug/trace_event.h"
[email protected]adbe30f2013-10-11 21:12:339#include "cc/debug/benchmark_instrumentation.h"
[email protected]7f0d825f2013-03-18 07:24:3010#include "cc/output/context_provider.h"
11#include "cc/output/output_surface.h"
[email protected]89e82672013-03-18 07:50:5612#include "cc/quads/draw_quad.h"
[email protected]e12dd0e2013-03-18 08:24:4013#include "cc/resources/prioritized_resource_manager.h"
14#include "cc/resources/resource_update_controller.h"
[email protected]9794fb32013-08-29 09:49:5915#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0416#include "cc/trees/layer_tree_host.h"
[email protected]943528e2013-11-07 05:01:3217#include "cc/trees/layer_tree_host_single_thread_client.h"
[email protected]556fd292013-03-18 08:03:0418#include "cc/trees/layer_tree_impl.h"
[email protected]aeeedad2014-08-22 18:16:2219#include "cc/trees/scoped_abort_remaining_swap_promises.h"
[email protected]de2cf8c2013-10-25 19:46:4620#include "ui/gfx/frame_time.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,
27 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
[email protected]a8a049c2013-03-11 23:27:0628 return make_scoped_ptr(
[email protected]27e6a212014-07-18 15:51:2729 new SingleThreadProxy(layer_tree_host, client, main_task_runner))
30 .PassAs<Proxy>();
[email protected]94f206c12012-08-25 00:09:1431}
32
[email protected]27e6a212014-07-18 15:51:2733SingleThreadProxy::SingleThreadProxy(
34 LayerTreeHost* layer_tree_host,
35 LayerTreeHostSingleThreadClient* client,
36 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
37 : Proxy(main_task_runner, NULL),
[email protected]a8a049c2013-03-11 23:27:0638 layer_tree_host_(layer_tree_host),
[email protected]943528e2013-11-07 05:01:3239 client_(client),
[email protected]aeeedad2014-08-22 18:16:2240 timing_history_(layer_tree_host->rendering_stats_instrumentation()),
[email protected]a8a049c2013-03-11 23:27:0641 next_frame_is_newly_committed_frame_(false),
[email protected]aeeedad2014-08-22 18:16:2242 inside_draw_(false),
43 defer_commits_(false),
44 commit_was_deferred_(false),
45 commit_requested_(false),
46 weak_factory_(this) {
[email protected]a8a049c2013-03-11 23:27:0647 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
48 DCHECK(Proxy::IsMainThread());
49 DCHECK(layer_tree_host);
[email protected]1e4c352b2013-01-10 02:05:2350
[email protected]089102b2013-03-14 03:54:5651 // Impl-side painting not supported without threaded compositing.
[email protected]d9c086a2013-04-17 16:12:4852 CHECK(!layer_tree_host->settings().impl_side_painting)
53 << "Threaded compositing must be enabled to use impl-side painting.";
[email protected]94f206c12012-08-25 00:09:1454}
55
[email protected]e96e3432013-12-19 18:56:0756void SingleThreadProxy::Start() {
[email protected]a8a049c2013-03-11 23:27:0657 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:2158 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]a8a049c2013-03-11 23:27:0659}
60
61SingleThreadProxy::~SingleThreadProxy() {
62 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
63 DCHECK(Proxy::IsMainThread());
[email protected]04049fc2013-05-01 03:13:2064 // Make sure Stop() got called or never Started.
65 DCHECK(!layer_tree_host_impl_);
[email protected]a8a049c2013-03-11 23:27:0666}
67
[email protected]a8a049c2013-03-11 23:27:0668void SingleThreadProxy::FinishAllRendering() {
[email protected]ccc08dc2014-01-30 07:33:2069 TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering");
[email protected]a8a049c2013-03-11 23:27:0670 DCHECK(Proxy::IsMainThread());
71 {
[email protected]61de5812012-11-08 07:03:4472 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2773 layer_tree_host_impl_->FinishAllRendering();
[email protected]a8a049c2013-03-11 23:27:0674 }
[email protected]94f206c12012-08-25 00:09:1475}
76
[email protected]a8a049c2013-03-11 23:27:0677bool SingleThreadProxy::IsStarted() const {
78 DCHECK(Proxy::IsMainThread());
[email protected]3209161d2013-03-29 19:17:3479 return layer_tree_host_impl_;
[email protected]94f206c12012-08-25 00:09:1480}
81
[email protected]14bd5542013-05-08 21:51:3082void SingleThreadProxy::SetLayerTreeHostClientReady() {
[email protected]ccc08dc2014-01-30 07:33:2083 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
[email protected]a8a049c2013-03-11 23:27:0684 // Scheduling is controlled by the embedder in the single thread case, so
85 // nothing to do.
[email protected]aeeedad2014-08-22 18:16:2286 DCHECK(Proxy::IsMainThread());
87 DebugScopedSetImplThread impl(this);
88 if (layer_tree_host_->settings().single_thread_proxy_scheduler &&
89 !scheduler_on_impl_thread_) {
90 SchedulerSettings scheduler_settings(layer_tree_host_->settings());
91 scheduler_on_impl_thread_ = Scheduler::Create(this,
92 scheduler_settings,
93 layer_tree_host_->id(),
94 MainThreadTaskRunner());
95 scheduler_on_impl_thread_->SetCanStart();
96 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
97 }
[email protected]a8a049c2013-03-11 23:27:0698}
99
100void SingleThreadProxy::SetVisible(bool visible) {
[email protected]ccc08dc2014-01-30 07:33:20101 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible");
[email protected]f7c01c82013-07-02 22:58:46102 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:27103 layer_tree_host_impl_->SetVisible(visible);
[email protected]aeeedad2014-08-22 18:16:22104 if (scheduler_on_impl_thread_)
105 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
[email protected]8ea875b2013-08-07 00:32:12106 // Changing visibility could change ShouldComposite().
[email protected]d9fce6722013-08-30 01:10:01107 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06108}
109
[email protected]04049fc2013-05-01 03:13:20110void SingleThreadProxy::CreateAndInitializeOutputSurface() {
111 TRACE_EVENT0(
112 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
[email protected]a8a049c2013-03-11 23:27:06113 DCHECK(Proxy::IsMainThread());
[email protected]497edf82014-05-20 21:53:15114 DCHECK(layer_tree_host_->output_surface_lost());
[email protected]94f206c12012-08-25 00:09:14115
[email protected]e96e3432013-12-19 18:56:07116 scoped_ptr<OutputSurface> output_surface =
117 layer_tree_host_->CreateOutputSurface();
[email protected]04049fc2013-05-01 03:13:20118
[email protected]da8e3b72b2014-04-25 02:33:45119 renderer_capabilities_for_main_thread_ = RendererCapabilities();
120
121 bool success = !!output_surface;
122 if (success) {
[email protected]819b9f52013-09-22 23:29:51123 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06124 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:21125 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27126 layer_tree_host_impl_->resource_provider());
[email protected]da8e3b72b2014-04-25 02:33:45127 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
[email protected]04049fc2013-05-01 03:13:20128 }
129
[email protected]da8e3b72b2014-04-25 02:33:45130 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
[email protected]04049fc2013-05-01 03:13:20131
[email protected]aeeedad2014-08-22 18:16:22132 if (success) {
133 if (scheduler_on_impl_thread_)
134 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
135 } else if (Proxy::MainThreadTaskRunner()) {
136 MainThreadTaskRunner()->PostTask(
137 FROM_HERE,
138 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface,
139 weak_factory_.GetWeakPtr()));
[email protected]04049fc2013-05-01 03:13:20140 }
[email protected]94f206c12012-08-25 00:09:14141}
142
[email protected]a8a049c2013-03-11 23:27:06143const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20144 DCHECK(Proxy::IsMainThread());
145 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06146 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14147}
148
[email protected]8b9e52b2014-01-17 16:35:31149void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20150 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
[email protected]c5134172013-12-11 06:19:48151 DCHECK(Proxy::IsMainThread());
[email protected]06cbc31b2014-01-17 06:43:20152 client_->ScheduleAnimation();
[email protected]aeeedad2014-08-22 18:16:22153 SetNeedsCommit();
[email protected]c5134172013-12-11 06:19:48154}
155
[email protected]8b9e52b2014-01-17 16:35:31156void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20157 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
[email protected]8b9e52b2014-01-17 16:35:31158 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22159 SetNeedsCommit();
[email protected]8b9e52b2014-01-17 16:35:31160}
161
[email protected]aeeedad2014-08-22 18:16:22162void SingleThreadProxy::DoCommit(const BeginFrameArgs& begin_frame_args) {
[email protected]ccc08dc2014-01-30 07:33:20163 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
[email protected]a8a049c2013-03-11 23:27:06164 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22165 layer_tree_host_->WillBeginMainFrame();
166 layer_tree_host_->BeginMainFrame(begin_frame_args);
167 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
168 layer_tree_host_->Layout();
169 commit_requested_ = false;
170
171 if (PrioritizedResourceManager* contents_texture_manager =
172 layer_tree_host_->contents_texture_manager()) {
173 contents_texture_manager->UnlinkAndClearEvictedBackings();
174 contents_texture_manager->SetMaxMemoryLimitBytes(
175 layer_tree_host_impl_->memory_allocation_limit_bytes());
176 contents_texture_manager->SetExternalPriorityCutoff(
177 layer_tree_host_impl_->memory_allocation_priority_cutoff());
178 }
179
180 scoped_ptr<ResourceUpdateQueue> queue =
181 make_scoped_ptr(new ResourceUpdateQueue);
182
183 layer_tree_host_->UpdateLayers(queue.get());
184
185 layer_tree_host_->WillCommit();
186
[email protected]a8a049c2013-03-11 23:27:06187 // Commit immediately.
188 {
[email protected]819b9f52013-09-22 23:29:51189 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46190 DebugScopedSetImplThread impl(this);
191
[email protected]9794fb32013-08-29 09:49:59192 // This CapturePostTasks should be destroyed before CommitComplete() is
193 // called since that goes out to the embedder, and we want the embedder
194 // to receive its callbacks before that.
195 BlockingTaskRunner::CapturePostTasks blocked;
196
[email protected]c1bb5af2013-03-13 19:06:27197 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14198
[email protected]5d2fec02013-11-28 20:08:33199 if (PrioritizedResourceManager* contents_texture_manager =
200 layer_tree_host_->contents_texture_manager()) {
201 contents_texture_manager->PushTexturePrioritiesToBackings();
[email protected]6e8c54922013-06-02 19:17:35202 }
[email protected]804c8982013-03-13 16:32:21203 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14204
[email protected]ed511b8d2013-03-25 03:29:29205 scoped_ptr<ResourceUpdateController> update_controller =
[email protected]a8a049c2013-03-11 23:27:06206 ResourceUpdateController::Create(
207 NULL,
[email protected]aeeedad2014-08-22 18:16:22208 MainThreadTaskRunner(),
[email protected]a8a049c2013-03-11 23:27:06209 queue.Pass(),
[email protected]c1bb5af2013-03-13 19:06:27210 layer_tree_host_impl_->resource_provider());
[email protected]ed511b8d2013-03-25 03:29:29211 update_controller->Finalize();
[email protected]94f206c12012-08-25 00:09:14212
[email protected]127bdc1a2013-09-11 01:44:48213 if (layer_tree_host_impl_->EvictedUIResourcesExist())
214 layer_tree_host_->RecreateUIResources();
215
[email protected]804c8982013-03-13 16:32:21216 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14217
[email protected]c1bb5af2013-03-13 19:06:27218 layer_tree_host_impl_->CommitComplete();
[email protected]94f206c12012-08-25 00:09:14219
[email protected]aeeedad2014-08-22 18:16:22220 UpdateBackgroundAnimateTicking();
221
[email protected]767f38d72014-03-18 21:26:41222#if DCHECK_IS_ON
[email protected]3519b872013-07-30 07:17:50223 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06224 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29225 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27226 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29227 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50228 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14229#endif
[email protected]8b9af6b2012-09-27 00:36:36230
[email protected]922c6e1f2013-10-09 04:04:09231 RenderingStatsInstrumentation* stats_instrumentation =
232 layer_tree_host_->rendering_stats_instrumentation();
[email protected]1bbed7a2014-07-08 02:54:00233 benchmark_instrumentation::IssueMainThreadRenderingStatsEvent(
[email protected]adbe30f2013-10-11 21:12:33234 stats_instrumentation->main_thread_rendering_stats());
[email protected]a9dc0d0f2013-08-17 02:43:18235 stats_instrumentation->AccumulateAndClearMainThreadStats();
[email protected]a8a049c2013-03-11 23:27:06236 }
[email protected]804c8982013-03-13 16:32:21237 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22238 layer_tree_host_->DidBeginMainFrame();
239 timing_history_.DidCommit();
240
[email protected]a8a049c2013-03-11 23:27:06241 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14242}
243
[email protected]a8a049c2013-03-11 23:27:06244void SingleThreadProxy::SetNeedsCommit() {
245 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22246 DebugScopedSetImplThread impl(this);
[email protected]943528e2013-11-07 05:01:32247 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22248 if (scheduler_on_impl_thread_)
249 scheduler_on_impl_thread_->SetNeedsCommit();
250 commit_requested_ = true;
[email protected]94f206c12012-08-25 00:09:14251}
252
[email protected]0023fc72014-01-10 20:05:06253void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20254 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
[email protected]aeeedad2014-08-22 18:16:22255 DCHECK(Proxy::IsMainThread());
256 DebugScopedSetImplThread impl(this);
[email protected]2decdd782014-08-13 22:36:06257 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22258 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14259}
260
[email protected]74b43cc2013-08-30 06:29:27261void SingleThreadProxy::SetNextCommitWaitsForActivation() {
262 // There is no activation here other than commit. So do nothing.
[email protected]aeeedad2014-08-22 18:16:22263 DCHECK(Proxy::IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27264}
265
[email protected]a8a049c2013-03-11 23:27:06266void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
[email protected]aeeedad2014-08-22 18:16:22267 DCHECK(Proxy::IsMainThread());
268 // Deferring commits only makes sense if there's a scheduler.
269 if (!scheduler_on_impl_thread_)
270 return;
271 if (defer_commits_ == defer_commits)
272 return;
273
274 if (defer_commits)
275 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
276 else
277 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
278
279 defer_commits_ = defer_commits;
280 if (!defer_commits_ && commit_was_deferred_) {
281 commit_was_deferred_ = false;
282 BeginMainFrame();
283 }
[email protected]6b16679e2012-10-27 00:44:28284}
285
[email protected]174c6d42014-08-12 01:43:06286bool SingleThreadProxy::CommitRequested() const {
[email protected]aeeedad2014-08-22 18:16:22287 DCHECK(Proxy::IsMainThread());
288 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06289}
[email protected]a8a049c2013-03-11 23:27:06290
[email protected]174c6d42014-08-12 01:43:06291bool SingleThreadProxy::BeginMainFrameRequested() const {
[email protected]aeeedad2014-08-22 18:16:22292 DCHECK(Proxy::IsMainThread());
293 // If there is no scheduler, then there can be no pending begin frame,
294 // as all frames are all manually initiated by the embedder of cc.
295 if (!scheduler_on_impl_thread_)
296 return false;
297 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06298}
[email protected]971728d2013-10-26 10:39:31299
[email protected]a8a049c2013-03-11 23:27:06300size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
301 return std::numeric_limits<size_t>::max();
302}
303
304void SingleThreadProxy::Stop() {
305 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
306 DCHECK(Proxy::IsMainThread());
307 {
[email protected]819b9f52013-09-22 23:29:51308 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06309 DebugScopedSetImplThread impl(this);
310
[email protected]446b23d2014-05-16 18:24:18311 BlockingTaskRunner::CapturePostTasks blocked;
[email protected]804c8982013-03-13 16:32:21312 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27313 layer_tree_host_impl_->resource_provider());
[email protected]aeeedad2014-08-22 18:16:22314 scheduler_on_impl_thread_.reset();
[email protected]a8a049c2013-03-11 23:27:06315 layer_tree_host_impl_.reset();
316 }
[email protected]7aba6662013-03-12 10:17:34317 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06318}
319
[email protected]3d9f7432013-04-06 00:35:18320void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
[email protected]ccc08dc2014-01-30 07:33:20321 TRACE_EVENT1(
322 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
[email protected]3d9f7432013-04-06 00:35:18323 DCHECK(Proxy::IsImplThread());
[email protected]d9fce6722013-08-30 01:10:01324 UpdateBackgroundAnimateTicking();
[email protected]aeeedad2014-08-22 18:16:22325 if (scheduler_on_impl_thread_)
326 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18327}
328
[email protected]4f48f6e2013-08-27 06:33:38329void SingleThreadProxy::NotifyReadyToActivate() {
[email protected]aeeedad2014-08-22 18:16:22330 // Impl-side painting only.
[email protected]4f48f6e2013-08-27 06:33:38331 NOTREACHED();
332}
333
[email protected]c1bb5af2013-03-13 19:06:27334void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]943528e2013-11-07 05:01:32335 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22336 if (scheduler_on_impl_thread_)
337 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06338}
339
[email protected]43b8f982014-04-30 21:24:33340void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
341 SetNeedsRedrawOnImplThread();
342}
343
[email protected]c48536a52013-09-14 00:02:08344void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
[email protected]aeeedad2014-08-22 18:16:22345 // Impl-side painting only.
[email protected]c48536a52013-09-14 00:02:08346 NOTREACHED();
347}
348
[email protected]0023fc72014-01-10 20:05:06349void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
350 const gfx::Rect& damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03351 layer_tree_host_impl_->SetViewportDamage(damage_rect);
[email protected]aeeedad2014-08-22 18:16:22352 SetNeedsRedrawOnImplThread();
[email protected]1cd9f5552013-04-26 04:22:03353}
354
[email protected]86126792013-03-16 20:07:54355void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06356 // Impl-side painting only.
357 NOTREACHED();
358}
359
[email protected]c1bb5af2013-03-13 19:06:27360void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]943528e2013-11-07 05:01:32361 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22362 if (scheduler_on_impl_thread_)
363 scheduler_on_impl_thread_->SetNeedsCommit();
[email protected]a8a049c2013-03-11 23:27:06364}
365
[email protected]c1bb5af2013-03-13 19:06:27366void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]85b57502014-03-11 15:37:48367 scoped_ptr<AnimationEventsVector> events) {
[email protected]ccc08dc2014-01-30 07:33:20368 TRACE_EVENT0(
369 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
[email protected]a8a049c2013-03-11 23:27:06370 DCHECK(Proxy::IsImplThread());
371 DebugScopedSetMainThread main(this);
[email protected]85b57502014-03-11 15:37:48372 layer_tree_host_->SetAnimationEvents(events.Pass());
[email protected]a8a049c2013-03-11 23:27:06373}
374
[email protected]c1bb5af2013-03-13 19:06:27375bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06376 size_t limit_bytes,
377 int priority_cutoff) {
378 DCHECK(IsImplThread());
[email protected]5d2fec02013-11-28 20:08:33379 PrioritizedResourceManager* contents_texture_manager =
380 layer_tree_host_->contents_texture_manager();
381
382 ResourceProvider* resource_provider =
383 layer_tree_host_impl_->resource_provider();
384
385 if (!contents_texture_manager || !resource_provider)
[email protected]e7595ead2013-10-10 10:10:07386 return false;
[email protected]a8a049c2013-03-11 23:27:06387
[email protected]5d2fec02013-11-28 20:08:33388 return contents_texture_manager->ReduceMemoryOnImplThread(
389 limit_bytes, priority_cutoff, resource_provider);
[email protected]94f206c12012-08-25 00:09:14390}
391
[email protected]c1bb5af2013-03-13 19:06:27392bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06393
[email protected]fa339032014-02-18 22:11:59394void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
395 DCHECK(IsImplThread());
396 renderer_capabilities_for_main_thread_ =
397 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
398}
399
[email protected]aeeedad2014-08-22 18:16:22400void SingleThreadProxy::DidManageTiles() {
401 // Impl-side painting only.
402 NOTREACHED();
403}
404
[email protected]c1bb5af2013-03-13 19:06:27405void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20406 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22407 {
408 DebugScopedSetMainThread main(this);
409 // This must happen before we notify the scheduler as it may try to recreate
410 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
411 layer_tree_host_->DidLoseOutputSurface();
412 }
[email protected]4d7e46a2013-11-08 05:33:40413 client_->DidAbortSwapBuffers();
[email protected]aeeedad2014-08-22 18:16:22414 if (scheduler_on_impl_thread_)
415 scheduler_on_impl_thread_->DidLoseOutputSurface();
[email protected]4d7e46a2013-11-08 05:33:40416}
417
418void SingleThreadProxy::DidSwapBuffersOnImplThread() {
[email protected]aeeedad2014-08-22 18:16:22419 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
420 if (scheduler_on_impl_thread_)
421 scheduler_on_impl_thread_->DidSwapBuffers();
[email protected]4d7e46a2013-11-08 05:33:40422 client_->DidPostSwapBuffers();
423}
424
[email protected]c14902662014-04-18 05:06:11425void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
426 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22427 if (scheduler_on_impl_thread_)
428 scheduler_on_impl_thread_->DidSwapBuffersComplete();
429 layer_tree_host_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10430}
431
[email protected]aeeedad2014-08-22 18:16:22432void SingleThreadProxy::BeginFrame(const BeginFrameArgs& args) {
433 TRACE_EVENT0("cc", "SingleThreadProxy::BeginFrame");
434 if (scheduler_on_impl_thread_)
simonhong96b59672014-09-04 04:50:03435 scheduler_on_impl_thread_->BeginFrame(args);
[email protected]aeeedad2014-08-22 18:16:22436}
437
[email protected]f0c2a242013-03-15 19:34:52438void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
[email protected]ccc08dc2014-01-30 07:33:20439 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately");
[email protected]51f81da2014-05-16 21:29:26440 DCHECK(Proxy::IsMainThread());
[email protected]497edf82014-05-20 21:53:15441 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]51f81da2014-05-16 21:29:26442
[email protected]aeeedad2014-08-22 18:16:22443 BeginFrameArgs begin_frame_args = BeginFrameArgs::Create(
444 frame_begin_time, base::TimeTicks(), BeginFrameArgs::DefaultInterval());
445 DoCommit(begin_frame_args);
[email protected]e0341352013-04-06 05:01:20446
447 LayerTreeHostImpl::FrameData frame;
[email protected]aeeedad2014-08-22 18:16:22448 DoComposite(frame_begin_time, &frame);
[email protected]74d9063c2013-01-18 03:14:47449}
450
[email protected]d12aa932014-08-01 13:10:38451void SingleThreadProxy::AsValueInto(base::debug::TracedValue* state) const {
452 // The following line casts away const modifiers because it is just
453 // setting debug state. We still want the AsValue() function and its
454 // call chain to be const throughout.
455 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
[email protected]a8a049c2013-03-11 23:27:06456
[email protected]d12aa932014-08-01 13:10:38457 state->BeginDictionary("layer_tree_host_impl");
458 layer_tree_host_impl_->AsValueInto(state);
459 state->EndDictionary();
[email protected]493067512012-09-19 23:34:10460}
461
[email protected]a8a049c2013-03-11 23:27:06462void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
463 {
464 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20465 if (layer_tree_host_impl_->renderer()) {
466 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06467 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20468 }
[email protected]a8a049c2013-03-11 23:27:06469 }
[email protected]8947cbe2012-11-28 05:27:43470}
471
[email protected]5d8bec72014-07-03 03:03:11472bool SingleThreadProxy::SupportsImplScrolling() const {
473 return false;
474}
475
[email protected]3d9f7432013-04-06 00:35:18476bool SingleThreadProxy::ShouldComposite() const {
477 DCHECK(Proxy::IsImplThread());
478 return layer_tree_host_impl_->visible() &&
479 layer_tree_host_impl_->CanDraw();
480}
481
[email protected]d9fce6722013-08-30 01:10:01482void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
483 DCHECK(Proxy::IsImplThread());
484 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
485 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
486}
487
[email protected]aeeedad2014-08-22 18:16:22488DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time,
489 LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20490 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20491 DCHECK(!layer_tree_host_->output_surface_lost());
492
[email protected]a8a049c2013-03-11 23:27:06493 {
494 DebugScopedSetImplThread impl(this);
495 base::AutoReset<bool> mark_inside(&inside_draw_, true);
496
[email protected]3d9f7432013-04-06 00:35:18497 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
498 // frame, so can only be used when such a frame is possible. Since
499 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
500 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50501 if (!ShouldComposite()) {
[email protected]d9fce6722013-08-30 01:10:01502 UpdateBackgroundAnimateTicking();
[email protected]aeeedad2014-08-22 18:16:22503 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18504 }
[email protected]a8a049c2013-03-11 23:27:06505
[email protected]aeeedad2014-08-22 18:16:22506 timing_history_.DidStartDrawing();
507
[email protected]fb7425a2013-04-22 16:28:55508 layer_tree_host_impl_->Animate(
[email protected]04c5900d2014-08-18 13:38:36509 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
[email protected]d9fce6722013-08-30 01:10:01510 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06511
dnetob71e30c2014-08-25 23:27:20512 layer_tree_host_impl_->PrepareToDraw(frame);
513 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
514 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06515
[email protected]3d9f7432013-04-06 00:35:18516 bool start_ready_animations = true;
517 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
518
[email protected]04c5900d2014-08-18 13:38:36519 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
[email protected]aeeedad2014-08-22 18:16:22520
521 timing_history_.DidFinishDrawing();
[email protected]a8a049c2013-03-11 23:27:06522 }
523
[email protected]aeeedad2014-08-22 18:16:22524 {
525 DebugScopedSetImplThread impl(this);
[email protected]174c6d42014-08-12 01:43:06526
dnetob71e30c2014-08-25 23:27:20527 // This CapturePostTasks should be destroyed before
528 // DidCommitAndDrawFrame() is called since that goes out to the
529 // embedder,
530 // and we want the embedder to receive its callbacks before that.
531 // NOTE: This maintains consistent ordering with the ThreadProxy since
532 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
533 // there as the main thread is not blocked, so any posted tasks inside
534 // the swap buffers will execute first.
535 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]aeeedad2014-08-22 18:16:22536
dnetob71e30c2014-08-25 23:27:20537 BlockingTaskRunner::CapturePostTasks blocked;
538 layer_tree_host_impl_->SwapBuffers(*frame);
[email protected]aeeedad2014-08-22 18:16:22539 }
540 DidCommitAndDrawFrame();
541
542 return DRAW_SUCCESS;
[email protected]a8a049c2013-03-11 23:27:06543}
544
[email protected]aeeedad2014-08-22 18:16:22545void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06546 if (next_frame_is_newly_committed_frame_) {
[email protected]aeeedad2014-08-22 18:16:22547 DebugScopedSetMainThread main(this);
[email protected]a8a049c2013-03-11 23:27:06548 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21549 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06550 }
551}
552
[email protected]4ea293f72014-08-13 03:03:17553bool SingleThreadProxy::MainFrameWillHappenForTesting() {
554 return false;
555}
[email protected]a8a049c2013-03-11 23:27:06556
[email protected]aeeedad2014-08-22 18:16:22557void SingleThreadProxy::SetNeedsBeginFrame(bool enable) {
558 layer_tree_host_impl_->SetNeedsBeginFrame(enable);
559}
560
561void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
562 layer_tree_host_impl_->WillBeginImplFrame(args);
563}
564
565void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
566 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
567 // Although this proxy is single-threaded, it's problematic to synchronously
568 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
569 // could cause a commit to occur in between a series of SetNeedsCommit calls
570 // (i.e. property modifications) causing some to fall on one frame and some to
571 // fall on the next. Doing it asynchronously instead matches the semantics of
572 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
573 // synchronous commit.
574 MainThreadTaskRunner()->PostTask(
575 FROM_HERE,
576 base::Bind(&SingleThreadProxy::BeginMainFrame,
577 weak_factory_.GetWeakPtr()));
578}
579
580void SingleThreadProxy::BeginMainFrame() {
581 if (defer_commits_) {
582 DCHECK(!commit_was_deferred_);
583 commit_was_deferred_ = true;
584 layer_tree_host_->DidDeferCommit();
585 return;
586 }
587
588 // This checker assumes NotifyReadyToCommit below causes a synchronous commit.
589 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
590
591 if (!layer_tree_host_->visible()) {
592 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
593 BeginMainFrameAbortedOnImplThread();
594 return;
595 }
596
597 if (layer_tree_host_->output_surface_lost()) {
598 TRACE_EVENT_INSTANT0(
599 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
600 BeginMainFrameAbortedOnImplThread();
601 return;
602 }
603
604 timing_history_.DidBeginMainFrame();
605
606 DCHECK(scheduler_on_impl_thread_);
607 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
608 scheduler_on_impl_thread_->NotifyReadyToCommit();
609}
610
611void SingleThreadProxy::BeginMainFrameAbortedOnImplThread() {
612 DebugScopedSetImplThread impl(this);
613 DCHECK(scheduler_on_impl_thread_->CommitPending());
614 DCHECK(!layer_tree_host_impl_->pending_tree());
615
616 // TODO(enne): SingleThreadProxy does not support cancelling commits yet so
617 // did_handle is always false.
618 bool did_handle = false;
619 layer_tree_host_impl_->BeginMainFrameAborted(did_handle);
620 scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle);
621}
622
623DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
624 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22625 LayerTreeHostImpl::FrameData frame;
626 return DoComposite(layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time,
627 &frame);
628}
629
630DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
631 NOTREACHED();
632 return INVALID_RESULT;
633}
634
635void SingleThreadProxy::ScheduledActionCommit() {
636 DebugScopedSetMainThread main(this);
637 DoCommit(layer_tree_host_impl_->CurrentBeginFrameArgs());
638}
639
640void SingleThreadProxy::ScheduledActionAnimate() {
641 TRACE_EVENT0("cc", "ScheduledActionAnimate");
642 layer_tree_host_impl_->Animate(
643 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
644}
645
646void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() {
647 // Impl-side painting only.
648 NOTREACHED();
649}
650
651void SingleThreadProxy::ScheduledActionActivateSyncTree() {
652}
653
654void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
655 DebugScopedSetMainThread main(this);
656 DCHECK(scheduler_on_impl_thread_);
657 // If possible, create the output surface in a post task. Synchronously
658 // creating the output surface makes tests more awkward since this differs
659 // from the ThreadProxy behavior. However, sometimes there is no
660 // task runner.
661 if (Proxy::MainThreadTaskRunner()) {
662 MainThreadTaskRunner()->PostTask(
663 FROM_HERE,
664 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface,
665 weak_factory_.GetWeakPtr()));
666 } else {
667 CreateAndInitializeOutputSurface();
668 }
669}
670
671void SingleThreadProxy::ScheduledActionManageTiles() {
672 // Impl-side painting only.
673 NOTREACHED();
674}
675
676void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
677}
678
679base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
680 return timing_history_.DrawDurationEstimate();
681}
682
683base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
684 return timing_history_.BeginMainFrameToCommitDurationEstimate();
685}
686
687base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
688 return timing_history_.CommitToActivateDurationEstimate();
689}
690
691void SingleThreadProxy::DidBeginImplFrameDeadline() {
692 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
693}
694
[email protected]bc5e77c2012-11-05 20:00:49695} // namespace cc