| 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 |