diff options
Diffstat (limited to 'webkit/glue/plugins/mac_accelerated_surface_container.cc')
| -rw-r--r-- | webkit/glue/plugins/mac_accelerated_surface_container.cc | 158 |
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; +} + |
