Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(344)

Unified Diff: gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc

Issue 255763002: gpu: Refactor and cleanup CHROMIUM_copy_texture implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: format Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 5ce4a223fb3d185563e6d8e1948f5b7b4916713b..258f63ef82da36b71abca2f06314ca849807a1a6 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -10,19 +10,19 @@
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
-#define SHADER0(src) \
- "#ifdef GL_ES\n"\
- "precision mediump float;\n"\
- "#endif\n"\
- #src
-#define SHADER(src) { false, SHADER0(src), }
-#define SHADER_EXTERNAL_OES0(src) \
- "#extension GL_OES_EGL_image_external : require\n"\
- "#ifdef GL_ES\n"\
- "precision mediump float;\n"\
- "#endif\n"\
- #src
-#define SHADER_EXTERNAL_OES(src) { true, SHADER_EXTERNAL_OES0(src), }
+#define SHADER(src) \
+ "#ifdef GL_ES\n" \
+ "precision mediump float;\n" \
+ "#endif\n" #src
+#define SHADER_2D(src) \
+ "#define SamplerType sampler2D\n" \
+ "#define TextureLookup texture2D\n" SHADER(src)
+#define SHADER_EXTERNAL_OES(src) \
+ "#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) }
namespace {
@@ -31,27 +31,23 @@ 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 };
piman 2014/04/25 03:30:40 This should be 2 components per vertex instead of
reveman 2014/04/25 20:27:10 I'll fix this in a follow up.
-enum ProgramId {
- PROGRAM_COPY_TEXTURE,
- PROGRAM_COPY_TEXTURE_FLIP_Y,
- PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA,
- PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA,
- PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY,
- PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY,
- PROGRAM_COPY_TEXTURE_OES,
- PROGRAM_COPY_TEXTURE_OES_FLIP_Y,
- PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA,
- PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA,
- PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY,
- PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY,
+enum ShaderId {
+ SHADER_COPY_TEXTURE,
+ SHADER_COPY_TEXTURE_FLIP_Y,
piman 2014/04/25 03:30:40 nit: it'd be nice to be consistent between FLIP_Y
reveman 2014/04/25 20:27:10 Done.
+ SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA,
+ SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA,
+ SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY,
+ SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY,
+ NUM_SHADERS,
};
-struct ShaderInfo {
- bool needs_egl_image_external;
- const char* source;
+enum SamplerId {
+ SAMPLER_TEXTURE_2D,
+ SAMPLER_TEXTURE_EXTERNAL_OES,
+ NUM_SAMPLERS,
};
-const ShaderInfo shader_infos[] = {
+const char* vertex_shader_source =
// VERTEX_SHADER_POS_TEX
SHADER(
uniform mat4 u_matrix;
@@ -60,123 +56,64 @@ const ShaderInfo shader_infos[] = {
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] = {
// FRAGMENT_SHADER_TEX
- SHADER(
- uniform sampler2D u_texSampler;
+ SHADERS(
+ uniform SamplerType u_texSampler;
varying vec2 v_uv;
void main(void) {
- gl_FragColor = texture2D(u_texSampler, v_uv.st);
+ gl_FragColor = TextureLookup(u_texSampler, v_uv.st);
}),
// FRAGMENT_SHADER_TEX_FLIP_Y
- SHADER(
- uniform sampler2D u_texSampler;
+ SHADERS(
+ uniform SamplerType u_texSampler;
varying vec2 v_uv;
void main(void) {
- gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
+ gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
piman 2014/04/25 03:30:40 Maybe for later... those shaders would be more eff
reveman 2014/04/25 20:27:10 I'll do this in a follow up. I need to change this
}),
// FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA
- SHADER(
- uniform sampler2D u_texSampler;
+ SHADERS(
+ uniform SamplerType u_texSampler;
varying vec2 v_uv;
void main(void) {
- gl_FragColor = texture2D(u_texSampler, v_uv.st);
+ gl_FragColor = TextureLookup(u_texSampler, v_uv.st);
gl_FragColor.rgb *= gl_FragColor.a;
}),
// FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA
- SHADER(
- uniform sampler2D u_texSampler;
+ SHADERS(
+ uniform SamplerType u_texSampler;
varying vec2 v_uv;
void main(void) {
- gl_FragColor = texture2D(u_texSampler, v_uv.st);
+ gl_FragColor = TextureLookup(u_texSampler, v_uv.st);
if (gl_FragColor.a > 0.0)
gl_FragColor.rgb /= gl_FragColor.a;
}),
// FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y
- SHADER(
- uniform sampler2D u_texSampler;
+ SHADERS(
+ uniform SamplerType u_texSampler;
varying vec2 v_uv;
void main(void) {
- gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
+ gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
gl_FragColor.rgb *= gl_FragColor.a;
}),
// FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y
- SHADER(
- uniform sampler2D u_texSampler;
- varying vec2 v_uv;
- void main(void) {
- gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
- if (gl_FragColor.a > 0.0)
- gl_FragColor.rgb /= gl_FragColor.a;
- }),
- // FRAGMENT_SHADER_TEX_OES
- SHADER_EXTERNAL_OES(
- precision mediump float;
- uniform samplerExternalOES u_texSampler;
+ SHADERS(
+ uniform SamplerType u_texSampler;
varying vec2 v_uv;
void main(void) {
- gl_FragColor = texture2D(u_texSampler, v_uv.st);
- }),
- // FRAGMENT_SHADER_TEX_OES_FLIP_Y
- SHADER_EXTERNAL_OES(
- precision mediump float;
- uniform samplerExternalOES u_texSampler;
- varying vec2 v_uv;
- void main(void) {
- gl_FragColor =
- texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
- }),
- // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA
- SHADER_EXTERNAL_OES(
- precision mediump float;
- uniform samplerExternalOES u_texSampler;
- varying vec2 v_uv;
- void main(void) {
- gl_FragColor = texture2D(u_texSampler, v_uv.st);
- gl_FragColor.rgb *= gl_FragColor.a;
- }),
- // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA
- SHADER_EXTERNAL_OES(
- precision mediump float;
- uniform samplerExternalOES u_texSampler;
- varying vec2 v_uv;
- void main(void) {
- gl_FragColor = texture2D(u_texSampler, v_uv.st);
+ gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
if (gl_FragColor.a > 0.0)
gl_FragColor.rgb /= gl_FragColor.a;
}),
- // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA_FLIP_Y
- SHADER_EXTERNAL_OES(
- precision mediump float;
- uniform samplerExternalOES u_texSampler;
- varying vec2 v_uv;
- void main(void) {
- gl_FragColor =
- texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
- gl_FragColor.rgb *= gl_FragColor.a;
- }),
- // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA_FLIP_Y
- SHADER_EXTERNAL_OES(
- precision mediump float;
- uniform samplerExternalOES u_texSampler;
- varying vec2 v_uv;
- void main(void) {
- gl_FragColor =
- texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
- if (gl_FragColor.a > 0.0)
- gl_FragColor.rgb /= gl_FragColor.a;
- }),
};
-const int kNumShaders = arraysize(shader_infos);
-
-// Returns the correct program to evaluate the copy operation for
+// Returns the correct shader id to evaluate the copy operation for
// the CHROMIUM_flipy and premultiply alpha pixel store settings.
-ProgramId GetProgram(
- bool flip_y,
- bool premultiply_alpha,
- bool unpremultiply_alpha,
- bool is_source_external_oes) {
+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) {
@@ -187,31 +124,44 @@ ProgramId GetProgram(
// bit 0: Flip_y
// bit 1: Premult
// bit 2: Unpremult
- // bit 3: External_oes
- static ProgramId program_ids[] = {
- PROGRAM_COPY_TEXTURE,
- PROGRAM_COPY_TEXTURE_FLIP_Y, // F
- PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P
- PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY, // F P
- PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U
- PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, // F U
- PROGRAM_COPY_TEXTURE, // P U
- PROGRAM_COPY_TEXTURE, // F P U
- PROGRAM_COPY_TEXTURE_OES, // E
- PROGRAM_COPY_TEXTURE_OES_FLIP_Y, // F E
- PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA, // P E
- PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY, // F P E
- PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA, // U E
- PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY, // F U E
- PROGRAM_COPY_TEXTURE_OES, // P U E
- PROGRAM_COPY_TEXTURE_OES, // F P U E
+ static ShaderId shader_ids[] = {
+ SHADER_COPY_TEXTURE,
+ SHADER_COPY_TEXTURE_FLIP_Y, // F
+ SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P
+ SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY, // F P
+ SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U
+ SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, // F U
+ SHADER_COPY_TEXTURE, // P U
+ SHADER_COPY_TEXTURE, // F P U
piman 2014/04/25 03:30:40 Shouldn't this last one be SHADER_COPY_TEXTURE_FLI
reveman 2014/04/25 20:27:10 Sure, I assume these last two are invalid configur
};
- unsigned index = (flip_y ? (1 << 0) : 0) |
- (premultiply_alpha ? (1 << 1) : 0) |
- (unpremultiply_alpha ? (1 << 2) : 0) |
- (is_source_external_oes ? (1 << 3) : 0);
- return program_ids[index];
+ unsigned index = (flip_y ? (1 << 0) : 0) |
+ (premultiply_alpha ? (1 << 1) : 0) |
+ (unpremultiply_alpha ? (1 << 2) : 0);
+ return shader_ids[index];
+}
+
+SamplerId GetSamplerId(GLenum source_target) {
+ switch (source_target) {
+ case GL_TEXTURE_2D:
+ return SAMPLER_TEXTURE_2D;
+ case GL_TEXTURE_EXTERNAL_OES:
+ return SAMPLER_TEXTURE_EXTERNAL_OES;
+ }
+
+ NOTREACHED();
+ return SAMPLER_TEXTURE_2D;
+}
+
+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)
+ DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure.";
+#endif
}
} // namespace
@@ -219,27 +169,17 @@ ProgramId GetProgram(
namespace gpu {
CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager()
- : initialized_(false),
- buffer_id_(0),
- framebuffer_(0) {
- for (int i = 0; i < kNumPrograms; ++i) {
- programs_[i] = 0;
- matrix_handle_[i] = 0;
- sampler_locations_[i] = 0;
- }
+ : initialized_(false), buffer_id_(0), framebuffer_(0), vertex_shader_(0) {
}
+CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {}
+
void CopyTextureCHROMIUMResourceManager::Initialize(
const gles2::GLES2Decoder* decoder) {
COMPILE_ASSERT(
kVertexPositionAttrib == 0u,
Position_attribs_must_be_0);
- const char* extensions =
- reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
- bool have_egl_image_external = extensions &&
- strstr(extensions, "GL_OES_EGL_image_external");
-
// Initialize all of the GPU resources required to perform the copy.
glGenBuffersARB(1, &buffer_id_);
glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
@@ -248,56 +188,8 @@ void CopyTextureCHROMIUMResourceManager::Initialize(
glGenFramebuffersEXT(1, &framebuffer_);
- // TODO(gman): Init these on demand.
- GLuint shaders[kNumShaders];
- for (int shader = 0; shader < kNumShaders; ++shader) {
- shaders[shader] = glCreateShader(
- shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
- const ShaderInfo& info = shader_infos[shader];
- if (info.needs_egl_image_external && !have_egl_image_external) {
- continue;
- }
- const char* shader_source = shader_infos[shader].source;
- glShaderSource(shaders[shader], 1, &shader_source, 0);
- glCompileShader(shaders[shader]);
-#ifndef NDEBUG
- GLint compile_status;
- glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status);
- if (GL_TRUE != compile_status)
- DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure.";
-#endif
- }
-
- // TODO(gman): Init these on demand.
- for (int program = 0; program < kNumPrograms; ++program) {
- const ShaderInfo& info = shader_infos[program + 1];
- if (info.needs_egl_image_external && !have_egl_image_external) {
- continue;
- }
- programs_[program] = glCreateProgram();
- glAttachShader(programs_[program], shaders[0]);
- glAttachShader(programs_[program], shaders[program + 1]);
-
- glBindAttribLocation(programs_[program], kVertexPositionAttrib,
- "a_position");
-
- glLinkProgram(programs_[program]);
-#ifndef NDEBUG
- GLint linked;
- glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked);
- if (!linked)
- DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure.";
-#endif
-
- sampler_locations_[program] = glGetUniformLocation(programs_[program],
- "u_texSampler");
-
- matrix_handle_[program] = glGetUniformLocation(programs_[program],
- "u_matrix");
- }
-
- for (int shader = 0; shader < kNumShaders; ++shader)
- glDeleteShader(shaders[shader]);
+ vertex_shader_ = glCreateShader(GL_VERTEX_SHADER);
+ CompileShader(vertex_shader_, vertex_shader_source);
decoder->RestoreBufferBindings();
@@ -310,9 +202,11 @@ void CopyTextureCHROMIUMResourceManager::Destroy() {
glDeleteFramebuffersEXT(1, &framebuffer_);
- for (int program = 0; program < kNumPrograms; ++program) {
- if (programs_[program])
- glDeleteProgram(programs_[program]);
+ glDeleteShader(vertex_shader_);
+ for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end();
+ ++it) {
+ const ProgramInfo& info = it->second;
+ glDeleteProgram(info.program);
}
glDeleteBuffersARB(1, &buffer_id_);
@@ -360,22 +254,45 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
return;
}
- GLuint program = GetProgram(
- flip_y, premultiply_alpha, unpremultiply_alpha,
- source_target == GL_TEXTURE_EXTERNAL_OES);
- glUseProgram(programs_[program]);
+ ShaderId shader_id =
+ GetShaderId(flip_y, premultiply_alpha, unpremultiply_alpha);
+ SamplerId sampler_id = GetSamplerId(source_target);
+
+ ProgramMapKey key(shader_id, sampler_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);
+ glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position");
+ glLinkProgram(info->program);
+#ifndef NDEBUG
+ GLint linked;
+ glGetProgramiv(info->program, GL_LINK_STATUS, &linked);
+ 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);
+ }
+ glUseProgram(info->program);
#ifndef NDEBUG
- glValidateProgram(programs_[program]);
+ glValidateProgram(info->program);
GLint validation_status;
- glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status);
+ glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status);
if (GL_TRUE != validation_status) {
DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader.";
return;
}
#endif
- glUniformMatrix4fv(matrix_handle_[program], 1, GL_FALSE, transform_matrix);
+ glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, dest_id);
// NVidia drivers require texture settings to be a certain way
@@ -402,7 +319,7 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE,
4 * sizeof(GLfloat), 0);
- glUniform1i(sampler_locations_[program], 0);
+ glUniform1i(info->sampler_locations, 0);
glBindTexture(source_target, source_id);
glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

Powered by Google App Engine
This is Rietveld 408576698