diff options
author | stuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-01 18:04:06 +0000 |
---|---|---|
committer | stuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-01 18:04:06 +0000 |
commit | 8b4755fa086ef5d41e6a6ed40a38ac45390b9511 (patch) | |
tree | 555a11c1fdaee95ebfb29cdfb9a7a2a7cce9a3c1 /chrome/plugin | |
parent | 56bf1b7944f2c7b2a620b0e1476086b7e60f0da6 (diff) | |
download | chromium_src-8b4755fa086ef5d41e6a6ed40a38ac45390b9511.zip chromium_src-8b4755fa086ef5d41e6a6ed40a38ac45390b9511.tar.gz chromium_src-8b4755fa086ef5d41e6a6ed40a38ac45390b9511.tar.bz2 |
Enable the invalidating Core Animation plugin drawing model on 10.5
This also adds a layer of abstraction between the concept of the accelerated surface, and our cross-process implementation (which is something we needed to fix in general, but was necessary here to avoid bleeding TransportDIB references into code that's not supposed to know about process separation). There's no in-process implementation since we don't support in-process plugins on the Mac, but the abstraction is now there if we want to add one in the future.
BUG=32012
TEST=Plugins using invalidating Core Animation model should run on 10.5
Review URL: http://codereview.chromium.org/3449023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61199 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/plugin')
-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 |
4 files changed, 170 insertions, 6 deletions
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_; |