| 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 98466724ed1cdd690fcb7f4672bf3f30fed87e30..da4b3bf2d23161035990d3a561abdacdf8e216ed 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 {
|
| + 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);
|
| -}
|
| -
|
| -SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents)
|
| - : compositor_client_(nullptr),
|
| +// static
|
| +scoped_ptr<SynchronousCompositorImpl> SynchronousCompositorImpl::Create(
|
| + RenderWidgetHostViewAndroid* rwhva,
|
| + WebContents* web_contents) {
|
| + DCHECK(web_contents);
|
| + ClientHolder* holder = ClientHolder::FromWebContents(web_contents);
|
| + if (!holder)
|
| + return nullptr; // Temporary until multiprocess is implemented.
|
| + DCHECK(holder->client());
|
| + return make_scoped_ptr(
|
| + new SynchronousCompositorImpl(rwhva, holder->client()));
|
| +}
|
| +
|
| +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_);
|
| @@ -158,7 +173,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;
|
| @@ -172,7 +186,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());
|
| @@ -202,7 +215,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 =
|
| @@ -228,7 +240,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 =
|
| @@ -242,10 +253,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();
|
| }
|
|
|
| @@ -265,7 +273,6 @@ void SynchronousCompositorImpl::SetMemoryPolicy(size_t bytes_limit) {
|
|
|
| void SynchronousCompositorImpl::PostInvalidate() {
|
| DCHECK(CalledOnValidThread());
|
| - DCHECK(compositor_client_);
|
| if (registered_with_client_)
|
| compositor_client_->PostInvalidate();
|
| }
|
| @@ -312,15 +319,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,
|
| @@ -332,7 +335,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_));
|
| }
|
|
|
| @@ -340,13 +343,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) {
|
| @@ -355,7 +358,6 @@ void SynchronousCompositorImpl::DeliverMessages() {
|
| }
|
|
|
| void SynchronousCompositorImpl::DidActivatePendingTree() {
|
| - DCHECK(compositor_client_);
|
| if (registered_with_client_)
|
| compositor_client_->DidUpdateContent();
|
| DeliverMessages();
|
| @@ -363,7 +365,6 @@ void SynchronousCompositorImpl::DidActivatePendingTree() {
|
|
|
| void SynchronousCompositorImpl::SetNeedsSynchronousAnimateInput() {
|
| DCHECK(CalledOnValidThread());
|
| - DCHECK(compositor_client_);
|
| if (!registered_with_client_)
|
| return;
|
| need_animate_input_ = true;
|
| @@ -378,7 +379,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.
|
| @@ -403,14 +403,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
|
|
|