Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc |
| =================================================================== |
| --- gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc (revision 0) |
| +++ gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc (revision 0) |
| @@ -0,0 +1,232 @@ |
| +// Copyright (c) 2012 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 "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
| +#include "gpu/command_buffer/common/types.h" |
| +//#include "gpu/command_buffer/common/gles2_cmd_format.h" |
|
greggman
2012/04/04 20:12:24
remove?
Jeff Timanus
2012/04/04 22:34:14
Done.
|
| +#include "gpu/command_buffer/service/gl_utils.h" |
| + |
| +#define SHADER0(Src) #Src |
| +#define SHADER(Src) SHADER0(Src) |
| + |
| +namespace { |
| + |
| +enum ShaderId { |
| + VERTEX_SHADER_POS_TEX, |
| + FRAGMENT_SHADER_TEX, |
| + FRAGMENT_SHADER_TEX_FLIP_Y, |
| + FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA, |
| + FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y |
| +}; |
| + |
| +enum ProgramId { |
| + PROGRAM_COPY_TEXTURE, |
| + PROGRAM_COPY_TEXTURE_FLIP_Y, |
| + PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, |
| + PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY |
| +}; |
| + |
| +// Returns the correct program to evaluate the copy operation for |
| +// the CHROMIUM_flipy and premultiply alpha pixel store settings. |
| +ProgramId GetProgram(bool flip_y, bool premultiply_alpha) { |
| + if (flip_y && premultiply_alpha) |
| + return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY; |
| + |
| + if (flip_y) |
| + return PROGRAM_COPY_TEXTURE_FLIP_Y; |
| + |
| + if (premultiply_alpha) |
| + return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA; |
| + |
| + return PROGRAM_COPY_TEXTURE; |
| +} |
| + |
| +const char* GetShaderSource(ShaderId shader) { |
| + switch (shader) { |
| + case VERTEX_SHADER_POS_TEX: |
| + return SHADER( |
| + precision mediump float; |
| + attribute vec4 a_position; |
| + attribute vec2 a_texCoord; |
| + varying vec2 v_uv; |
| + void main(void) { |
| + gl_Position = a_position; |
| + v_uv = a_texCoord; |
| + }); |
| + case FRAGMENT_SHADER_TEX: |
| + return SHADER( |
| + precision mediump float; |
| + uniform sampler2D u_texSampler; |
| + varying vec2 v_uv; |
| + void main(void) { |
| + gl_FragColor = texture2D(u_texSampler, v_uv.st); |
| + }); |
| + case FRAGMENT_SHADER_TEX_FLIP_Y: |
| + return SHADER( |
| + precision mediump float; |
| + uniform sampler2D u_texSampler; |
| + varying vec2 v_uv; |
| + void main(void) { |
| + gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
| + }); |
| + case FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA: |
| + return SHADER( |
| + precision mediump float; |
| + uniform sampler2D u_texSampler; |
| + varying vec2 v_uv; |
| + void main(void) { |
| + gl_FragColor = texture2D(u_texSampler, v_uv.st); |
| + gl_FragColor.rgb *= gl_FragColor.a; |
| + }); |
| + case FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y: |
| + return SHADER( |
| + precision mediump float; |
| + uniform sampler2D u_texSampler; |
| + varying vec2 v_uv; |
| + void main(void) { |
| + gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
| + gl_FragColor.rgb *= gl_FragColor.a; |
| + }); |
| + default: |
| + return 0; |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| +CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() { |
| + FreeResources(); |
| +} |
| + |
| +void CopyTextureCHROMIUMResourceManager::Initialize() { |
| + // Initialize all of the GPU resources required to perform the copy. |
| + GLfloat texture_vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, |
| + 1.0f, -1.0f, 0.0f, 1.0f, |
| + 1.0f, 1.0f, 0.0f, 1.0f, |
| + -1.0f, 1.0f, 0.0f, 1.0f }; |
| + |
| + GLfloat texture_coords[] = { 0.0f, 0.0f, |
| + 1.0f, 0.0f, |
| + 1.0f, 1.0f, |
| + 0.0f, 1.0f }; |
| + |
| + glGenBuffersARB(2, buffer_ids_); |
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); |
| + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), texture_vertices, |
| + GL_STATIC_DRAW); |
| + |
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); |
| + glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), texture_coords, |
| + GL_STATIC_DRAW); |
| + |
| + glGenFramebuffersEXT(1, &framebuffer_); |
| + |
| + shaders_[0] = glCreateShader(GL_VERTEX_SHADER); |
| + const char* shader_source = GetShaderSource(VERTEX_SHADER_POS_TEX); |
| + glShaderSource(shaders_[0], 1, &shader_source, 0); |
| + for (int shader = 1; shader < kNumShaders; ++shader) { |
| + shaders_[shader] = glCreateShader(GL_FRAGMENT_SHADER); |
| + shader_source = GetShaderSource(static_cast<ShaderId>(shader)); |
| + glShaderSource(shaders_[shader], 1, &shader_source, 0); |
| + } |
| + |
| + for (int shader = 0; shader < kNumShaders; ++shader) { |
| + glCompileShader(shaders_[shader]); |
| +#ifndef NDEBUG |
| + GLint compile_status; |
| + glGetShaderiv(shaders_[shader], GL_COMPILE_STATUS, &compile_status); |
| + if (GL_TRUE != compile_status) |
| + DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; |
| +#endif |
| + } |
| + |
| + for (int program = 0; program < kNumPrograms; ++program) { |
| + programs_[program] = glCreateProgram(); |
| + glAttachShader(programs_[program], shaders_[0]); |
| + glAttachShader(programs_[program], shaders_[program + 1]); |
| + |
| + glLinkProgram(programs_[program]); |
| +#ifndef NDEBUG |
| + GLint linked; |
| + glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); |
| + if (!linked) |
| + DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; |
| +#endif |
| + |
| + position_locations_[program] = glGetAttribLocation(programs_[program], |
| + "a_position"); |
| + texture_coordinate_locations_[program] = glGetAttribLocation( |
| + programs_[program], "a_texCoord"); |
| + sampler_locations_[program] = glGetUniformLocation(programs_[program], |
| + "u_texSampler"); |
| + } |
| +} |
| + |
| +void CopyTextureCHROMIUMResourceManager::FreeResources() { |
| + glDeleteFramebuffersEXT(1, &framebuffer_); |
| + |
| + for (int shader = 0; shader < kNumShaders; ++shader) |
|
greggman
2012/04/04 20:12:24
Once you've linked the programs there's no need to
Jeff Timanus
2012/04/04 22:34:14
Thanks for the suggestion. Done.
|
| + glDeleteShader(shaders_[shader]); |
| + |
| + for (int program = 0; program < kNumPrograms; ++program) |
| + glDeleteProgram(programs_[program]); |
| + |
| + glDeleteBuffersARB(2, buffer_ids_); |
| +} |
| + |
| +void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
| + GLenum target, |
| + GLuint source_id, |
| + GLuint dest_id, |
| + GLint level, |
| + bool flip_y, |
| + bool premultiply_alpha) { |
| + GLuint program = GetProgram(flip_y, premultiply_alpha); |
| + glUseProgram(programs_[program]); |
| + |
| +#ifndef NDEBUG |
| + glValidateProgram(program); |
| + GLint validation_status; |
| + glGetProgramiv(program, GL_VALIDATE_STATUS, &validation_status); |
| + DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; |
| +#endif |
| + |
| + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); |
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, |
| + dest_id, level); |
| + |
| +#ifndef NDEBUG |
| + GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| + DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; |
| +#endif |
| + |
| + glBindBuffer(GL_ARRAY_BUFFER, 0); |
| + glEnableVertexAttribArray(position_locations_[program]); |
| + glEnableVertexAttribArray(texture_coordinate_locations_[program]); |
| + |
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); |
| + glVertexAttribPointer(position_locations_[program], 4, GL_FLOAT, GL_FALSE, |
| + 4 * sizeof(GLfloat), 0); |
| + |
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); |
| + glVertexAttribPointer(texture_coordinate_locations_[program], 2, GL_FLOAT, |
| + GL_FALSE, 2 * sizeof(GLfloat), 0); |
| + |
| + glUniform1i(sampler_locations_[program], 0); |
|
greggman
2012/04/04 20:12:24
do you need to call glActiveTexture?
Jeff Timanus
2012/04/04 22:34:14
Yes! I do need to call glActiveTexture!
Done.
|
| + |
| + glBindTexture(GL_TEXTURE_2D, source_id); |
| + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| + |
| + glDisable(GL_DEPTH_TEST); |
| + glDisable(GL_SCISSOR_TEST); |
| + glDisable(GL_STENCIL_TEST); |
| + glDisable(GL_CULL_FACE); |
| + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| + glDepthMask(GL_FALSE); |
| + |
| + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| +} |
| Property changes on: gpu\command_buffer\service\gles2_cmd_copy_texture_chromium.cc |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + LF |