OLD | NEW |
| (Empty) |
1 #ifndef SkTextureCache_DEFINED | |
2 #define SkTextureCache_DEFINED | |
3 | |
4 #include "SkBitmap.h" | |
5 #include "SkPoint.h" | |
6 #include "SkGL.h" | |
7 #include "SkTDArray.h" | |
8 | |
9 class SkTextureCache { | |
10 public: | |
11 SkTextureCache(size_t maxCount, size_t maxSize); | |
12 ~SkTextureCache(); | |
13 | |
14 size_t getMaxCount() { return fTexCountMax; } | |
15 size_t getMaxSize() { return fTexSizeMax; } | |
16 | |
17 void setMaxCount(size_t count); | |
18 void setMaxSize(size_t size); | |
19 | |
20 /** Deletes all the caches. Pass true if the texture IDs are still valid, | |
21 and if so, it will call glDeleteTextures. Pass false if the texture IDs | |
22 are invalid (e.g. the gl-context has changed), in which case they will | |
23 just be abandoned. | |
24 */ | |
25 void deleteAllCaches(bool texturesAreValid); | |
26 | |
27 static int HashMask() { return kHashMask; } | |
28 | |
29 class Key { | |
30 public: | |
31 Key(const SkBitmap& bm) { | |
32 fGenID = bm.getGenerationID(); | |
33 fOffset = bm.pixelRefOffset(); | |
34 fWH = (bm.width() << 16) | bm.height(); | |
35 this->computeHash(); | |
36 } | |
37 | |
38 int getHashIndex() const { return fHashIndex; } | |
39 | |
40 friend bool operator==(const Key& a, const Key& b) { | |
41 return a.fHash == b.fHash && | |
42 a.fGenID == b.fGenID && | |
43 a.fOffset == b.fOffset && | |
44 a.fWH == b.fWH; | |
45 } | |
46 | |
47 friend bool operator<(const Key& a, const Key& b) { | |
48 if (a.fHash < b.fHash) { | |
49 return true; | |
50 } else if (a.fHash > b.fHash) { | |
51 return false; | |
52 } | |
53 | |
54 if (a.fGenID < b.fGenID) { | |
55 return true; | |
56 } else if (a.fGenID > b.fGenID) { | |
57 return false; | |
58 } | |
59 | |
60 if (a.fOffset < b.fOffset) { | |
61 return true; | |
62 } else if (a.fOffset > b.fOffset) { | |
63 return false; | |
64 } | |
65 | |
66 return a.fWH < b.fWH; | |
67 } | |
68 | |
69 private: | |
70 void computeHash() { | |
71 uint32_t hash = fGenID ^ fOffset ^ fWH; | |
72 fHash = hash; | |
73 hash ^= hash >> 16; | |
74 fHashIndex = hash & SkTextureCache::HashMask(); | |
75 } | |
76 | |
77 uint32_t fHash; // computed from the other fields | |
78 uint32_t fGenID; | |
79 size_t fOffset; | |
80 uint32_t fWH; | |
81 // for indexing into the texturecache's fHash | |
82 int fHashIndex; | |
83 }; | |
84 | |
85 class Entry { | |
86 public: | |
87 GLuint name() const { return fName; } | |
88 SkPoint texSize() const { return fTexSize; } | |
89 size_t memSize() const { return fMemSize; } | |
90 const Key& getKey() const { return fKey; } | |
91 | |
92 // call this to clear the texture name, in case the context has changed | |
93 // in which case we should't reference or delete this texture in GL | |
94 void abandonTexture() { fName = 0; } | |
95 | |
96 private: | |
97 Entry(const SkBitmap& bitmap); | |
98 ~Entry(); | |
99 | |
100 int lockCount() const { return fLockCount; } | |
101 bool isLocked() const { return fLockCount > 0; } | |
102 | |
103 void lock() { fLockCount += 1; } | |
104 void unlock() { | |
105 SkASSERT(fLockCount > 0); | |
106 fLockCount -= 1; | |
107 } | |
108 | |
109 private: | |
110 GLuint fName; | |
111 SkPoint fTexSize; | |
112 Key fKey; | |
113 size_t fMemSize; | |
114 int fLockCount; | |
115 | |
116 Entry* fPrev; | |
117 Entry* fNext; | |
118 | |
119 friend class SkTextureCache; | |
120 }; | |
121 | |
122 Entry* lock(const SkBitmap&); | |
123 void unlock(Entry*); | |
124 | |
125 private: | |
126 void purgeIfNecessary(size_t extraSize); | |
127 | |
128 #ifdef SK_DEBUG | |
129 void validate() const; | |
130 #else | |
131 void validate() const {} | |
132 #endif | |
133 | |
134 Entry* fHead; | |
135 Entry* fTail; | |
136 | |
137 // limits for the cache | |
138 size_t fTexCountMax; | |
139 size_t fTexSizeMax; | |
140 | |
141 // current values for the cache | |
142 size_t fTexCount; | |
143 size_t fTexSize; | |
144 | |
145 enum { | |
146 kHashBits = 6, | |
147 kHashCount = 1 << kHashBits, | |
148 kHashMask = kHashCount - 1 | |
149 }; | |
150 mutable Entry* fHash[kHashCount]; | |
151 SkTDArray<Entry*> fSorted; | |
152 | |
153 /* If we find the key, return the entry and ignore index. If we don't, | |
154 return NULL and set index to the place to insert the entry in fSorted | |
155 */ | |
156 Entry* find(const Key&, int* index) const; | |
157 // returns index or <0 if not found. Does NOT update hash | |
158 int findInSorted(const Key& key) const; | |
159 }; | |
160 | |
161 #endif | |
OLD | NEW |