blob: 2b49d31c62b5844177669a98674105b61afd3be7 [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]7f0d825f2013-03-18 07:24:309#include "cc/output/context_provider.h"
10#include "cc/output/output_surface.h"
[email protected]89e82672013-03-18 07:50:5611#include "cc/quads/draw_quad.h"
[email protected]e12dd0e2013-03-18 08:24:4012#include "cc/resources/prioritized_resource_manager.h"
13#include "cc/resources/resource_update_controller.h"
[email protected]556fd292013-03-18 08:03:0414#include "cc/trees/layer_tree_host.h"
15#include "cc/trees/layer_tree_impl.h"
[email protected]94f206c12012-08-25 00:09:1416
[email protected]9c88e562012-09-14 22:21:3017namespace cc {
[email protected]94f206c12012-08-25 00:09:1418
[email protected]a8a049c2013-03-11 23:27:0619scoped_ptr<Proxy> SingleThreadProxy::Create(LayerTreeHost* layer_tree_host) {
20 return make_scoped_ptr(
21 new SingleThreadProxy(layer_tree_host)).PassAs<Proxy>();
[email protected]94f206c12012-08-25 00:09:1422}
23
[email protected]a8a049c2013-03-11 23:27:0624SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host)
[email protected]810d40b72013-06-20 18:26:1525 : Proxy(NULL),
[email protected]a8a049c2013-03-11 23:27:0626 layer_tree_host_(layer_tree_host),
[email protected]e06e1122013-03-15 17:12:3827 created_offscreen_context_provider_(false),
[email protected]a8a049c2013-03-11 23:27:0628 next_frame_is_newly_committed_frame_(false),
[email protected]ccd6d9d2013-03-30 19:08:5829 inside_draw_(false) {
[email protected]a8a049c2013-03-11 23:27:0630 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
31 DCHECK(Proxy::IsMainThread());
32 DCHECK(layer_tree_host);
[email protected]1e4c352b2013-01-10 02:05:2333
[email protected]089102b2013-03-14 03:54:5634 // Impl-side painting not supported without threaded compositing.
[email protected]d9c086a2013-04-17 16:12:4835 CHECK(!layer_tree_host->settings().impl_side_painting)
36 << "Threaded compositing must be enabled to use impl-side painting.";
[email protected]94f206c12012-08-25 00:09:1437}
38
[email protected]04049fc2013-05-01 03:13:2039void SingleThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) {
40 DCHECK(first_output_surface);
[email protected]a8a049c2013-03-11 23:27:0641 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:2142 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]04049fc2013-05-01 03:13:2043 first_output_surface_ = first_output_surface.Pass();
[email protected]a8a049c2013-03-11 23:27:0644}
45
46SingleThreadProxy::~SingleThreadProxy() {
47 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
48 DCHECK(Proxy::IsMainThread());
[email protected]04049fc2013-05-01 03:13:2049 // Make sure Stop() got called or never Started.
50 DCHECK(!layer_tree_host_impl_);
[email protected]a8a049c2013-03-11 23:27:0651}
52
53bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
[email protected]ed511b8d2013-03-25 03:29:2954 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback");
[email protected]a8a049c2013-03-11 23:27:0655 DCHECK(Proxy::IsMainThread());
56
[email protected]e0341352013-04-06 05:01:2057 gfx::Rect device_viewport_damage_rect = rect;
58
59 LayerTreeHostImpl::FrameData frame;
60 if (!CommitAndComposite(base::TimeTicks::Now(),
61 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:3962 true, // for_readback
[email protected]e0341352013-04-06 05:01:2063 &frame))
[email protected]a8a049c2013-03-11 23:27:0664 return false;
65
66 {
[email protected]61de5812012-11-08 07:03:4467 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2768 layer_tree_host_impl_->Readback(pixels, rect);
[email protected]a8a049c2013-03-11 23:27:0669
[email protected]c1bb5af2013-03-13 19:06:2770 if (layer_tree_host_impl_->IsContextLost())
[email protected]a8a049c2013-03-11 23:27:0671 return false;
72
[email protected]e0341352013-04-06 05:01:2073 layer_tree_host_impl_->SwapBuffers(frame);
[email protected]a8a049c2013-03-11 23:27:0674 }
75 DidSwapFrame();
76
77 return true;
[email protected]94f206c12012-08-25 00:09:1478}
79
[email protected]a8a049c2013-03-11 23:27:0680void SingleThreadProxy::FinishAllRendering() {
81 DCHECK(Proxy::IsMainThread());
82 {
[email protected]61de5812012-11-08 07:03:4483 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2784 layer_tree_host_impl_->FinishAllRendering();
[email protected]a8a049c2013-03-11 23:27:0685 }
[email protected]94f206c12012-08-25 00:09:1486}
87
[email protected]a8a049c2013-03-11 23:27:0688bool SingleThreadProxy::IsStarted() const {
89 DCHECK(Proxy::IsMainThread());
[email protected]3209161d2013-03-29 19:17:3490 return layer_tree_host_impl_;
[email protected]94f206c12012-08-25 00:09:1491}
92
[email protected]14bd5542013-05-08 21:51:3093void SingleThreadProxy::SetLayerTreeHostClientReady() {
[email protected]a8a049c2013-03-11 23:27:0694 // Scheduling is controlled by the embedder in the single thread case, so
95 // nothing to do.
96}
97
98void SingleThreadProxy::SetVisible(bool visible) {
[email protected]f7c01c82013-07-02 22:58:4699 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:27100 layer_tree_host_impl_->SetVisible(visible);
[email protected]8ea875b2013-08-07 00:32:12101
102 // Changing visibility could change ShouldComposite().
103 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(!ShouldComposite());
[email protected]a8a049c2013-03-11 23:27:06104}
105
[email protected]04049fc2013-05-01 03:13:20106void SingleThreadProxy::CreateAndInitializeOutputSurface() {
107 TRACE_EVENT0(
108 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
[email protected]a8a049c2013-03-11 23:27:06109 DCHECK(Proxy::IsMainThread());
[email protected]94f206c12012-08-25 00:09:14110
[email protected]04049fc2013-05-01 03:13:20111 scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass();
[email protected]486544b2013-04-26 18:46:22112 if (!output_surface)
[email protected]04049fc2013-05-01 03:13:20113 output_surface = layer_tree_host_->CreateOutputSurface();
114 if (!output_surface) {
115 OnOutputSurfaceInitializeAttempted(false);
116 return;
117 }
118
[email protected]a8a049c2013-03-11 23:27:06119 scoped_refptr<cc::ContextProvider> offscreen_context_provider;
[email protected]e06e1122013-03-15 17:12:38120 if (created_offscreen_context_provider_) {
[email protected]a8a049c2013-03-11 23:27:06121 offscreen_context_provider =
122 layer_tree_host_->client()->OffscreenContextProviderForMainThread();
[email protected]22898ed2013-06-01 04:52:30123 if (!offscreen_context_provider.get()) {
[email protected]04049fc2013-05-01 03:13:20124 OnOutputSurfaceInitializeAttempted(false);
125 return;
126 }
[email protected]a8a049c2013-03-11 23:27:06127 }
128
[email protected]a8a049c2013-03-11 23:27:06129 {
130 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
131 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:21132 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27133 layer_tree_host_impl_->resource_provider());
[email protected]04049fc2013-05-01 03:13:20134 }
135
136 bool initialized;
137 {
138 DebugScopedSetImplThread impl(this);
139
140 DCHECK(output_surface);
141 initialized = layer_tree_host_impl_->InitializeRenderer(
142 output_surface.Pass());
[email protected]a8a049c2013-03-11 23:27:06143 if (initialized) {
144 renderer_capabilities_for_main_thread_ =
[email protected]c1bb5af2013-03-13 19:06:27145 layer_tree_host_impl_->GetRendererCapabilities();
[email protected]04049fc2013-05-01 03:13:20146
[email protected]e06e1122013-03-15 17:12:38147 layer_tree_host_impl_->resource_provider()->
148 set_offscreen_context_provider(offscreen_context_provider);
[email protected]22898ed2013-06-01 04:52:30149 } else if (offscreen_context_provider.get()) {
[email protected]a8a049c2013-03-11 23:27:06150 offscreen_context_provider->VerifyContexts();
[email protected]94f206c12012-08-25 00:09:14151 }
[email protected]a8a049c2013-03-11 23:27:06152 }
[email protected]94f206c12012-08-25 00:09:14153
[email protected]04049fc2013-05-01 03:13:20154 OnOutputSurfaceInitializeAttempted(initialized);
155}
[email protected]94f206c12012-08-25 00:09:14156
[email protected]04049fc2013-05-01 03:13:20157void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) {
158 LayerTreeHost::CreateResult result =
159 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
160 if (result == LayerTreeHost::CreateFailedButTryAgain) {
161 // Force another recreation attempt to happen by requesting another commit.
162 SetNeedsCommit();
163 }
[email protected]94f206c12012-08-25 00:09:14164}
165
[email protected]a8a049c2013-03-11 23:27:06166const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20167 DCHECK(Proxy::IsMainThread());
168 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06169 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14170}
171
[email protected]a8a049c2013-03-11 23:27:06172void SingleThreadProxy::SetNeedsAnimate() {
173 // Thread-only feature.
174 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14175}
176
[email protected]3519b872013-07-30 07:17:50177void SingleThreadProxy::SetNeedsUpdateLayers() {
178 DCHECK(Proxy::IsMainThread());
179 layer_tree_host_->ScheduleComposite();
180}
181
[email protected]a8a049c2013-03-11 23:27:06182void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
183 DCHECK(Proxy::IsMainThread());
184 // Commit immediately.
185 {
[email protected]f7c01c82013-07-02 22:58:46186 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
187 DebugScopedSetImplThread impl(this);
188
[email protected]372bad5f2013-03-21 16:38:43189 RenderingStatsInstrumentation* stats_instrumentation =
190 layer_tree_host_->rendering_stats_instrumentation();
[email protected]ed511b8d2013-03-25 03:29:29191 base::TimeTicks start_time = stats_instrumentation->StartRecording();
[email protected]372bad5f2013-03-21 16:38:43192
[email protected]c1bb5af2013-03-13 19:06:27193 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14194
[email protected]6e8c54922013-06-02 19:17:35195 if (layer_tree_host_->contents_texture_manager()) {
196 layer_tree_host_->contents_texture_manager()->
197 PushTexturePrioritiesToBackings();
198 }
[email protected]804c8982013-03-13 16:32:21199 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14200
[email protected]ed511b8d2013-03-25 03:29:29201 scoped_ptr<ResourceUpdateController> update_controller =
[email protected]a8a049c2013-03-11 23:27:06202 ResourceUpdateController::Create(
203 NULL,
[email protected]810d40b72013-06-20 18:26:15204 Proxy::MainThreadTaskRunner(),
[email protected]a8a049c2013-03-11 23:27:06205 queue.Pass(),
[email protected]c1bb5af2013-03-13 19:06:27206 layer_tree_host_impl_->resource_provider());
[email protected]ed511b8d2013-03-25 03:29:29207 update_controller->Finalize();
[email protected]94f206c12012-08-25 00:09:14208
[email protected]804c8982013-03-13 16:32:21209 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14210
[email protected]c1bb5af2013-03-13 19:06:27211 layer_tree_host_impl_->CommitComplete();
[email protected]94f206c12012-08-25 00:09:14212
[email protected]1d993172012-10-18 18:15:04213#ifndef NDEBUG
[email protected]3519b872013-07-30 07:17:50214 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06215 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29216 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27217 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29218 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50219 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14220#endif
[email protected]8b9af6b2012-09-27 00:36:36221
[email protected]ed511b8d2013-03-25 03:29:29222 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time);
[email protected]372bad5f2013-03-21 16:38:43223 stats_instrumentation->AddCommit(duration);
[email protected]c1e6cc062013-08-24 03:35:35224 stats_instrumentation->IssueTraceEventForMainThreadStats();
[email protected]a9dc0d0f2013-08-17 02:43:18225 stats_instrumentation->AccumulateAndClearMainThreadStats();
[email protected]a8a049c2013-03-11 23:27:06226 }
[email protected]804c8982013-03-13 16:32:21227 layer_tree_host_->CommitComplete();
[email protected]a8a049c2013-03-11 23:27:06228 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14229}
230
[email protected]a8a049c2013-03-11 23:27:06231void SingleThreadProxy::SetNeedsCommit() {
232 DCHECK(Proxy::IsMainThread());
[email protected]804c8982013-03-13 16:32:21233 layer_tree_host_->ScheduleComposite();
[email protected]94f206c12012-08-25 00:09:14234}
235
[email protected]b9d4a362013-04-23 05:36:27236void SingleThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03237 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14238}
239
[email protected]a8a049c2013-03-11 23:27:06240void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
241 // Thread-only feature.
242 NOTREACHED();
[email protected]6b16679e2012-10-27 00:44:28243}
244
[email protected]a8a049c2013-03-11 23:27:06245bool SingleThreadProxy::CommitRequested() const { return false; }
246
247size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
248 return std::numeric_limits<size_t>::max();
249}
250
251void SingleThreadProxy::Stop() {
252 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
253 DCHECK(Proxy::IsMainThread());
254 {
255 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
256 DebugScopedSetImplThread impl(this);
257
[email protected]804c8982013-03-13 16:32:21258 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27259 layer_tree_host_impl_->resource_provider());
[email protected]a8a049c2013-03-11 23:27:06260 layer_tree_host_impl_.reset();
261 }
[email protected]7aba6662013-03-12 10:17:34262 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06263}
264
[email protected]3d9f7432013-04-06 00:35:18265void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
266 DCHECK(Proxy::IsImplThread());
267 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(!ShouldComposite());
268}
269
[email protected]4f48f6e2013-08-27 06:33:38270void SingleThreadProxy::NotifyReadyToActivate() {
271 // Thread-only feature.
272 NOTREACHED();
273}
274
[email protected]c1bb5af2013-03-13 19:06:27275void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]804c8982013-03-13 16:32:21276 layer_tree_host_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06277}
278
[email protected]1cd9f5552013-04-26 04:22:03279void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) {
[email protected]27d851ab2013-06-28 01:09:50280 // TODO(brianderson): Once we move render_widget scheduling into this class,
281 // we can treat redraw requests more efficiently than CommitAndRedraw
282 // requests.
[email protected]1cd9f5552013-04-26 04:22:03283 layer_tree_host_impl_->SetViewportDamage(damage_rect);
284 SetNeedsCommit();
285}
286
[email protected]86126792013-03-16 20:07:54287void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06288 // Impl-side painting only.
289 NOTREACHED();
290}
291
[email protected]c1bb5af2013-03-13 19:06:27292void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]804c8982013-03-13 16:32:21293 layer_tree_host_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06294}
295
[email protected]c1bb5af2013-03-13 19:06:27296void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06297 scoped_ptr<AnimationEventsVector> events,
298 base::Time wall_clock_time) {
299 DCHECK(Proxy::IsImplThread());
300 DebugScopedSetMainThread main(this);
[email protected]804c8982013-03-13 16:32:21301 layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time);
[email protected]a8a049c2013-03-11 23:27:06302}
303
[email protected]c1bb5af2013-03-13 19:06:27304bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06305 size_t limit_bytes,
306 int priority_cutoff) {
307 DCHECK(IsImplThread());
[email protected]804c8982013-03-13 16:32:21308 if (!layer_tree_host_->contents_texture_manager())
[email protected]94f206c12012-08-25 00:09:14309 return false;
[email protected]a8a049c2013-03-11 23:27:06310
[email protected]b56c1302013-03-20 21:17:34311 return layer_tree_host_->contents_texture_manager()->ReduceMemoryOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27312 limit_bytes, priority_cutoff, layer_tree_host_impl_->resource_provider());
[email protected]94f206c12012-08-25 00:09:14313}
314
[email protected]c1bb5af2013-03-13 19:06:27315void SingleThreadProxy::ReduceWastedContentsTextureMemoryOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06316 // Impl-side painting only.
317 NOTREACHED();
[email protected]493067512012-09-19 23:34:10318}
319
[email protected]c1bb5af2013-03-13 19:06:27320void SingleThreadProxy::SendManagedMemoryStats() {
[email protected]a8a049c2013-03-11 23:27:06321 DCHECK(Proxy::IsImplThread());
[email protected]384b2c5e2013-04-23 01:02:22322 if (!layer_tree_host_impl_)
[email protected]a8a049c2013-03-11 23:27:06323 return;
[email protected]804c8982013-03-13 16:32:21324 if (!layer_tree_host_->contents_texture_manager())
[email protected]a8a049c2013-03-11 23:27:06325 return;
[email protected]94f206c12012-08-25 00:09:14326
[email protected]804c8982013-03-13 16:32:21327 PrioritizedResourceManager* contents_texture_manager =
328 layer_tree_host_->contents_texture_manager();
[email protected]c1bb5af2013-03-13 19:06:27329 layer_tree_host_impl_->SendManagedMemoryStats(
[email protected]b56c1302013-03-20 21:17:34330 contents_texture_manager->MemoryVisibleBytes(),
331 contents_texture_manager->MemoryVisibleAndNearbyBytes(),
332 contents_texture_manager->MemoryUseBytes());
[email protected]94f206c12012-08-25 00:09:14333}
334
[email protected]c1bb5af2013-03-13 19:06:27335bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06336
[email protected]2b154b22013-06-07 09:03:27337void SingleThreadProxy::DidTryInitializeRendererOnImplThread(
338 bool success,
339 scoped_refptr<ContextProvider> offscreen_context_provider) {
340 NOTREACHED()
341 << "This is only used on threaded compositing with impl-side painting";
342}
343
[email protected]c1bb5af2013-03-13 19:06:27344void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06345 // Cause a commit so we can notice the lost context.
[email protected]c1bb5af2013-03-13 19:06:27346 SetNeedsCommitOnImplThread();
[email protected]493067512012-09-19 23:34:10347}
348
[email protected]a8a049c2013-03-11 23:27:06349// Called by the legacy scheduling path (e.g. where render_widget does the
350// scheduling)
[email protected]f0c2a242013-03-15 19:34:52351void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
[email protected]e0341352013-04-06 05:01:20352 gfx::Rect device_viewport_damage_rect;
353
354 LayerTreeHostImpl::FrameData frame;
355 if (CommitAndComposite(frame_begin_time,
356 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39357 false, // for_readback
[email protected]e0341352013-04-06 05:01:20358 &frame)) {
359 layer_tree_host_impl_->SwapBuffers(frame);
[email protected]a8a049c2013-03-11 23:27:06360 DidSwapFrame();
361 }
[email protected]74d9063c2013-01-18 03:14:47362}
363
[email protected]a8a049c2013-03-11 23:27:06364scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
365 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
366 {
367 // The following line casts away const modifiers because it is just
368 // setting debug state. We still want the AsValue() function and its
369 // call chain to be const throughout.
370 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
371
372 state->Set("layer_tree_host_impl",
[email protected]c1bb5af2013-03-13 19:06:27373 layer_tree_host_impl_->AsValue().release());
[email protected]a8a049c2013-03-11 23:27:06374 }
375 return state.PassAs<base::Value>();
[email protected]493067512012-09-19 23:34:10376}
377
[email protected]a8a049c2013-03-11 23:27:06378void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
379 {
380 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20381 if (layer_tree_host_impl_->renderer()) {
382 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06383 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20384 }
[email protected]a8a049c2013-03-11 23:27:06385 }
[email protected]8947cbe2012-11-28 05:27:43386}
387
[email protected]e0341352013-04-06 05:01:20388bool SingleThreadProxy::CommitAndComposite(
389 base::TimeTicks frame_begin_time,
390 gfx::Rect device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39391 bool for_readback,
[email protected]e0341352013-04-06 05:01:20392 LayerTreeHostImpl::FrameData* frame) {
[email protected]a8a049c2013-03-11 23:27:06393 DCHECK(Proxy::IsMainThread());
[email protected]b1969fa2012-10-17 20:16:29394
[email protected]04049fc2013-05-01 03:13:20395 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded())
[email protected]16288a42012-12-17 23:31:05396 return false;
[email protected]a8a049c2013-03-11 23:27:06397
[email protected]d7763662013-05-09 18:14:37398 layer_tree_host_->AnimateLayers(frame_begin_time);
399
[email protected]a8a049c2013-03-11 23:27:06400 scoped_refptr<cc::ContextProvider> offscreen_context_provider;
[email protected]804c8982013-03-13 16:32:21401 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d &&
402 layer_tree_host_->needs_offscreen_context()) {
[email protected]a8a049c2013-03-11 23:27:06403 offscreen_context_provider =
404 layer_tree_host_->client()->OffscreenContextProviderForMainThread();
[email protected]22898ed2013-06-01 04:52:30405 if (offscreen_context_provider.get())
[email protected]e06e1122013-03-15 17:12:38406 created_offscreen_context_provider_ = true;
[email protected]a8a049c2013-03-11 23:27:06407 }
408
[email protected]6e8c54922013-06-02 19:17:35409 if (layer_tree_host_->contents_texture_manager()) {
410 layer_tree_host_->contents_texture_manager()
411 ->UnlinkAndClearEvictedBackings();
412 }
[email protected]a8a049c2013-03-11 23:27:06413
414 scoped_ptr<ResourceUpdateQueue> queue =
415 make_scoped_ptr(new ResourceUpdateQueue);
[email protected]804c8982013-03-13 16:32:21416 layer_tree_host_->UpdateLayers(
[email protected]c1bb5af2013-03-13 19:06:27417 queue.get(), layer_tree_host_impl_->memory_allocation_limit_bytes());
[email protected]a8a049c2013-03-11 23:27:06418
[email protected]804c8982013-03-13 16:32:21419 layer_tree_host_->WillCommit();
[email protected]a8a049c2013-03-11 23:27:06420 DoCommit(queue.Pass());
[email protected]e0341352013-04-06 05:01:20421 bool result = DoComposite(offscreen_context_provider,
422 frame_begin_time,
423 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39424 for_readback,
[email protected]e0341352013-04-06 05:01:20425 frame);
[email protected]804c8982013-03-13 16:32:21426 layer_tree_host_->DidBeginFrame();
[email protected]a8a049c2013-03-11 23:27:06427 return result;
[email protected]16288a42012-12-17 23:31:05428}
429
[email protected]3d9f7432013-04-06 00:35:18430bool SingleThreadProxy::ShouldComposite() const {
431 DCHECK(Proxy::IsImplThread());
432 return layer_tree_host_impl_->visible() &&
433 layer_tree_host_impl_->CanDraw();
434}
435
[email protected]a8a049c2013-03-11 23:27:06436bool SingleThreadProxy::DoComposite(
[email protected]f0c2a242013-03-15 19:34:52437 scoped_refptr<cc::ContextProvider> offscreen_context_provider,
[email protected]e0341352013-04-06 05:01:20438 base::TimeTicks frame_begin_time,
439 gfx::Rect device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39440 bool for_readback,
[email protected]e0341352013-04-06 05:01:20441 LayerTreeHostImpl::FrameData* frame) {
[email protected]04049fc2013-05-01 03:13:20442 DCHECK(!layer_tree_host_->output_surface_lost());
443
444 bool lost_output_surface = false;
[email protected]a8a049c2013-03-11 23:27:06445 {
446 DebugScopedSetImplThread impl(this);
447 base::AutoReset<bool> mark_inside(&inside_draw_, true);
448
[email protected]c1bb5af2013-03-13 19:06:27449 layer_tree_host_impl_->resource_provider()->
[email protected]e06e1122013-03-15 17:12:38450 set_offscreen_context_provider(offscreen_context_provider);
[email protected]a8a049c2013-03-11 23:27:06451
[email protected]2921d042013-05-10 05:01:39452 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
453
[email protected]3d9f7432013-04-06 00:35:18454 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
455 // frame, so can only be used when such a frame is possible. Since
456 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
457 // CanDraw() as well.
[email protected]2921d042013-05-10 05:01:39458 if (!ShouldComposite() || (for_readback && !can_do_readback)) {
[email protected]3d9f7432013-04-06 00:35:18459 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true);
[email protected]a8a049c2013-03-11 23:27:06460 return false;
[email protected]3d9f7432013-04-06 00:35:18461 }
[email protected]a8a049c2013-03-11 23:27:06462
[email protected]fb7425a2013-04-22 16:28:55463 layer_tree_host_impl_->Animate(
464 layer_tree_host_impl_->CurrentFrameTimeTicks(),
465 layer_tree_host_impl_->CurrentFrameTime());
[email protected]3d9f7432013-04-06 00:35:18466 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(false);
[email protected]a8a049c2013-03-11 23:27:06467
[email protected]e0341352013-04-06 05:01:20468 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect);
469 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
470 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]04049fc2013-05-01 03:13:20471 lost_output_surface = layer_tree_host_impl_->IsContextLost();
[email protected]a8a049c2013-03-11 23:27:06472
[email protected]3d9f7432013-04-06 00:35:18473 bool start_ready_animations = true;
474 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
475
[email protected]8347d692013-05-17 23:22:38476 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
[email protected]a8a049c2013-03-11 23:27:06477 }
478
[email protected]04049fc2013-05-01 03:13:20479 if (lost_output_surface) {
[email protected]a8a049c2013-03-11 23:27:06480 cc::ContextProvider* offscreen_contexts = layer_tree_host_impl_->
[email protected]c1bb5af2013-03-13 19:06:27481 resource_provider()->offscreen_context_provider();
[email protected]a8a049c2013-03-11 23:27:06482 if (offscreen_contexts)
483 offscreen_contexts->VerifyContexts();
[email protected]804c8982013-03-13 16:32:21484 layer_tree_host_->DidLoseOutputSurface();
[email protected]a8a049c2013-03-11 23:27:06485 return false;
486 }
487
488 return true;
489}
490
491void SingleThreadProxy::DidSwapFrame() {
492 if (next_frame_is_newly_committed_frame_) {
493 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21494 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06495 }
496}
497
498bool SingleThreadProxy::CommitPendingForTesting() { return false; }
499
[email protected]bc5e77c2012-11-05 20:00:49500} // namespace cc