summaryrefslogtreecommitdiffstats
path: root/content/browser/renderer_host
diff options
context:
space:
mode:
authormazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-11 03:58:59 +0000
committermazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-11 03:58:59 +0000
commita2a1f48277a24594cecd4b90585ec95923101128 (patch)
tree394b797212f48d6ae3c00485be443e48f0463d09 /content/browser/renderer_host
parentbd985a221a00d320a4fb585c3a5a920724d79621 (diff)
downloadchromium_src-a2a1f48277a24594cecd4b90585ec95923101128.zip
chromium_src-a2a1f48277a24594cecd4b90585ec95923101128.tar.gz
chromium_src-a2a1f48277a24594cecd4b90585ec95923101128.tar.bz2
Implement RenderWidgetHostViewMac::CopyFromCompositingSurface.
This adds the support of the browser side thumbailing to Mac Chrome. BUG=120001 TEST=Manually tested that thumbnails are properly generated on GPU composited pages with --enable-in-browser-thumbnailing. Review URL: http://codereview.chromium.org/10022007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131710 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/renderer_host')
-rw-r--r--content/browser/renderer_host/compositing_iosurface_mac.h24
-rw-r--r--content/browser/renderer_host/compositing_iosurface_mac.mm95
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm12
3 files changed, 111 insertions, 20 deletions
diff --git a/content/browser/renderer_host/compositing_iosurface_mac.h b/content/browser/renderer_host/compositing_iosurface_mac.h
index b81b286..6f0d8da 100644
--- a/content/browser/renderer_host/compositing_iosurface_mac.h
+++ b/content/browser/renderer_host/compositing_iosurface_mac.h
@@ -32,6 +32,12 @@ class CompositingIOSurfaceMac {
// be white.
void DrawIOSurface(NSView* view);
+ // Copy the data of the "live" OpenGL texture referring to this IOSurfaceRef
+ // into |out|. The image data is transformed so that it fits in |dst_size|.
+ // Caller must ensure that |out| is allocated with the size no less than
+ // |4 * dst_size.width() * dst_size.height()| bytes.
+ bool CopyTo(const gfx::Size& dst_size, void* out);
+
// Unref the IOSurface and delete the associated GL texture. If the GPU
// process is no longer referencing it, this will delete the IOSurface.
void UnrefIOSurface();
@@ -66,15 +72,17 @@ class CompositingIOSurfaceMac {
// Counter-clockwise verts starting from upper-left corner (0, 0).
struct SurfaceQuad {
- void set_size(gfx::Size size) {
+ void set_size(gfx::Size vertex_size, gfx::Size texcoord_size) {
// Texture coordinates are flipped vertically so they can be drawn on
// a projection with a flipped y-axis (origin is top left).
- float w = static_cast<float>(size.width());
- float h = static_cast<float>(size.height());
- verts_[0].set(0.0f, 0.0f, 0.0f, h);
- verts_[1].set(0.0f, h, 0.0f, 0.0f);
- verts_[2].set(w, h, w, 0.0f);
- verts_[3].set(w, 0.0f, w, h);
+ float vw = static_cast<float>(vertex_size.width());
+ float vh = static_cast<float>(vertex_size.height());
+ float tw = static_cast<float>(texcoord_size.width());
+ float th = static_cast<float>(texcoord_size.height());
+ verts_[0].set(0.0f, 0.0f, 0.0f, th);
+ verts_[1].set(0.0f, vh, 0.0f, 0.0f);
+ verts_[2].set(vw, vh, tw, 0.0f);
+ verts_[3].set(vw, 0.0f, tw, th);
}
SurfaceVertex verts_[4];
};
@@ -88,6 +96,8 @@ class CompositingIOSurfaceMac {
void UnrefIOSurfaceWithContextCurrent();
+ void DrawQuad(const SurfaceQuad& quad);
+
// Cached pointer to IOSurfaceSupport Singleton.
IOSurfaceSupport* io_surface_support_;
diff --git a/content/browser/renderer_host/compositing_iosurface_mac.mm b/content/browser/renderer_host/compositing_iosurface_mac.mm
index 6b4a53d..f1754cf 100644
--- a/content/browser/renderer_host/compositing_iosurface_mac.mm
+++ b/content/browser/renderer_host/compositing_iosurface_mac.mm
@@ -136,15 +136,7 @@ void CompositingIOSurfaceMac::DrawIOSurface(NSView* view) {
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_); CHECK_GL_ERROR();
glEnable(GL_TEXTURE_RECTANGLE_ARB); CHECK_GL_ERROR();
- glEnableClientState(GL_VERTEX_ARRAY); CHECK_GL_ERROR();
- glEnableClientState(GL_TEXTURE_COORD_ARRAY); CHECK_GL_ERROR();
-
- glVertexPointer(2, GL_FLOAT, sizeof(SurfaceVertex), &quad_.verts_[0].x_);
- glTexCoordPointer(2, GL_FLOAT, sizeof(SurfaceVertex), &quad_.verts_[0].tx_);
- glDrawArrays(GL_QUADS, 0, 4); CHECK_GL_ERROR();
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ DrawQuad(quad_);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); CHECK_GL_ERROR();
}
@@ -154,6 +146,77 @@ void CompositingIOSurfaceMac::DrawIOSurface(NSView* view) {
CGLSetCurrentContext(0);
}
+bool CompositingIOSurfaceMac::CopyTo(const gfx::Size& dst_size, void* out) {
+ if (!MapIOSurfaceToTexture(io_surface_handle_))
+ return false;
+
+ CGLSetCurrentContext(cglContext_);
+ GLuint target = GL_TEXTURE_RECTANGLE_ARB;
+
+ GLuint dst_texture = 0;
+ glGenTextures(1, &dst_texture); CHECK_GL_ERROR();
+ glBindTexture(target, dst_texture); CHECK_GL_ERROR();
+
+ GLuint dst_framebuffer = 0;
+ glGenFramebuffersEXT(1, &dst_framebuffer); CHECK_GL_ERROR();
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, dst_framebuffer); CHECK_GL_ERROR();
+
+ glTexImage2D(target,
+ 0,
+ GL_RGBA,
+ dst_size.width(),
+ dst_size.height(),
+ 0,
+ GL_BGRA,
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ NULL); CHECK_GL_ERROR();
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ target,
+ dst_texture,
+ 0); CHECK_GL_ERROR();
+ glBindTexture(target, 0); CHECK_GL_ERROR();
+
+ glViewport(0, 0, dst_size.width(), dst_size.height());
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, dst_size.width(), 0, dst_size.height(), -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ // Draw only the color channels from the incoming texture.
+ glColorMask(true, true, true, false);
+
+ // Draw the color channels from the incoming texture.
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_); CHECK_GL_ERROR();
+ glEnable(GL_TEXTURE_RECTANGLE_ARB); CHECK_GL_ERROR();
+
+ SurfaceQuad quad;
+ quad.set_size(dst_size, io_surface_size_);
+ DrawQuad(quad);
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); CHECK_GL_ERROR();
+
+ CGLFlushDrawable(cglContext_);
+
+ glReadPixels(0, 0, dst_size.width(), dst_size.height(),
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, out);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CHECK_GL_ERROR();
+
+ glDeleteFramebuffersEXT(1, &dst_framebuffer);
+ glDeleteTextures(1, &dst_texture);
+
+ CGLSetCurrentContext(0);
+ return true;
+}
+
bool CompositingIOSurfaceMac::MapIOSurfaceToTexture(
uint64 io_surface_handle) {
if (io_surface_.get() && io_surface_handle == io_surface_handle_)
@@ -176,7 +239,7 @@ bool CompositingIOSurfaceMac::MapIOSurfaceToTexture(
io_surface_support_->IOSurfaceGetWidth(io_surface_),
io_surface_support_->IOSurfaceGetHeight(io_surface_));
- quad_.set_size(io_surface_size_);
+ quad_.set_size(io_surface_size_, io_surface_size_);
GLenum target = GL_TEXTURE_RECTANGLE_ARB;
glGenTextures(1, &texture_);
@@ -209,6 +272,18 @@ void CompositingIOSurfaceMac::UnrefIOSurface() {
CGLSetCurrentContext(0);
}
+void CompositingIOSurfaceMac::DrawQuad(const SurfaceQuad& quad) {
+ glEnableClientState(GL_VERTEX_ARRAY); CHECK_GL_ERROR();
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY); CHECK_GL_ERROR();
+
+ glVertexPointer(2, GL_FLOAT, sizeof(SurfaceVertex), &quad.verts_[0].x_);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(SurfaceVertex), &quad.verts_[0].tx_);
+ glDrawArrays(GL_QUADS, 0, 4); CHECK_GL_ERROR();
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
void CompositingIOSurfaceMac::UnrefIOSurfaceWithContextCurrent() {
if (texture_) {
glDeleteTextures(1, &texture_);
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 6ba515f..9f5a2de 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -796,9 +796,15 @@ BackingStore* RenderWidgetHostViewMac::AllocBackingStore(
bool RenderWidgetHostViewMac::CopyFromCompositingSurface(
const gfx::Size& size,
skia::PlatformCanvas* output) {
- // TODO(mazda): Implement this.
- NOTIMPLEMENTED();
- return false;
+ if (!compositing_iosurface_.get() ||
+ !compositing_iosurface_->HasIOSurface())
+ return false;
+
+ if (!output->initialize(size.width(), size.height(), true))
+ return false;
+
+ return compositing_iosurface_->CopyTo(
+ size, output->getTopDevice()->accessBitmap(true).getPixels());
}
void RenderWidgetHostViewMac::AsyncCopyFromCompositingSurface(