diff options
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_mac.mm | 7 | ||||
-rw-r--r-- | chrome/chrome_common.gypi | 2 | ||||
-rw-r--r-- | chrome/common/accelerated_surface_mac.cc | 334 | ||||
-rw-r--r-- | chrome/common/accelerated_surface_mac.h | 108 | ||||
-rw-r--r-- | chrome/common/plugin_messages_internal.h | 6 | ||||
-rw-r--r-- | chrome/plugin/webplugin_delegate_stub.h | 2 | ||||
-rw-r--r-- | chrome/plugin/webplugin_proxy.cc | 22 | ||||
-rw-r--r-- | chrome/plugin/webplugin_proxy.h | 9 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.cc | 29 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.h | 8 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 346 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_host.cc | 42 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 39 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 93 | ||||
-rw-r--r-- | webkit/glue/webplugin.h | 20 | ||||
-rw-r--r-- | webkit/tools/test_shell/mac/accelerated_surface_stub.cc | 52 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell.gypi | 1 | ||||
-rw-r--r-- | webkit/webkit.gyp | 5 |
18 files changed, 359 insertions, 766 deletions
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 0d20f6b..079cecd 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -83,10 +83,6 @@ const size_t kMaxTooltipLength = 1024; forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp { renderWidgetHostView_->DrawGPUPluginInstances(glContext); - [super drawInCGLContext:glContext - pixelFormat:pixelFormat - forLayerTime:timeInterval - displayTime:timeStamp]; } @end @@ -583,7 +579,6 @@ void RenderWidgetHostViewMac::DrawGPUPluginInstances(CGLContextObj context) { glOrtho(0, rect.width(), rect.height(), 0, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - plugin_container_manager_.Draw(context); } @@ -1474,7 +1469,7 @@ extern NSString *NSTextInputReplacementRangeAttributeName; // TODO(hbono): Even though many input method works without implementing // this method, we need to save a copy of the string in the setMarkedText // method and create a NSAttributedString with the given range. - // http://crbug.com/37715 + NOTIMPLEMENTED(); return nil; } diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 4fb4c85..934e097 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -23,8 +23,6 @@ # .cc, .h, and .mm files under chrome/common that are used on all # platforms, including both 32-bit and 64-bit Windows. # Test files are not included. - 'common/accelerated_surface_mac.cc', - 'common/accelerated_surface_mac.h', 'common/app_mode_constants_mac.h', 'common/app_mode_constants_mac.mm', 'common/bindings_policy.h', diff --git a/chrome/common/accelerated_surface_mac.cc b/chrome/common/accelerated_surface_mac.cc deleted file mode 100644 index d12ecb6..0000000 --- a/chrome/common/accelerated_surface_mac.cc +++ /dev/null @@ -1,334 +0,0 @@ -// 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 "chrome/common/accelerated_surface_mac.h" - -#include "base/gfx/rect.h" -#include "base/logging.h" -#include "chrome/common/io_surface_support_mac.h" - -AcceleratedSurface::AcceleratedSurface() - : gl_context_(NULL), - pbuffer_(NULL), - surface_width_(0), - surface_height_(0), - texture_(0), - fbo_(0), - depth_stencil_renderbuffer_(0), - bound_fbo_(0), - bound_renderbuffer_(0) { -} - -bool AcceleratedSurface::Initialize() { - // Create a 1x1 pbuffer and associated context to bootstrap things - static const CGLPixelFormatAttribute attribs[] = { - (CGLPixelFormatAttribute) kCGLPFAPBuffer, - (CGLPixelFormatAttribute) 0 - }; - CGLPixelFormatObj pixel_format; - GLint num_pixel_formats; - if (CGLChoosePixelFormat(attribs, - &pixel_format, - &num_pixel_formats) != kCGLNoError) { - DLOG(ERROR) << "Error choosing pixel format."; - return false; - } - if (!pixel_format) { - return false; - } - CGLContextObj context; - CGLError res = CGLCreateContext(pixel_format, 0, &context); - CGLDestroyPixelFormat(pixel_format); - if (res != kCGLNoError) { - DLOG(ERROR) << "Error creating context."; - return false; - } - CGLPBufferObj pbuffer; - if (CGLCreatePBuffer(1, 1, - GL_TEXTURE_2D, GL_RGBA, - 0, &pbuffer) != kCGLNoError) { - CGLDestroyContext(context); - DLOG(ERROR) << "Error creating pbuffer."; - return false; - } - if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) { - CGLDestroyContext(context); - CGLDestroyPBuffer(pbuffer); - DLOG(ERROR) << "Error attaching pbuffer to context."; - return false; - } - gl_context_ = context; - pbuffer_ = pbuffer; - // Now we're ready to handle SetWindowSize calls, which will - // allocate and/or reallocate the IOSurface and associated offscreen - // OpenGL structures for rendering. - return true; -} - -void AcceleratedSurface::Destroy() { - // Release the old TransportDIB in the browser. - if (dib_free_callback_.get() && transport_dib_.get()) { - dib_free_callback_->Run(transport_dib_->id()); - } - transport_dib_.reset(); - if (gl_context_) - CGLDestroyContext(gl_context_); - if (pbuffer_) - CGLDestroyPBuffer(pbuffer_); -} - -// Call after making changes to the surface which require a visual update. -// Makes the rendering show up in other processes. -void AcceleratedSurface::SwapBuffers() { - if (bound_fbo_ != fbo_) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - } - if (io_surface_.get() != NULL) { - // 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_); - } else if (transport_dib_.get() != NULL) { - // Pre-Mac OS X 10.6, fetch the rendered image from the FBO and copy it - // into the TransportDIB. - // TODO(dspringer): There are a couple of options that can speed this up. - // First is to use async reads into a PBO, second is to use SPI that - // allows many tasks to access the same CGSSurface. - void* pixel_memory = transport_dib_->memory(); - if (pixel_memory) { - // Note that glReadPixels does an implicit glFlush(). - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - glReadPixels(0, - 0, - surface_width_, - surface_height_, - GL_BGRA, // This pixel format should have no conversion. - GL_UNSIGNED_INT_8_8_8_8_REV, - pixel_memory); - } - } - if (bound_fbo_ != fbo_) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); - } -} - -static void AddBooleanValue(CFMutableDictionaryRef dictionary, - const CFStringRef key, - bool value) { - CFDictionaryAddValue(dictionary, key, - (value ? kCFBooleanTrue : kCFBooleanFalse)); -} - -static void AddIntegerValue(CFMutableDictionaryRef dictionary, - const CFStringRef key, - int32 value) { - CFNumberRef number = CFNumberCreate(NULL, kCFNumberSInt32Type, &value); - CFDictionaryAddValue(dictionary, key, number); -} - -void AcceleratedSurface::AllocateRenderBuffers(GLenum target, - int32 width, int32 height) { - 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); - // Generate and bind the framebuffer object. - glGenFramebuffersEXT(1, &fbo_); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - bound_fbo_ = fbo_; - // Generate (but don't bind) the depth buffer -- we don't need - // this bound in order to do offscreen rendering. - glGenRenderbuffersEXT(1, &depth_stencil_renderbuffer_); - } - - // Reallocate the depth buffer. - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_renderbuffer_); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - GL_DEPTH24_STENCIL8_EXT, - width, - height); - - // Unbind the renderbuffers. - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, bound_renderbuffer_); - - // Make sure that subsequent set-up code affects the render texture. - glBindTexture(target, texture_); -} - -bool AcceleratedSurface::SetupFrameBufferObject(GLenum target) { - if (bound_fbo_ != fbo_) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); - } - GLenum fbo_status; - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, - texture_, - 0); - fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - depth_stencil_renderbuffer_); - fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - } - // Attach the depth and stencil buffer. - if (fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - 0x8D20, // GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER_EXT, - depth_stencil_renderbuffer_); - fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - } - if (bound_fbo_ != fbo_) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); - } - return fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT; -} - -bool AcceleratedSurface::MakeCurrent() { - if (CGLGetCurrentContext() != gl_context_) { - if (CGLSetCurrentContext(gl_context_) != kCGLNoError) { - DLOG(ERROR) << "Unable to make gl context current."; - return false; - } - } - return true; -} - -void AcceleratedSurface::Clear(const gfx::Rect& rect) { - glClearColor(1.0, 1.0, 1.0, 1.0); - glViewport(0, 0, rect.width(), rect.height()); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, rect.width(), 0, rect.height(), -1, 1); - glClear(GL_COLOR_BUFFER_BIT); -} - -uint64 AcceleratedSurface::SetSurfaceSize(int32 width, int32 height) { - if (surface_width_ == width && surface_height_ == height) { - // Return 0 to indicate to the caller that no new backing store - // allocation occurred. - return 0; - } - - IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); - if (!io_surface_support) - return 0; // Caller can try using SetWindowSizeForTransportDIB(). - - if (!MakeCurrent()) - return 0; - - // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on - // Mac OS X and is required for IOSurface interoperability. - GLenum target = GL_TEXTURE_RECTANGLE_ARB; - AllocateRenderBuffers(target, width, height); - - // Allocate a new IOSurface, which is the GPU resource that can be - // shared across processes. - scoped_cftyperef<CFMutableDictionaryRef> properties; - properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, - 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks)); - AddIntegerValue(properties, - io_surface_support->GetKIOSurfaceWidth(), width); - AddIntegerValue(properties, - io_surface_support->GetKIOSurfaceHeight(), height); - AddIntegerValue(properties, - io_surface_support->GetKIOSurfaceBytesPerElement(), 4); - AddBooleanValue(properties, - io_surface_support->GetKIOSurfaceIsGlobal(), true); - // I believe we should be able to unreference the IOSurfaces without - // synchronizing with the browser process because they are - // ultimately reference counted by the operating system. - io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); - - // Don't think we need to identify a plane. - GLuint plane = 0; - io_surface_support->CGLTexImageIOSurface2D(gl_context_, - target, - GL_RGBA, - width, - height, - GL_BGRA, - GL_UNSIGNED_INT_8_8_8_8_REV, - io_surface_.get(), - plane); - // Set up the frame buffer object. - SetupFrameBufferObject(target); - surface_width_ = width; - surface_height_ = height; - - // Now send back an identifier for the IOSurface. We originally - // intended to send back a mach port from IOSurfaceCreateMachPort - // but it looks like Chrome IPC would need to be modified to - // properly send mach ports between processes. For the time being we - // make our IOSurfaces global and send back their identifiers. On - // the browser process side the identifier is reconstituted into an - // IOSurface for on-screen rendering. - return io_surface_support->IOSurfaceGetID(io_surface_); -} - -TransportDIB::Handle AcceleratedSurface::SetTransportDIBSize( - int32 width, int32 height) { - if (surface_width_ == width && surface_height_ == height) { - // Return an invalid handle to indicate to the caller that no new backing - // store allocation occurred. - return TransportDIB::DefaultHandleValue(); - } - surface_width_ = width; - surface_height_ = height; - - // Release the old TransportDIB in the browser. - if (dib_free_callback_.get() && transport_dib_.get()) { - dib_free_callback_->Run(transport_dib_->id()); - } - transport_dib_.reset(); - - // Ask the renderer to create a TransportDIB. - size_t dib_size = width * 4 * height; // 4 bytes per pixel. - TransportDIB::Handle dib_handle; - if (dib_alloc_callback_.get()) { - dib_alloc_callback_->Run(dib_size, &dib_handle); - } - if (!TransportDIB::is_valid(dib_handle)) { - // If the allocator fails, it means the DIB was not created in the browser, - // so there is no need to run the deallocator here. - return TransportDIB::DefaultHandleValue(); - } - transport_dib_.reset(TransportDIB::Map(dib_handle)); - if (transport_dib_.get() == NULL) { - // TODO(dspringer): if the Map() fails, should the deallocator be run so - // that the DIB is deallocated in the browser? - return TransportDIB::DefaultHandleValue(); - } - - // Set up the render buffers and reserve enough space on the card for the - // framebuffer texture. - GLenum target = GL_TEXTURE_RECTANGLE_ARB; - AllocateRenderBuffers(target, width, height); - glTexImage2D(target, - 0, // mipmap level 0 - GL_RGBA8, // internal pixel format - width, - height, - 0, // 0 border - GL_BGRA, // Used for consistency - GL_UNSIGNED_INT_8_8_8_8_REV, - NULL); // No data, just reserve room on the card. - SetupFrameBufferObject(target); - return transport_dib_->handle(); -} - -void AcceleratedSurface::SetTransportDIBAllocAndFree( - Callback2<size_t, TransportDIB::Handle*>::Type* allocator, - Callback1<TransportDIB::Id>::Type* deallocator) { - dib_alloc_callback_.reset(allocator); - dib_free_callback_.reset(deallocator); -} diff --git a/chrome/common/accelerated_surface_mac.h b/chrome/common/accelerated_surface_mac.h deleted file mode 100644 index e8c27af..0000000 --- a/chrome/common/accelerated_surface_mac.h +++ /dev/null @@ -1,108 +0,0 @@ -// 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_ACCELERATED_SURFACE_MAC_H_ -#define CHROME_COMMON_ACCELERATED_SURFACE_MAC_H_ - -#include <CoreFoundation/CoreFoundation.h> -#include <OpenGL/OpenGL.h> - -#include "base/callback.h" -#include "base/scoped_cftyperef.h" -#include "base/scoped_ptr.h" -#include "chrome/common/transport_dib.h" - -namespace gfx { -class Rect; -} - -// Encapsulates an accelerated GL surface that can be shared across processes -// on systems that support it (10.6 and above). For systems that do not, it -// uses a regular dib. There will either be a GL Context or a TransportDIB, -// never both. - -class AcceleratedSurface { - public: - AcceleratedSurface(); - virtual ~AcceleratedSurface() { } - - // Set up internal buffers. Returns false upon failure. - bool Initialize(); - // Tear down. Must be called before destructor to prevent leaks. - void Destroy(); - - // These methods are used only when there is a GL surface. - - // Sets the accelerated surface to the given size, creating a new one if - // 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(int32 width, int32 height); - // Sets the GL context to be the current one for drawing. Returns true if - // it succeeded. - bool MakeCurrent(); - // Clear the surface to all white. Assumes the caller has already called - // MakeCurrent(). - void Clear(const gfx::Rect& rect); - // Call after making changes to the surface which require a visual update. - // Makes the rendering show up in other processes. - void SwapBuffers(); - CGLContextObj context() { return gl_context_; } - - // These methods are only used when there is a transport DIB. - - // Sets the transport DIB to the given size, creating a new one if the - // height or width changes. Returns a handle to the new DIB, or a default - // handle if no changes were made. - TransportDIB::Handle SetTransportDIBSize(int32 width, int32 height); - // Sets the methods to use for allocating and freeing memory for the - // transport DIB. - void SetTransportDIBAllocAndFree( - Callback2<size_t, TransportDIB::Handle*>::Type* allocator, - Callback1<TransportDIB::Id>::Type* deallocator); - - private: - // Helper function to generate names for the backing texture, render buffers - // and FBO. On return, the resulting buffer names can be attached to |fbo_|. - // |target| is the target type for the color buffer. - void AllocateRenderBuffers(GLenum target, int32 width, int32 height); - - // Helper function to attach the buffers previously allocated by a call to - // AllocateRenderBuffers(). On return, |fbo_| can be used for - // rendering. |target| must be the same value as used in the call to - // AllocateRenderBuffers(). Returns |true| if the resulting framebuffer - // object is valid. - bool SetupFrameBufferObject(GLenum target); - - CGLContextObj gl_context_; - CGLPBufferObj pbuffer_; - // Either |io_surface_| or |transport_dib_| is a valid pointer, but not both. - // |io_surface_| is non-NULL if the IOSurface APIs are supported (Mac OS X - // 10.6 and later). - // TODO(dspringer,kbr): Should the GPU backing store be encapsulated in its - // own class so all this implementation detail is hidden? - scoped_cftyperef<CFTypeRef> io_surface_; - // TODO(dspringer): If we end up keeping this TransportDIB mechanism, this - // should really be a scoped_ptr_malloc<>, with a deallocate functor that - // runs |dib_free_callback_|. I was not able to figure out how to - // make this work (or even compile). - scoped_ptr<TransportDIB> transport_dib_; - int32 surface_width_; - int32 surface_height_; - GLuint texture_; - GLuint fbo_; - GLuint depth_stencil_renderbuffer_; - // For tracking whether the default framebuffer / renderbuffer or - // ones created by the end user are currently bound - // TODO(kbr): Need to property hook up and track the OpenGL state and hook - // up the notion of the currently bound FBO. - GLuint bound_fbo_; - GLuint bound_renderbuffer_; - // Allocate a TransportDIB in the renderer. - scoped_ptr<Callback2<size_t, TransportDIB::Handle*>::Type> - dib_alloc_callback_; - scoped_ptr<Callback1<TransportDIB::Id>::Type> dib_free_callback_; -}; - -#endif // CHROME_COMMON_ACCELERATED_SURFACE_MAC_H_ diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h index 08e1aba..3a5594c 100644 --- a/chrome/common/plugin_messages_internal.h +++ b/chrome/common/plugin_messages_internal.h @@ -416,12 +416,6 @@ IPC_BEGIN_MESSAGES(PluginHost) int32 /* height */, TransportDIB::Handle /* handle to the TransportDIB */) - // Synthesize a fake window handle for the plug-in to identify the instance - // to the browser, allowing mapping to a surface for hardware accelleration - // of plug-in content. The browser generates the handle which is then set on - // the plug-in. - IPC_MESSAGE_ROUTED0(PluginHostMsg_BindFakePluginWindowHandle) - // 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 diff --git a/chrome/plugin/webplugin_delegate_stub.h b/chrome/plugin/webplugin_delegate_stub.h index 64dea79d..1bbd04d 100644 --- a/chrome/plugin/webplugin_delegate_stub.h +++ b/chrome/plugin/webplugin_delegate_stub.h @@ -33,7 +33,7 @@ class WebInputEvent; class WebPluginDelegateImpl; // Converts the IPC messages from WebPluginDelegateProxy into calls to the -// actual WebPluginDelegateImpl object. +// actual WebPluginDelegate object. class WebPluginDelegateStub : public IPC::Channel::Listener, public IPC::Message::Sender, public base::RefCounted<WebPluginDelegateStub> { diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index e7826fd..ffda5c1 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -576,28 +576,6 @@ void WebPluginProxy::SetDeferResourceLoading(unsigned long resource_id, Send(new PluginHostMsg_DeferResourceLoading(route_id_, resource_id, defer)); } -#if defined(OS_MACOSX) -void WebPluginProxy::BindFakePluginWindowHandle() { - Send(new PluginHostMsg_BindFakePluginWindowHandle(route_id_)); -} - -void WebPluginProxy::AcceleratedFrameBuffersDidSwap( - gfx::PluginWindowHandle window) { - // TODO(pinkerton): Rename this message. - Send(new PluginHostMsg_GPUPluginBuffersSwapped(route_id_, window)); -} - -void WebPluginProxy::SetAcceleratedSurface(gfx::PluginWindowHandle window, - int32 width, - int32 height, - uint64 accelerated_surface_identifier) { - // TODO(pinkerton): Rename this message. - Send(new PluginHostMsg_GPUPluginSetIOSurface(route_id_, window, width, - height, - accelerated_surface_identifier)); -} -#endif - void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { child_process_logging::SetActiveURL(page_url_); diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h index 9329d6c..0beb9cb 100644 --- a/chrome/plugin/webplugin_proxy.h +++ b/chrome/plugin/webplugin_proxy.h @@ -132,15 +132,6 @@ class WebPluginProxy : public webkit_glue::WebPlugin { webkit_glue::WebPluginResourceClient* resource_client); gfx::NativeViewId containing_window() { return containing_window_; } -#if defined(OS_MACOSX) - virtual void BindFakePluginWindowHandle(); - virtual void AcceleratedFrameBuffersDidSwap(gfx::PluginWindowHandle window); - virtual void SetAcceleratedSurface(gfx::PluginWindowHandle window, - int32 width, - int32 height, - uint64 accelerated_surface_identifier); -#endif - private: bool Send(IPC::Message* msg); diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index 10bf1f8..b00f1b5 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -402,8 +402,6 @@ void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { OnDeferResourceLoading) #if defined(OS_MACOSX) - IPC_MESSAGE_HANDLER(PluginHostMsg_BindFakePluginWindowHandle, - OnBindFakePluginWindowHandle); IPC_MESSAGE_HANDLER(PluginHostMsg_UpdateGeometry_ACK, OnUpdateGeometry_ACK) // Used only on 10.6 and later. @@ -1257,38 +1255,25 @@ WebPluginDelegateProxy::CreateSeekableResourceClient( return proxy; } +CommandBufferProxy* WebPluginDelegateProxy::CreateCommandBuffer() { +#if defined(ENABLE_GPU) #if defined(OS_MACOSX) -void WebPluginDelegateProxy::OnBindFakePluginWindowHandle() { - BindFakePluginWindowHandle(); -} - -// Synthesize a fake window handle for the plug-in to identify the instance -// to the browser, allowing mapping to a surface for hardware acceleration -// of plug-in content. The browser generates the handle which is then set on -// the plug-in. Returns true if it successfully sets the window handle on the -// plug-in. -bool WebPluginDelegateProxy::BindFakePluginWindowHandle() { + // 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 false; + return NULL; OnSetWindow(fake_window); if (!Send(new PluginMsg_SetFakeGPUPluginWindowHandle(instance_id_, fake_window))) { - return false; + return NULL; } - return true; -} #endif -CommandBufferProxy* WebPluginDelegateProxy::CreateCommandBuffer() { -#if defined(ENABLE_GPU) -#if defined(OS_MACOSX) - if (!BindFakePluginWindowHandle()) - return NULL; -#endif int command_buffer_id; if (!Send(new PluginMsg_CreateCommandBuffer(instance_id_, &command_buffer_id))) { diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h index cdeb62a..212758e 100644 --- a/chrome/renderer/webplugin_delegate_proxy.h +++ b/chrome/renderer/webplugin_delegate_proxy.h @@ -149,7 +149,6 @@ class WebPluginDelegateProxy void OnDeferResourceLoading(unsigned long resource_id, bool defer); #if defined(OS_MACOSX) - void OnBindFakePluginWindowHandle(); void OnUpdateGeometry_ACK(int ack_key); void OnGPUPluginSetIOSurface(gfx::PluginWindowHandle window, int32 width, @@ -189,13 +188,6 @@ class WebPluginDelegateProxy void WillDestroyWindow(); #if defined(OS_MACOSX) - // Synthesize a fake window handle for the plug-in to identify the instance - // to the browser, allowing mapping to a surface for hardware acceleration - // of plug-in content. The browser generates the handle which is then set on - // the plug-in. Returns true if it successfully sets the window handle on the - // plug-in. - bool BindFakePluginWindowHandle(); - // The Mac TransportDIB implementation uses base::SharedMemory, which // cannot be disposed of if an in-flight UpdateGeometry message refers to // the shared memory file descriptor. The old_transport_dibs_ map holds diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index b9637e9..e07dc99 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -31,7 +31,13 @@ // XWindowWrapper is stubbed out for unit-tests. #include "gpu/command_buffer/service/x_utils.h" #elif defined(OS_MACOSX) -#include "chrome/common/accelerated_surface_mac.h" +// The following two #includes CAN NOT go above the inclusion of +// gl_utils.h and therefore glew.h regardless of what the Google C++ +// style guide says. +#include <CoreFoundation/CoreFoundation.h> // NOLINT +#include <OpenGL/OpenGL.h> // NOLINT +#include "base/scoped_cftyperef.h" +#include "chrome/common/io_surface_support_mac.h" #endif namespace gpu { @@ -558,6 +564,20 @@ class GLES2DecoderImpl : public GLES2Decoder { #undef GLES2_CMD_OP +#if defined(OS_MACOSX) + // Helper function to generate names for the backing texture, render buffers + // and FBO. On return, the resulting buffer names can be attached to |fbo_|. + // |target| is the target type for the color buffer. + void AllocateRenderBuffers(GLenum target, int32 width, int32 height); + + // Helper function to attach the buffers previously allocated by a call to + // AllocateRenderBuffers(). On return, |fbo_| can be used for + // rendering. |target| must be the same value as used in the call to + // AllocateRenderBuffers(). Returns |true| if the resulting framebuffer + // object is valid. + bool SetupFrameBufferObject(GLenum target); +#endif + // Current GL error bits. uint32 error_bits_; @@ -606,7 +626,32 @@ class GLES2DecoderImpl : public GLES2Decoder { HGLRC gl_context_; HPBUFFERARB pbuffer_; #elif defined(OS_MACOSX) - AcceleratedSurface surface_; + CGLContextObj gl_context_; + CGLPBufferObj pbuffer_; + // Either |io_surface_| or |transport_dib_| is a valid pointer, but not both. + // |io_surface_| is non-NULL if the IOSurface APIs are supported (Mac OS X + // 10.6 and later). + // TODO(dspringer,kbr): Should the GPU backing store be encapsulated in its + // own class so all this implementation detail is hidden? + scoped_cftyperef<CFTypeRef> io_surface_; + // TODO(dspringer): If we end up keeping this TransportDIB mechanism, this + // should really be a scoped_ptr_malloc<>, with a deallocate functor that + // runs |dib_free_callback_|. I was not able to figure out how to + // make this work (or even compile). + scoped_ptr<TransportDIB> transport_dib_; + int32 surface_width_; + int32 surface_height_; + GLuint texture_; + GLuint fbo_; + GLuint depth_stencil_renderbuffer_; + // For tracking whether the default framebuffer / renderbuffer or + // ones created by the end user are currently bound + GLuint bound_fbo_; + GLuint bound_renderbuffer_; + // Allocate a TransportDIB in the renderer. + scoped_ptr<Callback2<size_t, TransportDIB::Handle*>::Type> + dib_alloc_callback_; + scoped_ptr<Callback1<TransportDIB::Id>::Type> dib_free_callback_; #endif bool anti_aliased_; @@ -639,6 +684,16 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) gl_device_context_(NULL), gl_context_(NULL), pbuffer_(NULL), +#elif defined(OS_MACOSX) + gl_context_(NULL), + pbuffer_(NULL), + surface_width_(0), + surface_height_(0), + texture_(0), + fbo_(0), + depth_stencil_renderbuffer_(0), + bound_fbo_(0), + bound_renderbuffer_(0), #endif anti_aliased_(false) { } @@ -946,7 +1001,13 @@ bool GLES2DecoderImpl::MakeCurrent() { #elif defined(OS_LINUX) return window()->MakeCurrent(); #elif defined(OS_MACOSX) - return surface_.MakeCurrent(); + if (CGLGetCurrentContext() != gl_context_) { + if (CGLSetCurrentContext(gl_context_) != kCGLNoError) { + DLOG(ERROR) << "Unable to make gl context current."; + return false; + } + } + return true; #else NOTREACHED(); return false; @@ -1052,7 +1113,48 @@ bool GLES2DecoderImpl::InitPlatformSpecific() { if (!window()->Initialize()) return false; #elif defined(OS_MACOSX) - return surface_.Initialize(); + // Create a 1x1 pbuffer and associated context to bootstrap things + static const CGLPixelFormatAttribute attribs[] = { + (CGLPixelFormatAttribute) kCGLPFAPBuffer, + (CGLPixelFormatAttribute) 0 + }; + CGLPixelFormatObj pixel_format; + GLint num_pixel_formats; + if (CGLChoosePixelFormat(attribs, + &pixel_format, + &num_pixel_formats) != kCGLNoError) { + DLOG(ERROR) << "Error choosing pixel format."; + return false; + } + if (!pixel_format) { + return false; + } + CGLContextObj context; + CGLError res = CGLCreateContext(pixel_format, 0, &context); + CGLDestroyPixelFormat(pixel_format); + if (res != kCGLNoError) { + DLOG(ERROR) << "Error creating context."; + return false; + } + CGLPBufferObj pbuffer; + if (CGLCreatePBuffer(1, 1, + GL_TEXTURE_2D, GL_RGBA, + 0, &pbuffer) != kCGLNoError) { + CGLDestroyContext(context); + DLOG(ERROR) << "Error creating pbuffer."; + return false; + } + if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) { + CGLDestroyContext(context); + CGLDestroyPBuffer(pbuffer); + DLOG(ERROR) << "Error attaching pbuffer to context."; + return false; + } + gl_context_ = context; + pbuffer_ = pbuffer; + // Now we're ready to handle SetWindowSize calls, which will + // allocate and/or reallocate the IOSurface and associated offscreen + // OpenGL structures for rendering. #endif return true; @@ -1138,12 +1240,151 @@ void GLES2DecoderImpl::DestroyPlatformSpecific() { } #if defined(OS_MACOSX) +#if !defined(UNIT_TEST) +static void AddBooleanValue(CFMutableDictionaryRef dictionary, + const CFStringRef key, + bool value) { + CFDictionaryAddValue(dictionary, key, + (value ? kCFBooleanTrue : kCFBooleanFalse)); +} + +static void AddIntegerValue(CFMutableDictionaryRef dictionary, + const CFStringRef key, + int32 value) { + CFNumberRef number = CFNumberCreate(NULL, kCFNumberSInt32Type, &value); + CFDictionaryAddValue(dictionary, key, number); +} +#endif // !defined(UNIT_TEST) + +void GLES2DecoderImpl::AllocateRenderBuffers(GLenum target, + int32 width, int32 height) { + 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); + // Generate and bind the framebuffer object. + glGenFramebuffersEXT(1, &fbo_); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); + bound_fbo_ = fbo_; + // Generate (but don't bind) the depth buffer -- we don't need + // this bound in order to do offscreen rendering. + glGenRenderbuffersEXT(1, &depth_stencil_renderbuffer_); + } + + // Reallocate the depth buffer. + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_renderbuffer_); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH24_STENCIL8_EXT, + width, + height); + + // Unbind the renderbuffers. + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, bound_renderbuffer_); + + // Make sure that subsequent set-up code affects the render texture. + glBindTexture(target, texture_); +} + +bool GLES2DecoderImpl::SetupFrameBufferObject(GLenum target) { + if (bound_fbo_ != fbo_) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); + } + GLenum fbo_status; + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + target, + texture_, + 0); + fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT) { + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, + depth_stencil_renderbuffer_); + fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + } + // Attach the depth and stencil buffer. + if (fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT) { + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT, + GL_RENDERBUFFER_EXT, + depth_stencil_renderbuffer_); + fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + } + if (bound_fbo_ != fbo_) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); + } + return fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT; +} uint64 GLES2DecoderImpl::SetWindowSizeForIOSurface(int32 width, int32 height) { #if defined(UNIT_TEST) return 0; #else - return surface_.SetSurfaceSize(width, height); + if (surface_width_ == width && surface_height_ == height) { + // Return 0 to indicate to the caller that no new backing store + // allocation occurred. + return 0; + } + + IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); + if (!io_surface_support) + return 0; // Caller can try using SetWindowSizeForTransportDIB(). + + if (!MakeCurrent()) + return 0; + + // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on + // Mac OS X and is required for IOSurface interoperability. + GLenum target = GL_TEXTURE_RECTANGLE_ARB; + AllocateRenderBuffers(target, width, height); + + // Allocate a new IOSurface, which is the GPU resource that can be + // shared across processes. + scoped_cftyperef<CFMutableDictionaryRef> properties; + properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + AddIntegerValue(properties, + io_surface_support->GetKIOSurfaceWidth(), width); + AddIntegerValue(properties, + io_surface_support->GetKIOSurfaceHeight(), height); + AddIntegerValue(properties, + io_surface_support->GetKIOSurfaceBytesPerElement(), 4); + AddBooleanValue(properties, + io_surface_support->GetKIOSurfaceIsGlobal(), true); + // I believe we should be able to unreference the IOSurfaces without + // synchronizing with the browser process because they are + // ultimately reference counted by the operating system. + io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); + + // Don't think we need to identify a plane. + GLuint plane = 0; + io_surface_support->CGLTexImageIOSurface2D(gl_context_, + target, + GL_RGBA, + width, + height, + GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, + io_surface_.get(), + plane); + // Set up the frame buffer object. + SetupFrameBufferObject(target); + surface_width_ = width; + surface_height_ = height; + + // Now send back an identifier for the IOSurface. We originally + // intended to send back a mach port from IOSurfaceCreateMachPort + // but it looks like Chrome IPC would need to be modified to + // properly send mach ports between processes. For the time being we + // make our IOSurfaces global and send back their identifiers. On + // the browser process side the identifier is reconstituted into an + // IOSurface for on-screen rendering. + return io_surface_support->IOSurfaceGetID(io_surface_); #endif // !defined(UNIT_TEST) } @@ -1152,14 +1393,61 @@ TransportDIB::Handle GLES2DecoderImpl::SetWindowSizeForTransportDIB( #if defined(UNIT_TEST) return TransportDIB::DefaultHandleValue(); #else - return surface_.SetTransportDIBSize(width, height); + if (surface_width_ == width && surface_height_ == height) { + // Return an invalid handle to indicate to the caller that no new backing + // store allocation occurred. + return TransportDIB::DefaultHandleValue(); + } + surface_width_ = width; + surface_height_ = height; + + // Release the old TransportDIB in the browser. + if (dib_free_callback_.get() && transport_dib_.get()) { + dib_free_callback_->Run(transport_dib_->id()); + } + transport_dib_.reset(); + + // Ask the renderer to create a TransportDIB. + size_t dib_size = width * 4 * height; // 4 bytes per pixel. + TransportDIB::Handle dib_handle; + if (dib_alloc_callback_.get()) { + dib_alloc_callback_->Run(dib_size, &dib_handle); + } + if (!TransportDIB::is_valid(dib_handle)) { + // If the allocator fails, it means the DIB was not created in the browser, + // so there is no need to run the deallocator here. + return TransportDIB::DefaultHandleValue(); + } + transport_dib_.reset(TransportDIB::Map(dib_handle)); + if (transport_dib_.get() == NULL) { + // TODO(dspringer): if the Map() fails, should the deallocator be run so + // that the DIB is deallocated in the browser? + return TransportDIB::DefaultHandleValue(); + } + + // Set up the render buffers and reserve enough space on the card for the + // framebuffer texture. + GLenum target = GL_TEXTURE_RECTANGLE_ARB; + AllocateRenderBuffers(target, width, height); + glTexImage2D(target, + 0, // mipmap level 0 + GL_RGBA8, // internal pixel format + width, + height, + 0, // 0 border + GL_BGRA, // Used for consistency + GL_UNSIGNED_INT_8_8_8_8_REV, + NULL); // No data, just reserve room on the card. + SetupFrameBufferObject(target); + return transport_dib_->handle(); #endif // !defined(UNIT_TEST) } void GLES2DecoderImpl::SetTransportDIBAllocAndFree( Callback2<size_t, TransportDIB::Handle*>::Type* allocator, Callback1<TransportDIB::Id>::Type* deallocator) { - surface_.SetTransportDIBAllocAndFree(allocator, deallocator); + dib_alloc_callback_.reset(allocator); + dib_free_callback_.reset(deallocator); } #endif // defined(OS_MACOSX) @@ -1173,7 +1461,15 @@ void GLES2DecoderImpl::Destroy() { DCHECK(window()); window()->Destroy(); #elif defined(OS_MACOSX) - surface_.Destroy(); + // Release the old TransportDIB in the browser. + if (dib_free_callback_.get() && transport_dib_.get()) { + dib_free_callback_->Run(transport_dib_->id()); + } + transport_dib_.reset(); + if (gl_context_) + CGLDestroyContext(gl_context_); + if (pbuffer_) + CGLDestroyPBuffer(pbuffer_); #endif DestroyPlatformSpecific(); @@ -1432,9 +1728,37 @@ void GLES2DecoderImpl::DoSwapBuffers() { DCHECK(window()); window()->SwapBuffers(); #elif defined(OS_MACOSX) - // TODO(kbr): Need to property hook up and track the OpenGL state and hook - // up the notion of the currently bound FBO. - surface_.SwapBuffers(); + if (bound_fbo_ != fbo_) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); + } + if (io_surface_.get() != NULL) { + // 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_); + } else if (transport_dib_.get() != NULL) { + // Pre-Mac OS X 10.6, fetch the rendered image from the FBO and copy it + // into the TransportDIB. + // TODO(dspringer): There are a couple of options that can speed this up. + // First is to use async reads into a PBO, second is to use SPI that + // allows many tasks to access the same CGSSurface. + void* pixel_memory = transport_dib_->memory(); + if (pixel_memory) { + // Note that glReadPixels does an implicit glFlush(). + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + glReadPixels(0, + 0, + surface_width_, + surface_height_, + GL_BGRA, // This pixel format should have no conversion. + GL_UNSIGNED_INT_8_8_8_8_REV, + pixel_memory); + } + } + if (bound_fbo_ != fbo_) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); + } #endif if (swap_buffers_callback_.get()) { swap_buffers_callback_->Run(); diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index 4cd5b3b..0db965c 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -9,9 +9,6 @@ #include "base/scoped_ptr.h" #include "base/string_piece.h" #include "base/string_util.h" -#if defined(OS_MACOSX) -#include "base/sys_info.h" -#endif #include "base/sys_string_conversions.h" #include "net/base/net_util.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" @@ -39,21 +36,6 @@ static NPAPI::PluginInstance* FindInstance(NPP id) { return reinterpret_cast<NPAPI::PluginInstance*>(id->ndata); } -#if defined(OS_MACOSX) -// Returns true if the OS supports shared accelerated surfaces via IOSurface. -// This is true on Snow Leopard and higher. -static bool SupportsSharingAcceleratedSurfaces() { - int32 major, minor, bugfix; - base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); -#if PINK_USE_COREANIMATION - // TODO(pinkerton): enable this, http://crbug.com/32012 - return major > 10 || (major == 10 && minor > 5); -#else - return false; -#endif -} -#endif - namespace NPAPI { scoped_refptr<PluginHost> PluginHost::singleton_; @@ -775,10 +757,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { } #ifndef NP_NO_QUICKDRAW case NPNVsupportsQuickDrawBool: { - // We do not admit to supporting the QuickDraw drawing model. The logic - // here is that our QuickDraw plugin support is so rudimentary that we - // only want to use it as a fallback to keep plugins from crashing: if a - // plugin knows enough to ask, we want them to use CoreGraphics. + // we do not admit to supporting the QuickDraw drawing model. NPBool* supports_qd = reinterpret_cast<NPBool*>(value); *supports_qd = FALSE; rv = NPERR_NO_ERROR; @@ -796,16 +775,9 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { rv = NPERR_NO_ERROR; break; } + case NPNVsupportsOpenGLBool: case NPNVsupportsCoreAnimationBool: { - // We only support the Core Animation model on 10.6 and higher - NPBool* supports_model = reinterpret_cast<NPBool*>(value); - *supports_model = SupportsSharingAcceleratedSurfaces() ? TRUE : FALSE; - rv = NPERR_NO_ERROR; - break; - } - case NPNVsupportsOpenGLBool: { - // This drawing model was never widely supported, and we don't plan to - // support it. + // we do not support these drawing and event models. NPBool* supports_model = reinterpret_cast<NPBool*>(value); *supports_model = FALSE; rv = NPERR_NO_ERROR; @@ -866,14 +838,14 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { return NPERR_GENERIC_ERROR; #if defined(OS_MACOSX) case NPPVpluginDrawingModel: { + // We only admit to supporting the CoreGraphics drawing model. The logic + // here is that our QuickDraw plugin support is so rudimentary that we + // only want to use it as a fallback to keep plugins from crashing: if + // a plugin knows enough to ask, we want them to use CoreGraphics. int model = reinterpret_cast<int>(value); if (model == NPDrawingModelCoreGraphics) { plugin->set_drawing_model(model); return NPERR_NO_ERROR; - } else if (model == NPDrawingModelCoreAnimation && - SupportsSharingAcceleratedSurfaces()) { - plugin->set_drawing_model(model); - return NPERR_NO_ERROR; } return NPERR_GENERIC_ERROR; } diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 8cf0d03..1327464 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -16,15 +16,10 @@ #include "base/gfx/rect.h" #include "base/ref_counted.h" #include "base/task.h" -#include "base/timer.h" #include "third_party/npapi/bindings/npapi.h" #include "webkit/glue/webcursor.h" #include "webkit/glue/webplugin_delegate.h" -#if defined(OS_MACOSX) -#include "chrome/common/accelerated_surface_mac.h" -#endif - #if defined(USE_X11) typedef struct _GdkDrawable GdkPixmap; #endif @@ -37,19 +32,8 @@ namespace WebKit { class WebMouseEvent; } -#if defined(OS_MACOSX) -class CoreAnimationRedrawTimerSource; -#ifdef __OBJC__ -@class CALayer; -@class CARenderer; -#else -class CALayer; -class CARenderer; -#endif -#endif - -// An implementation of WebPluginDelegate that runs in the plugin process, -// proxied from the renderer by WebPluginDelegateProxy. +// An implementation of WebPluginDelegate that proxies all calls to +// the plugin process. class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { public: enum PluginQuirks { @@ -162,12 +146,6 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // Informs the delegate that the plugin set a Cocoa NSCursor. void SetNSCursor(NSCursor* cursor); - // Informs the browser about the updated accelerated drawing surface. - void UpdateAcceleratedSurface(); - - // Uses a CARenderer to draw the plug-in's layer in our OpenGL surface. - void DrawLayerInSurface(); - #ifndef NP_NO_CARBON // Indicates that it's time to send the plugin a null event. void FireIdleEvent(); @@ -179,11 +157,10 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { } #if defined(OS_MACOSX) - // Allow setting a "fake" window handle to associate this plug-in with - // an IOSurface in the browser. Used for accelerated drawing surfaces. + // On Mac OS X and for the GPU plugin only, this handle is a fake + // one and comes in from the outside world. void set_windowed_handle(gfx::PluginWindowHandle handle) { windowed_handle_ = handle; - UpdateAcceleratedSurface(); } #endif @@ -267,7 +244,7 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // used for windowed plugins // Note: on Mac OS X, the only time the windowed handle is non-zero - // is the case of accelerated rendering, which uses a fake window handle to + // is the case of the GPU plugin, which uses a fake window handle to // identify itself back to the browser. It still performs all of its // work offscreen. gfx::PluginWindowHandle windowed_handle_; @@ -324,10 +301,6 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { #ifndef NP_NO_QUICKDRAW NP_Port qd_port_; #endif - CALayer* layer_; // Used for CA drawing mode. Weak, retained by plug-in. - AcceleratedSurface surface_; - CARenderer* renderer_; // Renders layer_ to surface_. - scoped_ptr<base::RepeatingTimer<WebPluginDelegateImpl> > redraw_timer_; #endif gfx::Rect window_rect_; gfx::Rect clip_rect_; @@ -383,7 +356,7 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { #ifndef NP_NO_CARBON // Moves our dummy window to match the current screen location of the plugin. void UpdateDummyWindowBounds(const gfx::Point& plugin_origin); - + #ifndef NP_NO_QUICKDRAW // Scrapes the contents of our dummy window into the given context. void ScrapeDummyWindowIntoContext(CGContextRef context); diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index c944c64..0a1e84e 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -3,7 +3,6 @@ // found in the LICENSE file. #import <Cocoa/Cocoa.h> -#import <QuartzCore/QuartzCore.h> #include "webkit/glue/plugins/webplugin_delegate_impl.h" @@ -17,6 +16,7 @@ #include "base/scoped_ptr.h" #include "base/stats_counters.h" #include "base/string_util.h" +#include "base/timer.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "webkit/default_plugin/plugin_impl.h" #include "webkit/glue/webplugin.h" @@ -49,8 +49,6 @@ using WebKit::WebInputEvent; using WebKit::WebMouseEvent; using WebKit::WebMouseWheelEvent; -const int kCoreAnimationRedrawPeriodMs = 20; // 50fps - // Important implementation notes: The Mac definition of NPAPI, particularly // the distinction between windowed and windowless modes, differs from the // Windows and Linux definitions. Most of those differences are @@ -171,21 +169,16 @@ class CarbonIdleEventSource { } // namespace -#pragma mark - - WebPluginDelegateImpl::WebPluginDelegateImpl( gfx::PluginWindowHandle containing_view, NPAPI::PluginInstance *instance) - : windowed_handle_(NULL), - windowless_needs_set_window_(true), + : windowless_needs_set_window_(true), // all Mac plugins are "windowless" in the Windows/X11 sense windowless_(true), plugin_(NULL), instance_(instance), parent_(containing_view), buffer_context_(NULL), - layer_(nil), - renderer_(nil), quirks_(0), have_focus_(false), focus_notifier_(NULL), @@ -263,31 +256,6 @@ void WebPluginDelegateImpl::PlatformInitialize() { #endif window_.type = NPWindowTypeDrawable; break; - case NPDrawingModelCoreAnimation: { // Assumes Cocoa event model. - 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. The surface itself will be created when the plug-in - // is sized. - CALayer* layer = nil; - NPError err = instance()->NPP_GetValue(NPPVpluginCoreAnimationLayer, - reinterpret_cast<void*>(&layer)); - if (!err) { - layer_ = layer; - plugin_->BindFakePluginWindowHandle(); - surface_.Initialize(); - UpdateAcceleratedSurface(); - renderer_ = [[CARenderer rendererWithCGLContext:surface_.context() - options:NULL] retain]; - [renderer_ setLayer:layer_]; - redraw_timer_.reset(new base::RepeatingTimer<WebPluginDelegateImpl>); - redraw_timer_->Start( - base::TimeDelta::FromMilliseconds(kCoreAnimationRedrawPeriodMs), - this, - &WebPluginDelegateImpl::DrawLayerInSurface); - } - break; - } default: NOTREACHED(); break; @@ -318,12 +286,6 @@ void WebPluginDelegateImpl::PlatformDestroyInstance() { if (instance()->event_model() == NPEventModelCarbon) CarbonIdleEventSource::SharedInstance()->UnregisterDelegate(this); #endif - if (redraw_timer_.get()) - redraw_timer_->Stop(); - [renderer_ release]; - renderer_ = nil; - layer_ = nil; - surface_.Destroy(); } void WebPluginDelegateImpl::UpdateGeometryAndContext( @@ -417,32 +379,8 @@ void WebPluginDelegateImpl::WindowlessUpdateGeometry( WindowlessSetWindow(true); } -void WebPluginDelegateImpl::DrawLayerInSurface() { - surface_.MakeCurrent(); - - surface_.Clear(window_rect_); - - // Ensure all changes are made before rendering. Not sure where the |-begin| - // comes from, but not doing this causes nothing to render. - [CATransaction commit]; - [renderer_ beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL]; - CGRect layerRect = [layer_ bounds]; - [renderer_ addUpdateRect:layerRect]; - [renderer_ render]; - [renderer_ endFrame]; - - surface_.SwapBuffers(); - plugin_->AcceleratedFrameBuffersDidSwap(windowed_handle()); -} - void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, const gfx::Rect& damage_rect) { - // There is currently nothing to do for the Core Animation drawing model, - // but there have been discussions on the plugin-futures mailing list that - // might require future work. - if (instance()->drawing_model() == NPDrawingModelCoreAnimation) - return; - // If we somehow get a paint before we've set up the plugin buffer, bail. if (!buffer_context_) return; @@ -520,8 +458,6 @@ void WebPluginDelegateImpl::WindowlessSetWindow(bool force_set_window) { SetWindowHasFocus(initial_window_focus_); } - UpdateAcceleratedSurface(); - DCHECK(err == NPERR_NO_ERROR); } @@ -644,30 +580,6 @@ void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) { } } -// Generate an IOSurface for accelerated drawing (but only in the case where a -// window handle has been set). Once the surface has been updated for the -// current size of the plug-in, tell the browser host view so it can adjust its -// bookkeeping and CALayer appropriately. -void WebPluginDelegateImpl::UpdateAcceleratedSurface() { - // Will only have a window handle when using the CoreAnimation drawing model. - if (!windowed_handle() || - instance()->drawing_model() != NPDrawingModelCoreAnimation) - return; - - [layer_ setFrame:CGRectMake(0, 0, - window_rect_.width(), window_rect_.height())]; - [renderer_ setBounds:[layer_ bounds]]; - - uint64 io_surface_id = surface_.SetSurfaceSize(window_rect_.width(), - window_rect_.height()); - if (io_surface_id) { - plugin_->SetAcceleratedSurface(windowed_handle(), - window_rect_.width(), - window_rect_.height(), - io_surface_id); - } -} - void WebPluginDelegateImpl::WindowFrameChanged(gfx::Rect window_frame, gfx::Rect view_frame) { instance()->set_window_frame(window_frame); @@ -688,7 +600,6 @@ void WebPluginDelegateImpl::SetNSCursor(NSCursor* cursor) { void WebPluginDelegateImpl::SetPluginRect(const gfx::Rect& rect) { window_rect_ = rect; - UpdateAcceleratedSurface(); PluginScreenLocationChanged(); } diff --git a/webkit/glue/webplugin.h b/webkit/glue/webplugin.h index 3f9c7e5..d83601a 100644 --- a/webkit/glue/webplugin.h +++ b/webkit/glue/webplugin.h @@ -144,26 +144,6 @@ class WebPlugin { virtual void SetDeferResourceLoading(unsigned long resource_id, bool defer) = 0; -#if defined(OS_MACOSX) - // Synthesize a fake window handle for the plug-in to identify the instance - // to the browser, allowing mapping to a surface for hardware accelleration - // of plug-in content. The browser generates the handle which is then set on - // the plug-in. - virtual void BindFakePluginWindowHandle() {} - - // 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) {} -#endif - // Gets the WebPluginDelegate that implements the interface. // This API is only for use with Pepper, and is only overridden // by in-renderer implementations. diff --git a/webkit/tools/test_shell/mac/accelerated_surface_stub.cc b/webkit/tools/test_shell/mac/accelerated_surface_stub.cc deleted file mode 100644 index 77ca622..0000000 --- a/webkit/tools/test_shell/mac/accelerated_surface_stub.cc +++ /dev/null @@ -1,52 +0,0 @@ -// 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. - -// This file is a complete and total hack intended to stub out some classes -// used by WebPluginDelegateImpl on Mac. Unfortunately, they live in -// chrome/common, so we can't compile them into TestShell. Instead, provide -// some stubs. It will need to be updated if new methods are added to -// AcceleratedSurface that get called from WebPluginDelegateImpl. It's not -// like plug-ins work in TestShell anyway. - -#include <CoreFoundation/CoreFoundation.h> -#include <OpenGL/OpenGL.h> - -#include "base/basictypes.h" -#include "base/gfx/rect.h" -#include "base/scoped_ptr.h" - -class TransportDIB { - public: - TransportDIB() { } - ~TransportDIB() { } -}; - -class AcceleratedSurface { - public: - AcceleratedSurface(); - virtual ~AcceleratedSurface(); - - bool Initialize(); - void Destroy(); - uint64 SetSurfaceSize(int32 width, int32 height); - bool MakeCurrent(); - void Clear(const gfx::Rect& rect); - void SwapBuffers(); - CGLContextObj context() { return NULL; } - private: - scoped_ptr<TransportDIB> ignore_; -}; - -AcceleratedSurface::AcceleratedSurface() { } -AcceleratedSurface::~AcceleratedSurface() { } -bool AcceleratedSurface::Initialize() { return false; } -void AcceleratedSurface::Destroy() { } -uint64 AcceleratedSurface::SetSurfaceSize(int32 width, int32 height) - { return 0; } -bool AcceleratedSurface::MakeCurrent() { return false; } -void AcceleratedSurface::Clear(const gfx::Rect& rect) { } -void AcceleratedSurface::SwapBuffers() { } - -// Needs to be instantiated in order to generate the dtor for the scoped_ptr. -AcceleratedSurface s; diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi index a1bd3cb..a28daf2 100644 --- a/webkit/tools/test_shell/test_shell.gypi +++ b/webkit/tools/test_shell/test_shell.gypi @@ -48,7 +48,6 @@ ], 'msvs_guid': '77C32787-1B96-CB84-B905-7F170629F0AC', 'sources': [ - 'mac/accelerated_surface_stub.cc', 'mac/DumpRenderTreePasteboard.h', 'mac/DumpRenderTreePasteboard.m', 'mac/test_shell_webview.h', diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp index 0754c9f..282bb3b 100644 --- a/webkit/webkit.gyp +++ b/webkit/webkit.gyp @@ -408,11 +408,6 @@ ['exclude', r'/mac_']], }, { # else: OS=="mac" 'sources/': [['exclude', 'plugin_(lib|list)_posix\\.cc$']], - 'link_settings': { - 'libraries': [ - '$(SDKROOT)/QuartzCore.framework', - ], - }, }], ['enable_gpu==1', { 'dependencies': [ |