Chromium Code Reviews| Index: cc/trees/thread_proxy.cc |
| diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc |
| index 3ea5f8813507c674afcfefb7eed7f1254264fb39..90d00c6e91d924c43ec036e4bdae0f3d5ea6013c 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_(false), |
|
danakj
2013/07/17 20:53:24
true
enne (OOO)
2013/07/18 17:36:37
Done.
|
| 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,19 @@ 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() { |
| @@ -1067,6 +1108,7 @@ void ThreadProxy::AcquireLayerTextures() { |
| completion.Wait(); |
| textures_acquired_ = true; |
| + can_cancel_commit_ = false; |
| } |
| void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread( |