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 215fdb1a116a2a7b50af1a7a036cde931b8a6b17..b278bee557b86a431f3af7c33f0838fdf0ec5fce 100644 |
| --- a/content/browser/android/in_process/synchronous_compositor_impl.cc |
| +++ b/content/browser/android/in_process/synchronous_compositor_impl.cc |
| @@ -8,6 +8,7 @@ |
| #include "base/bind.h" |
| #include "base/lazy_instance.h" |
| #include "base/message_loop/message_loop.h" |
| +#include "base/supports_user_data.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_compositor_registry.h" |
| @@ -20,6 +21,8 @@ |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "content/public/common/child_process_host.h" |
| #include "ui/gfx/geometry/scroll_offset.h" |
| #include "ui/gl/gl_surface.h" |
| @@ -27,20 +30,36 @@ namespace content { |
| namespace { |
| -int GetInProcessRendererId() { |
| - content::RenderProcessHost::iterator it = |
| - content::RenderProcessHost::AllHostsIterator(); |
| - if (it.IsAtEnd()) { |
| - // There should always be one RPH in single process mode. |
| - NOTREACHED(); |
| - return 0; |
| +const int kClientHolderLocatorKey = 0; |
| + |
| +class ClientHolder : public base::SupportsUserData::Data { |
|
no sievers
2015/10/07 19:13:38
That seems really complicated to store a pointer.
boliu
2015/10/08 03:14:44
Yeah can't be CVC because that could be created mu
|
| + public: |
| + static void CreateForWebContents(WebContents* contents, |
| + SynchronousCompositorClient* client) { |
| + DCHECK(contents); |
| + DCHECK(!FromWebContents(contents)); |
| + contents->SetUserData(&kClientHolderLocatorKey, new ClientHolder(client)); |
| } |
| - int id = it.GetCurrentValue()->GetID(); |
| - it.Advance(); |
| - DCHECK(it.IsAtEnd()); // Not multiprocess compatible. |
| - return id; |
| -} |
| + static ClientHolder* FromWebContents(WebContents* contents) { |
| + DCHECK(contents); |
| + return static_cast<ClientHolder*>( |
| + contents->GetUserData(&kClientHolderLocatorKey)); |
| + } |
| + |
| + SynchronousCompositorClient* client() const { return client_; } |
| + |
| + private: |
| + explicit ClientHolder(SynchronousCompositorClient* client) |
| + : client_(client) {} |
| + ~ClientHolder() override {} |
| + |
| + SynchronousCompositorClient* const client_; // Non-owning. |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ClientHolder); |
| +}; |
| + |
| +int g_process_id = ChildProcessHost::kInvalidUniqueID; |
| base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = |
| LAZY_INSTANCE_INITIALIZER; |
| @@ -52,73 +71,69 @@ base::Thread* CreateInProcessGpuThreadForSynchronousCompositor( |
| } // namespace |
| -DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); |
| - |
| -// static |
| -SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, |
| - int routing_id) { |
| +SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID( |
| + int routing_id) { |
| if (g_factory == nullptr) |
| return nullptr; |
| - RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id); |
| + if (g_process_id == ChildProcessHost::kInvalidUniqueID) |
| + return nullptr; |
| + RenderViewHost* rvh = RenderViewHost::FromID(g_process_id, routing_id); |
| if (!rvh) |
| return nullptr; |
| - WebContents* contents = WebContents::FromRenderViewHost(rvh); |
| - if (!contents) |
| + RenderWidgetHostViewAndroid* rwhva = |
| + static_cast<RenderWidgetHostViewAndroid*>(rvh->GetView()); |
| + if (!rwhva) |
| return nullptr; |
| - return FromWebContents(contents); |
| + return rwhva->GetSynchronousCompositorImpl(); |
| } |
| -SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID( |
| - int routing_id) { |
| - return FromID(GetInProcessRendererId(), routing_id); |
| +// static |
| +scoped_ptr<SynchronousCompositorImpl> SynchronousCompositorImpl::Create( |
| + RenderWidgetHostViewAndroid* rwhva, |
| + WebContents* web_contents) { |
| + DCHECK(web_contents); |
| + ClientHolder* holder = ClientHolder::FromWebContents(web_contents); |
| + if (!holder) |
| + return nullptr; |
| + DCHECK(holder->client()); |
| + return make_scoped_ptr( |
| + new SynchronousCompositorImpl(rwhva, holder->client())); |
| } |
| -SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents) |
| - : compositor_client_(nullptr), |
| +SynchronousCompositorImpl::SynchronousCompositorImpl( |
| + RenderWidgetHostViewAndroid* rwhva, |
| + SynchronousCompositorClient* client) |
| + : rwhva_(rwhva), |
| + routing_id_(rwhva_->GetRenderWidgetHost()->GetRoutingID()), |
| + compositor_client_(client), |
| output_surface_(nullptr), |
| begin_frame_source_(nullptr), |
| - contents_(contents), |
| - routing_id_(contents->GetRoutingID()), |
| synchronous_input_handler_proxy_(nullptr), |
| registered_with_client_(false), |
| is_active_(true), |
| renderer_needs_begin_frames_(false), |
| need_animate_input_(false), |
| weak_ptr_factory_(this) { |
| - DCHECK(contents); |
| DCHECK_NE(routing_id_, MSG_ROUTING_NONE); |
| -} |
| -SynchronousCompositorImpl::~SynchronousCompositorImpl() { |
| - DCHECK(!output_surface_); |
| - DCHECK(!begin_frame_source_); |
| - DCHECK(!synchronous_input_handler_proxy_); |
| -} |
| - |
| -void SynchronousCompositorImpl::SetClient( |
| - SynchronousCompositorClient* compositor_client) { |
| - DCHECK(CalledOnValidThread()); |
| - DCHECK_IMPLIES(compositor_client, !compositor_client_); |
| - DCHECK_IMPLIES(!compositor_client, compositor_client_); |
| - |
| - if (!compositor_client) { |
| - SynchronousCompositorRegistry::GetInstance()->UnregisterCompositor( |
| - routing_id_, this); |
| + int process_id = rwhva_->GetRenderWidgetHost()->GetProcess()->GetID(); |
| + if (g_process_id == ChildProcessHost::kInvalidUniqueID) { |
| + g_process_id = process_id; |
| + } else { |
| + DCHECK_EQ(g_process_id, process_id); // Not multiprocess compatible. |
| } |
| - compositor_client_ = compositor_client; |
| + SynchronousCompositorRegistry::GetInstance()->RegisterCompositor( |
| + routing_id_, this); |
| +} |
| - // SetClient is essentially the constructor and destructor of |
| - // SynchronousCompositorImpl. |
| - if (compositor_client_) { |
| - SynchronousCompositorRegistry::GetInstance()->RegisterCompositor( |
| - routing_id_, this); |
| - } |
| +SynchronousCompositorImpl::~SynchronousCompositorImpl() { |
| + SynchronousCompositorRegistry::GetInstance()->UnregisterCompositor( |
| + routing_id_, this); |
| } |
| void SynchronousCompositorImpl::RegisterWithClient() { |
| DCHECK(CalledOnValidThread()); |
| - DCHECK(compositor_client_); |
| DCHECK(output_surface_); |
| DCHECK(synchronous_input_handler_proxy_); |
| DCHECK(!registered_with_client_); |
| @@ -153,7 +168,6 @@ void SynchronousCompositorImpl::DidInitializeRendererObjects( |
| DCHECK(!begin_frame_source_); |
| DCHECK(output_surface); |
| DCHECK(begin_frame_source); |
| - DCHECK(compositor_client_); |
| DCHECK(synchronous_input_handler_proxy); |
| output_surface_ = output_surface; |
| @@ -167,7 +181,6 @@ void SynchronousCompositorImpl::DidInitializeRendererObjects( |
| void SynchronousCompositorImpl::DidDestroyRendererObjects() { |
| DCHECK(output_surface_); |
| DCHECK(begin_frame_source_); |
| - DCHECK(compositor_client_); |
| if (registered_with_client_) { |
| output_surface_->SetTreeActivationCallback(base::Closure()); |
| @@ -197,7 +210,6 @@ scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw( |
| const gfx::Transform& transform_for_tile_priority) { |
| DCHECK(CalledOnValidThread()); |
| DCHECK(output_surface_); |
| - DCHECK(compositor_client_); |
| DCHECK(begin_frame_source_); |
| scoped_ptr<cc::CompositorFrame> frame = |
| @@ -223,7 +235,6 @@ void SynchronousCompositorImpl::ReturnResources( |
| bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) { |
| DCHECK(CalledOnValidThread()); |
| DCHECK(output_surface_); |
| - DCHECK(compositor_client_); |
| DCHECK(begin_frame_source_); |
| scoped_ptr<cc::CompositorFrame> frame = |
| @@ -237,10 +248,7 @@ bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) { |
| void SynchronousCompositorImpl::UpdateFrameMetaData( |
| const cc::CompositorFrameMetadata& frame_metadata) { |
| - RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>( |
| - contents_->GetRenderWidgetHostView()); |
| - if (rwhv) |
| - rwhv->SynchronousFrameMetadata(frame_metadata); |
| + rwhva_->SynchronousFrameMetadata(frame_metadata); |
| DeliverMessages(); |
| } |
| @@ -260,7 +268,6 @@ void SynchronousCompositorImpl::SetMemoryPolicy(size_t bytes_limit) { |
| void SynchronousCompositorImpl::PostInvalidate() { |
| DCHECK(CalledOnValidThread()); |
| - DCHECK(compositor_client_); |
| if (registered_with_client_) |
| compositor_client_->PostInvalidate(); |
| } |
| @@ -307,15 +314,11 @@ void SynchronousCompositorImpl::BeginFrame(const cc::BeginFrameArgs& args) { |
| } |
| void SynchronousCompositorImpl::UpdateNeedsBeginFrames() { |
| - RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>( |
| - contents_->GetRenderWidgetHostView()); |
| - if (rwhv) |
| - rwhv->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_); |
| + rwhva_->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_); |
| } |
| void SynchronousCompositorImpl::DidOverscroll( |
| const DidOverscrollParams& params) { |
| - DCHECK(compositor_client_); |
| if (registered_with_client_) { |
| compositor_client_->DidOverscroll(params.accumulated_overscroll, |
| params.latest_overscroll_delta, |
| @@ -327,7 +330,7 @@ void SynchronousCompositorImpl::DidStopFlinging() { |
| // It's important that the fling-end notification follow the same path as it |
| // takes on other platforms (using an IPC). This ensures consistent |
| // bookkeeping at all stages of the input pipeline. |
| - contents_->GetRenderProcessHost()->OnMessageReceived( |
| + rwhva_->GetRenderWidgetHost()->GetProcess()->OnMessageReceived( |
| InputHostMsg_DidStopFlinging(routing_id_)); |
| } |
| @@ -335,13 +338,13 @@ InputEventAckState SynchronousCompositorImpl::HandleInputEvent( |
| const blink::WebInputEvent& input_event) { |
| DCHECK(CalledOnValidThread()); |
| return g_factory.Get().synchronous_input_event_filter()->HandleInputEvent( |
| - contents_->GetRoutingID(), input_event); |
| + routing_id_, input_event); |
| } |
| void SynchronousCompositorImpl::DeliverMessages() { |
| ScopedVector<IPC::Message> messages; |
| output_surface_->GetMessagesToDeliver(&messages); |
| - RenderProcessHost* rph = contents_->GetRenderProcessHost(); |
| + RenderProcessHost* rph = rwhva_->GetRenderWidgetHost()->GetProcess(); |
| for (ScopedVector<IPC::Message>::const_iterator i = messages.begin(); |
| i != messages.end(); |
| ++i) { |
| @@ -350,7 +353,6 @@ void SynchronousCompositorImpl::DeliverMessages() { |
| } |
| void SynchronousCompositorImpl::DidActivatePendingTree() { |
| - DCHECK(compositor_client_); |
| if (registered_with_client_) |
| compositor_client_->DidUpdateContent(); |
| DeliverMessages(); |
| @@ -358,7 +360,6 @@ void SynchronousCompositorImpl::DidActivatePendingTree() { |
| void SynchronousCompositorImpl::SetNeedsSynchronousAnimateInput() { |
| DCHECK(CalledOnValidThread()); |
| - DCHECK(compositor_client_); |
| if (!registered_with_client_) |
| return; |
| need_animate_input_ = true; |
| @@ -373,7 +374,6 @@ void SynchronousCompositorImpl::UpdateRootLayerState( |
| float min_page_scale_factor, |
| float max_page_scale_factor) { |
| DCHECK(CalledOnValidThread()); |
| - DCHECK(compositor_client_); |
| if (registered_with_client_) { |
| // TODO(miletus): Pass in ScrollOffset. crbug.com/414283. |
| @@ -398,14 +398,10 @@ void SynchronousCompositor::SetClientForWebContents( |
| WebContents* contents, |
| SynchronousCompositorClient* client) { |
| DCHECK(contents); |
| - if (client) { |
| - g_factory.Get(); // Ensure it's initialized. |
| - SynchronousCompositorImpl::CreateForWebContents(contents); |
| - } |
| - SynchronousCompositorImpl* instance = |
| - SynchronousCompositorImpl::FromWebContents(contents); |
| - DCHECK(instance); |
| - instance->SetClient(client); |
| + DCHECK(client); |
| + g_factory.Get(); // Ensure it's initialized. |
| + DCHECK(!ClientHolder::FromWebContents(contents)); |
| + ClientHolder::CreateForWebContents(contents, client); |
| } |
| } // namespace content |