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..7fcc1a5a75121d667c2799d7c73a626c551cbd34 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(nullptr); |
+ begin_frame_source_ = nullptr; |
+ |
+ if (output_surface_) |
+ output_surface_->set_external_begin_frame_source(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_->set_external_begin_frame_source(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_->set_external_begin_frame_source(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( |