summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/renderer_host/gpu_plugin_container_mac.cc158
-rw-r--r--chrome/browser/renderer_host/gpu_plugin_container_mac.h114
-rw-r--r--chrome/browser/renderer_host/gpu_plugin_container_manager_mac.cc100
-rw-r--r--chrome/browser/renderer_host/gpu_plugin_container_manager_mac.h78
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.h2
-rwxr-xr-xchrome/chrome_browser.gypi4
6 files changed, 455 insertions, 1 deletions
diff --git a/chrome/browser/renderer_host/gpu_plugin_container_mac.cc b/chrome/browser/renderer_host/gpu_plugin_container_mac.cc
new file mode 100644
index 0000000..a2b69f4
--- /dev/null
+++ b/chrome/browser/renderer_host/gpu_plugin_container_mac.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 "chrome/browser/renderer_host/gpu_plugin_container_mac.h"
+
+#include "base/logging.h"
+#include "chrome/browser/renderer_host/gpu_plugin_container_manager_mac.h"
+#include "chrome/common/io_surface_support_mac.h"
+#include "webkit/glue/webplugin.h"
+
+MacGPUPluginContainer::MacGPUPluginContainer()
+ : x_(0),
+ y_(0),
+ surface_(NULL),
+ width_(0),
+ height_(0),
+ texture_(0) {
+}
+
+MacGPUPluginContainer::~MacGPUPluginContainer() {
+ ReleaseIOSurface();
+}
+
+void MacGPUPluginContainer::ReleaseIOSurface() {
+ if (surface_) {
+ CFRelease(surface_);
+ surface_ = NULL;
+ }
+}
+
+void MacGPUPluginContainer::SetSizeAndIOSurface(
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier,
+ MacGPUPluginContainerManager* 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 MacGPUPluginContainer::SetSizeAndTransportDIB(
+ int32 width,
+ int32 height,
+ TransportDIB::Handle transport_dib,
+ MacGPUPluginContainerManager* manager) {
+ if (TransportDIB::is_valid(transport_dib)) {
+ transport_dib_.reset(TransportDIB::Map(transport_dib));
+ EnqueueTextureForDeletion(manager);
+ width_ = width;
+ height_ = height;
+ }
+}
+
+void MacGPUPluginContainer::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 MacGPUPluginContainer::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 MacGPUPluginContainer::EnqueueTextureForDeletion(
+ MacGPUPluginContainerManager* manager) {
+ manager->EnqueueTextureForDeletion(texture_);
+ texture_ = 0;
+}
+
diff --git a/chrome/browser/renderer_host/gpu_plugin_container_mac.h b/chrome/browser/renderer_host/gpu_plugin_container_mac.h
new file mode 100644
index 0000000..b985147
--- /dev/null
+++ b/chrome/browser/renderer_host/gpu_plugin_container_mac.h
@@ -0,0 +1,114 @@
+// 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_BROWSER_RENDERER_HOST_GPU_PLUGIN_CONTAINER_MAC_H_
+#define CHROME_BROWSER_RENDERER_HOST_GPU_PLUGIN_CONTAINER_MAC_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 MacGPUPluginContainerManager.
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <OpenGL/OpenGL.h>
+
+#include "app/gfx/native_widget_types.h"
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/gfx/rect.h"
+#include "chrome/common/transport_dib.h"
+
+namespace webkit_glue {
+struct WebPluginGeometry;
+}
+
+class MacGPUPluginContainerManager;
+
+class MacGPUPluginContainer {
+ public:
+ MacGPUPluginContainer();
+ virtual ~MacGPUPluginContainer();
+
+ // Sets the backing store and size of this plugin 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,
+ MacGPUPluginContainerManager* manager);
+ void SetSizeAndTransportDIB(int32 width,
+ int32 height,
+ TransportDIB::Handle transport_dib,
+ MacGPUPluginContainerManager* manager);
+
+ // Tells the plugin 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 plugin'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(MacGPUPluginContainerManager* manager);
+
+ private:
+ // We currently only have a viable implementation of this class on
+ // Snow Leopard. We need to think about fallback strategies that
+ // will work on Leopard.
+
+ // 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(MacGPUPluginContainer);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_GPU_PLUGIN_CONTAINER_MAC_H_
+
diff --git a/chrome/browser/renderer_host/gpu_plugin_container_manager_mac.cc b/chrome/browser/renderer_host/gpu_plugin_container_manager_mac.cc
new file mode 100644
index 0000000..8eae393
--- /dev/null
+++ b/chrome/browser/renderer_host/gpu_plugin_container_manager_mac.cc
@@ -0,0 +1,100 @@
+// 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/browser/renderer_host/gpu_plugin_container_manager_mac.h"
+
+#include "base/logging.h"
+#include "chrome/browser/renderer_host/gpu_plugin_container_mac.h"
+#include "webkit/glue/webplugin.h"
+
+MacGPUPluginContainerManager::MacGPUPluginContainerManager()
+ : current_id_(0) {
+}
+
+gfx::PluginWindowHandle
+MacGPUPluginContainerManager::AllocateFakePluginWindowHandle() {
+ MacGPUPluginContainer* container = new MacGPUPluginContainer();
+ gfx::PluginWindowHandle res =
+ static_cast<gfx::PluginWindowHandle>(++current_id_);
+ plugin_window_to_container_map_.insert(std::make_pair(res, container));
+ return res;
+}
+
+void MacGPUPluginContainerManager::DestroyFakePluginWindowHandle(
+ gfx::PluginWindowHandle id) {
+ MacGPUPluginContainer* container = MapIDToContainer(id);
+ if (container)
+ delete container;
+ plugin_window_to_container_map_.erase(id);
+}
+
+void MacGPUPluginContainerManager::SetSizeAndIOSurface(
+ gfx::PluginWindowHandle id,
+ int32 width,
+ int32 height,
+ uint64 io_surface_identifier) {
+ MacGPUPluginContainer* container = MapIDToContainer(id);
+ if (container)
+ container->SetSizeAndIOSurface(width, height,
+ io_surface_identifier, this);
+}
+
+void MacGPUPluginContainerManager::SetSizeAndTransportDIB(
+ gfx::PluginWindowHandle id,
+ int32 width,
+ int32 height,
+ TransportDIB::Handle transport_dib) {
+ MacGPUPluginContainer* container = MapIDToContainer(id);
+ if (container)
+ container->SetSizeAndTransportDIB(width, height,
+ transport_dib, this);
+}
+
+void MacGPUPluginContainerManager::MovePluginContainer(
+ const webkit_glue::WebPluginGeometry& move) {
+ MacGPUPluginContainer* container = MapIDToContainer(move.window);
+ if (container)
+ container->MoveTo(move);
+}
+
+void MacGPUPluginContainerManager::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) {
+ MacGPUPluginContainer* 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 MacGPUPluginContainerManager::EnqueueTextureForDeletion(GLuint texture) {
+ if (texture) {
+ textures_pending_deletion_.push_back(texture);
+ }
+}
+
+MacGPUPluginContainer* MacGPUPluginContainerManager::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/chrome/browser/renderer_host/gpu_plugin_container_manager_mac.h b/chrome/browser/renderer_host/gpu_plugin_container_manager_mac.h
new file mode 100644
index 0000000..89e8620
--- /dev/null
+++ b/chrome/browser/renderer_host/gpu_plugin_container_manager_mac.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 CHROME_BROWSER_RENDERER_HOST_GPU_PLUGIN_CONTAINER_MANAGER_MAC_H_
+#define CHROME_BROWSER_RENDERER_HOST_GPU_PLUGIN_CONTAINER_MANAGER_MAC_H_
+
+#include <OpenGL/OpenGL.h>
+#include <map>
+#include <vector>
+
+#include "app/gfx/native_widget_types.h"
+#include "base/basictypes.h"
+#include "chrome/common/transport_dib.h"
+
+namespace webkit_glue {
+struct WebPluginGeometry;
+}
+
+class MacGPUPluginContainer;
+
+// Helper class that manages the backing store and on-screen rendering
+// of instances of the GPU plugin on the Mac.
+class MacGPUPluginContainerManager {
+ public:
+ MacGPUPluginContainerManager();
+
+ // 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.
+ MacGPUPluginContainer* MapIDToContainer(gfx::PluginWindowHandle id);
+
+ // A map that associates plugin window handles with their containers.
+ typedef std::map<gfx::PluginWindowHandle, MacGPUPluginContainer*>
+ 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(MacGPUPluginContainerManager);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_GPU_PLUGIN_CONTAINER_MANAGER_MAC_H_
+
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h
index c8e4078..6433653 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h
@@ -13,10 +13,10 @@
#include "base/task.h"
#include "base/time.h"
#include "chrome/browser/cocoa/base_view.h"
+#include "chrome/browser/renderer_host/gpu_plugin_container_manager_mac.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "webkit/glue/webcursor.h"
#include "webkit/glue/webmenuitem.h"
-#include "webkit/glue/plugins/mac_gpu_plugin_container_manager.h"
class RenderWidgetHostViewMac;
class RWHVMEditCommandHelper;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index af3fcb8..6bb8d74 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1658,6 +1658,10 @@
'browser/renderer_host/global_request_id.h',
'browser/renderer_host/gpu_view_host.cc',
'browser/renderer_host/gpu_view_host.h',
+ 'browser/renderer_host/gpu_plugin_container_mac.cc',
+ 'browser/renderer_host/gpu_plugin_container_mac.h',
+ 'browser/renderer_host/gpu_plugin_container_manager_mac.cc',
+ 'browser/renderer_host/gpu_plugin_container_manager_mac.h',
'browser/renderer_host/gtk_im_context_wrapper.cc',
'browser/renderer_host/gtk_im_context_wrapper.h',
'browser/renderer_host/gtk_key_bindings_handler.cc',