From b48800428906ae455c2b63acacd44e390e1fee49 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Fri, 5 Apr 2013 11:17:55 -0700 Subject: Use float textures to render gradients when possible Float textures offer better precision for dithering. In addition this change removes two uniforms from gradient shaders. These uniforms were used to dither gradients but their value is a build time constant. Instead we hardcode the value directly in the shader source at compile time. Change-Id: I05e9fd3eef93771843bbd91b453274452dfaefee --- libs/hwui/ProgramCache.cpp | 88 +++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 48 deletions(-) (limited to 'libs/hwui/ProgramCache.cpp') diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index f78fb2d65415..2479630daea5 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -19,6 +19,7 @@ #include #include "Caches.h" +#include "Dither.h" #include "ProgramCache.h" namespace android { @@ -32,6 +33,9 @@ namespace uirenderer { #define MODULATE_OP_MODULATE 1 #define MODULATE_OP_MODULATE_A8 2 +#define STR(x) STR1(x) +#define STR1(x) #x + /////////////////////////////////////////////////////////////////////////////// // Vertex shaders snippets /////////////////////////////////////////////////////////////////////////////// @@ -51,17 +55,8 @@ const char* gVS_Header_Uniforms = "uniform mat4 transform;\n"; const char* gVS_Header_Uniforms_IsPoint = "uniform mediump float pointSize;\n"; -const char* gVS_Header_Uniforms_HasGradient[3] = { - // Linear - "uniform mat4 screenSpace;\n" - "uniform float ditherSize;\n", - // Circular - "uniform mat4 screenSpace;\n" - "uniform float ditherSize;\n", - // Sweep - "uniform mat4 screenSpace;\n" - "uniform float ditherSize;\n" -}; +const char* gVS_Header_Uniforms_HasGradient = + "uniform mat4 screenSpace;\n"; const char* gVS_Header_Uniforms_HasBitmap = "uniform mat4 textureTransform;\n" "uniform mediump vec2 textureDimension;\n"; @@ -105,21 +100,21 @@ const char* gVS_Main_OutTransformedTexCoords = const char* gVS_Main_OutGradient[6] = { // Linear " linear = vec2((screenSpace * position).x, 0.5);\n" - " ditherTexCoords = (transform * position).xy * ditherSize;\n", + " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n", " linear = (screenSpace * position).x;\n" - " ditherTexCoords = (transform * position).xy * ditherSize;\n", + " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n", // Circular " circular = (screenSpace * position).xy;\n" - " ditherTexCoords = (transform * position).xy * ditherSize;\n", + " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n", " circular = (screenSpace * position).xy;\n" - " ditherTexCoords = (transform * position).xy * ditherSize;\n", + " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n", // Sweep " sweep = (screenSpace * position).xy;\n" - " ditherTexCoords = (transform * position).xy * ditherSize;\n", + " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n", " sweep = (screenSpace * position).xy;\n" - " ditherTexCoords = (transform * position).xy * ditherSize;\n", + " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n", }; const char* gVS_Main_OutBitmapTexCoords = " outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n"; @@ -153,24 +148,14 @@ const char* gFS_Uniforms_TextureSampler = "uniform sampler2D baseSampler;\n"; const char* gFS_Uniforms_ExternalTextureSampler = "uniform samplerExternalOES baseSampler;\n"; -#define FS_UNIFORMS_DITHER \ - "uniform float ditherSizeSquared;\n" \ - "uniform sampler2D ditherSampler;\n" -#define FS_UNIFORMS_GRADIENT \ - "uniform vec4 startColor;\n" \ +const char* gFS_Uniforms_Dither = + "uniform sampler2D ditherSampler;"; +const char* gFS_Uniforms_GradientSampler[2] = { + "%s\n" + "uniform sampler2D gradientSampler;\n", + "%s\n" + "uniform vec4 startColor;\n" "uniform vec4 endColor;\n" -const char* gFS_Uniforms_GradientSampler[6] = { - // Linear - FS_UNIFORMS_DITHER "uniform sampler2D gradientSampler;\n", - FS_UNIFORMS_DITHER FS_UNIFORMS_GRADIENT, - - // Circular - FS_UNIFORMS_DITHER "uniform sampler2D gradientSampler;\n", - FS_UNIFORMS_DITHER FS_UNIFORMS_GRADIENT, - - // Sweep - FS_UNIFORMS_DITHER "uniform sampler2D gradientSampler;\n", - FS_UNIFORMS_DITHER FS_UNIFORMS_GRADIENT }; const char* gFS_Uniforms_BitmapSampler = "uniform sampler2D bitmapSampler;\n"; @@ -197,10 +182,14 @@ const char* gFS_Main_PointBitmapTexCoords = " highp vec2 outBitmapTexCoords = outPointBitmapTexCoords + " "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n"; -#define FS_MAIN_DITHER \ - "texture2D(ditherSampler, ditherTexCoords).a * ditherSizeSquared" +const char* gFS_Main_Dither[2] = { + // ES 2.0 + "texture2D(ditherSampler, ditherTexCoords).a * " STR(DITHER_KERNEL_SIZE_INV_SQUARE), + // ES 3.0 + "texture2D(ditherSampler, ditherTexCoords).r" +}; const char* gFS_Main_AddDitherToGradient = - " gradientColor += " FS_MAIN_DITHER ";\n"; + " gradientColor += %s;\n"; // Fast cases const char* gFS_Fast_SingleColor = @@ -233,18 +222,18 @@ const char* gFS_Fast_SingleModulateA8Texture_ApplyGamma = "}\n\n"; const char* gFS_Fast_SingleGradient[2] = { "\nvoid main(void) {\n" - " gl_FragColor = " FS_MAIN_DITHER " + texture2D(gradientSampler, linear);\n" + " gl_FragColor = %s + texture2D(gradientSampler, linear);\n" "}\n\n", "\nvoid main(void) {\n" - " gl_FragColor = " FS_MAIN_DITHER " + mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n" - "}\n\n" + " gl_FragColor = %s + mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n" + "}\n\n", }; const char* gFS_Fast_SingleModulateGradient[2] = { "\nvoid main(void) {\n" - " gl_FragColor = " FS_MAIN_DITHER " + color.a * texture2D(gradientSampler, linear);\n" + " gl_FragColor = %s + color.a * texture2D(gradientSampler, linear);\n" "}\n\n", "\nvoid main(void) {\n" - " gl_FragColor = " FS_MAIN_DITHER " + color.a * mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n" + " gl_FragColor = %s + color.a * mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n" "}\n\n" }; @@ -410,7 +399,7 @@ const char* gBlendOps[18] = { // Constructors/destructors /////////////////////////////////////////////////////////////////////////////// -ProgramCache::ProgramCache() { +ProgramCache::ProgramCache(): mHasES3(Extensions::getInstance().getMajorGlVersion() >= 3) { } ProgramCache::~ProgramCache() { @@ -484,7 +473,7 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description shader.append(gVS_Header_Uniforms_TextureTransform); } if (description.hasGradient) { - shader.append(gVS_Header_Uniforms_HasGradient[description.gradientType]); + shader.append(gVS_Header_Uniforms_HasGradient); } if (description.hasBitmap) { shader.append(gVS_Header_Uniforms_HasBitmap); @@ -601,7 +590,8 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti shader.append(gFS_Uniforms_ExternalTextureSampler); } if (description.hasGradient) { - shader.append(gFS_Uniforms_GradientSampler[gradientIndex(description)]); + shader.appendFormat(gFS_Uniforms_GradientSampler[description.isSimpleGradient], + gFS_Uniforms_Dither); } if (description.hasBitmap && description.isPoint) { shader.append(gFS_Header_Uniforms_PointHasBitmap); @@ -652,9 +642,11 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti fast = true; } else if (singleGradient) { if (!description.modulate) { - shader.append(gFS_Fast_SingleGradient[description.isSimpleGradient]); + shader.appendFormat(gFS_Fast_SingleGradient[description.isSimpleGradient], + gFS_Main_Dither[mHasES3]); } else { - shader.append(gFS_Fast_SingleModulateGradient[description.isSimpleGradient]); + shader.appendFormat(gFS_Fast_SingleModulateGradient[description.isSimpleGradient], + gFS_Main_Dither[mHasES3]); } fast = true; } @@ -708,7 +700,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti } if (description.hasGradient) { shader.append(gFS_Main_FetchGradient[gradientIndex(description)]); - shader.append(gFS_Main_AddDitherToGradient); + shader.appendFormat(gFS_Main_AddDitherToGradient, gFS_Main_Dither[mHasES3]); } if (description.hasBitmap) { if (description.isPoint) { -- cgit v1.2.3-59-g8ed1b