| 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 "SkImageFilter.h" | 9 #include "SkImageFilter.h" |
| 10 #include "SkLiteDL.h" | 10 #include "SkLiteDL.h" |
| 11 #include "SkMutex.h" | 11 #include "SkMutex.h" |
| 12 #include "SkSpinlock.h" | 12 #include "SkSpinlock.h" |
| 13 #include "SkTextBlob.h" |
| 14 |
| 15 // memcpy_v(dst, src0,bytes0, src1,bytes1, ...) copies an arbitrary number of sr
cs into dst. |
| 16 static void memcpy_v(void* dst) {} |
| 17 |
| 18 template <typename... Rest> |
| 19 static void memcpy_v(void* dst, const void* src, size_t bytes, Rest&&... rest) { |
| 20 memcpy(dst, src, bytes); |
| 21 memcpy_v(SkTAddOffset<void>(dst, bytes), std::forward<Rest>(rest)...); |
| 22 } |
| 23 |
| 24 // Convert images and image-based shaders to textures. |
| 25 static void optimize_for(GrContext* ctx, SkPaint* paint, sk_sp<const SkImage>* i
mage = nullptr) { |
| 26 SkMatrix matrix; |
| 27 SkShader::TileMode xy[2]; |
| 28 if (auto shader = paint->getShader()) |
| 29 if (auto image = shader->isAImage(&matrix, xy)) { // TODO: compose shaders
, etc. |
| 30 paint->setShader(image->makeTextureImage(ctx)->makeShader(xy[0], xy[1],
&matrix)); |
| 31 } |
| 32 |
| 33 if (image) { |
| 34 *image = (*image)->makeTextureImage(ctx); |
| 35 } |
| 36 } |
| 13 | 37 |
| 14 namespace { | 38 namespace { |
| 15 struct Op { | 39 struct Op { |
| 16 virtual ~Op() {} | 40 virtual ~Op() {} |
| 17 virtual void draw(SkCanvas*) = 0; | 41 virtual void draw(SkCanvas*) = 0; |
| 42 virtual void optimizeFor(GrContext*) {} |
| 18 | 43 |
| 19 size_t skip; | 44 size_t skip; |
| 20 }; | 45 }; |
| 21 | 46 |
| 22 struct Save final : Op { void draw(SkCanvas* c) override { c-> save();
} }; | 47 struct Save final : Op { void draw(SkCanvas* c) override { c-> save();
} }; |
| 23 struct Restore final : Op { void draw(SkCanvas* c) override { c->restore();
} }; | 48 struct Restore final : Op { void draw(SkCanvas* c) override { c->restore();
} }; |
| 24 struct SaveLayer final : Op { | 49 struct SaveLayer final : Op { |
| 25 SaveLayer(const SkRect* bounds, const SkPaint* paint, | 50 SaveLayer(const SkRect* bounds, const SkPaint* paint, |
| 26 const SkImageFilter* backdrop, uint32_t flags) { | 51 const SkImageFilter* backdrop, uint32_t flags) { |
| 27 if (bounds) { this->bounds = *bounds; } | 52 if (bounds) { this->bounds = *bounds; } |
| 28 if (paint) { this->paint = *paint; } | 53 if (paint) { this->paint = *paint; } |
| 29 this->backdrop = sk_ref_sp(backdrop); | 54 this->backdrop = sk_ref_sp(backdrop); |
| 30 this->flags = flags; | 55 this->flags = flags; |
| 31 } | 56 } |
| 32 SkRect bounds = {SK_ScalarMin,SK_ScalarMin, SK_Scala
rMax,SK_ScalarMax}; | 57 SkRect bounds = {SK_ScalarMin,SK_ScalarMin, SK_Scala
rMax,SK_ScalarMax}; |
| 33 SkPaint paint; | 58 SkPaint paint; |
| 34 sk_sp<const SkImageFilter> backdrop; | 59 sk_sp<const SkImageFilter> backdrop; |
| 35 uint32_t flags; | 60 uint32_t flags; |
| 36 void draw(SkCanvas* c) override { | 61 void draw(SkCanvas* c) override { |
| 37 c->saveLayer({ &bounds, &paint, backdrop.get(), flags }); | 62 c->saveLayer({ &bounds, &paint, backdrop.get(), flags }); |
| 38 } | 63 } |
| 64 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 39 }; | 65 }; |
| 40 | 66 |
| 41 struct Concat final : Op { | 67 struct Concat final : Op { |
| 42 Concat(const SkMatrix& matrix) : matrix(matrix) {} | 68 Concat(const SkMatrix& matrix) : matrix(matrix) {} |
| 43 SkMatrix matrix; | 69 SkMatrix matrix; |
| 44 void draw(SkCanvas* c) override { c->concat(matrix); } | 70 void draw(SkCanvas* c) override { c->concat(matrix); } |
| 45 }; | 71 }; |
| 46 struct SetMatrix final : Op { | 72 struct SetMatrix final : Op { |
| 47 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {} | 73 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {} |
| 48 SkMatrix matrix; | 74 SkMatrix matrix; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 74 ClipRegion(const SkRegion& region, SkRegion::Op op) : region(region), op
(op) {} | 100 ClipRegion(const SkRegion& region, SkRegion::Op op) : region(region), op
(op) {} |
| 75 SkRegion region; | 101 SkRegion region; |
| 76 SkRegion::Op op; | 102 SkRegion::Op op; |
| 77 void draw(SkCanvas* c) override { c->clipRegion(region, op); } | 103 void draw(SkCanvas* c) override { c->clipRegion(region, op); } |
| 78 }; | 104 }; |
| 79 | 105 |
| 80 struct DrawPaint final : Op { | 106 struct DrawPaint final : Op { |
| 81 DrawPaint(const SkPaint& paint) : paint(paint) {} | 107 DrawPaint(const SkPaint& paint) : paint(paint) {} |
| 82 SkPaint paint; | 108 SkPaint paint; |
| 83 void draw(SkCanvas* c) override { c->drawPaint(paint); } | 109 void draw(SkCanvas* c) override { c->drawPaint(paint); } |
| 110 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 84 }; | 111 }; |
| 85 struct DrawPath final : Op { | 112 struct DrawPath final : Op { |
| 86 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
aint) {} | 113 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
aint) {} |
| 87 SkPath path; | 114 SkPath path; |
| 88 SkPaint paint; | 115 SkPaint paint; |
| 89 void draw(SkCanvas* c) override { c->drawPath(path, paint); } | 116 void draw(SkCanvas* c) override { c->drawPath(path, paint); } |
| 117 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 90 }; | 118 }; |
| 91 struct DrawRect final : Op { | 119 struct DrawRect final : Op { |
| 92 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
aint) {} | 120 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
aint) {} |
| 93 SkRect rect; | 121 SkRect rect; |
| 94 SkPaint paint; | 122 SkPaint paint; |
| 95 void draw(SkCanvas* c) override { c->drawRect(rect, paint); } | 123 void draw(SkCanvas* c) override { c->drawRect(rect, paint); } |
| 124 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 96 }; | 125 }; |
| 97 struct DrawOval final : Op { | 126 struct DrawOval final : Op { |
| 98 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(p
aint) {} | 127 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(p
aint) {} |
| 99 SkRect oval; | 128 SkRect oval; |
| 100 SkPaint paint; | 129 SkPaint paint; |
| 101 void draw(SkCanvas* c) override { c->drawOval(oval, paint); } | 130 void draw(SkCanvas* c) override { c->drawOval(oval, paint); } |
| 131 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 102 }; | 132 }; |
| 103 struct DrawRRect final : Op { | 133 struct DrawRRect final : Op { |
| 104 DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), pa
int(paint) {} | 134 DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), pa
int(paint) {} |
| 105 SkRRect rrect; | 135 SkRRect rrect; |
| 106 SkPaint paint; | 136 SkPaint paint; |
| 107 void draw(SkCanvas* c) override { c->drawRRect(rrect, paint); } | 137 void draw(SkCanvas* c) override { c->drawRRect(rrect, paint); } |
| 138 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 108 }; | 139 }; |
| 109 struct DrawDRRect final : Op { | 140 struct DrawDRRect final : Op { |
| 110 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& pa
int) | 141 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& pa
int) |
| 111 : outer(outer), inner(inner), paint(paint) {} | 142 : outer(outer), inner(inner), paint(paint) {} |
| 112 SkRRect outer, inner; | 143 SkRRect outer, inner; |
| 113 SkPaint paint; | 144 SkPaint paint; |
| 114 void draw(SkCanvas* c) override { c->drawDRRect(outer, inner, paint); } | 145 void draw(SkCanvas* c) override { c->drawDRRect(outer, inner, paint); } |
| 146 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 115 }; | 147 }; |
| 116 | 148 |
| 117 template <typename T, typename... Args> | 149 struct DrawImage final : Op { |
| 118 static void* push(SkTDArray<uint8_t>* bytes, size_t pod, Args&&... args) { | 150 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const Sk
Paint* paint) |
| 119 size_t skip = SkAlignPtr(sizeof(T) + pod); | 151 : image(image), x(x), y(y) { |
| 120 auto op = (T*)bytes->append(skip); | 152 if (paint) { this->paint = *paint; } |
| 121 new (op) T{ std::forward<Args>(args)... }; | 153 } |
| 122 op->skip = skip; | 154 sk_sp<const SkImage> image; |
| 123 return op+1; | 155 SkScalar x,y; |
| 124 } | 156 SkPaint paint; |
| 157 void draw(SkCanvas* c) override { c->drawImage(image.get(), x,y, &paint)
; } |
| 158 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &i
mage); } |
| 159 }; |
| 160 struct DrawImageNine final : Op { |
| 161 DrawImageNine(sk_sp<const SkImage>&& image, |
| 162 const SkIRect& center, const SkRect& dst, const SkPaint* p
aint) |
| 163 : image(image), center(center), dst(dst) { |
| 164 if (paint) { this->paint = *paint; } |
| 165 } |
| 166 sk_sp<const SkImage> image; |
| 167 SkIRect center; |
| 168 SkRect dst; |
| 169 SkPaint paint; |
| 170 void draw(SkCanvas* c) override { c->drawImageNine(image.get(), center,
dst, &paint); } |
| 171 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &i
mage); } |
| 172 }; |
| 173 struct DrawImageRect final : Op { |
| 174 DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkR
ect& dst, |
| 175 const SkPaint* paint, SkCanvas::SrcRectConstraint constrai
nt) |
| 176 : image(image), dst(dst), constraint(constraint) { |
| 177 this->src = src ? *src : SkRect::MakeIWH(image->width(), image->heig
ht()); |
| 178 if (paint) { this->paint = *paint; } |
| 179 } |
| 180 sk_sp<const SkImage> image; |
| 181 SkRect src, dst; |
| 182 SkPaint paint; |
| 183 SkCanvas::SrcRectConstraint constraint; |
| 184 void draw(SkCanvas* c) override { |
| 185 c->drawImageRect(image.get(), src, dst, &paint, constraint); |
| 186 } |
| 187 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &i
mage); } |
| 188 }; |
| 125 | 189 |
| 126 template <typename Fn> | 190 struct DrawText final : Op { |
| 127 static void map(SkTDArray<uint8_t>* bytes, Fn&& fn) { | 191 DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint) |
| 128 for (uint8_t* ptr = bytes->begin(); ptr < bytes->end(); ) { | 192 : bytes(bytes), x(x), y(y), paint(paint) {} |
| 129 auto op = (Op*)ptr; | 193 size_t bytes; |
| 130 fn(op); | 194 SkScalar x,y; |
| 131 ptr += op->skip; | 195 SkPaint paint; |
| 196 void draw(SkCanvas* c) override { c->drawText(this+1, bytes, x,y, paint)
; } |
| 197 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 198 }; |
| 199 struct DrawPosText final : Op { |
| 200 DrawPosText(size_t bytes, const SkPaint& paint) |
| 201 : bytes(bytes), paint(paint) {} |
| 202 size_t bytes; |
| 203 SkPaint paint; |
| 204 void draw(SkCanvas* c) override { |
| 205 auto pos = SkTAddOffset<SkPoint>(this+1, bytes); |
| 206 c->drawPosText(this+1, bytes, pos, paint); |
| 132 } | 207 } |
| 208 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 209 }; |
| 210 struct DrawPosTextH final : Op { |
| 211 DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint) |
| 212 : bytes(bytes), y(y), paint(paint) {} |
| 213 size_t bytes; |
| 214 SkScalar y; |
| 215 SkPaint paint; |
| 216 void draw(SkCanvas* c) override { |
| 217 auto xs = SkTAddOffset<SkScalar>(this+1, bytes); |
| 218 c->drawPosTextH(this+1, bytes, xs, y, paint); |
| 219 } |
| 220 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 221 }; |
| 222 struct DrawTextBlob final : Op { |
| 223 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPai
nt& paint) |
| 224 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {} |
| 225 sk_sp<const SkTextBlob> blob; |
| 226 SkScalar x,y; |
| 227 SkPaint paint; |
| 228 void draw(SkCanvas* c) override { c->drawTextBlob(blob.get(), x,y, paint
); } |
| 229 void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); } |
| 230 }; |
| 231 } |
| 232 |
| 233 template <typename T, typename... Args> |
| 234 static void* push(SkTDArray<uint8_t>* bytes, size_t pod, Args&&... args) { |
| 235 size_t skip = SkAlignPtr(sizeof(T) + pod); |
| 236 auto op = (T*)bytes->append(skip); |
| 237 new (op) T{ std::forward<Args>(args)... }; |
| 238 op->skip = skip; |
| 239 return op+1; |
| 240 } |
| 241 |
| 242 template <typename Fn> |
| 243 static void map(SkTDArray<uint8_t>* bytes, Fn&& fn) { |
| 244 for (uint8_t* ptr = bytes->begin(); ptr < bytes->end(); ) { |
| 245 auto op = (Op*)ptr; |
| 246 fn(op); |
| 247 ptr += op->skip; |
| 133 } | 248 } |
| 134 } | 249 } |
| 135 | 250 |
| 136 void SkLiteDL:: save() { push <Save>(&fBytes, 0); } | 251 void SkLiteDL:: save() { push <Save>(&fBytes, 0); } |
| 137 void SkLiteDL::restore() { push<Restore>(&fBytes, 0); } | 252 void SkLiteDL::restore() { push<Restore>(&fBytes, 0); } |
| 138 void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint, | 253 void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint, |
| 139 const SkImageFilter* backdrop, uint32_t flags) { | 254 const SkImageFilter* backdrop, uint32_t flags) { |
| 140 push<SaveLayer>(&fBytes, 0, bounds, paint, backdrop, flags); | 255 push<SaveLayer>(&fBytes, 0, bounds, paint, backdrop, flags); |
| 141 } | 256 } |
| 142 | 257 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 168 void SkLiteDL::drawOval(const SkRect& oval, const SkPaint& paint) { | 283 void SkLiteDL::drawOval(const SkRect& oval, const SkPaint& paint) { |
| 169 push<DrawOval>(&fBytes, 0, oval, paint); | 284 push<DrawOval>(&fBytes, 0, oval, paint); |
| 170 } | 285 } |
| 171 void SkLiteDL::drawRRect(const SkRRect& rrect, const SkPaint& paint) { | 286 void SkLiteDL::drawRRect(const SkRRect& rrect, const SkPaint& paint) { |
| 172 push<DrawRRect>(&fBytes, 0, rrect, paint); | 287 push<DrawRRect>(&fBytes, 0, rrect, paint); |
| 173 } | 288 } |
| 174 void SkLiteDL::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPa
int& paint) { | 289 void SkLiteDL::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPa
int& paint) { |
| 175 push<DrawDRRect>(&fBytes, 0, outer, inner, paint); | 290 push<DrawDRRect>(&fBytes, 0, outer, inner, paint); |
| 176 } | 291 } |
| 177 | 292 |
| 293 void SkLiteDL::drawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPa
int* paint) { |
| 294 push<DrawImage>(&fBytes, 0, SkImage::MakeFromBitmap(bm), x,y, paint); |
| 295 } |
| 296 void SkLiteDL::drawBitmapNine(const SkBitmap& bm, const SkIRect& center, |
| 297 const SkRect& dst, const SkPaint* paint) { |
| 298 push<DrawImageNine>(&fBytes, 0, SkImage::MakeFromBitmap(bm), center, dst, pa
int); |
| 299 } |
| 300 void SkLiteDL::drawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRec
t& dst, |
| 301 const SkPaint* paint, SkCanvas::SrcRectConstraint
constraint) { |
| 302 push<DrawImageRect>(&fBytes, 0, SkImage::MakeFromBitmap(bm), src, dst, paint
, constraint); |
| 303 } |
| 304 |
| 305 void SkLiteDL::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkP
aint* paint) { |
| 306 push<DrawImage>(&fBytes, 0, sk_ref_sp(image), x,y, paint); |
| 307 } |
| 308 void SkLiteDL::drawImageNine(const SkImage* image, const SkIRect& center, |
| 309 const SkRect& dst, const SkPaint* paint) { |
| 310 push<DrawImageNine>(&fBytes, 0, sk_ref_sp(image), center, dst, paint); |
| 311 } |
| 312 void SkLiteDL::drawImageRect(const SkImage* image, const SkRect* src, const SkRe
ct& dst, |
| 313 const SkPaint* paint, SkCanvas::SrcRectConstraint c
onstraint) { |
| 314 push<DrawImageRect>(&fBytes, 0, sk_ref_sp(image), src, dst, paint, constrain
t); |
| 315 } |
| 316 |
| 317 void SkLiteDL::drawText(const void* text, size_t bytes, |
| 318 SkScalar x, SkScalar y, const SkPaint& paint) { |
| 319 void* pod = push<DrawText>(&fBytes, bytes, bytes, x, y, paint); |
| 320 memcpy_v(pod, text,bytes); |
| 321 } |
| 322 void SkLiteDL::drawPosText(const void* text, size_t bytes, |
| 323 const SkPoint pos[], const SkPaint& paint) { |
| 324 int n = paint.countText(text, bytes); |
| 325 void* pod = push<DrawPosText>(&fBytes, bytes+n*sizeof(SkPoint), bytes, paint
); |
| 326 memcpy_v(pod, text,bytes, pos,n*sizeof(SkPoint)); |
| 327 } |
| 328 void SkLiteDL::drawPosTextH(const void* text, size_t bytes, |
| 329 const SkScalar xs[], SkScalar y, const SkPaint& paint
) { |
| 330 int n = paint.countText(text, bytes); |
| 331 void* pod = push<DrawPosTextH>(&fBytes, bytes + n*sizeof(SkScalar), bytes, y
, paint); |
| 332 memcpy_v(pod, text,bytes, xs,n*sizeof(SkScalar)); |
| 333 } |
| 334 void SkLiteDL::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, cons
t SkPaint& paint) { |
| 335 push<DrawTextBlob>(&fBytes, 0, blob, x,y, paint); |
| 336 } |
| 337 |
| 338 |
| 178 void SkLiteDL::onDraw(SkCanvas* canvas) { | 339 void SkLiteDL::onDraw(SkCanvas* canvas) { |
| 179 map(&fBytes, [canvas](Op* op) { op->draw(canvas); }); | 340 map(&fBytes, [canvas](Op* op) { op->draw(canvas); }); |
| 180 } | 341 } |
| 181 | 342 |
| 343 void SkLiteDL::optimizeFor(GrContext* ctx) { |
| 344 map(&fBytes, [ctx](Op* op) { op->optimizeFor(ctx); }); |
| 345 } |
| 346 |
| 182 SkRect SkLiteDL::onGetBounds() { | 347 SkRect SkLiteDL::onGetBounds() { |
| 183 return fBounds; | 348 return fBounds; |
| 184 } | 349 } |
| 185 | 350 |
| 186 SkLiteDL:: SkLiteDL() {} | 351 SkLiteDL:: SkLiteDL() {} |
| 187 SkLiteDL::~SkLiteDL() {} | 352 SkLiteDL::~SkLiteDL() {} |
| 188 | 353 |
| 189 static const int kFreeStackByteLimit = 128*1024; | 354 static const int kFreeStackByteLimit = 128*1024; |
| 190 static const int kFreeStackCountLimit = 8; | 355 static const int kFreeStackCountLimit = 8; |
| 191 | 356 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 if (gFreeStackCount < kFreeStackCountLimit) { | 391 if (gFreeStackCount < kFreeStackCountLimit) { |
| 227 self->fNext = gFreeStack; | 392 self->fNext = gFreeStack; |
| 228 gFreeStack = self; | 393 gFreeStack = self; |
| 229 gFreeStackCount++; | 394 gFreeStackCount++; |
| 230 return; | 395 return; |
| 231 } | 396 } |
| 232 } | 397 } |
| 233 | 398 |
| 234 delete this; | 399 delete this; |
| 235 } | 400 } |
| OLD | NEW |