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..ada9175e6ef9fd08c31a251fb32c742698eb5bba |
--- /dev/null |
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc |
@@ -0,0 +1,143 @@ |
+// 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 "cc/input/input_handler.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/public/renderer/android/synchronous_compositor_client.h" |
+#include "content/public/renderer/content_renderer_client.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_ptr<cc::OutputSurface> CreateOutputSurfaceForRenderView( |
+ int view_id) { |
+ scoped_ptr<SynchronousCompositorOutputSurface> output_surface( |
+ new SynchronousCompositorOutputSurface(view_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.GetPointer()); |
+} |
+ |
+// static |
+void SynchronousCompositorImpl::DidBindOutputSurface( |
+ int routing_id, |
+ SynchronousCompositorOutputSurface* output_surface) { |
+ RenderViewHost* rvh = RenderViewHost::FromID(GetInProcessRendererId(), |
+ routing_id); |
+ if (!rvh) |
+ return; |
+ WebContents* contents = WebContents::FromRenderViewHost(rvh); |
+ if (!contents) |
+ return; |
+ SynchronousCompositorImpl::FromContents(contents)-> |
+ DidBindOutputSurface(output_surface); |
+} |
+ |
+SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents) |
+ : compositor_client_(NULL), |
+ output_surface_(NULL), |
+ contents_(contents) { |
+} |
+ |
+SynchronousCompositorImpl::~SynchronousCompositorImpl() { |
+ if (output_surface_) |
+ output_surface_->SetDelegate(NULL); |
+} |
+ |
+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::SetContinuousInvalidate(bool enable) { |
+ DCHECK(CalledOnValidThread()); |
+ if (compositor_client_) |
+ compositor_client_->SetContinuousInvalidate(enable); |
+} |
+ |
+void SynchronousCompositorImpl::DidCreateSynchronousOutputSurface( |
+ SynchronousCompositorOutputSurface* output_surface); |
+ DCHECK(CalledOnValidThread()); |
+ output_surface_ = output_surface; |
+ output_surface->SetDelegate(this); |
+ // TODO(joth): Migrate this up-call off of the Renderer Client. |
+ GetContentClient()->renderer()->DidCreateSynchronousCompositor( |
+ contents_->GetRenderViewHost()->GetRoutingID(), this)l |
+} |
+ |
+void SynchronousCompositorImpl::DidDestroySynchronousOutputSurface() { |
+ DCHECK(CalledOnValidThread()); |
+ output_surface_ = NULL; |
+ if (compositor_client_) |
+ compositor_client_->DidDestroyCompositor(this); |
+} |
+ |
+// 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); |
+} |
+ |
+} // namespace content |