blob: 05246ee91072913d826baaa23ced3ea8e8bdc263 [file] [log] [blame]
Chris Dalton47114db2021-01-06 00:35:20 -07001/*
2 * Copyright 2020 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 GrAATriangulator_DEFINED
9#define GrAATriangulator_DEFINED
10
11#include "src/gpu/GrTriangulator.h"
12
13// Triangulates the given path in device space with a mesh of alpha ramps for antialiasing.
Chris Daltond5384792021-01-20 15:43:24 -070014class GrAATriangulator : private GrTriangulator {
Chris Dalton47114db2021-01-06 00:35:20 -070015public:
Chris Daltond5384792021-01-20 15:43:24 -070016 static int PathToAATriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
17 GrEagerVertexAllocator* vertexAllocator) {
Chris Dalton8a42b092021-01-21 22:09:26 -070018 SkArenaAlloc alloc(kArenaDefaultChunkSize);
19 GrAATriangulator aaTriangulator(path, &alloc);
Chris Dalton47114db2021-01-06 00:35:20 -070020 aaTriangulator.fRoundVerticesToQuarterPixel = true;
21 aaTriangulator.fEmitCoverage = true;
Chris Dalton37d16f12021-01-20 18:32:48 -070022 bool isLinear;
23 Poly* polys = aaTriangulator.pathToPolys(tolerance, clipBounds, &isLinear);
Chris Daltond5384792021-01-20 15:43:24 -070024 return aaTriangulator.polysToAATriangles(polys, vertexAllocator);
Chris Dalton47114db2021-01-06 00:35:20 -070025 }
26
27 // Structs used by GrAATriangulator internals.
28 struct SSEdge;
29 struct EventList;
30 struct Event {
31 Event(SSEdge* edge, const SkPoint& point, uint8_t alpha)
32 : fEdge(edge), fPoint(point), fAlpha(alpha) {}
33 SSEdge* fEdge;
34 SkPoint fPoint;
35 uint8_t fAlpha;
36 void apply(VertexList* mesh, const Comparator&, EventList* events, GrAATriangulator*);
37 };
38 struct EventComparator {
39 enum class Op { kLessThan, kGreaterThan };
40 EventComparator(Op op) : fOp(op) {}
41 bool operator() (Event* const &e1, Event* const &e2) {
42 return fOp == Op::kLessThan ? e1->fAlpha < e2->fAlpha
43 : e1->fAlpha > e2->fAlpha;
44 }
45 Op fOp;
46 };
47
48private:
Chris Dalton8a42b092021-01-21 22:09:26 -070049 GrAATriangulator(const SkPath& path, SkArenaAlloc* alloc) : GrTriangulator(path, alloc) {}
Chris Dalton47114db2021-01-06 00:35:20 -070050
51 // For screenspace antialiasing, the algorithm is modified as follows:
52 //
53 // Run steps 1-5 above to produce polygons.
54 // 5b) Apply fill rules to extract boundary contours from the polygons:
55 void extractBoundary(EdgeList* boundary, Edge* e);
56 void extractBoundaries(const VertexList& inMesh, VertexList* innerVertices, const Comparator&);
57
58 // 5c) Simplify boundaries to remove "pointy" vertices that cause inversions:
59 void simplifyBoundary(EdgeList* boundary, const Comparator&);
60
61 // 5d) Displace edges by half a pixel inward and outward along their normals. Intersect to find
62 // new vertices, and set zero alpha on the exterior and one alpha on the interior. Build a
63 // new antialiased mesh from those vertices:
64 void strokeBoundary(EdgeList* boundary, VertexList* innerMesh, const Comparator&);
65
66 // Run steps 3-6 above on the new mesh, and produce antialiased triangles.
67 Poly* tessellate(const VertexList& mesh, const Comparator&) override;
Chris Daltond5384792021-01-20 15:43:24 -070068 int polysToAATriangles(Poly*, GrEagerVertexAllocator*);
Chris Dalton47114db2021-01-06 00:35:20 -070069
70 // Additional helpers and driver functions.
71 void makeEvent(SSEdge*, EventList* events);
72 void makeEvent(SSEdge*, Vertex* v, SSEdge* other, Vertex* dest, EventList* events,
73 const Comparator&);
74 void connectPartners(VertexList* mesh, const Comparator&);
75 void removeNonBoundaryEdges(const VertexList& mesh);
76 void connectSSEdge(Vertex* v, Vertex* dest, const Comparator&);
77 bool collapseOverlapRegions(VertexList* mesh, const Comparator&, EventComparator comp);
78
79 VertexList fOuterMesh;
80};
81
82#endif