| 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 |