Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
QuadPerEdgeAA.h
Go to the documentation of this file.
1/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef QuadPerEdgeAA_DEFINED
9#define QuadPerEdgeAA_DEFINED
10
22
23class GrCaps;
26struct GrShaderCaps;
27struct VertexWriter;
28
31
33enum class Subset : bool { kNo = false, kYes = true };
34enum class ColorType { kNone, kByte, kFloat, kLast = kFloat };
35static const int kColorTypeCount = static_cast<int>(ColorType::kLast) + 1;
36
38 kPictureFramed, // geometrically AA'd -> 8 verts/quad + an index buffer
39 kIndexedRects, // non-AA'd but indexed -> 4 verts/quad + an index buffer
40 kTriStrips, // non-AA'd -> 4 verts/quad but no index buffer
42};
43static const int kIndexBufferOptionCount = static_cast<int>(IndexBufferOption::kLast) + 1;
44
46
47// Gets the minimum ColorType that can represent a color.
49
50// Specifies the vertex configuration for an op that renders per-edge AA quads. The vertex
51// order (when enabled) is device position, color, local position, subset, aa edge equations.
52// This order matches the constructor argument order of VertexSpec and is the order that
53// GPAttributes maintains. If hasLocalCoords is false, then the local quad type can be ignored.
54struct VertexSpec {
55public:
57 : fDeviceQuadType(0) // kAxisAligned
58 , fLocalQuadType(0) // kAxisAligned
59 , fIndexBufferOption(0) // kPictureFramed
60 , fHasLocalCoords(false)
61 , fColorType(0) // kNone
62 , fHasSubset(false)
63 , fUsesCoverageAA(false)
64 , fCompatibleWithCoverageAsAlpha(false)
65 , fRequiresGeometrySubset(false) {}
66
70 bool hasLocalCoords,
71 Subset subset,
72 GrAAType aa,
73 bool coverageAsAlpha,
75 : fDeviceQuadType(static_cast<unsigned>(deviceQuadType))
76 , fLocalQuadType(static_cast<unsigned>(localQuadType))
77 , fIndexBufferOption(static_cast<unsigned>(indexBufferOption))
78 , fHasLocalCoords(hasLocalCoords)
79 , fColorType(static_cast<unsigned>(colorType))
80 , fHasSubset(static_cast<unsigned>(subset))
81 , fUsesCoverageAA(aa == GrAAType::kCoverage)
82 , fCompatibleWithCoverageAsAlpha(coverageAsAlpha)
83 , fRequiresGeometrySubset(aa == GrAAType::kCoverage &&
84 deviceQuadType > GrQuad::Type::kRectilinear) {}
85
86 GrQuad::Type deviceQuadType() const { return static_cast<GrQuad::Type>(fDeviceQuadType); }
87 GrQuad::Type localQuadType() const { return static_cast<GrQuad::Type>(fLocalQuadType); }
89 return static_cast<IndexBufferOption>(fIndexBufferOption);
90 }
91 bool hasLocalCoords() const { return fHasLocalCoords; }
92 ColorType colorType() const { return static_cast<ColorType>(fColorType); }
93 bool hasVertexColors() const { return ColorType::kNone != this->colorType(); }
94 bool hasSubset() const { return fHasSubset; }
95 bool usesCoverageAA() const { return fUsesCoverageAA; }
96 bool compatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
97 bool requiresGeometrySubset() const { return fRequiresGeometrySubset; }
98 // Will always be 2 or 3
99 int deviceDimensionality() const;
100 // Will always be 0 if hasLocalCoords is false, otherwise will be 2 or 3
101 int localDimensionality() const;
102
103 int verticesPerQuad() const { return fUsesCoverageAA ? 8 : 4; }
104
106 size_t vertexSize() const;
107
108 bool needsIndexBuffer() const {
109 return this->indexBufferOption() != IndexBufferOption::kTriStrips;
110 }
111
113 switch (this->indexBufferOption()) {
114 case IndexBufferOption::kPictureFramed:
116 case IndexBufferOption::kIndexedRects:
118 case IndexBufferOption::kTriStrips:
120 }
121
123 }
124
125private:
126 static_assert(GrQuad::kTypeCount <= 4, "GrQuad::Type doesn't fit in 2 bits");
127 static_assert(kColorTypeCount <= 4, "Color doesn't fit in 2 bits");
128 static_assert(kIndexBufferOptionCount <= 4, "IndexBufferOption doesn't fit in 2 bits");
129
130 unsigned fDeviceQuadType : 2;
131 unsigned fLocalQuadType : 2;
132 unsigned fIndexBufferOption : 2;
133 unsigned fHasLocalCoords : 1;
134 unsigned fColorType : 2;
135 unsigned fHasSubset : 1;
136 unsigned fUsesCoverageAA : 1;
137 unsigned fCompatibleWithCoverageAsAlpha : 1;
138 // The geometry subset serves to clip off pixels touched by quads with sharp corners that
139 // would otherwise exceed the miter limit for the AA-outset geometry.
140 unsigned fRequiresGeometrySubset : 1;
141 };
142
143 // A Tessellator is responsible for processing a series of device+local GrQuads into a VBO,
144 // as specified by a VertexSpec. This vertex data can then be processed by a GP created with
145 // MakeProcessor and/or MakeTexturedProcessor.
147 public:
148 explicit Tessellator(const VertexSpec& spec, char* vertices);
149
150 // Calculates (as needed) inset and outset geometry for anti-aliasing, and appends all
151 // necessary position and vertex attributes required by this Tessellator's VertexSpec into
152 // the 'vertices' the Tessellator was called with. The insetting and outsetting may
153 // damage the provided GrQuads (as this is intended to work with GrQuadBuffer::Iter).
154 // 'localQuad' can be null if the VertexSpec does not use local coords.
155 void append(GrQuad* deviceQuad, GrQuad* localQuad,
156 const SkPMColor4f& color, const SkRect& uvSubset, GrQuadAAFlags aaFlags);
157
158 SkDEBUGCODE(skgpu::BufferWriter::Mark vertexMark() const { return fVertexWriter.mark(); })
159
160 private:
161 // VertexSpec defines many unique ways to write vertex attributes, which can be handled
162 // generically by branching per-quad based on the VertexSpec. However, there are several
163 // specs that appear in the wild far more frequently, so they use explicit WriteQuadProcs
164 // that have no branches.
165 typedef void (*WriteQuadProc)(VertexWriter* vertices, const VertexSpec& spec,
166 const GrQuad* deviceQuad, const GrQuad* localQuad,
167 const float coverage[4], const SkPMColor4f& color,
168 const SkRect& geomSubset, const SkRect& texSubset);
169 static WriteQuadProc GetWriteQuadProc(const VertexSpec& spec);
170
174 WriteQuadProc fWriteProc;
175 };
176
178
180 const VertexSpec&,
181 const GrShaderCaps&,
182 const GrBackendFormat&,
184 const skgpu::Swizzle&,
185 sk_sp<GrColorSpaceXform> textureColorSpaceXform,
186 Saturate);
187
188 // This method will return the correct index buffer for the specified indexBufferOption.
189 // It will, correctly, return nullptr if the indexBufferOption is kTriStrips.
191
192 // What is the maximum number of quads allowed for the specified indexBuffer option?
194
195 // This method will issue the draw call on the provided GrOpsRenderPass, as specified by the
196 // indexing method in vertexSpec. It is up to the calling code to allocate, fill in, and bind a
197 // vertex buffer, and to acquire and bind the correct index buffer (if needed) with
198 // GrPrimitiveRestart::kNo.
199 //
200 // @param runningQuadCount the number of quads already stored in 'vertexBuffer' and
201 // 'indexBuffer' e.g., different GrMeshes have already been placed in
202 // the buffers to allow dynamic state changes.
203 // @param quadCount the number of quads that will be drawn by the provided 'mesh'.
204 // A subsequent ConfigureMesh call would the use
205 // 'runningQuadCount' + 'quadCount' for its new 'runningQuadCount'.
206 void IssueDraw(const GrCaps&, GrOpsRenderPass*, const VertexSpec&, int runningQuadCount,
207 int quadCount, int maxVerts, int absVertBufferOffset);
208
209 } // namespace skgpu::ganesh::QuadPerEdgeAA
210
211#endif // QuadPerEdgeAA_DEFINED
GrQuadAAFlags
GrPrimitiveType
Definition GrTypesPriv.h:42
GrAAType
SkColor4f color
#define SkUNREACHABLE
Definition SkAssert.h:135
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static const int kTypeCount
Definition GrQuad.h:48
GrQuadUtils::TessellationHelper fAAHelper
static SkDEBUGCODE(skgpu::BufferWriter::Mark vertexMark() const { return fVertexWriter.mark();}) private WriteQuadProc GetWriteQuadProc(const VertexSpec &spec)
void append(GrQuad *deviceQuad, GrQuad *localQuad, const SkPMColor4f &color, const SkRect &uvSubset, GrQuadAAFlags aaFlags)
int QuadLimit(IndexBufferOption option)
GrGeometryProcessor * MakeProcessor(SkArenaAlloc *arena, const VertexSpec &spec)
IndexBufferOption CalcIndexBufferOption(GrAAType aa, int numQuads)
GrGeometryProcessor * MakeTexturedProcessor(SkArenaAlloc *arena, const VertexSpec &spec, const GrShaderCaps &caps, const GrBackendFormat &backendFormat, GrSamplerState samplerState, const skgpu::Swizzle &swizzle, sk_sp< GrColorSpaceXform > textureColorSpaceXform, Saturate saturate)
ColorType MinColorType(SkPMColor4f color)
sk_sp< const GrBuffer > GetIndexBuffer(GrMeshDrawTarget *target, IndexBufferOption indexBufferOption)
void IssueDraw(const GrCaps &caps, GrOpsRenderPass *renderPass, const VertexSpec &spec, int runningQuadCount, int quadsInDraw, int maxVerts, int absVertBufferOffset)
static const int kColorTypeCount
static const int kIndexBufferOptionCount
Mark mark(size_t offset=0) const
IndexBufferOption indexBufferOption() const
VertexSpec(GrQuad::Type deviceQuadType, ColorType colorType, GrQuad::Type localQuadType, bool hasLocalCoords, Subset subset, GrAAType aa, bool coverageAsAlpha, IndexBufferOption indexBufferOption)