1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkBitmapCache.h" 9 #include "SkResourceCache.h" 10 #include "SkYUVPlanesCache.h" 11 12 #define CHECK_LOCAL(localCache, localName, globalName, ...) \ 13 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__)) 14 15 namespace { 16 static unsigned gYUVPlanesKeyNamespaceLabel; 17 18 struct YUVValue { 19 SkYUVPlanesCache::Info fInfo; 20 SkCachedData* fData; 21 }; 22 23 struct YUVPlanesKey : public SkResourceCache::Key { 24 YUVPlanesKey(uint32_t genID) 25 : fGenID(genID) 26 { 27 this->init(&gYUVPlanesKeyNamespaceLabel, SkMakeResourceCacheSharedIDForBitmap(genID), 28 sizeof(genID)); 29 } 30 31 uint32_t fGenID; 32 }; 33 34 struct YUVPlanesRec : public SkResourceCache::Rec { 35 YUVPlanesRec(YUVPlanesKey key, SkCachedData* data, SkYUVPlanesCache::Info* info) 36 : fKey(key) 37 { 38 fValue.fData = data; 39 fValue.fInfo = *info; 40 fValue.fData->attachToCacheAndRef(); 41 } 42 ~YUVPlanesRec() override { 43 fValue.fData->detachFromCacheAndUnref(); 44 } 45 46 YUVPlanesKey fKey; 47 YUVValue fValue; 48 49 const Key& getKey() const override { return fKey; } 50 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); } 51 const char* getCategory() const override { return "yuv-planes"; } 52 SkDiscardableMemory* diagnostic_only_getDiscardable() const override { 53 return fValue.fData->diagnostic_only_getDiscardable(); 54 } 55 56 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) { 57 const YUVPlanesRec& rec = static_cast<const YUVPlanesRec&>(baseRec); 58 YUVValue* result = static_cast<YUVValue*>(contextData); 59 60 SkCachedData* tmpData = rec.fValue.fData; 61 tmpData->ref(); 62 if (nullptr == tmpData->data()) { 63 tmpData->unref(); 64 return false; 65 } 66 result->fData = tmpData; 67 result->fInfo = rec.fValue.fInfo; 68 return true; 69 } 70 }; 71 } // namespace 72 73 SkCachedData* SkYUVPlanesCache::FindAndRef(uint32_t genID, Info* info, 74 SkResourceCache* localCache) { 75 YUVValue result; 76 YUVPlanesKey key(genID); 77 if (!CHECK_LOCAL(localCache, find, Find, key, YUVPlanesRec::Visitor, &result)) { 78 return nullptr; 79 } 80 81 *info = result.fInfo; 82 return result.fData; 83 } 84 85 void SkYUVPlanesCache::Add(uint32_t genID, SkCachedData* data, Info* info, 86 SkResourceCache* localCache) { 87 YUVPlanesKey key(genID); 88 return CHECK_LOCAL(localCache, add, Add, new YUVPlanesRec(key, data, info)); 89 } 90