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" |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 } | 656 } |
657 | 657 |
658 void SkLiteDL::makeThreadsafe() { | 658 void SkLiteDL::makeThreadsafe() { |
659 map(&fBytes, [](Op* op) { op->makeThreadsafe(); }); | 659 map(&fBytes, [](Op* op) { op->makeThreadsafe(); }); |
660 } | 660 } |
661 | 661 |
662 SkRect SkLiteDL::onGetBounds() { | 662 SkRect SkLiteDL::onGetBounds() { |
663 return fBounds; | 663 return fBounds; |
664 } | 664 } |
665 | 665 |
666 SkLiteDL:: SkLiteDL() {} | 666 #if !defined(SK_LITEDL_USES) |
| 667 #define SK_LITEDL_USES 16 |
| 668 #endif |
| 669 |
| 670 SkLiteDL:: SkLiteDL() : fUsesRemaining(SK_LITEDL_USES) {} |
667 SkLiteDL::~SkLiteDL() {} | 671 SkLiteDL::~SkLiteDL() {} |
668 | 672 |
669 static const int kFreeStackByteLimit = 128*1024; | 673 // If you're tempted to make this lock free, please don't forget about ABA. |
670 static const int kFreeStackCountLimit = 8; | |
671 | |
672 static SkSpinlock gFreeStackLock; | 674 static SkSpinlock gFreeStackLock; |
673 static SkLiteDL* gFreeStack = nullptr; | 675 static SkLiteDL* gFreeStack = nullptr; |
674 static int gFreeStackCount = 0; | |
675 | 676 |
676 sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) { | 677 sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) { |
677 sk_sp<SkLiteDL> dl; | 678 sk_sp<SkLiteDL> dl; |
678 { | 679 { |
679 SkAutoMutexAcquire lock(gFreeStackLock); | 680 SkAutoMutexAcquire lock(gFreeStackLock); |
680 if (gFreeStack) { | 681 if (gFreeStack) { |
681 dl.reset(gFreeStack); // Adopts the ref the stack's been holding. | 682 dl.reset(gFreeStack); // Adopts the ref the stack's been holding. |
682 gFreeStack = gFreeStack->fNext; | 683 gFreeStack = gFreeStack->fNext; |
683 gFreeStackCount--; | |
684 } | 684 } |
685 } | 685 } |
686 | 686 |
687 if (!dl) { | 687 if (!dl) { |
688 dl.reset(new SkLiteDL); | 688 dl.reset(new SkLiteDL); |
689 } | 689 } |
690 | 690 |
691 dl->fBounds = bounds; | 691 dl->fBounds = bounds; |
692 return dl; | 692 return dl; |
693 } | 693 } |
694 | 694 |
695 void SkLiteDL::internal_dispose() const { | 695 void SkLiteDL::internal_dispose() const { |
696 // Whether we delete this or leave it on the free stack, | 696 // Whether we delete this or leave it on the free stack, |
697 // we want its refcnt at 1. | 697 // we want its refcnt at 1. |
698 this->internal_dispose_restore_refcnt_to_1(); | 698 this->internal_dispose_restore_refcnt_to_1(); |
699 | 699 |
700 auto self = const_cast<SkLiteDL*>(this); | 700 auto self = const_cast<SkLiteDL*>(this); |
701 map(&self->fBytes, [](Op* op) { op->~Op(); }); | 701 map(&self->fBytes, [](Op* op) { op->~Op(); }); |
702 | 702 |
703 if (self->fBytes.reserved() < kFreeStackByteLimit) { | 703 if (--self->fUsesRemaining > 0) { |
704 self->fBytes.rewind(); | 704 self->fBytes.rewind(); |
| 705 |
705 SkAutoMutexAcquire lock(gFreeStackLock); | 706 SkAutoMutexAcquire lock(gFreeStackLock); |
706 if (gFreeStackCount < kFreeStackCountLimit) { | 707 self->fNext = gFreeStack; |
707 self->fNext = gFreeStack; | 708 gFreeStack = self; |
708 gFreeStack = self; | 709 return; |
709 gFreeStackCount++; | |
710 return; | |
711 } | |
712 } | 710 } |
713 | 711 |
714 delete this; | 712 delete this; |
715 } | 713 } |
OLD | NEW |