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 25 matching lines...) Expand all Loading... |
36 sk_careful_memcpy(dst, src, n*sizeof(S)); | 36 sk_careful_memcpy(dst, src, n*sizeof(S)); |
37 copy_v(SkTAddOffset<void>(dst, n*sizeof(S)), std::forward<Rest>(rest)...); | 37 copy_v(SkTAddOffset<void>(dst, n*sizeof(S)), std::forward<Rest>(rest)...); |
38 } | 38 } |
39 | 39 |
40 // Helper for getting back at arrays which have been copy_v'd together after an
Op. | 40 // Helper for getting back at arrays which have been copy_v'd together after an
Op. |
41 template <typename D, typename T> | 41 template <typename D, typename T> |
42 static D* pod(T* op, size_t offset = 0) { | 42 static D* pod(T* op, size_t offset = 0) { |
43 return SkTAddOffset<D>(op+1, offset); | 43 return SkTAddOffset<D>(op+1, offset); |
44 } | 44 } |
45 | 45 |
46 // Convert images and image-based shaders to textures. | |
47 static void optimize_for(GrContext* ctx, SkPaint* paint, sk_sp<const SkImage>* i
mage = nullptr) { | |
48 SkMatrix matrix; | |
49 SkShader::TileMode xy[2]; | |
50 if (auto shader = paint->getShader()) | |
51 if (auto image = shader->isAImage(&matrix, xy)) { // TODO: compose shaders
, etc. | |
52 paint->setShader(image->makeTextureImage(ctx)->makeShader(xy[0], xy[1],
&matrix)); | |
53 } | |
54 | |
55 if (image) { | |
56 *image = (*image)->makeTextureImage(ctx); | |
57 } | |
58 } | |
59 | |
60 // Pre-cache lazy non-threadsafe fields on SkPath and/or SkMatrix. | 46 // Pre-cache lazy non-threadsafe fields on SkPath and/or SkMatrix. |
61 static void make_threadsafe(SkPath* path, SkMatrix* matrix) { | 47 static void make_threadsafe(SkPath* path, SkMatrix* matrix) { |
62 if (path) { path->updateBoundsCache(); } | 48 if (path) { path->updateBoundsCache(); } |
63 if (matrix) { (void)matrix->getType(); } | 49 if (matrix) { (void)matrix->getType(); } |
64 } | 50 } |
65 | 51 |
66 namespace { | 52 namespace { |
67 #define TYPES(M)
\ | 53 #define TYPES(M)
\ |
68 M(Save) M(Restore) M(SaveLayer)
\ | 54 M(Save) M(Restore) M(SaveLayer)
\ |
69 M(Concat) M(SetMatrix) M(TranslateZ)
\ | 55 M(Concat) M(SetMatrix) M(TranslateZ)
\ |
70 M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion)
\ | 56 M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion)
\ |
71 M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawOval) M(DrawRRect) M(DrawDRRect)
\ | 57 M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawOval) M(DrawRRect) M(DrawDRRect)
\ |
72 M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) M(DrawShadowedPicture)
\ | 58 M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) M(DrawShadowedPicture)
\ |
73 M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice)
\ | 59 M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice)
\ |
74 M(DrawText) M(DrawPosText) M(DrawPosTextH)
\ | 60 M(DrawText) M(DrawPosText) M(DrawPosTextH)
\ |
75 M(DrawTextOnPath) M(DrawTextRSXform) M(DrawTextBlob)
\ | 61 M(DrawTextOnPath) M(DrawTextRSXform) M(DrawTextBlob)
\ |
76 M(DrawPatch) M(DrawPoints) M(DrawVertices) M(DrawAtlas) | 62 M(DrawPatch) M(DrawPoints) M(DrawVertices) M(DrawAtlas) |
77 | 63 |
78 #define M(T) T, | 64 #define M(T) T, |
79 enum class Type : uint8_t { TYPES(M) }; | 65 enum class Type : uint8_t { TYPES(M) }; |
80 #undef M | 66 #undef M |
81 | 67 |
82 struct Op { | 68 struct Op { |
83 // These are never called, only used to distinguish Ops that implement | 69 void makeThreadsafe() {} |
84 // them from those that don't by return type: the real methods return vo
id. | |
85 int optimizeFor(GrContext*) { sk_throw(); return 0;} | |
86 int makeThreadsafe() { sk_throw(); return 0;} | |
87 | 70 |
88 uint32_t type : 8; | 71 uint32_t type : 8; |
89 uint32_t skip : 24; | 72 uint32_t skip : 24; |
90 }; | 73 }; |
91 static_assert(sizeof(Op) == 4, ""); | 74 static_assert(sizeof(Op) == 4, ""); |
92 | 75 |
93 struct Save final : Op { | 76 struct Save final : Op { |
94 static const auto kType = Type::Save; | 77 static const auto kType = Type::Save; |
95 void draw(SkCanvas* c, const SkMatrix&) { c->save(); } | 78 void draw(SkCanvas* c, const SkMatrix&) { c->save(); } |
96 }; | 79 }; |
(...skipping 10 matching lines...) Expand all Loading... |
107 this->backdrop = sk_ref_sp(backdrop); | 90 this->backdrop = sk_ref_sp(backdrop); |
108 this->flags = flags; | 91 this->flags = flags; |
109 } | 92 } |
110 SkRect bounds = kUnset; | 93 SkRect bounds = kUnset; |
111 SkPaint paint; | 94 SkPaint paint; |
112 sk_sp<const SkImageFilter> backdrop; | 95 sk_sp<const SkImageFilter> backdrop; |
113 SkCanvas::SaveLayerFlags flags; | 96 SkCanvas::SaveLayerFlags flags; |
114 void draw(SkCanvas* c, const SkMatrix&) { | 97 void draw(SkCanvas* c, const SkMatrix&) { |
115 c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags })
; | 98 c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags })
; |
116 } | 99 } |
117 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
118 }; | 100 }; |
119 | 101 |
120 struct Concat final : Op { | 102 struct Concat final : Op { |
121 static const auto kType = Type::Concat; | 103 static const auto kType = Type::Concat; |
122 Concat(const SkMatrix& matrix) : matrix(matrix) {} | 104 Concat(const SkMatrix& matrix) : matrix(matrix) {} |
123 SkMatrix matrix; | 105 SkMatrix matrix; |
124 void draw(SkCanvas* c, const SkMatrix&) { c->concat(matrix); } | 106 void draw(SkCanvas* c, const SkMatrix&) { c->concat(matrix); } |
125 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } | 107 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } |
126 }; | 108 }; |
127 struct SetMatrix final : Op { | 109 struct SetMatrix final : Op { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 SkRegion region; | 157 SkRegion region; |
176 SkRegion::Op op; | 158 SkRegion::Op op; |
177 void draw(SkCanvas* c, const SkMatrix&) { c->clipRegion(region, op); } | 159 void draw(SkCanvas* c, const SkMatrix&) { c->clipRegion(region, op); } |
178 }; | 160 }; |
179 | 161 |
180 struct DrawPaint final : Op { | 162 struct DrawPaint final : Op { |
181 static const auto kType = Type::DrawPaint; | 163 static const auto kType = Type::DrawPaint; |
182 DrawPaint(const SkPaint& paint) : paint(paint) {} | 164 DrawPaint(const SkPaint& paint) : paint(paint) {} |
183 SkPaint paint; | 165 SkPaint paint; |
184 void draw(SkCanvas* c, const SkMatrix&) { c->drawPaint(paint); } | 166 void draw(SkCanvas* c, const SkMatrix&) { c->drawPaint(paint); } |
185 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
186 }; | 167 }; |
187 struct DrawPath final : Op { | 168 struct DrawPath final : Op { |
188 static const auto kType = Type::DrawPath; | 169 static const auto kType = Type::DrawPath; |
189 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
aint) {} | 170 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
aint) {} |
190 SkPath path; | 171 SkPath path; |
191 SkPaint paint; | 172 SkPaint paint; |
192 void draw(SkCanvas* c, const SkMatrix&) { c->drawPath(path, paint); } | 173 void draw(SkCanvas* c, const SkMatrix&) { c->drawPath(path, paint); } |
193 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
194 void makeThreadsafe() { make_threadsafe(&path, nullptr); } | 174 void makeThreadsafe() { make_threadsafe(&path, nullptr); } |
195 }; | 175 }; |
196 struct DrawRect final : Op { | 176 struct DrawRect final : Op { |
197 static const auto kType = Type::DrawRect; | 177 static const auto kType = Type::DrawRect; |
198 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
aint) {} | 178 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
aint) {} |
199 SkRect rect; | 179 SkRect rect; |
200 SkPaint paint; | 180 SkPaint paint; |
201 void draw(SkCanvas* c, const SkMatrix&) { c->drawRect(rect, paint); } | 181 void draw(SkCanvas* c, const SkMatrix&) { c->drawRect(rect, paint); } |
202 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
203 }; | 182 }; |
204 struct DrawOval final : Op { | 183 struct DrawOval final : Op { |
205 static const auto kType = Type::DrawOval; | 184 static const auto kType = Type::DrawOval; |
206 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(p
aint) {} | 185 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(p
aint) {} |
207 SkRect oval; | 186 SkRect oval; |
208 SkPaint paint; | 187 SkPaint paint; |
209 void draw(SkCanvas* c, const SkMatrix&) { c->drawOval(oval, paint); } | 188 void draw(SkCanvas* c, const SkMatrix&) { c->drawOval(oval, paint); } |
210 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
211 }; | 189 }; |
212 struct DrawRRect final : Op { | 190 struct DrawRRect final : Op { |
213 static const auto kType = Type::DrawRRect; | 191 static const auto kType = Type::DrawRRect; |
214 DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), pa
int(paint) {} | 192 DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), pa
int(paint) {} |
215 SkRRect rrect; | 193 SkRRect rrect; |
216 SkPaint paint; | 194 SkPaint paint; |
217 void draw(SkCanvas* c, const SkMatrix&) { c->drawRRect(rrect, paint); } | 195 void draw(SkCanvas* c, const SkMatrix&) { c->drawRRect(rrect, paint); } |
218 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
219 }; | 196 }; |
220 struct DrawDRRect final : Op { | 197 struct DrawDRRect final : Op { |
221 static const auto kType = Type::DrawDRRect; | 198 static const auto kType = Type::DrawDRRect; |
222 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& pa
int) | 199 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& pa
int) |
223 : outer(outer), inner(inner), paint(paint) {} | 200 : outer(outer), inner(inner), paint(paint) {} |
224 SkRRect outer, inner; | 201 SkRRect outer, inner; |
225 SkPaint paint; | 202 SkPaint paint; |
226 void draw(SkCanvas* c, const SkMatrix&) { c->drawDRRect(outer, inner, pa
int); } | 203 void draw(SkCanvas* c, const SkMatrix&) { c->drawDRRect(outer, inner, pa
int); } |
227 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
228 }; | 204 }; |
229 | 205 |
230 struct DrawAnnotation final : Op { | 206 struct DrawAnnotation final : Op { |
231 static const auto kType = Type::DrawAnnotation; | 207 static const auto kType = Type::DrawAnnotation; |
232 DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk
_ref_sp(value)) {} | 208 DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk
_ref_sp(value)) {} |
233 SkRect rect; | 209 SkRect rect; |
234 sk_sp<SkData> value; | 210 sk_sp<SkData> value; |
235 void draw(SkCanvas* c, const SkMatrix&) { | 211 void draw(SkCanvas* c, const SkMatrix&) { |
236 c->drawAnnotation(rect, pod<char>(this), value.get()); | 212 c->drawAnnotation(rect, pod<char>(this), value.get()); |
237 } | 213 } |
(...skipping 22 matching lines...) Expand all Loading... |
260 if (matrix) { this->matrix = *matrix; } | 236 if (matrix) { this->matrix = *matrix; } |
261 if (paint) { this->paint = *paint; has_paint = true; } | 237 if (paint) { this->paint = *paint; has_paint = true; } |
262 } | 238 } |
263 sk_sp<const SkPicture> picture; | 239 sk_sp<const SkPicture> picture; |
264 SkMatrix matrix = SkMatrix::I(); | 240 SkMatrix matrix = SkMatrix::I(); |
265 SkPaint paint; | 241 SkPaint paint; |
266 bool has_paint = false; // TODO: why is a default pai
nt not the same? | 242 bool has_paint = false; // TODO: why is a default pai
nt not the same? |
267 void draw(SkCanvas* c, const SkMatrix&) { | 243 void draw(SkCanvas* c, const SkMatrix&) { |
268 c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr)
; | 244 c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr)
; |
269 } | 245 } |
270 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
271 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } | 246 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } |
272 }; | 247 }; |
273 struct DrawShadowedPicture final : Op { | 248 struct DrawShadowedPicture final : Op { |
274 static const auto kType = Type::DrawShadowedPicture; | 249 static const auto kType = Type::DrawShadowedPicture; |
275 DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, co
nst SkPaint* paint) | 250 DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, co
nst SkPaint* paint) |
276 : picture(sk_ref_sp(picture)) { | 251 : picture(sk_ref_sp(picture)) { |
277 if (matrix) { this->matrix = *matrix; } | 252 if (matrix) { this->matrix = *matrix; } |
278 if (paint) { this->paint = *paint; } | 253 if (paint) { this->paint = *paint; } |
279 } | 254 } |
280 sk_sp<const SkPicture> picture; | 255 sk_sp<const SkPicture> picture; |
281 SkMatrix matrix = SkMatrix::I(); | 256 SkMatrix matrix = SkMatrix::I(); |
282 SkPaint paint; | 257 SkPaint paint; |
283 void draw(SkCanvas* c, const SkMatrix&) { | 258 void draw(SkCanvas* c, const SkMatrix&) { |
284 #ifdef SK_EXPERIMENTAL_SHADOWING | 259 #ifdef SK_EXPERIMENTAL_SHADOWING |
285 c->drawShadowedPicture(picture.get(), &matrix, &paint); | 260 c->drawShadowedPicture(picture.get(), &matrix, &paint); |
286 #endif | 261 #endif |
287 } | 262 } |
288 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
289 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } | 263 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } |
290 }; | 264 }; |
291 | 265 |
292 struct DrawImage final : Op { | 266 struct DrawImage final : Op { |
293 static const auto kType = Type::DrawImage; | 267 static const auto kType = Type::DrawImage; |
294 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const Sk
Paint* paint) | 268 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const Sk
Paint* paint) |
295 : image(std::move(image)), x(x), y(y) { | 269 : image(std::move(image)), x(x), y(y) { |
296 if (paint) { this->paint = *paint; } | 270 if (paint) { this->paint = *paint; } |
297 } | 271 } |
298 sk_sp<const SkImage> image; | 272 sk_sp<const SkImage> image; |
299 SkScalar x,y; | 273 SkScalar x,y; |
300 SkPaint paint; | 274 SkPaint paint; |
301 void draw(SkCanvas* c, const SkMatrix&) { c->drawImage(image.get(), x,y,
&paint); } | 275 void draw(SkCanvas* c, const SkMatrix&) { c->drawImage(image.get(), x,y,
&paint); } |
302 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); } | |
303 }; | 276 }; |
304 struct DrawImageNine final : Op { | 277 struct DrawImageNine final : Op { |
305 static const auto kType = Type::DrawImageNine; | 278 static const auto kType = Type::DrawImageNine; |
306 DrawImageNine(sk_sp<const SkImage>&& image, | 279 DrawImageNine(sk_sp<const SkImage>&& image, |
307 const SkIRect& center, const SkRect& dst, const SkPaint* p
aint) | 280 const SkIRect& center, const SkRect& dst, const SkPaint* p
aint) |
308 : image(std::move(image)), center(center), dst(dst) { | 281 : image(std::move(image)), center(center), dst(dst) { |
309 if (paint) { this->paint = *paint; } | 282 if (paint) { this->paint = *paint; } |
310 } | 283 } |
311 sk_sp<const SkImage> image; | 284 sk_sp<const SkImage> image; |
312 SkIRect center; | 285 SkIRect center; |
313 SkRect dst; | 286 SkRect dst; |
314 SkPaint paint; | 287 SkPaint paint; |
315 void draw(SkCanvas* c, const SkMatrix&) { | 288 void draw(SkCanvas* c, const SkMatrix&) { |
316 c->drawImageNine(image.get(), center, dst, &paint); | 289 c->drawImageNine(image.get(), center, dst, &paint); |
317 } | 290 } |
318 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); } | |
319 }; | 291 }; |
320 struct DrawImageRect final : Op { | 292 struct DrawImageRect final : Op { |
321 static const auto kType = Type::DrawImageRect; | 293 static const auto kType = Type::DrawImageRect; |
322 DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkR
ect& dst, | 294 DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkR
ect& dst, |
323 const SkPaint* paint, SkCanvas::SrcRectConstraint constrai
nt) | 295 const SkPaint* paint, SkCanvas::SrcRectConstraint constrai
nt) |
324 : image(std::move(image)), dst(dst), constraint(constraint) { | 296 : image(std::move(image)), dst(dst), constraint(constraint) { |
325 this->src = src ? *src : SkRect::MakeIWH(image->width(), image->heig
ht()); | 297 this->src = src ? *src : SkRect::MakeIWH(image->width(), image->heig
ht()); |
326 if (paint) { this->paint = *paint; } | 298 if (paint) { this->paint = *paint; } |
327 } | 299 } |
328 sk_sp<const SkImage> image; | 300 sk_sp<const SkImage> image; |
329 SkRect src, dst; | 301 SkRect src, dst; |
330 SkPaint paint; | 302 SkPaint paint; |
331 SkCanvas::SrcRectConstraint constraint; | 303 SkCanvas::SrcRectConstraint constraint; |
332 void draw(SkCanvas* c, const SkMatrix&) { | 304 void draw(SkCanvas* c, const SkMatrix&) { |
333 c->drawImageRect(image.get(), src, dst, &paint, constraint); | 305 c->drawImageRect(image.get(), src, dst, &paint, constraint); |
334 } | 306 } |
335 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); } | |
336 }; | 307 }; |
337 struct DrawImageLattice final : Op { | 308 struct DrawImageLattice final : Op { |
338 static const auto kType = Type::DrawImageLattice; | 309 static const auto kType = Type::DrawImageLattice; |
339 DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, | 310 DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, |
340 const SkRect& dst, const SkPaint* paint) | 311 const SkRect& dst, const SkPaint* paint) |
341 : image(std::move(image)), xs(xs), ys(ys), dst(dst) { | 312 : image(std::move(image)), xs(xs), ys(ys), dst(dst) { |
342 if (paint) { this->paint = *paint; } | 313 if (paint) { this->paint = *paint; } |
343 } | 314 } |
344 sk_sp<const SkImage> image; | 315 sk_sp<const SkImage> image; |
345 int xs, ys; | 316 int xs, ys; |
346 SkRect dst; | 317 SkRect dst; |
347 SkPaint paint; | 318 SkPaint paint; |
348 void draw(SkCanvas* c, const SkMatrix&) { | 319 void draw(SkCanvas* c, const SkMatrix&) { |
349 auto xdivs = pod<int>(this, 0), | 320 auto xdivs = pod<int>(this, 0), |
350 ydivs = pod<int>(this, xs*sizeof(int)); | 321 ydivs = pod<int>(this, xs*sizeof(int)); |
351 c->drawImageLattice(image.get(), {xdivs, xs, ydivs, ys}, dst, &paint
); | 322 c->drawImageLattice(image.get(), {xdivs, xs, ydivs, ys}, dst, &paint
); |
352 } | 323 } |
353 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &image); } | |
354 }; | 324 }; |
355 | 325 |
356 struct DrawText final : Op { | 326 struct DrawText final : Op { |
357 static const auto kType = Type::DrawText; | 327 static const auto kType = Type::DrawText; |
358 DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) | 328 DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) |
359 : bytes(bytes), x(x), y(y), paint(paint) {} | 329 : bytes(bytes), x(x), y(y), paint(paint) {} |
360 size_t bytes; | 330 size_t bytes; |
361 SkScalar x,y; | 331 SkScalar x,y; |
362 SkPaint paint; | 332 SkPaint paint; |
363 void draw(SkCanvas* c, const SkMatrix&) { | 333 void draw(SkCanvas* c, const SkMatrix&) { |
364 c->drawText(pod<void>(this), bytes, x,y, paint); | 334 c->drawText(pod<void>(this), bytes, x,y, paint); |
365 } | 335 } |
366 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
367 }; | 336 }; |
368 struct DrawPosText final : Op { | 337 struct DrawPosText final : Op { |
369 static const auto kType = Type::DrawPosText; | 338 static const auto kType = Type::DrawPosText; |
370 DrawPosText(size_t bytes, const SkPaint& paint, int n) | 339 DrawPosText(size_t bytes, const SkPaint& paint, int n) |
371 : bytes(bytes), paint(paint), n(n) {} | 340 : bytes(bytes), paint(paint), n(n) {} |
372 size_t bytes; | 341 size_t bytes; |
373 SkPaint paint; | 342 SkPaint paint; |
374 int n; | 343 int n; |
375 void draw(SkCanvas* c, const SkMatrix&) { | 344 void draw(SkCanvas* c, const SkMatrix&) { |
376 auto points = pod<SkPoint>(this); | 345 auto points = pod<SkPoint>(this); |
377 auto text = pod<void>(this, n*sizeof(SkPoint)); | 346 auto text = pod<void>(this, n*sizeof(SkPoint)); |
378 c->drawPosText(text, bytes, points, paint); | 347 c->drawPosText(text, bytes, points, paint); |
379 } | 348 } |
380 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
381 }; | 349 }; |
382 struct DrawPosTextH final : Op { | 350 struct DrawPosTextH final : Op { |
383 static const auto kType = Type::DrawPosTextH; | 351 static const auto kType = Type::DrawPosTextH; |
384 DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint, int n) | 352 DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint, int n) |
385 : bytes(bytes), y(y), paint(paint), n(n) {} | 353 : bytes(bytes), y(y), paint(paint), n(n) {} |
386 size_t bytes; | 354 size_t bytes; |
387 SkScalar y; | 355 SkScalar y; |
388 SkPaint paint; | 356 SkPaint paint; |
389 int n; | 357 int n; |
390 void draw(SkCanvas* c, const SkMatrix&) { | 358 void draw(SkCanvas* c, const SkMatrix&) { |
391 auto xs = pod<SkScalar>(this); | 359 auto xs = pod<SkScalar>(this); |
392 auto text = pod<void>(this, n*sizeof(SkScalar)); | 360 auto text = pod<void>(this, n*sizeof(SkScalar)); |
393 c->drawPosTextH(text, bytes, xs, y, paint); | 361 c->drawPosTextH(text, bytes, xs, y, paint); |
394 } | 362 } |
395 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
396 }; | 363 }; |
397 struct DrawTextOnPath final : Op { | 364 struct DrawTextOnPath final : Op { |
398 static const auto kType = Type::DrawTextOnPath; | 365 static const auto kType = Type::DrawTextOnPath; |
399 DrawTextOnPath(size_t bytes, const SkPath& path, | 366 DrawTextOnPath(size_t bytes, const SkPath& path, |
400 const SkMatrix* matrix, const SkPaint& paint) | 367 const SkMatrix* matrix, const SkPaint& paint) |
401 : bytes(bytes), path(path), paint(paint) { | 368 : bytes(bytes), path(path), paint(paint) { |
402 if (matrix) { this->matrix = *matrix; } | 369 if (matrix) { this->matrix = *matrix; } |
403 } | 370 } |
404 size_t bytes; | 371 size_t bytes; |
405 SkPath path; | 372 SkPath path; |
406 SkMatrix matrix = SkMatrix::I(); | 373 SkMatrix matrix = SkMatrix::I(); |
407 SkPaint paint; | 374 SkPaint paint; |
408 void draw(SkCanvas* c, const SkMatrix&) { | 375 void draw(SkCanvas* c, const SkMatrix&) { |
409 c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint); | 376 c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint); |
410 } | 377 } |
411 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
412 void makeThreadsafe() { make_threadsafe(&path, &matrix); } | 378 void makeThreadsafe() { make_threadsafe(&path, &matrix); } |
413 }; | 379 }; |
414 struct DrawTextRSXform final : Op { | 380 struct DrawTextRSXform final : Op { |
415 static const auto kType = Type::DrawTextRSXform; | 381 static const auto kType = Type::DrawTextRSXform; |
416 DrawTextRSXform(size_t bytes, const SkRect* cull, const SkPaint& paint) | 382 DrawTextRSXform(size_t bytes, const SkRect* cull, const SkPaint& paint) |
417 : bytes(bytes), paint(paint) { | 383 : bytes(bytes), paint(paint) { |
418 if (cull) { this->cull = *cull; } | 384 if (cull) { this->cull = *cull; } |
419 } | 385 } |
420 size_t bytes; | 386 size_t bytes; |
421 SkRect cull = kUnset; | 387 SkRect cull = kUnset; |
422 SkPaint paint; | 388 SkPaint paint; |
423 void draw(SkCanvas* c, const SkMatrix&) { | 389 void draw(SkCanvas* c, const SkMatrix&) { |
424 c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, byte
s), | 390 c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, byte
s), |
425 maybe_unset(cull), paint); | 391 maybe_unset(cull), paint); |
426 } | 392 } |
427 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
428 }; | 393 }; |
429 struct DrawTextBlob final : Op { | 394 struct DrawTextBlob final : Op { |
430 static const auto kType = Type::DrawTextBlob; | 395 static const auto kType = Type::DrawTextBlob; |
431 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPai
nt& paint) | 396 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPai
nt& paint) |
432 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {} | 397 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {} |
433 sk_sp<const SkTextBlob> blob; | 398 sk_sp<const SkTextBlob> blob; |
434 SkScalar x,y; | 399 SkScalar x,y; |
435 SkPaint paint; | 400 SkPaint paint; |
436 void draw(SkCanvas* c, const SkMatrix&) { | 401 void draw(SkCanvas* c, const SkMatrix&) { |
437 c->drawTextBlob(blob.get(), x,y, paint); | 402 c->drawTextBlob(blob.get(), x,y, paint); |
438 } | 403 } |
439 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
440 }; | 404 }; |
441 | 405 |
442 struct DrawPatch final : Op { | 406 struct DrawPatch final : Op { |
443 static const auto kType = Type::DrawPatch; | 407 static const auto kType = Type::DrawPatch; |
444 DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoi
nt texs[4], | 408 DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoi
nt texs[4], |
445 SkXfermode* xfermode, const SkPaint& paint) | 409 SkXfermode* xfermode, const SkPaint& paint) |
446 : xfermode(sk_ref_sp(xfermode)), paint(paint) { | 410 : xfermode(sk_ref_sp(xfermode)), paint(paint) { |
447 copy_v(this->cubics, cubics, 12); | 411 copy_v(this->cubics, cubics, 12); |
448 if (colors) { copy_v(this->colors, colors, 4); has_colors = true; } | 412 if (colors) { copy_v(this->colors, colors, 4); has_colors = true; } |
449 if (texs ) { copy_v(this->texs , texs , 4); has_texs = true; } | 413 if (texs ) { copy_v(this->texs , texs , 4); has_texs = true; } |
450 } | 414 } |
451 SkPoint cubics[12]; | 415 SkPoint cubics[12]; |
452 SkColor colors[4]; | 416 SkColor colors[4]; |
453 SkPoint texs[4]; | 417 SkPoint texs[4]; |
454 sk_sp<SkXfermode> xfermode; | 418 sk_sp<SkXfermode> xfermode; |
455 SkPaint paint; | 419 SkPaint paint; |
456 bool has_colors = false; | 420 bool has_colors = false; |
457 bool has_texs = false; | 421 bool has_texs = false; |
458 void draw(SkCanvas* c, const SkMatrix&) { | 422 void draw(SkCanvas* c, const SkMatrix&) { |
459 c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs
: nullptr, | 423 c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs
: nullptr, |
460 xfermode.get(), paint); | 424 xfermode.get(), paint); |
461 } | 425 } |
462 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
463 }; | 426 }; |
464 struct DrawPoints final : Op { | 427 struct DrawPoints final : Op { |
465 static const auto kType = Type::DrawPoints; | 428 static const auto kType = Type::DrawPoints; |
466 DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint) | 429 DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint) |
467 : mode(mode), count(count), paint(paint) {} | 430 : mode(mode), count(count), paint(paint) {} |
468 SkCanvas::PointMode mode; | 431 SkCanvas::PointMode mode; |
469 size_t count; | 432 size_t count; |
470 SkPaint paint; | 433 SkPaint paint; |
471 void draw(SkCanvas* c, const SkMatrix&) { | 434 void draw(SkCanvas* c, const SkMatrix&) { |
472 c->drawPoints(mode, count, pod<SkPoint>(this), paint); | 435 c->drawPoints(mode, count, pod<SkPoint>(this), paint); |
473 } | 436 } |
474 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
475 }; | 437 }; |
476 struct DrawVertices final : Op { | 438 struct DrawVertices final : Op { |
477 static const auto kType = Type::DrawVertices; | 439 static const auto kType = Type::DrawVertices; |
478 DrawVertices(SkCanvas::VertexMode mode, int count, SkXfermode* xfermode,
int nindices, | 440 DrawVertices(SkCanvas::VertexMode mode, int count, SkXfermode* xfermode,
int nindices, |
479 const SkPaint& paint, bool has_texs, bool has_colors, bool
has_indices) | 441 const SkPaint& paint, bool has_texs, bool has_colors, bool
has_indices) |
480 : mode(mode), count(count), xfermode(sk_ref_sp(xfermode)), nindices(
nindices) | 442 : mode(mode), count(count), xfermode(sk_ref_sp(xfermode)), nindices(
nindices) |
481 , paint(paint), has_texs(has_texs), has_colors(has_colors), has_indi
ces(has_indices) {} | 443 , paint(paint), has_texs(has_texs), has_colors(has_colors), has_indi
ces(has_indices) {} |
482 SkCanvas::VertexMode mode; | 444 SkCanvas::VertexMode mode; |
483 int count; | 445 int count; |
484 sk_sp<SkXfermode> xfermode; | 446 sk_sp<SkXfermode> xfermode; |
(...skipping 18 matching lines...) Expand all Loading... |
503 offset += count*sizeof(SkColor); | 465 offset += count*sizeof(SkColor); |
504 } | 466 } |
505 | 467 |
506 uint16_t* indices = nullptr; | 468 uint16_t* indices = nullptr; |
507 if (has_indices) { | 469 if (has_indices) { |
508 indices = pod<uint16_t>(this, offset); | 470 indices = pod<uint16_t>(this, offset); |
509 } | 471 } |
510 c->drawVertices(mode, count, vertices, texs, colors, xfermode.get(), | 472 c->drawVertices(mode, count, vertices, texs, colors, xfermode.get(), |
511 indices, nindices, paint); | 473 indices, nindices, paint); |
512 } | 474 } |
513 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint); } | |
514 }; | 475 }; |
515 struct DrawAtlas final : Op { | 476 struct DrawAtlas final : Op { |
516 static const auto kType = Type::DrawAtlas; | 477 static const auto kType = Type::DrawAtlas; |
517 DrawAtlas(const SkImage* atlas, int count, SkXfermode::Mode xfermode, | 478 DrawAtlas(const SkImage* atlas, int count, SkXfermode::Mode xfermode, |
518 const SkRect* cull, const SkPaint* paint, bool has_colors) | 479 const SkRect* cull, const SkPaint* paint, bool has_colors) |
519 : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_col
ors(has_colors) { | 480 : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_col
ors(has_colors) { |
520 if (cull) { this->cull = *cull; } | 481 if (cull) { this->cull = *cull; } |
521 if (paint) { this->paint = *paint; } | 482 if (paint) { this->paint = *paint; } |
522 } | 483 } |
523 sk_sp<const SkImage> atlas; | 484 sk_sp<const SkImage> atlas; |
524 int count; | 485 int count; |
525 SkXfermode::Mode xfermode; | 486 SkXfermode::Mode xfermode; |
526 SkRect cull = kUnset; | 487 SkRect cull = kUnset; |
527 SkPaint paint; | 488 SkPaint paint; |
528 bool has_colors; | 489 bool has_colors; |
529 void draw(SkCanvas* c, const SkMatrix&) { | 490 void draw(SkCanvas* c, const SkMatrix&) { |
530 auto xforms = pod<SkRSXform>(this, 0); | 491 auto xforms = pod<SkRSXform>(this, 0); |
531 auto texs = pod<SkRect>(this, count*sizeof(SkRSXform)); | 492 auto texs = pod<SkRect>(this, count*sizeof(SkRSXform)); |
532 auto colors = has_colors | 493 auto colors = has_colors |
533 ? pod<SkColor>(this, count*(sizeof(SkRSXform) + sizeof(SkRect))) | 494 ? pod<SkColor>(this, count*(sizeof(SkRSXform) + sizeof(SkRect))) |
534 : nullptr; | 495 : nullptr; |
535 c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, | 496 c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, |
536 maybe_unset(cull), &paint); | 497 maybe_unset(cull), &paint); |
537 } | 498 } |
538 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &atlas); } | |
539 }; | 499 }; |
540 } | 500 } |
541 | 501 |
542 template <typename T, typename... Args> | 502 template <typename T, typename... Args> |
543 void* SkLiteDL::push(size_t pod, Args&&... args) { | 503 void* SkLiteDL::push(size_t pod, Args&&... args) { |
544 size_t skip = SkAlignPtr(sizeof(T) + pod); | 504 size_t skip = SkAlignPtr(sizeof(T) + pod); |
545 SkASSERT(skip < (1<<24)); | 505 SkASSERT(skip < (1<<24)); |
546 if (fUsed + skip > fReserved) { | 506 if (fUsed + skip > fReserved) { |
547 static_assert(SkIsPow2(SKLITEDL_PAGE), "This math needs updating for non
-pow2."); | 507 static_assert(SkIsPow2(SKLITEDL_PAGE), "This math needs updating for non
-pow2."); |
548 // Next greater multiple of SKLITEDL_PAGE. | 508 // Next greater multiple of SKLITEDL_PAGE. |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 if (colors) { | 695 if (colors) { |
736 bytes += count*sizeof(SkColor); | 696 bytes += count*sizeof(SkColor); |
737 } | 697 } |
738 void* pod = this->push<DrawAtlas>(bytes, | 698 void* pod = this->push<DrawAtlas>(bytes, |
739 atlas, count, xfermode, cull, paint, color
s != nullptr); | 699 atlas, count, xfermode, cull, paint, color
s != nullptr); |
740 copy_v(pod, xforms, count, | 700 copy_v(pod, xforms, count, |
741 texs, count, | 701 texs, count, |
742 colors, colors ? count : 0); | 702 colors, colors ? count : 0); |
743 } | 703 } |
744 | 704 |
745 typedef void(* draw_fn)(void*, SkCanvas*, const SkMatrix&); | 705 typedef void(*draw_fn)(void*, SkCanvas*, const SkMatrix&); |
746 typedef void(*grcontext_fn)(void*, GrContext*); | 706 typedef void(*void_fn)(void*); |
747 typedef void(* void_fn)(void*); | |
748 | 707 |
749 // All ops implement draw(). | 708 // All ops implement draw(). |
750 #define M(T) [](void* op, SkCanvas* c, const SkMatrix& original) { ((T*)op)->dra
w(c, original); }, | 709 #define M(T) [](void* op, SkCanvas* c, const SkMatrix& original) { ((T*)op)->dra
w(c, original); }, |
751 static const draw_fn draw_fns[] = { TYPES(M) }; | 710 static const draw_fn draw_fns[] = { TYPES(M) }; |
752 #undef M | 711 #undef M |
753 | 712 |
754 // Ops that implement optimizeFor() or makeThreadsafe() return void from those f
unctions; | 713 #define M(T) [](void* op) { ((T*)op)->makeThreadsafe(); }, |
755 // the (throwing) defaults return int. | |
756 #define M(T) std::is_void<decltype(((T*)nullptr)->optimizeFor(nullptr))>::value
\ | |
757 ? [](void* op, GrContext* ctx) { ((T*)op)->optimizeFor(ctx); } : (grcontext_
fn)nullptr, | |
758 static const grcontext_fn optimize_for_fns[] = { TYPES(M) }; | |
759 #undef M | |
760 | |
761 #define M(T) std::is_void<decltype(((T*)nullptr)->makeThreadsafe())>::value \ | |
762 ? [](void* op) { ((T*)op)->makeThreadsafe(); } : (void_fn)nullptr, | |
763 static const void_fn make_threadsafe_fns[] = { TYPES(M) }; | 714 static const void_fn make_threadsafe_fns[] = { TYPES(M) }; |
764 #undef M | 715 #undef M |
765 | 716 |
766 // Older libstdc++ has pre-standard std::has_trivial_destructor. | 717 // Older libstdc++ has pre-standard std::has_trivial_destructor. |
767 #if defined(__GLIBCXX__) && (__GLIBCXX__ < 20130000) | 718 #if defined(__GLIBCXX__) && (__GLIBCXX__ < 20130000) |
768 template <typename T> using can_skip_destructor = std::has_trivial_destructo
r<T>; | 719 template <typename T> using can_skip_destructor = std::has_trivial_destructo
r<T>; |
769 #else | 720 #else |
770 template <typename T> using can_skip_destructor = std::is_trivially_destruct
ible<T>; | 721 template <typename T> using can_skip_destructor = std::is_trivially_destruct
ible<T>; |
771 #endif | 722 #endif |
772 | 723 |
773 // Most state ops (matrix, clip, save, restore) have a trivial destructor. | 724 // Most state ops (matrix, clip, save, restore) have a trivial destructor. |
774 #define M(T) !can_skip_destructor<T>::value ? [](void* op) { ((T*)op)->~T(); } :
(void_fn)nullptr, | 725 #define M(T) !can_skip_destructor<T>::value ? [](void* op) { ((T*)op)->~T(); } :
(void_fn)nullptr, |
775 static const void_fn dtor_fns[] = { TYPES(M) }; | 726 static const void_fn dtor_fns[] = { TYPES(M) }; |
776 #undef M | 727 #undef M |
777 | 728 |
778 void SkLiteDL::onDraw(SkCanvas* canvas) { | 729 void SkLiteDL::onDraw(SkCanvas* canvas) { this->map(draw_fns, canvas, canvas->ge
tTotalMatrix()); } |
779 SkMatrix original = canvas->getTotalMatrix(); | 730 void SkLiteDL::makeThreadsafe() { this->map(make_threadsafe_fns); } |
780 this->map(draw_fns, canvas, original); | |
781 } | |
782 void SkLiteDL::optimizeFor (GrContext* ctx) { this->map(optimize_for_fns, ctx)
; } | |
783 void SkLiteDL::makeThreadsafe() { this->map(make_threadsafe_fns);
} | |
784 | 731 |
785 SkRect SkLiteDL::onGetBounds() { | 732 SkRect SkLiteDL::onGetBounds() { |
786 return fBounds; | 733 return fBounds; |
787 } | 734 } |
788 | 735 |
789 SkLiteDL:: SkLiteDL(SkRect bounds) : fUsed(0), fReserved(0), fBounds(bounds) {} | 736 SkLiteDL:: SkLiteDL(SkRect bounds) : fUsed(0), fReserved(0), fBounds(bounds) {} |
790 | 737 |
791 SkLiteDL::~SkLiteDL() { | 738 SkLiteDL::~SkLiteDL() { |
792 this->reset(SkRect::MakeEmpty()); | 739 this->reset(SkRect::MakeEmpty()); |
793 } | 740 } |
794 | 741 |
795 sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) { | 742 sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) { |
796 return sk_sp<SkLiteDL>(new SkLiteDL(bounds)); | 743 return sk_sp<SkLiteDL>(new SkLiteDL(bounds)); |
797 } | 744 } |
798 | 745 |
799 void SkLiteDL::reset(SkRect bounds) { | 746 void SkLiteDL::reset(SkRect bounds) { |
800 SkASSERT(this->unique()); | 747 SkASSERT(this->unique()); |
801 this->map(dtor_fns); | 748 this->map(dtor_fns); |
802 | 749 |
803 // Leave fBytes and fReserved alone. | 750 // Leave fBytes and fReserved alone. |
804 fUsed = 0; | 751 fUsed = 0; |
805 fBounds = bounds; | 752 fBounds = bounds; |
806 } | 753 } |
OLD | NEW |