mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 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 "SkCanvas.h" |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 9 | #include "SkData.h" |
reed | 6ae6969 | 2016-09-02 04:56:53 -0700 | [diff] [blame] | 10 | #include "SkDrawFilter.h" |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 11 | #include "SkImageFilter.h" |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 12 | #include "SkLiteDL.h" |
mtklein | 883c8ef | 2016-08-16 09:36:18 -0700 | [diff] [blame] | 13 | #include "SkMath.h" |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 14 | #include "SkPicture.h" |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 15 | #include "SkRSXform.h" |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 16 | #include "SkTextBlob.h" |
| 17 | |
mtklein | 883c8ef | 2016-08-16 09:36:18 -0700 | [diff] [blame] | 18 | #ifndef SKLITEDL_PAGE |
| 19 | #define SKLITEDL_PAGE 4096 |
| 20 | #endif |
| 21 | |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 22 | // A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLayer(). |
mtklein | 3ff2cc8 | 2016-08-10 08:31:42 -0700 | [diff] [blame] | 23 | static const SkRect kUnset = { SK_ScalarInfinity, 0,0,0}; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 24 | static const SkRect* maybe_unset(const SkRect& r) { |
mtklein | 3ff2cc8 | 2016-08-10 08:31:42 -0700 | [diff] [blame] | 25 | return r.left() == SK_ScalarInfinity ? nullptr : &r; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 26 | } |
| 27 | |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 28 | // copy_v(dst, src,n, src,n, ...) copies an arbitrary number of typed srcs into dst. |
| 29 | static void copy_v(void* dst) {} |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 30 | |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 31 | template <typename S, typename... Rest> |
| 32 | static void copy_v(void* dst, const S* src, int n, Rest&&... rest) { |
| 33 | SkASSERTF(((uintptr_t)dst & (alignof(S)-1)) == 0, |
| 34 | "Expected %p to be aligned for at least %zu bytes.", dst, alignof(S)); |
| 35 | sk_careful_memcpy(dst, src, n*sizeof(S)); |
| 36 | copy_v(SkTAddOffset<void>(dst, n*sizeof(S)), std::forward<Rest>(rest)...); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 37 | } |
| 38 | |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 39 | // Helper for getting back at arrays which have been copy_v'd together after an Op. |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 40 | template <typename D, typename T> |
| 41 | static D* pod(T* op, size_t offset = 0) { |
| 42 | return SkTAddOffset<D>(op+1, offset); |
| 43 | } |
| 44 | |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 45 | // Pre-cache lazy non-threadsafe fields on SkPath and/or SkMatrix. |
| 46 | static void make_threadsafe(SkPath* path, SkMatrix* matrix) { |
mtklein | df0e3ec | 2016-09-02 06:51:57 -0700 | [diff] [blame] | 47 | if (path) { path->updateBoundsCache(); } |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 48 | if (matrix) { (void)matrix->getType(); } |
| 49 | } |
| 50 | |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 51 | namespace { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 52 | #define TYPES(M) \ |
reed | 6ae6969 | 2016-09-02 04:56:53 -0700 | [diff] [blame] | 53 | M(SetDrawFilter) M(Save) M(Restore) M(SaveLayer) \ |
mtklein | cbdf007 | 2016-08-19 09:05:27 -0700 | [diff] [blame] | 54 | M(Concat) M(SetMatrix) M(Translate) M(TranslateZ) \ |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 55 | M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion) \ |
msarett | 44df651 | 2016-08-25 13:54:30 -0700 | [diff] [blame] | 56 | M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawRegion) M(DrawOval) M(DrawArc) \ |
| 57 | M(DrawRRect) M(DrawDRRect) M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) \ |
bsalomon | ac3aa24 | 2016-08-19 11:25:19 -0700 | [diff] [blame] | 58 | M(DrawShadowedPicture) \ |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 59 | M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice) \ |
| 60 | M(DrawText) M(DrawPosText) M(DrawPosTextH) \ |
| 61 | M(DrawTextOnPath) M(DrawTextRSXform) M(DrawTextBlob) \ |
| 62 | M(DrawPatch) M(DrawPoints) M(DrawVertices) M(DrawAtlas) |
| 63 | |
| 64 | #define M(T) T, |
| 65 | enum class Type : uint8_t { TYPES(M) }; |
| 66 | #undef M |
| 67 | |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 68 | struct Op { |
mtklein | 91cd280 | 2016-08-17 11:39:48 -0700 | [diff] [blame] | 69 | void makeThreadsafe() {} |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 70 | |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 71 | uint32_t type : 8; |
| 72 | uint32_t skip : 24; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 73 | }; |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 74 | static_assert(sizeof(Op) == 4, ""); |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 75 | |
reed | 6ae6969 | 2016-09-02 04:56:53 -0700 | [diff] [blame] | 76 | struct SetDrawFilter final : Op { |
| 77 | #ifdef SK_SUPPORT_LEGACY_DRAWFILTER |
| 78 | static const auto kType = Type::SetDrawFilter; |
| 79 | SetDrawFilter(SkDrawFilter* df) : drawFilter(sk_ref_sp(df)) {} |
| 80 | sk_sp<SkDrawFilter> drawFilter; |
| 81 | #endif |
| 82 | void draw(SkCanvas* c, const SkMatrix&) { |
| 83 | #ifdef SK_SUPPORT_LEGACY_DRAWFILTER |
| 84 | c->setDrawFilter(drawFilter.get()); |
| 85 | #endif |
| 86 | } |
| 87 | }; |
| 88 | |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 89 | struct Save final : Op { |
| 90 | static const auto kType = Type::Save; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 91 | void draw(SkCanvas* c, const SkMatrix&) { c->save(); } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 92 | }; |
| 93 | struct Restore final : Op { |
| 94 | static const auto kType = Type::Restore; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 95 | void draw(SkCanvas* c, const SkMatrix&) { c->restore(); } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 96 | }; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 97 | struct SaveLayer final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 98 | static const auto kType = Type::SaveLayer; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 99 | SaveLayer(const SkRect* bounds, const SkPaint* paint, |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 100 | const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags) { |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 101 | if (bounds) { this->bounds = *bounds; } |
| 102 | if (paint) { this->paint = *paint; } |
| 103 | this->backdrop = sk_ref_sp(backdrop); |
| 104 | this->flags = flags; |
| 105 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 106 | SkRect bounds = kUnset; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 107 | SkPaint paint; |
| 108 | sk_sp<const SkImageFilter> backdrop; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 109 | SkCanvas::SaveLayerFlags flags; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 110 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 111 | c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags }); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 112 | } |
| 113 | }; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 114 | |
| 115 | struct Concat final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 116 | static const auto kType = Type::Concat; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 117 | Concat(const SkMatrix& matrix) : matrix(matrix) {} |
| 118 | SkMatrix matrix; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 119 | void draw(SkCanvas* c, const SkMatrix&) { c->concat(matrix); } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 120 | void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 121 | }; |
| 122 | struct SetMatrix final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 123 | static const auto kType = Type::SetMatrix; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 124 | SetMatrix(const SkMatrix& matrix) : matrix(matrix) {} |
| 125 | SkMatrix matrix; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 126 | void draw(SkCanvas* c, const SkMatrix& original) { |
| 127 | c->setMatrix(SkMatrix::Concat(original, matrix)); |
| 128 | } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 129 | void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 130 | }; |
mtklein | cbdf007 | 2016-08-19 09:05:27 -0700 | [diff] [blame] | 131 | struct Translate final : Op { |
| 132 | static const auto kType = Type::Translate; |
| 133 | Translate(SkScalar dx, SkScalar dy) : dx(dx), dy(dy) {} |
| 134 | SkScalar dx,dy; |
| 135 | void draw(SkCanvas* c, const SkMatrix&) { |
| 136 | c->translate(dx, dy); |
| 137 | } |
| 138 | }; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 139 | struct TranslateZ final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 140 | static const auto kType = Type::TranslateZ; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 141 | TranslateZ(SkScalar dz) : dz(dz) {} |
| 142 | SkScalar dz; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 143 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 144 | #ifdef SK_EXPERIMENTAL_SHADOWING |
| 145 | c->translateZ(dz); |
| 146 | #endif |
| 147 | } |
| 148 | }; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 149 | |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 150 | struct ClipPath final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 151 | static const auto kType = Type::ClipPath; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 152 | ClipPath(const SkPath& path, SkRegion::Op op, bool aa) : path(path), op(op), aa(aa) {} |
| 153 | SkPath path; |
| 154 | SkRegion::Op op; |
| 155 | bool aa; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 156 | void draw(SkCanvas* c, const SkMatrix&) { c->clipPath(path, op, aa); } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 157 | void makeThreadsafe() { make_threadsafe(&path, nullptr); } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 158 | }; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 159 | struct ClipRect final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 160 | static const auto kType = Type::ClipRect; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 161 | ClipRect(const SkRect& rect, SkRegion::Op op, bool aa) : rect(rect), op(op), aa(aa) {} |
| 162 | SkRect rect; |
| 163 | SkRegion::Op op; |
| 164 | bool aa; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 165 | void draw(SkCanvas* c, const SkMatrix&) { c->clipRect(rect, op, aa); } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 166 | }; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 167 | struct ClipRRect final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 168 | static const auto kType = Type::ClipRRect; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 169 | ClipRRect(const SkRRect& rrect, SkRegion::Op op, bool aa) : rrect(rrect), op(op), aa(aa) {} |
| 170 | SkRRect rrect; |
| 171 | SkRegion::Op op; |
| 172 | bool aa; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 173 | void draw(SkCanvas* c, const SkMatrix&) { c->clipRRect(rrect, op, aa); } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 174 | }; |
| 175 | struct ClipRegion final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 176 | static const auto kType = Type::ClipRegion; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 177 | ClipRegion(const SkRegion& region, SkRegion::Op op) : region(region), op(op) {} |
| 178 | SkRegion region; |
| 179 | SkRegion::Op op; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 180 | void draw(SkCanvas* c, const SkMatrix&) { c->clipRegion(region, op); } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 181 | }; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 182 | |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 183 | struct DrawPaint final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 184 | static const auto kType = Type::DrawPaint; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 185 | DrawPaint(const SkPaint& paint) : paint(paint) {} |
| 186 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 187 | void draw(SkCanvas* c, const SkMatrix&) { c->drawPaint(paint); } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 188 | }; |
| 189 | struct DrawPath final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 190 | static const auto kType = Type::DrawPath; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 191 | DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {} |
| 192 | SkPath path; |
| 193 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 194 | void draw(SkCanvas* c, const SkMatrix&) { c->drawPath(path, paint); } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 195 | void makeThreadsafe() { make_threadsafe(&path, nullptr); } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 196 | }; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 197 | struct DrawRect final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 198 | static const auto kType = Type::DrawRect; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 199 | DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(paint) {} |
| 200 | SkRect rect; |
| 201 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 202 | void draw(SkCanvas* c, const SkMatrix&) { c->drawRect(rect, paint); } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 203 | }; |
msarett | 44df651 | 2016-08-25 13:54:30 -0700 | [diff] [blame] | 204 | struct DrawRegion final : Op { |
| 205 | static const auto kType = Type::DrawRegion; |
| 206 | DrawRegion(const SkRegion& region, const SkPaint& paint) : region(region), paint(paint) {} |
| 207 | SkRegion region; |
| 208 | SkPaint paint; |
| 209 | void draw(SkCanvas* c, const SkMatrix&) { c->drawRegion(region, paint); } |
| 210 | }; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 211 | struct DrawOval final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 212 | static const auto kType = Type::DrawOval; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 213 | DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(paint) {} |
| 214 | SkRect oval; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 215 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 216 | void draw(SkCanvas* c, const SkMatrix&) { c->drawOval(oval, paint); } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 217 | }; |
bsalomon | ac3aa24 | 2016-08-19 11:25:19 -0700 | [diff] [blame] | 218 | struct DrawArc final : Op { |
| 219 | static const auto kType = Type::DrawArc; |
| 220 | DrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, |
| 221 | const SkPaint& paint) |
| 222 | : oval(oval), startAngle(startAngle), sweepAngle(sweepAngle), useCenter(useCenter) |
| 223 | , paint(paint) {} |
| 224 | SkRect oval; |
| 225 | SkScalar startAngle; |
| 226 | SkScalar sweepAngle; |
| 227 | bool useCenter; |
| 228 | SkPaint paint; |
| 229 | void draw(SkCanvas* c, const SkMatrix&) { c->drawArc(oval, startAngle, sweepAngle, |
| 230 | useCenter, paint); } |
| 231 | }; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 232 | struct DrawRRect final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 233 | static const auto kType = Type::DrawRRect; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 234 | DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), paint(paint) {} |
| 235 | SkRRect rrect; |
| 236 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 237 | void draw(SkCanvas* c, const SkMatrix&) { c->drawRRect(rrect, paint); } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 238 | }; |
| 239 | struct DrawDRRect final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 240 | static const auto kType = Type::DrawDRRect; |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 241 | DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) |
| 242 | : outer(outer), inner(inner), paint(paint) {} |
| 243 | SkRRect outer, inner; |
| 244 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 245 | void draw(SkCanvas* c, const SkMatrix&) { c->drawDRRect(outer, inner, paint); } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 246 | }; |
| 247 | |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 248 | struct DrawAnnotation final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 249 | static const auto kType = Type::DrawAnnotation; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 250 | DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk_ref_sp(value)) {} |
| 251 | SkRect rect; |
| 252 | sk_sp<SkData> value; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 253 | void draw(SkCanvas* c, const SkMatrix&) { |
| 254 | c->drawAnnotation(rect, pod<char>(this), value.get()); |
| 255 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 256 | }; |
| 257 | struct DrawDrawable final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 258 | static const auto kType = Type::DrawDrawable; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 259 | DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk_ref_sp(drawable)) { |
| 260 | if (matrix) { this->matrix = *matrix; } |
| 261 | } |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 262 | sk_sp<SkDrawable> drawable; |
| 263 | sk_sp<const SkPicture> snapped; |
| 264 | SkMatrix matrix = SkMatrix::I(); |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 265 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 266 | snapped ? c->drawPicture(snapped.get(), &matrix, nullptr) |
| 267 | : c->drawDrawable(drawable.get(), &matrix); |
| 268 | } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 269 | void makeThreadsafe() { |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 270 | snapped.reset(drawable->newPictureSnapshot()); |
| 271 | make_threadsafe(nullptr, &matrix); |
| 272 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 273 | }; |
| 274 | struct DrawPicture final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 275 | static const auto kType = Type::DrawPicture; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 276 | DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) |
| 277 | : picture(sk_ref_sp(picture)) { |
| 278 | if (matrix) { this->matrix = *matrix; } |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 279 | if (paint) { this->paint = *paint; has_paint = true; } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 280 | } |
| 281 | sk_sp<const SkPicture> picture; |
| 282 | SkMatrix matrix = SkMatrix::I(); |
| 283 | SkPaint paint; |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 284 | bool has_paint = false; // TODO: why is a default paint not the same? |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 285 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 286 | c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr); |
| 287 | } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 288 | void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 289 | }; |
| 290 | struct DrawShadowedPicture final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 291 | static const auto kType = Type::DrawShadowedPicture; |
vjiaoblack | e6f5d56 | 2016-08-25 06:30:23 -0700 | [diff] [blame] | 292 | DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, |
| 293 | const SkPaint* paint, const SkShadowParams& params) |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 294 | : picture(sk_ref_sp(picture)) { |
| 295 | if (matrix) { this->matrix = *matrix; } |
| 296 | if (paint) { this->paint = *paint; } |
vjiaoblack | e6f5d56 | 2016-08-25 06:30:23 -0700 | [diff] [blame] | 297 | this->params = params; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 298 | } |
| 299 | sk_sp<const SkPicture> picture; |
| 300 | SkMatrix matrix = SkMatrix::I(); |
| 301 | SkPaint paint; |
vjiaoblack | e6f5d56 | 2016-08-25 06:30:23 -0700 | [diff] [blame] | 302 | SkShadowParams params; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 303 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 304 | #ifdef SK_EXPERIMENTAL_SHADOWING |
vjiaoblack | e6f5d56 | 2016-08-25 06:30:23 -0700 | [diff] [blame] | 305 | c->drawShadowedPicture(picture.get(), &matrix, &paint, params); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 306 | #endif |
| 307 | } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 308 | void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 309 | }; |
| 310 | |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 311 | struct DrawImage final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 312 | static const auto kType = Type::DrawImage; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 313 | DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint) |
mtklein | baeec6d | 2016-08-09 15:09:39 -0700 | [diff] [blame] | 314 | : image(std::move(image)), x(x), y(y) { |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 315 | if (paint) { this->paint = *paint; } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 316 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 317 | sk_sp<const SkImage> image; |
| 318 | SkScalar x,y; |
| 319 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 320 | void draw(SkCanvas* c, const SkMatrix&) { c->drawImage(image.get(), x,y, &paint); } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 321 | }; |
| 322 | struct DrawImageNine final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 323 | static const auto kType = Type::DrawImageNine; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 324 | DrawImageNine(sk_sp<const SkImage>&& image, |
| 325 | const SkIRect& center, const SkRect& dst, const SkPaint* paint) |
mtklein | baeec6d | 2016-08-09 15:09:39 -0700 | [diff] [blame] | 326 | : image(std::move(image)), center(center), dst(dst) { |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 327 | if (paint) { this->paint = *paint; } |
| 328 | } |
| 329 | sk_sp<const SkImage> image; |
| 330 | SkIRect center; |
| 331 | SkRect dst; |
| 332 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 333 | void draw(SkCanvas* c, const SkMatrix&) { |
| 334 | c->drawImageNine(image.get(), center, dst, &paint); |
| 335 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 336 | }; |
| 337 | struct DrawImageRect final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 338 | static const auto kType = Type::DrawImageRect; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 339 | DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst, |
| 340 | const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) |
mtklein | baeec6d | 2016-08-09 15:09:39 -0700 | [diff] [blame] | 341 | : image(std::move(image)), dst(dst), constraint(constraint) { |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 342 | this->src = src ? *src : SkRect::MakeIWH(image->width(), image->height()); |
| 343 | if (paint) { this->paint = *paint; } |
| 344 | } |
| 345 | sk_sp<const SkImage> image; |
| 346 | SkRect src, dst; |
| 347 | SkPaint paint; |
| 348 | SkCanvas::SrcRectConstraint constraint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 349 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 350 | c->drawImageRect(image.get(), src, dst, &paint, constraint); |
| 351 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 352 | }; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 353 | struct DrawImageLattice final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 354 | static const auto kType = Type::DrawImageLattice; |
msarett | 0764efe | 2016-09-02 11:24:30 -0700 | [diff] [blame] | 355 | DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 356 | const SkRect& dst, const SkPaint* paint) |
msarett | 0764efe | 2016-09-02 11:24:30 -0700 | [diff] [blame] | 357 | : image(std::move(image)), xs(xs), ys(ys), fs(fs), dst(dst) { |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 358 | if (paint) { this->paint = *paint; } |
| 359 | } |
| 360 | sk_sp<const SkImage> image; |
msarett | 0764efe | 2016-09-02 11:24:30 -0700 | [diff] [blame] | 361 | int xs, ys, fs; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 362 | SkRect dst; |
| 363 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 364 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 365 | auto xdivs = pod<int>(this, 0), |
| 366 | ydivs = pod<int>(this, xs*sizeof(int)); |
msarett | 0764efe | 2016-09-02 11:24:30 -0700 | [diff] [blame] | 367 | auto flags = (0 == fs) ? nullptr : |
| 368 | pod<SkCanvas::Lattice::Flags>(this, (xs+ys)*sizeof(int)); |
| 369 | c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys}, dst, &paint); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 370 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 371 | }; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 372 | |
| 373 | struct DrawText final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 374 | static const auto kType = Type::DrawText; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 375 | DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) |
| 376 | : bytes(bytes), x(x), y(y), paint(paint) {} |
| 377 | size_t bytes; |
| 378 | SkScalar x,y; |
| 379 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 380 | void draw(SkCanvas* c, const SkMatrix&) { |
| 381 | c->drawText(pod<void>(this), bytes, x,y, paint); |
| 382 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 383 | }; |
| 384 | struct DrawPosText final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 385 | static const auto kType = Type::DrawPosText; |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 386 | DrawPosText(size_t bytes, const SkPaint& paint, int n) |
| 387 | : bytes(bytes), paint(paint), n(n) {} |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 388 | size_t bytes; |
| 389 | SkPaint paint; |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 390 | int n; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 391 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 392 | auto points = pod<SkPoint>(this); |
| 393 | auto text = pod<void>(this, n*sizeof(SkPoint)); |
| 394 | c->drawPosText(text, bytes, points, paint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 395 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 396 | }; |
| 397 | struct DrawPosTextH final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 398 | static const auto kType = Type::DrawPosTextH; |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 399 | DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint, int n) |
| 400 | : bytes(bytes), y(y), paint(paint), n(n) {} |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 401 | size_t bytes; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 402 | SkScalar y; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 403 | SkPaint paint; |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 404 | int n; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 405 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 406 | auto xs = pod<SkScalar>(this); |
| 407 | auto text = pod<void>(this, n*sizeof(SkScalar)); |
| 408 | c->drawPosTextH(text, bytes, xs, y, paint); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 409 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 410 | }; |
| 411 | struct DrawTextOnPath final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 412 | static const auto kType = Type::DrawTextOnPath; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 413 | DrawTextOnPath(size_t bytes, const SkPath& path, |
| 414 | const SkMatrix* matrix, const SkPaint& paint) |
| 415 | : bytes(bytes), path(path), paint(paint) { |
| 416 | if (matrix) { this->matrix = *matrix; } |
| 417 | } |
| 418 | size_t bytes; |
| 419 | SkPath path; |
| 420 | SkMatrix matrix = SkMatrix::I(); |
| 421 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 422 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 423 | c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint); |
| 424 | } |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 425 | void makeThreadsafe() { make_threadsafe(&path, &matrix); } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 426 | }; |
| 427 | struct DrawTextRSXform final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 428 | static const auto kType = Type::DrawTextRSXform; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 429 | DrawTextRSXform(size_t bytes, const SkRect* cull, const SkPaint& paint) |
| 430 | : bytes(bytes), paint(paint) { |
| 431 | if (cull) { this->cull = *cull; } |
| 432 | } |
| 433 | size_t bytes; |
| 434 | SkRect cull = kUnset; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 435 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 436 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 437 | c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, bytes), |
| 438 | maybe_unset(cull), paint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 439 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 440 | }; |
| 441 | struct DrawTextBlob final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 442 | static const auto kType = Type::DrawTextBlob; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 443 | DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) |
| 444 | : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {} |
| 445 | sk_sp<const SkTextBlob> blob; |
| 446 | SkScalar x,y; |
| 447 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 448 | void draw(SkCanvas* c, const SkMatrix&) { |
| 449 | c->drawTextBlob(blob.get(), x,y, paint); |
| 450 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 451 | }; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 452 | |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 453 | struct DrawPatch final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 454 | static const auto kType = Type::DrawPatch; |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 455 | DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texs[4], |
| 456 | SkXfermode* xfermode, const SkPaint& paint) |
| 457 | : xfermode(sk_ref_sp(xfermode)), paint(paint) { |
| 458 | copy_v(this->cubics, cubics, 12); |
| 459 | if (colors) { copy_v(this->colors, colors, 4); has_colors = true; } |
| 460 | if (texs ) { copy_v(this->texs , texs , 4); has_texs = true; } |
| 461 | } |
| 462 | SkPoint cubics[12]; |
| 463 | SkColor colors[4]; |
| 464 | SkPoint texs[4]; |
| 465 | sk_sp<SkXfermode> xfermode; |
| 466 | SkPaint paint; |
| 467 | bool has_colors = false; |
| 468 | bool has_texs = false; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 469 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 470 | c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs : nullptr, |
| 471 | xfermode.get(), paint); |
| 472 | } |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 473 | }; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 474 | struct DrawPoints final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 475 | static const auto kType = Type::DrawPoints; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 476 | DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint) |
| 477 | : mode(mode), count(count), paint(paint) {} |
| 478 | SkCanvas::PointMode mode; |
| 479 | size_t count; |
| 480 | SkPaint paint; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 481 | void draw(SkCanvas* c, const SkMatrix&) { |
| 482 | c->drawPoints(mode, count, pod<SkPoint>(this), paint); |
| 483 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 484 | }; |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 485 | struct DrawVertices final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 486 | static const auto kType = Type::DrawVertices; |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 487 | DrawVertices(SkCanvas::VertexMode mode, int count, SkXfermode* xfermode, int nindices, |
| 488 | const SkPaint& paint, bool has_texs, bool has_colors, bool has_indices) |
| 489 | : mode(mode), count(count), xfermode(sk_ref_sp(xfermode)), nindices(nindices) |
| 490 | , paint(paint), has_texs(has_texs), has_colors(has_colors), has_indices(has_indices) {} |
| 491 | SkCanvas::VertexMode mode; |
| 492 | int count; |
| 493 | sk_sp<SkXfermode> xfermode; |
| 494 | int nindices; |
| 495 | SkPaint paint; |
| 496 | bool has_texs; |
| 497 | bool has_colors; |
| 498 | bool has_indices; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 499 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 500 | SkPoint* vertices = pod<SkPoint>(this, 0); |
| 501 | size_t offset = count*sizeof(SkPoint); |
| 502 | |
| 503 | SkPoint* texs = nullptr; |
| 504 | if (has_texs) { |
| 505 | texs = pod<SkPoint>(this, offset); |
| 506 | offset += count*sizeof(SkPoint); |
| 507 | } |
| 508 | |
| 509 | SkColor* colors = nullptr; |
| 510 | if (has_colors) { |
| 511 | colors = pod<SkColor>(this, offset); |
| 512 | offset += count*sizeof(SkColor); |
| 513 | } |
| 514 | |
| 515 | uint16_t* indices = nullptr; |
| 516 | if (has_indices) { |
| 517 | indices = pod<uint16_t>(this, offset); |
| 518 | } |
| 519 | c->drawVertices(mode, count, vertices, texs, colors, xfermode.get(), |
| 520 | indices, nindices, paint); |
| 521 | } |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 522 | }; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 523 | struct DrawAtlas final : Op { |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 524 | static const auto kType = Type::DrawAtlas; |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 525 | DrawAtlas(const SkImage* atlas, int count, SkXfermode::Mode xfermode, |
| 526 | const SkRect* cull, const SkPaint* paint, bool has_colors) |
| 527 | : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_colors(has_colors) { |
| 528 | if (cull) { this->cull = *cull; } |
| 529 | if (paint) { this->paint = *paint; } |
| 530 | } |
| 531 | sk_sp<const SkImage> atlas; |
| 532 | int count; |
| 533 | SkXfermode::Mode xfermode; |
| 534 | SkRect cull = kUnset; |
| 535 | SkPaint paint; |
| 536 | bool has_colors; |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 537 | void draw(SkCanvas* c, const SkMatrix&) { |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 538 | auto xforms = pod<SkRSXform>(this, 0); |
| 539 | auto texs = pod<SkRect>(this, count*sizeof(SkRSXform)); |
| 540 | auto colors = has_colors |
| 541 | ? pod<SkColor>(this, count*(sizeof(SkRSXform) + sizeof(SkRect))) |
| 542 | : nullptr; |
| 543 | c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, |
| 544 | maybe_unset(cull), &paint); |
| 545 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 546 | }; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 547 | } |
| 548 | |
| 549 | template <typename T, typename... Args> |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 550 | void* SkLiteDL::push(size_t pod, Args&&... args) { |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 551 | size_t skip = SkAlignPtr(sizeof(T) + pod); |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 552 | SkASSERT(skip < (1<<24)); |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 553 | if (fUsed + skip > fReserved) { |
mtklein | 883c8ef | 2016-08-16 09:36:18 -0700 | [diff] [blame] | 554 | static_assert(SkIsPow2(SKLITEDL_PAGE), "This math needs updating for non-pow2."); |
| 555 | // Next greater multiple of SKLITEDL_PAGE. |
| 556 | fReserved = (fUsed + skip + SKLITEDL_PAGE) & ~(SKLITEDL_PAGE-1); |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 557 | fBytes.realloc(fReserved); |
| 558 | } |
| 559 | SkASSERT(fUsed + skip <= fReserved); |
| 560 | auto op = (T*)(fBytes.get() + fUsed); |
| 561 | fUsed += skip; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 562 | new (op) T{ std::forward<Args>(args)... }; |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 563 | op->type = (uint32_t)T::kType; |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 564 | op->skip = skip; |
| 565 | return op+1; |
| 566 | } |
| 567 | |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 568 | template <typename Fn, typename... Args> |
| 569 | inline void SkLiteDL::map(const Fn fns[], Args... args) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 570 | auto end = fBytes.get() + fUsed; |
| 571 | for (uint8_t* ptr = fBytes.get(); ptr < end; ) { |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 572 | auto op = (Op*)ptr; |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 573 | auto type = op->type; |
| 574 | auto skip = op->skip; |
| 575 | if (auto fn = fns[type]) { // We replace no-op functions with nullptrs |
| 576 | fn(op, args...); // to avoid the overhead of a pointless call. |
| 577 | } |
| 578 | ptr += skip; |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 579 | } |
| 580 | } |
| 581 | |
reed | 6ae6969 | 2016-09-02 04:56:53 -0700 | [diff] [blame] | 582 | #ifdef SK_SUPPORT_LEGACY_DRAWFILTER |
| 583 | void SkLiteDL::setDrawFilter(SkDrawFilter* df) { |
| 584 | this->push<SetDrawFilter>(0, df); |
| 585 | } |
| 586 | #endif |
| 587 | |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 588 | void SkLiteDL:: save() { this->push <Save>(0); } |
| 589 | void SkLiteDL::restore() { this->push<Restore>(0); } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 590 | void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint, |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 591 | const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 592 | this->push<SaveLayer>(0, bounds, paint, backdrop, flags); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 593 | } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 594 | |
mtklein | cbdf007 | 2016-08-19 09:05:27 -0700 | [diff] [blame] | 595 | void SkLiteDL:: concat(const SkMatrix& matrix) { this->push <Concat>(0, matrix); } |
| 596 | void SkLiteDL::setMatrix(const SkMatrix& matrix) { this->push<SetMatrix>(0, matrix); } |
| 597 | void SkLiteDL::translate(SkScalar dx, SkScalar dy) { this->push<Translate>(0, dx, dy); } |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 598 | void SkLiteDL::translateZ(SkScalar dz) { this->push<TranslateZ>(0, dz); } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 599 | |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 600 | void SkLiteDL::clipPath(const SkPath& path, SkRegion::Op op, bool aa) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 601 | this->push<ClipPath>(0, path, op, aa); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 602 | } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 603 | void SkLiteDL::clipRect(const SkRect& rect, SkRegion::Op op, bool aa) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 604 | this->push<ClipRect>(0, rect, op, aa); |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 605 | } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 606 | void SkLiteDL::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool aa) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 607 | this->push<ClipRRect>(0, rrect, op, aa); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 608 | } |
| 609 | void SkLiteDL::clipRegion(const SkRegion& region, SkRegion::Op op) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 610 | this->push<ClipRegion>(0, region, op); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 611 | } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 612 | |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 613 | void SkLiteDL::drawPaint(const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 614 | this->push<DrawPaint>(0, paint); |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 615 | } |
| 616 | void SkLiteDL::drawPath(const SkPath& path, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 617 | this->push<DrawPath>(0, path, paint); |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 618 | } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 619 | void SkLiteDL::drawRect(const SkRect& rect, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 620 | this->push<DrawRect>(0, rect, paint); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 621 | } |
msarett | 44df651 | 2016-08-25 13:54:30 -0700 | [diff] [blame] | 622 | void SkLiteDL::drawRegion(const SkRegion& region, const SkPaint& paint) { |
| 623 | this->push<DrawRegion>(0, region, paint); |
| 624 | } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 625 | void SkLiteDL::drawOval(const SkRect& oval, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 626 | this->push<DrawOval>(0, oval, paint); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 627 | } |
bsalomon | ac3aa24 | 2016-08-19 11:25:19 -0700 | [diff] [blame] | 628 | void SkLiteDL::drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, |
| 629 | const SkPaint& paint) { |
| 630 | this->push<DrawArc>(0, oval, startAngle, sweepAngle, useCenter, paint); |
| 631 | } |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 632 | void SkLiteDL::drawRRect(const SkRRect& rrect, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 633 | this->push<DrawRRect>(0, rrect, paint); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 634 | } |
| 635 | void SkLiteDL::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 636 | this->push<DrawDRRect>(0, outer, inner, paint); |
mtklein | 6f8411d | 2016-08-06 15:28:11 -0700 | [diff] [blame] | 637 | } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 638 | |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 639 | void SkLiteDL::drawAnnotation(const SkRect& rect, const char* key, SkData* value) { |
| 640 | size_t bytes = strlen(key)+1; |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 641 | void* pod = this->push<DrawAnnotation>(bytes, rect, value); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 642 | copy_v(pod, key,bytes); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 643 | } |
| 644 | void SkLiteDL::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 645 | this->push<DrawDrawable>(0, drawable, matrix); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 646 | } |
| 647 | void SkLiteDL::drawPicture(const SkPicture* picture, |
| 648 | const SkMatrix* matrix, const SkPaint* paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 649 | this->push<DrawPicture>(0, picture, matrix, paint); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 650 | } |
vjiaoblack | e6f5d56 | 2016-08-25 06:30:23 -0700 | [diff] [blame] | 651 | void SkLiteDL::drawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, |
| 652 | const SkPaint* paint, const SkShadowParams& params) { |
| 653 | push<DrawShadowedPicture>(0, picture, matrix, paint, params); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 654 | } |
| 655 | |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 656 | void SkLiteDL::drawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPaint* paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 657 | this->push<DrawImage>(0, SkImage::MakeFromBitmap(bm), x,y, paint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 658 | } |
| 659 | void SkLiteDL::drawBitmapNine(const SkBitmap& bm, const SkIRect& center, |
| 660 | const SkRect& dst, const SkPaint* paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 661 | this->push<DrawImageNine>(0, SkImage::MakeFromBitmap(bm), center, dst, paint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 662 | } |
| 663 | void SkLiteDL::drawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst, |
| 664 | const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 665 | this->push<DrawImageRect>(0, SkImage::MakeFromBitmap(bm), src, dst, paint, constraint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 666 | } |
msarett | 1688206 | 2016-08-16 09:31:08 -0700 | [diff] [blame] | 667 | void SkLiteDL::drawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& lattice, |
| 668 | const SkRect& dst, const SkPaint* paint) { |
| 669 | int xs = lattice.fXCount, ys = lattice.fYCount; |
msarett | 0764efe | 2016-09-02 11:24:30 -0700 | [diff] [blame] | 670 | int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0; |
| 671 | size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::Flags); |
| 672 | void* pod = this->push<DrawImageLattice>(bytes, SkImage::MakeFromBitmap(bm), xs, ys, fs, dst, |
msarett | 1688206 | 2016-08-16 09:31:08 -0700 | [diff] [blame] | 673 | paint); |
| 674 | copy_v(pod, lattice.fXDivs, xs, |
msarett | 0764efe | 2016-09-02 11:24:30 -0700 | [diff] [blame] | 675 | lattice.fYDivs, ys, |
| 676 | lattice.fFlags, fs); |
msarett | 1688206 | 2016-08-16 09:31:08 -0700 | [diff] [blame] | 677 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 678 | |
| 679 | void SkLiteDL::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 680 | this->push<DrawImage>(0, sk_ref_sp(image), x,y, paint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 681 | } |
| 682 | void SkLiteDL::drawImageNine(const SkImage* image, const SkIRect& center, |
| 683 | const SkRect& dst, const SkPaint* paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 684 | this->push<DrawImageNine>(0, sk_ref_sp(image), center, dst, paint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 685 | } |
| 686 | void SkLiteDL::drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, |
| 687 | const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 688 | this->push<DrawImageRect>(0, sk_ref_sp(image), src, dst, paint, constraint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 689 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 690 | void SkLiteDL::drawImageLattice(const SkImage* image, const SkCanvas::Lattice& lattice, |
| 691 | const SkRect& dst, const SkPaint* paint) { |
| 692 | int xs = lattice.fXCount, ys = lattice.fYCount; |
msarett | 0764efe | 2016-09-02 11:24:30 -0700 | [diff] [blame] | 693 | int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0; |
| 694 | size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::Flags); |
| 695 | void* pod = this->push<DrawImageLattice>(bytes, sk_ref_sp(image), xs, ys, fs, dst, paint); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 696 | copy_v(pod, lattice.fXDivs, xs, |
msarett | 0764efe | 2016-09-02 11:24:30 -0700 | [diff] [blame] | 697 | lattice.fYDivs, ys, |
| 698 | lattice.fFlags, fs); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 699 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 700 | |
| 701 | void SkLiteDL::drawText(const void* text, size_t bytes, |
| 702 | SkScalar x, SkScalar y, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 703 | void* pod = this->push<DrawText>(bytes, bytes, x, y, paint); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 704 | copy_v(pod, (const char*)text,bytes); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 705 | } |
| 706 | void SkLiteDL::drawPosText(const void* text, size_t bytes, |
| 707 | const SkPoint pos[], const SkPaint& paint) { |
| 708 | int n = paint.countText(text, bytes); |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 709 | void* pod = this->push<DrawPosText>(n*sizeof(SkPoint)+bytes, bytes, paint, n); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 710 | copy_v(pod, pos,n, (const char*)text,bytes); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 711 | } |
| 712 | void SkLiteDL::drawPosTextH(const void* text, size_t bytes, |
| 713 | const SkScalar xs[], SkScalar y, const SkPaint& paint) { |
| 714 | int n = paint.countText(text, bytes); |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 715 | void* pod = this->push<DrawPosTextH>(n*sizeof(SkScalar)+bytes, bytes, y, paint, n); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 716 | copy_v(pod, xs,n, (const char*)text,bytes); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 717 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 718 | void SkLiteDL::drawTextOnPath(const void* text, size_t bytes, |
| 719 | const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 720 | void* pod = this->push<DrawTextOnPath>(bytes, bytes, path, matrix, paint); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 721 | copy_v(pod, (const char*)text,bytes); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 722 | } |
| 723 | void SkLiteDL::drawTextRSXform(const void* text, size_t bytes, |
| 724 | const SkRSXform xforms[], const SkRect* cull, const SkPaint& paint) { |
| 725 | int n = paint.countText(text, bytes); |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 726 | void* pod = this->push<DrawTextRSXform>(bytes+n*sizeof(SkRSXform), bytes, cull, paint); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 727 | copy_v(pod, (const char*)text,bytes, xforms,n); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 728 | } |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 729 | void SkLiteDL::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 730 | this->push<DrawTextBlob>(0, blob, x,y, paint); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 731 | } |
| 732 | |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 733 | void SkLiteDL::drawPatch(const SkPoint points[12], const SkColor colors[4], const SkPoint texs[4], |
| 734 | SkXfermode* xfermode, const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 735 | this->push<DrawPatch>(0, points, colors, texs, xfermode, paint); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 736 | } |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 737 | void SkLiteDL::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint points[], |
| 738 | const SkPaint& paint) { |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 739 | void* pod = this->push<DrawPoints>(count*sizeof(SkPoint), mode, count, paint); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 740 | copy_v(pod, points,count); |
| 741 | } |
| 742 | void SkLiteDL::drawVertices(SkCanvas::VertexMode mode, int count, const SkPoint vertices[], |
| 743 | const SkPoint texs[], const SkColor colors[], SkXfermode* xfermode, |
| 744 | const uint16_t indices[], int nindices, const SkPaint& paint) { |
| 745 | size_t bytes = count * sizeof(SkPoint); |
| 746 | if (texs ) { bytes += count * sizeof(SkPoint); } |
| 747 | if (colors) { bytes += count * sizeof(SkColor); } |
| 748 | if (indices) { bytes += nindices * sizeof(uint16_t); } |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 749 | void* pod = this->push<DrawVertices>(bytes, mode, count, xfermode, nindices, paint, |
| 750 | texs != nullptr, colors != nullptr, indices != nullptr); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 751 | copy_v(pod, vertices, count, |
| 752 | texs, texs ? count : 0, |
| 753 | colors, colors ? count : 0, |
| 754 | indices, indices ? nindices : 0); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 755 | } |
| 756 | void SkLiteDL::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[], |
| 757 | const SkColor colors[], int count, SkXfermode::Mode xfermode, |
| 758 | const SkRect* cull, const SkPaint* paint) { |
| 759 | size_t bytes = count*(sizeof(SkRSXform) + sizeof(SkRect)); |
| 760 | if (colors) { |
| 761 | bytes += count*sizeof(SkColor); |
| 762 | } |
mtklein | b202833 | 2016-08-09 15:13:18 -0700 | [diff] [blame] | 763 | void* pod = this->push<DrawAtlas>(bytes, |
| 764 | atlas, count, xfermode, cull, paint, colors != nullptr); |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 765 | copy_v(pod, xforms, count, |
| 766 | texs, count, |
| 767 | colors, colors ? count : 0); |
mtklein | 29de8d9 | 2016-08-07 11:35:08 -0700 | [diff] [blame] | 768 | } |
| 769 | |
mtklein | 91cd280 | 2016-08-17 11:39:48 -0700 | [diff] [blame] | 770 | typedef void(*draw_fn)(void*, SkCanvas*, const SkMatrix&); |
| 771 | typedef void(*void_fn)(void*); |
mtklein | ec55959 | 2016-08-06 20:31:30 -0700 | [diff] [blame] | 772 | |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 773 | // All ops implement draw(). |
mtklein | 6480619 | 2016-08-16 17:18:27 -0700 | [diff] [blame] | 774 | #define M(T) [](void* op, SkCanvas* c, const SkMatrix& original) { ((T*)op)->draw(c, original); }, |
| 775 | static const draw_fn draw_fns[] = { TYPES(M) }; |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 776 | #undef M |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 777 | |
mtklein | 91cd280 | 2016-08-17 11:39:48 -0700 | [diff] [blame] | 778 | #define M(T) [](void* op) { ((T*)op)->makeThreadsafe(); }, |
mtklein | d559eb2 | 2016-08-11 07:08:28 -0700 | [diff] [blame] | 779 | static const void_fn make_threadsafe_fns[] = { TYPES(M) }; |
| 780 | #undef M |
| 781 | |
| 782 | // Older libstdc++ has pre-standard std::has_trivial_destructor. |
| 783 | #if defined(__GLIBCXX__) && (__GLIBCXX__ < 20130000) |
| 784 | template <typename T> using can_skip_destructor = std::has_trivial_destructor<T>; |
| 785 | #else |
| 786 | template <typename T> using can_skip_destructor = std::is_trivially_destructible<T>; |
| 787 | #endif |
| 788 | |
| 789 | // Most state ops (matrix, clip, save, restore) have a trivial destructor. |
| 790 | #define M(T) !can_skip_destructor<T>::value ? [](void* op) { ((T*)op)->~T(); } : (void_fn)nullptr, |
| 791 | static const void_fn dtor_fns[] = { TYPES(M) }; |
| 792 | #undef M |
| 793 | |
mtklein | 91cd280 | 2016-08-17 11:39:48 -0700 | [diff] [blame] | 794 | void SkLiteDL::onDraw(SkCanvas* canvas) { this->map(draw_fns, canvas, canvas->getTotalMatrix()); } |
| 795 | void SkLiteDL::makeThreadsafe() { this->map(make_threadsafe_fns); } |
mtklein | 03591a7 | 2016-08-07 13:35:46 -0700 | [diff] [blame] | 796 | |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 797 | SkRect SkLiteDL::onGetBounds() { |
| 798 | return fBounds; |
| 799 | } |
| 800 | |
mtklein | 883c8ef | 2016-08-16 09:36:18 -0700 | [diff] [blame] | 801 | SkLiteDL:: SkLiteDL(SkRect bounds) : fUsed(0), fReserved(0), fBounds(bounds) {} |
mtklein | 765b6e6 | 2016-08-08 12:23:02 -0700 | [diff] [blame] | 802 | |
mtklein | 883c8ef | 2016-08-16 09:36:18 -0700 | [diff] [blame] | 803 | SkLiteDL::~SkLiteDL() { |
| 804 | this->reset(SkRect::MakeEmpty()); |
| 805 | } |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 806 | |
| 807 | sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) { |
mtklein | 883c8ef | 2016-08-16 09:36:18 -0700 | [diff] [blame] | 808 | return sk_sp<SkLiteDL>(new SkLiteDL(bounds)); |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 809 | } |
| 810 | |
mtklein | 883c8ef | 2016-08-16 09:36:18 -0700 | [diff] [blame] | 811 | void SkLiteDL::reset(SkRect bounds) { |
| 812 | SkASSERT(this->unique()); |
| 813 | this->map(dtor_fns); |
mtklein | 9c5052f | 2016-08-06 12:51:51 -0700 | [diff] [blame] | 814 | |
mtklein | 883c8ef | 2016-08-16 09:36:18 -0700 | [diff] [blame] | 815 | // Leave fBytes and fReserved alone. |
| 816 | fUsed = 0; |
| 817 | fBounds = bounds; |
mtklein | 0c753e5 | 2016-08-09 07:40:23 -0700 | [diff] [blame] | 818 | } |
mtklein | f53fcc8 | 2016-09-08 08:49:08 -0700 | [diff] [blame] | 819 | |
| 820 | void SkLiteDL::drawAsLayer(SkCanvas* canvas, const SkMatrix* matrix, const SkPaint* paint) { |
| 821 | auto fallback_plan = [&] { |
| 822 | SkRect bounds = this->getBounds(); |
| 823 | canvas->saveLayer(&bounds, paint); |
| 824 | this->draw(canvas, matrix); |
| 825 | canvas->restore(); |
| 826 | }; |
| 827 | |
| 828 | // TODO: single-draw specializations |
| 829 | |
| 830 | return fallback_plan(); |
| 831 | } |