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 |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e2b2b82e011a9ad6c16a840908a270b1c6619403 |
| --- /dev/null |
| +++ b/content/browser/android/in_process/synchronous_compositor_impl.cc |
| @@ -0,0 +1,169 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/browser/android/in_process/synchronous_compositor_impl.h" |
| + |
| +#include "base/lazy_instance.h" |
| +#include "base/message_loop.h" |
| +#include "content/public/browser/android/synchronous_compositor_client.h" |
| +#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/renderer/android/synchronous_compositor_factory.h" |
| + |
| +namespace content { |
| + |
| +namespace { |
| + |
| +int GetInProcessRendererId() { |
| + content::RenderProcessHost::iterator it = |
| + content::RenderProcessHost::AllHostsIterator(); |
| + if (it.IsAtEnd()) { |
| + // There should always be one RPH in single process more. |
| + NOTREACHED(); |
| + return 0; |
| + } |
| + |
| + int id = it.GetCurrentValue()->GetID(); |
| + it.Advance(); |
| + DCHECK(it.IsAtEnd()); // Not multiprocess compatible. |
| + return id; |
| +} |
| + |
| +class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { |
| + public: |
| + // SynchronousCompositorFactory |
| + virtual scoped_refptr<base::MessageLoopProxy> |
| + GetCompositorMessageLoop() OVERRIDE { |
| + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
| + } |
| + |
| + virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface( |
| + int routing_id) OVERRIDE { |
| + scoped_ptr<SynchronousCompositorOutputSurface> output_surface( |
| + new SynchronousCompositorOutputSurface(routing_id)); |
| + return output_surface.PassAs<cc::OutputSurface>(); |
| + } |
| +}; |
| + |
| +base::LazyInstance<SynchronousCompositorFactoryImpl> g_factory = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| +} // namespace |
| + |
| +DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); |
| + |
| +void SynchronousCompositorImpl::InitFactory() { |
| + SynchronousCompositorFactory::SetInstance(g_factory.Pointer()); |
| +} |
| + |
| +// static |
| +SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID( |
| + int routing_id) { |
| + RenderViewHost* rvh = RenderViewHost::FromID(GetInProcessRendererId(), |
| + routing_id); |
| + if (!rvh) |
| + return NULL; |
| + WebContents* contents = WebContents::FromRenderViewHost(rvh); |
| + if (!contents) |
| + return NULL; |
| + return FromWebContents(contents); |
|
mkosiba (inactive)
2013/05/30 11:05:29
nit: it's a bit hard to figure out that this metho
|
| +} |
| + |
| +// static |
| +SynchronousCompositorImpl* SynchronousCompositorImpl::GetOrCreateForWebContents( |
| + WebContents* contents) { |
| + SynchronousCompositorImpl* instance = FromWebContents(contents); |
|
mkosiba (inactive)
2013/05/30 11:05:29
same here
|
| + if (instance) |
| + return instance; |
| + CreateForWebContents(contents); |
|
mkosiba (inactive)
2013/05/30 11:05:29
and here
|
| + return FromWebContents(contents); |
|
joth
2013/05/30 19:18:05
and here?
IKWYM about taking some effort to read
|
| +} |
| + |
| +SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents) |
| + : compositor_client_(NULL), |
| + output_surface_(NULL), |
| + contents_(contents) { |
| +} |
| + |
| +SynchronousCompositorImpl::~SynchronousCompositorImpl() { |
| + if (compositor_client_) |
| + compositor_client_->DidDestroyCompositor(this); |
| +} |
| + |
| +bool SynchronousCompositorImpl::IsHwReady() { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(output_surface_); |
| + |
| + return output_surface_->IsHwReady(); |
| +} |
| + |
| +void SynchronousCompositorImpl::SetClient( |
| + SynchronousCompositorClient* compositor_client) { |
| + DCHECK(CalledOnValidThread()); |
| + compositor_client_ = compositor_client; |
| +} |
| + |
| +bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(output_surface_); |
| + |
| + return output_surface_->DemandDrawSw(canvas); |
| +} |
| + |
| +bool SynchronousCompositorImpl::DemandDrawHw( |
| + gfx::Size view_size, |
| + const gfx::Transform& transform, |
| + gfx::Rect damage_area) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(output_surface_); |
| + |
| + return output_surface_->DemandDrawHw(view_size, transform, damage_area); |
| +} |
| + |
| +void SynchronousCompositorImpl::DidBindOutputSurface( |
| + SynchronousCompositorOutputSurface* output_surface) { |
| + DCHECK(CalledOnValidThread()); |
| + output_surface_ = output_surface; |
| + if (compositor_client_) |
| + compositor_client_->DidInitializeCompositor(this); |
| +} |
| + |
| +void SynchronousCompositorImpl::DidDestroySynchronousOutputSurface( |
| + 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_ = NULL; |
| + if (compositor_client_) |
| + compositor_client_->DidDestroyCompositor(this); |
| + compositor_client_ = NULL; |
| + } |
| +} |
| + |
| +void SynchronousCompositorImpl::SetContinuousInvalidate(bool enable) { |
| + DCHECK(CalledOnValidThread()); |
| + if (compositor_client_) |
| + compositor_client_->SetContinuousInvalidate(enable); |
| +} |
| + |
| +// Not using base::NonThreadSafe as we want to enforce a more exacting threading |
| +// requirement: SynchronousCompositorImpl() must only be used on the UI thread. |
| +bool SynchronousCompositorImpl::CalledOnValidThread() const { |
| + return BrowserThread::CurrentlyOn(BrowserThread::UI); |
| +} |
| + |
| +// static |
| +void SynchronousCompositor::Init() { |
| + SynchronousCompositorImpl::InitFactory(); |
| +} |
| + |
| +// static |
| +SynchronousCompositor* SynchronousCompositor::GetOrCreateForWebContents( |
| + WebContents* contents) { |
| + return SynchronousCompositorImpl::GetOrCreateForWebContents(contents); |
| +} |
| + |
| +} // namespace content |