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 |