summaryrefslogtreecommitdiffstats
path: root/content/browser
diff options
context:
space:
mode:
authorjbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-09 01:29:39 +0000
committerjbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-09 01:29:39 +0000
commit8c49844ef9aeda8e7f7ea8fde657b39ad5766bc0 (patch)
tree6f162cf06be9e4d5b4cd69337de9305274339663 /content/browser
parenta1da28cad77e028c38f54c6355cfcd1b96a705df (diff)
downloadchromium_src-8c49844ef9aeda8e7f7ea8fde657b39ad5766bc0.zip
chromium_src-8c49844ef9aeda8e7f7ea8fde657b39ad5766bc0.tar.gz
chromium_src-8c49844ef9aeda8e7f7ea8fde657b39ad5766bc0.tar.bz2
Optimize Mac OSX IOSurface blit code.
Review URL: https://chromiumcodereview.appspot.com/10384058 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135967 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/renderer_host/compositing_iosurface_mac.h20
-rw-r--r--content/browser/renderer_host/compositing_iosurface_mac.mm174
2 files changed, 165 insertions, 29 deletions
diff --git a/content/browser/renderer_host/compositing_iosurface_mac.h b/content/browser/renderer_host/compositing_iosurface_mac.h
index 6f0d8da..697102d 100644
--- a/content/browser/renderer_host/compositing_iosurface_mac.h
+++ b/content/browser/renderer_host/compositing_iosurface_mac.h
@@ -64,6 +64,10 @@ class CompositingIOSurfaceMac {
tx_ = tx;
ty_ = ty;
}
+ void set_position(float x, float y) {
+ x_ = x;
+ y_ = y;
+ }
float x_;
float y_;
float tx_;
@@ -84,12 +88,21 @@ class CompositingIOSurfaceMac {
verts_[2].set(vw, vh, tw, 0.0f);
verts_[3].set(vw, 0.0f, tw, th);
}
+ void set_rect(float x1, float y1, float x2, float y2) {
+ verts_[0].set_position(x1, y1);
+ verts_[1].set_position(x1, y2);
+ verts_[2].set_position(x2, y2);
+ verts_[3].set_position(x2, y1);
+ }
SurfaceVertex verts_[4];
};
CompositingIOSurfaceMac(IOSurfaceSupport* io_surface_support,
NSOpenGLContext* glContext,
- CGLContextObj cglContext);
+ CGLContextObj cglContext,
+ GLuint shader_program_blit_rgb,
+ GLint blit_rgb_sampler_location,
+ GLuint shader_program_white);
// Returns true if IOSurface is ready to render. False otherwise.
bool MapIOSurfaceToTexture(uint64 io_surface_handle);
@@ -119,6 +132,11 @@ class CompositingIOSurfaceMac {
// with it.
GLuint texture_;
+ // Shader parameters.
+ GLuint shader_program_blit_rgb_;
+ GLint blit_rgb_sampler_location_;
+ GLuint shader_program_white_;
+
SurfaceQuad quad_;
};
diff --git a/content/browser/renderer_host/compositing_iosurface_mac.mm b/content/browser/renderer_host/compositing_iosurface_mac.mm
index 61133a7..9c35fb7 100644
--- a/content/browser/renderer_host/compositing_iosurface_mac.mm
+++ b/content/browser/renderer_host/compositing_iosurface_mac.mm
@@ -25,6 +25,84 @@
} while (0)
#endif
+#define SHADER_STRING_GLSL(shader) #shader
+
+namespace {
+
+static const char* g_vertex_shader_blit_rgb = SHADER_STRING_GLSL(
+ varying vec2 texture_coordinate;
+ void main() {
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+ texture_coordinate = vec2(gl_MultiTexCoord0);
+ });
+
+static const char* g_fragment_shader_blit_rgb = SHADER_STRING_GLSL(
+ varying vec2 texture_coordinate;
+ uniform sampler2DRect texture;
+ void main() {
+ gl_FragColor = vec4(texture2DRect(texture, texture_coordinate).rgb, 1.0);
+ });
+
+static const char* g_vertex_shader_white = SHADER_STRING_GLSL(
+ void main() {
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+ });
+
+static const char* g_fragment_shader_white = SHADER_STRING_GLSL(
+ void main() {
+ gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+ });
+
+// Create and compile shader, return its ID or 0 on error.
+GLuint CompileShaderGLSL(GLenum type, const char* shader_str) {
+ GLuint shader = glCreateShader(type);
+ glShaderSource(shader, 1, &shader_str, NULL);
+ glCompileShader(shader); CHECK_GL_ERROR();
+ GLint error;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &error);
+ if (error != GL_TRUE) {
+ glDeleteShader(shader);
+ return 0;
+ }
+ return shader;
+}
+
+// Compile the given vertex and shader source strings into a GLSL program.
+GLuint CreateProgramGLSL(const char* vertex_shader_str,
+ const char* fragment_shader_str) {
+ GLuint vertex_shader =
+ CompileShaderGLSL(GL_VERTEX_SHADER, vertex_shader_str);
+ if (!vertex_shader)
+ return 0;
+
+ GLuint fragment_shader =
+ CompileShaderGLSL(GL_FRAGMENT_SHADER, fragment_shader_str);
+ if (!fragment_shader) {
+ glDeleteShader(vertex_shader);
+ return 0;
+ }
+
+ GLuint program = glCreateProgram(); CHECK_GL_ERROR();
+ glAttachShader(program, vertex_shader);
+ glAttachShader(program, fragment_shader);
+ glLinkProgram(program); CHECK_GL_ERROR();
+
+ // Flag shaders for deletion so that they will be deleted when the program
+ // is deleted. That way we don't have to retain these IDs.
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+
+ GLint error;
+ glGetProgramiv(program, GL_LINK_STATUS, &error);
+ if (error != GL_TRUE) {
+ glDeleteProgram(program);
+ return 0;
+ }
+ return program;
+}
+
+} // namespace
+
CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create() {
TRACE_EVENT0("browser", "CompositingIOSurfaceMac::Create");
IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
@@ -75,18 +153,44 @@ CompositingIOSurfaceMac* CompositingIOSurfaceMac::Create() {
swapInterval = 1;
[glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+ // Build shaders.
+ CGLSetCurrentContext(cglContext);
+ GLuint shader_program_blit_rgb =
+ CreateProgramGLSL(g_vertex_shader_blit_rgb, g_fragment_shader_blit_rgb);
+ GLuint shader_program_white =
+ CreateProgramGLSL(g_vertex_shader_white, g_fragment_shader_white);
+ GLint blit_rgb_sampler_location =
+ glGetUniformLocation(shader_program_blit_rgb, "texture");
+ CGLSetCurrentContext(0);
+
+ if (!shader_program_blit_rgb || !shader_program_white ||
+ blit_rgb_sampler_location == -1) {
+ LOG(ERROR) << "IOSurface shader build error";
+ return NULL;
+ }
+
return new CompositingIOSurfaceMac(io_surface_support, glContext.release(),
- cglContext);
+ cglContext,
+ shader_program_blit_rgb,
+ blit_rgb_sampler_location,
+ shader_program_white);
}
CompositingIOSurfaceMac::CompositingIOSurfaceMac(
IOSurfaceSupport* io_surface_support,
NSOpenGLContext* glContext,
- CGLContextObj cglContext)
+ CGLContextObj cglContext,
+ GLuint shader_program_blit_rgb,
+ GLint blit_rgb_sampler_location,
+ GLuint shader_program_white)
: io_surface_support_(io_surface_support),
glContext_(glContext),
cglContext_(cglContext),
- io_surface_handle_(0) {
+ io_surface_handle_(0),
+ texture_(0),
+ shader_program_blit_rgb_(shader_program_blit_rgb),
+ blit_rgb_sampler_location_(blit_rgb_sampler_location),
+ shader_program_white_(shader_program_white) {
}
CompositingIOSurfaceMac::~CompositingIOSurfaceMac() {
@@ -108,39 +212,54 @@ void CompositingIOSurfaceMac::DrawIOSurface(NSView* view) {
"has_io_surface", has_io_surface);
[glContext_ setView:view];
- NSSize window_size = [view frame].size;
- glViewport(0, 0, window_size.width, window_size.height);
+ gfx::Size window_size([view frame].size.width, [view frame].size.height);
+ glViewport(0, 0, window_size.width(), window_size.height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(0, window_size.width, window_size.height, 0, -1, 1);
+ glOrtho(0, window_size.width(), window_size.height(), 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
- glColorMask(true, true, true, true);
- // Should match the clear color of RenderWidgetHostViewMac.
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- // TODO(jbates): Just clear the right and bottom edges when the size doesn't
- // match the window. Then use a shader to blit the texture without its alpha
- // channel.
- glClear(GL_COLOR_BUFFER_BIT);
-
if (has_io_surface) {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- // Draw only the color channels from the incoming texture.
- glColorMask(true, true, true, false);
+ glUseProgram(shader_program_blit_rgb_);
- // 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();
+ int texture_unit = 0;
+ glUniform1i(blit_rgb_sampler_location_, texture_unit);
+ glActiveTexture(GL_TEXTURE0 + texture_unit);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_);
DrawQuad(quad_);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); CHECK_GL_ERROR();
+
+ // Fill the resize gutters with white.
+ if (window_size.width() > io_surface_size_.width() ||
+ window_size.height() > io_surface_size_.height()) {
+ glUseProgram(shader_program_white_);
+ SurfaceQuad filler_quad;
+ if (window_size.width() > io_surface_size_.width()) {
+ // Draw right-side gutter down to the bottom of the window.
+ filler_quad.set_rect(io_surface_size_.width(), 0.0f,
+ window_size.width(), window_size.height());
+ DrawQuad(filler_quad);
+ }
+ if (window_size.height() > io_surface_size_.height()) {
+ // Draw bottom gutter to the width of the IOSurface.
+ filler_quad.set_rect(0.0f, io_surface_size_.height(),
+ io_surface_size_.width(), window_size.height());
+ DrawQuad(filler_quad);
+ }
+ }
+
+ glUseProgram(0); CHECK_GL_ERROR();
+ } else {
+ // Should match the clear color of RenderWidgetHostViewMac.
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
}
CGLFlushDrawable(cglContext_);
@@ -190,20 +309,19 @@ bool CompositingIOSurfaceMac::CopyTo(const gfx::Size& dst_size, void* out) {
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);
+ glUseProgram(shader_program_blit_rgb_);
- // 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();
+ int texture_unit = 0;
+ glUniform1i(blit_rgb_sampler_location_, texture_unit);
+ glActiveTexture(GL_TEXTURE0 + texture_unit);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_);
SurfaceQuad quad;
quad.set_size(dst_size, io_surface_size_);
DrawQuad(quad);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); CHECK_GL_ERROR();
+ glUseProgram(0);
CGLFlushDrawable(cglContext_);