diff options
Diffstat (limited to 'cc/trees/thread_proxy.cc')
-rw-r--r-- | cc/trees/thread_proxy.cc | 100 |
1 files changed, 71 insertions, 29 deletions
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 2bf8247..775330e 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -90,6 +90,7 @@ ThreadProxy::ThreadProxy( using_synchronous_renderer_compositor_( layer_tree_host->settings().using_synchronous_renderer_compositor), inside_draw_(false), + can_cancel_commit_(true), defer_commits_(false), renew_tree_priority_on_impl_thread_pending_(false), draw_duration_history_(kDurationHistorySize), @@ -128,10 +129,15 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) { &begin_frame_sent_to_main_thread_completion)); begin_frame_sent_to_main_thread_completion.Wait(); } + in_composite_and_readback_ = true; BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>()); in_composite_and_readback_ = false; + // Composite and readback requires a second commit to undo any changes + // that it made. + can_cancel_commit_ = false; + // Perform a synchronous readback. ReadbackRequest request; request.rect = rect; @@ -301,6 +307,17 @@ void ThreadProxy::OnOutputSurfaceInitializeAttempted( } } +void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() { + DCHECK(IsMainThread()); + if (commit_request_sent_to_impl_thread_) + return; + commit_request_sent_to_impl_thread_ = true; + Proxy::ImplThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread, + impl_thread_weak_ptr_)); +} + const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const { DCHECK(IsMainThread()); DCHECK(!layer_tree_host_->output_surface_lost()); @@ -314,30 +331,26 @@ void ThreadProxy::SetNeedsAnimate() { TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate"); animate_requested_ = true; + can_cancel_commit_ = false; + SendCommitRequestToImplThreadIfNeeded(); +} - if (commit_request_sent_to_impl_thread_) - return; - commit_request_sent_to_impl_thread_ = true; - Proxy::ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread, - impl_thread_weak_ptr_)); +void ThreadProxy::SetNeedsUpdateLayers() { + DCHECK(IsMainThread()); + SendCommitRequestToImplThreadIfNeeded(); } void ThreadProxy::SetNeedsCommit() { DCHECK(IsMainThread()); + // Unconditionally set here to handle SetNeedsCommit calls during a commit. + can_cancel_commit_ = false; + if (commit_requested_) return; TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit"); commit_requested_ = true; - if (commit_request_sent_to_impl_thread_) - return; - commit_request_sent_to_impl_thread_ = true; - Proxy::ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread, - impl_thread_weak_ptr_)); + SendCommitRequestToImplThreadIfNeeded(); } void ThreadProxy::DidLoseOutputSurfaceOnImplThread() { @@ -680,21 +693,23 @@ void ThreadProxy::BeginFrameOnMainThread( // callbacks will trigger another frame. animate_requested_ = false; - if (begin_frame_state) - layer_tree_host_->ApplyScrollAndScale(*begin_frame_state->scroll_info); - if (!in_composite_and_readback_ && !layer_tree_host_->visible()) { commit_requested_ = false; commit_request_sent_to_impl_thread_ = false; TRACE_EVENT0("cc", "EarlyOut_NotVisible"); + bool did_handle = false; Proxy::ImplThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread, - impl_thread_weak_ptr_)); + impl_thread_weak_ptr_, + did_handle)); return; } + if (begin_frame_state) + layer_tree_host_->ApplyScrollAndScale(*begin_frame_state->scroll_info); + layer_tree_host_->WillBeginFrame(); if (begin_frame_state) { @@ -718,24 +733,44 @@ void ThreadProxy::BeginFrameOnMainThread( // UpdateLayers. commit_requested_ = false; commit_request_sent_to_impl_thread_ = false; + bool can_cancel_this_commit = + can_cancel_commit_ && !in_composite_and_readback_; + can_cancel_commit_ = true; scoped_ptr<ResourceUpdateQueue> queue = make_scoped_ptr(new ResourceUpdateQueue); - layer_tree_host_->UpdateLayers( + bool updated = layer_tree_host_->UpdateLayers( queue.get(), - begin_frame_state ? - begin_frame_state->memory_allocation_limit_bytes : 0u); + begin_frame_state ? begin_frame_state->memory_allocation_limit_bytes + : 0u); // Once single buffered layers are committed, they cannot be modified until // they are drawn by the impl thread. textures_acquired_ = false; layer_tree_host_->WillCommit(); - // Before applying scrolls and calling animate, we set animate_requested_ to - // false. If it is true now, it means SetNeedAnimate was called again, but - // during a state when commit_request_sent_to_impl_thread_ = true. We need to - // force that call to happen again now so that the commit request is sent to - // the impl thread. + + if (!updated && can_cancel_this_commit) { + TRACE_EVENT0("cc", "EarlyOut_NoUpdates"); + bool did_handle = true; + Proxy::ImplThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread, + impl_thread_weak_ptr_, + did_handle)); + + // Although the commit is internally aborted, this is because it has been + // detected to be a no-op. From the perspective of an embedder, this commit + // went through, and input should no longer be throttled, etc. + layer_tree_host_->CommitComplete(); + layer_tree_host_->DidBeginFrame(); + return; + } + + // Before calling animate, we set animate_requested_ to false. If it is true + // now, it means SetNeedAnimate was called again, but during a state when + // commit_request_sent_to_impl_thread_ = true. We need to force that call to + // happen again now so that the commit request is sent to the impl thread. if (animate_requested_) { // Forces SetNeedsAnimate to consider posting a commit task. animate_requested_ = false; @@ -831,13 +866,18 @@ void ThreadProxy::StartCommitOnImplThread( scheduler_on_impl_thread_->AnticipatedDrawTime()); } -void ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread() { +void ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread(bool did_handle) { TRACE_EVENT0("cc", "ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread"); DCHECK(IsImplThread()); DCHECK(scheduler_on_impl_thread_); DCHECK(scheduler_on_impl_thread_->CommitPending()); - scheduler_on_impl_thread_->BeginFrameAbortedByMainThread(); + // If the begin frame data was handled, then scroll and scale set was applied + // by the main thread, so the active tree needs to be updated as if these sent + // values were applied and committed. + if (did_handle) + layer_tree_host_impl_->active_tree()->ApplySentScrollAndScaleDeltas(); + scheduler_on_impl_thread_->BeginFrameAbortedByMainThread(did_handle); } void ThreadProxy::ScheduledActionCommit() { @@ -905,7 +945,8 @@ void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { ScheduledActionDrawAndSwapResult ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { - TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap"); + TRACE_EVENT1( + "cc", "ThreadProxy::ScheduledActionDrawAndSwap", "forced", forced_draw); ScheduledActionDrawAndSwapResult result; result.did_draw = false; @@ -1066,6 +1107,7 @@ void ThreadProxy::AcquireLayerTextures() { completion.Wait(); textures_acquired_ = true; + can_cancel_commit_ = false; } void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread( |