summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc44
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h8
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h16
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.h19
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm123
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.cc23
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.h8
-rwxr-xr-xchrome/chrome.gyp2
-rwxr-xr-xchrome/chrome_browser.gypi1
-rw-r--r--chrome/chrome_common.gypi2
-rwxr-xr-xchrome/chrome_renderer.gypi2
-rw-r--r--chrome/common/command_buffer_messages_internal.h11
-rw-r--r--chrome/common/gpu_plugin.cc2
-rw-r--r--chrome/common/io_surface_support_mac.cc242
-rw-r--r--chrome/common/io_surface_support_mac.h66
-rw-r--r--chrome/common/plugin_messages_internal.h32
-rw-r--r--chrome/common/render_messages_internal.h35
-rw-r--r--chrome/plugin/command_buffer_stub.cc29
-rw-r--r--chrome/plugin/command_buffer_stub.h9
-rw-r--r--chrome/plugin/webplugin_delegate_stub.cc15
-rw-r--r--chrome/plugin/webplugin_delegate_stub.h8
-rw-r--r--chrome/renderer/command_buffer_proxy.cc7
-rw-r--r--chrome/renderer/command_buffer_proxy.h4
-rw-r--r--chrome/renderer/render_view.cc27
-rw-r--r--chrome/renderer/render_view.h12
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.cc16
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc46
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h5
28 files changed, 809 insertions, 5 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index cde8932..6a20f26 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -143,6 +143,15 @@ void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_GetScreenInfo, OnMsgGetScreenInfo)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowRect, OnMsgGetWindowRect)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetRootWindowRect, OnMsgGetRootWindowRect)
+ // The following messages are only used on 10.6 and later
+ IPC_MESSAGE_HANDLER(ViewHostMsg_AllocateFakePluginWindowHandle,
+ OnAllocateFakePluginWindowHandle)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyFakePluginWindowHandle,
+ OnDestroyFakePluginWindowHandle)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_GPUPluginSetIOSurface,
+ OnGPUPluginSetIOSurface)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_GPUPluginBuffersSwapped,
+ OnGPUPluginBuffersSwapped)
#endif
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP_EX()
@@ -874,6 +883,41 @@ void RenderWidgetHost::OnMsgGetRootWindowRect(gfx::NativeViewId window_id,
}
}
+void RenderWidgetHost::OnAllocateFakePluginWindowHandle(
+ gfx::PluginWindowHandle* id) {
+ // TODO(kbr): similar potential issue here as in OnMsgCreatePluginContainer.
+ // Possibly less of an issue because this is only used for the GPU plugin.
+ if (view_) {
+ *id = view_->AllocateFakePluginWindowHandle();
+ } else {
+ NOTIMPLEMENTED();
+ }
+}
+
+void RenderWidgetHost::OnDestroyFakePluginWindowHandle(
+ gfx::PluginWindowHandle id) {
+ if (view_) {
+ view_->DestroyFakePluginWindowHandle(id);
+ } else {
+ NOTIMPLEMENTED();
+ }
+}
+
+void RenderWidgetHost::OnGPUPluginSetIOSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 mach_port) {
+ if (view_) {
+ view_->GPUPluginSetIOSurface(window, width, height, mach_port);
+ }
+}
+
+void RenderWidgetHost::OnGPUPluginBuffersSwapped(
+ gfx::PluginWindowHandle window) {
+ if (view_) {
+ view_->GPUPluginBuffersSwapped(window);
+ }
+}
#endif
void RenderWidgetHost::PaintBackingStoreRect(
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index f08dee3..ea6c843 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -444,6 +444,14 @@ class RenderWidgetHost : public IPC::Channel::Listener,
WebKit::WebScreenInfo* results);
void OnMsgGetWindowRect(gfx::NativeViewId window_id, gfx::Rect* results);
void OnMsgGetRootWindowRect(gfx::NativeViewId window_id, gfx::Rect* results);
+ // The following handlers are only used on 10.6 and later
+ void OnAllocateFakePluginWindowHandle(gfx::PluginWindowHandle* id);
+ void OnDestroyFakePluginWindowHandle(gfx::PluginWindowHandle id);
+ void OnGPUPluginSetIOSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 mach_port);
+ void OnGPUPluginBuffersSwapped(gfx::PluginWindowHandle window);
#endif
// Paints the given bitmap to the current backing store at the given location.
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h
index 0a87d3d..ccb1b31 100644
--- a/chrome/browser/renderer_host/render_widget_host_view.h
+++ b/chrome/browser/renderer_host/render_widget_host_view.h
@@ -5,6 +5,10 @@
#ifndef CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_H_
#define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_H_
+#if defined(OS_MACOSX)
+#include <OpenGL/OpenGL.h>
+#endif
+
#include "app/gfx/native_widget_types.h"
#include "base/shared_memory.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -166,6 +170,18 @@ class RenderWidgetHostView {
// message and renderer-side handling) can be removed in favor of using
// WasHidden/DidBecomeSelected.
virtual void SetWindowVisibility(bool visible) = 0;
+
+ // Methods associated with GPU plugin instances
+ virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle() = 0;
+ virtual void DestroyFakePluginWindowHandle(
+ gfx::PluginWindowHandle window) = 0;
+ virtual void GPUPluginSetIOSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier) = 0;
+ virtual void GPUPluginBuffersSwapped(gfx::PluginWindowHandle window) = 0;
+ // Draws the current GPU plugin instances into the given context.
+ virtual void DrawGPUPluginInstances(CGLContextObj context) = 0;
#endif
#if defined(OS_LINUX)
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h
index 4edfa1ef..c9834bf 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MAC_H_
#import <Cocoa/Cocoa.h>
+#import <QuartzCore/CALayer.h>
#include "base/scoped_nsobject.h"
#include "base/scoped_ptr.h"
@@ -15,6 +16,7 @@
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "webkit/glue/webcursor.h"
#include "webkit/glue/webmenuitem.h"
+#include "webkit/glue/plugins/mac_gpu_plugin_container_manager.h"
class RenderWidgetHostViewMac;
class RWHVMEditCommandHelper;
@@ -112,6 +114,17 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
virtual void SetWindowVisibility(bool visible);
virtual void SetBackground(const SkBitmap& background);
+ // Methods associated with GPU plugin instances
+ virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle();
+ virtual void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
+ virtual void GPUPluginSetIOSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier);
+ virtual void GPUPluginBuffersSwapped(gfx::PluginWindowHandle window);
+ // Draws the current GPU plugin instances into the given context.
+ virtual void DrawGPUPluginInstances(CGLContextObj context);
+
void KillSelf();
void set_parent_view(BaseView* parent_view) { parent_view_ = parent_view; }
@@ -181,6 +194,9 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
// methods needs it.
NSRect im_caret_rect_;
+ // The Core Animation layer, if any, hosting the GPU plugins' output.
+ scoped_nsobject<CALayer> gpu_plugin_layer_;
+
private:
// Updates the display cursor to the current cursor if the cursor is over this
// render view.
@@ -220,6 +236,9 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
// Used for positioning a popup menu.
BaseView* parent_view_;
+ // Helper class for managing instances of the GPU plugin.
+ MacGPUPluginContainerManager plugin_container_manager_;
+
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac);
};
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index a20ff65..db78a46 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <QuartzCore/CAOpenGLLayer.h>
+
#include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
#import "base/chrome_application_mac.h"
@@ -20,6 +22,7 @@
#include "chrome/common/edit_command.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/common/render_messages.h"
+#include "chrome/common/io_surface_support_mac.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/mac/WebInputEventFactory.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
@@ -53,6 +56,35 @@ const size_t kMaxTooltipLength = 1024;
}
+// GPUPluginLayer --------------------------------------------------------------
+
+// This subclass of CAOpenGLLayer hosts the output of the GPU plugins
+// on the page.
+
+@interface GPUPluginLayer : CAOpenGLLayer {
+ RenderWidgetHostViewMac* renderWidgetHostView_; // weak
+}
+
+- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r;
+@end
+
+@implementation GPUPluginLayer
+- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r {
+ self = [super init];
+ if (self != nil) {
+ renderWidgetHostView_ = r;
+ }
+ return self;
+}
+
+-(void)drawInCGLContext:(CGLContextObj)glContext
+ pixelFormat:(CGLPixelFormatObj)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval
+ displayTime:(const CVTimeStamp *)timeStamp {
+ renderWidgetHostView_->DrawGPUPluginInstances(glContext);
+}
+@end
+
// RenderWidgetHostView --------------------------------------------------------
// static
@@ -174,6 +206,26 @@ gfx::NativeView RenderWidgetHostViewMac::GetNativeView() {
void RenderWidgetHostViewMac::MovePluginWindows(
const std::vector<webkit_glue::WebPluginGeometry>& moves) {
+ // The only case we need to notice plugin window moves is the case
+ // of the GPU plugin. As soon as the GPU plugin becomes the GPU
+ // process all of this code will go away.
+ if (moves.size() > 0) {
+ for (std::vector<webkit_glue::WebPluginGeometry>::const_iterator iter =
+ moves.begin();
+ iter != moves.end();
+ ++iter) {
+ webkit_glue::WebPluginGeometry geom = *iter;
+ // Ignore bogus moves which claim to move the plugin to (0, 0)
+ // with width and height (0, 0)
+ if (geom.window_rect.x() != 0 ||
+ geom.window_rect.y() != 0 ||
+ geom.window_rect.width() != 0 ||
+ geom.window_rect.height() != 0) {
+ plugin_container_manager_.MovePluginContainer(geom);
+ }
+ }
+ }
+
// All plugin stuff is TBD. TODO(avi,awalker): fill in
// http://crbug.com/8192
}
@@ -440,6 +492,73 @@ void RenderWidgetHostViewMac::KillSelf() {
}
}
+gfx::PluginWindowHandle
+RenderWidgetHostViewMac::AllocateFakePluginWindowHandle() {
+ // We currently only support the GPU plugin on 10.6 and later.
+ if (!IOSurfaceSupport::Initialize())
+ return 0;
+
+ // If we don't already have a GPUPluginLayer allocated for our view,
+ // set one up now.
+ if (gpu_plugin_layer_.get() == nil) {
+ RenderWidgetHostViewCocoa* our_view = native_view();
+ // Try to get AppKit to allocate the layer
+ [our_view setWantsLayer:YES];
+ CALayer* root_layer = [our_view layer];
+ if (root_layer == nil) {
+ root_layer = [CALayer layer];
+ [our_view setLayer:root_layer];
+ }
+
+ GPUPluginLayer* gpu_layer =
+ [[GPUPluginLayer alloc] initWithRenderWidgetHostViewMac:this];
+
+ // Make our layer resize to fit the superlayer
+ gpu_layer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
+ // Set up its initial size
+ [gpu_layer setFrame:NSRectToCGRect([our_view bounds])];
+
+ [root_layer addSublayer:gpu_layer];
+ gpu_plugin_layer_.reset(gpu_layer);
+ }
+
+ return plugin_container_manager_.AllocateFakePluginWindowHandle();
+}
+
+void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle(
+ gfx::PluginWindowHandle window) {
+ plugin_container_manager_.DestroyFakePluginWindowHandle(window);
+}
+
+void RenderWidgetHostViewMac::GPUPluginSetIOSurface(
+ gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier) {
+ plugin_container_manager_.SetSizeAndBackingStore(window,
+ width,
+ height,
+ io_surface_identifier);
+}
+
+void RenderWidgetHostViewMac::GPUPluginBuffersSwapped(
+ gfx::PluginWindowHandle window) {
+ [gpu_plugin_layer_.get() setNeedsDisplay];
+}
+
+void RenderWidgetHostViewMac::DrawGPUPluginInstances(CGLContextObj context) {
+ CGLSetCurrentContext(context);
+ gfx::Rect rect = GetWindowRect();
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ // Note that we place the origin at the upper left corner with +y
+ // going down
+ glOrtho(0, rect.width(), rect.height(), 0, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ plugin_container_manager_.Draw(context);
+}
+
void RenderWidgetHostViewMac::ShutdownHost() {
shutdown_factory_.RevokeAll();
render_widget_host_->Shutdown();
@@ -870,6 +989,10 @@ void RenderWidgetHostViewMac::SetBackground(const SkBitmap& background) {
if (renderWidgetHostView_->whiteout_start_time_.is_null())
renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks::Now();
}
+
+ // This helps keep the GPU plugins' output in better sync with the
+ // window as it resizes.
+ [renderWidgetHostView_->gpu_plugin_layer_.get() setNeedsDisplay];
}
- (BOOL)canBecomeKeyView {
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.cc b/chrome/browser/renderer_host/test/test_render_view_host.cc
index 95c5b7b..776ef53 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.cc
+++ b/chrome/browser/renderer_host/test/test_render_view_host.cc
@@ -91,6 +91,29 @@ gfx::Rect TestRenderWidgetHostView::GetRootWindowRect() {
void TestRenderWidgetHostView::SetActive(bool active) {
// <viettrungluu@gmail.com>: Do I need to do anything here?
}
+
+gfx::PluginWindowHandle
+TestRenderWidgetHostView::AllocateFakePluginWindowHandle() {
+ return NULL;
+}
+
+void TestRenderWidgetHostView::DestroyFakePluginWindowHandle(
+ gfx::PluginWindowHandle window) {
+}
+
+void TestRenderWidgetHostView::GPUPluginSetIOSurface(
+ gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier) {
+}
+
+void TestRenderWidgetHostView::GPUPluginBuffersSwapped(
+ gfx::PluginWindowHandle window) {
+}
+
+void TestRenderWidgetHostView::DrawGPUPluginInstances(CGLContextObj context) {
+}
#endif
void RenderViewHostTestHarness::NavigateAndCommit(const GURL& url) {
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h
index 7ec1304..fde21b5 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.h
+++ b/chrome/browser/renderer_host/test/test_render_view_host.h
@@ -78,6 +78,14 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual gfx::Rect GetRootWindowRect();
virtual void SetActive(bool active);
virtual void SetWindowVisibility(bool visible) {}
+ virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle();
+ virtual void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
+ virtual void GPUPluginSetIOSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier);
+ virtual void GPUPluginBuffersSwapped(gfx::PluginWindowHandle window);
+ virtual void DrawGPUPluginInstances(CGLContextObj context);
#endif
#if defined(OS_LINUX)
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 72c1349..1c6d346 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -526,7 +526,7 @@
'third_party/wtl/include',
],
}],
- ['OS=="win" or (OS=="linux" and target_arch!="arm")', {
+ ['enable_gpu==1', {
'dependencies': [
'../gpu/gpu.gyp:command_buffer_service',
],
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index c181704e..88cf2aa 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2179,6 +2179,7 @@
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework',
'$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
+ '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
],
'mac_bundle_resources': [
'browser/utility.sb',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index e928f01..c7b405f 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -57,6 +57,8 @@
'common/devtools_messages_internal.h',
'common/gpu_messages.h',
'common/gpu_messages_internal.h',
+ 'common/io_surface_support_mac.cc',
+ 'common/io_surface_support_mac.h',
'common/logging_chrome.cc',
'common/logging_chrome.h',
'common/main_function_params.h',
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index a15c82b..1a41678 100755
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -185,7 +185,7 @@
}],
],
}],
- ['OS=="win" or (OS=="linux" and target_arch!="arm")', {
+ ['enable_gpu==1', {
'sources': [
'renderer/command_buffer_proxy.cc',
'renderer/command_buffer_proxy.h',
diff --git a/chrome/common/command_buffer_messages_internal.h b/chrome/common/command_buffer_messages_internal.h
index 274223b5..f6fb423 100644
--- a/chrome/common/command_buffer_messages_internal.h
+++ b/chrome/common/command_buffer_messages_internal.h
@@ -41,4 +41,15 @@ IPC_BEGIN_MESSAGES(CommandBuffer)
base::SharedMemoryHandle /* transfer_buffer */,
size_t /* size */)
+#if defined(OS_MACOSX)
+ // On Mac OS X the GPU plugin must be offscreen, because there is no
+ // true cross-process window hierarchy. For this reason we must send
+ // resize events explicitly to the command buffer stub so it can
+ // reallocate its backing store and send the new one back to the
+ // browser. This message is currently used only on 10.6 and later.
+ IPC_MESSAGE_ROUTED2(CommandBufferMsg_SetWindowSize,
+ int32 /* width */,
+ int32 /* height */)
+#endif
+
IPC_END_MESSAGES(CommandBuffer)
diff --git a/chrome/common/gpu_plugin.cc b/chrome/common/gpu_plugin.cc
index fc79cbb..d9d67db 100644
--- a/chrome/common/gpu_plugin.cc
+++ b/chrome/common/gpu_plugin.cc
@@ -27,7 +27,7 @@ void RegisterInternalGPUPlugin() {
L"",
L"",
{
-#if !defined(OS_LINUX)
+#if !defined(OS_POSIX) || defined(OS_MACOSX)
gpu_plugin::NP_GetEntryPoints,
#endif
gpu_plugin::NP_Initialize,
diff --git a/chrome/common/io_surface_support_mac.cc b/chrome/common/io_surface_support_mac.cc
new file mode 100644
index 0000000..80b2539
--- /dev/null
+++ b/chrome/common/io_surface_support_mac.cc
@@ -0,0 +1,242 @@
+// Copyright (c) 2010 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 <dlfcn.h>
+
+#include "base/singleton.h"
+#include "chrome/common/io_surface_support_mac.h"
+
+typedef CFTypeRef (*IOSurfaceCreateProcPtr)(CFDictionaryRef properties);
+typedef uint32 (*IOSurfaceGetIDProcPtr)(CFTypeRef io_surface);
+typedef CFTypeRef (*IOSurfaceLookupProcPtr)(uint32 io_surface_id);
+typedef mach_port_t (*IOSurfaceCreateMachPortProcPtr)(CFTypeRef io_surface);
+typedef CFTypeRef (*IOSurfaceLookupFromMachPortProcPtr)(mach_port_t port);
+typedef CGLError (*CGLTexImageIOSurface2DProcPtr)(CGLContextObj ctx,
+ GLenum target,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ CFTypeRef io_surface,
+ GLuint plane);
+
+class IOSurfaceSupportImpl : public IOSurfaceSupport {
+ public:
+ static IOSurfaceSupportImpl* Initialize();
+
+ bool InitializedSuccessfully() {
+ return initialized_successfully_;
+ }
+
+ virtual CFStringRef GetKIOSurfaceWidth();
+ virtual CFStringRef GetKIOSurfaceHeight();
+ virtual CFStringRef GetKIOSurfaceBytesPerElement();
+ virtual CFStringRef GetKIOSurfaceIsGlobal();
+
+ virtual CFTypeRef IOSurfaceCreate(CFDictionaryRef properties);
+ virtual uint32 IOSurfaceGetID(CFTypeRef io_surface);
+ virtual CFTypeRef IOSurfaceLookup(uint32 io_surface_id);
+ virtual mach_port_t IOSurfaceCreateMachPort(CFTypeRef io_surface);
+ virtual CFTypeRef IOSurfaceLookupFromMachPort(mach_port_t port);
+
+ virtual CGLError CGLTexImageIOSurface2D(CGLContextObj ctx,
+ GLenum target,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ CFTypeRef io_surface,
+ GLuint plane);
+
+ private:
+ IOSurfaceSupportImpl();
+ ~IOSurfaceSupportImpl();
+
+ void* iosurface_handle_;
+ void* opengl_handle_;
+ CFStringRef k_io_surface_width_;
+ CFStringRef k_io_surface_height_;
+ CFStringRef k_io_surface_bytes_per_element_;
+ CFStringRef k_io_surface_is_global_;
+ IOSurfaceCreateProcPtr io_surface_create_;
+ IOSurfaceGetIDProcPtr io_surface_get_id_;
+ IOSurfaceLookupProcPtr io_surface_lookup_;
+ IOSurfaceCreateMachPortProcPtr io_surface_create_mach_port_;
+ IOSurfaceLookupFromMachPortProcPtr io_surface_lookup_from_mach_port_;
+ CGLTexImageIOSurface2DProcPtr cgl_tex_image_io_surface_2d_;
+ bool initialized_successfully_;
+
+ friend struct DefaultSingletonTraits<IOSurfaceSupportImpl>;
+ DISALLOW_EVIL_CONSTRUCTORS(IOSurfaceSupportImpl);
+};
+
+static Singleton<IOSurfaceSupportImpl> sole_instance_;
+
+IOSurfaceSupportImpl* IOSurfaceSupportImpl::Initialize() {
+ IOSurfaceSupportImpl* impl = sole_instance_.get();
+ if (impl->InitializedSuccessfully())
+ return impl;
+ return NULL;
+}
+
+CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceWidth() {
+ return k_io_surface_width_;
+}
+
+CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceHeight() {
+ return k_io_surface_height_;
+}
+
+CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceBytesPerElement() {
+ return k_io_surface_bytes_per_element_;
+}
+
+CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceIsGlobal() {
+ return k_io_surface_is_global_;
+}
+
+CFTypeRef IOSurfaceSupportImpl::IOSurfaceCreate(CFDictionaryRef properties) {
+ return io_surface_create_(properties);
+}
+
+uint32 IOSurfaceSupportImpl::IOSurfaceGetID(
+ CFTypeRef io_surface) {
+ return io_surface_get_id_(io_surface);
+}
+
+CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookup(uint32 io_surface_id) {
+ return io_surface_lookup_(io_surface_id);
+}
+
+mach_port_t IOSurfaceSupportImpl::IOSurfaceCreateMachPort(
+ CFTypeRef io_surface) {
+ return io_surface_create_mach_port_(io_surface);
+}
+
+CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookupFromMachPort(mach_port_t port) {
+ return io_surface_lookup_from_mach_port_(port);
+}
+
+CGLError IOSurfaceSupportImpl::CGLTexImageIOSurface2D(CGLContextObj ctx,
+ GLenum target,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ CFTypeRef io_surface,
+ GLuint plane) {
+ return cgl_tex_image_io_surface_2d_(ctx,
+ target,
+ internal_format,
+ width,
+ height,
+ format,
+ type,
+ io_surface,
+ plane);
+}
+
+IOSurfaceSupportImpl::IOSurfaceSupportImpl()
+ : iosurface_handle_(NULL),
+ opengl_handle_(NULL),
+ k_io_surface_width_(NULL),
+ k_io_surface_height_(NULL),
+ k_io_surface_bytes_per_element_(NULL),
+ k_io_surface_is_global_(NULL),
+ io_surface_create_(NULL),
+ io_surface_get_id_(NULL),
+ io_surface_lookup_(NULL),
+ io_surface_create_mach_port_(NULL),
+ io_surface_lookup_from_mach_port_(NULL),
+ cgl_tex_image_io_surface_2d_(NULL),
+ initialized_successfully_(false) {
+ iosurface_handle_ = dlopen(
+ "/System/Library/Frameworks/IOSurface.framework/IOSurface",
+ RTLD_LAZY | RTLD_LOCAL);
+ if (!iosurface_handle_)
+ return;
+ opengl_handle_ = dlopen(
+ "/System/Library/Frameworks/OpenGL.framework/OpenGL",
+ RTLD_LAZY | RTLD_LOCAL);
+ if (!opengl_handle_) {
+ dlclose(iosurface_handle_);
+ iosurface_handle_ = NULL;
+ return;
+ }
+
+ void* surface_width_ptr = dlsym(iosurface_handle_, "kIOSurfaceWidth");
+ void* surface_height_ptr = dlsym(iosurface_handle_, "kIOSurfaceHeight");
+ void* surface_bytes_per_element_ptr =
+ dlsym(iosurface_handle_, "kIOSurfaceBytesPerElement");
+ void* surface_is_global_ptr =
+ dlsym(iosurface_handle_, "kIOSurfaceIsGlobal");
+ void* surface_create_ptr = dlsym(iosurface_handle_, "IOSurfaceCreate");
+ void* surface_get_id_ptr = dlsym(iosurface_handle_, "IOSurfaceGetID");
+ void* surface_lookup_ptr = dlsym(iosurface_handle_, "IOSurfaceLookup");
+ void* surface_create_mach_port_ptr =
+ dlsym(iosurface_handle_, "IOSurfaceCreateMachPort");
+ void* surface_lookup_from_mach_port_ptr =
+ dlsym(iosurface_handle_, "IOSurfaceLookupFromMachPort");
+ void* tex_image_io_surface_2d_ptr =
+ dlsym(opengl_handle_, "CGLTexImageIOSurface2D");
+ if (!surface_width_ptr ||
+ !surface_height_ptr ||
+ !surface_bytes_per_element_ptr ||
+ !surface_is_global_ptr ||
+ !surface_create_ptr ||
+ !surface_get_id_ptr ||
+ !surface_lookup_ptr ||
+ !surface_create_mach_port_ptr ||
+ !surface_lookup_from_mach_port_ptr ||
+ !tex_image_io_surface_2d_ptr) {
+ dlclose(iosurface_handle_);
+ iosurface_handle_ = NULL;
+ dlclose(opengl_handle_);
+ opengl_handle_ = NULL;
+ return;
+ }
+
+ k_io_surface_width_ = *static_cast<CFStringRef*>(surface_width_ptr);
+ k_io_surface_height_ = *static_cast<CFStringRef*>(surface_height_ptr);
+ k_io_surface_bytes_per_element_ =
+ *static_cast<CFStringRef*>(surface_bytes_per_element_ptr);
+ k_io_surface_is_global_ = *static_cast<CFStringRef*>(surface_is_global_ptr);
+ io_surface_create_ = reinterpret_cast<IOSurfaceCreateProcPtr>(
+ surface_create_ptr);
+ io_surface_get_id_ =
+ reinterpret_cast<IOSurfaceGetIDProcPtr>(surface_get_id_ptr);
+ io_surface_lookup_ =
+ reinterpret_cast<IOSurfaceLookupProcPtr>(surface_lookup_ptr);
+ io_surface_create_mach_port_ =
+ reinterpret_cast<IOSurfaceCreateMachPortProcPtr>(
+ surface_create_mach_port_ptr);
+ io_surface_lookup_from_mach_port_ =
+ reinterpret_cast<IOSurfaceLookupFromMachPortProcPtr>(
+ surface_lookup_from_mach_port_ptr);
+ cgl_tex_image_io_surface_2d_ =
+ reinterpret_cast<CGLTexImageIOSurface2DProcPtr>(
+ tex_image_io_surface_2d_ptr);
+ initialized_successfully_ = true;
+}
+
+IOSurfaceSupportImpl::~IOSurfaceSupportImpl() {
+ if (iosurface_handle_)
+ dlclose(iosurface_handle_);
+ if (opengl_handle_)
+ dlclose(opengl_handle_);
+}
+
+IOSurfaceSupport* IOSurfaceSupport::Initialize() {
+ return IOSurfaceSupportImpl::Initialize();
+}
+
+IOSurfaceSupport::IOSurfaceSupport() {
+}
+
+IOSurfaceSupport::~IOSurfaceSupport() {
+}
+
diff --git a/chrome/common/io_surface_support_mac.h b/chrome/common/io_surface_support_mac.h
new file mode 100644
index 0000000..6ad116f
--- /dev/null
+++ b/chrome/common/io_surface_support_mac.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2010 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 CHROME_COMMON_IO_SURFACE_SUPPORT_MAC_H_
+#define CHROME_COMMON_IO_SURFACE_SUPPORT_MAC_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <mach/mach.h>
+#include <OpenGL/OpenGL.h>
+
+#include "base/basictypes.h"
+
+// This Mac OS X-specific class provides dynamically-linked access to
+// IOSurface.framework, which is only available on 10.6 and later.
+// Since Chromium is built on 10.5 we must dynamically look up all of
+// the entry points we need in this framework.
+
+// See IOSurface/IOSurfaceAPI.h and OpenGL/CGLIOSurface.h on 10.6 for
+// documentation of the fields and methods of this class.
+
+class IOSurfaceSupport {
+ public:
+ // Returns an instance of the IOSurfaceSupport class if the
+ // operating system supports it, NULL otherwise. It is safe to call
+ // this multiple times.
+ static IOSurfaceSupport* Initialize();
+
+ virtual CFStringRef GetKIOSurfaceWidth() = 0;
+ virtual CFStringRef GetKIOSurfaceHeight() = 0;
+ virtual CFStringRef GetKIOSurfaceBytesPerElement() = 0;
+ virtual CFStringRef GetKIOSurfaceIsGlobal() = 0;
+
+ virtual CFTypeRef IOSurfaceCreate(CFDictionaryRef properties) = 0;
+
+ // The following two APIs assume the IOSurface was created with the
+ // kIOSurfaceIsGlobal key set to true
+ virtual uint32 IOSurfaceGetID(CFTypeRef io_surface) = 0;
+ virtual CFTypeRef IOSurfaceLookup(uint32 io_surface_id) = 0;
+
+ // The following two APIs are more robust and secure, but
+ // unfortunately it looks like it will be a lot of work to correctly
+ // transmit a mach port from process to process (possibly requiring
+ // a side channel for or extension of the Chrome IPC mechanism)
+ virtual mach_port_t IOSurfaceCreateMachPort(CFTypeRef io_surface) = 0;
+ virtual CFTypeRef IOSurfaceLookupFromMachPort(mach_port_t port) = 0;
+
+ virtual CGLError CGLTexImageIOSurface2D(CGLContextObj ctx,
+ GLenum target,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ CFTypeRef io_surface,
+ GLuint plane) = 0;
+
+ protected:
+ IOSurfaceSupport();
+ virtual ~IOSurfaceSupport();
+
+ DISALLOW_COPY_AND_ASSIGN(IOSurfaceSupport);
+};
+
+#endif // CHROME_COMMON_IO_SURFACE_SUPPORT_MAC_H_
+
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index aecccac..05e532b 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -291,6 +291,15 @@ IPC_BEGIN_MESSAGES(Plugin)
IPC_MESSAGE_CONTROL1(PluginMsg_ResetModalDialogEvent,
gfx::NativeViewId /* containing_window */)
+
+#if defined(OS_MACOSX)
+ // This message, used only on 10.6 and later, transmits the "fake"
+ // window handle allocated by the browser on behalf of the renderer
+ // to the GPU plugin.
+ IPC_MESSAGE_ROUTED1(PluginMsg_SetFakeGPUPluginWindowHandle,
+ gfx::PluginWindowHandle /* window */)
+#endif
+
IPC_END_MESSAGES(Plugin)
@@ -385,6 +394,29 @@ IPC_BEGIN_MESSAGES(PluginHost)
#if defined(OS_MACOSX)
IPC_MESSAGE_ROUTED1(PluginHostMsg_UpdateGeometry_ACK,
int /* ack_key */)
+
+ // This message, used only on 10.6 and later, is sent from the
+ // plug-in process to the renderer process to indicate that the GPU
+ // plugin allocated a new IOSurface object of the given width and
+ // height. This information is then forwarded on to the browser
+ // process.
+ //
+ // NOTE: the original intent was to pass a mach port as the
+ // IOSurface identifier but it looks like that will be a lot of
+ // work. For now we pass an ID from IOSurfaceGetID.
+ IPC_MESSAGE_ROUTED4(PluginHostMsg_GPUPluginSetIOSurface,
+ gfx::PluginWindowHandle /* window */,
+ int32 /* width */,
+ int32 /* height */,
+ uint64 /* identifier for IOSurface */)
+
+ // This message, currently used only on 10.6 and later, notifies the
+ // renderer process (and from there the browser process) that the
+ // GPU plugin swapped the buffers associated with the given
+ // "window", which should cause the browser to redraw the various
+ // GPU plugins' contents.
+ IPC_MESSAGE_ROUTED1(PluginHostMsg_GPUPluginBuffersSwapped,
+ gfx::PluginWindowHandle /* window */)
#endif
IPC_END_MESSAGES(PluginHost)
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 1dcef7e..7b25b7a 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1781,6 +1781,41 @@ IPC_BEGIN_MESSAGES(ViewHost)
// renderer is finished with them.
IPC_MESSAGE_CONTROL1(ViewHostMsg_FreeTransportDIB,
TransportDIB::Id /* DIB id */)
+
+ //---------------------------------------------------------------------------
+ // Messages related to the GPU plugin on Mac OS X 10.6 and later
+
+ // This is sent from the renderer to the browser to allocate a fake
+ // PluginWindowHandle on the browser side which is used to identify
+ // the plugin to the browser later when backing store is allocated
+ // or reallocated.
+ IPC_SYNC_MESSAGE_ROUTED0_1(ViewHostMsg_AllocateFakePluginWindowHandle,
+ gfx::PluginWindowHandle /* id */)
+
+ // Destroys a fake window handle previously allocated using
+ // AllocateFakePluginWindowHandle.
+ IPC_MESSAGE_ROUTED1(ViewHostMsg_DestroyFakePluginWindowHandle,
+ gfx::PluginWindowHandle /* id */)
+
+ // This message is sent from the renderer to the browser on behalf
+ // of the GPU plugin to indicate that a new backing store was
+ // allocated for that GPU plugin instance.
+ //
+ // NOTE: the original intent was to pass a mach port as the
+ // IOSurface identifier but it looks like that will be a lot of
+ // work. For now we pass an ID from IOSurfaceGetID.
+ IPC_MESSAGE_ROUTED4(ViewHostMsg_GPUPluginSetIOSurface,
+ gfx::PluginWindowHandle /* window */,
+ int32 /* width */,
+ int32 /* height */,
+ uint64 /* identifier for IOSurface */)
+
+ // This message notifies the browser process that the GPU plugin
+ // swapped the buffers associated with the given "window", which
+ // should cause the browser to redraw the various GPU plugins'
+ // contents.
+ IPC_MESSAGE_ROUTED1(ViewHostMsg_GPUPluginBuffersSwapped,
+ gfx::PluginWindowHandle /* window */)
#endif
// A renderer sends this to the browser process when it wants to create a
diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc
index 4b062e8..b019b1f 100644
--- a/chrome/plugin/command_buffer_stub.cc
+++ b/chrome/plugin/command_buffer_stub.cc
@@ -5,14 +5,17 @@
#include "base/process_util.h"
#include "base/shared_memory.h"
#include "chrome/common/command_buffer_messages.h"
+#include "chrome/common/plugin_messages.h"
#include "chrome/plugin/command_buffer_stub.h"
#include "chrome/plugin/plugin_channel.h"
using gpu::Buffer;
CommandBufferStub::CommandBufferStub(PluginChannel* channel,
+ int plugin_host_route_id,
gfx::PluginWindowHandle window)
: channel_(channel),
+ plugin_host_route_id_(plugin_host_route_id),
window_(window) {
route_id_ = channel->GenerateRouteID();
channel->AddRoute(route_id_, this, false);
@@ -58,6 +61,11 @@ void CommandBufferStub::OnInitialize(int32 size,
command_buffer_->SetPutOffsetChangeCallback(
NewCallback(processor_.get(),
&gpu::GPUProcessor::ProcessCommands));
+#if defined(OS_MACOSX)
+ processor_->SetSwapBuffersCallback(
+ NewCallback(this,
+ &CommandBufferStub::SwapBuffersCallback));
+#endif
buffer.shared_memory->ShareToProcess(peer_handle, ring_buffer);
} else {
processor_ = NULL;
@@ -108,6 +116,24 @@ void CommandBufferStub::OnGetTransferBuffer(
base::CloseProcessHandle(peer_handle);
}
+#if defined(OS_MACOSX)
+void CommandBufferStub::OnSetWindowSize(int32 width, int32 height) {
+ uint64 new_backing_store = processor_->SetWindowSize(width, height);
+ if (new_backing_store) {
+ Send(new PluginHostMsg_GPUPluginSetIOSurface(plugin_host_route_id_,
+ window_,
+ width,
+ height,
+ new_backing_store));
+ }
+}
+
+void CommandBufferStub::SwapBuffersCallback() {
+ Send(new PluginHostMsg_GPUPluginBuffersSwapped(plugin_host_route_id_,
+ window_));
+}
+#endif
+
void CommandBufferStub::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(CommandBufferStub, msg)
IPC_MESSAGE_HANDLER(CommandBufferMsg_Initialize, OnInitialize);
@@ -119,6 +145,9 @@ void CommandBufferStub::OnMessageReceived(const IPC::Message& msg) {
OnDestroyTransferBuffer);
IPC_MESSAGE_HANDLER(CommandBufferMsg_GetTransferBuffer,
OnGetTransferBuffer);
+#if defined(OS_MACOSX)
+ IPC_MESSAGE_HANDLER(CommandBufferMsg_SetWindowSize, OnSetWindowSize);
+#endif
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
}
diff --git a/chrome/plugin/command_buffer_stub.h b/chrome/plugin/command_buffer_stub.h
index 1001ce9..7759392 100644
--- a/chrome/plugin/command_buffer_stub.h
+++ b/chrome/plugin/command_buffer_stub.h
@@ -22,7 +22,9 @@ class CommandBufferService;
class CommandBufferStub : public IPC::Channel::Listener,
public IPC::Message::Sender {
public:
- CommandBufferStub(PluginChannel* channel, gfx::PluginWindowHandle window);
+ CommandBufferStub(PluginChannel* channel,
+ int plugin_host_route_id,
+ gfx::PluginWindowHandle window);
virtual ~CommandBufferStub();
@@ -45,8 +47,13 @@ class CommandBufferStub : public IPC::Channel::Listener,
void OnGetTransferBuffer(int32 id,
base::SharedMemoryHandle* transfer_buffer,
size_t* size);
+#if defined(OS_MACOSX)
+ void OnSetWindowSize(int32 width, int32 height);
+ void SwapBuffersCallback();
+#endif
scoped_refptr<PluginChannel> channel_;
+ int plugin_host_route_id_;
gfx::PluginWindowHandle window_;
int route_id_;
scoped_ptr<gpu::CommandBufferService> command_buffer_;
diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc
index cf6e842..80d6e62 100644
--- a/chrome/plugin/webplugin_delegate_stub.cc
+++ b/chrome/plugin/webplugin_delegate_stub.cc
@@ -139,6 +139,10 @@ void WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) {
OnHTTPRangeRequestReply)
IPC_MESSAGE_HANDLER(PluginMsg_CreateCommandBuffer,
OnCreateCommandBuffer)
+#if defined(OS_MACOSX)
+ IPC_MESSAGE_HANDLER(PluginMsg_SetFakeGPUPluginWindowHandle,
+ OnSetFakeGPUPluginWindowHandle)
+#endif
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
@@ -375,7 +379,8 @@ void WebPluginDelegateStub::OnInstallMissingPlugin() {
void WebPluginDelegateStub::OnCreateCommandBuffer(int* route_id) {
#if defined(ENABLE_GPU)
command_buffer_stub_.reset(new CommandBufferStub(
- static_cast<PluginChannel*>(PluginChannelBase::GetCurrentChannel()),
+ channel_,
+ instance_id_,
delegate_->windowed_handle()));
*route_id = command_buffer_stub_->route_id();
@@ -428,3 +433,11 @@ void WebPluginDelegateStub::OnHTTPRangeRequestReply(
delegate_->CreateSeekableResourceClient(resource_id, range_request_id);
webplugin_->OnResourceCreated(resource_id, resource_client);
}
+
+#if defined(OS_MACOSX)
+void WebPluginDelegateStub::OnSetFakeGPUPluginWindowHandle(
+ gfx::PluginWindowHandle window) {
+ delegate_->set_windowed_handle(window);
+}
+#endif
+
diff --git a/chrome/plugin/webplugin_delegate_stub.h b/chrome/plugin/webplugin_delegate_stub.h
index b783832..5a04758 100644
--- a/chrome/plugin/webplugin_delegate_stub.h
+++ b/chrome/plugin/webplugin_delegate_stub.h
@@ -115,6 +115,14 @@ class WebPluginDelegateStub : public IPC::Channel::Listener,
// If this is the GPU plugin, the stub object that forwards to the
// command buffer service.
scoped_ptr<CommandBufferStub> command_buffer_stub_;
+
+#if defined(OS_MACOSX)
+ // If this is the GPU plugin, we need to be receive a fake window
+ // handle which is used for subsequent communication back to the
+ // browser.
+ void OnSetFakeGPUPluginWindowHandle(gfx::PluginWindowHandle window);
+#endif
+
#endif
DISALLOW_IMPLICIT_CONSTRUCTORS(WebPluginDelegateStub);
diff --git a/chrome/renderer/command_buffer_proxy.cc b/chrome/renderer/command_buffer_proxy.cc
index 2b08090..9c337c9 100644
--- a/chrome/renderer/command_buffer_proxy.cc
+++ b/chrome/renderer/command_buffer_proxy.cc
@@ -169,3 +169,10 @@ void CommandBufferProxy::SetParseError(
// Not implemented in proxy.
NOTREACHED();
}
+
+#if defined(OS_MACOSX)
+void CommandBufferProxy::SetWindowSize(int32 width, int32 height) {
+ Send(new CommandBufferMsg_SetWindowSize(route_id_, width, height));
+}
+#endif
+
diff --git a/chrome/renderer/command_buffer_proxy.h b/chrome/renderer/command_buffer_proxy.h
index 077b0c5..b7bed4e 100644
--- a/chrome/renderer/command_buffer_proxy.h
+++ b/chrome/renderer/command_buffer_proxy.h
@@ -44,6 +44,10 @@ class CommandBufferProxy : public gpu::CommandBuffer,
virtual void SetToken(int32 token);
virtual void SetParseError(gpu::error::Error error);
+#if defined(OS_MACOSX)
+ virtual void SetWindowSize(int32 width, int32 height);
+#endif
+
private:
// As with the service, the client takes ownership of the ring buffer.
int32 size_;
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 0594162..96b38c9 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -4234,3 +4234,30 @@ bool RenderView::SendAndRunNestedMessageLoop(IPC::SyncMessage* message) {
return rv;
}
+
+#if defined(OS_MACOSX)
+gfx::PluginWindowHandle RenderView::AllocateFakePluginWindowHandle() {
+ gfx::PluginWindowHandle window = NULL;
+ Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
+ routing_id(), &window));
+ return window;
+}
+
+void RenderView::DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window) {
+ if (window)
+ Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(), window));
+}
+
+void RenderView::GPUPluginSetIOSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier) {
+ Send(new ViewHostMsg_GPUPluginSetIOSurface(
+ routing_id(), window, width, height, io_surface_identifier));
+}
+
+void RenderView::GPUPluginBuffersSwapped(gfx::PluginWindowHandle window) {
+ Send(new ViewHostMsg_GPUPluginBuffersSwapped(routing_id(), window));
+}
+#endif
+
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 7545654..1bb7c97 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -469,6 +469,18 @@ class RenderView : public RenderWidget,
// 'zh-TW' for Traditional Chinse.
std::string DetectLanguage();
+#if defined(OS_MACOSX)
+ // Helper routines for GPU plugin support. Used by the
+ // WebPluginDelegateProxy, which has a pointer to the RenderView.
+ gfx::PluginWindowHandle AllocateFakePluginWindowHandle();
+ void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
+ void GPUPluginSetIOSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier);
+ void GPUPluginBuffersSwapped(gfx::PluginWindowHandle window);
+#endif
+
protected:
// RenderWidget overrides:
virtual void Close();
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc
index 4a17fc8..4c02715 100644
--- a/chrome/renderer/webplugin_delegate_pepper.cc
+++ b/chrome/renderer/webplugin_delegate_pepper.cc
@@ -152,6 +152,18 @@ void WebPluginDelegatePepper::UpdateGeometry(
if (nested_delegate_)
nested_delegate_->UpdateGeometry(window_rect, clip_rect);
+#if defined(ENABLE_GPU)
+#if defined(OS_MACOSX)
+ // Send the new window size to the command buffer service code so it
+ // can allocate a new backing store. The handle to the new backing
+ // store is sent back to the browser asynchronously.
+ if (command_buffer_.get()) {
+ command_buffer_->SetWindowSize(window_rect_.width(),
+ window_rect_.height());
+ }
+#endif // OS_MACOSX
+#endif // ENABLE_GPU
+
if (!instance())
return;
@@ -350,6 +362,10 @@ NPError WebPluginDelegatePepper::Device3DInitializeContext(
// Ensure the service knows the window size before rendering anything.
nested_delegate_->UpdateGeometry(window_rect_, clip_rect_);
+#if defined(OS_MACOSX)
+ command_buffer_->SetWindowSize(window_rect_.width(),
+ window_rect_.height());
+#endif // OS_MACOSX
// Save the implementation information (the CommandBuffer).
Device3DImpl* impl = new Device3DImpl;
impl->command_buffer = command_buffer_.get();
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index b71798e..7059890 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -386,6 +386,11 @@ void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(PluginHostMsg_UpdateGeometry_ACK,
OnUpdateGeometry_ACK)
+ // Used only on 10.6 and later
+ IPC_MESSAGE_HANDLER(PluginHostMsg_GPUPluginSetIOSurface,
+ OnGPUPluginSetIOSurface)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_GPUPluginBuffersSwapped,
+ OnGPUPluginBuffersSwapped)
#endif
IPC_MESSAGE_UNHANDLED_ERROR()
@@ -891,6 +896,14 @@ void WebPluginDelegateProxy::OnSetWindow(gfx::PluginWindowHandle window) {
void WebPluginDelegateProxy::WillDestroyWindow() {
DCHECK(window_);
plugin_->WillDestroyWindow(window_);
+#if defined(OS_MACOSX)
+ if (window_) {
+ // This is actually a "fake" window handle only for the GPU
+ // plugin. Deallocate it on the browser side.
+ if (render_view_)
+ render_view_->DestroyFakePluginWindowHandle(window_);
+ }
+#endif
window_ = gfx::kNullPluginWindow;
}
@@ -1199,6 +1212,23 @@ WebPluginDelegateProxy::CreateSeekableResourceClient(
CommandBufferProxy* WebPluginDelegateProxy::CreateCommandBuffer() {
#if defined(ENABLE_GPU)
+#if defined(OS_MACOSX)
+ // We need to synthesize a fake window handle for this nested
+ // delegate to identify the instance of the GPU plugin back to the
+ // browser.
+ gfx::PluginWindowHandle fake_window = NULL;
+ if (render_view_)
+ fake_window = render_view_->AllocateFakePluginWindowHandle();
+ // If we aren't running on 10.6, this allocation will fail.
+ if (!fake_window)
+ return NULL;
+ OnSetWindow(fake_window);
+ if (!Send(new PluginMsg_SetFakeGPUPluginWindowHandle(instance_id_,
+ fake_window))) {
+ return NULL;
+ }
+#endif
+
int command_buffer_id;
if (!Send(new PluginMsg_CreateCommandBuffer(instance_id_,
&command_buffer_id))) {
@@ -1247,4 +1277,20 @@ void WebPluginDelegateProxy::OnUpdateGeometry_ACK(int ack_key) {
old_transport_dibs_.erase(iterator);
}
+
+void WebPluginDelegateProxy::OnGPUPluginSetIOSurface(
+ gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier) {
+ if (render_view_)
+ render_view_->GPUPluginSetIOSurface(window, width, height,
+ io_surface_identifier);
+}
+
+void WebPluginDelegateProxy::OnGPUPluginBuffersSwapped(
+ gfx::PluginWindowHandle window) {
+ if (render_view_)
+ render_view_->GPUPluginBuffersSwapped(window);
+}
#endif
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index 6a71bdb..a56da38 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -145,6 +145,11 @@ class WebPluginDelegateProxy
#if defined(OS_MACOSX)
void OnUpdateGeometry_ACK(int ack_key);
+ void OnGPUPluginSetIOSurface(gfx::PluginWindowHandle window,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier);
+ void OnGPUPluginBuffersSwapped(gfx::PluginWindowHandle window);
#endif
// Draw a graphic indicating a crashed plugin.