diff options
20 files changed, 333 insertions, 79 deletions
diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc index f155279..e31d161 100644 --- a/content/browser/plugin_process_host.cc +++ b/content/browser/plugin_process_host.cc @@ -201,6 +201,9 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info, // any associated values) if present in the browser command line static const char* const kSwitchNames[] = { switches::kDisableBreakpad, +#if defined(OS_MACOSX) + switches::kDisableCompositedCoreAnimationPlugins, +#endif switches::kDisableLogging, switches::kEnableDCHECK, switches::kEnableLogging, diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 3950f0a..3dca1b3 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -655,6 +655,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kDisableApplicationCache, switches::kDisableAudio, switches::kDisableBreakpad, +#if defined(OS_MACOSX) + switches::kDisableCompositedCoreAnimationPlugins, +#endif switches::kDisableDataTransferItems, switches::kDisableDatabases, switches::kDisableDesktopNotifications, diff --git a/content/common/plugin_messages.h b/content/common/plugin_messages.h index d5f073c..8ede47c 100644 --- a/content/common/plugin_messages.h +++ b/content/common/plugin_messages.h @@ -382,6 +382,9 @@ IPC_MESSAGE_ROUTED1(PluginHostMsg_FocusChanged, IPC_MESSAGE_ROUTED0(PluginHostMsg_StartIme) +//---------------------------------------------------------------------- +// Legacy Core Animation plugin implementation rendering directly to screen. + // This message, used in Mac OS X 10.5 and earlier, is sent from the plug-in // process to the renderer process to indicate that the plug-in allocated a // new TransportDIB that holds the GPU's rendered image. This information is @@ -435,6 +438,29 @@ IPC_MESSAGE_ROUTED1(PluginHostMsg_FreeTransportDIB, IPC_MESSAGE_ROUTED2(PluginHostMsg_AcceleratedSurfaceBuffersSwapped, gfx::PluginWindowHandle /* window */, uint64 /* surface_id */) + +//---------------------------------------------------------------------- +// New Core Animation plugin implementation rendering via compositor. + +// Notifies the renderer process that this plugin will be using the +// accelerated rendering path. +IPC_MESSAGE_ROUTED0(PluginHostMsg_AcceleratedPluginEnabledRendering) + +// Notifies the renderer process that the plugin allocated a new +// IOSurface into which it is rendering. The renderer process forwards +// this IOSurface to the GPU process, causing it to be bound to a +// texture from which the compositor can render. Any previous +// IOSurface allocated by this plugin must be implicitly released by +// the receipt of this message. +IPC_MESSAGE_ROUTED3(PluginHostMsg_AcceleratedPluginAllocatedIOSurface, + int32 /* width */, + int32 /* height */, + uint32 /* surface_id */) + +// Notifies the renderer process that the plugin produced a new frame +// of content into its IOSurface, and therefore that the compositor +// needs to redraw. +IPC_MESSAGE_ROUTED0(PluginHostMsg_AcceleratedPluginSwappedIOSurface) #endif IPC_MESSAGE_CONTROL1(PluginHostMsg_ClearSiteDataResult, diff --git a/content/plugin/webplugin_accelerated_surface_proxy_mac.cc b/content/plugin/webplugin_accelerated_surface_proxy_mac.cc index 9573a27..65749f0 100644 --- a/content/plugin/webplugin_accelerated_surface_proxy_mac.cc +++ b/content/plugin/webplugin_accelerated_surface_proxy_mac.cc @@ -7,30 +7,53 @@ #include "content/plugin/webplugin_accelerated_surface_proxy_mac.h" #include "base/bind.h" +#include "base/command_line.h" #include "content/plugin/webplugin_proxy.h" +#include "ui/base/ui_base_switches.h" #include "ui/gfx/surface/accelerated_surface_mac.h" +#include "ui/gfx/surface/io_surface_support_mac.h" #include "ui/gfx/surface/transport_dib.h" -WebPluginAcceleratedSurfaceProxy::WebPluginAcceleratedSurfaceProxy( +WebPluginAcceleratedSurfaceProxy* WebPluginAcceleratedSurfaceProxy::Create( WebPluginProxy* plugin_proxy, - gfx::GpuPreference gpu_preference) - : plugin_proxy_(plugin_proxy), - window_handle_(NULL) { - surface_ = new AcceleratedSurface; - // It's possible for OpenGL to fail to initialze (e.g., if an incompatible + gfx::GpuPreference gpu_preference) { + bool composited = !CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableCompositedCoreAnimationPlugins); + + // Require IOSurface support for drawing Core Animation plugins. + if (composited && !IOSurfaceSupport::Initialize()) + return NULL; + + AcceleratedSurface* surface = new AcceleratedSurface; + // It's possible for OpenGL to fail to initialize (e.g., if an incompatible // mode is forced via flags), so handle that gracefully. - if (!surface_->Initialize(NULL, true, gpu_preference)) { - delete surface_; - surface_ = NULL; - return; + if (!surface->Initialize(NULL, true, gpu_preference)) { + delete surface; + surface = NULL; + if (composited) + return NULL; + } + + if (!composited && surface) { + // Only used for 10.5 support, but harmless on 10.6+. + surface->SetTransportDIBAllocAndFree( + base::Bind(&WebPluginProxy::AllocSurfaceDIB, + base::Unretained(plugin_proxy)), + base::Bind(&WebPluginProxy::FreeSurfaceDIB, + base::Unretained(plugin_proxy))); } - // Only used for 10.5 support, but harmless on 10.6+. - surface_->SetTransportDIBAllocAndFree( - base::Bind(&WebPluginProxy::AllocSurfaceDIB, - base::Unretained(plugin_proxy)), - base::Bind(&WebPluginProxy::FreeSurfaceDIB, - base::Unretained(plugin_proxy))); + return new WebPluginAcceleratedSurfaceProxy( + plugin_proxy, surface, composited); +} + +WebPluginAcceleratedSurfaceProxy::WebPluginAcceleratedSurfaceProxy( + WebPluginProxy* plugin_proxy, + AcceleratedSurface* surface, + bool composited) + : plugin_proxy_(plugin_proxy), + surface_(surface), + composited_(composited) { } WebPluginAcceleratedSurfaceProxy::~WebPluginAcceleratedSurfaceProxy() { @@ -46,17 +69,28 @@ void WebPluginAcceleratedSurfaceProxy::SetWindowHandle( window_handle_ = window; } +bool WebPluginAcceleratedSurfaceProxy::IsComposited() { + return composited_; +} + void WebPluginAcceleratedSurfaceProxy::SetSize(const gfx::Size& size) { if (!surface_) return; - uint64 io_surface_id = surface_->SetSurfaceSize(size); - if (io_surface_id) { - plugin_proxy_->SetAcceleratedSurface(window_handle_, size, io_surface_id); + if (composited_) { + uint32 io_surface_id = surface_->SetSurfaceSize(size); + // If allocation fails for some reason, still inform the plugin proxy. + plugin_proxy_->AcceleratedPluginAllocatedIOSurface( + size.width(), size.height(), io_surface_id); } else { - TransportDIB::Handle transport_dib = surface_->SetTransportDIBSize(size); - if (TransportDIB::is_valid_handle(transport_dib)) { - plugin_proxy_->SetAcceleratedDIB(window_handle_, size, transport_dib); + uint32 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_handle(transport_dib)) { + plugin_proxy_->SetAcceleratedDIB(window_handle_, size, transport_dib); + } } } } @@ -78,6 +112,10 @@ void WebPluginAcceleratedSurfaceProxy::EndDrawing() { return; surface_->SwapBuffers(); - plugin_proxy_->AcceleratedFrameBuffersDidSwap( - window_handle_, surface_->GetSurfaceId()); + if (composited_) { + plugin_proxy_->AcceleratedPluginSwappedIOSurface(); + } else { + plugin_proxy_->AcceleratedFrameBuffersDidSwap( + window_handle_, surface_->GetSurfaceId()); + } } diff --git a/content/plugin/webplugin_accelerated_surface_proxy_mac.h b/content/plugin/webplugin_accelerated_surface_proxy_mac.h index f0290ba..6abf39f 100644 --- a/content/plugin/webplugin_accelerated_surface_proxy_mac.h +++ b/content/plugin/webplugin_accelerated_surface_proxy_mac.h @@ -19,22 +19,31 @@ class WebPluginAcceleratedSurfaceProxy : public webkit::npapi::WebPluginAcceleratedSurface { public: // Creates a new WebPluginAcceleratedSurfaceProxy that uses plugin_proxy - // to proxy calls. plugin_proxy must outlive this object. - WebPluginAcceleratedSurfaceProxy(WebPluginProxy* plugin_proxy, - gfx::GpuPreference gpu_preference); + // to proxy calls. plugin_proxy must outlive this object. Returns NULL if + // initialization fails. + static WebPluginAcceleratedSurfaceProxy* Create( + WebPluginProxy* plugin_proxy, + gfx::GpuPreference gpu_preference); + virtual ~WebPluginAcceleratedSurfaceProxy(); // WebPluginAcceleratedSurface implementation. virtual void SetWindowHandle(gfx::PluginWindowHandle window) OVERRIDE; + virtual bool IsComposited() OVERRIDE; virtual void SetSize(const gfx::Size& size) OVERRIDE; virtual CGLContextObj context() OVERRIDE; virtual void StartDrawing() OVERRIDE; virtual void EndDrawing() OVERRIDE; private: + WebPluginAcceleratedSurfaceProxy(WebPluginProxy* plugin_proxy, + AcceleratedSurface* surface, + bool composited); + WebPluginProxy* plugin_proxy_; // Weak ref. gfx::PluginWindowHandle window_handle_; AcceleratedSurface* surface_; + bool composited_; DISALLOW_COPY_AND_ASSIGN(WebPluginAcceleratedSurfaceProxy); }; diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc index bd4a36d..5b0ac6d 100644 --- a/content/plugin/webplugin_proxy.cc +++ b/content/plugin/webplugin_proxy.cc @@ -674,8 +674,8 @@ void WebPluginProxy::BindFakePluginWindowHandle(bool opaque) { WebPluginAcceleratedSurface* WebPluginProxy::GetAcceleratedSurface( gfx::GpuPreference gpu_preference) { if (!accelerated_surface_.get()) - accelerated_surface_.reset(new WebPluginAcceleratedSurfaceProxy( - this, gpu_preference)); + accelerated_surface_.reset( + WebPluginAcceleratedSurfaceProxy::Create(this, gpu_preference)); return accelerated_surface_.get(); } @@ -710,6 +710,22 @@ void WebPluginProxy::AllocSurfaceDIB(const size_t size, void WebPluginProxy::FreeSurfaceDIB(TransportDIB::Id dib_id) { Send(new PluginHostMsg_FreeTransportDIB(route_id_, dib_id)); } + +void WebPluginProxy::AcceleratedPluginEnabledRendering() { + Send(new PluginHostMsg_AcceleratedPluginEnabledRendering(route_id_)); +} + +void WebPluginProxy::AcceleratedPluginAllocatedIOSurface(int32 width, + int32 height, + uint32 surface_id) { + Send(new PluginHostMsg_AcceleratedPluginAllocatedIOSurface( + route_id_, width, height, surface_id)); +} + +void WebPluginProxy::AcceleratedPluginSwappedIOSurface() { + Send(new PluginHostMsg_AcceleratedPluginSwappedIOSurface( + route_id_)); +} #endif void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { diff --git a/content/plugin/webplugin_proxy.h b/content/plugin/webplugin_proxy.h index ddd32fa..2c44c94 100644 --- a/content/plugin/webplugin_proxy.h +++ b/content/plugin/webplugin_proxy.h @@ -136,11 +136,14 @@ class WebPluginProxy : public webkit::npapi::WebPlugin { virtual void StartIme() OVERRIDE; - virtual void BindFakePluginWindowHandle(bool opaque) OVERRIDE; - virtual webkit::npapi::WebPluginAcceleratedSurface* GetAcceleratedSurface(gfx::GpuPreference gpu_preference) OVERRIDE; + //---------------------------------------------------------------------- + // Legacy Core Animation plugin implementation rendering directly to screen. + + virtual void BindFakePluginWindowHandle(bool opaque) OVERRIDE; + // Tell the browser (via the renderer) to invalidate because the // accelerated buffers have changed. virtual void AcceleratedFrameBuffersDidSwap( @@ -168,6 +171,20 @@ class WebPluginProxy : public webkit::npapi::WebPlugin { virtual void AllocSurfaceDIB(const size_t size, TransportDIB::Handle* dib_handle); virtual void FreeSurfaceDIB(TransportDIB::Id dib_id); + + //---------------------------------------------------------------------- + // New accelerated plugin implementation which renders via the compositor. + + // Tells the renderer, and from there the GPU process, that the plugin + // is using accelerated rather than software rendering. + virtual void AcceleratedPluginEnabledRendering() OVERRIDE; + + // Tells the renderer, and from there the GPU process, that the plugin + // allocated the given IOSurface to be used as its backing store. + virtual void AcceleratedPluginAllocatedIOSurface(int32 width, + int32 height, + uint32 surface_id) OVERRIDE; + virtual void AcceleratedPluginSwappedIOSurface() OVERRIDE; #endif virtual void URLRedirectResponse(bool allow, int resource_id) OVERRIDE; diff --git a/content/renderer/webplugin_delegate_proxy.cc b/content/renderer/webplugin_delegate_proxy.cc index c47ca68..4d57b17 100644 --- a/content/renderer/webplugin_delegate_proxy.cc +++ b/content/renderer/webplugin_delegate_proxy.cc @@ -169,6 +169,9 @@ WebPluginDelegateProxy::WebPluginDelegateProxy( : render_view_(render_view), plugin_(NULL), uses_shared_bitmaps_(false), +#if defined(OS_MACOSX) + uses_compositor_(false), +#endif window_(gfx::kNullPluginWindow), mime_type_(mime_type), instance_id_(MSG_ROUTING_NONE), @@ -435,6 +438,13 @@ bool WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { OnAcceleratedSurfaceFreeTransportDIB) IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedSurfaceBuffersSwapped, OnAcceleratedSurfaceBuffersSwapped) + // Used only on 10.6 and later. + IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginEnabledRendering, + OnAcceleratedPluginEnabledRendering) + IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginAllocatedIOSurface, + OnAcceleratedPluginAllocatedIOSurface) + IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginSwappedIOSurface, + OnAcceleratedPluginSwappedIOSurface) #endif IPC_MESSAGE_HANDLER(PluginHostMsg_URLRedirectResponse, OnURLRedirectResponse) @@ -1030,7 +1040,11 @@ void WebPluginDelegateProxy::ImeCompositionCompleted(const string16& text, #endif // OS_MACOSX void WebPluginDelegateProxy::OnSetWindow(gfx::PluginWindowHandle window) { +#if defined(OS_MACOSX) + uses_shared_bitmaps_ = !window && !uses_compositor_; +#else uses_shared_bitmaps_ = !window; +#endif window_ = window; if (plugin_) plugin_->SetWindow(window); @@ -1386,6 +1400,24 @@ void WebPluginDelegateProxy::OnAcceleratedSurfaceBuffersSwapped( if (render_view_) render_view_->AcceleratedSurfaceBuffersSwapped(window, surface_id); } + +void WebPluginDelegateProxy::OnAcceleratedPluginEnabledRendering() { + uses_compositor_ = true; + OnSetWindow(NULL); +} + +void WebPluginDelegateProxy::OnAcceleratedPluginAllocatedIOSurface( + int32 width, + int32 height, + uint32 surface_id) { + if (plugin_) + plugin_->AcceleratedPluginAllocatedIOSurface(width, height, surface_id); +} + +void WebPluginDelegateProxy::OnAcceleratedPluginSwappedIOSurface() { + if (plugin_) + plugin_->AcceleratedPluginSwappedIOSurface(); +} #endif #if defined(OS_WIN) diff --git a/content/renderer/webplugin_delegate_proxy.h b/content/renderer/webplugin_delegate_proxy.h index 5c2592b..d89fd40 100644 --- a/content/renderer/webplugin_delegate_proxy.h +++ b/content/renderer/webplugin_delegate_proxy.h @@ -187,6 +187,13 @@ class WebPluginDelegateProxy void OnAcceleratedSurfaceFreeTransportDIB(TransportDIB::Id dib_id); void OnAcceleratedSurfaceBuffersSwapped(gfx::PluginWindowHandle window, uint64 surface_id); + + // New accelerated plugin implementation. + void OnAcceleratedPluginEnabledRendering(); + void OnAcceleratedPluginAllocatedIOSurface(int32 width, + int32 height, + uint32 surface_id); + void OnAcceleratedPluginSwappedIOSurface(); #endif void OnURLRedirectResponse(bool allow, int resource_id); @@ -270,6 +277,9 @@ class WebPluginDelegateProxy base::WeakPtr<RenderViewImpl> render_view_; webkit::npapi::WebPlugin* plugin_; bool uses_shared_bitmaps_; +#if defined(OS_MACOSX) + bool uses_compositor_; +#endif gfx::PluginWindowHandle window_; scoped_refptr<PluginChannelHost> channel_host_; std::string mime_type_; diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc index 73a5606..9df9957 100644 --- a/ui/base/ui_base_switches.cc +++ b/ui/base/ui_base_switches.cc @@ -14,4 +14,9 @@ const char kLang[] = "lang"; // path should point to a locale.pak file. const char kLocalePak[] = "locale_pak"; +#if defined(OS_MACOSX) +const char kDisableCompositedCoreAnimationPlugins[] = + "disable-composited-core-animation-plugins"; +#endif + } // namespace switches diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h index 27f4f08..2bb97d3 100644 --- a/ui/base/ui_base_switches.h +++ b/ui/base/ui_base_switches.h @@ -8,6 +8,7 @@ #define UI_BASE_UI_BASE_SWITCHES_H_ #pragma once +#include "base/compiler_specific.h" #include "ui/base/ui_export.h" namespace switches { @@ -15,6 +16,15 @@ namespace switches { UI_EXPORT extern const char kLang[]; UI_EXPORT extern const char kLocalePak[]; +#if defined(OS_MACOSX) +// TODO(kbr): remove this and the associated old code path: +// http://crbug.com/105344 +// This isn't really the right place for this switch, but is the most +// convenient place where it can be shared between +// src/webkit/plugins/npapi/ and src/content/plugin/ . +UI_EXPORT extern const char kDisableCompositedCoreAnimationPlugins[]; +#endif + } // namespace switches #endif // UI_BASE_UI_BASE_SWITCHES_H_ diff --git a/ui/gfx/surface/accelerated_surface_mac.cc b/ui/gfx/surface/accelerated_surface_mac.cc index b0fb156..1a0fd31 100644 --- a/ui/gfx/surface/accelerated_surface_mac.cc +++ b/ui/gfx/surface/accelerated_surface_mac.cc @@ -87,9 +87,9 @@ void AcceleratedSurface::SwapBuffers() { if (allocate_fbo_) { // Bind and unbind the framebuffer to make changes to the // IOSurface show up in the other process. - glFlush(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); + glFlush(); } else { // Copy the current framebuffer's contents into our "live" texture. // Note that the current GL context might not be ours at this point! @@ -146,16 +146,24 @@ static void AddIntegerValue(CFMutableDictionaryRef dictionary, CFDictionaryAddValue(dictionary, key, number.get()); } +// Creates a new OpenGL texture object bound to the given texture target. +// Caller owns the returned texture. +static GLuint CreateTexture(GLenum target) { + GLuint texture = 0; + glGenTextures(1, &texture); + glBindTexture(target, texture); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + return texture; +} + void AcceleratedSurface::AllocateRenderBuffers(GLenum target, const gfx::Size& size) { if (!texture_) { // Generate the texture object. - glGenTextures(1, &texture_); - glBindTexture(target, texture_); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + texture_ = CreateTexture(target); // Generate and bind the framebuffer object. glGenFramebuffersEXT(1, &fbo_); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); @@ -225,7 +233,7 @@ void AcceleratedSurface::Clear(const gfx::Rect& rect) { glClear(GL_COLOR_BUFFER_BIT); } -uint64 AcceleratedSurface::SetSurfaceSize(const gfx::Size& size) { +uint32 AcceleratedSurface::SetSurfaceSize(const gfx::Size& size) { if (surface_size_ == size) { // Return 0 to indicate to the caller that no new backing store // allocation occurred. @@ -255,12 +263,7 @@ uint64 AcceleratedSurface::SetSurfaceSize(const gfx::Size& size) { AllocateRenderBuffers(target, clamped_size); } else if (!texture_) { // Generate the texture object. - glGenTextures(1, &texture_); - glBindTexture(target, texture_); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + texture_ = CreateTexture(target); } // Allocate a new IOSurface, which is the GPU resource that can be @@ -315,7 +318,7 @@ uint64 AcceleratedSurface::SetSurfaceSize(const gfx::Size& size) { return io_surface_id_; } -uint64 AcceleratedSurface::GetSurfaceId() { +uint32 AcceleratedSurface::GetSurfaceId() { return io_surface_id_; } diff --git a/ui/gfx/surface/accelerated_surface_mac.h b/ui/gfx/surface/accelerated_surface_mac.h index 83c95d6..37f50a7 100644 --- a/ui/gfx/surface/accelerated_surface_mac.h +++ b/ui/gfx/surface/accelerated_surface_mac.h @@ -64,11 +64,11 @@ class SURFACE_EXPORT AcceleratedSurface { // the height or width changes. Returns a unique id of the IOSurface to // which the surface is bound, or 0 if no changes were made or an error // occurred. MakeCurrent() will have been called on the new surface. - uint64 SetSurfaceSize(const gfx::Size& size); + uint32 SetSurfaceSize(const gfx::Size& size); - // Returns the id of this surface's IOSruface, or 0 for + // Returns the id of this surface's IOSurface, or 0 for // transport DIB surfaces. - uint64 GetSurfaceId(); + uint32 GetSurfaceId(); // Sets the GL context to be the current one for drawing. Returns true if // it succeeded. @@ -148,7 +148,7 @@ class SURFACE_EXPORT AcceleratedSurface { base::mac::ScopedCFTypeRef<CFTypeRef> io_surface_; // The id of |io_surface_| or 0 if that's NULL. - uint64 io_surface_id_; + uint32 io_surface_id_; // TODO(dspringer): If we end up keeping this TransportDIB mechanism, this // should really be a scoped_ptr_malloc<>, with a deallocate functor that diff --git a/webkit/plugins/npapi/plugin_host.cc b/webkit/plugins/npapi/plugin_host.cc index bad6fdb..73204d2 100644 --- a/webkit/plugins/npapi/plugin_host.cc +++ b/webkit/plugins/npapi/plugin_host.cc @@ -4,6 +4,7 @@ #include "webkit/plugins/npapi/plugin_host.h" +#include "base/command_line.h" #include "base/file_util.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -16,6 +17,7 @@ #include "third_party/npapi/bindings/npruntime.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" +#include "ui/base/ui_base_switches.h" #include "ui/gfx/gl/gl_implementation.h" #include "ui/gfx/gl/gl_surface.h" #include "webkit/glue/webkit_glue.h" @@ -71,6 +73,11 @@ static bool SupportsSharingAcceleratedSurfaces() { } return (implementation == gfx::kGLImplementationDesktopGL); } + +static bool UsingCompositedCoreAnimationPlugins() { + return !CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableCompositedCoreAnimationPlugins); +} #endif PluginHost::PluginHost() { @@ -826,8 +833,12 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { break; } case NPNVsupportsInvalidatingCoreAnimationBool: { + // The composited code path for this model only works on 10.6 and higher. + // The old direct-to-screen code path supports 10.5. NPBool* supports_model = reinterpret_cast<NPBool*>(value); - *supports_model = true; + bool composited = webkit::npapi::UsingCompositedCoreAnimationPlugins(); + *supports_model = composited ? + webkit::npapi::SupportsSharingAcceleratedSurfaces() : true; rv = NPERR_NO_ERROR; break; } @@ -901,7 +912,9 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { case NPPVpluginDrawingModel: { int model = reinterpret_cast<int>(value); if (model == NPDrawingModelCoreGraphics || - model == NPDrawingModelInvalidatingCoreAnimation || + (model == NPDrawingModelInvalidatingCoreAnimation && + (webkit::npapi::SupportsSharingAcceleratedSurfaces() || + !webkit::npapi::UsingCompositedCoreAnimationPlugins())) || (model == NPDrawingModelCoreAnimation && webkit::npapi::SupportsSharingAcceleratedSurfaces())) { plugin->set_drawing_model(static_cast<NPDrawingModel>(model)); diff --git a/webkit/plugins/npapi/webplugin.h b/webkit/plugins/npapi/webplugin.h index 53a2ca4..f861517 100644 --- a/webkit/plugins/npapi/webplugin.h +++ b/webkit/plugins/npapi/webplugin.h @@ -156,6 +156,13 @@ class WebPlugin { // Returns the accelerated surface abstraction for accelerated plugins. virtual WebPluginAcceleratedSurface* GetAcceleratedSurface( gfx::GpuPreference gpu_preference); + + // Composited Core Animation plugin support. + virtual void AcceleratedPluginEnabledRendering() = 0; + virtual void AcceleratedPluginAllocatedIOSurface(int32 width, + int32 height, + uint32 surface_id) = 0; + virtual void AcceleratedPluginSwappedIOSurface() = 0; #endif // Handles NPN_URLRedirectResponse calls issued by plugins in response to diff --git a/webkit/plugins/npapi/webplugin_accelerated_surface_mac.h b/webkit/plugins/npapi/webplugin_accelerated_surface_mac.h index 5c528f3..2f46861 100644 --- a/webkit/plugins/npapi/webplugin_accelerated_surface_mac.h +++ b/webkit/plugins/npapi/webplugin_accelerated_surface_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -25,6 +25,10 @@ class WebPluginAcceleratedSurface { // surface. virtual void SetWindowHandle(gfx::PluginWindowHandle window) = 0; + // Indicates whether the new code path which renders the plugins via + // the compositor should be used. + virtual bool IsComposited() = 0; + // Sets the size of the surface. virtual void SetSize(const gfx::Size& size) = 0; diff --git a/webkit/plugins/npapi/webplugin_delegate_impl.h b/webkit/plugins/npapi/webplugin_delegate_impl.h index 97fde32..f811d72 100644 --- a/webkit/plugins/npapi/webplugin_delegate_impl.h +++ b/webkit/plugins/npapi/webplugin_delegate_impl.h @@ -475,6 +475,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate { CALayer* layer_; // Used for CA drawing mode. Weak, retained by plug-in. WebPluginAcceleratedSurface* surface_; // Weak ref. + bool composited_; // If CA plugin, whether it's rendering via compositor. CARenderer* renderer_; // Renders layer_ to surface_. scoped_ptr<base::RepeatingTimer<WebPluginDelegateImpl> > redraw_timer_; diff --git a/webkit/plugins/npapi/webplugin_delegate_impl_mac.mm b/webkit/plugins/npapi/webplugin_delegate_impl_mac.mm index 8e0243a..5127eaf 100644 --- a/webkit/plugins/npapi/webplugin_delegate_impl_mac.mm +++ b/webkit/plugins/npapi/webplugin_delegate_impl_mac.mm @@ -267,6 +267,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( buffer_context_(NULL), layer_(nil), surface_(NULL), + composited_(false), renderer_(nil), containing_window_has_focus_(false), initial_window_focus_(false), @@ -402,11 +403,16 @@ bool WebPluginDelegateImpl::PlatformInitialize() { // without any drawing; returning false would be a more confusing user // experience (since it triggers a missing plugin placeholder). if (surface_ && surface_->context()) { + composited_ = surface_->IsComposited(); renderer_ = [[CARenderer rendererWithCGLContext:surface_->context() options:NULL] retain]; [renderer_ setLayer:layer_]; } - plugin_->BindFakePluginWindowHandle(false); + if (composited_) { + plugin_->AcceleratedPluginEnabledRendering(); + } else { + plugin_->BindFakePluginWindowHandle(false); + } } break; } @@ -415,9 +421,10 @@ bool WebPluginDelegateImpl::PlatformInitialize() { break; } - // Let the WebPlugin know that we are windowless (unless this is a - // Core Animation plugin, in which case BindFakePluginWindowHandle will take - // care of setting up the appropriate window handle). + // Let the WebPlugin know that we are windowless, unless this is a Core + // Animation plugin, in which case AcceleratedPluginEnabledRendering + // calls SetWindow. Rendering breaks if SetWindow is called before + // accelerated rendering is enabled. if (!layer_) plugin_->SetWindow(NULL); @@ -1035,7 +1042,8 @@ void WebPluginDelegateImpl::PluginVisibilityChanged() { #endif if (instance()->drawing_model() == NPDrawingModelCoreAnimation) { bool plugin_visible = container_is_visible_ && !clip_rect_.IsEmpty(); - if (plugin_visible && !redraw_timer_->IsRunning() && windowed_handle()) { + if (plugin_visible && !redraw_timer_->IsRunning() && + (composited_ || windowed_handle())) { redraw_timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kCoreAnimationRedrawPeriodMs), this, &WebPluginDelegateImpl::DrawLayerInSurface); @@ -1062,7 +1070,10 @@ void WebPluginDelegateImpl::StartIme() { void WebPluginDelegateImpl::DrawLayerInSurface() { // If we haven't plumbed up the surface yet, don't try to draw. - if (!windowed_handle() || !renderer_) + if (!renderer_) + return; + + if (!composited_ && !windowed_handle()) return; [renderer_ beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL]; @@ -1084,8 +1095,10 @@ void WebPluginDelegateImpl::DrawLayerInSurface() { // 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_) + if (!surface_ || !layer_) + return; + + if (!composited_ && !windowed_handle()) return; [CATransaction begin]; @@ -1097,10 +1110,15 @@ void WebPluginDelegateImpl::UpdateAcceleratedSurface() { [renderer_ setBounds:[layer_ bounds]]; surface_->SetSize(window_rect_.size()); + if (composited_) { + // Kick off the drawing timer, if necessary. + PluginVisibilityChanged(); + } } void WebPluginDelegateImpl::set_windowed_handle( gfx::PluginWindowHandle handle) { + DCHECK(!composited_); windowed_handle_ = handle; surface_->SetWindowHandle(handle); UpdateAcceleratedSurface(); diff --git a/webkit/plugins/npapi/webplugin_impl.cc b/webkit/plugins/npapi/webplugin_impl.cc index b78aeab..3ea5256 100644 --- a/webkit/plugins/npapi/webplugin_impl.cc +++ b/webkit/plugins/npapi/webplugin_impl.cc @@ -489,38 +489,31 @@ WebPluginImpl::~WebPluginImpl() { } void WebPluginImpl::SetWindow(gfx::PluginWindowHandle window) { -#if defined(OS_MACOSX) - // The only time this is called twice, and the second time with a - // non-zero PluginWindowHandle, is the case when this WebPluginImpl - // is created on behalf of the GPU plugin. This entire code path - // will go away soon, as soon as the GPU plugin becomes the GPU - // process, so it is being separated out for easy deletion. - - // The logic we want here is: if (window) DCHECK(!window_); - DCHECK(!(window_ && window)); - window_ = window; - // Lie to ourselves about being windowless even if we got a fake - // plugin window handle, so we continue to get input events. - windowless_ = true; - accepts_input_events_ = true; - // We do not really need to notify the page delegate that a plugin - // window was created -- so don't. -#else if (window) { DCHECK(!windowless_); window_ = window; +#if defined(OS_MACOSX) + // TODO(kbr): remove. http://crbug.com/105344 + + // Lie to ourselves about being windowless even if we got a fake + // plugin window handle, so we continue to get input events. + windowless_ = true; + accepts_input_events_ = true; + // We do not really need to notify the page delegate that a plugin + // window was created -- so don't. +#else accepts_input_events_ = false; if (page_delegate_) { // Tell the view delegate that the plugin window was created, so that it // can create necessary container widgets. page_delegate_->CreatedPluginWindow(window); } +#endif } else { DCHECK(!window_); // Make sure not called twice. windowless_ = true; accepts_input_events_ = true; } -#endif } void WebPluginImpl::SetAcceptsInputEvents(bool accepts) { @@ -754,6 +747,39 @@ void WebPluginImpl::URLRedirectResponse(bool allow, int resource_id) { } } +#if defined(OS_MACOSX) +void WebPluginImpl::AcceleratedPluginEnabledRendering() { +} + +void WebPluginImpl::AcceleratedPluginAllocatedIOSurface(int32 width, + int32 height, + uint32 surface_id) { + next_io_surface_allocated_ = true; + next_io_surface_width_ = width; + next_io_surface_height_ = height; + next_io_surface_id_ = surface_id; +} + +void WebPluginImpl::AcceleratedPluginSwappedIOSurface() { + if (container_) { + // Deferring the call to setBackingIOSurfaceId is an attempt to + // work around garbage occasionally showing up in the plugin's + // area during live resizing of Core Animation plugins. The + // assumption was that by the time this was called, the plugin + // process would have populated the newly allocated IOSurface. It + // is not 100% clear at this point why any garbage is getting + // through. More investigation is needed. http://crbug.com/105346 + if (next_io_surface_allocated_) { + container_->setBackingIOSurfaceId(next_io_surface_width_, + next_io_surface_height_, + next_io_surface_id_); + next_io_surface_allocated_ = false; + } + container_->commitBackingTexture(); + } +} +#endif + void WebPluginImpl::Invalidate() { if (container_) container_->invalidate(); diff --git a/webkit/plugins/npapi/webplugin_impl.h b/webkit/plugins/npapi/webplugin_impl.h index c9c798c..ec0f30f 100644 --- a/webkit/plugins/npapi/webplugin_impl.h +++ b/webkit/plugins/npapi/webplugin_impl.h @@ -109,6 +109,13 @@ class WebPluginImpl : public WebPlugin, virtual std::string GetCookies(const GURL& url, const GURL& first_party_for_cookies) OVERRIDE; virtual void URLRedirectResponse(bool allow, int resource_id) OVERRIDE; +#if defined(OS_MACOSX) + virtual void AcceleratedPluginEnabledRendering() OVERRIDE; + virtual void AcceleratedPluginAllocatedIOSurface(int32 width, + int32 height, + uint32 surface_id) OVERRIDE; + virtual void AcceleratedPluginSwappedIOSurface() OVERRIDE; +#endif // Given a (maybe partial) url, completes using the base url. GURL CompleteURL(const char* url); @@ -255,6 +262,12 @@ class WebPluginImpl : public WebPlugin, bool windowless_; gfx::PluginWindowHandle window_; +#if defined(OS_MACOSX) + bool next_io_surface_allocated_; + int32 next_io_surface_width_; + int32 next_io_surface_height_; + uint32 next_io_surface_id_; +#endif bool accepts_input_events_; base::WeakPtr<WebPluginPageDelegate> page_delegate_; WebKit::WebFrame* webframe_; |