diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-29 12:59:57 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-29 12:59:57 +0000 |
commit | 4af0af612f8cfb6951feb10ffe3091821866bd44 (patch) | |
tree | 53682cd4bf4f3d0db27768493da80577b497d310 /src/gpu/gl | |
parent | 1fcc1b80994f7bfa60bbc74e924484da09b47e3b (diff) |
Add helpers to add/modulate glsl vec4s.
Review URL: https://codereview.appspot.com/6497046/
git-svn-id: http://skia.googlecode.com/svn/trunk@5332 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 102 | ||||
-rw-r--r-- | src/gpu/gl/GrGLSL.cpp | 77 | ||||
-rw-r--r-- | src/gpu/gl/GrGLSL.h | 53 |
3 files changed, 146 insertions, 86 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 9613697678..50e839b77c 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -46,20 +46,6 @@ inline const char* vector_all_coords(int count) { return ALL[count]; } -inline const char* all_ones_vec(int count) { - static const char* ONESVEC[] = {"ERROR", "1.0", "vec2(1,1)", - "vec3(1,1,1)", "vec4(1,1,1,1)"}; - GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ONESVEC)); - return ONESVEC[count]; -} - -inline const char* all_zeros_vec(int count) { - static const char* ZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)", - "vec3(0,0,0)", "vec4(0,0,0,0)"}; - GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ZEROSVEC)); - return ZEROSVEC[count]; -} - inline const char* declared_color_output_name() { return "fsColorOut"; } inline const char* dual_source_output_name() { return "dualSourceOut"; } @@ -146,62 +132,6 @@ void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, } } -// assigns modulation of two vars to an output var -// vars can be vec4s or floats (or one of each) -// result is always vec4 -// if either var is "" then assign to the other var -// if both are "" then assign all ones -static inline void modulate_helper(const char* outputVar, - const char* var0, - const char* var1, - SkString* code) { - GrAssert(NULL != outputVar); - GrAssert(NULL != var0); - GrAssert(NULL != var1); - GrAssert(NULL != code); - - bool has0 = '\0' != *var0; - bool has1 = '\0' != *var1; - - if (!has0 && !has1) { - code->appendf("\t%s = %s;\n", outputVar, all_ones_vec(4)); - } else if (!has0) { - code->appendf("\t%s = vec4(%s);\n", outputVar, var1); - } else if (!has1) { - code->appendf("\t%s = vec4(%s);\n", outputVar, var0); - } else { - code->appendf("\t%s = vec4(%s * %s);\n", outputVar, var0, var1); - } -} - -// assigns addition of two vars to an output var -// vars can be vec4s or floats (or one of each) -// result is always vec4 -// if either var is "" then assign to the other var -// if both are "" then assign all zeros -static inline void add_helper(const char* outputVar, - const char* var0, - const char* var1, - SkString* code) { - GrAssert(NULL != outputVar); - GrAssert(NULL != var0); - GrAssert(NULL != var1); - GrAssert(NULL != code); - - bool has0 = '\0' != *var0; - bool has1 = '\0' != *var1; - - if (!has0 && !has1) { - code->appendf("\t%s = %s;\n", outputVar, all_zeros_vec(4)); - } else if (!has0) { - code->appendf("\t%s = vec4(%s);\n", outputVar, var1); - } else if (!has1) { - code->appendf("\t%s = vec4(%s);\n", outputVar, var0); - } else { - code->appendf("\t%s = vec4(%s + %s);\n", outputVar, var0, var1); - } -} - // given two blend coeffecients determine whether the src // and/or dst computation can be omitted. static inline void needBlendInputs(SkXfermode::Coeff srcCoeff, @@ -260,13 +190,13 @@ static void blendTermString(SkString* str, SkXfermode::Coeff coeff, str->printf("(%s * %s)", src, value); break; case SkXfermode::kISC_Coeff: - str->printf("((%s - %s) * %s)", all_ones_vec(4), src, value); + str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value); break; case SkXfermode::kDC_Coeff: str->printf("(%s * %s)", dst, value); break; case SkXfermode::kIDC_Coeff: - str->printf("((%s - %s) * %s)", all_ones_vec(4), dst, value); + str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value); break; case SkXfermode::kSA_Coeff: /** src alpha */ str->printf("(%s.a * %s)", src, value); @@ -298,7 +228,9 @@ static void addColorFilter(SkString* fsCode, const char * outputVar, blendTermString(&colorStr, colorCoeff, filterColor, inColor, inColor); blendTermString(&constStr, uniformCoeff, filterColor, inColor, filterColor); - add_helper(outputVar, colorStr.c_str(), constStr.c_str(), fsCode); + fsCode->appendf("\t%s = ", outputVar); + GrGLSLAdd4f(fsCode, colorStr.c_str(), constStr.c_str()); + fsCode->append(";\n"); } bool GrGLProgram::genEdgeCoverage(SkString* coverageVar, @@ -458,9 +390,9 @@ const char* GrGLProgram::adjustInColor(const SkString& inColor) const { return inColor.c_str(); } else { if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) { - return all_ones_vec(4); + return GrGLSLOnesVecf(4); } else { - return all_zeros_vec(4); + return GrGLSLZerosVecf(4); } } } @@ -736,7 +668,7 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) { !applyColorMatrix) { builder.fFSCode.appendf("\t%s = %s;\n", colorOutput.getName().c_str(), - all_zeros_vec(4)); + GrGLSLZerosVecf(4)); wroteFragColorZero = true; } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) { builder.fFSCode.append("\tvec4 filteredColor;\n"); @@ -854,12 +786,11 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) { if (outputIsZero) { builder.fFSCode.appendf("\t%s = %s;\n", dual_source_output_name(), - all_zeros_vec(4)); + GrGLSLZerosVecf(4)); } else { - modulate_helper(dual_source_output_name(), - coeff.c_str(), - inCoverage.c_str(), - &builder.fFSCode); + builder.fFSCode.appendf("\t%s =", dual_source_output_name()); + GrGLSLModulate4f(&builder.fFSCode, coeff.c_str(), inCoverage.c_str()); + builder.fFSCode.append(";\n"); } dualSourceOutputWritten = true; } @@ -872,12 +803,11 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) { if (coverageIsZero) { builder.fFSCode.appendf("\t%s = %s;\n", colorOutput.getName().c_str(), - all_zeros_vec(4)); + GrGLSLZerosVecf(4)); } else { - modulate_helper(colorOutput.getName().c_str(), - inColor.c_str(), - inCoverage.c_str(), - &builder.fFSCode); + builder.fFSCode.appendf("\t%s = ", colorOutput.getName().c_str()); + GrGLSLModulate4f(&builder.fFSCode, inColor.c_str(), inCoverage.c_str()); + builder.fFSCode.append(";\n"); } } diff --git a/src/gpu/gl/GrGLSL.cpp b/src/gpu/gl/GrGLSL.cpp index f1f7d92f40..21e9183b6c 100644 --- a/src/gpu/gl/GrGLSL.cpp +++ b/src/gpu/gl/GrGLSL.cpp @@ -7,6 +7,7 @@ #include "GrGLSL.h" #include "GrGLShaderVar.h" +#include "SkString.h" GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, const GrGLInterface* gl) { @@ -93,3 +94,79 @@ const char* GrGLSLVectorNonhomogCoords(int count) { const char* GrGLSLVectorNonhomogCoord(GrSLType type) { return GrGLSLVectorNonhomogCoords(GrSLTypeToVecLength(type)); } + +GrSLConstantVec GrGLSLModulate4f(SkString* outAppend, + const char* in0, + const char* in1, + GrSLConstantVec default0, + GrSLConstantVec default1) { + GrAssert(NULL != outAppend); + + bool has0 = NULL != in0 && '\0' != *in0; + bool has1 = NULL != in1 && '\0' != *in1; + + GrAssert(has0 || kNone_GrSLConstantVec != default0); + GrAssert(has1 || kNone_GrSLConstantVec != default1); + + if (!has0 && !has1) { + GrAssert(kZeros_GrSLConstantVec == default0 || kOnes_GrSLConstantVec == default0); + GrAssert(kZeros_GrSLConstantVec == default1 || kOnes_GrSLConstantVec == default1); + if (kZeros_GrSLConstantVec == default0 || kZeros_GrSLConstantVec == default1) { + outAppend->append(GrGLSLZerosVecf(4)); + return kZeros_GrSLConstantVec; + } else { + outAppend->appendf(GrGLSLOnesVecf(4)); + return kOnes_GrSLConstantVec; + } + } else if (!has0) { + GrAssert(kZeros_GrSLConstantVec == default0 || kOnes_GrSLConstantVec == default0); + if (kZeros_GrSLConstantVec == default0) { + outAppend->append(GrGLSLZerosVecf(4)); + return kZeros_GrSLConstantVec; + } else { + outAppend->appendf("vec4(%s)", in1); + return kNone_GrSLConstantVec; + } + } else if (!has1) { + GrAssert(kZeros_GrSLConstantVec == default1 || kOnes_GrSLConstantVec == default1); + if (kZeros_GrSLConstantVec == default1) { + outAppend->append(GrGLSLZerosVecf(4)); + return kZeros_GrSLConstantVec; + } else { + outAppend->appendf("vec4(%s)", in0); + return kNone_GrSLConstantVec; + } + } else { + outAppend->appendf("vec4(%s * %s)", in0, in1); + return kNone_GrSLConstantVec; + } +} + +GrSLConstantVec GrGLSLAdd4f(SkString* outAppend, + const char* in0, + const char* in1, + GrSLConstantVec default0, + GrSLConstantVec default1) { + GrAssert(NULL != outAppend); + + bool has0 = NULL != in0 && '\0' != *in0; + bool has1 = NULL != in1 && '\0' != *in1; + + if (!has0 && !has1) { + GrAssert(kZeros_GrSLConstantVec == default0); + GrAssert(kZeros_GrSLConstantVec == default1); + outAppend->append(GrGLSLZerosVecf(4)); + return kZeros_GrSLConstantVec; + } else if (!has0) { + GrAssert(kZeros_GrSLConstantVec == default0); + outAppend->appendf("vec4(%s)", in1); + return kNone_GrSLConstantVec; + } else if (!has1) { + GrAssert(kZeros_GrSLConstantVec == default1); + outAppend->appendf("vec4(%s)", in0); + return kNone_GrSLConstantVec; + } else { + outAppend->appendf("(vec4(%s) + vec4(%s))", in0, in1); + return kNone_GrSLConstantVec; + } +} diff --git a/src/gpu/gl/GrGLSL.h b/src/gpu/gl/GrGLSL.h index f69385f239..6595608615 100644 --- a/src/gpu/gl/GrGLSL.h +++ b/src/gpu/gl/GrGLSL.h @@ -11,6 +11,7 @@ #include "gl/GrGLInterface.h" 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. @@ -45,6 +46,12 @@ enum GrSLType { kSampler2D_GrSLType }; +enum GrSLConstantVec { + kZeros_GrSLConstantVec, + kOnes_GrSLConstantVec, + kNone_GrSLConstantVec, +}; + namespace { inline int GrSLTypeToVecLength(GrSLType type) { static const int kVecLengths[] = { @@ -60,6 +67,20 @@ inline int GrSLTypeToVecLength(GrSLType type) { GrAssert((size_t) type < GR_ARRAY_COUNT(kVecLengths)); return kVecLengths[type]; } + +const char* GrGLSLOnesVecf(int count) { + static const char* kONESVEC[] = {"ERROR", "1.0", "vec2(1,1)", + "vec3(1,1,1)", "vec4(1,1,1,1)"}; + GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(kONESVEC)); + return kONESVEC[count]; +} + +const char* GrGLSLZerosVecf(int count) { + static const char* kZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)", + "vec3(0,0,0)", "vec4(0,0,0,0)"}; + GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(kZEROSVEC)); + return kZEROSVEC[count]; +} } /** @@ -107,4 +128,36 @@ const char* GrGLSLVectorHomogCoord(GrSLType type); 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 vec4 or + * float. The result is always a vec4. The inputs may be expressions, not just identifier names. + * Either can be NULL or "" in which case the default params control whether vec4(1,1,1,1) or + * vec4(0,0,0,0) is assumed. It is an error to pass kNone for default<i> if in<i> is NULL or "". + * Note that when if function determines that the result is a zeros or ones vec then any expression + * represented by in0 or in1 will not be emitted. The return value indicates whether a zeros, ones + * or neither was appeneded. + */ +GrSLConstantVec GrGLSLModulate4f(SkString* outAppend, + const char* in0, + const char* in1, + GrSLConstantVec default0 = kOnes_GrSLConstantVec, + GrSLConstantVec default1 = kOnes_GrSLConstantVec); + + +/** + * Produces a string that is the result of adding two inputs. The inputs must be vec4 or float. + * The result is always a vec4. The inputs may be expressions, not just identifier names. Either + * can be NULL or "" in which case if the default is kZeros then vec4(0,0,0,0) is assumed. It is an + * error to pass kOnes for either default or to pass kNone for default<i> if in<i> is NULL or "". + * Note that if the function determines that the result is a zeros vec any expression represented + * by in0 or in1 will not be emitted. The return value indicates whether a zeros vec was appended + * or not. + */ +GrSLConstantVec GrGLSLAdd4f(SkString* outAppend, + const char* in0, + const char* in1, + GrSLConstantVec default0 = kZeros_GrSLConstantVec, + GrSLConstantVec default1 = kZeros_GrSLConstantVec); + #endif |