From a1d12dd619c86c9ac121a3095ff5e5633c11e876 Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Fri, 21 Sep 2012 14:50:14 -0700 Subject: Optimize shaders for dithered gradients It's faster to compute a dither calculation in the vertex shader and use a varying (letting the GPU interpolate the fragment values) than to perform that calculation in the fragment shader as part of a texture lookup. Issue #7207600 Prime mr1 shader performance issues Issue #7158326 Bad framerates on MR1 (Mako, Manta, Prime) Change-Id: I15789582a6e9e2d8b9dd22aa5b0f72f0ba1cce7f --- libs/hwui/Dither.cpp | 4 +++- libs/hwui/ProgramCache.cpp | 53 +++++++++++++++++++++++++++++----------------- 2 files changed, 37 insertions(+), 20 deletions(-) (limited to 'libs') diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp index 5817977..e80b325 100755 --- a/libs/hwui/Dither.cpp +++ b/libs/hwui/Dither.cpp @@ -76,8 +76,10 @@ void Dither::setupProgram(Program* program, GLuint* textureUnit) { bindDitherTexture(); + float ditherSize = 1.0f / DITHER_KERNEL_SIZE; glUniform1i(program->getUniform("ditherSampler"), textureSlot); - glUniform1f(program->getUniform("ditherSize"), 1.0f / DITHER_KERNEL_SIZE); + glUniform1f(program->getUniform("ditherSize"), ditherSize); + glUniform1f(program->getUniform("ditherSizeSquared"), ditherSize * ditherSize); } }; // namespace uirenderer diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 6baf448..8c81ce2 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -53,11 +53,14 @@ const char* gVS_Header_Uniforms_IsPoint = "uniform mediump float pointSize;\n"; const char* gVS_Header_Uniforms_HasGradient[3] = { // Linear - "uniform mat4 screenSpace;\n", + "uniform mat4 screenSpace;\n" + "uniform float ditherSize;\n", // Circular - "uniform mat4 screenSpace;\n", + "uniform mat4 screenSpace;\n" + "uniform float ditherSize;\n", // Sweep "uniform mat4 screenSpace;\n" + "uniform float ditherSize;\n" }; const char* gVS_Header_Uniforms_HasBitmap = "uniform mat4 textureTransform;\n" @@ -75,16 +78,22 @@ const char* gVS_Header_Varyings_PointHasBitmap = "varying highp vec2 outPointBitmapTexCoords;\n"; const char* gVS_Header_Varyings_HasGradient[6] = { // Linear - "varying highp vec2 linear;\n", - "varying float linear;\n", + "varying highp vec2 linear;\n" + "varying vec2 ditherTexCoords;\n", + "varying float linear;\n" + "varying vec2 ditherTexCoords;\n", // Circular - "varying highp vec2 circular;\n", - "varying highp vec2 circular;\n", + "varying highp vec2 circular;\n" + "varying vec2 ditherTexCoords;\n", + "varying highp vec2 circular;\n" + "varying vec2 ditherTexCoords;\n", // Sweep - "varying highp vec2 sweep;\n", - "varying highp vec2 sweep;\n", + "varying highp vec2 sweep;\n" + "varying vec2 ditherTexCoords;\n", + "varying highp vec2 sweep;\n" + "varying vec2 ditherTexCoords;\n", }; const char* gVS_Main = "\nvoid main(void) {\n"; @@ -94,16 +103,22 @@ const char* gVS_Main_OutTransformedTexCoords = " outTexCoords = (mainTextureTransform * vec4(texCoords, 0.0, 1.0)).xy;\n"; const char* gVS_Main_OutGradient[6] = { // Linear - " linear = vec2((screenSpace * position).x, 0.5);\n", - " linear = (screenSpace * position).x;\n", + " linear = vec2((screenSpace * position).x, 0.5);\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", + " linear = (screenSpace * position).x;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", // Circular - " circular = (screenSpace * position).xy;\n", - " circular = (screenSpace * position).xy;\n", + " circular = (screenSpace * position).xy;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", + " circular = (screenSpace * position).xy;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", // Sweep - " sweep = (screenSpace * position).xy;\n", - " sweep = (screenSpace * position).xy;\n", + " sweep = (screenSpace * position).xy;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", + " sweep = (screenSpace * position).xy;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", }; const char* gVS_Main_OutBitmapTexCoords = " outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n"; @@ -144,7 +159,7 @@ const char* gFS_Uniforms_TextureSampler = const char* gFS_Uniforms_ExternalTextureSampler = "uniform samplerExternalOES baseSampler;\n"; #define FS_UNIFORMS_DITHER \ - "uniform float ditherSize;\n" \ + "uniform float ditherSizeSquared;\n" \ "uniform sampler2D ditherSampler;\n" #define FS_UNIFORMS_GRADIENT \ "uniform vec4 startColor;\n" \ @@ -188,7 +203,7 @@ const char* gFS_Main_PointBitmapTexCoords = "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n"; #define FS_MAIN_DITHER \ - "texture2D(ditherSampler, gl_FragCoord.xy * ditherSize).a * ditherSize * ditherSize" + "texture2D(ditherSampler, ditherTexCoords).a * ditherSizeSquared" const char* gFS_Main_AddDitherToGradient = " gradientColor += " FS_MAIN_DITHER ";\n"; @@ -505,9 +520,6 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description } else if (description.isAA) { shader.append(gVS_Main_AA); } - if (description.hasGradient) { - shader.append(gVS_Main_OutGradient[gradientIndex(description)]); - } if (description.hasBitmap) { shader.append(description.isPoint ? gVS_Main_OutPointBitmapTexCoords : @@ -518,6 +530,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description } // Output transformed position shader.append(gVS_Main_Position); + if (description.hasGradient) { + shader.append(gVS_Main_OutGradient[gradientIndex(description)]); + } } // End the shader shader.append(gVS_Footer); -- cgit v1.1