Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: src/core/SkImageFilter.cpp

Issue 1381523002: Revert of Implement SkImageFilter::Cache with SkResourceCache. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkImageFilter.h ('k') | src/core/SkResourceCache.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkMatrixImageFilter.h" 14 #include "SkMatrixImageFilter.h"
15 #include "SkMutex.h" 15 #include "SkMutex.h"
16 #include "SkOncePtr.h" 16 #include "SkOncePtr.h"
17 #include "SkPixelRef.h"
18 #include "SkReadBuffer.h" 17 #include "SkReadBuffer.h"
19 #include "SkRect.h" 18 #include "SkRect.h"
20 #include "SkResourceCache.h"
21 #include "SkTDynamicHash.h" 19 #include "SkTDynamicHash.h"
22 #include "SkTInternalLList.h" 20 #include "SkTInternalLList.h"
23 #include "SkValidationUtils.h" 21 #include "SkValidationUtils.h"
24 #include "SkWriteBuffer.h" 22 #include "SkWriteBuffer.h"
25 #if SK_SUPPORT_GPU 23 #if SK_SUPPORT_GPU
26 #include "GrContext.h" 24 #include "GrContext.h"
27 #include "GrDrawContext.h" 25 #include "GrDrawContext.h"
28 #include "SkGrPixelRef.h" 26 #include "SkGrPixelRef.h"
29 #include "SkGr.h" 27 #include "SkGr.h"
30 #endif 28 #endif
31 29
30 #ifdef SK_BUILD_FOR_IOS
31 enum { kDefaultCacheSize = 2 * 1024 * 1024 };
32 #else
33 enum { kDefaultCacheSize = 128 * 1024 * 1024 };
34 #endif
35
32 #ifndef SK_IGNORE_TO_STRING 36 #ifndef SK_IGNORE_TO_STRING
33 void SkImageFilter::CropRect::toString(SkString* str) const { 37 void SkImageFilter::CropRect::toString(SkString* str) const {
34 if (!fFlags) { 38 if (!fFlags) {
35 return; 39 return;
36 } 40 }
37 41
38 str->appendf("cropRect ("); 42 str->appendf("cropRect (");
39 if (fFlags & CropRect::kHasLeft_CropEdge) { 43 if (fFlags & CropRect::kHasLeft_CropEdge) {
40 str->appendf("%.2f, ", fRect.fLeft); 44 str->appendf("%.2f, ", fRect.fLeft);
41 } else { 45 } else {
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 return true; 470 return true;
467 } else { 471 } else {
468 return false; 472 return false;
469 } 473 }
470 } 474 }
471 } 475 }
472 #endif 476 #endif
473 477
474 namespace { 478 namespace {
475 479
476 class ImageFilterRec : public SkResourceCache::Rec { 480 class CacheImpl : public SkImageFilter::Cache {
477 public: 481 public:
478 struct Keys { 482 CacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) {
479 Keys(SkImageFilter::Cache::Key ifcKey) : fIFCKey(ifcKey) { 483 }
480 static bool unique_namespace; 484 virtual ~CacheImpl() {
481 fRCKey.init(&unique_namespace, 485 SkTDynamicHash<Value, Key>::Iter iter(&fLookup);
482 0 /*shared ids allow fine-grained purging, which we can' t use here*/, 486
483 sizeof(fIFCKey)); 487 while (!iter.done()) {
488 Value* v = &*iter;
489 ++iter;
490 delete v;
484 } 491 }
485 // The SkImageFilter::Cache::Key must immediately follow the SkResourceC ache::Key. 492 }
486 SkResourceCache::Key fRCKey; 493 struct Value {
487 const SkImageFilter::Cache::Key fIFCKey; 494 Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset)
495 : fKey(key), fBitmap(bitmap), fOffset(offset) {}
496 Key fKey;
497 SkBitmap fBitmap;
498 SkIPoint fOffset;
499 static const Key& GetKey(const Value& v) {
500 return v.fKey;
501 }
502 static uint32_t Hash(const Key& key) {
503 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key), sizeof(Key));
504 }
505 SK_DECLARE_INTERNAL_LLIST_INTERFACE(Value);
488 }; 506 };
489 507 bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const override {
490 ImageFilterRec(SkImageFilter::Cache::Key ifcKey, const SkBitmap& bm, const S kIPoint& offset) 508 SkAutoMutexAcquire mutex(fMutex);
491 : fKeys(ifcKey) 509 if (Value* v = fLookup.find(key)) {
492 , fBitmap(bm) 510 *result = v->fBitmap;
493 , fOffset(offset) {} 511 *offset = v->fOffset;
494 512 if (v != fLRU.head()) {
495 const Key& getKey() const override { return fKeys.fRCKey; } 513 fLRU.remove(v);
496 size_t bytesUsed() const override { return sizeof(*this) + fBitmap.getSize() ; } 514 fLRU.addToHead(v);
497 const char* getCategory() const override { return "SkImageFilter::Cache"; } 515 }
498 516 return true;
499 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
500 if (auto pr = fBitmap.pixelRef()) {
501 return pr->diagnostic_only_getDiscardable();
502 } 517 }
503 return nullptr; 518 return false;
519 }
520 void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) ove rride {
521 SkAutoMutexAcquire mutex(fMutex);
522 if (Value* v = fLookup.find(key)) {
523 removeInternal(v);
524 }
525 Value* v = new Value(key, result, offset);
526 fLookup.add(v);
527 fLRU.addToHead(v);
528 fCurrentBytes += result.getSize();
529 while (fCurrentBytes > fMaxBytes) {
530 Value* tail = fLRU.tail();
531 SkASSERT(tail);
532 if (tail == v) {
533 break;
534 }
535 removeInternal(tail);
536 }
504 } 537 }
505 538
506 const SkBitmap& bitmap() const { return fBitmap; } 539 void purge() override {
507 const SkIPoint& offset() const { return fOffset; } 540 SkAutoMutexAcquire mutex(fMutex);
541 while (fCurrentBytes > 0) {
542 Value* tail = fLRU.tail();
543 SkASSERT(tail);
544 this->removeInternal(tail);
545 }
546 }
508 547
509 private: 548 private:
510 const Keys fKeys; 549 void removeInternal(Value* v) {
511 const SkBitmap fBitmap; 550 fCurrentBytes -= v->fBitmap.getSize();
512 const SkIPoint fOffset; 551 fLRU.remove(v);
513 }; 552 fLookup.remove(v->fKey);
514 553 delete v;
515 struct GetVisitor {
516 SkBitmap* fResult;
517 SkIPoint* fOffset;
518
519 static bool Visit(const SkResourceCache::Rec& rec, void* context) {
520 auto r = (const ImageFilterRec&)rec;
521 auto c = (GetVisitor*)context;
522 *c->fResult = r.bitmap();
523 *c->fOffset = r.offset();
524 return true;
525 }
526 };
527
528 // Thread-safe SkImageFilter::Cache that uses the global SkResourceCache.
529 class GlobalCache : public SkImageFilter::Cache {
530 public:
531 GlobalCache() {}
532
533 void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) ove rride {
534 const SkBitmap* bm = &result;
535 SkBitmap copy;
536 // Image filters allocate their own result bitmaps.
537 // If we're putting a bitmap into the SkResourceCache backed by discarda ble memory,
538 // we'd better make sure those bitmaps are discardable too (and vice ver sa).
539 // The expected case in Chrome is: rcIsDiscardable == true, bmIsDiscarda ble == false.
540 auto allocator = SkResourceCache::GetAllocator();
541 #if 0
542 bool rcIsDiscardable = allocator,
543 bmIsDiscardable = bm->pixelRef() && bm->pixelRef()->diagnostic_only _getDiscardable();
544 if (rcIsDiscardable != bmIsDiscardable) {
545 #else
546 {
547 #endif
548 bm->copyTo(&copy, allocator);
549 bm = &copy;
550 }
551 SkResourceCache::Add(new ImageFilterRec(key, *bm, offset));
552 }
553
554 bool get(const Key& ifcKey, SkBitmap* result, SkIPoint* offset) const overri de {
555 const ImageFilterRec::Keys keys(ifcKey);
556 GetVisitor visitor { result, offset };
557 return SkResourceCache::Find(keys.fRCKey, GetVisitor::Visit, &visitor);
558 }
559 };
560
561 // Non-thread-safe siloed SkImageFilter::Cache, meant to be small and ephemeral.
562 class LocalCache : public SkImageFilter::Cache {
563 public:
564 LocalCache(size_t maxBytes) : fRC(maxBytes) {
565 SkASSERT(fRC.allocator() == nullptr);
566 }
567
568 void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) ove rride {
569 SkASSERT(result.pixelRef() == nullptr ||
570 result.pixelRef()->diagnostic_only_getDiscardable() == nullptr) ;
571 fRC.add(new ImageFilterRec(key, result, offset));
572 }
573
574 bool get(const Key& ifcKey, SkBitmap* result, SkIPoint* offset) const overri de {
575 const ImageFilterRec::Keys keys(ifcKey);
576 GetVisitor visitor { result, offset };
577 return fRC.find(keys.fRCKey, GetVisitor::Visit, &visitor);
578 } 554 }
579 private: 555 private:
580 mutable SkResourceCache fRC; // SkResourceCache::find() is not const (updat es LRU). 556 SkTDynamicHash<Value, Key> fLookup;
557 mutable SkTInternalLList<Value> fLRU;
558 size_t fMaxBytes;
559 size_t fCurrentBytes;
560 mutable SkMutex fMutex;
581 }; 561 };
582 562
583 } // namespace 563 } // namespace
584 564
585 SkImageFilter::Cache* SkImageFilter::Cache::Create(size_t maxBytes) { 565 SkImageFilter::Cache* SkImageFilter::Cache::Create(size_t maxBytes) {
586 return new LocalCache(maxBytes); 566 return new CacheImpl(maxBytes);
587 } 567 }
588 568
589 SK_DECLARE_STATIC_ONCE_PTR(SkImageFilter::Cache, cache); 569 SK_DECLARE_STATIC_ONCE_PTR(SkImageFilter::Cache, cache);
590 SkImageFilter::Cache* SkImageFilter::Cache::Get() { 570 SkImageFilter::Cache* SkImageFilter::Cache::Get() {
591 return cache.get([]{ return new GlobalCache; }); 571 return cache.get([]{ return SkImageFilter::Cache::Create(kDefaultCacheSize); });
572 }
573
574 void SkImageFilter::PurgeCache() {
575 Cache::Get()->purge();
592 } 576 }
593 577
594 //////////////////////////////////////////////////////////////////////////////// /////////////////// 578 //////////////////////////////////////////////////////////////////////////////// ///////////////////
595 579
596 SkBaseDevice* SkImageFilter::Proxy::createDevice(int w, int h) { 580 SkBaseDevice* SkImageFilter::Proxy::createDevice(int w, int h) {
597 SkBaseDevice::CreateInfo cinfo(SkImageInfo::MakeN32Premul(w, h), 581 SkBaseDevice::CreateInfo cinfo(SkImageInfo::MakeN32Premul(w, h),
598 SkBaseDevice::kNever_TileUsage, 582 SkBaseDevice::kNever_TileUsage,
599 kUnknown_SkPixelGeometry, 583 kUnknown_SkPixelGeometry,
600 true /*forImageFilter*/); 584 true /*forImageFilter*/);
601 SkBaseDevice* dev = fDevice->onCreateDevice(cinfo, nullptr); 585 SkBaseDevice* dev = fDevice->onCreateDevice(cinfo, nullptr);
602 if (nullptr == dev) { 586 if (nullptr == dev) {
603 const SkSurfaceProps surfaceProps(fDevice->fSurfaceProps.flags(), 587 const SkSurfaceProps surfaceProps(fDevice->fSurfaceProps.flags(),
604 kUnknown_SkPixelGeometry); 588 kUnknown_SkPixelGeometry);
605 dev = SkBitmapDevice::Create(cinfo.fInfo, surfaceProps); 589 dev = SkBitmapDevice::Create(cinfo.fInfo, surfaceProps);
606 } 590 }
607 return dev; 591 return dev;
608 } 592 }
609 593
610 bool SkImageFilter::Proxy::filterImage(const SkImageFilter* filter, const SkBitm ap& src, 594 bool SkImageFilter::Proxy::filterImage(const SkImageFilter* filter, const SkBitm ap& src,
611 const SkImageFilter::Context& ctx, 595 const SkImageFilter::Context& ctx,
612 SkBitmap* result, SkIPoint* offset) { 596 SkBitmap* result, SkIPoint* offset) {
613 return fDevice->filterImage(filter, src, ctx, result, offset); 597 return fDevice->filterImage(filter, src, ctx, result, offset);
614 } 598 }
615 599
OLDNEW
« no previous file with comments | « include/core/SkImageFilter.h ('k') | src/core/SkResourceCache.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698