blob: 4e47b33093a8f77ee2b8f55b29b629e0d15c1a01 [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]9794fb32013-08-29 09:49:5914#include "cc/trees/blocking_task_runner.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)
[email protected]810d40b72013-06-20 18:26:1526 : Proxy(NULL),
[email protected]a8a049c2013-03-11 23:27:0627 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;
[email protected]a8a049c2013-03-11 23:27:0673 }
[email protected]a8a049c2013-03-11 23:27:0674
75 return true;
[email protected]94f206c12012-08-25 00:09:1476}
77
[email protected]a8a049c2013-03-11 23:27:0678void SingleThreadProxy::FinishAllRendering() {
79 DCHECK(Proxy::IsMainThread());
80 {
[email protected]61de5812012-11-08 07:03:4481 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2782 layer_tree_host_impl_->FinishAllRendering();
[email protected]a8a049c2013-03-11 23:27:0683 }
[email protected]94f206c12012-08-25 00:09:1484}
85
[email protected]a8a049c2013-03-11 23:27:0686bool SingleThreadProxy::IsStarted() const {
87 DCHECK(Proxy::IsMainThread());
[email protected]3209161d2013-03-29 19:17:3488 return layer_tree_host_impl_;
[email protected]94f206c12012-08-25 00:09:1489}
90
[email protected]14bd5542013-05-08 21:51:3091void SingleThreadProxy::SetLayerTreeHostClientReady() {
[email protected]a8a049c2013-03-11 23:27:0692 // Scheduling is controlled by the embedder in the single thread case, so
93 // nothing to do.
94}
95
96void SingleThreadProxy::SetVisible(bool visible) {
[email protected]f7c01c82013-07-02 22:58:4697 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2798 layer_tree_host_impl_->SetVisible(visible);
[email protected]8ea875b2013-08-07 00:32:1299
100 // Changing visibility could change ShouldComposite().
[email protected]d9fce6722013-08-30 01:10:01101 UpdateBackgroundAnimateTicking();
[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 =
[email protected]f10dc472013-09-27 03:31:59120 layer_tree_host_->client()->OffscreenContextProvider();
121 if (!offscreen_context_provider.get() ||
122 !offscreen_context_provider->BindToCurrentThread()) {
[email protected]04049fc2013-05-01 03:13:20123 OnOutputSurfaceInitializeAttempted(false);
124 return;
125 }
[email protected]a8a049c2013-03-11 23:27:06126 }
127
[email protected]a8a049c2013-03-11 23:27:06128 {
[email protected]819b9f52013-09-22 23:29:51129 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06130 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:21131 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27132 layer_tree_host_impl_->resource_provider());
[email protected]04049fc2013-05-01 03:13:20133 }
134
135 bool initialized;
136 {
137 DebugScopedSetImplThread impl(this);
138
139 DCHECK(output_surface);
140 initialized = layer_tree_host_impl_->InitializeRenderer(
141 output_surface.Pass());
[email protected]a8a049c2013-03-11 23:27:06142 if (initialized) {
143 renderer_capabilities_for_main_thread_ =
[email protected]c1bb5af2013-03-13 19:06:27144 layer_tree_host_impl_->GetRendererCapabilities();
[email protected]22898ed2013-06-01 04:52:30145 } else if (offscreen_context_provider.get()) {
[email protected]a8a049c2013-03-11 23:27:06146 offscreen_context_provider->VerifyContexts();
[email protected]b5174d712013-08-28 08:10:43147 offscreen_context_provider = NULL;
[email protected]94f206c12012-08-25 00:09:14148 }
[email protected]b5174d712013-08-28 08:10:43149
150 layer_tree_host_impl_->SetOffscreenContextProvider(
151 offscreen_context_provider);
[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]819b9f52013-09-22 23:29:51186 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46187 DebugScopedSetImplThread impl(this);
188
[email protected]9794fb32013-08-29 09:49:59189 // This CapturePostTasks should be destroyed before CommitComplete() is
190 // called since that goes out to the embedder, and we want the embedder
191 // to receive its callbacks before that.
192 BlockingTaskRunner::CapturePostTasks blocked;
193
[email protected]372bad5f2013-03-21 16:38:43194 RenderingStatsInstrumentation* stats_instrumentation =
195 layer_tree_host_->rendering_stats_instrumentation();
[email protected]ed511b8d2013-03-25 03:29:29196 base::TimeTicks start_time = stats_instrumentation->StartRecording();
[email protected]372bad5f2013-03-21 16:38:43197
[email protected]c1bb5af2013-03-13 19:06:27198 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14199
[email protected]6e8c54922013-06-02 19:17:35200 if (layer_tree_host_->contents_texture_manager()) {
201 layer_tree_host_->contents_texture_manager()->
202 PushTexturePrioritiesToBackings();
203 }
[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]810d40b72013-06-20 18:26:15209 Proxy::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]1d993172012-10-18 18:15:04221#ifndef NDEBUG
[email protected]3519b872013-07-30 07:17:50222 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06223 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29224 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27225 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29226 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50227 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14228#endif
[email protected]8b9af6b2012-09-27 00:36:36229
[email protected]ed511b8d2013-03-25 03:29:29230 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time);
[email protected]372bad5f2013-03-21 16:38:43231 stats_instrumentation->AddCommit(duration);
[email protected]c1e6cc062013-08-24 03:35:35232 stats_instrumentation->IssueTraceEventForMainThreadStats();
[email protected]a9dc0d0f2013-08-17 02:43:18233 stats_instrumentation->AccumulateAndClearMainThreadStats();
[email protected]a8a049c2013-03-11 23:27:06234 }
[email protected]804c8982013-03-13 16:32:21235 layer_tree_host_->CommitComplete();
[email protected]a8a049c2013-03-11 23:27:06236 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14237}
238
[email protected]a8a049c2013-03-11 23:27:06239void SingleThreadProxy::SetNeedsCommit() {
240 DCHECK(Proxy::IsMainThread());
[email protected]804c8982013-03-13 16:32:21241 layer_tree_host_->ScheduleComposite();
[email protected]94f206c12012-08-25 00:09:14242}
243
[email protected]b9d4a362013-04-23 05:36:27244void SingleThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03245 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]94f206c12012-08-25 00:09:14246}
247
[email protected]74b43cc2013-08-30 06:29:27248void SingleThreadProxy::SetNextCommitWaitsForActivation() {
249 // There is no activation here other than commit. So do nothing.
250}
251
[email protected]a8a049c2013-03-11 23:27:06252void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
253 // Thread-only feature.
254 NOTREACHED();
[email protected]6b16679e2012-10-27 00:44:28255}
256
[email protected]a8a049c2013-03-11 23:27:06257bool SingleThreadProxy::CommitRequested() const { return false; }
258
259size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
260 return std::numeric_limits<size_t>::max();
261}
262
263void SingleThreadProxy::Stop() {
264 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
265 DCHECK(Proxy::IsMainThread());
266 {
[email protected]819b9f52013-09-22 23:29:51267 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06268 DebugScopedSetImplThread impl(this);
269
[email protected]804c8982013-03-13 16:32:21270 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27271 layer_tree_host_impl_->resource_provider());
[email protected]a8a049c2013-03-11 23:27:06272 layer_tree_host_impl_.reset();
273 }
[email protected]7aba6662013-03-12 10:17:34274 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06275}
276
[email protected]3d9f7432013-04-06 00:35:18277void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
278 DCHECK(Proxy::IsImplThread());
[email protected]d9fce6722013-08-30 01:10:01279 UpdateBackgroundAnimateTicking();
[email protected]3d9f7432013-04-06 00:35:18280}
281
[email protected]4f48f6e2013-08-27 06:33:38282void SingleThreadProxy::NotifyReadyToActivate() {
283 // Thread-only feature.
284 NOTREACHED();
285}
286
[email protected]c1bb5af2013-03-13 19:06:27287void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]804c8982013-03-13 16:32:21288 layer_tree_host_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06289}
290
[email protected]c48536a52013-09-14 00:02:08291void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
292 // Thread-only/Impl-side-painting-only feature.
293 NOTREACHED();
294}
295
[email protected]1cd9f5552013-04-26 04:22:03296void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) {
[email protected]27d851ab2013-06-28 01:09:50297 // TODO(brianderson): Once we move render_widget scheduling into this class,
298 // we can treat redraw requests more efficiently than CommitAndRedraw
299 // requests.
[email protected]1cd9f5552013-04-26 04:22:03300 layer_tree_host_impl_->SetViewportDamage(damage_rect);
301 SetNeedsCommit();
302}
303
[email protected]86126792013-03-16 20:07:54304void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06305 // Impl-side painting only.
306 NOTREACHED();
307}
308
[email protected]c1bb5af2013-03-13 19:06:27309void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]804c8982013-03-13 16:32:21310 layer_tree_host_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06311}
312
[email protected]c1bb5af2013-03-13 19:06:27313void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06314 scoped_ptr<AnimationEventsVector> events,
315 base::Time wall_clock_time) {
316 DCHECK(Proxy::IsImplThread());
317 DebugScopedSetMainThread main(this);
[email protected]804c8982013-03-13 16:32:21318 layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time);
[email protected]a8a049c2013-03-11 23:27:06319}
320
[email protected]c1bb5af2013-03-13 19:06:27321bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06322 size_t limit_bytes,
323 int priority_cutoff) {
324 DCHECK(IsImplThread());
[email protected]804c8982013-03-13 16:32:21325 if (!layer_tree_host_->contents_texture_manager())
[email protected]94f206c12012-08-25 00:09:14326 return false;
[email protected]a8a049c2013-03-11 23:27:06327
[email protected]b56c1302013-03-20 21:17:34328 return layer_tree_host_->contents_texture_manager()->ReduceMemoryOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27329 limit_bytes, priority_cutoff, layer_tree_host_impl_->resource_provider());
[email protected]94f206c12012-08-25 00:09:14330}
331
[email protected]c1bb5af2013-03-13 19:06:27332void SingleThreadProxy::ReduceWastedContentsTextureMemoryOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06333 // Impl-side painting only.
334 NOTREACHED();
[email protected]493067512012-09-19 23:34:10335}
336
[email protected]c1bb5af2013-03-13 19:06:27337void SingleThreadProxy::SendManagedMemoryStats() {
[email protected]a8a049c2013-03-11 23:27:06338 DCHECK(Proxy::IsImplThread());
[email protected]384b2c5e2013-04-23 01:02:22339 if (!layer_tree_host_impl_)
[email protected]a8a049c2013-03-11 23:27:06340 return;
[email protected]804c8982013-03-13 16:32:21341 if (!layer_tree_host_->contents_texture_manager())
[email protected]a8a049c2013-03-11 23:27:06342 return;
[email protected]94f206c12012-08-25 00:09:14343
[email protected]804c8982013-03-13 16:32:21344 PrioritizedResourceManager* contents_texture_manager =
345 layer_tree_host_->contents_texture_manager();
[email protected]c1bb5af2013-03-13 19:06:27346 layer_tree_host_impl_->SendManagedMemoryStats(
[email protected]b56c1302013-03-20 21:17:34347 contents_texture_manager->MemoryVisibleBytes(),
348 contents_texture_manager->MemoryVisibleAndNearbyBytes(),
349 contents_texture_manager->MemoryUseBytes());
[email protected]94f206c12012-08-25 00:09:14350}
351
[email protected]c1bb5af2013-03-13 19:06:27352bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06353
[email protected]c1bb5af2013-03-13 19:06:27354void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06355 // Cause a commit so we can notice the lost context.
[email protected]c1bb5af2013-03-13 19:06:27356 SetNeedsCommitOnImplThread();
[email protected]493067512012-09-19 23:34:10357}
358
[email protected]a8a049c2013-03-11 23:27:06359// Called by the legacy scheduling path (e.g. where render_widget does the
360// scheduling)
[email protected]f0c2a242013-03-15 19:34:52361void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
[email protected]e0341352013-04-06 05:01:20362 gfx::Rect device_viewport_damage_rect;
363
364 LayerTreeHostImpl::FrameData frame;
365 if (CommitAndComposite(frame_begin_time,
366 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39367 false, // for_readback
[email protected]e0341352013-04-06 05:01:20368 &frame)) {
[email protected]819b9f52013-09-22 23:29:51369 {
370 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
371 DebugScopedSetImplThread impl(this);
372
373 // This CapturePostTasks should be destroyed before
374 // DidCommitAndDrawFrame() is called since that goes out to the embedder,
375 // and we want the embedder to receive its callbacks before that.
376 // NOTE: This maintains consistent ordering with the ThreadProxy since
377 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
378 // there as the main thread is not blocked, so any posted tasks inside
379 // the swap buffers will execute first.
380 BlockingTaskRunner::CapturePostTasks blocked;
381
382 layer_tree_host_impl_->SwapBuffers(frame);
383 }
[email protected]a8a049c2013-03-11 23:27:06384 DidSwapFrame();
385 }
[email protected]74d9063c2013-01-18 03:14:47386}
387
[email protected]a8a049c2013-03-11 23:27:06388scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
389 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
390 {
391 // The following line casts away const modifiers because it is just
392 // setting debug state. We still want the AsValue() function and its
393 // call chain to be const throughout.
394 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
395
396 state->Set("layer_tree_host_impl",
[email protected]c1bb5af2013-03-13 19:06:27397 layer_tree_host_impl_->AsValue().release());
[email protected]a8a049c2013-03-11 23:27:06398 }
399 return state.PassAs<base::Value>();
[email protected]493067512012-09-19 23:34:10400}
401
[email protected]a8a049c2013-03-11 23:27:06402void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
403 {
404 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20405 if (layer_tree_host_impl_->renderer()) {
406 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06407 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20408 }
[email protected]a8a049c2013-03-11 23:27:06409 }
[email protected]8947cbe2012-11-28 05:27:43410}
411
[email protected]e0341352013-04-06 05:01:20412bool SingleThreadProxy::CommitAndComposite(
413 base::TimeTicks frame_begin_time,
414 gfx::Rect device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39415 bool for_readback,
[email protected]e0341352013-04-06 05:01:20416 LayerTreeHostImpl::FrameData* frame) {
[email protected]a8a049c2013-03-11 23:27:06417 DCHECK(Proxy::IsMainThread());
[email protected]b1969fa2012-10-17 20:16:29418
[email protected]04049fc2013-05-01 03:13:20419 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded())
[email protected]16288a42012-12-17 23:31:05420 return false;
[email protected]a8a049c2013-03-11 23:27:06421
[email protected]d7763662013-05-09 18:14:37422 layer_tree_host_->AnimateLayers(frame_begin_time);
423
[email protected]6e8c54922013-06-02 19:17:35424 if (layer_tree_host_->contents_texture_manager()) {
425 layer_tree_host_->contents_texture_manager()
426 ->UnlinkAndClearEvictedBackings();
[email protected]990e050a2013-09-23 18:50:21427 layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
428 layer_tree_host_impl_->memory_allocation_limit_bytes());
429 layer_tree_host_->contents_texture_manager()->SetExternalPriorityCutoff(
430 layer_tree_host_impl_->memory_allocation_priority_cutoff());
[email protected]6e8c54922013-06-02 19:17:35431 }
[email protected]a8a049c2013-03-11 23:27:06432
433 scoped_ptr<ResourceUpdateQueue> queue =
434 make_scoped_ptr(new ResourceUpdateQueue);
[email protected]990e050a2013-09-23 18:50:21435 layer_tree_host_->UpdateLayers(queue.get());
[email protected]a8a049c2013-03-11 23:27:06436
[email protected]804c8982013-03-13 16:32:21437 layer_tree_host_->WillCommit();
[email protected]a024d0e2013-09-26 19:20:45438
439 scoped_refptr<cc::ContextProvider> offscreen_context_provider;
440 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d &&
441 layer_tree_host_->needs_offscreen_context()) {
442 offscreen_context_provider =
[email protected]f10dc472013-09-27 03:31:59443 layer_tree_host_->client()->OffscreenContextProvider();
444 if (offscreen_context_provider.get() &&
445 !offscreen_context_provider->BindToCurrentThread())
446 offscreen_context_provider = NULL;
447
[email protected]a024d0e2013-09-26 19:20:45448 if (offscreen_context_provider.get())
449 created_offscreen_context_provider_ = true;
450 }
451
[email protected]a8a049c2013-03-11 23:27:06452 DoCommit(queue.Pass());
[email protected]e0341352013-04-06 05:01:20453 bool result = DoComposite(offscreen_context_provider,
454 frame_begin_time,
455 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39456 for_readback,
[email protected]e0341352013-04-06 05:01:20457 frame);
[email protected]804c8982013-03-13 16:32:21458 layer_tree_host_->DidBeginFrame();
[email protected]a8a049c2013-03-11 23:27:06459 return result;
[email protected]16288a42012-12-17 23:31:05460}
461
[email protected]3d9f7432013-04-06 00:35:18462bool SingleThreadProxy::ShouldComposite() const {
463 DCHECK(Proxy::IsImplThread());
464 return layer_tree_host_impl_->visible() &&
465 layer_tree_host_impl_->CanDraw();
466}
467
[email protected]d9fce6722013-08-30 01:10:01468void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
469 DCHECK(Proxy::IsImplThread());
470 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
471 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
472}
473
[email protected]a8a049c2013-03-11 23:27:06474bool SingleThreadProxy::DoComposite(
[email protected]f0c2a242013-03-15 19:34:52475 scoped_refptr<cc::ContextProvider> offscreen_context_provider,
[email protected]e0341352013-04-06 05:01:20476 base::TimeTicks frame_begin_time,
477 gfx::Rect device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39478 bool for_readback,
[email protected]e0341352013-04-06 05:01:20479 LayerTreeHostImpl::FrameData* frame) {
[email protected]04049fc2013-05-01 03:13:20480 DCHECK(!layer_tree_host_->output_surface_lost());
481
482 bool lost_output_surface = false;
[email protected]a8a049c2013-03-11 23:27:06483 {
484 DebugScopedSetImplThread impl(this);
485 base::AutoReset<bool> mark_inside(&inside_draw_, true);
486
[email protected]b5174d712013-08-28 08:10:43487 layer_tree_host_impl_->SetOffscreenContextProvider(
488 offscreen_context_provider);
[email protected]a8a049c2013-03-11 23:27:06489
[email protected]2921d042013-05-10 05:01:39490 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
491
[email protected]3d9f7432013-04-06 00:35:18492 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
493 // frame, so can only be used when such a frame is possible. Since
494 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
495 // CanDraw() as well.
[email protected]2921d042013-05-10 05:01:39496 if (!ShouldComposite() || (for_readback && !can_do_readback)) {
[email protected]d9fce6722013-08-30 01:10:01497 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06498 return false;
[email protected]3d9f7432013-04-06 00:35:18499 }
[email protected]a8a049c2013-03-11 23:27:06500
[email protected]fb7425a2013-04-22 16:28:55501 layer_tree_host_impl_->Animate(
502 layer_tree_host_impl_->CurrentFrameTimeTicks(),
503 layer_tree_host_impl_->CurrentFrameTime());
[email protected]d9fce6722013-08-30 01:10:01504 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06505
[email protected]e0341352013-04-06 05:01:20506 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect);
507 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
508 layer_tree_host_impl_->DidDrawAllLayers(*frame);
[email protected]04049fc2013-05-01 03:13:20509 lost_output_surface = layer_tree_host_impl_->IsContextLost();
[email protected]a8a049c2013-03-11 23:27:06510
[email protected]3d9f7432013-04-06 00:35:18511 bool start_ready_animations = true;
512 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
513
[email protected]8347d692013-05-17 23:22:38514 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
[email protected]a8a049c2013-03-11 23:27:06515 }
516
[email protected]04049fc2013-05-01 03:13:20517 if (lost_output_surface) {
[email protected]b5174d712013-08-28 08:10:43518 cc::ContextProvider* offscreen_contexts =
519 layer_tree_host_impl_->offscreen_context_provider();
[email protected]a8a049c2013-03-11 23:27:06520 if (offscreen_contexts)
521 offscreen_contexts->VerifyContexts();
[email protected]804c8982013-03-13 16:32:21522 layer_tree_host_->DidLoseOutputSurface();
[email protected]a8a049c2013-03-11 23:27:06523 return false;
524 }
525
526 return true;
527}
528
529void SingleThreadProxy::DidSwapFrame() {
530 if (next_frame_is_newly_committed_frame_) {
531 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21532 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06533 }
534}
535
536bool SingleThreadProxy::CommitPendingForTesting() { return false; }
537
[email protected]bc5e77c2012-11-05 20:00:49538} // namespace cc