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