summaryrefslogtreecommitdiffstats
path: root/libs/hwui/ProgramCache.cpp
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2012-07-30 14:47:51 -0700
committerRomain Guy <romainguy@google.com>2012-07-31 18:55:16 -0700
commit42e1e0d482d774cf18a55773e434f02edb9e4462 (patch)
tree33ac1bca20382f2e8ccbf176c89b3476f2ae5c9b /libs/hwui/ProgramCache.cpp
parent8ab8fbbf46d8779f53301e7f706f97608eed7117 (diff)
downloadframeworks_base-42e1e0d482d774cf18a55773e434f02edb9e4462.zip
frameworks_base-42e1e0d482d774cf18a55773e434f02edb9e4462.tar.gz
frameworks_base-42e1e0d482d774cf18a55773e434f02edb9e4462.tar.bz2
Improve gradients
Avoid using textures for common gradients (two stops from 0.0 to 1.0) Change-Id: Iff55d21b126c8cfc4cfb701669f2339c8f6b131a
Diffstat (limited to 'libs/hwui/ProgramCache.cpp')
-rw-r--r--libs/hwui/ProgramCache.cpp72
1 files changed, 49 insertions, 23 deletions
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 70bd1a8..d601f01 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -71,13 +71,16 @@ const char* gVS_Header_Varyings_PointHasBitmap =
"varying highp vec2 outPointBitmapTexCoords;\n";
// TODO: These values are used to sample from textures,
// they may need to be highp
-const char* gVS_Header_Varyings_HasGradient[3] = {
+const char* gVS_Header_Varyings_HasGradient[6] = {
// Linear
"varying highp vec2 linear;\n",
+ "varying highp float linear;\n",
// Circular
"varying highp vec2 circular;\n",
+ "varying highp vec2 circular;\n",
// Sweep
- "varying highp vec2 sweep;\n"
+ "varying highp vec2 sweep;\n",
+ "varying highp vec2 sweep;\n",
};
const char* gVS_Main =
"\nvoid main(void) {\n";
@@ -85,13 +88,16 @@ const char* gVS_Main_OutTexCoords =
" outTexCoords = texCoords;\n";
const char* gVS_Main_OutTransformedTexCoords =
" outTexCoords = (mainTextureTransform * vec4(texCoords, 0.0, 1.0)).xy;\n";
-const char* gVS_Main_OutGradient[3] = {
+const char* gVS_Main_OutGradient[6] = {
// Linear
" linear = vec2((screenSpace * position).x, 0.5);\n",
+ " linear = (screenSpace * position).x;\n",
// Circular
" circular = (screenSpace * position).xy;\n",
+ " circular = (screenSpace * position).xy;\n",
// Sweep
- " sweep = (screenSpace * position).xy;\n"
+ " sweep = (screenSpace * position).xy;\n",
+ " sweep = (screenSpace * position).xy;\n",
};
const char* gVS_Main_OutBitmapTexCoords =
" outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
@@ -131,13 +137,19 @@ const char* gFS_Uniforms_TextureSampler =
"uniform sampler2D sampler;\n";
const char* gFS_Uniforms_ExternalTextureSampler =
"uniform samplerExternalOES sampler;\n";
-const char* gFS_Uniforms_GradientSampler[3] = {
+const char* gFS_Uniforms_GradientSampler[6] = {
// Linear
"uniform sampler2D gradientSampler;\n",
+ "uniform vec4 startColor;\n"
+ "uniform vec4 endColor;\n",
// Circular
"uniform sampler2D gradientSampler;\n",
+ "uniform vec4 startColor;\n"
+ "uniform vec4 endColor;\n",
// Sweep
- "uniform sampler2D gradientSampler;\n"
+ "uniform sampler2D gradientSampler;\n",
+ "uniform vec4 startColor;\n"
+ "uniform vec4 endColor;\n",
};
const char* gFS_Uniforms_BitmapSampler =
"uniform sampler2D bitmapSampler;\n";
@@ -193,14 +205,22 @@ const char* gFS_Fast_SingleModulateA8Texture_ApplyGamma =
"\nvoid main(void) {\n"
" gl_FragColor = color * pow(texture2D(sampler, outTexCoords).a, gamma);\n"
"}\n\n";
-const char* gFS_Fast_SingleGradient =
+const char* gFS_Fast_SingleGradient[2] = {
"\nvoid main(void) {\n"
" gl_FragColor = texture2D(gradientSampler, linear);\n"
- "}\n\n";
-const char* gFS_Fast_SingleModulateGradient =
+ "}\n\n",
+ "\nvoid main(void) {\n"
+ " gl_FragColor = mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n"
+ "}\n\n"
+};
+const char* gFS_Fast_SingleModulateGradient[2] = {
"\nvoid main(void) {\n"
" gl_FragColor = color.a * texture2D(gradientSampler, linear);\n"
- "}\n\n";
+ "}\n\n",
+ "\nvoid main(void) {\n"
+ " gl_FragColor = color.a * mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n"
+ "}\n\n"
+};
// General case
const char* gFS_Main_FetchColor =
@@ -232,15 +252,18 @@ const char* gFS_Main_FetchA8Texture[2] = {
// Modulate
" fragColor = color * texture2D(sampler, outTexCoords).a;\n"
};
-const char* gFS_Main_FetchGradient[3] = {
+const char* gFS_Main_FetchGradient[6] = {
// Linear
" vec4 gradientColor = texture2D(gradientSampler, linear);\n",
+ " vec4 gradientColor = mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n",
// Circular
- " highp float index = length(circular);\n"
- " vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n",
+ " vec4 gradientColor = texture2D(gradientSampler, vec2(length(circular), 0.5));\n",
+ " vec4 gradientColor = mix(startColor, endColor, clamp(length(circular), 0.0, 1.0));\n",
// Sweep
" highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
- " vec4 gradientColor = texture2D(gradientSampler, vec2(index - floor(index), 0.5));\n"
+ " vec4 gradientColor = texture2D(gradientSampler, vec2(index - floor(index), 0.5));\n",
+ " highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
+ " vec4 gradientColor = mix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
};
const char* gFS_Main_FetchBitmap =
" vec4 bitmapColor = texture2D(bitmapSampler, outBitmapTexCoords);\n";
@@ -395,8 +418,11 @@ Program* ProgramCache::generateProgram(const ProgramDescription& description, pr
String8 vertexShader = generateVertexShader(description);
String8 fragmentShader = generateFragmentShader(description);
- Program* program = new Program(description, vertexShader.string(), fragmentShader.string());
- return program;
+ return new Program(description, vertexShader.string(), fragmentShader.string());
+}
+
+static inline size_t gradientIndex(const ProgramDescription& description) {
+ return description.gradientType * 2 + description.isSimpleGradient;
}
String8 ProgramCache::generateVertexShader(const ProgramDescription& description) {
@@ -430,7 +456,7 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Header_Varyings_IsAA);
}
if (description.hasGradient) {
- shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
+ shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
}
if (description.hasBitmap) {
shader.append(description.isPoint ?
@@ -449,7 +475,7 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Main_AA);
}
if (description.hasGradient) {
- shader.append(gVS_Main_OutGradient[description.gradientType]);
+ shader.append(gVS_Main_OutGradient[gradientIndex(description)]);
}
if (description.hasBitmap) {
shader.append(description.isPoint ?
@@ -491,7 +517,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gVS_Header_Varyings_IsAA);
}
if (description.hasGradient) {
- shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
+ shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
}
if (description.hasBitmap) {
shader.append(description.isPoint ?
@@ -517,7 +543,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gFS_Uniforms_AA);
}
if (description.hasGradient) {
- shader.append(gFS_Uniforms_GradientSampler[description.gradientType]);
+ shader.append(gFS_Uniforms_GradientSampler[gradientIndex(description)]);
}
if (description.hasBitmap && description.isPoint) {
shader.append(gFS_Header_Uniforms_PointHasBitmap);
@@ -567,9 +593,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
fast = true;
} else if (singleGradient) {
if (!description.modulate) {
- shader.append(gFS_Fast_SingleGradient);
+ shader.append(gFS_Fast_SingleGradient[description.isSimpleGradient]);
} else {
- shader.append(gFS_Fast_SingleModulateGradient);
+ shader.append(gFS_Fast_SingleModulateGradient[description.isSimpleGradient]);
}
fast = true;
}
@@ -624,7 +650,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gFS_Main_AccountForAA);
}
if (description.hasGradient) {
- shader.append(gFS_Main_FetchGradient[description.gradientType]);
+ shader.append(gFS_Main_FetchGradient[gradientIndex(description)]);
}
if (description.hasBitmap) {
if (description.isPoint) {