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