summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-01 18:18:21 +0000
committerjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-01 18:18:21 +0000
commit86f557dfc7f23c5044cdf9dca214836562be8a27 (patch)
tree1f889037b2133857d2dd60275f60c000a3678ea4 /content
parent3184f90bff4653bfb7a90ec4a1398559c4668247 (diff)
downloadchromium_src-86f557dfc7f23c5044cdf9dca214836562be8a27.zip
chromium_src-86f557dfc7f23c5044cdf9dca214836562be8a27.tar.gz
chromium_src-86f557dfc7f23c5044cdf9dca214836562be8a27.tar.bz2
Introduce SynchronousCompositor + Client
Makes a direct API from aw/browser into the content/renderer compositor (for use in single process only). Plumb through the webview SW draw path as first step to removing the synchronous IPC path. BUG=230226 NOTRY=true Review URL: https://chromiumcodereview.appspot.com/14445008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197660 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/content_common.gypi2
-rw-r--r--content/content_renderer.gypi2
-rw-r--r--content/public/common/content_switches.cc5
-rw-r--r--content/public/common/content_switches.h1
-rw-r--r--content/public/renderer/android/OWNERS6
-rw-r--r--content/public/renderer/android/synchronous_compositor.h35
-rw-r--r--content/public/renderer/android/synchronous_compositor_client.h28
-rw-r--r--content/public/renderer/content_renderer_client.h9
-rw-r--r--content/renderer/android/synchronous_compositor_output_surface.cc69
-rw-r--r--content/renderer/android/synchronous_compositor_output_surface.h56
-rw-r--r--content/renderer/render_widget.cc14
11 files changed, 227 insertions, 0 deletions
diff --git a/content/content_common.gypi b/content/content_common.gypi
index e0558e9..57b47ba 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -22,6 +22,8 @@
'../base/base.gyp:base',
],
'sources': [
+ 'public/common/android/synchronous_compositor_client.h',
+ 'public/common/android/synchronous_compositor.h',
'public/common/bindings_policy.h',
'public/common/child_process_host.h',
'public/common/child_process_host_delegate.cc',
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index ec70560..20acfb7 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -66,6 +66,8 @@
'renderer/android/email_detector.h',
'renderer/android/phone_number_detector.cc',
'renderer/android/phone_number_detector.h',
+ 'renderer/android/synchronous_compositor_output_surface.cc',
+ 'renderer/android/synchronous_compositor_output_surface.h',
'renderer/device_orientation_dispatcher.cc',
'renderer/device_orientation_dispatcher.h',
'renderer/devtools/devtools_agent.cc',
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 8929515..208e4e1 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -437,6 +437,11 @@ const char kForceCompositingMode[] = "force-compositing-mode";
// via field trials.
const char kDisableForceCompositingMode[] = "disable-force-compositing-mode";
+// Enable the synchronous renderer compositor API. See
+// ContentRendererClient::DidCreateSynchronousCompositor()
+const char kEnableSynchronousRendererCompositor[] =
+ "enable-synchronous-renderer-compositor";
+
// Some field trials may be randomized in the browser, and the randomly selected
// outcome needs to be propagated to the renderer. For instance, this is used
// to modify histograms recorded in the renderer, or to get the renderer to
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 4692f9e..fd750b7 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -130,6 +130,7 @@ CONTENT_EXPORT extern const char kEnableSoftwareCompositingGLAdapter[];
CONTENT_EXPORT extern const char kEnableSmoothScrolling[];
CONTENT_EXPORT extern const char kEnableStatsTable[];
extern const char kEnableStrictSiteIsolation[];
+extern const char kEnableSynchronousRendererCompositor[];
CONTENT_EXPORT extern const char kEnableThreadedCompositing[];
CONTENT_EXPORT extern const char kDisableThreadedCompositing[];
extern const char kEnableVirtualGLContexts[];
diff --git a/content/public/renderer/android/OWNERS b/content/public/renderer/android/OWNERS
new file mode 100644
index 0000000..cff1ac9
--- /dev/null
+++ b/content/public/renderer/android/OWNERS
@@ -0,0 +1,6 @@
+# While the SynchronousCompositor API is in active development include
+# all the following owners in any changes under this path.
+
+jamesr@chromium.org
+joth@chromium.org
+mkosiba@chromium.org
diff --git a/content/public/renderer/android/synchronous_compositor.h b/content/public/renderer/android/synchronous_compositor.h
new file mode 100644
index 0000000..f0c380d
--- /dev/null
+++ b/content/public/renderer/android/synchronous_compositor.h
@@ -0,0 +1,35 @@
+// Copyright (c) 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.
+
+#ifndef CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSTIOR_
+#define CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_
+
+class SkCanvas;
+
+namespace content {
+
+class SynchronousCompositorClient;
+
+// Interface for embedders that which to direct compositing operations
+// synchronously under their own control. Only meaningful when the
+// kEnableSyncrhonousRendererCompositor flag is specified.
+class SynchronousCompositor {
+ public:
+ // Allows changing or resetting the client to NULL (this must be used if
+ // the client is being deleted prior to the DidDestroyCompositor() call
+ // being received by the client). Ownership of |client| remains with
+ // the caller.
+ virtual void SetClient(SynchronousCompositorClient* client) = 0;
+
+ // "On demand" SW draw, into the supplied canvas (observing the transform
+ // and clip set there-in).
+ virtual bool DemandDrawSw(SkCanvas* canvas) = 0;
+
+ protected:
+ virtual ~SynchronousCompositor() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSTIOR_
diff --git a/content/public/renderer/android/synchronous_compositor_client.h b/content/public/renderer/android/synchronous_compositor_client.h
new file mode 100644
index 0000000..dcbe09a
--- /dev/null
+++ b/content/public/renderer/android/synchronous_compositor_client.h
@@ -0,0 +1,28 @@
+// Copyright (c) 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.
+
+#ifndef CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSTIOR_CLIENT_H_
+#define CONTENT_PUBLIC_RENDERER_ANDROID_SYNCRHONOUS_COMPOSITOR_CLIENT_H_
+
+namespace content {
+
+class SynchronousCompositor;
+
+class SynchronousCompositorClient {
+ public:
+ // Indication to the client that |compositor| is going out of scope, and
+ // must not be accessed within or after this call.
+ // NOTE if the client goes away before the compositor it must call
+ // SynchronousCompositor::SetClient(NULL) to release the back pointer.
+ virtual void DidDestroyCompositor(SynchronousCompositor* compositor) = 0;
+
+ // TODO(joth): Add scroll getters and setters, and invalidations.
+
+ protected:
+ virtual ~SynchronousCompositorClient() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_RENDERER_ANDROID_SYNCHRONOUS_COMPOSTIOR_CLIENT_H_
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index 653d38c..84b6d58 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -59,6 +59,7 @@ class WebMediaPlayerParams;
namespace content {
class RenderView;
+class SynchronousCompositor;
// Embedder API for participating in renderer logic.
class CONTENT_EXPORT ContentRendererClient {
@@ -234,6 +235,14 @@ class CONTENT_EXPORT ContentRendererClient {
// RenderThreadImpl. If NULL, then a new thread will be created.
virtual base::MessageLoop* OverrideCompositorMessageLoop() const;
+ // Called when a render view's compositor instance is created, when the
+ // kEnableSynchronousRendererCompositor flag is used.
+ // NOTE this is called on the Compositor thread: the embedder must
+ // implement OverrideCompositorMessageLoop() when using this interface.
+ virtual void DidCreateSynchronousCompositor(
+ int render_view_id,
+ SynchronousCompositor* compositor) {}
+
// Allow the embedder to disable input event filtering by the compositor.
virtual bool ShouldCreateCompositorInputHandler() const;
};
diff --git a/content/renderer/android/synchronous_compositor_output_surface.cc b/content/renderer/android/synchronous_compositor_output_surface.cc
new file mode 100644
index 0000000..87792ea
--- /dev/null
+++ b/content/renderer/android/synchronous_compositor_output_surface.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 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/renderer/android/synchronous_compositor_output_surface.h"
+
+#include "base/logging.h"
+#include "cc/output/output_surface_client.h"
+#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/public/renderer/android/synchronous_compositor_client.h"
+#include "content/public/renderer/content_renderer_client.h"
+#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkPicture.h"
+
+namespace content {
+
+SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
+ int32 routing_id,
+ WebGraphicsContext3DCommandBufferImpl* context)
+ : cc::OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>(context)),
+ compositor_client_(NULL),
+ routing_id_(routing_id) {
+ // WARNING: may be called on any thread.
+}
+
+SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() {
+ DCHECK(CalledOnValidThread());
+ if (compositor_client_)
+ compositor_client_->DidDestroyCompositor(this);
+}
+
+bool SynchronousCompositorOutputSurface::BindToClient(
+ cc::OutputSurfaceClient* surface_client) {
+ DCHECK(CalledOnValidThread());
+ if (!cc::OutputSurface::BindToClient(surface_client))
+ return false;
+ GetContentClient()->renderer()->DidCreateSynchronousCompositor(routing_id_,
+ this);
+ return true;
+}
+
+void SynchronousCompositorOutputSurface::SendFrameToParentCompositor(
+ cc::CompositorFrame* frame) {
+ // Intentional no-op: see http://crbug.com/237006
+}
+
+void SynchronousCompositorOutputSurface::SetClient(
+ SynchronousCompositorClient* compositor_client) {
+ DCHECK(CalledOnValidThread());
+ compositor_client_ = compositor_client;
+}
+
+bool SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
+ DCHECK(CalledOnValidThread());
+ NOTIMPLEMENTED(); // TODO(joth): call through to OutputSurfaceClient
+ return false;
+}
+
+// Not using base::NonThreadSafe as we want to enforce a more exacting threading
+// requirement: SynchronousCompositorOutputSurface() must only be used by
+// embedders that supply their own compositor loop via
+// OverrideCompositorMessageLoop().
+bool SynchronousCompositorOutputSurface::CalledOnValidThread() const {
+ return base::MessageLoop::current() && (base::MessageLoop::current() ==
+ GetContentClient()->renderer()->OverrideCompositorMessageLoop());
+}
+
+} // namespace content
diff --git a/content/renderer/android/synchronous_compositor_output_surface.h b/content/renderer/android/synchronous_compositor_output_surface.h
new file mode 100644
index 0000000..04af44f
--- /dev/null
+++ b/content/renderer/android/synchronous_compositor_output_surface.h
@@ -0,0 +1,56 @@
+// Copyright (c) 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.
+
+#ifndef CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
+#define CONTENT_RENDERER_ANDOIRD_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/output/output_surface.h"
+#include "content/public/renderer/android/synchronous_compositor.h"
+
+namespace content {
+
+class SynchronousCompositorClient;
+class WebGraphicsContext3DCommandBufferImpl;
+
+// Specialization of the output surface that adapts it to implement the
+// content::SynchronousCompositor public API. This class effects an "inversion
+// of control" - enabling drawing to be orchestrated by the embedding
+// layer, instead of driven by the compositor internals - hence it holds two
+// 'client' pointers (including |client_| in the OutputSurface baseclass) which
+// represent the consumers of the two roles in plays.
+// This class can be created only on the main thread, but then becomes pinned
+// to a fixed thread when BindToClient is called.
+class SynchronousCompositorOutputSurface
+ : NON_EXPORTED_BASE(public cc::OutputSurface),
+ NON_EXPORTED_BASE(public SynchronousCompositor) {
+ public:
+ SynchronousCompositorOutputSurface(
+ int32 routing_id,
+ WebGraphicsContext3DCommandBufferImpl* context);
+ virtual ~SynchronousCompositorOutputSurface();
+
+ // OutputSurface.
+ virtual bool BindToClient(cc::OutputSurfaceClient* surface_client) OVERRIDE;
+ virtual void SendFrameToParentCompositor(cc::CompositorFrame* frame) OVERRIDE;
+
+ // SynchronousCompositor.
+ virtual void SetClient(SynchronousCompositorClient* compositor_client)
+ OVERRIDE;
+ virtual bool DemandDrawSw(SkCanvas* canvas) OVERRIDE;
+
+ private:
+ bool CalledOnValidThread() const;
+
+ SynchronousCompositorClient* compositor_client_;
+ int routing_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorOutputSurface);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_OUTPUT_SURFACE_H_
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index f8d3137..b681e5d 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -58,6 +58,10 @@
#include "webkit/plugins/npapi/webplugin.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+#if defined(OS_ANDROID)
+#include "content/renderer/android/synchronous_compositor_output_surface.h"
+#endif
+
#if defined(OS_POSIX)
#include "ipc/ipc_channel_posix.h"
#include "third_party/skia/include/core/SkMallocPixelRef.h"
@@ -581,6 +585,16 @@ scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface() {
if (!context)
return scoped_ptr<cc::OutputSurface>();
+#if defined(OS_ANDROID)
+ if (command_line.HasSwitch(switches::kEnableSynchronousRendererCompositor)) {
+ // TODO(joth): Move above the |context| creation step above when the
+ // SynchronousCompositor no longer depends on externally created context.
+ return scoped_ptr<cc::OutputSurface>(
+ new SynchronousCompositorOutputSurface(routing_id(),
+ context));
+ }
+#endif
+
bool composite_to_mailbox =
command_line.HasSwitch(cc::switches::kCompositeToMailbox);
DCHECK(!composite_to_mailbox || command_line.HasSwitch(