Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: skia/ext/cdl_picture_buffer.cc

Issue 2523673004: [NOT FOR COMMIT] Fully replace SkCanvas uses.
Patch Set: Support Android build. Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « skia/ext/cdl_picture_buffer.h ('k') | skia/ext/cdl_picture_recorder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "cdl_picture_buffer.h"
9
10 #if CDL_ENABLED
11
12 #include "base/trace_event/trace_event.h"
13 #include "cdl_canvas.h"
14 #include "cdl_paint.h"
15 #include "cdl_picture.h"
16
17 #include "SkCanvas.h"
18 #include "SkData.h"
19 #include "SkDrawFilter.h"
20 #include "SkImageFilter.h"
21 #include "SkMath.h"
22 #include "SkPicture.h"
23 #include "SkRSXform.h"
24 #include "SkTextBlob.h"
25
26 #ifndef SKLITEDL_PAGE
27 #define SKLITEDL_PAGE 4096
28 #endif
29
30 // A stand-in for an optional SkRect which was not set, e.g. bounds for a
31 // saveLayer().
32 static const SkRect kUnset = {SK_ScalarInfinity, 0, 0, 0};
33 static const SkRect* maybe_unset(const SkRect& r) {
34 return r.left() == SK_ScalarInfinity ? nullptr : &r;
35 }
36
37 // copy_v(dst, src,n, src,n, ...) copies an arbitrary number of typed srcs into
38 // dst.
39 static void copy_v(void* dst) {}
40
41 template <typename S, typename... Rest>
42 static void copy_v(void* dst, const S* src, int n, Rest&&... rest) {
43 SkASSERTF(((uintptr_t)dst & (alignof(S) - 1)) == 0,
44 "Expected %p to be aligned for at least %zu bytes.", dst,
45 alignof(S));
46 sk_careful_memcpy(dst, src, n * sizeof(S));
47 copy_v(SkTAddOffset<void>(dst, n * sizeof(S)), std::forward<Rest>(rest)...);
48 }
49
50 // Helper for getting back at arrays which have been copy_v'd together after an
51 // Op.
52 template <typename D, typename T>
53 static D* pod(T* op, size_t offset = 0) {
54 return SkTAddOffset<D>(op + 1, offset);
55 }
56
57 // Pre-cache lazy non-threadsafe fields on SkPath and/or SkMatrix.
58 static void make_threadsafe(SkPath* path, SkMatrix* matrix) {
59 if (path) {
60 path->updateBoundsCache();
61 }
62 if (matrix) {
63 (void)matrix->getType();
64 }
65 }
66
67 namespace {
68 #define TYPES(M) \
69 M(SetDrawFilter) \
70 M(Save) \
71 M(Restore) \
72 M(SaveLayer) \
73 M(Concat) \
74 M(SetMatrix) \
75 M(Translate) \
76 M(ClipPath) \
77 M(ClipRect) \
78 M(ClipRRect) \
79 M(ClipRegion) \
80 M(DrawPaint) \
81 M(DrawPath) \
82 M(DrawRect) \
83 M(DrawOval) \
84 M(DrawRRect) \
85 M(DrawDRRect) \
86 M(DrawAnnotation) \
87 M(DrawPicture) \
88 M(DrawImage) \
89 M(DrawImageRect) \
90 M(DrawText) \
91 M(DrawPosText) \
92 M(DrawTextBlob) \
93 M(DrawPoints)
94
95 #define M(T) T,
96 enum class Type : uint8_t { TYPES(M) };
97 #undef M
98
99 struct Op {
100 void makeThreadsafe() {}
101
102 uint32_t type : 8;
103 uint32_t skip : 24;
104 };
105 static_assert(sizeof(Op) == 4, "");
106
107 struct SetDrawFilter final : Op {
108 #ifdef SK_SUPPORT_LEGACY_DRAWFILTER
109 static const auto kType = Type::SetDrawFilter;
110 SetDrawFilter(SkDrawFilter* df) : drawFilter(sk_ref_sp(df)) {}
111 sk_sp<SkDrawFilter> drawFilter;
112 #endif
113 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
114 #ifdef SK_SUPPORT_LEGACY_DRAWFILTER
115 c->setDrawFilter(drawFilter.get());
116 #endif
117 }
118 };
119
120 struct Save final : Op {
121 static const auto kType = Type::Save;
122 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
123 c->save();
124 }
125 };
126 struct Restore final : Op {
127 static const auto kType = Type::Restore;
128 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
129 c->restore();
130 }
131 };
132 struct SaveLayer final : Op {
133 static const auto kType = Type::SaveLayer;
134 SaveLayer(const SkRect* bounds,
135 const CdlPaint* paint,
136 const SkImageFilter* backdrop,
137 SkCanvas::SaveLayerFlags flags)
138 : has_paint(false) {
139 if (bounds) {
140 this->bounds = *bounds;
141 }
142 if (paint) {
143 this->paint = *paint;
144 has_paint = true;
145 }
146 this->backdrop = sk_ref_sp(backdrop);
147 this->flags = flags;
148 }
149 SkRect bounds = kUnset;
150 CdlPaint paint;
151 bool has_paint;
152 sk_sp<const SkImageFilter> backdrop;
153 SkCanvas::SaveLayerFlags flags;
154 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
155 c->saveLayer({maybe_unset(bounds), has_paint ? &paint : nullptr,
156 backdrop.get(), flags});
157 }
158 };
159
160 struct Concat final : Op {
161 static const auto kType = Type::Concat;
162 Concat(const SkMatrix& matrix) : matrix(matrix) {}
163 SkMatrix matrix;
164 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
165 c->concat(matrix);
166 }
167 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); }
168 };
169 struct SetMatrix final : Op {
170 static const auto kType = Type::SetMatrix;
171 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {}
172 SkMatrix matrix;
173 void draw(CdlCanvas* c,
174 const SkMatrix& original,
175 CdlPictureBuffer::DrawContext&) {
176 c->setMatrix(SkMatrix::Concat(original, matrix));
177 }
178 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); }
179 };
180 struct Translate final : Op {
181 static const auto kType = Type::Translate;
182 Translate(SkScalar dx, SkScalar dy) : dx(dx), dy(dy) {}
183 SkScalar dx, dy;
184 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
185 c->translate(dx, dy);
186 }
187 };
188
189 struct ClipPath final : Op {
190 static const auto kType = Type::ClipPath;
191 ClipPath(const SkPath& path, SkCanvas::ClipOp op, bool aa)
192 : path(path), op(op), aa(aa) {}
193 SkPath path;
194 SkCanvas::ClipOp op;
195 bool aa;
196 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
197 c->clipPath(path, op, aa);
198 }
199 void makeThreadsafe() { make_threadsafe(&path, nullptr); }
200 };
201 struct ClipRect final : Op {
202 static const auto kType = Type::ClipRect;
203 ClipRect(const SkRect& rect, SkCanvas::ClipOp op, bool aa)
204 : rect(rect), op(op), aa(aa) {}
205 SkRect rect;
206 SkCanvas::ClipOp op;
207 bool aa;
208 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
209 c->clipRect(rect, op, aa);
210 }
211 };
212 struct ClipRRect final : Op {
213 static const auto kType = Type::ClipRRect;
214 ClipRRect(const SkRRect& rrect, SkCanvas::ClipOp op, bool aa)
215 : rrect(rrect), op(op), aa(aa) {}
216 SkRRect rrect;
217 SkCanvas::ClipOp op;
218 bool aa;
219 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
220 c->clipRRect(rrect, op, aa);
221 }
222 };
223 struct ClipRegion final : Op {
224 static const auto kType = Type::ClipRegion;
225 ClipRegion(const SkRegion& region, SkCanvas::ClipOp op)
226 : region(region), op(op) {}
227 SkRegion region;
228 SkCanvas::ClipOp op;
229 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
230 c->clipRegion(region, op);
231 }
232 };
233
234 struct DrawPaint final : Op {
235 static const auto kType = Type::DrawPaint;
236 DrawPaint(const CdlPaint& paint) : paint(paint) {}
237 CdlPaint paint;
238 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
239 c->drawPaint(paint);
240 }
241 };
242 struct DrawPath final : Op {
243 static const auto kType = Type::DrawPath;
244 DrawPath(const SkPath& path, const CdlPaint& paint)
245 : path(path), paint(paint) {}
246 SkPath path;
247 CdlPaint paint;
248 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
249 c->drawPath(path, paint);
250 }
251 void makeThreadsafe() { make_threadsafe(&path, nullptr); }
252 };
253 struct DrawRect final : Op {
254 static const auto kType = Type::DrawRect;
255 DrawRect(const SkRect& rect, const CdlPaint& paint)
256 : rect(rect), paint(paint) {}
257 SkRect rect;
258 CdlPaint paint;
259 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
260 c->drawRect(rect, paint);
261 }
262 };
263
264 struct DrawRRect final : Op {
265 static const auto kType = Type::DrawRRect;
266 DrawRRect(const SkRRect& rrect, const CdlPaint& paint)
267 : rrect(rrect), paint(paint) {}
268 SkRRect rrect;
269 CdlPaint paint;
270 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
271 c->drawRRect(rrect, paint);
272 }
273 };
274 struct DrawDRRect final : Op {
275 static const auto kType = Type::DrawDRRect;
276 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const CdlPaint& paint)
277 : outer(outer), inner(inner), paint(paint) {}
278 SkRRect outer, inner;
279 CdlPaint paint;
280 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
281 c->drawDRRect(outer, inner, paint);
282 }
283 };
284
285 struct DrawOval final : Op {
286 static const auto kType = Type::DrawOval;
287 DrawOval(const SkRect& oval, const CdlPaint& paint)
288 : oval(oval), paint(paint) {}
289 SkRect oval;
290 CdlPaint paint;
291 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
292 c->drawOval(oval, paint);
293 }
294 };
295
296 struct DrawAnnotation final : Op {
297 static const auto kType = Type::DrawAnnotation;
298 DrawAnnotation(const SkRect& rect, SkData* value)
299 : rect(rect), value(sk_ref_sp(value)) {}
300 SkRect rect;
301 sk_sp<SkData> value;
302 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
303 // TODO(cdl)
304 // c->drawAnnotation(rect, pod<char>(this), value.get());
305 }
306 };
307
308 struct DrawPicture final : Op {
309 static const auto kType = Type::DrawPicture;
310 DrawPicture(const CdlPicture* picture,
311 const SkMatrix* matrix,
312 const CdlPaint* paint)
313 : picture(sk_ref_sp(picture)), has_paint(false) {
314 if (matrix) {
315 this->matrix = *matrix;
316 }
317 if (paint) {
318 this->paint = *paint;
319 has_paint = true;
320 }
321 }
322 sk_sp<const CdlPicture> picture;
323 SkMatrix matrix = SkMatrix::I();
324 CdlPaint paint;
325 bool has_paint; // TODO: why is a default paint not the same?
326 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
327 c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr);
328 }
329 void makeThreadsafe() { make_threadsafe(nullptr, &matrix); }
330 };
331
332 struct DrawImage final : Op {
333 static const auto kType = Type::DrawImage;
334 DrawImage(sk_sp<const SkImage>&& image,
335 SkScalar x,
336 SkScalar y,
337 const CdlPaint* paint)
338 : image(std::move(image)), x(x), y(y), has_paint(false) {
339 if (paint) {
340 this->paint = *paint;
341 has_paint = true;
342 }
343 }
344 sk_sp<const SkImage> image;
345 SkScalar x, y;
346 CdlPaint paint;
347 bool has_paint;
348 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
349 c->drawImage(image.get(), x, y, has_paint ? &paint : nullptr);
350 }
351 };
352
353 struct DrawImageRect final : Op {
354 static const auto kType = Type::DrawImageRect;
355 DrawImageRect(sk_sp<const SkImage>&& image,
356 const SkRect* src,
357 const SkRect& dst,
358 const CdlPaint* paint,
359 SkCanvas::SrcRectConstraint constraint)
360 : image(std::move(image)),
361 dst(dst),
362 has_paint(false),
363 constraint(constraint) {
364 this->src = src ? *src : SkRect::MakeIWH(image->width(), image->height());
365 if (paint) {
366 this->paint = *paint;
367 has_paint = true;
368 }
369 }
370 sk_sp<const SkImage> image;
371 SkRect src, dst;
372 CdlPaint paint;
373 bool has_paint;
374 SkCanvas::SrcRectConstraint constraint;
375 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
376 c->drawImageRect(image.get(), src, dst, has_paint ? &paint : nullptr,
377 constraint);
378 }
379 };
380
381 struct DrawText final : Op {
382 static const auto kType = Type::DrawText;
383 DrawText(size_t bytes, SkScalar x, SkScalar y, const CdlPaint& paint)
384 : bytes(bytes), x(x), y(y), paint(paint) {}
385 size_t bytes;
386 SkScalar x, y;
387 CdlPaint paint;
388 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
389 c->drawText(pod<void>(this), bytes, x, y, paint);
390 }
391 };
392 struct DrawPosText final : Op {
393 static const auto kType = Type::DrawPosText;
394 DrawPosText(size_t bytes, const CdlPaint& paint, int n)
395 : bytes(bytes), paint(paint), n(n) {}
396 size_t bytes;
397 CdlPaint paint;
398 int n;
399 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
400 auto points = pod<SkPoint>(this);
401 auto text = pod<void>(this, n * sizeof(SkPoint));
402 c->drawPosText(text, bytes, points, paint);
403 }
404 };
405
406 struct DrawTextBlob final : Op {
407 static const auto kType = Type::DrawTextBlob;
408 DrawTextBlob(const SkTextBlob* blob,
409 SkScalar x,
410 SkScalar y,
411 const CdlPaint& paint)
412 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {}
413 sk_sp<const SkTextBlob> blob;
414 SkScalar x, y;
415 CdlPaint paint;
416 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext& dc) {
417 c->drawTextBlob(blob.get(), x, y, paint);
418 }
419 };
420
421 struct DrawPoints final : Op {
422 static const auto kType = Type::DrawPoints;
423 DrawPoints(SkCanvas::PointMode mode, size_t count, const CdlPaint& paint)
424 : mode(mode), count(count), paint(paint) {}
425 SkCanvas::PointMode mode;
426 size_t count;
427 CdlPaint paint;
428 void draw(CdlCanvas* c, const SkMatrix&, CdlPictureBuffer::DrawContext&) {
429 c->drawPoints(mode, count, pod<SkPoint>(this), paint);
430 }
431 };
432
433 } // anon namespace
434
435 template <typename T, typename... Args>
436 void* CdlPictureBuffer::push(size_t pod, Args&&... args) {
437 size_t skip = SkAlignPtr(sizeof(T) + pod);
438 SkASSERT(skip < (1 << 24));
439 if (fUsed + skip > fReserved) {
440 static_assert(SkIsPow2(SKLITEDL_PAGE),
441 "This math needs updating for non-pow2.");
442 // Next greater multiple of SKLITEDL_PAGE.
443 fReserved = (fUsed + skip + SKLITEDL_PAGE) & ~(SKLITEDL_PAGE - 1);
444 fBytes.realloc(fReserved);
445 }
446 SkASSERT(fUsed + skip <= fReserved);
447 auto op = (T*)(fBytes.get() + fUsed);
448 fUsed += skip;
449 new (op) T{std::forward<Args>(args)...};
450 op->type = (uint32_t)T::kType;
451 op->skip = skip;
452 return op + 1;
453 }
454
455 template <typename Fn, typename... Args>
456 inline void CdlPictureBuffer::map(const Fn fns[],
457 int start_offset,
458 int end_offset,
459 Args... args) {
460 auto start = fBytes.get() + start_offset;
461 auto end = fBytes.get() + end_offset;
462 for (uint8_t* ptr = start; ptr < end;) {
463 auto op = (Op*)ptr;
464 auto type = op->type;
465 auto skip = op->skip;
466 if (auto fn = fns[type]) { // We replace no-op functions with nullptrs
467 fn(op, args...); // to avoid the overhead of a pointless call.
468 }
469 ptr += skip;
470 }
471 }
472
473 #ifdef SK_SUPPORT_LEGACY_DRAWFILTER
474 void CdlPictureBuffer::setDrawFilter(SkDrawFilter* df) {
475 this->push<SetDrawFilter>(0, df);
476 }
477 #endif
478
479 void CdlPictureBuffer::save() {
480 this->push<Save>(0);
481 }
482 void CdlPictureBuffer::restore() {
483 this->push<Restore>(0);
484 }
485 void CdlPictureBuffer::saveLayer(const SkRect* bounds,
486 const CdlPaint* paint,
487 const SkImageFilter* backdrop,
488 SkCanvas::SaveLayerFlags flags) {
489 this->push<SaveLayer>(0, bounds, paint, backdrop, flags);
490 }
491
492 void CdlPictureBuffer::concat(const SkMatrix& matrix) {
493 this->push<Concat>(0, matrix);
494 }
495 void CdlPictureBuffer::setMatrix(const SkMatrix& matrix) {
496 this->push<SetMatrix>(0, matrix);
497 }
498 void CdlPictureBuffer::translate(SkScalar dx, SkScalar dy) {
499 this->push<Translate>(0, dx, dy);
500 }
501
502 void CdlPictureBuffer::clipPath(const SkPath& path,
503 SkCanvas::ClipOp op,
504 bool aa) {
505 this->push<ClipPath>(0, path, op, aa);
506 }
507 void CdlPictureBuffer::clipRect(const SkRect& rect,
508 SkCanvas::ClipOp op,
509 bool aa) {
510 this->push<ClipRect>(0, rect, op, aa);
511 }
512 void CdlPictureBuffer::clipRRect(const SkRRect& rrect,
513 SkCanvas::ClipOp op,
514 bool aa) {
515 this->push<ClipRRect>(0, rrect, op, aa);
516 }
517 void CdlPictureBuffer::clipRegion(const SkRegion& region, SkCanvas::ClipOp op) {
518 this->push<ClipRegion>(0, region, op);
519 }
520
521 void CdlPictureBuffer::drawPaint(const CdlPaint& paint) {
522 this->push<DrawPaint>(0, paint);
523 }
524 void CdlPictureBuffer::drawPath(const SkPath& path, const CdlPaint& paint) {
525 this->push<DrawPath>(0, path, paint);
526 }
527 void CdlPictureBuffer::drawRect(const SkRect& rect, const CdlPaint& paint) {
528 this->push<DrawRect>(0, rect, paint);
529 }
530
531 void CdlPictureBuffer::drawRRect(const SkRRect& rrect, const CdlPaint& paint) {
532 this->push<DrawRRect>(0, rrect, paint);
533 }
534 void CdlPictureBuffer::drawDRRect(const SkRRect& outer,
535 const SkRRect& inner,
536 const CdlPaint& paint) {
537 this->push<DrawDRRect>(0, outer, inner, paint);
538 }
539
540 void CdlPictureBuffer::drawOval(const SkRect& oval, const CdlPaint& paint) {
541 this->push<DrawOval>(0, oval, paint);
542 }
543
544 void CdlPictureBuffer::drawAnnotation(const SkRect& rect,
545 const char* key,
546 SkData* value) {
547 size_t bytes = strlen(key) + 1;
548 void* pod = this->push<DrawAnnotation>(bytes, rect, value);
549 copy_v(pod, key, bytes);
550 }
551
552 void CdlPictureBuffer::drawPicture(const CdlPicture* picture,
553 const SkMatrix* matrix,
554 const CdlPaint* paint) {
555 this->push<DrawPicture>(0, picture, matrix, paint);
556 }
557
558 void CdlPictureBuffer::drawImage(sk_sp<const SkImage> image,
559 SkScalar x,
560 SkScalar y,
561 const CdlPaint* paint) {
562 this->push<DrawImage>(0, std::move(image), x, y, paint);
563 }
564
565 void CdlPictureBuffer::drawImageRect(sk_sp<const SkImage> image,
566 const SkRect* src,
567 const SkRect& dst,
568 const CdlPaint* paint,
569 SkCanvas::SrcRectConstraint constraint) {
570 this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint);
571 }
572
573 void CdlPictureBuffer::drawText(const void* text,
574 size_t bytes,
575 SkScalar x,
576 SkScalar y,
577 const CdlPaint& paint) {
578 void* pod = this->push<DrawText>(bytes, bytes, x, y, paint);
579 copy_v(pod, (const char*)text, bytes);
580 }
581 void CdlPictureBuffer::drawPosText(const void* text,
582 size_t bytes,
583 const SkPoint pos[],
584 const CdlPaint& paint) {
585 int n = paint.toSkPaint().countText(text, bytes);
586 void* pod =
587 this->push<DrawPosText>(n * sizeof(SkPoint) + bytes, bytes, paint, n);
588 copy_v(pod, pos, n, (const char*)text, bytes);
589 }
590
591 void CdlPictureBuffer::drawTextBlob(const SkTextBlob* blob,
592 SkScalar x,
593 SkScalar y,
594 const CdlPaint& paint) {
595 this->push<DrawTextBlob>(0, blob, x, y, paint);
596 }
597
598 void CdlPictureBuffer::drawPoints(SkCanvas::PointMode mode,
599 size_t count,
600 const SkPoint points[],
601 const CdlPaint& paint) {
602 void* pod =
603 this->push<DrawPoints>(count * sizeof(SkPoint), mode, count, paint);
604 copy_v(pod, points, count);
605 }
606
607 typedef void (*draw_fn)(void*,
608 CdlCanvas*,
609 const SkMatrix&,
610 CdlPictureBuffer::DrawContext&);
611 typedef void (*void_fn)(void*);
612
613 // All ops implement draw().
614 #define M(T) \
615 [](void* op, CdlCanvas* c, const SkMatrix& original, \
616 CdlPictureBuffer::DrawContext& dc) { ((T*)op)->draw(c, original, dc); },
617 static const draw_fn draw_fns[] = {TYPES(M)};
618 #undef M
619
620 #define M(T) [](void* op) { ((T*)op)->makeThreadsafe(); },
621 static const void_fn make_threadsafe_fns[] = {TYPES(M)};
622 #undef M
623
624 // Older libstdc++ has pre-standard std::has_trivial_destructor.
625 #if defined(__GLIBCXX__) && (__GLIBCXX__ < 20130000)
626 template <typename T>
627 using can_skip_destructor = std::has_trivial_destructor<T>;
628 #else
629 template <typename T>
630 using can_skip_destructor = std::is_trivially_destructible<T>;
631 #endif
632
633 // Most state ops (matrix, clip, save, restore) have a trivial destructor.
634 #define M(T) \
635 !can_skip_destructor<T>::value ? [](void* op) { ((T*)op)->~T(); } \
636 : (void_fn) nullptr,
637 static const void_fn dtor_fns[] = {TYPES(M)};
638 #undef M
639
640 void CdlPictureBuffer::playback(CdlCanvas* canvas,
641 int start_offset,
642 int end_offset) {
643 DrawContext dc;
644 this->map(draw_fns, start_offset, end_offset, canvas,
645 canvas->getTotalMatrix(), dc);
646 }
647
648 void CdlPictureBuffer::makeThreadsafe() {
649 this->map(make_threadsafe_fns, 0, fUsed);
650 }
651
652 SkRect CdlPictureBuffer::getBounds() {
653 return fBounds;
654 }
655
656 CdlPictureBuffer::CdlPictureBuffer(SkRect bounds)
657 : fUsed(0), fReserved(0), fBounds(bounds) {}
658
659 CdlPictureBuffer::~CdlPictureBuffer() {
660 this->reset(SkRect::MakeEmpty());
661 }
662
663 void CdlPictureBuffer::resetForNextPicture(SkRect bounds) {
664 fBounds = bounds;
665 }
666
667 void CdlPictureBuffer::reset(SkRect bounds) {
668 SkASSERT(this->unique());
669 this->map(dtor_fns, 0, fUsed);
670
671 // Leave fBytes and fReserved alone.
672 fUsed = 0;
673 fBounds = bounds;
674 }
675
676 void CdlPictureBuffer::drawAsLayer(CdlCanvas* canvas,
677 const SkMatrix* matrix,
678 const SkPaint* paint) {
679 // TODO(cdl)
680 /*
681 auto fallback_plan = [&] {
682 SkRect bounds = this->getBounds();
683 canvas->saveLayer(&bounds, paint);
684 this->draw(canvas, matrix);
685 canvas->restore();
686 };
687
688 // TODO: single-draw specializations
689
690 return fallback_plan();
691 */
692 }
693
694 void CdlPictureBuffer::setBounds(const SkRect& bounds) {
695 fBounds = bounds;
696 }
697
698 #endif // CDL_ENABLED
OLDNEW
« no previous file with comments | « skia/ext/cdl_picture_buffer.h ('k') | skia/ext/cdl_picture_recorder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698