summaryrefslogtreecommitdiff
path: root/libs/hwui/ProgramCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/ProgramCache.cpp')
-rw-r--r--libs/hwui/ProgramCache.cpp174
1 files changed, 41 insertions, 133 deletions
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 42ef76296006..00de9924ace1 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -161,9 +161,35 @@ const char* gFS_Uniforms_HasRoundRectClip =
"uniform vec4 roundRectInnerRectLTRB;\n"
"uniform float roundRectRadius;\n";
+const char* gFS_OETF[2] = {
+ "\nvec4 OETF(const vec4 linear) {\n"
+ " return linear;\n"
+ "}\n",
+ // We expect linear data to be scRGB so we mirror the gamma function
+ "\nvec4 OETF(const vec4 linear) {"
+ " return vec4(sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)), linear.a);\n"
+ "}\n",
+};
+
+const char* gFS_Transfer_Functions = R"__SHADER__(
+ float OETF_sRGB(const float linear) {
+ // IEC 61966-2-1:1999
+ return linear <= 0.0031308 ? linear * 12.92 : (pow(linear, 1.0 / 2.4) * 1.055) - 0.055;
+ }
+
+ vec3 OETF_sRGB(const vec3 linear) {
+ return vec3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b));
+ }
+
+ float EOTF_sRGB(float srgb) {
+ // IEC 61966-2-1:1999
+ return srgb <= 0.04045 ? srgb / 12.92 : pow((srgb + 0.055) / 1.055, 2.4);
+ }
+)__SHADER__";
+
// Dithering must be done in the quantization space
// When we are writing to an sRGB framebuffer, we must do the following:
-// EOCF(OECF(color) + dither)
+// EOTF(OETF(color) + dither)
// The dithering pattern is generated with a triangle noise generator in the range [-0.0,1.0]
// TODO: Handle linear fp16 render targets
const char* gFS_Gradient_Functions = R"__SHADER__(
@@ -173,20 +199,6 @@ const char* gFS_Gradient_Functions = R"__SHADER__(
highp float xy = p.x * p.y;
return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
}
-
- float OECF_sRGB(const float linear) {
- // IEC 61966-2-1:1999
- return linear <= 0.0031308 ? linear * 12.92 : (pow(linear, 1.0 / 2.4) * 1.055) - 0.055;
- }
-
- vec3 OECF_sRGB(const vec3 linear) {
- return vec3(OECF_sRGB(linear.r), OECF_sRGB(linear.g), OECF_sRGB(linear.b));
- }
-
- float EOCF_sRGB(float srgb) {
- // IEC 61966-2-1:1999
- return srgb <= 0.04045 ? srgb / 12.92 : pow((srgb + 0.055) / 1.055, 2.4);
- }
)__SHADER__";
const char* gFS_Gradient_Preamble[2] = {
// Linear framebuffer
@@ -195,8 +207,8 @@ const char* gFS_Gradient_Preamble[2] = {
"}\n"
"\nvec4 gammaMix(const vec4 a, const vec4 b, float v) {\n"
" vec4 c = mix(a, b, v);\n"
- " c.a = EOCF_sRGB(c.a);\n" // This is technically incorrect but preserves compatibility
- " return vec4(OECF_sRGB(c.rgb) * c.a, c.a);\n"
+ " c.a = EOTF_sRGB(c.a);\n" // This is technically incorrect but preserves compatibility
+ " return vec4(OETF_sRGB(c.rgb) * c.a, c.a);\n"
"}\n",
// sRGB framebuffer
"\nvec4 dither(const vec4 color) {\n"
@@ -232,52 +244,6 @@ const char* gFS_Main =
const char* gFS_Main_AddDither =
" fragColor = dither(fragColor);\n";
-// Fast cases
-const char* gFS_Fast_SingleColor =
- "\nvoid main(void) {\n"
- " gl_FragColor = color;\n"
- "}\n\n";
-const char* gFS_Fast_SingleTexture =
- "\nvoid main(void) {\n"
- " gl_FragColor = texture2D(baseSampler, outTexCoords);\n"
- "}\n\n";
-const char* gFS_Fast_SingleModulateTexture =
- "\nvoid main(void) {\n"
- " gl_FragColor = color.a * texture2D(baseSampler, outTexCoords);\n"
- "}\n\n";
-const char* gFS_Fast_SingleA8Texture =
- "\nvoid main(void) {\n"
- " gl_FragColor = texture2D(baseSampler, outTexCoords);\n"
- "}\n\n";
-const char* gFS_Fast_SingleA8Texture_ApplyGamma =
- "\nvoid main(void) {\n"
- " gl_FragColor = vec4(0.0, 0.0, 0.0, pow(texture2D(baseSampler, outTexCoords).a, GAMMA));\n"
- "}\n\n";
-const char* gFS_Fast_SingleModulateA8Texture =
- "\nvoid main(void) {\n"
- " gl_FragColor = color * texture2D(baseSampler, outTexCoords).a;\n"
- "}\n\n";
-const char* gFS_Fast_SingleModulateA8Texture_ApplyGamma =
- "\nvoid main(void) {\n"
- " gl_FragColor = color * gamma(texture2D(baseSampler, outTexCoords).a, color.rgb);\n"
- "}\n\n";
-const char* gFS_Fast_SingleGradient[2] = {
- "\nvoid main(void) {\n"
- " gl_FragColor = dither(texture2D(gradientSampler, linear));\n"
- "}\n\n",
- "\nvoid main(void) {\n"
- " gl_FragColor = dither(gammaMix(startColor, endColor, clamp(linear, 0.0, 1.0)));\n"
- "}\n\n",
-};
-const char* gFS_Fast_SingleModulateGradient[2] = {
- "\nvoid main(void) {\n"
- " gl_FragColor = dither(color.a * texture2D(gradientSampler, linear));\n"
- "}\n\n",
- "\nvoid main(void) {\n"
- " gl_FragColor = dither(color.a * gammaMix(startColor, endColor, clamp(linear, 0.0, 1.0)));\n"
- "}\n\n"
-};
-
// General case
const char* gFS_Main_FetchColor =
" fragColor = color;\n";
@@ -290,7 +256,7 @@ const char* gFS_Main_ApplyVertexAlphaShadowInterp =
" fragColor *= texture2D(baseSampler, vec2(alpha, 0.5)).a;\n";
const char* gFS_Main_FetchTexture[2] = {
// Don't modulate
- " fragColor = texture2D(baseSampler, outTexCoords);\n",
+ " fragColor = OETF(texture2D(baseSampler, outTexCoords));\n",
// Modulate
" fragColor = color * texture2D(baseSampler, outTexCoords);\n"
};
@@ -321,9 +287,9 @@ const char* gFS_Main_FetchGradient[6] = {
" vec4 gradientColor = gammaMix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
};
const char* gFS_Main_FetchBitmap =
- " vec4 bitmapColor = texture2D(bitmapSampler, outBitmapTexCoords);\n";
+ " vec4 bitmapColor = OETF(texture2D(bitmapSampler, outBitmapTexCoords));\n";
const char* gFS_Main_FetchBitmapNpot =
- " vec4 bitmapColor = texture2D(bitmapSampler, wrap(outBitmapTexCoords));\n";
+ " vec4 bitmapColor = OETF(texture2D(bitmapSampler, wrap(outBitmapTexCoords)));\n";
const char* gFS_Main_BlendShadersBG =
" fragColor = blendShaders(gradientColor, bitmapColor)";
const char* gFS_Main_BlendShadersGB =
@@ -649,71 +615,6 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.appendFormat(gFS_Gamma_Preamble, Properties::textGamma, 1.0f / Properties::textGamma);
}
- // Optimization for common cases
- if (!description.hasVertexAlpha
- && !blendFramebuffer
- && !description.hasColors
- && description.colorOp == ProgramDescription::ColorFilterMode::None
- && !description.hasDebugHighlight
- && !description.hasRoundRectClip) {
- bool fast = false;
-
- const bool noShader = !description.hasGradient && !description.hasBitmap;
- const bool singleTexture = (description.hasTexture || description.hasExternalTexture) &&
- !description.hasAlpha8Texture && noShader;
- const bool singleA8Texture = description.hasTexture &&
- description.hasAlpha8Texture && noShader;
- const bool singleGradient = !description.hasTexture && !description.hasExternalTexture &&
- description.hasGradient && !description.hasBitmap &&
- description.gradientType == ProgramDescription::kGradientLinear;
-
- if (singleColor) {
- shader.append(gFS_Fast_SingleColor);
- fast = true;
- } else if (singleTexture) {
- if (!description.modulate) {
- shader.append(gFS_Fast_SingleTexture);
- } else {
- shader.append(gFS_Fast_SingleModulateTexture);
- }
- fast = true;
- } else if (singleA8Texture) {
- if (!description.modulate) {
- if (description.hasGammaCorrection) {
- shader.append(gFS_Fast_SingleA8Texture_ApplyGamma);
- } else {
- shader.append(gFS_Fast_SingleA8Texture);
- }
- } else {
- if (description.hasGammaCorrection) {
- shader.append(gFS_Fast_SingleModulateA8Texture_ApplyGamma);
- } else {
- shader.append(gFS_Fast_SingleModulateA8Texture);
- }
- }
- fast = true;
- } else if (singleGradient) {
- shader.append(gFS_Gradient_Functions);
- shader.append(gFS_Gradient_Preamble[mHasSRGB]);
- if (!description.modulate) {
- shader.append(gFS_Fast_SingleGradient[description.isSimpleGradient]);
- } else {
- shader.append(gFS_Fast_SingleModulateGradient[description.isSimpleGradient]);
- }
- fast = true;
- }
-
- if (fast) {
-#if DEBUG_PROGRAMS
- PROGRAM_LOGD("*** Fast case:\n");
- PROGRAM_LOGD("*** Generated fragment shader:\n\n");
- printLongString(shader);
-#endif
-
- return shader;
- }
- }
-
if (description.hasBitmap) {
if (description.isShaderBitmapExternal) {
shader.append(gFS_Uniforms_BitmapExternalSampler);
@@ -736,6 +637,13 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
if (description.useShaderBasedWrap) {
generateTextureWrap(shader, description.bitmapWrapS, description.bitmapWrapT);
}
+ if (description.hasGradient || description.hasLinearTexture) {
+ shader.append(gFS_Transfer_Functions);
+ }
+ if (description.hasBitmap || ((description.hasTexture || description.hasExternalTexture) &&
+ !description.hasAlpha8Texture)) {
+ shader.append(gFS_OETF[description.hasLinearTexture && !mHasSRGB]);
+ }
if (description.hasGradient) {
shader.append(gFS_Gradient_Functions);
shader.append(gFS_Gradient_Preamble[mHasSRGB]);
@@ -827,10 +735,10 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
// End the shader
shader.append(gFS_Footer);
-#if DEBUG_PROGRAMS
+//#if DEBUG_PROGRAMS
PROGRAM_LOGD("*** Generated fragment shader:\n\n");
printLongString(shader);
-#endif
+//#endif
return shader;
}