Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1011)

Side by Side Diff: cc/trees/single_thread_proxy.cc

Issue 134623005: Make SingleThreadProxy a SchedulerClient (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix tests; remove weak_ptr_ Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/trees/single_thread_proxy.h" 5 #include "cc/trees/single_thread_proxy.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "cc/debug/benchmark_instrumentation.h" 9 #include "cc/debug/benchmark_instrumentation.h"
10 #include "cc/output/context_provider.h" 10 #include "cc/output/context_provider.h"
(...skipping 16 matching lines...) Expand all
27 new SingleThreadProxy(layer_tree_host, client)).PassAs<Proxy>(); 27 new SingleThreadProxy(layer_tree_host, client)).PassAs<Proxy>();
28 } 28 }
29 29
30 SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, 30 SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
31 LayerTreeHostSingleThreadClient* client) 31 LayerTreeHostSingleThreadClient* client)
32 : Proxy(NULL), 32 : Proxy(NULL),
33 layer_tree_host_(layer_tree_host), 33 layer_tree_host_(layer_tree_host),
34 client_(client), 34 client_(client),
35 created_offscreen_context_provider_(false), 35 created_offscreen_context_provider_(false),
36 next_frame_is_newly_committed_frame_(false), 36 next_frame_is_newly_committed_frame_(false),
37 inside_draw_(false) { 37 inside_draw_(false),
38 defer_commits_(false),
39 finish_commit_deferred_(false),
40 weak_factory_(this) {
38 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); 41 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
39 DCHECK(Proxy::IsMainThread()); 42 DCHECK(Proxy::IsMainThread());
40 DCHECK(layer_tree_host); 43 DCHECK(layer_tree_host);
41 44
42 // Impl-side painting not supported without threaded compositing. 45 // Impl-side painting not supported without threaded compositing.
43 CHECK(!layer_tree_host->settings().impl_side_painting) 46 CHECK(!layer_tree_host->settings().impl_side_painting)
44 << "Threaded compositing must be enabled to use impl-side painting."; 47 << "Threaded compositing must be enabled to use impl-side painting.";
45 } 48 }
46 49
47 void SingleThreadProxy::Start() { 50 void SingleThreadProxy::Start() {
48 DebugScopedSetImplThread impl(this); 51 DebugScopedSetImplThread impl(this);
49 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); 52 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
53 SchedulerSettings scheduler_settings(layer_tree_host_->settings());
54 scheduler_on_impl_thread_ =
55 Scheduler::Create(this, scheduler_settings, layer_tree_host_->id());
56 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
50 } 57 }
51 58
52 SingleThreadProxy::~SingleThreadProxy() { 59 SingleThreadProxy::~SingleThreadProxy() {
53 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy"); 60 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
54 DCHECK(Proxy::IsMainThread()); 61 DCHECK(Proxy::IsMainThread());
55 // Make sure Stop() got called or never Started. 62 // Make sure Stop() got called or never Started.
56 DCHECK(!layer_tree_host_impl_); 63 DCHECK(!layer_tree_host_impl_);
57 } 64 }
58 65
59 bool SingleThreadProxy::CompositeAndReadback(void* pixels, 66 bool SingleThreadProxy::CompositeAndReadback(void* pixels,
60 const gfx::Rect& rect) { 67 const gfx::Rect& rect) {
61 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback"); 68 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback");
62 DCHECK(Proxy::IsMainThread()); 69 DCHECK(Proxy::IsMainThread());
63 70 // TODO(enne): make this go through the SetNeedsForcedCommitForReadback logic.
64 gfx::Rect device_viewport_damage_rect = rect; 71 bool do_commit = true;
65 72 bool for_readback = true;
66 LayerTreeHostImpl::FrameData frame; 73 gfx::Rect device_viewport_damage_rect(rect);
67 if (!CommitAndComposite(gfx::FrameTime::Now(), 74 if (CommitAndCompositeInternal(gfx::FrameTime::Now(),
68 device_viewport_damage_rect, 75 device_viewport_damage_rect,
69 true, // for_readback 76 do_commit,
70 &frame)) 77 for_readback).draw_result !=
78 DrawSwapReadbackResult::DRAW_SUCCESS)
71 return false; 79 return false;
72 80
73 { 81 {
74 DebugScopedSetImplThread impl(this); 82 DebugScopedSetImplThread impl(this);
75 layer_tree_host_impl_->Readback(pixels, rect); 83 layer_tree_host_impl_->Readback(pixels, rect);
76 84
77 if (layer_tree_host_impl_->IsContextLost()) 85 if (layer_tree_host_impl_->IsContextLost())
78 return false; 86 return false;
79 } 87 }
80 88
(...skipping 11 matching lines...) Expand all
92 100
93 bool SingleThreadProxy::IsStarted() const { 101 bool SingleThreadProxy::IsStarted() const {
94 DCHECK(Proxy::IsMainThread()); 102 DCHECK(Proxy::IsMainThread());
95 return layer_tree_host_impl_; 103 return layer_tree_host_impl_;
96 } 104 }
97 105
98 void SingleThreadProxy::SetLayerTreeHostClientReady() { 106 void SingleThreadProxy::SetLayerTreeHostClientReady() {
99 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); 107 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
100 // Scheduling is controlled by the embedder in the single thread case, so 108 // Scheduling is controlled by the embedder in the single thread case, so
101 // nothing to do. 109 // nothing to do.
110 DCHECK(Proxy::IsMainThread());
111 DebugScopedSetImplThread impl(this);
112 scheduler_on_impl_thread_->SetCanStart();
102 } 113 }
103 114
104 void SingleThreadProxy::SetVisible(bool visible) { 115 void SingleThreadProxy::SetVisible(bool visible) {
105 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); 116 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible");
106 DebugScopedSetImplThread impl(this); 117 DebugScopedSetImplThread impl(this);
107 layer_tree_host_impl_->SetVisible(visible); 118 layer_tree_host_impl_->SetVisible(visible);
119 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
108 120
109 // Changing visibility could change ShouldComposite(). 121 // Changing visibility could change ShouldComposite().
110 UpdateBackgroundAnimateTicking(); 122 UpdateBackgroundAnimateTicking();
111 } 123 }
112 124
113 void SingleThreadProxy::CreateAndInitializeOutputSurface() { 125 void SingleThreadProxy::CreateAndInitializeOutputSurface() {
114 TRACE_EVENT0( 126 TRACE_EVENT0(
115 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); 127 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
116 DCHECK(Proxy::IsMainThread()); 128 DCHECK(Proxy::IsMainThread());
117 129
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 if (!initialized && offscreen_context_provider.get()) { 162 if (!initialized && offscreen_context_provider.get()) {
151 offscreen_context_provider->VerifyContexts(); 163 offscreen_context_provider->VerifyContexts();
152 offscreen_context_provider = NULL; 164 offscreen_context_provider = NULL;
153 } 165 }
154 166
155 layer_tree_host_impl_->SetOffscreenContextProvider( 167 layer_tree_host_impl_->SetOffscreenContextProvider(
156 offscreen_context_provider); 168 offscreen_context_provider);
157 } 169 }
158 170
159 OnOutputSurfaceInitializeAttempted(initialized); 171 OnOutputSurfaceInitializeAttempted(initialized);
172
173 // This must happen after OnCreateAndInitializeOutputSurfaceAttempted as it
174 // causes a commit and the output surface needs to be initialized beforehand.
175 if (initialized) {
176 DebugScopedSetImplThread impl(this);
177 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
178 }
160 } 179 }
161 180
162 void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) { 181 void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) {
163 LayerTreeHost::CreateResult result = 182 LayerTreeHost::CreateResult result =
164 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); 183 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
165 if (result == LayerTreeHost::CreateFailedButTryAgain) { 184 if (result == LayerTreeHost::CreateFailedButTryAgain) {
166 // Force another recreation attempt to happen by requesting another commit. 185 Proxy::MainThreadTaskRunner()->PostTask(
167 SetNeedsCommit(); 186 FROM_HERE,
187 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface,
188 weak_factory_.GetWeakPtr()));
168 } 189 }
169 } 190 }
170 191
171 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { 192 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
172 DCHECK(Proxy::IsMainThread()); 193 DCHECK(Proxy::IsMainThread());
173 DCHECK(!layer_tree_host_->output_surface_lost()); 194 DCHECK(!layer_tree_host_->output_surface_lost());
174 return renderer_capabilities_for_main_thread_; 195 return renderer_capabilities_for_main_thread_;
175 } 196 }
176 197
177 void SingleThreadProxy::SetNeedsAnimate() { 198 void SingleThreadProxy::SetNeedsAnimate() {
178 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); 199 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
179 DCHECK(Proxy::IsMainThread()); 200 DCHECK(Proxy::IsMainThread());
180 client_->ScheduleAnimation(); 201 SetNeedsCommit();
181 } 202 }
182 203
183 void SingleThreadProxy::SetNeedsUpdateLayers() { 204 void SingleThreadProxy::SetNeedsUpdateLayers() {
184 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); 205 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
185 DCHECK(Proxy::IsMainThread()); 206 DCHECK(Proxy::IsMainThread());
186 client_->ScheduleComposite(); 207 SetNeedsCommit();
187 } 208 }
188 209
189 void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { 210 void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) {
190 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); 211 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
191 DCHECK(Proxy::IsMainThread()); 212 DCHECK(Proxy::IsMainThread());
213 layer_tree_host_->WillBeginMainFrame();
214 layer_tree_host_->Layout();
215 layer_tree_host_->AnimateLayers(frame_begin_time);
216
217 if (PrioritizedResourceManager* contents_texture_manager =
218 layer_tree_host_->contents_texture_manager()) {
219 contents_texture_manager->UnlinkAndClearEvictedBackings();
220 contents_texture_manager->SetMaxMemoryLimitBytes(
221 layer_tree_host_impl_->memory_allocation_limit_bytes());
222 contents_texture_manager->SetExternalPriorityCutoff(
223 layer_tree_host_impl_->memory_allocation_priority_cutoff());
224 }
225
226 scoped_ptr<ResourceUpdateQueue> queue =
227 make_scoped_ptr(new ResourceUpdateQueue);
228
229 layer_tree_host_->UpdateLayers(queue.get());
230
231 layer_tree_host_->WillCommit();
232
192 // Commit immediately. 233 // Commit immediately.
193 { 234 {
194 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 235 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
195 DebugScopedSetImplThread impl(this); 236 DebugScopedSetImplThread impl(this);
196 237
197 // This CapturePostTasks should be destroyed before CommitComplete() is 238 // This CapturePostTasks should be destroyed before CommitComplete() is
198 // called since that goes out to the embedder, and we want the embedder 239 // called since that goes out to the embedder, and we want the embedder
199 // to receive its callbacks before that. 240 // to receive its callbacks before that.
200 BlockingTaskRunner::CapturePostTasks blocked; 241 BlockingTaskRunner::CapturePostTasks blocked;
201 242
(...skipping 13 matching lines...) Expand all
215 layer_tree_host_impl_->resource_provider()); 256 layer_tree_host_impl_->resource_provider());
216 update_controller->Finalize(); 257 update_controller->Finalize();
217 258
218 if (layer_tree_host_impl_->EvictedUIResourcesExist()) 259 if (layer_tree_host_impl_->EvictedUIResourcesExist())
219 layer_tree_host_->RecreateUIResources(); 260 layer_tree_host_->RecreateUIResources();
220 261
221 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); 262 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
222 263
223 layer_tree_host_impl_->CommitComplete(); 264 layer_tree_host_impl_->CommitComplete();
224 265
266 UpdateBackgroundAnimateTicking();
267
225 #ifndef NDEBUG 268 #ifndef NDEBUG
226 // In the single-threaded case, the scale and scroll deltas should never be 269 // In the single-threaded case, the scale and scroll deltas should never be
227 // touched on the impl layer tree. 270 // touched on the impl layer tree.
228 scoped_ptr<ScrollAndScaleSet> scroll_info = 271 scoped_ptr<ScrollAndScaleSet> scroll_info =
229 layer_tree_host_impl_->ProcessScrollDeltas(); 272 layer_tree_host_impl_->ProcessScrollDeltas();
230 DCHECK(!scroll_info->scrolls.size()); 273 DCHECK(!scroll_info->scrolls.size());
231 DCHECK_EQ(1.f, scroll_info->page_scale_delta); 274 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
232 #endif 275 #endif
233 276
234 RenderingStatsInstrumentation* stats_instrumentation = 277 RenderingStatsInstrumentation* stats_instrumentation =
235 layer_tree_host_->rendering_stats_instrumentation(); 278 layer_tree_host_->rendering_stats_instrumentation();
236 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( 279 BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent(
237 stats_instrumentation->main_thread_rendering_stats()); 280 stats_instrumentation->main_thread_rendering_stats());
238 stats_instrumentation->AccumulateAndClearMainThreadStats(); 281 stats_instrumentation->AccumulateAndClearMainThreadStats();
239 } 282 }
240 layer_tree_host_->CommitComplete(); 283 layer_tree_host_->CommitComplete();
284 layer_tree_host_->DidBeginMainFrame();
285 timing_history_.DidCommit();
286
241 next_frame_is_newly_committed_frame_ = true; 287 next_frame_is_newly_committed_frame_ = true;
242 } 288 }
243 289
244 void SingleThreadProxy::SetNeedsCommit() { 290 void SingleThreadProxy::SetNeedsCommit() {
245 DCHECK(Proxy::IsMainThread()); 291 scheduler_on_impl_thread_->SetNeedsCommit();
246 client_->ScheduleComposite();
247 } 292 }
248 293
249 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { 294 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
250 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); 295 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
296 DCHECK(Proxy::IsMainThread());
297 DebugScopedSetImplThread impl(this);
251 SetNeedsRedrawRectOnImplThread(damage_rect); 298 SetNeedsRedrawRectOnImplThread(damage_rect);
252 client_->ScheduleComposite();
253 } 299 }
254 300
255 void SingleThreadProxy::SetNextCommitWaitsForActivation() { 301 void SingleThreadProxy::SetNextCommitWaitsForActivation() {
256 // There is no activation here other than commit. So do nothing. 302 // There is no activation here other than commit. So do nothing.
303 DCHECK(Proxy::IsMainThread());
257 } 304 }
258 305
259 void SingleThreadProxy::SetDeferCommits(bool defer_commits) { 306 void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
260 // Thread-only feature. 307 DCHECK(Proxy::IsMainThread());
261 NOTREACHED(); 308 if (defer_commits_ == defer_commits)
309 return;
310
311 defer_commits_ = defer_commits;
312 if (!defer_commits_ && finish_commit_deferred_) {
313 scheduler_on_impl_thread_->FinishCommit();
314 finish_commit_deferred_ = false;
315 }
262 } 316 }
263 317
264 bool SingleThreadProxy::CommitRequested() const { return false; } 318 bool SingleThreadProxy::CommitRequested() const {
319 DCHECK(Proxy::IsMainThread());
320 return finish_commit_deferred_;
321 }
265 322
266 bool SingleThreadProxy::BeginMainFrameRequested() const { return false; } 323 bool SingleThreadProxy::BeginMainFrameRequested() const {
324 DCHECK(Proxy::IsMainThread());
325 return finish_commit_deferred_;
326 }
267 327
268 size_t SingleThreadProxy::MaxPartialTextureUpdates() const { 328 size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
269 return std::numeric_limits<size_t>::max(); 329 return std::numeric_limits<size_t>::max();
270 } 330 }
271 331
272 void SingleThreadProxy::Stop() { 332 void SingleThreadProxy::Stop() {
273 TRACE_EVENT0("cc", "SingleThreadProxy::stop"); 333 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
274 DCHECK(Proxy::IsMainThread()); 334 DCHECK(Proxy::IsMainThread());
275 { 335 {
276 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 336 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
277 DebugScopedSetImplThread impl(this); 337 DebugScopedSetImplThread impl(this);
278 338
279 layer_tree_host_->DeleteContentsTexturesOnImplThread( 339 layer_tree_host_->DeleteContentsTexturesOnImplThread(
280 layer_tree_host_impl_->resource_provider()); 340 layer_tree_host_impl_->resource_provider());
341 scheduler_on_impl_thread_.reset();
281 layer_tree_host_impl_.reset(); 342 layer_tree_host_impl_.reset();
282 } 343 }
283 layer_tree_host_ = NULL; 344 layer_tree_host_ = NULL;
284 } 345 }
285 346
286 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { 347 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
287 TRACE_EVENT1( 348 TRACE_EVENT1(
288 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); 349 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
289 DCHECK(Proxy::IsImplThread()); 350 DCHECK(Proxy::IsImplThread());
290 UpdateBackgroundAnimateTicking(); 351 UpdateBackgroundAnimateTicking();
352 scheduler_on_impl_thread_->SetCanDraw(can_draw);
291 } 353 }
292 354
293 void SingleThreadProxy::NotifyReadyToActivate() { 355 void SingleThreadProxy::NotifyReadyToActivate() {
294 // Thread-only feature. 356 // Impl-side painting only.
295 NOTREACHED(); 357 NOTREACHED();
296 } 358 }
297 359
298 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { 360 void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
299 client_->ScheduleComposite(); 361 scheduler_on_impl_thread_->SetNeedsRedraw();
300 } 362 }
301 363
302 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { 364 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
303 // Thread-only/Impl-side-painting-only feature. 365 // Impl-side painting only.
304 NOTREACHED(); 366 NOTREACHED();
305 } 367 }
306 368
307 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( 369 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
308 const gfx::Rect& damage_rect) { 370 const gfx::Rect& damage_rect) {
309 // TODO(brianderson): Once we move render_widget scheduling into this class,
310 // we can treat redraw requests more efficiently than CommitAndRedraw
311 // requests.
312 layer_tree_host_impl_->SetViewportDamage(damage_rect); 371 layer_tree_host_impl_->SetViewportDamage(damage_rect);
313 SetNeedsCommit(); 372 SetNeedsRedrawOnImplThread();
314 } 373 }
315 374
316 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { 375 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
317 // Impl-side painting only. 376 // Impl-side painting only.
318 NOTREACHED(); 377 NOTREACHED();
319 } 378 }
320 379
321 void SingleThreadProxy::SetNeedsCommitOnImplThread() { 380 void SingleThreadProxy::SetNeedsCommitOnImplThread() {
322 client_->ScheduleComposite(); 381 scheduler_on_impl_thread_->SetNeedsCommit();
323 } 382 }
324 383
325 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( 384 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
326 scoped_ptr<AnimationEventsVector> events, 385 scoped_ptr<AnimationEventsVector> events,
327 base::Time wall_clock_time) { 386 base::Time wall_clock_time) {
328 TRACE_EVENT0( 387 TRACE_EVENT0(
329 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); 388 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
330 DCHECK(Proxy::IsImplThread()); 389 DCHECK(Proxy::IsImplThread());
331 DebugScopedSetMainThread main(this); 390 DebugScopedSetMainThread main(this);
332 layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time); 391 layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 424 }
366 425
367 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } 426 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
368 427
369 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { 428 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
370 DCHECK(IsImplThread()); 429 DCHECK(IsImplThread());
371 renderer_capabilities_for_main_thread_ = 430 renderer_capabilities_for_main_thread_ =
372 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); 431 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
373 } 432 }
374 433
434 void SingleThreadProxy::DidActivatePendingTree() {
435 // Impl-side painting only.
436 NOTREACHED();
437 }
438
439 void SingleThreadProxy::DidManageTiles() {
440 // Impl-side painting only.
441 NOTREACHED();
442 }
443
375 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { 444 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
376 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); 445 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
377 // Cause a commit so we can notice the lost context. 446 {
378 SetNeedsCommitOnImplThread(); 447 DebugScopedSetMainThread main(this);
448 // This must happen before we notify the scheduler as it may try to recreate
449 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
450 layer_tree_host_->DidLoseOutputSurface();
451 }
452
453 // TODO(enne): this client call could maybe be removed.
379 client_->DidAbortSwapBuffers(); 454 client_->DidAbortSwapBuffers();
455
456 scheduler_on_impl_thread_->DidLoseOutputSurface();
380 } 457 }
381 458
382 void SingleThreadProxy::DidSwapBuffersOnImplThread() { 459 void SingleThreadProxy::DidSwapBuffersOnImplThread() {
460 // TODO(enne): Maybe this is redundant with DidCommitAndDrawFrame and can be
461 // removed?
383 client_->DidPostSwapBuffers(); 462 client_->DidPostSwapBuffers();
384 } 463 }
385 464
386 void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() { 465 void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() {
387 TRACE_EVENT0("cc", "SingleThreadProxy::OnSwapBuffersCompleteOnImplThread"); 466 TRACE_EVENT0("cc", "SingleThreadProxy::OnSwapBuffersCompleteOnImplThread");
388 client_->DidCompleteSwapBuffers(); 467 client_->DidCompleteSwapBuffers();
389 } 468 }
390 469
391 // Called by the legacy scheduling path (e.g. where render_widget does the 470 void SingleThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
392 // scheduling) 471 TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
472 scheduler_on_impl_thread_->BeginImplFrame(args);
473 }
474
393 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { 475 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
394 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); 476 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately");
477 bool do_commit = true;
478 bool for_readback = false;
395 gfx::Rect device_viewport_damage_rect; 479 gfx::Rect device_viewport_damage_rect;
396 480 CommitAndCompositeInternal(gfx::FrameTime::Now(),
397 LayerTreeHostImpl::FrameData frame; 481 device_viewport_damage_rect,
398 if (CommitAndComposite(frame_begin_time, 482 do_commit,
399 device_viewport_damage_rect, 483 for_readback);
400 false, // for_readback
401 &frame)) {
402 {
403 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
404 DebugScopedSetImplThread impl(this);
405
406 // This CapturePostTasks should be destroyed before
407 // DidCommitAndDrawFrame() is called since that goes out to the embedder,
408 // and we want the embedder to receive its callbacks before that.
409 // NOTE: This maintains consistent ordering with the ThreadProxy since
410 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
411 // there as the main thread is not blocked, so any posted tasks inside
412 // the swap buffers will execute first.
413 BlockingTaskRunner::CapturePostTasks blocked;
414
415 layer_tree_host_impl_->SwapBuffers(frame);
416 }
417 DidSwapFrame();
418 }
419 } 484 }
420 485
421 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { 486 scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
422 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 487 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
423 { 488 {
424 // The following line casts away const modifiers because it is just 489 // The following line casts away const modifiers because it is just
425 // setting debug state. We still want the AsValue() function and its 490 // setting debug state. We still want the AsValue() function and its
426 // call chain to be const throughout. 491 // call chain to be const throughout.
427 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); 492 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
428 493
429 state->Set("layer_tree_host_impl", 494 state->Set("layer_tree_host_impl",
430 layer_tree_host_impl_->AsValue().release()); 495 layer_tree_host_impl_->AsValue().release());
431 } 496 }
432 return state.PassAs<base::Value>(); 497 return state.PassAs<base::Value>();
433 } 498 }
434 499
435 void SingleThreadProxy::ForceSerializeOnSwapBuffers() { 500 void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
436 { 501 {
437 DebugScopedSetImplThread impl(this); 502 DebugScopedSetImplThread impl(this);
438 if (layer_tree_host_impl_->renderer()) { 503 if (layer_tree_host_impl_->renderer()) {
439 DCHECK(!layer_tree_host_->output_surface_lost()); 504 DCHECK(!layer_tree_host_->output_surface_lost());
440 layer_tree_host_impl_->renderer()->DoNoOp(); 505 layer_tree_host_impl_->renderer()->DoNoOp();
441 } 506 }
442 } 507 }
443 } 508 }
444 509
445 bool SingleThreadProxy::CommitAndComposite( 510 bool SingleThreadProxy::ShouldComposite() const {
446 base::TimeTicks frame_begin_time, 511 DCHECK(Proxy::IsImplThread());
447 const gfx::Rect& device_viewport_damage_rect, 512 return scheduler_on_impl_thread_->WillDrawIfNeeded();
448 bool for_readback, 513 }
449 LayerTreeHostImpl::FrameData* frame) {
450 TRACE_EVENT0("cc", "SingleThreadProxy::CommitAndComposite");
451 DCHECK(Proxy::IsMainThread());
452 514
453 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) 515 void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
454 return false; 516 DCHECK(Proxy::IsImplThread());
517 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
518 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
519 }
455 520
456 layer_tree_host_->AnimateLayers(frame_begin_time); 521 scoped_refptr<ContextProvider> SingleThreadProxy::OffscreenContextProvider() {
457
458 if (PrioritizedResourceManager* contents_texture_manager =
459 layer_tree_host_->contents_texture_manager()) {
460 contents_texture_manager->UnlinkAndClearEvictedBackings();
461 contents_texture_manager->SetMaxMemoryLimitBytes(
462 layer_tree_host_impl_->memory_allocation_limit_bytes());
463 contents_texture_manager->SetExternalPriorityCutoff(
464 layer_tree_host_impl_->memory_allocation_priority_cutoff());
465 }
466
467 scoped_ptr<ResourceUpdateQueue> queue =
468 make_scoped_ptr(new ResourceUpdateQueue);
469 layer_tree_host_->UpdateLayers(queue.get());
470
471 layer_tree_host_->WillCommit();
472
473 scoped_refptr<ContextProvider> offscreen_context_provider; 522 scoped_refptr<ContextProvider> offscreen_context_provider;
474 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d && 523 if (renderer_capabilities_for_main_thread_.using_offscreen_context3d &&
475 layer_tree_host_->needs_offscreen_context()) { 524 layer_tree_host_->needs_offscreen_context()) {
476 offscreen_context_provider = 525 offscreen_context_provider =
477 layer_tree_host_->client()->OffscreenContextProvider(); 526 layer_tree_host_->client()->OffscreenContextProvider();
478 if (offscreen_context_provider.get() && 527 if (offscreen_context_provider.get() &&
479 !offscreen_context_provider->BindToCurrentThread()) 528 !offscreen_context_provider->BindToCurrentThread())
480 offscreen_context_provider = NULL; 529 offscreen_context_provider = NULL;
481 530
482 if (offscreen_context_provider.get()) 531 if (offscreen_context_provider.get())
483 created_offscreen_context_provider_ = true; 532 created_offscreen_context_provider_ = true;
484 } 533 }
485 534 return offscreen_context_provider;
486 DoCommit(queue.Pass());
487 bool result = DoComposite(offscreen_context_provider,
488 frame_begin_time,
489 device_viewport_damage_rect,
490 for_readback,
491 frame);
492 layer_tree_host_->DidBeginMainFrame();
493 return result;
494 } 535 }
495 536
496 bool SingleThreadProxy::ShouldComposite() const { 537 DrawSwapReadbackResult::DrawResult SingleThreadProxy::DoComposite(
497 DCHECK(Proxy::IsImplThread());
498 return layer_tree_host_impl_->visible() &&
499 layer_tree_host_impl_->CanDraw();
500 }
501
502 void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
503 DCHECK(Proxy::IsImplThread());
504 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
505 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
506 }
507
508 bool SingleThreadProxy::DoComposite(
509 scoped_refptr<ContextProvider> offscreen_context_provider, 538 scoped_refptr<ContextProvider> offscreen_context_provider,
510 base::TimeTicks frame_begin_time, 539 base::TimeTicks frame_begin_time,
511 const gfx::Rect& device_viewport_damage_rect, 540 const gfx::Rect& device_viewport_damage_rect,
512 bool for_readback, 541 bool for_readback,
513 LayerTreeHostImpl::FrameData* frame) { 542 LayerTreeHostImpl::FrameData* frame) {
514 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); 543 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
515 DCHECK(!layer_tree_host_->output_surface_lost()); 544 DCHECK(!layer_tree_host_->output_surface_lost());
516 545
517 bool lost_output_surface = false; 546 bool lost_output_surface = false;
518 { 547 {
519 DebugScopedSetImplThread impl(this); 548 DebugScopedSetImplThread impl(this);
520 base::AutoReset<bool> mark_inside(&inside_draw_, true); 549 base::AutoReset<bool> mark_inside(&inside_draw_, true);
521 550
522 layer_tree_host_impl_->SetOffscreenContextProvider( 551 layer_tree_host_impl_->SetOffscreenContextProvider(
523 offscreen_context_provider); 552 offscreen_context_provider);
524 553
525 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); 554 bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels();
526 555
527 // We guard PrepareToDraw() with CanDraw() because it always returns a valid 556 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
528 // frame, so can only be used when such a frame is possible. Since 557 // frame, so can only be used when such a frame is possible. Since
529 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on 558 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
530 // CanDraw() as well. 559 // CanDraw() as well.
531 if (!ShouldComposite() || (for_readback && !can_do_readback)) { 560 if (!ShouldComposite() || (for_readback && !can_do_readback)) {
532 UpdateBackgroundAnimateTicking(); 561 UpdateBackgroundAnimateTicking();
533 return false; 562 return DrawSwapReadbackResult::DRAW_ABORTED_CANT_DRAW;
534 } 563 }
535 564
536 layer_tree_host_impl_->Animate( 565 layer_tree_host_impl_->Animate(
537 layer_tree_host_impl_->CurrentFrameTimeTicks(), 566 layer_tree_host_impl_->CurrentFrameTimeTicks(),
538 layer_tree_host_impl_->CurrentFrameTime()); 567 layer_tree_host_impl_->CurrentFrameTime());
539 UpdateBackgroundAnimateTicking(); 568 UpdateBackgroundAnimateTicking();
540 569
541 if (!layer_tree_host_impl_->IsContextLost()) { 570 if (!layer_tree_host_impl_->IsContextLost()) {
542 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect); 571 layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect);
543 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); 572 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
544 layer_tree_host_impl_->DidDrawAllLayers(*frame); 573 layer_tree_host_impl_->DidDrawAllLayers(*frame);
545 } 574 }
546 lost_output_surface = layer_tree_host_impl_->IsContextLost(); 575 lost_output_surface = layer_tree_host_impl_->IsContextLost();
547 576
548 bool start_ready_animations = true; 577 bool start_ready_animations = true;
549 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); 578 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
550 579
551 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); 580 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
552 } 581 }
553 582
554 if (lost_output_surface) { 583 if (lost_output_surface) {
555 ContextProvider* offscreen_contexts = 584 ContextProvider* offscreen_contexts =
556 layer_tree_host_impl_->offscreen_context_provider(); 585 layer_tree_host_impl_->offscreen_context_provider();
557 if (offscreen_contexts) 586 if (offscreen_contexts)
558 offscreen_contexts->VerifyContexts(); 587 offscreen_contexts->VerifyContexts();
559 layer_tree_host_->DidLoseOutputSurface(); 588 DidLoseOutputSurfaceOnImplThread();
560 return false; 589 if (for_readback)
590 return DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST;
561 } 591 }
562 592
563 return true; 593 return DrawSwapReadbackResult::DRAW_SUCCESS;
564 } 594 }
565 595
566 void SingleThreadProxy::DidSwapFrame() { 596 void SingleThreadProxy::DidCommitAndDrawFrame() {
567 if (next_frame_is_newly_committed_frame_) { 597 if (next_frame_is_newly_committed_frame_) {
568 next_frame_is_newly_committed_frame_ = false; 598 next_frame_is_newly_committed_frame_ = false;
569 layer_tree_host_->DidCommitAndDrawFrame(); 599 layer_tree_host_->DidCommitAndDrawFrame();
570 } 600 }
571 } 601 }
572 602
573 bool SingleThreadProxy::CommitPendingForTesting() { return false; } 603 bool SingleThreadProxy::CommitPendingForTesting() { return false; }
574 604
605 scoped_ptr<base::Value> SingleThreadProxy::SchedulerStateAsValueForTesting() {
606 DebugScopedSetImplThread impl(this);
607 return scheduler_on_impl_thread_->StateAsValue().Pass();
608 }
609
610 void SingleThreadProxy::SetNeedsBeginImplFrame(bool enable) {
611 if (OutputSurface* surface = layer_tree_host_impl_->output_surface())
612 surface->SetNeedsBeginImplFrame(enable);
613 }
614
615 void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
616 if (defer_commits_) {
617 DCHECK(!finish_commit_deferred_);
618 finish_commit_deferred_ = true;
619 return;
620 }
621 timing_history_.DidBeginMainFrame();
622
623 // This is poorly named, but tells the scheduler that we are ready to
624 // start the commit. In threaded mode, this is when the uploads are done.
625 // In single-threaded mode, it doesn't really matter. Doing no work here
626 // and all the work in commit prevents needless carrying of state (like
627 // the upload queue) from BeginMainFrame to commit.
628 scheduler_on_impl_thread_->FinishCommit();
629 }
630
631 DrawSwapReadbackResult
632 SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
633 bool do_commit = false;
634 bool for_readback = false;
635 gfx::Rect device_viewport_damage_rect;
636 return CommitAndCompositeInternal(gfx::FrameTime::Now(),
637 device_viewport_damage_rect,
638 do_commit,
639 for_readback);
640 }
641
642 DrawSwapReadbackResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
643 return ScheduledActionDrawAndSwapIfPossible();
644 }
645
646 DrawSwapReadbackResult SingleThreadProxy::ScheduledActionDrawAndReadback() {
647 // The SingleThreadProxy never asks for a commit for readback,
648 // so this should never happen.
649 NOTREACHED();
650 DrawSwapReadbackResult result;
651 return result;
652 }
653
654 DrawSwapReadbackResult SingleThreadProxy::CommitAndCompositeInternal(
655 base::TimeTicks frame_begin_time,
656 gfx::Rect device_viewport_damage_rect,
657 bool do_commit,
658 bool for_readback) {
659 DCHECK(Proxy::IsMainThread());
660 DrawSwapReadbackResult result;
661
662 if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) {
663 result.draw_result = DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST;
664 return result;
665 }
666
667 if (do_commit)
668 DoCommit(frame_begin_time);
669
670 scoped_refptr<ContextProvider> offscreen_context_provider =
671 OffscreenContextProvider();
672 LayerTreeHostImpl::FrameData frame;
673 timing_history_.DidStartDrawing();
674 result.draw_result = DoComposite(offscreen_context_provider,
675 frame_begin_time,
676 device_viewport_damage_rect,
677 for_readback,
678 &frame);
679 if (result.draw_result != DrawSwapReadbackResult::DRAW_SUCCESS)
680 return result;
681
682 timing_history_.DidFinishDrawing();
683
684 result.did_readback = for_readback;
685
686 {
687 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
688 DebugScopedSetImplThread impl(this);
689
690 // This CapturePostTasks should be destroyed before
691 // DidCommitAndDrawFrame() is called since that goes out to the embedder,
692 // and we want the embedder to receive its callbacks before that.
693 // NOTE: This maintains consistent ordering with the ThreadProxy since
694 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
695 // there as the main thread is not blocked, so any posted tasks inside
696 // the swap buffers will execute first.
697 BlockingTaskRunner::CapturePostTasks blocked;
698 result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
699 }
700
701 DidCommitAndDrawFrame();
702
703 return result;
704 }
705
706 void SingleThreadProxy::ScheduledActionCommit() {
707 DebugScopedSetMainThread main(this);
708 DoCommit(gfx::FrameTime::Now());
709 }
710
711 void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() {
712 // Impl-side painting only.
713 NOTREACHED();
714 }
715
716 void SingleThreadProxy::ScheduledActionActivatePendingTree() {
717 // Impl-side painting only.
718 NOTREACHED();
719 }
720
721 void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
722 DebugScopedSetMainThread main(this);
723 layer_tree_host_->InitializeOutputSurfaceIfNeeded();
724 }
725
726 void SingleThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
727 scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures();
728 }
729
730 void SingleThreadProxy::ScheduledActionManageTiles() {
731 // Impl-side painting only.
732 NOTREACHED();
733 }
734
735 void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {}
736
737 base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
738 return timing_history_.DrawDurationEstimate();
739 }
740
741 base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
742 return timing_history_.BeginMainFrameToCommitDurationEstimate();
743 }
744
745 base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
746 return timing_history_.CommitToActivateDurationEstimate();
747 }
748
749 void SingleThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure,
750 base::TimeTicks deadline) {
751 base::TimeDelta delta = deadline - gfx::FrameTime::Now();
752 if (delta <= base::TimeDelta())
753 delta = base::TimeDelta();
754 Proxy::MainThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
755 }
756
757 void SingleThreadProxy::DidBeginImplFrameDeadline() {
758 layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
759 }
760
575 } // namespace cc 761 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698