OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
9 #include "SkData.h" | 9 #include "SkData.h" |
10 #include "SkImageFilter.h" | 10 #include "SkImageFilter.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 } | 53 } |
54 } | 54 } |
55 | 55 |
56 // Pre-cache lazy non-threadsafe fields on SkPath and/or SkMatrix. | 56 // Pre-cache lazy non-threadsafe fields on SkPath and/or SkMatrix. |
57 static void make_threadsafe(SkPath* path, SkMatrix* matrix) { | 57 static void make_threadsafe(SkPath* path, SkMatrix* matrix) { |
58 if (path) { path->updateBoundsCache(); } | 58 if (path) { path->updateBoundsCache(); } |
59 if (matrix) { (void)matrix->getType(); } | 59 if (matrix) { (void)matrix->getType(); } |
60 } | 60 } |
61 | 61 |
62 namespace { | 62 namespace { |
63 #define TYPES(M)
\ | 63 struct Op { |
64 M(Save) M(Restore) M(SaveLayer)
\ | 64 virtual ~Op() {} |
65 M(Concat) M(SetMatrix) M(TranslateZ)
\ | 65 virtual void draw(SkCanvas*) = 0; |
66 M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion)
\ | 66 virtual void optimizeFor(GrContext*) {} |
67 M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawOval) M(DrawRRect) M(DrawDRRect)
\ | 67 virtual void makeThreadsafe() {} |
68 M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) M(DrawShadowedPicture)
\ | |
69 M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice)
\ | |
70 M(DrawText) M(DrawPosText) M(DrawPosTextH)
\ | |
71 M(DrawTextOnPath) M(DrawTextRSXform) M(DrawTextBlob)
\ | |
72 M(DrawPatch) M(DrawPoints) M(DrawVertices) M(DrawAtlas) | |
73 | 68 |
74 #define M(T) T, | 69 size_t skip; |
75 enum class Type : uint8_t { TYPES(M) }; | 70 }; |
76 #undef M | |
77 | 71 |
78 struct Op { | 72 struct Save final : Op { void draw(SkCanvas* c) override { c-> save();
} }; |
79 // These are never called, only used to distinguish Ops that implement | 73 struct Restore final : Op { void draw(SkCanvas* c) override { c->restore();
} }; |
80 // them from those that don't by return type: the real methods return vo
id. | |
81 int optimizeFor(GrContext*) { sk_throw(); return 0;} | |
82 int makeThreadsafe() { sk_throw(); return 0;} | |
83 | |
84 uint32_t type : 8; | |
85 uint32_t skip : 24; | |
86 }; | |
87 static_assert(sizeof(Op) == 4, ""); | |
88 | |
89 struct Save final : Op { | |
90 static const auto kType = Type::Save; | |
91 void draw(SkCanvas* c) { c->save(); } | |
92 }; | |
93 struct Restore final : Op { | |
94 static const auto kType = Type::Restore; | |
95 void draw(SkCanvas* c) { c->restore(); } | |
96 }; | |
97 struct SaveLayer final : Op { | 74 struct SaveLayer final : Op { |
98 static const auto kType = Type::SaveLayer; | |
99 SaveLayer(const SkRect* bounds, const SkPaint* paint, | 75 SaveLayer(const SkRect* bounds, const SkPaint* paint, |
100 const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags)
{ | 76 const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags)
{ |
101 if (bounds) { this->bounds = *bounds; } | 77 if (bounds) { this->bounds = *bounds; } |
102 if (paint) { this->paint = *paint; } | 78 if (paint) { this->paint = *paint; } |
103 this->backdrop = sk_ref_sp(backdrop); | 79 this->backdrop = sk_ref_sp(backdrop); |
104 this->flags = flags; | 80 this->flags = flags; |
105 } | 81 } |
106 SkRect bounds = kUnset; | 82 SkRect bounds = kUnset; |
107 SkPaint paint; | 83 SkPaint paint; |
108 sk_sp<const SkImageFilter> backdrop; | 84 sk_sp<const SkImageFilter> backdrop; |
109 SkCanvas::SaveLayerFlags flags; | 85 SkCanvas::SaveLayerFlags flags; |
110 void draw(SkCanvas* c) { | 86 void draw(SkCanvas* c) override { |
111 c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags })
; | 87 c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags })
; |
112 } | 88 } |
113 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 89 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
114 }; | 90 }; |
115 | 91 |
116 struct Concat final : Op { | 92 struct Concat final : Op { |
117 static const auto kType = Type::Concat; | |
118 Concat(const SkMatrix& matrix) : matrix(matrix) {} | 93 Concat(const SkMatrix& matrix) : matrix(matrix) {} |
119 SkMatrix matrix; | 94 SkMatrix matrix; |
120 void draw(SkCanvas* c) { c->concat(matrix); } | 95 void draw(SkCanvas* c) override { c->concat(matrix); } |
121 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } | 96 void makeThreadsafe() override { make_threadsafe(nullptr, &matrix); } |
122 }; | 97 }; |
123 struct SetMatrix final : Op { | 98 struct SetMatrix final : Op { |
124 static const auto kType = Type::SetMatrix; | |
125 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {} | 99 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {} |
126 SkMatrix matrix; | 100 SkMatrix matrix; |
127 void draw(SkCanvas* c) { c->setMatrix(matrix); } | 101 void draw(SkCanvas* c) override { c->setMatrix(matrix); } |
128 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } | 102 void makeThreadsafe() override { make_threadsafe(nullptr, &matrix); } |
129 }; | 103 }; |
130 struct TranslateZ final : Op { | 104 struct TranslateZ final : Op { |
131 static const auto kType = Type::TranslateZ; | |
132 TranslateZ(SkScalar dz) : dz(dz) {} | 105 TranslateZ(SkScalar dz) : dz(dz) {} |
133 SkScalar dz; | 106 SkScalar dz; |
134 void draw(SkCanvas* c) { | 107 void draw(SkCanvas* c) override { |
135 #ifdef SK_EXPERIMENTAL_SHADOWING | 108 #ifdef SK_EXPERIMENTAL_SHADOWING |
136 c->translateZ(dz); | 109 c->translateZ(dz); |
137 #endif | 110 #endif |
138 } | 111 } |
139 }; | 112 }; |
140 | 113 |
141 struct ClipPath final : Op { | 114 struct ClipPath final : Op { |
142 static const auto kType = Type::ClipPath; | |
143 ClipPath(const SkPath& path, SkRegion::Op op, bool aa) : path(path), op(
op), aa(aa) {} | 115 ClipPath(const SkPath& path, SkRegion::Op op, bool aa) : path(path), op(
op), aa(aa) {} |
144 SkPath path; | 116 SkPath path; |
145 SkRegion::Op op; | 117 SkRegion::Op op; |
146 bool aa; | 118 bool aa; |
147 void draw(SkCanvas* c) { c->clipPath(path, op, aa); } | 119 void draw(SkCanvas* c) override { c->clipPath(path, op, aa); } |
148 void makeThreadsafe() { make_threadsafe(&path, nullptr); } | 120 void makeThreadsafe() override { make_threadsafe(&path, nullptr); } |
149 }; | 121 }; |
150 struct ClipRect final : Op { | 122 struct ClipRect final : Op { |
151 static const auto kType = Type::ClipRect; | |
152 ClipRect(const SkRect& rect, SkRegion::Op op, bool aa) : rect(rect), op(
op), aa(aa) {} | 123 ClipRect(const SkRect& rect, SkRegion::Op op, bool aa) : rect(rect), op(
op), aa(aa) {} |
153 SkRect rect; | 124 SkRect rect; |
154 SkRegion::Op op; | 125 SkRegion::Op op; |
155 bool aa; | 126 bool aa; |
156 void draw(SkCanvas* c) { c->clipRect(rect, op, aa); } | 127 void draw(SkCanvas* c) override { c->clipRect(rect, op, aa); } |
157 }; | 128 }; |
158 struct ClipRRect final : Op { | 129 struct ClipRRect final : Op { |
159 static const auto kType = Type::ClipRRect; | |
160 ClipRRect(const SkRRect& rrect, SkRegion::Op op, bool aa) : rrect(rrect)
, op(op), aa(aa) {} | 130 ClipRRect(const SkRRect& rrect, SkRegion::Op op, bool aa) : rrect(rrect)
, op(op), aa(aa) {} |
161 SkRRect rrect; | 131 SkRRect rrect; |
162 SkRegion::Op op; | 132 SkRegion::Op op; |
163 bool aa; | 133 bool aa; |
164 void draw(SkCanvas* c) { c->clipRRect(rrect, op, aa); } | 134 void draw(SkCanvas* c) override { c->clipRRect(rrect, op, aa); } |
165 }; | 135 }; |
166 struct ClipRegion final : Op { | 136 struct ClipRegion final : Op { |
167 static const auto kType = Type::ClipRegion; | |
168 ClipRegion(const SkRegion& region, SkRegion::Op op) : region(region), op
(op) {} | 137 ClipRegion(const SkRegion& region, SkRegion::Op op) : region(region), op
(op) {} |
169 SkRegion region; | 138 SkRegion region; |
170 SkRegion::Op op; | 139 SkRegion::Op op; |
171 void draw(SkCanvas* c) { c->clipRegion(region, op); } | 140 void draw(SkCanvas* c) override { c->clipRegion(region, op); } |
172 }; | 141 }; |
173 | 142 |
174 struct DrawPaint final : Op { | 143 struct DrawPaint final : Op { |
175 static const auto kType = Type::DrawPaint; | |
176 DrawPaint(const SkPaint& paint) : paint(paint) {} | 144 DrawPaint(const SkPaint& paint) : paint(paint) {} |
177 SkPaint paint; | 145 SkPaint paint; |
178 void draw(SkCanvas* c) { c->drawPaint(paint); } | 146 void draw(SkCanvas* c) override { c->drawPaint(paint); } |
179 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 147 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
180 }; | 148 }; |
181 struct DrawPath final : Op { | 149 struct DrawPath final : Op { |
182 static const auto kType = Type::DrawPath; | |
183 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
aint) {} | 150 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
aint) {} |
184 SkPath path; | 151 SkPath path; |
185 SkPaint paint; | 152 SkPaint paint; |
186 void draw(SkCanvas* c) { c->drawPath(path, paint); } | 153 void draw(SkCanvas* c) override { c->drawPath(path, paint); } |
187 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 154 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
188 void makeThreadsafe() { make_threadsafe(&path, nullptr); } | 155 void makeThreadsafe() override { make_threadsafe(&path, nullptr); } |
189 }; | 156 }; |
190 struct DrawRect final : Op { | 157 struct DrawRect final : Op { |
191 static const auto kType = Type::DrawRect; | |
192 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
aint) {} | 158 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
aint) {} |
193 SkRect rect; | 159 SkRect rect; |
194 SkPaint paint; | 160 SkPaint paint; |
195 void draw(SkCanvas* c) { c->drawRect(rect, paint); } | 161 void draw(SkCanvas* c) override { c->drawRect(rect, paint); } |
196 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 162 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
197 }; | 163 }; |
198 struct DrawOval final : Op { | 164 struct DrawOval final : Op { |
199 static const auto kType = Type::DrawOval; | |
200 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(p
aint) {} | 165 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(p
aint) {} |
201 SkRect oval; | 166 SkRect oval; |
202 SkPaint paint; | 167 SkPaint paint; |
203 void draw(SkCanvas* c) { c->drawOval(oval, paint); } | 168 void draw(SkCanvas* c) override { c->drawOval(oval, paint); } |
204 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 169 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
205 }; | 170 }; |
206 struct DrawRRect final : Op { | 171 struct DrawRRect final : Op { |
207 static const auto kType = Type::DrawRRect; | |
208 DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), pa
int(paint) {} | 172 DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), pa
int(paint) {} |
209 SkRRect rrect; | 173 SkRRect rrect; |
210 SkPaint paint; | 174 SkPaint paint; |
211 void draw(SkCanvas* c) { c->drawRRect(rrect, paint); } | 175 void draw(SkCanvas* c) override { c->drawRRect(rrect, paint); } |
212 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 176 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
213 }; | 177 }; |
214 struct DrawDRRect final : Op { | 178 struct DrawDRRect final : Op { |
215 static const auto kType = Type::DrawDRRect; | |
216 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& pa
int) | 179 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& pa
int) |
217 : outer(outer), inner(inner), paint(paint) {} | 180 : outer(outer), inner(inner), paint(paint) {} |
218 SkRRect outer, inner; | 181 SkRRect outer, inner; |
219 SkPaint paint; | 182 SkPaint paint; |
220 void draw(SkCanvas* c) { c->drawDRRect(outer, inner, paint); } | 183 void draw(SkCanvas* c) override { c->drawDRRect(outer, inner, paint); } |
221 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 184 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
222 }; | 185 }; |
223 | 186 |
224 struct DrawAnnotation final : Op { | 187 struct DrawAnnotation final : Op { |
225 static const auto kType = Type::DrawAnnotation; | |
226 DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk
_ref_sp(value)) {} | 188 DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk
_ref_sp(value)) {} |
227 SkRect rect; | 189 SkRect rect; |
228 sk_sp<SkData> value; | 190 sk_sp<SkData> value; |
229 void draw(SkCanvas* c) { c->drawAnnotation(rect, pod<char>(this), value.
get()); } | 191 void draw(SkCanvas* c) override { c->drawAnnotation(rect, pod<char>(this
), value.get()); } |
230 }; | 192 }; |
231 struct DrawDrawable final : Op { | 193 struct DrawDrawable final : Op { |
232 static const auto kType = Type::DrawDrawable; | |
233 DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk
_ref_sp(drawable)) { | 194 DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk
_ref_sp(drawable)) { |
234 if (matrix) { this->matrix = *matrix; } | 195 if (matrix) { this->matrix = *matrix; } |
235 } | 196 } |
236 sk_sp<SkDrawable> drawable; | 197 sk_sp<SkDrawable> drawable; |
237 sk_sp<const SkPicture> snapped; | 198 sk_sp<const SkPicture> snapped; |
238 SkMatrix matrix = SkMatrix::I(); | 199 SkMatrix matrix = SkMatrix::I(); |
239 void draw(SkCanvas* c) { | 200 void draw(SkCanvas* c) override { |
240 snapped ? c->drawPicture(snapped.get(), &matrix, nullptr) | 201 snapped ? c->drawPicture(snapped.get(), &matrix, nullptr) |
241 : c->drawDrawable(drawable.get(), &matrix); | 202 : c->drawDrawable(drawable.get(), &matrix); |
242 } | 203 } |
243 void makeThreadsafe() { | 204 void makeThreadsafe() override { |
244 snapped.reset(drawable->newPictureSnapshot()); | 205 snapped.reset(drawable->newPictureSnapshot()); |
245 make_threadsafe(nullptr, &matrix); | 206 make_threadsafe(nullptr, &matrix); |
246 } | 207 } |
247 }; | 208 }; |
248 struct DrawPicture final : Op { | 209 struct DrawPicture final : Op { |
249 static const auto kType = Type::DrawPicture; | |
250 DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPa
int* paint) | 210 DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPa
int* paint) |
251 : picture(sk_ref_sp(picture)) { | 211 : picture(sk_ref_sp(picture)) { |
252 if (matrix) { this->matrix = *matrix; } | 212 if (matrix) { this->matrix = *matrix; } |
253 if (paint) { this->paint = *paint; has_paint = true; } | 213 if (paint) { this->paint = *paint; has_paint = true; } |
254 } | 214 } |
255 sk_sp<const SkPicture> picture; | 215 sk_sp<const SkPicture> picture; |
256 SkMatrix matrix = SkMatrix::I(); | 216 SkMatrix matrix = SkMatrix::I(); |
257 SkPaint paint; | 217 SkPaint paint; |
258 bool has_paint = false; // TODO: why is a default pai
nt not the same? | 218 bool has_paint = false; // TODO: why is a default pai
nt not the same? |
259 void draw(SkCanvas* c) { | 219 void draw(SkCanvas* c) override { |
260 c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr)
; | 220 c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr)
; |
261 } | 221 } |
262 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 222 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
263 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } | 223 void makeThreadsafe() override { make_threadsafe(nullptr, &matrix); } |
264 }; | 224 }; |
265 struct DrawShadowedPicture final : Op { | 225 struct DrawShadowedPicture final : Op { |
266 static const auto kType = Type::DrawShadowedPicture; | |
267 DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, co
nst SkPaint* paint) | 226 DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, co
nst SkPaint* paint) |
268 : picture(sk_ref_sp(picture)) { | 227 : picture(sk_ref_sp(picture)) { |
269 if (matrix) { this->matrix = *matrix; } | 228 if (matrix) { this->matrix = *matrix; } |
270 if (paint) { this->paint = *paint; } | 229 if (paint) { this->paint = *paint; } |
271 } | 230 } |
272 sk_sp<const SkPicture> picture; | 231 sk_sp<const SkPicture> picture; |
273 SkMatrix matrix = SkMatrix::I(); | 232 SkMatrix matrix = SkMatrix::I(); |
274 SkPaint paint; | 233 SkPaint paint; |
275 void draw(SkCanvas* c) { | 234 void draw(SkCanvas* c) override { |
276 #ifdef SK_EXPERIMENTAL_SHADOWING | 235 #ifdef SK_EXPERIMENTAL_SHADOWING |
277 c->drawShadowedPicture(picture.get(), &matrix, &paint); | 236 c->drawShadowedPicture(picture.get(), &matrix, &paint); |
278 #endif | 237 #endif |
279 } | 238 } |
280 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 239 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
281 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } | 240 void makeThreadsafe() override { make_threadsafe(nullptr, &matrix); } |
282 }; | 241 }; |
283 | 242 |
284 struct DrawImage final : Op { | 243 struct DrawImage final : Op { |
285 static const auto kType = Type::DrawImage; | |
286 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const Sk
Paint* paint) | 244 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const Sk
Paint* paint) |
287 : image(std::move(image)), x(x), y(y) { | 245 : image(std::move(image)), x(x), y(y) { |
288 if (paint) { this->paint = *paint; } | 246 if (paint) { this->paint = *paint; } |
289 } | 247 } |
290 sk_sp<const SkImage> image; | 248 sk_sp<const SkImage> image; |
291 SkScalar x,y; | 249 SkScalar x,y; |
292 SkPaint paint; | 250 SkPaint paint; |
293 void draw(SkCanvas* c) { c->drawImage(image.get(), x,y, &paint); } | 251 void draw(SkCanvas* c) override { c->drawImage(image.get(), x,y, &paint)
; } |
294 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); } | 252 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &i
mage); } |
295 }; | 253 }; |
296 struct DrawImageNine final : Op { | 254 struct DrawImageNine final : Op { |
297 static const auto kType = Type::DrawImageNine; | |
298 DrawImageNine(sk_sp<const SkImage>&& image, | 255 DrawImageNine(sk_sp<const SkImage>&& image, |
299 const SkIRect& center, const SkRect& dst, const SkPaint* p
aint) | 256 const SkIRect& center, const SkRect& dst, const SkPaint* p
aint) |
300 : image(std::move(image)), center(center), dst(dst) { | 257 : image(std::move(image)), center(center), dst(dst) { |
301 if (paint) { this->paint = *paint; } | 258 if (paint) { this->paint = *paint; } |
302 } | 259 } |
303 sk_sp<const SkImage> image; | 260 sk_sp<const SkImage> image; |
304 SkIRect center; | 261 SkIRect center; |
305 SkRect dst; | 262 SkRect dst; |
306 SkPaint paint; | 263 SkPaint paint; |
307 void draw(SkCanvas* c) { c->drawImageNine(image.get(), center, dst, &pai
nt); } | 264 void draw(SkCanvas* c) override { c->drawImageNine(image.get(), center,
dst, &paint); } |
308 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); } | 265 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &i
mage); } |
309 }; | 266 }; |
310 struct DrawImageRect final : Op { | 267 struct DrawImageRect final : Op { |
311 static const auto kType = Type::DrawImageRect; | |
312 DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkR
ect& dst, | 268 DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkR
ect& dst, |
313 const SkPaint* paint, SkCanvas::SrcRectConstraint constrai
nt) | 269 const SkPaint* paint, SkCanvas::SrcRectConstraint constrai
nt) |
314 : image(std::move(image)), dst(dst), constraint(constraint) { | 270 : image(std::move(image)), dst(dst), constraint(constraint) { |
315 this->src = src ? *src : SkRect::MakeIWH(image->width(), image->heig
ht()); | 271 this->src = src ? *src : SkRect::MakeIWH(image->width(), image->heig
ht()); |
316 if (paint) { this->paint = *paint; } | 272 if (paint) { this->paint = *paint; } |
317 } | 273 } |
318 sk_sp<const SkImage> image; | 274 sk_sp<const SkImage> image; |
319 SkRect src, dst; | 275 SkRect src, dst; |
320 SkPaint paint; | 276 SkPaint paint; |
321 SkCanvas::SrcRectConstraint constraint; | 277 SkCanvas::SrcRectConstraint constraint; |
322 void draw(SkCanvas* c) { | 278 void draw(SkCanvas* c) override { |
323 c->drawImageRect(image.get(), src, dst, &paint, constraint); | 279 c->drawImageRect(image.get(), src, dst, &paint, constraint); |
324 } | 280 } |
325 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); } | 281 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &i
mage); } |
326 }; | 282 }; |
327 struct DrawImageLattice final : Op { | 283 struct DrawImageLattice final : Op { |
328 static const auto kType = Type::DrawImageLattice; | |
329 DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, | 284 DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, |
330 const SkRect& dst, const SkPaint* paint) | 285 const SkRect& dst, const SkPaint* paint) |
331 : image(std::move(image)), xs(xs), ys(ys), dst(dst) { | 286 : image(std::move(image)), xs(xs), ys(ys), dst(dst) { |
332 if (paint) { this->paint = *paint; } | 287 if (paint) { this->paint = *paint; } |
333 } | 288 } |
334 sk_sp<const SkImage> image; | 289 sk_sp<const SkImage> image; |
335 int xs, ys; | 290 int xs, ys; |
336 SkRect dst; | 291 SkRect dst; |
337 SkPaint paint; | 292 SkPaint paint; |
338 void draw(SkCanvas* c) { | 293 void draw(SkCanvas* c) override { |
339 auto xdivs = pod<int>(this, 0), | 294 auto xdivs = pod<int>(this, 0), |
340 ydivs = pod<int>(this, xs*sizeof(int)); | 295 ydivs = pod<int>(this, xs*sizeof(int)); |
341 c->drawImageLattice(image.get(), {xdivs, xs, ydivs, ys}, dst, &paint
); | 296 c->drawImageLattice(image.get(), {xdivs, xs, ydivs, ys}, dst, &paint
); |
342 } | 297 } |
343 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); } | 298 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &i
mage); } |
344 }; | 299 }; |
345 | 300 |
346 struct DrawText final : Op { | 301 struct DrawText final : Op { |
347 static const auto kType = Type::DrawText; | |
348 DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) | 302 DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) |
349 : bytes(bytes), x(x), y(y), paint(paint) {} | 303 : bytes(bytes), x(x), y(y), paint(paint) {} |
350 size_t bytes; | 304 size_t bytes; |
351 SkScalar x,y; | 305 SkScalar x,y; |
352 SkPaint paint; | 306 SkPaint paint; |
353 void draw(SkCanvas* c) { c->drawText(pod<void>(this), bytes, x,y, paint)
; } | 307 void draw(SkCanvas* c) override { c->drawText(pod<void>(this), bytes, x,
y, paint); } |
354 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 308 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
355 }; | 309 }; |
356 struct DrawPosText final : Op { | 310 struct DrawPosText final : Op { |
357 static const auto kType = Type::DrawPosText; | |
358 DrawPosText(size_t bytes, const SkPaint& paint, int n) | 311 DrawPosText(size_t bytes, const SkPaint& paint, int n) |
359 : bytes(bytes), paint(paint), n(n) {} | 312 : bytes(bytes), paint(paint), n(n) {} |
360 size_t bytes; | 313 size_t bytes; |
361 SkPaint paint; | 314 SkPaint paint; |
362 int n; | 315 int n; |
363 void draw(SkCanvas* c) { | 316 void draw(SkCanvas* c) override { |
364 auto points = pod<SkPoint>(this); | 317 auto points = pod<SkPoint>(this); |
365 auto text = pod<void>(this, n*sizeof(SkPoint)); | 318 auto text = pod<void>(this, n*sizeof(SkPoint)); |
366 c->drawPosText(text, bytes, points, paint); | 319 c->drawPosText(text, bytes, points, paint); |
367 } | 320 } |
368 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 321 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
369 }; | 322 }; |
370 struct DrawPosTextH final : Op { | 323 struct DrawPosTextH final : Op { |
371 static const auto kType = Type::DrawPosTextH; | |
372 DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint, int n) | 324 DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint, int n) |
373 : bytes(bytes), y(y), paint(paint), n(n) {} | 325 : bytes(bytes), y(y), paint(paint), n(n) {} |
374 size_t bytes; | 326 size_t bytes; |
375 SkScalar y; | 327 SkScalar y; |
376 SkPaint paint; | 328 SkPaint paint; |
377 int n; | 329 int n; |
378 void draw(SkCanvas* c) { | 330 void draw(SkCanvas* c) override { |
379 auto xs = pod<SkScalar>(this); | 331 auto xs = pod<SkScalar>(this); |
380 auto text = pod<void>(this, n*sizeof(SkScalar)); | 332 auto text = pod<void>(this, n*sizeof(SkScalar)); |
381 c->drawPosTextH(text, bytes, xs, y, paint); | 333 c->drawPosTextH(text, bytes, xs, y, paint); |
382 } | 334 } |
383 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 335 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
384 }; | 336 }; |
385 struct DrawTextOnPath final : Op { | 337 struct DrawTextOnPath final : Op { |
386 static const auto kType = Type::DrawTextOnPath; | |
387 DrawTextOnPath(size_t bytes, const SkPath& path, | 338 DrawTextOnPath(size_t bytes, const SkPath& path, |
388 const SkMatrix* matrix, const SkPaint& paint) | 339 const SkMatrix* matrix, const SkPaint& paint) |
389 : bytes(bytes), path(path), paint(paint) { | 340 : bytes(bytes), path(path), paint(paint) { |
390 if (matrix) { this->matrix = *matrix; } | 341 if (matrix) { this->matrix = *matrix; } |
391 } | 342 } |
392 size_t bytes; | 343 size_t bytes; |
393 SkPath path; | 344 SkPath path; |
394 SkMatrix matrix = SkMatrix::I(); | 345 SkMatrix matrix = SkMatrix::I(); |
395 SkPaint paint; | 346 SkPaint paint; |
396 void draw(SkCanvas* c) { | 347 void draw(SkCanvas* c) override { |
397 c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint); | 348 c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint); |
398 } | 349 } |
399 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 350 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
400 void makeThreadsafe() { make_threadsafe(&path, &matrix); } | 351 void makeThreadsafe() override { make_threadsafe(&path, &matrix); } |
401 }; | 352 }; |
402 struct DrawTextRSXform final : Op { | 353 struct DrawTextRSXform final : Op { |
403 static const auto kType = Type::DrawTextRSXform; | |
404 DrawTextRSXform(size_t bytes, const SkRect* cull, const SkPaint& paint) | 354 DrawTextRSXform(size_t bytes, const SkRect* cull, const SkPaint& paint) |
405 : bytes(bytes), paint(paint) { | 355 : bytes(bytes), paint(paint) { |
406 if (cull) { this->cull = *cull; } | 356 if (cull) { this->cull = *cull; } |
407 } | 357 } |
408 size_t bytes; | 358 size_t bytes; |
409 SkRect cull = kUnset; | 359 SkRect cull = kUnset; |
410 SkPaint paint; | 360 SkPaint paint; |
411 void draw(SkCanvas* c) { | 361 void draw(SkCanvas* c) override { |
412 c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, byte
s), | 362 c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, byte
s), |
413 maybe_unset(cull), paint); | 363 maybe_unset(cull), paint); |
414 } | 364 } |
415 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 365 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
416 }; | 366 }; |
417 struct DrawTextBlob final : Op { | 367 struct DrawTextBlob final : Op { |
418 static const auto kType = Type::DrawTextBlob; | |
419 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPai
nt& paint) | 368 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPai
nt& paint) |
420 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {} | 369 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {} |
421 sk_sp<const SkTextBlob> blob; | 370 sk_sp<const SkTextBlob> blob; |
422 SkScalar x,y; | 371 SkScalar x,y; |
423 SkPaint paint; | 372 SkPaint paint; |
424 void draw(SkCanvas* c) { c->drawTextBlob(blob.get(), x,y, paint); } | 373 void draw(SkCanvas* c) override { c->drawTextBlob(blob.get(), x,y, paint
); } |
425 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 374 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
426 }; | 375 }; |
427 | 376 |
428 struct DrawPatch final : Op { | 377 struct DrawPatch final : Op { |
429 static const auto kType = Type::DrawPatch; | |
430 DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoi
nt texs[4], | 378 DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoi
nt texs[4], |
431 SkXfermode* xfermode, const SkPaint& paint) | 379 SkXfermode* xfermode, const SkPaint& paint) |
432 : xfermode(sk_ref_sp(xfermode)), paint(paint) { | 380 : xfermode(sk_ref_sp(xfermode)), paint(paint) { |
433 copy_v(this->cubics, cubics, 12); | 381 copy_v(this->cubics, cubics, 12); |
434 if (colors) { copy_v(this->colors, colors, 4); has_colors = true; } | 382 if (colors) { copy_v(this->colors, colors, 4); has_colors = true; } |
435 if (texs ) { copy_v(this->texs , texs , 4); has_texs = true; } | 383 if (texs ) { copy_v(this->texs , texs , 4); has_texs = true; } |
436 } | 384 } |
437 SkPoint cubics[12]; | 385 SkPoint cubics[12]; |
438 SkColor colors[4]; | 386 SkColor colors[4]; |
439 SkPoint texs[4]; | 387 SkPoint texs[4]; |
440 sk_sp<SkXfermode> xfermode; | 388 sk_sp<SkXfermode> xfermode; |
441 SkPaint paint; | 389 SkPaint paint; |
442 bool has_colors = false; | 390 bool has_colors = false; |
443 bool has_texs = false; | 391 bool has_texs = false; |
444 void draw(SkCanvas* c) { | 392 void draw(SkCanvas* c) override { |
445 c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs
: nullptr, | 393 c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs
: nullptr, |
446 xfermode.get(), paint); | 394 xfermode.get(), paint); |
447 } | 395 } |
448 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 396 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
449 }; | 397 }; |
450 struct DrawPoints final : Op { | 398 struct DrawPoints final : Op { |
451 static const auto kType = Type::DrawPoints; | |
452 DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint) | 399 DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint) |
453 : mode(mode), count(count), paint(paint) {} | 400 : mode(mode), count(count), paint(paint) {} |
454 SkCanvas::PointMode mode; | 401 SkCanvas::PointMode mode; |
455 size_t count; | 402 size_t count; |
456 SkPaint paint; | 403 SkPaint paint; |
457 void draw(SkCanvas* c) { c->drawPoints(mode, count, pod<SkPoint>(this),
paint); } | 404 void draw(SkCanvas* c) override { c->drawPoints(mode, count, pod<SkPoint
>(this), paint); } |
458 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 405 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
459 }; | 406 }; |
460 struct DrawVertices final : Op { | 407 struct DrawVertices final : Op { |
461 static const auto kType = Type::DrawVertices; | |
462 DrawVertices(SkCanvas::VertexMode mode, int count, SkXfermode* xfermode,
int nindices, | 408 DrawVertices(SkCanvas::VertexMode mode, int count, SkXfermode* xfermode,
int nindices, |
463 const SkPaint& paint, bool has_texs, bool has_colors, bool
has_indices) | 409 const SkPaint& paint, bool has_texs, bool has_colors, bool
has_indices) |
464 : mode(mode), count(count), xfermode(sk_ref_sp(xfermode)), nindices(
nindices) | 410 : mode(mode), count(count), xfermode(sk_ref_sp(xfermode)), nindices(
nindices) |
465 , paint(paint), has_texs(has_texs), has_colors(has_colors), has_indi
ces(has_indices) {} | 411 , paint(paint), has_texs(has_texs), has_colors(has_colors), has_indi
ces(has_indices) {} |
466 SkCanvas::VertexMode mode; | 412 SkCanvas::VertexMode mode; |
467 int count; | 413 int count; |
468 sk_sp<SkXfermode> xfermode; | 414 sk_sp<SkXfermode> xfermode; |
469 int nindices; | 415 int nindices; |
470 SkPaint paint; | 416 SkPaint paint; |
471 bool has_texs; | 417 bool has_texs; |
472 bool has_colors; | 418 bool has_colors; |
473 bool has_indices; | 419 bool has_indices; |
474 void draw(SkCanvas* c) { | 420 void draw(SkCanvas* c) override { |
475 SkPoint* vertices = pod<SkPoint>(this, 0); | 421 SkPoint* vertices = pod<SkPoint>(this, 0); |
476 size_t offset = count*sizeof(SkPoint); | 422 size_t offset = count*sizeof(SkPoint); |
477 | 423 |
478 SkPoint* texs = nullptr; | 424 SkPoint* texs = nullptr; |
479 if (has_texs) { | 425 if (has_texs) { |
480 texs = pod<SkPoint>(this, offset); | 426 texs = pod<SkPoint>(this, offset); |
481 offset += count*sizeof(SkPoint); | 427 offset += count*sizeof(SkPoint); |
482 } | 428 } |
483 | 429 |
484 SkColor* colors = nullptr; | 430 SkColor* colors = nullptr; |
485 if (has_colors) { | 431 if (has_colors) { |
486 colors = pod<SkColor>(this, offset); | 432 colors = pod<SkColor>(this, offset); |
487 offset += count*sizeof(SkColor); | 433 offset += count*sizeof(SkColor); |
488 } | 434 } |
489 | 435 |
490 uint16_t* indices = nullptr; | 436 uint16_t* indices = nullptr; |
491 if (has_indices) { | 437 if (has_indices) { |
492 indices = pod<uint16_t>(this, offset); | 438 indices = pod<uint16_t>(this, offset); |
493 } | 439 } |
494 c->drawVertices(mode, count, vertices, texs, colors, xfermode.get(), | 440 c->drawVertices(mode, count, vertices, texs, colors, xfermode.get(), |
495 indices, nindices, paint); | 441 indices, nindices, paint); |
496 } | 442 } |
497 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | 443 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
498 }; | 444 }; |
499 struct DrawAtlas final : Op { | 445 struct DrawAtlas final : Op { |
500 static const auto kType = Type::DrawAtlas; | |
501 DrawAtlas(const SkImage* atlas, int count, SkXfermode::Mode xfermode, | 446 DrawAtlas(const SkImage* atlas, int count, SkXfermode::Mode xfermode, |
502 const SkRect* cull, const SkPaint* paint, bool has_colors) | 447 const SkRect* cull, const SkPaint* paint, bool has_colors) |
503 : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_col
ors(has_colors) { | 448 : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_col
ors(has_colors) { |
504 if (cull) { this->cull = *cull; } | 449 if (cull) { this->cull = *cull; } |
505 if (paint) { this->paint = *paint; } | 450 if (paint) { this->paint = *paint; } |
506 } | 451 } |
507 sk_sp<const SkImage> atlas; | 452 sk_sp<const SkImage> atlas; |
508 int count; | 453 int count; |
509 SkXfermode::Mode xfermode; | 454 SkXfermode::Mode xfermode; |
510 SkRect cull = kUnset; | 455 SkRect cull = kUnset; |
511 SkPaint paint; | 456 SkPaint paint; |
512 bool has_colors; | 457 bool has_colors; |
513 void draw(SkCanvas* c) { | 458 void draw(SkCanvas* c) override { |
514 auto xforms = pod<SkRSXform>(this, 0); | 459 auto xforms = pod<SkRSXform>(this, 0); |
515 auto texs = pod<SkRect>(this, count*sizeof(SkRSXform)); | 460 auto texs = pod<SkRect>(this, count*sizeof(SkRSXform)); |
516 auto colors = has_colors | 461 auto colors = has_colors |
517 ? pod<SkColor>(this, count*(sizeof(SkRSXform) + sizeof(SkRect))) | 462 ? pod<SkColor>(this, count*(sizeof(SkRSXform) + sizeof(SkRect))) |
518 : nullptr; | 463 : nullptr; |
519 c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, | 464 c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, |
520 maybe_unset(cull), &paint); | 465 maybe_unset(cull), &paint); |
521 } | 466 } |
522 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &atlas); } | 467 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &a
tlas); } |
523 }; | 468 }; |
524 } | 469 } |
525 | 470 |
526 template <typename T, typename... Args> | 471 template <typename T, typename... Args> |
527 void* SkLiteDL::push(size_t pod, Args&&... args) { | 472 void* SkLiteDL::push(size_t pod, Args&&... args) { |
528 size_t skip = SkAlignPtr(sizeof(T) + pod); | 473 size_t skip = SkAlignPtr(sizeof(T) + pod); |
529 SkASSERT(skip < (1<<24)); | |
530 if (fUsed + skip > fReserved) { | 474 if (fUsed + skip > fReserved) { |
531 fReserved = (fUsed + skip + 4096) & ~4095; // Next greater multiple of
4096. | 475 fReserved = (fUsed + skip + 4096) & ~4095; // Next greater multiple of
4096. |
532 fBytes.realloc(fReserved); | 476 fBytes.realloc(fReserved); |
533 } | 477 } |
534 SkASSERT(fUsed + skip <= fReserved); | 478 SkASSERT(fUsed + skip <= fReserved); |
535 auto op = (T*)(fBytes.get() + fUsed); | 479 auto op = (T*)(fBytes.get() + fUsed); |
536 fUsed += skip; | 480 fUsed += skip; |
537 new (op) T{ std::forward<Args>(args)... }; | 481 new (op) T{ std::forward<Args>(args)... }; |
538 op->type = (uint32_t)T::kType; | |
539 op->skip = skip; | 482 op->skip = skip; |
540 return op+1; | 483 return op+1; |
541 } | 484 } |
542 | 485 |
543 template <typename... Args> | 486 template <typename Fn> |
544 inline void SkLiteDL::map(void (*const fns[])(void*, Args...), Args... args) { | 487 void SkLiteDL::map(Fn&& fn) { |
545 auto end = fBytes.get() + fUsed; | 488 auto end = fBytes.get() + fUsed; |
546 for (uint8_t* ptr = fBytes.get(); ptr < end; ) { | 489 for (uint8_t* ptr = fBytes.get(); ptr < end; ) { |
547 auto op = (Op*)ptr; | 490 auto op = (Op*)ptr; |
548 auto type = op->type; | 491 fn(op); |
549 auto skip = op->skip; | 492 ptr += op->skip; |
550 if (auto fn = fns[type]) { // We replace no-op functions with nullptrs | |
551 fn(op, args...); // to avoid the overhead of a pointless call
. | |
552 } | |
553 ptr += skip; | |
554 } | 493 } |
555 } | 494 } |
556 | 495 |
557 void SkLiteDL:: save() { this->push <Save>(0); } | 496 void SkLiteDL:: save() { this->push <Save>(0); } |
558 void SkLiteDL::restore() { this->push<Restore>(0); } | 497 void SkLiteDL::restore() { this->push<Restore>(0); } |
559 void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint, | 498 void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint, |
560 const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags
flags) { | 499 const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags
flags) { |
561 this->push<SaveLayer>(0, bounds, paint, backdrop, flags); | 500 this->push<SaveLayer>(0, bounds, paint, backdrop, flags); |
562 } | 501 } |
563 | 502 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 if (colors) { | 647 if (colors) { |
709 bytes += count*sizeof(SkColor); | 648 bytes += count*sizeof(SkColor); |
710 } | 649 } |
711 void* pod = this->push<DrawAtlas>(bytes, | 650 void* pod = this->push<DrawAtlas>(bytes, |
712 atlas, count, xfermode, cull, paint, color
s != nullptr); | 651 atlas, count, xfermode, cull, paint, color
s != nullptr); |
713 copy_v(pod, xforms, count, | 652 copy_v(pod, xforms, count, |
714 texs, count, | 653 texs, count, |
715 colors, colors ? count : 0); | 654 colors, colors ? count : 0); |
716 } | 655 } |
717 | 656 |
718 typedef void(* skcanvas_fn)(void*, SkCanvas*); | |
719 typedef void(*grcontext_fn)(void*, GrContext*); | |
720 typedef void(* void_fn)(void*); | |
721 | 657 |
722 // All ops implement draw(). | 658 void SkLiteDL::onDraw(SkCanvas* canvas) { |
723 #define M(T) [](void* op, SkCanvas* c) { ((T*)op)->draw(c); }, | 659 this->map([canvas](Op* op) { op->draw(canvas); }); |
724 static const skcanvas_fn draw_fns[] = { TYPES(M) }; | 660 } |
725 #undef M | |
726 | 661 |
727 // Ops that implement optimizeFor() or makeThreadsafe() return void from those f
unctions; | 662 void SkLiteDL::optimizeFor(GrContext* ctx) { |
728 // the (throwing) defaults return int. | 663 this->map([ctx](Op* op) { op->optimizeFor(ctx); }); |
729 #define M(T) std::is_void<decltype(((T*)nullptr)->optimizeFor(nullptr))>::value
\ | 664 } |
730 ? [](void* op, GrContext* ctx) { ((T*)op)->optimizeFor(ctx); } : (grcontext_
fn)nullptr, | |
731 static const grcontext_fn optimize_for_fns[] = { TYPES(M) }; | |
732 #undef M | |
733 | 665 |
734 #define M(T) std::is_void<decltype(((T*)nullptr)->makeThreadsafe())>::value \ | 666 void SkLiteDL::makeThreadsafe() { |
735 ? [](void* op) { ((T*)op)->makeThreadsafe(); } : (void_fn)nullptr, | 667 this->map([](Op* op) { op->makeThreadsafe(); }); |
736 static const void_fn make_threadsafe_fns[] = { TYPES(M) }; | 668 } |
737 #undef M | |
738 | |
739 // Most state ops (matrix, clip, save, restore) have a trivial destructor. | |
740 #define M(T) !std::is_trivially_destructible<T>::value \ | |
741 ? [](void* op) { ((T*)op)->~T(); } : (void_fn)nullptr, | |
742 static const void_fn dtor_fns[] = { TYPES(M) }; | |
743 #undef M | |
744 | |
745 void SkLiteDL::onDraw (SkCanvas* canvas) { this->map(draw_fns, canvas); } | |
746 void SkLiteDL::optimizeFor (GrContext* ctx) { this->map(optimize_for_fns, ct
x); } | |
747 void SkLiteDL::makeThreadsafe() { this->map(make_threadsafe_fns)
; } | |
748 | 669 |
749 SkRect SkLiteDL::onGetBounds() { | 670 SkRect SkLiteDL::onGetBounds() { |
750 return fBounds; | 671 return fBounds; |
751 } | 672 } |
752 | 673 |
753 #if !defined(SK_LITEDL_USES) | 674 #if !defined(SK_LITEDL_USES) |
754 #define SK_LITEDL_USES 16 | 675 #define SK_LITEDL_USES 16 |
755 #endif | 676 #endif |
756 | 677 |
757 SkLiteDL:: SkLiteDL() : fUsed(0), fReserved(0), fUsesRemaining(SK_LITEDL_USES) {
} | 678 SkLiteDL:: SkLiteDL() : fUsed(0), fReserved(0), fUsesRemaining(SK_LITEDL_USES) {
} |
(...skipping 20 matching lines...) Expand all Loading... |
778 dl->fBounds = bounds; | 699 dl->fBounds = bounds; |
779 return dl; | 700 return dl; |
780 } | 701 } |
781 | 702 |
782 void SkLiteDL::internal_dispose() const { | 703 void SkLiteDL::internal_dispose() const { |
783 // Whether we delete this or leave it on the free stack, | 704 // Whether we delete this or leave it on the free stack, |
784 // we want its refcnt at 1. | 705 // we want its refcnt at 1. |
785 this->internal_dispose_restore_refcnt_to_1(); | 706 this->internal_dispose_restore_refcnt_to_1(); |
786 | 707 |
787 auto self = const_cast<SkLiteDL*>(this); | 708 auto self = const_cast<SkLiteDL*>(this); |
788 self->map(dtor_fns); | 709 self->map([](Op* op) { op->~Op(); }); |
789 | 710 |
790 if (--self->fUsesRemaining > 0) { | 711 if (--self->fUsesRemaining > 0) { |
791 self->fUsed = 0; | 712 self->fUsed = 0; |
792 | 713 |
793 SkAutoMutexAcquire lock(gFreeStackLock); | 714 SkAutoMutexAcquire lock(gFreeStackLock); |
794 self->fNext = gFreeStack; | 715 self->fNext = gFreeStack; |
795 gFreeStack = self; | 716 gFreeStack = self; |
796 return; | 717 return; |
797 } | 718 } |
798 | 719 |
799 delete this; | 720 delete this; |
800 } | 721 } |
801 | 722 |
802 void SkLiteDL::PurgeFreelist() { | 723 void SkLiteDL::PurgeFreelist() { |
803 SkAutoMutexAcquire lock(gFreeStackLock); | 724 SkAutoMutexAcquire lock(gFreeStackLock); |
804 while (gFreeStack) { | 725 while (gFreeStack) { |
805 SkLiteDL* top = gFreeStack; | 726 SkLiteDL* top = gFreeStack; |
806 gFreeStack = gFreeStack->fNext; | 727 gFreeStack = gFreeStack->fNext; |
807 delete top; // Calling unref() here would just put it back on the list
! | 728 delete top; // Calling unref() here would just put it back on the list
! |
808 } | 729 } |
809 } | 730 } |
OLD | NEW |