From 5bab13b465fa8c9ac2b7782ee0d20def86568f37 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Mon, 16 Jul 2012 15:35:57 -0700 Subject: Cache gl operations to avoid redundancy Change-Id: I1e8f607a94685f3aa8f63e40fe2a265bca8a084e --- .../graphics/android/rendering/ShaderProgram.cpp | 79 ++++++++++++++++------ .../graphics/android/rendering/ShaderProgram.h | 6 ++ 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp index d7266a3..9e13ca1 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp @@ -257,6 +257,16 @@ GLint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragm return program; } +void ShaderProgram::initProgram(ShaderType type) +{ + // initialize shader's static texSampler and position values + glUseProgram(m_handleArray[type].programHandle); + + if (m_handleArray[type].texSamplerHandle != -1) + glUniform1i(m_handleArray[type].texSamplerHandle, 0); + glEnableVertexAttribArray(m_handleArray[type].positionHandle); +} + ShaderProgram::ShaderProgram() : m_blendingEnabled(false) , m_contrast(1) @@ -321,6 +331,7 @@ void ShaderProgram::initGLResources() GLint pureColorValue = glGetUniformLocation(pureColorProgram, "inputColor"); m_handleArray[PureColor].init(-1, -1, pureColorPosition, pureColorProgram, pureColorProjMtx, pureColorValue, -1, -1, -1, -1); + initProgram(PureColor); GLint tex2DAlpha = glGetUniformLocation(tex2DProgram, "alpha"); GLint tex2DPosition = glGetAttribLocation(tex2DProgram, "vPosition"); @@ -329,6 +340,7 @@ void ShaderProgram::initGLResources() GLint tex2DFillPortion = glGetUniformLocation(tex2DProgram, "fillPortion"); m_handleArray[Tex2D].init(tex2DAlpha, -1, tex2DPosition, tex2DProgram, tex2DProjMtx, -1, tex2DTexSampler, -1, tex2DFillPortion, -1); + initProgram(Tex2D); GLint tex2DInvAlpha = glGetUniformLocation(tex2DInvProgram, "alpha"); GLint tex2DInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast"); @@ -340,6 +352,7 @@ void ShaderProgram::initGLResources() tex2DInvPosition, tex2DInvProgram, tex2DInvProjMtx, -1, tex2DInvTexSampler, -1, tex2DInvFillPortion, -1); + initProgram(Tex2DInv); GLint repeatTexAlpha = glGetUniformLocation(repeatTexProgram, "alpha"); GLint repeatTexPosition = glGetAttribLocation(repeatTexProgram, "vPosition"); @@ -351,6 +364,7 @@ void ShaderProgram::initGLResources() repeatTexProgram,repeatTexProjMtx, -1, repeatTexTexSampler, -1, repeatTexFillPortion, repeatTexScale); + initProgram(RepeatTex); GLint repeatTexInvAlpha = glGetUniformLocation(repeatTexInvProgram, "alpha"); GLint repeatTexInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast"); @@ -364,6 +378,7 @@ void ShaderProgram::initGLResources() repeatTexInvProjMtx, -1, repeatTexInvTexSampler, -1, repeatTexInvFillPortion, repeatTexInvScale); + initProgram(RepeatTexInv); GLint texOESAlpha = glGetUniformLocation(texOESProgram, "alpha"); GLint texOESPosition = glGetAttribLocation(texOESProgram, "vPosition"); @@ -372,6 +387,7 @@ void ShaderProgram::initGLResources() GLint texOESFillPortion = glGetUniformLocation(texOESProgram, "fillPortion"); m_handleArray[TexOES].init(texOESAlpha, -1, texOESPosition, texOESProgram, texOESProjMtx, -1, texOESTexSampler, -1, texOESFillPortion, -1); + initProgram(TexOES); GLint texOESInvAlpha = glGetUniformLocation(texOESInvProgram, "alpha"); GLint texOESInvContrast = glGetUniformLocation(texOESInvProgram, "contrast"); @@ -383,6 +399,7 @@ void ShaderProgram::initGLResources() texOESInvPosition, texOESInvProgram, texOESInvProjMtx, -1, texOESInvTexSampler, -1, texOESInvFillPortion, -1); + initProgram(TexOESInv); GLint videoPosition = glGetAttribLocation(videoProgram, "vPosition"); GLint videoProjMtx = glGetUniformLocation(videoProgram, "projectionMatrix"); @@ -391,6 +408,7 @@ void ShaderProgram::initGLResources() m_handleArray[Video].init(-1, -1, videoPosition, videoProgram, videoProjMtx, -1, videoTexSampler, videoTexMtx, -1, -1); + initProgram(Video); const GLfloat coord[] = { 0.0f, 0.0f, // C @@ -539,6 +557,16 @@ void ShaderProgram::setupDrawing(const IntRect& invScreenRect, // Set up m_clipProjectionMatrix, m_currentScale and m_webViewMatrix before // calling this function. setupSurfaceProjectionMatrix(); + + //// initialize frame-constant values //// + glActiveTexture(GL_TEXTURE0); + glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); + + //// initialize GL cache //// + m_cachedProgramType = UndefinedShader; + m_cachedOpacity = -1; + m_cachedFillPortion = FloatRect(); + m_cachedPureColor = Color(); } // Calculate the right color value sent into the shader considering the (0,1) @@ -695,23 +723,33 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix, const Color& pureColor, const FloatRect& fillPortion, const FloatSize& repeatScale) { - glUseProgram(m_handleArray[type].programHandle); + if (m_cachedProgramType != type) { + glUseProgram(m_handleArray[type].programHandle); + glVertexAttribPointer(m_handleArray[type].positionHandle, + 2, GL_FLOAT, GL_FALSE, 0, 0); + m_cachedProgramType = type; + } glUniformMatrix4fv(m_handleArray[type].projMtxHandle, 1, GL_FALSE, matrix); if (type != PureColor) { - glActiveTexture(GL_TEXTURE0); - glUniform1i(m_handleArray[type].texSamplerHandle, 0); glBindTexture(textureTarget, textureId); glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, filter); glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, filter); - glUniform1f(m_handleArray[type].alphaHandle, opacity); + + if (m_cachedOpacity != opacity) { + glUniform1f(m_handleArray[type].alphaHandle, opacity); + m_cachedOpacity = opacity; + } GLint contrastHandle = m_handleArray[type].contrastHandle; if (contrastHandle != -1) glUniform1f(contrastHandle, m_contrast); - glUniform4f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y(), - fillPortion.width(), fillPortion.height()); + if (m_cachedFillPortion != fillPortion) { + glUniform4f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y(), + fillPortion.width(), fillPortion.height()); + m_cachedFillPortion = fillPortion; + } // Only when we have repeat scale, this handle can be >= 0; if (m_handleArray[type].scaleHandle != -1) { @@ -719,16 +757,14 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix, repeatScale.width(), repeatScale.height()); } } else { - glUniform4f(m_handleArray[type].pureColorHandle, - pureColor.red() / 255.0, pureColor.green() / 255.0, - pureColor.blue() / 255.0, pureColor.alpha() / 255.0); + if (m_cachedPureColor != pureColor) { + glUniform4f(m_handleArray[type].pureColorHandle, + pureColor.red() / 255.0, pureColor.green() / 255.0, + pureColor.blue() / 255.0, pureColor.alpha() / 255.0); + m_cachedPureColor = pureColor; + } } - GLint positionHandle = m_handleArray[type].positionHandle; - glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(positionHandle); - glVertexAttribPointer(positionHandle, 2, GL_FLOAT, GL_FALSE, 0, 0); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -819,7 +855,13 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, int textureId) { // switch to our custom yuv video rendering program - glUseProgram(m_handleArray[Video].programHandle); + if (m_cachedProgramType != Video) { + glUseProgram(m_handleArray[Video].programHandle); + glVertexAttribPointer(m_handleArray[Video].positionHandle, + 2, GL_FLOAT, GL_FALSE, 0, 0); + m_cachedProgramType = Video; + } + // TODO: Merge drawVideoLayerQuad into drawQuad. TransformationMatrix modifiedDrawMatrix; modifiedDrawMatrix.scale3d(m_currentScale, m_currentScale, 1); @@ -835,15 +877,8 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, projectionMatrix); glUniformMatrix4fv(m_handleArray[Video].videoMtxHandle, 1, GL_FALSE, textureMatrix); - glActiveTexture(GL_TEXTURE0); - glUniform1i(m_handleArray[Video].texSamplerHandle, 0); glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId); - GLint videoPosition = m_handleArray[Video].positionHandle; - glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]); - glEnableVertexAttribArray(videoPosition); - glVertexAttribPointer(videoPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - setBlendingState(false); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h index 27eb737..9c5dc17 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h @@ -168,6 +168,7 @@ public: private: GLuint loadShader(GLenum shaderType, const char* pSource); GLint createProgram(const char* vertexSource, const char* fragmentSource); + void initProgram(ShaderType type); GLfloat* getTileProjectionMatrix(const DrawQuadData* data); void setBlendingState(bool enableBlending); void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId, @@ -231,6 +232,11 @@ private: GLfloat m_tileProjMatrix[16]; Vector m_resources; + + ShaderType m_cachedProgramType; + GLfloat m_cachedOpacity; + FloatRect m_cachedFillPortion; + Color m_cachedPureColor; }; } // namespace WebCore -- cgit v1.1