diff options
Diffstat (limited to 'chrome/browser')
7 files changed, 241 insertions, 0 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) |