Chromium Code Reviews| Index: cc/trees/thread_proxy.cc |
| diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc |
| index dda25ecb79ad4b24337fa6a00cda38c3bbd4b5e6..288ec43f0be34298dcc6f4b9fcf75e5234158ea9 100644 |
| --- a/cc/trees/thread_proxy.cc |
| +++ b/cc/trees/thread_proxy.cc |
| @@ -126,19 +126,27 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) { |
| return false; |
| } |
| - // Perform a synchronous commit. |
| + // Perform a synchronous commit with an associated readback. |
| + ReadbackRequest request; |
| + request.rect = rect; |
| + request.pixels = pixels; |
| { |
| DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| CompletionEvent begin_frame_sent_to_main_thread_completion; |
| - Proxy::ImplThreadTaskRunner()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&ThreadProxy::ForceCommitOnImplThread, |
| - impl_thread_weak_ptr_, |
| - &begin_frame_sent_to_main_thread_completion)); |
| + Proxy::ImplThreadTaskRunner() |
| + ->PostTask(FROM_HERE, |
| + base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread, |
| + impl_thread_weak_ptr_, |
| + &begin_frame_sent_to_main_thread_completion, |
| + &request)); |
| begin_frame_sent_to_main_thread_completion.Wait(); |
| } |
| in_composite_and_readback_ = true; |
| + // This is the forced commit. |
| + // Note: The Impl thread also queues a separate BeginFrameOnMainThread on the |
| + // main thread, which will be called after this CompositeAndReadback |
| + // completes, to replace the forced commit. |
| BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>()); |
| in_composite_and_readback_ = false; |
| @@ -146,48 +154,35 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) { |
| // that it made. |
| can_cancel_commit_ = false; |
| - // Perform a synchronous readback. |
| - ReadbackRequest request; |
| - request.rect = rect; |
| - request.pixels = pixels; |
| - { |
| - DebugScopedSetMainThreadBlocked main_thread_blocked(this); |
| - Proxy::ImplThreadTaskRunner()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&ThreadProxy::RequestReadbackOnImplThread, |
| - impl_thread_weak_ptr_, |
| - &request)); |
| - request.completion.Wait(); |
| - } |
| + request.completion.Wait(); |
| return request.success; |
| } |
| -void ThreadProxy::ForceCommitOnImplThread(CompletionEvent* completion) { |
| - TRACE_EVENT0("cc", "ThreadProxy::ForceCommitOnImplThread"); |
| +void ThreadProxy::ForceCommitForReadbackOnImplThread( |
| + CompletionEvent* begin_frame_sent_completion, |
| + ReadbackRequest* request) { |
| + TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread"); |
| DCHECK(IsImplThread()); |
| DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_); |
| - |
| - scheduler_on_impl_thread_->SetNeedsForcedCommit(); |
| - if (scheduler_on_impl_thread_->CommitPending()) { |
| - completion->Signal(); |
| - return; |
| - } |
| - |
| - begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ = completion; |
| -} |
| - |
| -void ThreadProxy::RequestReadbackOnImplThread(ReadbackRequest* request) { |
| - DCHECK(Proxy::IsImplThread()); |
| DCHECK(!readback_request_on_impl_thread_); |
| + |
| if (!layer_tree_host_impl_) { |
| + begin_frame_sent_completion->Signal(); |
| request->success = false; |
| request->completion.Signal(); |
| return; |
| } |
| readback_request_on_impl_thread_ = request; |
| - scheduler_on_impl_thread_->SetNeedsRedraw(); |
| - scheduler_on_impl_thread_->SetNeedsForcedRedraw(); |
| + |
| + scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback(); |
| + if (scheduler_on_impl_thread_->CommitPending()) { |
| + begin_frame_sent_completion->Signal(); |
| + return; |
| + } |
| + |
| + begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ = |
| + begin_frame_sent_completion; |
| } |
| void ThreadProxy::FinishAllRendering() { |
| @@ -999,14 +994,14 @@ void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { |
| main_thread_weak_ptr_)); |
| } |
| -ScheduledActionDrawAndSwapResult |
| -ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { |
| - TRACE_EVENT1( |
| - "cc", "ThreadProxy::ScheduledActionDrawAndSwap", "forced", forced_draw); |
| - |
| - ScheduledActionDrawAndSwapResult result; |
| +DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal( |
| + bool forced_draw, |
| + bool swap_requested, |
| + bool readback_requested) { |
| + DrawSwapReadbackResult result; |
| result.did_draw = false; |
| result.did_swap = false; |
| + result.did_readback = false; |
| DCHECK(IsImplThread()); |
| DCHECK(layer_tree_host_impl_.get()); |
| if (!layer_tree_host_impl_) |
| @@ -1041,7 +1036,10 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { |
| // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on |
| // CanDraw() as well. |
| - bool drawing_for_readback = !!readback_request_on_impl_thread_; |
| + // readback_request_on_impl_thread_ may be for the pending tree, do |
| + // not perform the readback unless explicitly requested. |
| + bool drawing_for_readback = |
| + readback_requested && !!readback_request_on_impl_thread_; |
| bool can_do_readback = layer_tree_host_impl_->renderer()->CanReadPixels(); |
| LayerTreeHostImpl::FrameData frame; |
| @@ -1074,17 +1072,19 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) { |
| layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); |
| // Check for a pending CompositeAndReadback. |
| - if (readback_request_on_impl_thread_) { |
| - readback_request_on_impl_thread_->success = false; |
| - if (draw_frame) { |
| + if (drawing_for_readback) { |
| + DCHECK(!swap_requested); |
| + result.did_readback = false; |
| + if (draw_frame && !layer_tree_host_impl_->IsContextLost()) { |
|
brianderson
2013/09/06 22:04:29
It was easier to check for context lost here than
|
| layer_tree_host_impl_->Readback(readback_request_on_impl_thread_->pixels, |
| readback_request_on_impl_thread_->rect); |
| - readback_request_on_impl_thread_->success = |
| - !layer_tree_host_impl_->IsContextLost(); |
| + result.did_readback = true; |
| } |
| + readback_request_on_impl_thread_->success = result.did_readback; |
| readback_request_on_impl_thread_->completion.Signal(); |
| readback_request_on_impl_thread_ = NULL; |
| } else if (draw_frame) { |
| + DCHECK(swap_requested); |
| result.did_swap = layer_tree_host_impl_->SwapBuffers(frame); |
| if (frame.contains_incomplete_tile) |
| @@ -1177,14 +1177,31 @@ void ThreadProxy::ScheduledActionAcquireLayerTexturesForMainThread() { |
| texture_acquisition_completion_event_on_impl_thread_ = NULL; |
| } |
| -ScheduledActionDrawAndSwapResult |
| -ThreadProxy::ScheduledActionDrawAndSwapIfPossible() { |
| - return ScheduledActionDrawAndSwapInternal(false); |
| +DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() { |
| + TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap"); |
| + bool forced_draw = false; |
| + bool swap_requested = true; |
| + bool readback_requested = false; |
| + return DrawSwapReadbackInternal( |
| + forced_draw, swap_requested, readback_requested); |
| +} |
| + |
| +DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndSwapForced() { |
| + TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced"); |
| + bool forced_draw = true; |
| + bool swap_requested = true; |
| + bool readback_requested = false; |
| + return DrawSwapReadbackInternal( |
| + forced_draw, swap_requested, readback_requested); |
| } |
| -ScheduledActionDrawAndSwapResult |
| -ThreadProxy::ScheduledActionDrawAndSwapForced() { |
| - return ScheduledActionDrawAndSwapInternal(true); |
| +DrawSwapReadbackResult ThreadProxy::ScheduledActionDrawAndReadback() { |
| + TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndReadback"); |
| + bool forced_draw = true; |
| + bool swap_requested = false; |
| + bool readback_requested = true; |
| + return DrawSwapReadbackInternal( |
| + forced_draw, swap_requested, readback_requested); |
| } |
| void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { |
| @@ -1285,6 +1302,8 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { |
| scheduler_settings.impl_side_painting = settings.impl_side_painting; |
| scheduler_settings.timeout_and_draw_when_animation_checkerboards = |
| settings.timeout_and_draw_when_animation_checkerboards; |
| + scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = |
| + settings.maximum_number_of_failed_draws_before_draw_is_forced_; |
| scheduler_settings.using_synchronous_renderer_compositor = |
| settings.using_synchronous_renderer_compositor; |
| scheduler_settings.throttle_frame_production = |