| 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 "SkMath.h" |
| 12 #include "SkPicture.h" | 13 #include "SkPicture.h" |
| 13 #include "SkMutex.h" | 14 #include "SkMutex.h" |
| 14 #include "SkRSXform.h" | 15 #include "SkRSXform.h" |
| 15 #include "SkSpinlock.h" | 16 #include "SkSpinlock.h" |
| 16 #include "SkTextBlob.h" | 17 #include "SkTextBlob.h" |
| 17 | 18 |
| 19 #ifndef SKLITEDL_PAGE |
| 20 #define SKLITEDL_PAGE 4096 |
| 21 #endif |
| 22 |
| 18 // A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLa
yer(). | 23 // A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLa
yer(). |
| 19 static const SkRect kUnset = { SK_ScalarInfinity, 0,0,0}; | 24 static const SkRect kUnset = { SK_ScalarInfinity, 0,0,0}; |
| 20 static const SkRect* maybe_unset(const SkRect& r) { | 25 static const SkRect* maybe_unset(const SkRect& r) { |
| 21 return r.left() == SK_ScalarInfinity ? nullptr : &r; | 26 return r.left() == SK_ScalarInfinity ? nullptr : &r; |
| 22 } | 27 } |
| 23 | 28 |
| 24 // copy_v(dst, src,n, src,n, ...) copies an arbitrary number of typed srcs into
dst. | 29 // copy_v(dst, src,n, src,n, ...) copies an arbitrary number of typed srcs into
dst. |
| 25 static void copy_v(void* dst) {} | 30 static void copy_v(void* dst) {} |
| 26 | 31 |
| 27 template <typename S, typename... Rest> | 32 template <typename S, typename... Rest> |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 } | 525 } |
| 521 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &atlas); } | 526 void optimizeFor(GrContext* ctx) { optimize_for(ctx, &paint, &atlas); } |
| 522 }; | 527 }; |
| 523 } | 528 } |
| 524 | 529 |
| 525 template <typename T, typename... Args> | 530 template <typename T, typename... Args> |
| 526 void* SkLiteDL::push(size_t pod, Args&&... args) { | 531 void* SkLiteDL::push(size_t pod, Args&&... args) { |
| 527 size_t skip = SkAlignPtr(sizeof(T) + pod); | 532 size_t skip = SkAlignPtr(sizeof(T) + pod); |
| 528 SkASSERT(skip < (1<<24)); | 533 SkASSERT(skip < (1<<24)); |
| 529 if (fUsed + skip > fReserved) { | 534 if (fUsed + skip > fReserved) { |
| 530 fReserved = (fUsed + skip + 4096) & ~4095; // Next greater multiple of
4096. | 535 static_assert(SkIsPow2(SKLITEDL_PAGE), "This math needs updating for non
-pow2."); |
| 536 // Next greater multiple of SKLITEDL_PAGE. |
| 537 fReserved = (fUsed + skip + SKLITEDL_PAGE) & ~(SKLITEDL_PAGE-1); |
| 531 fBytes.realloc(fReserved); | 538 fBytes.realloc(fReserved); |
| 532 } | 539 } |
| 533 SkASSERT(fUsed + skip <= fReserved); | 540 SkASSERT(fUsed + skip <= fReserved); |
| 534 auto op = (T*)(fBytes.get() + fUsed); | 541 auto op = (T*)(fBytes.get() + fUsed); |
| 535 fUsed += skip; | 542 fUsed += skip; |
| 536 new (op) T{ std::forward<Args>(args)... }; | 543 new (op) T{ std::forward<Args>(args)... }; |
| 537 op->type = (uint32_t)T::kType; | 544 op->type = (uint32_t)T::kType; |
| 538 op->skip = skip; | 545 op->skip = skip; |
| 539 return op+1; | 546 return op+1; |
| 540 } | 547 } |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 void SkLiteDL::makeThreadsafe() { this->map(make_threadsafe_fns)
; } | 759 void SkLiteDL::makeThreadsafe() { this->map(make_threadsafe_fns)
; } |
| 753 | 760 |
| 754 SkRect SkLiteDL::onGetBounds() { | 761 SkRect SkLiteDL::onGetBounds() { |
| 755 return fBounds; | 762 return fBounds; |
| 756 } | 763 } |
| 757 | 764 |
| 758 bool SkLiteDL::empty() const { | 765 bool SkLiteDL::empty() const { |
| 759 return fUsed == 0; | 766 return fUsed == 0; |
| 760 } | 767 } |
| 761 | 768 |
| 762 #if !defined(SK_LITEDL_USES) | 769 SkLiteDL:: SkLiteDL(SkRect bounds) : fUsed(0), fReserved(0), fBounds(bounds) {} |
| 763 #define SK_LITEDL_USES 16 | |
| 764 #endif | |
| 765 | 770 |
| 766 SkLiteDL:: SkLiteDL() : fUsed(0), fReserved(0), fUsesRemaining(SK_LITEDL_USES) {
} | 771 SkLiteDL::~SkLiteDL() { |
| 767 SkLiteDL::~SkLiteDL() {} | 772 this->reset(SkRect::MakeEmpty()); |
| 768 | 773 } |
| 769 // If you're tempted to make this lock free, please don't forget about ABA. | |
| 770 static SkSpinlock gFreeStackLock; | |
| 771 static SkLiteDL* gFreeStack = nullptr; | |
| 772 | 774 |
| 773 sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) { | 775 sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) { |
| 774 sk_sp<SkLiteDL> dl; | 776 return sk_sp<SkLiteDL>(new SkLiteDL(bounds)); |
| 775 { | |
| 776 SkAutoMutexAcquire lock(gFreeStackLock); | |
| 777 if (gFreeStack) { | |
| 778 dl.reset(gFreeStack); // Adopts the ref the stack's been holding. | |
| 779 gFreeStack = gFreeStack->fNext; | |
| 780 } | |
| 781 } | |
| 782 | |
| 783 if (!dl) { | |
| 784 dl.reset(new SkLiteDL); | |
| 785 } | |
| 786 | |
| 787 dl->fBounds = bounds; | |
| 788 return dl; | |
| 789 } | 777 } |
| 790 | 778 |
| 791 void SkLiteDL::internal_dispose() const { | 779 void SkLiteDL::reset(SkRect bounds) { |
| 792 // Whether we delete this or leave it on the free stack, | 780 SkASSERT(this->unique()); |
| 793 // we want its refcnt at 1. | 781 this->map(dtor_fns); |
| 794 this->internal_dispose_restore_refcnt_to_1(); | |
| 795 | 782 |
| 796 auto self = const_cast<SkLiteDL*>(this); | 783 // Leave fBytes and fReserved alone. |
| 797 self->map(dtor_fns); | 784 fUsed = 0; |
| 798 | 785 fBounds = bounds; |
| 799 if (--self->fUsesRemaining > 0) { | |
| 800 self->fUsed = 0; | |
| 801 | |
| 802 SkAutoMutexAcquire lock(gFreeStackLock); | |
| 803 self->fNext = gFreeStack; | |
| 804 gFreeStack = self; | |
| 805 return; | |
| 806 } | |
| 807 | |
| 808 delete this; | |
| 809 } | 786 } |
| 810 | |
| 811 void SkLiteDL::PurgeFreelist() { | |
| 812 SkAutoMutexAcquire lock(gFreeStackLock); | |
| 813 while (gFreeStack) { | |
| 814 SkLiteDL* top = gFreeStack; | |
| 815 gFreeStack = gFreeStack->fNext; | |
| 816 delete top; // Calling unref() here would just put it back on the list
! | |
| 817 } | |
| 818 } | |
| OLD | NEW |