blob: f1f8a4f5824c8ca38fbc96620c5a9864ee8a5e95 [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]5195fc52013-12-03 22:57:4347void SingleThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) {
48 DCHECK(first_output_surface);
[email protected]a8a049c2013-03-11 23:27:0649 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:2150 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
[email protected]5195fc52013-12-03 22:57:4351 first_output_surface_ = first_output_surface.Pass();
[email protected]a8a049c2013-03-11 23:27:0652}
53
54SingleThreadProxy::~SingleThreadProxy() {
55 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
56 DCHECK(Proxy::IsMainThread());
[email protected]04049fc2013-05-01 03:13:2057 // Make sure Stop() got called or never Started.
58 DCHECK(!layer_tree_host_impl_);
[email protected]a8a049c2013-03-11 23:27:0659}
60
61bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
[email protected]ed511b8d2013-03-25 03:29:2962 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback");
[email protected]a8a049c2013-03-11 23:27:0663 DCHECK(Proxy::IsMainThread());
64
[email protected]e0341352013-04-06 05:01:2065 gfx::Rect device_viewport_damage_rect = rect;
66
67 LayerTreeHostImpl::FrameData frame;
[email protected]de2cf8c2013-10-25 19:46:4668 if (!CommitAndComposite(gfx::FrameTime::Now(),
[email protected]e0341352013-04-06 05:01:2069 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:3970 true, // for_readback
[email protected]e0341352013-04-06 05:01:2071 &frame))
[email protected]a8a049c2013-03-11 23:27:0672 return false;
73
74 {
[email protected]61de5812012-11-08 07:03:4475 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:2776 layer_tree_host_impl_->Readback(pixels, rect);
[email protected]a8a049c2013-03-11 23:27:0677
[email protected]c1bb5af2013-03-13 19:06:2778 if (layer_tree_host_impl_->IsContextLost())
[email protected]a8a049c2013-03-11 23:27:0679 return false;
[email protected]a8a049c2013-03-11 23:27:0680 }
[email protected]a8a049c2013-03-11 23:27:0681
82 return true;
[email protected]94f206c12012-08-25 00:09:1483}
84
[email protected]a8a049c2013-03-11 23:27:0685void SingleThreadProxy::FinishAllRendering() {
86 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]a8a049c2013-03-11 23:27:0699 // Scheduling is controlled by the embedder in the single thread case, so
100 // nothing to do.
101}
102
103void SingleThreadProxy::SetVisible(bool visible) {
[email protected]f7c01c82013-07-02 22:58:46104 DebugScopedSetImplThread impl(this);
[email protected]c1bb5af2013-03-13 19:06:27105 layer_tree_host_impl_->SetVisible(visible);
[email protected]8ea875b2013-08-07 00:32:12106
107 // Changing visibility could change ShouldComposite().
[email protected]d9fce6722013-08-30 01:10:01108 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06109}
110
[email protected]04049fc2013-05-01 03:13:20111void SingleThreadProxy::CreateAndInitializeOutputSurface() {
112 TRACE_EVENT0(
113 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
[email protected]a8a049c2013-03-11 23:27:06114 DCHECK(Proxy::IsMainThread());
[email protected]94f206c12012-08-25 00:09:14115
[email protected]5195fc52013-12-03 22:57:43116 scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass();
117 if (!output_surface)
118 output_surface = layer_tree_host_->CreateOutputSurface();
[email protected]04049fc2013-05-01 03:13:20119 if (!output_surface) {
120 OnOutputSurfaceInitializeAttempted(false);
121 return;
122 }
123
[email protected]e51444a2013-12-10 23:05:01124 scoped_refptr<ContextProvider> offscreen_context_provider;
[email protected]e06e1122013-03-15 17:12:38125 if (created_offscreen_context_provider_) {
[email protected]a8a049c2013-03-11 23:27:06126 offscreen_context_provider =
[email protected]f10dc472013-09-27 03:31:59127 layer_tree_host_->client()->OffscreenContextProvider();
128 if (!offscreen_context_provider.get() ||
129 !offscreen_context_provider->BindToCurrentThread()) {
[email protected]04049fc2013-05-01 03:13:20130 OnOutputSurfaceInitializeAttempted(false);
131 return;
132 }
[email protected]a8a049c2013-03-11 23:27:06133 }
134
[email protected]a8a049c2013-03-11 23:27:06135 {
[email protected]819b9f52013-09-22 23:29:51136 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06137 DebugScopedSetImplThread impl(this);
[email protected]804c8982013-03-13 16:32:21138 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27139 layer_tree_host_impl_->resource_provider());
[email protected]04049fc2013-05-01 03:13:20140 }
141
142 bool initialized;
143 {
144 DebugScopedSetImplThread impl(this);
145
146 DCHECK(output_surface);
147 initialized = layer_tree_host_impl_->InitializeRenderer(
148 output_surface.Pass());
[email protected]a8a049c2013-03-11 23:27:06149 if (initialized) {
150 renderer_capabilities_for_main_thread_ =
[email protected]c1bb5af2013-03-13 19:06:27151 layer_tree_host_impl_->GetRendererCapabilities();
[email protected]22898ed2013-06-01 04:52:30152 } else if (offscreen_context_provider.get()) {
[email protected]a8a049c2013-03-11 23:27:06153 offscreen_context_provider->VerifyContexts();
[email protected]b5174d712013-08-28 08:10:43154 offscreen_context_provider = NULL;
[email protected]94f206c12012-08-25 00:09:14155 }
[email protected]b5174d712013-08-28 08:10:43156
157 layer_tree_host_impl_->SetOffscreenContextProvider(
158 offscreen_context_provider);
[email protected]a8a049c2013-03-11 23:27:06159 }
[email protected]94f206c12012-08-25 00:09:14160
[email protected]04049fc2013-05-01 03:13:20161 OnOutputSurfaceInitializeAttempted(initialized);
162}
[email protected]94f206c12012-08-25 00:09:14163
[email protected]04049fc2013-05-01 03:13:20164void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) {
165 LayerTreeHost::CreateResult result =
166 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
167 if (result == LayerTreeHost::CreateFailedButTryAgain) {
168 // Force another recreation attempt to happen by requesting another commit.
169 SetNeedsCommit();
170 }
[email protected]94f206c12012-08-25 00:09:14171}
172
[email protected]a8a049c2013-03-11 23:27:06173const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
[email protected]04049fc2013-05-01 03:13:20174 DCHECK(Proxy::IsMainThread());
175 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06176 return renderer_capabilities_for_main_thread_;
[email protected]94f206c12012-08-25 00:09:14177}
178
[email protected]c5134172013-12-11 06:19:48179void SingleThreadProxy::SetNeedsAnimate() {
[email protected]3519b872013-07-30 07:17:50180 DCHECK(Proxy::IsMainThread());
[email protected]807f55e2013-12-11 04:11:29181 client_->ScheduleAnimation();
[email protected]3519b872013-07-30 07:17:50182}
183
[email protected]c5134172013-12-11 06:19:48184void SingleThreadProxy::SetNeedsUpdateLayers() {
185 DCHECK(Proxy::IsMainThread());
186 client_->ScheduleComposite();
187}
188
[email protected]a8a049c2013-03-11 23:27:06189void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
190 DCHECK(Proxy::IsMainThread());
191 // Commit immediately.
192 {
[email protected]819b9f52013-09-22 23:29:51193 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]f7c01c82013-07-02 22:58:46194 DebugScopedSetImplThread impl(this);
195
[email protected]9794fb32013-08-29 09:49:59196 // This CapturePostTasks should be destroyed before CommitComplete() is
197 // called since that goes out to the embedder, and we want the embedder
198 // to receive its callbacks before that.
199 BlockingTaskRunner::CapturePostTasks blocked;
200
[email protected]c1bb5af2013-03-13 19:06:27201 layer_tree_host_impl_->BeginCommit();
[email protected]94f206c12012-08-25 00:09:14202
[email protected]5d2fec02013-11-28 20:08:33203 if (PrioritizedResourceManager* contents_texture_manager =
204 layer_tree_host_->contents_texture_manager()) {
205 contents_texture_manager->PushTexturePrioritiesToBackings();
[email protected]6e8c54922013-06-02 19:17:35206 }
[email protected]804c8982013-03-13 16:32:21207 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14208
[email protected]ed511b8d2013-03-25 03:29:29209 scoped_ptr<ResourceUpdateController> update_controller =
[email protected]a8a049c2013-03-11 23:27:06210 ResourceUpdateController::Create(
211 NULL,
[email protected]810d40b72013-06-20 18:26:15212 Proxy::MainThreadTaskRunner(),
[email protected]a8a049c2013-03-11 23:27:06213 queue.Pass(),
[email protected]c1bb5af2013-03-13 19:06:27214 layer_tree_host_impl_->resource_provider());
[email protected]ed511b8d2013-03-25 03:29:29215 update_controller->Finalize();
[email protected]94f206c12012-08-25 00:09:14216
[email protected]127bdc1a2013-09-11 01:44:48217 if (layer_tree_host_impl_->EvictedUIResourcesExist())
218 layer_tree_host_->RecreateUIResources();
219
[email protected]804c8982013-03-13 16:32:21220 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
[email protected]94f206c12012-08-25 00:09:14221
[email protected]c1bb5af2013-03-13 19:06:27222 layer_tree_host_impl_->CommitComplete();
[email protected]94f206c12012-08-25 00:09:14223
[email protected]1d993172012-10-18 18:15:04224#ifndef NDEBUG
[email protected]3519b872013-07-30 07:17:50225 // In the single-threaded case, the scale and scroll deltas should never be
[email protected]a8a049c2013-03-11 23:27:06226 // touched on the impl layer tree.
[email protected]ed511b8d2013-03-25 03:29:29227 scoped_ptr<ScrollAndScaleSet> scroll_info =
[email protected]c1bb5af2013-03-13 19:06:27228 layer_tree_host_impl_->ProcessScrollDeltas();
[email protected]ed511b8d2013-03-25 03:29:29229 DCHECK(!scroll_info->scrolls.size());
[email protected]3519b872013-07-30 07:17:50230 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
[email protected]94f206c12012-08-25 00:09:14231#endif
[email protected]8b9af6b2012-09-27 00:36:36232
[email protected]922c6e1f2013-10-09 04:04:09233 RenderingStatsInstrumentation* stats_instrumentation =
234 layer_tree_host_->rendering_stats_instrumentation();
[email protected]adbe30f2013-10-11 21:12:33235 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent(
236 stats_instrumentation->main_thread_rendering_stats());
[email protected]a9dc0d0f2013-08-17 02:43:18237 stats_instrumentation->AccumulateAndClearMainThreadStats();
[email protected]a8a049c2013-03-11 23:27:06238 }
[email protected]804c8982013-03-13 16:32:21239 layer_tree_host_->CommitComplete();
[email protected]a8a049c2013-03-11 23:27:06240 next_frame_is_newly_committed_frame_ = true;
[email protected]94f206c12012-08-25 00:09:14241}
242
[email protected]a8a049c2013-03-11 23:27:06243void SingleThreadProxy::SetNeedsCommit() {
244 DCHECK(Proxy::IsMainThread());
[email protected]943528e2013-11-07 05:01:32245 client_->ScheduleComposite();
[email protected]94f206c12012-08-25 00:09:14246}
247
[email protected]b9d4a362013-04-23 05:36:27248void SingleThreadProxy::SetNeedsRedraw(gfx::Rect damage_rect) {
[email protected]1cd9f5552013-04-26 04:22:03249 SetNeedsRedrawRectOnImplThread(damage_rect);
[email protected]943528e2013-11-07 05:01:32250 client_->ScheduleComposite();
[email protected]94f206c12012-08-25 00:09:14251}
252
[email protected]74b43cc2013-08-30 06:29:27253void SingleThreadProxy::SetNextCommitWaitsForActivation() {
254 // There is no activation here other than commit. So do nothing.
255}
256
[email protected]a8a049c2013-03-11 23:27:06257void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
258 // Thread-only feature.
259 NOTREACHED();
[email protected]6b16679e2012-10-27 00:44:28260}
261
[email protected]a8a049c2013-03-11 23:27:06262bool SingleThreadProxy::CommitRequested() const { return false; }
263
[email protected]971728d2013-10-26 10:39:31264bool SingleThreadProxy::BeginMainFrameRequested() const { return false; }
265
[email protected]a8a049c2013-03-11 23:27:06266size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
267 return std::numeric_limits<size_t>::max();
268}
269
270void SingleThreadProxy::Stop() {
271 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
272 DCHECK(Proxy::IsMainThread());
273 {
[email protected]819b9f52013-09-22 23:29:51274 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
[email protected]a8a049c2013-03-11 23:27:06275 DebugScopedSetImplThread impl(this);
276
[email protected]804c8982013-03-13 16:32:21277 layer_tree_host_->DeleteContentsTexturesOnImplThread(
[email protected]c1bb5af2013-03-13 19:06:27278 layer_tree_host_impl_->resource_provider());
[email protected]a8a049c2013-03-11 23:27:06279 layer_tree_host_impl_.reset();
280 }
[email protected]7aba6662013-03-12 10:17:34281 layer_tree_host_ = NULL;
[email protected]a8a049c2013-03-11 23:27:06282}
283
[email protected]3d9f7432013-04-06 00:35:18284void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
285 DCHECK(Proxy::IsImplThread());
[email protected]d9fce6722013-08-30 01:10:01286 UpdateBackgroundAnimateTicking();
[email protected]3d9f7432013-04-06 00:35:18287}
288
[email protected]4f48f6e2013-08-27 06:33:38289void SingleThreadProxy::NotifyReadyToActivate() {
290 // Thread-only feature.
291 NOTREACHED();
292}
293
[email protected]c1bb5af2013-03-13 19:06:27294void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
[email protected]943528e2013-11-07 05:01:32295 client_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06296}
297
[email protected]c48536a52013-09-14 00:02:08298void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
299 // Thread-only/Impl-side-painting-only feature.
300 NOTREACHED();
301}
302
[email protected]1cd9f5552013-04-26 04:22:03303void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) {
[email protected]27d851ab2013-06-28 01:09:50304 // TODO(brianderson): Once we move render_widget scheduling into this class,
305 // we can treat redraw requests more efficiently than CommitAndRedraw
306 // requests.
[email protected]1cd9f5552013-04-26 04:22:03307 layer_tree_host_impl_->SetViewportDamage(damage_rect);
308 SetNeedsCommit();
309}
310
[email protected]86126792013-03-16 20:07:54311void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06312 // Impl-side painting only.
313 NOTREACHED();
314}
315
[email protected]c1bb5af2013-03-13 19:06:27316void SingleThreadProxy::SetNeedsCommitOnImplThread() {
[email protected]943528e2013-11-07 05:01:32317 client_->ScheduleComposite();
[email protected]a8a049c2013-03-11 23:27:06318}
319
[email protected]c1bb5af2013-03-13 19:06:27320void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06321 scoped_ptr<AnimationEventsVector> events,
322 base::Time wall_clock_time) {
323 DCHECK(Proxy::IsImplThread());
324 DebugScopedSetMainThread main(this);
[email protected]804c8982013-03-13 16:32:21325 layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time);
[email protected]a8a049c2013-03-11 23:27:06326}
327
[email protected]c1bb5af2013-03-13 19:06:27328bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
[email protected]a8a049c2013-03-11 23:27:06329 size_t limit_bytes,
330 int priority_cutoff) {
331 DCHECK(IsImplThread());
[email protected]5d2fec02013-11-28 20:08:33332 PrioritizedResourceManager* contents_texture_manager =
333 layer_tree_host_->contents_texture_manager();
334
335 ResourceProvider* resource_provider =
336 layer_tree_host_impl_->resource_provider();
337
338 if (!contents_texture_manager || !resource_provider)
[email protected]e7595ead2013-10-10 10:10:07339 return false;
[email protected]a8a049c2013-03-11 23:27:06340
[email protected]5d2fec02013-11-28 20:08:33341 return contents_texture_manager->ReduceMemoryOnImplThread(
342 limit_bytes, priority_cutoff, resource_provider);
[email protected]94f206c12012-08-25 00:09:14343}
344
[email protected]c1bb5af2013-03-13 19:06:27345void SingleThreadProxy::SendManagedMemoryStats() {
[email protected]a8a049c2013-03-11 23:27:06346 DCHECK(Proxy::IsImplThread());
[email protected]384b2c5e2013-04-23 01:02:22347 if (!layer_tree_host_impl_)
[email protected]a8a049c2013-03-11 23:27:06348 return;
[email protected]804c8982013-03-13 16:32:21349 PrioritizedResourceManager* contents_texture_manager =
350 layer_tree_host_->contents_texture_manager();
[email protected]5d2fec02013-11-28 20:08:33351 if (!contents_texture_manager)
352 return;
353
[email protected]c1bb5af2013-03-13 19:06:27354 layer_tree_host_impl_->SendManagedMemoryStats(
[email protected]b56c1302013-03-20 21:17:34355 contents_texture_manager->MemoryVisibleBytes(),
356 contents_texture_manager->MemoryVisibleAndNearbyBytes(),
357 contents_texture_manager->MemoryUseBytes());
[email protected]94f206c12012-08-25 00:09:14358}
359
[email protected]c1bb5af2013-03-13 19:06:27360bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
[email protected]a8a049c2013-03-11 23:27:06361
[email protected]c1bb5af2013-03-13 19:06:27362void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
[email protected]a8a049c2013-03-11 23:27:06363 // Cause a commit so we can notice the lost context.
[email protected]c1bb5af2013-03-13 19:06:27364 SetNeedsCommitOnImplThread();
[email protected]4d7e46a2013-11-08 05:33:40365 client_->DidAbortSwapBuffers();
366}
367
368void SingleThreadProxy::DidSwapBuffersOnImplThread() {
369 client_->DidPostSwapBuffers();
370}
371
372void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() {
373 client_->DidCompleteSwapBuffers();
[email protected]493067512012-09-19 23:34:10374}
375
[email protected]a8a049c2013-03-11 23:27:06376// Called by the legacy scheduling path (e.g. where render_widget does the
377// scheduling)
[email protected]f0c2a242013-03-15 19:34:52378void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
[email protected]e0341352013-04-06 05:01:20379 gfx::Rect device_viewport_damage_rect;
380
381 LayerTreeHostImpl::FrameData frame;
382 if (CommitAndComposite(frame_begin_time,
383 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39384 false, // for_readback
[email protected]e0341352013-04-06 05:01:20385 &frame)) {
[email protected]819b9f52013-09-22 23:29:51386 {
387 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
388 DebugScopedSetImplThread impl(this);
389
390 // This CapturePostTasks should be destroyed before
391 // DidCommitAndDrawFrame() is called since that goes out to the embedder,
392 // and we want the embedder to receive its callbacks before that.
393 // NOTE: This maintains consistent ordering with the ThreadProxy since
394 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
395 // there as the main thread is not blocked, so any posted tasks inside
396 // the swap buffers will execute first.
397 BlockingTaskRunner::CapturePostTasks blocked;
398
399 layer_tree_host_impl_->SwapBuffers(frame);
400 }
[email protected]a8a049c2013-03-11 23:27:06401 DidSwapFrame();
402 }
[email protected]74d9063c2013-01-18 03:14:47403}
404
[email protected]a8a049c2013-03-11 23:27:06405scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
406 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
407 {
408 // The following line casts away const modifiers because it is just
409 // setting debug state. We still want the AsValue() function and its
410 // call chain to be const throughout.
411 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
412
413 state->Set("layer_tree_host_impl",
[email protected]c1bb5af2013-03-13 19:06:27414 layer_tree_host_impl_->AsValue().release());
[email protected]a8a049c2013-03-11 23:27:06415 }
416 return state.PassAs<base::Value>();
[email protected]493067512012-09-19 23:34:10417}
418
[email protected]a8a049c2013-03-11 23:27:06419void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
420 {
421 DebugScopedSetImplThread impl(this);
[email protected]04049fc2013-05-01 03:13:20422 if (layer_tree_host_impl_->renderer()) {
423 DCHECK(!layer_tree_host_->output_surface_lost());
[email protected]a8a049c2013-03-11 23:27:06424 layer_tree_host_impl_->renderer()->DoNoOp();
[email protected]04049fc2013-05-01 03:13:20425 }
[email protected]a8a049c2013-03-11 23:27:06426 }
[email protected]8947cbe2012-11-28 05:27:43427}
428
[email protected]e0341352013-04-06 05:01:20429bool SingleThreadProxy::CommitAndComposite(
430 base::TimeTicks frame_begin_time,
431 gfx::Rect device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39432 bool for_readback,
[email protected]e0341352013-04-06 05:01:20433 LayerTreeHostImpl::FrameData* frame) {
[email protected]a8a049c2013-03-11 23:27:06434 DCHECK(Proxy::IsMainThread());
[email protected]b1969fa2012-10-17 20:16:29435
[email protected]04049fc2013-05-01 03:13:20436 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded())
[email protected]16288a42012-12-17 23:31:05437 return false;
[email protected]a8a049c2013-03-11 23:27:06438
[email protected]d7763662013-05-09 18:14:37439 layer_tree_host_->AnimateLayers(frame_begin_time);
440
[email protected]5d2fec02013-11-28 20:08:33441 if (PrioritizedResourceManager* contents_texture_manager =
442 layer_tree_host_->contents_texture_manager()) {
443 contents_texture_manager->UnlinkAndClearEvictedBackings();
444 contents_texture_manager->SetMaxMemoryLimitBytes(
[email protected]990e050a2013-09-23 18:50:21445 layer_tree_host_impl_->memory_allocation_limit_bytes());
[email protected]5d2fec02013-11-28 20:08:33446 contents_texture_manager->SetExternalPriorityCutoff(
[email protected]990e050a2013-09-23 18:50:21447 layer_tree_host_impl_->memory_allocation_priority_cutoff());
[email protected]6e8c54922013-06-02 19:17:35448 }
[email protected]a8a049c2013-03-11 23:27:06449
450 scoped_ptr<ResourceUpdateQueue> queue =
451 make_scoped_ptr(new ResourceUpdateQueue);
[email protected]990e050a2013-09-23 18:50:21452 layer_tree_host_->UpdateLayers(queue.get());
[email protected]a8a049c2013-03-11 23:27:06453
[email protected]804c8982013-03-13 16:32:21454 layer_tree_host_->WillCommit();
[email protected]a024d0e2013-09-26 19:20:45455
[email protected]e51444a2013-12-10 23:05:01456 scoped_refptr<ContextProvider> offscreen_context_provider;
[email protected]a024d0e2013-09-26 19:20:45457 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d &&
458 layer_tree_host_->needs_offscreen_context()) {
459 offscreen_context_provider =
[email protected]f10dc472013-09-27 03:31:59460 layer_tree_host_->client()->OffscreenContextProvider();
461 if (offscreen_context_provider.get() &&
462 !offscreen_context_provider->BindToCurrentThread())
463 offscreen_context_provider = NULL;
464
[email protected]a024d0e2013-09-26 19:20:45465 if (offscreen_context_provider.get())
466 created_offscreen_context_provider_ = true;
467 }
468
[email protected]a8a049c2013-03-11 23:27:06469 DoCommit(queue.Pass());
[email protected]e0341352013-04-06 05:01:20470 bool result = DoComposite(offscreen_context_provider,
471 frame_begin_time,
472 device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39473 for_readback,
[email protected]e0341352013-04-06 05:01:20474 frame);
[email protected]daea3d42013-10-23 17:04:50475 layer_tree_host_->DidBeginMainFrame();
[email protected]a8a049c2013-03-11 23:27:06476 return result;
[email protected]16288a42012-12-17 23:31:05477}
478
[email protected]3d9f7432013-04-06 00:35:18479bool SingleThreadProxy::ShouldComposite() const {
480 DCHECK(Proxy::IsImplThread());
481 return layer_tree_host_impl_->visible() &&
482 layer_tree_host_impl_->CanDraw();
483}
484
[email protected]d9fce6722013-08-30 01:10:01485void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
486 DCHECK(Proxy::IsImplThread());
487 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
488 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
489}
490
[email protected]a8a049c2013-03-11 23:27:06491bool SingleThreadProxy::DoComposite(
[email protected]e51444a2013-12-10 23:05:01492 scoped_refptr<ContextProvider> offscreen_context_provider,
[email protected]e0341352013-04-06 05:01:20493 base::TimeTicks frame_begin_time,
494 gfx::Rect device_viewport_damage_rect,
[email protected]2921d042013-05-10 05:01:39495 bool for_readback,
[email protected]e0341352013-04-06 05:01:20496 LayerTreeHostImpl::FrameData* frame) {
[email protected]04049fc2013-05-01 03:13:20497 DCHECK(!layer_tree_host_->output_surface_lost());
498
499 bool lost_output_surface = false;
[email protected]a8a049c2013-03-11 23:27:06500 {
501 DebugScopedSetImplThread impl(this);
502 base::AutoReset<bool> mark_inside(&inside_draw_, true);
503
[email protected]b5174d712013-08-28 08:10:43504 layer_tree_host_impl_->SetOffscreenContextProvider(
505 offscreen_context_provider);
[email protected]a8a049c2013-03-11 23:27:06506
[email protected]2921d042013-05-10 05:01:39507 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
508
[email protected]3d9f7432013-04-06 00:35:18509 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
510 // frame, so can only be used when such a frame is possible. Since
511 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
512 // CanDraw() as well.
[email protected]2921d042013-05-10 05:01:39513 if (!ShouldComposite() || (for_readback && !can_do_readback)) {
[email protected]d9fce6722013-08-30 01:10:01514 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06515 return false;
[email protected]3d9f7432013-04-06 00:35:18516 }
[email protected]a8a049c2013-03-11 23:27:06517
[email protected]fb7425a2013-04-22 16:28:55518 layer_tree_host_impl_->Animate(
519 layer_tree_host_impl_->CurrentFrameTimeTicks(),
520 layer_tree_host_impl_->CurrentFrameTime());
[email protected]d9fce6722013-08-30 01:10:01521 UpdateBackgroundAnimateTicking();
[email protected]a8a049c2013-03-11 23:27:06522
[email protected]13044fe72013-12-02 20:52:19523 if (!layer_tree_host_impl_->IsContextLost()) {
524 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect);
525 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
526 layer_tree_host_impl_->DidDrawAllLayers(*frame);
527 }
[email protected]04049fc2013-05-01 03:13:20528 lost_output_surface = layer_tree_host_impl_->IsContextLost();
[email protected]a8a049c2013-03-11 23:27:06529
[email protected]3d9f7432013-04-06 00:35:18530 bool start_ready_animations = true;
531 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
532
[email protected]8347d692013-05-17 23:22:38533 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
[email protected]a8a049c2013-03-11 23:27:06534 }
535
[email protected]04049fc2013-05-01 03:13:20536 if (lost_output_surface) {
[email protected]e51444a2013-12-10 23:05:01537 ContextProvider* offscreen_contexts =
[email protected]b5174d712013-08-28 08:10:43538 layer_tree_host_impl_->offscreen_context_provider();
[email protected]a8a049c2013-03-11 23:27:06539 if (offscreen_contexts)
540 offscreen_contexts->VerifyContexts();
[email protected]804c8982013-03-13 16:32:21541 layer_tree_host_->DidLoseOutputSurface();
[email protected]a8a049c2013-03-11 23:27:06542 return false;
543 }
544
545 return true;
546}
547
548void SingleThreadProxy::DidSwapFrame() {
549 if (next_frame_is_newly_committed_frame_) {
550 next_frame_is_newly_committed_frame_ = false;
[email protected]804c8982013-03-13 16:32:21551 layer_tree_host_->DidCommitAndDrawFrame();
[email protected]a8a049c2013-03-11 23:27:06552 }
553}
554
555bool SingleThreadProxy::CommitPendingForTesting() { return false; }
556
[email protected]bc5e77c2012-11-05 20:00:49557} // namespace cc