diff options
Diffstat (limited to 'libs/hwui/ProgramCache.cpp')
| -rw-r--r-- | libs/hwui/ProgramCache.cpp | 87 |
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 |
