ccpr: Use a more stable formula to find quadratic coordinates

The 3x3 inverse grew unstable on small curves with large coordinates,
not to mention being inefficient. This fixes many bad pixels on the
chalkboard.

Also begins scaling curve gradients by the AA bloat, in order to match
triangle edges more closely and visualize curve AA in the ccpr sample.

Bug: skia:
Change-Id: I0f7da2e7599d4d5c458b3dd307185679dc78bb50
Reviewed-on: https://skia-review.googlesource.com/115527
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Chris Dalton 2018-03-21 12:14:10 -06:00 committed by Skia Commit-Bot
parent ca37f32c70
commit 52076d1df5
4 changed files with 23 additions and 23 deletions

View File

@ -310,7 +310,7 @@ void CCPRGeometryView::DrawCoverageCountOp::drawRenderPass(GrOpFlushState* state
SkDEBUGCODE(proc.enableDebugBloat(kDebugBloat));
SkSTArray<1, GrMesh> mesh;
if (RenderPass::kCubics == renderPass) {
if (GrCCCoverageProcessor::RenderPassIsCubic(renderPass)) {
sk_sp<GrBuffer> instBuff(rp->createBuffer(
fView->fQuadPointInstances.count() * sizeof(QuadPointInstance),
kVertex_GrBufferType, kDynamic_GrAccessPattern,

View File

@ -112,9 +112,10 @@ void GrCCCubicHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
fGradMatrix.reset(kFloat2x2_GrSLType, scope);
varyingHandler->addVarying("grad_matrix", &fGradMatrix);
// "klm" was just defined by the base class.
code->appendf("%s[0] = 3 * klm[0] * %s[0].xy;", OutName(fGradMatrix), fKLMMatrix.c_str());
code->appendf("%s[1] = -klm[1] * %s[2].xy - klm[2] * %s[1].xy;",
OutName(fGradMatrix), fKLMMatrix.c_str(), fKLMMatrix.c_str());
code->appendf("%s[0] = 2*bloat * 3 * klm[0] * %s[0].xy;",
OutName(fGradMatrix), fKLMMatrix.c_str());
code->appendf("%s[1] = -2*bloat * (klm[1] * %s[2].xy + klm[2] * %s[1].xy);",
OutName(fGradMatrix), fKLMMatrix.c_str(), fKLMMatrix.c_str());
}
void GrCCCubicHullShader::emitCoverage(GrGLSLFPFragmentBuilder* f,
@ -138,13 +139,13 @@ void GrCCCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
fdKLMDdx.reset(kFloat4_GrSLType, scope);
varyingHandler->addVarying("dklmddx", &fdKLMDdx, Interpolation::kCanBeFlat);
code->appendf("%s = float4(%s[0].x, %s[1].x, %s[2].x, %s.x);",
code->appendf("%s = 2*bloat * float4(%s[0].x, %s[1].x, %s[2].x, %s.x);",
OutName(fdKLMDdx), fKLMMatrix.c_str(), fKLMMatrix.c_str(),
fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str());
fdKLMDdy.reset(kFloat4_GrSLType, scope);
varyingHandler->addVarying("dklmddy", &fdKLMDdy, Interpolation::kCanBeFlat);
code->appendf("%s = float4(%s[0].y, %s[1].y, %s[2].y, %s.y);",
code->appendf("%s = 2*bloat * float4(%s[0].y, %s[1].y, %s[2].y, %s.y);",
OutName(fdKLMDdy), fKLMMatrix.c_str(), fKLMMatrix.c_str(),
fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str());
}

View File

@ -16,14 +16,12 @@ using Shader = GrCCCoverageProcessor::Shader;
void GrCCQuadraticShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, const char* wind,
GeometryVars* vars) const {
s->declareGlobal(fCanonicalMatrix);
s->codeAppendf("%s = float3x3(0.0, 0, 1, "
"0.5, 0, 1, "
"1.0, 1, 1) * "
"inverse(float3x3(%s[0], 1, "
"%s[1], 1, "
"%s[2], 1));",
fCanonicalMatrix.c_str(), pts, pts, pts);
s->declareGlobal(fQCoordMatrix);
s->codeAppendf("%s = float2x2(1, 1, .5, 0) * inverse(float2x2(%s[2] - %s[0], %s[1] - %s[0]));",
fQCoordMatrix.c_str(), pts, pts, pts, pts);
s->declareGlobal(fQCoord0);
s->codeAppendf("%s = %s[0];", fQCoord0.c_str(), pts);
s->declareGlobal(fEdgeDistanceEquation);
s->codeAppendf("float2 edgept0 = %s[%s > 0 ? 2 : 0];", pts, wind);
@ -42,8 +40,8 @@ void GrCCQuadraticShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
fXYDW.reset(kFloat4_GrSLType, scope);
varyingHandler->addVarying("xydw", &fXYDW);
code->appendf("%s.xy = (%s * float3(%s, 1)).xy;",
OutName(fXYDW), fCanonicalMatrix.c_str(), position);
code->appendf("%s.xy = %s * (%s - %s);",
OutName(fXYDW), fQCoordMatrix.c_str(), position, fQCoord0.c_str());
code->appendf("%s.z = dot(%s.xy, %s) + %s.z;",
OutName(fXYDW), fEdgeDistanceEquation.c_str(), position,
fEdgeDistanceEquation.c_str());
@ -81,8 +79,8 @@ void GrCCQuadraticHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandle
GrGLSLVarying::Scope scope, SkString* code) {
fGrad.reset(kFloat2_GrSLType, scope);
varyingHandler->addVarying("grad", &fGrad);
code->appendf("%s = float2(2 * %s.x, -1) * float2x2(%s);",
OutName(fGrad), OutName(fXYDW), fCanonicalMatrix.c_str());
code->appendf("%s = 2*bloat * float2(2 * %s.x, -1) * %s;",
OutName(fGrad), OutName(fXYDW), fQCoordMatrix.c_str());
}
void GrCCQuadraticHullShader::emitCoverage(GrGLSLFPFragmentBuilder* f,
@ -106,14 +104,14 @@ void GrCCQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHand
fdXYDdx.reset(kFloat3_GrSLType, scope);
varyingHandler->addVarying("dXYDdx", &fdXYDdx, Interpolation::kCanBeFlat);
code->appendf("%s = float3(%s[0].x, %s[0].y, %s.x);",
OutName(fdXYDdx), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(),
code->appendf("%s = 2*bloat * float3(%s[0].x, %s[0].y, %s.x);",
OutName(fdXYDdx), fQCoordMatrix.c_str(), fQCoordMatrix.c_str(),
fEdgeDistanceEquation.c_str());
fdXYDdy.reset(kFloat3_GrSLType, scope);
varyingHandler->addVarying("dXYDdy", &fdXYDdy, Interpolation::kCanBeFlat);
code->appendf("%s = float3(%s[1].x, %s[1].y, %s.y);",
OutName(fdXYDdy), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(),
code->appendf("%s = 2*bloat * float3(%s[1].x, %s[1].y, %s.y);",
OutName(fdXYDdy), fQCoordMatrix.c_str(), fQCoordMatrix.c_str(),
fEdgeDistanceEquation.c_str());
}

View File

@ -35,7 +35,8 @@ protected:
void onEmitFragmentCode(GrGLSLFPFragmentBuilder*, const char* outputCoverage) const final;
virtual void emitCoverage(GrGLSLFPFragmentBuilder*, const char* outputCoverage) const = 0;
const GrShaderVar fCanonicalMatrix{"canonical_matrix", kFloat3x3_GrSLType};
const GrShaderVar fQCoordMatrix{"qcoord_matrix", kFloat2x2_GrSLType};
const GrShaderVar fQCoord0{"qcoord0", kFloat2_GrSLType};
const GrShaderVar fEdgeDistanceEquation{"edge_distance_equation", kFloat3_GrSLType};
GrGLSLVarying fXYDW;
};