diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2011-06-24 14:37:35 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-06-24 14:37:35 -0700 |
commit | 53448d163d8dbb96e2d01046483298b078c17eb0 (patch) | |
tree | 2e66b574e65b4fa6a23c3eb69017d433b8191b81 | |
parent | d5c8fc35c6fd034d37978ad6c4df7e0afdbb0e1b (diff) | |
parent | 64036ff80901c6af07b1f00a3a4da3966fc166c9 (diff) | |
download | external_webkit-53448d163d8dbb96e2d01046483298b078c17eb0.zip external_webkit-53448d163d8dbb96e2d01046483298b078c17eb0.tar.gz external_webkit-53448d163d8dbb96e2d01046483298b078c17eb0.tar.bz2 |
Merge "Browser ST: Support both OES and 2D texture target"
8 files changed, 193 insertions, 37 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index bbf1532..8a1b587 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -238,7 +238,8 @@ void BaseTile::draw(float transparency, SkRect& rect, float scale) if (m_texture->readyFor(this)) { XLOG("draw tile %d, %d, %.2f with texture %x", x(), y(), scale, m_texture); TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId, - transparency); + transparency, + textureInfo->getTextureTarget()); } m_texture->consumerRelease(); } diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index 67456a3..74b246f 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -962,7 +962,8 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) //TODO determine when drawing if the alpha value is used. TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), bounds, textureInfo->m_textureId, - m_drawOpacity, true); + m_drawOpacity, true, + textureInfo->getTextureTarget()); } if (!ready) m_dirty = true; diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.cpp b/Source/WebCore/platform/graphics/android/MediaLayer.cpp index 1ba6d46..3d1fe12 100644 --- a/Source/WebCore/platform/graphics/android/MediaLayer.cpp +++ b/Source/WebCore/platform/graphics/android/MediaLayer.cpp @@ -119,7 +119,8 @@ bool MediaLayer::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) textureInfo->m_internalFormat == GL_ALPHA; TilesManager::instance()->shader()->drawLayerQuad(m, mediaBounds, textureInfo->m_textureId, - 1.0f, forceBlending); + 1.0f, forceBlending, + textureInfo->getTextureTarget()); } m_bufferedTexture->consumerRelease(); } diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp index 635130b..655af0e 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp @@ -32,6 +32,7 @@ #include "GLUtils.h" #include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> #include <cutils/log.h> #include <wtf/CurrentTime.h> #include <wtf/text/CString.h> @@ -51,7 +52,6 @@ static const char gVertexShader[] = "}\n"; static const char gFragmentShader[] = - "#extension GL_OES_EGL_image_external : require\n" "precision mediump float;\n" "varying vec2 v_texCoord; \n" "uniform float alpha; \n" @@ -80,6 +80,33 @@ static const char gVideoFragmentShader[] = " gl_FragColor = texture2D(s_yuvTexture, v_texCoord);\n" "}\n"; +// In the long run, the gSurfaceTextureOESFragmentShader is the official way of +// doing Surface Texture for RGBA format. +// Now since the driver is not ready for it yet, we had to support both to be +// ready for the switch. +// TODO: remove SurfaceTexture2D support after switching to OES method. +static const char gSurfaceTexture2DFragmentShader[] = + "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "varying vec2 v_texCoord; \n" + "uniform float alpha; \n" + "uniform sampler2D s_texture; \n" + "void main() {\n" + " gl_FragColor = texture2D(s_texture, v_texCoord); \n" + " gl_FragColor *= alpha; " + "}\n"; + +static const char gSurfaceTextureOESFragmentShader[] = + "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "varying vec2 v_texCoord; \n" + "uniform float alpha; \n" + "uniform samplerExternalOES s_texture; \n" + "void main() {\n" + " gl_FragColor = texture2D(s_texture, v_texCoord); \n" + " gl_FragColor *= alpha; " + "}\n"; + GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource) { GLuint shader = glCreateShader(shaderType); @@ -157,21 +184,41 @@ void ShaderProgram::init() { m_program = createProgram(gVertexShader, gFragmentShader); m_videoProgram = createProgram(gVideoVertexShader, gVideoFragmentShader); - if (m_program == -1 || m_videoProgram == -1) + m_surfTex2DProgram = + createProgram(gVertexShader, gSurfaceTexture2DFragmentShader); + m_surfTexOESProgram = + createProgram(gVertexShader, gSurfaceTextureOESFragmentShader); + + if (m_program == -1 + || m_videoProgram == -1 + || m_surfTex2DProgram == -1 + || m_surfTexOESProgram == -1) return; m_hProjectionMatrix = glGetUniformLocation(m_program, "projectionMatrix"); m_hAlpha = glGetUniformLocation(m_program, "alpha"); m_hTexSampler = glGetUniformLocation(m_program, "s_texture"); - m_hPosition = glGetAttribLocation(m_program, "vPosition"); - m_hVideoProjectionMatrix = glGetUniformLocation(m_videoProgram, "projectionMatrix"); + m_hVideoProjectionMatrix = + glGetUniformLocation(m_videoProgram, "projectionMatrix"); m_hVideoTextureMatrix = glGetUniformLocation(m_videoProgram, "textureMatrix"); m_hVideoTexSampler = glGetUniformLocation(m_videoProgram, "s_yuvTexture"); - m_hVideoPosition = glGetAttribLocation(m_program, "vPosition"); + m_hST2DProjectionMatrix = + glGetUniformLocation(m_surfTex2DProgram, "projectionMatrix"); + m_hST2DAlpha = glGetUniformLocation(m_surfTex2DProgram, "alpha"); + m_hST2DTexSampler = glGetUniformLocation(m_surfTex2DProgram, "s_texture"); + m_hST2DPosition = glGetAttribLocation(m_surfTex2DProgram, "vPosition"); + + m_hSTOESProjectionMatrix = + glGetUniformLocation(m_surfTexOESProgram, "projectionMatrix"); + m_hSTOESAlpha = glGetUniformLocation(m_surfTexOESProgram, "alpha"); + m_hSTOESTexSampler = glGetUniformLocation(m_surfTexOESProgram, "s_texture"); + m_hSTOESPosition = glGetAttribLocation(m_surfTexOESProgram, "vPosition"); + + const GLfloat coord[] = { 0.0f, 0.0f, // C 1.0f, 0.0f, // D @@ -182,6 +229,8 @@ void ShaderProgram::init() glGenBuffers(1, m_textureBuffer); glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), coord, GL_STATIC_DRAW); + + GLUtils::checkGlError("init"); } void ShaderProgram::resetBlending() @@ -232,21 +281,51 @@ void ShaderProgram::setProjectionMatrix(SkRect& geometry) glUniformMatrix4fv(m_hProjectionMatrix, 1, GL_FALSE, projectionMatrix); } -void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity) +void ShaderProgram::drawQuadInternal(SkRect& geometry, + GLint textureId, + float opacity, + GLint program, + GLint texSampler, + GLenum textureTarget, + GLint position, + GLint alpha) { + glUseProgram(program); setProjectionMatrix(geometry); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); + glUniform1i(texSampler, 0); + glBindTexture(textureTarget, textureId); + glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(m_hPosition); - glVertexAttribPointer(m_hPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - glUniform1f(alpha(), opacity); + glEnableVertexAttribArray(position); + glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0); + glUniform1f(alpha, opacity); setBlendingState(opacity < 1.0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} +void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity, + GLenum textureTarget) +{ + if (textureTarget == GL_TEXTURE_2D) { + drawQuadInternal(geometry, textureId, opacity, m_program, + m_hTexSampler, GL_TEXTURE_2D, + m_hPosition, alpha()); + } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES) { + drawQuadInternal(geometry, textureId, opacity, m_surfTexOESProgram, + m_hSTOESTexSampler, GL_TEXTURE_EXTERNAL_OES, + m_hSTOESPosition, m_hSTOESAlpha); + } else if (!textureTarget) { + drawQuadInternal(geometry, textureId, opacity, m_surfTex2DProgram, + m_hST2DTexSampler, GL_TEXTURE_2D, + m_hST2DPosition, m_hST2DAlpha); + } GLUtils::checkGlError("drawQuad"); } @@ -373,9 +452,34 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo return result.z(); } +void ShaderProgram::drawLayerQuadInternal(const GLfloat* projectionMatrix, + int textureId, float opacity, + GLenum textureTarget, GLint program, + GLint matrix, GLint texSample, + GLint position, GLint alpha) +{ + glUseProgram(program); + glUniformMatrix4fv(matrix, 1, GL_FALSE, projectionMatrix); + + glActiveTexture(GL_TEXTURE0); + glUniform1i(texSample, 0); + glBindTexture(textureTarget, textureId); + glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + + glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); + glEnableVertexAttribArray(position); + glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0); + glUniform1f(alpha, opacity); +} + + void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix, SkRect& geometry, int textureId, float opacity, - bool forceBlending) + bool forceBlending, GLenum textureTarget) { TransformationMatrix modifiedDrawMatrix = drawMatrix; @@ -386,18 +490,27 @@ void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix, GLfloat projectionMatrix[16]; GLUtils::toGLMatrix(projectionMatrix, renderMatrix); - glUniformMatrix4fv(m_hProjectionMatrix, 1, GL_FALSE, projectionMatrix); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); - - glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(m_hPosition); - glVertexAttribPointer(m_hPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - glUniform1f(alpha(), opacity); + if (textureTarget == GL_TEXTURE_2D) { + drawLayerQuadInternal(projectionMatrix, textureId, opacity, + GL_TEXTURE_2D, m_program, + m_hProjectionMatrix, m_hTexSampler, + m_hPosition, alpha()); + } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES) { + drawLayerQuadInternal(projectionMatrix, textureId, opacity, + GL_TEXTURE_EXTERNAL_OES, m_surfTexOESProgram, + m_hSTOESProjectionMatrix, m_hSTOESTexSampler, + m_hSTOESPosition, m_hSTOESAlpha); + } else if (!textureTarget) { + drawLayerQuadInternal(projectionMatrix, textureId, opacity, + GL_TEXTURE_2D, m_surfTex2DProgram, + m_hST2DProjectionMatrix, m_hST2DTexSampler, + m_hST2DPosition, m_hST2DAlpha); + } setBlendingState(forceBlending || opacity < 1.0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + GLUtils::checkGlError("drawLayerQuad"); } void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, @@ -418,6 +531,7 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, glUniformMatrix4fv(m_hVideoTextureMatrix, 1, GL_FALSE, textureMatrix); glActiveTexture(GL_TEXTURE0); + glUniform1i(m_hVideoTexSampler, 0); glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId); glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); @@ -426,9 +540,6 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, setBlendingState(false); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - // switch back to our normal rendering program - glUseProgram(m_program); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/ShaderProgram.h index 55afe4f..2577fb0 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.h @@ -38,11 +38,25 @@ class ShaderProgram { // Drawing void setViewport(SkRect& viewport); - void drawQuad(SkRect& geometry, int textureId, float opacity); float zValue(const TransformationMatrix& drawMatrix, float w, float h); + + // For drawQuad and drawLayerQuad, they can handle 3 cases for now: + // 1) textureTarget == GL_TEXTURE_2D + // Normal texture in GL_TEXTURE_2D target. + // 2) textureTarget == GL_TEXTURE_EXTERNAL_OES + // Surface texture in GL_TEXTURE_EXTERNAL_OES target. + // 3) textureTarget == 0 (Will be deprecated soon) + // Surface texture in GL_TEXTURE_2D target. + // + // TODO: Shrink the support modes into 2 (1 and 2) after media framework + // support Surface texture in GL_TEXTURE_EXTERNAL_OES target on all + // platforms. + void drawQuad(SkRect& geometry, int textureId, float opacity, + GLenum textureTarget = GL_TEXTURE_2D); void drawLayerQuad(const TransformationMatrix& drawMatrix, - SkRect& geometry, int textureId, float opacity, - bool forceBlending = false); + SkRect& geometry, int textureId, float opacity, + bool forceBlending = false, + GLenum textureTarget = GL_TEXTURE_2D); void drawVideoLayerQuad(const TransformationMatrix& drawMatrix, float* textureMatrix, SkRect& geometry, int textureId); void setViewRect(const IntRect& viewRect); @@ -71,10 +85,21 @@ class ShaderProgram { void setBlendingState(bool enableBlending); + void drawQuadInternal(SkRect& geometry, GLint textureId, float opacity, + GLint program, GLint texSampler, GLenum textureTarget, + GLint position, GLint alpha); + + void drawLayerQuadInternal(const GLfloat* projectionMatrix, int textureId, + float opacity, GLenum textureTarget, GLint program, + GLint matrix, GLint texSample, + GLint position, GLint alpha); + bool m_blendingEnabled; int m_program; int m_videoProgram; + int m_surfTex2DProgram; + int m_surfTexOESProgram; TransformationMatrix m_projectionMatrix; GLuint m_textureBuffer[1]; @@ -96,6 +121,16 @@ class ShaderProgram { int m_hVideoTextureMatrix; int m_hVideoTexSampler; + GLint m_hST2DProjectionMatrix; + GLint m_hST2DAlpha; + GLint m_hST2DTexSampler; + GLint m_hST2DPosition; + + GLint m_hSTOESProjectionMatrix; + GLint m_hSTOESAlpha; + GLint m_hSTOESTexSampler; + GLint m_hSTOESPosition; + // attribs GLint m_hPosition; GLint m_hVideoPosition; diff --git a/Source/WebCore/platform/graphics/android/SharedTexture.cpp b/Source/WebCore/platform/graphics/android/SharedTexture.cpp index ecd9f54..cbe44da 100644 --- a/Source/WebCore/platform/graphics/android/SharedTexture.cpp +++ b/Source/WebCore/platform/graphics/android/SharedTexture.cpp @@ -198,14 +198,6 @@ TextureInfo* SharedTexture::lockTarget() // Note that the source and targe are the same when using Surface Texture. if (m_sharedTextureMode == SurfaceTextureMode) { m_sourceTexture->m_surfaceTexture->updateTexImage(); - - // Surface Texture requires the filter to be non mipmap - glBindTexture(GL_TEXTURE_2D, m_sourceTexture->m_textureId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - return m_sourceTexture; } diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.cpp b/Source/WebCore/platform/graphics/android/TextureInfo.cpp index ce132c8..849e6fc 100644 --- a/Source/WebCore/platform/graphics/android/TextureInfo.cpp +++ b/Source/WebCore/platform/graphics/android/TextureInfo.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "TextureInfo.h" + #include "WebCoreJni.h" #include <JNIUtility.h> @@ -62,4 +63,17 @@ bool TextureInfo::operator==(const TextureInfo& otherTexture) return otherTexture.m_textureId == m_textureId && equalsAttributes(&otherTexture); } +GLenum TextureInfo::getTextureTarget() +{ + if (m_surfaceTexture.get()) { + GLenum target = m_surfaceTexture->getCurrentTextureTarget(); + // TODO: remove this translation when TEXTURE_2D+RGBA surface texture + // support is deprecated. + if (target == GL_TEXTURE_2D) + return 0; + return target; + } + return GL_TEXTURE_2D; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.h b/Source/WebCore/platform/graphics/android/TextureInfo.h index dfc3092..252d288 100644 --- a/Source/WebCore/platform/graphics/android/TextureInfo.h +++ b/Source/WebCore/platform/graphics/android/TextureInfo.h @@ -58,6 +58,7 @@ public: void copyAttributes(const TextureInfo* sourceTexture); SharedTextureMode getSharedTextureMode() { return m_sharedTextureMode; } + GLenum getTextureTarget(); bool operator==(const TextureInfo& otherTexture); GLuint m_textureId; |