| Index: cc/trees/single_thread_proxy.cc
|
| diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
|
| index 4031509a8ffdd7b527c44a5260336e5dcdc2e0e1..7689249f5ecb8c4788413cd647897f0568bdee4b 100644
|
| --- a/cc/trees/single_thread_proxy.cc
|
| +++ b/cc/trees/single_thread_proxy.cc
|
| @@ -34,7 +34,10 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
|
| client_(client),
|
| created_offscreen_context_provider_(false),
|
| next_frame_is_newly_committed_frame_(false),
|
| - inside_draw_(false) {
|
| + inside_draw_(false),
|
| + defer_commits_(false),
|
| + finish_commit_deferred_(false),
|
| + weak_factory_(this) {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
|
| DCHECK(Proxy::IsMainThread());
|
| DCHECK(layer_tree_host);
|
| @@ -47,6 +50,10 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
|
| void SingleThreadProxy::Start() {
|
| DebugScopedSetImplThread impl(this);
|
| layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
|
| + SchedulerSettings scheduler_settings(layer_tree_host_->settings());
|
| + scheduler_on_impl_thread_ =
|
| + Scheduler::Create(this, scheduler_settings, layer_tree_host_->id());
|
| + scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
|
| }
|
|
|
| SingleThreadProxy::~SingleThreadProxy() {
|
| @@ -60,14 +67,15 @@ bool SingleThreadProxy::CompositeAndReadback(void* pixels,
|
| const gfx::Rect& rect) {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback");
|
| DCHECK(Proxy::IsMainThread());
|
| -
|
| - gfx::Rect device_viewport_damage_rect = rect;
|
| -
|
| - LayerTreeHostImpl::FrameData frame;
|
| - if (!CommitAndComposite(gfx::FrameTime::Now(),
|
| - device_viewport_damage_rect,
|
| - true, // for_readback
|
| - &frame))
|
| + // TODO(enne): make this go through the SetNeedsForcedCommitForReadback logic.
|
| + bool do_commit = true;
|
| + bool for_readback = true;
|
| + gfx::Rect device_viewport_damage_rect(rect);
|
| + if (CommitAndCompositeInternal(gfx::FrameTime::Now(),
|
| + device_viewport_damage_rect,
|
| + do_commit,
|
| + for_readback).draw_result !=
|
| + DrawSwapReadbackResult::DRAW_SUCCESS)
|
| return false;
|
|
|
| {
|
| @@ -99,12 +107,16 @@ void SingleThreadProxy::SetLayerTreeHostClientReady() {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
|
| // Scheduling is controlled by the embedder in the single thread case, so
|
| // nothing to do.
|
| + DCHECK(Proxy::IsMainThread());
|
| + DebugScopedSetImplThread impl(this);
|
| + scheduler_on_impl_thread_->SetCanStart();
|
| }
|
|
|
| void SingleThreadProxy::SetVisible(bool visible) {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible");
|
| DebugScopedSetImplThread impl(this);
|
| layer_tree_host_impl_->SetVisible(visible);
|
| + scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
|
|
|
| // Changing visibility could change ShouldComposite().
|
| UpdateBackgroundAnimateTicking();
|
| @@ -157,14 +169,23 @@ void SingleThreadProxy::CreateAndInitializeOutputSurface() {
|
| }
|
|
|
| OnOutputSurfaceInitializeAttempted(initialized);
|
| +
|
| + // This must happen after OnCreateAndInitializeOutputSurfaceAttempted as it
|
| + // causes a commit and the output surface needs to be initialized beforehand.
|
| + if (initialized) {
|
| + DebugScopedSetImplThread impl(this);
|
| + scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
|
| + }
|
| }
|
|
|
| void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) {
|
| LayerTreeHost::CreateResult result =
|
| layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
|
| if (result == LayerTreeHost::CreateFailedButTryAgain) {
|
| - // Force another recreation attempt to happen by requesting another commit.
|
| - SetNeedsCommit();
|
| + Proxy::MainThreadTaskRunner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface,
|
| + weak_factory_.GetWeakPtr()));
|
| }
|
| }
|
|
|
| @@ -177,18 +198,38 @@ const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
|
| void SingleThreadProxy::SetNeedsAnimate() {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
|
| DCHECK(Proxy::IsMainThread());
|
| - client_->ScheduleAnimation();
|
| + SetNeedsCommit();
|
| }
|
|
|
| void SingleThreadProxy::SetNeedsUpdateLayers() {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
|
| DCHECK(Proxy::IsMainThread());
|
| - client_->ScheduleComposite();
|
| + SetNeedsCommit();
|
| }
|
|
|
| -void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
|
| +void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
|
| DCHECK(Proxy::IsMainThread());
|
| + layer_tree_host_->WillBeginMainFrame();
|
| + layer_tree_host_->Layout();
|
| + layer_tree_host_->AnimateLayers(frame_begin_time);
|
| +
|
| + if (PrioritizedResourceManager* contents_texture_manager =
|
| + layer_tree_host_->contents_texture_manager()) {
|
| + contents_texture_manager->UnlinkAndClearEvictedBackings();
|
| + contents_texture_manager->SetMaxMemoryLimitBytes(
|
| + layer_tree_host_impl_->memory_allocation_limit_bytes());
|
| + contents_texture_manager->SetExternalPriorityCutoff(
|
| + layer_tree_host_impl_->memory_allocation_priority_cutoff());
|
| + }
|
| +
|
| + scoped_ptr<ResourceUpdateQueue> queue =
|
| + make_scoped_ptr(new ResourceUpdateQueue);
|
| +
|
| + layer_tree_host_->UpdateLayers(queue.get());
|
| +
|
| + layer_tree_host_->WillCommit();
|
| +
|
| // Commit immediately.
|
| {
|
| DebugScopedSetMainThreadBlocked main_thread_blocked(this);
|
| @@ -222,6 +263,8 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
|
|
|
| layer_tree_host_impl_->CommitComplete();
|
|
|
| + UpdateBackgroundAnimateTicking();
|
| +
|
| #ifndef NDEBUG
|
| // In the single-threaded case, the scale and scroll deltas should never be
|
| // touched on the impl layer tree.
|
| @@ -238,32 +281,49 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
|
| stats_instrumentation->AccumulateAndClearMainThreadStats();
|
| }
|
| layer_tree_host_->CommitComplete();
|
| + layer_tree_host_->DidBeginMainFrame();
|
| + timing_history_.DidCommit();
|
| +
|
| next_frame_is_newly_committed_frame_ = true;
|
| }
|
|
|
| void SingleThreadProxy::SetNeedsCommit() {
|
| - DCHECK(Proxy::IsMainThread());
|
| - client_->ScheduleComposite();
|
| + scheduler_on_impl_thread_->SetNeedsCommit();
|
| }
|
|
|
| void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
|
| + DCHECK(Proxy::IsMainThread());
|
| + DebugScopedSetImplThread impl(this);
|
| SetNeedsRedrawRectOnImplThread(damage_rect);
|
| - client_->ScheduleComposite();
|
| }
|
|
|
| void SingleThreadProxy::SetNextCommitWaitsForActivation() {
|
| // There is no activation here other than commit. So do nothing.
|
| + DCHECK(Proxy::IsMainThread());
|
| }
|
|
|
| void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
|
| - // Thread-only feature.
|
| - NOTREACHED();
|
| + DCHECK(Proxy::IsMainThread());
|
| + if (defer_commits_ == defer_commits)
|
| + return;
|
| +
|
| + defer_commits_ = defer_commits;
|
| + if (!defer_commits_ && finish_commit_deferred_) {
|
| + scheduler_on_impl_thread_->FinishCommit();
|
| + finish_commit_deferred_ = false;
|
| + }
|
| }
|
|
|
| -bool SingleThreadProxy::CommitRequested() const { return false; }
|
| +bool SingleThreadProxy::CommitRequested() const {
|
| + DCHECK(Proxy::IsMainThread());
|
| + return finish_commit_deferred_;
|
| +}
|
|
|
| -bool SingleThreadProxy::BeginMainFrameRequested() const { return false; }
|
| +bool SingleThreadProxy::BeginMainFrameRequested() const {
|
| + DCHECK(Proxy::IsMainThread());
|
| + return finish_commit_deferred_;
|
| +}
|
|
|
| size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
|
| return std::numeric_limits<size_t>::max();
|
| @@ -278,6 +338,7 @@ void SingleThreadProxy::Stop() {
|
|
|
| layer_tree_host_->DeleteContentsTexturesOnImplThread(
|
| layer_tree_host_impl_->resource_provider());
|
| + scheduler_on_impl_thread_.reset();
|
| layer_tree_host_impl_.reset();
|
| }
|
| layer_tree_host_ = NULL;
|
| @@ -288,29 +349,27 @@ void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
|
| "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
|
| DCHECK(Proxy::IsImplThread());
|
| UpdateBackgroundAnimateTicking();
|
| + scheduler_on_impl_thread_->SetCanDraw(can_draw);
|
| }
|
|
|
| void SingleThreadProxy::NotifyReadyToActivate() {
|
| - // Thread-only feature.
|
| + // Impl-side painting only.
|
| NOTREACHED();
|
| }
|
|
|
| void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
|
| - client_->ScheduleComposite();
|
| + scheduler_on_impl_thread_->SetNeedsRedraw();
|
| }
|
|
|
| void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
|
| - // Thread-only/Impl-side-painting-only feature.
|
| + // Impl-side painting only.
|
| NOTREACHED();
|
| }
|
|
|
| void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
|
| const gfx::Rect& damage_rect) {
|
| - // TODO(brianderson): Once we move render_widget scheduling into this class,
|
| - // we can treat redraw requests more efficiently than CommitAndRedraw
|
| - // requests.
|
| layer_tree_host_impl_->SetViewportDamage(damage_rect);
|
| - SetNeedsCommit();
|
| + SetNeedsRedrawOnImplThread();
|
| }
|
|
|
| void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
|
| @@ -319,7 +378,7 @@ void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
|
| }
|
|
|
| void SingleThreadProxy::SetNeedsCommitOnImplThread() {
|
| - client_->ScheduleComposite();
|
| + scheduler_on_impl_thread_->SetNeedsCommit();
|
| }
|
|
|
| void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
|
| @@ -372,14 +431,34 @@ void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
|
| layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
|
| }
|
|
|
| +void SingleThreadProxy::DidActivatePendingTree() {
|
| + // Impl-side painting only.
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void SingleThreadProxy::DidManageTiles() {
|
| + // Impl-side painting only.
|
| + NOTREACHED();
|
| +}
|
| +
|
| void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
|
| - // Cause a commit so we can notice the lost context.
|
| - SetNeedsCommitOnImplThread();
|
| + {
|
| + DebugScopedSetMainThread main(this);
|
| + // This must happen before we notify the scheduler as it may try to recreate
|
| + // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
|
| + layer_tree_host_->DidLoseOutputSurface();
|
| + }
|
| +
|
| + // TODO(enne): this client call could maybe be removed.
|
| client_->DidAbortSwapBuffers();
|
| +
|
| + scheduler_on_impl_thread_->DidLoseOutputSurface();
|
| }
|
|
|
| void SingleThreadProxy::DidSwapBuffersOnImplThread() {
|
| + // TODO(enne): Maybe this is redundant with DidCommitAndDrawFrame and can be
|
| + // removed?
|
| client_->DidPostSwapBuffers();
|
| }
|
|
|
| @@ -388,34 +467,20 @@ void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() {
|
| client_->DidCompleteSwapBuffers();
|
| }
|
|
|
| -// Called by the legacy scheduling path (e.g. where render_widget does the
|
| -// scheduling)
|
| +void SingleThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
|
| + TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
|
| + scheduler_on_impl_thread_->BeginImplFrame(args);
|
| +}
|
| +
|
| void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
|
| TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately");
|
| + bool do_commit = true;
|
| + bool for_readback = false;
|
| gfx::Rect device_viewport_damage_rect;
|
| -
|
| - LayerTreeHostImpl::FrameData frame;
|
| - if (CommitAndComposite(frame_begin_time,
|
| - device_viewport_damage_rect,
|
| - false, // for_readback
|
| - &frame)) {
|
| - {
|
| - DebugScopedSetMainThreadBlocked main_thread_blocked(this);
|
| - DebugScopedSetImplThread impl(this);
|
| -
|
| - // This CapturePostTasks should be destroyed before
|
| - // DidCommitAndDrawFrame() is called since that goes out to the embedder,
|
| - // and we want the embedder to receive its callbacks before that.
|
| - // NOTE: This maintains consistent ordering with the ThreadProxy since
|
| - // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
|
| - // there as the main thread is not blocked, so any posted tasks inside
|
| - // the swap buffers will execute first.
|
| - BlockingTaskRunner::CapturePostTasks blocked;
|
| -
|
| - layer_tree_host_impl_->SwapBuffers(frame);
|
| - }
|
| - DidSwapFrame();
|
| - }
|
| + CommitAndCompositeInternal(gfx::FrameTime::Now(),
|
| + device_viewport_damage_rect,
|
| + do_commit,
|
| + for_readback);
|
| }
|
|
|
| scoped_ptr<base::Value> SingleThreadProxy::AsValue() const {
|
| @@ -442,34 +507,18 @@ void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
|
| }
|
| }
|
|
|
| -bool SingleThreadProxy::CommitAndComposite(
|
| - base::TimeTicks frame_begin_time,
|
| - const gfx::Rect& device_viewport_damage_rect,
|
| - bool for_readback,
|
| - LayerTreeHostImpl::FrameData* frame) {
|
| - TRACE_EVENT0("cc", "SingleThreadProxy::CommitAndComposite");
|
| - DCHECK(Proxy::IsMainThread());
|
| -
|
| - if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded())
|
| - return false;
|
| -
|
| - layer_tree_host_->AnimateLayers(frame_begin_time);
|
| -
|
| - if (PrioritizedResourceManager* contents_texture_manager =
|
| - layer_tree_host_->contents_texture_manager()) {
|
| - contents_texture_manager->UnlinkAndClearEvictedBackings();
|
| - contents_texture_manager->SetMaxMemoryLimitBytes(
|
| - layer_tree_host_impl_->memory_allocation_limit_bytes());
|
| - contents_texture_manager->SetExternalPriorityCutoff(
|
| - layer_tree_host_impl_->memory_allocation_priority_cutoff());
|
| - }
|
| -
|
| - scoped_ptr<ResourceUpdateQueue> queue =
|
| - make_scoped_ptr(new ResourceUpdateQueue);
|
| - layer_tree_host_->UpdateLayers(queue.get());
|
| +bool SingleThreadProxy::ShouldComposite() const {
|
| + DCHECK(Proxy::IsImplThread());
|
| + return scheduler_on_impl_thread_->WillDrawIfNeeded();
|
| +}
|
|
|
| - layer_tree_host_->WillCommit();
|
| +void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
|
| + DCHECK(Proxy::IsImplThread());
|
| + layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
|
| + !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
|
| +}
|
|
|
| +scoped_refptr<ContextProvider> SingleThreadProxy::OffscreenContextProvider() {
|
| scoped_refptr<ContextProvider> offscreen_context_provider;
|
| if (renderer_capabilities_for_main_thread_.using_offscreen_context3d &&
|
| layer_tree_host_->needs_offscreen_context()) {
|
| @@ -482,30 +531,10 @@ bool SingleThreadProxy::CommitAndComposite(
|
| if (offscreen_context_provider.get())
|
| created_offscreen_context_provider_ = true;
|
| }
|
| -
|
| - DoCommit(queue.Pass());
|
| - bool result = DoComposite(offscreen_context_provider,
|
| - frame_begin_time,
|
| - device_viewport_damage_rect,
|
| - for_readback,
|
| - frame);
|
| - layer_tree_host_->DidBeginMainFrame();
|
| - return result;
|
| -}
|
| -
|
| -bool SingleThreadProxy::ShouldComposite() const {
|
| - DCHECK(Proxy::IsImplThread());
|
| - return layer_tree_host_impl_->visible() &&
|
| - layer_tree_host_impl_->CanDraw();
|
| + return offscreen_context_provider;
|
| }
|
|
|
| -void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
|
| - DCHECK(Proxy::IsImplThread());
|
| - layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
|
| - !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
|
| -}
|
| -
|
| -bool SingleThreadProxy::DoComposite(
|
| +DrawSwapReadbackResult::DrawResult SingleThreadProxy::DoComposite(
|
| scoped_refptr<ContextProvider> offscreen_context_provider,
|
| base::TimeTicks frame_begin_time,
|
| const gfx::Rect& device_viewport_damage_rect,
|
| @@ -530,7 +559,7 @@ bool SingleThreadProxy::DoComposite(
|
| // CanDraw() as well.
|
| if (!ShouldComposite() || (for_readback && !can_do_readback)) {
|
| UpdateBackgroundAnimateTicking();
|
| - return false;
|
| + return DrawSwapReadbackResult::DRAW_ABORTED_CANT_DRAW;
|
| }
|
|
|
| layer_tree_host_impl_->Animate(
|
| @@ -556,14 +585,15 @@ bool SingleThreadProxy::DoComposite(
|
| layer_tree_host_impl_->offscreen_context_provider();
|
| if (offscreen_contexts)
|
| offscreen_contexts->VerifyContexts();
|
| - layer_tree_host_->DidLoseOutputSurface();
|
| - return false;
|
| + DidLoseOutputSurfaceOnImplThread();
|
| + if (for_readback)
|
| + return DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST;
|
| }
|
|
|
| - return true;
|
| + return DrawSwapReadbackResult::DRAW_SUCCESS;
|
| }
|
|
|
| -void SingleThreadProxy::DidSwapFrame() {
|
| +void SingleThreadProxy::DidCommitAndDrawFrame() {
|
| if (next_frame_is_newly_committed_frame_) {
|
| next_frame_is_newly_committed_frame_ = false;
|
| layer_tree_host_->DidCommitAndDrawFrame();
|
| @@ -572,4 +602,160 @@ void SingleThreadProxy::DidSwapFrame() {
|
|
|
| bool SingleThreadProxy::CommitPendingForTesting() { return false; }
|
|
|
| +scoped_ptr<base::Value> SingleThreadProxy::SchedulerStateAsValueForTesting() {
|
| + DebugScopedSetImplThread impl(this);
|
| + return scheduler_on_impl_thread_->StateAsValue().Pass();
|
| +}
|
| +
|
| +void SingleThreadProxy::SetNeedsBeginImplFrame(bool enable) {
|
| + if (OutputSurface* surface = layer_tree_host_impl_->output_surface())
|
| + surface->SetNeedsBeginImplFrame(enable);
|
| +}
|
| +
|
| +void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
|
| + if (defer_commits_) {
|
| + DCHECK(!finish_commit_deferred_);
|
| + finish_commit_deferred_ = true;
|
| + return;
|
| + }
|
| + timing_history_.DidBeginMainFrame();
|
| +
|
| + // This is poorly named, but tells the scheduler that we are ready to
|
| + // start the commit. In threaded mode, this is when the uploads are done.
|
| + // In single-threaded mode, it doesn't really matter. Doing no work here
|
| + // and all the work in commit prevents needless carrying of state (like
|
| + // the upload queue) from BeginMainFrame to commit.
|
| + scheduler_on_impl_thread_->FinishCommit();
|
| +}
|
| +
|
| +DrawSwapReadbackResult
|
| +SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
|
| + bool do_commit = false;
|
| + bool for_readback = false;
|
| + gfx::Rect device_viewport_damage_rect;
|
| + return CommitAndCompositeInternal(gfx::FrameTime::Now(),
|
| + device_viewport_damage_rect,
|
| + do_commit,
|
| + for_readback);
|
| +}
|
| +
|
| +DrawSwapReadbackResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
|
| + return ScheduledActionDrawAndSwapIfPossible();
|
| +}
|
| +
|
| +DrawSwapReadbackResult SingleThreadProxy::ScheduledActionDrawAndReadback() {
|
| + // The SingleThreadProxy never asks for a commit for readback,
|
| + // so this should never happen.
|
| + NOTREACHED();
|
| + DrawSwapReadbackResult result;
|
| + return result;
|
| +}
|
| +
|
| +DrawSwapReadbackResult SingleThreadProxy::CommitAndCompositeInternal(
|
| + base::TimeTicks frame_begin_time,
|
| + gfx::Rect device_viewport_damage_rect,
|
| + bool do_commit,
|
| + bool for_readback) {
|
| + DCHECK(Proxy::IsMainThread());
|
| + DrawSwapReadbackResult result;
|
| +
|
| + if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) {
|
| + result.draw_result = DrawSwapReadbackResult::DRAW_ABORTED_CONTEXT_LOST;
|
| + return result;
|
| + }
|
| +
|
| + if (do_commit)
|
| + DoCommit(frame_begin_time);
|
| +
|
| + scoped_refptr<ContextProvider> offscreen_context_provider =
|
| + OffscreenContextProvider();
|
| + LayerTreeHostImpl::FrameData frame;
|
| + timing_history_.DidStartDrawing();
|
| + result.draw_result = DoComposite(offscreen_context_provider,
|
| + frame_begin_time,
|
| + device_viewport_damage_rect,
|
| + for_readback,
|
| + &frame);
|
| + if (result.draw_result != DrawSwapReadbackResult::DRAW_SUCCESS)
|
| + return result;
|
| +
|
| + timing_history_.DidFinishDrawing();
|
| +
|
| + result.did_readback = for_readback;
|
| +
|
| + {
|
| + DebugScopedSetMainThreadBlocked main_thread_blocked(this);
|
| + DebugScopedSetImplThread impl(this);
|
| +
|
| + // This CapturePostTasks should be destroyed before
|
| + // DidCommitAndDrawFrame() is called since that goes out to the embedder,
|
| + // and we want the embedder to receive its callbacks before that.
|
| + // NOTE: This maintains consistent ordering with the ThreadProxy since
|
| + // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
|
| + // there as the main thread is not blocked, so any posted tasks inside
|
| + // the swap buffers will execute first.
|
| + BlockingTaskRunner::CapturePostTasks blocked;
|
| + result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
|
| + }
|
| +
|
| + DidCommitAndDrawFrame();
|
| +
|
| + return result;
|
| +}
|
| +
|
| +void SingleThreadProxy::ScheduledActionCommit() {
|
| + DebugScopedSetMainThread main(this);
|
| + DoCommit(gfx::FrameTime::Now());
|
| +}
|
| +
|
| +void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() {
|
| + // Impl-side painting only.
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void SingleThreadProxy::ScheduledActionActivatePendingTree() {
|
| + // Impl-side painting only.
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
|
| + DebugScopedSetMainThread main(this);
|
| + layer_tree_host_->InitializeOutputSurfaceIfNeeded();
|
| +}
|
| +
|
| +void SingleThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() {
|
| + scheduler_on_impl_thread_->SetMainThreadNeedsLayerTextures();
|
| +}
|
| +
|
| +void SingleThreadProxy::ScheduledActionManageTiles() {
|
| + // Impl-side painting only.
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {}
|
| +
|
| +base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
|
| + return timing_history_.DrawDurationEstimate();
|
| +}
|
| +
|
| +base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
|
| + return timing_history_.BeginMainFrameToCommitDurationEstimate();
|
| +}
|
| +
|
| +base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
|
| + return timing_history_.CommitToActivateDurationEstimate();
|
| +}
|
| +
|
| +void SingleThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure,
|
| + base::TimeTicks deadline) {
|
| + base::TimeDelta delta = deadline - gfx::FrameTime::Now();
|
| + if (delta <= base::TimeDelta())
|
| + delta = base::TimeDelta();
|
| + Proxy::MainThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
|
| +}
|
| +
|
| +void SingleThreadProxy::DidBeginImplFrameDeadline() {
|
| + layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame();
|
| +}
|
| +
|
| } // namespace cc
|
|
|