blob: eab791cffff477a315ba2f097364d5d3ad657bb6 [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
ethannicholase9709e82016-01-07 13:34:16 -080048// When the SkPathRef genID changes, invalidate a corresponding GrResource described by key.
Brian Salomon99a813c2020-03-02 12:50:47 -050049class UniqueKeyInvalidator : public SkIDChangeListener {
ethannicholase9709e82016-01-07 13:34:16 -080050public:
Brian Salomon99a813c2020-03-02 12:50:47 -050051 UniqueKeyInvalidator(const GrUniqueKey& key, uint32_t contextUniqueID)
Brian Salomon238069b2018-07-11 15:58:57 -040052 : fMsg(key, contextUniqueID) {}
53
ethannicholase9709e82016-01-07 13:34:16 -080054private:
55 GrUniqueKeyInvalidatedMessage fMsg;
56
Brian Salomon99a813c2020-03-02 12:50:47 -050057 void changed() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
ethannicholase9709e82016-01-07 13:34:16 -080058};
59
Brian Salomondbf70722019-02-07 11:31:24 -050060bool cache_match(GrGpuBuffer* vertexBuffer, SkScalar tol, int* actualCount) {
senorblanco84cd6212015-08-04 10:01:58 -070061 if (!vertexBuffer) {
62 return false;
63 }
64 const SkData* data = vertexBuffer->getUniqueKey().getCustomData();
65 SkASSERT(data);
66 const TessInfo* info = static_cast<const TessInfo*>(data->data());
67 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) {
senorblanco06f989a2015-09-02 09:05:17 -070068 *actualCount = info->fCount;
senorblanco84cd6212015-08-04 10:01:58 -070069 return true;
70 }
71 return false;
72}
73
Chris Daltond081dce2020-01-23 12:09:04 -070074class StaticVertexAllocator : public GrEagerVertexAllocator {
senorblanco6599eff2016-03-10 08:38:45 -080075public:
Chris Daltond081dce2020-01-23 12:09:04 -070076 StaticVertexAllocator(GrResourceProvider* resourceProvider, bool canMapVB)
Robert Phillips6ffcb232020-10-14 12:40:13 -040077 : fResourceProvider(resourceProvider)
78 , fCanMapVB(canMapVB)
79 , fVertices(nullptr) {
senorblanco6599eff2016-03-10 08:38:45 -080080 }
Robert Phillips6ffcb232020-10-14 12:40:13 -040081
Chris Daltond081dce2020-01-23 12:09:04 -070082#ifdef SK_DEBUG
83 ~StaticVertexAllocator() override {
84 SkASSERT(!fLockStride);
85 }
86#endif
87 void* lock(size_t stride, int eagerCount) override {
88 SkASSERT(!fLockStride);
89 SkASSERT(stride);
90 size_t size = eagerCount * stride;
Brian Salomonae64c192019-02-05 09:41:37 -050091 fVertexBuffer = fResourceProvider->createBuffer(size, GrGpuBufferType::kVertex,
Brian Salomondbf70722019-02-07 11:31:24 -050092 kStatic_GrAccessPattern);
John Stilesa008b0f2020-08-16 08:48:02 -040093 if (!fVertexBuffer) {
senorblanco6599eff2016-03-10 08:38:45 -080094 return nullptr;
95 }
96 if (fCanMapVB) {
senorblancof57372d2016-08-31 10:36:19 -070097 fVertices = fVertexBuffer->map();
senorblanco6599eff2016-03-10 08:38:45 -080098 } else {
Chris Daltond081dce2020-01-23 12:09:04 -070099 fVertices = sk_malloc_throw(eagerCount * stride);
senorblanco6599eff2016-03-10 08:38:45 -0800100 }
Chris Daltond081dce2020-01-23 12:09:04 -0700101 fLockStride = stride;
senorblanco6599eff2016-03-10 08:38:45 -0800102 return fVertices;
103 }
104 void unlock(int actualCount) override {
Chris Daltond081dce2020-01-23 12:09:04 -0700105 SkASSERT(fLockStride);
senorblanco6599eff2016-03-10 08:38:45 -0800106 if (fCanMapVB) {
107 fVertexBuffer->unmap();
108 } else {
Chris Daltond081dce2020-01-23 12:09:04 -0700109 fVertexBuffer->updateData(fVertices, actualCount * fLockStride);
senorblancof57372d2016-08-31 10:36:19 -0700110 sk_free(fVertices);
senorblanco6599eff2016-03-10 08:38:45 -0800111 }
112 fVertices = nullptr;
Chris Daltond081dce2020-01-23 12:09:04 -0700113 fLockStride = 0;
senorblanco6599eff2016-03-10 08:38:45 -0800114 }
Brian Salomondbf70722019-02-07 11:31:24 -0500115 sk_sp<GrGpuBuffer> detachVertexBuffer() { return std::move(fVertexBuffer); }
Brian Salomon12d22642019-01-29 14:38:50 -0500116
senorblanco6599eff2016-03-10 08:38:45 -0800117private:
Brian Salomondbf70722019-02-07 11:31:24 -0500118 sk_sp<GrGpuBuffer> fVertexBuffer;
senorblanco6599eff2016-03-10 08:38:45 -0800119 GrResourceProvider* fResourceProvider;
120 bool fCanMapVB;
senorblancof57372d2016-08-31 10:36:19 -0700121 void* fVertices;
Chris Daltond081dce2020-01-23 12:09:04 -0700122 size_t fLockStride = 0;
senorblanco6599eff2016-03-10 08:38:45 -0800123};
124
ethannicholase9709e82016-01-07 13:34:16 -0800125} // namespace
senorblancod6ed19c2015-02-26 06:58:17 -0800126
Chris Dalton17dc4182020-03-25 16:18:16 -0600127GrTriangulatingPathRenderer::GrTriangulatingPathRenderer()
Stephen White8a3c0592019-05-29 11:26:16 -0400128 : fMaxVerbCount(GR_AA_TESSELLATOR_MAX_VERB_COUNT) {
senorblancod6ed19c2015-02-26 06:58:17 -0800129}
130
Chris Dalton5ed44232017-09-07 13:22:46 -0600131GrPathRenderer::CanDrawPath
Chris Dalton17dc4182020-03-25 16:18:16 -0600132GrTriangulatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
Chris Daltone5ede4b2017-09-07 18:33:08 +0000133 // This path renderer can draw fill styles, and can do screenspace antialiasing via a
134 // one-pixel coverage ramp. It can do convex and concave paths, but we'll leave the convex
135 // ones to simpler algorithms. We pass on paths that have styles, though they may come back
Chris Dalton09e56892019-03-13 00:22:01 -0600136 // around after applying the styling information to the geometry to create a filled path.
Chris Daltone5ede4b2017-09-07 18:33:08 +0000137 if (!args.fShape->style().isSimpleFill() || args.fShape->knownToBeConvex()) {
Chris Dalton5ed44232017-09-07 13:22:46 -0600138 return CanDrawPath::kNo;
senorblancof57372d2016-08-31 10:36:19 -0700139 }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600140 switch (args.fAAType) {
141 case GrAAType::kNone:
142 case GrAAType::kMSAA:
143 // Prefer MSAA, if any antialiasing. In the non-analytic-AA case, We skip paths that
144 // don't have a key since the real advantage of this path renderer comes from caching
145 // the tessellated geometry.
146 if (!args.fShape->hasUnstyledKey()) {
147 return CanDrawPath::kNo;
148 }
149 break;
150 case GrAAType::kCoverage:
151 // Use analytic AA if we don't have MSAA. In this case, we do not cache, so we accept
152 // paths without keys.
153 SkPath path;
154 args.fShape->asPath(&path);
155 if (path.countVerbs() > fMaxVerbCount) {
156 return CanDrawPath::kNo;
157 }
158 break;
senorblancof57372d2016-08-31 10:36:19 -0700159 }
Chris Dalton5ed44232017-09-07 13:22:46 -0600160 return CanDrawPath::kYes;
senorblancod6ed19c2015-02-26 06:58:17 -0800161}
162
Brian Salomon9530f7e2017-07-11 09:03:10 -0400163namespace {
164
Chris Dalton17dc4182020-03-25 16:18:16 -0600165class TriangulatingPathOp final : public GrMeshDrawOp {
Brian Salomon9530f7e2017-07-11 09:03:10 -0400166private:
167 using Helper = GrSimpleMeshDrawOpHelperWithStencil;
168
senorblanco9ba39722015-03-05 07:13:42 -0800169public:
Brian Salomon25a88092016-12-01 09:36:50 -0500170 DEFINE_OP_CLASS_ID
senorblanco9ba39722015-03-05 07:13:42 -0800171
Robert Phillipsb97da532019-02-12 15:24:12 -0500172 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
Robert Phillips7c525e62018-06-12 10:11:12 -0400173 GrPaint&& paint,
Michael Ludwig2686d692020-04-17 20:21:37 +0000174 const GrStyledShape& shape,
Brian Salomon9530f7e2017-07-11 09:03:10 -0400175 const SkMatrix& viewMatrix,
176 SkIRect devClipBounds,
177 GrAAType aaType,
178 const GrUserStencilSettings* stencilSettings) {
Chris Dalton17dc4182020-03-25 16:18:16 -0600179 return Helper::FactoryHelper<TriangulatingPathOp>(context, std::move(paint), shape,
180 viewMatrix, devClipBounds, aaType,
181 stencilSettings);
senorblanco9ba39722015-03-05 07:13:42 -0800182 }
183
Chris Dalton17dc4182020-03-25 16:18:16 -0600184 const char* name() const override { return "TriangulatingPathOp"; }
senorblanco9ba39722015-03-05 07:13:42 -0800185
Chris Dalton1706cbf2019-05-21 19:35:29 -0600186 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillips740d34f2020-03-11 09:36:13 -0400187 if (fProgramInfo) {
Chris Daltonbe457422020-03-16 18:05:03 -0600188 fProgramInfo->visitFPProxies(func);
Robert Phillips740d34f2020-03-11 09:36:13 -0400189 } else {
190 fHelper.visitProxies(func);
191 }
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400192 }
193
Chris Dalton17dc4182020-03-25 16:18:16 -0600194 TriangulatingPathOp(Helper::MakeArgs helperArgs,
195 const SkPMColor4f& color,
Michael Ludwig2686d692020-04-17 20:21:37 +0000196 const GrStyledShape& shape,
Chris Dalton17dc4182020-03-25 16:18:16 -0600197 const SkMatrix& viewMatrix,
198 const SkIRect& devClipBounds,
199 GrAAType aaType,
200 const GrUserStencilSettings* stencilSettings)
Brian Salomon9530f7e2017-07-11 09:03:10 -0400201 : INHERITED(ClassID())
202 , fHelper(helperArgs, aaType, stencilSettings)
203 , fColor(color)
204 , fShape(shape)
205 , fViewMatrix(viewMatrix)
206 , fDevClipBounds(devClipBounds)
207 , fAntiAlias(GrAAType::kCoverage == aaType) {
208 SkRect devBounds;
209 viewMatrix.mapRect(&devBounds, shape.bounds());
210 if (shape.inverseFilled()) {
211 // Because the clip bounds are used to add a contour for inverse fills, they must also
212 // include the path bounds.
213 devBounds.join(SkRect::Make(fDevClipBounds));
214 }
Greg Daniel5faf4742019-10-01 15:14:44 -0400215 this->setBounds(devBounds, HasAABloat::kNo, IsHairline::kNo);
Brian Salomon9530f7e2017-07-11 09:03:10 -0400216 }
217
218 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
219
Chris Dalton6ce447a2019-06-23 18:07:38 -0600220 GrProcessorSet::Analysis finalize(
221 const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
222 GrClampType clampType) override {
Brian Salomon9530f7e2017-07-11 09:03:10 -0400223 GrProcessorAnalysisCoverage coverage = fAntiAlias
224 ? GrProcessorAnalysisCoverage::kSingleChannel
225 : GrProcessorAnalysisCoverage::kNone;
Brian Osman8fa7ab42019-03-18 10:22:42 -0400226 // This Op uses uniform (not vertex) color, so doesn't need to track wide color.
227 return fHelper.finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -0600228 caps, clip, hasMixedSampledCoverage, clampType, coverage, &fColor, nullptr);
Brian Salomon9530f7e2017-07-11 09:03:10 -0400229 }
230
Brian Salomon92aee3d2016-12-21 09:20:25 -0500231private:
senorblancof57372d2016-08-31 10:36:19 -0700232 SkPath getPath() const {
233 SkASSERT(!fShape.style().applies());
bsalomonee432412016-06-27 07:18:18 -0700234 SkPath path;
235 fShape.asPath(&path);
senorblancof57372d2016-08-31 10:36:19 -0700236 return path;
237 }
238
Robert Phillips6ffcb232020-10-14 12:40:13 -0400239 static void CreateKey(GrUniqueKey* key,
240 const GrStyledShape& shape,
241 const SkIRect& devClipBounds) {
senorblanco84cd6212015-08-04 10:01:58 -0700242 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
Robert Phillips6ffcb232020-10-14 12:40:13 -0400243
244 bool inverseFill = shape.inverseFilled();
245
246 static constexpr int kClipBoundsCnt = sizeof(devClipBounds) / sizeof(uint32_t);
247 int shapeKeyDataCnt = shape.unstyledKeySize();
bsalomonee432412016-06-27 07:18:18 -0700248 SkASSERT(shapeKeyDataCnt >= 0);
Robert Phillips6ffcb232020-10-14 12:40:13 -0400249 GrUniqueKey::Builder builder(key, kDomain, shapeKeyDataCnt + kClipBoundsCnt, "Path");
250 shape.writeUnstyledKey(&builder[0]);
bsalomonee432412016-06-27 07:18:18 -0700251 // For inverse fills, the tessellation is dependent on clip bounds.
252 if (inverseFill) {
Robert Phillips6ffcb232020-10-14 12:40:13 -0400253 memcpy(&builder[shapeKeyDataCnt], &devClipBounds, sizeof(devClipBounds));
bsalomonee432412016-06-27 07:18:18 -0700254 } else {
Robert Phillips6ffcb232020-10-14 12:40:13 -0400255 memset(&builder[shapeKeyDataCnt], 0, sizeof(devClipBounds));
bsalomonee432412016-06-27 07:18:18 -0700256 }
Robert Phillips6ffcb232020-10-14 12:40:13 -0400257
bsalomonee432412016-06-27 07:18:18 -0700258 builder.finish();
Robert Phillips6ffcb232020-10-14 12:40:13 -0400259 }
260
261 void createNonAAMesh(Target* target) {
262 SkASSERT(!fAntiAlias);
263 GrResourceProvider* rp = target->resourceProvider();
264
265 GrUniqueKey key;
266 CreateKey(&key, fShape, fDevClipBounds);
267
Brian Salomondbf70722019-02-07 11:31:24 -0500268 sk_sp<GrGpuBuffer> cachedVertexBuffer(rp->findByUniqueKey<GrGpuBuffer>(key));
bsalomonee432412016-06-27 07:18:18 -0700269 int actualCount;
senorblancof57372d2016-08-31 10:36:19 -0700270 SkScalar tol = GrPathUtils::kDefaultTolerance;
271 tol = GrPathUtils::scaleToleranceToSrc(tol, fViewMatrix, fShape.bounds());
bsalomonee432412016-06-27 07:18:18 -0700272 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) {
Robert Phillips740d34f2020-03-11 09:36:13 -0400273 this->createMesh(target, std::move(cachedVertexBuffer), 0, actualCount);
bsalomonee432412016-06-27 07:18:18 -0700274 return;
senorblanco84cd6212015-08-04 10:01:58 -0700275 }
276
senorblancof57372d2016-08-31 10:36:19 -0700277 SkRect clipBounds = SkRect::Make(fDevClipBounds);
278
279 SkMatrix vmi;
280 if (!fViewMatrix.invert(&vmi)) {
281 return;
282 }
283 vmi.mapRect(&clipBounds);
Chris Dalton8e2b6942020-04-22 15:55:00 -0600284 int numCountedCurves;
senorblanco6599eff2016-03-10 08:38:45 -0800285 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags();
Chris Daltond081dce2020-01-23 12:09:04 -0700286 StaticVertexAllocator allocator(rp, canMapVB);
Robert Phillips6ffcb232020-10-14 12:40:13 -0400287 int vertexCount = GrTriangulator::PathToTriangles(this->getPath(), tol, clipBounds,
288 &allocator, GrTriangulator::Mode::kNormal,
Chris Dalton8e2b6942020-04-22 15:55:00 -0600289 &numCountedCurves);
290 if (vertexCount == 0) {
senorblanco6599eff2016-03-10 08:38:45 -0800291 return;
292 }
Brian Salomondbf70722019-02-07 11:31:24 -0500293 sk_sp<GrGpuBuffer> vb = allocator.detachVertexBuffer();
bsalomonee432412016-06-27 07:18:18 -0700294 TessInfo info;
Chris Dalton8e2b6942020-04-22 15:55:00 -0600295 info.fTolerance = (numCountedCurves == 0) ? 0 : tol;
296 info.fCount = vertexCount;
Brian Salomon99a813c2020-03-02 12:50:47 -0500297 fShape.addGenIDChangeListener(
298 sk_make_sp<UniqueKeyInvalidator>(key, target->contextUniqueID()));
Brian Salomon12d22642019-01-29 14:38:50 -0500299 key.setCustomData(SkData::MakeWithCopy(&info, sizeof(info)));
300 rp->assignUniqueKeyToResource(key, vb.get());
301
Chris Dalton8e2b6942020-04-22 15:55:00 -0600302 this->createMesh(target, std::move(vb), 0, vertexCount);
senorblanco6599eff2016-03-10 08:38:45 -0800303 }
304
Robert Phillips6ffcb232020-10-14 12:40:13 -0400305 void createAAMesh(Target* target) {
senorblancof57372d2016-08-31 10:36:19 -0700306 SkASSERT(fAntiAlias);
Robert Phillips6ffcb232020-10-14 12:40:13 -0400307 SkPath path = this->getPath();
senorblancof57372d2016-08-31 10:36:19 -0700308 if (path.isEmpty()) {
309 return;
310 }
311 SkRect clipBounds = SkRect::Make(fDevClipBounds);
312 path.transform(fViewMatrix);
313 SkScalar tol = GrPathUtils::kDefaultTolerance;
Chris Daltond081dce2020-01-23 12:09:04 -0700314 sk_sp<const GrBuffer> vertexBuffer;
315 int firstVertex;
Chris Dalton8e2b6942020-04-22 15:55:00 -0600316 int numCountedCurves;
Chris Daltond081dce2020-01-23 12:09:04 -0700317 GrEagerDynamicVertexAllocator allocator(target, &vertexBuffer, &firstVertex);
Chris Dalton8e2b6942020-04-22 15:55:00 -0600318 int vertexCount = GrTriangulator::PathToTriangles(path, tol, clipBounds, &allocator,
319 GrTriangulator::Mode::kEdgeAntialias,
320 &numCountedCurves);
321 if (vertexCount == 0) {
senorblancof57372d2016-08-31 10:36:19 -0700322 return;
323 }
Chris Dalton8e2b6942020-04-22 15:55:00 -0600324 this->createMesh(target, std::move(vertexBuffer), firstVertex, vertexCount);
senorblancof57372d2016-08-31 10:36:19 -0700325 }
326
Robert Phillips2669a7b2020-03-12 12:07:19 -0400327 GrProgramInfo* programInfo() override { return fProgramInfo; }
328
Robert Phillips4133dc42020-03-11 15:55:55 -0400329 void onCreateProgramInfo(const GrCaps* caps,
330 SkArenaAlloc* arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400331 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400332 GrAppliedClip&& appliedClip,
Greg Danield358cbe2020-09-11 09:33:54 -0400333 const GrXferProcessor::DstProxyView& dstProxyView,
334 GrXferBarrierFlags renderPassXferBarriers) override {
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500335 GrGeometryProcessor* gp;
joshualittdf0c5572015-08-03 11:35:28 -0700336 {
337 using namespace GrDefaultGeoProcFactory;
338
339 Color color(fColor);
Brian Salomon9530f7e2017-07-11 09:03:10 -0400340 LocalCoords::Type localCoordsType = fHelper.usesLocalCoords()
Brian Salomon8c852be2017-01-04 10:44:42 -0500341 ? LocalCoords::kUsePosition_Type
342 : LocalCoords::kUnused_Type;
joshualittdf0c5572015-08-03 11:35:28 -0700343 Coverage::Type coverageType;
senorblancof57372d2016-08-31 10:36:19 -0700344 if (fAntiAlias) {
Brian Osman605c6d52019-03-15 12:10:35 -0400345 if (fHelper.compatibleWithCoverageAsAlpha()) {
Brian Osman80879d42019-01-07 16:15:27 -0500346 coverageType = Coverage::kAttributeTweakAlpha_Type;
senorblancof57372d2016-08-31 10:36:19 -0700347 } else {
348 coverageType = Coverage::kAttribute_Type;
349 }
Brian Salomon8c852be2017-01-04 10:44:42 -0500350 } else {
joshualittdf0c5572015-08-03 11:35:28 -0700351 coverageType = Coverage::kSolid_Type;
joshualittdf0c5572015-08-03 11:35:28 -0700352 }
senorblancof57372d2016-08-31 10:36:19 -0700353 if (fAntiAlias) {
Brian Osmanf0aee742020-03-12 09:28:44 -0400354 gp = GrDefaultGeoProcFactory::MakeForDeviceSpace(arena, color, coverageType,
Brian Salomon8c852be2017-01-04 10:44:42 -0500355 localCoordsType, fViewMatrix);
senorblancof57372d2016-08-31 10:36:19 -0700356 } else {
Brian Osmanf0aee742020-03-12 09:28:44 -0400357 gp = GrDefaultGeoProcFactory::Make(arena, color, coverageType, localCoordsType,
Brian Salomon8c852be2017-01-04 10:44:42 -0500358 fViewMatrix);
senorblancof57372d2016-08-31 10:36:19 -0700359 }
joshualittdf0c5572015-08-03 11:35:28 -0700360 }
Robert Phillips7cd0bfe2019-11-20 16:08:10 -0500361 if (!gp) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400362 return;
Stephen Whitecc700832017-02-15 11:45:16 -0500363 }
Robert Phillips740d34f2020-03-11 09:36:13 -0400364
Chris Daltondcc8c542020-01-28 17:55:56 -0700365#ifdef SK_DEBUG
Chris Dalton17dc4182020-03-25 16:18:16 -0600366 auto mode = (fAntiAlias) ? GrTriangulator::Mode::kEdgeAntialias
367 : GrTriangulator::Mode::kNormal;
368 SkASSERT(GrTriangulator::GetVertexStride(mode) == gp->vertexStride());
Chris Daltondcc8c542020-01-28 17:55:56 -0700369#endif
senorblanco84cd6212015-08-04 10:01:58 -0700370
Chris Dalton17dc4182020-03-25 16:18:16 -0600371 GrPrimitiveType primitiveType = TRIANGULATOR_WIREFRAME ? GrPrimitiveType::kLines
372 : GrPrimitiveType::kTriangles;
Robert Phillipse94cdd22019-11-04 14:15:58 -0500373
Brian Salomon8afde5f2020-04-01 16:22:00 -0400374 fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400375 std::move(appliedClip), dstProxyView,
Greg Danield358cbe2020-09-11 09:33:54 -0400376 gp, primitiveType,
377 renderPassXferBarriers);
Robert Phillips740d34f2020-03-11 09:36:13 -0400378 }
379
Robert Phillips740d34f2020-03-11 09:36:13 -0400380 void onPrepareDraws(Target* target) override {
381 if (fAntiAlias) {
Robert Phillips6ffcb232020-10-14 12:40:13 -0400382 this->createAAMesh(target);
Robert Phillips740d34f2020-03-11 09:36:13 -0400383 } else {
Robert Phillips6ffcb232020-10-14 12:40:13 -0400384 this->createNonAAMesh(target);
Robert Phillips740d34f2020-03-11 09:36:13 -0400385 }
386 }
387
388 void createMesh(Target* target, sk_sp<const GrBuffer> vb, int firstVertex, int count) {
389 fMesh = target->allocMesh();
Chris Dalton37c7bdd2020-03-13 09:21:12 -0600390 fMesh->set(std::move(vb), count, firstVertex);
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700391 }
392
393 void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
Robert Phillips740d34f2020-03-11 09:36:13 -0400394 if (!fProgramInfo) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400395 this->createProgramInfo(flushState);
Robert Phillips740d34f2020-03-11 09:36:13 -0400396 }
Robert Phillips3968fcb2019-12-05 16:40:31 -0500397
Robert Phillips740d34f2020-03-11 09:36:13 -0400398 if (!fProgramInfo || !fMesh) {
399 return;
400 }
401
Chris Dalton765ed362020-03-16 17:34:44 -0600402 flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
403 flushState->bindTextures(fProgramInfo->primProc(), nullptr, fProgramInfo->pipeline());
404 flushState->drawMesh(*fMesh);
senorblanco9ba39722015-03-05 07:13:42 -0800405 }
406
John Stilesaf366522020-08-13 09:57:34 -0400407#if GR_TEST_UTILS
408 SkString onDumpInfo() const override {
409 return SkStringPrintf("Color 0x%08x, aa: %d\n%s",
410 fColor.toBytes_RGBA(), fAntiAlias, fHelper.dumpInfo().c_str());
411 }
412#endif
413
Robert Phillips740d34f2020-03-11 09:36:13 -0400414 Helper fHelper;
415 SkPMColor4f fColor;
Michael Ludwig2686d692020-04-17 20:21:37 +0000416 GrStyledShape fShape;
Robert Phillips740d34f2020-03-11 09:36:13 -0400417 SkMatrix fViewMatrix;
418 SkIRect fDevClipBounds;
419 bool fAntiAlias;
420
Chris Daltoneb694b72020-03-16 09:25:50 -0600421 GrSimpleMesh* fMesh = nullptr;
Robert Phillips740d34f2020-03-11 09:36:13 -0400422 GrProgramInfo* fProgramInfo = nullptr;
reed1b55a962015-09-17 20:16:13 -0700423
John Stiles7571f9e2020-09-02 22:42:33 -0400424 using INHERITED = GrMeshDrawOp;
senorblanco9ba39722015-03-05 07:13:42 -0800425};
426
Brian Salomon9530f7e2017-07-11 09:03:10 -0400427} // anonymous namespace
428
Chris Dalton17dc4182020-03-25 16:18:16 -0600429bool GrTriangulatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
Brian Osman11052242016-10-27 14:47:55 -0400430 GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
Chris Dalton17dc4182020-03-25 16:18:16 -0600431 "GrTriangulatingPathRenderer::onDrawPath");
Michael Ludwig7c12e282020-05-29 09:54:07 -0400432
Chris Dalton17dc4182020-03-25 16:18:16 -0600433 std::unique_ptr<GrDrawOp> op = TriangulatingPathOp::Make(
Michael Ludwig7c12e282020-05-29 09:54:07 -0400434 args.fContext, std::move(args.fPaint), *args.fShape, *args.fViewMatrix,
435 *args.fClipConservativeBounds, args.fAAType, args.fUserStencilSettings);
436 args.fRenderTargetContext->addDrawOp(args.fClip, std::move(op));
senorblancod6ed19c2015-02-26 06:58:17 -0800437 return true;
438}
joshualitt2fbd4062015-05-07 13:06:41 -0700439
440///////////////////////////////////////////////////////////////////////////////////////////////////
441
Hal Canary6f6961e2017-01-31 13:50:44 -0500442#if GR_TEST_UTILS
joshualitt2fbd4062015-05-07 13:06:41 -0700443
Chris Dalton17dc4182020-03-25 16:18:16 -0600444GR_DRAW_OP_TEST_DEFINE(TriangulatingPathOp) {
joshualitt2fbd4062015-05-07 13:06:41 -0700445 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
John Stiles31954bf2020-08-07 17:35:54 -0400446 const SkPath& path = GrTest::TestPath(random);
bsalomond3030ac2016-09-01 07:20:29 -0700447 SkIRect devClipBounds = SkIRect::MakeLTRB(
senorblancof57372d2016-08-31 10:36:19 -0700448 random->nextU(), random->nextU(), random->nextU(), random->nextU());
bsalomond3030ac2016-09-01 07:20:29 -0700449 devClipBounds.sort();
Brian Salomon9530f7e2017-07-11 09:03:10 -0400450 static constexpr GrAAType kAATypes[] = {GrAAType::kNone, GrAAType::kMSAA, GrAAType::kCoverage};
451 GrAAType aaType;
452 do {
453 aaType = kAATypes[random->nextULessThan(SK_ARRAY_COUNT(kAATypes))];
Chris Dalton6ce447a2019-06-23 18:07:38 -0600454 } while(GrAAType::kMSAA == aaType && numSamples <= 1);
bsalomon6663acf2016-05-10 09:14:17 -0700455 GrStyle style;
456 do {
457 GrTest::TestStyle(random, &style);
senorblancof57372d2016-08-31 10:36:19 -0700458 } while (!style.isSimpleFill());
Michael Ludwig2686d692020-04-17 20:21:37 +0000459 GrStyledShape shape(path, style);
Chris Dalton17dc4182020-03-25 16:18:16 -0600460 return TriangulatingPathOp::Make(context, std::move(paint), shape, viewMatrix, devClipBounds,
461 aaType, GrGetRandomStencil(random, context));
joshualitt2fbd4062015-05-07 13:06:41 -0700462}
463
464#endif