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 |