 Chromium Code Reviews
 Chromium Code Reviews Issue 9968113:
  Addition of GL_CHROMIUM_copy_texture extension.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src/
    
  
    Issue 9968113:
  Addition of GL_CHROMIUM_copy_texture extension.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src/| 
 | 
| OLD | NEW | 
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | |
| 6 #include "gpu/command_buffer/common/types.h" | |
| 7 //#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.
 | |
| 8 #include "gpu/command_buffer/service/gl_utils.h" | |
| 9 | |
| 10 #define SHADER0(Src) #Src | |
| 11 #define SHADER(Src) SHADER0(Src) | |
| 12 | |
| 13 namespace { | |
| 14 | |
| 15 enum ShaderId { | |
| 16 VERTEX_SHADER_POS_TEX, | |
| 17 FRAGMENT_SHADER_TEX, | |
| 18 FRAGMENT_SHADER_TEX_FLIP_Y, | |
| 19 FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA, | |
| 20 FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y | |
| 21 }; | |
| 22 | |
| 23 enum ProgramId { | |
| 24 PROGRAM_COPY_TEXTURE, | |
| 25 PROGRAM_COPY_TEXTURE_FLIP_Y, | |
| 26 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, | |
| 27 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY | |
| 28 }; | |
| 29 | |
| 30 // Returns the correct program to evaluate the copy operation for | |
| 31 // the CHROMIUM_flipy and premultiply alpha pixel store settings. | |
| 32 ProgramId GetProgram(bool flip_y, bool premultiply_alpha) { | |
| 33 if (flip_y && premultiply_alpha) | |
| 34 return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY; | |
| 35 | |
| 36 if (flip_y) | |
| 37 return PROGRAM_COPY_TEXTURE_FLIP_Y; | |
| 38 | |
| 39 if (premultiply_alpha) | |
| 40 return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA; | |
| 41 | |
| 42 return PROGRAM_COPY_TEXTURE; | |
| 43 } | |
| 44 | |
| 45 const char* GetShaderSource(ShaderId shader) { | |
| 46 switch (shader) { | |
| 47 case VERTEX_SHADER_POS_TEX: | |
| 48 return SHADER( | |
| 49 precision mediump float; | |
| 50 attribute vec4 a_position; | |
| 51 attribute vec2 a_texCoord; | |
| 52 varying vec2 v_uv; | |
| 53 void main(void) { | |
| 54 gl_Position = a_position; | |
| 55 v_uv = a_texCoord; | |
| 56 }); | |
| 57 case FRAGMENT_SHADER_TEX: | |
| 58 return SHADER( | |
| 59 precision mediump float; | |
| 60 uniform sampler2D u_texSampler; | |
| 61 varying vec2 v_uv; | |
| 62 void main(void) { | |
| 63 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
| 64 }); | |
| 65 case FRAGMENT_SHADER_TEX_FLIP_Y: | |
| 66 return SHADER( | |
| 67 precision mediump float; | |
| 68 uniform sampler2D u_texSampler; | |
| 69 varying vec2 v_uv; | |
| 70 void main(void) { | |
| 71 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
| 72 }); | |
| 73 case FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA: | |
| 74 return SHADER( | |
| 75 precision mediump float; | |
| 76 uniform sampler2D u_texSampler; | |
| 77 varying vec2 v_uv; | |
| 78 void main(void) { | |
| 79 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
| 80 gl_FragColor.rgb *= gl_FragColor.a; | |
| 81 }); | |
| 82 case FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y: | |
| 83 return SHADER( | |
| 84 precision mediump float; | |
| 85 uniform sampler2D u_texSampler; | |
| 86 varying vec2 v_uv; | |
| 87 void main(void) { | |
| 88 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
| 89 gl_FragColor.rgb *= gl_FragColor.a; | |
| 90 }); | |
| 91 default: | |
| 92 return 0; | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 } // namespace | |
| 97 | |
| 98 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() { | |
| 99 FreeResources(); | |
| 100 } | |
| 101 | |
| 102 void CopyTextureCHROMIUMResourceManager::Initialize() { | |
| 103 // Initialize all of the GPU resources required to perform the copy. | |
| 104 GLfloat texture_vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, | |
| 105 1.0f, -1.0f, 0.0f, 1.0f, | |
| 106 1.0f, 1.0f, 0.0f, 1.0f, | |
| 107 -1.0f, 1.0f, 0.0f, 1.0f }; | |
| 108 | |
| 109 GLfloat texture_coords[] = { 0.0f, 0.0f, | |
| 110 1.0f, 0.0f, | |
| 111 1.0f, 1.0f, | |
| 112 0.0f, 1.0f }; | |
| 113 | |
| 114 glGenBuffersARB(2, buffer_ids_); | |
| 115 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | |
| 116 glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), texture_vertices, | |
| 117 GL_STATIC_DRAW); | |
| 118 | |
| 119 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | |
| 120 glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), texture_coords, | |
| 121 GL_STATIC_DRAW); | |
| 122 | |
| 123 glGenFramebuffersEXT(1, &framebuffer_); | |
| 124 | |
| 125 shaders_[0] = glCreateShader(GL_VERTEX_SHADER); | |
| 126 const char* shader_source = GetShaderSource(VERTEX_SHADER_POS_TEX); | |
| 127 glShaderSource(shaders_[0], 1, &shader_source, 0); | |
| 128 for (int shader = 1; shader < kNumShaders; ++shader) { | |
| 129 shaders_[shader] = glCreateShader(GL_FRAGMENT_SHADER); | |
| 130 shader_source = GetShaderSource(static_cast<ShaderId>(shader)); | |
| 131 glShaderSource(shaders_[shader], 1, &shader_source, 0); | |
| 132 } | |
| 133 | |
| 134 for (int shader = 0; shader < kNumShaders; ++shader) { | |
| 135 glCompileShader(shaders_[shader]); | |
| 136 #ifndef NDEBUG | |
| 137 GLint compile_status; | |
| 138 glGetShaderiv(shaders_[shader], GL_COMPILE_STATUS, &compile_status); | |
| 139 if (GL_TRUE != compile_status) | |
| 140 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | |
| 141 #endif | |
| 142 } | |
| 143 | |
| 144 for (int program = 0; program < kNumPrograms; ++program) { | |
| 145 programs_[program] = glCreateProgram(); | |
| 146 glAttachShader(programs_[program], shaders_[0]); | |
| 147 glAttachShader(programs_[program], shaders_[program + 1]); | |
| 148 | |
| 149 glLinkProgram(programs_[program]); | |
| 150 #ifndef NDEBUG | |
| 151 GLint linked; | |
| 152 glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); | |
| 153 if (!linked) | |
| 154 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | |
| 155 #endif | |
| 156 | |
| 157 position_locations_[program] = glGetAttribLocation(programs_[program], | |
| 158 "a_position"); | |
| 159 texture_coordinate_locations_[program] = glGetAttribLocation( | |
| 160 programs_[program], "a_texCoord"); | |
| 161 sampler_locations_[program] = glGetUniformLocation(programs_[program], | |
| 162 "u_texSampler"); | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 void CopyTextureCHROMIUMResourceManager::FreeResources() { | |
| 167 glDeleteFramebuffersEXT(1, &framebuffer_); | |
| 168 | |
| 169 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.
 | |
| 170 glDeleteShader(shaders_[shader]); | |
| 171 | |
| 172 for (int program = 0; program < kNumPrograms; ++program) | |
| 173 glDeleteProgram(programs_[program]); | |
| 174 | |
| 175 glDeleteBuffersARB(2, buffer_ids_); | |
| 176 } | |
| 177 | |
| 178 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | |
| 179 GLenum target, | |
| 180 GLuint source_id, | |
| 181 GLuint dest_id, | |
| 182 GLint level, | |
| 183 bool flip_y, | |
| 184 bool premultiply_alpha) { | |
| 185 GLuint program = GetProgram(flip_y, premultiply_alpha); | |
| 186 glUseProgram(programs_[program]); | |
| 187 | |
| 188 #ifndef NDEBUG | |
| 189 glValidateProgram(program); | |
| 190 GLint validation_status; | |
| 191 glGetProgramiv(program, GL_VALIDATE_STATUS, &validation_status); | |
| 192 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | |
| 193 #endif | |
| 194 | |
| 195 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); | |
| 196 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, | |
| 197 dest_id, level); | |
| 198 | |
| 199 #ifndef NDEBUG | |
| 200 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | |
| 201 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | |
| 202 #endif | |
| 203 | |
| 204 glBindBuffer(GL_ARRAY_BUFFER, 0); | |
| 205 glEnableVertexAttribArray(position_locations_[program]); | |
| 206 glEnableVertexAttribArray(texture_coordinate_locations_[program]); | |
| 207 | |
| 208 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | |
| 209 glVertexAttribPointer(position_locations_[program], 4, GL_FLOAT, GL_FALSE, | |
| 210 4 * sizeof(GLfloat), 0); | |
| 211 | |
| 212 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | |
| 213 glVertexAttribPointer(texture_coordinate_locations_[program], 2, GL_FLOAT, | |
| 214 GL_FALSE, 2 * sizeof(GLfloat), 0); | |
| 215 | |
| 216 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.
 | |
| 217 | |
| 218 glBindTexture(GL_TEXTURE_2D, source_id); | |
| 219 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 220 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
| 222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
| 223 | |
| 224 glDisable(GL_DEPTH_TEST); | |
| 225 glDisable(GL_SCISSOR_TEST); | |
| 226 glDisable(GL_STENCIL_TEST); | |
| 227 glDisable(GL_CULL_FACE); | |
| 228 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 229 glDepthMask(GL_FALSE); | |
| 230 | |
| 231 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
| 232 } | |
| OLD | NEW |