blob: b3712b67734cd339b6a4dc4081377b07cc9f116c [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"
henrikaea769fd2014-09-08 07:15:0515#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(
danakjf446a072014-09-27 21:55:4829 new SingleThreadProxy(layer_tree_host, client, main_task_runner));
[email protected]94f206c12012-08-25 00:09:1430}
31
[email protected]27e6a212014-07-18 15:51:2732SingleThreadProxy::SingleThreadProxy(
33 LayerTreeHost* layer_tree_host,
34 LayerTreeHostSingleThreadClient* client,
35 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
36 : Proxy(main_task_runner, NULL),
[email protected]a8a049c2013-03-11 23:27:0637 layer_tree_host_(layer_tree_host),
[email protected]943528e2013-11-07 05:01:3238 client_(client),
[email protected]aeeedad2014-08-22 18:16:2239 timing_history_(layer_tree_host->rendering_stats_instrumentation()),
[email protected]a8a049c2013-03-11 23:27:0640 next_frame_is_newly_committed_frame_(false),
[email protected]aeeedad2014-08-22 18:16:2241 inside_draw_(false),
42 defer_commits_(false),
43 commit_was_deferred_(false),
44 commit_requested_(false),
45 weak_factory_(this) {
[email protected]a8a049c2013-03-11 23:27:0646 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
47 DCHECK(Proxy::IsMainThread());
48 DCHECK(layer_tree_host);
henrikaea769fd2014-09-08 07:15:0549
50 // Impl-side painting not supported without threaded compositing.
51 CHECK(!layer_tree_host->settings().impl_side_painting)
52 << "Threaded compositing must be enabled to use impl-side painting.";
[email protected]94f206c12012-08-25 00:09:1453}
54
[email protected]e96e3432013-12-19 18:56:0755void SingleThreadProxy::Start() {
[email protected]a8a049c2013-03-11 23:27:0656 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:2157 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]a8a049c2013-03-11 23:27:0658}
59
60SingleThreadProxy::~SingleThreadProxy() {
61 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
62 DCHECK(Proxy::IsMainThread());
[email protected]04049fc2013-05-01 03:13:2063 // Make sure Stop() got called or never Started.
64 DCHECK(!layer_tree_host_impl_);
[email protected]a8a049c2013-03-11 23:27:0665}
66
[email protected]a8a049c2013-03-11 23:27:0667void SingleThreadProxy::FinishAllRendering() {
[email protected]ccc08dc2014-01-30 07:33:2068 TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering");
[email protected]a8a049c2013-03-11 23:27:0669 DCHECK(Proxy::IsMainThread());
70 {
[email protected]61de5812012-11-08 07:03:4471 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2772 layer_tree_host_impl_->FinishAllRendering();
[email protected]a8a049c2013-03-11 23:27:0673 }
[email protected]94f206c12012-08-25 00:09:1474}
75
[email protected]a8a049c2013-03-11 23:27:0676bool SingleThreadProxy::IsStarted() const {
77 DCHECK(Proxy::IsMainThread());
[email protected]3209161d2013-03-29 19:17:3478 return layer_tree_host_impl_;
[email protected]94f206c12012-08-25 00:09:1479}
80
[email protected]14bd5542013-05-08 21:51:3081void SingleThreadProxy::SetLayerTreeHostClientReady() {
[email protected]ccc08dc2014-01-30 07:33:2082 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
[email protected]a8a049c2013-03-11 23:27:0683 // Scheduling is controlled by the embedder in the single thread case, so
84 // nothing to do.
[email protected]aeeedad2014-08-22 18:16:2285 DCHECK(Proxy::IsMainThread());
86 DebugScopedSetImplThread impl(this);
87 if (layer_tree_host_->settings().single_thread_proxy_scheduler &&
88 !scheduler_on_impl_thread_) {
89 SchedulerSettings scheduler_settings(layer_tree_host_->settings());
90 scheduler_on_impl_thread_ = Scheduler::Create(this,
91 scheduler_settings,
92 layer_tree_host_->id(),
93 MainThreadTaskRunner());
94 scheduler_on_impl_thread_->SetCanStart();
95 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
96 }
[email protected]a8a049c2013-03-11 23:27:0697}
98
99void SingleThreadProxy::SetVisible(bool visible) {
[email protected]ccc08dc2014-01-30 07:33:20100 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible");
[email protected]f7c01c82013-07-02 22:58:46101 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:27102 layer_tree_host_impl_->SetVisible(visible);
[email protected]aeeedad2014-08-22 18:16:22103 if (scheduler_on_impl_thread_)
104 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
[email protected]8ea875b2013-08-07 00:32:12105 // Changing visibility could change ShouldComposite().
[email protected]d9fce6722013-08-30 01:10:01106 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06107}
108
enne2097cab2014-09-25 20:16:31109void SingleThreadProxy::RequestNewOutputSurface() {
[email protected]a8a049c2013-03-11 23:27:06110 DCHECK(Proxy::IsMainThread());
[email protected]497edf82014-05-20 21:53:15111 DCHECK(layer_tree_host_->output_surface_lost());
enne2097cab2014-09-25 20:16:31112 layer_tree_host_->RequestNewOutputSurface();
113}
[email protected]94f206c12012-08-25 00:09:14114
enne2097cab2014-09-25 20:16:31115void SingleThreadProxy::SetOutputSurface(
116 scoped_ptr<OutputSurface> output_surface) {
117 DCHECK(Proxy::IsMainThread());
118 DCHECK(layer_tree_host_->output_surface_lost());
[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,
enne2097cab2014-09-25 20:16:31138 base::Bind(&SingleThreadProxy::RequestNewOutputSurface,
[email protected]aeeedad2014-08-22 18:16:22139 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.
henrikaea769fd2014-09-08 07:15:05195 BlockingTaskRunner::CapturePostTasks blocked(
196 blocking_main_thread_task_runner());
[email protected]9794fb32013-08-29 09:49:59197
[email protected]c1bb5af2013-03-13 19:06:27198 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14199
[email protected]5d2fec02013-11-28 20:08:33200 if (PrioritizedResourceManager* contents_texture_manager =
201 layer_tree_host_->contents_texture_manager()) {
202 contents_texture_manager->PushTexturePrioritiesToBackings();
[email protected]6e8c54922013-06-02 19:17:35203 }
[email protected]804c8982013-03-13 16:32:21204 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14205
[email protected]ed511b8d2013-03-25 03:29:29206 scoped_ptr<ResourceUpdateController> update_controller =
[email protected]a8a049c2013-03-11 23:27:06207 ResourceUpdateController::Create(
208 NULL,
[email protected]aeeedad2014-08-22 18:16:22209 MainThreadTaskRunner(),
[email protected]a8a049c2013-03-11 23:27:06210 queue.Pass(),
[email protected]c1bb5af2013-03-13 19:06:27211 layer_tree_host_impl_->resource_provider());
[email protected]ed511b8d2013-03-25 03:29:29212 update_controller->Finalize();
[email protected]94f206c12012-08-25 00:09:14213
[email protected]127bdc1a2013-09-11 01:44:48214 if (layer_tree_host_impl_->EvictedUIResourcesExist())
215 layer_tree_host_->RecreateUIResources();
216
[email protected]804c8982013-03-13 16:32:21217 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14218
[email protected]c1bb5af2013-03-13 19:06:27219 layer_tree_host_impl_->CommitComplete();
[email protected]94f206c12012-08-25 00:09:14220
[email protected]aeeedad2014-08-22 18:16:22221 UpdateBackgroundAnimateTicking();
222
[email protected]767f38d72014-03-18 21:26:41223#if DCHECK_IS_ON
[email protected]3519b872013-07-30 07:17:50224 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06225 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29226 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27227 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29228 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50229 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14230#endif
[email protected]8b9af6b2012-09-27 00:36:36231
[email protected]922c6e1f2013-10-09 04:04:09232 RenderingStatsInstrumentation* stats_instrumentation =
233 layer_tree_host_->rendering_stats_instrumentation();
[email protected]1bbed7a2014-07-08 02:54:00234 benchmark_instrumentation::IssueMainThreadRenderingStatsEvent(
[email protected]adbe30f2013-10-11 21:12:33235 stats_instrumentation->main_thread_rendering_stats());
[email protected]a9dc0d0f2013-08-17 02:43:18236 stats_instrumentation->AccumulateAndClearMainThreadStats();
[email protected]a8a049c2013-03-11 23:27:06237 }
[email protected]804c8982013-03-13 16:32:21238 layer_tree_host_->CommitComplete();
[email protected]aeeedad2014-08-22 18:16:22239 layer_tree_host_->DidBeginMainFrame();
240 timing_history_.DidCommit();
241
[email protected]a8a049c2013-03-11 23:27:06242 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14243}
244
[email protected]a8a049c2013-03-11 23:27:06245void SingleThreadProxy::SetNeedsCommit() {
246 DCHECK(Proxy::IsMainThread());
[email protected]aeeedad2014-08-22 18:16:22247 DebugScopedSetImplThread impl(this);
[email protected]943528e2013-11-07 05:01:32248 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22249 if (scheduler_on_impl_thread_)
250 scheduler_on_impl_thread_->SetNeedsCommit();
251 commit_requested_ = true;
[email protected]94f206c12012-08-25 00:09:14252}
253
[email protected]0023fc72014-01-10 20:05:06254void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20255 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
[email protected]aeeedad2014-08-22 18:16:22256 DCHECK(Proxy::IsMainThread());
257 DebugScopedSetImplThread impl(this);
[email protected]2decdd782014-08-13 22:36:06258 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22259 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14260}
261
[email protected]74b43cc2013-08-30 06:29:27262void SingleThreadProxy::SetNextCommitWaitsForActivation() {
henrikaea769fd2014-09-08 07:15:05263 // There is no activation here other than commit. So do nothing.
[email protected]aeeedad2014-08-22 18:16:22264 DCHECK(Proxy::IsMainThread());
[email protected]74b43cc2013-08-30 06:29:27265}
266
[email protected]a8a049c2013-03-11 23:27:06267void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
[email protected]aeeedad2014-08-22 18:16:22268 DCHECK(Proxy::IsMainThread());
269 // Deferring commits only makes sense if there's a scheduler.
270 if (!scheduler_on_impl_thread_)
271 return;
272 if (defer_commits_ == defer_commits)
273 return;
274
275 if (defer_commits)
276 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
277 else
278 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
279
280 defer_commits_ = defer_commits;
281 if (!defer_commits_ && commit_was_deferred_) {
282 commit_was_deferred_ = false;
283 BeginMainFrame();
284 }
[email protected]6b16679e2012-10-27 00:44:28285}
286
[email protected]174c6d42014-08-12 01:43:06287bool SingleThreadProxy::CommitRequested() const {
[email protected]aeeedad2014-08-22 18:16:22288 DCHECK(Proxy::IsMainThread());
289 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06290}
[email protected]a8a049c2013-03-11 23:27:06291
[email protected]174c6d42014-08-12 01:43:06292bool SingleThreadProxy::BeginMainFrameRequested() const {
[email protected]aeeedad2014-08-22 18:16:22293 DCHECK(Proxy::IsMainThread());
294 // If there is no scheduler, then there can be no pending begin frame,
295 // as all frames are all manually initiated by the embedder of cc.
296 if (!scheduler_on_impl_thread_)
297 return false;
298 return commit_requested_;
[email protected]174c6d42014-08-12 01:43:06299}
[email protected]971728d2013-10-26 10:39:31300
[email protected]a8a049c2013-03-11 23:27:06301size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
302 return std::numeric_limits<size_t>::max();
303}
304
305void SingleThreadProxy::Stop() {
306 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
307 DCHECK(Proxy::IsMainThread());
308 {
[email protected]819b9f52013-09-22 23:29:51309 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06310 DebugScopedSetImplThread impl(this);
311
skyostil3976a3f2014-09-04 22:07:23312 BlockingTaskRunner::CapturePostTasks blocked(
313 blocking_main_thread_task_runner());
[email protected]804c8982013-03-13 16:32:21314 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27315 layer_tree_host_impl_->resource_provider());
danakjf446a072014-09-27 21:55:48316 scheduler_on_impl_thread_ = nullptr;
317 layer_tree_host_impl_ = nullptr;
[email protected]a8a049c2013-03-11 23:27:06318 }
[email protected]7aba6662013-03-12 10:17:34319 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06320}
321
[email protected]3d9f7432013-04-06 00:35:18322void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
[email protected]ccc08dc2014-01-30 07:33:20323 TRACE_EVENT1(
324 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
[email protected]3d9f7432013-04-06 00:35:18325 DCHECK(Proxy::IsImplThread());
[email protected]d9fce6722013-08-30 01:10:01326 UpdateBackgroundAnimateTicking();
[email protected]aeeedad2014-08-22 18:16:22327 if (scheduler_on_impl_thread_)
328 scheduler_on_impl_thread_->SetCanDraw(can_draw);
[email protected]3d9f7432013-04-06 00:35:18329}
330
[email protected]4f48f6e2013-08-27 06:33:38331void SingleThreadProxy::NotifyReadyToActivate() {
henrikaea769fd2014-09-08 07:15:05332 // Impl-side painting only.
333 NOTREACHED();
[email protected]4f48f6e2013-08-27 06:33:38334}
335
[email protected]c1bb5af2013-03-13 19:06:27336void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]943528e2013-11-07 05:01:32337 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22338 if (scheduler_on_impl_thread_)
339 scheduler_on_impl_thread_->SetNeedsRedraw();
[email protected]a8a049c2013-03-11 23:27:06340}
341
[email protected]43b8f982014-04-30 21:24:33342void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
343 SetNeedsRedrawOnImplThread();
344}
345
[email protected]c48536a52013-09-14 00:02:08346void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
henrikaea769fd2014-09-08 07:15:05347 // Impl-side painting only.
348 NOTREACHED();
[email protected]c48536a52013-09-14 00:02:08349}
350
[email protected]0023fc72014-01-10 20:05:06351void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
352 const gfx::Rect& damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03353 layer_tree_host_impl_->SetViewportDamage(damage_rect);
[email protected]aeeedad2014-08-22 18:16:22354 SetNeedsRedrawOnImplThread();
[email protected]1cd9f5552013-04-26 04:22:03355}
356
[email protected]86126792013-03-16 20:07:54357void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
henrikaea769fd2014-09-08 07:15:05358 // Impl-side painting only.
359 NOTREACHED();
[email protected]a8a049c2013-03-11 23:27:06360}
361
[email protected]c1bb5af2013-03-13 19:06:27362void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]943528e2013-11-07 05:01:32363 client_->ScheduleComposite();
[email protected]aeeedad2014-08-22 18:16:22364 if (scheduler_on_impl_thread_)
365 scheduler_on_impl_thread_->SetNeedsCommit();
[email protected]a8a049c2013-03-11 23:27:06366}
367
[email protected]c1bb5af2013-03-13 19:06:27368void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]85b57502014-03-11 15:37:48369 scoped_ptr<AnimationEventsVector> events) {
[email protected]ccc08dc2014-01-30 07:33:20370 TRACE_EVENT0(
371 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
[email protected]a8a049c2013-03-11 23:27:06372 DCHECK(Proxy::IsImplThread());
373 DebugScopedSetMainThread main(this);
[email protected]85b57502014-03-11 15:37:48374 layer_tree_host_->SetAnimationEvents(events.Pass());
[email protected]a8a049c2013-03-11 23:27:06375}
376
[email protected]c1bb5af2013-03-13 19:06:27377bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06378 size_t limit_bytes,
379 int priority_cutoff) {
380 DCHECK(IsImplThread());
[email protected]5d2fec02013-11-28 20:08:33381 PrioritizedResourceManager* contents_texture_manager =
382 layer_tree_host_->contents_texture_manager();
383
384 ResourceProvider* resource_provider =
385 layer_tree_host_impl_->resource_provider();
386
387 if (!contents_texture_manager || !resource_provider)
[email protected]e7595ead2013-10-10 10:10:07388 return false;
[email protected]a8a049c2013-03-11 23:27:06389
[email protected]5d2fec02013-11-28 20:08:33390 return contents_texture_manager->ReduceMemoryOnImplThread(
391 limit_bytes, priority_cutoff, resource_provider);
[email protected]94f206c12012-08-25 00:09:14392}
393
[email protected]c1bb5af2013-03-13 19:06:27394bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06395
[email protected]fa339032014-02-18 22:11:59396void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
397 DCHECK(IsImplThread());
398 renderer_capabilities_for_main_thread_ =
399 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
400}
401
henrikaea769fd2014-09-08 07:15:05402void SingleThreadProxy::DidManageTiles() {
403 // Impl-side painting only.
404 NOTREACHED();
405}
406
[email protected]c1bb5af2013-03-13 19:06:27407void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20408 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22409 {
410 DebugScopedSetMainThread main(this);
411 // This must happen before we notify the scheduler as it may try to recreate
412 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
413 layer_tree_host_->DidLoseOutputSurface();
414 }
[email protected]4d7e46a2013-11-08 05:33:40415 client_->DidAbortSwapBuffers();
[email protected]aeeedad2014-08-22 18:16:22416 if (scheduler_on_impl_thread_)
417 scheduler_on_impl_thread_->DidLoseOutputSurface();
[email protected]4d7e46a2013-11-08 05:33:40418}
419
420void SingleThreadProxy::DidSwapBuffersOnImplThread() {
[email protected]aeeedad2014-08-22 18:16:22421 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
422 if (scheduler_on_impl_thread_)
423 scheduler_on_impl_thread_->DidSwapBuffers();
[email protected]4d7e46a2013-11-08 05:33:40424 client_->DidPostSwapBuffers();
425}
426
[email protected]c14902662014-04-18 05:06:11427void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
428 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
[email protected]aeeedad2014-08-22 18:16:22429 if (scheduler_on_impl_thread_)
430 scheduler_on_impl_thread_->DidSwapBuffersComplete();
431 layer_tree_host_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10432}
433
[email protected]aeeedad2014-08-22 18:16:22434void SingleThreadProxy::BeginFrame(const BeginFrameArgs& args) {
435 TRACE_EVENT0("cc", "SingleThreadProxy::BeginFrame");
436 if (scheduler_on_impl_thread_)
simonhong96b59672014-09-04 04:50:03437 scheduler_on_impl_thread_->BeginFrame(args);
[email protected]aeeedad2014-08-22 18:16:22438}
439
[email protected]f0c2a242013-03-15 19:34:52440void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
[email protected]ccc08dc2014-01-30 07:33:20441 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately");
[email protected]51f81da2014-05-16 21:29:26442 DCHECK(Proxy::IsMainThread());
[email protected]497edf82014-05-20 21:53:15443 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]51f81da2014-05-16 21:29:26444
[email protected]aeeedad2014-08-22 18:16:22445 BeginFrameArgs begin_frame_args = BeginFrameArgs::Create(
446 frame_begin_time, base::TimeTicks(), BeginFrameArgs::DefaultInterval());
447 DoCommit(begin_frame_args);
[email protected]e0341352013-04-06 05:01:20448
449 LayerTreeHostImpl::FrameData frame;
[email protected]aeeedad2014-08-22 18:16:22450 DoComposite(frame_begin_time, &frame);
[email protected]74d9063c2013-01-18 03:14:47451}
452
[email protected]d12aa932014-08-01 13:10:38453void SingleThreadProxy::AsValueInto(base::debug::TracedValue* state) const {
454 // The following line casts away const modifiers because it is just
455 // setting debug state. We still want the AsValue() function and its
456 // call chain to be const throughout.
457 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
[email protected]a8a049c2013-03-11 23:27:06458
[email protected]d12aa932014-08-01 13:10:38459 state->BeginDictionary("layer_tree_host_impl");
460 layer_tree_host_impl_->AsValueInto(state);
461 state->EndDictionary();
[email protected]493067512012-09-19 23:34:10462}
463
[email protected]a8a049c2013-03-11 23:27:06464void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
465 {
466 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20467 if (layer_tree_host_impl_->renderer()) {
468 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06469 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20470 }
[email protected]a8a049c2013-03-11 23:27:06471 }
[email protected]8947cbe2012-11-28 05:27:43472}
473
[email protected]5d8bec72014-07-03 03:03:11474bool SingleThreadProxy::SupportsImplScrolling() const {
475 return false;
476}
477
[email protected]3d9f7432013-04-06 00:35:18478bool SingleThreadProxy::ShouldComposite() const {
479 DCHECK(Proxy::IsImplThread());
480 return layer_tree_host_impl_->visible() &&
481 layer_tree_host_impl_->CanDraw();
482}
483
[email protected]d9fce6722013-08-30 01:10:01484void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
485 DCHECK(Proxy::IsImplThread());
486 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
487 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
488}
489
[email protected]aeeedad2014-08-22 18:16:22490DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time,
491 LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20492 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20493 DCHECK(!layer_tree_host_->output_surface_lost());
494
[email protected]a8a049c2013-03-11 23:27:06495 {
496 DebugScopedSetImplThread impl(this);
497 base::AutoReset<bool> mark_inside(&inside_draw_, true);
498
[email protected]3d9f7432013-04-06 00:35:18499 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
500 // frame, so can only be used when such a frame is possible. Since
501 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
502 // CanDraw() as well.
[email protected]2aae96792014-05-15 23:10:50503 if (!ShouldComposite()) {
[email protected]d9fce6722013-08-30 01:10:01504 UpdateBackgroundAnimateTicking();
[email protected]aeeedad2014-08-22 18:16:22505 return DRAW_ABORTED_CANT_DRAW;
[email protected]3d9f7432013-04-06 00:35:18506 }
[email protected]a8a049c2013-03-11 23:27:06507
[email protected]aeeedad2014-08-22 18:16:22508 timing_history_.DidStartDrawing();
509
[email protected]fb7425a2013-04-22 16:28:55510 layer_tree_host_impl_->Animate(
[email protected]04c5900d2014-08-18 13:38:36511 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
[email protected]d9fce6722013-08-30 01:10:01512 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06513
dnetob71e30c2014-08-25 23:27:20514 layer_tree_host_impl_->PrepareToDraw(frame);
515 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
516 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]a8a049c2013-03-11 23:27:06517
[email protected]3d9f7432013-04-06 00:35:18518 bool start_ready_animations = true;
519 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
520
[email protected]04c5900d2014-08-18 13:38:36521 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
[email protected]aeeedad2014-08-22 18:16:22522
523 timing_history_.DidFinishDrawing();
[email protected]a8a049c2013-03-11 23:27:06524 }
525
[email protected]aeeedad2014-08-22 18:16:22526 {
527 DebugScopedSetImplThread impl(this);
[email protected]174c6d42014-08-12 01:43:06528
dnetob71e30c2014-08-25 23:27:20529 // This CapturePostTasks should be destroyed before
530 // DidCommitAndDrawFrame() is called since that goes out to the
531 // embedder,
532 // and we want the embedder to receive its callbacks before that.
533 // NOTE: This maintains consistent ordering with the ThreadProxy since
534 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
535 // there as the main thread is not blocked, so any posted tasks inside
536 // the swap buffers will execute first.
537 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]aeeedad2014-08-22 18:16:22538
skyostil3976a3f2014-09-04 22:07:23539 BlockingTaskRunner::CapturePostTasks blocked(
540 blocking_main_thread_task_runner());
dnetob71e30c2014-08-25 23:27:20541 layer_tree_host_impl_->SwapBuffers(*frame);
[email protected]aeeedad2014-08-22 18:16:22542 }
543 DidCommitAndDrawFrame();
544
545 return DRAW_SUCCESS;
[email protected]a8a049c2013-03-11 23:27:06546}
547
[email protected]aeeedad2014-08-22 18:16:22548void SingleThreadProxy::DidCommitAndDrawFrame() {
[email protected]a8a049c2013-03-11 23:27:06549 if (next_frame_is_newly_committed_frame_) {
[email protected]aeeedad2014-08-22 18:16:22550 DebugScopedSetMainThread main(this);
[email protected]a8a049c2013-03-11 23:27:06551 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21552 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06553 }
554}
555
[email protected]4ea293f72014-08-13 03:03:17556bool SingleThreadProxy::MainFrameWillHappenForTesting() {
557 return false;
558}
[email protected]a8a049c2013-03-11 23:27:06559
[email protected]aeeedad2014-08-22 18:16:22560void SingleThreadProxy::SetNeedsBeginFrame(bool enable) {
561 layer_tree_host_impl_->SetNeedsBeginFrame(enable);
562}
563
564void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
565 layer_tree_host_impl_->WillBeginImplFrame(args);
566}
567
568void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
569 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
570 // Although this proxy is single-threaded, it's problematic to synchronously
571 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
572 // could cause a commit to occur in between a series of SetNeedsCommit calls
573 // (i.e. property modifications) causing some to fall on one frame and some to
574 // fall on the next. Doing it asynchronously instead matches the semantics of
575 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
576 // synchronous commit.
577 MainThreadTaskRunner()->PostTask(
578 FROM_HERE,
579 base::Bind(&SingleThreadProxy::BeginMainFrame,
580 weak_factory_.GetWeakPtr()));
581}
582
583void SingleThreadProxy::BeginMainFrame() {
584 if (defer_commits_) {
585 DCHECK(!commit_was_deferred_);
586 commit_was_deferred_ = true;
587 layer_tree_host_->DidDeferCommit();
588 return;
589 }
590
591 // This checker assumes NotifyReadyToCommit below causes a synchronous commit.
592 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
593
594 if (!layer_tree_host_->visible()) {
595 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
596 BeginMainFrameAbortedOnImplThread();
597 return;
598 }
599
600 if (layer_tree_host_->output_surface_lost()) {
601 TRACE_EVENT_INSTANT0(
602 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
603 BeginMainFrameAbortedOnImplThread();
604 return;
605 }
606
607 timing_history_.DidBeginMainFrame();
608
609 DCHECK(scheduler_on_impl_thread_);
610 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
611 scheduler_on_impl_thread_->NotifyReadyToCommit();
612}
613
614void SingleThreadProxy::BeginMainFrameAbortedOnImplThread() {
615 DebugScopedSetImplThread impl(this);
616 DCHECK(scheduler_on_impl_thread_->CommitPending());
617 DCHECK(!layer_tree_host_impl_->pending_tree());
618
619 // TODO(enne): SingleThreadProxy does not support cancelling commits yet so
620 // did_handle is always false.
621 bool did_handle = false;
622 layer_tree_host_impl_->BeginMainFrameAborted(did_handle);
623 scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle);
624}
625
626DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
627 DebugScopedSetImplThread impl(this);
[email protected]aeeedad2014-08-22 18:16:22628 LayerTreeHostImpl::FrameData frame;
629 return DoComposite(layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time,
630 &frame);
631}
632
633DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
634 NOTREACHED();
635 return INVALID_RESULT;
636}
637
638void SingleThreadProxy::ScheduledActionCommit() {
639 DebugScopedSetMainThread main(this);
640 DoCommit(layer_tree_host_impl_->CurrentBeginFrameArgs());
641}
642
643void SingleThreadProxy::ScheduledActionAnimate() {
644 TRACE_EVENT0("cc", "ScheduledActionAnimate");
645 layer_tree_host_impl_->Animate(
646 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
647}
648
649void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() {
henrikaea769fd2014-09-08 07:15:05650 // Impl-side painting only.
651 NOTREACHED();
[email protected]aeeedad2014-08-22 18:16:22652}
653
654void SingleThreadProxy::ScheduledActionActivateSyncTree() {
655}
656
657void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
658 DebugScopedSetMainThread main(this);
659 DCHECK(scheduler_on_impl_thread_);
660 // If possible, create the output surface in a post task. Synchronously
661 // creating the output surface makes tests more awkward since this differs
662 // from the ThreadProxy behavior. However, sometimes there is no
663 // task runner.
664 if (Proxy::MainThreadTaskRunner()) {
665 MainThreadTaskRunner()->PostTask(
666 FROM_HERE,
enne2097cab2014-09-25 20:16:31667 base::Bind(&SingleThreadProxy::RequestNewOutputSurface,
[email protected]aeeedad2014-08-22 18:16:22668 weak_factory_.GetWeakPtr()));
669 } else {
enne2097cab2014-09-25 20:16:31670 RequestNewOutputSurface();
[email protected]aeeedad2014-08-22 18:16:22671 }
672}
673
674void SingleThreadProxy::ScheduledActionManageTiles() {
henrikaea769fd2014-09-08 07:15:05675 // Impl-side painting only.
676 NOTREACHED();
[email protected]aeeedad2014-08-22 18:16:22677}
678
679void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
680}
681
682base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
683 return timing_history_.DrawDurationEstimate();
684}
685
686base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
687 return timing_history_.BeginMainFrameToCommitDurationEstimate();
688}
689
690base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
691 return timing_history_.CommitToActivateDurationEstimate();
692}
693
694void SingleThreadProxy::DidBeginImplFrameDeadline() {
695 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
696}
697
[email protected]bc5e77c2012-11-05 20:00:49698} // namespace cc