diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 6f2fee691..993c75471 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 d746ecbc3..fff03c291 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 c8db3a56c..69e22c960 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 484836a5b..1e3c779ec 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 c9f1fb02c..eff1645d2 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 3ecb0bec4..aa3d780aa 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(lumaEffect.getMode(), inputColor, dstColor); diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index dff2d8cd4..9360ba920 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 ebb2f6988..ad6e061ec 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 b2052a8d2..a6b8d97c0 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 785126560..91e399734 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 4dca88473..9cca054a4 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 a69333f43..b0435928e 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,31 +196,20 @@ 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()); + 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()); } } -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; - } -} - -} - bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]) { @@ -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 46eed0973..c8ad77cff 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 f48f03854..3dfd5e50e 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; + + if (mulFactor.isZeros()) { + outAppend->appendf("%s = vec4(0);\n", vec4VarName); + } + outAppend->appendf("%s *= %s;\n", vec4VarName, mulFactor.c_str()); } -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; - } -} diff --git a/src/gpu/gl/GrGLSL.h b/src/gpu/gl/GrGLSL.h index b97e709ac..9387d2bbb 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 +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()); + } + + /** 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 + static GrGLSLExpr VectorCast(const GrGLSLExpr& 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 + static GrGLSLExpr Mul(const GrGLSLExpr& in0, const GrGLSLExpr& 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 + static GrGLSLExpr Add(const GrGLSLExpr& in0, const GrGLSLExpr& 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 + static GrGLSLExpr Sub(const GrGLSLExpr& in0, const GrGLSLExpr& in1); + + enum ExprType { + kZeros_ExprType, + kOnes_ExprType, + kFullExpr_ExprType, + }; + ExprType fType; + SkString fExpr; + + template friend class GrGLSLExpr; + + /** Multiplies two expressions component-wise. */ + template friend GrGLSLExpr operator*(const GrGLSLExpr&, const GrGLSLExpr&); + /** Adds two expressions component-wise. */ + template friend GrGLSLExpr operator+(const GrGLSLExpr&, const GrGLSLExpr&); + /** Subtracts two expressions component-wise. */ + template friend GrGLSLExpr operator-(const GrGLSLExpr&, const GrGLSLExpr&); + /** 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); +}; + + +template +inline GrGLSLExpr operator*(const GrGLSLExpr& in0, const GrGLSLExpr&in1) { + return GrGLSLExpr::Mul(in0, in1); } -/** 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); - -/** 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 if in 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 -GrSLConstantVec GrGLSLModulatef(SkString* outAppend, - const char* in0, - const char* in1, - GrSLConstantVec default0 = kOnes_GrSLConstantVec, - GrSLConstantVec default1 = kOnes_GrSLConstantVec, - bool omitIfConstVec = false); +inline GrGLSLExpr operator+(const GrGLSLExpr& in0, const GrGLSLExpr&in1) { + return GrGLSLExpr::Add(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 if in 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 -GrSLConstantVec GrGLSLAddf(SkString* outAppend, - const char* in0, - const char* in1, - GrSLConstantVec default0 = kZeros_GrSLConstantVec, - GrSLConstantVec default1 = kZeros_GrSLConstantVec, - bool omitIfConstVec = false); +inline GrGLSLExpr operator-(const GrGLSLExpr& in0, const GrGLSLExpr&in1) { + return GrGLSLExpr::Sub(in0, in1); +} + +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); /** - * 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 if in 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. + * Does an inplace mul, *=, of vec4VarName by mulFactor. + * A semicolon and newline are added after the assignment. */ -template -GrSLConstantVec GrGLSLSubtractf(SkString* outAppend, - const char* in0, - const char* in1, - GrSLConstantVec default0 = kZeros_GrSLConstantVec, - GrSLConstantVec default1 = kZeros_GrSLConstantVec, - bool omitIfConstVec = false); - -/** - * 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); - -/** - * 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. - */ -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 292048c6a..008d512f9 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 -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 +inline GrGLSLExpr GrGLSLExpr::VectorCast(const GrGLSLExpr& expr) { + if (expr.isZeros()) { + return GrGLSLExpr(0); } - return constVec; -} + if (expr.isOnes()) { + return GrGLSLExpr(1); + } + return GrGLSLExpr(GrGLSLExpr::CastStr(), expr.c_str()); } -template -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(kZeros_GrSLConstantVec, outAppend, omitIfConstVec); - } else { - // both inputs are ones vectors - return return_const_vecf(kOnes_GrSLConstantVec, outAppend, omitIfConstVec); - } - } else if (!has0) { - SkASSERT(kZeros_GrSLConstantVec == default0 || kOnes_GrSLConstantVec == default0); - if (kZeros_GrSLConstantVec == default0) { - return return_const_vecf(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(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; +template +template +inline GrGLSLExpr GrGLSLExpr::Mul(const GrGLSLExpr& in0, const GrGLSLExpr& in1) { + SK_COMPILE_ASSERT(N == M || M == 1, binary_op_dimensions_incompatible); + if (in0.isZeros() || in1.isZeros()) { + return GrGLSLExpr(0); } + if (in0.isOnes()) { + return VectorCast(in1); + } + if (in1.isOnes()) { + return in0; + } + return GrGLSLExpr("(%s * %s)", in0.c_str(), in1.c_str()); } -template -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(kZeros_GrSLConstantVec, outAppend, omitIfConstVec); - } else if (1 == sum) { - outAppend->append(GrGLSLOnesVecf(N)); - return return_const_vecf(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 +template +inline GrGLSLExpr GrGLSLExpr::Add(const GrGLSLExpr& in0, const GrGLSLExpr& in1) { + SK_COMPILE_ASSERT(N == M || M == 1, binary_op_dimensions_incompatible); + if (in1.isZeros()) { + return in0; } + if (in0.isZeros()) { + return VectorCast(in1); + } + if (in0.isOnes() && in1.isOnes()) { + return GrGLSLExpr(2); + } + return GrGLSLExpr("(%s + %s)", in0.c_str(), in1.c_str()); } -template -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(kZeros_GrSLConstantVec, outAppend, omitIfConstVec); - } else { - SkASSERT(1 == diff); - return return_const_vecf(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)); - } - return kNone_GrSLConstantVec; - } else { - outAppend->appendf("(%s(%s) - %s(%s))", - GrGLSLFloatVectorTypeString(N), - in0, - GrGLSLFloatVectorTypeString(N), - in1); - return kNone_GrSLConstantVec; +template +template +inline GrGLSLExpr GrGLSLExpr::Sub(const GrGLSLExpr& in0, const GrGLSLExpr& 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(0); + } + } + + return GrGLSLExpr("(%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 eb7cfa72f..8b7d614a0 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 208c61060..d7ba58e07 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;