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 "src/core/SkYUVPlanesCache.h"
9
10 #include "include/core/SkYUVAPixmaps.h"
11 #include "src/core/SkBitmapCache.h"
12 #include "src/core/SkCachedData.h"
13 #include "src/core/SkResourceCache.h"
14
15 #include <cstddef>
16
17 class SkDiscardableMemory;
18
19 #define CHECK_LOCAL(localCache, localName, globalName, ...) \
20 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::globalName(__VA_ARGS__))
21
22 namespace {
23 static unsigned gYUVPlanesKeyNamespaceLabel;
24
25 struct YUVValue {
26 SkYUVAPixmaps fPixmaps;
27 SkCachedData* fData;
28 };
29
30 struct YUVPlanesKey : public SkResourceCache::Key {
YUVPlanesKey__anon3f10ca570111::YUVPlanesKey31 YUVPlanesKey(uint32_t genID)
32 : fGenID(genID)
33 {
34 this->init(&gYUVPlanesKeyNamespaceLabel, SkMakeResourceCacheSharedIDForBitmap(genID),
35 sizeof(genID));
36 }
37
38 uint32_t fGenID;
39 };
40
41 struct YUVPlanesRec : public SkResourceCache::Rec {
YUVPlanesRec__anon3f10ca570111::YUVPlanesRec42 YUVPlanesRec(YUVPlanesKey key, SkCachedData* data, const SkYUVAPixmaps& pixmaps)
43 : fKey(key)
44 {
45 fValue.fData = data;
46 fValue.fPixmaps = pixmaps;
47 fValue.fData->attachToCacheAndRef();
48 }
~YUVPlanesRec__anon3f10ca570111::YUVPlanesRec49 ~YUVPlanesRec() override {
50 fValue.fData->detachFromCacheAndUnref();
51 }
52
53 YUVPlanesKey fKey;
54 YUVValue fValue;
55
getKey__anon3f10ca570111::YUVPlanesRec56 const Key& getKey() const override { return fKey; }
bytesUsed__anon3f10ca570111::YUVPlanesRec57 size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
getCategory__anon3f10ca570111::YUVPlanesRec58 const char* getCategory() const override { return "yuv-planes"; }
diagnostic_only_getDiscardable__anon3f10ca570111::YUVPlanesRec59 SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
60 return fValue.fData->diagnostic_only_getDiscardable();
61 }
62
Visitor__anon3f10ca570111::YUVPlanesRec63 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
64 const YUVPlanesRec& rec = static_cast<const YUVPlanesRec&>(baseRec);
65 YUVValue* result = static_cast<YUVValue*>(contextData);
66
67 SkCachedData* tmpData = rec.fValue.fData;
68 tmpData->ref();
69 if (nullptr == tmpData->data()) {
70 tmpData->unref();
71 return false;
72 }
73 result->fData = tmpData;
74 result->fPixmaps = rec.fValue.fPixmaps;
75 return true;
76 }
77 };
78 } // namespace
79
FindAndRef(uint32_t genID,SkYUVAPixmaps * pixmaps,SkResourceCache * localCache)80 SkCachedData* SkYUVPlanesCache::FindAndRef(uint32_t genID,
81 SkYUVAPixmaps* pixmaps,
82 SkResourceCache* localCache) {
83 YUVValue result;
84 YUVPlanesKey key(genID);
85 if (!CHECK_LOCAL(localCache, find, Find, key, YUVPlanesRec::Visitor, &result)) {
86 return nullptr;
87 }
88
89 *pixmaps = result.fPixmaps;
90 return result.fData;
91 }
92
Add(uint32_t genID,SkCachedData * data,const SkYUVAPixmaps & pixmaps,SkResourceCache * localCache)93 void SkYUVPlanesCache::Add(uint32_t genID, SkCachedData* data, const SkYUVAPixmaps& pixmaps,
94 SkResourceCache* localCache) {
95 YUVPlanesKey key(genID);
96 return CHECK_LOCAL(localCache, add, Add, new YUVPlanesRec(key, data, pixmaps));
97 }
98