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