Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc |
| index e6e3035c9e868ccbd11a5107ad5e919d9d4fca64..ce0f1070137a373b9a8fb670fbc25d8f00919d50 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc |
| @@ -10,6 +10,7 @@ |
| #include "gpu/command_buffer/service/gl_utils.h" |
| #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| +#include "gpu/command_buffer/service/texture_manager.h" |
| #include "ui/gl/gl_version_info.h" |
| namespace { |
| @@ -86,46 +87,44 @@ FragmentShaderId GetFragmentShaderId(bool premultiply_alpha, |
| return shader_ids[0][SAMPLER_2D]; |
| } |
| -const char* kShaderPrecisionPreamble = "\ |
| - #ifdef GL_ES\n\ |
| - precision mediump float;\n\ |
| - #define TexCoordPrecision mediump\n\ |
| - #else\n\ |
| - #define TexCoordPrecision\n\ |
| - #endif\n"; |
| +const char* kShaderPrecisionPreamble = |
| + "#ifdef GL_ES\n" |
| + "precision mediump float;\n" |
| + "#define TexCoordPrecision mediump\n" |
| + "#else\n" |
| + "#define TexCoordPrecision\n" |
| + "#endif\n"; |
| std::string GetVertexShaderSource(const gl::GLVersionInfo& gl_version_info) { |
| std::string source; |
| // Preamble for core and compatibility mode. |
| if (gl_version_info.is_desktop_core_profile) { |
| - source += std::string("\ |
| - #version 150\n\ |
| - #define ATTRIBUTE in\n\ |
| - #define VARYING out\n"); |
| + source += std::string("#version 150\n"); |
|
Zhenyao Mo
2016/11/14 20:04:50
This is incorrect. Now we have
1) desktop core pr
qiankun
2016/11/18 01:25:40
I updated the shaders per underlying context. I th
|
| } else { |
| - source += std::string("\ |
| - #define ATTRIBUTE attribute\n\ |
| - #define VARYING varying\n"); |
| + source += std::string("#version 300 es\n"); |
| } |
| + source += std::string( |
| + "#define ATTRIBUTE in\n" |
| + "#define VARYING out\n"); |
| // Preamble for texture precision. |
| source += std::string(kShaderPrecisionPreamble); |
| // Main shader source. |
| - source += std::string("\ |
| - uniform vec2 u_vertex_dest_mult;\n\ |
| - uniform vec2 u_vertex_dest_add;\n\ |
| - uniform vec2 u_vertex_source_mult;\n\ |
| - uniform vec2 u_vertex_source_add;\n\ |
| - ATTRIBUTE vec2 a_position;\n\ |
| - VARYING TexCoordPrecision vec2 v_uv;\n\ |
| - void main(void) {\n\ |
| - gl_Position = vec4(0, 0, 0, 1);\n\ |
| - gl_Position.xy = a_position.xy * u_vertex_dest_mult + \ |
| - u_vertex_dest_add;\n\ |
| - v_uv = a_position.xy * u_vertex_source_mult + u_vertex_source_add;\n\ |
| - }\n"); |
| + source += std::string( |
| + "uniform vec2 u_vertex_dest_mult;\n" |
| + "uniform vec2 u_vertex_dest_add;\n" |
| + "uniform vec2 u_vertex_source_mult;\n" |
| + "uniform vec2 u_vertex_source_add;\n" |
| + "ATTRIBUTE vec2 a_position;\n" |
| + "VARYING TexCoordPrecision vec2 v_uv;\n" |
| + "void main(void) {\n" |
| + " gl_Position = vec4(0, 0, 0, 1);\n" |
| + " gl_Position.xy = a_position.xy * u_vertex_dest_mult + " |
| + "u_vertex_dest_add;\n" |
| + " v_uv = a_position.xy * u_vertex_source_mult + u_vertex_source_add;\n" |
| + "}\n"); |
| return source; |
| } |
| @@ -134,45 +133,66 @@ std::string GetFragmentShaderSource(const gl::GLVersionInfo& gl_version_info, |
| bool premultiply_alpha, |
| bool unpremultiply_alpha, |
| bool nv_egl_stream_consumer_external, |
| - GLenum target) { |
| + GLenum target, |
| + GLenum source_format, |
| + GLenum format) { |
| std::string source; |
| // Preamble for core and compatibility mode. |
| if (gl_version_info.is_desktop_core_profile) { |
| - source += std::string("\ |
| - #version 150\n\ |
| - out vec4 frag_color;\n\ |
| - #define VARYING in\n\ |
| - #define FRAGCOLOR frag_color\n\ |
| - #define TextureLookup texture\n"); |
| + source += std::string("#version 150\n"); |
| } else { |
| - switch (target) { |
| - case GL_TEXTURE_2D: |
| - source += std::string("#define TextureLookup texture2D\n"); |
| - break; |
| - case GL_TEXTURE_RECTANGLE_ARB: |
| - source += std::string("#define TextureLookup texture2DRect\n"); |
| - break; |
| - case GL_TEXTURE_EXTERNAL_OES: |
| - source += |
| - std::string("#extension GL_OES_EGL_image_external : enable\n"); |
| - |
| - if (nv_egl_stream_consumer_external) { |
| - source += std::string( |
| - "#extension GL_NV_EGL_stream_consumer_external : enable\n"); |
| - } |
| - |
| - source += std::string("#define TextureLookup texture2D\n"); |
| - break; |
| - default: |
| - NOTREACHED(); |
| - break; |
| + source += std::string("#version 300 es\n"); |
| + if (target == GL_TEXTURE_EXTERNAL_OES) { |
| + source += std::string("#extension GL_OES_EGL_image_external : enable\n"); |
| + |
| + if (nv_egl_stream_consumer_external) { |
| + source += std::string( |
| + "#extension GL_NV_EGL_stream_consumer_external : enable\n"); |
| + } |
| } |
| - source += std::string("\ |
| - #define VARYING varying\n\ |
| - #define FRAGCOLOR gl_FragColor\n"); |
| } |
| + // Preamble for texture precision. |
| + source += std::string(kShaderPrecisionPreamble); |
| + |
| + if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(format)) { |
| + source += std::string("#define TextureType ivec4\n"); |
| + if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) |
| + source += std::string("#define InnerScaleValue 1\n"); |
| + else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) |
| + source += std::string("#define InnerScaleValue 1u\n"); |
| + else |
| + source += std::string("#define InnerScaleValue 255.0\n"); |
| + source += std::string("#define OuterScaleValue 1\n"); |
| + } else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(format)) { |
| + source += std::string("#define TextureType uvec4\n"); |
| + if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) |
| + source += std::string("#define InnerScaleValue 1\n"); |
| + else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) |
| + source += std::string("#define InnerScaleValue 1u\n"); |
| + else |
| + source += std::string("#define InnerScaleValue 255.0\n"); |
| + source += std::string("#define OuterScaleValue 1u\n"); |
| + } else { |
| + source += std::string("#define TextureType vec4\n"); |
| + if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) { |
| + source += std::string("#define InnerScaleValue 1\n"); |
| + source += std::string("#define OuterScaleValue (1.0 / 255.0)\n"); |
| + } else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) { |
| + source += std::string("#define InnerScaleValue 1u\n"); |
| + source += std::string("#define OuterScaleValue (1.0 / 255.0)\n"); |
| + } else { |
| + source += std::string("#define InnerScaleValue 1.0\n"); |
| + source += std::string("#define OuterScaleValue 1.0\n"); |
| + } |
| + } |
| + source += std::string( |
| + "out TextureType frag_color;\n" |
| + "#define VARYING in\n" |
| + "#define FRAGCOLOR frag_color\n" |
| + "#define TextureLookup texture\n"); |
| + |
| // Preamble for sampler type. |
| switch (target) { |
| case GL_TEXTURE_2D: |
| @@ -189,42 +209,72 @@ std::string GetFragmentShaderSource(const gl::GLVersionInfo& gl_version_info, |
| break; |
| } |
| - // Preamble for texture precision. |
| - source += std::string(kShaderPrecisionPreamble); |
| - |
| // Main shader source. |
| - source += std::string("\ |
| - uniform SamplerType u_sampler;\n\ |
| - uniform mat4 u_tex_coord_transform;\n\ |
| - VARYING TexCoordPrecision vec2 v_uv;\n\ |
| - void main(void) {\n\ |
| - TexCoordPrecision vec4 uv = u_tex_coord_transform * vec4(v_uv, 0, 1);\n\ |
| - FRAGCOLOR = TextureLookup(u_sampler, uv.st);\n"); |
| + source += std::string( |
| + "uniform mediump SamplerType u_sampler;\n" |
| + "uniform mat4 u_tex_coord_transform;\n" |
| + "VARYING TexCoordPrecision vec2 v_uv;\n" |
| + "void main(void) {\n" |
| + " TexCoordPrecision vec4 uv = u_tex_coord_transform * vec4(v_uv, 0, " |
| + "1);\n" |
| + " vec4 color = TextureLookup(u_sampler, uv.st);\n" |
| + " FRAGCOLOR = TextureType(color * InnerScaleValue) * " |
| + "OuterScaleValue;\n"); |
| // Post-processing to premultiply or un-premultiply alpha. |
| if (premultiply_alpha) { |
| - source += std::string(" FRAGCOLOR.rgb *= FRAGCOLOR.a;\n"); |
| + source += std::string("FRAGCOLOR.rgb *= FRAGCOLOR.a;\n"); |
| } |
| if (unpremultiply_alpha) { |
| - source += std::string("\ |
| - if (FRAGCOLOR.a > 0.0)\n\ |
| - FRAGCOLOR.rgb /= FRAGCOLOR.a;\n"); |
| + source += std::string( |
| + "if (FRAGCOLOR.a > 0.0)\n" |
| + " FRAGCOLOR.rgb /= FRAGCOLOR.a;\n"); |
| } |
| // Main function end. |
| - source += std::string(" }\n"); |
| + source += std::string("}\n"); |
| return source; |
| } |
| +GLenum getIntermediateFormat(GLenum format) { |
| + switch (format) { |
| + case GL_LUMINANCE_ALPHA: |
| + case GL_LUMINANCE: |
| + case GL_ALPHA: |
| + case GL_R16F: |
| + case GL_R32F: |
| + case GL_RG16F: |
| + case GL_RG32F: |
| + case GL_R11F_G11F_B10F: |
| + case GL_RGB9_E5: |
| + case GL_RGB16F: |
| + case GL_RGB32F: |
| + case GL_RGBA16F: |
| + case GL_RGBA32F: |
| + return GL_RGBA; |
| + case GL_SRGB8: |
| + return GL_SRGB8_ALPHA8; |
| + case GL_RGB8UI: |
| + return GL_RGBA8UI; |
| + default: |
| + return format; |
| + } |
| +} |
| + |
| void CompileShader(GLuint shader, const char* shader_source) { |
| glShaderSource(shader, 1, &shader_source, 0); |
| glCompileShader(shader); |
| #ifndef NDEBUG |
| GLint compile_status; |
| glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); |
| - if (GL_TRUE != compile_status) |
| + if (GL_TRUE != compile_status) { |
| DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; |
| + char buffer[1024]; |
| + GLsizei length = 0; |
| + glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); |
| + std::string log(buffer, length); |
| + } |
| #endif |
| } |
| @@ -419,21 +469,14 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
| GLsizei height, |
| bool flip_y, |
| bool premultiply_alpha, |
| - bool unpremultiply_alpha) { |
| + bool unpremultiply_alpha, |
| + SupportedCopyMethodByFormat method) { |
| bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
| - // GL_INVALID_OPERATION is generated if the currently bound framebuffer's |
| - // format does not contain a superset of the components required by the base |
| - // format of internalformat. |
| - // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml |
| - bool source_format_contain_superset_of_dest_format = |
| - (source_internal_format == dest_internal_format && |
| - source_internal_format != GL_BGRA_EXT) || |
| - (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); |
| + |
| // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
| // so restrict this to GL_TEXTURE_2D. |
| if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D && |
| - !flip_y && !premultiply_alpha_change && |
| - source_format_contain_superset_of_dest_format) { |
| + !flip_y && !premultiply_alpha_change && method == DIRECT_COPY) { |
| DoCopyTexImage2D(decoder, |
| source_target, |
| source_id, |
| @@ -446,10 +489,30 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
| return; |
| } |
| + GLenum adjusted_internal_format = getIntermediateFormat(dest_internal_format); |
| + GLuint adjusted_texture = dest_id; |
| + if (method == DRAW_AND_COPY) { |
| + glGenTextures(1, &adjusted_texture); |
| + glBindTexture(dest_target, adjusted_texture); |
| + GLenum format = TextureManager::ExtractFormatFromStorageFormat( |
| + adjusted_internal_format); |
| + GLenum type = |
| + TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); |
| + |
| + glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, |
| + format, type, nullptr); |
| + } |
| // Use kIdentityMatrix if no transform passed in. |
| - DoCopyTextureWithTransform(decoder, source_target, source_id, dest_target, |
| - dest_id, width, height, flip_y, premultiply_alpha, |
| - unpremultiply_alpha, kIdentityMatrix); |
| + DoCopyTextureWithTransform( |
| + decoder, source_target, source_id, source_internal_format, dest_target, |
| + adjusted_texture, adjusted_internal_format, width, height, flip_y, |
| + premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); |
| + |
| + if (method == DRAW_AND_COPY) { |
| + DoCopyTexImage2D(decoder, dest_target, adjusted_texture, dest_target, |
| + dest_id, dest_internal_format, width, height, |
| + framebuffer_); |
| + } |
| } |
| void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
| @@ -472,7 +535,8 @@ void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
| GLsizei source_height, |
| bool flip_y, |
| bool premultiply_alpha, |
| - bool unpremultiply_alpha) { |
| + bool unpremultiply_alpha, |
| + SupportedCopyMethodByFormat method) { |
| bool use_gl_copy_tex_sub_image_2d = true; |
| #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
| // glDrawArrays is faster than glCopyTexSubImage2D on IA Mesa driver, |
| @@ -482,19 +546,12 @@ void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
| use_gl_copy_tex_sub_image_2d = false; |
| #endif |
| bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
| - // GL_INVALID_OPERATION is generated if the currently bound framebuffer's |
| - // format does not contain a superset of the components required by the base |
| - // format of internalformat. |
| - // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml |
| - bool source_format_contain_superset_of_dest_format = |
| - (source_internal_format == dest_internal_format && |
| - source_internal_format != GL_BGRA_EXT) || |
| - (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); |
| + |
| // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
| // so restrict this to GL_TEXTURE_2D. |
| if (use_gl_copy_tex_sub_image_2d && source_target == GL_TEXTURE_2D && |
| dest_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && |
| - source_format_contain_superset_of_dest_format) { |
| + method == DIRECT_COPY) { |
| DoCopyTexSubImage2D(decoder, source_target, source_id, dest_target, dest_id, |
| xoffset, yoffset, x, y, width, height, framebuffer_); |
| return; |
| @@ -529,18 +586,21 @@ void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( |
| bool premultiply_alpha, |
| bool unpremultiply_alpha, |
| const GLfloat transform_matrix[16]) { |
| - DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id, |
| - xoffset, yoffset, x, y, width, height, dest_width, dest_height, |
| - source_width, source_height, flip_y, premultiply_alpha, |
| - unpremultiply_alpha, transform_matrix); |
| + DoCopyTextureInternal( |
| + decoder, source_target, source_id, source_internal_format, dest_target, |
| + dest_id, dest_internal_format, xoffset, yoffset, x, y, width, height, |
| + dest_width, dest_height, source_width, source_height, flip_y, |
| + premultiply_alpha, unpremultiply_alpha, transform_matrix); |
| } |
| void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( |
| const gles2::GLES2Decoder* decoder, |
| GLenum source_target, |
| GLuint source_id, |
| + GLenum source_format, |
| GLenum dest_target, |
| GLuint dest_id, |
| + GLenum dest_format, |
| GLsizei width, |
| GLsizei height, |
| bool flip_y, |
| @@ -549,18 +609,20 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( |
| const GLfloat transform_matrix[16]) { |
| GLsizei dest_width = width; |
| GLsizei dest_height = height; |
| - DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id, |
| - 0, 0, 0, 0, width, height, dest_width, dest_height, |
| - width, height, flip_y, premultiply_alpha, |
| - unpremultiply_alpha, transform_matrix); |
| + DoCopyTextureInternal( |
| + decoder, source_target, source_id, source_format, dest_target, dest_id, |
| + dest_format, 0, 0, 0, 0, width, height, dest_width, dest_height, width, |
| + height, flip_y, premultiply_alpha, unpremultiply_alpha, transform_matrix); |
| } |
| void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( |
| const gles2::GLES2Decoder* decoder, |
| GLenum source_target, |
| GLuint source_id, |
| + GLenum source_format, |
| GLenum dest_target, |
| GLuint dest_id, |
| + GLenum dest_format, |
| GLint xoffset, |
| GLint yoffset, |
| GLint x, |
| @@ -627,7 +689,8 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( |
| *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); |
| std::string source = GetFragmentShaderSource( |
| gl_version_info, premultiply_alpha, unpremultiply_alpha, |
| - nv_egl_stream_consumer_external_, source_target); |
| + nv_egl_stream_consumer_external_, source_target, source_format, |
| + dest_format); |
| CompileShader(*fragment_shader, source.c_str()); |
| } |
| glAttachShader(info->program, *fragment_shader); |