ccpr: Add an MSAA atlas mode
Adds the option to use a multisampled (or mixed sampled) atlas, and
uses the sample mask and stencil buffer instead of coverage counts.
Bug: skia:
Change-Id: I9fb76d17895ae25208124f6c27e37977ac31b5eb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/227428
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.h b/src/gpu/ccpr/GrCCCoverageProcessor.h
index e652a7c..e8db8a7 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.h
@@ -47,12 +47,16 @@
// Defines a single primitive shape with 3 input points (i.e. Triangles and Quadratics).
// X,Y point values are transposed.
struct TriPointInstance {
- float fX[3];
- float fY[3];
+ float fValues[6];
- void set(const SkPoint[3], const Sk2f& trans);
- void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans);
- void set(const Sk2f& P0, const Sk2f& P1, const Sk2f& P2, const Sk2f& trans);
+ enum class Ordering : bool {
+ kXYTransposed,
+ kXYInterleaved,
+ };
+
+ void set(const SkPoint[3], const Sk2f& translate, Ordering);
+ void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& translate, Ordering);
+ void set(const Sk2f& P0, const Sk2f& P1, const Sk2f& P2, const Sk2f& translate, Ordering);
};
// Defines a single primitive shape with 4 input points, or 3 input points plus a "weight"
@@ -147,8 +151,12 @@
varyingHandler, scope, code, position, coverage, cornerCoverage, wind);
}
- void emitFragmentCode(const GrCCCoverageProcessor&, GrGLSLFPFragmentBuilder*,
- const char* skOutputColor, const char* skOutputCoverage) const;
+ // Writes the signed coverage value at the current pixel to "outputCoverage".
+ virtual void emitFragmentCoverageCode(
+ GrGLSLFPFragmentBuilder*, const char* outputCoverage) const = 0;
+
+ // Assigns the built-in sample mask at the current pixel.
+ virtual void emitSampleMaskCode(GrGLSLFPFragmentBuilder*) const = 0;
// Calculates the winding direction of the input points (+1, -1, or 0). Wind for extremely
// thin triangles gets rounded to zero.
@@ -191,10 +199,6 @@
GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code, const char* position,
const char* coverage, const char* cornerCoverage, const char* wind) = 0;
- // Emits the fragment code that calculates a pixel's signed coverage value.
- virtual void onEmitFragmentCode(GrGLSLFPFragmentBuilder*,
- const char* outputCoverage) const = 0;
-
// Returns the name of a Shader's internal varying at the point where where its value is
// assigned. This is intended to work whether called for a vertex or a geometry shader.
const char* OutName(const GrGLSLVarying& varying) const {
@@ -239,21 +243,29 @@
return "";
}
-inline void GrCCCoverageProcessor::TriPointInstance::set(const SkPoint p[3], const Sk2f& trans) {
- this->set(p[0], p[1], p[2], trans);
+inline void GrCCCoverageProcessor::TriPointInstance::set(
+ const SkPoint p[3], const Sk2f& translate, Ordering ordering) {
+ this->set(p[0], p[1], p[2], translate, ordering);
}
-inline void GrCCCoverageProcessor::TriPointInstance::set(const SkPoint& p0, const SkPoint& p1,
- const SkPoint& p2, const Sk2f& trans) {
+inline void GrCCCoverageProcessor::TriPointInstance::set(
+ const SkPoint& p0, const SkPoint& p1, const SkPoint& p2, const Sk2f& translate,
+ Ordering ordering) {
Sk2f P0 = Sk2f::Load(&p0);
Sk2f P1 = Sk2f::Load(&p1);
Sk2f P2 = Sk2f::Load(&p2);
- this->set(P0, P1, P2, trans);
+ this->set(P0, P1, P2, translate, ordering);
}
-inline void GrCCCoverageProcessor::TriPointInstance::set(const Sk2f& P0, const Sk2f& P1,
- const Sk2f& P2, const Sk2f& trans) {
- Sk2f::Store3(this, P0 + trans, P1 + trans, P2 + trans);
+inline void GrCCCoverageProcessor::TriPointInstance::set(
+ const Sk2f& P0, const Sk2f& P1, const Sk2f& P2, const Sk2f& translate, Ordering ordering) {
+ if (Ordering::kXYTransposed == ordering) {
+ Sk2f::Store3(fValues, P0 + translate, P1 + translate, P2 + translate);
+ } else {
+ (P0 + translate).store(fValues);
+ (P1 + translate).store(fValues + 2);
+ (P2 + translate).store(fValues + 4);
+ }
}
inline void GrCCCoverageProcessor::QuadPointInstance::set(const SkPoint p[4], float dx, float dy) {