summaryrefslogtreecommitdiffstats
path: root/libs/hwui/ProgramCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/ProgramCache.cpp')
-rw-r--r--libs/hwui/ProgramCache.cpp87
1 files changed, 82 insertions, 5 deletions
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 0b6c7b5..80b1917 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -39,8 +39,12 @@ const char* gVS_Header_Attributes =
"attribute vec4 position;\n";
const char* gVS_Header_Attributes_TexCoords =
"attribute vec2 texCoords;\n";
+const char* gVS_Header_Attributes_Distance =
+ "attribute float vtxDistance;\n";
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",
@@ -51,11 +55,15 @@ const char* gVS_Header_Uniforms_HasGradient[3] = {
};
const char* gVS_Header_Uniforms_HasBitmap =
"uniform mat4 textureTransform;\n"
- "uniform vec2 textureDimension;\n";
+ "uniform mediump vec2 textureDimension;\n";
const char* gVS_Header_Varyings_HasTexture =
"varying vec2 outTexCoords;\n";
+const char* gVS_Header_Varyings_HasWidth =
+ "varying float distance;\n";
const char* gVS_Header_Varyings_HasBitmap =
"varying vec2 outBitmapTexCoords;\n";
+const char* gVS_Header_Varyings_PointHasBitmap =
+ "varying vec2 outPointBitmapTexCoords;\n";
const char* gVS_Header_Varyings_HasGradient[3] = {
// Linear
"varying vec2 linear;\n",
@@ -78,8 +86,14 @@ const char* gVS_Main_OutGradient[3] = {
};
const char* gVS_Main_OutBitmapTexCoords =
" outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
+const char* gVS_Main_OutPointBitmapTexCoords =
+ " outPointBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
const char* gVS_Main_Position =
" gl_Position = transform * position;\n";
+const char* gVS_Main_PointSize =
+ " gl_PointSize = pointSize;\n";
+const char* gVS_Main_Width =
+ " distance = vtxDistance;\n";
const char* gVS_Footer =
"}\n\n";
@@ -93,6 +107,13 @@ const char* gFS_Header =
"precision mediump float;\n\n";
const char* gFS_Uniforms_Color =
"uniform vec4 color;\n";
+const char* gFS_Uniforms_Width =
+ "uniform float width;\n"
+ "uniform float boundaryWidth;\n"
+ "uniform float inverseBoundaryWidth;\n";
+const char* gFS_Header_Uniforms_PointHasBitmap =
+ "uniform vec2 textureDimension;\n"
+ "uniform float pointSize;\n";
const char* gFS_Uniforms_TextureSampler =
"uniform sampler2D sampler;\n";
const char* gFS_Uniforms_GradientSampler[3] = {
@@ -121,6 +142,10 @@ const char* gFS_Main =
"\nvoid main(void) {\n"
" lowp vec4 fragColor;\n";
+const char* gFS_Main_PointBitmapTexCoords =
+ " vec2 outBitmapTexCoords = outPointBitmapTexCoords + "
+ "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n";
+
// Fast cases
const char* gFS_Fast_SingleColor =
"\nvoid main(void) {\n"
@@ -154,6 +179,14 @@ const char* gFS_Fast_SingleModulateGradient =
// General case
const char* gFS_Main_FetchColor =
" fragColor = color;\n";
+const char* gFS_Main_ModulateColor =
+ " fragColor *= color.a;\n";
+const char* gFS_Main_AccountForWidth =
+ " if (distance < boundaryWidth) {\n"
+ " fragColor *= (distance * inverseBoundaryWidth);\n"
+ " } else if (distance > (1.0 - boundaryWidth)) {\n"
+ " fragColor *= ((1.0 - distance) * inverseBoundaryWidth);\n"
+ " }\n";
const char* gFS_Main_FetchTexture[2] = {
// Don't modulate
" fragColor = texture2D(sampler, outTexCoords);\n",
@@ -339,6 +372,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.hasTexture) {
shader.append(gVS_Header_Attributes_TexCoords);
}
+ if (description.hasWidth) {
+ shader.append(gVS_Header_Attributes_Distance);
+ }
// Uniforms
shader.append(gVS_Header_Uniforms);
if (description.hasGradient) {
@@ -347,15 +383,23 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.hasBitmap) {
shader.append(gVS_Header_Uniforms_HasBitmap);
}
+ if (description.isPoint) {
+ shader.append(gVS_Header_Uniforms_IsPoint);
+ }
// Varyings
if (description.hasTexture) {
shader.append(gVS_Header_Varyings_HasTexture);
}
+ if (description.hasWidth) {
+ shader.append(gVS_Header_Varyings_HasWidth);
+ }
if (description.hasGradient) {
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Header_Varyings_HasBitmap);
+ shader.append(description.isPoint ?
+ gVS_Header_Varyings_PointHasBitmap :
+ gVS_Header_Varyings_HasBitmap);
}
// Begin the shader
@@ -363,11 +407,19 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.hasTexture) {
shader.append(gVS_Main_OutTexCoords);
}
+ if (description.hasWidth) {
+ shader.append(gVS_Main_Width);
+ }
if (description.hasGradient) {
shader.append(gVS_Main_OutGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Main_OutBitmapTexCoords);
+ shader.append(description.isPoint ?
+ gVS_Main_OutPointBitmapTexCoords :
+ gVS_Main_OutBitmapTexCoords);
+ }
+ if (description.isPoint) {
+ shader.append(gVS_Main_PointSize);
}
// Output transformed position
shader.append(gVS_Main_Position);
@@ -395,11 +447,16 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
if (description.hasTexture) {
shader.append(gVS_Header_Varyings_HasTexture);
}
+ if (description.hasWidth) {
+ shader.append(gVS_Header_Varyings_HasWidth);
+ }
if (description.hasGradient) {
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Header_Varyings_HasBitmap);
+ shader.append(description.isPoint ?
+ gVS_Header_Varyings_PointHasBitmap :
+ gVS_Header_Varyings_HasBitmap);
}
// Uniforms
@@ -414,12 +471,19 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
if (description.hasTexture) {
shader.append(gFS_Uniforms_TextureSampler);
}
+ if (description.hasWidth) {
+ shader.append(gFS_Uniforms_Width);
+ }
if (description.hasGradient) {
shader.append(gFS_Uniforms_GradientSampler[description.gradientType]);
}
+ if (description.hasBitmap && description.isPoint) {
+ shader.append(gFS_Header_Uniforms_PointHasBitmap);
+ }
// Optimization for common cases
- if (!blendFramebuffer && description.colorOp == ProgramDescription::kColorNone) {
+ if (!description.hasWidth && !blendFramebuffer &&
+ description.colorOp == ProgramDescription::kColorNone && !description.isPoint) {
bool fast = false;
const bool noShader = !description.hasGradient && !description.hasBitmap;
@@ -503,16 +567,23 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gFS_Main_FetchColor);
}
}
+ if (description.hasWidth) {
+ shader.append(gFS_Main_AccountForWidth);
+ }
if (description.hasGradient) {
shader.append(gFS_Main_FetchGradient[description.gradientType]);
}
if (description.hasBitmap) {
+ if (description.isPoint) {
+ shader.append(gFS_Main_PointBitmapTexCoords);
+ }
if (!description.isBitmapNpot) {
shader.append(gFS_Main_FetchBitmap);
} else {
shader.append(gFS_Main_FetchBitmapNpot);
}
}
+ bool applyModulate = false;
// Case when we have two shaders set
if (description.hasGradient && description.hasBitmap) {
int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
@@ -522,15 +593,21 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gFS_Main_BlendShadersGB);
}
shader.append(gFS_Main_BlendShaders_Modulate[op]);
+ applyModulate = true;
} else {
if (description.hasGradient) {
int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
shader.append(gFS_Main_GradientShader_Modulate[op]);
+ applyModulate = true;
} else if (description.hasBitmap) {
int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
shader.append(gFS_Main_BitmapShader_Modulate[op]);
+ applyModulate = true;
}
}
+ if (description.modulate && applyModulate) {
+ shader.append(gFS_Main_ModulateColor);
+ }
// Apply the color op if needed
shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
// Output the fragment