aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-10 06:30:18 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-10 06:30:18 +0000
commit824c346b6e0e114063c1a8ad4ba7c3a669ee2cff (patch)
tree746fca51437b25e3a6e851a42ec40ec3d5ac6ee0 /src
parentab9d30cb01d0c8401537dc115aba2842b0f4f27f (diff)
Express (GLSL expression, possibly known value) pairs as a class
Express (GLSL expression, possibly known value) pairs as a class instead of two variables Introduces GrGLSLExpr<N> to encapsulate the expression and possibly constant-folded value of the expression. This simplifies passing of the expressions to functions. Changes the shaders with following patterns: { // Stage 0: Linear Gradient vec4 colorTemp = mix(uGradientStartColor_Stage0, uGradientEndColor_Stage0, clamp(vMatrixCoord_Stage0.x, 0.0, 1 colorTemp.rgb *= colorTemp.a; - output_Stage0 = vec4((vColor) * (colorTemp)); + output_Stage0 = (vColor * colorTemp); + } Previously the vector cast was always added if constant folding was effective, regardless of the term dimensions. Now the vector upcast is not inserted in places where it is not needed, ie. when the binary operator term is of the target dimension. Also, some parentheses can be omitted. It is assumed that GrGLSLExpr<N>("string") constructors construct a simple expression or parenthesized expression. Otherwise the shader code remains identical. R=jvanverth@google.com, bsalomon@google.com, robertphillips@google.com Author: kkinnunen@nvidia.com Review URL: https://codereview.chromium.org/25048002 git-svn-id: http://skia.googlecode.com/svn/trunk@11690 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/core/SkXfermode.cpp2
-rw-r--r--src/effects/SkArithmeticMode.cpp2
-rw-r--r--src/effects/SkBitmapAlphaThresholdShader.cpp8
-rw-r--r--src/effects/SkColorMatrixFilter.cpp2
-rw-r--r--src/effects/SkLumaColorFilter.cpp2
-rw-r--r--src/effects/SkLumaXfermode.cpp2
-rw-r--r--src/effects/gradients/SkGradientShader.cpp14
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp6
-rw-r--r--src/gpu/GrAARectRenderer.cpp12
-rw-r--r--src/gpu/GrOvalRenderer.cpp15
-rw-r--r--src/gpu/effects/GrBezierEffect.cpp16
-rw-r--r--src/gpu/gl/GrGLProgram.cpp131
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h11
-rw-r--r--src/gpu/gl/GrGLSL.cpp73
-rw-r--r--src/gpu/gl/GrGLSL.h309
-rw-r--r--src/gpu/gl/GrGLSL_impl.h284
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp50
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h43
18 files changed, 416 insertions, 566 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index 6f2fee6913..993c754711 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -944,7 +944,7 @@ public:
// We don't try to optimize for this case at all
if (NULL == inputColor) {
- builder->fsCodeAppendf("\t\tconst vec4 ones = %s;\n", GrGLSLOnesVecf(4));
+ builder->fsCodeAppendf("\t\tconst vec4 ones = vec4(1);\n");
inputColor = "ones";
}
builder->fsCodeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode));
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp
index d746ecbc31..fff03c291f 100644
--- a/src/effects/SkArithmeticMode.cpp
+++ b/src/effects/SkArithmeticMode.cpp
@@ -366,7 +366,7 @@ void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
// We don't try to optimize for this case at all
if (NULL == inputColor) {
- builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4));
+ builder->fsCodeAppendf("\t\tconst vec4 src = vec4(1);\n");
} else {
builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor);
if (gUseUnpremul) {
diff --git a/src/effects/SkBitmapAlphaThresholdShader.cpp b/src/effects/SkBitmapAlphaThresholdShader.cpp
index c8db3a56ca..69e22c9608 100644
--- a/src/effects/SkBitmapAlphaThresholdShader.cpp
+++ b/src/effects/SkBitmapAlphaThresholdShader.cpp
@@ -149,12 +149,8 @@ public:
"\t\t\tcolor.a = thresh;\n"
"\t\t}\n");
- builder->fsCodeAppend("color = ");
- SkString outStr;
- outStr.appendf("\t\t%s = ", outputColor);
- GrGLSLModulatef<4>(&outStr, inputColor, "color");
- outStr.append(";\n");
- builder->fsCodeAppend(outStr.c_str());
+ builder->fsCodeAppendf("color = %s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<4>("color")).c_str());
}
virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& e) SK_OVERRIDE {
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index 484836a5b3..1e3c779ec6 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -410,7 +410,7 @@ public:
if (NULL == inputColor) {
// could optimize this case, but we aren't for now.
- inputColor = GrGLSLOnesVecf(4);
+ inputColor = "vec4(1)";
}
// The max() is to guard against 0 / 0 during unpremul when the incoming color is
// transparent black.
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index c9f1fb02c3..eff1645d27 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -120,7 +120,7 @@ public:
const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE {
if (NULL == inputColor) {
- inputColor = GrGLSLOnesVecf(4);
+ inputColor = "vec4(1)";
}
// The max() is to guard against 0 / 0 during unpremul when the incoming color is
diff --git a/src/effects/SkLumaXfermode.cpp b/src/effects/SkLumaXfermode.cpp
index 3ecb0bec4a..aa3d780aa0 100644
--- a/src/effects/SkLumaXfermode.cpp
+++ b/src/effects/SkLumaXfermode.cpp
@@ -214,7 +214,7 @@ void GrGLLumaMaskEffect::emitCode(GrGLShaderBuilder* builder,
const char* dstColor = builder->dstColor();
SkASSERT(NULL != dstColor);
if (NULL == inputColor) {
- inputColor = GrGLSLOnesVecf(4);
+ inputColor = "vec4(1)";
}
const char *opA = lumaOpA<char>(lumaEffect.getMode(), inputColor, dstColor);
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index dff2d8cd43..9360ba920e 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -950,11 +950,8 @@ void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
}
- SkString output;
- builder->fsCodeAppendf("\t%s = ", outputColor);
- GrGLSLModulatef<4>(&output, inputColor, "colorTemp");
- builder->fsCodeAppend(output.c_str());
- builder->fsCodeAppend(";\n");
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<4>("colorTemp")).c_str());
} else if (GrGradientEffect::kThree_ColorType == ColorTypeFromKey(key)){
builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
gradientTValue);
@@ -977,11 +974,8 @@ void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
}
- SkString output;
- builder->fsCodeAppendf("\t%s = ", outputColor);
- GrGLSLModulatef<4>(&output, inputColor, "colorTemp");
- builder->fsCodeAppend(output.c_str());
- builder->fsCodeAppend(";\n");
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<4>("colorTemp")).c_str());
} else {
builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n",
gradientTValue,
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index ebb2f6988f..ad6e061ec4 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -559,9 +559,9 @@ public:
builder->fsCodeAppendf("\t\t\tedgeAlpha = "
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n");
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("edgeAlpha")).c_str());
builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
}
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index b2052a8d28..a6b8d97c0b 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -84,9 +84,9 @@ public:
"\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
fsRectName, fsRectName);
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "coverage");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("coverage")).c_str());
}
static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
@@ -217,9 +217,9 @@ public:
"\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
fsWidthHeightName);
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "coverage");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("coverage")).c_str());
}
static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 785126560a..91e3997349 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -116,9 +116,8 @@ public:
builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
}
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("edgeAlpha")).c_str());
}
static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
@@ -249,9 +248,8 @@ public:
builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
}
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("edgeAlpha")).c_str());
}
static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
@@ -408,9 +406,8 @@ public:
builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
}
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("edgeAlpha")).c_str());
}
static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 4dca884734..9cca054a40 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -110,9 +110,8 @@ void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder,
}
}
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("edgeAlpha")).c_str());
}
GrGLEffect::EffectKey GrGLConicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
@@ -239,9 +238,9 @@ void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder,
}
}
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("edgeAlpha")).c_str());
+
builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
}
@@ -383,9 +382,8 @@ void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder,
}
}
- SkString modulate;
- GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ (GrGLSLExpr<4>(inputColor) * GrGLSLExpr<1>("edgeAlpha")).c_str());
}
GrGLEffect::EffectKey GrGLCubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index a69333f437..b0435928eb 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -158,13 +158,13 @@ inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff,
str->printf("(%s * %s)", src, value);
break;
case SkXfermode::kISC_Coeff:
- str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value);
+ str->printf("((vec4(1) - %s) * %s)", src, value);
break;
case SkXfermode::kDC_Coeff:
str->printf("(%s * %s)", dst, value);
break;
case SkXfermode::kIDC_Coeff:
- str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value);
+ str->printf("((vec4(1) - %s) * %s)", dst, value);
break;
case SkXfermode::kSA_Coeff: /** src alpha */
str->printf("(%s.a * %s)", src, value);
@@ -196,29 +196,18 @@ void add_color_filter(GrGLShaderBuilder* builder,
SkString colorStr, constStr;
blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor);
blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor);
-
- SkString sum;
- GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str());
- builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str());
-}
-}
-
-namespace {
-
-void expand_known_value4f(SkString* string, GrSLConstantVec vec) {
- SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec));
- switch (vec) {
- case kNone_GrSLConstantVec:
- break;
- case kZeros_GrSLConstantVec:
- *string = GrGLSLZerosVecf(4);
- break;
- case kOnes_GrSLConstantVec:
- *string = GrGLSLOnesVecf(4);
- break;
+ GrGLSLExpr<4> sum;
+ if (colorStr.isEmpty() && constStr.isEmpty()) {
+ sum = GrGLSLExpr<4>(0);
+ } else if (colorStr.isEmpty()) {
+ sum = constStr;
+ } else if (constStr.isEmpty()) {
+ sum = colorStr;
+ } else {
+ sum = GrGLSLExpr<4>(colorStr) + GrGLSLExpr<4>(constStr);
}
+ builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str());
}
-
}
bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
@@ -229,8 +218,7 @@ bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
// incoming color to current stage being processed.
- SkString inColor = builder->getInputColor();
- GrSLConstantVec knownColorValue = builder->getKnownColorValue();
+ GrGLSLExpr<4> inColor = builder->getInputColor();
// Get the coeffs for the Mode-based color filter, determine if color is needed.
SkXfermode::Coeff colorCoeff;
@@ -246,8 +234,7 @@ bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
builder->createAndEmitEffects(colorStages,
fDesc.effectKeys(),
needColor ? fDesc.numColorEffects() : 0,
- &inColor,
- &knownColorValue));
+ &inColor));
// Insert the color filter. This will soon be replaced by a color effect.
if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) {
@@ -257,35 +244,24 @@ bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
&colorFilterColorUniName);
builder->fsCodeAppend("\tvec4 filteredColor;\n");
- const char* color;
- // add_color_filter requires a real input string.
- if (knownColorValue == kOnes_GrSLConstantVec) {
- color = GrGLSLOnesVecf(4);
- } else if (knownColorValue == kZeros_GrSLConstantVec) {
- color = GrGLSLZerosVecf(4);
- } else {
- color = inColor.c_str();
- }
add_color_filter(builder, "filteredColor", filterColorCoeff,
- colorCoeff, colorFilterColorUniName, color);
+ colorCoeff, colorFilterColorUniName, inColor.c_str());
inColor = "filteredColor";
}
///////////////////////////////////////////////////////////////////////////
// compute the partial coverage
- SkString inCoverage = builder->getInputCoverage();
- GrSLConstantVec knownCoverageValue = builder->getKnownCoverageValue();
+ GrGLSLExpr<4> inCoverage = builder->getInputCoverage();
fCoverageEffects.reset(
builder->createAndEmitEffects(coverageStages,
fDesc.getEffectKeys() + fDesc.numColorEffects(),
fDesc.numCoverageEffects(),
- &inCoverage,
- &knownCoverageValue));
+ &inCoverage));
// discard if coverage is zero
- if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageValue) {
- if (kZeros_GrSLConstantVec == knownCoverageValue) {
+ if (header.fDiscardIfZeroCoverage && !inCoverage.isOnes()) {
+ if (inCoverage.isZeros()) {
// This is unfortunate.
builder->fsCodeAppend("\tdiscard;\n");
} else {
@@ -298,79 +274,30 @@ bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
const char* secondaryOutputName = builder->enableSecondaryOutput();
// default coeff to ones for kCoverage_DualSrcOutput
- SkString coeff;
- GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec;
+ GrGLSLExpr<4> coeff(1);
if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
// Get (1-A) into coeff
- SkString inColorAlpha;
- GrGLSLGetComponent4f(&inColorAlpha,
- inColor.c_str(),
- kA_GrColorComponentFlag,
- knownColorValue,
- true);
- knownCoeffValue = GrGLSLSubtractf<1>(&coeff,
- NULL,
- inColorAlpha.c_str(),
- kOnes_GrSLConstantVec,
- knownColorValue,
- true);
+ coeff = GrGLSLExprCast4(GrGLSLExpr<1>(1) - GrGLSLExprExtractAlpha(inColor));
} else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == header.fCoverageOutput) {
// Get (1-RGBA) into coeff
- knownCoeffValue = GrGLSLSubtractf<4>(&coeff,
- NULL,
- inColor.c_str(),
- kOnes_GrSLConstantVec,
- knownColorValue,
- true);
+ coeff = GrGLSLExpr<4>(1) - inColor;
}
// Get coeff * coverage into modulate and then write that to the dual source output.
- SkString modulate;
- GrGLSLModulatef<4>(&modulate,
- coeff.c_str(),
- inCoverage.c_str(),
- knownCoeffValue,
- knownCoverageValue,
- false);
- builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_str());
+ builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inCoverage).c_str());
}
///////////////////////////////////////////////////////////////////////////
// combine color and coverage as frag color
// Get "color * coverage" into fragColor
- SkString fragColor;
- GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor,
- inColor.c_str(),
- inCoverage.c_str(),
- knownColorValue,
- knownCoverageValue,
- true);
+ GrGLSLExpr<4> fragColor = inColor * inCoverage;
// Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
- SkString dstCoeff;
- GrSLConstantVec knownDstCoeffValue = GrGLSLSubtractf<4>(&dstCoeff,
- NULL,
- inCoverage.c_str(),
- kOnes_GrSLConstantVec,
- knownCoverageValue,
- true);
- SkString dstContribution;
- GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContribution,
- dstCoeff.c_str(),
- builder->dstColor(),
- knownDstCoeffValue,
- kNone_GrSLConstantVec,
- true);
- SkString oldFragColor = fragColor;
- fragColor.reset();
- GrGLSLAddf<4>(&fragColor,
- oldFragColor.c_str(),
- dstContribution.c_str(),
- knownFragColorValue,
- knownDstContributionValue,
- false);
- } else {
- expand_known_value4f(&fragColor, knownFragColorValue);
+ GrGLSLExpr<4> dstCoeff = GrGLSLExpr<4>(1) - inCoverage;
+
+ GrGLSLExpr<4> dstContribution = dstCoeff * GrGLSLExpr<4>(builder->dstColor());
+
+ fragColor = fragColor + dstContribution;
}
builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragColor.c_str());
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index 46eed09739..c8ad77cff5 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -113,17 +113,6 @@ private:
kColorInputCnt
};
- static GrSLConstantVec KnownColorInputValue(ColorInput ci) {
- switch (ci) {
- case GrGLProgramDesc::kTransBlack_ColorInput:
- return kZeros_GrSLConstantVec;
- case GrGLProgramDesc::kSolidWhite_ColorInput:
- return kOnes_GrSLConstantVec;
- default:
- return kNone_GrSLConstantVec;
- }
- }
-
enum CoverageOutput {
// modulate color and coverage, write result as the color output.
kModulate_CoverageOutput,
diff --git a/src/gpu/gl/GrGLSL.cpp b/src/gpu/gl/GrGLSL.cpp
index f48f038546..3dfd5e50ed 100644
--- a/src/gpu/gl/GrGLSL.cpp
+++ b/src/gpu/gl/GrGLSL.cpp
@@ -63,26 +63,6 @@ const char* GrGetGLSLVersionDecl(const GrGLContextInfo& info) {
}
}
-const char* GrGLSLVectorHomogCoord(int count) {
- static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
- SkASSERT(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
- return HOMOGS[count];
-}
-
-const char* GrGLSLVectorHomogCoord(GrSLType type) {
- return GrGLSLVectorHomogCoord(GrSLTypeToVecLength(type));
-}
-
-const char* GrGLSLVectorNonhomogCoords(int count) {
- static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
- SkASSERT(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
- return NONHOMOGS[count];
-}
-
-const char* GrGLSLVectorNonhomogCoords(GrSLType type) {
- return GrGLSLVectorNonhomogCoords(GrSLTypeToVecLength(type));
-}
-
namespace {
void append_tabs(SkString* outAppend, int tabCnt) {
static const char kTabs[] = "\t\t\t\t\t\t\t\t";
@@ -94,50 +74,19 @@ namespace {
}
}
-GrSLConstantVec GrGLSLMulVarBy4f(SkString* outAppend,
- int tabCnt,
- const char* vec4VarName,
- const char* mulFactor,
- GrSLConstantVec mulFactorDefault) {
- bool haveFactor = NULL != mulFactor && '\0' != *mulFactor;
-
- SkASSERT(NULL != outAppend);
- SkASSERT(NULL != vec4VarName);
- SkASSERT(kNone_GrSLConstantVec != mulFactorDefault || haveFactor);
-
- if (!haveFactor) {
- if (kOnes_GrSLConstantVec == mulFactorDefault) {
- return kNone_GrSLConstantVec;
- } else {
- SkASSERT(kZeros_GrSLConstantVec == mulFactorDefault);
- append_tabs(outAppend, tabCnt);
- outAppend->appendf("%s = vec4(0, 0, 0, 0);\n", vec4VarName);
- return kZeros_GrSLConstantVec;
- }
+void GrGLSLMulVarBy4f(SkString* outAppend,
+ unsigned tabCnt,
+ const char* vec4VarName,
+ const GrGLSLExpr<4>& mulFactor) {
+ if (mulFactor.isOnes()) {
+ *outAppend = SkString();
}
+
append_tabs(outAppend, tabCnt);
- outAppend->appendf("%s *= %s;\n", vec4VarName, mulFactor);
- return kNone_GrSLConstantVec;
-}
-GrSLConstantVec GrGLSLGetComponent4f(SkString* outAppend,
- const char* expr,
- GrColorComponentFlags component,
- GrSLConstantVec defaultExpr,
- bool omitIfConst) {
- if (NULL == expr || '\0' == *expr) {
- SkASSERT(defaultExpr != kNone_GrSLConstantVec);
- if (!omitIfConst) {
- if (kOnes_GrSLConstantVec == defaultExpr) {
- outAppend->append("1.0");
- } else {
- SkASSERT(kZeros_GrSLConstantVec == defaultExpr);
- outAppend->append("0.0");
- }
- }
- return defaultExpr;
- } else {
- outAppend->appendf("(%s).%c", expr, GrColorComponentFlagToChar(component));
- return kNone_GrSLConstantVec;
+ if (mulFactor.isZeros()) {
+ outAppend->appendf("%s = vec4(0);\n", vec4VarName);
}
+ outAppend->appendf("%s *= %s;\n", vec4VarName, mulFactor.c_str());
}
+
diff --git a/src/gpu/gl/GrGLSL.h b/src/gpu/gl/GrGLSL.h
index b97e709aca..9387d2bbbb 100644
--- a/src/gpu/gl/GrGLSL.h
+++ b/src/gpu/gl/GrGLSL.h
@@ -11,10 +11,10 @@
#include "gl/GrGLInterface.h"
#include "GrColor.h"
#include "GrTypesPriv.h"
+#include "SkString.h"
class GrGLContextInfo;
class GrGLShaderVar;
-class SkString;
// Limited set of GLSL versions we build shaders for. Caller should round
// down the GLSL version to one of these enums.
@@ -37,43 +37,6 @@ enum GrGLSLGeneration {
k150_GrGLSLGeneration,
};
-enum GrSLConstantVec {
- kZeros_GrSLConstantVec,
- kOnes_GrSLConstantVec,
- kNone_GrSLConstantVec,
-};
-
-namespace {
-static inline int GrSLTypeToVecLength(GrSLType type) {
- static const int kVecLengths[] = {
- 0, // kVoid_GrSLType
- 1, // kFloat_GrSLType
- 2, // kVec2f_GrSLType
- 3, // kVec3f_GrSLType
- 4, // kVec4f_GrSLType
- 1, // kMat33f_GrSLType
- 1, // kMat44f_GrSLType
- 1, // kSampler2D_GrSLType
- };
- GR_STATIC_ASSERT(kGrSLTypeCount == GR_ARRAY_COUNT(kVecLengths));
- return kVecLengths[type];
-}
-
-static inline const char* GrGLSLOnesVecf(int count) {
- static const char* kONESVEC[] = {"ERROR", "1.0", "vec2(1,1)",
- "vec3(1,1,1)", "vec4(1,1,1,1)"};
- SkASSERT(count >= 1 && count < (int)GR_ARRAY_COUNT(kONESVEC));
- return kONESVEC[count];
-}
-
-static inline const char* GrGLSLZerosVecf(int count) {
- static const char* kZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)",
- "vec3(0,0,0)", "vec4(0,0,0,0)"};
- SkASSERT(count >= 1 && count < (int)GR_ARRAY_COUNT(kZEROSVEC));
- return kZEROSVEC[count];
-}
-}
-
/**
* Gets the most recent GLSL Generation compatible with the OpenGL context.
*/
@@ -89,7 +52,7 @@ const char* GrGetGLSLVersionDecl(const GrGLContextInfo&);
/**
* Converts a GrSLType to a string containing the name of the equivalent GLSL type.
*/
-static const char* GrGLSLTypeString(GrSLType t) {
+static inline const char* GrGLSLTypeString(GrSLType t) {
switch (t) {
case kVoid_GrSLType:
return "void";
@@ -113,101 +76,203 @@ static const char* GrGLSLTypeString(GrSLType t) {
}
}
-/** Return the type enum for a vector of floats of length n (1..4),
- e.g. 1 -> "float", 2 -> "vec2", ... */
-static inline const char* GrGLSLFloatVectorTypeString(int n) {
- return GrGLSLTypeString(GrSLFloatVectorType(n));
-}
+/** A class representing a GLSL expression.
+ * The instance can be a variable name, expression or vecN(0) or vecN(1). Does simple constant
+ * folding with help of 1 and 0.
+ * Complex expressions can be constructed with operators *, +, -
+ */
+template <int N>
+class GrGLSLExpr {
+public:
+ /** Constructs an invalid expression.
+ * Useful only as a return value from functions that never actually return
+ * this and instances that will be assigned to later. */
+ GrGLSLExpr()
+ : fType(kFullExpr_ExprType) {
+ SK_COMPILE_ASSERT(N > 0 && N <= 4, dimensions_not_in_range);
+ // The only constructor that is allowed to build an empty expression.
+ SkASSERT(!this->isValid());
+ }
-/** Return the GLSL swizzle operator for a homogenous component of a vector
- with the given number of coordinates, e.g. 2 -> ".y", 3 -> ".z" */
-const char* GrGLSLVectorHomogCoord(int count);
-const char* GrGLSLVectorHomogCoord(GrSLType type);
+ /** Constructs an expression with all components as value v */
+ explicit GrGLSLExpr(int v) {
+ SK_COMPILE_ASSERT(N > 0 && N <= 4, dimensions_not_in_range);
+ if (v == 0) {
+ fType = kZeros_ExprType;
+ } else if (v == 1) {
+ fType = kOnes_ExprType;
+ } else {
+ fType = kFullExpr_ExprType;
+ fExpr.appendf(CastIntStr(), v);
+ }
+ }
+
+ /** Constructs an expression from a string.
+ * Argument expr is a simple expression or a parenthesized expression. */
+ // TODO: make explicit once effects input Exprs.
+ GrGLSLExpr(const char expr[]) {
+ SK_COMPILE_ASSERT(N > 0 && N <= 4, dimensions_not_in_range);
+ if (NULL == expr) { // TODO: remove this once effects input Exprs.
+ fType = kOnes_ExprType;
+ } else {
+ fType = kFullExpr_ExprType;
+ fExpr = expr;
+ }
+ SkASSERT(this->isValid());
+ }
+
+ /** Constructs an expression from a string.
+ * Argument expr is a simple expression or a parenthesized expression. */
+ // TODO: make explicit once effects input Exprs.
+ GrGLSLExpr(const SkString& expr) {
+ SK_COMPILE_ASSERT(N > 0 && N <= 4, dimensions_not_in_range);
+ if (expr.isEmpty()) { // TODO: remove this once effects input Exprs.
+ fType = kOnes_ExprType;
+ } else {
+ fType = kFullExpr_ExprType;
+ fExpr = expr;
+ }
+ SkASSERT(this->isValid());
+ }
+
+ bool isOnes() const { return kOnes_ExprType == fType; }
+ bool isZeros() const { return kZeros_ExprType == fType; }
+
+ const char* c_str() const {
+ if (kZeros_ExprType == fType) {
+ return ZerosStr();
+ } else if (kOnes_ExprType == fType) {
+ return OnesStr();
+ }
+ SkASSERT(!fExpr.isEmpty()); // Empty expressions should not be used.
+ return fExpr.c_str();
+ }
+
+private:
+ GrGLSLExpr(const char format[], const char in0[])
+ : fType(kFullExpr_ExprType) {
+ fExpr.appendf(format, in0);
+ }
+
+ GrGLSLExpr(const char format[], const char in0[], const char in1[])
+ : fType(kFullExpr_ExprType) {
+ fExpr.appendf(format, in0, in1);
+ }
+
+ GrGLSLExpr(const char format[], const char in0[], char in1)
+ : fType(kFullExpr_ExprType) {
+ fExpr.appendf(format, in0, in1);
+ }
+
+ bool isValid() const {
+ return kFullExpr_ExprType != fType || !fExpr.isEmpty();
+ }
+
+ static const char* ZerosStr();
+ static const char* OnesStr();
+ static const char* ExtractAlphaStr();
+ static const char* CastStr();
+ static const char* CastIntStr();
+
+ /** Casts the expression expr into smaller or bigger expression.
+ * Casting is done with GLSL rules:
+ * M==3, N==4 vec3(a, b, c) -> vec4(a, b, c, 0)
+ * N==4, M==3 vec4(a, b, c, d) -> vec3(a, b, c)
+ */
+ template <int M>
+ static GrGLSLExpr<N> VectorCast(const GrGLSLExpr<M>& expr);
+
+ /** GLSL multiplication: component-wise or multiply each component by a scalar.
+ * M == N --> vecN(in0.x * in1.x, ...)
+ * M == 1 --> vecN(in0.x * in1, ...)
+ * otherwise --> compile-time error
+ */
+ template <int M>
+ static GrGLSLExpr<N> Mul(const GrGLSLExpr<N>& in0, const GrGLSLExpr<M>& in1);
+
+ /** GLSL addition: component-wise or add a scalar to each compoment.
+ * M == N --> vecN(in0.x + in1.x, ...)
+ * M == 1 --> vecN(in0.x + in1, ...)
+ * otherwise --> compile-time error
+ */
+ template <int M>
+ static GrGLSLExpr<N> Add(const GrGLSLExpr<N>& in0, const GrGLSLExpr<M>& in1);
+
+ /** GLSL subtraction: component-wise or subtract compoments by a scalar.
+ * M == N --> vecN(in0.x - in1.x, ...)
+ * M == 1 --> vecN(in0.x - in1, ...)
+ * otherwise --> compile-time error
+ */
+ template <int M>
+ static GrGLSLExpr<N> Sub(const GrGLSLExpr<N>& in0, const GrGLSLExpr<M>& in1);
+
+ enum ExprType {
+ kZeros_ExprType,
+ kOnes_ExprType,
+ kFullExpr_ExprType,
+ };
+ ExprType fType;
+ SkString fExpr;
+
+ template <int> friend class GrGLSLExpr;
+
+ /** Multiplies two expressions component-wise. */
+ template <int M> friend GrGLSLExpr<M> operator*(const GrGLSLExpr<M>&, const GrGLSLExpr<M>&);
+ /** Adds two expressions component-wise. */
+ template <int M> friend GrGLSLExpr<M> operator+(const GrGLSLExpr<M>&, const GrGLSLExpr<M>&);
+ /** Subtracts two expressions component-wise. */
+ template <int M> friend GrGLSLExpr<M> operator-(const GrGLSLExpr<M>&, const GrGLSLExpr<M>&);
+ /** Multiplies every component of an expression with a scalar expression. */
+ friend GrGLSLExpr<4> operator*(const GrGLSLExpr<4>&, const GrGLSLExpr<1>&);
+ /** Adds a scalar expression to every component of an expression. */
+ friend GrGLSLExpr<4> operator+(const GrGLSLExpr<4>&, const GrGLSLExpr<1>&);
+ /** Subtracts a scalar expression from every component of an expression. */
+ friend GrGLSLExpr<4> operator-(const GrGLSLExpr<4>&, const GrGLSLExpr<1>&);
+
+ friend GrGLSLExpr<1> GrGLSLExprExtractAlpha(const GrGLSLExpr<4>& expr);
+ friend GrGLSLExpr<4> GrGLSLExprCast4(const GrGLSLExpr<1>& expr);
+};
-/** Return the GLSL swizzle operator for a nonhomogenous components of a vector
- with the given number of coordinates, e.g. 2 -> ".x", 3 -> ".xy" */
-const char* GrGLSLVectorNonhomogCoords(int count);
-const char* GrGLSLVectorNonhomogCoords(GrSLType type);
-/**
- * Produces a string that is the result of modulating two inputs. The inputs must be vecN or
- * float. The result is always a vecN. The inputs may be expressions, not just identifier names.
- * Either can be NULL or "" in which case the default params control whether a vector of ones or
- * zeros. It is an error to pass kNone for default<i> if in<i> is NULL or "". Note that when the
- * function determines that the result is a zeros or ones vec then any expression represented by
- * or in1 will not be emitted (side effects won't occur). The return value indicates whether a
- * known zeros or ones vector resulted. The output can be suppressed when known vector is produced
- * by passing true for omitIfConstVec.
- */
template <int N>
-GrSLConstantVec GrGLSLModulatef(SkString* outAppend,
- const char* in0,
- const char* in1,
- GrSLConstantVec default0 = kOnes_GrSLConstantVec,
- GrSLConstantVec default1 = kOnes_GrSLConstantVec,
- bool omitIfConstVec = false);
+inline GrGLSLExpr<N> operator*(const GrGLSLExpr<N>& in0, const GrGLSLExpr<N>&in1) {
+ return GrGLSLExpr<N>::Mul(in0, in1);
+}
-/**
- * Produces a string that is the result of adding two inputs. The inputs must be vecN or
- * float. The result is always a vecN. The inputs may be expressions, not just identifier names.
- * Either can be NULL or "" in which case the default params control whether a vector of ones or
- * zeros. It is an error to pass kNone for default<i> if in<i> is NULL or "". Note that when the
- * function determines that the result is a zeros or ones vec then any expression represented by
- * or in1 will not be emitted (side effects won't occur). The return value indicates whether a
- * known zeros or ones vector resulted. The output can be suppressed when known vector is produced
- * by passing true for omitIfConstVec.
- */
template <int N>
-GrSLConstantVec GrGLSLAddf(SkString* outAppend,
- const char* in0,
- const char* in1,
- GrSLConstantVec default0 = kZeros_GrSLConstantVec,
- GrSLConstantVec default1 = kZeros_GrSLConstantVec,
- bool omitIfConstVec = false);
+inline GrGLSLExpr<N> operator+(const GrGLSLExpr<N>& in0, const GrGLSLExpr<N>&in1) {
+ return GrGLSLExpr<N>::Add(in0, in1);
+}
-/**
- * Produces a string that is the result of subtracting two inputs. The inputs must be vecN or
- * float. The result is always a vecN. The inputs may be expressions, not just identifier names.
- * Either can be NULL or "" in which case the default params control whether a vector of ones or
- * zeros. It is an error to pass kNone for default<i> if in<i> is NULL or "". Note that when the
- * function determines that the result is a zeros or ones vec then any expression represented by
- * or in1 will not be emitted (side effects won't occur). The return value indicates whether a
- * known zeros or ones vector resulted. The output can be suppressed when known vector is produced
- * by passing true for omitIfConstVec.
- */
template <int N>
-GrSLConstantVec GrGLSLSubtractf(SkString* outAppend,
- const char* in0,
- const char* in1,
- GrSLConstantVec default0 = kZeros_GrSLConstantVec,
- GrSLConstantVec default1 = kZeros_GrSLConstantVec,
- bool omitIfConstVec = false);
+inline GrGLSLExpr<N> operator-(const GrGLSLExpr<N>& in0, const GrGLSLExpr<N>&in1) {
+ return GrGLSLExpr<N>::Sub(in0, in1);
+}
-/**
- * Does an inplace mul, *=, of vec4VarName by mulFactor. If mulFactorDefault is not kNone then
- * mulFactor may be either "" or NULL. In this case either nothing will be appended (kOnes) or an
- * assignment of vec(0,0,0,0) will be appended (kZeros). The assignment is prepended by tabCnt tabs.
- * A semicolon and newline are added after the assignment. (TODO: Remove tabCnt when we auto-insert
- * tabs to GrGLEffect-generated lines.) If a zeros vec is assigned then the return value is
- * kZeros, otherwise kNone.
- */
-GrSLConstantVec GrGLSLMulVarBy4f(SkString* outAppend,
- int tabCnt,
- const char* vec4VarName,
- const char* mulFactor,
- GrSLConstantVec mulFactorDefault = kOnes_GrSLConstantVec);
+inline GrGLSLExpr<4> operator*(const GrGLSLExpr<4>& in0, const GrGLSLExpr<1>& in1) {
+ return GrGLSLExpr<4>::Mul(in0, in1);
+}
+
+inline GrGLSLExpr<4> operator+(const GrGLSLExpr<4>& in0, const GrGLSLExpr<1>& in1) {
+ return GrGLSLExpr<4>::Add(in0, in1);
+}
+
+inline GrGLSLExpr<4> operator-(const GrGLSLExpr<4>& in0, const GrGLSLExpr<1>& in1) {
+ return GrGLSLExpr<4>::Sub(in0, in1);
+}
+
+/** Casts an vec1 expression to vec4 expresison, eg. vec1(v) -> vec4(v,v,v,v). */
+GrGLSLExpr<4> GrGLSLExprCast4(const GrGLSLExpr<1>& expr);
+
+/** Extracts alpha component from an expression of vec<4>. */
+GrGLSLExpr<1> GrGLSLExprExtractAlpha(const GrGLSLExpr<4>& expr);
/**
- * Given an expression that evaluates to a GLSL vec4, extract a component. If expr is NULL or ""
- * the value of defaultExpr is used. It is an error to pass an empty expr and have set defaultExpr
- * to kNone. The return value indicates whether the value is known to be 0 or 1. If omitIfConst is
- * set then nothing is appended when the return is not kNone.
+ * Does an inplace mul, *=, of vec4VarName by mulFactor.
+ * A semicolon and newline are added after the assignment.
*/
-GrSLConstantVec GrGLSLGetComponent4f(SkString* outAppend,
- const char* expr,
- GrColorComponentFlags component,
- GrSLConstantVec defaultExpr = kNone_GrSLConstantVec,
- bool omitIfConst = false);
+void GrGLSLMulVarBy4f(SkString* outAppend, unsigned tabCnt,
+ const char* vec4VarName, const GrGLSLExpr<4>& mulFactor);
#include "GrGLSL_impl.h"
diff --git a/src/gpu/gl/GrGLSL_impl.h b/src/gpu/gl/GrGLSL_impl.h
index 292048c6a6..008d512f9c 100644
--- a/src/gpu/gl/GrGLSL_impl.h
+++ b/src/gpu/gl/GrGLSL_impl.h
@@ -8,185 +8,133 @@
#ifndef GrGLSL_impl_DEFINED
#define GrGLSL_impl_DEFINED
-#include "SkString.h"
+template<>
+inline const char* GrGLSLExpr<4>::ZerosStr() {
+ return "vec4(0)";
+}
+
+template<>
+inline const char* GrGLSLExpr<4>::OnesStr() {
+ return "vec4(1)";
+}
+
+template<>
+inline const char* GrGLSLExpr<4>::ExtractAlphaStr() {
+ return "%s.a";
+}
+
+template<>
+inline const char* GrGLSLExpr<4>::CastStr() {
+ return "vec4(%s)";
+}
+template<>
+inline const char* GrGLSLExpr<4>::CastIntStr() {
+ return "vec4(%d)";
+}
+
+template<>
+inline const char* GrGLSLExpr<1>::ZerosStr() {
+ return "0";
+}
+
+template<>
+inline const char* GrGLSLExpr<1>::OnesStr() {
+ return "1";
+}
+
+// GrGLSLExpr<1>::ExtractAlphaStr() and GrGLSLExpr<1>::CastStr() are
+// unimplemented because using them is likely an error. This is now caught
+// compile-time.
+
+template<>
+inline const char* GrGLSLExpr<1>::CastIntStr() {
+ return "%d";
+}
+
+template<>
+template<>
+inline GrGLSLExpr<4> GrGLSLExpr<4>::VectorCast(const GrGLSLExpr<4>& expr) {
+ return expr;
+}
+
+template<>
+template<>
+inline GrGLSLExpr<1> GrGLSLExpr<1>::VectorCast(const GrGLSLExpr<1>& expr) {
+ return expr;
+}
-namespace {
template<int N>
-GrSLConstantVec return_const_vecf(GrSLConstantVec constVec, SkString* outAppend, bool omitAppend) {
- SkASSERT(kNone_GrSLConstantVec != constVec);
- if (!omitAppend) {
- if (kZeros_GrSLConstantVec == constVec) {
- outAppend->append(GrGLSLZerosVecf(N));
- } else {
- outAppend->append(GrGLSLOnesVecf(N));
- }
+template<int M>
+inline GrGLSLExpr<N> GrGLSLExpr<N>::VectorCast(const GrGLSLExpr<M>& expr) {
+ if (expr.isZeros()) {
+ return GrGLSLExpr<N>(0);
}
- return constVec;
-}
-}
-
-template <int N>
-GrSLConstantVec GrGLSLModulatef(SkString* outAppend,
- const char* in0,
- const char* in1,
- GrSLConstantVec default0,
- GrSLConstantVec default1,
- bool omitIfConstVec) {
- SkASSERT(N > 0 && N <= 4);
- SkASSERT(NULL != outAppend);
-
- bool has0 = NULL != in0 && '\0' != *in0;
- bool has1 = NULL != in1 && '\0' != *in1;
-
- SkASSERT(has0 || kNone_GrSLConstantVec != default0);
- SkASSERT(has1 || kNone_GrSLConstantVec != default1);
-
- if (!has0 && !has1) {
- SkASSERT(kZeros_GrSLConstantVec == default0 || kOnes_GrSLConstantVec == default0);
- SkASSERT(kZeros_GrSLConstantVec == default1 || kOnes_GrSLConstantVec == default1);
- if (kZeros_GrSLConstantVec == default0 || kZeros_GrSLConstantVec == default1) {
- return return_const_vecf<N>(kZeros_GrSLConstantVec, outAppend, omitIfConstVec);
- } else {
- // both inputs are ones vectors
- return return_const_vecf<N>(kOnes_GrSLConstantVec, outAppend, omitIfConstVec);
- }
- } else if (!has0) {
- SkASSERT(kZeros_GrSLConstantVec == default0 || kOnes_GrSLConstantVec == default0);
- if (kZeros_GrSLConstantVec == default0) {
- return return_const_vecf<N>(kZeros_GrSLConstantVec, outAppend, omitIfConstVec);
- } else {
- outAppend->appendf("%s(%s)", GrGLSLFloatVectorTypeString(N), in1);
- return kNone_GrSLConstantVec;
- }
- } else if (!has1) {
- SkASSERT(kZeros_GrSLConstantVec == default1 || kOnes_GrSLConstantVec == default1);
- if (kZeros_GrSLConstantVec == default1) {
- return return_const_vecf<N>(kZeros_GrSLConstantVec, outAppend, omitIfConstVec);
- } else {
- outAppend->appendf("%s(%s)", GrGLSLFloatVectorTypeString(N), in0);
- return kNone_GrSLConstantVec;
- }
- } else {
- outAppend->appendf("%s((%s) * (%s))", GrGLSLFloatVectorTypeString(N), in0, in1);
- return kNone_GrSLConstantVec;
+ if (expr.isOnes()) {
+ return GrGLSLExpr<N>(1);
}
+ return GrGLSLExpr<N>(GrGLSLExpr<N>::CastStr(), expr.c_str());
}
-template <int N>
-GrSLConstantVec GrGLSLAddf(SkString* outAppend,
- const char* in0,
- const char* in1,
- GrSLConstantVec default0,
- GrSLConstantVec default1,
- bool omitIfConstVec) {
- SkASSERT(N > 0 && N <= 4);
- SkASSERT(NULL != outAppend);
-
- bool has0 = NULL != in0 && '\0' != *in0;
- bool has1 = NULL != in1 && '\0' != *in1;
-
- if (!has0 && !has1) {
- SkASSERT(kNone_GrSLConstantVec != default0);
- SkASSERT(kNone_GrSLConstantVec != default1);
- int sum = (kOnes_GrSLConstantVec == default0) + (kOnes_GrSLConstantVec == default1);
- if (0 == sum) {
- return return_const_vecf<N>(kZeros_GrSLConstantVec, outAppend, omitIfConstVec);
- } else if (1 == sum) {
- outAppend->append(GrGLSLOnesVecf(N));
- return return_const_vecf<N>(kOnes_GrSLConstantVec, outAppend, omitIfConstVec);
- } else {
- SkASSERT(2 == sum);
- outAppend->appendf("%s(2)", GrGLSLFloatVectorTypeString(N));
- return kNone_GrSLConstantVec;
- }
- } else if (!has0) {
- SkASSERT(kNone_GrSLConstantVec != default0);
- if (kZeros_GrSLConstantVec == default0) {
- outAppend->appendf("%s(%s)", GrGLSLFloatVectorTypeString(N), in1);
- } else {
- outAppend->appendf("%s(%s) + %s",
- GrGLSLFloatVectorTypeString(N),
- in1,
- GrGLSLOnesVecf(N));
- }
- return kNone_GrSLConstantVec;
- } else if (!has1) {
- SkASSERT(kNone_GrSLConstantVec != default1);
- if (kZeros_GrSLConstantVec == default1) {
- outAppend->appendf("%s(%s)", GrGLSLFloatVectorTypeString(N), in0);
- } else {
- outAppend->appendf("%s(%s) + %s",
- GrGLSLFloatVectorTypeString(N),
- in0,
- GrGLSLOnesVecf(N));
- }
- return kNone_GrSLConstantVec;
- } else {
- outAppend->appendf("(%s(%s) + %s(%s))",
- GrGLSLFloatVectorTypeString(N),
- in0,
- GrGLSLFloatVectorTypeString(N),
- in1);
- return kNone_GrSLConstantVec;
+template<int N>
+template<int M>
+inline GrGLSLExpr<N> GrGLSLExpr<N>::Mul(const GrGLSLExpr<N>& in0, const GrGLSLExpr<M>& in1) {
+ SK_COMPILE_ASSERT(N == M || M == 1, binary_op_dimensions_incompatible);
+ if (in0.isZeros() || in1.isZeros()) {
+ return GrGLSLExpr<N>(0);
+ }
+ if (in0.isOnes()) {
+ return VectorCast<M>(in1);
+ }
+ if (in1.isOnes()) {
+ return in0;
}
+ return GrGLSLExpr<N>("(%s * %s)", in0.c_str(), in1.c_str());
}
-template <int N>
-GrSLConstantVec GrGLSLSubtractf(SkString* outAppend,
- const char* in0,
- const char* in1,
- GrSLConstantVec default0,
- GrSLConstantVec default1,
- bool omitIfConstVec) {
- SkASSERT(N > 0 && N <= 4);
- SkASSERT(NULL != outAppend);
-
- bool has0 = NULL != in0 && '\0' != *in0;
- bool has1 = NULL != in1 && '\0' != *in1;
-
- if (!has0 && !has1) {
- SkASSERT(kNone_GrSLConstantVec != default0);
- SkASSERT(kNone_GrSLConstantVec != default1);
- int diff = (kOnes_GrSLConstantVec == default0) - (kOnes_GrSLConstantVec == default1);
- if (-1 == diff) {
- outAppend->appendf("%s(-1)", GrGLSLFloatVectorTypeString(N));
- return kNone_GrSLConstantVec;
- } else if (0 == diff) {
- return return_const_vecf<N>(kZeros_GrSLConstantVec, outAppend, omitIfConstVec);
- } else {
- SkASSERT(1 == diff);
- return return_const_vecf<N>(kOnes_GrSLConstantVec, outAppend, omitIfConstVec);
- }
- } else if (!has0) {
- SkASSERT(kNone_GrSLConstantVec != default0);
- if (kZeros_GrSLConstantVec == default0) {
- outAppend->appendf("-%s(%s)", GrGLSLFloatVectorTypeString(N), in1);
- } else {
- outAppend->appendf("%s - %s(%s)",
- GrGLSLOnesVecf(N),
- GrGLSLFloatVectorTypeString(N),
- in1);
- }
- return kNone_GrSLConstantVec;
- } else if (!has1) {
- SkASSERT(kNone_GrSLConstantVec != default1);
- if (kZeros_GrSLConstantVec == default1) {
- outAppend->appendf("%s(%s)", GrGLSLFloatVectorTypeString(N), in0);
- } else {
- outAppend->appendf("%s(%s) - %s",
- GrGLSLFloatVectorTypeString(N),
- in0,
- GrGLSLOnesVecf(N));
+template<int N>
+template<int M>
+inline GrGLSLExpr<N> GrGLSLExpr<N>::Add(const GrGLSLExpr<N>& in0, const GrGLSLExpr<M>& in1) {
+ SK_COMPILE_ASSERT(N == M || M == 1, binary_op_dimensions_incompatible);
+ if (in1.isZeros()) {
+ return in0;
+ }
+ if (in0.isZeros()) {
+ return VectorCast<M>(in1);
+ }
+ if (in0.isOnes() && in1.isOnes()) {
+ return GrGLSLExpr<N>(2);
+ }
+ return GrGLSLExpr<N>("(%s + %s)", in0.c_str(), in1.c_str());
+}
+
+template<int N>
+template<int M>
+inline GrGLSLExpr<N> GrGLSLExpr<N>::Sub(const GrGLSLExpr<N>& in0, const GrGLSLExpr<M>& in1) {
+ SK_COMPILE_ASSERT(N == M || M == 1, binary_op_dimensions_incompatible);
+ if (in1.isZeros()) {
+ return in0;
+ }
+ if (in1.isOnes()) {
+ if (in0.isOnes()) {
+ return GrGLSLExpr<N>(0);
}
- return kNone_GrSLConstantVec;
- } else {
- outAppend->appendf("(%s(%s) - %s(%s))",
- GrGLSLFloatVectorTypeString(N),
- in0,
- GrGLSLFloatVectorTypeString(N),
- in1);
- return kNone_GrSLConstantVec;
}
+
+ return GrGLSLExpr<N>("(%s - %s)", in0.c_str(), in1.c_str());
+}
+
+inline GrGLSLExpr<4> GrGLSLExprCast4(const GrGLSLExpr<1>& expr) {
+ return GrGLSLExpr<4>::VectorCast(expr);
+}
+
+inline GrGLSLExpr<1> GrGLSLExprExtractAlpha(const GrGLSLExpr<4>& expr) {
+ if (expr.isZeros()) {
+ return GrGLSLExpr<1>(0);
+ }
+ if (expr.isOnes()) {
+ return GrGLSLExpr<1>(1);
+ }
+ return GrGLSLExpr<1>(GrGLSLExpr<4>::ExtractAlphaStr(), expr.c_str());
}
#endif
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index eb7cfa72f4..8b7d614a0b 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -99,8 +99,6 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
, fFSOutputs(kMaxFSOutputs)
, fUniforms(kVarsPerBlock)
, fSetupFragPosition(false)
- , fKnownColorValue(GrGLProgramDesc::KnownColorInputValue(desc.getHeader().fColorInput))
- , fKnownCoverageValue(GrGLProgramDesc::KnownColorInputValue(desc.getHeader().fCoverageInput))
, fHasCustomColorOutput(false)
, fHasSecondaryOutput(false)
, fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) {
@@ -152,6 +150,10 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec4f_GrSLType, "Color", &name);
fInputColor = name;
+ } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) {
+ fInputColor = GrGLSLExpr<4>(1);
+ } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fColorInput) {
+ fInputColor = GrGLSLExpr<4>(0);
}
if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
@@ -159,6 +161,10 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec4f_GrSLType, "Coverage", &name);
fInputCoverage = name;
+ } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) {
+ fInputCoverage = GrGLSLExpr<4>(1);
+ } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fCoverageInput) {
+ fInputCoverage = GrGLSLExpr<4>(0);
}
if (k110_GrGLSLGeneration != fGpu->glslGeneration()) {
@@ -289,7 +295,7 @@ void GrGLShaderBuilder::fsAppendTextureLookupAndModulate(
GrSLType varyingType) {
SkString lookup;
this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
- GrGLSLModulatef<4>(&fFSCode, modulation, lookup.c_str());
+ fFSCode.append((GrGLSLExpr<4>(modulation) * GrGLSLExpr<4>(lookup)).c_str());
}
GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy,
@@ -509,12 +515,11 @@ void GrGLShaderBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programE
const GrEffectStage* effectStages[],
const EffectKey effectKeys[],
int effectCnt,
- SkString* fsInOutColor,
- GrSLConstantVec* fsInOutColorKnownValue) {
+ GrGLSLExpr<4>* fsInOutColor) {
bool effectEmitted = false;
- SkString inColor = *fsInOutColor;
- SkString outColor;
+ GrGLSLExpr<4> inColor = *fsInOutColor;
+ GrGLSLExpr<4> outColor;
for (int e = 0; e < effectCnt; ++e) {
SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect());
@@ -522,24 +527,29 @@ void GrGLShaderBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programE
CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
- if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) {
+ if (inColor.isZeros()) {
+ SkString inColorName;
+
// Effects have no way to communicate zeros, they treat an empty string as ones.
- this->nameVariable(&inColor, '\0', "input");
- this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZerosVecf(4));
+ this->nameVariable(&inColorName, '\0', "input");
+ this->fsCodeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor.c_str());
+ inColor = inColorName;
}
// create var to hold stage result
- this->nameVariable(&outColor, '\0', "output");
- this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
+ SkString outColorName;
+ this->nameVariable(&outColorName, '\0', "output");
+ this->fsCodeAppendf("\tvec4 %s;\n", outColorName.c_str());
+ outColor = outColorName;
+
programEffectsBuilder->emitEffect(stage,
effectKeys[e],
outColor.c_str(),
- inColor.isEmpty() ? NULL : inColor.c_str(),
+ inColor.isOnes() ? NULL : inColor.c_str(),
fCodeStage.stageIndex());
inColor = outColor;
- *fsInOutColorKnownValue = kNone_GrSLConstantVec;
effectEmitted = true;
}
@@ -829,16 +839,14 @@ GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects(
const GrEffectStage* effectStages[],
const EffectKey effectKeys[],
int effectCnt,
- SkString* inOutFSColor,
- GrSLConstantVec* fsInOutColorKnownValue) {
+ GrGLSLExpr<4>* inOutFSColor) {
GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt);
this->INHERITED::createAndEmitEffects(&programEffectsBuilder,
effectStages,
effectKeys,
effectCnt,
- inOutFSColor,
- fsInOutColorKnownValue);
+ inOutFSColor);
return programEffectsBuilder.finish();
}
@@ -939,15 +947,13 @@ GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects(
const GrEffectStage* effectStages[],
const EffectKey effectKeys[],
int effectCnt,
- SkString* inOutFSColor,
- GrSLConstantVec* fsInOutColorKnownValue) {
+ GrGLSLExpr<4>* inOutFSColor) {
GrGLTexGenProgramEffectsBuilder texGenEffectsBuilder(this, effectCnt);
this->INHERITED::createAndEmitEffects(&texGenEffectsBuilder,
effectStages,
effectKeys,
effectCnt,
- inOutFSColor,
- fsInOutColorKnownValue);
+ inOutFSColor);
return texGenEffectsBuilder.finish();
}
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index 208c61060b..d7ba58e077 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -167,40 +167,26 @@ public:
/**
* Interfaces used by GrGLProgram.
- * TODO: These are used by GrGLProgram to insert a mode color filter. Remove these when the
- * color filter is expressed as a GrEffect.
*/
- const SkString& getInputColor() const {
- SkASSERT(fInputColor.isEmpty() != (kNone_GrSLConstantVec == fKnownColorValue));
+ const GrGLSLExpr<4>& getInputColor() const {
return fInputColor;
}
- GrSLConstantVec getKnownColorValue() const {
- SkASSERT(fInputColor.isEmpty() != (kNone_GrSLConstantVec == fKnownColorValue));
- return fKnownColorValue;
- }
- const SkString& getInputCoverage() const {
- SkASSERT(fInputCoverage.isEmpty() != (kNone_GrSLConstantVec == fKnownCoverageValue));
+ const GrGLSLExpr<4>& getInputCoverage() const {
return fInputCoverage;
}
- GrSLConstantVec getKnownCoverageValue() const {
- SkASSERT(fInputCoverage.isEmpty() != (kNone_GrSLConstantVec == fKnownCoverageValue));
- return fKnownCoverageValue;
- }
/**
* Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
* deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
* generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
- * is updated to be the output color of the last stage. fsInOutColorKnownValue specifies whether
- * the input color has a known constant value and is updated to refer to the status of the
- * output color. The handles to texture samplers for effectStage[i] are added to
+ * is updated to be the output color of the last stage.
+ * The handles to texture samplers for effectStage[i] are added to
* effectSamplerHandles[i].
*/
virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
const EffectKey effectKeys[],
int effectCnt,
- SkString* inOutFSColor,
- GrSLConstantVec* fsInOutColorKnownValue) = 0;
+ GrGLSLExpr<4>* inOutFSColor) = 0;
const char* getColorOutputName() const;
const char* enableSecondaryOutput();
@@ -225,8 +211,8 @@ public:
protected:
GrGpuGL* gpu() const { return fGpu; }
- void setInputColor(const char* inputColor) { fInputColor = inputColor; }
- void setInputCoverage(const char* inputCoverage) { fInputCoverage = inputCoverage; }
+ void setInputColor(const GrGLSLExpr<4>& inputColor) { fInputColor = inputColor; }
+ void setInputCoverage(const GrGLSLExpr<4>& inputCoverage) { fInputCoverage = inputCoverage; }
/** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
@@ -241,8 +227,7 @@ protected:
const GrEffectStage* effectStages[],
const EffectKey effectKeys[],
int effectCnt,
- SkString* inOutFSColor,
- GrSLConstantVec* fsInOutColorKnownValue);
+ GrGLSLExpr<4>* inOutFSColor);
virtual bool compileAndAttachShaders(GrGLuint programId) const;
virtual void bindProgramLocations(GrGLuint programId) const;
@@ -344,10 +329,8 @@ private:
bool fSetupFragPosition;
GrGLUniformManager::UniformHandle fDstCopySamplerUniform;
- SkString fInputColor;
- GrSLConstantVec fKnownColorValue;
- SkString fInputCoverage;
- GrSLConstantVec fKnownCoverageValue;
+ GrGLSLExpr<4> fInputColor;
+ GrGLSLExpr<4> fInputCoverage;
bool fHasCustomColorOutput;
bool fHasSecondaryOutput;
@@ -413,8 +396,7 @@ public:
const GrEffectStage* effectStages[],
const EffectKey effectKeys[],
int effectCnt,
- SkString* inOutFSColor,
- GrSLConstantVec* fsInOutColorKnownValue) SK_OVERRIDE;
+ GrGLSLExpr<4>* inOutFSColor) SK_OVERRIDE;
GrGLUniformManager::UniformHandle getViewMatrixUniform() const {
return fViewMatrixUniform;
@@ -463,8 +445,7 @@ public:
const GrEffectStage* effectStages[],
const EffectKey effectKeys[],
int effectCnt,
- SkString* inOutFSColor,
- GrSLConstantVec* fsInOutColorKnownValue) SK_OVERRIDE;
+ GrGLSLExpr<4>* inOutFSColor) SK_OVERRIDE;
private:
int fNumTexCoordSets;