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 #include "SkImageFilterCacheKey.h" |
9 | 10 |
10 #include "SkBitmap.h" | 11 #include "SkBitmap.h" |
11 #include "SkBitmapDevice.h" | 12 #include "SkBitmapDevice.h" |
12 #include "SkChecksum.h" | 13 #include "SkChecksum.h" |
13 #include "SkDevice.h" | 14 #include "SkDevice.h" |
14 #include "SkLocalMatrixImageFilter.h" | 15 #include "SkLocalMatrixImageFilter.h" |
15 #include "SkMatrixImageFilter.h" | 16 #include "SkMatrixImageFilter.h" |
16 #include "SkOncePtr.h" | 17 #include "SkOncePtr.h" |
17 #include "SkReadBuffer.h" | 18 #include "SkReadBuffer.h" |
18 #include "SkRect.h" | 19 #include "SkRect.h" |
| 20 #include "SkSpecialImage.h" |
19 #include "SkTDynamicHash.h" | 21 #include "SkTDynamicHash.h" |
20 #include "SkTInternalLList.h" | 22 #include "SkTInternalLList.h" |
21 #include "SkValidationUtils.h" | 23 #include "SkValidationUtils.h" |
22 #include "SkWriteBuffer.h" | 24 #include "SkWriteBuffer.h" |
23 #if SK_SUPPORT_GPU | 25 #if SK_SUPPORT_GPU |
24 #include "GrContext.h" | 26 #include "GrContext.h" |
25 #include "GrDrawContext.h" | 27 #include "GrDrawContext.h" |
26 #include "SkGrPixelRef.h" | 28 #include "SkGrPixelRef.h" |
27 #include "SkGr.h" | 29 #include "SkGr.h" |
28 #endif | 30 #endif |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 static int32_t gImageFilterUniqueID; | 97 static int32_t gImageFilterUniqueID; |
96 | 98 |
97 // Never return 0. | 99 // Never return 0. |
98 int32_t id; | 100 int32_t id; |
99 do { | 101 do { |
100 id = sk_atomic_inc(&gImageFilterUniqueID) + 1; | 102 id = sk_atomic_inc(&gImageFilterUniqueID) + 1; |
101 } while (0 == id); | 103 } while (0 == id); |
102 return id; | 104 return id; |
103 } | 105 } |
104 | 106 |
105 struct SkImageFilter::Cache::Key { | |
106 Key(const uint32_t uniqueID, const SkMatrix& matrix, const SkIRect& clipBoun
ds, uint32_t srcGenID) | |
107 : fUniqueID(uniqueID), fMatrix(matrix), fClipBounds(clipBounds), fSrcGenID
(srcGenID) { | |
108 // Assert that Key is tightly-packed, since it is hashed. | |
109 static_assert(sizeof(Key) == sizeof(uint32_t) + sizeof(SkMatrix) + sizeo
f(SkIRect) + | |
110 sizeof(uint32_t), "image_filter_key_tight_p
acking"); | |
111 fMatrix.getType(); // force initialization of type, so hashes match | |
112 } | |
113 uint32_t fUniqueID; | |
114 SkMatrix fMatrix; | |
115 SkIRect fClipBounds; | |
116 uint32_t fSrcGenID; | |
117 bool operator==(const Key& other) const { | |
118 return fUniqueID == other.fUniqueID | |
119 && fMatrix == other.fMatrix | |
120 && fClipBounds == other.fClipBounds | |
121 && fSrcGenID == other.fSrcGenID; | |
122 } | |
123 }; | |
124 | |
125 SkImageFilter::Common::~Common() { | 107 SkImageFilter::Common::~Common() { |
126 for (int i = 0; i < fInputs.count(); ++i) { | 108 for (int i = 0; i < fInputs.count(); ++i) { |
127 SkSafeUnref(fInputs[i]); | 109 SkSafeUnref(fInputs[i]); |
128 } | 110 } |
129 } | 111 } |
130 | 112 |
131 void SkImageFilter::Common::allocInputs(int count) { | 113 void SkImageFilter::Common::allocInputs(int count) { |
132 const size_t size = count * sizeof(SkImageFilter*); | 114 const size_t size = count * sizeof(SkImageFilter*); |
133 fInputs.reset(count); | 115 fInputs.reset(count); |
134 sk_bzero(fInputs.get(), size); | 116 sk_bzero(fInputs.get(), size); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 buffer.writeRect(fCropRect.rect()); | 212 buffer.writeRect(fCropRect.rect()); |
231 buffer.writeUInt(fCropRect.flags()); | 213 buffer.writeUInt(fCropRect.flags()); |
232 } | 214 } |
233 | 215 |
234 bool SkImageFilter::filterImageDeprecated(Proxy* proxy, const SkBitmap& src, | 216 bool SkImageFilter::filterImageDeprecated(Proxy* proxy, const SkBitmap& src, |
235 const Context& context, | 217 const Context& context, |
236 SkBitmap* result, SkIPoint* offset) co
nst { | 218 SkBitmap* result, SkIPoint* offset) co
nst { |
237 SkASSERT(result); | 219 SkASSERT(result); |
238 SkASSERT(offset); | 220 SkASSERT(offset); |
239 uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0; | 221 uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0; |
240 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcGenID); | 222 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), |
| 223 srcGenID, SkIRect::MakeWH(0, 0)); |
241 if (context.cache()) { | 224 if (context.cache()) { |
242 if (context.cache()->get(key, result, offset)) { | 225 if (context.cache()->get(key, result, offset)) { |
243 return true; | 226 return true; |
244 } | 227 } |
245 } | 228 } |
246 /* | 229 /* |
247 * Give the proxy first shot at the filter. If it returns false, ask | 230 * Give the proxy first shot at the filter. If it returns false, ask |
248 * the filter to do it. | 231 * the filter to do it. |
249 */ | 232 */ |
250 if ((proxy && proxy->filterImage(this, src, context, result, offset)) || | 233 if ((proxy && proxy->filterImage(this, src, context, result, offset)) || |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 } else { | 507 } else { |
525 return false; | 508 return false; |
526 } | 509 } |
527 } | 510 } |
528 #endif | 511 #endif |
529 | 512 |
530 namespace { | 513 namespace { |
531 | 514 |
532 class CacheImpl : public SkImageFilter::Cache { | 515 class CacheImpl : public SkImageFilter::Cache { |
533 public: | 516 public: |
534 CacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) { | 517 CacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) { } |
535 } | 518 ~CacheImpl() override { |
536 virtual ~CacheImpl() { | |
537 SkTDynamicHash<Value, Key>::Iter iter(&fLookup); | 519 SkTDynamicHash<Value, Key>::Iter iter(&fLookup); |
538 | 520 |
539 while (!iter.done()) { | 521 while (!iter.done()) { |
540 Value* v = &*iter; | 522 Value* v = &*iter; |
541 ++iter; | 523 ++iter; |
542 delete v; | 524 delete v; |
543 } | 525 } |
544 } | 526 } |
545 struct Value { | 527 struct Value { |
546 Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset) | 528 Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset) |
547 : fKey(key), fBitmap(bitmap), fOffset(offset) {} | 529 : fKey(key), fBitmap(bitmap), fOffset(offset) {} |
| 530 Value(const Key& key, SkSpecialImage* image, const SkIPoint& offset) |
| 531 : fKey(key), fImage(SkRef(image)), fOffset(offset) {} |
| 532 |
548 Key fKey; | 533 Key fKey; |
549 SkBitmap fBitmap; | 534 SkBitmap fBitmap; |
| 535 SkAutoTUnref<SkSpecialImage> fImage; |
550 SkIPoint fOffset; | 536 SkIPoint fOffset; |
551 static const Key& GetKey(const Value& v) { | 537 static const Key& GetKey(const Value& v) { |
552 return v.fKey; | 538 return v.fKey; |
553 } | 539 } |
554 static uint32_t Hash(const Key& key) { | 540 static uint32_t Hash(const Key& key) { |
555 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key),
sizeof(Key)); | 541 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key),
sizeof(Key)); |
556 } | 542 } |
557 SK_DECLARE_INTERNAL_LLIST_INTERFACE(Value); | 543 SK_DECLARE_INTERNAL_LLIST_INTERFACE(Value); |
558 }; | 544 }; |
| 545 |
559 bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const override
{ | 546 bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const override
{ |
560 SkAutoMutexAcquire mutex(fMutex); | 547 SkAutoMutexAcquire mutex(fMutex); |
561 if (Value* v = fLookup.find(key)) { | 548 if (Value* v = fLookup.find(key)) { |
562 *result = v->fBitmap; | 549 *result = v->fBitmap; |
563 *offset = v->fOffset; | 550 *offset = v->fOffset; |
564 if (v != fLRU.head()) { | 551 if (v != fLRU.head()) { |
565 fLRU.remove(v); | 552 fLRU.remove(v); |
566 fLRU.addToHead(v); | 553 fLRU.addToHead(v); |
567 } | 554 } |
568 return true; | 555 return true; |
569 } | 556 } |
570 return false; | 557 return false; |
571 } | 558 } |
| 559 |
| 560 SkSpecialImage* get(const Key& key, SkIPoint* offset) const override { |
| 561 SkAutoMutexAcquire mutex(fMutex); |
| 562 if (Value* v = fLookup.find(key)) { |
| 563 *offset = v->fOffset; |
| 564 if (v != fLRU.head()) { |
| 565 fLRU.remove(v); |
| 566 fLRU.addToHead(v); |
| 567 } |
| 568 return v->fImage; |
| 569 } |
| 570 return nullptr; |
| 571 } |
| 572 |
572 void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) ove
rride { | 573 void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) ove
rride { |
573 SkAutoMutexAcquire mutex(fMutex); | 574 SkAutoMutexAcquire mutex(fMutex); |
574 if (Value* v = fLookup.find(key)) { | 575 if (Value* v = fLookup.find(key)) { |
575 removeInternal(v); | 576 this->removeInternal(v); |
576 } | 577 } |
577 Value* v = new Value(key, result, offset); | 578 Value* v = new Value(key, result, offset); |
578 fLookup.add(v); | 579 fLookup.add(v); |
579 fLRU.addToHead(v); | 580 fLRU.addToHead(v); |
580 fCurrentBytes += result.getSize(); | 581 fCurrentBytes += result.getSize(); |
581 while (fCurrentBytes > fMaxBytes) { | 582 while (fCurrentBytes > fMaxBytes) { |
582 Value* tail = fLRU.tail(); | 583 Value* tail = fLRU.tail(); |
583 SkASSERT(tail); | 584 SkASSERT(tail); |
584 if (tail == v) { | 585 if (tail == v) { |
585 break; | 586 break; |
586 } | 587 } |
587 removeInternal(tail); | 588 this->removeInternal(tail); |
588 } | 589 } |
589 } | 590 } |
590 | 591 |
| 592 void set(const Key& key, SkSpecialImage* image, const SkIPoint& offset) over
ride { |
| 593 SkAutoMutexAcquire mutex(fMutex); |
| 594 if (Value* v = fLookup.find(key)) { |
| 595 this->removeInternal(v); |
| 596 } |
| 597 Value* v = new Value(key, image, offset); |
| 598 fLookup.add(v); |
| 599 fLRU.addToHead(v); |
| 600 fCurrentBytes += image->getSize(); |
| 601 while (fCurrentBytes > fMaxBytes) { |
| 602 Value* tail = fLRU.tail(); |
| 603 SkASSERT(tail); |
| 604 if (tail == v) { |
| 605 break; |
| 606 } |
| 607 this->removeInternal(tail); |
| 608 } |
| 609 } |
| 610 |
591 void purge() override { | 611 void purge() override { |
592 SkAutoMutexAcquire mutex(fMutex); | 612 SkAutoMutexAcquire mutex(fMutex); |
593 while (fCurrentBytes > 0) { | 613 while (fCurrentBytes > 0) { |
594 Value* tail = fLRU.tail(); | 614 Value* tail = fLRU.tail(); |
595 SkASSERT(tail); | 615 SkASSERT(tail); |
596 this->removeInternal(tail); | 616 this->removeInternal(tail); |
597 } | 617 } |
598 } | 618 } |
599 | 619 |
600 void purgeByKeys(const Key keys[], int count) override { | 620 void purgeByKeys(const Key keys[], int count) override { |
601 SkAutoMutexAcquire mutex(fMutex); | 621 SkAutoMutexAcquire mutex(fMutex); |
602 for (int i = 0; i < count; i++) { | 622 for (int i = 0; i < count; i++) { |
603 if (Value* v = fLookup.find(keys[i])) { | 623 if (Value* v = fLookup.find(keys[i])) { |
604 this->removeInternal(v); | 624 this->removeInternal(v); |
605 } | 625 } |
606 } | 626 } |
607 } | 627 } |
608 | 628 |
609 private: | 629 private: |
610 void removeInternal(Value* v) { | 630 void removeInternal(Value* v) { |
611 fCurrentBytes -= v->fBitmap.getSize(); | 631 if (v->fImage) { |
| 632 fCurrentBytes -= v->fImage->getSize(); |
| 633 } else { |
| 634 fCurrentBytes -= v->fBitmap.getSize(); |
| 635 } |
612 fLRU.remove(v); | 636 fLRU.remove(v); |
613 fLookup.remove(v->fKey); | 637 fLookup.remove(v->fKey); |
614 delete v; | 638 delete v; |
615 } | 639 } |
616 private: | 640 private: |
617 SkTDynamicHash<Value, Key> fLookup; | 641 SkTDynamicHash<Value, Key> fLookup; |
618 mutable SkTInternalLList<Value> fLRU; | 642 mutable SkTInternalLList<Value> fLRU; |
619 size_t fMaxBytes; | 643 size_t fMaxBytes; |
620 size_t fCurrentBytes; | 644 size_t fCurrentBytes; |
621 mutable SkMutex fMutex; | 645 mutable SkMutex fMutex; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 } | 677 } |
654 return dev; | 678 return dev; |
655 } | 679 } |
656 | 680 |
657 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, | 681 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, |
658 const SkImageFilter::Context& ctx, | 682 const SkImageFilter::Context& ctx, |
659 SkBitmap* result, SkIPoint* offset) { | 683 SkBitmap* result, SkIPoint* offset) { |
660 return fDevice->filterImage(filter, src, ctx, result, offset); | 684 return fDevice->filterImage(filter, src, ctx, result, offset); |
661 } | 685 } |
662 | 686 |
OLD | NEW |