• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 #if !defined(SK_ENABLE_OPTIMIZE_SIZE)
12 
13 #include "src/gpu/ganesh/geometry/GrTriangulator.h"
14 
15 // Triangulates the given path in device space with a mesh of alpha ramps for antialiasing.
16 class GrAATriangulator : private GrTriangulator {
17 public:
PathToAATriangles(const SkPath & path,SkScalar tolerance,const SkRect & clipBounds,GrEagerVertexAllocator * vertexAllocator)18     static int PathToAATriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
19                                  GrEagerVertexAllocator* vertexAllocator) {
20         SkArenaAlloc alloc(kArenaDefaultChunkSize);
21         GrAATriangulator aaTriangulator(path, &alloc);
22         aaTriangulator.fRoundVerticesToQuarterPixel = true;
23         aaTriangulator.fEmitCoverage = true;
24         bool isLinear;
25         auto [ polys, success ] = aaTriangulator.pathToPolys(tolerance, clipBounds, &isLinear);
26         if (!success) {
27             return 0;
28         }
29         return aaTriangulator.polysToAATriangles(polys, vertexAllocator);
30     }
31 
32     // Structs used by GrAATriangulator internals.
33     struct SSEdge;
34     struct EventList;
35     struct Event {
EventEvent36         Event(SSEdge* edge, const SkPoint& point, uint8_t alpha)
37                 : fEdge(edge), fPoint(point), fAlpha(alpha) {}
38         SSEdge* fEdge;
39         SkPoint fPoint;
40         uint8_t fAlpha;
41         void apply(VertexList* mesh, const Comparator&, EventList* events, GrAATriangulator*);
42     };
43     struct EventComparator {
44         enum class Op { kLessThan, kGreaterThan };
EventComparatorEventComparator45         EventComparator(Op op) : fOp(op) {}
operatorEventComparator46         bool operator() (Event* const &e1, Event* const &e2) {
47             return fOp == Op::kLessThan ? e1->fAlpha < e2->fAlpha
48                                         : e1->fAlpha > e2->fAlpha;
49         }
50         Op fOp;
51     };
52 
53 private:
GrAATriangulator(const SkPath & path,SkArenaAlloc * alloc)54     GrAATriangulator(const SkPath& path, SkArenaAlloc* alloc) : GrTriangulator(path, alloc) {}
55 
56     // For screenspace antialiasing, the algorithm is modified as follows:
57     //
58     // Run steps 1-5 above to produce polygons.
59     // 5b) Apply fill rules to extract boundary contours from the polygons:
60     void extractBoundary(EdgeList* boundary, Edge* e) const;
61     void extractBoundaries(const VertexList& inMesh, VertexList* innerVertices,
62                            const Comparator&);
63 
64     // 5c) Simplify boundaries to remove "pointy" vertices that cause inversions:
65     void simplifyBoundary(EdgeList* boundary, const Comparator&);
66 
67     // 5d) Displace edges by half a pixel inward and outward along their normals. Intersect to find
68     //     new vertices, and set zero alpha on the exterior and one alpha on the interior. Build a
69     //     new antialiased mesh from those vertices:
70     void strokeBoundary(EdgeList* boundary, VertexList* innerMesh, const Comparator&);
71 
72     // Run steps 3-6 above on the new mesh, and produce antialiased triangles.
73     std::tuple<Poly*, bool> tessellate(const VertexList& mesh, const Comparator&) override;
74     int polysToAATriangles(Poly*, GrEagerVertexAllocator*) const;
75 
76     // Additional helpers and driver functions.
77     void makeEvent(SSEdge*, EventList* events) const;
78     void makeEvent(SSEdge*, Vertex* v, SSEdge* other, Vertex* dest, EventList* events,
79                    const Comparator&) const;
80     void connectPartners(VertexList* mesh, const Comparator&);
81     void removeNonBoundaryEdges(const VertexList& mesh) const;
82     void connectSSEdge(Vertex* v, Vertex* dest, const Comparator&);
83     bool collapseOverlapRegions(VertexList* mesh, const Comparator&, EventComparator comp);
84 
85     // FIXME: fOuterMesh should be plumbed through function parameters instead.
86     mutable VertexList fOuterMesh;
87 };
88 
89 #endif // SK_ENABLE_OPTIMIZE_SIZE
90 
91 #endif // GrAATriangulator_DEFINED
92