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 |