From 87a12aa24a87540251e0d2d0a223e761ceb31da2 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Mon, 14 Feb 2011 11:26:30 -0500 Subject: [PATCH] Selectively enable and disable GL_BLEND for better performance. Change-Id: I473e2bff91c2e0b1ec2436f0666506023a7c0945 --- .../platform/graphics/android/BaseLayerAndroid.cpp | 3 +-- WebCore/platform/graphics/android/LayerAndroid.cpp | 3 ++- WebCore/platform/graphics/android/MediaLayer.cpp | 27 ++++++++++++-------- .../platform/graphics/android/ShaderProgram.cpp | 29 +++++++++++++++++++++- WebCore/platform/graphics/android/ShaderProgram.h | 9 ++++++- WebKit/android/plugins/PluginWidgetAndroid.cpp | 4 ++- 6 files changed, 59 insertions(+), 16 deletions(-) diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 2f0e999c5..00eac744f 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -268,8 +268,6 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, (float)m_color.green() / 255.0, (float)m_color.blue() / 255.0, 1); glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glViewport(left, top, width, height); ShaderProgram* shader = TilesManager::instance()->shader(); @@ -281,6 +279,7 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, glUniform1i(shader->textureSampler(), 0); shader->setViewRect(viewRect); shader->setViewport(visibleRect); + shader->resetBlending(); ret = drawBasePictureInGL(visibleRect, scale); diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index bee423c98..7e998c1fb 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -861,9 +861,10 @@ bool LayerAndroid::drawGL(SkMatrix& matrix) uniqueId(), this, getWidth(), getHeight(), m_drawingTexture, textureRect.x(), textureRect.y(), textureRect.width(), textureRect.height()); + //TODO determine when drawing if the alpha value is used. TilesManager::instance()->shader()->drawLayerQuad(m, bounds, textureInfo->m_textureId, - m_drawOpacity); + m_drawOpacity, true); } m_drawingTexture->consumerRelease(); } diff --git a/WebCore/platform/graphics/android/MediaLayer.cpp b/WebCore/platform/graphics/android/MediaLayer.cpp index 7a4c02d06..ad4fc76bd 100644 --- a/WebCore/platform/graphics/android/MediaLayer.cpp +++ b/WebCore/platform/graphics/android/MediaLayer.cpp @@ -84,19 +84,26 @@ bool MediaLayer::drawGL(SkMatrix& matrix) if (m_bufferedTexture) { TextureInfo* textureInfo = m_bufferedTexture->consumerLock(); if (textureInfo) { - // the layer's shader draws the content inverted so we must undo - // that change in the transformation matrix - TransformationMatrix m = drawTransform(); - if (!m_isContentInverted) { - m.flipY(); - m.translate(0, -getSize().height()); - } SkRect rect; rect.set(0, 0, getSize().width(), getSize().height()); - TilesManager::instance()->shader()->drawLayerQuad(m, rect, - textureInfo->m_textureId, - 1.0f); //TODO fix this m_drawOpacity + + if (textureInfo->m_width != 0 && textureInfo->m_height != 0) { + // the layer's shader draws the content inverted so we must undo + // that change in the transformation matrix + TransformationMatrix m = drawTransform(); + if (!m_isContentInverted) { + m.flipY(); + m.translate(0, -getSize().height()); + } + + bool forceBlending = textureInfo->m_internalFormat == GL_RGBA || + textureInfo->m_internalFormat == GL_ALPHA; + TilesManager::instance()->shader()->drawLayerQuad(m, rect, + textureInfo->m_textureId, + 1.0f, forceBlending); + } + if (!rect.isEmpty()) needsInval = false; } diff --git a/WebCore/platform/graphics/android/ShaderProgram.cpp b/WebCore/platform/graphics/android/ShaderProgram.cpp index c4129f165..828cc3741 100644 --- a/WebCore/platform/graphics/android/ShaderProgram.cpp +++ b/WebCore/platform/graphics/android/ShaderProgram.cpp @@ -146,6 +146,7 @@ GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFrag } ShaderProgram::ShaderProgram() + : m_blendingEnabled(false) { init(); } @@ -181,6 +182,27 @@ void ShaderProgram::init() glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), coord, GL_STATIC_DRAW); } +void ShaderProgram::resetBlending() +{ + glDisable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + m_blendingEnabled = false; +} + +void ShaderProgram::setBlendingState(bool enableBlending) +{ + if (enableBlending == m_blendingEnabled) + return; + + if (enableBlending) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); + + m_blendingEnabled = enableBlending; +} + ///////////////////////////////////////////////////////////////////////////////////////// // Drawing ///////////////////////////////////////////////////////////////////////////////////////// @@ -222,6 +244,7 @@ void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity) glVertexAttribPointer(m_hPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); glUniform1f(alpha(), opacity); + setBlendingState(opacity < 1.0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); GLUtils::checkGlError("drawQuad"); @@ -278,7 +301,8 @@ IntRect ShaderProgram::clippedRectWithViewport(const IntRect& rect, int margin) } void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix, - SkRect& geometry, int textureId, float opacity) + SkRect& geometry, int textureId, float opacity, + bool forceBlending) { TransformationMatrix renderMatrix = drawMatrix; @@ -297,6 +321,7 @@ void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix, glVertexAttribPointer(m_hPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); glUniform1f(alpha(), opacity); + setBlendingState(forceBlending || opacity < 1.0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -317,12 +342,14 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, glUniformMatrix4fv(m_hVideoProjectionMatrix, 1, GL_FALSE, projectionMatrix); glUniformMatrix4fv(m_hVideoTextureMatrix, 1, GL_FALSE, textureMatrix); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId); glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); glEnableVertexAttribArray(m_hVideoPosition); glVertexAttribPointer(m_hVideoPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); + setBlendingState(false); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // switch back to our normal rendering program diff --git a/WebCore/platform/graphics/android/ShaderProgram.h b/WebCore/platform/graphics/android/ShaderProgram.h index 5e2045cb3..9419511b3 100644 --- a/WebCore/platform/graphics/android/ShaderProgram.h +++ b/WebCore/platform/graphics/android/ShaderProgram.h @@ -40,7 +40,8 @@ class ShaderProgram { void setViewport(SkRect& viewport); void drawQuad(SkRect& geometry, int textureId, float opacity); void drawLayerQuad(const TransformationMatrix& drawMatrix, - SkRect& geometry, int textureId, float opacity); + SkRect& geometry, int textureId, float opacity, + bool forceBlending = false); void drawVideoLayerQuad(const TransformationMatrix& drawMatrix, float* textureMatrix, SkRect& geometry, int textureId); void setViewRect(const IntRect& viewRect); @@ -49,11 +50,17 @@ class ShaderProgram { void clip(const FloatRect& rect); IntRect clippedRectWithViewport(const IntRect& rect, int margin = 0); + void resetBlending(); + private: GLuint loadShader(GLenum shaderType, const char* pSource); GLuint createProgram(const char* vertexSource, const char* fragmentSource); void setProjectionMatrix(SkRect& geometry); + void setBlendingState(bool enableBlending); + + bool m_blendingEnabled; + int m_program; int m_videoProgram; diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp index 06506ba79..be89a6836 100644 --- a/WebKit/android/plugins/PluginWidgetAndroid.cpp +++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp @@ -164,8 +164,10 @@ bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) { weakWebViewRef = env->NewWeakGlobalRef(webview); m_layer = new WebCore::MediaLayer(weakWebViewRef); } - else if (model != kOpenGL_ANPDrawingModel && m_layer != 0) + else if (model != kOpenGL_ANPDrawingModel && m_layer != 0) { m_layer->unref(); + m_layer = 0; + } if (m_drawingModel != model) { // Trigger layer computation in RenderLayerCompositor -- 2.11.0