summaryrefslogtreecommitdiff
path: root/libs/hwui/ProgramCache.cpp
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-04-05 11:17:55 -0700
committerRomain Guy <romainguy@google.com>2013-04-05 14:17:17 -0700
commitb48800428906ae455c2b63acacd44e390e1fee49 (patch)
treebc0de8c6f51eb5c9cac2d5fe1d5a41fede6d727a /libs/hwui/ProgramCache.cpp
parent80fdc9624e6d53a78031bf99d34e7c01d53ad66e (diff)
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
Diffstat (limited to 'libs/hwui/ProgramCache.cpp')
-rw-r--r--libs/hwui/ProgramCache.cpp88
1 files changed, 40 insertions, 48 deletions
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 <utils/String8.h>
#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) {