OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 | 10 |
11 #ifndef GrResourceCache_DEFINED | 11 #ifndef GrResourceCache_DEFINED |
12 #define GrResourceCache_DEFINED | 12 #define GrResourceCache_DEFINED |
13 | 13 |
14 #include "GrConfig.h" | 14 #include "GrConfig.h" |
15 #include "GrTypes.h" | 15 #include "GrTypes.h" |
16 #include "GrTHashTable.h" | 16 #include "GrTMultiMap.h" |
17 #include "GrBinHashKey.h" | 17 #include "GrBinHashKey.h" |
18 #include "SkMessageBus.h" | 18 #include "SkMessageBus.h" |
19 #include "SkTInternalLList.h" | 19 #include "SkTInternalLList.h" |
20 | 20 |
21 class GrResource; | 21 class GrResource; |
22 class GrResourceEntry; | 22 class GrResourceEntry; |
23 | 23 |
24 class GrResourceKey { | 24 class GrResourceKey { |
25 public: | 25 public: |
26 enum { | |
27 kHashBits = 7, | |
28 kHashCount = 1 << kHashBits, | |
29 kHashMask = kHashCount - 1 | |
30 }; | |
31 | |
32 static GrCacheID::Domain ScratchDomain() { | 26 static GrCacheID::Domain ScratchDomain() { |
33 static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); | 27 static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); |
34 return gDomain; | 28 return gDomain; |
35 } | 29 } |
36 | 30 |
37 /** Uniquely identifies the GrResource subclass in the key to avoid collisio
ns | 31 /** Uniquely identifies the GrResource subclass in the key to avoid collisio
ns |
38 across resource types. */ | 32 across resource types. */ |
39 typedef uint8_t ResourceType; | 33 typedef uint8_t ResourceType; |
40 | 34 |
41 /** Flags set by the GrResource subclass. */ | 35 /** Flags set by the GrResource subclass. */ |
(...skipping 12 matching lines...) Expand all Loading... |
54 } | 48 } |
55 | 49 |
56 GrResourceKey() { | 50 GrResourceKey() { |
57 fKey.reset(); | 51 fKey.reset(); |
58 } | 52 } |
59 | 53 |
60 void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) { | 54 void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) { |
61 this->init(id.getDomain(), id.getKey(), type, flags); | 55 this->init(id.getDomain(), id.getKey(), type, flags); |
62 } | 56 } |
63 | 57 |
64 //!< returns hash value [0..kHashMask] for the key | 58 uint32_t getHash() const { |
65 int getHash() const { | 59 return fKey.getHash(); |
66 return fKey.getHash() & kHashMask; | |
67 } | 60 } |
68 | 61 |
69 bool isScratch() const { | 62 bool isScratch() const { |
70 return ScratchDomain() == | 63 return ScratchDomain() == |
71 *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() + | 64 *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() + |
72 kCacheIDDomainOffset); | 65 kCacheIDDomainOffset); |
73 } | 66 } |
74 | 67 |
75 ResourceType getResourceType() const { | 68 ResourceType getResourceType() const { |
76 return *reinterpret_cast<const ResourceType*>(fKey.getData() + | 69 return *reinterpret_cast<const ResourceType*>(fKey.getData() + |
77 kResourceTypeOffset); | 70 kResourceTypeOffset); |
78 } | 71 } |
79 | 72 |
80 ResourceFlags getResourceFlags() const { | 73 ResourceFlags getResourceFlags() const { |
81 return *reinterpret_cast<const ResourceFlags*>(fKey.getData() + | 74 return *reinterpret_cast<const ResourceFlags*>(fKey.getData() + |
82 kResourceFlagsOffset); | 75 kResourceFlagsOffset); |
83 } | 76 } |
84 | 77 |
85 bool operator==(const GrResourceKey& other) const { return fKey == other.fKe
y; } | 78 bool operator==(const GrResourceKey& other) const { return fKey == other.fKe
y; } |
86 bool operator<(const GrResourceKey& other) const { return fKey < other.fKey;
} | |
87 | |
88 static bool LessThan(const GrResourceEntry& entry, const GrResourceKey& key)
; | |
89 static bool Equals(const GrResourceEntry& entry, const GrResourceKey& key); | |
90 #ifdef SK_DEBUG | |
91 static bool LessThan(const GrResourceEntry& a, const GrResourceEntry& b); | |
92 static bool Equals(const GrResourceEntry& a, const GrResourceEntry& b); | |
93 #endif | |
94 | 79 |
95 private: | 80 private: |
96 enum { | 81 enum { |
97 kCacheIDKeyOffset = 0, | 82 kCacheIDKeyOffset = 0, |
98 kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key), | 83 kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key), |
99 kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain), | 84 kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain), |
100 kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType), | 85 kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType), |
101 kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags), | 86 kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags), |
102 kKeySize = SkAlign4(kPadOffset), | 87 kKeySize = SkAlign4(kPadOffset), |
103 kPadSize = kKeySize - kPadOffset | 88 kPadSize = kKeySize - kPadOffset |
(...skipping 24 matching lines...) Expand all Loading... |
128 GrResourceKey key; | 113 GrResourceKey key; |
129 }; | 114 }; |
130 | 115 |
131 /////////////////////////////////////////////////////////////////////////////// | 116 /////////////////////////////////////////////////////////////////////////////// |
132 | 117 |
133 class GrResourceEntry { | 118 class GrResourceEntry { |
134 public: | 119 public: |
135 GrResource* resource() const { return fResource; } | 120 GrResource* resource() const { return fResource; } |
136 const GrResourceKey& key() const { return fKey; } | 121 const GrResourceKey& key() const { return fKey; } |
137 | 122 |
| 123 static const GrResourceKey& GetKey(const GrResourceEntry& e) { return e.key(
); } |
| 124 static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); } |
| 125 static bool Equal(const GrResourceEntry& a, const GrResourceKey& b) { |
| 126 return a.key() == b; |
| 127 } |
138 #ifdef SK_DEBUG | 128 #ifdef SK_DEBUG |
139 void validate() const; | 129 void validate() const; |
140 #else | 130 #else |
141 void validate() const {} | 131 void validate() const {} |
142 #endif | 132 #endif |
143 | 133 |
144 private: | 134 private: |
145 GrResourceEntry(const GrResourceKey& key, GrResource* resource); | 135 GrResourceEntry(const GrResourceKey& key, GrResource* resource); |
146 ~GrResourceEntry(); | 136 ~GrResourceEntry(); |
147 | 137 |
148 GrResourceKey fKey; | 138 GrResourceKey fKey; |
149 GrResource* fResource; | 139 GrResource* fResource; |
150 | 140 |
151 // we're a linked list | 141 // Linked list for the LRU ordering. |
152 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceEntry); | 142 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceEntry); |
153 | 143 |
154 friend class GrResourceCache; | 144 friend class GrResourceCache; |
155 friend class GrDLinkedList; | |
156 }; | 145 }; |
157 | 146 |
158 inline bool GrResourceKey::LessThan(const GrResourceEntry& entry, const GrResour
ceKey& key) { | |
159 return entry.key() < key; | |
160 } | |
161 | |
162 inline bool GrResourceKey::Equals(const GrResourceEntry& entry, const GrResource
Key& key) { | |
163 return entry.key() == key; | |
164 } | |
165 | |
166 #ifdef SK_DEBUG | |
167 inline bool GrResourceKey::LessThan(const GrResourceEntry& a, const GrResourceEn
try& b) { | |
168 return a.key() < b.key(); | |
169 } | |
170 | |
171 inline bool GrResourceKey::Equals(const GrResourceEntry& a, const GrResourceEntr
y& b) { | |
172 return a.key() == b.key(); | |
173 } | |
174 #endif | |
175 | |
176 /////////////////////////////////////////////////////////////////////////////// | 147 /////////////////////////////////////////////////////////////////////////////// |
177 | 148 |
178 /** | 149 /** |
179 * Cache of GrResource objects. | 150 * Cache of GrResource objects. |
180 * | 151 * |
181 * These have a corresponding GrResourceKey, built from 128bits identifying the | 152 * These have a corresponding GrResourceKey, built from 128bits identifying the |
182 * resource. | 153 * resource. Multiple resources can map to same GrResourceKey. |
183 * | 154 * |
184 * The cache stores the entries in a double-linked list, which is its LRU. | 155 * The cache stores the entries in a double-linked list, which is its LRU. |
185 * When an entry is "locked" (i.e. given to the caller), it is moved to the | 156 * When an entry is "locked" (i.e. given to the caller), it is moved to the |
186 * head of the list. If/when we must purge some of the entries, we walk the | 157 * head of the list. If/when we must purge some of the entries, we walk the |
187 * list backwards from the tail, since those are the least recently used. | 158 * list backwards from the tail, since those are the least recently used. |
188 * | 159 * |
189 * For fast searches, we maintain a sorted array (based on the GrResourceKey) | 160 * For fast searches, we maintain a hash map based on the GrResourceKey. |
190 * which we can bsearch. When a new entry is added, it is inserted into this | |
191 * array. | |
192 * | |
193 * For even faster searches, a hash is computed from the Key. If there is | |
194 * a collision between two keys with the same hash, we fall back on the | |
195 * bsearch, and update the hash to reflect the most recent Key requested. | |
196 * | 161 * |
197 * It is a goal to make the GrResourceCache the central repository and bookkeep
er | 162 * It is a goal to make the GrResourceCache the central repository and bookkeep
er |
198 * of all resources. It should replace the linked list of GrResources that | 163 * of all resources. It should replace the linked list of GrResources that |
199 * GrGpu uses to call abandon/release. | 164 * GrGpu uses to call abandon/release. |
200 */ | 165 */ |
201 class GrResourceCache { | 166 class GrResourceCache { |
202 public: | 167 public: |
203 GrResourceCache(int maxCount, size_t maxBytes); | 168 GrResourceCache(int maxCount, size_t maxBytes); |
204 ~GrResourceCache(); | 169 ~GrResourceCache(); |
205 | 170 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 enum BudgetBehaviors { | 306 enum BudgetBehaviors { |
342 kAccountFor_BudgetBehavior, | 307 kAccountFor_BudgetBehavior, |
343 kIgnore_BudgetBehavior | 308 kIgnore_BudgetBehavior |
344 }; | 309 }; |
345 | 310 |
346 void internalDetach(GrResourceEntry*, BudgetBehaviors behavior = kAccountFor
_BudgetBehavior); | 311 void internalDetach(GrResourceEntry*, BudgetBehaviors behavior = kAccountFor
_BudgetBehavior); |
347 void attachToHead(GrResourceEntry*, BudgetBehaviors behavior = kAccountFor_B
udgetBehavior); | 312 void attachToHead(GrResourceEntry*, BudgetBehaviors behavior = kAccountFor_B
udgetBehavior); |
348 | 313 |
349 void removeInvalidResource(GrResourceEntry* entry); | 314 void removeInvalidResource(GrResourceEntry* entry); |
350 | 315 |
351 GrTHashTable<GrResourceEntry, GrResourceKey, 8> fCache; | 316 GrTMultiMap<GrResourceEntry, |
| 317 GrResourceKey, |
| 318 GrResourceEntry::GetKey, |
| 319 GrResourceEntry::Hash, |
| 320 GrResourceEntry::Equal> fCache; |
352 | 321 |
353 // We're an internal doubly linked list | 322 // We're an internal doubly linked list |
354 typedef SkTInternalLList<GrResourceEntry> EntryList; | 323 typedef SkTInternalLList<GrResourceEntry> EntryList; |
355 EntryList fList; | 324 EntryList fList; |
356 | 325 |
357 #ifdef SK_DEBUG | 326 #ifdef SK_DEBUG |
358 // These objects cannot be returned by a search | 327 // These objects cannot be returned by a search |
359 EntryList fExclusiveList; | 328 EntryList fExclusiveList; |
360 #endif | 329 #endif |
361 | 330 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 GrResourceCache* fCache; | 377 GrResourceCache* fCache; |
409 }; | 378 }; |
410 #else | 379 #else |
411 class GrAutoResourceCacheValidate { | 380 class GrAutoResourceCacheValidate { |
412 public: | 381 public: |
413 GrAutoResourceCacheValidate(GrResourceCache*) {} | 382 GrAutoResourceCacheValidate(GrResourceCache*) {} |
414 }; | 383 }; |
415 #endif | 384 #endif |
416 | 385 |
417 #endif | 386 #endif |
OLD | NEW |