| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * Copyright 2016 Google Inc. | 
|  | 3  * | 
|  | 4  * Use of this source code is governed by a BSD-style license that can be | 
|  | 5  * found in the LICENSE file. | 
|  | 6  */ | 
|  | 7 | 
|  | 8 #include "SkCanvas.h" | 
|  | 9 #include "SkLiteDL.h" | 
|  | 10 #include "SkMutex.h" | 
|  | 11 #include "SkSpinlock.h" | 
|  | 12 | 
|  | 13 namespace { | 
|  | 14     struct Op { | 
|  | 15         virtual ~Op() {} | 
|  | 16         virtual void draw(SkCanvas*) = 0; | 
|  | 17 | 
|  | 18         size_t skip; | 
|  | 19     }; | 
|  | 20 | 
|  | 21     struct Save    final : Op { void draw(SkCanvas* c) override { c->   save(); 
     } }; | 
|  | 22     struct Restore final : Op { void draw(SkCanvas* c) override { c->restore(); 
     } }; | 
|  | 23 | 
|  | 24     struct Concat final : Op { | 
|  | 25         Concat(const SkMatrix& matrix) : matrix(matrix) {} | 
|  | 26         SkMatrix matrix; | 
|  | 27         void draw(SkCanvas* c) override { c->concat(matrix); } | 
|  | 28     }; | 
|  | 29     struct SetMatrix final : Op { | 
|  | 30         SetMatrix(const SkMatrix& matrix) : matrix(matrix) {} | 
|  | 31         SkMatrix matrix; | 
|  | 32         void draw(SkCanvas* c) override { c->setMatrix(matrix); } | 
|  | 33     }; | 
|  | 34 | 
|  | 35     struct ClipRect final : Op { | 
|  | 36         ClipRect(const SkRect& rect, SkRegion::Op op, bool aa) : rect(rect), op(
     op), aa(aa) {} | 
|  | 37         SkRect       rect; | 
|  | 38         SkRegion::Op op; | 
|  | 39         bool         aa; | 
|  | 40         void draw(SkCanvas* c) override { c->clipRect(rect, op, aa); } | 
|  | 41     }; | 
|  | 42 | 
|  | 43     struct DrawRect final : Op { | 
|  | 44         DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(p
     aint) {} | 
|  | 45         SkRect  rect; | 
|  | 46         SkPaint paint; | 
|  | 47         void draw(SkCanvas* c) override { c->drawRect(rect, paint); } | 
|  | 48     }; | 
|  | 49 | 
|  | 50     struct DrawPath final : Op { | 
|  | 51         DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(p
     aint) {} | 
|  | 52         SkPath  path; | 
|  | 53         SkPaint paint; | 
|  | 54         void draw(SkCanvas* c) override { c->drawPath(path, paint); } | 
|  | 55     }; | 
|  | 56 | 
|  | 57     template <typename T, typename... Args> | 
|  | 58     static void* push(SkTDArray<uint8_t>* bytes, size_t pod, Args&&... args) { | 
|  | 59         size_t skip = SkAlignPtr(sizeof(T) + pod); | 
|  | 60         auto op = (T*)bytes->append(skip); | 
|  | 61         new (op) T{ std::forward<Args>(args)... }; | 
|  | 62         op->skip = skip; | 
|  | 63         return op+1; | 
|  | 64     } | 
|  | 65 | 
|  | 66     template <typename Fn> | 
|  | 67     static void map(SkTDArray<uint8_t>* bytes, Fn&& fn) { | 
|  | 68         for (uint8_t* ptr = bytes->begin(); ptr < bytes->end(); ) { | 
|  | 69             auto op = (Op*)ptr; | 
|  | 70             fn(op); | 
|  | 71             ptr += op->skip; | 
|  | 72         } | 
|  | 73     } | 
|  | 74 } | 
|  | 75 | 
|  | 76 void SkLiteDL::   save() { push   <Save>(&fBytes, 0); } | 
|  | 77 void SkLiteDL::restore() { push<Restore>(&fBytes, 0); } | 
|  | 78 | 
|  | 79 void SkLiteDL::   concat(const SkMatrix& matrix) { push   <Concat>(&fBytes, 0, m
     atrix); } | 
|  | 80 void SkLiteDL::setMatrix(const SkMatrix& matrix) { push<SetMatrix>(&fBytes, 0, m
     atrix); } | 
|  | 81 | 
|  | 82 void SkLiteDL::clipRect(const SkRect& rect, SkRegion::Op op, bool aa) { | 
|  | 83     push<ClipRect>(&fBytes, 0, rect, op, aa); | 
|  | 84 } | 
|  | 85 | 
|  | 86 void SkLiteDL::drawRect(const SkRect& rect, const SkPaint& paint) { | 
|  | 87     push<DrawRect>(&fBytes, 0, rect, paint); | 
|  | 88 } | 
|  | 89 void SkLiteDL::drawPath(const SkPath& path, const SkPaint& paint) { | 
|  | 90     push<DrawPath>(&fBytes, 0, path, paint); | 
|  | 91 } | 
|  | 92 | 
|  | 93 void SkLiteDL::onDraw(SkCanvas* canvas) { | 
|  | 94     map(&fBytes, [canvas](Op* op) { op->draw(canvas); }); | 
|  | 95 } | 
|  | 96 | 
|  | 97 SkRect SkLiteDL::onGetBounds() { | 
|  | 98     return fBounds; | 
|  | 99 } | 
|  | 100 | 
|  | 101 SkLiteDL:: SkLiteDL() {} | 
|  | 102 SkLiteDL::~SkLiteDL() {} | 
|  | 103 | 
|  | 104 static const int kFreeStackByteLimit  = 128*1024; | 
|  | 105 static const int kFreeStackCountLimit = 8; | 
|  | 106 | 
|  | 107 static SkSpinlock gFreeStackLock; | 
|  | 108 static SkLiteDL*  gFreeStack      = nullptr; | 
|  | 109 static int        gFreeStackCount = 0; | 
|  | 110 | 
|  | 111 sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) { | 
|  | 112     sk_sp<SkLiteDL> dl; | 
|  | 113     { | 
|  | 114         SkAutoMutexAcquire lock(gFreeStackLock); | 
|  | 115         if (gFreeStack) { | 
|  | 116             dl.reset(gFreeStack);  // Adopts the ref the stack's been holding. | 
|  | 117             gFreeStack = gFreeStack->fNext; | 
|  | 118             gFreeStackCount--; | 
|  | 119         } | 
|  | 120     } | 
|  | 121 | 
|  | 122     if (!dl) { | 
|  | 123         dl.reset(new SkLiteDL); | 
|  | 124     } | 
|  | 125 | 
|  | 126     dl->fBounds = bounds; | 
|  | 127     return dl; | 
|  | 128 } | 
|  | 129 | 
|  | 130 void SkLiteDL::internal_dispose() const { | 
|  | 131     // Whether we delete this or leave it on the free stack, | 
|  | 132     // we want its refcnt at 1. | 
|  | 133     this->internal_dispose_restore_refcnt_to_1(); | 
|  | 134 | 
|  | 135     auto self = const_cast<SkLiteDL*>(this); | 
|  | 136     map(&self->fBytes, [](Op* op) { op->~Op(); }); | 
|  | 137 | 
|  | 138     if (self->fBytes.reserved() < kFreeStackByteLimit) { | 
|  | 139         self->fBytes.rewind(); | 
|  | 140         SkAutoMutexAcquire lock(gFreeStackLock); | 
|  | 141         if (gFreeStackCount < kFreeStackCountLimit) { | 
|  | 142             self->fNext = gFreeStack; | 
|  | 143             gFreeStack = self; | 
|  | 144             gFreeStackCount++; | 
|  | 145             return; | 
|  | 146         } | 
|  | 147     } | 
|  | 148 | 
|  | 149     delete this; | 
|  | 150 } | 
| OLD | NEW | 
|---|