1 /* 2 * Copyright 2013 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 #ifndef SkScaledImageCache_DEFINED 9 #define SkScaledImageCache_DEFINED 10 11 #include "SkBitmap.h" 12 13 class SkMipMap; 14 15 /** 16 * Cache object for bitmaps (with possible scale in X Y as part of the key). 17 * 18 * Multiple caches can be instantiated, but each instance is not implicitly 19 * thread-safe, so if a given instance is to be shared across threads, the 20 * caller must manage the access itself (e.g. via a mutex). 21 * 22 * As a convenience, a global instance is also defined, which can be safely 23 * access across threads via the static methods (e.g. FindAndLock, etc.). 24 */ 25 class SkScaledImageCache { 26 public: 27 struct ID; 28 29 /* 30 * The following static methods are thread-safe wrappers around a global 31 * instance of this cache. 32 */ 33 34 static ID* FindAndLock(const SkBitmap& original, SkScalar scaleX, 35 SkScalar scaleY, SkBitmap* scaled); 36 static ID* FindAndLockMip(const SkBitmap& original, SkMipMap const**); 37 38 static ID* AddAndLock(const SkBitmap& original, SkScalar scaleX, 39 SkScalar scaleY, const SkBitmap& scaled); 40 static ID* AddAndLockMip(const SkBitmap& original, const SkMipMap*); 41 42 static void Unlock(ID*); 43 44 static size_t GetBytesUsed(); 45 static size_t GetByteLimit(); 46 static size_t SetByteLimit(size_t newLimit); 47 48 /////////////////////////////////////////////////////////////////////////// 49 50 SkScaledImageCache(size_t byteLimit); 51 ~SkScaledImageCache(); 52 53 /** 54 * Search the cache for a scaled version of original. If found, return it 55 * in scaled, and return its ID pointer. Use the returned ptr to unlock 56 * the cache when you are done using scaled. 57 * 58 * If a match is not found, scaled will be unmodifed, and NULL will be 59 * returned. 60 */ 61 ID* findAndLock(const SkBitmap& original, SkScalar scaleX, 62 SkScalar scaleY, SkBitmap* scaled); 63 ID* findAndLockMip(const SkBitmap& original, SkMipMap const**); 64 65 /** 66 * To add a new (scaled) bitmap to the cache, call AddAndLock. Use the 67 * returned ptr to unlock the cache when you are done using scaled. 68 */ 69 ID* addAndLock(const SkBitmap& original, SkScalar scaleX, 70 SkScalar scaleY, const SkBitmap& scaled); 71 ID* addAndLockMip(const SkBitmap& original, const SkMipMap*); 72 73 /** 74 * Given a non-null ID ptr returned by either findAndLock or addAndLock, 75 * this releases the associated resources to be available to be purged 76 * if needed. After this, the cached bitmap should no longer be 77 * referenced by the caller. 78 */ 79 void unlock(ID*); 80 81 size_t getBytesUsed() const { return fBytesUsed; } 82 size_t getByteLimit() const { return fByteLimit; } 83 84 /** 85 * Set the maximum number of bytes available to this cache. If the current 86 * cache exceeds this new value, it will be purged to try to fit within 87 * this new limit. 88 */ 89 size_t setByteLimit(size_t newLimit); 90 91 public: 92 struct Rec; 93 private: 94 Rec* fHead; 95 Rec* fTail; 96 97 class Hash; 98 Hash* fHash; 99 100 size_t fBytesUsed; 101 size_t fByteLimit; 102 int fCount; 103 104 Rec* findAndLock(const SkBitmap& original, SkScalar sx, SkScalar sy); 105 106 void purgeAsNeeded(); 107 108 // linklist management 109 void moveToHead(Rec*); 110 void addToHead(Rec*); 111 void detach(Rec*); 112 #ifdef SK_DEBUG 113 void validate() const; 114 #else 115 void validate() const {} 116 #endif 117 }; 118 119 #endif 120