 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/| 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,243 @@ | 
| +// 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/service/gl_utils.h" | 
| + | 
| +#define SHADER0(Src) #Src | 
| +#define SHADER(Src) SHADER0(Src) | 
| + | 
| +namespace { | 
| + | 
| +const GLfloat kQuadVertices[] = { -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 }; | 
| + | 
| +const GLfloat kTextureCoords[] = { 0.0f, 0.0f, | 
| + 1.0f, 0.0f, | 
| + 1.0f, 1.0f, | 
| + 0.0f, 1.0f }; | 
| + | 
| +const int kNumShaders = 5; | 
| +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 | 
| + | 
| +void CopyTextureCHROMIUMResourceManager::Initialize() { | 
| + // Initialize all of the GPU resources required to perform the copy. | 
| + glGenBuffersARB(2, buffer_ids_); | 
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | 
| + glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, | 
| + GL_STATIC_DRAW); | 
| + | 
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | 
| + glBufferData(GL_ARRAY_BUFFER, sizeof(kTextureCoords), kTextureCoords, | 
| + GL_STATIC_DRAW); | 
| + | 
| + glGenFramebuffersEXT(1, &framebuffer_); | 
| + | 
| + GLuint shaders[kNumShaders]; | 
| + for (int shader = 0; shader < kNumShaders; ++shader) { | 
| + shaders[shader] = glCreateShader( | 
| + shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); | 
| + const char* shader_source = GetShaderSource(static_cast<ShaderId>(shader)); | 
| + glShaderSource(shaders[shader], 1, &shader_source, 0); | 
| + 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 | 
| + | 
| + glBindAttribLocation(programs_[program], kVertexPositionAttrib, | 
| 
greggman
2012/04/17 04:58:06
These BindAttribLocation statements need to come b
 
Jeff Timanus
2012/04/18 14:59:08
Done.
 | 
| + "a_position"); | 
| + glBindAttribLocation(programs_[program], kVertexTextureAttrib, | 
| + "a_texCoord"); | 
| + sampler_locations_[program] = glGetUniformLocation(programs_[program], | 
| + "u_texSampler"); | 
| + | 
| + } | 
| + | 
| + for (int shader = 0; shader < kNumShaders; ++shader) | 
| + glDeleteShader(shaders[shader]); | 
| + | 
| + initialized_ = true; | 
| +} | 
| + | 
| +void CopyTextureCHROMIUMResourceManager::Destroy() { | 
| + if (!initialized_) | 
| + return; | 
| + | 
| + glDeleteFramebuffersEXT(1, &framebuffer_); | 
| + | 
| + 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) { | 
| + if (!initialized_) { | 
| + DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; | 
| + return; | 
| + } | 
| + | 
| + GLuint program = GetProgram(flip_y, premultiply_alpha); | 
| + glUseProgram(programs_[program]); | 
| + | 
| +#ifndef NDEBUG | 
| + glValidateProgram(programs_[program]); | 
| + GLint validation_status; | 
| + glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status); | 
| + if (GL_TRUE != validation_status) { | 
| + DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | 
| + return; | 
| + } | 
| +#endif | 
| + | 
| + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); | 
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, | 
| + dest_id, level); | 
| + | 
| +#ifndef NDEBUG | 
| + GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 
| + if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | 
| + DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | 
| + return; | 
| + } | 
| +#endif | 
| + | 
| + glEnableVertexAttribArray(kVertexPositionAttrib); | 
| + glEnableVertexAttribArray(kVertexTextureAttrib); | 
| + | 
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | 
| + glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, | 
| + 4 * sizeof(GLfloat), 0); | 
| + | 
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | 
| + glVertexAttribPointer(kVertexTextureAttrib, 2, GL_FLOAT, GL_FALSE, | 
| + 2 * sizeof(GLfloat), 0); | 
| + | 
| + glActiveTexture(GL_TEXTURE0); | 
| + glUniform1i(sampler_locations_[program], 0); | 
| + | 
| + 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); | 
| + glDisable(GL_BLEND); | 
| + | 
| + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | 
| +} | 
| + | 
| Property changes on: gpu\command_buffer\service\gles2_cmd_copy_texture_chromium.cc | 
| ___________________________________________________________________ | 
| Added: svn:eol-style | 
| + LF |