Index: cc/trees/thread_proxy.cc |
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc |
index 2bf824711d0592ce946327514bba8d995533b276..3d73b2168f8dc150f08c67d27f2c8a4c86199637 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,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()); |
+ DCHECK(!layer_tree_host_impl_->pending_tree()); |
- 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 +946,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 +1108,7 @@ void ThreadProxy::AcquireLayerTextures() { |
completion.Wait(); |
textures_acquired_ = true; |
+ can_cancel_commit_ = false; |
} |
void ThreadProxy::AcquireLayerTexturesForMainThreadOnImplThread( |