Chromium Code Reviews| 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/service/gl_utils.h" | |
| 8 | |
| 9 #define SHADER0(Src) #Src | |
| 10 #define SHADER(Src) SHADER0(Src) | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 const int kNumShaders = 5; | |
| 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 void CopyTextureCHROMIUMResourceManager::Initialize() { | |
| 99 // Initialize all of the GPU resources required to perform the copy. | |
| 100 GLfloat texture_vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, | |
|
apatrick_chromium
2012/04/16 19:17:21
These two could be const static. Not a big deal bu
Jeff Timanus
2012/04/17 01:27:34
Done.
| |
| 101 1.0f, -1.0f, 0.0f, 1.0f, | |
| 102 1.0f, 1.0f, 0.0f, 1.0f, | |
| 103 -1.0f, 1.0f, 0.0f, 1.0f }; | |
| 104 | |
| 105 GLfloat texture_coords[] = { 0.0f, 0.0f, | |
| 106 1.0f, 0.0f, | |
| 107 1.0f, 1.0f, | |
| 108 0.0f, 1.0f }; | |
| 109 | |
| 110 glGenBuffersARB(2, buffer_ids_); | |
| 111 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | |
| 112 glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), texture_vertices, | |
|
apatrick_chromium
2012/04/16 19:17:21
sizeof(texture_vertices)
Jeff Timanus
2012/04/17 01:27:34
Done.
| |
| 113 GL_STATIC_DRAW); | |
| 114 | |
| 115 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | |
| 116 glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), texture_coords, | |
|
apatrick_chromium
2012/04/16 19:17:21
sizeof(texture_coords)
Jeff Timanus
2012/04/17 01:27:34
Done.
| |
| 117 GL_STATIC_DRAW); | |
| 118 | |
| 119 glGenFramebuffersEXT(1, &framebuffer_); | |
| 120 | |
| 121 GLuint shaders[kNumShaders]; | |
| 122 for (int shader = 0; shader < kNumShaders; ++shader) { | |
| 123 shaders[shader] = glCreateShader( | |
| 124 shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); | |
| 125 const char* shader_source = GetShaderSource(static_cast<ShaderId>(shader)); | |
| 126 glShaderSource(shaders[shader], 1, &shader_source, 0); | |
| 127 glCompileShader(shaders[shader]); | |
| 128 #ifndef NDEBUG | |
| 129 GLint compile_status; | |
| 130 glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status); | |
| 131 if (GL_TRUE != compile_status) | |
| 132 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | |
| 133 #endif | |
| 134 } | |
| 135 | |
| 136 for (int program = 0; program < kNumPrograms; ++program) { | |
| 137 programs_[program] = glCreateProgram(); | |
| 138 glAttachShader(programs_[program], shaders[0]); | |
| 139 glAttachShader(programs_[program], shaders[program + 1]); | |
| 140 | |
| 141 glLinkProgram(programs_[program]); | |
| 142 #ifndef NDEBUG | |
| 143 GLint linked; | |
| 144 glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); | |
| 145 if (!linked) | |
| 146 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | |
| 147 #endif | |
| 148 | |
| 149 position_locations_[program] = glGetAttribLocation(programs_[program], | |
| 150 "a_position"); | |
| 151 texture_coordinate_locations_[program] = glGetAttribLocation( | |
| 152 programs_[program], "a_texCoord"); | |
| 153 sampler_locations_[program] = glGetUniformLocation(programs_[program], | |
| 154 "u_texSampler"); | |
| 155 } | |
| 156 | |
| 157 for (int shader = 0; shader < kNumShaders; ++shader) | |
| 158 glDeleteShader(shaders[shader]); | |
| 159 } | |
| 160 | |
| 161 void CopyTextureCHROMIUMResourceManager::Destroy() { | |
|
greggman
2012/04/15 22:22:41
nit: if I do this
c = new CopyTextureChromiumReso
Jeff Timanus
2012/04/17 01:27:34
A good observation. I added an initialized_ flag
| |
| 162 glDeleteFramebuffersEXT(1, &framebuffer_); | |
| 163 | |
| 164 for (int program = 0; program < kNumPrograms; ++program) | |
| 165 glDeleteProgram(programs_[program]); | |
| 166 | |
| 167 glDeleteBuffersARB(2, buffer_ids_); | |
| 168 } | |
| 169 | |
| 170 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | |
| 171 GLenum target, | |
| 172 GLuint source_id, | |
| 173 GLuint dest_id, | |
| 174 GLint level, | |
| 175 bool flip_y, | |
| 176 bool premultiply_alpha) { | |
| 177 GLuint program = GetProgram(flip_y, premultiply_alpha); | |
| 178 glUseProgram(programs_[program]); | |
| 179 | |
| 180 #ifndef NDEBUG | |
| 181 glValidateProgram(program); | |
| 182 GLint validation_status; | |
| 183 glGetProgramiv(program, GL_VALIDATE_STATUS, &validation_status); | |
| 184 if (GL_TRUE != validation_status) { | |
| 185 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | |
| 186 return; | |
| 187 } | |
| 188 #endif | |
| 189 | |
| 190 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); | |
| 191 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, | |
| 192 dest_id, level); | |
| 193 | |
| 194 #ifndef NDEBUG | |
| 195 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | |
| 196 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | |
| 197 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | |
| 198 return; | |
| 199 } | |
| 200 #endif | |
| 201 | |
| 202 glBindBuffer(GL_ARRAY_BUFFER, 0); | |
| 203 glEnableVertexAttribArray(position_locations_[program]); | |
| 204 glEnableVertexAttribArray(texture_coordinate_locations_[program]); | |
| 205 | |
| 206 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | |
| 207 glVertexAttribPointer(position_locations_[program], 4, GL_FLOAT, GL_FALSE, | |
| 208 4 * sizeof(GLfloat), 0); | |
| 209 | |
| 210 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | |
| 211 glVertexAttribPointer(texture_coordinate_locations_[program], 2, GL_FLOAT, | |
| 212 GL_FALSE, 2 * sizeof(GLfloat), 0); | |
| 213 | |
| 214 glActiveTexture(GL_TEXTURE0); | |
| 215 glUniform1i(sampler_locations_[program], 0); | |
| 216 | |
| 217 glBindTexture(GL_TEXTURE_2D, source_id); | |
| 218 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 219 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
| 221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
| 222 | |
| 223 glDisable(GL_DEPTH_TEST); | |
| 224 glDisable(GL_SCISSOR_TEST); | |
| 225 glDisable(GL_STENCIL_TEST); | |
| 226 glDisable(GL_CULL_FACE); | |
| 227 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 228 glDepthMask(GL_FALSE); | |
| 229 glDisable(GL_BLEND); | |
| 230 | |
| 231 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
| 232 } | |
| 233 | |
| OLD | NEW |