Chromium Code Reviews| Index: content/browser/android/in_process/synchronous_compositor_impl.cc |
| diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc |
| index 06be5be5696b865d8f0a91047519bdeccc416dfe..7e05800b4cbedce0488f5a5e1e367066264c31bb 100644 |
| --- a/content/browser/android/in_process/synchronous_compositor_impl.cc |
| +++ b/content/browser/android/in_process/synchronous_compositor_impl.cc |
| @@ -4,9 +4,11 @@ |
| #include "content/browser/android/in_process/synchronous_compositor_impl.h" |
| +#include "base/auto_reset.h" |
| #include "base/lazy_instance.h" |
| #include "base/message_loop/message_loop.h" |
| #include "cc/input/input_handler.h" |
| +#include "content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h" |
| #include "content/browser/android/in_process/synchronous_compositor_factory_impl.h" |
| #include "content/browser/android/in_process/synchronous_input_event_filter.h" |
| #include "content/browser/renderer_host/render_widget_host_view_android.h" |
| @@ -65,15 +67,18 @@ SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID( |
| SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents) |
| : compositor_client_(NULL), |
| output_surface_(NULL), |
| + begin_frame_source_(nullptr), |
| contents_(contents), |
| input_handler_(NULL), |
| + invoking_composite_(false), |
| weak_ptr_factory_(this) { |
| DCHECK(contents); |
| } |
| SynchronousCompositorImpl::~SynchronousCompositorImpl() { |
| - if (compositor_client_) |
| - compositor_client_->DidDestroyCompositor(this); |
| + NotifyDidDestroyCompositorToClient(); |
| + if (begin_frame_source_) |
| + begin_frame_source_->SetCompositor(nullptr); |
| SetInputHandler(NULL); |
| } |
| @@ -94,6 +99,34 @@ void SynchronousCompositor::SetRecordFullDocument(bool record_full_document) { |
| g_factory.Get().SetRecordFullDocument(record_full_document); |
| } |
| +void SynchronousCompositorImpl::DidInitializeExternalBeginFrameSource( |
| + SynchronousCompositorExternalBeginFrameSource* begin_frame_source) { |
| + DCHECK(!begin_frame_source_); |
| + DCHECK(!output_surface_); |
| + DCHECK(begin_frame_source); |
| + begin_frame_source_ = begin_frame_source; |
| + begin_frame_source_->SetCompositor(this); |
| +} |
| + |
| +void SynchronousCompositorImpl::DidDestroyExternalBeginFrameSource( |
| + SynchronousCompositorExternalBeginFrameSource* begin_frame_source) { |
| + DCHECK(begin_frame_source_); |
| + DCHECK_EQ(begin_frame_source_, begin_frame_source); |
| + begin_frame_source_->SetCompositor(this); |
|
boliu
2014/11/03 19:17:45
SetCompositor(nullptr);
simonhong
2014/11/03 21:26:24
Done.
|
| + begin_frame_source_ = nullptr; |
| + |
| + if (output_surface_) |
| + output_surface_->SetExternalBeginFrameSource(nullptr); |
| + |
| + NotifyDidDestroyCompositorToClient(); |
| +} |
| + |
| +void SynchronousCompositorImpl::NotifyDidDestroyCompositorToClient() { |
| + if (compositor_client_) |
| + compositor_client_->DidDestroyCompositor(this); |
| + compositor_client_ = nullptr; |
| +} |
| + |
| bool SynchronousCompositorImpl::InitializeHwDraw() { |
| DCHECK(CalledOnValidThread()); |
| DCHECK(output_surface_); |
| @@ -124,7 +157,12 @@ scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw( |
| const gfx::Transform& transform_for_tile_priority) { |
| DCHECK(CalledOnValidThread()); |
| DCHECK(output_surface_); |
| + DCHECK(!invoking_composite_); |
| + DCHECK(compositor_client_); |
| + DCHECK(begin_frame_source_); |
| + base::AutoReset<bool> invoking_composite_resetter(&invoking_composite_, |
| + true); |
| scoped_ptr<cc::CompositorFrame> frame = |
| output_surface_->DemandDrawHw(surface_size, |
| transform, |
| @@ -135,6 +173,9 @@ scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw( |
| if (frame.get()) |
| UpdateFrameMetaData(frame->metadata); |
| + compositor_client_->SetContinuousInvalidate( |
| + begin_frame_source_->NeedsBeginFrames()); |
| + |
| return frame.Pass(); |
| } |
| @@ -147,10 +188,20 @@ void SynchronousCompositorImpl::ReturnResources( |
| bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) { |
| DCHECK(CalledOnValidThread()); |
| DCHECK(output_surface_); |
| + DCHECK(!invoking_composite_); |
| + DCHECK(compositor_client_); |
| + DCHECK(begin_frame_source_); |
| - scoped_ptr<cc::CompositorFrame> frame = output_surface_->DemandDrawSw(canvas); |
| + base::AutoReset<bool> invoking_composite_resetter(&invoking_composite_, |
| + true); |
| + scoped_ptr<cc::CompositorFrame> frame = |
| + output_surface_->DemandDrawSw(canvas); |
| if (frame.get()) |
| UpdateFrameMetaData(frame->metadata); |
| + |
| + compositor_client_->SetContinuousInvalidate( |
| + begin_frame_source_->NeedsBeginFrames()); |
| + |
| return !!frame.get(); |
| } |
| @@ -176,24 +227,27 @@ void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset() { |
| } |
| void SynchronousCompositorImpl::DidBindOutputSurface( |
| - SynchronousCompositorOutputSurface* output_surface) { |
| + SynchronousCompositorOutputSurface* output_surface) { |
| DCHECK(CalledOnValidThread()); |
| + DCHECK(begin_frame_source_); |
| + DCHECK(output_surface); |
| output_surface_ = output_surface; |
| if (compositor_client_) |
| compositor_client_->DidInitializeCompositor(this); |
| + |
| + output_surface_->SetExternalBeginFrameSource(begin_frame_source_); |
| } |
| void SynchronousCompositorImpl::DidDestroySynchronousOutputSurface( |
| - SynchronousCompositorOutputSurface* output_surface) { |
| + SynchronousCompositorOutputSurface* output_surface) { |
| DCHECK(CalledOnValidThread()); |
| // Allow for transient hand-over when two output surfaces may refer to |
| // a single delegate. |
| if (output_surface_ == output_surface) { |
| + output_surface_->SetExternalBeginFrameSource(nullptr); |
| output_surface_ = NULL; |
| - if (compositor_client_) |
| - compositor_client_->DidDestroyCompositor(this); |
| - compositor_client_ = NULL; |
| + NotifyDidDestroyCompositorToClient(); |
| } |
| } |
| @@ -226,10 +280,16 @@ void SynchronousCompositorImpl::DidStopFlinging() { |
| rwhv->DidStopFlinging(); |
| } |
| -void SynchronousCompositorImpl::SetContinuousInvalidate(bool enable) { |
| +void SynchronousCompositorImpl::NeedsBeginFramesChanged() const { |
| DCHECK(CalledOnValidThread()); |
| - if (compositor_client_) |
| - compositor_client_->SetContinuousInvalidate(enable); |
| + DCHECK(begin_frame_source_); |
| + if (invoking_composite_) |
| + return; |
| + |
| + if (compositor_client_) { |
| + compositor_client_->SetContinuousInvalidate( |
| + begin_frame_source_->NeedsBeginFrames()); |
| + } |
| } |
| InputEventAckState SynchronousCompositorImpl::HandleInputEvent( |