OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
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 "SkImageFilter.h" | 8 #include "SkImageFilter.h" |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkBitmapDevice.h" | 11 #include "SkBitmapDevice.h" |
12 #include "SkChecksum.h" | 12 #include "SkChecksum.h" |
13 #include "SkDevice.h" | 13 #include "SkDevice.h" |
14 #include "SkLocalMatrixImageFilter.h" | 14 #include "SkLocalMatrixImageFilter.h" |
15 #include "SkMatrixImageFilter.h" | 15 #include "SkMatrixImageFilter.h" |
16 #include "SkMutex.h" | 16 #include "SkMutex.h" |
17 #include "SkOncePtr.h" | 17 #include "SkOncePtr.h" |
18 #include "SkReadBuffer.h" | 18 #include "SkReadBuffer.h" |
19 #include "SkRect.h" | 19 #include "SkRect.h" |
20 #include "SkTDynamicHash.h" | 20 #include "SkTDynamicHash.h" |
| 21 #include "SkTHash.h" |
21 #include "SkTInternalLList.h" | 22 #include "SkTInternalLList.h" |
22 #include "SkValidationUtils.h" | 23 #include "SkValidationUtils.h" |
23 #include "SkWriteBuffer.h" | 24 #include "SkWriteBuffer.h" |
24 #if SK_SUPPORT_GPU | 25 #if SK_SUPPORT_GPU |
25 #include "GrContext.h" | 26 #include "GrContext.h" |
26 #include "GrDrawContext.h" | 27 #include "GrDrawContext.h" |
27 #include "SkGrPixelRef.h" | 28 #include "SkGrPixelRef.h" |
28 #include "SkGr.h" | 29 #include "SkGr.h" |
29 #endif | 30 #endif |
30 | 31 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 fInputs[i] = inputs[i]; | 195 fInputs[i] = inputs[i]; |
195 SkSafeRef(fInputs[i]); | 196 SkSafeRef(fInputs[i]); |
196 } | 197 } |
197 } | 198 } |
198 | 199 |
199 SkImageFilter::~SkImageFilter() { | 200 SkImageFilter::~SkImageFilter() { |
200 for (int i = 0; i < fInputCount; i++) { | 201 for (int i = 0; i < fInputCount; i++) { |
201 SkSafeUnref(fInputs[i]); | 202 SkSafeUnref(fInputs[i]); |
202 } | 203 } |
203 delete[] fInputs; | 204 delete[] fInputs; |
| 205 Cache::Get()->purgeByImageFilterId(fUniqueID); |
204 } | 206 } |
205 | 207 |
206 SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer) | 208 SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer) |
207 : fUsesSrcInput(false) | 209 : fUsesSrcInput(false) |
208 , fUniqueID(next_image_filter_unique_id()) { | 210 , fUniqueID(next_image_filter_unique_id()) { |
209 Common common; | 211 Common common; |
210 if (common.unflatten(buffer, inputCount)) { | 212 if (common.unflatten(buffer, inputCount)) { |
211 fCropRect = common.cropRect(); | 213 fCropRect = common.cropRect(); |
212 fInputCount = common.inputCount(); | 214 fInputCount = common.inputCount(); |
213 fInputs = new SkImageFilter* [fInputCount]; | 215 fInputs = new SkImageFilter* [fInputCount]; |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 CacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) { | 561 CacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) { |
560 } | 562 } |
561 virtual ~CacheImpl() { | 563 virtual ~CacheImpl() { |
562 SkTDynamicHash<Value, Key>::Iter iter(&fLookup); | 564 SkTDynamicHash<Value, Key>::Iter iter(&fLookup); |
563 | 565 |
564 while (!iter.done()) { | 566 while (!iter.done()) { |
565 Value* v = &*iter; | 567 Value* v = &*iter; |
566 ++iter; | 568 ++iter; |
567 delete v; | 569 delete v; |
568 } | 570 } |
| 571 fIdToKeys.foreach([](uint32_t, SkTArray<Key>** array) { delete *array; }
); |
569 } | 572 } |
570 struct Value { | 573 struct Value { |
571 Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset) | 574 Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset) |
572 : fKey(key), fBitmap(bitmap), fOffset(offset) {} | 575 : fKey(key), fBitmap(bitmap), fOffset(offset) {} |
573 Key fKey; | 576 Key fKey; |
574 SkBitmap fBitmap; | 577 SkBitmap fBitmap; |
575 SkIPoint fOffset; | 578 SkIPoint fOffset; |
576 static const Key& GetKey(const Value& v) { | 579 static const Key& GetKey(const Value& v) { |
577 return v.fKey; | 580 return v.fKey; |
578 } | 581 } |
(...skipping 14 matching lines...) Expand all Loading... |
593 return true; | 596 return true; |
594 } | 597 } |
595 return false; | 598 return false; |
596 } | 599 } |
597 void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) ove
rride { | 600 void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) ove
rride { |
598 SkAutoMutexAcquire mutex(fMutex); | 601 SkAutoMutexAcquire mutex(fMutex); |
599 if (Value* v = fLookup.find(key)) { | 602 if (Value* v = fLookup.find(key)) { |
600 removeInternal(v); | 603 removeInternal(v); |
601 } | 604 } |
602 Value* v = new Value(key, result, offset); | 605 Value* v = new Value(key, result, offset); |
| 606 if (SkTArray<Key>** array = fIdToKeys.find(key.fUniqueID)) { |
| 607 (*array)->push_back(key); |
| 608 } else { |
| 609 SkTArray<Key>* keyArray = new SkTArray<Key>(); |
| 610 keyArray->push_back(key); |
| 611 fIdToKeys.set(key.fUniqueID, keyArray); |
| 612 } |
603 fLookup.add(v); | 613 fLookup.add(v); |
604 fLRU.addToHead(v); | 614 fLRU.addToHead(v); |
605 fCurrentBytes += result.getSize(); | 615 fCurrentBytes += result.getSize(); |
606 while (fCurrentBytes > fMaxBytes) { | 616 while (fCurrentBytes > fMaxBytes) { |
607 Value* tail = fLRU.tail(); | 617 Value* tail = fLRU.tail(); |
608 SkASSERT(tail); | 618 SkASSERT(tail); |
609 if (tail == v) { | 619 if (tail == v) { |
610 break; | 620 break; |
611 } | 621 } |
612 removeInternal(tail); | 622 removeInternal(tail); |
613 } | 623 } |
614 } | 624 } |
615 | 625 |
616 void purge() override { | 626 void purge() override { |
617 SkAutoMutexAcquire mutex(fMutex); | 627 SkAutoMutexAcquire mutex(fMutex); |
618 while (fCurrentBytes > 0) { | 628 while (fCurrentBytes > 0) { |
619 Value* tail = fLRU.tail(); | 629 Value* tail = fLRU.tail(); |
620 SkASSERT(tail); | 630 SkASSERT(tail); |
621 this->removeInternal(tail); | 631 this->removeInternal(tail); |
622 } | 632 } |
623 } | 633 } |
624 | 634 |
| 635 void purgeByImageFilterId(uint32_t uniqueID) override { |
| 636 SkAutoMutexAcquire mutex(fMutex); |
| 637 if (SkTArray<Key>** array = fIdToKeys.find(uniqueID)) { |
| 638 for (auto& key : **array) { |
| 639 if (Value* v = fLookup.find(key)) { |
| 640 this->removeInternal(v); |
| 641 } |
| 642 } |
| 643 fIdToKeys.remove(uniqueID); |
| 644 delete *array; // This can be deleted outside the lock |
| 645 } |
| 646 } |
| 647 |
625 private: | 648 private: |
626 void removeInternal(Value* v) { | 649 void removeInternal(Value* v) { |
627 fCurrentBytes -= v->fBitmap.getSize(); | 650 fCurrentBytes -= v->fBitmap.getSize(); |
628 fLRU.remove(v); | 651 fLRU.remove(v); |
629 fLookup.remove(v->fKey); | 652 fLookup.remove(v->fKey); |
630 delete v; | 653 delete v; |
631 } | 654 } |
632 private: | 655 private: |
633 SkTDynamicHash<Value, Key> fLookup; | 656 SkTDynamicHash<Value, Key> fLookup; |
634 mutable SkTInternalLList<Value> fLRU; | 657 SkTHashMap<uint32_t, SkTArray<Key>*> fIdToKeys; |
635 size_t fMaxBytes; | 658 mutable SkTInternalLList<Value> fLRU; |
636 size_t fCurrentBytes; | 659 size_t fMaxBytes; |
637 mutable SkMutex fMutex; | 660 size_t fCurrentBytes; |
| 661 mutable SkMutex fMutex; |
638 }; | 662 }; |
639 | 663 |
640 } // namespace | 664 } // namespace |
641 | 665 |
642 SkImageFilter::Cache* SkImageFilter::Cache::Create(size_t maxBytes) { | 666 SkImageFilter::Cache* SkImageFilter::Cache::Create(size_t maxBytes) { |
643 return new CacheImpl(maxBytes); | 667 return new CacheImpl(maxBytes); |
644 } | 668 } |
645 | 669 |
646 SK_DECLARE_STATIC_ONCE_PTR(SkImageFilter::Cache, cache); | 670 SK_DECLARE_STATIC_ONCE_PTR(SkImageFilter::Cache, cache); |
647 SkImageFilter::Cache* SkImageFilter::Cache::Get() { | 671 SkImageFilter::Cache* SkImageFilter::Cache::Get() { |
(...skipping 20 matching lines...) Expand all Loading... |
668 } | 692 } |
669 return dev; | 693 return dev; |
670 } | 694 } |
671 | 695 |
672 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, | 696 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, |
673 const SkImageFilter::Context& ctx, | 697 const SkImageFilter::Context& ctx, |
674 SkBitmap* result, SkIPoint* offset) { | 698 SkBitmap* result, SkIPoint* offset) { |
675 return fDevice->filterImage(filter, src, ctx, result, offset); | 699 return fDevice->filterImage(filter, src, ctx, result, offset); |
676 } | 700 } |
677 | 701 |
OLD | NEW |