blob: ece908bf4ba38732af71aadd89a4a258fbff5540 [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]de2cf8c2013-10-25 19:46:4619#include "ui/gfx/frame_time.h"
[email protected]94f206c12012-08-25 00:09:1420
[email protected]9c88e562012-09-14 22:21:3021namespace cc {
[email protected]94f206c12012-08-25 00:09:1422
[email protected]943528e2013-11-07 05:01:3223scoped_ptr<Proxy> SingleThreadProxy::Create(
24 LayerTreeHost* layer_tree_host,
25 LayerTreeHostSingleThreadClient* client) {
[email protected]a8a049c2013-03-11 23:27:0626 return make_scoped_ptr(
[email protected]943528e2013-11-07 05:01:3227 new SingleThreadProxy(layer_tree_host, client)).PassAs<Proxy>();
[email protected]94f206c12012-08-25 00:09:1428}
29
[email protected]943528e2013-11-07 05:01:3230SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
31 LayerTreeHostSingleThreadClient* client)
[email protected]810d40b72013-06-20 18:26:1532 : Proxy(NULL),
[email protected]a8a049c2013-03-11 23:27:0633 layer_tree_host_(layer_tree_host),
[email protected]943528e2013-11-07 05:01:3234 client_(client),
[email protected]e06e1122013-03-15 17:12:3835 created_offscreen_context_provider_(false),
[email protected]a8a049c2013-03-11 23:27:0636 next_frame_is_newly_committed_frame_(false),
[email protected]ccd6d9d2013-03-30 19:08:5837 inside_draw_(false) {
[email protected]a8a049c2013-03-11 23:27:0638 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
39 DCHECK(Proxy::IsMainThread());
40 DCHECK(layer_tree_host);
[email protected]1e4c352b2013-01-10 02:05:2341
[email protected]089102b2013-03-14 03:54:5642 // Impl-side painting not supported without threaded compositing.
[email protected]d9c086a2013-04-17 16:12:4843 CHECK(!layer_tree_host->settings().impl_side_painting)
44 << "Threaded compositing must be enabled to use impl-side painting.";
[email protected]94f206c12012-08-25 00:09:1445}
46
[email protected]e96e3432013-12-19 18:56:0747void SingleThreadProxy::Start() {
[email protected]a8a049c2013-03-11 23:27:0648 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:2149 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]a8a049c2013-03-11 23:27:0650}
51
52SingleThreadProxy::~SingleThreadProxy() {
53 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
54 DCHECK(Proxy::IsMainThread());
[email protected]04049fc2013-05-01 03:13:2055 // Make sure Stop() got called or never Started.
56 DCHECK(!layer_tree_host_impl_);
[email protected]a8a049c2013-03-11 23:27:0657}
58
[email protected]0023fc72014-01-10 20:05:0659bool SingleThreadProxy::CompositeAndReadback(void* pixels,
60 const gfx::Rect& rect) {
[email protected]ed511b8d2013-03-25 03:29:2961 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback");
[email protected]a8a049c2013-03-11 23:27:0662 DCHECK(Proxy::IsMainThread());
63
[email protected]e0341352013-04-06 05:01:2064 gfx::Rect device_viewport_damage_rect = rect;
65
66 LayerTreeHostImpl::FrameData frame;
[email protected]de2cf8c2013-10-25 19:46:4667 if (!CommitAndComposite(gfx::FrameTime::Now(),
[email protected]e0341352013-04-06 05:01:2068 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:3969 true, // for_readback
[email protected]e0341352013-04-06 05:01:2070 &frame))
[email protected]a8a049c2013-03-11 23:27:0671 return false;
72
73 {
[email protected]61de5812012-11-08 07:03:4474 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2775 layer_tree_host_impl_->Readback(pixels, rect);
[email protected]a8a049c2013-03-11 23:27:0676
[email protected]c1bb5af2013-03-13 19:06:2777 if (layer_tree_host_impl_->IsContextLost())
[email protected]a8a049c2013-03-11 23:27:0678 return false;
[email protected]a8a049c2013-03-11 23:27:0679 }
[email protected]a8a049c2013-03-11 23:27:0680
81 return true;
[email protected]94f206c12012-08-25 00:09:1482}
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
[email protected]14bd5542013-05-08 21:51:3098void SingleThreadProxy::SetLayerTreeHostClientReady() {
[email protected]ccc08dc2014-01-30 07:33:2099 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
[email protected]a8a049c2013-03-11 23:27:06100 // Scheduling is controlled by the embedder in the single thread case, so
101 // nothing to do.
102}
103
104void SingleThreadProxy::SetVisible(bool visible) {
[email protected]ccc08dc2014-01-30 07:33:20105 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible");
[email protected]f7c01c82013-07-02 22:58:46106 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:27107 layer_tree_host_impl_->SetVisible(visible);
[email protected]8ea875b2013-08-07 00:32:12108
109 // Changing visibility could change ShouldComposite().
[email protected]d9fce6722013-08-30 01:10:01110 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06111}
112
[email protected]04049fc2013-05-01 03:13:20113void SingleThreadProxy::CreateAndInitializeOutputSurface() {
114 TRACE_EVENT0(
115 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
[email protected]a8a049c2013-03-11 23:27:06116 DCHECK(Proxy::IsMainThread());
[email protected]94f206c12012-08-25 00:09:14117
[email protected]e96e3432013-12-19 18:56:07118 scoped_ptr<OutputSurface> output_surface =
119 layer_tree_host_->CreateOutputSurface();
[email protected]04049fc2013-05-01 03:13:20120 if (!output_surface) {
121 OnOutputSurfaceInitializeAttempted(false);
122 return;
123 }
124
[email protected]e51444a2013-12-10 23:05:01125 scoped_refptr<ContextProvider> offscreen_context_provider;
[email protected]e06e1122013-03-15 17:12:38126 if (created_offscreen_context_provider_) {
[email protected]a8a049c2013-03-11 23:27:06127 offscreen_context_provider =
[email protected]f10dc472013-09-27 03:31:59128 layer_tree_host_->client()->OffscreenContextProvider();
129 if (!offscreen_context_provider.get() ||
130 !offscreen_context_provider->BindToCurrentThread()) {
[email protected]04049fc2013-05-01 03:13:20131 OnOutputSurfaceInitializeAttempted(false);
132 return;
133 }
[email protected]a8a049c2013-03-11 23:27:06134 }
135
[email protected]a8a049c2013-03-11 23:27:06136 {
[email protected]819b9f52013-09-22 23:29:51137 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06138 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:21139 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27140 layer_tree_host_impl_->resource_provider());
[email protected]04049fc2013-05-01 03:13:20141 }
142
143 bool initialized;
144 {
145 DebugScopedSetImplThread impl(this);
146
147 DCHECK(output_surface);
148 initialized = layer_tree_host_impl_->InitializeRenderer(
149 output_surface.Pass());
[email protected]fa339032014-02-18 22:11:59150 if (!initialized && offscreen_context_provider.get()) {
[email protected]a8a049c2013-03-11 23:27:06151 offscreen_context_provider->VerifyContexts();
[email protected]b5174d712013-08-28 08:10:43152 offscreen_context_provider = NULL;
[email protected]94f206c12012-08-25 00:09:14153 }
[email protected]b5174d712013-08-28 08:10:43154
155 layer_tree_host_impl_->SetOffscreenContextProvider(
156 offscreen_context_provider);
[email protected]a8a049c2013-03-11 23:27:06157 }
[email protected]94f206c12012-08-25 00:09:14158
[email protected]04049fc2013-05-01 03:13:20159 OnOutputSurfaceInitializeAttempted(initialized);
160}
[email protected]94f206c12012-08-25 00:09:14161
[email protected]04049fc2013-05-01 03:13:20162void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) {
163 LayerTreeHost::CreateResult result =
164 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
165 if (result == LayerTreeHost::CreateFailedButTryAgain) {
166 // Force another recreation attempt to happen by requesting another commit.
167 SetNeedsCommit();
168 }
[email protected]94f206c12012-08-25 00:09:14169}
170
[email protected]a8a049c2013-03-11 23:27:06171const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20172 DCHECK(Proxy::IsMainThread());
173 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06174 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14175}
176
[email protected]8b9e52b2014-01-17 16:35:31177void SingleThreadProxy::SetNeedsAnimate() {
[email protected]ccc08dc2014-01-30 07:33:20178 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
[email protected]c5134172013-12-11 06:19:48179 DCHECK(Proxy::IsMainThread());
[email protected]06cbc31b2014-01-17 06:43:20180 client_->ScheduleAnimation();
[email protected]c5134172013-12-11 06:19:48181}
182
[email protected]8b9e52b2014-01-17 16:35:31183void SingleThreadProxy::SetNeedsUpdateLayers() {
[email protected]ccc08dc2014-01-30 07:33:20184 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
[email protected]8b9e52b2014-01-17 16:35:31185 DCHECK(Proxy::IsMainThread());
186 client_->ScheduleComposite();
187}
188
[email protected]a8a049c2013-03-11 23:27:06189void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
[email protected]ccc08dc2014-01-30 07:33:20190 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
[email protected]a8a049c2013-03-11 23:27:06191 DCHECK(Proxy::IsMainThread());
192 // Commit immediately.
193 {
[email protected]819b9f52013-09-22 23:29:51194 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46195 DebugScopedSetImplThread impl(this);
196
[email protected]9794fb32013-08-29 09:49:59197 // This CapturePostTasks should be destroyed before CommitComplete() is
198 // called since that goes out to the embedder, and we want the embedder
199 // to receive its callbacks before that.
200 BlockingTaskRunner::CapturePostTasks blocked;
201
[email protected]c1bb5af2013-03-13 19:06:27202 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14203
[email protected]5d2fec02013-11-28 20:08:33204 if (PrioritizedResourceManager* contents_texture_manager =
205 layer_tree_host_->contents_texture_manager()) {
206 contents_texture_manager->PushTexturePrioritiesToBackings();
[email protected]6e8c54922013-06-02 19:17:35207 }
[email protected]804c8982013-03-13 16:32:21208 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14209
[email protected]ed511b8d2013-03-25 03:29:29210 scoped_ptr<ResourceUpdateController> update_controller =
[email protected]a8a049c2013-03-11 23:27:06211 ResourceUpdateController::Create(
212 NULL,
[email protected]810d40b72013-06-20 18:26:15213 Proxy::MainThreadTaskRunner(),
[email protected]a8a049c2013-03-11 23:27:06214 queue.Pass(),
[email protected]c1bb5af2013-03-13 19:06:27215 layer_tree_host_impl_->resource_provider());
[email protected]ed511b8d2013-03-25 03:29:29216 update_controller->Finalize();
[email protected]94f206c12012-08-25 00:09:14217
[email protected]127bdc1a2013-09-11 01:44:48218 if (layer_tree_host_impl_->EvictedUIResourcesExist())
219 layer_tree_host_->RecreateUIResources();
220
[email protected]804c8982013-03-13 16:32:21221 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14222
[email protected]c1bb5af2013-03-13 19:06:27223 layer_tree_host_impl_->CommitComplete();
[email protected]94f206c12012-08-25 00:09:14224
[email protected]1d993172012-10-18 18:15:04225#ifndef NDEBUG
[email protected]3519b872013-07-30 07:17:50226 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06227 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29228 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27229 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29230 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50231 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14232#endif
[email protected]8b9af6b2012-09-27 00:36:36233
[email protected]922c6e1f2013-10-09 04:04:09234 RenderingStatsInstrumentation* stats_instrumentation =
235 layer_tree_host_->rendering_stats_instrumentation();
[email protected]adbe30f2013-10-11 21:12:33236 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent(
237 stats_instrumentation->main_thread_rendering_stats());
[email protected]a9dc0d0f2013-08-17 02:43:18238 stats_instrumentation->AccumulateAndClearMainThreadStats();
[email protected]a8a049c2013-03-11 23:27:06239 }
[email protected]804c8982013-03-13 16:32:21240 layer_tree_host_->CommitComplete();
[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]943528e2013-11-07 05:01:32246 client_->ScheduleComposite();
[email protected]94f206c12012-08-25 00:09:14247}
248
[email protected]0023fc72014-01-10 20:05:06249void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
[email protected]ccc08dc2014-01-30 07:33:20250 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
[email protected]1cd9f5552013-04-26 04:22:03251 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]943528e2013-11-07 05:01:32252 client_->ScheduleComposite();
[email protected]94f206c12012-08-25 00:09:14253}
254
[email protected]74b43cc2013-08-30 06:29:27255void SingleThreadProxy::SetNextCommitWaitsForActivation() {
256 // There is no activation here other than commit. So do nothing.
257}
258
[email protected]a8a049c2013-03-11 23:27:06259void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
260 // Thread-only feature.
261 NOTREACHED();
[email protected]6b16679e2012-10-27 00:44:28262}
263
[email protected]a8a049c2013-03-11 23:27:06264bool SingleThreadProxy::CommitRequested() const { return false; }
265
[email protected]971728d2013-10-26 10:39:31266bool SingleThreadProxy::BeginMainFrameRequested() const { return false; }
267
[email protected]a8a049c2013-03-11 23:27:06268size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
269 return std::numeric_limits<size_t>::max();
270}
271
272void SingleThreadProxy::Stop() {
273 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
274 DCHECK(Proxy::IsMainThread());
275 {
[email protected]819b9f52013-09-22 23:29:51276 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06277 DebugScopedSetImplThread impl(this);
278
[email protected]804c8982013-03-13 16:32:21279 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27280 layer_tree_host_impl_->resource_provider());
[email protected]a8a049c2013-03-11 23:27:06281 layer_tree_host_impl_.reset();
282 }
[email protected]7aba6662013-03-12 10:17:34283 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06284}
285
[email protected]3d9f7432013-04-06 00:35:18286void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
[email protected]ccc08dc2014-01-30 07:33:20287 TRACE_EVENT1(
288 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
[email protected]3d9f7432013-04-06 00:35:18289 DCHECK(Proxy::IsImplThread());
[email protected]d9fce6722013-08-30 01:10:01290 UpdateBackgroundAnimateTicking();
[email protected]3d9f7432013-04-06 00:35:18291}
292
[email protected]4f48f6e2013-08-27 06:33:38293void SingleThreadProxy::NotifyReadyToActivate() {
294 // Thread-only feature.
295 NOTREACHED();
296}
297
[email protected]c1bb5af2013-03-13 19:06:27298void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]943528e2013-11-07 05:01:32299 client_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06300}
301
[email protected]c48536a52013-09-14 00:02:08302void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
303 // Thread-only/Impl-side-painting-only feature.
304 NOTREACHED();
305}
306
[email protected]0023fc72014-01-10 20:05:06307void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
308 const gfx::Rect& damage_rect) {
[email protected]27d851ab2013-06-28 01:09:50309 // TODO(brianderson): Once we move render_widget scheduling into this class,
310 // we can treat redraw requests more efficiently than CommitAndRedraw
311 // requests.
[email protected]1cd9f5552013-04-26 04:22:03312 layer_tree_host_impl_->SetViewportDamage(damage_rect);
313 SetNeedsCommit();
314}
315
[email protected]86126792013-03-16 20:07:54316void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06317 // Impl-side painting only.
318 NOTREACHED();
319}
320
[email protected]c1bb5af2013-03-13 19:06:27321void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]943528e2013-11-07 05:01:32322 client_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06323}
324
[email protected]c1bb5af2013-03-13 19:06:27325void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]85b57502014-03-11 15:37:48326 scoped_ptr<AnimationEventsVector> events) {
[email protected]ccc08dc2014-01-30 07:33:20327 TRACE_EVENT0(
328 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
[email protected]a8a049c2013-03-11 23:27:06329 DCHECK(Proxy::IsImplThread());
330 DebugScopedSetMainThread main(this);
[email protected]85b57502014-03-11 15:37:48331 layer_tree_host_->SetAnimationEvents(events.Pass());
[email protected]a8a049c2013-03-11 23:27:06332}
333
[email protected]c1bb5af2013-03-13 19:06:27334bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06335 size_t limit_bytes,
336 int priority_cutoff) {
337 DCHECK(IsImplThread());
[email protected]5d2fec02013-11-28 20:08:33338 PrioritizedResourceManager* contents_texture_manager =
339 layer_tree_host_->contents_texture_manager();
340
341 ResourceProvider* resource_provider =
342 layer_tree_host_impl_->resource_provider();
343
344 if (!contents_texture_manager || !resource_provider)
[email protected]e7595ead2013-10-10 10:10:07345 return false;
[email protected]a8a049c2013-03-11 23:27:06346
[email protected]5d2fec02013-11-28 20:08:33347 return contents_texture_manager->ReduceMemoryOnImplThread(
348 limit_bytes, priority_cutoff, resource_provider);
[email protected]94f206c12012-08-25 00:09:14349}
350
[email protected]c1bb5af2013-03-13 19:06:27351void SingleThreadProxy::SendManagedMemoryStats() {
[email protected]a8a049c2013-03-11 23:27:06352 DCHECK(Proxy::IsImplThread());
[email protected]384b2c5e2013-04-23 01:02:22353 if (!layer_tree_host_impl_)
[email protected]a8a049c2013-03-11 23:27:06354 return;
[email protected]804c8982013-03-13 16:32:21355 PrioritizedResourceManager* contents_texture_manager =
356 layer_tree_host_->contents_texture_manager();
[email protected]5d2fec02013-11-28 20:08:33357 if (!contents_texture_manager)
358 return;
359
[email protected]c1bb5af2013-03-13 19:06:27360 layer_tree_host_impl_->SendManagedMemoryStats(
[email protected]b56c1302013-03-20 21:17:34361 contents_texture_manager->MemoryVisibleBytes(),
362 contents_texture_manager->MemoryVisibleAndNearbyBytes(),
363 contents_texture_manager->MemoryUseBytes());
[email protected]94f206c12012-08-25 00:09:14364}
365
[email protected]c1bb5af2013-03-13 19:06:27366bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06367
[email protected]fa339032014-02-18 22:11:59368void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
369 DCHECK(IsImplThread());
370 renderer_capabilities_for_main_thread_ =
371 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
372}
373
[email protected]c1bb5af2013-03-13 19:06:27374void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20375 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
[email protected]a8a049c2013-03-11 23:27:06376 // Cause a commit so we can notice the lost context.
[email protected]c1bb5af2013-03-13 19:06:27377 SetNeedsCommitOnImplThread();
[email protected]4d7e46a2013-11-08 05:33:40378 client_->DidAbortSwapBuffers();
379}
380
381void SingleThreadProxy::DidSwapBuffersOnImplThread() {
382 client_->DidPostSwapBuffers();
383}
384
385void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() {
[email protected]ccc08dc2014-01-30 07:33:20386 TRACE_EVENT0("cc", "SingleThreadProxy::OnSwapBuffersCompleteOnImplThread");
[email protected]4d7e46a2013-11-08 05:33:40387 client_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10388}
389
[email protected]a8a049c2013-03-11 23:27:06390// Called by the legacy scheduling path (e.g. where render_widget does the
391// scheduling)
[email protected]f0c2a242013-03-15 19:34:52392void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
[email protected]ccc08dc2014-01-30 07:33:20393 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately");
[email protected]e0341352013-04-06 05:01:20394 gfx::Rect device_viewport_damage_rect;
395
396 LayerTreeHostImpl::FrameData frame;
397 if (CommitAndComposite(frame_begin_time,
398 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39399 false, // for_readback
[email protected]e0341352013-04-06 05:01:20400 &frame)) {
[email protected]819b9f52013-09-22 23:29:51401 {
402 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
403 DebugScopedSetImplThread impl(this);
404
405 // This CapturePostTasks should be destroyed before
406 // DidCommitAndDrawFrame() is called since that goes out to the embedder,
407 // and we want the embedder to receive its callbacks before that.
408 // NOTE: This maintains consistent ordering with the ThreadProxy since
409 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
410 // there as the main thread is not blocked, so any posted tasks inside
411 // the swap buffers will execute first.
412 BlockingTaskRunner::CapturePostTasks blocked;
413
414 layer_tree_host_impl_->SwapBuffers(frame);
415 }
[email protected]a8a049c2013-03-11 23:27:06416 DidSwapFrame();
417 }
[email protected]74d9063c2013-01-18 03:14:47418}
419
[email protected]a8a049c2013-03-11 23:27:06420scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
421 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
422 {
423 // The following line casts away const modifiers because it is just
424 // setting debug state. We still want the AsValue() function and its
425 // call chain to be const throughout.
426 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
427
428 state->Set("layer_tree_host_impl",
[email protected]c1bb5af2013-03-13 19:06:27429 layer_tree_host_impl_->AsValue().release());
[email protected]a8a049c2013-03-11 23:27:06430 }
431 return state.PassAs<base::Value>();
[email protected]493067512012-09-19 23:34:10432}
433
[email protected]a8a049c2013-03-11 23:27:06434void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
435 {
436 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20437 if (layer_tree_host_impl_->renderer()) {
438 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06439 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20440 }
[email protected]a8a049c2013-03-11 23:27:06441 }
[email protected]8947cbe2012-11-28 05:27:43442}
443
[email protected]e0341352013-04-06 05:01:20444bool SingleThreadProxy::CommitAndComposite(
445 base::TimeTicks frame_begin_time,
[email protected]0023fc72014-01-10 20:05:06446 const gfx::Rect& device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39447 bool for_readback,
[email protected]e0341352013-04-06 05:01:20448 LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20449 TRACE_EVENT0("cc", "SingleThreadProxy::CommitAndComposite");
[email protected]a8a049c2013-03-11 23:27:06450 DCHECK(Proxy::IsMainThread());
[email protected]b1969fa2012-10-17 20:16:29451
[email protected]04049fc2013-05-01 03:13:20452 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded())
[email protected]16288a42012-12-17 23:31:05453 return false;
[email protected]a8a049c2013-03-11 23:27:06454
[email protected]d7763662013-05-09 18:14:37455 layer_tree_host_->AnimateLayers(frame_begin_time);
456
[email protected]5d2fec02013-11-28 20:08:33457 if (PrioritizedResourceManager* contents_texture_manager =
458 layer_tree_host_->contents_texture_manager()) {
459 contents_texture_manager->UnlinkAndClearEvictedBackings();
460 contents_texture_manager->SetMaxMemoryLimitBytes(
[email protected]990e050a2013-09-23 18:50:21461 layer_tree_host_impl_->memory_allocation_limit_bytes());
[email protected]5d2fec02013-11-28 20:08:33462 contents_texture_manager->SetExternalPriorityCutoff(
[email protected]990e050a2013-09-23 18:50:21463 layer_tree_host_impl_->memory_allocation_priority_cutoff());
[email protected]6e8c54922013-06-02 19:17:35464 }
[email protected]a8a049c2013-03-11 23:27:06465
466 scoped_ptr<ResourceUpdateQueue> queue =
467 make_scoped_ptr(new ResourceUpdateQueue);
[email protected]990e050a2013-09-23 18:50:21468 layer_tree_host_->UpdateLayers(queue.get());
[email protected]a8a049c2013-03-11 23:27:06469
[email protected]804c8982013-03-13 16:32:21470 layer_tree_host_->WillCommit();
[email protected]a024d0e2013-09-26 19:20:45471
[email protected]e51444a2013-12-10 23:05:01472 scoped_refptr<ContextProvider> offscreen_context_provider;
[email protected]a024d0e2013-09-26 19:20:45473 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d &&
474 layer_tree_host_->needs_offscreen_context()) {
475 offscreen_context_provider =
[email protected]f10dc472013-09-27 03:31:59476 layer_tree_host_->client()->OffscreenContextProvider();
477 if (offscreen_context_provider.get() &&
478 !offscreen_context_provider->BindToCurrentThread())
479 offscreen_context_provider = NULL;
480
[email protected]a024d0e2013-09-26 19:20:45481 if (offscreen_context_provider.get())
482 created_offscreen_context_provider_ = true;
483 }
484
[email protected]a8a049c2013-03-11 23:27:06485 DoCommit(queue.Pass());
[email protected]e0341352013-04-06 05:01:20486 bool result = DoComposite(offscreen_context_provider,
487 frame_begin_time,
488 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39489 for_readback,
[email protected]e0341352013-04-06 05:01:20490 frame);
[email protected]daea3d42013-10-23 17:04:50491 layer_tree_host_->DidBeginMainFrame();
[email protected]a8a049c2013-03-11 23:27:06492 return result;
[email protected]16288a42012-12-17 23:31:05493}
494
[email protected]3d9f7432013-04-06 00:35:18495bool SingleThreadProxy::ShouldComposite() const {
496 DCHECK(Proxy::IsImplThread());
497 return layer_tree_host_impl_->visible() &&
498 layer_tree_host_impl_->CanDraw();
499}
500
[email protected]d9fce6722013-08-30 01:10:01501void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
502 DCHECK(Proxy::IsImplThread());
503 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
504 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
505}
506
[email protected]a8a049c2013-03-11 23:27:06507bool SingleThreadProxy::DoComposite(
[email protected]e51444a2013-12-10 23:05:01508 scoped_refptr<ContextProvider> offscreen_context_provider,
[email protected]e0341352013-04-06 05:01:20509 base::TimeTicks frame_begin_time,
[email protected]0023fc72014-01-10 20:05:06510 const gfx::Rect& device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39511 bool for_readback,
[email protected]e0341352013-04-06 05:01:20512 LayerTreeHostImpl::FrameData* frame) {
[email protected]ccc08dc2014-01-30 07:33:20513 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
[email protected]04049fc2013-05-01 03:13:20514 DCHECK(!layer_tree_host_->output_surface_lost());
515
516 bool lost_output_surface = false;
[email protected]a8a049c2013-03-11 23:27:06517 {
518 DebugScopedSetImplThread impl(this);
519 base::AutoReset<bool> mark_inside(&inside_draw_, true);
520
[email protected]b5174d712013-08-28 08:10:43521 layer_tree_host_impl_->SetOffscreenContextProvider(
522 offscreen_context_provider);
[email protected]a8a049c2013-03-11 23:27:06523
[email protected]2921d042013-05-10 05:01:39524 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
525
[email protected]3d9f7432013-04-06 00:35:18526 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
527 // frame, so can only be used when such a frame is possible. Since
528 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
529 // CanDraw() as well.
[email protected]2921d042013-05-10 05:01:39530 if (!ShouldComposite() || (for_readback && !can_do_readback)) {
[email protected]d9fce6722013-08-30 01:10:01531 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06532 return false;
[email protected]3d9f7432013-04-06 00:35:18533 }
[email protected]a8a049c2013-03-11 23:27:06534
[email protected]fb7425a2013-04-22 16:28:55535 layer_tree_host_impl_->Animate(
[email protected]27152642014-03-11 20:42:00536 layer_tree_host_impl_->CurrentFrameTimeTicks());
[email protected]d9fce6722013-08-30 01:10:01537 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06538
[email protected]13044fe72013-12-02 20:52:19539 if (!layer_tree_host_impl_->IsContextLost()) {
540 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect);
541 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
542 layer_tree_host_impl_->DidDrawAllLayers(*frame);
543 }
[email protected]04049fc2013-05-01 03:13:20544 lost_output_surface = layer_tree_host_impl_->IsContextLost();
[email protected]a8a049c2013-03-11 23:27:06545
[email protected]3d9f7432013-04-06 00:35:18546 bool start_ready_animations = true;
547 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
548
[email protected]8347d692013-05-17 23:22:38549 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
[email protected]a8a049c2013-03-11 23:27:06550 }
551
[email protected]04049fc2013-05-01 03:13:20552 if (lost_output_surface) {
[email protected]e51444a2013-12-10 23:05:01553 ContextProvider* offscreen_contexts =
[email protected]b5174d712013-08-28 08:10:43554 layer_tree_host_impl_->offscreen_context_provider();
[email protected]a8a049c2013-03-11 23:27:06555 if (offscreen_contexts)
556 offscreen_contexts->VerifyContexts();
[email protected]804c8982013-03-13 16:32:21557 layer_tree_host_->DidLoseOutputSurface();
[email protected]a8a049c2013-03-11 23:27:06558 return false;
559 }
560
561 return true;
562}
563
564void SingleThreadProxy::DidSwapFrame() {
565 if (next_frame_is_newly_committed_frame_) {
566 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21567 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06568 }
569}
570
571bool SingleThreadProxy::CommitPendingForTesting() { return false; }
572
[email protected]bc5e77c2012-11-05 20:00:49573} // namespace cc