Skip to content

Commit a1d12dd

Browse files
committed
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
1 parent 537d47f commit a1d12dd

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

libs/hwui/Dither.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ void Dither::setupProgram(Program* program, GLuint* textureUnit) {
7676

7777
bindDitherTexture();
7878

79+
float ditherSize = 1.0f / DITHER_KERNEL_SIZE;
7980
glUniform1i(program->getUniform("ditherSampler"), textureSlot);
80-
glUniform1f(program->getUniform("ditherSize"), 1.0f / DITHER_KERNEL_SIZE);
81+
glUniform1f(program->getUniform("ditherSize"), ditherSize);
82+
glUniform1f(program->getUniform("ditherSizeSquared"), ditherSize * ditherSize);
8183
}
8284

8385
}; // namespace uirenderer

libs/hwui/ProgramCache.cpp

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,14 @@ const char* gVS_Header_Uniforms_IsPoint =
5353
"uniform mediump float pointSize;\n";
5454
const char* gVS_Header_Uniforms_HasGradient[3] = {
5555
// Linear
56-
"uniform mat4 screenSpace;\n",
56+
"uniform mat4 screenSpace;\n"
57+
"uniform float ditherSize;\n",
5758
// Circular
58-
"uniform mat4 screenSpace;\n",
59+
"uniform mat4 screenSpace;\n"
60+
"uniform float ditherSize;\n",
5961
// Sweep
6062
"uniform mat4 screenSpace;\n"
63+
"uniform float ditherSize;\n"
6164
};
6265
const char* gVS_Header_Uniforms_HasBitmap =
6366
"uniform mat4 textureTransform;\n"
@@ -75,16 +78,22 @@ const char* gVS_Header_Varyings_PointHasBitmap =
7578
"varying highp vec2 outPointBitmapTexCoords;\n";
7679
const char* gVS_Header_Varyings_HasGradient[6] = {
7780
// Linear
78-
"varying highp vec2 linear;\n",
79-
"varying float linear;\n",
81+
"varying highp vec2 linear;\n"
82+
"varying vec2 ditherTexCoords;\n",
83+
"varying float linear;\n"
84+
"varying vec2 ditherTexCoords;\n",
8085

8186
// Circular
82-
"varying highp vec2 circular;\n",
83-
"varying highp vec2 circular;\n",
87+
"varying highp vec2 circular;\n"
88+
"varying vec2 ditherTexCoords;\n",
89+
"varying highp vec2 circular;\n"
90+
"varying vec2 ditherTexCoords;\n",
8491

8592
// Sweep
86-
"varying highp vec2 sweep;\n",
87-
"varying highp vec2 sweep;\n",
93+
"varying highp vec2 sweep;\n"
94+
"varying vec2 ditherTexCoords;\n",
95+
"varying highp vec2 sweep;\n"
96+
"varying vec2 ditherTexCoords;\n",
8897
};
8998
const char* gVS_Main =
9099
"\nvoid main(void) {\n";
@@ -94,16 +103,22 @@ const char* gVS_Main_OutTransformedTexCoords =
94103
" outTexCoords = (mainTextureTransform * vec4(texCoords, 0.0, 1.0)).xy;\n";
95104
const char* gVS_Main_OutGradient[6] = {
96105
// Linear
97-
" linear = vec2((screenSpace * position).x, 0.5);\n",
98-
" linear = (screenSpace * position).x;\n",
106+
" linear = vec2((screenSpace * position).x, 0.5);\n"
107+
" ditherTexCoords = (gl_Position * ditherSize).xy;\n",
108+
" linear = (screenSpace * position).x;\n"
109+
" ditherTexCoords = (gl_Position * ditherSize).xy;\n",
99110

100111
// Circular
101-
" circular = (screenSpace * position).xy;\n",
102-
" circular = (screenSpace * position).xy;\n",
112+
" circular = (screenSpace * position).xy;\n"
113+
" ditherTexCoords = (gl_Position * ditherSize).xy;\n",
114+
" circular = (screenSpace * position).xy;\n"
115+
" ditherTexCoords = (gl_Position * ditherSize).xy;\n",
103116

104117
// Sweep
105-
" sweep = (screenSpace * position).xy;\n",
106-
" sweep = (screenSpace * position).xy;\n",
118+
" sweep = (screenSpace * position).xy;\n"
119+
" ditherTexCoords = (gl_Position * ditherSize).xy;\n",
120+
" sweep = (screenSpace * position).xy;\n"
121+
" ditherTexCoords = (gl_Position * ditherSize).xy;\n",
107122
};
108123
const char* gVS_Main_OutBitmapTexCoords =
109124
" outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
@@ -144,7 +159,7 @@ const char* gFS_Uniforms_TextureSampler =
144159
const char* gFS_Uniforms_ExternalTextureSampler =
145160
"uniform samplerExternalOES baseSampler;\n";
146161
#define FS_UNIFORMS_DITHER \
147-
"uniform float ditherSize;\n" \
162+
"uniform float ditherSizeSquared;\n" \
148163
"uniform sampler2D ditherSampler;\n"
149164
#define FS_UNIFORMS_GRADIENT \
150165
"uniform vec4 startColor;\n" \
@@ -188,7 +203,7 @@ const char* gFS_Main_PointBitmapTexCoords =
188203
"((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n";
189204

190205
#define FS_MAIN_DITHER \
191-
"texture2D(ditherSampler, gl_FragCoord.xy * ditherSize).a * ditherSize * ditherSize"
206+
"texture2D(ditherSampler, ditherTexCoords).a * ditherSizeSquared"
192207
const char* gFS_Main_AddDitherToGradient =
193208
" gradientColor += " FS_MAIN_DITHER ";\n";
194209

@@ -505,9 +520,6 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
505520
} else if (description.isAA) {
506521
shader.append(gVS_Main_AA);
507522
}
508-
if (description.hasGradient) {
509-
shader.append(gVS_Main_OutGradient[gradientIndex(description)]);
510-
}
511523
if (description.hasBitmap) {
512524
shader.append(description.isPoint ?
513525
gVS_Main_OutPointBitmapTexCoords :
@@ -518,6 +530,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
518530
}
519531
// Output transformed position
520532
shader.append(gVS_Main_Position);
533+
if (description.hasGradient) {
534+
shader.append(gVS_Main_OutGradient[gradientIndex(description)]);
535+
}
521536
}
522537
// End the shader
523538
shader.append(gVS_Footer);

0 commit comments

Comments
 (0)