summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorkbr@google.com <kbr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-04 17:46:23 +0000
committerkbr@google.com <kbr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-04 17:46:23 +0000
commit77e74dbed3b57987515c260b651b72cec15825dc (patch)
tree66685b53d127093075f720f99fbb0869ab74c01d /chrome/renderer
parent1ad13a2d0dd8d03b50e6fbadd6a26ea72712d2d9 (diff)
downloadchromium_src-77e74dbed3b57987515c260b651b72cec15825dc.zip
chromium_src-77e74dbed3b57987515c260b651b72cec15825dc.tar.gz
chromium_src-77e74dbed3b57987515c260b651b72cec15825dc.tar.bz2
Initial port of accelerated compositor to Mac OS X 10.6. Reused
infrastructure added for Pepper 3D and Core Animation plugins to render the compositor's output. The implementation allocates a fake "plugin window handle" on the browser side which is the "root" handle, containing the compositor's output, and which, if present, is drawn before any other accelerated plugin instances. Added messages from GPU process to browser process for handling window resizing and presentation of output. Added support to GGL for "view" contexts on Mac OS X, used only for the accelerated compositor, and requiring explicit resize notifications. The remainder of this port will go into the WebKit repository under https://bugs.webkit.org/show_bug.cgi?id=43398 after this for dependency reasons. Tested manually with CSS 3D and WebGL demos. Several stability and correctness issues remain and will be addressed in following CLs; however, the current code works for the majority of basic use cases including switching between accelerated compositing on and off, and scrolling of content. BUG=38969 TEST=none Review URL: http://codereview.chromium.org/3067026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54923 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/ggl/ggl.cc39
-rw-r--r--chrome/renderer/ggl/ggl.h24
-rw-r--r--chrome/renderer/gpu_channel_host.cc6
-rw-r--r--chrome/renderer/gpu_channel_host.h3
-rw-r--r--chrome/renderer/render_view.cc4
-rw-r--r--chrome/renderer/render_view.h3
-rw-r--r--chrome/renderer/webgles2context_impl.cc18
-rw-r--r--chrome/renderer/webgles2context_impl.h4
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc2
9 files changed, 87 insertions, 16 deletions
diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc
index db7eb1b..011b5f5 100644
--- a/chrome/renderer/ggl/ggl.cc
+++ b/chrome/renderer/ggl/ggl.cc
@@ -59,7 +59,14 @@ class Context : public base::SupportsWeakPtr<Context> {
// Initialize a GGL context that can be used in association with a a GPU
// channel acquired from a RenderWidget or RenderView.
- bool Initialize(gfx::NativeViewId view, const gfx::Size& size);
+ bool Initialize(gfx::NativeViewId view,
+ int render_view_id,
+ const gfx::Size& size);
+
+#if defined(OS_MACOSX)
+ // Asynchronously resizes an onscreen frame buffer.
+ void ResizeOnscreen(const gfx::Size& size);
+#endif
// Asynchronously resizes an offscreen frame buffer.
void ResizeOffscreen(const gfx::Size& size);
@@ -114,7 +121,9 @@ Context::~Context() {
Destroy();
}
-bool Context::Initialize(gfx::NativeViewId view, const gfx::Size& size) {
+bool Context::Initialize(gfx::NativeViewId view,
+ int render_view_id,
+ const gfx::Size& size) {
DCHECK(size.width() >= 0 && size.height() >= 0);
if (channel_->state() != GpuChannelHost::CONNECTED)
@@ -134,7 +143,8 @@ bool Context::Initialize(gfx::NativeViewId view, const gfx::Size& size) {
// Create a proxy to a command buffer in the GPU process.
if (view) {
- command_buffer_ = channel_->CreateViewCommandBuffer(view);
+ command_buffer_ =
+ channel_->CreateViewCommandBuffer(view, render_view_id);
} else {
CommandBufferProxy* parent_command_buffer =
parent_.get() ? parent_->command_buffer_ : NULL;
@@ -189,6 +199,13 @@ bool Context::Initialize(gfx::NativeViewId view, const gfx::Size& size) {
return true;
}
+#if defined(OS_MACOSX)
+void Context::ResizeOnscreen(const gfx::Size& size) {
+ DCHECK(size.width() > 0 && size.height() > 0);
+ command_buffer_->SetWindowSize(size);
+}
+#endif
+
void Context::ResizeOffscreen(const gfx::Size& size) {
DCHECK(size.width() > 0 && size.height() > 0);
command_buffer_->ResizeOffscreenFrameBuffer(size);
@@ -264,10 +281,12 @@ void Context::DisableShaderTranslation() {
#endif // ENABLE_GPU
-Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view) {
+Context* CreateViewContext(GpuChannelHost* channel,
+ gfx::NativeViewId view,
+ int render_view_id) {
#if defined(ENABLE_GPU)
scoped_ptr<Context> context(new Context(channel, NULL));
- if (!context->Initialize(view, gfx::Size()))
+ if (!context->Initialize(view, render_view_id, gfx::Size()))
return NULL;
return context.release();
@@ -276,12 +295,20 @@ Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view) {
#endif
}
+#if defined(OS_MACOSX)
+void ResizeOnscreenContext(Context* context, const gfx::Size& size) {
+#if defined(ENABLE_GPU)
+ context->ResizeOnscreen(size);
+#endif
+}
+#endif
+
Context* CreateOffscreenContext(GpuChannelHost* channel,
Context* parent,
const gfx::Size& size) {
#if defined(ENABLE_GPU)
scoped_ptr<Context> context(new Context(channel, parent));
- if (!context->Initialize(0, size))
+ if (!context->Initialize(0, 0, size))
return NULL;
return context.release();
diff --git a/chrome/renderer/ggl/ggl.h b/chrome/renderer/ggl/ggl.h
index bf2d87d..ce34c7f 100644
--- a/chrome/renderer/ggl/ggl.h
+++ b/chrome/renderer/ggl/ggl.h
@@ -37,7 +37,29 @@ bool Initialize();
bool Terminate();
// Create a GGL context that renders directly to a view.
-Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view);
+//
+// NOTE: on Mac OS X, this entry point is only used to set up the
+// accelerated compositor's output. On this platform, we actually pass
+// a gfx::PluginWindowHandle in place of the gfx::NativeViewId,
+// because the facility to allocate a fake PluginWindowHandle is
+// already in place. We could add more entry points and messages to
+// allocate both fake PluginWindowHandles and NativeViewIds and map
+// from fake NativeViewIds to PluginWindowHandles, but this seems like
+// unnecessary complexity at the moment.
+//
+// The render_view_id is currently also only used on Mac OS X.
+// TODO(kbr): clean up the arguments to this function and make them
+// more cross-platform.
+Context* CreateViewContext(GpuChannelHost* channel,
+ gfx::NativeViewId view,
+ int render_view_id);
+
+#if defined(OS_MACOSX)
+// On Mac OS X only, view contexts actually behave like offscreen contexts, and
+// require an explicit resize operation which is slightly different from that
+// of offscreen contexts.
+void ResizeOnscreenContext(Context* context, const gfx::Size& size);
+#endif
// Create a GGL context that renders to an offscreen frame buffer. If parent is
// not NULL, that context can access a copy of the created
diff --git a/chrome/renderer/gpu_channel_host.cc b/chrome/renderer/gpu_channel_host.cc
index 1f2eb21..70a5224 100644
--- a/chrome/renderer/gpu_channel_host.cc
+++ b/chrome/renderer/gpu_channel_host.cc
@@ -68,14 +68,16 @@ bool GpuChannelHost::Send(IPC::Message* message) {
}
CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer(
- gfx::NativeViewId view) {
+ gfx::NativeViewId view, int render_view_id) {
#if defined(ENABLE_GPU)
// An error occurred. Need to get the host again to reinitialize it.
if (!channel_.get())
return NULL;
int32 route_id;
- if (!Send(new GpuChannelMsg_CreateViewCommandBuffer(view, &route_id)) &&
+ if (!Send(new GpuChannelMsg_CreateViewCommandBuffer(view,
+ render_view_id,
+ &route_id)) &&
route_id != MSG_ROUTING_NONE) {
return NULL;
}
diff --git a/chrome/renderer/gpu_channel_host.h b/chrome/renderer/gpu_channel_host.h
index 854aea5..6c33acb 100644
--- a/chrome/renderer/gpu_channel_host.h
+++ b/chrome/renderer/gpu_channel_host.h
@@ -53,7 +53,8 @@ class GpuChannelHost : public IPC::Channel::Listener,
virtual bool Send(IPC::Message* msg);
// Create and connect to a command buffer in the GPU process.
- CommandBufferProxy* CreateViewCommandBuffer(gfx::NativeViewId view);
+ CommandBufferProxy* CreateViewCommandBuffer(gfx::NativeViewId view,
+ int render_view_id);
// Create and connect to a command buffer in the GPU process.
CommandBufferProxy* CreateOffscreenCommandBuffer(CommandBufferProxy* parent,
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index a7787a5..39c4193 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -5169,10 +5169,10 @@ void RenderView::EnsureDocumentTag() {
#if defined(OS_MACOSX)
gfx::PluginWindowHandle RenderView::AllocateFakePluginWindowHandle(
- bool opaque) {
+ bool opaque, bool root) {
gfx::PluginWindowHandle window = NULL;
Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
- routing_id(), opaque, &window));
+ routing_id(), opaque, root, &window));
return window;
}
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 82a293a..3d3cdbd 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -287,7 +287,8 @@ class RenderView : public RenderWidget,
#if defined(OS_MACOSX)
// Helper routines for GPU plugin support. Used by the
// WebPluginDelegateProxy, which has a pointer to the RenderView.
- gfx::PluginWindowHandle AllocateFakePluginWindowHandle(bool opaque);
+ gfx::PluginWindowHandle AllocateFakePluginWindowHandle(bool opaque,
+ bool root);
void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
void AcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
int32 width,
diff --git a/chrome/renderer/webgles2context_impl.cc b/chrome/renderer/webgles2context_impl.cc
index a14e0e3..d0e35d7 100644
--- a/chrome/renderer/webgles2context_impl.cc
+++ b/chrome/renderer/webgles2context_impl.cc
@@ -45,8 +45,16 @@ bool WebGLES2ContextImpl::initialize(
RenderView* renderview = RenderView::FromWebView(web_view);
if (!renderview)
return false;
- gfx::NativeViewId view_id = renderview->host_window();
- context_ = ggl::CreateViewContext(host, view_id);
+ gfx::NativeViewId view_id;
+#if !defined(OS_MACOSX)
+ view_id = renderview->host_window();
+#else
+ view_id = static_cast<gfx::NativeViewId>(
+ renderview->AllocateFakePluginWindowHandle(true, true));
+#endif
+ context_ = ggl::CreateViewContext(
+ host, view_id,
+ renderview->routing_id());
} else {
ggl::Context* parent_context = NULL;
@@ -83,5 +91,11 @@ unsigned WebGLES2ContextImpl::getOffscreenContentParentTextureId() {
return ggl::GetParentTextureId(context_);
}
+#if defined(OS_MACOSX)
+void WebGLES2ContextImpl::resizeOnscreenContent(const WebKit::WebSize& size) {
+ ggl::ResizeOnscreenContext(context_, size);
+}
+#endif
+
#endif // defined(ENABLE_GPU)
diff --git a/chrome/renderer/webgles2context_impl.h b/chrome/renderer/webgles2context_impl.h
index 3183634..e8c267e 100644
--- a/chrome/renderer/webgles2context_impl.h
+++ b/chrome/renderer/webgles2context_impl.h
@@ -27,6 +27,10 @@ class WebGLES2ContextImpl : public WebKit::WebGLES2Context {
virtual void resizeOffscreenContent(const WebKit::WebSize&);
virtual unsigned getOffscreenContentParentTextureId();
+#if defined(OS_MACOSX)
+ virtual void resizeOnscreenContent(const WebKit::WebSize&);
+#endif
+
ggl::Context* context() { return context_; }
private:
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index fb35163..1be5f5d 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -1399,7 +1399,7 @@ void WebPluginDelegateProxy::OnBindFakePluginWindowHandle(bool opaque) {
bool WebPluginDelegateProxy::BindFakePluginWindowHandle(bool opaque) {
gfx::PluginWindowHandle fake_window = NULL;
if (render_view_)
- fake_window = render_view_->AllocateFakePluginWindowHandle(opaque);
+ fake_window = render_view_->AllocateFakePluginWindowHandle(opaque, false);
// If we aren't running on 10.6, this allocation will fail.
if (!fake_window)
return false;