blob: e8d3e765da29bdbe48a5e1af492112fa100c99e4 [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]681ccff2013-03-18 06:13:529#include "cc/base/thread.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]556fd292013-03-18 08:03:0415#include "cc/trees/layer_tree_host.h"
16#include "cc/trees/layer_tree_impl.h"
[email protected]94f206c12012-08-25 00:09:1417
[email protected]9c88e562012-09-14 22:21:3018namespace cc {
[email protected]94f206c12012-08-25 00:09:1419
[email protected]a8a049c2013-03-11 23:27:0620scoped_ptr<Proxy> SingleThreadProxy::Create(LayerTreeHost* layer_tree_host) {
21 return make_scoped_ptr(
22 new SingleThreadProxy(layer_tree_host)).PassAs<Proxy>();
[email protected]94f206c12012-08-25 00:09:1423}
24
[email protected]a8a049c2013-03-11 23:27:0625SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host)
26 : Proxy(scoped_ptr<Thread>(NULL)),
27 layer_tree_host_(layer_tree_host),
[email protected]e06e1122013-03-15 17:12:3828 created_offscreen_context_provider_(false),
[email protected]a8a049c2013-03-11 23:27:0629 next_frame_is_newly_committed_frame_(false),
[email protected]ccd6d9d2013-03-30 19:08:5830 inside_draw_(false) {
[email protected]a8a049c2013-03-11 23:27:0631 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
32 DCHECK(Proxy::IsMainThread());
33 DCHECK(layer_tree_host);
[email protected]1e4c352b2013-01-10 02:05:2334
[email protected]089102b2013-03-14 03:54:5635 // Impl-side painting not supported without threaded compositing.
[email protected]d9c086a2013-04-17 16:12:4836 CHECK(!layer_tree_host->settings().impl_side_painting)
37 << "Threaded compositing must be enabled to use impl-side painting.";
[email protected]94f206c12012-08-25 00:09:1438}
39
[email protected]04049fc2013-05-01 03:13:2040void SingleThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) {
41 DCHECK(first_output_surface);
[email protected]a8a049c2013-03-11 23:27:0642 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:2143 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]04049fc2013-05-01 03:13:2044 first_output_surface_ = first_output_surface.Pass();
[email protected]a8a049c2013-03-11 23:27:0645}
46
47SingleThreadProxy::~SingleThreadProxy() {
48 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
49 DCHECK(Proxy::IsMainThread());
[email protected]04049fc2013-05-01 03:13:2050 // Make sure Stop() got called or never Started.
51 DCHECK(!layer_tree_host_impl_);
[email protected]a8a049c2013-03-11 23:27:0652}
53
54bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
[email protected]ed511b8d2013-03-25 03:29:2955 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback");
[email protected]a8a049c2013-03-11 23:27:0656 DCHECK(Proxy::IsMainThread());
57
[email protected]e0341352013-04-06 05:01:2058 gfx::Rect device_viewport_damage_rect = rect;
59
60 LayerTreeHostImpl::FrameData frame;
61 if (!CommitAndComposite(base::TimeTicks::Now(),
62 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:3963 true, // for_readback
[email protected]e0341352013-04-06 05:01:2064 &frame))
[email protected]a8a049c2013-03-11 23:27:0665 return false;
66
67 {
[email protected]61de5812012-11-08 07:03:4468 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2769 layer_tree_host_impl_->Readback(pixels, rect);
[email protected]a8a049c2013-03-11 23:27:0670
[email protected]c1bb5af2013-03-13 19:06:2771 if (layer_tree_host_impl_->IsContextLost())
[email protected]a8a049c2013-03-11 23:27:0672 return false;
73
[email protected]e0341352013-04-06 05:01:2074 layer_tree_host_impl_->SwapBuffers(frame);
[email protected]a8a049c2013-03-11 23:27:0675 }
76 DidSwapFrame();
77
78 return true;
[email protected]94f206c12012-08-25 00:09:1479}
80
[email protected]a8a049c2013-03-11 23:27:0681void SingleThreadProxy::FinishAllRendering() {
82 DCHECK(Proxy::IsMainThread());
83 {
[email protected]61de5812012-11-08 07:03:4484 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2785 layer_tree_host_impl_->FinishAllRendering();
[email protected]a8a049c2013-03-11 23:27:0686 }
[email protected]94f206c12012-08-25 00:09:1487}
88
[email protected]a8a049c2013-03-11 23:27:0689bool SingleThreadProxy::IsStarted() const {
90 DCHECK(Proxy::IsMainThread());
[email protected]3209161d2013-03-29 19:17:3491 return layer_tree_host_impl_;
[email protected]94f206c12012-08-25 00:09:1492}
93
[email protected]14bd5542013-05-08 21:51:3094void SingleThreadProxy::SetLayerTreeHostClientReady() {
[email protected]a8a049c2013-03-11 23:27:0695 // Scheduling is controlled by the embedder in the single thread case, so
96 // nothing to do.
97}
98
99void SingleThreadProxy::SetVisible(bool visible) {
[email protected]fa8818f2013-05-29 21:25:18100 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:27101 layer_tree_host_impl_->SetVisible(visible);
[email protected]a8a049c2013-03-11 23:27:06102}
103
[email protected]04049fc2013-05-01 03:13:20104void SingleThreadProxy::CreateAndInitializeOutputSurface() {
105 TRACE_EVENT0(
106 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
[email protected]a8a049c2013-03-11 23:27:06107 DCHECK(Proxy::IsMainThread());
[email protected]94f206c12012-08-25 00:09:14108
[email protected]04049fc2013-05-01 03:13:20109 scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass();
[email protected]486544b2013-04-26 18:46:22110 if (!output_surface)
[email protected]04049fc2013-05-01 03:13:20111 output_surface = layer_tree_host_->CreateOutputSurface();
112 if (!output_surface) {
113 OnOutputSurfaceInitializeAttempted(false);
114 return;
115 }
116
[email protected]a8a049c2013-03-11 23:27:06117 scoped_refptr<cc::ContextProvider> offscreen_context_provider;
[email protected]e06e1122013-03-15 17:12:38118 if (created_offscreen_context_provider_) {
[email protected]a8a049c2013-03-11 23:27:06119 offscreen_context_provider =
120 layer_tree_host_->client()->OffscreenContextProviderForMainThread();
[email protected]22898ed2013-06-01 04:52:30121 if (!offscreen_context_provider.get()) {
[email protected]04049fc2013-05-01 03:13:20122 OnOutputSurfaceInitializeAttempted(false);
123 return;
124 }
[email protected]a8a049c2013-03-11 23:27:06125 }
126
[email protected]a8a049c2013-03-11 23:27:06127 {
128 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
129 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:21130 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27131 layer_tree_host_impl_->resource_provider());
[email protected]04049fc2013-05-01 03:13:20132 }
133
134 bool initialized;
135 {
136 DebugScopedSetImplThread impl(this);
137
138 DCHECK(output_surface);
139 initialized = layer_tree_host_impl_->InitializeRenderer(
140 output_surface.Pass());
[email protected]a8a049c2013-03-11 23:27:06141 if (initialized) {
142 renderer_capabilities_for_main_thread_ =
[email protected]c1bb5af2013-03-13 19:06:27143 layer_tree_host_impl_->GetRendererCapabilities();
[email protected]04049fc2013-05-01 03:13:20144
[email protected]e06e1122013-03-15 17:12:38145 layer_tree_host_impl_->resource_provider()->
146 set_offscreen_context_provider(offscreen_context_provider);
[email protected]22898ed2013-06-01 04:52:30147 } else if (offscreen_context_provider.get()) {
[email protected]a8a049c2013-03-11 23:27:06148 offscreen_context_provider->VerifyContexts();
[email protected]94f206c12012-08-25 00:09:14149 }
[email protected]a8a049c2013-03-11 23:27:06150 }
[email protected]94f206c12012-08-25 00:09:14151
[email protected]04049fc2013-05-01 03:13:20152 OnOutputSurfaceInitializeAttempted(initialized);
153}
[email protected]94f206c12012-08-25 00:09:14154
[email protected]04049fc2013-05-01 03:13:20155void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) {
156 LayerTreeHost::CreateResult result =
157 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
158 if (result == LayerTreeHost::CreateFailedButTryAgain) {
159 // Force another recreation attempt to happen by requesting another commit.
160 SetNeedsCommit();
161 }
[email protected]94f206c12012-08-25 00:09:14162}
163
[email protected]a8a049c2013-03-11 23:27:06164const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20165 DCHECK(Proxy::IsMainThread());
166 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06167 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14168}
169
[email protected]a8a049c2013-03-11 23:27:06170void SingleThreadProxy::SetNeedsAnimate() {
171 // Thread-only feature.
172 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14173}
174
[email protected]a8a049c2013-03-11 23:27:06175void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
176 DCHECK(Proxy::IsMainThread());
177 // Commit immediately.
178 {
[email protected]fa8818f2013-05-29 21:25:18179 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
180 DebugScopedSetImplThread impl(this);
181
[email protected]372bad5f2013-03-21 16:38:43182 RenderingStatsInstrumentation* stats_instrumentation =
183 layer_tree_host_->rendering_stats_instrumentation();
[email protected]ed511b8d2013-03-25 03:29:29184 base::TimeTicks start_time = stats_instrumentation->StartRecording();
[email protected]372bad5f2013-03-21 16:38:43185
[email protected]c1bb5af2013-03-13 19:06:27186 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14187
[email protected]6e8c54922013-06-02 19:17:35188 if (layer_tree_host_->contents_texture_manager()) {
189 layer_tree_host_->contents_texture_manager()->
190 PushTexturePrioritiesToBackings();
191 }
[email protected]804c8982013-03-13 16:32:21192 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14193
[email protected]ed511b8d2013-03-25 03:29:29194 scoped_ptr<ResourceUpdateController> update_controller =
[email protected]a8a049c2013-03-11 23:27:06195 ResourceUpdateController::Create(
196 NULL,
197 Proxy::MainThread(),
198 queue.Pass(),
[email protected]c1bb5af2013-03-13 19:06:27199 layer_tree_host_impl_->resource_provider());
[email protected]ed511b8d2013-03-25 03:29:29200 update_controller->Finalize();
[email protected]94f206c12012-08-25 00:09:14201
[email protected]804c8982013-03-13 16:32:21202 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14203
[email protected]c1bb5af2013-03-13 19:06:27204 layer_tree_host_impl_->CommitComplete();
[email protected]94f206c12012-08-25 00:09:14205
[email protected]1d993172012-10-18 18:15:04206#ifndef NDEBUG
[email protected]a8a049c2013-03-11 23:27:06207 // In the single-threaded case, the scroll deltas should never be
208 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29209 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27210 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29211 DCHECK(!scroll_info->scrolls.size());
[email protected]94f206c12012-08-25 00:09:14212#endif
[email protected]8b9af6b2012-09-27 00:36:36213
[email protected]ed511b8d2013-03-25 03:29:29214 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time);
[email protected]372bad5f2013-03-21 16:38:43215 stats_instrumentation->AddCommit(duration);
[email protected]a8a049c2013-03-11 23:27:06216 }
[email protected]804c8982013-03-13 16:32:21217 layer_tree_host_->CommitComplete();
[email protected]a8a049c2013-03-11 23:27:06218 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14219}
220
[email protected]a8a049c2013-03-11 23:27:06221void SingleThreadProxy::SetNeedsCommit() {
222 DCHECK(Proxy::IsMainThread());
[email protected]804c8982013-03-13 16:32:21223 layer_tree_host_->ScheduleComposite();
[email protected]94f206c12012-08-25 00:09:14224}
225
[email protected]b9d4a362013-04-23 05:36:27226void SingleThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03227 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14228}
229
[email protected]c1bb5af2013-03-13 19:06:27230void SingleThreadProxy::OnHasPendingTreeStateChanged(bool have_pending_tree) {
[email protected]a8a049c2013-03-11 23:27:06231 // Thread-only feature.
232 NOTREACHED();
[email protected]2e7ca422012-12-20 02:57:27233}
234
[email protected]a8a049c2013-03-11 23:27:06235void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
236 // Thread-only feature.
237 NOTREACHED();
[email protected]6b16679e2012-10-27 00:44:28238}
239
[email protected]a8a049c2013-03-11 23:27:06240bool SingleThreadProxy::CommitRequested() const { return false; }
241
242size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
243 return std::numeric_limits<size_t>::max();
244}
245
246void SingleThreadProxy::Stop() {
247 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
248 DCHECK(Proxy::IsMainThread());
249 {
250 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
251 DebugScopedSetImplThread impl(this);
252
[email protected]804c8982013-03-13 16:32:21253 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27254 layer_tree_host_impl_->resource_provider());
[email protected]a8a049c2013-03-11 23:27:06255 layer_tree_host_impl_.reset();
256 }
[email protected]7aba6662013-03-12 10:17:34257 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06258}
259
[email protected]3d9f7432013-04-06 00:35:18260void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
261 DCHECK(Proxy::IsImplThread());
262 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(!ShouldComposite());
263}
264
[email protected]c1bb5af2013-03-13 19:06:27265void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]804c8982013-03-13 16:32:21266 layer_tree_host_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06267}
268
[email protected]1cd9f5552013-04-26 04:22:03269void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) {
270 // FIXME: Once we move render_widget scheduling into this class, we can
271 // treat redraw requests more efficiently than CommitAndRedraw requests.
272 layer_tree_host_impl_->SetViewportDamage(damage_rect);
273 SetNeedsCommit();
274}
275
[email protected]86126792013-03-16 20:07:54276void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06277 // Impl-side painting only.
278 NOTREACHED();
279}
280
[email protected]c1bb5af2013-03-13 19:06:27281void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]804c8982013-03-13 16:32:21282 layer_tree_host_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06283}
284
[email protected]c1bb5af2013-03-13 19:06:27285void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
[email protected]804c8982013-03-13 16:32:21286 layer_tree_host_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06287}
288
[email protected]c1bb5af2013-03-13 19:06:27289void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06290 scoped_ptr<AnimationEventsVector> events,
291 base::Time wall_clock_time) {
292 DCHECK(Proxy::IsImplThread());
293 DebugScopedSetMainThread main(this);
[email protected]804c8982013-03-13 16:32:21294 layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time);
[email protected]a8a049c2013-03-11 23:27:06295}
296
[email protected]c1bb5af2013-03-13 19:06:27297bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06298 size_t limit_bytes,
299 int priority_cutoff) {
300 DCHECK(IsImplThread());
[email protected]804c8982013-03-13 16:32:21301 if (!layer_tree_host_->contents_texture_manager())
[email protected]94f206c12012-08-25 00:09:14302 return false;
[email protected]a8a049c2013-03-11 23:27:06303
[email protected]b56c1302013-03-20 21:17:34304 return layer_tree_host_->contents_texture_manager()->ReduceMemoryOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27305 limit_bytes, priority_cutoff, layer_tree_host_impl_->resource_provider());
[email protected]94f206c12012-08-25 00:09:14306}
307
[email protected]c1bb5af2013-03-13 19:06:27308void SingleThreadProxy::ReduceWastedContentsTextureMemoryOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06309 // Impl-side painting only.
310 NOTREACHED();
[email protected]493067512012-09-19 23:34:10311}
312
[email protected]c1bb5af2013-03-13 19:06:27313void SingleThreadProxy::SendManagedMemoryStats() {
[email protected]a8a049c2013-03-11 23:27:06314 DCHECK(Proxy::IsImplThread());
[email protected]384b2c5e2013-04-23 01:02:22315 if (!layer_tree_host_impl_)
[email protected]a8a049c2013-03-11 23:27:06316 return;
[email protected]804c8982013-03-13 16:32:21317 if (!layer_tree_host_->contents_texture_manager())
[email protected]a8a049c2013-03-11 23:27:06318 return;
[email protected]94f206c12012-08-25 00:09:14319
[email protected]804c8982013-03-13 16:32:21320 PrioritizedResourceManager* contents_texture_manager =
321 layer_tree_host_->contents_texture_manager();
[email protected]c1bb5af2013-03-13 19:06:27322 layer_tree_host_impl_->SendManagedMemoryStats(
[email protected]b56c1302013-03-20 21:17:34323 contents_texture_manager->MemoryVisibleBytes(),
324 contents_texture_manager->MemoryVisibleAndNearbyBytes(),
325 contents_texture_manager->MemoryUseBytes());
[email protected]94f206c12012-08-25 00:09:14326}
327
[email protected]c1bb5af2013-03-13 19:06:27328bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06329
[email protected]2b154b22013-06-07 09:03:27330void SingleThreadProxy::DidTryInitializeRendererOnImplThread(
331 bool success,
332 scoped_refptr<ContextProvider> offscreen_context_provider) {
333 NOTREACHED()
334 << "This is only used on threaded compositing with impl-side painting";
335}
336
[email protected]c1bb5af2013-03-13 19:06:27337void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06338 // Cause a commit so we can notice the lost context.
[email protected]c1bb5af2013-03-13 19:06:27339 SetNeedsCommitOnImplThread();
[email protected]493067512012-09-19 23:34:10340}
341
[email protected]a8a049c2013-03-11 23:27:06342// Called by the legacy scheduling path (e.g. where render_widget does the
343// scheduling)
[email protected]f0c2a242013-03-15 19:34:52344void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
[email protected]e0341352013-04-06 05:01:20345 gfx::Rect device_viewport_damage_rect;
346
347 LayerTreeHostImpl::FrameData frame;
348 if (CommitAndComposite(frame_begin_time,
349 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39350 false, // for_readback
[email protected]e0341352013-04-06 05:01:20351 &frame)) {
352 layer_tree_host_impl_->SwapBuffers(frame);
[email protected]a8a049c2013-03-11 23:27:06353 DidSwapFrame();
354 }
[email protected]74d9063c2013-01-18 03:14:47355}
356
[email protected]a8a049c2013-03-11 23:27:06357scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
358 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
359 {
360 // The following line casts away const modifiers because it is just
361 // setting debug state. We still want the AsValue() function and its
362 // call chain to be const throughout.
363 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
364
365 state->Set("layer_tree_host_impl",
[email protected]c1bb5af2013-03-13 19:06:27366 layer_tree_host_impl_->AsValue().release());
[email protected]a8a049c2013-03-11 23:27:06367 }
368 return state.PassAs<base::Value>();
[email protected]493067512012-09-19 23:34:10369}
370
[email protected]a8a049c2013-03-11 23:27:06371void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
372 {
373 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20374 if (layer_tree_host_impl_->renderer()) {
375 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06376 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20377 }
[email protected]a8a049c2013-03-11 23:27:06378 }
[email protected]8947cbe2012-11-28 05:27:43379}
380
[email protected]e0341352013-04-06 05:01:20381bool SingleThreadProxy::CommitAndComposite(
382 base::TimeTicks frame_begin_time,
383 gfx::Rect device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39384 bool for_readback,
[email protected]e0341352013-04-06 05:01:20385 LayerTreeHostImpl::FrameData* frame) {
[email protected]a8a049c2013-03-11 23:27:06386 DCHECK(Proxy::IsMainThread());
[email protected]b1969fa2012-10-17 20:16:29387
[email protected]04049fc2013-05-01 03:13:20388 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded())
[email protected]16288a42012-12-17 23:31:05389 return false;
[email protected]a8a049c2013-03-11 23:27:06390
[email protected]d7763662013-05-09 18:14:37391 layer_tree_host_->AnimateLayers(frame_begin_time);
392
[email protected]a8a049c2013-03-11 23:27:06393 scoped_refptr<cc::ContextProvider> offscreen_context_provider;
[email protected]804c8982013-03-13 16:32:21394 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d &&
395 layer_tree_host_->needs_offscreen_context()) {
[email protected]a8a049c2013-03-11 23:27:06396 offscreen_context_provider =
397 layer_tree_host_->client()->OffscreenContextProviderForMainThread();
[email protected]22898ed2013-06-01 04:52:30398 if (offscreen_context_provider.get())
[email protected]e06e1122013-03-15 17:12:38399 created_offscreen_context_provider_ = true;
[email protected]a8a049c2013-03-11 23:27:06400 }
401
[email protected]6e8c54922013-06-02 19:17:35402 if (layer_tree_host_->contents_texture_manager()) {
403 layer_tree_host_->contents_texture_manager()
404 ->UnlinkAndClearEvictedBackings();
405 }
[email protected]a8a049c2013-03-11 23:27:06406
407 scoped_ptr<ResourceUpdateQueue> queue =
408 make_scoped_ptr(new ResourceUpdateQueue);
[email protected]804c8982013-03-13 16:32:21409 layer_tree_host_->UpdateLayers(
[email protected]c1bb5af2013-03-13 19:06:27410 queue.get(), layer_tree_host_impl_->memory_allocation_limit_bytes());
[email protected]a8a049c2013-03-11 23:27:06411
[email protected]804c8982013-03-13 16:32:21412 layer_tree_host_->WillCommit();
[email protected]a8a049c2013-03-11 23:27:06413 DoCommit(queue.Pass());
[email protected]e0341352013-04-06 05:01:20414 bool result = DoComposite(offscreen_context_provider,
415 frame_begin_time,
416 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39417 for_readback,
[email protected]e0341352013-04-06 05:01:20418 frame);
[email protected]804c8982013-03-13 16:32:21419 layer_tree_host_->DidBeginFrame();
[email protected]a8a049c2013-03-11 23:27:06420 return result;
[email protected]16288a42012-12-17 23:31:05421}
422
[email protected]3d9f7432013-04-06 00:35:18423bool SingleThreadProxy::ShouldComposite() const {
424 DCHECK(Proxy::IsImplThread());
425 return layer_tree_host_impl_->visible() &&
426 layer_tree_host_impl_->CanDraw();
427}
428
[email protected]a8a049c2013-03-11 23:27:06429bool SingleThreadProxy::DoComposite(
[email protected]f0c2a242013-03-15 19:34:52430 scoped_refptr<cc::ContextProvider> offscreen_context_provider,
[email protected]e0341352013-04-06 05:01:20431 base::TimeTicks frame_begin_time,
432 gfx::Rect device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39433 bool for_readback,
[email protected]e0341352013-04-06 05:01:20434 LayerTreeHostImpl::FrameData* frame) {
[email protected]04049fc2013-05-01 03:13:20435 DCHECK(!layer_tree_host_->output_surface_lost());
436
437 bool lost_output_surface = false;
[email protected]a8a049c2013-03-11 23:27:06438 {
439 DebugScopedSetImplThread impl(this);
440 base::AutoReset<bool> mark_inside(&inside_draw_, true);
441
[email protected]c1bb5af2013-03-13 19:06:27442 layer_tree_host_impl_->resource_provider()->
[email protected]e06e1122013-03-15 17:12:38443 set_offscreen_context_provider(offscreen_context_provider);
[email protected]a8a049c2013-03-11 23:27:06444
[email protected]2921d042013-05-10 05:01:39445 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
446
[email protected]3d9f7432013-04-06 00:35:18447 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
448 // frame, so can only be used when such a frame is possible. Since
449 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
450 // CanDraw() as well.
[email protected]2921d042013-05-10 05:01:39451 if (!ShouldComposite() || (for_readback && !can_do_readback)) {
[email protected]3d9f7432013-04-06 00:35:18452 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true);
[email protected]a8a049c2013-03-11 23:27:06453 return false;
[email protected]3d9f7432013-04-06 00:35:18454 }
[email protected]a8a049c2013-03-11 23:27:06455
[email protected]fb7425a2013-04-22 16:28:55456 layer_tree_host_impl_->Animate(
457 layer_tree_host_impl_->CurrentFrameTimeTicks(),
458 layer_tree_host_impl_->CurrentFrameTime());
[email protected]3d9f7432013-04-06 00:35:18459 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(false);
[email protected]a8a049c2013-03-11 23:27:06460
[email protected]e0341352013-04-06 05:01:20461 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect);
462 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
463 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]04049fc2013-05-01 03:13:20464 lost_output_surface = layer_tree_host_impl_->IsContextLost();
[email protected]a8a049c2013-03-11 23:27:06465
[email protected]3d9f7432013-04-06 00:35:18466 bool start_ready_animations = true;
467 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
468
[email protected]8347d692013-05-17 23:22:38469 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
[email protected]a8a049c2013-03-11 23:27:06470 }
471
[email protected]04049fc2013-05-01 03:13:20472 if (lost_output_surface) {
[email protected]a8a049c2013-03-11 23:27:06473 cc::ContextProvider* offscreen_contexts = layer_tree_host_impl_->
[email protected]c1bb5af2013-03-13 19:06:27474 resource_provider()->offscreen_context_provider();
[email protected]a8a049c2013-03-11 23:27:06475 if (offscreen_contexts)
476 offscreen_contexts->VerifyContexts();
[email protected]804c8982013-03-13 16:32:21477 layer_tree_host_->DidLoseOutputSurface();
[email protected]a8a049c2013-03-11 23:27:06478 return false;
479 }
480
481 return true;
482}
483
484void SingleThreadProxy::DidSwapFrame() {
485 if (next_frame_is_newly_committed_frame_) {
486 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21487 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06488 }
489}
490
491bool SingleThreadProxy::CommitPendingForTesting() { return false; }
492
493skia::RefPtr<SkPicture> SingleThreadProxy::CapturePicture() {
494 // Impl-side painting only.
495 NOTREACHED();
496 return skia::RefPtr<SkPicture>();
[email protected]b9dcf43a2013-01-09 00:15:29497}
498
[email protected]bc5e77c2012-11-05 20:00:49499} // namespace cc