Update mojo surfaces bindings and mojo/cc/ glue
[chromium-blink-merge.git] / cc / trees / single_thread_proxy.cc
blob12898df950658050255fc33a4667f3ac758d72f8
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.
5 #include "cc/trees/single_thread_proxy.h"
7 #include "base/auto_reset.h"
8 #include "base/debug/trace_event.h"
9 #include "cc/debug/benchmark_instrumentation.h"
10 #include "cc/output/context_provider.h"
11 #include "cc/output/output_surface.h"
12 #include "cc/quads/draw_quad.h"
13 #include "cc/resources/prioritized_resource_manager.h"
14 #include "cc/resources/resource_update_controller.h"
15 #include "cc/trees/blocking_task_runner.h"
16 #include "cc/trees/layer_tree_host.h"
17 #include "cc/trees/layer_tree_host_single_thread_client.h"
18 #include "cc/trees/layer_tree_impl.h"
19 #include "cc/trees/scoped_abort_remaining_swap_promises.h"
20 #include "ui/gfx/frame_time.h"
22 namespace cc {
24 scoped_ptr<Proxy> SingleThreadProxy::Create(
25 LayerTreeHost* layer_tree_host,
26 LayerTreeHostSingleThreadClient* client,
27 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
28 return make_scoped_ptr(
29 new SingleThreadProxy(layer_tree_host, client, main_task_runner))
30 .PassAs<Proxy>();
33 SingleThreadProxy::SingleThreadProxy(
34 LayerTreeHost* layer_tree_host,
35 LayerTreeHostSingleThreadClient* client,
36 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
37 : Proxy(main_task_runner, NULL),
38 layer_tree_host_(layer_tree_host),
39 client_(client),
40 timing_history_(layer_tree_host->rendering_stats_instrumentation()),
41 next_frame_is_newly_committed_frame_(false),
42 inside_draw_(false),
43 defer_commits_(false),
44 commit_was_deferred_(false),
45 commit_requested_(false),
46 weak_factory_(this) {
47 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
48 DCHECK(Proxy::IsMainThread());
49 DCHECK(layer_tree_host);
51 // Impl-side painting not supported without threaded compositing.
52 CHECK(!layer_tree_host->settings().impl_side_painting)
53 << "Threaded compositing must be enabled to use impl-side painting.";
56 void SingleThreadProxy::Start() {
57 DebugScopedSetImplThread impl(this);
58 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
61 SingleThreadProxy::~SingleThreadProxy() {
62 TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
63 DCHECK(Proxy::IsMainThread());
64 // Make sure Stop() got called or never Started.
65 DCHECK(!layer_tree_host_impl_);
68 void SingleThreadProxy::FinishAllRendering() {
69 TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering");
70 DCHECK(Proxy::IsMainThread());
72 DebugScopedSetImplThread impl(this);
73 layer_tree_host_impl_->FinishAllRendering();
77 bool SingleThreadProxy::IsStarted() const {
78 DCHECK(Proxy::IsMainThread());
79 return layer_tree_host_impl_;
82 void SingleThreadProxy::SetLayerTreeHostClientReady() {
83 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
84 // Scheduling is controlled by the embedder in the single thread case, so
85 // nothing to do.
86 DCHECK(Proxy::IsMainThread());
87 DebugScopedSetImplThread impl(this);
88 if (layer_tree_host_->settings().single_thread_proxy_scheduler &&
89 !scheduler_on_impl_thread_) {
90 SchedulerSettings scheduler_settings(layer_tree_host_->settings());
91 scheduler_on_impl_thread_ = Scheduler::Create(this,
92 scheduler_settings,
93 layer_tree_host_->id(),
94 MainThreadTaskRunner());
95 scheduler_on_impl_thread_->SetCanStart();
96 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
100 void SingleThreadProxy::SetVisible(bool visible) {
101 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible");
102 DebugScopedSetImplThread impl(this);
103 layer_tree_host_impl_->SetVisible(visible);
104 if (scheduler_on_impl_thread_)
105 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
106 // Changing visibility could change ShouldComposite().
107 UpdateBackgroundAnimateTicking();
110 void SingleThreadProxy::CreateAndInitializeOutputSurface() {
111 TRACE_EVENT0(
112 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
113 DCHECK(Proxy::IsMainThread());
114 DCHECK(layer_tree_host_->output_surface_lost());
116 scoped_ptr<OutputSurface> output_surface =
117 layer_tree_host_->CreateOutputSurface();
119 renderer_capabilities_for_main_thread_ = RendererCapabilities();
121 bool success = !!output_surface;
122 if (success) {
123 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
124 DebugScopedSetImplThread impl(this);
125 layer_tree_host_->DeleteContentsTexturesOnImplThread(
126 layer_tree_host_impl_->resource_provider());
127 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
130 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
132 if (success) {
133 if (scheduler_on_impl_thread_)
134 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
135 } else if (Proxy::MainThreadTaskRunner()) {
136 MainThreadTaskRunner()->PostTask(
137 FROM_HERE,
138 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface,
139 weak_factory_.GetWeakPtr()));
143 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
144 DCHECK(Proxy::IsMainThread());
145 DCHECK(!layer_tree_host_->output_surface_lost());
146 return renderer_capabilities_for_main_thread_;
149 void SingleThreadProxy::SetNeedsAnimate() {
150 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
151 DCHECK(Proxy::IsMainThread());
152 client_->ScheduleAnimation();
153 SetNeedsCommit();
156 void SingleThreadProxy::SetNeedsUpdateLayers() {
157 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
158 DCHECK(Proxy::IsMainThread());
159 SetNeedsCommit();
162 void SingleThreadProxy::DoCommit(const BeginFrameArgs& begin_frame_args) {
163 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
164 DCHECK(Proxy::IsMainThread());
165 layer_tree_host_->WillBeginMainFrame();
166 layer_tree_host_->BeginMainFrame(begin_frame_args);
167 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
168 layer_tree_host_->Layout();
169 commit_requested_ = false;
171 if (PrioritizedResourceManager* contents_texture_manager =
172 layer_tree_host_->contents_texture_manager()) {
173 contents_texture_manager->UnlinkAndClearEvictedBackings();
174 contents_texture_manager->SetMaxMemoryLimitBytes(
175 layer_tree_host_impl_->memory_allocation_limit_bytes());
176 contents_texture_manager->SetExternalPriorityCutoff(
177 layer_tree_host_impl_->memory_allocation_priority_cutoff());
180 scoped_ptr<ResourceUpdateQueue> queue =
181 make_scoped_ptr(new ResourceUpdateQueue);
183 layer_tree_host_->UpdateLayers(queue.get());
185 layer_tree_host_->WillCommit();
187 // Commit immediately.
189 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
190 DebugScopedSetImplThread impl(this);
192 // This CapturePostTasks should be destroyed before CommitComplete() is
193 // called since that goes out to the embedder, and we want the embedder
194 // to receive its callbacks before that.
195 BlockingTaskRunner::CapturePostTasks blocked;
197 layer_tree_host_impl_->BeginCommit();
199 if (PrioritizedResourceManager* contents_texture_manager =
200 layer_tree_host_->contents_texture_manager()) {
201 contents_texture_manager->PushTexturePrioritiesToBackings();
203 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
205 scoped_ptr<ResourceUpdateController> update_controller =
206 ResourceUpdateController::Create(
207 NULL,
208 MainThreadTaskRunner(),
209 queue.Pass(),
210 layer_tree_host_impl_->resource_provider());
211 update_controller->Finalize();
213 if (layer_tree_host_impl_->EvictedUIResourcesExist())
214 layer_tree_host_->RecreateUIResources();
216 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
218 layer_tree_host_impl_->CommitComplete();
220 UpdateBackgroundAnimateTicking();
222 #if DCHECK_IS_ON
223 // In the single-threaded case, the scale and scroll deltas should never be
224 // touched on the impl layer tree.
225 scoped_ptr<ScrollAndScaleSet> scroll_info =
226 layer_tree_host_impl_->ProcessScrollDeltas();
227 DCHECK(!scroll_info->scrolls.size());
228 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
229 #endif
231 RenderingStatsInstrumentation* stats_instrumentation =
232 layer_tree_host_->rendering_stats_instrumentation();
233 benchmark_instrumentation::IssueMainThreadRenderingStatsEvent(
234 stats_instrumentation->main_thread_rendering_stats());
235 stats_instrumentation->AccumulateAndClearMainThreadStats();
237 layer_tree_host_->CommitComplete();
238 layer_tree_host_->DidBeginMainFrame();
239 timing_history_.DidCommit();
241 next_frame_is_newly_committed_frame_ = true;
244 void SingleThreadProxy::SetNeedsCommit() {
245 DCHECK(Proxy::IsMainThread());
246 DebugScopedSetImplThread impl(this);
247 client_->ScheduleComposite();
248 if (scheduler_on_impl_thread_)
249 scheduler_on_impl_thread_->SetNeedsCommit();
250 commit_requested_ = true;
253 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
254 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
255 DCHECK(Proxy::IsMainThread());
256 DebugScopedSetImplThread impl(this);
257 client_->ScheduleComposite();
258 SetNeedsRedrawRectOnImplThread(damage_rect);
261 void SingleThreadProxy::SetNextCommitWaitsForActivation() {
262 // There is no activation here other than commit. So do nothing.
263 DCHECK(Proxy::IsMainThread());
266 void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
267 DCHECK(Proxy::IsMainThread());
268 // Deferring commits only makes sense if there's a scheduler.
269 if (!scheduler_on_impl_thread_)
270 return;
271 if (defer_commits_ == defer_commits)
272 return;
274 if (defer_commits)
275 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
276 else
277 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
279 defer_commits_ = defer_commits;
280 if (!defer_commits_ && commit_was_deferred_) {
281 commit_was_deferred_ = false;
282 BeginMainFrame();
286 bool SingleThreadProxy::CommitRequested() const {
287 DCHECK(Proxy::IsMainThread());
288 return commit_requested_;
291 bool SingleThreadProxy::BeginMainFrameRequested() const {
292 DCHECK(Proxy::IsMainThread());
293 // If there is no scheduler, then there can be no pending begin frame,
294 // as all frames are all manually initiated by the embedder of cc.
295 if (!scheduler_on_impl_thread_)
296 return false;
297 return commit_requested_;
300 size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
301 return std::numeric_limits<size_t>::max();
304 void SingleThreadProxy::Stop() {
305 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
306 DCHECK(Proxy::IsMainThread());
308 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
309 DebugScopedSetImplThread impl(this);
311 BlockingTaskRunner::CapturePostTasks blocked;
312 layer_tree_host_->DeleteContentsTexturesOnImplThread(
313 layer_tree_host_impl_->resource_provider());
314 scheduler_on_impl_thread_.reset();
315 layer_tree_host_impl_.reset();
317 layer_tree_host_ = NULL;
320 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
321 TRACE_EVENT1(
322 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
323 DCHECK(Proxy::IsImplThread());
324 UpdateBackgroundAnimateTicking();
325 if (scheduler_on_impl_thread_)
326 scheduler_on_impl_thread_->SetCanDraw(can_draw);
329 void SingleThreadProxy::NotifyReadyToActivate() {
330 // Impl-side painting only.
331 NOTREACHED();
334 void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
335 client_->ScheduleComposite();
336 if (scheduler_on_impl_thread_)
337 scheduler_on_impl_thread_->SetNeedsRedraw();
340 void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
341 SetNeedsRedrawOnImplThread();
344 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
345 // Impl-side painting only.
346 NOTREACHED();
349 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
350 const gfx::Rect& damage_rect) {
351 layer_tree_host_impl_->SetViewportDamage(damage_rect);
352 SetNeedsRedrawOnImplThread();
355 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
356 // Impl-side painting only.
357 NOTREACHED();
360 void SingleThreadProxy::SetNeedsCommitOnImplThread() {
361 client_->ScheduleComposite();
362 if (scheduler_on_impl_thread_)
363 scheduler_on_impl_thread_->SetNeedsCommit();
366 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
367 scoped_ptr<AnimationEventsVector> events) {
368 TRACE_EVENT0(
369 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
370 DCHECK(Proxy::IsImplThread());
371 DebugScopedSetMainThread main(this);
372 layer_tree_host_->SetAnimationEvents(events.Pass());
375 bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
376 size_t limit_bytes,
377 int priority_cutoff) {
378 DCHECK(IsImplThread());
379 PrioritizedResourceManager* contents_texture_manager =
380 layer_tree_host_->contents_texture_manager();
382 ResourceProvider* resource_provider =
383 layer_tree_host_impl_->resource_provider();
385 if (!contents_texture_manager || !resource_provider)
386 return false;
388 return contents_texture_manager->ReduceMemoryOnImplThread(
389 limit_bytes, priority_cutoff, resource_provider);
392 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
394 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
395 DCHECK(IsImplThread());
396 renderer_capabilities_for_main_thread_ =
397 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
400 void SingleThreadProxy::DidManageTiles() {
401 // Impl-side painting only.
402 NOTREACHED();
405 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
406 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
408 DebugScopedSetMainThread main(this);
409 // This must happen before we notify the scheduler as it may try to recreate
410 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
411 layer_tree_host_->DidLoseOutputSurface();
413 client_->DidAbortSwapBuffers();
414 if (scheduler_on_impl_thread_)
415 scheduler_on_impl_thread_->DidLoseOutputSurface();
418 void SingleThreadProxy::DidSwapBuffersOnImplThread() {
419 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
420 if (scheduler_on_impl_thread_)
421 scheduler_on_impl_thread_->DidSwapBuffers();
422 client_->DidPostSwapBuffers();
425 void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
426 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
427 if (scheduler_on_impl_thread_)
428 scheduler_on_impl_thread_->DidSwapBuffersComplete();
429 layer_tree_host_->DidCompleteSwapBuffers();
432 void SingleThreadProxy::BeginFrame(const BeginFrameArgs& args) {
433 TRACE_EVENT0("cc", "SingleThreadProxy::BeginFrame");
434 if (scheduler_on_impl_thread_)
435 scheduler_on_impl_thread_->BeginImplFrame(args);
438 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
439 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately");
440 DCHECK(Proxy::IsMainThread());
441 DCHECK(!layer_tree_host_->output_surface_lost());
443 BeginFrameArgs begin_frame_args = BeginFrameArgs::Create(
444 frame_begin_time, base::TimeTicks(), BeginFrameArgs::DefaultInterval());
445 DoCommit(begin_frame_args);
447 LayerTreeHostImpl::FrameData frame;
448 DoComposite(frame_begin_time, &frame);
451 void SingleThreadProxy::AsValueInto(base::debug::TracedValue* state) const {
452 // The following line casts away const modifiers because it is just
453 // setting debug state. We still want the AsValue() function and its
454 // call chain to be const throughout.
455 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
457 state->BeginDictionary("layer_tree_host_impl");
458 layer_tree_host_impl_->AsValueInto(state);
459 state->EndDictionary();
462 void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
464 DebugScopedSetImplThread impl(this);
465 if (layer_tree_host_impl_->renderer()) {
466 DCHECK(!layer_tree_host_->output_surface_lost());
467 layer_tree_host_impl_->renderer()->DoNoOp();
472 bool SingleThreadProxy::SupportsImplScrolling() const {
473 return false;
476 bool SingleThreadProxy::ShouldComposite() const {
477 DCHECK(Proxy::IsImplThread());
478 return layer_tree_host_impl_->visible() &&
479 layer_tree_host_impl_->CanDraw();
482 void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
483 DCHECK(Proxy::IsImplThread());
484 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
485 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
488 DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time,
489 LayerTreeHostImpl::FrameData* frame) {
490 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
491 DCHECK(!layer_tree_host_->output_surface_lost());
494 DebugScopedSetImplThread impl(this);
495 base::AutoReset<bool> mark_inside(&inside_draw_, true);
497 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
498 // frame, so can only be used when such a frame is possible. Since
499 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
500 // CanDraw() as well.
501 if (!ShouldComposite()) {
502 UpdateBackgroundAnimateTicking();
503 return DRAW_ABORTED_CANT_DRAW;
506 timing_history_.DidStartDrawing();
508 layer_tree_host_impl_->Animate(
509 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
510 UpdateBackgroundAnimateTicking();
512 if (!layer_tree_host_impl_->IsContextLost()) {
513 layer_tree_host_impl_->PrepareToDraw(frame);
514 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
515 layer_tree_host_impl_->DidDrawAllLayers(*frame);
518 bool start_ready_animations = true;
519 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
521 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
523 timing_history_.DidFinishDrawing();
527 DebugScopedSetImplThread impl(this);
529 if (layer_tree_host_impl_->IsContextLost()) {
530 DidLoseOutputSurfaceOnImplThread();
531 } else {
532 // This CapturePostTasks should be destroyed before
533 // DidCommitAndDrawFrame() is called since that goes out to the
534 // embedder,
535 // and we want the embedder to receive its callbacks before that.
536 // NOTE: This maintains consistent ordering with the ThreadProxy since
537 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
538 // there as the main thread is not blocked, so any posted tasks inside
539 // the swap buffers will execute first.
540 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
542 BlockingTaskRunner::CapturePostTasks blocked;
543 layer_tree_host_impl_->SwapBuffers(*frame);
546 DidCommitAndDrawFrame();
548 return DRAW_SUCCESS;
551 void SingleThreadProxy::DidCommitAndDrawFrame() {
552 if (next_frame_is_newly_committed_frame_) {
553 DebugScopedSetMainThread main(this);
554 next_frame_is_newly_committed_frame_ = false;
555 layer_tree_host_->DidCommitAndDrawFrame();
559 bool SingleThreadProxy::MainFrameWillHappenForTesting() {
560 return false;
563 void SingleThreadProxy::SetNeedsBeginFrame(bool enable) {
564 layer_tree_host_impl_->SetNeedsBeginFrame(enable);
567 void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
568 layer_tree_host_impl_->WillBeginImplFrame(args);
571 void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
572 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
573 // Although this proxy is single-threaded, it's problematic to synchronously
574 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
575 // could cause a commit to occur in between a series of SetNeedsCommit calls
576 // (i.e. property modifications) causing some to fall on one frame and some to
577 // fall on the next. Doing it asynchronously instead matches the semantics of
578 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
579 // synchronous commit.
580 MainThreadTaskRunner()->PostTask(
581 FROM_HERE,
582 base::Bind(&SingleThreadProxy::BeginMainFrame,
583 weak_factory_.GetWeakPtr()));
586 void SingleThreadProxy::BeginMainFrame() {
587 if (defer_commits_) {
588 DCHECK(!commit_was_deferred_);
589 commit_was_deferred_ = true;
590 layer_tree_host_->DidDeferCommit();
591 return;
594 // This checker assumes NotifyReadyToCommit below causes a synchronous commit.
595 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
597 if (!layer_tree_host_->visible()) {
598 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
599 BeginMainFrameAbortedOnImplThread();
600 return;
603 if (layer_tree_host_->output_surface_lost()) {
604 TRACE_EVENT_INSTANT0(
605 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
606 BeginMainFrameAbortedOnImplThread();
607 return;
610 timing_history_.DidBeginMainFrame();
612 DCHECK(scheduler_on_impl_thread_);
613 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
614 scheduler_on_impl_thread_->NotifyReadyToCommit();
617 void SingleThreadProxy::BeginMainFrameAbortedOnImplThread() {
618 DebugScopedSetImplThread impl(this);
619 DCHECK(scheduler_on_impl_thread_->CommitPending());
620 DCHECK(!layer_tree_host_impl_->pending_tree());
622 // TODO(enne): SingleThreadProxy does not support cancelling commits yet so
623 // did_handle is always false.
624 bool did_handle = false;
625 layer_tree_host_impl_->BeginMainFrameAborted(did_handle);
626 scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle);
629 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
630 DebugScopedSetImplThread impl(this);
631 if (layer_tree_host_impl_->IsContextLost()) {
632 DidCommitAndDrawFrame();
633 return DRAW_SUCCESS;
636 LayerTreeHostImpl::FrameData frame;
637 return DoComposite(layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time,
638 &frame);
641 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
642 NOTREACHED();
643 return INVALID_RESULT;
646 void SingleThreadProxy::ScheduledActionCommit() {
647 DebugScopedSetMainThread main(this);
648 DoCommit(layer_tree_host_impl_->CurrentBeginFrameArgs());
651 void SingleThreadProxy::ScheduledActionAnimate() {
652 TRACE_EVENT0("cc", "ScheduledActionAnimate");
653 layer_tree_host_impl_->Animate(
654 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
657 void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() {
658 // Impl-side painting only.
659 NOTREACHED();
662 void SingleThreadProxy::ScheduledActionActivateSyncTree() {
665 void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
666 DebugScopedSetMainThread main(this);
667 DCHECK(scheduler_on_impl_thread_);
668 // If possible, create the output surface in a post task. Synchronously
669 // creating the output surface makes tests more awkward since this differs
670 // from the ThreadProxy behavior. However, sometimes there is no
671 // task runner.
672 if (Proxy::MainThreadTaskRunner()) {
673 MainThreadTaskRunner()->PostTask(
674 FROM_HERE,
675 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface,
676 weak_factory_.GetWeakPtr()));
677 } else {
678 CreateAndInitializeOutputSurface();
682 void SingleThreadProxy::ScheduledActionManageTiles() {
683 // Impl-side painting only.
684 NOTREACHED();
687 void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
690 base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
691 return timing_history_.DrawDurationEstimate();
694 base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
695 return timing_history_.BeginMainFrameToCommitDurationEstimate();
698 base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
699 return timing_history_.CommitToActivateDurationEstimate();
702 void SingleThreadProxy::DidBeginImplFrameDeadline() {
703 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
706 } // namespace cc