| 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
|
|
|