| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "gpu/command_buffer/common/types.h" | 8 #include "gpu/command_buffer/common/types.h" |
| 9 #include "gpu/command_buffer/service/gl_utils.h" | 9 #include "gpu/command_buffer/service/gl_utils.h" |
| 10 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 10 | 11 |
| 11 #define SHADER0(Src) \ | 12 #define SHADER0(Src) \ |
| 12 "#ifdef GL_ES\n"\ | 13 "#ifdef GL_ES\n"\ |
| 13 "precision mediump float;\n"\ | 14 "precision mediump float;\n"\ |
| 14 "#endif\n"\ | 15 "#endif\n"\ |
| 15 #Src | 16 #Src |
| 16 #define SHADER(Src) SHADER0(Src) | 17 #define SHADER(Src) SHADER0(Src) |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 if (gl_FragColor.a > 0.0) | 136 if (gl_FragColor.a > 0.0) |
| 136 gl_FragColor.rgb /= gl_FragColor.a; | 137 gl_FragColor.rgb /= gl_FragColor.a; |
| 137 }); | 138 }); |
| 138 default: | 139 default: |
| 139 return 0; | 140 return 0; |
| 140 } | 141 } |
| 141 } | 142 } |
| 142 | 143 |
| 143 } // namespace | 144 } // namespace |
| 144 | 145 |
| 145 void CopyTextureCHROMIUMResourceManager::Initialize() { | 146 namespace gpu { |
| 147 |
| 148 void CopyTextureCHROMIUMResourceManager::Initialize( |
| 149 const gles2::GLES2Decoder* decoder) { |
| 146 COMPILE_ASSERT( | 150 COMPILE_ASSERT( |
| 147 kVertexPositionAttrib == 0u || kVertexTextureAttrib == 0u, | 151 kVertexPositionAttrib == 0u || kVertexTextureAttrib == 0u, |
| 148 CopyTexture_One_of_these_attribs_must_be_0); | 152 CopyTexture_One_of_these_attribs_must_be_0); |
| 149 | 153 |
| 150 // Initialize all of the GPU resources required to perform the copy. | 154 // Initialize all of the GPU resources required to perform the copy. |
| 151 glGenBuffersARB(2, buffer_ids_); | 155 glGenBuffersARB(2, buffer_ids_); |
| 152 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | 156 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); |
| 153 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, | 157 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, |
| 154 GL_STATIC_DRAW); | 158 GL_STATIC_DRAW); |
| 155 | 159 |
| 156 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | 160 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); |
| 157 glBufferData(GL_ARRAY_BUFFER, sizeof(kTextureCoords), kTextureCoords, | 161 glBufferData(GL_ARRAY_BUFFER, sizeof(kTextureCoords), kTextureCoords, |
| 158 GL_STATIC_DRAW); | 162 GL_STATIC_DRAW); |
| 159 | 163 |
| 160 glGenFramebuffersEXT(1, &framebuffer_); | 164 glGenFramebuffersEXT(1, &framebuffer_); |
| 161 | 165 |
| 166 // TODO(gman): Init these on demand. |
| 162 GLuint shaders[kNumShaders]; | 167 GLuint shaders[kNumShaders]; |
| 163 for (int shader = 0; shader < kNumShaders; ++shader) { | 168 for (int shader = 0; shader < kNumShaders; ++shader) { |
| 164 shaders[shader] = glCreateShader( | 169 shaders[shader] = glCreateShader( |
| 165 shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); | 170 shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); |
| 166 const char* shader_source = GetShaderSource(static_cast<ShaderId>(shader)); | 171 const char* shader_source = GetShaderSource(static_cast<ShaderId>(shader)); |
| 167 glShaderSource(shaders[shader], 1, &shader_source, 0); | 172 glShaderSource(shaders[shader], 1, &shader_source, 0); |
| 168 glCompileShader(shaders[shader]); | 173 glCompileShader(shaders[shader]); |
| 169 #ifndef NDEBUG | 174 #ifndef NDEBUG |
| 170 GLint compile_status; | 175 GLint compile_status; |
| 171 glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status); | 176 glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status); |
| 172 if (GL_TRUE != compile_status) | 177 if (GL_TRUE != compile_status) |
| 173 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | 178 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; |
| 174 #endif | 179 #endif |
| 175 } | 180 } |
| 176 | 181 |
| 182 // TODO(gman): Init these on demand. |
| 177 for (int program = 0; program < kNumPrograms; ++program) { | 183 for (int program = 0; program < kNumPrograms; ++program) { |
| 178 programs_[program] = glCreateProgram(); | 184 programs_[program] = glCreateProgram(); |
| 179 glAttachShader(programs_[program], shaders[0]); | 185 glAttachShader(programs_[program], shaders[0]); |
| 180 glAttachShader(programs_[program], shaders[program + 1]); | 186 glAttachShader(programs_[program], shaders[program + 1]); |
| 181 | 187 |
| 182 glBindAttribLocation(programs_[program], kVertexPositionAttrib, | 188 glBindAttribLocation(programs_[program], kVertexPositionAttrib, |
| 183 "a_position"); | 189 "a_position"); |
| 184 glBindAttribLocation(programs_[program], kVertexTextureAttrib, | 190 glBindAttribLocation(programs_[program], kVertexTextureAttrib, |
| 185 "a_texCoord"); | 191 "a_texCoord"); |
| 186 | 192 |
| 187 glLinkProgram(programs_[program]); | 193 glLinkProgram(programs_[program]); |
| 188 #ifndef NDEBUG | 194 #ifndef NDEBUG |
| 189 GLint linked; | 195 GLint linked; |
| 190 glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); | 196 glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); |
| 191 if (!linked) | 197 if (!linked) |
| 192 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | 198 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; |
| 193 #endif | 199 #endif |
| 194 | 200 |
| 195 sampler_locations_[program] = glGetUniformLocation(programs_[program], | 201 sampler_locations_[program] = glGetUniformLocation(programs_[program], |
| 196 "u_texSampler"); | 202 "u_texSampler"); |
| 197 } | 203 } |
| 198 | 204 |
| 199 for (int shader = 0; shader < kNumShaders; ++shader) | 205 for (int shader = 0; shader < kNumShaders; ++shader) |
| 200 glDeleteShader(shaders[shader]); | 206 glDeleteShader(shaders[shader]); |
| 201 | 207 |
| 208 decoder->RestoreBufferBindings(); |
| 209 |
| 202 initialized_ = true; | 210 initialized_ = true; |
| 203 } | 211 } |
| 204 | 212 |
| 205 void CopyTextureCHROMIUMResourceManager::Destroy() { | 213 void CopyTextureCHROMIUMResourceManager::Destroy() { |
| 206 if (!initialized_) | 214 if (!initialized_) |
| 207 return; | 215 return; |
| 208 | 216 |
| 209 glDeleteFramebuffersEXT(1, &framebuffer_); | 217 glDeleteFramebuffersEXT(1, &framebuffer_); |
| 210 | 218 |
| 211 for (int program = 0; program < kNumPrograms; ++program) | 219 for (int program = 0; program < kNumPrograms; ++program) |
| 212 glDeleteProgram(programs_[program]); | 220 glDeleteProgram(programs_[program]); |
| 213 | 221 |
| 214 glDeleteBuffersARB(2, buffer_ids_); | 222 glDeleteBuffersARB(2, buffer_ids_); |
| 215 } | 223 } |
| 216 | 224 |
| 217 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | 225 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
| 226 const gles2::GLES2Decoder* decoder, |
| 218 GLenum target, | 227 GLenum target, |
| 219 GLuint source_id, | 228 GLuint source_id, |
| 220 GLuint dest_id, | 229 GLuint dest_id, |
| 221 GLint level, | 230 GLint level, |
| 231 GLsizei width, |
| 232 GLsizei height, |
| 222 bool flip_y, | 233 bool flip_y, |
| 223 bool premultiply_alpha, | 234 bool premultiply_alpha, |
| 224 bool unpremultiply_alpha) { | 235 bool unpremultiply_alpha) { |
| 225 if (!initialized_) { | 236 if (!initialized_) { |
| 226 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; | 237 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; |
| 227 return; | 238 return; |
| 228 } | 239 } |
| 229 | 240 |
| 230 GLuint program = GetProgram(flip_y, premultiply_alpha, unpremultiply_alpha); | 241 GLuint program = GetProgram(flip_y, premultiply_alpha, unpremultiply_alpha); |
| 231 glUseProgram(programs_[program]); | 242 glUseProgram(programs_[program]); |
| 232 | 243 |
| 233 #ifndef NDEBUG | 244 #ifndef NDEBUG |
| 234 glValidateProgram(programs_[program]); | 245 glValidateProgram(programs_[program]); |
| 235 GLint validation_status; | 246 GLint validation_status; |
| 236 glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status); | 247 glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status); |
| 237 if (GL_TRUE != validation_status) { | 248 if (GL_TRUE != validation_status) { |
| 238 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | 249 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; |
| 239 return; | 250 return; |
| 240 } | 251 } |
| 241 #endif | 252 #endif |
| 242 | 253 |
| 254 glActiveTexture(GL_TEXTURE0); |
| 255 glBindTexture(GL_TEXTURE_2D, dest_id); |
| 256 // NVidia drivers require texture settings to be a certain way |
| 257 // or they won't report FRAMEBUFFER_COMPLETE. |
| 258 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 259 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 260 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 243 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); | 262 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); |
| 244 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, | 263 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, |
| 245 dest_id, level); | 264 dest_id, level); |
| 246 | 265 |
| 247 #ifndef NDEBUG | 266 #ifndef NDEBUG |
| 248 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 267 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| 249 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | 268 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { |
| 250 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | 269 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; |
| 251 return; | 270 } else |
| 271 #endif |
| 272 { |
| 273 glEnableVertexAttribArray(kVertexPositionAttrib); |
| 274 glEnableVertexAttribArray(kVertexTextureAttrib); |
| 275 |
| 276 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); |
| 277 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, |
| 278 4 * sizeof(GLfloat), 0); |
| 279 |
| 280 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); |
| 281 glVertexAttribPointer(kVertexTextureAttrib, 2, GL_FLOAT, GL_FALSE, |
| 282 2 * sizeof(GLfloat), 0); |
| 283 |
| 284 glUniform1i(sampler_locations_[program], 0); |
| 285 |
| 286 glBindTexture(GL_TEXTURE_2D, source_id); |
| 287 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 288 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 289 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 290 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 291 |
| 292 glDisable(GL_DEPTH_TEST); |
| 293 glDisable(GL_SCISSOR_TEST); |
| 294 glDisable(GL_STENCIL_TEST); |
| 295 glDisable(GL_CULL_FACE); |
| 296 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| 297 glDepthMask(GL_FALSE); |
| 298 glDisable(GL_BLEND); |
| 299 |
| 300 glViewport(0, 0, width, height); |
| 301 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| 252 } | 302 } |
| 253 #endif | |
| 254 | 303 |
| 255 glEnableVertexAttribArray(kVertexPositionAttrib); | 304 decoder->RestoreAttribute(kVertexTextureAttrib); |
| 256 glEnableVertexAttribArray(kVertexTextureAttrib); | 305 decoder->RestoreAttribute(kVertexPositionAttrib); |
| 257 | 306 decoder->RestoreTextureUnitBindings(0); |
| 258 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | 307 decoder->RestoreTextureState(source_id); |
| 259 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, | 308 decoder->RestoreTextureState(dest_id); |
| 260 4 * sizeof(GLfloat), 0); | 309 decoder->RestoreActiveTexture(); |
| 261 | 310 decoder->RestoreProgramBindings(); |
| 262 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | 311 decoder->RestoreBufferBindings(); |
| 263 glVertexAttribPointer(kVertexTextureAttrib, 2, GL_FLOAT, GL_FALSE, | 312 decoder->RestoreFramebufferBindings(); |
| 264 2 * sizeof(GLfloat), 0); | 313 decoder->RestoreGlobalState(); |
| 265 | |
| 266 glActiveTexture(GL_TEXTURE0); | |
| 267 glUniform1i(sampler_locations_[program], 0); | |
| 268 | |
| 269 glBindTexture(GL_TEXTURE_2D, source_id); | |
| 270 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 271 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
| 273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
| 274 | |
| 275 glDisable(GL_DEPTH_TEST); | |
| 276 glDisable(GL_SCISSOR_TEST); | |
| 277 glDisable(GL_STENCIL_TEST); | |
| 278 glDisable(GL_CULL_FACE); | |
| 279 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 280 glDepthMask(GL_FALSE); | |
| 281 glDisable(GL_BLEND); | |
| 282 | |
| 283 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
| 284 } | 314 } |
| 285 | 315 |
| 316 } // namespace |
| 317 |
| OLD | NEW |