Skip to content

Commit a938f56

Browse files
author
Romain Guy
committed
Fix modulation and gamma correction issues
Modulation is normally enabled in a shader when drawing with an alpha mask (A8 texture.) Modulation is used to do one of two things: - Colorize the primitive (to draw text in red for instance) - Apply extra translucency (50% translucent circle filled with a bitmap) The current implementation has four issues: 1. Unnecessary work is performed by assigning the modulation color to vec4 fragColor early in the shader 2. The modulation color's alpha is applied twice when the primitive is drawn with an SkShader 3. The decision to modulate is wrong and triggers when any of the RGB channels is < 1.0. Only the alpha channel needs to be taken into account to make the decision 4. Gamma correction is not applied properly This change addresses all four issues above. Change-Id: I73fcc74efc4b094bf2d1b835f10ffaa2ea4b9eb9
1 parent 494ac35 commit a938f56

File tree

2 files changed

+51
-39
lines changed

2 files changed

+51
-39
lines changed

libs/hwui/Program.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,7 @@ struct ProgramDescription {
204204
* be provided with a modulation color.
205205
*/
206206
bool setColor(const float r, const float g, const float b, const float a) {
207-
modulate = a < COLOR_COMPONENT_THRESHOLD || r < COLOR_COMPONENT_THRESHOLD ||
208-
g < COLOR_COMPONENT_THRESHOLD || b < COLOR_COMPONENT_THRESHOLD;
207+
modulate = a < COLOR_COMPONENT_THRESHOLD;
209208
return modulate;
210209
}
211210

libs/hwui/ProgramCache.cpp

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ const char* gFS_Header_Uniforms_PointHasBitmap =
140140
"uniform vec2 textureDimension;\n"
141141
"uniform float pointSize;\n";
142142
const char* gFS_Uniforms_TextureSampler =
143-
"uniform sampler2D sampler;\n";
143+
"uniform sampler2D baseSampler;\n";
144144
const char* gFS_Uniforms_ExternalTextureSampler =
145-
"uniform samplerExternalOES sampler;\n";
145+
"uniform samplerExternalOES baseSampler;\n";
146146
#define FS_UNIFORMS_DITHER \
147147
"uniform float ditherSize;\n" \
148148
"uniform sampler2D ditherSampler;\n"
@@ -199,27 +199,27 @@ const char* gFS_Fast_SingleColor =
199199
"}\n\n";
200200
const char* gFS_Fast_SingleTexture =
201201
"\nvoid main(void) {\n"
202-
" gl_FragColor = texture2D(sampler, outTexCoords);\n"
202+
" gl_FragColor = texture2D(baseSampler, outTexCoords);\n"
203203
"}\n\n";
204204
const char* gFS_Fast_SingleModulateTexture =
205205
"\nvoid main(void) {\n"
206-
" gl_FragColor = color.a * texture2D(sampler, outTexCoords);\n"
206+
" gl_FragColor = color.a * texture2D(baseSampler, outTexCoords);\n"
207207
"}\n\n";
208208
const char* gFS_Fast_SingleA8Texture =
209209
"\nvoid main(void) {\n"
210-
" gl_FragColor = texture2D(sampler, outTexCoords);\n"
210+
" gl_FragColor = texture2D(baseSampler, outTexCoords);\n"
211211
"}\n\n";
212212
const char* gFS_Fast_SingleA8Texture_ApplyGamma =
213213
"\nvoid main(void) {\n"
214-
" gl_FragColor = vec4(0.0, 0.0, 0.0, pow(texture2D(sampler, outTexCoords).a, gamma));\n"
214+
" gl_FragColor = vec4(0.0, 0.0, 0.0, pow(texture2D(baseSampler, outTexCoords).a, gamma));\n"
215215
"}\n\n";
216216
const char* gFS_Fast_SingleModulateA8Texture =
217217
"\nvoid main(void) {\n"
218-
" gl_FragColor = color * texture2D(sampler, outTexCoords).a;\n"
218+
" gl_FragColor = color * texture2D(baseSampler, outTexCoords).a;\n"
219219
"}\n\n";
220220
const char* gFS_Fast_SingleModulateA8Texture_ApplyGamma =
221221
"\nvoid main(void) {\n"
222-
" gl_FragColor = color * pow(texture2D(sampler, outTexCoords).a, gamma);\n"
222+
" gl_FragColor = color * pow(texture2D(baseSampler, outTexCoords).a, gamma);\n"
223223
"}\n\n";
224224
const char* gFS_Fast_SingleGradient[2] = {
225225
"\nvoid main(void) {\n"
@@ -243,8 +243,6 @@ const char* gFS_Main_FetchColor =
243243
" fragColor = color;\n";
244244
const char* gFS_Main_ModulateColor =
245245
" fragColor *= color.a;\n";
246-
const char* gFS_Main_ModulateColor_ApplyGamma =
247-
" fragColor *= pow(color.a, gamma);\n";
248246
const char* gFS_Main_AccountForAA =
249247
" fragColor *= (1.0 - smoothstep(boundaryWidth, 0.5, abs(0.5 - widthProportion)))\n"
250248
" * (1.0 - smoothstep(boundaryLength, 0.5, abs(0.5 - lengthProportion)));\n";
@@ -253,15 +251,17 @@ const char* gFS_Main_AccountForAARect =
253251

254252
const char* gFS_Main_FetchTexture[2] = {
255253
// Don't modulate
256-
" fragColor = texture2D(sampler, outTexCoords);\n",
254+
" fragColor = texture2D(baseSampler, outTexCoords);\n",
257255
// Modulate
258-
" fragColor = color * texture2D(sampler, outTexCoords);\n"
256+
" fragColor = color * texture2D(baseSampler, outTexCoords);\n"
259257
};
260-
const char* gFS_Main_FetchA8Texture[2] = {
258+
const char* gFS_Main_FetchA8Texture[4] = {
261259
// Don't modulate
262-
" fragColor = texture2D(sampler, outTexCoords);\n",
260+
" fragColor = texture2D(baseSampler, outTexCoords);\n",
261+
" fragColor = texture2D(baseSampler, outTexCoords);\n",
263262
// Modulate
264-
" fragColor = color * texture2D(sampler, outTexCoords).a;\n"
263+
" fragColor = color * texture2D(baseSampler, outTexCoords).a;\n",
264+
" fragColor = color * pow(texture2D(baseSampler, outTexCoords).a, gamma);\n"
265265
};
266266
const char* gFS_Main_FetchGradient[6] = {
267267
// Linear
@@ -289,29 +289,38 @@ const char* gFS_Main_BlendShadersBG =
289289
" fragColor = blendShaders(gradientColor, bitmapColor)";
290290
const char* gFS_Main_BlendShadersGB =
291291
" fragColor = blendShaders(bitmapColor, gradientColor)";
292-
const char* gFS_Main_BlendShaders_Modulate[3] = {
292+
const char* gFS_Main_BlendShaders_Modulate[6] = {
293293
// Don't modulate
294294
";\n",
295+
";\n",
295296
// Modulate
296297
" * fragColor.a;\n",
298+
" * fragColor.a;\n",
297299
// Modulate with alpha 8 texture
298-
" * texture2D(sampler, outTexCoords).a;\n"
300+
" * texture2D(baseSampler, outTexCoords).a;\n",
301+
" * pow(texture2D(baseSampler, outTexCoords).a, gamma);\n"
299302
};
300-
const char* gFS_Main_GradientShader_Modulate[3] = {
303+
const char* gFS_Main_GradientShader_Modulate[6] = {
301304
// Don't modulate
302305
" fragColor = gradientColor;\n",
306+
" fragColor = gradientColor;\n",
303307
// Modulate
304308
" fragColor = gradientColor * fragColor.a;\n",
309+
" fragColor = gradientColor * fragColor.a;\n",
305310
// Modulate with alpha 8 texture
306-
" fragColor = gradientColor * texture2D(sampler, outTexCoords).a;\n"
311+
" fragColor = gradientColor * texture2D(baseSampler, outTexCoords).a;\n",
312+
" fragColor = gradientColor * pow(texture2D(baseSampler, outTexCoords).a, gamma);\n"
307313
};
308-
const char* gFS_Main_BitmapShader_Modulate[3] = {
314+
const char* gFS_Main_BitmapShader_Modulate[6] = {
309315
// Don't modulate
310316
" fragColor = bitmapColor;\n",
317+
" fragColor = bitmapColor;\n",
311318
// Modulate
312319
" fragColor = bitmapColor * fragColor.a;\n",
320+
" fragColor = bitmapColor * fragColor.a;\n",
313321
// Modulate with alpha 8 texture
314-
" fragColor = bitmapColor * texture2D(sampler, outTexCoords).a;\n"
322+
" fragColor = bitmapColor * texture2D(baseSampler, outTexCoords).a;\n",
323+
" fragColor = bitmapColor * pow(texture2D(baseSampler, outTexCoords).a, gamma);\n"
315324
};
316325
const char* gFS_Main_FragColor =
317326
" gl_FragColor = fragColor;\n";
@@ -518,6 +527,14 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
518527
return shader;
519528
}
520529

530+
static bool shaderOp(const ProgramDescription& description, String8& shader,
531+
const int modulateOp, const char** snippets) {
532+
int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
533+
op = op * 2 + description.hasGammaCorrection;
534+
shader.append(snippets[op]);
535+
return description.hasAlpha8Texture;
536+
}
537+
521538
String8 ProgramCache::generateFragmentShader(const ProgramDescription& description) {
522539
String8 shader;
523540

@@ -661,13 +678,14 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
661678
if (description.hasTexture || description.hasExternalTexture) {
662679
if (description.hasAlpha8Texture) {
663680
if (!description.hasGradient && !description.hasBitmap) {
664-
shader.append(gFS_Main_FetchA8Texture[modulateOp]);
681+
shader.append(gFS_Main_FetchA8Texture[modulateOp * 2 +
682+
description.hasGammaCorrection]);
665683
}
666684
} else {
667685
shader.append(gFS_Main_FetchTexture[modulateOp]);
668686
}
669687
} else {
670-
if ((!description.hasGradient && !description.hasBitmap) || description.modulate) {
688+
if (!description.hasGradient && !description.hasBitmap) {
671689
shader.append(gFS_Main_FetchColor);
672690
}
673691
}
@@ -688,32 +706,27 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
688706
bool applyModulate = false;
689707
// Case when we have two shaders set
690708
if (description.hasGradient && description.hasBitmap) {
691-
int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
692709
if (description.isBitmapFirst) {
693710
shader.append(gFS_Main_BlendShadersBG);
694711
} else {
695712
shader.append(gFS_Main_BlendShadersGB);
696713
}
697-
shader.append(gFS_Main_BlendShaders_Modulate[op]);
698-
applyModulate = true;
714+
applyModulate = shaderOp(description, shader, modulateOp,
715+
gFS_Main_BlendShaders_Modulate);
699716
} else {
700717
if (description.hasGradient) {
701-
int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
702-
shader.append(gFS_Main_GradientShader_Modulate[op]);
703-
applyModulate = true;
718+
applyModulate = shaderOp(description, shader, modulateOp,
719+
gFS_Main_GradientShader_Modulate);
704720
} else if (description.hasBitmap) {
705-
int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
706-
shader.append(gFS_Main_BitmapShader_Modulate[op]);
707-
applyModulate = true;
721+
applyModulate = shaderOp(description, shader, modulateOp,
722+
gFS_Main_BitmapShader_Modulate);
708723
}
709724
}
725+
710726
if (description.modulate && applyModulate) {
711-
if (description.hasGammaCorrection) {
712-
shader.append(gFS_Main_ModulateColor_ApplyGamma);
713-
} else {
714-
shader.append(gFS_Main_ModulateColor);
715-
}
727+
shader.append(gFS_Main_ModulateColor);
716728
}
729+
717730
// Apply the color op if needed
718731
shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
719732

0 commit comments

Comments
 (0)