blob: 7718557796cd604eb89ba9e137a0f9e7995b20ba [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.
14class GrAATriangulator : public GrTriangulator {
15public:
16 static int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
17 GrEagerVertexAllocator* vertexAllocator) {
18 GrAATriangulator aaTriangulator(path);
19 aaTriangulator.fRoundVerticesToQuarterPixel = true;
20 aaTriangulator.fEmitCoverage = true;
21 return aaTriangulator.pathToTriangles(tolerance, clipBounds, vertexAllocator);
22 }
23
24 // Structs used by GrAATriangulator internals.
25 struct SSEdge;
26 struct EventList;
27 struct Event {
28 Event(SSEdge* edge, const SkPoint& point, uint8_t alpha)
29 : fEdge(edge), fPoint(point), fAlpha(alpha) {}
30 SSEdge* fEdge;
31 SkPoint fPoint;
32 uint8_t fAlpha;
33 void apply(VertexList* mesh, const Comparator&, EventList* events, GrAATriangulator*);
34 };
35 struct EventComparator {
36 enum class Op { kLessThan, kGreaterThan };
37 EventComparator(Op op) : fOp(op) {}
38 bool operator() (Event* const &e1, Event* const &e2) {
39 return fOp == Op::kLessThan ? e1->fAlpha < e2->fAlpha
40 : e1->fAlpha > e2->fAlpha;
41 }
42 Op fOp;
43 };
44
45private:
46 GrAATriangulator(const SkPath& path) : GrTriangulator(path) {}
47
48 // For screenspace antialiasing, the algorithm is modified as follows:
49 //
50 // Run steps 1-5 above to produce polygons.
51 // 5b) Apply fill rules to extract boundary contours from the polygons:
52 void extractBoundary(EdgeList* boundary, Edge* e);
53 void extractBoundaries(const VertexList& inMesh, VertexList* innerVertices, const Comparator&);
54
55 // 5c) Simplify boundaries to remove "pointy" vertices that cause inversions:
56 void simplifyBoundary(EdgeList* boundary, const Comparator&);
57
58 // 5d) Displace edges by half a pixel inward and outward along their normals. Intersect to find
59 // new vertices, and set zero alpha on the exterior and one alpha on the interior. Build a
60 // new antialiased mesh from those vertices:
61 void strokeBoundary(EdgeList* boundary, VertexList* innerMesh, const Comparator&);
62
63 // Run steps 3-6 above on the new mesh, and produce antialiased triangles.
64 Poly* tessellate(const VertexList& mesh, const Comparator&) override;
65 int64_t countPoints(Poly* polys) const override;
66 void* polysToTriangles(Poly* polys, void* data) override;
67
68 // Additional helpers and driver functions.
69 void makeEvent(SSEdge*, EventList* events);
70 void makeEvent(SSEdge*, Vertex* v, SSEdge* other, Vertex* dest, EventList* events,
71 const Comparator&);
72 void connectPartners(VertexList* mesh, const Comparator&);
73 void removeNonBoundaryEdges(const VertexList& mesh);
74 void connectSSEdge(Vertex* v, Vertex* dest, const Comparator&);
75 bool collapseOverlapRegions(VertexList* mesh, const Comparator&, EventComparator comp);
76
77 VertexList fOuterMesh;
78};
79
80#endif