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 {
|
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
|
||||||
auto& shader = args.fGeomProc.cast<GrFillPathShader>();
|
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);
|
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;");
|
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->fPositionVar.set(kFloat2_GrSLType, "vertexpos");
|
||||||
gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
|
gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
|
||||||
@ -41,13 +45,16 @@ public:
|
|||||||
const GrShaderCaps&,
|
const GrShaderCaps&,
|
||||||
const GrGeometryProcessor& geomProc) override {
|
const GrGeometryProcessor& geomProc) override {
|
||||||
const GrFillPathShader& shader = geomProc.cast<GrFillPathShader>();
|
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;
|
const SkPMColor4f& color = shader.fColor;
|
||||||
pdman.set4f(fColorUniform, color.fR, color.fG, color.fB, color.fA);
|
pdman.set4f(fColorUniform, color.fR, color.fG, color.fB, color.fA);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrGLSLUniformHandler::UniformHandle fViewMatrixUniform;
|
GrGLSLUniformHandler::UniformHandle fAffineMatrixUniform;
|
||||||
|
GrGLSLUniformHandler::UniformHandle fTranslateUniform;
|
||||||
GrGLSLUniformHandler::UniformHandle fColorUniform;
|
GrGLSLUniformHandler::UniformHandle fColorUniform;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,14 +62,14 @@ GrGLSLGeometryProcessor* GrFillPathShader::createGLSLInstance(const GrShaderCaps
|
|||||||
return new Impl;
|
return new Impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrFillTriangleShader::emitVertexCode(Impl*, GrGLSLVertexBuilder* v, const char* viewMatrix,
|
void GrFillTriangleShader::emitVertexCode(Impl*, GrGLSLVertexBuilder* v,
|
||||||
GrGLSLUniformHandler* uniformHandler) const {
|
GrGLSLUniformHandler* uniformHandler) const {
|
||||||
v->codeAppendf(R"(
|
v->codeAppend(R"(
|
||||||
localcoord = input_point;
|
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 {
|
GrGLSLUniformHandler* uniformHandler) const {
|
||||||
v->codeAppend(R"(
|
v->codeAppend(R"(
|
||||||
float4x2 P = float4x2(input_points_0_1, input_points_2_3);
|
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;
|
vertexidx = (vertexidx + 1) & 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
localcoord = P[vertexidx];)");
|
localcoord = P[vertexidx];
|
||||||
|
vertexpos = AFFINE_MATRIX * localcoord + TRANSLATE;)");
|
||||||
v->codeAppendf("vertexpos = (%s * float3(localcoord, 1)).xy;", viewMatrix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrFillBoundingBoxShader::emitVertexCode(Impl* impl, GrGLSLVertexBuilder* v,
|
void GrFillBoundingBoxShader::emitVertexCode(Impl* impl, GrGLSLVertexBuilder* v,
|
||||||
const char* viewMatrix,
|
|
||||||
GrGLSLUniformHandler* uniformHandler) const {
|
GrGLSLUniformHandler* uniformHandler) const {
|
||||||
v->codeAppendf(R"(
|
v->codeAppendf(R"(
|
||||||
// Bloat the bounding box by 1/4px to avoid potential T-junctions at the edges.
|
// 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;
|
float2 bloat = float2(abs(M_[0]) + abs(M_[1])) * .25;
|
||||||
|
|
||||||
// Find the vertex position.
|
// Find the vertex position.
|
||||||
float2 T = float2(sk_VertexID & 1, sk_VertexID >> 1);
|
float2 T = float2(sk_VertexID & 1, sk_VertexID >> 1);
|
||||||
localcoord = mix(pathBounds.xy - bloat, pathBounds.zw + bloat, T);
|
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:
|
protected:
|
||||||
class Impl;
|
class Impl;
|
||||||
|
|
||||||
virtual void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix,
|
virtual void emitVertexCode(Impl*, GrGLSLVertexBuilder*, GrGLSLUniformHandler*) const = 0;
|
||||||
GrGLSLUniformHandler*) const = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const SkPMColor4f fColor;
|
const SkPMColor4f fColor;
|
||||||
@ -76,8 +75,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const char* name() const override { return "GrFillTriangleShader"; }
|
const char* name() const override { return "GrFillTriangleShader"; }
|
||||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix,
|
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, GrGLSLUniformHandler*) const override;
|
||||||
GrGLSLUniformHandler*) const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fills an array of convex hulls surrounding 4-point cubic instances.
|
// Fills an array of convex hulls surrounding 4-point cubic instances.
|
||||||
@ -94,8 +92,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const char* name() const override { return "GrFillCubicHullShader"; }
|
const char* name() const override { return "GrFillCubicHullShader"; }
|
||||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix,
|
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, GrGLSLUniformHandler*) const override;
|
||||||
GrGLSLUniformHandler*) const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fills a path's bounding box, with subpixel outset to avoid possible T-junctions with extreme
|
// Fills a path's bounding box, with subpixel outset to avoid possible T-junctions with extreme
|
||||||
@ -114,8 +111,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const char* name() const override { return "GrFillBoundingBoxShader"; }
|
const char* name() const override { return "GrFillBoundingBoxShader"; }
|
||||||
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix,
|
void emitVertexCode(Impl*, GrGLSLVertexBuilder*, GrGLSLUniformHandler*) const override;
|
||||||
GrGLSLUniformHandler*) const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,24 +57,23 @@ protected:
|
|||||||
args.fVaryingHandler->emitAttributes(shader);
|
args.fVaryingHandler->emitAttributes(shader);
|
||||||
auto v = args.fVertBuilder;
|
auto v = args.fVertBuilder;
|
||||||
|
|
||||||
GrShaderVar vertexPos = (*shader.vertexAttributes().begin()).asShaderVar();
|
const char* affineMatrix, *translate;
|
||||||
if (!shader.viewMatrix().isIdentity()) {
|
fAffineMatrixUniform = args.fUniformHandler->addUniform(
|
||||||
const char* viewMatrix;
|
nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "affineMatrix", &affineMatrix);
|
||||||
fViewMatrixUniform = args.fUniformHandler->addUniform(
|
fTranslateUniform = args.fUniformHandler->addUniform(
|
||||||
nullptr, kVertex_GrShaderFlag, kFloat3x3_GrSLType, "view_matrix", &viewMatrix);
|
nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "translate", &translate);
|
||||||
v->codeAppendf("float2 vertexpos = (%s * float3(inputPoint, 1)).xy;", viewMatrix);
|
v->codeAppendf("float2 vertexpos = float2x2(%s) * inputPoint + %s;",
|
||||||
|
affineMatrix, translate);
|
||||||
if (shader.willUseTessellationShaders()) {
|
if (shader.willUseTessellationShaders()) {
|
||||||
// If y is infinity then x is a conic weight. Don't transform.
|
// If y is infinity then x is a conic weight. Don't transform.
|
||||||
v->codeAppendf("vertexpos = (isinf(inputPoint.y)) ? inputPoint : vertexpos;");
|
v->codeAppendf("vertexpos = (isinf(inputPoint.y)) ? inputPoint : vertexpos;");
|
||||||
}
|
}
|
||||||
vertexPos.set(kFloat2_GrSLType, "vertexpos");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shader.willUseTessellationShaders()) { // This is the case for the triangle shader.
|
if (!shader.willUseTessellationShaders()) { // This is the case for the triangle shader.
|
||||||
gpArgs->fPositionVar = vertexPos;
|
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertexpos");
|
||||||
} else {
|
} else {
|
||||||
v->declareGlobal(GrShaderVar("P", kFloat2_GrSLType, GrShaderVar::TypeModifier::Out));
|
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.
|
// The fragment shader is normally disabled, but output fully opaque white.
|
||||||
@ -85,13 +84,13 @@ protected:
|
|||||||
void setData(const GrGLSLProgramDataManager& pdman,
|
void setData(const GrGLSLProgramDataManager& pdman,
|
||||||
const GrShaderCaps&,
|
const GrShaderCaps&,
|
||||||
const GrGeometryProcessor& geomProc) override {
|
const GrGeometryProcessor& geomProc) override {
|
||||||
const auto& shader = geomProc.cast<GrStencilPathShader>();
|
const SkMatrix& m = geomProc.cast<GrStencilPathShader>().viewMatrix();
|
||||||
if (!shader.viewMatrix().isIdentity()) {
|
pdman.set4f(fAffineMatrixUniform, m.getScaleX(), m.getSkewY(), m.getSkewX(), m.getScaleY());
|
||||||
pdman.setSkMatrix(fViewMatrixUniform, shader.viewMatrix());
|
pdman.set2f(fTranslateUniform, m.getTranslateX(), m.getTranslateY());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GrGLSLUniformHandler::UniformHandle fViewMatrixUniform;
|
GrGLSLUniformHandler::UniformHandle fAffineMatrixUniform;
|
||||||
|
GrGLSLUniformHandler::UniformHandle fTranslateUniform;
|
||||||
};
|
};
|
||||||
|
|
||||||
GrGLSLGeometryProcessor* GrStencilPathShader::createGLSLInstance(const GrShaderCaps&) const {
|
GrGLSLGeometryProcessor* GrStencilPathShader::createGLSLInstance(const GrShaderCaps&) const {
|
||||||
@ -375,13 +374,13 @@ class GrCurveMiddleOutShader::Impl : public GrStencilPathShader::Impl {
|
|||||||
float T = find_middle_out_T();
|
float T = find_middle_out_T();
|
||||||
pos = eval_rational_cubic(P, T);
|
pos = eval_rational_cubic(P, T);
|
||||||
})");
|
})");
|
||||||
if (!shader.viewMatrix().isIdentity()) {
|
const char* affineMatrix, *translate;
|
||||||
const char* viewMatrix;
|
fAffineMatrixUniform = args.fUniformHandler->addUniform(
|
||||||
fViewMatrixUniform = args.fUniformHandler->addUniform(
|
nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "affineMatrix", &affineMatrix);
|
||||||
nullptr, kVertex_GrShaderFlag, kFloat3x3_GrSLType, "view_matrix", &viewMatrix);
|
fTranslateUniform = args.fUniformHandler->addUniform(
|
||||||
|
nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "translate", &translate);
|
||||||
args.fVertBuilder->codeAppendf(R"(
|
args.fVertBuilder->codeAppendf(R"(
|
||||||
pos = (%s * float3(pos, 1)).xy;)", viewMatrix);
|
pos = float2x2(%s) * pos + %s;)", affineMatrix, translate);
|
||||||
}
|
|
||||||
gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos");
|
gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos");
|
||||||
|
|
||||||
// The fragment shader is normally disabled, but output fully opaque white.
|
// The fragment shader is normally disabled, but output fully opaque white.
|
||||||
|
@ -85,9 +85,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
constexpr static Attribute kSinglePointAttrib{"inputPoint", kFloat2_GrVertexAttribType,
|
constexpr static Attribute kSinglePointAttrib{"inputPoint", kFloat2_GrVertexAttribType,
|
||||||
kFloat2_GrSLType};
|
kFloat2_GrSLType};
|
||||||
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
|
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {}
|
||||||
b->add32(this->viewMatrix().isIdentity());
|
|
||||||
}
|
|
||||||
GrGLSLGeometryProcessor* createGLSLInstance(const GrShaderCaps&) const override;
|
GrGLSLGeometryProcessor* createGLSLInstance(const GrShaderCaps&) const override;
|
||||||
|
|
||||||
class Impl;
|
class Impl;
|
||||||
|
@ -79,17 +79,15 @@ void GrStrokeInstancedShaderImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// View matrix uniforms.
|
// View matrix uniforms.
|
||||||
if (!shader.viewMatrix().isIdentity()) {
|
|
||||||
const char* translateName, *affineMatrixName;
|
const char* translateName, *affineMatrixName;
|
||||||
fAffineMatrixUniform = args.fUniformHandler->addUniform(
|
fAffineMatrixUniform = args.fUniformHandler->addUniform(nullptr, kVertex_GrShaderFlag,
|
||||||
nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "affineMatrix",
|
kFloat4_GrSLType, "affineMatrix",
|
||||||
&affineMatrixName);
|
&affineMatrixName);
|
||||||
fTranslateUniform = args.fUniformHandler->addUniform(
|
fTranslateUniform = args.fUniformHandler->addUniform(nullptr, kVertex_GrShaderFlag,
|
||||||
nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "translate", &translateName);
|
kFloat2_GrSLType, "translate",
|
||||||
args.fVertBuilder->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n",
|
&translateName);
|
||||||
affineMatrixName);
|
args.fVertBuilder->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n", affineMatrixName);
|
||||||
args.fVertBuilder->codeAppendf("float2 TRANSLATE = %s;\n", translateName);
|
args.fVertBuilder->codeAppendf("float2 TRANSLATE = %s;\n", translateName);
|
||||||
}
|
|
||||||
|
|
||||||
// Tessellation code.
|
// Tessellation code.
|
||||||
args.fVertBuilder->codeAppend(R"(
|
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.
|
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
|
// 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.
|
// translate until the end; we just need to perform the scale and skew right now.
|
||||||
args.fVertBuilder->codeAppend(R"(
|
args.fVertBuilder->codeAppend(R"(
|
||||||
|
@ -251,11 +251,7 @@ void GrStrokeShaderImpl::emitTessellationCode(const GrStrokeShader& shader, SkSt
|
|||||||
float2 ortho = normalize(float2(tangent.y, -tangent.x));
|
float2 ortho = normalize(float2(tangent.y, -tangent.x));
|
||||||
strokeCoord += ortho * (STROKE_RADIUS * strokeOutset);)");
|
strokeCoord += ortho * (STROKE_RADIUS * strokeOutset);)");
|
||||||
|
|
||||||
if (shader.viewMatrix().isIdentity()) {
|
if (!shader.stroke().isHairlineStyle()) {
|
||||||
// No transform matrix.
|
|
||||||
gpArgs->fPositionVar.set(kFloat2_GrSLType, "strokeCoord");
|
|
||||||
gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "strokeCoord");
|
|
||||||
} else if (!shader.stroke().isHairlineStyle()) {
|
|
||||||
// Normal case. Do the transform after tessellation.
|
// Normal case. Do the transform after tessellation.
|
||||||
code->append(R"(
|
code->append(R"(
|
||||||
float2 devCoord = AFFINE_MATRIX * strokeCoord + TRANSLATE;)");
|
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.
|
// Set up the view matrix, if any.
|
||||||
const SkMatrix& m = shader.viewMatrix();
|
const SkMatrix& m = shader.viewMatrix();
|
||||||
if (!m.isIdentity()) {
|
|
||||||
pdman.set2f(fTranslateUniform, m.getTranslateX(), m.getTranslateY());
|
pdman.set2f(fTranslateUniform, m.getTranslateX(), m.getTranslateY());
|
||||||
pdman.set4f(fAffineMatrixUniform, m.getScaleX(), m.getSkewY(), m.getSkewX(),
|
pdman.set4f(fAffineMatrixUniform, m.getScaleX(), m.getSkewY(), m.getSkewX(),
|
||||||
m.getScaleY());
|
m.getScaleY());
|
||||||
}
|
|
||||||
|
|
||||||
if (!shader.hasDynamicColor()) {
|
if (!shader.hasDynamicColor()) {
|
||||||
pdman.set4fv(fColorUniform, 1, shader.color().vec());
|
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) | (uint32_t)fMode;
|
||||||
key = (key << 2) | ((keyNeedsJoin) ? fStroke.getJoin() : 0);
|
key = (key << 2) | ((keyNeedsJoin) ? fStroke.getJoin() : 0);
|
||||||
key = (key << 1) | (uint32_t)fStroke.isHairlineStyle();
|
key = (key << 1) | (uint32_t)fStroke.isHairlineStyle();
|
||||||
key = (key << 1) | (uint32_t)this->viewMatrix().isIdentity();
|
|
||||||
b->add32(key);
|
b->add32(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,9 +87,9 @@ void GrStrokeTessellationShaderImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs
|
|||||||
float JOIN_TYPE = dynamicStrokeAttr.y;)", parametricPrecisionName);
|
float JOIN_TYPE = dynamicStrokeAttr.y;)", parametricPrecisionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shader.viewMatrix().isIdentity()) {
|
|
||||||
fTranslateUniform = uniHandler->addUniform(nullptr, kTessEvaluation_GrShaderFlag,
|
fTranslateUniform = uniHandler->addUniform(nullptr, kTessEvaluation_GrShaderFlag,
|
||||||
kFloat2_GrSLType, "translate", nullptr);
|
kFloat2_GrSLType, "translate", nullptr);
|
||||||
|
// View matrix uniforms.
|
||||||
const char* affineMatrixName;
|
const char* affineMatrixName;
|
||||||
// Hairlines apply the affine matrix in their vertex shader, prior to tessellation.
|
// 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.
|
// 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()) {
|
if (shader.stroke().isHairlineStyle()) {
|
||||||
affineMatrixVisibility |= kVertex_GrShaderFlag;
|
affineMatrixVisibility |= kVertex_GrShaderFlag;
|
||||||
}
|
}
|
||||||
fAffineMatrixUniform = uniHandler->addUniform(nullptr, affineMatrixVisibility,
|
fAffineMatrixUniform = uniHandler->addUniform(nullptr, affineMatrixVisibility, kFloat4_GrSLType,
|
||||||
kFloat4_GrSLType, "affineMatrix",
|
"affineMatrix", &affineMatrixName);
|
||||||
&affineMatrixName);
|
|
||||||
if (affineMatrixVisibility & kVertex_GrShaderFlag) {
|
if (affineMatrixVisibility & kVertex_GrShaderFlag) {
|
||||||
v->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n", affineMatrixName);
|
v->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n", affineMatrixName);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
v->codeAppend(R"(
|
v->codeAppend(R"(
|
||||||
// Unpack the control points.
|
// Unpack the control points.
|
||||||
float2 prevControlPoint = prevCtrlPtAttr;
|
float2 prevControlPoint = prevCtrlPtAttr;
|
||||||
float4x2 P = float4x2(pts01Attr, pts23Attr);)");
|
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
|
// 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.
|
// translate until the end; we just need to perform the scale and skew right now.
|
||||||
if (shader.hasConics()) {
|
if (shader.hasConics()) {
|
||||||
@ -558,14 +556,12 @@ SkString GrStrokeTessellationShaderImpl::getTessEvaluationShaderGLSL(
|
|||||||
code.appendf("#define STROKE_RADIUS tcsStrokeRadius\n");
|
code.appendf("#define STROKE_RADIUS tcsStrokeRadius\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shader.viewMatrix().isIdentity()) {
|
|
||||||
const char* translateName = uniformHandler.getUniformCStr(fTranslateUniform);
|
const char* translateName = uniformHandler.getUniformCStr(fTranslateUniform);
|
||||||
code.appendf("uniform vec2 %s;\n", translateName);
|
code.appendf("uniform vec2 %s;\n", translateName);
|
||||||
code.appendf("#define TRANSLATE %s\n", translateName);
|
code.appendf("#define TRANSLATE %s\n", translateName);
|
||||||
const char* affineMatrixName = uniformHandler.getUniformCStr(fAffineMatrixUniform);
|
const char* affineMatrixName = uniformHandler.getUniformCStr(fAffineMatrixUniform);
|
||||||
code.appendf("uniform vec4 %s;\n", affineMatrixName);
|
code.appendf("uniform vec4 %s;\n", affineMatrixName);
|
||||||
code.appendf("#define AFFINE_MATRIX mat2(%s)\n", affineMatrixName);
|
code.appendf("#define AFFINE_MATRIX mat2(%s)\n", affineMatrixName);
|
||||||
}
|
|
||||||
|
|
||||||
code.append(R"(
|
code.append(R"(
|
||||||
in vec4 tcsPts01[];
|
in vec4 tcsPts01[];
|
||||||
|
Loading…
Reference in New Issue
Block a user