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 |