| 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 ce8b68101e76202ee3df8a06eb5a3dd0d6387687..af564389ea5c63d1579e2c685b7f14926dd8d498 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
|
| @@ -4,15 +4,19 @@
|
|
|
| #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
|
|
|
| -#include <string.h>
|
| +#include <algorithm>
|
| +
|
| #include "base/basictypes.h"
|
| #include "gpu/command_buffer/common/types.h"
|
| #include "gpu/command_buffer/service/gl_utils.h"
|
| #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
|
|
|
| -#define SHADER(src) \
|
| - "#ifdef GL_ES\n" \
|
| - "precision mediump float;\n" \
|
| +#define SHADER(src) \
|
| + "#ifdef GL_ES\n" \
|
| + "precision mediump float;\n" \
|
| + "#define TexCoordPrecision mediump\n" \
|
| + "#else\n" \
|
| + "#define TexCoordPrecision\n" \
|
| "#endif\n" #src
|
| #define SHADER_2D(src) \
|
| "#define SamplerType sampler2D\n" \
|
| @@ -21,135 +25,133 @@
|
| "#extension GL_OES_EGL_image_external : require\n" \
|
| "#define SamplerType samplerExternalOES\n" \
|
| "#define TextureLookup texture2D\n" SHADER(src)
|
| -#define SHADERS(src) \
|
| - { SHADER_2D(src), SHADER_EXTERNAL_OES(src) }
|
| +#define FRAGMENT_SHADERS(src) \
|
| + SHADER_2D(src), SHADER_EXTERNAL_OES(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 };
|
| -
|
| -enum ShaderId {
|
| - SHADER_COPY_TEXTURE,
|
| - SHADER_COPY_TEXTURE_FLIP_Y,
|
| - SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA,
|
| - SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA,
|
| - SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y,
|
| - SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y,
|
| - NUM_SHADERS,
|
| +enum VertexShaderId {
|
| + VERTEX_SHADER_COPY_TEXTURE,
|
| + VERTEX_SHADER_COPY_TEXTURE_FLIP_Y,
|
| + NUM_VERTEX_SHADERS,
|
| };
|
|
|
| -enum SamplerId {
|
| - SAMPLER_TEXTURE_2D,
|
| - SAMPLER_TEXTURE_EXTERNAL_OES,
|
| - NUM_SAMPLERS,
|
| +enum FragmentShaderId {
|
| + FRAGMENT_SHADER_COPY_TEXTURE_2D,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_2D,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_EXTERNAL_OES,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_2D,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_EXTERNAL_OES,
|
| + NUM_FRAGMENT_SHADERS,
|
| };
|
|
|
| -const char* vertex_shader_source =
|
| +const char* vertex_shader_source[NUM_VERTEX_SHADERS] = {
|
| + // VERTEX_SHADER_COPY_TEXTURE
|
| SHADER(
|
| uniform mat4 u_matrix;
|
| attribute vec4 a_position;
|
| - varying vec2 v_uv;
|
| + varying TexCoordPrecision vec2 v_uv;
|
| void main(void) {
|
| gl_Position = u_matrix * a_position;
|
| - v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5);
|
| - });
|
| -
|
| -const char* fragment_shader_source[NUM_SHADERS][NUM_SAMPLERS] = {
|
| - // SHADER_COPY_TEXTURE
|
| - SHADERS(
|
| - uniform SamplerType u_texSampler;
|
| - varying vec2 v_uv;
|
| - void main(void) {
|
| - gl_FragColor = TextureLookup(u_texSampler, v_uv.st);
|
| - }),
|
| - // SHADER_COPY_TEXTURE_FLIP_Y
|
| - SHADERS(
|
| - uniform SamplerType u_texSampler;
|
| - varying vec2 v_uv;
|
| - void main(void) {
|
| - gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
|
| + v_uv = a_position.xy * vec2(0.5, 0.5) + vec2(0.5, 0.5);
|
| }),
|
| - // SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA
|
| - SHADERS(
|
| - uniform SamplerType u_texSampler;
|
| - varying vec2 v_uv;
|
| + // VERTEX_SHADER_COPY_TEXTURE_FLIP_Y
|
| + SHADER(
|
| + uniform mat4 u_matrix;
|
| + attribute vec4 a_position;
|
| + varying TexCoordPrecision vec2 v_uv;
|
| void main(void) {
|
| - gl_FragColor = TextureLookup(u_texSampler, v_uv.st);
|
| - gl_FragColor.rgb *= gl_FragColor.a;
|
| + gl_Position = u_matrix * a_position;
|
| + v_uv = a_position.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5);
|
| }),
|
| - // SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA
|
| - SHADERS(
|
| - uniform SamplerType u_texSampler;
|
| - varying vec2 v_uv;
|
| +};
|
| +
|
| +const char* fragment_shader_source[NUM_FRAGMENT_SHADERS] = {
|
| + // FRAGMENT_SHADER_COPY_TEXTURE_*
|
| + FRAGMENT_SHADERS(
|
| + uniform SamplerType u_sampler;
|
| + varying TexCoordPrecision vec2 v_uv;
|
| void main(void) {
|
| - gl_FragColor = TextureLookup(u_texSampler, v_uv.st);
|
| - if (gl_FragColor.a > 0.0)
|
| - gl_FragColor.rgb /= gl_FragColor.a;
|
| + gl_FragColor = TextureLookup(u_sampler, v_uv.st);
|
| }),
|
| - // SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y
|
| - SHADERS(
|
| - uniform SamplerType u_texSampler;
|
| - varying vec2 v_uv;
|
| + // FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_*
|
| + FRAGMENT_SHADERS(
|
| + uniform SamplerType u_sampler;
|
| + varying TexCoordPrecision vec2 v_uv;
|
| void main(void) {
|
| - gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
|
| + gl_FragColor = TextureLookup(u_sampler, v_uv.st);
|
| gl_FragColor.rgb *= gl_FragColor.a;
|
| }),
|
| - // SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y
|
| - SHADERS(
|
| - uniform SamplerType u_texSampler;
|
| - varying vec2 v_uv;
|
| + // FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_*
|
| + FRAGMENT_SHADERS(
|
| + uniform SamplerType u_sampler;
|
| + varying TexCoordPrecision vec2 v_uv;
|
| void main(void) {
|
| - gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
|
| + gl_FragColor = TextureLookup(u_sampler, v_uv.st);
|
| if (gl_FragColor.a > 0.0)
|
| gl_FragColor.rgb /= gl_FragColor.a;
|
| }),
|
| };
|
|
|
| -// Returns the correct shader id to evaluate the copy operation for
|
| -// the CHROMIUM_flipy and premultiply alpha pixel store settings.
|
| -ShaderId GetShaderId(bool flip_y,
|
| - bool premultiply_alpha,
|
| - bool unpremultiply_alpha) {
|
| - // If both pre-multiply and unpremultiply are requested, then perform no
|
| - // alpha manipulation.
|
| - if (premultiply_alpha && unpremultiply_alpha) {
|
| - premultiply_alpha = false;
|
| - unpremultiply_alpha = false;
|
| - }
|
| -
|
| - // bit 0: Flip_y
|
| - // bit 1: Premult
|
| - // bit 2: Unpremult
|
| - static ShaderId shader_ids[] = {
|
| - SHADER_COPY_TEXTURE,
|
| - SHADER_COPY_TEXTURE_FLIP_Y, // F
|
| - SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P
|
| - SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y, // F P
|
| - SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U
|
| - SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y, // F U
|
| - SHADER_COPY_TEXTURE, // P U
|
| - SHADER_COPY_TEXTURE_FLIP_Y, // F P U
|
| +// Returns the correct vertex shader id to evaluate the copy operation for
|
| +// the CHROMIUM_flipy setting.
|
| +VertexShaderId GetVertexShaderId(bool flip_y) {
|
| + // bit 0: flip y
|
| + static VertexShaderId shader_ids[] = {
|
| + VERTEX_SHADER_COPY_TEXTURE,
|
| + VERTEX_SHADER_COPY_TEXTURE_FLIP_Y,
|
| };
|
|
|
| - unsigned index = (flip_y ? (1 << 0) : 0) |
|
| - (premultiply_alpha ? (1 << 1) : 0) |
|
| - (unpremultiply_alpha ? (1 << 2) : 0);
|
| + unsigned index = flip_y ? 1 : 0;
|
| return shader_ids[index];
|
| }
|
|
|
| -SamplerId GetSamplerId(GLenum source_target) {
|
| - switch (source_target) {
|
| +// Returns the correct fragment shader id to evaluate the copy operation for
|
| +// the premultiply alpha pixel store settings and target.
|
| +FragmentShaderId GetFragmentShaderId(bool premultiply_alpha,
|
| + bool unpremultiply_alpha,
|
| + GLenum target) {
|
| + enum {
|
| + SAMPLER_2D,
|
| + SAMPLER_EXTERNAL_OES,
|
| + NUM_SAMPLERS
|
| + };
|
| +
|
| + // bit 0: premultiply alpha
|
| + // bit 1: unpremultiply alpha
|
| + static FragmentShaderId shader_ids[][NUM_SAMPLERS] = {
|
| + {
|
| + FRAGMENT_SHADER_COPY_TEXTURE_2D,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES,
|
| + },
|
| + {
|
| + FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_2D,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_EXTERNAL_OES,
|
| + },
|
| + {
|
| + FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_2D,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_EXTERNAL_OES,
|
| + },
|
| + {
|
| + FRAGMENT_SHADER_COPY_TEXTURE_2D,
|
| + FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES,
|
| + }};
|
| +
|
| + unsigned index = (premultiply_alpha ? (1 << 0) : 0) |
|
| + (unpremultiply_alpha ? (1 << 1) : 0);
|
| +
|
| + switch (target) {
|
| case GL_TEXTURE_2D:
|
| - return SAMPLER_TEXTURE_2D;
|
| + return shader_ids[index][SAMPLER_2D];
|
| case GL_TEXTURE_EXTERNAL_OES:
|
| - return SAMPLER_TEXTURE_EXTERNAL_OES;
|
| + return shader_ids[index][SAMPLER_EXTERNAL_OES];
|
| + default:
|
| + break;
|
| }
|
|
|
| NOTREACHED();
|
| - return SAMPLER_TEXTURE_2D;
|
| + return shader_ids[index][SAMPLER_2D];
|
| }
|
|
|
| void CompileShader(GLuint shader, const char* shader_source) {
|
| @@ -163,13 +165,21 @@ void CompileShader(GLuint shader, const char* shader_source) {
|
| #endif
|
| }
|
|
|
| +void DeleteShader(GLuint shader) {
|
| + if (shader)
|
| + glDeleteShader(shader);
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace gpu {
|
|
|
| CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager()
|
| - : initialized_(false), buffer_id_(0), framebuffer_(0), vertex_shader_(0) {
|
| -}
|
| + : initialized_(false),
|
| + vertex_shaders_(NUM_VERTEX_SHADERS, 0u),
|
| + fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u),
|
| + buffer_id_(0u),
|
| + framebuffer_(0u) {}
|
|
|
| CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {}
|
|
|
| @@ -182,14 +192,15 @@ void CopyTextureCHROMIUMResourceManager::Initialize(
|
| // Initialize all of the GPU resources required to perform the copy.
|
| glGenBuffersARB(1, &buffer_id_);
|
| glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
|
| - glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices,
|
| - GL_STATIC_DRAW);
|
| + const GLfloat kQuadVertices[] = {-1.0f, -1.0f,
|
| + 1.0f, -1.0f,
|
| + 1.0f, 1.0f,
|
| + -1.0f, 1.0f};
|
| + glBufferData(
|
| + GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, GL_STATIC_DRAW);
|
|
|
| glGenFramebuffersEXT(1, &framebuffer_);
|
|
|
| - vertex_shader_ = glCreateShader(GL_VERTEX_SHADER);
|
| - CompileShader(vertex_shader_, vertex_shader_source);
|
| -
|
| decoder->RestoreBufferBindings();
|
|
|
| initialized_ = true;
|
| @@ -201,7 +212,10 @@ void CopyTextureCHROMIUMResourceManager::Destroy() {
|
|
|
| glDeleteFramebuffersEXT(1, &framebuffer_);
|
|
|
| - glDeleteShader(vertex_shader_);
|
| + std::for_each(vertex_shaders_.begin(), vertex_shaders_.end(), DeleteShader);
|
| + std::for_each(
|
| + fragment_shaders_.begin(), fragment_shaders_.end(), DeleteShader);
|
| +
|
| for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end();
|
| ++it) {
|
| const ProgramInfo& info = it->second;
|
| @@ -253,19 +267,30 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
|
| return;
|
| }
|
|
|
| - ShaderId shader_id =
|
| - GetShaderId(flip_y, premultiply_alpha, unpremultiply_alpha);
|
| - SamplerId sampler_id = GetSamplerId(source_target);
|
| + VertexShaderId vertex_shader_id = GetVertexShaderId(flip_y);
|
| + DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size());
|
| + GLuint* vertex_shader = &vertex_shaders_[vertex_shader_id];
|
| + if (!*vertex_shader) {
|
| + *vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
| + CompileShader(*vertex_shader, vertex_shader_source[vertex_shader_id]);
|
| + }
|
| +
|
| + FragmentShaderId fragment_shader_id = GetFragmentShaderId(
|
| + premultiply_alpha, unpremultiply_alpha, source_target);
|
| + DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size());
|
| + GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id];
|
| + if (!*fragment_shader) {
|
| + *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
| + CompileShader(*fragment_shader, fragment_shader_source[fragment_shader_id]);
|
| + }
|
|
|
| - ProgramMapKey key(shader_id, sampler_id);
|
| + ProgramMapKey key(vertex_shader_id, fragment_shader_id);
|
| ProgramInfo* info = &programs_[key];
|
| // Create program if necessary.
|
| if (!info->program) {
|
| - GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
|
| - CompileShader(shader, fragment_shader_source[shader_id][sampler_id]);
|
| info->program = glCreateProgram();
|
| - glAttachShader(info->program, vertex_shader_);
|
| - glAttachShader(info->program, shader);
|
| + glAttachShader(info->program, *vertex_shader);
|
| + glAttachShader(info->program, *fragment_shader);
|
| glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position");
|
| glLinkProgram(info->program);
|
| #ifndef NDEBUG
|
| @@ -274,10 +299,8 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
|
| if (!linked)
|
| DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure.";
|
| #endif
|
| - info->sampler_locations =
|
| - glGetUniformLocation(info->program, "u_texSampler");
|
| info->matrix_handle = glGetUniformLocation(info->program, "u_matrix");
|
| - glDeleteShader(shader);
|
| + info->sampler_handle = glGetUniformLocation(info->program, "u_sampler");
|
| }
|
| glUseProgram(info->program);
|
|
|
| @@ -315,10 +338,9 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
|
| glEnableVertexAttribArray(kVertexPositionAttrib);
|
|
|
| glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
|
| - glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE,
|
| - 4 * sizeof(GLfloat), 0);
|
| + glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
|
|
| - glUniform1i(info->sampler_locations, 0);
|
| + glUniform1i(info->sampler_handle, 0);
|
|
|
| glBindTexture(source_target, source_id);
|
| glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| @@ -349,5 +371,4 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
|
| decoder->RestoreGlobalState();
|
| }
|
|
|
| -} // namespace
|
| -
|
| +} // namespace gpu
|
|
|