diff options
Diffstat (limited to 'chrome')
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. |