Delete identity matrix shaders from tessellation
Every shader always has a matrix now. The 4 FMAs (literally) that this saved by specializing the shader weren't worth it. Bug: skia:10419 Change-Id: I506dbd6d723f6dd022345956fdb5b60b0dd94932 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/412416 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
parent
e1c2beb3be
commit
64d06ba897
@ -17,14 +17,18 @@ public:
|
||||
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
|
||||
auto& shader = args.fGeomProc.cast<GrFillPathShader>();
|
||||
|
||||
const char* viewMatrix;
|
||||
fViewMatrixUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat3x3_GrSLType, "view_matrix", &viewMatrix);
|
||||
|
||||
args.fVaryingHandler->emitAttributes(shader);
|
||||
|
||||
const char* affineMatrix, *translate;
|
||||
fAffineMatrixUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "affineMatrix", &affineMatrix);
|
||||
fTranslateUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "translate", &translate);
|
||||
|
||||
args.fVertBuilder->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);", affineMatrix);
|
||||
args.fVertBuilder->codeAppendf("float2 TRANSLATE = %s;", translate);
|
||||
args.fVertBuilder->codeAppend("float2 localcoord, vertexpos;");
|
||||
shader.emitVertexCode(this, args.fVertBuilder, viewMatrix, args.fUniformHandler);
|
||||
shader.emitVertexCode(this, args.fVertBuilder, args.fUniformHandler);
|
||||
|
||||
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertexpos");
|
||||
gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
|
||||
@ -41,13 +45,16 @@ public:
|
||||
const GrShaderCaps&,
|
||||
const GrGeometryProcessor& geomProc) override {
|
||||
const GrFillPathShader& shader = geomProc.cast<GrFillPathShader>();
|
||||
pdman.setSkMatrix(fViewMatrixUniform, shader.viewMatrix());
|
||||
const SkMatrix& m = shader.viewMatrix();
|
||||
pdman.set4f(fAffineMatrixUniform, m.getScaleX(), m.getSkewY(), m.getSkewX(), m.getScaleY());
|
||||
pdman.set2f(fTranslateUniform, m.getTranslateX(), m.getTranslateY());
|
||||
|
||||
const SkPMColor4f& color = shader.fColor;
|
||||
pdman.set4f(fColorUniform, color.fR, color.fG, color.fB, color.fA);
|
||||
}
|
||||
|
||||
GrGLSLUniformHandler::UniformHandle fViewMatrixUniform;
|
||||
GrGLSLUniformHandler::UniformHandle fAffineMatrixUniform;
|
||||
GrGLSLUniformHandler::UniformHandle fTranslateUniform;
|
||||
GrGLSLUniformHandler::UniformHandle fColorUniform;
|
||||
};
|
||||
|
||||
@ -55,14 +62,14 @@ GrGLSLGeometryProcessor* GrFillPathShader::createGLSLInstance(const GrShaderCaps
|
||||
return new Impl;
|
||||
}
|
||||
|
||||
void GrFillTriangleShader::emitVertexCode(Impl*, GrGLSLVertexBuilder* v, const char* viewMatrix,
|
||||
void GrFillTriangleShader::emitVertexCode(Impl*, GrGLSLVertexBuilder* v,
|
||||
GrGLSLUniformHandler* uniformHandler) const {
|
||||
v->codeAppendf(R"(
|
||||
v->codeAppend(R"(
|
||||
localcoord = input_point;
|
||||
vertexpos = (%s * float3(localcoord, 1)).xy;)", viewMatrix);
|
||||
vertexpos = AFFINE_MATRIX * localcoord + TRANSLATE;)");
|
||||
}
|
||||
|
||||
void GrFillCubicHullShader::emitVertexCode(Impl*, GrGLSLVertexBuilder* v, const char* viewMatrix,
|
||||
void GrFillCubicHullShader::emitVertexCode(Impl*, GrGLSLVertexBuilder* v,
|
||||
GrGLSLUniformHandler* uniformHandler) const {
|
||||
v->codeAppend(R"(
|
||||
float4x2 P = float4x2(input_points_0_1, input_points_2_3);
|
||||
@ -118,21 +125,19 @@ void GrFillCubicHullShader::emitVertexCode(Impl*, GrGLSLVertexBuilder* v, const
|
||||
vertexidx = (vertexidx + 1) & 3;
|
||||
}
|
||||
|
||||
localcoord = P[vertexidx];)");
|
||||
|
||||
v->codeAppendf("vertexpos = (%s * float3(localcoord, 1)).xy;", viewMatrix);
|
||||
localcoord = P[vertexidx];
|
||||
vertexpos = AFFINE_MATRIX * localcoord + TRANSLATE;)");
|
||||
}
|
||||
|
||||
void GrFillBoundingBoxShader::emitVertexCode(Impl* impl, GrGLSLVertexBuilder* v,
|
||||
const char* viewMatrix,
|
||||
GrGLSLUniformHandler* uniformHandler) const {
|
||||
v->codeAppendf(R"(
|
||||
// Bloat the bounding box by 1/4px to avoid potential T-junctions at the edges.
|
||||
float2x2 M_ = inverse(float2x2(%s));
|
||||
float2x2 M_ = inverse(AFFINE_MATRIX);
|
||||
float2 bloat = float2(abs(M_[0]) + abs(M_[1])) * .25;
|
||||
|
||||
// Find the vertex position.
|
||||
float2 T = float2(sk_VertexID & 1, sk_VertexID >> 1);
|
||||
localcoord = mix(pathBounds.xy - bloat, pathBounds.zw + bloat, T);
|
||||
vertexpos = (%s * float3(localcoord, 1)).xy;)", viewMatrix, viewMatrix);
|
||||
vertexpos = AFFINE_MATRIX * localcoord + TRANSLATE;)");
|
||||
}
|
||||
|
@ -56,8 +56,7 @@ public:
|
||||
protected:
|
||||
class Impl;
|
||||
|
||||
virtual void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix,
|
||||
GrGLSLUniformHandler*) const = 0;
|
||||
virtual void emitVertexCode(Impl*, GrGLSLVertexBuilder*, GrGLSLUniformHandler*) const = 0;
|
||||
|
||||
private:
|
||||
const SkPMColor4f fColor;
|
||||
@ -76,8 +75,7 @@ public:
|
||||
|
||||
private:
|
||||
const char* name() const override { return "GrFillTriangleShader"; }
|
||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix,
|
||||
GrGLSLUniformHandler*) const override;
|
||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, GrGLSLUniformHandler*) const override;
|
||||
};
|
||||
|
||||
// Fills an array of convex hulls surrounding 4-point cubic instances.
|
||||
@ -94,8 +92,7 @@ public:
|
||||
|
||||
private:
|
||||
const char* name() const override { return "GrFillCubicHullShader"; }
|
||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix,
|
||||
GrGLSLUniformHandler*) const override;
|
||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, GrGLSLUniformHandler*) const override;
|
||||
};
|
||||
|
||||
// Fills a path's bounding box, with subpixel outset to avoid possible T-junctions with extreme
|
||||
@ -114,8 +111,7 @@ public:
|
||||
|
||||
private:
|
||||
const char* name() const override { return "GrFillBoundingBoxShader"; }
|
||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix,
|
||||
GrGLSLUniformHandler*) const override;
|
||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, GrGLSLUniformHandler*) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -57,24 +57,23 @@ protected:
|
||||
args.fVaryingHandler->emitAttributes(shader);
|
||||
auto v = args.fVertBuilder;
|
||||
|
||||
GrShaderVar vertexPos = (*shader.vertexAttributes().begin()).asShaderVar();
|
||||
if (!shader.viewMatrix().isIdentity()) {
|
||||
const char* viewMatrix;
|
||||
fViewMatrixUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat3x3_GrSLType, "view_matrix", &viewMatrix);
|
||||
v->codeAppendf("float2 vertexpos = (%s * float3(inputPoint, 1)).xy;", viewMatrix);
|
||||
const char* affineMatrix, *translate;
|
||||
fAffineMatrixUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "affineMatrix", &affineMatrix);
|
||||
fTranslateUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "translate", &translate);
|
||||
v->codeAppendf("float2 vertexpos = float2x2(%s) * inputPoint + %s;",
|
||||
affineMatrix, translate);
|
||||
if (shader.willUseTessellationShaders()) {
|
||||
// If y is infinity then x is a conic weight. Don't transform.
|
||||
v->codeAppendf("vertexpos = (isinf(inputPoint.y)) ? inputPoint : vertexpos;");
|
||||
}
|
||||
vertexPos.set(kFloat2_GrSLType, "vertexpos");
|
||||
}
|
||||
|
||||
if (!shader.willUseTessellationShaders()) { // This is the case for the triangle shader.
|
||||
gpArgs->fPositionVar = vertexPos;
|
||||
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertexpos");
|
||||
} else {
|
||||
v->declareGlobal(GrShaderVar("P", kFloat2_GrSLType, GrShaderVar::TypeModifier::Out));
|
||||
v->codeAppendf("P = %s;", vertexPos.c_str());
|
||||
v->codeAppendf("P = %s;", "vertexpos");
|
||||
}
|
||||
|
||||
// The fragment shader is normally disabled, but output fully opaque white.
|
||||
@ -85,13 +84,13 @@ protected:
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrShaderCaps&,
|
||||
const GrGeometryProcessor& geomProc) override {
|
||||
const auto& shader = geomProc.cast<GrStencilPathShader>();
|
||||
if (!shader.viewMatrix().isIdentity()) {
|
||||
pdman.setSkMatrix(fViewMatrixUniform, shader.viewMatrix());
|
||||
}
|
||||
const SkMatrix& m = geomProc.cast<GrStencilPathShader>().viewMatrix();
|
||||
pdman.set4f(fAffineMatrixUniform, m.getScaleX(), m.getSkewY(), m.getSkewX(), m.getScaleY());
|
||||
pdman.set2f(fTranslateUniform, m.getTranslateX(), m.getTranslateY());
|
||||
}
|
||||
|
||||
GrGLSLUniformHandler::UniformHandle fViewMatrixUniform;
|
||||
GrGLSLUniformHandler::UniformHandle fAffineMatrixUniform;
|
||||
GrGLSLUniformHandler::UniformHandle fTranslateUniform;
|
||||
};
|
||||
|
||||
GrGLSLGeometryProcessor* GrStencilPathShader::createGLSLInstance(const GrShaderCaps&) const {
|
||||
@ -375,13 +374,13 @@ class GrCurveMiddleOutShader::Impl : public GrStencilPathShader::Impl {
|
||||
float T = find_middle_out_T();
|
||||
pos = eval_rational_cubic(P, T);
|
||||
})");
|
||||
if (!shader.viewMatrix().isIdentity()) {
|
||||
const char* viewMatrix;
|
||||
fViewMatrixUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat3x3_GrSLType, "view_matrix", &viewMatrix);
|
||||
const char* affineMatrix, *translate;
|
||||
fAffineMatrixUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "affineMatrix", &affineMatrix);
|
||||
fTranslateUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "translate", &translate);
|
||||
args.fVertBuilder->codeAppendf(R"(
|
||||
pos = (%s * float3(pos, 1)).xy;)", viewMatrix);
|
||||
}
|
||||
pos = float2x2(%s) * pos + %s;)", affineMatrix, translate);
|
||||
gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos");
|
||||
|
||||
// The fragment shader is normally disabled, but output fully opaque white.
|
||||
|
@ -85,9 +85,7 @@ public:
|
||||
protected:
|
||||
constexpr static Attribute kSinglePointAttrib{"inputPoint", kFloat2_GrVertexAttribType,
|
||||
kFloat2_GrSLType};
|
||||
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
|
||||
b->add32(this->viewMatrix().isIdentity());
|
||||
}
|
||||
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {}
|
||||
GrGLSLGeometryProcessor* createGLSLInstance(const GrShaderCaps&) const override;
|
||||
|
||||
class Impl;
|
||||
|
@ -79,17 +79,15 @@ void GrStrokeInstancedShaderImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
}
|
||||
|
||||
// View matrix uniforms.
|
||||
if (!shader.viewMatrix().isIdentity()) {
|
||||
const char* translateName, *affineMatrixName;
|
||||
fAffineMatrixUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "affineMatrix",
|
||||
fAffineMatrixUniform = args.fUniformHandler->addUniform(nullptr, kVertex_GrShaderFlag,
|
||||
kFloat4_GrSLType, "affineMatrix",
|
||||
&affineMatrixName);
|
||||
fTranslateUniform = args.fUniformHandler->addUniform(
|
||||
nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "translate", &translateName);
|
||||
args.fVertBuilder->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n",
|
||||
affineMatrixName);
|
||||
fTranslateUniform = args.fUniformHandler->addUniform(nullptr, kVertex_GrShaderFlag,
|
||||
kFloat2_GrSLType, "translate",
|
||||
&translateName);
|
||||
args.fVertBuilder->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n", affineMatrixName);
|
||||
args.fVertBuilder->codeAppendf("float2 TRANSLATE = %s;\n", translateName);
|
||||
}
|
||||
|
||||
// Tessellation code.
|
||||
args.fVertBuilder->codeAppend(R"(
|
||||
@ -103,7 +101,7 @@ void GrStrokeInstancedShaderImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
P[3] = P[2]; // Setting p3 equal to p2 works for the remaining rotational logic.
|
||||
})");
|
||||
}
|
||||
if (shader.stroke().isHairlineStyle() && !shader.viewMatrix().isIdentity()) {
|
||||
if (shader.stroke().isHairlineStyle()) {
|
||||
// Hairline case. Transform the points before tessellation. We can still hold off on the
|
||||
// translate until the end; we just need to perform the scale and skew right now.
|
||||
args.fVertBuilder->codeAppend(R"(
|
||||
|
@ -251,11 +251,7 @@ void GrStrokeShaderImpl::emitTessellationCode(const GrStrokeShader& shader, SkSt
|
||||
float2 ortho = normalize(float2(tangent.y, -tangent.x));
|
||||
strokeCoord += ortho * (STROKE_RADIUS * strokeOutset);)");
|
||||
|
||||
if (shader.viewMatrix().isIdentity()) {
|
||||
// No transform matrix.
|
||||
gpArgs->fPositionVar.set(kFloat2_GrSLType, "strokeCoord");
|
||||
gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "strokeCoord");
|
||||
} else if (!shader.stroke().isHairlineStyle()) {
|
||||
if (!shader.stroke().isHairlineStyle()) {
|
||||
// Normal case. Do the transform after tessellation.
|
||||
code->append(R"(
|
||||
float2 devCoord = AFFINE_MATRIX * strokeCoord + TRANSLATE;)");
|
||||
@ -322,11 +318,9 @@ void GrStrokeShaderImpl::setData(const GrGLSLProgramDataManager& pdman, const Gr
|
||||
|
||||
// Set up the view matrix, if any.
|
||||
const SkMatrix& m = shader.viewMatrix();
|
||||
if (!m.isIdentity()) {
|
||||
pdman.set2f(fTranslateUniform, m.getTranslateX(), m.getTranslateY());
|
||||
pdman.set4f(fAffineMatrixUniform, m.getScaleX(), m.getSkewY(), m.getSkewX(),
|
||||
m.getScaleY());
|
||||
}
|
||||
|
||||
if (!shader.hasDynamicColor()) {
|
||||
pdman.set4fv(fColorUniform, 1, shader.color().vec());
|
||||
@ -344,7 +338,6 @@ void GrStrokeShader::getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuil
|
||||
key = (key << 2) | (uint32_t)fMode;
|
||||
key = (key << 2) | ((keyNeedsJoin) ? fStroke.getJoin() : 0);
|
||||
key = (key << 1) | (uint32_t)fStroke.isHairlineStyle();
|
||||
key = (key << 1) | (uint32_t)this->viewMatrix().isIdentity();
|
||||
b->add32(key);
|
||||
}
|
||||
|
||||
|
@ -87,9 +87,9 @@ void GrStrokeTessellationShaderImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs
|
||||
float JOIN_TYPE = dynamicStrokeAttr.y;)", parametricPrecisionName);
|
||||
}
|
||||
|
||||
if (!shader.viewMatrix().isIdentity()) {
|
||||
fTranslateUniform = uniHandler->addUniform(nullptr, kTessEvaluation_GrShaderFlag,
|
||||
kFloat2_GrSLType, "translate", nullptr);
|
||||
// View matrix uniforms.
|
||||
const char* affineMatrixName;
|
||||
// Hairlines apply the affine matrix in their vertex shader, prior to tessellation.
|
||||
// Otherwise the entire view matrix gets applied at the end of the tess eval shader.
|
||||
@ -97,20 +97,18 @@ void GrStrokeTessellationShaderImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs
|
||||
if (shader.stroke().isHairlineStyle()) {
|
||||
affineMatrixVisibility |= kVertex_GrShaderFlag;
|
||||
}
|
||||
fAffineMatrixUniform = uniHandler->addUniform(nullptr, affineMatrixVisibility,
|
||||
kFloat4_GrSLType, "affineMatrix",
|
||||
&affineMatrixName);
|
||||
fAffineMatrixUniform = uniHandler->addUniform(nullptr, affineMatrixVisibility, kFloat4_GrSLType,
|
||||
"affineMatrix", &affineMatrixName);
|
||||
if (affineMatrixVisibility & kVertex_GrShaderFlag) {
|
||||
v->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n", affineMatrixName);
|
||||
}
|
||||
}
|
||||
|
||||
v->codeAppend(R"(
|
||||
// Unpack the control points.
|
||||
float2 prevControlPoint = prevCtrlPtAttr;
|
||||
float4x2 P = float4x2(pts01Attr, pts23Attr);)");
|
||||
|
||||
if (shader.stroke().isHairlineStyle() && !shader.viewMatrix().isIdentity()) {
|
||||
if (shader.stroke().isHairlineStyle()) {
|
||||
// Hairline case. Transform the points before tessellation. We can still hold off on the
|
||||
// translate until the end; we just need to perform the scale and skew right now.
|
||||
if (shader.hasConics()) {
|
||||
@ -558,14 +556,12 @@ SkString GrStrokeTessellationShaderImpl::getTessEvaluationShaderGLSL(
|
||||
code.appendf("#define STROKE_RADIUS tcsStrokeRadius\n");
|
||||
}
|
||||
|
||||
if (!shader.viewMatrix().isIdentity()) {
|
||||
const char* translateName = uniformHandler.getUniformCStr(fTranslateUniform);
|
||||
code.appendf("uniform vec2 %s;\n", translateName);
|
||||
code.appendf("#define TRANSLATE %s\n", translateName);
|
||||
const char* affineMatrixName = uniformHandler.getUniformCStr(fAffineMatrixUniform);
|
||||
code.appendf("uniform vec4 %s;\n", affineMatrixName);
|
||||
code.appendf("#define AFFINE_MATRIX mat2(%s)\n", affineMatrixName);
|
||||
}
|
||||
|
||||
code.append(R"(
|
||||
in vec4 tcsPts01[];
|
||||
|
Loading…
Reference in New Issue
Block a user