Chromium Code Reviews| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| 11 #include "gpu/command_buffer/service/gl_utils.h" | 11 #include "gpu/command_buffer/service/gl_utils.h" |
| 12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 13 #include "gpu/command_buffer/service/texture_manager.h" | |
| 13 #include "ui/gl/gl_version_info.h" | 14 #include "ui/gl/gl_version_info.h" |
| 14 | 15 |
| 15 namespace { | 16 namespace { |
| 16 | 17 |
| 17 const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, | 18 const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, |
| 18 0.0f, 1.0f, 0.0f, 0.0f, | 19 0.0f, 1.0f, 0.0f, 0.0f, |
| 19 0.0f, 0.0f, 1.0f, 0.0f, | 20 0.0f, 0.0f, 1.0f, 0.0f, |
| 20 0.0f, 0.0f, 0.0f, 1.0f}; | 21 0.0f, 0.0f, 0.0f, 1.0f}; |
| 21 | 22 |
| 22 enum FragmentShaderId { | 23 enum FragmentShaderId { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 case GL_TEXTURE_EXTERNAL_OES: | 80 case GL_TEXTURE_EXTERNAL_OES: |
| 80 return shader_ids[index][SAMPLER_EXTERNAL_OES]; | 81 return shader_ids[index][SAMPLER_EXTERNAL_OES]; |
| 81 default: | 82 default: |
| 82 break; | 83 break; |
| 83 } | 84 } |
| 84 | 85 |
| 85 NOTREACHED(); | 86 NOTREACHED(); |
| 86 return shader_ids[0][SAMPLER_2D]; | 87 return shader_ids[0][SAMPLER_2D]; |
| 87 } | 88 } |
| 88 | 89 |
| 89 const char* kShaderPrecisionPreamble = "\ | 90 const char* kShaderPrecisionPreamble = |
| 90 #ifdef GL_ES\n\ | 91 "#ifdef GL_ES\n" |
| 91 precision mediump float;\n\ | 92 "precision mediump float;\n" |
| 92 #define TexCoordPrecision mediump\n\ | 93 "#define TexCoordPrecision mediump\n" |
| 93 #else\n\ | 94 "#else\n" |
| 94 #define TexCoordPrecision\n\ | 95 "#define TexCoordPrecision\n" |
| 95 #endif\n"; | 96 "#endif\n"; |
| 96 | 97 |
| 97 std::string GetVertexShaderSource(const gl::GLVersionInfo& gl_version_info) { | 98 std::string GetVertexShaderSource(const gl::GLVersionInfo& gl_version_info) { |
| 98 std::string source; | 99 std::string source; |
| 99 | 100 |
| 100 // Preamble for core and compatibility mode. | 101 if (gl_version_info.is_es) { |
| 101 if (gl_version_info.is_desktop_core_profile) { | 102 if (gl_version_info.is_es3) { |
| 102 source += std::string("\ | 103 source += std::string("#version 300 es\n"); |
|
Ken Russell (switch to Gerrit)
2016/12/07 06:38:01
All of the explicit constructor calls to std::stri
qiankun
2016/12/10 00:12:40
Done.
| |
| 103 #version 150\n\ | 104 source += std::string( |
| 104 #define ATTRIBUTE in\n\ | 105 "#define ATTRIBUTE in\n" |
| 105 #define VARYING out\n"); | 106 "#define VARYING out\n"); |
| 107 } else { | |
| 108 source += std::string( | |
| 109 "#define ATTRIBUTE attribute\n" | |
| 110 "#define VARYING varying\n"); | |
| 111 } | |
| 106 } else { | 112 } else { |
| 107 source += std::string("\ | 113 source += std::string("#version 150\n"); |
| 108 #define ATTRIBUTE attribute\n\ | 114 source += std::string( |
| 109 #define VARYING varying\n"); | 115 "#define ATTRIBUTE in\n" |
| 116 "#define VARYING out\n"); | |
| 110 } | 117 } |
| 111 | 118 |
| 112 // Preamble for texture precision. | 119 // Preamble for texture precision. |
| 113 source += std::string(kShaderPrecisionPreamble); | 120 source += std::string(kShaderPrecisionPreamble); |
| 114 | 121 |
| 115 // Main shader source. | 122 // Main shader source. |
| 116 source += std::string("\ | 123 source += std::string( |
| 117 uniform vec2 u_vertex_dest_mult;\n\ | 124 "uniform vec2 u_vertex_dest_mult;\n" |
| 118 uniform vec2 u_vertex_dest_add;\n\ | 125 "uniform vec2 u_vertex_dest_add;\n" |
| 119 uniform vec2 u_vertex_source_mult;\n\ | 126 "uniform vec2 u_vertex_source_mult;\n" |
| 120 uniform vec2 u_vertex_source_add;\n\ | 127 "uniform vec2 u_vertex_source_add;\n" |
| 121 ATTRIBUTE vec2 a_position;\n\ | 128 "ATTRIBUTE vec2 a_position;\n" |
| 122 VARYING TexCoordPrecision vec2 v_uv;\n\ | 129 "VARYING TexCoordPrecision vec2 v_uv;\n" |
| 123 void main(void) {\n\ | 130 "void main(void) {\n" |
| 124 gl_Position = vec4(0, 0, 0, 1);\n\ | 131 " gl_Position = vec4(0, 0, 0, 1);\n" |
| 125 gl_Position.xy = a_position.xy * u_vertex_dest_mult + \ | 132 " gl_Position.xy = a_position.xy * u_vertex_dest_mult + " |
| 126 u_vertex_dest_add;\n\ | 133 "u_vertex_dest_add;\n" |
| 127 v_uv = a_position.xy * u_vertex_source_mult + u_vertex_source_add;\n\ | 134 " v_uv = a_position.xy * u_vertex_source_mult + u_vertex_source_add;\n" |
| 128 }\n"); | 135 "}\n"); |
| 129 | 136 |
| 130 return source; | 137 return source; |
| 131 } | 138 } |
| 132 | 139 |
| 133 std::string GetFragmentShaderSource(const gl::GLVersionInfo& gl_version_info, | 140 std::string GetFragmentShaderSource(const gl::GLVersionInfo& gl_version_info, |
| 134 bool premultiply_alpha, | 141 bool premultiply_alpha, |
| 135 bool unpremultiply_alpha, | 142 bool unpremultiply_alpha, |
| 136 bool nv_egl_stream_consumer_external, | 143 bool nv_egl_stream_consumer_external, |
| 137 GLenum target) { | 144 GLenum target, |
| 145 GLenum source_format, | |
| 146 GLenum dest_format) { | |
| 138 std::string source; | 147 std::string source; |
| 139 | 148 |
| 140 // Preamble for core and compatibility mode. | 149 // Preamble for core and compatibility mode. |
| 141 if (gl_version_info.is_desktop_core_profile) { | 150 if (gl_version_info.is_es) { |
| 142 source += std::string("\ | 151 if (gl_version_info.is_es3) { |
| 143 #version 150\n\ | 152 source += std::string("#version 300 es\n"); |
| 144 out vec4 frag_color;\n\ | 153 } |
| 145 #define VARYING in\n\ | 154 if (target == GL_TEXTURE_EXTERNAL_OES) { |
| 146 #define FRAGCOLOR frag_color\n\ | 155 source += std::string("#extension GL_OES_EGL_image_external : enable\n"); |
| 147 #define TextureLookup texture\n"); | 156 |
| 157 if (nv_egl_stream_consumer_external) { | |
| 158 source += std::string( | |
| 159 "#extension GL_NV_EGL_stream_consumer_external : enable\n"); | |
| 160 } | |
| 161 } | |
| 148 } else { | 162 } else { |
| 163 source += std::string("#version 150\n"); | |
| 164 } | |
| 165 | |
| 166 // Preamble for texture precision. | |
| 167 source += std::string(kShaderPrecisionPreamble); | |
| 168 | |
| 169 if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(dest_format)) { | |
| 170 source += std::string("#define TextureType ivec4\n"); | |
|
Ken Russell (switch to Gerrit)
2016/12/07 06:38:01
In particular: all of the explicit calls to std::s
qiankun
2016/12/10 00:12:40
Done.
| |
| 171 source += std::string("#define ZERO 0\n"); | |
| 172 source += std::string("#define MAX_COLOR 255\n"); | |
| 173 if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) | |
| 174 source += std::string("#define InnerScaleValue 1\n"); | |
| 175 else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) | |
| 176 source += std::string("#define InnerScaleValue 1u\n"); | |
| 177 else | |
| 178 source += std::string("#define InnerScaleValue 255.0\n"); | |
| 179 source += std::string("#define OuterScaleValue 1\n"); | |
| 180 } else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(dest_format)) { | |
| 181 source += std::string("#define TextureType uvec4\n"); | |
| 182 source += std::string("#define ZERO 0u\n"); | |
| 183 source += std::string("#define MAX_COLOR 255u\n"); | |
| 184 if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) | |
| 185 source += std::string("#define InnerScaleValue 1\n"); | |
| 186 else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) | |
| 187 source += std::string("#define InnerScaleValue 1u\n"); | |
| 188 else | |
| 189 source += std::string("#define InnerScaleValue 255.0\n"); | |
| 190 source += std::string("#define OuterScaleValue 1u\n"); | |
| 191 } else { | |
| 192 source += std::string("#define TextureType vec4\n"); | |
| 193 source += std::string("#define ZERO 0.0\n"); | |
| 194 source += std::string("#define MAX_COLOR 1.0\n"); | |
| 195 if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) { | |
| 196 source += std::string("#define InnerScaleValue 1\n"); | |
| 197 source += std::string("#define OuterScaleValue (1.0 / 255.0)\n"); | |
| 198 } else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) { | |
| 199 source += std::string("#define InnerScaleValue 1u\n"); | |
| 200 source += std::string("#define OuterScaleValue (1.0 / 255.0)\n"); | |
| 201 } else { | |
| 202 source += std::string("#define InnerScaleValue 1.0\n"); | |
| 203 source += std::string("#define OuterScaleValue 1.0\n"); | |
| 204 } | |
| 205 } | |
| 206 if (gl_version_info.is_es2) { | |
| 149 switch (target) { | 207 switch (target) { |
| 150 case GL_TEXTURE_2D: | 208 case GL_TEXTURE_2D: |
| 151 source += std::string("#define TextureLookup texture2D\n"); | |
| 152 break; | |
| 153 case GL_TEXTURE_RECTANGLE_ARB: | |
| 154 source += std::string("#define TextureLookup texture2DRect\n"); | |
| 155 break; | |
| 156 case GL_TEXTURE_EXTERNAL_OES: | 209 case GL_TEXTURE_EXTERNAL_OES: |
| 157 source += | |
| 158 std::string("#extension GL_OES_EGL_image_external : enable\n"); | |
| 159 | |
| 160 if (nv_egl_stream_consumer_external) { | |
| 161 source += std::string( | |
| 162 "#extension GL_NV_EGL_stream_consumer_external : enable\n"); | |
| 163 } | |
| 164 | |
| 165 source += std::string("#define TextureLookup texture2D\n"); | 210 source += std::string("#define TextureLookup texture2D\n"); |
| 166 break; | 211 break; |
| 167 default: | 212 default: |
| 168 NOTREACHED(); | 213 NOTREACHED(); |
| 169 break; | 214 break; |
| 170 } | 215 } |
| 171 source += std::string("\ | 216 |
| 172 #define VARYING varying\n\ | 217 source += std::string( |
| 173 #define FRAGCOLOR gl_FragColor\n"); | 218 "#define VARYING varying\n" |
| 219 "#define FRAGCOLOR gl_FragColor\n"); | |
| 220 } else { | |
| 221 source += std::string( | |
| 222 "#define VARYING in\n" | |
| 223 "out TextureType frag_color;\n" | |
| 224 "#define FRAGCOLOR frag_color\n" | |
| 225 "#define TextureLookup texture\n"); | |
| 174 } | 226 } |
| 175 | 227 |
| 176 // Preamble for sampler type. | 228 // Preamble for sampler type. |
| 177 switch (target) { | 229 switch (target) { |
| 178 case GL_TEXTURE_2D: | 230 case GL_TEXTURE_2D: |
| 179 source += std::string("#define SamplerType sampler2D\n"); | 231 source += std::string("#define SamplerType sampler2D\n"); |
| 180 break; | 232 break; |
| 181 case GL_TEXTURE_RECTANGLE_ARB: | 233 case GL_TEXTURE_RECTANGLE_ARB: |
| 182 source += std::string("#define SamplerType sampler2DRect\n"); | 234 source += std::string("#define SamplerType sampler2DRect\n"); |
| 183 break; | 235 break; |
| 184 case GL_TEXTURE_EXTERNAL_OES: | 236 case GL_TEXTURE_EXTERNAL_OES: |
| 185 source += std::string("#define SamplerType samplerExternalOES\n"); | 237 source += std::string("#define SamplerType samplerExternalOES\n"); |
| 186 break; | 238 break; |
| 187 default: | 239 default: |
| 188 NOTREACHED(); | 240 NOTREACHED(); |
| 189 break; | 241 break; |
| 190 } | 242 } |
| 191 | 243 |
| 192 // Preamble for texture precision. | |
| 193 source += std::string(kShaderPrecisionPreamble); | |
| 194 | |
| 195 // Main shader source. | 244 // Main shader source. |
| 196 source += std::string("\ | 245 source += std::string( |
| 197 uniform SamplerType u_sampler;\n\ | 246 "uniform mediump SamplerType u_sampler;\n" |
| 198 uniform mat4 u_tex_coord_transform;\n\ | 247 "uniform mat4 u_tex_coord_transform;\n" |
| 199 VARYING TexCoordPrecision vec2 v_uv;\n\ | 248 "VARYING TexCoordPrecision vec2 v_uv;\n" |
| 200 void main(void) {\n\ | 249 "void main(void) {\n" |
| 201 TexCoordPrecision vec4 uv = u_tex_coord_transform * vec4(v_uv, 0, 1);\n\ | 250 " TexCoordPrecision vec4 uv = u_tex_coord_transform * vec4(v_uv, 0, " |
|
Ken Russell (switch to Gerrit)
2016/12/07 06:38:01
I'd break this line after the "=" operator with a
qiankun
2016/12/10 00:12:40
Done.
| |
| 202 FRAGCOLOR = TextureLookup(u_sampler, uv.st);\n"); | 251 "1);\n" |
| 252 " vec4 color = TextureLookup(u_sampler, uv.st);\n" | |
| 253 " FRAGCOLOR = TextureType(color * InnerScaleValue) * " | |
|
Ken Russell (switch to Gerrit)
2016/12/07 06:38:01
Same here.
qiankun
2016/12/10 00:12:40
Done.
| |
| 254 "OuterScaleValue;\n"); | |
| 203 | 255 |
| 204 // Post-processing to premultiply or un-premultiply alpha. | 256 // Post-processing to premultiply or un-premultiply alpha. |
| 205 if (premultiply_alpha) { | 257 // Check dest format has alpha channel first. |
| 206 source += std::string(" FRAGCOLOR.rgb *= FRAGCOLOR.a;\n"); | 258 if ((gpu::gles2::GLES2Util::GetChannelsForFormat(dest_format) & 0x0008) != |
| 207 } | 259 0) { |
| 208 if (unpremultiply_alpha) { | 260 if (premultiply_alpha) { |
| 209 source += std::string("\ | 261 source += std::string(" FRAGCOLOR.rgb *= FRAGCOLOR.a;\n"); |
| 210 if (FRAGCOLOR.a > 0.0)\n\ | 262 source += std::string(" FRAGCOLOR.rgb /= MAX_COLOR;\n"); |
| 211 FRAGCOLOR.rgb /= FRAGCOLOR.a;\n"); | 263 } |
| 264 if (unpremultiply_alpha) { | |
| 265 source += std::string( | |
| 266 " if (FRAGCOLOR.a > ZERO) {\n" | |
| 267 " FRAGCOLOR.rgb /= FRAGCOLOR.a;\n" | |
| 268 " FRAGCOLOR.rgb *= MAX_COLOR;\n" | |
| 269 " }\n"); | |
| 270 } | |
| 212 } | 271 } |
| 213 | 272 |
| 214 // Main function end. | 273 // Main function end. |
| 215 source += std::string(" }\n"); | 274 source += std::string("}\n"); |
| 216 | 275 |
| 217 return source; | 276 return source; |
| 218 } | 277 } |
| 219 | 278 |
| 279 GLenum getIntermediateFormat(GLenum format) { | |
| 280 switch (format) { | |
| 281 case GL_LUMINANCE_ALPHA: | |
| 282 case GL_LUMINANCE: | |
| 283 case GL_ALPHA: | |
| 284 return GL_RGBA; | |
| 285 case GL_SRGB_EXT: | |
| 286 return GL_SRGB_ALPHA_EXT; | |
| 287 case GL_RGB16F: | |
| 288 return GL_RGBA16F; | |
| 289 case GL_RGB9_E5: | |
| 290 case GL_RGB32F: | |
| 291 return GL_RGBA32F; | |
| 292 case GL_SRGB8: | |
| 293 return GL_SRGB8_ALPHA8; | |
| 294 case GL_RGB8UI: | |
| 295 return GL_RGBA8UI; | |
| 296 default: | |
| 297 return format; | |
| 298 } | |
| 299 } | |
| 300 | |
| 220 void CompileShader(GLuint shader, const char* shader_source) { | 301 void CompileShader(GLuint shader, const char* shader_source) { |
| 221 glShaderSource(shader, 1, &shader_source, 0); | 302 glShaderSource(shader, 1, &shader_source, 0); |
| 222 glCompileShader(shader); | 303 glCompileShader(shader); |
| 223 #ifndef NDEBUG | 304 #ifndef NDEBUG |
|
Ken Russell (switch to Gerrit)
2016/12/07 06:38:01
Could you change this to #if DCHECK_IS_ON() ? We r
qiankun
2016/12/10 00:12:40
Done.
| |
| 224 GLint compile_status; | 305 GLint compile_status; |
| 225 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); | 306 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); |
| 226 if (GL_TRUE != compile_status) | 307 if (GL_TRUE != compile_status) { |
| 227 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | 308 char buffer[1024]; |
| 309 GLsizei length = 0; | |
| 310 glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); | |
| 311 std::string log(buffer, length); | |
| 312 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure: " << log; | |
| 313 } | |
| 228 #endif | 314 #endif |
| 229 } | 315 } |
| 230 | 316 |
| 231 void DeleteShader(GLuint shader) { | 317 void DeleteShader(GLuint shader) { |
| 232 if (shader) | 318 if (shader) |
| 233 glDeleteShader(shader); | 319 glDeleteShader(shader); |
| 234 } | 320 } |
| 235 | 321 |
| 236 bool BindFramebufferTexture2D(GLenum target, | 322 bool BindFramebufferTexture2D(GLenum target, |
| 237 GLuint texture_id, | 323 GLuint texture_id, |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 GLenum source_target, | 498 GLenum source_target, |
| 413 GLuint source_id, | 499 GLuint source_id, |
| 414 GLenum source_internal_format, | 500 GLenum source_internal_format, |
| 415 GLenum dest_target, | 501 GLenum dest_target, |
| 416 GLuint dest_id, | 502 GLuint dest_id, |
| 417 GLenum dest_internal_format, | 503 GLenum dest_internal_format, |
| 418 GLsizei width, | 504 GLsizei width, |
| 419 GLsizei height, | 505 GLsizei height, |
| 420 bool flip_y, | 506 bool flip_y, |
| 421 bool premultiply_alpha, | 507 bool premultiply_alpha, |
| 422 bool unpremultiply_alpha) { | 508 bool unpremultiply_alpha, |
| 509 SupportedCopyMethodByFormat method) { | |
| 423 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | 510 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
| 424 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | 511 |
| 425 // format does not contain a superset of the components required by the base | |
| 426 // format of internalformat. | |
| 427 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | |
| 428 bool source_format_contain_superset_of_dest_format = | |
| 429 (source_internal_format == dest_internal_format && | |
| 430 source_internal_format != GL_BGRA_EXT) || | |
| 431 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | |
| 432 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | 512 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
| 433 // so restrict this to GL_TEXTURE_2D. | 513 // so restrict this to GL_TEXTURE_2D. |
| 434 if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D && | 514 if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D && |
| 435 !flip_y && !premultiply_alpha_change && | 515 !flip_y && !premultiply_alpha_change && method == DIRECT_COPY) { |
| 436 source_format_contain_superset_of_dest_format) { | |
| 437 DoCopyTexImage2D(decoder, | 516 DoCopyTexImage2D(decoder, |
| 438 source_target, | 517 source_target, |
| 439 source_id, | 518 source_id, |
| 440 dest_target, | 519 dest_target, |
| 441 dest_id, | 520 dest_id, |
| 442 dest_internal_format, | 521 dest_internal_format, |
| 443 width, | 522 width, |
| 444 height, | 523 height, |
| 445 framebuffer_); | 524 framebuffer_); |
| 446 return; | 525 return; |
| 447 } | 526 } |
| 448 | 527 |
| 528 GLenum adjusted_internal_format = getIntermediateFormat(dest_internal_format); | |
| 529 GLuint intermediate_texture = dest_id; | |
| 530 if (method == DRAW_AND_COPY) { | |
| 531 glGenTextures(1, &intermediate_texture); | |
| 532 glBindTexture(dest_target, intermediate_texture); | |
| 533 GLenum format = TextureManager::ExtractFormatFromStorageFormat( | |
| 534 adjusted_internal_format); | |
| 535 GLenum type = | |
| 536 TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); | |
| 537 | |
| 538 glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, | |
| 539 format, type, nullptr); | |
| 540 } | |
| 449 // Use kIdentityMatrix if no transform passed in. | 541 // Use kIdentityMatrix if no transform passed in. |
| 450 DoCopyTextureWithTransform(decoder, source_target, source_id, dest_target, | 542 DoCopyTextureWithTransform( |
| 451 dest_id, width, height, flip_y, premultiply_alpha, | 543 decoder, source_target, source_id, source_internal_format, dest_target, |
| 452 unpremultiply_alpha, kIdentityMatrix); | 544 intermediate_texture, adjusted_internal_format, width, height, flip_y, |
| 545 premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); | |
| 546 | |
| 547 if (method == DRAW_AND_COPY) { | |
| 548 DoCopyTexImage2D(decoder, dest_target, intermediate_texture, dest_target, | |
| 549 dest_id, dest_internal_format, width, height, | |
| 550 framebuffer_); | |
| 551 glDeleteTextures(1, &intermediate_texture); | |
| 552 } | |
| 453 } | 553 } |
| 454 | 554 |
| 455 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( | 555 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
| 456 const gles2::GLES2Decoder* decoder, | 556 const gles2::GLES2Decoder* decoder, |
| 457 GLenum source_target, | 557 GLenum source_target, |
| 458 GLuint source_id, | 558 GLuint source_id, |
| 459 GLenum source_internal_format, | 559 GLenum source_internal_format, |
| 460 GLenum dest_target, | 560 GLenum dest_target, |
| 461 GLuint dest_id, | 561 GLuint dest_id, |
| 462 GLenum dest_internal_format, | 562 GLenum dest_internal_format, |
| 463 GLint xoffset, | 563 GLint xoffset, |
| 464 GLint yoffset, | 564 GLint yoffset, |
| 465 GLint x, | 565 GLint x, |
| 466 GLint y, | 566 GLint y, |
| 467 GLsizei width, | 567 GLsizei width, |
| 468 GLsizei height, | 568 GLsizei height, |
| 469 GLsizei dest_width, | 569 GLsizei dest_width, |
| 470 GLsizei dest_height, | 570 GLsizei dest_height, |
| 471 GLsizei source_width, | 571 GLsizei source_width, |
| 472 GLsizei source_height, | 572 GLsizei source_height, |
| 473 bool flip_y, | 573 bool flip_y, |
| 474 bool premultiply_alpha, | 574 bool premultiply_alpha, |
| 475 bool unpremultiply_alpha) { | 575 bool unpremultiply_alpha, |
| 576 SupportedCopyMethodByFormat method) { | |
| 476 bool use_gl_copy_tex_sub_image_2d = true; | 577 bool use_gl_copy_tex_sub_image_2d = true; |
| 477 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | 578 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
| 478 // glDrawArrays is faster than glCopyTexSubImage2D on IA Mesa driver, | 579 // glDrawArrays is faster than glCopyTexSubImage2D on IA Mesa driver, |
| 479 // although opposite in Android. | 580 // although opposite in Android. |
| 480 // TODO(dshwang): After Mesa fixes this issue, remove this hack. | 581 // TODO(dshwang): After Mesa fixes this issue, remove this hack. |
| 481 // https://bugs.freedesktop.org/show_bug.cgi?id=98478 crbug.com/535198 | 582 // https://bugs.freedesktop.org/show_bug.cgi?id=98478 crbug.com/535198 |
| 482 use_gl_copy_tex_sub_image_2d = false; | 583 use_gl_copy_tex_sub_image_2d = false; |
| 483 #endif | 584 #endif |
| 484 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | 585 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
| 485 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | 586 |
| 486 // format does not contain a superset of the components required by the base | |
| 487 // format of internalformat. | |
| 488 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | |
| 489 bool source_format_contain_superset_of_dest_format = | |
| 490 (source_internal_format == dest_internal_format && | |
| 491 source_internal_format != GL_BGRA_EXT) || | |
| 492 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | |
| 493 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | 587 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
| 494 // so restrict this to GL_TEXTURE_2D. | 588 // so restrict this to GL_TEXTURE_2D. |
| 495 if (use_gl_copy_tex_sub_image_2d && source_target == GL_TEXTURE_2D && | 589 if (use_gl_copy_tex_sub_image_2d && source_target == GL_TEXTURE_2D && |
| 496 dest_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && | 590 dest_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && |
| 497 source_format_contain_superset_of_dest_format) { | 591 method == DIRECT_COPY) { |
| 498 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_target, dest_id, | 592 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_target, dest_id, |
| 499 xoffset, yoffset, x, y, width, height, framebuffer_); | 593 xoffset, yoffset, x, y, width, height, framebuffer_); |
| 500 return; | 594 return; |
| 501 } | 595 } |
| 502 | 596 |
| 597 GLint dest_xoffset = xoffset; | |
| 598 GLint dest_yoffset = yoffset; | |
| 599 GLuint dest_texture = dest_id; | |
| 600 GLuint intermediate_texture = 0; | |
| 601 if (method == DRAW_AND_COPY) { | |
| 602 GLenum adjusted_internal_format = | |
| 603 getIntermediateFormat(dest_internal_format); | |
| 604 glGenTextures(1, &intermediate_texture); | |
| 605 glBindTexture(dest_target, intermediate_texture); | |
| 606 GLenum format = TextureManager::ExtractFormatFromStorageFormat( | |
| 607 adjusted_internal_format); | |
| 608 GLenum type = | |
| 609 TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); | |
| 610 | |
| 611 glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, | |
| 612 format, type, nullptr); | |
| 613 dest_texture = intermediate_texture; | |
| 614 dest_xoffset = 0; | |
| 615 dest_yoffset = 0; | |
| 616 dest_width = width; | |
| 617 dest_height = height; | |
| 618 } | |
| 619 | |
| 503 DoCopySubTextureWithTransform( | 620 DoCopySubTextureWithTransform( |
| 504 decoder, source_target, source_id, source_internal_format, dest_target, | 621 decoder, source_target, source_id, source_internal_format, dest_target, |
| 505 dest_id, dest_internal_format, xoffset, yoffset, x, y, width, height, | 622 dest_texture, dest_internal_format, dest_xoffset, dest_yoffset, x, y, |
| 506 dest_width, dest_height, source_width, source_height, flip_y, | 623 width, height, dest_width, dest_height, source_width, source_height, |
| 507 premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); | 624 flip_y, premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); |
| 625 | |
| 626 if (method == DRAW_AND_COPY) { | |
| 627 DoCopyTexSubImage2D(decoder, dest_target, intermediate_texture, dest_target, | |
| 628 dest_id, xoffset, yoffset, 0, 0, width, height, | |
| 629 framebuffer_); | |
| 630 glDeleteTextures(1, &intermediate_texture); | |
| 631 } | |
| 508 } | 632 } |
| 509 | 633 |
| 510 void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( | 634 void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( |
| 511 const gles2::GLES2Decoder* decoder, | 635 const gles2::GLES2Decoder* decoder, |
| 512 GLenum source_target, | 636 GLenum source_target, |
| 513 GLuint source_id, | 637 GLuint source_id, |
| 514 GLenum source_internal_format, | 638 GLenum source_internal_format, |
| 515 GLenum dest_target, | 639 GLenum dest_target, |
| 516 GLuint dest_id, | 640 GLuint dest_id, |
| 517 GLenum dest_internal_format, | 641 GLenum dest_internal_format, |
| 518 GLint xoffset, | 642 GLint xoffset, |
| 519 GLint yoffset, | 643 GLint yoffset, |
| 520 GLint x, | 644 GLint x, |
| 521 GLint y, | 645 GLint y, |
| 522 GLsizei width, | 646 GLsizei width, |
| 523 GLsizei height, | 647 GLsizei height, |
| 524 GLsizei dest_width, | 648 GLsizei dest_width, |
| 525 GLsizei dest_height, | 649 GLsizei dest_height, |
| 526 GLsizei source_width, | 650 GLsizei source_width, |
| 527 GLsizei source_height, | 651 GLsizei source_height, |
| 528 bool flip_y, | 652 bool flip_y, |
| 529 bool premultiply_alpha, | 653 bool premultiply_alpha, |
| 530 bool unpremultiply_alpha, | 654 bool unpremultiply_alpha, |
| 531 const GLfloat transform_matrix[16]) { | 655 const GLfloat transform_matrix[16]) { |
| 532 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id, | 656 DoCopyTextureInternal( |
| 533 xoffset, yoffset, x, y, width, height, dest_width, dest_height, | 657 decoder, source_target, source_id, source_internal_format, dest_target, |
| 534 source_width, source_height, flip_y, premultiply_alpha, | 658 dest_id, dest_internal_format, xoffset, yoffset, x, y, width, height, |
| 535 unpremultiply_alpha, transform_matrix); | 659 dest_width, dest_height, source_width, source_height, flip_y, |
| 660 premultiply_alpha, unpremultiply_alpha, transform_matrix); | |
| 536 } | 661 } |
| 537 | 662 |
| 538 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( | 663 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( |
| 539 const gles2::GLES2Decoder* decoder, | 664 const gles2::GLES2Decoder* decoder, |
| 540 GLenum source_target, | 665 GLenum source_target, |
| 541 GLuint source_id, | 666 GLuint source_id, |
| 667 GLenum source_format, | |
| 542 GLenum dest_target, | 668 GLenum dest_target, |
| 543 GLuint dest_id, | 669 GLuint dest_id, |
| 670 GLenum dest_format, | |
| 544 GLsizei width, | 671 GLsizei width, |
| 545 GLsizei height, | 672 GLsizei height, |
| 546 bool flip_y, | 673 bool flip_y, |
| 547 bool premultiply_alpha, | 674 bool premultiply_alpha, |
| 548 bool unpremultiply_alpha, | 675 bool unpremultiply_alpha, |
| 549 const GLfloat transform_matrix[16]) { | 676 const GLfloat transform_matrix[16]) { |
| 550 GLsizei dest_width = width; | 677 GLsizei dest_width = width; |
| 551 GLsizei dest_height = height; | 678 GLsizei dest_height = height; |
| 552 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id, | 679 DoCopyTextureInternal( |
| 553 0, 0, 0, 0, width, height, dest_width, dest_height, | 680 decoder, source_target, source_id, source_format, dest_target, dest_id, |
| 554 width, height, flip_y, premultiply_alpha, | 681 dest_format, 0, 0, 0, 0, width, height, dest_width, dest_height, width, |
| 555 unpremultiply_alpha, transform_matrix); | 682 height, flip_y, premultiply_alpha, unpremultiply_alpha, transform_matrix); |
| 556 } | 683 } |
| 557 | 684 |
| 558 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( | 685 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( |
| 559 const gles2::GLES2Decoder* decoder, | 686 const gles2::GLES2Decoder* decoder, |
| 560 GLenum source_target, | 687 GLenum source_target, |
| 561 GLuint source_id, | 688 GLuint source_id, |
| 689 GLenum source_format, | |
| 562 GLenum dest_target, | 690 GLenum dest_target, |
| 563 GLuint dest_id, | 691 GLuint dest_id, |
| 692 GLenum dest_format, | |
| 564 GLint xoffset, | 693 GLint xoffset, |
| 565 GLint yoffset, | 694 GLint yoffset, |
| 566 GLint x, | 695 GLint x, |
| 567 GLint y, | 696 GLint y, |
| 568 GLsizei width, | 697 GLsizei width, |
| 569 GLsizei height, | 698 GLsizei height, |
| 570 GLsizei dest_width, | 699 GLsizei dest_width, |
| 571 GLsizei dest_height, | 700 GLsizei dest_height, |
| 572 GLsizei source_width, | 701 GLsizei source_width, |
| 573 GLsizei source_height, | 702 GLsizei source_height, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 735 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
| 607 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); | 736 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); |
| 608 } | 737 } |
| 609 | 738 |
| 610 FragmentShaderId fragment_shader_id = GetFragmentShaderId( | 739 FragmentShaderId fragment_shader_id = GetFragmentShaderId( |
| 611 premultiply_alpha, unpremultiply_alpha, source_target); | 740 premultiply_alpha, unpremultiply_alpha, source_target); |
| 612 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); | 741 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); |
| 613 | 742 |
| 614 ProgramMapKey key(fragment_shader_id); | 743 ProgramMapKey key(fragment_shader_id); |
| 615 ProgramInfo* info = &programs_[key]; | 744 ProgramInfo* info = &programs_[key]; |
| 745 // TODO(qiankun.miao@intel.com): check if it is possible to cache program and | |
|
Ken Russell (switch to Gerrit)
2016/12/07 06:38:01
It must be possible. The program cache key just ne
qiankun
2016/12/10 00:25:30
I extended fragment id to support source format an
| |
| 746 // shader for ES3 and WEBGL2 context. | |
| 616 // Create program if necessary. | 747 // Create program if necessary. |
| 617 if (!info->program) { | 748 if (!info->program || |
| 749 decoder->GetFeatureInfo()->context_type() == CONTEXT_TYPE_OPENGLES3 || | |
| 750 decoder->GetFeatureInfo()->context_type() == CONTEXT_TYPE_WEBGL2) { | |
| 618 info->program = glCreateProgram(); | 751 info->program = glCreateProgram(); |
| 619 if (!vertex_shader_) { | 752 if (!vertex_shader_) { |
| 620 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER); | 753 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER); |
| 621 std::string source = GetVertexShaderSource(gl_version_info); | 754 std::string source = GetVertexShaderSource(gl_version_info); |
| 622 CompileShader(vertex_shader_, source.c_str()); | 755 CompileShader(vertex_shader_, source.c_str()); |
| 623 } | 756 } |
| 624 glAttachShader(info->program, vertex_shader_); | 757 glAttachShader(info->program, vertex_shader_); |
| 625 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id]; | 758 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id]; |
| 626 if (!*fragment_shader) { | 759 if (!*fragment_shader || |
| 760 decoder->GetFeatureInfo()->context_type() == CONTEXT_TYPE_OPENGLES3 || | |
| 761 decoder->GetFeatureInfo()->context_type() == CONTEXT_TYPE_WEBGL2) { | |
| 627 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); | 762 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); |
| 628 std::string source = GetFragmentShaderSource( | 763 std::string source = GetFragmentShaderSource( |
| 629 gl_version_info, premultiply_alpha, unpremultiply_alpha, | 764 gl_version_info, premultiply_alpha, unpremultiply_alpha, |
| 630 nv_egl_stream_consumer_external_, source_target); | 765 nv_egl_stream_consumer_external_, source_target, source_format, |
| 766 dest_format); | |
| 631 CompileShader(*fragment_shader, source.c_str()); | 767 CompileShader(*fragment_shader, source.c_str()); |
| 632 } | 768 } |
| 633 glAttachShader(info->program, *fragment_shader); | 769 glAttachShader(info->program, *fragment_shader); |
| 634 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); | 770 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); |
| 635 glLinkProgram(info->program); | 771 glLinkProgram(info->program); |
| 636 #ifndef NDEBUG | 772 #ifndef NDEBUG |
| 637 GLint linked; | 773 GLint linked; |
| 638 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); | 774 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); |
| 639 if (!linked) | 775 if (!linked) |
| 640 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | 776 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 771 decoder->RestoreTextureUnitBindings(0); | 907 decoder->RestoreTextureUnitBindings(0); |
| 772 decoder->RestoreActiveTexture(); | 908 decoder->RestoreActiveTexture(); |
| 773 decoder->RestoreProgramBindings(); | 909 decoder->RestoreProgramBindings(); |
| 774 decoder->RestoreBufferBindings(); | 910 decoder->RestoreBufferBindings(); |
| 775 decoder->RestoreFramebufferBindings(); | 911 decoder->RestoreFramebufferBindings(); |
| 776 decoder->RestoreGlobalState(); | 912 decoder->RestoreGlobalState(); |
| 777 } | 913 } |
| 778 | 914 |
| 779 } // namespace gles2 | 915 } // namespace gles2 |
| 780 } // namespace gpu | 916 } // namespace gpu |
| OLD | NEW |