diff options
-rw-r--r-- | chrome/chrome.gyp | 2 | ||||
-rw-r--r-- | chrome/plugin/webplugin_accelerated_surface_proxy_mac.cc | 61 | ||||
-rw-r--r-- | chrome/plugin/webplugin_accelerated_surface_proxy_mac.h | 39 | ||||
-rw-r--r-- | chrome/plugin/webplugin_proxy.cc | 44 | ||||
-rw-r--r-- | chrome/plugin/webplugin_proxy.h | 32 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_host.cc | 21 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin.h | 17 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_accelerated_surface_mac.h | 43 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 10 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 37 | ||||
-rw-r--r-- | webkit/glue/webkit_glue.gypi | 1 |
11 files changed, 250 insertions, 57 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 8624a7b..ca49e30 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -619,6 +619,8 @@ 'plugin/plugin_main_mac.mm', 'plugin/plugin_thread.cc', 'plugin/plugin_thread.h', + 'plugin/webplugin_accelerated_surface_proxy_mac.cc', + 'plugin/webplugin_accelerated_surface_proxy_mac.h', 'plugin/webplugin_delegate_stub.cc', 'plugin/webplugin_delegate_stub.h', 'plugin/webplugin_proxy.cc', diff --git a/chrome/plugin/webplugin_accelerated_surface_proxy_mac.cc b/chrome/plugin/webplugin_accelerated_surface_proxy_mac.cc new file mode 100644 index 0000000..551d711 --- /dev/null +++ b/chrome/plugin/webplugin_accelerated_surface_proxy_mac.cc @@ -0,0 +1,61 @@ +// 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. + +#import <OpenGL/OpenGL.h> + +#include "chrome/plugin/webplugin_accelerated_surface_proxy_mac.h" + +#include "app/surface/accelerated_surface_mac.h" +#include "app/surface/transport_dib.h" +#include "chrome/plugin/webplugin_proxy.h" + +WebPluginAcceleratedSurfaceProxy::WebPluginAcceleratedSurfaceProxy( + WebPluginProxy* plugin_proxy) : plugin_proxy_(plugin_proxy) { + surface_ = new AcceleratedSurface; + surface_->Initialize(NULL, true); + + // Only used for 10.5 support, but harmless on 10.6+. + surface_->SetTransportDIBAllocAndFree( + NewCallback(plugin_proxy_, &WebPluginProxy::AllocSurfaceDIB), + NewCallback(plugin_proxy_, &WebPluginProxy::FreeSurfaceDIB)); +} + +WebPluginAcceleratedSurfaceProxy::~WebPluginAcceleratedSurfaceProxy() { + if (surface_) { + surface_->Destroy(); + delete surface_; + surface_ = NULL; + } +} + +void WebPluginAcceleratedSurfaceProxy::SetWindowHandle( + gfx::PluginWindowHandle window) { + window_handle_ = window; +} + +void WebPluginAcceleratedSurfaceProxy::SetSize(const gfx::Size& size) { + uint64 io_surface_id = surface_->SetSurfaceSize(size); + if (io_surface_id) { + plugin_proxy_->SetAcceleratedSurface(window_handle_, size, io_surface_id); + } else { + TransportDIB::Handle transport_dib = surface_->SetTransportDIBSize(size); + if (TransportDIB::is_valid(transport_dib)) { + plugin_proxy_->SetAcceleratedDIB(window_handle_, size, transport_dib); + } + } +} + +CGLContextObj WebPluginAcceleratedSurfaceProxy::context() { + return surface_->context(); +} + +void WebPluginAcceleratedSurfaceProxy::StartDrawing() { + surface_->MakeCurrent(); + surface_->Clear(gfx::Rect(surface_->GetSize())); +} + +void WebPluginAcceleratedSurfaceProxy::EndDrawing() { + surface_->SwapBuffers(); + plugin_proxy_->AcceleratedFrameBuffersDidSwap(window_handle_); +} diff --git a/chrome/plugin/webplugin_accelerated_surface_proxy_mac.h b/chrome/plugin/webplugin_accelerated_surface_proxy_mac.h new file mode 100644 index 0000000..8764ab9 --- /dev/null +++ b/chrome/plugin/webplugin_accelerated_surface_proxy_mac.h @@ -0,0 +1,39 @@ +// 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_PLUGIN_WEBPLUGIN_ACCELERATED_SURFACE_PROXY_H_ +#define CHROME_PLUGIN_WEBPLUGIN_ACCELERATED_SURFACE_PROXY_H_ +#pragma once + +#include "webkit/glue/plugins/webplugin_accelerated_surface_mac.h" + +class WebPluginProxy; +class AcceleratedSurface; + +// Out-of-process implementation of WebPluginAcceleratedSurface that proxies +// calls through a WebPluginProxy. +class WebPluginAcceleratedSurfaceProxy + : public webkit_glue::WebPluginAcceleratedSurface { + public: + // Creates a new WebPluginAcceleratedSurfaceProxy that uses plugin_proxy + // to proxy calls. plugin_proxy must outlive this object. + WebPluginAcceleratedSurfaceProxy(WebPluginProxy* plugin_proxy); + virtual ~WebPluginAcceleratedSurfaceProxy(); + + // WebPluginAcceleratedSurface implementation. + virtual void SetWindowHandle(gfx::PluginWindowHandle window); + virtual void SetSize(const gfx::Size& size); + virtual CGLContextObj context(); + virtual void StartDrawing(); + virtual void EndDrawing(); + + private: + WebPluginProxy* plugin_proxy_; // Weak ref. + gfx::PluginWindowHandle window_handle_; + AcceleratedSurface* surface_; + + DISALLOW_COPY_AND_ASSIGN(WebPluginAcceleratedSurfaceProxy); +}; + +#endif // CHROME_PLUGIN_WEBPLUGIN_ACCELERATED_SURFACE_PROXY_H_ diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index 5441dc8..5ec1b43 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -23,6 +23,9 @@ #include "chrome/plugin/npobject_util.h" #include "chrome/plugin/plugin_channel.h" #include "chrome/plugin/plugin_thread.h" +#if defined(OS_MACOSX) +#include "chrome/plugin/webplugin_accelerated_surface_proxy_mac.h" +#endif #include "gfx/blit.h" #include "gfx/canvas.h" #if defined(OS_WIN) @@ -38,6 +41,9 @@ using WebKit::WebBindings; using webkit_glue::WebPluginResourceClient; +#if defined(OS_MACOSX) +using webkit_glue::WebPluginAcceleratedSurface; +#endif typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap; static ContextMap& GetContextMap() { @@ -92,6 +98,12 @@ WebPluginProxy::~WebPluginProxy() { if (windowless_shm_pixmap_ != None) XFreePixmap(x11_util::GetXDisplay(), windowless_shm_pixmap_); #endif + +#if defined(OS_MACOSX) + // Destroy the surface early, since it may send messages during cleanup. + if (accelerated_surface_.get()) + accelerated_surface_.reset(); +#endif } bool WebPluginProxy::Send(IPC::Message* msg) { @@ -640,17 +652,41 @@ void WebPluginProxy::BindFakePluginWindowHandle(bool opaque) { Send(new PluginHostMsg_BindFakePluginWindowHandle(route_id_, opaque)); } +WebPluginAcceleratedSurface* WebPluginProxy::GetAcceleratedSurface() { + if (!accelerated_surface_.get()) + accelerated_surface_.reset(new WebPluginAcceleratedSurfaceProxy(this)); + return accelerated_surface_.get(); +} + void WebPluginProxy::AcceleratedFrameBuffersDidSwap( gfx::PluginWindowHandle window) { Send(new PluginHostMsg_AcceleratedSurfaceBuffersSwapped(route_id_, window)); } -void WebPluginProxy::SetAcceleratedSurface(gfx::PluginWindowHandle window, - int32 width, - int32 height, +void WebPluginProxy::SetAcceleratedSurface( + gfx::PluginWindowHandle window, + const gfx::Size& size, uint64 accelerated_surface_identifier) { Send(new PluginHostMsg_AcceleratedSurfaceSetIOSurface( - route_id_, window, width, height, accelerated_surface_identifier)); + route_id_, window, size.width(), size.height(), + accelerated_surface_identifier)); +} + +void WebPluginProxy::SetAcceleratedDIB( + gfx::PluginWindowHandle window, + const gfx::Size& size, + const TransportDIB::Handle& dib_handle) { + Send(new PluginHostMsg_AcceleratedSurfaceSetTransportDIB( + route_id_, window, size.width(), size.height(), dib_handle)); +} + +void WebPluginProxy::AllocSurfaceDIB(const size_t size, + TransportDIB::Handle* dib_handle) { + Send(new PluginHostMsg_AllocTransportDIB(route_id_, size, dib_handle)); +} + +void WebPluginProxy::FreeSurfaceDIB(TransportDIB::Id dib_id) { + Send(new PluginHostMsg_FreeTransportDIB(route_id_, dib_id)); } #endif diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h index b390261..2134bf3 100644 --- a/chrome/plugin/webplugin_proxy.h +++ b/chrome/plugin/webplugin_proxy.h @@ -28,6 +28,9 @@ class PluginChannel; class WebPluginDelegateImpl; +#if defined(OS_MACOSX) +class WebPluginAcceleratedSurfaceProxy; +#endif // This is an implementation of WebPlugin that proxies all calls to the // renderer. @@ -139,11 +142,35 @@ class WebPluginProxy : public webkit_glue::WebPlugin { #if defined(OS_MACOSX) virtual void BindFakePluginWindowHandle(bool opaque); + + virtual webkit_glue::WebPluginAcceleratedSurface* GetAcceleratedSurface(); + + // Tell the browser (via the renderer) to invalidate because the + // accelerated buffers have changed. virtual void AcceleratedFrameBuffersDidSwap(gfx::PluginWindowHandle window); + + // Tell the renderer and browser to associate the given plugin handle with + // |accelerated_surface_identifier|. The geometry is used to resize any + // native "window" (which on the Mac is a just a view). + // This method is used when IOSurface support is available. virtual void SetAcceleratedSurface(gfx::PluginWindowHandle window, - int32 width, - int32 height, + const gfx::Size& size, uint64 accelerated_surface_identifier); + + // Tell the renderer and browser to associate the given plugin handle with + // |dib_handle|. The geometry is used to resize any native "window" (which + // on the Mac is just a view). + // This method is used when IOSurface support is not available. + virtual void SetAcceleratedDIB( + gfx::PluginWindowHandle window, + const gfx::Size& size, + const TransportDIB::Handle& dib_handle); + + // Create/destroy TranportDIBs via messages to the browser process. + // These are only used when IOSurface support is not available. + virtual void AllocSurfaceDIB(const size_t size, + TransportDIB::Handle* dib_handle); + virtual void FreeSurfaceDIB(TransportDIB::Id dib_id); #endif private: @@ -181,6 +208,7 @@ class WebPluginProxy : public webkit_glue::WebPlugin { scoped_ptr<TransportDIB> background_dib_; scoped_cftyperef<CGContextRef> windowless_context_; scoped_cftyperef<CGContextRef> background_context_; + scoped_ptr<WebPluginAcceleratedSurfaceProxy> accelerated_surface_; #else scoped_ptr<skia::PlatformCanvas> windowless_canvas_; scoped_ptr<skia::PlatformCanvas> background_canvas_; diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index a1a6d5f..b0fe8fa 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -797,16 +797,21 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { rv = NPERR_NO_ERROR; break; } - case NPNVsupportsCoreAnimationBool: - case NPNVsupportsInvalidatingCoreAnimationBool: { + case NPNVsupportsCoreAnimationBool: { // We only support the Core Animation model on 10.6 and higher // TODO(stuartmorgan): Once existing CA plugins have implemented the - // invalidating version, remove support for the other version. + // invalidating version, remove support for this one. NPBool* supports_model = reinterpret_cast<NPBool*>(value); *supports_model = SupportsSharingAcceleratedSurfaces() ? true : false; rv = NPERR_NO_ERROR; break; } + case NPNVsupportsInvalidatingCoreAnimationBool: { + NPBool* supports_model = reinterpret_cast<NPBool*>(value); + *supports_model = true; + rv = NPERR_NO_ERROR; + break; + } case NPNVsupportsOpenGLBool: { // This drawing model was never widely supported, and we don't plan to // support it. @@ -871,12 +876,10 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { #if defined(OS_MACOSX) case NPPVpluginDrawingModel: { int model = reinterpret_cast<int>(value); - if (model == NPDrawingModelCoreGraphics) { - plugin->set_drawing_model(static_cast<NPDrawingModel>(model)); - return NPERR_NO_ERROR; - } else if ((model == NPDrawingModelCoreAnimation || - model == NPDrawingModelInvalidatingCoreAnimation) && - SupportsSharingAcceleratedSurfaces()) { + if (model == NPDrawingModelCoreGraphics || + model == NPDrawingModelInvalidatingCoreAnimation || + (model == NPDrawingModelCoreAnimation && + SupportsSharingAcceleratedSurfaces())) { plugin->set_drawing_model(static_cast<NPDrawingModel>(model)); return NPERR_NO_ERROR; } diff --git a/webkit/glue/plugins/webplugin.h b/webkit/glue/plugins/webplugin.h index 19c6cb0..1a14d545 100644 --- a/webkit/glue/plugins/webplugin.h +++ b/webkit/glue/plugins/webplugin.h @@ -29,6 +29,9 @@ namespace webkit_glue { class WebPluginDelegate; class WebPluginParentView; class WebPluginResourceClient; +#if defined(OS_MACOSX) +class WebPluginAcceleratedSurface; +#endif // Describes the new location for a plugin window. struct WebPluginGeometry { @@ -151,19 +154,11 @@ class WebPlugin { // of plug-in content. The browser generates the handle which is then set on // the plug-in. |opaque| indicates whether the content should be treated as // opaque or translucent. + // TODO(stuartmorgan): Move this into WebPluginProxy. virtual void BindFakePluginWindowHandle(bool opaque) {} - // Tell the browser (via the renderer) to invalidate because the - // accelerated buffers have changed. - virtual void AcceleratedFrameBuffersDidSwap(gfx::PluginWindowHandle window) {} - - // Tell the renderer and browser to associate the given plugin handle with - // |accelerated_surface_identifier|. The geometry is used to resize any - // native "window" (which on the Mac is a CALayer). - virtual void SetAcceleratedSurface(gfx::PluginWindowHandle window, - int32 width, - int32 height, - uint64 accelerated_surface_identifier) {} + // Returns the accelerated surface abstraction for accelerated plugins. + virtual WebPluginAcceleratedSurface* GetAcceleratedSurface() { return NULL; } #endif // Gets the WebPluginDelegate that implements the interface. diff --git a/webkit/glue/plugins/webplugin_accelerated_surface_mac.h b/webkit/glue/plugins/webplugin_accelerated_surface_mac.h new file mode 100644 index 0000000..ba3f8ca --- /dev/null +++ b/webkit/glue/plugins/webplugin_accelerated_surface_mac.h @@ -0,0 +1,43 @@ +// Copyright (c) 2006-2009 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 WEBKIT_GLUE_WEBPLUGIN_ACCELERATED_SURFACE_MAC_H_ +#define WEBKIT_GLUE_WEBPLUGIN_ACCELERATED_SURFACE_MAC_H_ +#pragma once + +#include "gfx/native_widget_types.h" +#include "gfx/size.h" + +// Avoid having to include OpenGL headers here. +typedef struct _CGLContextObject* CGLContextObj; + +namespace webkit_glue { + +// Interface class for interacting with an accelerated plugin surface, used +// for the Core Animation flavors of plugin drawing on the Mac. +class WebPluginAcceleratedSurface { + public: + virtual ~WebPluginAcceleratedSurface() {} + + // Sets the window handle used throughout the browser to identify this + // surface. + virtual void SetWindowHandle(gfx::PluginWindowHandle window) = 0; + + // Sets the size of the surface. + virtual void SetSize(const gfx::Size& size) = 0; + + // Returns the context used to draw into this surface. + virtual CGLContextObj context() = 0; + + // Readies the surface for drawing. Must be called before any drawing session. + virtual void StartDrawing() = 0; + + // Ends a drawing session. Changes to the surface may not be reflected until + // this is called. + virtual void EndDrawing() = 0; +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_WEBPLUGIN_ACCELERATED_SURFACE_MAC_H_ diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 650d398..55381f9 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -11,6 +11,7 @@ #include <list> #include "base/ref_counted.h" +#include "base/scoped_ptr.h" #include "base/task.h" #include "base/time.h" #include "base/timer.h" @@ -20,10 +21,6 @@ #include "webkit/glue/plugins/webplugin_delegate.h" #include "webkit/glue/webcursor.h" -#if defined(OS_MACOSX) -#include "app/surface/accelerated_surface_mac.h" -#endif - #if defined(USE_X11) #include "app/x11_util.h" @@ -52,6 +49,9 @@ class QuickDrawDrawingManager; class CALayer; class CARenderer; #endif +namespace webkit_glue { +class WebPluginAcceleratedSurface; +} #endif // An implementation of WebPluginDelegate that runs in the plugin process, @@ -432,7 +432,7 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { #endif CALayer* layer_; // Used for CA drawing mode. Weak, retained by plug-in. - AcceleratedSurface* surface_; + webkit_glue::WebPluginAcceleratedSurface* surface_; // Weak ref. CARenderer* renderer_; // Renders layer_ to surface_. scoped_ptr<base::RepeatingTimer<WebPluginDelegateImpl> > redraw_timer_; diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index 614f1d2..e048eaf 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -24,6 +24,7 @@ #include "webkit/glue/plugins/plugin_stream_url.h" #include "webkit/glue/plugins/plugin_web_event_converter_mac.h" #include "webkit/glue/plugins/webplugin.h" +#include "webkit/glue/plugins/webplugin_accelerated_surface_mac.h" #include "webkit/glue/webkit_glue.h" #ifndef NP_NO_CARBON @@ -359,9 +360,9 @@ bool WebPluginDelegateImpl::PlatformInitialize() { if (instance()->event_model() != NPEventModelCocoa) return false; window_.type = NPWindowTypeDrawable; - // Ask the plug-in for the CALayer it created for rendering content. Have - // the renderer tell the browser to create a "windowed plugin" to host - // the IOSurface. + // Ask the plug-in for the CALayer it created for rendering content. + // Create a surface to host it, and request a "window" handle to identify + // the surface. CALayer* layer = nil; NPError err = instance()->NPP_GetValue(NPPVpluginCoreAnimationLayer, reinterpret_cast<void*>(&layer)); @@ -371,8 +372,8 @@ bool WebPluginDelegateImpl::PlatformInitialize() { redraw_timer_.reset(new base::RepeatingTimer<WebPluginDelegateImpl>); } layer_ = layer; - surface_ = new AcceleratedSurface; - surface_->Initialize(NULL, true); + surface_ = plugin_->GetAcceleratedSurface(); + renderer_ = [[CARenderer rendererWithCGLContext:surface_->context() options:NULL] retain]; [renderer_ setLayer:layer_]; @@ -421,11 +422,6 @@ void WebPluginDelegateImpl::PlatformDestroyInstance() { [renderer_ release]; renderer_ = nil; layer_ = nil; - if (surface_) { - surface_->Destroy(); - delete surface_; - surface_ = NULL; - } } void WebPluginDelegateImpl::UpdateGeometryAndContext( @@ -948,9 +944,7 @@ void WebPluginDelegateImpl::DrawLayerInSurface() { if (!windowed_handle()) return; - surface_->MakeCurrent(); - - surface_->Clear(window_rect_); + surface_->StartDrawing(); [renderer_ beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL]; if (CGRectIsEmpty([renderer_ updateBounds])) { @@ -963,13 +957,10 @@ void WebPluginDelegateImpl::DrawLayerInSurface() { [renderer_ render]; [renderer_ endFrame]; - surface_->SwapBuffers(); - plugin_->AcceleratedFrameBuffersDidSwap(windowed_handle()); + surface_->EndDrawing(); } -// Update the size of the IOSurface to match the current size of the plug-in, -// then tell the browser host view so it can adjust its bookkeeping and CALayer -// appropriately. +// Update the size of the surface to match the current size of the plug-in. void WebPluginDelegateImpl::UpdateAcceleratedSurface() { // Will only have a window handle when using a Core Animation drawing model. if (!windowed_handle() || !layer_) @@ -978,19 +969,13 @@ void WebPluginDelegateImpl::UpdateAcceleratedSurface() { [layer_ setFrame:CGRectMake(0, 0, window_rect_.width(), window_rect_.height())]; [renderer_ setBounds:[layer_ bounds]]; - - uint64 io_surface_id = surface_->SetSurfaceSize(window_rect_.size()); - if (io_surface_id) { - plugin_->SetAcceleratedSurface(windowed_handle(), - window_rect_.width(), - window_rect_.height(), - io_surface_id); - } + surface_->SetSize(window_rect_.size()); } void WebPluginDelegateImpl::set_windowed_handle( gfx::PluginWindowHandle handle) { windowed_handle_ = handle; + surface_->SetWindowHandle(handle); UpdateAcceleratedSurface(); // Kick off the drawing timer, if necessary. PluginVisibilityChanged(); diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index f5d03c4..80e53c8 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -288,6 +288,7 @@ 'plugins/webplugin.h', 'plugins/webplugin_2d_device_delegate.h', 'plugins/webplugin_3d_device_delegate.h', + 'plugins/webplugin_accelerated_surface_mac.h', 'plugins/webplugin_delegate.h', 'plugins/webplugin_delegate_impl.cc', 'plugins/webplugin_delegate_impl.h', |