OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
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 "SkBitmapCache.h" | 8 #include "SkBitmapCache.h" |
| 9 #include "SkImage.h" |
9 #include "SkResourceCache.h" | 10 #include "SkResourceCache.h" |
10 #include "SkMipMap.h" | 11 #include "SkMipMap.h" |
11 #include "SkPixelRef.h" | 12 #include "SkPixelRef.h" |
12 #include "SkRect.h" | 13 #include "SkRect.h" |
13 | 14 |
14 /** | 15 /** |
15 * Use this for bitmapcache and mipmapcache entries. | 16 * Use this for bitmapcache and mipmapcache entries. |
16 */ | 17 */ |
17 uint64_t SkMakeResourceCacheSharedIDForBitmap(uint32_t bitmapGenID) { | 18 uint64_t SkMakeResourceCacheSharedIDForBitmap(uint32_t bitmapGenID) { |
18 uint64_t sharedID = SkSetFourByteTag('b', 'm', 'a', 'p'); | 19 uint64_t sharedID = SkSetFourByteTag('b', 'm', 'a', 'p'); |
(...skipping 17 matching lines...) Expand all Loading... |
36 it should be somewhere else (in SkBitmap?). | 37 it should be somewhere else (in SkBitmap?). |
37 */ | 38 */ |
38 static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) { | 39 static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) { |
39 if (!(bm.pixelRef())) { | 40 if (!(bm.pixelRef())) { |
40 return SkIRect::MakeEmpty(); | 41 return SkIRect::MakeEmpty(); |
41 } | 42 } |
42 SkIPoint origin = bm.pixelRefOrigin(); | 43 SkIPoint origin = bm.pixelRefOrigin(); |
43 return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height()); | 44 return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height()); |
44 } | 45 } |
45 | 46 |
| 47 /** |
| 48 * This function finds the bounds of the image. Today this is just the entire b
ounds, |
| 49 * but in the future we may support subsets within an image, in which case this
should |
| 50 * return that subset (see get_bounds_from_bitmap). |
| 51 */ |
| 52 static SkIRect get_bounds_from_image(const SkImage* image) { |
| 53 return SkIRect::MakeWH(image->width(), image->height()); |
| 54 } |
| 55 |
| 56 SkBitmapCacheDesc SkBitmapCacheDesc::Make(const SkBitmap& bm, int width, int hei
ght) { |
| 57 SkBitmapCacheDesc desc; |
| 58 desc.fImageID = bm.getGenerationID(); |
| 59 desc.fWidth = width; |
| 60 desc.fHeight = height; |
| 61 desc.fBounds = get_bounds_from_bitmap(bm); |
| 62 return desc; |
| 63 } |
| 64 |
| 65 SkBitmapCacheDesc SkBitmapCacheDesc::Make(const SkBitmap& bm) { |
| 66 return Make(bm, bm.width(), bm.height()); |
| 67 } |
| 68 |
| 69 SkBitmapCacheDesc SkBitmapCacheDesc::Make(const SkImage* image, int width, int h
eight) { |
| 70 SkBitmapCacheDesc desc; |
| 71 desc.fImageID = image->uniqueID(); |
| 72 desc.fWidth = width; |
| 73 desc.fHeight = height; |
| 74 desc.fBounds = get_bounds_from_image(image); |
| 75 return desc; |
| 76 } |
| 77 |
| 78 SkBitmapCacheDesc SkBitmapCacheDesc::Make(const SkImage* image) { |
| 79 return Make(image, image->width(), image->height()); |
| 80 } |
| 81 |
46 namespace { | 82 namespace { |
47 static unsigned gBitmapKeyNamespaceLabel; | 83 static unsigned gBitmapKeyNamespaceLabel; |
48 | 84 |
49 struct BitmapKey : public SkResourceCache::Key { | 85 struct BitmapKey : public SkResourceCache::Key { |
50 public: | 86 public: |
51 BitmapKey(uint32_t genID, int width, int height, const SkIRect& bounds) | 87 BitmapKey(uint32_t genID, int width, int height, const SkIRect& bounds) |
52 : fGenID(genID) | 88 : fGenID(genID) |
53 , fWidth(width) | 89 , fWidth(width) |
54 , fHeight(height) | 90 , fHeight(height) |
55 , fBounds(bounds) | 91 , fBounds(bounds) |
56 { | 92 { |
57 this->init(&gBitmapKeyNamespaceLabel, SkMakeResourceCacheSharedIDForBitm
ap(genID), | 93 this->init(&gBitmapKeyNamespaceLabel, SkMakeResourceCacheSharedIDForBitm
ap(fGenID), |
58 sizeof(fGenID) + sizeof(fWidth) + sizeof(fHeight) + sizeof(fB
ounds)); | 94 sizeof(fGenID) + sizeof(fWidth) + sizeof(fHeight) + sizeof(fB
ounds)); |
59 } | 95 } |
60 | 96 |
| 97 BitmapKey(const SkBitmapCacheDesc& desc) |
| 98 : fGenID(desc.fImageID) |
| 99 , fWidth(desc.fWidth) |
| 100 , fHeight(desc.fHeight) |
| 101 , fBounds(desc.fBounds) |
| 102 { |
| 103 this->init(&gBitmapKeyNamespaceLabel, SkMakeResourceCacheSharedIDForBitm
ap(fGenID), |
| 104 sizeof(fGenID) + sizeof(fWidth) + sizeof(fHeight) + sizeof(fB
ounds)); |
| 105 } |
| 106 |
61 void dump() const { | 107 void dump() const { |
62 SkDebugf("-- add [%d %d] %d [%d %d %d %d]\n", fWidth, fHeight, fGenID, | 108 SkDebugf("-- add [%d %d] %d [%d %d %d %d]\n", fWidth, fHeight, fGenID, |
63 fBounds.x(), fBounds.y(), fBounds.width(), fBounds.height()); | 109 fBounds.x(), fBounds.y(), fBounds.width(), fBounds.height()); |
64 } | 110 } |
65 | 111 |
66 const uint32_t fGenID; | 112 const uint32_t fGenID; |
67 const int fWidth; | 113 const int fWidth; |
68 const int fHeight; | 114 const int fHeight; |
69 const SkIRect fBounds; | 115 const SkIRect fBounds; |
70 }; | 116 }; |
71 | 117 |
72 struct BitmapRec : public SkResourceCache::Rec { | 118 struct BitmapRec : public SkResourceCache::Rec { |
73 BitmapRec(uint32_t genID, int width, int height, const SkIRect& bounds, | 119 BitmapRec(uint32_t genID, int width, int height, const SkIRect& bounds, |
74 const SkBitmap& result) | 120 const SkBitmap& result) |
75 : fKey(genID, width, height, bounds) | 121 : fKey(genID, width, height, bounds) |
76 , fBitmap(result) | 122 , fBitmap(result) |
77 { | 123 { |
78 #ifdef TRACE_NEW_BITMAP_CACHE_RECS | 124 #ifdef TRACE_NEW_BITMAP_CACHE_RECS |
79 fKey.dump(); | 125 fKey.dump(); |
80 #endif | 126 #endif |
81 } | 127 } |
82 | 128 |
| 129 BitmapRec(const SkBitmapCacheDesc& desc, const SkBitmap& result) |
| 130 : fKey(desc) |
| 131 , fBitmap(result) |
| 132 { |
| 133 #ifdef TRACE_NEW_BITMAP_CACHE_RECS |
| 134 fKey.dump(); |
| 135 #endif |
| 136 } |
| 137 |
83 const Key& getKey() const override { return fKey; } | 138 const Key& getKey() const override { return fKey; } |
84 size_t bytesUsed() const override { return sizeof(fKey) + fBitmap.getSize();
} | 139 size_t bytesUsed() const override { return sizeof(fKey) + fBitmap.getSize();
} |
85 | 140 |
86 const char* getCategory() const override { return "bitmap"; } | 141 const char* getCategory() const override { return "bitmap"; } |
87 SkDiscardableMemory* diagnostic_only_getDiscardable() const override { | 142 SkDiscardableMemory* diagnostic_only_getDiscardable() const override { |
88 return fBitmap.pixelRef()->diagnostic_only_getDiscardable(); | 143 return fBitmap.pixelRef()->diagnostic_only_getDiscardable(); |
89 } | 144 } |
90 | 145 |
91 static bool Finder(const SkResourceCache::Rec& baseRec, void* contextBitmap)
{ | 146 static bool Finder(const SkResourceCache::Rec& baseRec, void* contextBitmap)
{ |
92 const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec); | 147 const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec); |
93 SkBitmap* result = (SkBitmap*)contextBitmap; | 148 SkBitmap* result = (SkBitmap*)contextBitmap; |
94 | 149 |
95 *result = rec.fBitmap; | 150 *result = rec.fBitmap; |
96 result->lockPixels(); | 151 result->lockPixels(); |
97 return SkToBool(result->getPixels()); | 152 return SkToBool(result->getPixels()); |
98 } | 153 } |
99 | 154 |
100 private: | 155 private: |
101 BitmapKey fKey; | 156 BitmapKey fKey; |
102 SkBitmap fBitmap; | 157 SkBitmap fBitmap; |
103 }; | 158 }; |
104 } // namespace | 159 } // namespace |
105 | 160 |
106 #define CHECK_LOCAL(localCache, localName, globalName, ...) \ | 161 #define CHECK_LOCAL(localCache, localName, globalName, ...) \ |
107 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::global
Name(__VA_ARGS__)) | 162 ((localCache) ? localCache->localName(__VA_ARGS__) : SkResourceCache::global
Name(__VA_ARGS__)) |
108 | 163 |
109 bool SkBitmapCache::FindWH(const SkBitmap& src, int width, int height, SkBitmap*
result, | 164 bool SkBitmapCache::FindWH(const SkBitmapCacheDesc& desc, SkBitmap* result, |
110 SkResourceCache* localCache) { | 165 SkResourceCache* localCache) { |
111 if (0 == width || 0 == height) { | 166 if (0 == desc.fWidth || 0 == desc.fHeight) { |
| 167 // degenerate |
| 168 return false; |
| 169 } |
| 170 return CHECK_LOCAL(localCache, find, Find, BitmapKey(desc), BitmapRec::Finde
r, result); |
| 171 } |
| 172 |
| 173 bool SkBitmapCache::AddWH(const SkBitmapCacheDesc& desc, const SkBitmap& result, |
| 174 SkResourceCache* localCache) { |
| 175 if (0 == desc.fWidth || 0 == desc.fHeight) { |
112 // degenerate, and the key we use for mipmaps | 176 // degenerate, and the key we use for mipmaps |
113 return false; | 177 return false; |
114 } | 178 } |
115 BitmapKey key(src.getGenerationID(), width, height, get_bounds_from_bitmap(s
rc)); | |
116 | |
117 return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Finder, result); | |
118 } | |
119 | |
120 void SkBitmapCache::AddWH(const SkBitmap& src, int width, int height, | |
121 const SkBitmap& result, SkResourceCache* localCache) { | |
122 if (0 == width || 0 == height) { | |
123 // degenerate, and the key we use for mipmaps | |
124 return; | |
125 } | |
126 SkASSERT(result.isImmutable()); | 179 SkASSERT(result.isImmutable()); |
127 BitmapRec* rec = new BitmapRec(src.getGenerationID(), width, height, | 180 BitmapRec* rec = new BitmapRec(desc, result); |
128 get_bounds_from_bitmap(src), result); | |
129 CHECK_LOCAL(localCache, add, Add, rec); | 181 CHECK_LOCAL(localCache, add, Add, rec); |
130 src.pixelRef()->notifyAddedToCache(); | 182 return true; |
131 } | 183 } |
132 | 184 |
133 bool SkBitmapCache::Find(uint32_t genID, const SkIRect& subset, SkBitmap* result
, | 185 bool SkBitmapCache::Find(uint32_t genID, const SkIRect& subset, SkBitmap* result
, |
134 SkResourceCache* localCache) { | 186 SkResourceCache* localCache) { |
135 BitmapKey key(genID, SK_Scalar1, SK_Scalar1, subset); | 187 BitmapKey key(genID, SK_Scalar1, SK_Scalar1, subset); |
136 | 188 |
137 return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Finder, result); | 189 return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Finder, result); |
138 } | 190 } |
139 | 191 |
140 bool SkBitmapCache::Add(SkPixelRef* pr, const SkIRect& subset, const SkBitmap& r
esult, | 192 bool SkBitmapCache::Add(SkPixelRef* pr, const SkIRect& subset, const SkBitmap& r
esult, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 *(const SkMipMap**)contextMip = mm; | 271 *(const SkMipMap**)contextMip = mm; |
220 return true; | 272 return true; |
221 } | 273 } |
222 | 274 |
223 private: | 275 private: |
224 MipMapKey fKey; | 276 MipMapKey fKey; |
225 const SkMipMap* fMipMap; | 277 const SkMipMap* fMipMap; |
226 }; | 278 }; |
227 } | 279 } |
228 | 280 |
229 const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src, SkResourceCache*
localCache) { | 281 const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmapCacheDesc& desc, |
230 MipMapKey key(src.getGenerationID(), get_bounds_from_bitmap(src)); | 282 SkResourceCache* localCache) { |
| 283 // Note: we ignore width/height from desc, just need id and bounds |
| 284 MipMapKey key(desc.fImageID, desc.fBounds); |
231 const SkMipMap* result; | 285 const SkMipMap* result; |
232 | 286 |
233 if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Finder, &result)) { | 287 if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Finder, &result)) { |
234 result = nullptr; | 288 result = nullptr; |
235 } | 289 } |
236 return result; | 290 return result; |
237 } | 291 } |
238 | 292 |
239 static SkResourceCache::DiscardableFactory get_fact(SkResourceCache* localCache)
{ | 293 static SkResourceCache::DiscardableFactory get_fact(SkResourceCache* localCache)
{ |
240 return localCache ? localCache->GetDiscardableFactory() | 294 return localCache ? localCache->GetDiscardableFactory() |
241 : SkResourceCache::GetDiscardableFactory(); | 295 : SkResourceCache::GetDiscardableFactory(); |
242 } | 296 } |
243 | 297 |
244 const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l
ocalCache) { | 298 const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l
ocalCache) { |
245 SkMipMap* mipmap = SkMipMap::Build(src, get_fact(localCache)); | 299 SkMipMap* mipmap = SkMipMap::Build(src, get_fact(localCache)); |
246 if (mipmap) { | 300 if (mipmap) { |
247 MipMapRec* rec = new MipMapRec(src, mipmap); | 301 MipMapRec* rec = new MipMapRec(src, mipmap); |
248 CHECK_LOCAL(localCache, add, Add, rec); | 302 CHECK_LOCAL(localCache, add, Add, rec); |
249 src.pixelRef()->notifyAddedToCache(); | 303 src.pixelRef()->notifyAddedToCache(); |
250 } | 304 } |
251 return mipmap; | 305 return mipmap; |
252 } | 306 } |
OLD | NEW |