| 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 cdf2f302a07fd4919afb23073072133f7126250d..9e8ba0feceea1d9c906cdbaaeb664a03312219fe 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
|
| @@ -7,6 +7,7 @@
|
| #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 SHADER0(Src) \
|
| "#ifdef GL_ES\n"\
|
| @@ -27,7 +28,7 @@ const GLfloat kTextureCoords[] = { 0.0f, 0.0f,
|
| 1.0f, 1.0f,
|
| 0.0f, 1.0f };
|
|
|
| -const int kNumShaders = 7;
|
| +const int kNumShaders = 13;
|
| enum ShaderId {
|
| VERTEX_SHADER_POS_TEX,
|
| FRAGMENT_SHADER_TEX,
|
| @@ -35,7 +36,13 @@ enum ShaderId {
|
| FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA,
|
| FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA,
|
| FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y,
|
| - FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y
|
| + FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y,
|
| + FRAGMENT_SHADER_TEX_OES,
|
| + FRAGMENT_SHADER_TEX_OES_FLIP_Y,
|
| + FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA,
|
| + FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA,
|
| + FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA_FLIP_Y,
|
| + FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA_FLIP_Y
|
| };
|
|
|
| enum ProgramId {
|
| @@ -44,13 +51,19 @@ enum ProgramId {
|
| 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_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
|
| };
|
|
|
| // Returns the correct program 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 unpremultiply_alpha, bool is_source_external_oes) {
|
| // If both pre-multiply and unpremultiply are requested, then perform no
|
| // alpha manipulation.
|
| if (premultiply_alpha && unpremultiply_alpha) {
|
| @@ -58,6 +71,25 @@ ProgramId GetProgram(bool flip_y, bool premultiply_alpha,
|
| unpremultiply_alpha = false;
|
| }
|
|
|
| + if (is_source_external_oes) {
|
| + if (flip_y && premultiply_alpha)
|
| + return PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY;
|
| +
|
| + if (flip_y && unpremultiply_alpha)
|
| + return PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY;
|
| +
|
| + if (flip_y)
|
| + return PROGRAM_COPY_TEXTURE_OES_FLIP_Y;
|
| +
|
| + if (premultiply_alpha)
|
| + return PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA;
|
| +
|
| + if (unpremultiply_alpha)
|
| + return PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA;
|
| +
|
| + return PROGRAM_COPY_TEXTURE_OES;
|
| + }
|
| +
|
| if (flip_y && premultiply_alpha)
|
| return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY;
|
|
|
| @@ -135,6 +167,70 @@ const char* GetShaderSource(ShaderId shader) {
|
| if (gl_FragColor.a > 0.0)
|
| gl_FragColor.rgb /= gl_FragColor.a;
|
| });
|
| + case FRAGMENT_SHADER_TEX_OES:
|
| + // Cannot use the SHADER() macro because of the '#' char
|
| + return
|
| + "#extension GL_OES_EGL_image_external : require\n"
|
| + "precision mediump float;\n"
|
| + "uniform samplerExternalOES u_texSampler;\n"
|
| + "varying vec2 v_uv;\n"
|
| + "void main(void) {\n"
|
| + " gl_FragColor = texture2D(u_texSampler, v_uv.st);\n"
|
| + "}\n";
|
| + case FRAGMENT_SHADER_TEX_OES_FLIP_Y:
|
| + return
|
| + "#extension GL_OES_EGL_image_external : require\n"
|
| + "precision mediump float;\n"
|
| + "uniform samplerExternalOES u_texSampler;\n"
|
| + "varying vec2 v_uv;\n"
|
| + "void main(void) {\n"
|
| + " gl_FragColor =\n"
|
| + " texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));\n"
|
| + "}\n";
|
| + case FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA:
|
| + return
|
| + "#extension GL_OES_EGL_image_external : require\n"
|
| + "precision mediump float;\n"
|
| + "uniform samplerExternalOES u_texSampler;\n"
|
| + "varying vec2 v_uv;\n"
|
| + "void main(void) {\n"
|
| + " gl_FragColor = texture2D(u_texSampler, v_uv.st);\n"
|
| + " gl_FragColor.rgb *= gl_FragColor.a;\n"
|
| + "}\n";
|
| + case FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA:
|
| + return
|
| + "#extension GL_OES_EGL_image_external : require\n"
|
| + "precision mediump float;\n"
|
| + "uniform samplerExternalOES u_texSampler;\n"
|
| + "varying vec2 v_uv;\n"
|
| + "void main(void) {\n"
|
| + " gl_FragColor = texture2D(u_texSampler, v_uv.st);\n"
|
| + " if (gl_FragColor.a > 0.0)\n"
|
| + " gl_FragColor.rgb /= gl_FragColor.a;\n"
|
| + "}\n";
|
| + case FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA_FLIP_Y:
|
| + return
|
| + "#extension GL_OES_EGL_image_external : require\n"
|
| + "precision mediump float;\n"
|
| + "uniform samplerExternalOES u_texSampler;\n"
|
| + "varying vec2 v_uv;\n"
|
| + "void main(void) {\n"
|
| + " gl_FragColor =\n"
|
| + " texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));\n"
|
| + " gl_FragColor.rgb *= gl_FragColor.a;\n"
|
| + "}\n";
|
| + case FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA_FLIP_Y:
|
| + return
|
| + "#extension GL_OES_EGL_image_external : require\n"
|
| + "precision mediump float;\n"
|
| + "uniform samplerExternalOES u_texSampler;\n"
|
| + "varying vec2 v_uv;\n"
|
| + "void main(void) {\n"
|
| + " gl_FragColor =\n"
|
| + " texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));\n"
|
| + " if (gl_FragColor.a > 0.0)\n"
|
| + " gl_FragColor.rgb /= gl_FragColor.a;\n"
|
| + "}\n";
|
| default:
|
| return 0;
|
| }
|
| @@ -142,6 +238,8 @@ const char* GetShaderSource(ShaderId shader) {
|
|
|
| } // namespace
|
|
|
| +namespace gpu {
|
| +
|
| void CopyTextureCHROMIUMResourceManager::Initialize() {
|
| COMPILE_ASSERT(
|
| kVertexPositionAttrib == 0u || kVertexTextureAttrib == 0u,
|
| @@ -215,19 +313,27 @@ void CopyTextureCHROMIUMResourceManager::Destroy() {
|
| }
|
|
|
| void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
|
| - GLenum target,
|
| + const gles2::GLES2Decoder* decoder,
|
| + GLenum source_target,
|
| + GLenum dest_target,
|
| GLuint source_id,
|
| GLuint dest_id,
|
| GLint level,
|
| + GLsizei width,
|
| + GLsizei height,
|
| bool flip_y,
|
| bool premultiply_alpha,
|
| bool unpremultiply_alpha) {
|
| + DCHECK(source_target == GL_TEXTURE_2D ||
|
| + source_target == GL_TEXTURE_EXTERNAL_OES);
|
| if (!initialized_) {
|
| DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
|
| return;
|
| }
|
|
|
| - GLuint program = GetProgram(flip_y, premultiply_alpha, unpremultiply_alpha);
|
| + GLuint program = GetProgram(
|
| + flip_y, premultiply_alpha, unpremultiply_alpha,
|
| + source_target == GL_TEXTURE_EXTERNAL_OES);
|
| glUseProgram(programs_[program]);
|
|
|
| #ifndef NDEBUG
|
| @@ -240,46 +346,66 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
|
| }
|
| #endif
|
|
|
| + glActiveTexture(GL_TEXTURE0);
|
| + glBindTexture(GL_TEXTURE_2D, dest_id);
|
| + // NVidia drivers require texture settings to be a certain way
|
| + // or they won't report FRAMEBUFFER_COMPLETE.
|
| + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_);
|
| - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target,
|
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target,
|
| dest_id, level);
|
|
|
| #ifndef NDEBUG
|
| GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
|
| if (GL_FRAMEBUFFER_COMPLETE != fb_status) {
|
| DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer.";
|
| - return;
|
| - }
|
| + } else
|
| #endif
|
| + {
|
| + glEnableVertexAttribArray(kVertexPositionAttrib);
|
| + glEnableVertexAttribArray(kVertexTextureAttrib);
|
| +
|
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]);
|
| + glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE,
|
| + 4 * sizeof(GLfloat), 0);
|
| +
|
| + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]);
|
| + glVertexAttribPointer(kVertexTextureAttrib, 2, GL_FLOAT, GL_FALSE,
|
| + 2 * sizeof(GLfloat), 0);
|
| +
|
| + glUniform1i(sampler_locations_[program], 0);
|
| +
|
| + glBindTexture(source_target, source_id);
|
| + glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| + glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| + glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| + glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| +
|
| + glDisable(GL_DEPTH_TEST);
|
| + glDisable(GL_SCISSOR_TEST);
|
| + glDisable(GL_STENCIL_TEST);
|
| + glDisable(GL_CULL_FACE);
|
| + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
| + glDepthMask(GL_FALSE);
|
| + glDisable(GL_BLEND);
|
| +
|
| + glViewport(0, 0, width, height);
|
| + glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| + }
|
|
|
| - glEnableVertexAttribArray(kVertexPositionAttrib);
|
| - glEnableVertexAttribArray(kVertexTextureAttrib);
|
| -
|
| - glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]);
|
| - glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE,
|
| - 4 * sizeof(GLfloat), 0);
|
| -
|
| - glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]);
|
| - glVertexAttribPointer(kVertexTextureAttrib, 2, GL_FLOAT, GL_FALSE,
|
| - 2 * sizeof(GLfloat), 0);
|
| -
|
| - glActiveTexture(GL_TEXTURE0);
|
| - glUniform1i(sampler_locations_[program], 0);
|
| -
|
| - glBindTexture(GL_TEXTURE_2D, source_id);
|
| - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| -
|
| - glDisable(GL_DEPTH_TEST);
|
| - glDisable(GL_SCISSOR_TEST);
|
| - glDisable(GL_STENCIL_TEST);
|
| - glDisable(GL_CULL_FACE);
|
| - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
| - glDepthMask(GL_FALSE);
|
| - glDisable(GL_BLEND);
|
| -
|
| - glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| + decoder->RestoreAttribute(kVertexTextureAttrib);
|
| + decoder->RestoreAttribute(kVertexPositionAttrib);
|
| + decoder->RestoreTextureUnitBindings(0);
|
| + decoder->RestoreTextureState(source_id);
|
| + decoder->RestoreTextureState(dest_id);
|
| + decoder->RestoreActiveTexture();
|
| + decoder->RestoreProgramBindings();
|
| + decoder->RestoreBufferBindings();
|
| + decoder->RestoreFramebufferBindings();
|
| + decoder->RestoreGlobalState();
|
| }
|
|
|
| +} // namespace
|
|
|