blob: fcb0ce171bdd1f37b5357de22a1e0df8b71021c3 [file] [log] [blame]
senorblancod6ed19c2015-02-26 06:58:17 -08001/*
2 * Copyright 2015 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
Chris Dalton17dc4182020-03-25 16:18:16 -06008#include "src/gpu/ops/GrTriangulatingPathRenderer.h"
Brian Salomon71fe9452020-03-02 16:59:40 -05009
10#include "include/private/SkIDChangeListener.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/core/SkGeometry.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040012#include "src/gpu/GrAuditTrail.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/GrCaps.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/GrDefaultGeoProcFactory.h"
15#include "src/gpu/GrDrawOpTest.h"
Chris Daltond081dce2020-01-23 12:09:04 -070016#include "src/gpu/GrEagerVertexAllocator.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/gpu/GrOpFlushState.h"
Robert Phillips740d34f2020-03-11 09:36:13 -040018#include "src/gpu/GrProgramInfo.h"
Michael Ludwig7c12e282020-05-29 09:54:07 -040019#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "src/gpu/GrResourceCache.h"
21#include "src/gpu/GrResourceProvider.h"
Chris Daltoneb694b72020-03-16 09:25:50 -060022#include "src/gpu/GrSimpleMesh.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/GrStyle.h"
Chris Dalton17dc4182020-03-25 16:18:16 -060024#include "src/gpu/GrTriangulator.h"
Michael Ludwig663afe52019-06-03 16:46:19 -040025#include "src/gpu/geometry/GrPathUtils.h"
Michael Ludwig2686d692020-04-17 20:21:37 +000026#include "src/gpu/geometry/GrStyledShape.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050027#include "src/gpu/ops/GrMeshDrawOp.h"
Robert Phillips55f681f2020-02-28 08:58:15 -050028#include "src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h"
joshualitt74417822015-08-07 11:42:16 -070029
Chris Dalton17dc4182020-03-25 16:18:16 -060030#include <cstdio>
Brian Salomon71fe9452020-03-02 16:59:40 -050031
Stephen Whitea7701e02018-01-23 15:35:05 -050032#ifndef GR_AA_TESSELLATOR_MAX_VERB_COUNT
33#define GR_AA_TESSELLATOR_MAX_VERB_COUNT 10
34#endif
35
senorblancod6ed19c2015-02-26 06:58:17 -080036/*
Chris Dalton17dc4182020-03-25 16:18:16 -060037 * This path renderer linearizes and decomposes the path into triangles using GrTriangulator,
38 * uploads the triangles to a vertex buffer, and renders them with a single draw call. It can do
39 * screenspace antialiasing with a one-pixel coverage ramp.
senorblancod6ed19c2015-02-26 06:58:17 -080040 */
senorblancod6ed19c2015-02-26 06:58:17 -080041namespace {
42
senorblanco84cd6212015-08-04 10:01:58 -070043struct TessInfo {
44 SkScalar fTolerance;
senorblanco06f989a2015-09-02 09:05:17 -070045 int fCount;
senorblanco84cd6212015-08-04 10:01:58 -070046};
47
Robert Phillips6cc9d8d2020-10-20 09:42:33 -040048static sk_sp<SkData> create_data(int vertexCount, int numCountedCurves, SkScalar tol) {
49 TessInfo info;
50 info.fTolerance = (numCountedCurves == 0) ? 0 : tol;
51 info.fCount = vertexCount;
52 return SkData::MakeWithCopy(&info, sizeof(info));
53}
54
55bool cache_match(const SkData* data, SkScalar tol, int* actualCount) {
56 SkASSERT(data);
57
58 const TessInfo* info = static_cast<const TessInfo*>(data->data());
59 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) {
60 *actualCount = info->fCount;
61 return true;
62 }
63 return false;
64}
65
ethannicholase9709e82016-01-07 13:34:16 -080066// When the SkPathRef genID changes, invalidate a corresponding GrResource described by key.
Brian Salomon99a813c2020-03-02 12:50:47 -050067class UniqueKeyInvalidator : public SkIDChangeListener {
ethannicholase9709e82016-01-07 13:34:16 -080068public:
Brian Salomon99a813c2020-03-02 12:50:47 -050069 UniqueKeyInvalidator(const GrUniqueKey& key, uint32_t contextUniqueID)
Brian Salomon238069b2018-07-11 15:58:57 -040070 : fMsg(key, contextUniqueID) {}
71
ethannicholase9709e82016-01-07 13:34:16 -080072private:
73 GrUniqueKeyInvalidatedMessage fMsg;
74
Brian Salomon99a813c2020-03-02 12:50:47 -050075 void changed() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
ethannicholase9709e82016-01-07 13:34:16 -080076};
77
Chris Daltond081dce2020-01-23 12:09:04 -070078class StaticVertexAllocator : public GrEagerVertexAllocator {
senorblanco6599eff2016-03-10 08:38:45 -080079public:
Chris Daltond081dce2020-01-23 12:09:04 -070080 StaticVertexAllocator(GrResourceProvider* resourceProvider, bool canMapVB)
Robert Phillips6ffcb232020-10-14 12:40:13 -040081 : fResourceProvider(resourceProvider)
82 , fCanMapVB(canMapVB)
83 , fVertices(nullptr) {
senorblanco6599eff2016-03-10 08:38:45 -080084 }
Robert Phillips6ffcb232020-10-14 12:40:13 -040085
Chris Daltond081dce2020-01-23 12:09:04 -070086#ifdef SK_DEBUG
87 ~StaticVertexAllocator() override {
88 SkASSERT(!fLockStride);
89 }
90#endif
91 void* lock(size_t stride, int eagerCount) override {
92 SkASSERT(!fLockStride);
93 SkASSERT(stride);
94 size_t size = eagerCount * stride;
Brian Salomonae64c192019-02-05 09:41:37 -050095 fVertexBuffer = fResourceProvider->createBuffer(size, GrGpuBufferType::kVertex,
Brian Salomondbf70722019-02-07 11:31:24 -050096 kStatic_GrAccessPattern);
John Stilesa008b0f2020-08-16 08:48:02 -040097 if (!fVertexBuffer) {
senorblanco6599eff2016-03-10 08:38:45 -080098 return nullptr;
99 }
100 if (fCanMapVB) {
senorblancof57372d2016-08-31 10:36:19 -0700101 fVertices = fVertexBuffer->map();
senorblanco6599eff2016-03-10 08:38:45 -0800102 } else {
Chris Daltond081dce2020-01-23 12:09:04 -0700103 fVertices = sk_malloc_throw(eagerCount * stride);
senorblanco6599eff2016-03-10 08:38:45 -0800104 }
Chris Daltond081dce2020-01-23 12:09:04 -0700105 fLockStride = stride;
senorblanco6599eff2016-03-10 08:38:45 -0800106 return fVertices;
107 }
108 void unlock(int actualCount) override {
Chris Daltond081dce2020-01-23 12:09:04 -0700109 SkASSERT(fLockStride);
senorblanco6599eff2016-03-10 08:38:45 -0800110 if (fCanMapVB) {
111 fVertexBuffer->unmap();
112 } else {
Chris Daltond081dce2020-01-23 12:09:04 -0700113 fVertexBuffer->updateData(fVertices, actualCount * fLockStride);
senorblancof57372d2016-08-31 10:36:19 -0700114 sk_free(fVertices);
senorblanco6599eff2016-03-10 08:38:45 -0800115 }
116 fVertices = nullptr;
Chris Daltond081dce2020-01-23 12:09:04 -0700117 fLockStride = 0;
senorblanco6599eff2016-03-10 08:38:45 -0800118 }
Brian Salomondbf70722019-02-07 11:31:24 -0500119 sk_sp<GrGpuBuffer> detachVertexBuffer() { return std::move(fVertexBuffer); }
Brian Salomon12d22642019-01-29 14:38:50 -0500120
senorblanco6599eff2016-03-10 08:38:45 -0800121private:
Brian Salomondbf70722019-02-07 11:31:24 -0500122 sk_sp<GrGpuBuffer> fVertexBuffer;
senorblanco6599eff2016-03-10 08:38:45 -0800123 GrResourceProvider* fResourceProvider;
124 bool fCanMapVB;
senorblancof57372d2016-08-31 10:36:19 -0700125 void* fVertices;
Chris Daltond081dce2020-01-23 12:09:04 -0700126 size_t fLockStride = 0;
senorblanco6599eff2016-03-10 08:38:45 -0800127};
128
ethannicholase9709e82016-01-07 13:34:16 -0800129} // namespace
senorblancod6ed19c2015-02-26 06:58:17 -0800130
Chris Dalton17dc4182020-03-25 16:18:16 -0600131GrTriangulatingPathRenderer::GrTriangulatingPathRenderer()
Stephen White8a3c0592019-05-29 11:26:16 -0400132 : fMaxVerbCount(GR_AA_TESSELLATOR_MAX_VERB_COUNT) {
senorblancod6ed19c2015-02-26 06:58:17 -0800133}
134
Chris Dalton5ed44232017-09-07 13:22:46 -0600135GrPathRenderer::CanDrawPath
Chris Dalton17dc4182020-03-25 16:18:16 -0600136GrTriangulatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
Chris Daltone5ede4b2017-09-07 18:33:08 +0000137 // This path renderer can draw fill styles, and can do screenspace antialiasing via a
138 // one-pixel coverage ramp. It can do convex and concave paths, but we'll leave the convex
139 // ones to simpler algorithms. We pass on paths that have styles, though they may come back
Chris Dalton09e56892019-03-13 00:22:01 -0600140 // around after applying the styling information to the geometry to create a filled path.
Chris Daltone5ede4b2017-09-07 18:33:08 +0000141 if (!args.fShape->style().isSimpleFill() || args.fShape->knownToBeConvex()) {
Chris Dalton5ed44232017-09-07 13:22:46 -0600142 return CanDrawPath::kNo;
senorblancof57372d2016-08-31 10:36:19 -0700143 }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600144 switch (args.fAAType) {
145 case GrAAType::kNone:
146 case GrAAType::kMSAA:
147 // Prefer MSAA, if any antialiasing. In the non-analytic-AA case, We skip paths that
148 // don't have a key since the real advantage of this path renderer comes from caching
149 // the tessellated geometry.
150 if (!args.fShape->hasUnstyledKey()) {
151 return CanDrawPath::kNo;
152 }
153 break;
154 case GrAAType::kCoverage:
155 // Use analytic AA if we don't have MSAA. In this case, we do not cache, so we accept
156 // paths without keys.
157 SkPath path;
158 args.fShape->asPath(&path);
159 if (path.countVerbs() > fMaxVerbCount) {
160 return CanDrawPath::kNo;
161 }
162 break;
senorblancof57372d2016-08-31 10:36:19 -0700163 }
Chris Dalton5ed44232017-09-07 13:22:46 -0600164 return CanDrawPath::kYes;
senorblancod6ed19c2015-02-26 06:58:17 -0800165}
166
Brian Salomon9530f7e2017-07-11 09:03:10 -0400167namespace {
168
Chris Dalton17dc4182020-03-25 16:18:16 -0600169class TriangulatingPathOp final : public GrMeshDrawOp {
Brian Salomon9530f7e2017-07-11 09:03:10 -0400170private:
171 using Helper = GrSimpleMeshDrawOpHelperWithStencil;
172
senorblanco9ba39722015-03-05 07:13:42 -0800173public:
Brian Salomon25a88092016-12-01 09:36:50 -0500174 DEFINE_OP_CLASS_ID
senorblanco9ba39722015-03-05 07:13:42 -0800175
Robert Phillipsb97da532019-02-12 15:24:12 -0500176 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
Robert Phillips7c525e62018-06-12 10:11:12 -0400177 GrPaint&& paint,
Michael Ludwig2686d692020-04-17 20:21:37 +0000178 const GrStyledShape& shape,
Brian Salomon9530f7e2017-07-11 09:03:10 -0400179 const SkMatrix& viewMatrix,
180 SkIRect devClipBounds,
181 GrAAType aaType,
182 const GrUserStencilSettings* stencilSettings) {
Chris Dalton17dc4182020-03-25 16:18:16 -0600183 return Helper::FactoryHelper<TriangulatingPathOp>(context, std::move(paint), shape,
184 viewMatrix, devClipBounds, aaType,
185 stencilSettings);
senorblanco9ba39722015-03-05 07:13:42 -0800186 }
187
Chris Dalton17dc4182020-03-25 16:18:16 -0600188 const char* name() const override { return "TriangulatingPathOp"; }
senorblanco9ba39722015-03-05 07:13:42 -0800189
Chris Dalton1706cbf2019-05-21 19:35:29 -0600190 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillips740d34f2020-03-11 09:36:13 -0400191 if (fProgramInfo) {
Chris Daltonbe457422020-03-16 18:05:03 -0600192 fProgramInfo->visitFPProxies(func);
Robert Phillips740d34f2020-03-11 09:36:13 -0400193 } else {
194 fHelper.visitProxies(func);
195 }
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400196 }
197
Chris Dalton17dc4182020-03-25 16:18:16 -0600198 TriangulatingPathOp(Helper::MakeArgs helperArgs,
199 const SkPMColor4f& color,
Michael Ludwig2686d692020-04-17 20:21:37 +0000200 const GrStyledShape& shape,
Chris Dalton17dc4182020-03-25 16:18:16 -0600201 const SkMatrix& viewMatrix,
202 const SkIRect& devClipBounds,
203 GrAAType aaType,
204 const GrUserStencilSettings* stencilSettings)
Brian Salomon9530f7e2017-07-11 09:03:10 -0400205 : INHERITED(ClassID())
206 , fHelper(helperArgs, aaType, stencilSettings)
207 , fColor(color)
208 , fShape(shape)
209 , fViewMatrix(viewMatrix)
210 , fDevClipBounds(devClipBounds)
211 , fAntiAlias(GrAAType::kCoverage == aaType) {
212 SkRect devBounds;
213 viewMatrix.mapRect(&devBounds, shape.bounds());
214 if (shape.inverseFilled()) {
215 // Because the clip bounds are used to add a contour for inverse fills, they must also
216 // include the path bounds.
217 devBounds.join(SkRect::Make(fDevClipBounds));
218 }
Greg Daniel5faf4742019-10-01 15:14:44 -0400219 this->setBounds(devBounds, HasAABloat::kNo, IsHairline::kNo);
Brian Salomon9530f7e2017-07-11 09:03:10 -0400220 }
221
222 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
223
Chris Dalton6ce447a2019-06-23 18:07:38 -0600224 GrProcessorSet::Analysis finalize(
225 const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
226 GrClampType clampType) override {
Brian Salomon9530f7e2017-07-11 09:03:10 -0400227 GrProcessorAnalysisCoverage coverage = fAntiAlias
228 ? GrProcessorAnalysisCoverage::kSingleChannel
229 : GrProcessorAnalysisCoverage::kNone;
Brian Osman8fa7ab42019-03-18 10:22:42 -0400230 // This Op uses uniform (not vertex) color, so doesn't need to track wide color.
231 return fHelper.finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -0600232 caps, clip, hasMixedSampledCoverage, clampType, coverage, &fColor, nullptr);
Brian Salomon9530f7e2017-07-11 09:03:10 -0400233 }
234
Brian Salomon92aee3d2016-12-21 09:20:25 -0500235private:
senorblancof57372d2016-08-31 10:36:19 -0700236 SkPath getPath() const {
237 SkASSERT(!fShape.style().applies());
bsalomonee432412016-06-27 07:18:18 -0700238 SkPath path;
239 fShape.asPath(&path);
senorblancof57372d2016-08-31 10:36:19 -0700240 return path;
241 }
242
Robert Phillips6ffcb232020-10-14 12:40:13 -0400243 static void CreateKey(GrUniqueKey* key,
244 const GrStyledShape& shape,
245 const SkIRect& devClipBounds) {
senorblanco84cd6212015-08-04 10:01:58 -0700246 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
Robert Phillips6ffcb232020-10-14 12:40:13 -0400247
248 bool inverseFill = shape.inverseFilled();
249
250 static constexpr int kClipBoundsCnt = sizeof(devClipBounds) / sizeof(uint32_t);
251 int shapeKeyDataCnt = shape.unstyledKeySize();
bsalomonee432412016-06-27 07:18:18 -0700252 SkASSERT(shapeKeyDataCnt >= 0);
Robert Phillips6ffcb232020-10-14 12:40:13 -0400253 GrUniqueKey::Builder builder(key, kDomain, shapeKeyDataCnt + kClipBoundsCnt, "Path");
254 shape.writeUnstyledKey(&builder[0]);
bsalomonee432412016-06-27 07:18:18 -0700255 // For inverse fills, the tessellation is dependent on clip bounds.
256 if (inverseFill) {
Robert Phillips6ffcb232020-10-14 12:40:13 -0400257 memcpy(&builder[shapeKeyDataCnt], &devClipBounds, sizeof(devClipBounds));
bsalomonee432412016-06-27 07:18:18 -0700258 } else {
Robert Phillips6ffcb232020-10-14 12:40:13 -0400259 memset(&builder[shapeKeyDataCnt], 0, sizeof(devClipBounds));
bsalomonee432412016-06-27 07:18:18 -0700260 }
Robert Phillips6ffcb232020-10-14 12:40:13 -0400261
bsalomonee432412016-06-27 07:18:18 -0700262 builder.finish();
Robert Phillips6ffcb232020-10-14 12:40:13 -0400263 }
264
265 void createNonAAMesh(Target* target) {
266 SkASSERT(!fAntiAlias);
267 GrResourceProvider* rp = target->resourceProvider();
268
269 GrUniqueKey key;
270 CreateKey(&key, fShape, fDevClipBounds);
271
Robert Phillips6cc9d8d2020-10-20 09:42:33 -0400272 SkScalar tol = GrPathUtils::scaleToleranceToSrc(GrPathUtils::kDefaultTolerance,
273 fViewMatrix, fShape.bounds());
274
Brian Salomondbf70722019-02-07 11:31:24 -0500275 sk_sp<GrGpuBuffer> cachedVertexBuffer(rp->findByUniqueKey<GrGpuBuffer>(key));
Robert Phillips6cc9d8d2020-10-20 09:42:33 -0400276 if (cachedVertexBuffer) {
277 int actualCount;
278
279 if (cache_match(cachedVertexBuffer->getUniqueKey().getCustomData(), tol,
280 &actualCount)) {
281 this->createMesh(target, std::move(cachedVertexBuffer), 0, actualCount);
282 return;
283 }
senorblanco84cd6212015-08-04 10:01:58 -0700284 }
285
senorblancof57372d2016-08-31 10:36:19 -0700286 SkRect clipBounds = SkRect::Make(fDevClipBounds);
287
288 SkMatrix vmi;
289 if (!fViewMatrix.invert(&vmi)) {
290 return;
291 }
292 vmi.mapRect(&clipBounds);
Chris Dalton8e2b6942020-04-22 15:55:00 -0600293 int numCountedCurves;
senorblanco6599eff2016-03-10 08:38:45 -0800294 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags();
Chris Daltond081dce2020-01-23 12:09:04 -0700295 StaticVertexAllocator allocator(rp, canMapVB);
Robert Phillips6ffcb232020-10-14 12:40:13 -0400296 int vertexCount = GrTriangulator::PathToTriangles(this->getPath(), tol, clipBounds,
297 &allocator, GrTriangulator::Mode::kNormal,
Chris Dalton8e2b6942020-04-22 15:55:00 -0600298 &numCountedCurves);
299 if (vertexCount == 0) {
senorblanco6599eff2016-03-10 08:38:45 -0800300 return;
301 }
Brian Salomondbf70722019-02-07 11:31:24 -0500302 sk_sp<GrGpuBuffer> vb = allocator.detachVertexBuffer();
Robert Phillips6cc9d8d2020-10-20 09:42:33 -0400303
304 key.setCustomData(create_data(vertexCount, numCountedCurves, tol));
305
Brian Salomon99a813c2020-03-02 12:50:47 -0500306 fShape.addGenIDChangeListener(
307 sk_make_sp<UniqueKeyInvalidator>(key, target->contextUniqueID()));
Brian Salomon12d22642019-01-29 14:38:50 -0500308 rp->assignUniqueKeyToResource(key, vb.get());
309
Chris Dalton8e2b6942020-04-22 15:55:00 -0600310 this->createMesh(target, std::move(vb), 0, vertexCount);
senorblanco6599eff2016-03-10 08:38:45 -0800311 }
312
Robert Phillips6ffcb232020-10-14 12:40:13 -0400313 void createAAMesh(Target* target) {
senorblancof57372d2016-08-31 10:36:19 -0700314 SkASSERT(fAntiAlias);
Robert Phillips6ffcb232020-10-14 12:40:13 -0400315 SkPath path = this->getPath();
senorblancof57372d2016-08-31 10:36:19 -0700316 if (path.isEmpty()) {
317 return;
318 }
319 SkRect clipBounds = SkRect::Make(fDevClipBounds);
320 path.transform(fViewMatrix);
321 SkScalar tol = GrPathUtils::kDefaultTolerance;
Chris Daltond081dce2020-01-23 12:09:04 -0700322 sk_sp<const GrBuffer> vertexBuffer;
323 int firstVertex;
Chris Dalton8e2b6942020-04-22 15:55:00 -0600324 int numCountedCurves;
Chris Daltond081dce2020-01-23 12:09:04 -0700325 GrEagerDynamicVertexAllocator allocator(target, &vertexBuffer, &firstVertex);
Chris Dalton8e2b6942020-04-22 15:55:00 -0600326 int vertexCount = GrTriangulator::PathToTriangles(path, tol, clipBounds, &allocator,
327 GrTriangulator::Mode::kEdgeAntialias,
328 &numCountedCurves);
329 if (vertexCount == 0) {
senorblancof57372d2016-08-31 10:36:19 -0700330 return;
331 }
Chris Dalton8e2b6942020-04-22 15:55:00 -0600332 this->createMesh(target, std::move(vertexBuffer), firstVertex, vertexCount);
senorblancof57372d2016-08-31 10:36:19 -0700333 }
334
Robert Phillips2669a7b2020-03-12 12:07:19 -0400335 GrProgramInfo* programInfo() override { return fProgramInfo; }
336
Robert Phillips4133dc42020-03-11 15:55:55 -0400337 void onCreateProgramInfo(const GrCaps* caps,
338 SkArenaAlloc* arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400339 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400340 GrAppliedClip&& appliedClip,
Greg Danield358cbe2020-09-11 09:33:54 -0400341 const GrXferProcessor::DstProxyView& dstProxyView,
342 GrXferBarrierFlags renderPassXferBarriers) override {
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500343 GrGeometryProcessor* gp;
joshualittdf0c5572015-08-03 11:35:28 -0700344 {
345 using namespace GrDefaultGeoProcFactory;
346
347 Color color(fColor);
Brian Salomon9530f7e2017-07-11 09:03:10 -0400348 LocalCoords::Type localCoordsType = fHelper.usesLocalCoords()
Brian Salomon8c852be2017-01-04 10:44:42 -0500349 ? LocalCoords::kUsePosition_Type
350 : LocalCoords::kUnused_Type;
joshualittdf0c5572015-08-03 11:35:28 -0700351 Coverage::Type coverageType;
senorblancof57372d2016-08-31 10:36:19 -0700352 if (fAntiAlias) {
Brian Osman605c6d52019-03-15 12:10:35 -0400353 if (fHelper.compatibleWithCoverageAsAlpha()) {
Brian Osman80879d42019-01-07 16:15:27 -0500354 coverageType = Coverage::kAttributeTweakAlpha_Type;
senorblancof57372d2016-08-31 10:36:19 -0700355 } else {
356 coverageType = Coverage::kAttribute_Type;
357 }
Brian Salomon8c852be2017-01-04 10:44:42 -0500358 } else {
joshualittdf0c5572015-08-03 11:35:28 -0700359 coverageType = Coverage::kSolid_Type;
joshualittdf0c5572015-08-03 11:35:28 -0700360 }
senorblancof57372d2016-08-31 10:36:19 -0700361 if (fAntiAlias) {
Brian Osmanf0aee742020-03-12 09:28:44 -0400362 gp = GrDefaultGeoProcFactory::MakeForDeviceSpace(arena, color, coverageType,
Brian Salomon8c852be2017-01-04 10:44:42 -0500363 localCoordsType, fViewMatrix);
senorblancof57372d2016-08-31 10:36:19 -0700364 } else {
Brian Osmanf0aee742020-03-12 09:28:44 -0400365 gp = GrDefaultGeoProcFactory::Make(arena, color, coverageType, localCoordsType,
Brian Salomon8c852be2017-01-04 10:44:42 -0500366 fViewMatrix);
senorblancof57372d2016-08-31 10:36:19 -0700367 }
joshualittdf0c5572015-08-03 11:35:28 -0700368 }
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500369 if (!gp) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400370 return;
Stephen Whitecc700832017-02-15 11:45:16 -0500371 }
Robert Phillips740d34f2020-03-11 09:36:13 -0400372
Chris Daltondcc8c542020-01-28 17:55:56 -0700373#ifdef SK_DEBUG
Chris Dalton17dc4182020-03-25 16:18:16 -0600374 auto mode = (fAntiAlias) ? GrTriangulator::Mode::kEdgeAntialias
375 : GrTriangulator::Mode::kNormal;
376 SkASSERT(GrTriangulator::GetVertexStride(mode) == gp->vertexStride());
Chris Daltondcc8c542020-01-28 17:55:56 -0700377#endif
senorblanco84cd6212015-08-04 10:01:58 -0700378
Chris Dalton17dc4182020-03-25 16:18:16 -0600379 GrPrimitiveType primitiveType = TRIANGULATOR_WIREFRAME ? GrPrimitiveType::kLines
380 : GrPrimitiveType::kTriangles;
Robert Phillipse94cdd22019-11-04 14:15:58 -0500381
Brian Salomon8afde5f2020-04-01 16:22:00 -0400382 fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400383 std::move(appliedClip), dstProxyView,
Greg Danield358cbe2020-09-11 09:33:54 -0400384 gp, primitiveType,
385 renderPassXferBarriers);
Robert Phillips740d34f2020-03-11 09:36:13 -0400386 }
387
Robert Phillips740d34f2020-03-11 09:36:13 -0400388 void onPrepareDraws(Target* target) override {
389 if (fAntiAlias) {
Robert Phillips6ffcb232020-10-14 12:40:13 -0400390 this->createAAMesh(target);
Robert Phillips740d34f2020-03-11 09:36:13 -0400391 } else {
Robert Phillips6ffcb232020-10-14 12:40:13 -0400392 this->createNonAAMesh(target);
Robert Phillips740d34f2020-03-11 09:36:13 -0400393 }
394 }
395
396 void createMesh(Target* target, sk_sp<const GrBuffer> vb, int firstVertex, int count) {
397 fMesh = target->allocMesh();
Chris Dalton37c7bdd2020-03-13 09:21:12 -0600398 fMesh->set(std::move(vb), count, firstVertex);
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700399 }
400
401 void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
Robert Phillips740d34f2020-03-11 09:36:13 -0400402 if (!fProgramInfo) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400403 this->createProgramInfo(flushState);
Robert Phillips740d34f2020-03-11 09:36:13 -0400404 }
Robert Phillips3968fcb2019-12-05 16:40:31 -0500405
Robert Phillips740d34f2020-03-11 09:36:13 -0400406 if (!fProgramInfo || !fMesh) {
407 return;
408 }
409
Chris Dalton765ed362020-03-16 17:34:44 -0600410 flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
411 flushState->bindTextures(fProgramInfo->primProc(), nullptr, fProgramInfo->pipeline());
412 flushState->drawMesh(*fMesh);
senorblanco9ba39722015-03-05 07:13:42 -0800413 }
414
John Stilesaf366522020-08-13 09:57:34 -0400415#if GR_TEST_UTILS
416 SkString onDumpInfo() const override {
417 return SkStringPrintf("Color 0x%08x, aa: %d\n%s",
418 fColor.toBytes_RGBA(), fAntiAlias, fHelper.dumpInfo().c_str());
419 }
420#endif
421
Robert Phillips740d34f2020-03-11 09:36:13 -0400422 Helper fHelper;
423 SkPMColor4f fColor;
Michael Ludwig2686d692020-04-17 20:21:37 +0000424 GrStyledShape fShape;
Robert Phillips740d34f2020-03-11 09:36:13 -0400425 SkMatrix fViewMatrix;
426 SkIRect fDevClipBounds;
427 bool fAntiAlias;
428
Chris Daltoneb694b72020-03-16 09:25:50 -0600429 GrSimpleMesh* fMesh = nullptr;
Robert Phillips740d34f2020-03-11 09:36:13 -0400430 GrProgramInfo* fProgramInfo = nullptr;
reed1b55a962015-09-17 20:16:13 -0700431
John Stiles7571f9e2020-09-02 22:42:33 -0400432 using INHERITED = GrMeshDrawOp;
senorblanco9ba39722015-03-05 07:13:42 -0800433};
434
Brian Salomon9530f7e2017-07-11 09:03:10 -0400435} // anonymous namespace
436
Chris Dalton17dc4182020-03-25 16:18:16 -0600437bool GrTriangulatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
Brian Osman11052242016-10-27 14:47:55 -0400438 GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
Chris Dalton17dc4182020-03-25 16:18:16 -0600439 "GrTriangulatingPathRenderer::onDrawPath");
Michael Ludwig7c12e282020-05-29 09:54:07 -0400440
Chris Dalton17dc4182020-03-25 16:18:16 -0600441 std::unique_ptr<GrDrawOp> op = TriangulatingPathOp::Make(
Michael Ludwig7c12e282020-05-29 09:54:07 -0400442 args.fContext, std::move(args.fPaint), *args.fShape, *args.fViewMatrix,
443 *args.fClipConservativeBounds, args.fAAType, args.fUserStencilSettings);
444 args.fRenderTargetContext->addDrawOp(args.fClip, std::move(op));
senorblancod6ed19c2015-02-26 06:58:17 -0800445 return true;
446}
joshualitt2fbd4062015-05-07 13:06:41 -0700447
448///////////////////////////////////////////////////////////////////////////////////////////////////
449
Hal Canary6f6961e2017-01-31 13:50:44 -0500450#if GR_TEST_UTILS
joshualitt2fbd4062015-05-07 13:06:41 -0700451
Chris Dalton17dc4182020-03-25 16:18:16 -0600452GR_DRAW_OP_TEST_DEFINE(TriangulatingPathOp) {
joshualitt2fbd4062015-05-07 13:06:41 -0700453 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
John Stiles31954bf2020-08-07 17:35:54 -0400454 const SkPath& path = GrTest::TestPath(random);
bsalomond3030ac2016-09-01 07:20:29 -0700455 SkIRect devClipBounds = SkIRect::MakeLTRB(
senorblancof57372d2016-08-31 10:36:19 -0700456 random->nextU(), random->nextU(), random->nextU(), random->nextU());
bsalomond3030ac2016-09-01 07:20:29 -0700457 devClipBounds.sort();
Brian Salomon9530f7e2017-07-11 09:03:10 -0400458 static constexpr GrAAType kAATypes[] = {GrAAType::kNone, GrAAType::kMSAA, GrAAType::kCoverage};
459 GrAAType aaType;
460 do {
461 aaType = kAATypes[random->nextULessThan(SK_ARRAY_COUNT(kAATypes))];
Chris Dalton6ce447a2019-06-23 18:07:38 -0600462 } while(GrAAType::kMSAA == aaType && numSamples <= 1);
bsalomon6663acf2016-05-10 09:14:17 -0700463 GrStyle style;
464 do {
465 GrTest::TestStyle(random, &style);
senorblancof57372d2016-08-31 10:36:19 -0700466 } while (!style.isSimpleFill());
Michael Ludwig2686d692020-04-17 20:21:37 +0000467 GrStyledShape shape(path, style);
Chris Dalton17dc4182020-03-25 16:18:16 -0600468 return TriangulatingPathOp::Make(context, std::move(paint), shape, viewMatrix, devClipBounds,
469 aaType, GrGetRandomStencil(random, context));
joshualitt2fbd4062015-05-07 13:06:41 -0700470}
471
472#endif