| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/core/SkYUVPlanesCache.h" |
| |
| #include "include/core/SkYUVAPixmaps.h" |
| #include "src/core/SkBitmapCache.h" |
| #include "src/core/SkCachedData.h" |
| #include "src/core/SkResourceCache.h" |
| |
| #define CHECK_LOCAL(localCache, localName, globalName, ...) \ |
| ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__)) |
| |
| namespace { |
| static unsigned gYUVPlanesKeyNamespaceLabel; |
| |
| struct YUVValue { |
| SkYUVAPixmaps fPixmaps; |
| SkCachedData* fData; |
| }; |
| |
| struct YUVPlanesKey : public SkResourceCache::Key { |
| YUVPlanesKey(uint32_t genID) |
| : fGenID(genID) |
| { |
| this->init(&gYUVPlanesKeyNamespaceLabel, SkMakeResourceCacheSharedIDForBitmap(genID), |
| sizeof(genID)); |
| } |
| |
| uint32_t fGenID; |
| }; |
| |
| struct YUVPlanesRec : public SkResourceCache::Rec { |
| YUVPlanesRec(YUVPlanesKey key, SkCachedData* data, const SkYUVAPixmaps& pixmaps) |
| : fKey(key) |
| { |
| fValue.fData = data; |
| fValue.fPixmaps = pixmaps; |
| fValue.fData->attachToCacheAndRef(); |
| } |
| ~YUVPlanesRec() override { |
| fValue.fData->detachFromCacheAndUnref(); |
| } |
| |
| YUVPlanesKey fKey; |
| YUVValue fValue; |
| |
| const Key& getKey() const override { return fKey; } |
| size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); } |
| const char* getCategory() const override { return "yuv-planes"; } |
| SkDiscardableMemory* diagnostic_only_getDiscardable() const override { |
| return fValue.fData->diagnostic_only_getDiscardable(); |
| } |
| |
| static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) { |
| const YUVPlanesRec& rec = static_cast<const YUVPlanesRec&>(baseRec); |
| YUVValue* result = static_cast<YUVValue*>(contextData); |
| |
| SkCachedData* tmpData = rec.fValue.fData; |
| tmpData->ref(); |
| if (nullptr == tmpData->data()) { |
| tmpData->unref(); |
| return false; |
| } |
| result->fData = tmpData; |
| result->fPixmaps = rec.fValue.fPixmaps; |
| return true; |
| } |
| }; |
| } // namespace |
| |
| SkCachedData* SkYUVPlanesCache::FindAndRef(uint32_t genID, |
| SkYUVAPixmaps* pixmaps, |
| SkResourceCache* localCache) { |
| YUVValue result; |
| YUVPlanesKey key(genID); |
| if (!CHECK_LOCAL(localCache, find, Find, key, YUVPlanesRec::Visitor, &result)) { |
| return nullptr; |
| } |
| |
| *pixmaps = result.fPixmaps; |
| return result.fData; |
| } |
| |
| void SkYUVPlanesCache::Add(uint32_t genID, SkCachedData* data, const SkYUVAPixmaps& pixmaps, |
| SkResourceCache* localCache) { |
| YUVPlanesKey key(genID); |
| return CHECK_LOCAL(localCache, add, Add, new YUVPlanesRec(key, data, pixmaps)); |
| } |