• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
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 skgpu_graphite_geom_Geometry_DEFINED
9 #define skgpu_graphite_geom_Geometry_DEFINED
10 
11 #include "include/core/SkVertices.h"
12 #include "src/core/SkVerticesPriv.h"
13 #include "src/gpu/graphite/geom/AnalyticBlurMask.h"
14 #include "src/gpu/graphite/geom/CoverageMaskShape.h"
15 #include "src/gpu/graphite/geom/EdgeAAQuad.h"
16 #include "src/gpu/graphite/geom/Rect.h"
17 #include "src/gpu/graphite/geom/Shape.h"
18 #include "src/gpu/graphite/geom/SubRunData.h"
19 
20 namespace skgpu::graphite {
21 
22 /**
23  * Geometry is a container that can house Shapes, SkVertices, text SubRuns, and per-edge AA quads.
24  * TODO - Add unit tests for Geometry.
25  */
26 class Geometry {
27 public:
28     enum class Type : uint8_t {
29         kEmpty, kShape, kVertices, kSubRun, kEdgeAAQuad, kCoverageMaskShape, kAnalyticBlur
30     };
31 
Geometry()32     Geometry() {}
Geometry(Geometry && geom)33     Geometry(Geometry&& geom) { *this = std::move(geom); }
Geometry(const Geometry & geom)34     Geometry(const Geometry& geom) { *this = geom; }
35 
Geometry(const Shape & shape)36     explicit Geometry(const Shape& shape) { this->setShape(shape); }
Geometry(const SubRunData & subrun)37     explicit Geometry(const SubRunData& subrun) { this->setSubRun(subrun); }
Geometry(sk_sp<SkVertices> vertices)38     explicit Geometry(sk_sp<SkVertices> vertices) { this->setVertices(std::move(vertices)); }
Geometry(const EdgeAAQuad & edgeAAQuad)39     explicit Geometry(const EdgeAAQuad& edgeAAQuad) { this->setEdgeAAQuad(edgeAAQuad); }
Geometry(const CoverageMaskShape & mask)40     explicit Geometry(const CoverageMaskShape& mask) { this->setCoverageMaskShape(mask); }
Geometry(const AnalyticBlurMask & blur)41     explicit Geometry(const AnalyticBlurMask& blur) { this->setAnalyticBlur(blur); }
42 
~Geometry()43     ~Geometry() { this->setType(Type::kEmpty); }
44 
45     Geometry& operator=(Geometry&& geom) {
46         if (this != &geom) {
47             switch (geom.type()) {
48                 case Type::kEmpty:
49                     this->setType(Type::kEmpty);
50                     break;
51                 case Type::kShape:
52                     this->setShape(geom.shape());
53                     geom.setType(Type::kEmpty);
54                     break;
55                 case Type::kVertices:
56                     this->setVertices(std::move(geom.fVertices));
57                     geom.setType(Type::kEmpty);
58                     break;
59                 case Type::kSubRun:
60                     this->setSubRun(geom.subRunData());
61                     geom.setType(Type::kEmpty);
62                     break;
63                 case Type::kEdgeAAQuad:
64                     this->setEdgeAAQuad(geom.edgeAAQuad());
65                     geom.setType(Type::kEmpty);
66                     break;
67                 case Type::kCoverageMaskShape:
68                     this->setCoverageMaskShape(geom.coverageMaskShape());
69                     geom.setType(Type::kEmpty);
70                     break;
71                 case Type::kAnalyticBlur:
72                     this->setAnalyticBlur(geom.analyticBlurMask());
73                     geom.setType(Type::kEmpty);
74                     break;
75             }
76         }
77         return *this;
78     }
79     Geometry& operator=(const Geometry& geom) {
80         switch (geom.type()) {
81             case Type::kEmpty: this->setType(Type::kEmpty); break;
82             case Type::kShape: this->setShape(geom.shape()); break;
83             case Type::kSubRun: this->setSubRun(geom.subRunData()); break;
84             case Type::kVertices: this->setVertices(geom.fVertices); break;
85             case Type::kEdgeAAQuad: this->setEdgeAAQuad(geom.edgeAAQuad()); break;
86             case Type::kCoverageMaskShape:
87                     this->setCoverageMaskShape(geom.coverageMaskShape()); break;
88             case Type::kAnalyticBlur: this->setAnalyticBlur(geom.analyticBlurMask()); break;
89             default: break;
90         }
91         return *this;
92     }
93 
type()94     Type type() const { return fType; }
95 
isShape()96     bool isShape() const { return fType == Type::kShape; }
isVertices()97     bool isVertices() const { return fType == Type::kVertices; }
isSubRun()98     bool isSubRun() const { return fType == Type::kSubRun; }
isEdgeAAQuad()99     bool isEdgeAAQuad() const { return fType == Type::kEdgeAAQuad; }
isCoverageMaskShape()100     bool isCoverageMaskShape() const { return fType == Type::kCoverageMaskShape; }
isAnalyticBlur()101     bool isAnalyticBlur() const { return fType == Type::kAnalyticBlur; }
isEmpty()102     bool isEmpty() const {
103         return fType == (Type::kEmpty) || (this->isShape() && this->shape().isEmpty());
104     }
105 
shape()106     const Shape& shape() const { SkASSERT(this->isShape()); return fShape; }
subRunData()107     const SubRunData& subRunData() const { SkASSERT(this->isSubRun()); return fSubRunData; }
edgeAAQuad()108     const EdgeAAQuad& edgeAAQuad() const { SkASSERT(this->isEdgeAAQuad()); return fEdgeAAQuad; }
coverageMaskShape()109     const CoverageMaskShape& coverageMaskShape() const {
110         SkASSERT(this->isCoverageMaskShape()); return fCoverageMaskShape;
111     }
analyticBlurMask()112     const AnalyticBlurMask& analyticBlurMask() const {
113         SkASSERT(this->isAnalyticBlur()); return fAnalyticBlurMask;
114     }
vertices()115     const SkVertices* vertices() const { SkASSERT(this->isVertices()); return fVertices.get(); }
refVertices()116     sk_sp<SkVertices> refVertices() const {
117         SkASSERT(this->isVertices());
118         return fVertices;
119     }
120 
setShape(const Shape & shape)121     void setShape(const Shape& shape) {
122         if (fType == Type::kShape) {
123             fShape = shape;
124         } else {
125             this->setType(Type::kShape);
126             new (&fShape) Shape(shape);
127         }
128     }
setSubRun(const SubRunData & subRun)129     void setSubRun(const SubRunData& subRun) {
130         if (fType == Type::kSubRun) {
131             fSubRunData = subRun;
132         } else {
133             this->setType(Type::kSubRun);
134             new (&fSubRunData) SubRunData(subRun);
135         }
136     }
setVertices(sk_sp<SkVertices> vertices)137     void setVertices(sk_sp<SkVertices> vertices) {
138         if (fType == Type::kVertices) {
139             fVertices = std::move(vertices);
140         } else {
141             this->setType(Type::kVertices);
142             new (&fVertices) sk_sp<SkVertices>(std::move(vertices));
143         }
144     }
145 
setEdgeAAQuad(const EdgeAAQuad & edgeAAQuad)146     void setEdgeAAQuad(const EdgeAAQuad& edgeAAQuad) {
147         if (fType == Type::kEdgeAAQuad) {
148             fEdgeAAQuad = edgeAAQuad;
149         } else {
150             this->setType(Type::kEdgeAAQuad);
151             new (&fEdgeAAQuad) EdgeAAQuad(edgeAAQuad);
152         }
153     }
154 
setCoverageMaskShape(const CoverageMaskShape & maskShape)155     void setCoverageMaskShape(const CoverageMaskShape& maskShape) {
156         if (fType == Type::kCoverageMaskShape) {
157             fCoverageMaskShape = maskShape;
158         } else {
159             this->setType(Type::kCoverageMaskShape);
160             new (&fCoverageMaskShape) CoverageMaskShape(maskShape);
161         }
162     }
163 
setAnalyticBlur(const AnalyticBlurMask & blur)164     void setAnalyticBlur(const AnalyticBlurMask& blur) {
165         if (fType == Type::kAnalyticBlur) {
166             fAnalyticBlurMask = blur;
167         } else {
168             this->setType(Type::kAnalyticBlur);
169             new (&fAnalyticBlurMask) AnalyticBlurMask(blur);
170         }
171     }
172 
bounds()173     Rect bounds() const {
174         switch (fType) {
175             case Type::kEmpty: return Rect(0, 0, 0, 0);
176             case Type::kShape: return fShape.bounds();
177             case Type::kVertices: return fVertices->bounds();
178             case Type::kSubRun: return fSubRunData.bounds();
179             case Type::kEdgeAAQuad: return fEdgeAAQuad.bounds();
180             case Type::kCoverageMaskShape: return fCoverageMaskShape.bounds();
181             case Type::kAnalyticBlur: return fAnalyticBlurMask.drawBounds();
182         }
183         SkUNREACHABLE;
184     }
185 
186 private:
setType(Type type)187     void setType(Type type) {
188         static_assert(std::is_trivially_destructible<EdgeAAQuad>::value);
189         if (this->isShape() && type != Type::kShape) {
190             fShape.~Shape();
191         } else if (this->isSubRun() && type != Type::kSubRun) {
192             fSubRunData.~SubRunData();
193         } else if (this->isVertices() && type != Type::kVertices) {
194             fVertices.~sk_sp<SkVertices>();
195         } else if (this->isCoverageMaskShape() && type != Type::kCoverageMaskShape) {
196             fCoverageMaskShape.~CoverageMaskShape();
197         } else if (this->isAnalyticBlur() && type != Type::kAnalyticBlur) {
198             fAnalyticBlurMask.~AnalyticBlurMask();
199         }
200         fType = type;
201     }
202 
203     Type fType = Type::kEmpty;
204     union {
205         Shape fShape;
206         SubRunData fSubRunData;
207         sk_sp<SkVertices> fVertices;
208         EdgeAAQuad fEdgeAAQuad;
209         CoverageMaskShape fCoverageMaskShape;
210         AnalyticBlurMask fAnalyticBlurMask;
211     };
212 };
213 
214 } // namespace skgpu::graphite
215 
216 #endif // skgpu_graphite_geom_Geometry_DEFINED
217