Flutter Engine
The Flutter Engine
Geometry.h
Go to the documentation of this file.
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
19
20namespace 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 */
26class Geometry {
27public:
28 enum class Type : uint8_t {
29 kEmpty, kShape, kVertices, kSubRun, kEdgeAAQuad, kCoverageMaskShape, kAnalyticBlur
30 };
31
33 Geometry(Geometry&& geom) { *this = std::move(geom); }
34 Geometry(const Geometry& geom) { *this = geom; }
35
36 explicit Geometry(const Shape& shape) { this->setShape(shape); }
37 explicit Geometry(const SubRunData& subrun) { this->setSubRun(subrun); }
38 explicit Geometry(sk_sp<SkVertices> vertices) { this->setVertices(std::move(vertices)); }
39 explicit Geometry(const EdgeAAQuad& edgeAAQuad) { this->setEdgeAAQuad(edgeAAQuad); }
40 explicit Geometry(const CoverageMaskShape& mask) { this->setCoverageMaskShape(mask); }
41 explicit Geometry(const AnalyticBlurMask& blur) { this->setAnalyticBlur(blur); }
42
43 ~Geometry() { this->setType(Type::kEmpty); }
44
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;
64 this->setEdgeAAQuad(geom.edgeAAQuad());
65 geom.setType(Type::kEmpty);
66 break;
68 this->setCoverageMaskShape(geom.coverageMaskShape());
69 geom.setType(Type::kEmpty);
70 break;
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;
87 this->setCoverageMaskShape(geom.coverageMaskShape()); break;
88 case Type::kAnalyticBlur: this->setAnalyticBlur(geom.analyticBlurMask()); break;
89 default: break;
90 }
91 return *this;
92 }
93
94 Type type() const { return fType; }
95
96 bool isShape() const { return fType == Type::kShape; }
97 bool isVertices() const { return fType == Type::kVertices; }
98 bool isSubRun() const { return fType == Type::kSubRun; }
99 bool isEdgeAAQuad() const { return fType == Type::kEdgeAAQuad; }
100 bool isCoverageMaskShape() const { return fType == Type::kCoverageMaskShape; }
101 bool isAnalyticBlur() const { return fType == Type::kAnalyticBlur; }
102 bool isEmpty() const {
103 return fType == (Type::kEmpty) || (this->isShape() && this->shape().isEmpty());
104 }
105
106 const Shape& shape() const { SkASSERT(this->isShape()); return fShape; }
107 const SubRunData& subRunData() const { SkASSERT(this->isSubRun()); return fSubRunData; }
108 const EdgeAAQuad& edgeAAQuad() const { SkASSERT(this->isEdgeAAQuad()); return fEdgeAAQuad; }
111 }
114 }
115 const SkVertices* vertices() const { SkASSERT(this->isVertices()); return fVertices.get(); }
117 SkASSERT(this->isVertices());
118 return fVertices;
119 }
120
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 }
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 }
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
147 if (fType == Type::kEdgeAAQuad) {
149 } else {
150 this->setType(Type::kEdgeAAQuad);
152 }
153 }
154
156 if (fType == Type::kCoverageMaskShape) {
157 fCoverageMaskShape = maskShape;
158 } else {
159 this->setType(Type::kCoverageMaskShape);
160 new (&fCoverageMaskShape) CoverageMaskShape(maskShape);
161 }
162 }
163
165 if (fType == Type::kAnalyticBlur) {
166 fAnalyticBlurMask = blur;
167 } else {
168 this->setType(Type::kAnalyticBlur);
170 }
171 }
172
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();
182 }
184 }
185
186private:
187 void setType(Type type) {
189 if (this->isShape() && type != Type::kShape) {
190 fShape.~Shape();
191 } else if (this->isSubRun() && type != Type::kSubRun) {
193 } else if (this->isVertices() && type != Type::kVertices) {
195 } else if (this->isCoverageMaskShape() && type != Type::kCoverageMaskShape) {
197 } else if (this->isAnalyticBlur() && type != Type::kAnalyticBlur) {
198 fAnalyticBlurMask.~AnalyticBlurMask();
199 }
200 fType = type;
201 }
202
203 Type fType = Type::kEmpty;
204 union {
211 };
212};
213
214} // namespace skgpu::graphite
215
216#endif // skgpu_graphite_geom_Geometry_DEFINED
#define SkUNREACHABLE
Definition: SkAssert.h:135
#define SkASSERT(cond)
Definition: SkAssert.h:116
Shape
Definition: aaxfermodes.cpp:43
const SkRect & bounds() const
Definition: SkVertices.h:98
T * get() const
Definition: SkRefCnt.h:303
~sk_sp()
Definition: SkRefCnt.h:255
const SkVertices * vertices() const
Definition: Geometry.h:115
Geometry(const AnalyticBlurMask &blur)
Definition: Geometry.h:41
void setAnalyticBlur(const AnalyticBlurMask &blur)
Definition: Geometry.h:164
Geometry(const CoverageMaskShape &mask)
Definition: Geometry.h:40
Geometry(const Geometry &geom)
Definition: Geometry.h:34
sk_sp< SkVertices > refVertices() const
Definition: Geometry.h:116
Geometry(const EdgeAAQuad &edgeAAQuad)
Definition: Geometry.h:39
bool isSubRun() const
Definition: Geometry.h:98
Geometry(sk_sp< SkVertices > vertices)
Definition: Geometry.h:38
const EdgeAAQuad & edgeAAQuad() const
Definition: Geometry.h:108
void setEdgeAAQuad(const EdgeAAQuad &edgeAAQuad)
Definition: Geometry.h:146
const CoverageMaskShape & coverageMaskShape() const
Definition: Geometry.h:109
bool isVertices() const
Definition: Geometry.h:97
const Shape & shape() const
Definition: Geometry.h:106
Geometry & operator=(const Geometry &geom)
Definition: Geometry.h:79
bool isCoverageMaskShape() const
Definition: Geometry.h:100
Geometry(const Shape &shape)
Definition: Geometry.h:36
const AnalyticBlurMask & analyticBlurMask() const
Definition: Geometry.h:112
bool isShape() const
Definition: Geometry.h:96
const SubRunData & subRunData() const
Definition: Geometry.h:107
void setVertices(sk_sp< SkVertices > vertices)
Definition: Geometry.h:137
bool isAnalyticBlur() const
Definition: Geometry.h:101
AnalyticBlurMask fAnalyticBlurMask
Definition: Geometry.h:210
void setShape(const Shape &shape)
Definition: Geometry.h:121
Geometry(const SubRunData &subrun)
Definition: Geometry.h:37
bool isEmpty() const
Definition: Geometry.h:102
Geometry(Geometry &&geom)
Definition: Geometry.h:33
void setSubRun(const SubRunData &subRun)
Definition: Geometry.h:129
void setCoverageMaskShape(const CoverageMaskShape &maskShape)
Definition: Geometry.h:155
Geometry & operator=(Geometry &&geom)
Definition: Geometry.h:45
CoverageMaskShape fCoverageMaskShape
Definition: Geometry.h:209
bool isEdgeAAQuad() const
Definition: Geometry.h:99
sk_sp< SkVertices > fVertices
Definition: Geometry.h:207
Rect bounds() const
Definition: Shape.cpp:69
bool isEmpty() const
Definition: Shape.h:59
uint8_t value
TRect< Scalar > Rect
Definition: rect.h:769