1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkScaledImageCache.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,203 @@ 1.4 +/* 1.5 + * Copyright 2013 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkScaledImageCache_DEFINED 1.12 +#define SkScaledImageCache_DEFINED 1.13 + 1.14 +#include "SkBitmap.h" 1.15 + 1.16 +class SkDiscardableMemory; 1.17 +class SkMipMap; 1.18 + 1.19 +/** 1.20 + * Cache object for bitmaps (with possible scale in X Y as part of the key). 1.21 + * 1.22 + * Multiple caches can be instantiated, but each instance is not implicitly 1.23 + * thread-safe, so if a given instance is to be shared across threads, the 1.24 + * caller must manage the access itself (e.g. via a mutex). 1.25 + * 1.26 + * As a convenience, a global instance is also defined, which can be safely 1.27 + * access across threads via the static methods (e.g. FindAndLock, etc.). 1.28 + */ 1.29 +class SkScaledImageCache { 1.30 +public: 1.31 + struct ID; 1.32 + 1.33 + /** 1.34 + * Returns a locked/pinned SkDiscardableMemory instance for the specified 1.35 + * number of bytes, or NULL on failure. 1.36 + */ 1.37 + typedef SkDiscardableMemory* (*DiscardableFactory)(size_t bytes); 1.38 + 1.39 + /* 1.40 + * The following static methods are thread-safe wrappers around a global 1.41 + * instance of this cache. 1.42 + */ 1.43 + 1.44 + static ID* FindAndLock(uint32_t pixelGenerationID, 1.45 + int32_t width, 1.46 + int32_t height, 1.47 + SkBitmap* returnedBitmap); 1.48 + 1.49 + static ID* FindAndLock(const SkBitmap& original, SkScalar scaleX, 1.50 + SkScalar scaleY, SkBitmap* returnedBitmap); 1.51 + static ID* FindAndLockMip(const SkBitmap& original, 1.52 + SkMipMap const** returnedMipMap); 1.53 + 1.54 + 1.55 + static ID* AddAndLock(uint32_t pixelGenerationID, 1.56 + int32_t width, 1.57 + int32_t height, 1.58 + const SkBitmap& bitmap); 1.59 + 1.60 + static ID* AddAndLock(const SkBitmap& original, SkScalar scaleX, 1.61 + SkScalar scaleY, const SkBitmap& bitmap); 1.62 + static ID* AddAndLockMip(const SkBitmap& original, const SkMipMap* mipMap); 1.63 + 1.64 + static void Unlock(ID*); 1.65 + 1.66 + static size_t GetBytesUsed(); 1.67 + static size_t GetByteLimit(); 1.68 + static size_t SetByteLimit(size_t newLimit); 1.69 + 1.70 + static SkBitmap::Allocator* GetAllocator(); 1.71 + 1.72 + /** 1.73 + * Call SkDebugf() with diagnostic information about the state of the cache 1.74 + */ 1.75 + static void Dump(); 1.76 + 1.77 + /////////////////////////////////////////////////////////////////////////// 1.78 + 1.79 + /** 1.80 + * Construct the cache to call DiscardableFactory when it 1.81 + * allocates memory for the pixels. In this mode, the cache has 1.82 + * not explicit budget, and so methods like getBytesUsed() and 1.83 + * getByteLimit() will return 0, and setByteLimit will ignore its argument 1.84 + * and return 0. 1.85 + */ 1.86 + SkScaledImageCache(DiscardableFactory); 1.87 + 1.88 + /** 1.89 + * Construct the cache, allocating memory with malloc, and respect the 1.90 + * byteLimit, purging automatically when a new image is added to the cache 1.91 + * that pushes the total bytesUsed over the limit. Note: The limit can be 1.92 + * changed at runtime with setByteLimit. 1.93 + */ 1.94 + SkScaledImageCache(size_t byteLimit); 1.95 + 1.96 + ~SkScaledImageCache(); 1.97 + 1.98 + /** 1.99 + * Search the cache for a matching bitmap (using generationID, 1.100 + * width, and height as a search key). If found, return it in 1.101 + * returnedBitmap, and return its ID pointer. Use the returned 1.102 + * ptr to unlock the cache when you are done using 1.103 + * returnedBitmap. 1.104 + * 1.105 + * If a match is not found, returnedBitmap will be unmodifed, and 1.106 + * NULL will be returned. 1.107 + * 1.108 + * This is used if there is no scaling or subsetting, for example 1.109 + * by SkLazyPixelRef. 1.110 + */ 1.111 + ID* findAndLock(uint32_t pixelGenerationID, int32_t width, int32_t height, 1.112 + SkBitmap* returnedBitmap); 1.113 + 1.114 + /** 1.115 + * Search the cache for a scaled version of original. If found, 1.116 + * return it in returnedBitmap, and return its ID pointer. Use 1.117 + * the returned ptr to unlock the cache when you are done using 1.118 + * returnedBitmap. 1.119 + * 1.120 + * If a match is not found, returnedBitmap will be unmodifed, and 1.121 + * NULL will be returned. 1.122 + */ 1.123 + ID* findAndLock(const SkBitmap& original, SkScalar scaleX, 1.124 + SkScalar scaleY, SkBitmap* returnedBitmap); 1.125 + ID* findAndLockMip(const SkBitmap& original, 1.126 + SkMipMap const** returnedMipMap); 1.127 + 1.128 + /** 1.129 + * To add a new bitmap (or mipMap) to the cache, call 1.130 + * AddAndLock. Use the returned ptr to unlock the cache when you 1.131 + * are done using scaled. 1.132 + * 1.133 + * Use (generationID, width, and height) or (original, scaleX, 1.134 + * scaleY) or (original) as a search key 1.135 + */ 1.136 + ID* addAndLock(uint32_t pixelGenerationID, int32_t width, int32_t height, 1.137 + const SkBitmap& bitmap); 1.138 + ID* addAndLock(const SkBitmap& original, SkScalar scaleX, 1.139 + SkScalar scaleY, const SkBitmap& bitmap); 1.140 + ID* addAndLockMip(const SkBitmap& original, const SkMipMap* mipMap); 1.141 + 1.142 + /** 1.143 + * Given a non-null ID ptr returned by either findAndLock or addAndLock, 1.144 + * this releases the associated resources to be available to be purged 1.145 + * if needed. After this, the cached bitmap should no longer be 1.146 + * referenced by the caller. 1.147 + */ 1.148 + void unlock(ID*); 1.149 + 1.150 + size_t getBytesUsed() const { return fBytesUsed; } 1.151 + size_t getByteLimit() const { return fByteLimit; } 1.152 + 1.153 + /** 1.154 + * Set the maximum number of bytes available to this cache. If the current 1.155 + * cache exceeds this new value, it will be purged to try to fit within 1.156 + * this new limit. 1.157 + */ 1.158 + size_t setByteLimit(size_t newLimit); 1.159 + 1.160 + SkBitmap::Allocator* allocator() const { return fAllocator; }; 1.161 + 1.162 + /** 1.163 + * Call SkDebugf() with diagnostic information about the state of the cache 1.164 + */ 1.165 + void dump() const; 1.166 + 1.167 +public: 1.168 + struct Rec; 1.169 + struct Key; 1.170 +private: 1.171 + Rec* fHead; 1.172 + Rec* fTail; 1.173 + 1.174 + class Hash; 1.175 + Hash* fHash; 1.176 + 1.177 + DiscardableFactory fDiscardableFactory; 1.178 + // the allocator is NULL or one that matches discardables 1.179 + SkBitmap::Allocator* fAllocator; 1.180 + 1.181 + size_t fBytesUsed; 1.182 + size_t fByteLimit; 1.183 + int fCount; 1.184 + 1.185 + Rec* findAndLock(uint32_t generationID, SkScalar sx, SkScalar sy, 1.186 + const SkIRect& bounds); 1.187 + Rec* findAndLock(const Key& key); 1.188 + ID* addAndLock(Rec* rec); 1.189 + 1.190 + void purgeRec(Rec*); 1.191 + void purgeAsNeeded(); 1.192 + 1.193 + // linklist management 1.194 + void moveToHead(Rec*); 1.195 + void addToHead(Rec*); 1.196 + void detach(Rec*); 1.197 + 1.198 + void init(); // called by constructors 1.199 + 1.200 +#ifdef SK_DEBUG 1.201 + void validate() const; 1.202 +#else 1.203 + void validate() const {} 1.204 +#endif 1.205 +}; 1.206 +#endif