summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins/mac_accelerated_surface_container.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/glue/plugins/mac_accelerated_surface_container.cc')
-rw-r--r--webkit/glue/plugins/mac_accelerated_surface_container.cc158
1 files changed, 158 insertions, 0 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;
+}
+