summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r--webkit/glue/plugins/mac_accelerated_surface_container.cc158
-rw-r--r--webkit/glue/plugins/mac_accelerated_surface_container.h110
-rw-r--r--webkit/glue/plugins/mac_accelerated_surface_container_manager.cc103
-rw-r--r--webkit/glue/plugins/mac_accelerated_surface_container_manager.h78
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h2
5 files changed, 450 insertions, 1 deletions
diff --git a/webkit/glue/plugins/mac_accelerated_surface_container.cc b/webkit/glue/plugins/mac_accelerated_surface_container.cc
new file mode 100644
index 0000000..7d9ae67
--- /dev/null
+++ b/webkit/glue/plugins/mac_accelerated_surface_container.cc
@@ -0,0 +1,158 @@
+// 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 "webkit/glue/plugins/mac_accelerated_surface_container.h"
+
+#include "app/surface/io_surface_support_mac.h"
+#include "base/logging.h"
+#include "webkit/glue/webplugin.h"
+#include "webkit/glue/plugins/mac_accelerated_surface_container_manager.h"
+
+MacAcceleratedSurfaceContainer::MacAcceleratedSurfaceContainer()
+ : x_(0),
+ y_(0),
+ surface_(NULL),
+ width_(0),
+ height_(0),
+ texture_(0) {
+}
+
+MacAcceleratedSurfaceContainer::~MacAcceleratedSurfaceContainer() {
+ ReleaseIOSurface();
+}
+
+void MacAcceleratedSurfaceContainer::ReleaseIOSurface() {
+ if (surface_) {
+ CFRelease(surface_);
+ surface_ = NULL;
+ }
+}
+
+void MacAcceleratedSurfaceContainer::SetSizeAndIOSurface(
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier,
+ MacAcceleratedSurfaceContainerManager* manager) {
+ ReleaseIOSurface();
+ IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
+ if (io_surface_support) {
+ surface_ = io_surface_support->IOSurfaceLookup(
+ static_cast<uint32>(io_surface_identifier));
+ EnqueueTextureForDeletion(manager);
+ width_ = width;
+ height_ = height;
+ }
+}
+
+void MacAcceleratedSurfaceContainer::SetSizeAndTransportDIB(
+ int32 width,
+ int32 height,
+ TransportDIB::Handle transport_dib,
+ MacAcceleratedSurfaceContainerManager* manager) {
+ if (TransportDIB::is_valid(transport_dib)) {
+ transport_dib_.reset(TransportDIB::Map(transport_dib));
+ EnqueueTextureForDeletion(manager);
+ width_ = width;
+ height_ = height;
+ }
+}
+
+void MacAcceleratedSurfaceContainer::MoveTo(
+ const webkit_glue::WebPluginGeometry& geom) {
+ x_ = geom.window_rect.x();
+ y_ = geom.window_rect.y();
+ // TODO(kbr): may need to pay attention to cutout rects.
+ clipRect_ = geom.clip_rect;
+}
+
+void MacAcceleratedSurfaceContainer::Draw(CGLContextObj context) {
+ IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
+ GLenum target = GL_TEXTURE_RECTANGLE_ARB;
+ if (!texture_) {
+ if ((io_surface_support && !surface_) ||
+ (!io_surface_support && !transport_dib_.get()))
+ return;
+ glGenTextures(1, &texture_);
+ glBindTexture(target, texture_);
+ glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ // When using an IOSurface, the texture does not need to be repeatedly
+ // uploaded, so bind the IOSurface once during texture gen in this case.
+ if (io_surface_support) {
+ DCHECK(surface_);
+ // Don't think we need to identify a plane.
+ GLuint plane = 0;
+ io_surface_support->CGLTexImageIOSurface2D(context,
+ target,
+ GL_RGBA,
+ width_,
+ height_,
+ GL_BGRA,
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ surface_,
+ plane);
+ } else {
+ // Reserve space on the card for the actual texture upload, done with the
+ // glTexSubImage2D() call, below.
+ glTexImage2D(target,
+ 0, // mipmap level 0
+ GL_RGBA, // internal format
+ width_,
+ height_,
+ 0, // no border
+ GL_BGRA, // The GPU plugin read BGRA pixels
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ NULL); // No data, this call just reserves room.
+ }
+ }
+
+ // If using TransportDIBs, the texture needs to be uploaded every frame.
+ if (transport_dib_.get() != NULL) {
+ void* pixel_memory = transport_dib_->memory();
+ if (pixel_memory) {
+ glBindTexture(target, texture_);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Needed for NPOT textures.
+ glTexSubImage2D(target,
+ 0, // mipmap level 0
+ 0, // x-offset
+ 0, // y-offset
+ width_,
+ height_,
+ GL_BGRA, // The GPU plugin gave us BGRA pixels
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ pixel_memory);
+ }
+ }
+
+ if (texture_) {
+ // TODO(kbr): convert this to use only OpenGL ES 2.0 functionality
+ glBindTexture(target, texture_);
+ glEnable(target);
+ glBegin(GL_TRIANGLE_STRIP);
+ // TODO(kbr): may need to pay attention to cutout rects.
+ int clipX = clipRect_.x();
+ int clipY = clipRect_.y();
+ int clipWidth = clipRect_.width();
+ int clipHeight = clipRect_.height();
+ int x = x_ + clipX;
+ int y = y_ + clipY;
+ glTexCoord2f(clipX, height_ - clipY);
+ glVertex3f(x, y, 0);
+ glTexCoord2f(clipX + clipWidth, height_ - clipY);
+ glVertex3f(x + clipWidth, y, 0);
+ glTexCoord2f(clipX, height_ - clipY - clipHeight);
+ glVertex3f(x, y + clipHeight, 0);
+ glTexCoord2f(clipX + clipWidth, height_ - clipY - clipHeight);
+ glVertex3f(x + clipWidth, y + clipHeight, 0);
+ glEnd();
+ glDisable(target);
+ }
+}
+
+void MacAcceleratedSurfaceContainer::EnqueueTextureForDeletion(
+ MacAcceleratedSurfaceContainerManager* manager) {
+ manager->EnqueueTextureForDeletion(texture_);
+ texture_ = 0;
+}
+
diff --git a/webkit/glue/plugins/mac_accelerated_surface_container.h b/webkit/glue/plugins/mac_accelerated_surface_container.h
new file mode 100644
index 0000000..0fd1793
--- /dev/null
+++ b/webkit/glue/plugins/mac_accelerated_surface_container.h
@@ -0,0 +1,110 @@
+// 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 WEBKIT_GLUE_PLUGINS_MAC_ACCELERATED_SURFACE_CONTAINER_H_
+#define WEBKIT_GLUE_PLUGINS_MAC_ACCELERATED_SURFACE_CONTAINER_H_
+
+// The "GPU plugin" is currently implemented as a special kind of
+// NPAPI plugin to provide high-performance on-screen 3D rendering for
+// Pepper 3D.
+//
+// On Windows and X11 platforms the GPU plugin relies on cross-process
+// parenting of windows, which is not supported via any public APIs in
+// the Mac OS X window system.
+//
+// To achieve full hardware acceleration we use the new IOSurface APIs
+// introduced in Mac OS X 10.6. The GPU plugin's process produces an
+// IOSurface and renders into it using OpenGL. It uses the
+// IOSurfaceGetID and IOSurfaceLookup APIs to pass a reference to this
+// surface to the browser process for on-screen rendering. The GPU
+// plugin essentially looks like a windowless plugin; the browser
+// process gets all of the mouse events, because the plugin process
+// does not have an on-screen window.
+//
+// This class encapsulates some of the management of these data
+// structures, in conjunction with the MacAcceleratedSurfaceContainerManager.
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <OpenGL/OpenGL.h>
+
+#include "app/gfx/native_widget_types.h"
+#include "app/surface/transport_dib.h"
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/gfx/rect.h"
+
+namespace webkit_glue {
+struct WebPluginGeometry;
+}
+
+class MacAcceleratedSurfaceContainerManager;
+
+class MacAcceleratedSurfaceContainer {
+ public:
+ MacAcceleratedSurfaceContainer();
+ virtual ~MacAcceleratedSurfaceContainer();
+
+ // Sets the backing store and size of this accelerated surface container.
+ // There are two versions: the IOSurface version is used on systems where the
+ // IOSurface API is supported (Mac OS X 10.6 and later); the TransportDIB is
+ // used on Mac OS X 10.5 and earlier.
+ void SetSizeAndIOSurface(int32 width,
+ int32 height,
+ uint64 io_surface_identifier,
+ MacAcceleratedSurfaceContainerManager* manager);
+ void SetSizeAndTransportDIB(int32 width,
+ int32 height,
+ TransportDIB::Handle transport_dib,
+ MacAcceleratedSurfaceContainerManager* manager);
+
+ // Tells the accelerated surface container that it has moved relative to the
+ // origin of the window, for example because of a scroll event.
+ void MoveTo(const webkit_glue::WebPluginGeometry& geom);
+
+ // Draws this accelerated surface's contents, texture mapped onto a quad in
+ // the given OpenGL context. TODO(kbr): figure out and define exactly how the
+ // coordinate system will work out.
+ void Draw(CGLContextObj context);
+
+ // Enqueue our texture for later deletion. Call this before deleting
+ // this object.
+ void EnqueueTextureForDeletion(MacAcceleratedSurfaceContainerManager* manager);
+
+ private:
+ // The x and y coordinates of the plugin window on the web page.
+ int x_;
+ int y_;
+
+ void ReleaseIOSurface();
+
+ // The IOSurfaceRef, if any, that has been handed from the GPU
+ // plugin process back to the browser process for drawing.
+ // This is held as a CFTypeRef because we can't refer to the
+ // IOSurfaceRef type when building on 10.5.
+ CFTypeRef surface_;
+
+ // The TransportDIB which is used in pre-10.6 systems where the IOSurface
+ // API is not supported. This is a weak reference to the actual TransportDIB
+ // whic is owned by the GPU process.
+ scoped_ptr<TransportDIB> transport_dib_;
+
+ // The width and height of the surface.
+ int32 width_;
+ int32 height_;
+
+ // The clip rectangle, relative to the (x_, y_) origin.
+ gfx::Rect clipRect_;
+
+ // The "live" OpenGL texture referring to this IOSurfaceRef. Note
+ // that per the CGLTexImageIOSurface2D API we do not need to
+ // explicitly update this texture's contents once created. All we
+ // need to do is ensure it is re-bound before attempting to draw
+ // with it.
+ GLuint texture_;
+
+ DISALLOW_COPY_AND_ASSIGN(MacAcceleratedSurfaceContainer);
+};
+
+#endif // WEBKIT_GLUE_PLUGINS_MAC_ACCELERATED_SURFACE_CONTAINER_H_
+
diff --git a/webkit/glue/plugins/mac_accelerated_surface_container_manager.cc b/webkit/glue/plugins/mac_accelerated_surface_container_manager.cc
new file mode 100644
index 0000000..a149661
--- /dev/null
+++ b/webkit/glue/plugins/mac_accelerated_surface_container_manager.cc
@@ -0,0 +1,103 @@
+// 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 "webkit/glue/plugins/mac_accelerated_surface_container_manager.h"
+
+#include "base/logging.h"
+#include "webkit/glue/webplugin.h"
+#include "webkit/glue/plugins/mac_accelerated_surface_container.h"
+
+MacAcceleratedSurfaceContainerManager::MacAcceleratedSurfaceContainerManager()
+ : current_id_(0) {
+}
+
+gfx::PluginWindowHandle
+MacAcceleratedSurfaceContainerManager::AllocateFakePluginWindowHandle() {
+ MacAcceleratedSurfaceContainer* container =
+ new MacAcceleratedSurfaceContainer();
+ gfx::PluginWindowHandle res =
+ static_cast<gfx::PluginWindowHandle>(++current_id_);
+ plugin_window_to_container_map_.insert(std::make_pair(res, container));
+ return res;
+}
+
+void MacAcceleratedSurfaceContainerManager::DestroyFakePluginWindowHandle(
+ gfx::PluginWindowHandle id) {
+ MacAcceleratedSurfaceContainer* container = MapIDToContainer(id);
+ if (container)
+ delete container;
+ plugin_window_to_container_map_.erase(id);
+}
+
+void MacAcceleratedSurfaceContainerManager::SetSizeAndIOSurface(
+ gfx::PluginWindowHandle id,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier) {
+ MacAcceleratedSurfaceContainer* container = MapIDToContainer(id);
+ if (container)
+ container->SetSizeAndIOSurface(width, height,
+ io_surface_identifier, this);
+}
+
+void MacAcceleratedSurfaceContainerManager::SetSizeAndTransportDIB(
+ gfx::PluginWindowHandle id,
+ int32 width,
+ int32 height,
+ TransportDIB::Handle transport_dib) {
+ MacAcceleratedSurfaceContainer* container = MapIDToContainer(id);
+ if (container)
+ container->SetSizeAndTransportDIB(width, height,
+ transport_dib, this);
+}
+
+void MacAcceleratedSurfaceContainerManager::MovePluginContainer(
+ const webkit_glue::WebPluginGeometry& move) {
+ MacAcceleratedSurfaceContainer* container = MapIDToContainer(move.window);
+ if (container)
+ container->MoveTo(move);
+}
+
+void MacAcceleratedSurfaceContainerManager::Draw(CGLContextObj context) {
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ GLenum target = GL_TEXTURE_RECTANGLE_ARB;
+ glTexEnvi(target, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ for (PluginWindowToContainerMap::const_iterator i =
+ plugin_window_to_container_map_.begin();
+ i != plugin_window_to_container_map_.end(); ++i) {
+ MacAcceleratedSurfaceContainer* container = i->second;
+ container->Draw(context);
+ }
+
+ // Unbind any texture from the texture target to ensure that the
+ // next time through we will have to re-bind the texture and thereby
+ // pick up modifications from the other process.
+ glBindTexture(target, 0);
+
+ glFlush();
+}
+
+void MacAcceleratedSurfaceContainerManager::EnqueueTextureForDeletion(
+ GLuint texture) {
+ if (texture) {
+ textures_pending_deletion_.push_back(texture);
+ }
+}
+
+MacAcceleratedSurfaceContainer*
+ MacAcceleratedSurfaceContainerManager::MapIDToContainer(
+ gfx::PluginWindowHandle id) {
+ PluginWindowToContainerMap::const_iterator i =
+ plugin_window_to_container_map_.find(id);
+ if (i != plugin_window_to_container_map_.end())
+ return i->second;
+
+ LOG(ERROR) << "Request for plugin container for unknown window id " << id;
+
+ return NULL;
+}
+
diff --git a/webkit/glue/plugins/mac_accelerated_surface_container_manager.h b/webkit/glue/plugins/mac_accelerated_surface_container_manager.h
new file mode 100644
index 0000000..da86e361
--- /dev/null
+++ b/webkit/glue/plugins/mac_accelerated_surface_container_manager.h
@@ -0,0 +1,78 @@
+// 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 WEBKIT_GLUE_PLUGINS_MAC_ACCELERATED_SURFACE_CONTAINER_MANAGER_H_
+#define WEBKIT_GLUE_PLUGINS_MAC_ACCELERATED_SURFACE_CONTAINER_MANAGER_H_
+
+#include <OpenGL/OpenGL.h>
+#include <map>
+#include <vector>
+
+#include "app/gfx/native_widget_types.h"
+#include "app/surface/transport_dib.h"
+#include "base/basictypes.h"
+
+namespace webkit_glue {
+struct WebPluginGeometry;
+}
+
+class MacAcceleratedSurfaceContainer;
+
+// Helper class that manages the backing store and on-screen rendering
+// of instances of the GPU plugin on the Mac.
+class MacAcceleratedSurfaceContainerManager {
+ public:
+ MacAcceleratedSurfaceContainerManager();
+
+ // Allocates a new "fake" PluginWindowHandle, which is used as the
+ // key for the other operations.
+ gfx::PluginWindowHandle AllocateFakePluginWindowHandle();
+
+ // Destroys a fake PluginWindowHandle and associated storage.
+ void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle id);
+
+ // Sets the size and backing store of the plugin instance. There are two
+ // versions: the IOSurface version is used on systems where the IOSurface
+ // API is supported (Mac OS X 10.6 and later); the TransportDIB is used on
+ // Mac OS X 10.5 and earlier.
+ void SetSizeAndIOSurface(gfx::PluginWindowHandle id,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier);
+ void SetSizeAndTransportDIB(gfx::PluginWindowHandle id,
+ int32 width,
+ int32 height,
+ TransportDIB::Handle transport_dib);
+
+ // Takes an update from WebKit about a plugin's position and size and moves
+ // the plugin accordingly.
+ void MovePluginContainer(const webkit_glue::WebPluginGeometry& move);
+
+ // Draws all of the managed plugin containers into the given OpenGL
+ // context, which must already be current.
+ void Draw(CGLContextObj context);
+
+ // Called by the container to enqueue its OpenGL texture objects for
+ // deletion.
+ void EnqueueTextureForDeletion(GLuint texture);
+
+ private:
+ uint32 current_id_;
+
+ // Maps a "fake" plugin window handle to the corresponding container.
+ MacAcceleratedSurfaceContainer* MapIDToContainer(gfx::PluginWindowHandle id);
+
+ // A map that associates plugin window handles with their containers.
+ typedef std::map<gfx::PluginWindowHandle, MacAcceleratedSurfaceContainer*>
+ PluginWindowToContainerMap;
+ PluginWindowToContainerMap plugin_window_to_container_map_;
+
+ // A list of OpenGL textures waiting to be deleted
+ std::vector<GLuint> textures_pending_deletion_;
+
+ DISALLOW_COPY_AND_ASSIGN(MacAcceleratedSurfaceContainerManager);
+};
+
+#endif // WEBKIT_GLUE_PLUGINS_MAC_ACCELERATED_SURFACE_CONTAINER_MANAGER_H_
+
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index 99fadde..e72bb825 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -22,7 +22,7 @@
#include "webkit/glue/webplugin_delegate.h"
#if defined(OS_MACOSX)
-#include "chrome/common/accelerated_surface_mac.h"
+#include "app/surface/accelerated_surface_mac.h"
#endif
#if defined(USE_X11)