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"; }
}
}
-// 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,
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);
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,
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);
}
}
}
!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");
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;
}
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");
}
}
#include "GrGLSL.h"
#include "GrGLShaderVar.h"
+#include "SkString.h"
GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding,
const GrGLInterface* gl) {
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;
+ }
+}
#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.
kSampler2D_GrSLType
};
+enum GrSLConstantVec {
+ kZeros_GrSLConstantVec,
+ kOnes_GrSLConstantVec,
+ kNone_GrSLConstantVec,
+};
+
namespace {
inline int GrSLTypeToVecLength(GrSLType type) {
static const int kVecLengths[] = {
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];
+}
}
/**
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