Commit 474e4dc5 authored by mazda@chromium.org's avatar mazda@chromium.org

Support copying a partial rectangle region from the compositing surface on Mac.

This CL also made RenderWidgetHostView::MacCopyFromCompositingSurface support HiDPI.

BUG=118571
TEST=Manual


Review URL: https://chromiumcodereview.appspot.com/10835014

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148690 0039d316-1c4b-4281-b951-d872f2087c98
parent b741edc2
......@@ -15,6 +15,10 @@
class IOSurfaceSupport;
namespace gfx {
class Rect;
}
namespace content {
// This class manages an OpenGL context and IOSurface for the accelerated
......@@ -35,10 +39,14 @@ class CompositingIOSurfaceMac {
void DrawIOSurface(NSView* view, float scale_factor);
// 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|.
// into |out|. The copied region is specified with |src_pixel_subrect| and
// the data is transformed so that it fits in |dst_pixel_size|.
// |src_pixel_subrect| and |dst_pixel_size| are not in DIP but in pixel.
// 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);
// |4 * dst_pixel_size.width() * dst_pixel_size.height()| bytes.
bool CopyTo(const gfx::Rect& src_pixel_subrect,
const gfx::Size& dst_pixel_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.
......@@ -65,7 +73,6 @@ class CompositingIOSurfaceMac {
// Vertex structure for use in glDraw calls.
struct SurfaceVertex {
SurfaceVertex() : x_(0.0f), y_(0.0f), tx_(0.0f), ty_(0.0f) { }
// Currently the texture coords are always the same as vertex coords.
void set(float x, float y, float tx, float ty) {
x_ = x;
y_ = y;
......@@ -76,6 +83,10 @@ class CompositingIOSurfaceMac {
x_ = x;
y_ = y;
}
void set_texcoord(float tx, float ty) {
tx_ = tx;
ty_ = ty;
}
float x_;
float y_;
float tx_;
......@@ -102,6 +113,14 @@ class CompositingIOSurfaceMac {
verts_[2].set_position(x2, y2);
verts_[3].set_position(x2, y1);
}
void set_texcoord_rect(float tx1, float ty1, float tx2, float ty2) {
// Texture coordinates are flipped vertically so they can be drawn on
// a projection with a flipped y-axis (origin is top left).
verts_[0].set_texcoord(tx1, ty2);
verts_[1].set_texcoord(tx1, ty1);
verts_[2].set_texcoord(tx2, ty1);
verts_[3].set_texcoord(tx2, ty2);
}
SurfaceVertex verts_[4];
};
......
......@@ -12,6 +12,7 @@
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
#include "content/public/browser/browser_thread.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_switches.h"
......@@ -303,7 +304,10 @@ void CompositingIOSurfaceMac::DrawIOSurface(NSView* view, float scale_factor) {
CGLSetCurrentContext(0);
}
bool CompositingIOSurfaceMac::CopyTo(const gfx::Size& dst_size, void* out) {
bool CompositingIOSurfaceMac::CopyTo(
const gfx::Rect& src_pixel_subrect,
const gfx::Size& dst_pixel_size,
void* out) {
if (!MapIOSurfaceToTexture(io_surface_handle_))
return false;
......@@ -321,8 +325,8 @@ bool CompositingIOSurfaceMac::CopyTo(const gfx::Size& dst_size, void* out) {
glTexImage2D(target,
0,
GL_RGBA,
dst_size.width(),
dst_size.height(),
dst_pixel_size.width(),
dst_pixel_size.height(),
0,
GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV,
......@@ -334,11 +338,11 @@ bool CompositingIOSurfaceMac::CopyTo(const gfx::Size& dst_size, void* out) {
0); CHECK_GL_ERROR();
glBindTexture(target, 0); CHECK_GL_ERROR();
glViewport(0, 0, dst_size.width(), dst_size.height());
glViewport(0, 0, dst_pixel_size.width(), dst_pixel_size.height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, dst_size.width(), 0, dst_size.height(), -1, 1);
glOrtho(0, dst_pixel_size.width(), 0, dst_pixel_size.height(), -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
......@@ -353,7 +357,9 @@ bool CompositingIOSurfaceMac::CopyTo(const gfx::Size& dst_size, void* out) {
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_);
SurfaceQuad quad;
quad.set_size(dst_size, pixel_io_surface_size_);
quad.set_rect(0.0f, 0.0f, dst_pixel_size.width(), dst_pixel_size.height());
quad.set_texcoord_rect(src_pixel_subrect.x(), src_pixel_subrect.y(),
src_pixel_subrect.right(), src_pixel_subrect.bottom());
DrawQuad(quad);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); CHECK_GL_ERROR();
......@@ -361,7 +367,7 @@ bool CompositingIOSurfaceMac::CopyTo(const gfx::Size& dst_size, void* out) {
CGLFlushDrawable(cglContext_);
glReadPixels(0, 0, dst_size.width(), dst_size.height(),
glReadPixels(0, 0, dst_pixel_size.width(), dst_pixel_size.height(),
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, out);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CHECK_GL_ERROR();
......
......@@ -503,12 +503,12 @@ void RenderWidgetHostImpl::CopyFromBackingStore(
if (view_ && is_accelerated_compositing_active_) {
TRACE_EVENT0("browser",
"RenderWidgetHostImpl::CopyFromBackingStore::FromCompositingSurface");
#if defined(USE_AURA) || defined(OS_LINUX)
#if defined(USE_AURA) || defined(OS_LINUX) || defined(OS_MACOSX)
gfx::Rect copy_rect = src_subrect.IsEmpty() ?
gfx::Rect(view_->GetViewBounds().size()) : src_subrect;
#else
// Just passes an empty rect to CopyFromCompositingSurface on non-Aura Win
// and Mac because copying a partial rectangle is not supported.
// because copying a partial rectangle is not supported.
gfx::Rect copy_rect;
#endif
view_->CopyFromCompositingSurface(copy_rect,
......
......@@ -822,22 +822,22 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurface(
const base::Callback<void(bool)>& callback,
skia::PlatformCanvas* output) {
base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
// TODO(mazda): Support copying a partial rectangle from the compositing
// surface with |src_subrect| (http://crbug.com/118571).
if (!src_subrect.IsEmpty()) {
NOTIMPLEMENTED();
return;
}
if (!compositing_iosurface_.get() ||
!compositing_iosurface_->HasIOSurface())
return;
if (!output->initialize(dst_size.width(), dst_size.height(), true))
float scale = ScaleFactor(cocoa_view_);
gfx::Size dst_pixel_size = dst_size.Scale(scale);
if (!output->initialize(
dst_pixel_size.width(), dst_pixel_size.height(), true))
return;
gfx::Rect src_pixel_subrect(src_subrect.origin().Scale(scale),
src_subrect.size().Scale(scale));
const bool result = compositing_iosurface_->CopyTo(
dst_size, output->getTopDevice()->accessBitmap(true).getPixels());
src_pixel_subrect,
dst_pixel_size,
output->getTopDevice()->accessBitmap(true).getPixels());
scoped_callback_runner.Release();
callback.Run(result);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment