summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2012-09-21 14:50:14 -0700
committerChet Haase <chet@google.com>2012-09-21 16:20:57 -0700
commita1d12dd619c86c9ac121a3095ff5e5633c11e876 (patch)
tree3e53e0a133aeaf86ec84b13a952c6aa6be3dbee7 /libs
parent537d47f510ce49acee09516ed5dde680d910ff94 (diff)
downloadframeworks_base-a1d12dd619c86c9ac121a3095ff5e5633c11e876.zip
frameworks_base-a1d12dd619c86c9ac121a3095ff5e5633c11e876.tar.gz
frameworks_base-a1d12dd619c86c9ac121a3095ff5e5633c11e876.tar.bz2
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
Diffstat (limited to 'libs')
-rwxr-xr-xlibs/hwui/Dither.cpp4
-rw-r--r--libs/hwui/ProgramCache.cpp53
2 files changed, 37 insertions, 20 deletions
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);