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