Declare outputColor and outputCoverage inside emitCode.

This is useful because it allows the variables to be declared as `const`
when they are trivial values like `half4(1)`. This enables the constant
folder to simplify or eliminate them. In most cases, this is only a
small benefit, as you'd expect a competent GPU driver to do the same.
However, Mali-400 can benefit significantly from optimizing away the
multiplication against a constant half4(1) coverage in Porter-Duff.

Mali-400 performance is back to normal: http://screen/3cDxdaGkYE8oBcS

Change-Id: I21fd23f91f747079cd05b082f7b3444aeabafb93
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/382476
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2021-03-09 20:16:43 -05:00 committed by Skia Commit-Bot
parent 38847cda89
commit 4d7ac49dca
27 changed files with 109 additions and 84 deletions

View File

@ -72,13 +72,13 @@ public:
}
vertBuilder->codeAppendf("%s = color;", varying.vsOut());
fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
fragBuilder->codeAppendf("half4 %s = %s;", args.fOutputColor, varying.fsIn());
// Position
this->writeOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name());
// Coverage
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& primProc) override {

View File

@ -113,12 +113,13 @@ class GLSLClockwiseTestProcessor : public GrGLSLGeometryProcessor {
args.fVaryingHandler->emitAttributes(proc);
gpArgs->fPositionVar.set(kFloat2_GrSLType, "position");
args.fFragBuilder->codeAppendf(
"%s = sk_Clockwise ? half4(0,1,0,1) : half4(1,0,0,1);", args.fOutputColor);
"half4 %s = sk_Clockwise ? half4(0,1,0,1) : half4(1,0,0,1);",
args.fOutputColor);
if (!proc.readSkFragCoord()) {
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
} else {
// Verify layout(origin_upper_left) on gl_FragCoord does not affect gl_FrontFacing.
args.fFragBuilder->codeAppendf("%s = half4(min(half(sk_FragCoord.y), 1));",
args.fFragBuilder->codeAppendf("half4 %s = half4(min(half(sk_FragCoord.y), 1));",
args.fOutputCoverage);
}
}

View File

@ -123,8 +123,8 @@ class FwidthSquircleTestProcessor::Impl : public GrGLSLGeometryProcessor {
f->codeAppendf("fnwidth += 1e-10;"); // Guard against divide-by-zero.
f->codeAppendf("half coverage = clamp(half(.5 - fn/fnwidth), 0, 1);");
f->codeAppendf("%s = half4(.51, .42, .71, 1) * .89;", args.fOutputColor);
f->codeAppendf("%s = half4(coverage);", args.fOutputCoverage);
f->codeAppendf("half4 %s = half4(.51, .42, .71, 1) * .89;", args.fOutputColor);
f->codeAppendf("half4 %s = half4(coverage);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman,

View File

@ -170,8 +170,8 @@ class SampleLocationsTestProcessor::Impl : public GrGLSLGeometryProcessor {
}
// Fragment shader: Output RED.
f->codeAppendf("%s = half4(1,0,0,1);", args.fOutputColor);
f->codeAppendf("%s = half4(1);", args.fOutputCoverage);
f->codeAppendf("const half4 %s = half4(1,0,0,1);", args.fOutputColor);
f->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
// Now turn off all the samples inside our sub-rectangle. As long as the shaderBuilder's
// sample offsets and sample mask are correlated with actual HW sample locations, no red

View File

@ -170,8 +170,8 @@ void TessellationTestTriShader::Impl::writeFragmentShader(
f->codeAppendf(R"(
half3 d = half3(1 - barycentric_coord/fwidth(barycentric_coord));
half coverage = max(max(d.x, d.y), d.z);
%s = half4(0, coverage, coverage, 1);
%s = half4(1);)", color, coverage);
half4 %s = half4(0, coverage, coverage, 1);
const half4 %s = half4(1);)", color, coverage);
}
class TessellationTestRectShader : public GrGeometryProcessor {

View File

@ -77,6 +77,7 @@ public:
SkASSERT(!tweakAlpha || gp.hasVertexCoverage());
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
if (gp.hasVertexColor() || tweakAlpha) {
GrGLSLVarying varying(kHalf4_GrSLType);
varyingHandler->addVarying("color", &varying);
@ -127,9 +128,9 @@ public:
if (gp.hasVertexCoverage() && !tweakAlpha) {
fragBuilder->codeAppendf("half alpha = 1.0;");
varyingHandler->addPassThroughAttribute(gp.fInCoverage, "alpha");
fragBuilder->codeAppendf("%s = half4(alpha);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(alpha);", args.fOutputCoverage);
} else if (gp.coverage() == 0xff) {
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
} else {
const char* fragCoverage;
fCoverageUniform = uniformHandler->addUniform(nullptr,
@ -137,7 +138,8 @@ public:
kHalf_GrSLType,
"Coverage",
&fragCoverage);
fragBuilder->codeAppendf("%s = half4(%s);", args.fOutputCoverage, fragCoverage);
fragBuilder->codeAppendf("half4 %s = half4(%s);",
args.fOutputCoverage, fragCoverage);
}
}

View File

@ -48,10 +48,10 @@ public:
kHalf4_GrSLType,
"Color",
&stagedLocalVarName);
fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
fragBuilder->codeAppendf("half4 %s = %s;", args.fOutputColor, stagedLocalVarName);
// setup constant solid coverage
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
void emitTransforms(GrGLSLVaryingHandler* varyingHandler,

View File

@ -162,6 +162,8 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
const GrCCPathProcessor& proc = args.fGP.cast<GrCCPathProcessor>();
GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLVertexBuilder* v = args.fVertBuilder;
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
bool isCoverageCount = (CoverageMode::kCoverageCount == proc.fCoverageMode);
const char* atlasAdjust;
@ -174,13 +176,12 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
varyingHandler->addVarying("texcoord", &texcoord);
GrGLSLVarying color(kHalf4_GrSLType);
f->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(
kInstanceAttribs[kColorAttribIdx], args.fOutputColor, Interpolation::kCanBeFlat);
// The vertex shader bloats and intersects the devBounds and devBounds45 rectangles, in order to
// find an octagon that circumscribes the (bloated) path.
GrGLSLVertexBuilder* v = args.fVertBuilder;
// Are we clockwise? (Positive wind => nonzero fill rule.)
// Or counter-clockwise? (negative wind => even/odd fill rule.)
v->codeAppendf("float wind = sign(devbounds.z - devbounds.x);");
@ -229,10 +230,7 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
this->writeLocalCoord(v, args.fUniformHandler, gpArgs, gpArgs->fPositionVar, proc.fLocalMatrix,
&fLocalMatrixUni);
// Fragment shader.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
// Look up coverage in the atlas.
// Fragment shader. Look up coverage in the atlas.
f->codeAppendf("half coverage = ");
f->appendTextureLookup(args.fTexSamplers[0], SkStringPrintf("%s.xy", texcoord.fsIn()).c_str());
f->codeAppendf(".a;");
@ -250,5 +248,5 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
f->codeAppend ("coverage = 1 - abs(fract(coverage) * 2 - 1);");
}
f->codeAppendf("%s = half4(coverage);", args.fOutputCoverage);
f->codeAppendf("half4 %s = half4(coverage);", args.fOutputCoverage);
}

View File

@ -76,6 +76,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
// Setup position
@ -146,10 +147,10 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
kFloat_GrSLType,
"Coverage",
&coverageScale);
fragBuilder->codeAppendf("%s = half4(half(%s) * %s);",
fragBuilder->codeAppendf("half4 %s = half4(half(%s) * %s);",
args.fOutputCoverage, coverageScale, edgeAlpha.c_str());
} else {
fragBuilder->codeAppendf("%s = half4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
fragBuilder->codeAppendf("half4 %s = half4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
}
}
@ -271,6 +272,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
// Setup position
@ -306,10 +308,10 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
kHalf_GrSLType,
"Coverage",
&coverageScale);
fragBuilder->codeAppendf("%s = half4(%s * edgeAlpha);", args.fOutputCoverage,
fragBuilder->codeAppendf("half4 %s = half4(%s * edgeAlpha);", args.fOutputCoverage,
coverageScale);
} else {
fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(edgeAlpha);", args.fOutputCoverage);
}
}

View File

@ -45,6 +45,7 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
if (btgp.hasVertexColor()) {
varyingHandler->addPassThroughAttribute(btgp.inColor(), args.fOutputColor);
} else {
@ -64,9 +65,9 @@ public:
if (btgp.maskFormat() == kARGB_GrMaskFormat) {
// modulate by color
fragBuilder->codeAppendf("%s = %s * texColor;", args.fOutputColor, args.fOutputColor);
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
} else {
fragBuilder->codeAppendf("%s = texColor;", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = texColor;", args.fOutputCoverage);
}
}

View File

@ -53,6 +53,7 @@ public:
#endif
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;\n", args.fOutputColor);
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
// Setup position
@ -152,7 +153,7 @@ public:
fragBuilder->codeAppend("half val = smoothstep(-afwidth, afwidth, distance);");
}
fragBuilder->codeAppendf("%s = half4(val);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(val);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
@ -342,6 +343,7 @@ public:
&texIdx, &st);
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(dfPathEffect.inColor(), args.fOutputColor);
if (dfPathEffect.matrix().hasPerspective()) {
@ -436,7 +438,7 @@ public:
fragBuilder->codeAppend("half val = smoothstep(-afwidth, afwidth, distance);");
}
fragBuilder->codeAppendf("%s = half4(val);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(val);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
@ -604,6 +606,7 @@ public:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// setup pass through color
fragBuilder->codeAppendf("half4 %s;\n", args.fOutputColor);
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
// Setup position
@ -735,13 +738,13 @@ public:
// doing gamma-correct rendering (to an sRGB or F16 buffer), then we actually want distance
// mapped linearly to coverage, so use a linear step:
if (isGammaCorrect) {
fragBuilder->codeAppendf("%s = "
"half4(saturate((distance + half3(afwidth)) / half3(2.0 * afwidth)), 1.0);",
args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = "
"half4(saturate((distance + half3(afwidth)) / half3(2.0 * afwidth)), 1.0);",
args.fOutputCoverage);
} else {
fragBuilder->codeAppendf(
"%s = half4(smoothstep(half3(-afwidth), half3(afwidth), distance), 1.0);",
args.fOutputCoverage);
"half4 %s = half4(smoothstep(half3(-afwidth), half3(afwidth), distance), 1.0);",
args.fOutputCoverage);
}
}

View File

@ -30,6 +30,7 @@ public:
varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams");
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(rsgp.inColor(), args.fOutputColor);
// Setup position
@ -41,7 +42,7 @@ public:
fragBuilder->codeAppend("half factor = ");
fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv");
fragBuilder->codeAppend(".a;");
fragBuilder->codeAppendf("%s = half4(factor);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(factor);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {

View File

@ -157,6 +157,7 @@ SkString GrGLSLProgramBuilder::emitFragProc(const GrFragmentProcessor& fp,
// Program builders have a bit of state we need to clear with each effect
AutoStageAdvance adv(this);
this->nameExpression(&output, "output");
fFS.codeAppendf("half4 %s;", output.c_str());
int samplerIdx = 0;
for (auto [subFP, subGLSLFP] : GrGLSLFragmentProcessor::ParallelRange(fp, glslFP)) {
@ -317,7 +318,6 @@ void GrGLSLProgramBuilder::nameExpression(SkString* output, const char* baseName
} else {
outName = this->nameVariable(/*prefix=*/'\0', baseName);
}
fFS.codeAppendf("half4 %s;", outName.c_str());
*output = outName;
}

View File

@ -568,6 +568,7 @@ public:
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const QuadEdgeEffect& qe = args.fGP.cast<QuadEdgeEffect>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
@ -581,10 +582,9 @@ public:
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.fInQuadEdge.name());
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(qe.fInColor, args.fOutputColor);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, qe.fInPosition.name());
if (qe.fUsesLocalCoords) {
@ -611,7 +611,7 @@ public:
fragBuilder->codeAppendf("edgeAlpha = "
"saturate(0.5 - edgeAlpha / length(gF));}");
fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(edgeAlpha);", args.fOutputCoverage);
}
static inline void GenKey(const GrGeometryProcessor& gp,

View File

@ -912,6 +912,7 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
// Setup position
@ -937,7 +938,7 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
fragBuilder->codeAppendf("half alpha = 1.0;");
fragBuilder->codeAppendf("alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circleParams.fsIn());
}
fragBuilder->codeAppendf("%s = half4(alpha);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(alpha);", args.fOutputCoverage);
}
void GLDashingCircleEffect::setData(const GrGLSLProgramDataManager& pdman,
@ -1115,6 +1116,7 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
// Setup position
@ -1164,7 +1166,7 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
fragBuilder->codeAppendf("alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;",
inRectParams.fsIn());
}
fragBuilder->codeAppendf("%s = half4(alpha);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(alpha);", args.fOutputCoverage);
}
void GLDashingLineEffect::setData(const GrGLSLProgramDataManager& pdman,

View File

@ -154,6 +154,7 @@ public:
kVertex_GrShaderFlag);
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
if (gp.colorAttr().isInitialized()) {
GrGLSLVarying varying(kHalf4_GrSLType);
varyingHandler->addVarying("color", &varying);
@ -295,7 +296,7 @@ public:
fragBuilder->codeAppendf("%s = %s;", var.c_str(), varying.fsIn());
}
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
static inline void GenKey(const GrGeometryProcessor& gp,

View File

@ -475,6 +475,9 @@ void FillRRectOp::onPrepareDraws(Target* target) {
class FillRRectOp::Processor::Impl : public GrGLSLGeometryProcessor {
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
GrGLSLVertexBuilder* v = args.fVertBuilder;
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
const auto& proc = args.fGP.cast<Processor>();
bool useHWDerivatives = (proc.fFlags & ProcessorFlags::kUseHWDerivatives);
@ -482,12 +485,11 @@ class FillRRectOp::Processor::Impl : public GrGLSLGeometryProcessor {
GrGLSLVaryingHandler* varyings = args.fVaryingHandler;
varyings->emitAttributes(proc);
f->codeAppendf("half4 %s;", args.fOutputColor);
varyings->addPassThroughAttribute(*proc.fColorAttrib, args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
// Emit the vertex shader.
GrGLSLVertexBuilder* v = args.fVertBuilder;
// When MSAA is enabled, we need to make sure every sample gets lit up on pixels that have
// fractional coverage. We do this by making the ramp wider.
v->codeAppendf("float aa_bloat_multiplier = %i;",
@ -627,8 +629,6 @@ class FillRRectOp::Processor::Impl : public GrGLSLGeometryProcessor {
v->codeAppend("}");
// Emit the fragment shader.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
f->codeAppendf("float x_plus_1=%s.x, y=%s.y;", arcCoord.fsIn(), arcCoord.fsIn());
f->codeAppendf("half coverage;");
f->codeAppendf("if (0 == x_plus_1) {");
@ -656,7 +656,7 @@ class FillRRectOp::Processor::Impl : public GrGLSLGeometryProcessor {
if (proc.fFlags & ProcessorFlags::kFakeNonAA) {
f->codeAppendf("coverage = (coverage >= .5) ? 1 : 0;");
}
f->codeAppendf("%s = half4(coverage);", args.fOutputCoverage);
f->codeAppendf("half4 %s = half4(coverage);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&) override {}

View File

@ -71,6 +71,7 @@ public:
args.fFragBuilder->codeAppend("float4 textureDomain;");
args.fVaryingHandler->addPassThroughAttribute(
latticeGP.fInTextureDomain, "textureDomain", Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
args.fVaryingHandler->addPassThroughAttribute(latticeGP.fInColor,
args.fOutputColor,
Interpolation::kCanBeFlat);
@ -82,7 +83,7 @@ public:
"clamp(textureCoords, textureDomain.xy, textureDomain.zw)",
&fColorSpaceXformHelper);
args.fFragBuilder->codeAppend(";");
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
GrGLSLColorSpaceXformHelper fColorSpaceXformHelper;
};

View File

@ -152,6 +152,7 @@ private:
}
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(cgp.fInColor, args.fOutputColor);
// Setup position
@ -199,7 +200,7 @@ private:
capRadius.fsIn(), capRadius.fsIn());
}
}
fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(edgeAlpha);", args.fOutputCoverage);
}
static void GenKey(const GrGeometryProcessor& gp,
@ -381,6 +382,7 @@ private:
fragBuilder->codeAppendf("half lastIntervalLength = %s;", lastIntervalLength.fsIn());
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(
bcscgp.fInColor, args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
@ -462,7 +464,7 @@ private:
edgeAlpha *= dashAlpha;
)", fnName.c_str(), fnName.c_str(), fnName.c_str(), fnName.c_str(), fnName.c_str(),
fnName.c_str());
fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(edgeAlpha);", args.fOutputCoverage);
}
static void GenKey(const GrGeometryProcessor& gp,
@ -580,6 +582,7 @@ private:
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(egp.fInColor, args.fOutputColor);
// Setup position
@ -651,7 +654,7 @@ private:
fragBuilder->codeAppend("edgeAlpha *= saturate(0.5+test*invlen);");
}
fragBuilder->codeAppendf("%s = half4(half(edgeAlpha));", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(half(edgeAlpha));", args.fOutputCoverage);
}
static void GenKey(const GrGeometryProcessor& gp,
@ -776,6 +779,7 @@ private:
vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), diegp.fInEllipseOffsets1.name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(diegp.fInColor, args.fOutputColor);
// Setup position
@ -843,7 +847,7 @@ private:
fragBuilder->codeAppend("edgeAlpha *= saturate(0.5+test*invlen);");
}
fragBuilder->codeAppendf("%s = half4(half(edgeAlpha));", args.fOutputCoverage);
fragBuilder->codeAppendf("half4 %s = half4(half(edgeAlpha));", args.fOutputCoverage);
}
static void GenKey(const GrGeometryProcessor& gp,

View File

@ -640,15 +640,19 @@ public:
gpArgs->fLocalCoordVar = gp.fLocalCoord.asShaderVar();
// Solid color before any texturing gets modulated in
const char* blendDst;
if (gp.fColor.isInitialized()) {
SkASSERT(gp.fCoverageMode != CoverageMode::kWithColor || !gp.fNeedsPerspective);
// The color cannot be flat if the varying coverage has been modulated into it
args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
args.fVaryingHandler->addPassThroughAttribute(gp.fColor, args.fOutputColor,
gp.fCoverageMode == CoverageMode::kWithColor ?
Interpolation::kInterpolated : Interpolation::kCanBeFlat);
blendDst = args.fOutputColor;
} else {
// Output color must be initialized to something
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputColor);
args.fFragBuilder->codeAppendf("half4 %s = half4(1);", args.fOutputColor);
blendDst = nullptr;
}
// If there is a texture, must also handle texture coordinates and reading from
@ -675,19 +679,18 @@ public:
args.fVaryingHandler->addPassThroughAttribute(gp.fTexSubset, "subset",
Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppend(
"texCoord = clamp(texCoord, subset.xy, subset.zw);");
"texCoord = clamp(texCoord, subset.LT, subset.RB);");
}
// Now modulate the starting output color by the texture lookup
args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor);
args.fFragBuilder->codeAppendf(
"%s = %s(",
args.fOutputColor,
(gp.fSaturate == Saturate::kYes) ? "saturate" : "");
args.fFragBuilder->appendTextureLookupAndBlend(
args.fOutputColor, SkBlendMode::kModulate, args.fTexSamplers[0],
blendDst, SkBlendMode::kModulate, args.fTexSamplers[0],
"texCoord", &fTextureColorSpaceXformHelper);
args.fFragBuilder->codeAppend(";");
if (gp.fSaturate == Saturate::kYes) {
args.fFragBuilder->codeAppendf("%s = saturate(%s);",
args.fOutputColor, args.fOutputColor);
}
args.fFragBuilder->codeAppend(");");
} else {
// Saturate is only intended for use with a proxy to account for the fact
// that GrTextureOp skips SkPaint conversion, which normally handles this.
@ -740,13 +743,14 @@ public:
#endif
}
args.fFragBuilder->codeAppendf("%s = half4(half(coverage));",
args.fFragBuilder->codeAppendf("half4 %s = half4(half(coverage));",
args.fOutputCoverage);
} else {
// Set coverage to 1, since it's either non-AA or the coverage was already
// folded into the output color
SkASSERT(!gp.fGeomSubset.isInitialized());
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("const half4 %s = half4(1);",
args.fOutputCoverage);
}
}
GrGLSLColorSpaceXformHelper fTextureColorSpaceXformHelper;

View File

@ -63,6 +63,7 @@ class DrawAtlasPathShader::Impl : public GrGLSLGeometryProcessor {
args.fVaryingHandler->addVarying("atlascoord", &atlasCoord);
GrGLSLVarying color(kHalf4_GrSLType);
args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
args.fVaryingHandler->addPassThroughAttribute(
kInstanceAttribs[2], args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
@ -92,7 +93,7 @@ class DrawAtlasPathShader::Impl : public GrGLSLGeometryProcessor {
gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
}
args.fFragBuilder->codeAppendf("%s = ", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("half4 %s = ", args.fOutputCoverage);
args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], atlasCoord.fsIn());
args.fFragBuilder->codeAppendf(".aaaa;");
}

View File

@ -33,8 +33,8 @@ public:
fColorUniform = args.fUniformHandler->addUniform(
nullptr, kFragment_GrShaderFlag, kHalf4_GrSLType, "color", &color);
args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, color);
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("half4 %s = %s;", args.fOutputColor, color);
args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman,

View File

@ -401,16 +401,16 @@ private:
const char* colorUniformName;
fColorUniform = uniHandler->addUniform(nullptr, kFragment_GrShaderFlag, kHalf4_GrSLType,
"color", &colorUniformName);
args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUniformName);
args.fFragBuilder->codeAppendf("half4 %s = %s;", args.fOutputColor, colorUniformName);
} else {
// Color gets passed in from the tess evaluation shader.
SkString flatness(args.fShaderCaps->preferFlatInterpolation() ? "flat" : "");
args.fFragBuilder->declareGlobal(GrShaderVar(SkString("tesColor"), kHalf4_GrSLType,
TypeModifier::In, 0, SkString(),
flatness));
args.fFragBuilder->codeAppendf("%s = tesColor;", args.fOutputColor);
args.fFragBuilder->codeAppendf("half4 %s = tesColor;", args.fOutputColor);
}
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman,
@ -1244,14 +1244,15 @@ class GrStrokeTessellateShader::IndirectImpl : public GrGLSLGeometryProcessor {
const char* colorUniformName;
fColorUniform = args.fUniformHandler->addUniform(
nullptr, kFragment_GrShaderFlag, kHalf4_GrSLType, "color", &colorUniformName);
args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUniformName);
args.fFragBuilder->codeAppendf("half4 %s = %s;", args.fOutputColor, colorUniformName);
} else {
// Color gets passed in through an instance attrib.
args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
args.fVaryingHandler->addPassThroughAttribute(
shader.fAttribs.back(), args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
}
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman,

View File

@ -498,12 +498,14 @@ class GLSLMeshTestProcessor : public GrGLSLGeometryProcessor {
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
const GrMeshTestProcessor& mp = args.fGP.cast<GrMeshTestProcessor>();
GrGLSLVertexBuilder* v = args.fVertBuilder;
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
varyingHandler->emitAttributes(mp);
f->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(mp.inColor(), args.fOutputColor);
GrGLSLVertexBuilder* v = args.fVertBuilder;
if (!mp.fInstanceLocation.isInitialized()) {
v->codeAppendf("float2 vertex = %s;", mp.fVertexPosition.name());
} else {
@ -517,8 +519,7 @@ class GLSLMeshTestProcessor : public GrGLSLGeometryProcessor {
}
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertex");
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
f->codeAppendf("%s = half4(1);", args.fOutputCoverage);
f->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
};

View File

@ -95,17 +95,17 @@ class GLSLPipelineDynamicStateTestProcessor : public GrGLSLGeometryProcessor {
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
const GrPipelineDynamicStateTestProcessor& mp =
args.fGP.cast<GrPipelineDynamicStateTestProcessor>();
GrGLSLVertexBuilder* v = args.fVertBuilder;
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
varyingHandler->emitAttributes(mp);
f->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(mp.inColor(), args.fOutputColor);
GrGLSLVertexBuilder* v = args.fVertBuilder;
v->codeAppendf("float2 vertex = %s;", mp.inVertex().name());
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertex");
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
f->codeAppendf("%s = half4(1);", args.fOutputCoverage);
f->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
};

View File

@ -83,8 +83,9 @@ private:
this->writeOutputPosition(args.fVertBuilder, gpArgs,
gp.fAttributes[0].name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputColor);
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputColor);
fragBuilder->codeAppendf("const half4 %s = half4(1);",
args.fOutputCoverage);
}
void setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& primProc) override {}

View File

@ -63,8 +63,9 @@ private:
args.fVaryingHandler->addVarying("color", &colorVarying,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
args.fVertBuilder->codeAppendf("%s = %s;", colorVarying.vsOut(), gp.fInColor.name());
args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorVarying.fsIn());
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("half4 %s = %s;",
args.fOutputColor, colorVarying.fsIn());
args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
this->writeOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name());
this->writeLocalCoord(args.fVertBuilder, args.fUniformHandler, gpArgs,
gp.fInLocalCoords.asShaderVar(), gp.fLocalMatrix,