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

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

Issue 1057283003: Remove parts of //cc we aren't using (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « cc/trees/single_thread_proxy.h ('k') | cc/trees/swap_promise_monitor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "cc/trees/single_thread_proxy.h"
6
7 #include "base/auto_reset.h"
8 #include "base/profiler/scoped_tracker.h"
9 #include "base/trace_event/trace_event.h"
10 #include "cc/debug/benchmark_instrumentation.h"
11 #include "cc/debug/devtools_instrumentation.h"
12 #include "cc/output/context_provider.h"
13 #include "cc/output/output_surface.h"
14 #include "cc/quads/draw_quad.h"
15 #include "cc/resources/prioritized_resource_manager.h"
16 #include "cc/resources/resource_update_controller.h"
17 #include "cc/scheduler/commit_earlyout_reason.h"
18 #include "cc/trees/layer_tree_host.h"
19 #include "cc/trees/layer_tree_host_single_thread_client.h"
20 #include "cc/trees/layer_tree_impl.h"
21 #include "cc/trees/scoped_abort_remaining_swap_promises.h"
22 #include "ui/gfx/frame_time.h"
23
24 namespace cc {
25
26 scoped_ptr<Proxy> SingleThreadProxy::Create(
27 LayerTreeHost* layer_tree_host,
28 LayerTreeHostSingleThreadClient* client,
29 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
30 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
31 return make_scoped_ptr(new SingleThreadProxy(
32 layer_tree_host,
33 client,
34 main_task_runner,
35 external_begin_frame_source.Pass()));
36 }
37
38 SingleThreadProxy::SingleThreadProxy(
39 LayerTreeHost* layer_tree_host,
40 LayerTreeHostSingleThreadClient* client,
41 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
42 scoped_ptr<BeginFrameSource> external_begin_frame_source)
43 : Proxy(main_task_runner, NULL),
44 layer_tree_host_(layer_tree_host),
45 client_(client),
46 timing_history_(layer_tree_host->rendering_stats_instrumentation()),
47 next_frame_is_newly_committed_frame_(false),
48 inside_draw_(false),
49 defer_commits_(false),
50 commit_requested_(false),
51 inside_synchronous_composite_(false),
52 output_surface_creation_requested_(false),
53 external_begin_frame_source_(external_begin_frame_source.Pass()),
54 weak_factory_(this) {
55 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
56 DCHECK(Proxy::IsMainThread());
57 DCHECK(layer_tree_host);
58 }
59
60 void SingleThreadProxy::Start() {
61 DebugScopedSetImplThread impl(this);
62 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
63 }
64
65 SingleThreadProxy::~SingleThreadProxy() {
66 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
67 DCHECK(Proxy::IsMainThread());
68 // Make sure Stop() got called or never Started.
69 DCHECK(!layer_tree_host_impl_);
70 }
71
72 void SingleThreadProxy::FinishAllRendering() {
73 TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering");
74 DCHECK(Proxy::IsMainThread());
75 {
76 DebugScopedSetImplThread impl(this);
77 layer_tree_host_impl_->FinishAllRendering();
78 }
79 }
80
81 bool SingleThreadProxy::IsStarted() const {
82 DCHECK(Proxy::IsMainThread());
83 return layer_tree_host_impl_;
84 }
85
86 bool SingleThreadProxy::CommitToActiveTree() const {
87 // With SingleThreadProxy we skip the pending tree and commit directly to the
88 // active tree.
89 return true;
90 }
91
92 void SingleThreadProxy::SetLayerTreeHostClientReady() {
93 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
94 // Scheduling is controlled by the embedder in the single thread case, so
95 // nothing to do.
96 DCHECK(Proxy::IsMainThread());
97 DebugScopedSetImplThread impl(this);
98 if (layer_tree_host_->settings().single_thread_proxy_scheduler &&
99 !scheduler_on_impl_thread_) {
100 SchedulerSettings scheduler_settings(
101 layer_tree_host_->settings().ToSchedulerSettings());
102 // SingleThreadProxy should run in main thread low latency mode.
103 scheduler_settings.main_thread_should_always_be_low_latency = true;
104 scheduler_on_impl_thread_ =
105 Scheduler::Create(this,
106 scheduler_settings,
107 layer_tree_host_->id(),
108 MainThreadTaskRunner(),
109 external_begin_frame_source_.Pass());
110 scheduler_on_impl_thread_->SetCanStart();
111 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
112 }
113 }
114
115 void SingleThreadProxy::SetVisible(bool visible) {
116 TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible);
117 DebugScopedSetImplThread impl(this);
118 layer_tree_host_impl_->SetVisible(visible);
119 if (scheduler_on_impl_thread_)
120 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
121 // Changing visibility could change ShouldComposite().
122 }
123
124 void SingleThreadProxy::SetThrottleFrameProduction(bool throttle) {
125 TRACE_EVENT1("cc", "SingleThreadProxy::SetThrottleFrameProduction",
126 "throttle", throttle);
127 DebugScopedSetImplThread impl(this);
128 if (scheduler_on_impl_thread_)
129 scheduler_on_impl_thread_->SetThrottleFrameProduction(throttle);
130 }
131
132 void SingleThreadProxy::RequestNewOutputSurface() {
133 DCHECK(Proxy::IsMainThread());
134 DCHECK(layer_tree_host_->output_surface_lost());
135 output_surface_creation_callback_.Cancel();
136 if (output_surface_creation_requested_)
137 return;
138 output_surface_creation_requested_ = true;
139 layer_tree_host_->RequestNewOutputSurface();
140 }
141
142 void SingleThreadProxy::SetOutputSurface(
143 scoped_ptr<OutputSurface> output_surface) {
144 DCHECK(Proxy::IsMainThread());
145 DCHECK(layer_tree_host_->output_surface_lost());
146 DCHECK(output_surface_creation_requested_);
147 renderer_capabilities_for_main_thread_ = RendererCapabilities();
148
149 bool success;
150 {
151 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
152 DebugScopedSetImplThread impl(this);
153 layer_tree_host_->DeleteContentsTexturesOnImplThread(
154 layer_tree_host_impl_->resource_provider());
155 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
156 }
157
158 if (success) {
159 layer_tree_host_->DidInitializeOutputSurface();
160 if (scheduler_on_impl_thread_)
161 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
162 else if (!inside_synchronous_composite_)
163 SetNeedsCommit();
164 output_surface_creation_requested_ = false;
165 } else {
166 // DidFailToInitializeOutputSurface is treated as a RequestNewOutputSurface,
167 // and so output_surface_creation_requested remains true.
168 layer_tree_host_->DidFailToInitializeOutputSurface();
169 }
170 }
171
172 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
173 DCHECK(Proxy::IsMainThread());
174 DCHECK(!layer_tree_host_->output_surface_lost());
175 return renderer_capabilities_for_main_thread_;
176 }
177
178 void SingleThreadProxy::SetNeedsAnimate() {
179 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
180 DCHECK(Proxy::IsMainThread());
181 client_->ScheduleAnimation();
182 SetNeedsCommit();
183 }
184
185 void SingleThreadProxy::SetNeedsUpdateLayers() {
186 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
187 DCHECK(Proxy::IsMainThread());
188 SetNeedsCommit();
189 }
190
191 void SingleThreadProxy::DoAnimate() {
192 // Don't animate if there is no root layer.
193 // TODO(mithro): Both Animate and UpdateAnimationState already have a
194 // "!active_tree_->root_layer()" check?
195 if (!layer_tree_host_impl_->active_tree()->root_layer()) {
196 return;
197 }
198
199 layer_tree_host_impl_->Animate(
200 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
201
202 // If animations are not visible, update the animation state now as it
203 // won't happen in DoComposite.
204 if (!layer_tree_host_impl_->AnimationsAreVisible()) {
205 layer_tree_host_impl_->UpdateAnimationState(true);
206 }
207 }
208
209 void SingleThreadProxy::DoCommit() {
210 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
211 DCHECK(Proxy::IsMainThread());
212
213 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
214 // fixed.
215 tracked_objects::ScopedTracker tracking_profile1(
216 FROM_HERE_WITH_EXPLICIT_FUNCTION("461509 SingleThreadProxy::DoCommit1"));
217 commit_requested_ = false;
218 layer_tree_host_->WillCommit();
219 devtools_instrumentation::ScopedCommitTrace commit_task(
220 layer_tree_host_->id());
221
222 // Commit immediately.
223 {
224 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
225 // is fixed.
226 tracked_objects::ScopedTracker tracking_profile2(
227 FROM_HERE_WITH_EXPLICIT_FUNCTION(
228 "461509 SingleThreadProxy::DoCommit2"));
229 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
230 DebugScopedSetImplThread impl(this);
231
232 // This CapturePostTasks should be destroyed before CommitComplete() is
233 // called since that goes out to the embedder, and we want the embedder
234 // to receive its callbacks before that.
235 commit_blocking_task_runner_.reset(new BlockingTaskRunner::CapturePostTasks(
236 blocking_main_thread_task_runner()));
237
238 layer_tree_host_impl_->BeginCommit();
239
240 if (PrioritizedResourceManager* contents_texture_manager =
241 layer_tree_host_->contents_texture_manager()) {
242 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
243 // is fixed.
244 tracked_objects::ScopedTracker tracking_profile3(
245 FROM_HERE_WITH_EXPLICIT_FUNCTION(
246 "461509 SingleThreadProxy::DoCommit3"));
247 contents_texture_manager->PushTexturePrioritiesToBackings();
248 }
249 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
250
251 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
252 // is fixed.
253 tracked_objects::ScopedTracker tracking_profile4(
254 FROM_HERE_WITH_EXPLICIT_FUNCTION(
255 "461509 SingleThreadProxy::DoCommit4"));
256 scoped_ptr<ResourceUpdateController> update_controller =
257 ResourceUpdateController::Create(
258 NULL,
259 MainThreadTaskRunner(),
260 queue_for_commit_.Pass(),
261 layer_tree_host_impl_->resource_provider());
262
263 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
264 // is fixed.
265 tracked_objects::ScopedTracker tracking_profile5(
266 FROM_HERE_WITH_EXPLICIT_FUNCTION(
267 "461509 SingleThreadProxy::DoCommit5"));
268 update_controller->Finalize();
269
270 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
271 // is fixed.
272 tracked_objects::ScopedTracker tracking_profile6(
273 FROM_HERE_WITH_EXPLICIT_FUNCTION(
274 "461509 SingleThreadProxy::DoCommit6"));
275 if (layer_tree_host_impl_->EvictedUIResourcesExist())
276 layer_tree_host_->RecreateUIResources();
277
278 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
279 // is fixed.
280 tracked_objects::ScopedTracker tracking_profile7(
281 FROM_HERE_WITH_EXPLICIT_FUNCTION(
282 "461509 SingleThreadProxy::DoCommit7"));
283 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
284
285 #if DCHECK_IS_ON()
286 // In the single-threaded case, the scale and scroll deltas should never be
287 // touched on the impl layer tree.
288 scoped_ptr<ScrollAndScaleSet> scroll_info =
289 layer_tree_host_impl_->ProcessScrollDeltas();
290 DCHECK(!scroll_info->scrolls.size());
291 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
292 #endif
293
294 if (layer_tree_host_->settings().impl_side_painting) {
295 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
296 // is fixed.
297 tracked_objects::ScopedTracker tracking_profile8(
298 FROM_HERE_WITH_EXPLICIT_FUNCTION(
299 "461509 SingleThreadProxy::DoCommit8"));
300 // Commit goes directly to the active tree, but we need to synchronously
301 // "activate" the tree still during commit to satisfy any potential
302 // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
303 // might not be ready to draw, so DidActivateSyncTree must set
304 // the flag to force the tree to not draw until textures are ready.
305 NotifyReadyToActivate();
306 } else {
307 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
308 // is fixed.
309 tracked_objects::ScopedTracker tracking_profile9(
310 FROM_HERE_WITH_EXPLICIT_FUNCTION(
311 "461509 SingleThreadProxy::DoCommit9"));
312 CommitComplete();
313 }
314 }
315 }
316
317 void SingleThreadProxy::CommitComplete() {
318 DCHECK(!layer_tree_host_impl_->pending_tree())
319 << "Activation is expected to have synchronously occurred by now.";
320 DCHECK(commit_blocking_task_runner_);
321
322 // Notify commit complete on the impl side after activate to satisfy any
323 // SetNextCommitWaitsForActivation calls.
324 layer_tree_host_impl_->CommitComplete();
325
326 DebugScopedSetMainThread main(this);
327 commit_blocking_task_runner_.reset();
328 layer_tree_host_->CommitComplete();
329 layer_tree_host_->DidBeginMainFrame();
330 timing_history_.DidCommit();
331
332 next_frame_is_newly_committed_frame_ = true;
333 }
334
335 void SingleThreadProxy::SetNeedsCommit() {
336 DCHECK(Proxy::IsMainThread());
337 DebugScopedSetImplThread impl(this);
338 client_->ScheduleComposite();
339 if (scheduler_on_impl_thread_)
340 scheduler_on_impl_thread_->SetNeedsCommit();
341 commit_requested_ = true;
342 }
343
344 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
345 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
346 DCHECK(Proxy::IsMainThread());
347 DebugScopedSetImplThread impl(this);
348 client_->ScheduleComposite();
349 SetNeedsRedrawRectOnImplThread(damage_rect);
350 }
351
352 void SingleThreadProxy::SetNextCommitWaitsForActivation() {
353 // Activation always forced in commit, so nothing to do.
354 DCHECK(Proxy::IsMainThread());
355 }
356
357 void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
358 DCHECK(Proxy::IsMainThread());
359 // Deferring commits only makes sense if there's a scheduler.
360 if (!scheduler_on_impl_thread_)
361 return;
362 if (defer_commits_ == defer_commits)
363 return;
364
365 if (defer_commits)
366 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
367 else
368 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
369
370 defer_commits_ = defer_commits;
371 scheduler_on_impl_thread_->SetDeferCommits(defer_commits);
372 }
373
374 bool SingleThreadProxy::CommitRequested() const {
375 DCHECK(Proxy::IsMainThread());
376 return commit_requested_;
377 }
378
379 bool SingleThreadProxy::BeginMainFrameRequested() const {
380 DCHECK(Proxy::IsMainThread());
381 // If there is no scheduler, then there can be no pending begin frame,
382 // as all frames are all manually initiated by the embedder of cc.
383 if (!scheduler_on_impl_thread_)
384 return false;
385 return commit_requested_;
386 }
387
388 size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
389 return std::numeric_limits<size_t>::max();
390 }
391
392 void SingleThreadProxy::Stop() {
393 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
394 DCHECK(Proxy::IsMainThread());
395 {
396 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
397 DebugScopedSetImplThread impl(this);
398
399 BlockingTaskRunner::CapturePostTasks blocked(
400 blocking_main_thread_task_runner());
401 layer_tree_host_->DeleteContentsTexturesOnImplThread(
402 layer_tree_host_impl_->resource_provider());
403 scheduler_on_impl_thread_ = nullptr;
404 layer_tree_host_impl_ = nullptr;
405 }
406 layer_tree_host_ = NULL;
407 }
408
409 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
410 TRACE_EVENT1(
411 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
412 DCHECK(Proxy::IsImplThread());
413 if (scheduler_on_impl_thread_)
414 scheduler_on_impl_thread_->SetCanDraw(can_draw);
415 }
416
417 void SingleThreadProxy::NotifyReadyToActivate() {
418 TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
419 DebugScopedSetImplThread impl(this);
420 if (scheduler_on_impl_thread_)
421 scheduler_on_impl_thread_->NotifyReadyToActivate();
422 }
423
424 void SingleThreadProxy::NotifyReadyToDraw() {
425 }
426
427 void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
428 client_->ScheduleComposite();
429 if (scheduler_on_impl_thread_)
430 scheduler_on_impl_thread_->SetNeedsRedraw();
431 }
432
433 void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
434 client_->ScheduleComposite();
435 if (scheduler_on_impl_thread_)
436 scheduler_on_impl_thread_->SetNeedsAnimate();
437 }
438
439 void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
440 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
441 if (scheduler_on_impl_thread_)
442 scheduler_on_impl_thread_->SetNeedsPrepareTiles();
443 }
444
445 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
446 const gfx::Rect& damage_rect) {
447 layer_tree_host_impl_->SetViewportDamage(damage_rect);
448 SetNeedsRedrawOnImplThread();
449 }
450
451 void SingleThreadProxy::SetNeedsCommitOnImplThread() {
452 client_->ScheduleComposite();
453 if (scheduler_on_impl_thread_)
454 scheduler_on_impl_thread_->SetNeedsCommit();
455 }
456
457 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
458 scoped_ptr<AnimationEventsVector> events) {
459 TRACE_EVENT0(
460 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
461 DCHECK(Proxy::IsImplThread());
462 DebugScopedSetMainThread main(this);
463 layer_tree_host_->SetAnimationEvents(events.Pass());
464 }
465
466 bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
467 size_t limit_bytes,
468 int priority_cutoff) {
469 DCHECK(IsImplThread());
470 PrioritizedResourceManager* contents_texture_manager =
471 layer_tree_host_->contents_texture_manager();
472
473 ResourceProvider* resource_provider =
474 layer_tree_host_impl_->resource_provider();
475
476 if (!contents_texture_manager || !resource_provider)
477 return false;
478
479 return contents_texture_manager->ReduceMemoryOnImplThread(
480 limit_bytes, priority_cutoff, resource_provider);
481 }
482
483 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
484
485 void SingleThreadProxy::DidActivateSyncTree() {
486 // Non-impl-side painting finishes commit in DoCommit. Impl-side painting
487 // defers until here to simulate SetNextCommitWaitsForActivation.
488 if (layer_tree_host_impl_->settings().impl_side_painting) {
489 // This is required because NotifyReadyToActivate gets called immediately
490 // after commit since single thread commits directly to the active tree.
491 layer_tree_host_impl_->SetRequiresHighResToDraw();
492
493 // Synchronously call to CommitComplete. Resetting
494 // |commit_blocking_task_runner| would make sure all tasks posted during
495 // commit/activation before CommitComplete.
496 CommitComplete();
497 }
498
499 timing_history_.DidActivateSyncTree();
500 }
501
502 void SingleThreadProxy::DidPrepareTiles() {
503 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
504 DCHECK(Proxy::IsImplThread());
505 if (scheduler_on_impl_thread_)
506 scheduler_on_impl_thread_->DidPrepareTiles();
507 }
508
509 void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
510 layer_tree_host_->DidCompletePageScaleAnimation();
511 }
512
513 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
514 DCHECK(IsImplThread());
515 renderer_capabilities_for_main_thread_ =
516 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
517 }
518
519 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
520 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
521 {
522 DebugScopedSetMainThread main(this);
523 // This must happen before we notify the scheduler as it may try to recreate
524 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
525 layer_tree_host_->DidLoseOutputSurface();
526 }
527 client_->DidAbortSwapBuffers();
528 if (scheduler_on_impl_thread_)
529 scheduler_on_impl_thread_->DidLoseOutputSurface();
530 }
531
532 void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
533 base::TimeDelta interval) {
534 if (scheduler_on_impl_thread_)
535 scheduler_on_impl_thread_->CommitVSyncParameters(timebase, interval);
536 }
537
538 void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
539 if (scheduler_on_impl_thread_)
540 scheduler_on_impl_thread_->SetEstimatedParentDrawTime(draw_time);
541 }
542
543 void SingleThreadProxy::DidSwapBuffersOnImplThread() {
544 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
545 if (scheduler_on_impl_thread_)
546 scheduler_on_impl_thread_->DidSwapBuffers();
547 client_->DidPostSwapBuffers();
548 }
549
550 void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
551 TRACE_EVENT0("cc,benchmark",
552 "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
553 if (scheduler_on_impl_thread_)
554 scheduler_on_impl_thread_->DidSwapBuffersComplete();
555 layer_tree_host_->DidCompleteSwapBuffers();
556 }
557
558 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
559 TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
560 DCHECK(Proxy::IsMainThread());
561 base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);
562
563 if (layer_tree_host_->output_surface_lost()) {
564 RequestNewOutputSurface();
565 // RequestNewOutputSurface could have synchronously created an output
566 // surface, so check again before returning.
567 if (layer_tree_host_->output_surface_lost())
568 return;
569 }
570
571 {
572 BeginFrameArgs begin_frame_args(BeginFrameArgs::Create(
573 BEGINFRAME_FROM_HERE, frame_begin_time, base::TimeTicks(),
574 BeginFrameArgs::DefaultInterval(), BeginFrameArgs::SYNCHRONOUS));
575 DoBeginMainFrame(begin_frame_args);
576 DoCommit();
577
578 DCHECK_EQ(0u, layer_tree_host_->num_queued_swap_promises())
579 << "Commit should always succeed and transfer promises.";
580 }
581
582 {
583 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
584 if (layer_tree_host_impl_->settings().impl_side_painting) {
585 layer_tree_host_impl_->ActivateSyncTree();
586 DCHECK(!layer_tree_host_impl_->active_tree()
587 ->needs_update_draw_properties());
588 layer_tree_host_impl_->PrepareTiles();
589 layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
590 }
591
592 DoAnimate();
593
594 LayerTreeHostImpl::FrameData frame;
595 DoComposite(frame_begin_time, &frame);
596
597 // DoComposite could abort, but because this is a synchronous composite
598 // another draw will never be scheduled, so break remaining promises.
599 layer_tree_host_impl_->active_tree()->BreakSwapPromises(
600 SwapPromise::SWAP_FAILS);
601 }
602 }
603
604 void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
605 {
606 DebugScopedSetImplThread impl(this);
607 if (layer_tree_host_impl_->renderer()) {
608 DCHECK(!layer_tree_host_->output_surface_lost());
609 layer_tree_host_impl_->renderer()->DoNoOp();
610 }
611 }
612 }
613
614 bool SingleThreadProxy::SupportsImplScrolling() const {
615 return false;
616 }
617
618 bool SingleThreadProxy::ShouldComposite() const {
619 DCHECK(Proxy::IsImplThread());
620 return layer_tree_host_impl_->visible() &&
621 layer_tree_host_impl_->CanDraw();
622 }
623
624 void SingleThreadProxy::ScheduleRequestNewOutputSurface() {
625 if (output_surface_creation_callback_.IsCancelled() &&
626 !output_surface_creation_requested_) {
627 output_surface_creation_callback_.Reset(
628 base::Bind(&SingleThreadProxy::RequestNewOutputSurface,
629 weak_factory_.GetWeakPtr()));
630 MainThreadTaskRunner()->PostTask(
631 FROM_HERE, output_surface_creation_callback_.callback());
632 }
633 }
634
635 DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time,
636 LayerTreeHostImpl::FrameData* frame) {
637 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
638 DCHECK(!layer_tree_host_->output_surface_lost());
639
640 DrawResult draw_result;
641 bool draw_frame;
642 {
643 DebugScopedSetImplThread impl(this);
644 base::AutoReset<bool> mark_inside(&inside_draw_, true);
645
646 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
647 // is fixed.
648 tracked_objects::ScopedTracker tracking_profile1(
649 FROM_HERE_WITH_EXPLICIT_FUNCTION(
650 "461509 SingleThreadProxy::DoComposite1"));
651
652 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
653 // frame, so can only be used when such a frame is possible. Since
654 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
655 // CanDraw() as well.
656 if (!ShouldComposite()) {
657 return DRAW_ABORTED_CANT_DRAW;
658 }
659
660 timing_history_.DidStartDrawing();
661
662 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
663 // is fixed.
664 tracked_objects::ScopedTracker tracking_profile2(
665 FROM_HERE_WITH_EXPLICIT_FUNCTION(
666 "461509 SingleThreadProxy::DoComposite2"));
667 draw_result = layer_tree_host_impl_->PrepareToDraw(frame);
668 draw_frame = draw_result == DRAW_SUCCESS;
669 if (draw_frame) {
670 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
671 // is fixed.
672 tracked_objects::ScopedTracker tracking_profile3(
673 FROM_HERE_WITH_EXPLICIT_FUNCTION(
674 "461509 SingleThreadProxy::DoComposite3"));
675 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
676 }
677 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
678 // is fixed.
679 tracked_objects::ScopedTracker tracking_profile4(
680 FROM_HERE_WITH_EXPLICIT_FUNCTION(
681 "461509 SingleThreadProxy::DoComposite4"));
682 layer_tree_host_impl_->DidDrawAllLayers(*frame);
683
684 bool start_ready_animations = draw_frame;
685 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
686 // is fixed.
687 tracked_objects::ScopedTracker tracking_profile5(
688 FROM_HERE_WITH_EXPLICIT_FUNCTION(
689 "461509 SingleThreadProxy::DoComposite5"));
690 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
691 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
692 // is fixed.
693 tracked_objects::ScopedTracker tracking_profile6(
694 FROM_HERE_WITH_EXPLICIT_FUNCTION(
695 "461509 SingleThreadProxy::DoComposite6"));
696 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
697
698 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
699 // is fixed.
700 tracked_objects::ScopedTracker tracking_profile7(
701 FROM_HERE_WITH_EXPLICIT_FUNCTION(
702 "461509 SingleThreadProxy::DoComposite7"));
703 timing_history_.DidFinishDrawing();
704 }
705
706 if (draw_frame) {
707 DebugScopedSetImplThread impl(this);
708
709 // This CapturePostTasks should be destroyed before
710 // DidCommitAndDrawFrame() is called since that goes out to the
711 // embedder,
712 // and we want the embedder to receive its callbacks before that.
713 // NOTE: This maintains consistent ordering with the ThreadProxy since
714 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
715 // there as the main thread is not blocked, so any posted tasks inside
716 // the swap buffers will execute first.
717 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
718
719 BlockingTaskRunner::CapturePostTasks blocked(
720 blocking_main_thread_task_runner());
721 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
722 // is fixed.
723 tracked_objects::ScopedTracker tracking_profile8(
724 FROM_HERE_WITH_EXPLICIT_FUNCTION(
725 "461509 SingleThreadProxy::DoComposite8"));
726 layer_tree_host_impl_->SwapBuffers(*frame);
727 }
728 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509 is
729 // fixed.
730 tracked_objects::ScopedTracker tracking_profile9(
731 FROM_HERE_WITH_EXPLICIT_FUNCTION(
732 "461509 SingleThreadProxy::DoComposite9"));
733 DidCommitAndDrawFrame();
734
735 return draw_result;
736 }
737
738 void SingleThreadProxy::DidCommitAndDrawFrame() {
739 if (next_frame_is_newly_committed_frame_) {
740 DebugScopedSetMainThread main(this);
741 next_frame_is_newly_committed_frame_ = false;
742 layer_tree_host_->DidCommitAndDrawFrame();
743 }
744 }
745
746 bool SingleThreadProxy::MainFrameWillHappenForTesting() {
747 return false;
748 }
749
750 void SingleThreadProxy::SetChildrenNeedBeginFrames(
751 bool children_need_begin_frames) {
752 scheduler_on_impl_thread_->SetChildrenNeedBeginFrames(
753 children_need_begin_frames);
754 }
755
756 void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
757 layer_tree_host_impl_->WillBeginImplFrame(args);
758 }
759
760 void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
761 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
762 // Although this proxy is single-threaded, it's problematic to synchronously
763 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
764 // could cause a commit to occur in between a series of SetNeedsCommit calls
765 // (i.e. property modifications) causing some to fall on one frame and some to
766 // fall on the next. Doing it asynchronously instead matches the semantics of
767 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
768 // synchronous commit.
769 MainThreadTaskRunner()->PostTask(
770 FROM_HERE,
771 base::Bind(&SingleThreadProxy::BeginMainFrame,
772 weak_factory_.GetWeakPtr()));
773 }
774
775 void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
776 layer_tree_host_->BeginMainFrameNotExpectedSoon();
777 }
778
779 void SingleThreadProxy::BeginMainFrame() {
780 if (defer_commits_) {
781 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
782 TRACE_EVENT_SCOPE_THREAD);
783 BeginMainFrameAbortedOnImplThread(
784 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
785 return;
786 }
787
788 // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
789 // commit.
790 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
791
792 if (!layer_tree_host_->visible()) {
793 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
794 BeginMainFrameAbortedOnImplThread(
795 CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
796 return;
797 }
798
799 if (layer_tree_host_->output_surface_lost()) {
800 TRACE_EVENT_INSTANT0(
801 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
802 BeginMainFrameAbortedOnImplThread(
803 CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST);
804 return;
805 }
806
807 const BeginFrameArgs& begin_frame_args =
808 layer_tree_host_impl_->CurrentBeginFrameArgs();
809 DoBeginMainFrame(begin_frame_args);
810 }
811
812 void SingleThreadProxy::DoBeginMainFrame(
813 const BeginFrameArgs& begin_frame_args) {
814 layer_tree_host_->WillBeginMainFrame();
815 layer_tree_host_->BeginMainFrame(begin_frame_args);
816 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
817 layer_tree_host_->Layout();
818
819 if (PrioritizedResourceManager* contents_texture_manager =
820 layer_tree_host_->contents_texture_manager()) {
821 contents_texture_manager->UnlinkAndClearEvictedBackings();
822 contents_texture_manager->SetMaxMemoryLimitBytes(
823 layer_tree_host_impl_->memory_allocation_limit_bytes());
824 contents_texture_manager->SetExternalPriorityCutoff(
825 layer_tree_host_impl_->memory_allocation_priority_cutoff());
826 }
827
828 DCHECK(!queue_for_commit_);
829 queue_for_commit_ = make_scoped_ptr(new ResourceUpdateQueue);
830
831 layer_tree_host_->UpdateLayers(queue_for_commit_.get());
832
833 timing_history_.DidBeginMainFrame();
834
835 // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
836 // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
837 // thread_proxy.cc
838 if (scheduler_on_impl_thread_) {
839 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
840 scheduler_on_impl_thread_->NotifyReadyToCommit();
841 }
842 }
843
844 void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
845 CommitEarlyOutReason reason) {
846 DebugScopedSetImplThread impl(this);
847 DCHECK(scheduler_on_impl_thread_->CommitPending());
848 DCHECK(!layer_tree_host_impl_->pending_tree());
849
850 layer_tree_host_impl_->BeginMainFrameAborted(reason);
851 scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
852 }
853
854 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
855 DebugScopedSetImplThread impl(this);
856 LayerTreeHostImpl::FrameData frame;
857 return DoComposite(layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time,
858 &frame);
859 }
860
861 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
862 NOTREACHED();
863 return INVALID_RESULT;
864 }
865
866 void SingleThreadProxy::ScheduledActionCommit() {
867 DebugScopedSetMainThread main(this);
868 DoCommit();
869 }
870
871 void SingleThreadProxy::ScheduledActionAnimate() {
872 TRACE_EVENT0("cc", "ScheduledActionAnimate");
873 DebugScopedSetImplThread impl(this);
874 DoAnimate();
875 }
876
877 void SingleThreadProxy::ScheduledActionActivateSyncTree() {
878 DebugScopedSetImplThread impl(this);
879 layer_tree_host_impl_->ActivateSyncTree();
880 }
881
882 void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
883 DebugScopedSetMainThread main(this);
884 DCHECK(scheduler_on_impl_thread_);
885 // If possible, create the output surface in a post task. Synchronously
886 // creating the output surface makes tests more awkward since this differs
887 // from the ThreadProxy behavior. However, sometimes there is no
888 // task runner.
889 if (Proxy::MainThreadTaskRunner()) {
890 ScheduleRequestNewOutputSurface();
891 } else {
892 RequestNewOutputSurface();
893 }
894 }
895
896 void SingleThreadProxy::ScheduledActionPrepareTiles() {
897 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
898 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
899 DebugScopedSetImplThread impl(this);
900 layer_tree_host_impl_->PrepareTiles();
901 }
902
903 void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
904 }
905
906 base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
907 return timing_history_.DrawDurationEstimate();
908 }
909
910 base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
911 return timing_history_.BeginMainFrameToCommitDurationEstimate();
912 }
913
914 base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
915 return timing_history_.CommitToActivateDurationEstimate();
916 }
917
918 void SingleThreadProxy::DidBeginImplFrameDeadline() {
919 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
920 }
921
922 void SingleThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) {
923 layer_tree_host_->SendBeginFramesToChildren(args);
924 }
925
926 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/single_thread_proxy.h ('k') | cc/trees/swap_promise_monitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698