| 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 <string.h> | 7 #include <string.h> |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "gpu/command_buffer/common/types.h" | 9 #include "gpu/command_buffer/common/types.h" |
| 10 #include "gpu/command_buffer/service/gl_utils.h" | 10 #include "gpu/command_buffer/service/gl_utils.h" |
| 11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 12 | 12 |
| 13 #define SHADER0(src) \ | 13 #define SHADER(src) \ |
| 14 "#ifdef GL_ES\n"\ | 14 "#ifdef GL_ES\n" \ |
| 15 "precision mediump float;\n"\ | 15 "precision mediump float;\n" \ |
| 16 "#endif\n"\ | 16 "#endif\n" #src |
| 17 #src | 17 #define SHADER_2D(src) \ |
| 18 #define SHADER(src) { false, SHADER0(src), } | 18 "#define SamplerType sampler2D\n" \ |
| 19 #define SHADER_EXTERNAL_OES0(src) \ | 19 "#define TextureLookup texture2D\n" SHADER(src) |
| 20 "#extension GL_OES_EGL_image_external : require\n"\ | 20 #define SHADER_EXTERNAL_OES(src) \ |
| 21 "#ifdef GL_ES\n"\ | 21 "#extension GL_OES_EGL_image_external : require\n" \ |
| 22 "precision mediump float;\n"\ | 22 "#define SamplerType samplerExternalOES\n" \ |
| 23 "#endif\n"\ | 23 "#define TextureLookup texture2D\n" SHADER(src) |
| 24 #src | 24 #define SHADERS(src) \ |
| 25 #define SHADER_EXTERNAL_OES(src) { true, SHADER_EXTERNAL_OES0(src), } | 25 { SHADER_2D(src), SHADER_EXTERNAL_OES(src) } |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 const GLfloat kQuadVertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, | 29 const GLfloat kQuadVertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, |
| 30 1.0f, -1.0f, 0.0f, 1.0f, | 30 1.0f, -1.0f, 0.0f, 1.0f, |
| 31 1.0f, 1.0f, 0.0f, 1.0f, | 31 1.0f, 1.0f, 0.0f, 1.0f, |
| 32 -1.0f, 1.0f, 0.0f, 1.0f }; | 32 -1.0f, 1.0f, 0.0f, 1.0f }; |
| 33 | 33 |
| 34 enum ProgramId { | 34 enum ShaderId { |
| 35 PROGRAM_COPY_TEXTURE, | 35 SHADER_COPY_TEXTURE, |
| 36 PROGRAM_COPY_TEXTURE_FLIP_Y, | 36 SHADER_COPY_TEXTURE_FLIP_Y, |
| 37 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, | 37 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA, |
| 38 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, | 38 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, |
| 39 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY, | 39 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y, |
| 40 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, | 40 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y, |
| 41 PROGRAM_COPY_TEXTURE_OES, | 41 NUM_SHADERS, |
| 42 PROGRAM_COPY_TEXTURE_OES_FLIP_Y, | |
| 43 PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA, | |
| 44 PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA, | |
| 45 PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY, | |
| 46 PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY, | |
| 47 }; | 42 }; |
| 48 | 43 |
| 49 struct ShaderInfo { | 44 enum SamplerId { |
| 50 bool needs_egl_image_external; | 45 SAMPLER_TEXTURE_2D, |
| 51 const char* source; | 46 SAMPLER_TEXTURE_EXTERNAL_OES, |
| 47 NUM_SAMPLERS, |
| 52 }; | 48 }; |
| 53 | 49 |
| 54 const ShaderInfo shader_infos[] = { | 50 const char* vertex_shader_source = |
| 55 // VERTEX_SHADER_POS_TEX | |
| 56 SHADER( | 51 SHADER( |
| 57 uniform mat4 u_matrix; | 52 uniform mat4 u_matrix; |
| 58 attribute vec4 a_position; | 53 attribute vec4 a_position; |
| 59 varying vec2 v_uv; | 54 varying vec2 v_uv; |
| 60 void main(void) { | 55 void main(void) { |
| 61 gl_Position = u_matrix * a_position; | 56 gl_Position = u_matrix * a_position; |
| 62 v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5); | 57 v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5); |
| 63 }), | 58 }); |
| 64 // FRAGMENT_SHADER_TEX | 59 |
| 65 SHADER( | 60 const char* fragment_shader_source[NUM_SHADERS][NUM_SAMPLERS] = { |
| 66 uniform sampler2D u_texSampler; | 61 // SHADER_COPY_TEXTURE |
| 62 SHADERS( |
| 63 uniform SamplerType u_texSampler; |
| 67 varying vec2 v_uv; | 64 varying vec2 v_uv; |
| 68 void main(void) { | 65 void main(void) { |
| 69 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 66 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
| 70 }), | 67 }), |
| 71 // FRAGMENT_SHADER_TEX_FLIP_Y | 68 // SHADER_COPY_TEXTURE_FLIP_Y |
| 72 SHADER( | 69 SHADERS( |
| 73 uniform sampler2D u_texSampler; | 70 uniform SamplerType u_texSampler; |
| 74 varying vec2 v_uv; | 71 varying vec2 v_uv; |
| 75 void main(void) { | 72 void main(void) { |
| 76 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 73 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
| 77 }), | 74 }), |
| 78 // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA | 75 // SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA |
| 79 SHADER( | 76 SHADERS( |
| 80 uniform sampler2D u_texSampler; | 77 uniform SamplerType u_texSampler; |
| 81 varying vec2 v_uv; | 78 varying vec2 v_uv; |
| 82 void main(void) { | 79 void main(void) { |
| 83 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 80 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
| 84 gl_FragColor.rgb *= gl_FragColor.a; | 81 gl_FragColor.rgb *= gl_FragColor.a; |
| 85 }), | 82 }), |
| 86 // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA | 83 // SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA |
| 87 SHADER( | 84 SHADERS( |
| 88 uniform sampler2D u_texSampler; | 85 uniform SamplerType u_texSampler; |
| 89 varying vec2 v_uv; | 86 varying vec2 v_uv; |
| 90 void main(void) { | 87 void main(void) { |
| 91 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 88 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
| 92 if (gl_FragColor.a > 0.0) | 89 if (gl_FragColor.a > 0.0) |
| 93 gl_FragColor.rgb /= gl_FragColor.a; | 90 gl_FragColor.rgb /= gl_FragColor.a; |
| 94 }), | 91 }), |
| 95 // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y | 92 // SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y |
| 96 SHADER( | 93 SHADERS( |
| 97 uniform sampler2D u_texSampler; | 94 uniform SamplerType u_texSampler; |
| 98 varying vec2 v_uv; | 95 varying vec2 v_uv; |
| 99 void main(void) { | 96 void main(void) { |
| 100 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 97 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
| 101 gl_FragColor.rgb *= gl_FragColor.a; | 98 gl_FragColor.rgb *= gl_FragColor.a; |
| 102 }), | 99 }), |
| 103 // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y | 100 // SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y |
| 104 SHADER( | 101 SHADERS( |
| 105 uniform sampler2D u_texSampler; | 102 uniform SamplerType u_texSampler; |
| 106 varying vec2 v_uv; | 103 varying vec2 v_uv; |
| 107 void main(void) { | 104 void main(void) { |
| 108 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 105 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
| 109 if (gl_FragColor.a > 0.0) | 106 if (gl_FragColor.a > 0.0) |
| 110 gl_FragColor.rgb /= gl_FragColor.a; | 107 gl_FragColor.rgb /= gl_FragColor.a; |
| 111 }), | 108 }), |
| 112 // FRAGMENT_SHADER_TEX_OES | |
| 113 SHADER_EXTERNAL_OES( | |
| 114 precision mediump float; | |
| 115 uniform samplerExternalOES u_texSampler; | |
| 116 varying vec2 v_uv; | |
| 117 void main(void) { | |
| 118 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
| 119 }), | |
| 120 // FRAGMENT_SHADER_TEX_OES_FLIP_Y | |
| 121 SHADER_EXTERNAL_OES( | |
| 122 precision mediump float; | |
| 123 uniform samplerExternalOES u_texSampler; | |
| 124 varying vec2 v_uv; | |
| 125 void main(void) { | |
| 126 gl_FragColor = | |
| 127 texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
| 128 }), | |
| 129 // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA | |
| 130 SHADER_EXTERNAL_OES( | |
| 131 precision mediump float; | |
| 132 uniform samplerExternalOES u_texSampler; | |
| 133 varying vec2 v_uv; | |
| 134 void main(void) { | |
| 135 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
| 136 gl_FragColor.rgb *= gl_FragColor.a; | |
| 137 }), | |
| 138 // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA | |
| 139 SHADER_EXTERNAL_OES( | |
| 140 precision mediump float; | |
| 141 uniform samplerExternalOES u_texSampler; | |
| 142 varying vec2 v_uv; | |
| 143 void main(void) { | |
| 144 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
| 145 if (gl_FragColor.a > 0.0) | |
| 146 gl_FragColor.rgb /= gl_FragColor.a; | |
| 147 }), | |
| 148 // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA_FLIP_Y | |
| 149 SHADER_EXTERNAL_OES( | |
| 150 precision mediump float; | |
| 151 uniform samplerExternalOES u_texSampler; | |
| 152 varying vec2 v_uv; | |
| 153 void main(void) { | |
| 154 gl_FragColor = | |
| 155 texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
| 156 gl_FragColor.rgb *= gl_FragColor.a; | |
| 157 }), | |
| 158 // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA_FLIP_Y | |
| 159 SHADER_EXTERNAL_OES( | |
| 160 precision mediump float; | |
| 161 uniform samplerExternalOES u_texSampler; | |
| 162 varying vec2 v_uv; | |
| 163 void main(void) { | |
| 164 gl_FragColor = | |
| 165 texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
| 166 if (gl_FragColor.a > 0.0) | |
| 167 gl_FragColor.rgb /= gl_FragColor.a; | |
| 168 }), | |
| 169 }; | 109 }; |
| 170 | 110 |
| 171 const int kNumShaders = arraysize(shader_infos); | 111 // Returns the correct shader id to evaluate the copy operation for |
| 172 | |
| 173 // Returns the correct program to evaluate the copy operation for | |
| 174 // the CHROMIUM_flipy and premultiply alpha pixel store settings. | 112 // the CHROMIUM_flipy and premultiply alpha pixel store settings. |
| 175 ProgramId GetProgram( | 113 ShaderId GetShaderId(bool flip_y, |
| 176 bool flip_y, | 114 bool premultiply_alpha, |
| 177 bool premultiply_alpha, | 115 bool unpremultiply_alpha) { |
| 178 bool unpremultiply_alpha, | |
| 179 bool is_source_external_oes) { | |
| 180 // If both pre-multiply and unpremultiply are requested, then perform no | 116 // If both pre-multiply and unpremultiply are requested, then perform no |
| 181 // alpha manipulation. | 117 // alpha manipulation. |
| 182 if (premultiply_alpha && unpremultiply_alpha) { | 118 if (premultiply_alpha && unpremultiply_alpha) { |
| 183 premultiply_alpha = false; | 119 premultiply_alpha = false; |
| 184 unpremultiply_alpha = false; | 120 unpremultiply_alpha = false; |
| 185 } | 121 } |
| 186 | 122 |
| 187 // bit 0: Flip_y | 123 // bit 0: Flip_y |
| 188 // bit 1: Premult | 124 // bit 1: Premult |
| 189 // bit 2: Unpremult | 125 // bit 2: Unpremult |
| 190 // bit 3: External_oes | 126 static ShaderId shader_ids[] = { |
| 191 static ProgramId program_ids[] = { | 127 SHADER_COPY_TEXTURE, |
| 192 PROGRAM_COPY_TEXTURE, | 128 SHADER_COPY_TEXTURE_FLIP_Y, // F |
| 193 PROGRAM_COPY_TEXTURE_FLIP_Y, // F | 129 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P |
| 194 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P | 130 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y, // F P |
| 195 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY, // F P | 131 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U |
| 196 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U | 132 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y, // F U |
| 197 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, // F U | 133 SHADER_COPY_TEXTURE, // P U |
| 198 PROGRAM_COPY_TEXTURE, // P U | 134 SHADER_COPY_TEXTURE_FLIP_Y, // F P U |
| 199 PROGRAM_COPY_TEXTURE, // F P U | |
| 200 PROGRAM_COPY_TEXTURE_OES, // E | |
| 201 PROGRAM_COPY_TEXTURE_OES_FLIP_Y, // F E | |
| 202 PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA, // P E | |
| 203 PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY, // F P E | |
| 204 PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA, // U E | |
| 205 PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY, // F U E | |
| 206 PROGRAM_COPY_TEXTURE_OES, // P U E | |
| 207 PROGRAM_COPY_TEXTURE_OES, // F P U E | |
| 208 }; | 135 }; |
| 209 | 136 |
| 210 unsigned index = (flip_y ? (1 << 0) : 0) | | 137 unsigned index = (flip_y ? (1 << 0) : 0) | |
| 211 (premultiply_alpha ? (1 << 1) : 0) | | 138 (premultiply_alpha ? (1 << 1) : 0) | |
| 212 (unpremultiply_alpha ? (1 << 2) : 0) | | 139 (unpremultiply_alpha ? (1 << 2) : 0); |
| 213 (is_source_external_oes ? (1 << 3) : 0); | 140 return shader_ids[index]; |
| 214 return program_ids[index]; | 141 } |
| 142 |
| 143 SamplerId GetSamplerId(GLenum source_target) { |
| 144 switch (source_target) { |
| 145 case GL_TEXTURE_2D: |
| 146 return SAMPLER_TEXTURE_2D; |
| 147 case GL_TEXTURE_EXTERNAL_OES: |
| 148 return SAMPLER_TEXTURE_EXTERNAL_OES; |
| 149 } |
| 150 |
| 151 NOTREACHED(); |
| 152 return SAMPLER_TEXTURE_2D; |
| 153 } |
| 154 |
| 155 void CompileShader(GLuint shader, const char* shader_source) { |
| 156 glShaderSource(shader, 1, &shader_source, 0); |
| 157 glCompileShader(shader); |
| 158 #ifndef NDEBUG |
| 159 GLint compile_status; |
| 160 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); |
| 161 if (GL_TRUE != compile_status) |
| 162 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; |
| 163 #endif |
| 215 } | 164 } |
| 216 | 165 |
| 217 } // namespace | 166 } // namespace |
| 218 | 167 |
| 219 namespace gpu { | 168 namespace gpu { |
| 220 | 169 |
| 221 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() | 170 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() |
| 222 : initialized_(false), | 171 : initialized_(false), buffer_id_(0), framebuffer_(0), vertex_shader_(0) { |
| 223 buffer_id_(0), | |
| 224 framebuffer_(0) { | |
| 225 for (int i = 0; i < kNumPrograms; ++i) { | |
| 226 programs_[i] = 0; | |
| 227 matrix_handle_[i] = 0; | |
| 228 sampler_locations_[i] = 0; | |
| 229 } | |
| 230 } | 172 } |
| 231 | 173 |
| 174 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {} |
| 175 |
| 232 void CopyTextureCHROMIUMResourceManager::Initialize( | 176 void CopyTextureCHROMIUMResourceManager::Initialize( |
| 233 const gles2::GLES2Decoder* decoder) { | 177 const gles2::GLES2Decoder* decoder) { |
| 234 COMPILE_ASSERT( | 178 COMPILE_ASSERT( |
| 235 kVertexPositionAttrib == 0u, | 179 kVertexPositionAttrib == 0u, |
| 236 Position_attribs_must_be_0); | 180 Position_attribs_must_be_0); |
| 237 | 181 |
| 238 const char* extensions = | |
| 239 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); | |
| 240 bool have_egl_image_external = extensions && | |
| 241 strstr(extensions, "GL_OES_EGL_image_external"); | |
| 242 | |
| 243 // Initialize all of the GPU resources required to perform the copy. | 182 // Initialize all of the GPU resources required to perform the copy. |
| 244 glGenBuffersARB(1, &buffer_id_); | 183 glGenBuffersARB(1, &buffer_id_); |
| 245 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 184 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
| 246 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, | 185 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, |
| 247 GL_STATIC_DRAW); | 186 GL_STATIC_DRAW); |
| 248 | 187 |
| 249 glGenFramebuffersEXT(1, &framebuffer_); | 188 glGenFramebuffersEXT(1, &framebuffer_); |
| 250 | 189 |
| 251 // TODO(gman): Init these on demand. | 190 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER); |
| 252 GLuint shaders[kNumShaders]; | 191 CompileShader(vertex_shader_, vertex_shader_source); |
| 253 for (int shader = 0; shader < kNumShaders; ++shader) { | |
| 254 shaders[shader] = glCreateShader( | |
| 255 shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); | |
| 256 const ShaderInfo& info = shader_infos[shader]; | |
| 257 if (info.needs_egl_image_external && !have_egl_image_external) { | |
| 258 continue; | |
| 259 } | |
| 260 const char* shader_source = shader_infos[shader].source; | |
| 261 glShaderSource(shaders[shader], 1, &shader_source, 0); | |
| 262 glCompileShader(shaders[shader]); | |
| 263 #ifndef NDEBUG | |
| 264 GLint compile_status; | |
| 265 glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status); | |
| 266 if (GL_TRUE != compile_status) | |
| 267 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | |
| 268 #endif | |
| 269 } | |
| 270 | |
| 271 // TODO(gman): Init these on demand. | |
| 272 for (int program = 0; program < kNumPrograms; ++program) { | |
| 273 const ShaderInfo& info = shader_infos[program + 1]; | |
| 274 if (info.needs_egl_image_external && !have_egl_image_external) { | |
| 275 continue; | |
| 276 } | |
| 277 programs_[program] = glCreateProgram(); | |
| 278 glAttachShader(programs_[program], shaders[0]); | |
| 279 glAttachShader(programs_[program], shaders[program + 1]); | |
| 280 | |
| 281 glBindAttribLocation(programs_[program], kVertexPositionAttrib, | |
| 282 "a_position"); | |
| 283 | |
| 284 glLinkProgram(programs_[program]); | |
| 285 #ifndef NDEBUG | |
| 286 GLint linked; | |
| 287 glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); | |
| 288 if (!linked) | |
| 289 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | |
| 290 #endif | |
| 291 | |
| 292 sampler_locations_[program] = glGetUniformLocation(programs_[program], | |
| 293 "u_texSampler"); | |
| 294 | |
| 295 matrix_handle_[program] = glGetUniformLocation(programs_[program], | |
| 296 "u_matrix"); | |
| 297 } | |
| 298 | |
| 299 for (int shader = 0; shader < kNumShaders; ++shader) | |
| 300 glDeleteShader(shaders[shader]); | |
| 301 | 192 |
| 302 decoder->RestoreBufferBindings(); | 193 decoder->RestoreBufferBindings(); |
| 303 | 194 |
| 304 initialized_ = true; | 195 initialized_ = true; |
| 305 } | 196 } |
| 306 | 197 |
| 307 void CopyTextureCHROMIUMResourceManager::Destroy() { | 198 void CopyTextureCHROMIUMResourceManager::Destroy() { |
| 308 if (!initialized_) | 199 if (!initialized_) |
| 309 return; | 200 return; |
| 310 | 201 |
| 311 glDeleteFramebuffersEXT(1, &framebuffer_); | 202 glDeleteFramebuffersEXT(1, &framebuffer_); |
| 312 | 203 |
| 313 for (int program = 0; program < kNumPrograms; ++program) { | 204 glDeleteShader(vertex_shader_); |
| 314 if (programs_[program]) | 205 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end(); |
| 315 glDeleteProgram(programs_[program]); | 206 ++it) { |
| 207 const ProgramInfo& info = it->second; |
| 208 glDeleteProgram(info.program); |
| 316 } | 209 } |
| 317 | 210 |
| 318 glDeleteBuffersARB(1, &buffer_id_); | 211 glDeleteBuffersARB(1, &buffer_id_); |
| 319 } | 212 } |
| 320 | 213 |
| 321 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | 214 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
| 322 const gles2::GLES2Decoder* decoder, | 215 const gles2::GLES2Decoder* decoder, |
| 323 GLenum source_target, | 216 GLenum source_target, |
| 324 GLenum dest_target, | 217 GLenum dest_target, |
| 325 GLuint source_id, | 218 GLuint source_id, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 353 bool premultiply_alpha, | 246 bool premultiply_alpha, |
| 354 bool unpremultiply_alpha, | 247 bool unpremultiply_alpha, |
| 355 const GLfloat transform_matrix[16]) { | 248 const GLfloat transform_matrix[16]) { |
| 356 DCHECK(source_target == GL_TEXTURE_2D || | 249 DCHECK(source_target == GL_TEXTURE_2D || |
| 357 source_target == GL_TEXTURE_EXTERNAL_OES); | 250 source_target == GL_TEXTURE_EXTERNAL_OES); |
| 358 if (!initialized_) { | 251 if (!initialized_) { |
| 359 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; | 252 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; |
| 360 return; | 253 return; |
| 361 } | 254 } |
| 362 | 255 |
| 363 GLuint program = GetProgram( | 256 ShaderId shader_id = |
| 364 flip_y, premultiply_alpha, unpremultiply_alpha, | 257 GetShaderId(flip_y, premultiply_alpha, unpremultiply_alpha); |
| 365 source_target == GL_TEXTURE_EXTERNAL_OES); | 258 SamplerId sampler_id = GetSamplerId(source_target); |
| 366 glUseProgram(programs_[program]); | 259 |
| 260 ProgramMapKey key(shader_id, sampler_id); |
| 261 ProgramInfo* info = &programs_[key]; |
| 262 // Create program if necessary. |
| 263 if (!info->program) { |
| 264 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); |
| 265 CompileShader(shader, fragment_shader_source[shader_id][sampler_id]); |
| 266 info->program = glCreateProgram(); |
| 267 glAttachShader(info->program, vertex_shader_); |
| 268 glAttachShader(info->program, shader); |
| 269 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); |
| 270 glLinkProgram(info->program); |
| 271 #ifndef NDEBUG |
| 272 GLint linked; |
| 273 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); |
| 274 if (!linked) |
| 275 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; |
| 276 #endif |
| 277 info->sampler_locations = |
| 278 glGetUniformLocation(info->program, "u_texSampler"); |
| 279 info->matrix_handle = glGetUniformLocation(info->program, "u_matrix"); |
| 280 glDeleteShader(shader); |
| 281 } |
| 282 glUseProgram(info->program); |
| 367 | 283 |
| 368 #ifndef NDEBUG | 284 #ifndef NDEBUG |
| 369 glValidateProgram(programs_[program]); | 285 glValidateProgram(info->program); |
| 370 GLint validation_status; | 286 GLint validation_status; |
| 371 glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status); | 287 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); |
| 372 if (GL_TRUE != validation_status) { | 288 if (GL_TRUE != validation_status) { |
| 373 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | 289 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; |
| 374 return; | 290 return; |
| 375 } | 291 } |
| 376 #endif | 292 #endif |
| 377 | 293 |
| 378 glUniformMatrix4fv(matrix_handle_[program], 1, GL_FALSE, transform_matrix); | 294 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); |
| 379 glActiveTexture(GL_TEXTURE0); | 295 glActiveTexture(GL_TEXTURE0); |
| 380 glBindTexture(GL_TEXTURE_2D, dest_id); | 296 glBindTexture(GL_TEXTURE_2D, dest_id); |
| 381 // NVidia drivers require texture settings to be a certain way | 297 // NVidia drivers require texture settings to be a certain way |
| 382 // or they won't report FRAMEBUFFER_COMPLETE. | 298 // or they won't report FRAMEBUFFER_COMPLETE. |
| 383 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 299 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 384 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 300 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 385 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 386 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 387 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); | 303 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); |
| 388 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target, | 304 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target, |
| 389 dest_id, level); | 305 dest_id, level); |
| 390 | 306 |
| 391 #ifndef NDEBUG | 307 #ifndef NDEBUG |
| 392 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 308 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| 393 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | 309 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { |
| 394 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | 310 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; |
| 395 } else | 311 } else |
| 396 #endif | 312 #endif |
| 397 { | 313 { |
| 398 decoder->ClearAllAttributes(); | 314 decoder->ClearAllAttributes(); |
| 399 glEnableVertexAttribArray(kVertexPositionAttrib); | 315 glEnableVertexAttribArray(kVertexPositionAttrib); |
| 400 | 316 |
| 401 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 317 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
| 402 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, | 318 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, |
| 403 4 * sizeof(GLfloat), 0); | 319 4 * sizeof(GLfloat), 0); |
| 404 | 320 |
| 405 glUniform1i(sampler_locations_[program], 0); | 321 glUniform1i(info->sampler_locations, 0); |
| 406 | 322 |
| 407 glBindTexture(source_target, source_id); | 323 glBindTexture(source_target, source_id); |
| 408 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 324 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 409 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 325 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 410 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 326 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 411 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 327 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 412 | 328 |
| 413 glDisable(GL_DEPTH_TEST); | 329 glDisable(GL_DEPTH_TEST); |
| 414 glDisable(GL_SCISSOR_TEST); | 330 glDisable(GL_SCISSOR_TEST); |
| 415 glDisable(GL_STENCIL_TEST); | 331 glDisable(GL_STENCIL_TEST); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 428 decoder->RestoreTextureUnitBindings(0); | 344 decoder->RestoreTextureUnitBindings(0); |
| 429 decoder->RestoreActiveTexture(); | 345 decoder->RestoreActiveTexture(); |
| 430 decoder->RestoreProgramBindings(); | 346 decoder->RestoreProgramBindings(); |
| 431 decoder->RestoreBufferBindings(); | 347 decoder->RestoreBufferBindings(); |
| 432 decoder->RestoreFramebufferBindings(); | 348 decoder->RestoreFramebufferBindings(); |
| 433 decoder->RestoreGlobalState(); | 349 decoder->RestoreGlobalState(); |
| 434 } | 350 } |
| 435 | 351 |
| 436 } // namespace | 352 } // namespace |
| 437 | 353 |
| OLD | NEW |