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" |
11 #include "SkLiteDL.h" | 11 #include "SkLiteDL.h" |
12 #include "SkPicture.h" | 12 #include "SkPicture.h" |
13 #include "SkMutex.h" | 13 #include "SkMutex.h" |
14 #include "SkRSXform.h" | 14 #include "SkRSXform.h" |
15 #include "SkSpinlock.h" | 15 #include "SkSpinlock.h" |
16 #include "SkTextBlob.h" | 16 #include "SkTextBlob.h" |
17 | 17 |
18 // TODO: make sure DrawPosText and DrawPosTextH positions are aligned | |
19 // (move the text after the positions). | |
20 | |
21 // A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLa
yer(). | 18 // A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLa
yer(). |
22 static const SkRect kUnset = {SK_ScalarInfinity, 0,0,0}; | 19 static const SkRect kUnset = {SK_ScalarInfinity, 0,0,0}; |
23 static const SkRect* maybe_unset(const SkRect& r) { | 20 static const SkRect* maybe_unset(const SkRect& r) { |
24 return r.left() == SK_ScalarInfinity ? nullptr : &r; | 21 return r.left() == SK_ScalarInfinity ? nullptr : &r; |
25 } | 22 } |
26 | 23 |
27 // memcpy_v(dst, src,bytes, src,bytes, ...) copies an arbitrary number of srcs i
nto dst. | 24 // copy_v(dst, src,n, src,n, ...) copies an arbitrary number of typed srcs into
dst. |
28 static void memcpy_v(void* dst) {} | 25 static void copy_v(void* dst) {} |
29 | 26 |
30 template <typename... Rest> | 27 template <typename S, typename... Rest> |
31 static void memcpy_v(void* dst, const void* src, size_t bytes, Rest&&... rest) { | 28 static void copy_v(void* dst, const S* src, int n, Rest&&... rest) { |
32 sk_careful_memcpy(dst, src, bytes); | 29 SkASSERTF(((uintptr_t)dst & (alignof(S)-1)) == 0, |
33 memcpy_v(SkTAddOffset<void>(dst, bytes), std::forward<Rest>(rest)...); | 30 "Expected %p to be aligned for at least %zu bytes.", dst, alignof(
S)); |
| 31 sk_careful_memcpy(dst, src, n*sizeof(S)); |
| 32 copy_v(SkTAddOffset<void>(dst, n*sizeof(S)), std::forward<Rest>(rest)...); |
34 } | 33 } |
35 | 34 |
36 // Helper for getting back at arrays which have been memcpy_v'd together after a
n Op. | 35 // Helper for getting back at arrays which have been copy_v'd together after an
Op. |
37 template <typename D, typename T> | 36 template <typename D, typename T> |
38 static D* pod(T* op, size_t offset = 0) { | 37 static D* pod(T* op, size_t offset = 0) { |
39 return SkTAddOffset<D>(op+1, offset); | 38 return SkTAddOffset<D>(op+1, offset); |
40 } | 39 } |
41 | 40 |
42 // Convert images and image-based shaders to textures. | 41 // Convert images and image-based shaders to textures. |
43 static void optimize_for(GrContext* ctx, SkPaint* paint, sk_sp<const SkImage>* i
mage = nullptr) { | 42 static void optimize_for(GrContext* ctx, SkPaint* paint, sk_sp<const SkImage>* i
mage = nullptr) { |
44 SkMatrix matrix; | 43 SkMatrix matrix; |
45 SkShader::TileMode xy[2]; | 44 SkShader::TileMode xy[2]; |
46 if (auto shader = paint->getShader()) | 45 if (auto shader = paint->getShader()) |
47 if (auto image = shader->isAImage(&matrix, xy)) { // TODO: compose shaders
, etc. | 46 if (auto image = shader->isAImage(&matrix, xy)) { // TODO: compose shaders
, etc. |
48 paint->setShader(image->makeTextureImage(ctx)->makeShader(xy[0], xy[1],
&matrix)); | 47 paint->setShader(image->makeTextureImage(ctx)->makeShader(xy[0], xy[1],
&matrix)); |
49 } | 48 } |
50 | 49 |
51 if (image) { | 50 if (image) { |
52 *image = (*image)->makeTextureImage(ctx); | 51 *image = (*image)->makeTextureImage(ctx); |
53 } | 52 } |
54 } | 53 } |
55 | 54 |
| 55 // Pre-cache lazy non-threadsafe fields on SkPath and/or SkMatrix. |
| 56 static void make_threadsafe(SkPath* path, SkMatrix* matrix) { |
| 57 if (path) { path->updateBoundsCache(); } |
| 58 if (matrix) { (void)matrix->getType(); } |
| 59 } |
| 60 |
56 namespace { | 61 namespace { |
57 struct Op { | 62 struct Op { |
58 virtual ~Op() {} | 63 virtual ~Op() {} |
59 virtual void draw(SkCanvas*) = 0; | 64 virtual void draw(SkCanvas*) = 0; |
60 virtual void optimizeFor(GrContext*) {} | 65 virtual void optimizeFor(GrContext*) {} |
| 66 virtual void makeThreadsafe() {} |
61 | 67 |
62 size_t skip; | 68 size_t skip; |
63 }; | 69 }; |
64 | 70 |
65 struct Save final : Op { void draw(SkCanvas* c) override { c-> save();
} }; | 71 struct Save final : Op { void draw(SkCanvas* c) override { c-> save();
} }; |
66 struct Restore final : Op { void draw(SkCanvas* c) override { c->restore();
} }; | 72 struct Restore final : Op { void draw(SkCanvas* c) override { c->restore();
} }; |
67 struct SaveLayer final : Op { | 73 struct SaveLayer final : Op { |
68 SaveLayer(const SkRect* bounds, const SkPaint* paint, | 74 SaveLayer(const SkRect* bounds, const SkPaint* paint, |
69 const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags)
{ | 75 const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags)
{ |
70 if (bounds) { this->bounds = *bounds; } | 76 if (bounds) { this->bounds = *bounds; } |
71 if (paint) { this->paint = *paint; } | 77 if (paint) { this->paint = *paint; } |
72 this->backdrop = sk_ref_sp(backdrop); | 78 this->backdrop = sk_ref_sp(backdrop); |
73 this->flags = flags; | 79 this->flags = flags; |
74 } | 80 } |
75 SkRect bounds = kUnset; | 81 SkRect bounds = kUnset; |
76 SkPaint paint; | 82 SkPaint paint; |
77 sk_sp<const SkImageFilter> backdrop; | 83 sk_sp<const SkImageFilter> backdrop; |
78 SkCanvas::SaveLayerFlags flags; | 84 SkCanvas::SaveLayerFlags flags; |
79 void draw(SkCanvas* c) override { | 85 void draw(SkCanvas* c) override { |
80 c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags })
; | 86 c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags })
; |
81 } | 87 } |
82 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 88 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
83 }; | 89 }; |
84 | 90 |
85 struct Concat final : Op { | 91 struct Concat final : Op { |
86 Concat(const SkMatrix& matrix) : matrix(matrix) {} | 92 Concat(const SkMatrix& matrix) : matrix(matrix) {} |
87 SkMatrix matrix; | 93 SkMatrix matrix; |
88 void draw(SkCanvas* c) override { c->concat(matrix); } | 94 void draw(SkCanvas* c) override { c->concat(matrix); } |
| 95 void makeThreadsafe() override { make_threadsafe(nullptr, &matrix); } |
89 }; | 96 }; |
90 struct SetMatrix final : Op { | 97 struct SetMatrix final : Op { |
91 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {} | 98 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {} |
92 SkMatrix matrix; | 99 SkMatrix matrix; |
93 void draw(SkCanvas* c) override { c->setMatrix(matrix); } | 100 void draw(SkCanvas* c) override { c->setMatrix(matrix); } |
| 101 void makeThreadsafe() override { make_threadsafe(nullptr, &matrix); } |
94 }; | 102 }; |
95 struct TranslateZ final : Op { | 103 struct TranslateZ final : Op { |
96 TranslateZ(SkScalar dz) : dz(dz) {} | 104 TranslateZ(SkScalar dz) : dz(dz) {} |
97 SkScalar dz; | 105 SkScalar dz; |
98 void draw(SkCanvas* c) override { | 106 void draw(SkCanvas* c) override { |
99 #ifdef SK_EXPERIMENTAL_SHADOWING | 107 #ifdef SK_EXPERIMENTAL_SHADOWING |
100 c->translateZ(dz); | 108 c->translateZ(dz); |
101 #endif | 109 #endif |
102 } | 110 } |
103 }; | 111 }; |
104 | 112 |
105 struct ClipPath final : Op { | 113 struct ClipPath final : Op { |
106 ClipPath(const SkPath& path, SkRegion::Op op, bool aa) : path(path), op(
op), aa(aa) {} | 114 ClipPath(const SkPath& path, SkRegion::Op op, bool aa) : path(path), op(
op), aa(aa) {} |
107 SkPath path; | 115 SkPath path; |
108 SkRegion::Op op; | 116 SkRegion::Op op; |
109 bool aa; | 117 bool aa; |
110 void draw(SkCanvas* c) override { c->clipPath(path, op, aa); } | 118 void draw(SkCanvas* c) override { c->clipPath(path, op, aa); } |
| 119 void makeThreadsafe() override { make_threadsafe(&path, nullptr); } |
111 }; | 120 }; |
112 struct ClipRect final : Op { | 121 struct ClipRect final : Op { |
113 ClipRect(const SkRect& rect, SkRegion::Op op, bool aa) : rect(rect), op(
op), aa(aa) {} | 122 ClipRect(const SkRect& rect, SkRegion::Op op, bool aa) : rect(rect), op(
op), aa(aa) {} |
114 SkRect rect; | 123 SkRect rect; |
115 SkRegion::Op op; | 124 SkRegion::Op op; |
116 bool aa; | 125 bool aa; |
117 void draw(SkCanvas* c) override { c->clipRect(rect, op, aa); } | 126 void draw(SkCanvas* c) override { c->clipRect(rect, op, aa); } |
118 }; | 127 }; |
119 struct ClipRRect final : Op { | 128 struct ClipRRect final : Op { |
120 ClipRRect(const SkRRect& rrect, SkRegion::Op op, bool aa) : rrect(rrect)
, op(op), aa(aa) {} | 129 ClipRRect(const SkRRect& rrect, SkRegion::Op op, bool aa) : rrect(rrect)
, op(op), aa(aa) {} |
(...skipping 14 matching lines...) Expand all Loading... |
135 SkPaint paint; | 144 SkPaint paint; |
136 void draw(SkCanvas* c) override { c->drawPaint(paint); } | 145 void draw(SkCanvas* c) override { c->drawPaint(paint); } |
137 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 146 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
138 }; | 147 }; |
139 struct DrawPath final : Op { | 148 struct DrawPath final : Op { |
140 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
aint) {} | 149 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
aint) {} |
141 SkPath path; | 150 SkPath path; |
142 SkPaint paint; | 151 SkPaint paint; |
143 void draw(SkCanvas* c) override { c->drawPath(path, paint); } | 152 void draw(SkCanvas* c) override { c->drawPath(path, paint); } |
144 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 153 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 154 void makeThreadsafe() override { make_threadsafe(&path, nullptr); } |
145 }; | 155 }; |
146 struct DrawRect final : Op { | 156 struct DrawRect final : Op { |
147 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
aint) {} | 157 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
aint) {} |
148 SkRect rect; | 158 SkRect rect; |
149 SkPaint paint; | 159 SkPaint paint; |
150 void draw(SkCanvas* c) override { c->drawRect(rect, paint); } | 160 void draw(SkCanvas* c) override { c->drawRect(rect, paint); } |
151 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 161 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
152 }; | 162 }; |
153 struct DrawOval final : Op { | 163 struct DrawOval final : Op { |
154 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(p
aint) {} | 164 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(p
aint) {} |
(...skipping 21 matching lines...) Expand all Loading... |
176 struct DrawAnnotation final : Op { | 186 struct DrawAnnotation final : Op { |
177 DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk
_ref_sp(value)) {} | 187 DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk
_ref_sp(value)) {} |
178 SkRect rect; | 188 SkRect rect; |
179 sk_sp<SkData> value; | 189 sk_sp<SkData> value; |
180 void draw(SkCanvas* c) override { c->drawAnnotation(rect, pod<char>(this
), value.get()); } | 190 void draw(SkCanvas* c) override { c->drawAnnotation(rect, pod<char>(this
), value.get()); } |
181 }; | 191 }; |
182 struct DrawDrawable final : Op { | 192 struct DrawDrawable final : Op { |
183 DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk
_ref_sp(drawable)) { | 193 DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk
_ref_sp(drawable)) { |
184 if (matrix) { this->matrix = *matrix; } | 194 if (matrix) { this->matrix = *matrix; } |
185 } | 195 } |
186 sk_sp<SkDrawable> drawable; | 196 sk_sp<SkDrawable> drawable; |
187 SkMatrix matrix = SkMatrix::I(); | 197 sk_sp<const SkPicture> snapped; |
188 void draw(SkCanvas* c) override { c->drawDrawable(drawable.get(), &matri
x); } | 198 SkMatrix matrix = SkMatrix::I(); |
| 199 void draw(SkCanvas* c) override { |
| 200 snapped ? c->drawPicture(snapped.get(), &matrix, nullptr) |
| 201 : c->drawDrawable(drawable.get(), &matrix); |
| 202 } |
| 203 void makeThreadsafe() override { |
| 204 snapped.reset(drawable->newPictureSnapshot()); |
| 205 make_threadsafe(nullptr, &matrix); |
| 206 } |
189 }; | 207 }; |
190 struct DrawPicture final : Op { | 208 struct DrawPicture final : Op { |
191 DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPa
int* paint) | 209 DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPa
int* paint) |
192 : picture(sk_ref_sp(picture)) { | 210 : picture(sk_ref_sp(picture)) { |
193 if (matrix) { this->matrix = *matrix; } | 211 if (matrix) { this->matrix = *matrix; } |
194 if (paint) { this->paint = *paint; } | 212 if (paint) { this->paint = *paint; has_paint = true; } |
195 } | 213 } |
196 sk_sp<const SkPicture> picture; | 214 sk_sp<const SkPicture> picture; |
197 SkMatrix matrix = SkMatrix::I(); | 215 SkMatrix matrix = SkMatrix::I(); |
198 SkPaint paint; | 216 SkPaint paint; |
199 void draw(SkCanvas* c) override { c->drawPicture(picture.get(), &matrix,
&paint); } | 217 bool has_paint = false; // TODO: why is a default pai
nt not the same? |
| 218 void draw(SkCanvas* c) override { |
| 219 c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr)
; |
| 220 } |
200 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 221 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 222 void makeThreadsafe() override { make_threadsafe(nullptr, &matrix); } |
201 }; | 223 }; |
202 struct DrawShadowedPicture final : Op { | 224 struct DrawShadowedPicture final : Op { |
203 DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, co
nst SkPaint* paint) | 225 DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, co
nst SkPaint* paint) |
204 : picture(sk_ref_sp(picture)) { | 226 : picture(sk_ref_sp(picture)) { |
205 if (matrix) { this->matrix = *matrix; } | 227 if (matrix) { this->matrix = *matrix; } |
206 if (paint) { this->paint = *paint; } | 228 if (paint) { this->paint = *paint; } |
207 } | 229 } |
208 sk_sp<const SkPicture> picture; | 230 sk_sp<const SkPicture> picture; |
209 SkMatrix matrix = SkMatrix::I(); | 231 SkMatrix matrix = SkMatrix::I(); |
210 SkPaint paint; | 232 SkPaint paint; |
211 void draw(SkCanvas* c) override { | 233 void draw(SkCanvas* c) override { |
212 #ifdef SK_EXPERIMENTAL_SHADOWING | 234 #ifdef SK_EXPERIMENTAL_SHADOWING |
213 c->drawShadowedPicture(picture.get(), &matrix, &paint); | 235 c->drawShadowedPicture(picture.get(), &matrix, &paint); |
214 #endif | 236 #endif |
215 } | 237 } |
216 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 238 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 239 void makeThreadsafe() override { make_threadsafe(nullptr, &matrix); } |
217 }; | 240 }; |
218 | 241 |
219 struct DrawImage final : Op { | 242 struct DrawImage final : Op { |
220 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const Sk
Paint* paint) | 243 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const Sk
Paint* paint) |
221 : image(image), x(x), y(y) { | 244 : image(image), x(x), y(y) { |
222 if (paint) { this->paint = *paint; } | 245 if (paint) { this->paint = *paint; } |
223 } | 246 } |
224 sk_sp<const SkImage> image; | 247 sk_sp<const SkImage> image; |
225 SkScalar x,y; | 248 SkScalar x,y; |
226 SkPaint paint; | 249 SkPaint paint; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 struct DrawText final : Op { | 300 struct DrawText final : Op { |
278 DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) | 301 DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) |
279 : bytes(bytes), x(x), y(y), paint(paint) {} | 302 : bytes(bytes), x(x), y(y), paint(paint) {} |
280 size_t bytes; | 303 size_t bytes; |
281 SkScalar x,y; | 304 SkScalar x,y; |
282 SkPaint paint; | 305 SkPaint paint; |
283 void draw(SkCanvas* c) override { c->drawText(pod<void>(this), bytes, x,
y, paint); } | 306 void draw(SkCanvas* c) override { c->drawText(pod<void>(this), bytes, x,
y, paint); } |
284 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 307 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
285 }; | 308 }; |
286 struct DrawPosText final : Op { | 309 struct DrawPosText final : Op { |
287 DrawPosText(size_t bytes, const SkPaint& paint) | 310 DrawPosText(size_t bytes, const SkPaint& paint, int n) |
288 : bytes(bytes), paint(paint) {} | 311 : bytes(bytes), paint(paint), n(n) {} |
289 size_t bytes; | 312 size_t bytes; |
290 SkPaint paint; | 313 SkPaint paint; |
| 314 int n; |
291 void draw(SkCanvas* c) override { | 315 void draw(SkCanvas* c) override { |
292 c->drawPosText(pod<void>(this), bytes, pod<SkPoint>(this, bytes), pa
int); | 316 auto points = pod<SkPoint>(this); |
| 317 auto text = pod<void>(this, n*sizeof(SkPoint)); |
| 318 c->drawPosText(text, bytes, points, paint); |
293 } | 319 } |
294 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 320 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
295 }; | 321 }; |
296 struct DrawPosTextH final : Op { | 322 struct DrawPosTextH final : Op { |
297 DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint) | 323 DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint, int n) |
298 : bytes(bytes), y(y), paint(paint) {} | 324 : bytes(bytes), y(y), paint(paint), n(n) {} |
299 size_t bytes; | 325 size_t bytes; |
300 SkScalar y; | 326 SkScalar y; |
301 SkPaint paint; | 327 SkPaint paint; |
| 328 int n; |
302 void draw(SkCanvas* c) override { | 329 void draw(SkCanvas* c) override { |
303 c->drawPosTextH(pod<void>(this), bytes, pod<SkScalar>(this, bytes),
y, paint); | 330 auto xs = pod<SkScalar>(this); |
| 331 auto text = pod<void>(this, n*sizeof(SkScalar)); |
| 332 c->drawPosTextH(text, bytes, xs, y, paint); |
304 } | 333 } |
305 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 334 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
306 }; | 335 }; |
307 struct DrawTextOnPath final : Op { | 336 struct DrawTextOnPath final : Op { |
308 DrawTextOnPath(size_t bytes, const SkPath& path, | 337 DrawTextOnPath(size_t bytes, const SkPath& path, |
309 const SkMatrix* matrix, const SkPaint& paint) | 338 const SkMatrix* matrix, const SkPaint& paint) |
310 : bytes(bytes), path(path), paint(paint) { | 339 : bytes(bytes), path(path), paint(paint) { |
311 if (matrix) { this->matrix = *matrix; } | 340 if (matrix) { this->matrix = *matrix; } |
312 } | 341 } |
313 size_t bytes; | 342 size_t bytes; |
314 SkPath path; | 343 SkPath path; |
315 SkMatrix matrix = SkMatrix::I(); | 344 SkMatrix matrix = SkMatrix::I(); |
316 SkPaint paint; | 345 SkPaint paint; |
317 void draw(SkCanvas* c) override { | 346 void draw(SkCanvas* c) override { |
318 c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint); | 347 c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint); |
319 } | 348 } |
320 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 349 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 350 void makeThreadsafe() override { make_threadsafe(&path, &matrix); } |
321 }; | 351 }; |
322 struct DrawTextRSXform final : Op { | 352 struct DrawTextRSXform final : Op { |
323 DrawTextRSXform(size_t bytes, const SkRect* cull, const SkPaint& paint) | 353 DrawTextRSXform(size_t bytes, const SkRect* cull, const SkPaint& paint) |
324 : bytes(bytes), paint(paint) { | 354 : bytes(bytes), paint(paint) { |
325 if (cull) { this->cull = *cull; } | 355 if (cull) { this->cull = *cull; } |
326 } | 356 } |
327 size_t bytes; | 357 size_t bytes; |
328 SkRect cull = kUnset; | 358 SkRect cull = kUnset; |
329 SkPaint paint; | 359 SkPaint paint; |
330 void draw(SkCanvas* c) override { | 360 void draw(SkCanvas* c) override { |
331 c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, byte
s), | 361 c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, byte
s), |
332 maybe_unset(cull), paint); | 362 maybe_unset(cull), paint); |
333 } | 363 } |
334 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 364 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
335 }; | 365 }; |
336 struct DrawTextBlob final : Op { | 366 struct DrawTextBlob final : Op { |
337 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPai
nt& paint) | 367 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPai
nt& paint) |
338 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {} | 368 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {} |
339 sk_sp<const SkTextBlob> blob; | 369 sk_sp<const SkTextBlob> blob; |
340 SkScalar x,y; | 370 SkScalar x,y; |
341 SkPaint paint; | 371 SkPaint paint; |
342 void draw(SkCanvas* c) override { c->drawTextBlob(blob.get(), x,y, paint
); } | 372 void draw(SkCanvas* c) override { c->drawTextBlob(blob.get(), x,y, paint
); } |
343 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 373 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
344 }; | 374 }; |
345 | 375 |
| 376 struct DrawPatch final : Op { |
| 377 DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoi
nt texs[4], |
| 378 SkXfermode* xfermode, const SkPaint& paint) |
| 379 : xfermode(sk_ref_sp(xfermode)), paint(paint) { |
| 380 copy_v(this->cubics, cubics, 12); |
| 381 if (colors) { copy_v(this->colors, colors, 4); has_colors = true; } |
| 382 if (texs ) { copy_v(this->texs , texs , 4); has_texs = true; } |
| 383 } |
| 384 SkPoint cubics[12]; |
| 385 SkColor colors[4]; |
| 386 SkPoint texs[4]; |
| 387 sk_sp<SkXfermode> xfermode; |
| 388 SkPaint paint; |
| 389 bool has_colors = false; |
| 390 bool has_texs = false; |
| 391 void draw(SkCanvas* c) override { |
| 392 c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs
: nullptr, |
| 393 xfermode.get(), paint); |
| 394 } |
| 395 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 396 }; |
346 struct DrawPoints final : Op { | 397 struct DrawPoints final : Op { |
347 DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint) | 398 DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint) |
348 : mode(mode), count(count), paint(paint) {} | 399 : mode(mode), count(count), paint(paint) {} |
349 SkCanvas::PointMode mode; | 400 SkCanvas::PointMode mode; |
350 size_t count; | 401 size_t count; |
351 SkPaint paint; | 402 SkPaint paint; |
352 void draw(SkCanvas* c) override { c->drawPoints(mode, count, pod<SkPoint
>(this), paint); } | 403 void draw(SkCanvas* c) override { c->drawPoints(mode, count, pod<SkPoint
>(this), paint); } |
353 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } | 404 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
354 }; | 405 }; |
| 406 struct DrawVertices final : Op { |
| 407 DrawVertices(SkCanvas::VertexMode mode, int count, SkXfermode* xfermode,
int nindices, |
| 408 const SkPaint& paint, bool has_texs, bool has_colors, bool
has_indices) |
| 409 : mode(mode), count(count), xfermode(sk_ref_sp(xfermode)), nindices(
nindices) |
| 410 , paint(paint), has_texs(has_texs), has_colors(has_colors), has_indi
ces(has_indices) {} |
| 411 SkCanvas::VertexMode mode; |
| 412 int count; |
| 413 sk_sp<SkXfermode> xfermode; |
| 414 int nindices; |
| 415 SkPaint paint; |
| 416 bool has_texs; |
| 417 bool has_colors; |
| 418 bool has_indices; |
| 419 void draw(SkCanvas* c) override { |
| 420 SkPoint* vertices = pod<SkPoint>(this, 0); |
| 421 size_t offset = count*sizeof(SkPoint); |
| 422 |
| 423 SkPoint* texs = nullptr; |
| 424 if (has_texs) { |
| 425 texs = pod<SkPoint>(this, offset); |
| 426 offset += count*sizeof(SkPoint); |
| 427 } |
| 428 |
| 429 SkColor* colors = nullptr; |
| 430 if (has_colors) { |
| 431 colors = pod<SkColor>(this, offset); |
| 432 offset += count*sizeof(SkColor); |
| 433 } |
| 434 |
| 435 uint16_t* indices = nullptr; |
| 436 if (has_indices) { |
| 437 indices = pod<uint16_t>(this, offset); |
| 438 } |
| 439 c->drawVertices(mode, count, vertices, texs, colors, xfermode.get(), |
| 440 indices, nindices, paint); |
| 441 } |
| 442 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 443 }; |
355 struct DrawAtlas final : Op { | 444 struct DrawAtlas final : Op { |
356 DrawAtlas(const SkImage* atlas, int count, SkXfermode::Mode xfermode, | 445 DrawAtlas(const SkImage* atlas, int count, SkXfermode::Mode xfermode, |
357 const SkRect* cull, const SkPaint* paint, bool has_colors) | 446 const SkRect* cull, const SkPaint* paint, bool has_colors) |
358 : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_col
ors(has_colors) { | 447 : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_col
ors(has_colors) { |
359 if (cull) { this->cull = *cull; } | 448 if (cull) { this->cull = *cull; } |
360 if (paint) { this->paint = *paint; } | 449 if (paint) { this->paint = *paint; } |
361 } | 450 } |
362 sk_sp<const SkImage> atlas; | 451 sk_sp<const SkImage> atlas; |
363 int count; | 452 int count; |
364 SkXfermode::Mode xfermode; | 453 SkXfermode::Mode xfermode; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 void SkLiteDL::drawRRect(const SkRRect& rrect, const SkPaint& paint) { | 524 void SkLiteDL::drawRRect(const SkRRect& rrect, const SkPaint& paint) { |
436 push<DrawRRect>(&fBytes, 0, rrect, paint); | 525 push<DrawRRect>(&fBytes, 0, rrect, paint); |
437 } | 526 } |
438 void SkLiteDL::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPa
int& paint) { | 527 void SkLiteDL::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPa
int& paint) { |
439 push<DrawDRRect>(&fBytes, 0, outer, inner, paint); | 528 push<DrawDRRect>(&fBytes, 0, outer, inner, paint); |
440 } | 529 } |
441 | 530 |
442 void SkLiteDL::drawAnnotation(const SkRect& rect, const char* key, SkData* value
) { | 531 void SkLiteDL::drawAnnotation(const SkRect& rect, const char* key, SkData* value
) { |
443 size_t bytes = strlen(key)+1; | 532 size_t bytes = strlen(key)+1; |
444 void* pod = push<DrawAnnotation>(&fBytes, bytes, rect, value); | 533 void* pod = push<DrawAnnotation>(&fBytes, bytes, rect, value); |
445 memcpy_v(pod, key,bytes); | 534 copy_v(pod, key,bytes); |
446 } | 535 } |
447 void SkLiteDL::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { | 536 void SkLiteDL::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { |
448 push<DrawDrawable>(&fBytes, 0, drawable, matrix); | 537 push<DrawDrawable>(&fBytes, 0, drawable, matrix); |
449 } | 538 } |
450 void SkLiteDL::drawPicture(const SkPicture* picture, | 539 void SkLiteDL::drawPicture(const SkPicture* picture, |
451 const SkMatrix* matrix, const SkPaint* paint) { | 540 const SkMatrix* matrix, const SkPaint* paint) { |
452 push<DrawPicture>(&fBytes, 0, picture, matrix, paint); | 541 push<DrawPicture>(&fBytes, 0, picture, matrix, paint); |
453 } | 542 } |
454 void SkLiteDL::drawShadowedPicture(const SkPicture* picture, | 543 void SkLiteDL::drawShadowedPicture(const SkPicture* picture, |
455 const SkMatrix* matrix, const SkPaint* paint)
{ | 544 const SkMatrix* matrix, const SkPaint* paint)
{ |
(...skipping 21 matching lines...) Expand all Loading... |
477 } | 566 } |
478 void SkLiteDL::drawImageRect(const SkImage* image, const SkRect* src, const SkRe
ct& dst, | 567 void SkLiteDL::drawImageRect(const SkImage* image, const SkRect* src, const SkRe
ct& dst, |
479 const SkPaint* paint, SkCanvas::SrcRectConstraint c
onstraint) { | 568 const SkPaint* paint, SkCanvas::SrcRectConstraint c
onstraint) { |
480 push<DrawImageRect>(&fBytes, 0, sk_ref_sp(image), src, dst, paint, constrain
t); | 569 push<DrawImageRect>(&fBytes, 0, sk_ref_sp(image), src, dst, paint, constrain
t); |
481 } | 570 } |
482 void SkLiteDL::drawImageLattice(const SkImage* image, const SkCanvas::Lattice& l
attice, | 571 void SkLiteDL::drawImageLattice(const SkImage* image, const SkCanvas::Lattice& l
attice, |
483 const SkRect& dst, const SkPaint* paint) { | 572 const SkRect& dst, const SkPaint* paint) { |
484 int xs = lattice.fXCount, ys = lattice.fYCount; | 573 int xs = lattice.fXCount, ys = lattice.fYCount; |
485 size_t bytes = (xs + ys) * sizeof(int); | 574 size_t bytes = (xs + ys) * sizeof(int); |
486 void* pod = push<DrawImageLattice>(&fBytes, bytes, sk_ref_sp(image), xs, ys,
dst, paint); | 575 void* pod = push<DrawImageLattice>(&fBytes, bytes, sk_ref_sp(image), xs, ys,
dst, paint); |
487 memcpy_v(pod, lattice.fXDivs,xs*sizeof(int), | 576 copy_v(pod, lattice.fXDivs, xs, |
488 lattice.fYDivs,ys*sizeof(int)); | 577 lattice.fYDivs, ys); |
489 } | 578 } |
490 | 579 |
491 void SkLiteDL::drawText(const void* text, size_t bytes, | 580 void SkLiteDL::drawText(const void* text, size_t bytes, |
492 SkScalar x, SkScalar y, const SkPaint& paint) { | 581 SkScalar x, SkScalar y, const SkPaint& paint) { |
493 void* pod = push<DrawText>(&fBytes, bytes, bytes, x, y, paint); | 582 void* pod = push<DrawText>(&fBytes, bytes, bytes, x, y, paint); |
494 memcpy_v(pod, text,bytes); | 583 copy_v(pod, (const char*)text,bytes); |
495 } | 584 } |
496 void SkLiteDL::drawPosText(const void* text, size_t bytes, | 585 void SkLiteDL::drawPosText(const void* text, size_t bytes, |
497 const SkPoint pos[], const SkPaint& paint) { | 586 const SkPoint pos[], const SkPaint& paint) { |
498 int n = paint.countText(text, bytes); | 587 int n = paint.countText(text, bytes); |
499 void* pod = push<DrawPosText>(&fBytes, bytes+n*sizeof(SkPoint), bytes, paint
); | 588 void* pod = push<DrawPosText>(&fBytes, n*sizeof(SkPoint)+bytes, bytes, paint
, n); |
500 memcpy_v(pod, text,bytes, pos,n*sizeof(SkPoint)); | 589 copy_v(pod, pos,n, (const char*)text,bytes); |
501 } | 590 } |
502 void SkLiteDL::drawPosTextH(const void* text, size_t bytes, | 591 void SkLiteDL::drawPosTextH(const void* text, size_t bytes, |
503 const SkScalar xs[], SkScalar y, const SkPaint& paint
) { | 592 const SkScalar xs[], SkScalar y, const SkPaint& paint
) { |
504 int n = paint.countText(text, bytes); | 593 int n = paint.countText(text, bytes); |
505 void* pod = push<DrawPosTextH>(&fBytes, bytes+n*sizeof(SkScalar), bytes, y,
paint); | 594 void* pod = push<DrawPosTextH>(&fBytes, n*sizeof(SkScalar)+bytes, bytes, y,
paint, n); |
506 memcpy_v(pod, text,bytes, xs,n*sizeof(SkScalar)); | 595 copy_v(pod, xs,n, (const char*)text,bytes); |
507 } | 596 } |
508 void SkLiteDL::drawTextOnPath(const void* text, size_t bytes, | 597 void SkLiteDL::drawTextOnPath(const void* text, size_t bytes, |
509 const SkPath& path, const SkMatrix* matrix, const
SkPaint& paint) { | 598 const SkPath& path, const SkMatrix* matrix, const
SkPaint& paint) { |
510 void* pod = push<DrawTextOnPath>(&fBytes, bytes, bytes, path, matrix, paint)
; | 599 void* pod = push<DrawTextOnPath>(&fBytes, bytes, bytes, path, matrix, paint)
; |
511 memcpy_v(pod, text,bytes); | 600 copy_v(pod, (const char*)text,bytes); |
512 } | 601 } |
513 void SkLiteDL::drawTextRSXform(const void* text, size_t bytes, | 602 void SkLiteDL::drawTextRSXform(const void* text, size_t bytes, |
514 const SkRSXform xforms[], const SkRect* cull, con
st SkPaint& paint) { | 603 const SkRSXform xforms[], const SkRect* cull, con
st SkPaint& paint) { |
515 int n = paint.countText(text, bytes); | 604 int n = paint.countText(text, bytes); |
516 void* pod = push<DrawTextRSXform>(&fBytes, bytes+n*sizeof(SkRSXform), bytes,
cull, paint); | 605 void* pod = push<DrawTextRSXform>(&fBytes, bytes+n*sizeof(SkRSXform), bytes,
cull, paint); |
517 memcpy_v(pod, text,bytes, xforms,n*sizeof(SkRSXform)); | 606 copy_v(pod, (const char*)text,bytes, xforms,n); |
518 } | 607 } |
519 void SkLiteDL::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, cons
t SkPaint& paint) { | 608 void SkLiteDL::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, cons
t SkPaint& paint) { |
520 push<DrawTextBlob>(&fBytes, 0, blob, x,y, paint); | 609 push<DrawTextBlob>(&fBytes, 0, blob, x,y, paint); |
521 } | 610 } |
522 | 611 |
| 612 void SkLiteDL::drawPatch(const SkPoint points[12], const SkColor colors[4], cons
t SkPoint texs[4], |
| 613 SkXfermode* xfermode, const SkPaint& paint) { |
| 614 push<DrawPatch>(&fBytes, 0, points, colors, texs, xfermode, paint); |
| 615 } |
523 void SkLiteDL::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint
points[], | 616 void SkLiteDL::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint
points[], |
524 const SkPaint& paint) { | 617 const SkPaint& paint) { |
525 void* pod = push<DrawPoints>(&fBytes, count*sizeof(SkPoint), mode, count, pa
int); | 618 void* pod = push<DrawPoints>(&fBytes, count*sizeof(SkPoint), mode, count, pa
int); |
526 memcpy_v(pod, points,count*sizeof(SkPoint)); | 619 copy_v(pod, points,count); |
| 620 } |
| 621 void SkLiteDL::drawVertices(SkCanvas::VertexMode mode, int count, const SkPoint
vertices[], |
| 622 const SkPoint texs[], const SkColor colors[], SkXfer
mode* xfermode, |
| 623 const uint16_t indices[], int nindices, const SkPain
t& paint) { |
| 624 size_t bytes = count * sizeof(SkPoint); |
| 625 if (texs ) { bytes += count * sizeof(SkPoint); } |
| 626 if (colors) { bytes += count * sizeof(SkColor); } |
| 627 if (indices) { bytes += nindices * sizeof(uint16_t); } |
| 628 void* pod = push<DrawVertices>(&fBytes, bytes, mode, count, xfermode, nindic
es, paint, |
| 629 texs != nullptr, colors != nullptr, indices !
= nullptr); |
| 630 copy_v(pod, vertices, count, |
| 631 texs, texs ? count : 0, |
| 632 colors, colors ? count : 0, |
| 633 indices, indices ? nindices : 0); |
527 } | 634 } |
528 void SkLiteDL::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const S
kRect texs[], | 635 void SkLiteDL::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const S
kRect texs[], |
529 const SkColor colors[], int count, SkXfermode::Mode xfe
rmode, | 636 const SkColor colors[], int count, SkXfermode::Mode xfe
rmode, |
530 const SkRect* cull, const SkPaint* paint) { | 637 const SkRect* cull, const SkPaint* paint) { |
531 size_t bytes = count*(sizeof(SkRSXform) + sizeof(SkRect)); | 638 size_t bytes = count*(sizeof(SkRSXform) + sizeof(SkRect)); |
532 if (colors) { | 639 if (colors) { |
533 bytes += count*sizeof(SkColor); | 640 bytes += count*sizeof(SkColor); |
534 } | 641 } |
535 void* pod = push<DrawAtlas>(&fBytes, bytes, | 642 void* pod = push<DrawAtlas>(&fBytes, bytes, |
536 atlas, count, xfermode, cull, paint, colors != n
ullptr); | 643 atlas, count, xfermode, cull, paint, colors != n
ullptr); |
537 memcpy_v(pod, xforms, count*sizeof(SkRSXform), | 644 copy_v(pod, xforms, count, |
538 texs, count*sizeof(SkRect), | 645 texs, count, |
539 colors, colors ? count*sizeof(SkColor) : 0); | 646 colors, colors ? count : 0); |
540 } | 647 } |
541 | 648 |
542 | 649 |
543 void SkLiteDL::onDraw(SkCanvas* canvas) { | 650 void SkLiteDL::onDraw(SkCanvas* canvas) { |
544 map(&fBytes, [canvas](Op* op) { op->draw(canvas); }); | 651 map(&fBytes, [canvas](Op* op) { op->draw(canvas); }); |
545 } | 652 } |
546 | 653 |
547 void SkLiteDL::optimizeFor(GrContext* ctx) { | 654 void SkLiteDL::optimizeFor(GrContext* ctx) { |
548 map(&fBytes, [ctx](Op* op) { op->optimizeFor(ctx); }); | 655 map(&fBytes, [ctx](Op* op) { op->optimizeFor(ctx); }); |
549 } | 656 } |
550 | 657 |
| 658 void SkLiteDL::makeThreadsafe() { |
| 659 map(&fBytes, [](Op* op) { op->makeThreadsafe(); }); |
| 660 } |
| 661 |
551 SkRect SkLiteDL::onGetBounds() { | 662 SkRect SkLiteDL::onGetBounds() { |
552 return fBounds; | 663 return fBounds; |
553 } | 664 } |
554 | 665 |
555 SkLiteDL:: SkLiteDL() {} | 666 SkLiteDL:: SkLiteDL() {} |
556 SkLiteDL::~SkLiteDL() {} | 667 SkLiteDL::~SkLiteDL() {} |
557 | 668 |
558 static const int kFreeStackByteLimit = 128*1024; | 669 static const int kFreeStackByteLimit = 128*1024; |
559 static const int kFreeStackCountLimit = 8; | 670 static const int kFreeStackCountLimit = 8; |
560 | 671 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 if (gFreeStackCount < kFreeStackCountLimit) { | 706 if (gFreeStackCount < kFreeStackCountLimit) { |
596 self->fNext = gFreeStack; | 707 self->fNext = gFreeStack; |
597 gFreeStack = self; | 708 gFreeStack = self; |
598 gFreeStackCount++; | 709 gFreeStackCount++; |
599 return; | 710 return; |
600 } | 711 } |
601 } | 712 } |
602 | 713 |
603 delete this; | 714 delete this; |
604 } | 715 } |
OLD | NEW |