Index: src/gpu/GrResourceCache.h |
diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h |
index ca30732bbc176fed947b048779022412004fcc94..7ff05b72ed0a1209f475e3b3d6dde6e3aa0bfe68 100644 |
--- a/src/gpu/GrResourceCache.h |
+++ b/src/gpu/GrResourceCache.h |
@@ -13,22 +13,16 @@ |
#include "GrConfig.h" |
#include "GrTypes.h" |
-#include "GrTHashTable.h" |
#include "GrBinHashKey.h" |
+#include "GrResource.h" |
#include "SkMessageBus.h" |
+#include "SkTDynamicHash.h" |
#include "SkTInternalLList.h" |
-class GrResource; |
class GrResourceEntry; |
class GrResourceKey { |
public: |
- enum { |
- kHashBits = 7, |
- kHashCount = 1 << kHashBits, |
- kHashMask = kHashCount - 1 |
- }; |
- |
static GrCacheID::Domain ScratchDomain() { |
static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); |
return gDomain; |
@@ -61,9 +55,8 @@ public: |
this->init(id.getDomain(), id.getKey(), type, flags); |
} |
- //!< returns hash value [0..kHashMask] for the key |
- int getHash() const { |
- return fKey.getHash() & kHashMask; |
+ uint32_t getHash() const { |
+ return fKey.getHash(); |
} |
bool isScratch() const { |
@@ -83,14 +76,6 @@ public: |
} |
bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; } |
- bool operator<(const GrResourceKey& other) const { return fKey < other.fKey; } |
- |
- static bool LessThan(const GrResourceEntry& entry, const GrResourceKey& key); |
- static bool Equals(const GrResourceEntry& entry, const GrResourceKey& key); |
-#ifdef SK_DEBUG |
- static bool LessThan(const GrResourceEntry& a, const GrResourceEntry& b); |
- static bool Equals(const GrResourceEntry& a, const GrResourceEntry& b); |
-#endif |
private: |
enum { |
@@ -130,69 +115,58 @@ struct GrResourceInvalidatedMessage { |
/////////////////////////////////////////////////////////////////////////////// |
+/** GrResourceEntry represents one entry in lookup cache (hash). It might represent multiple entries |
mtklein
2013/12/03 19:02:02
I think we need to rework this comment.
/** GrRes
|
+ * (resources) in the GrResourceCache. |
+ */ |
class GrResourceEntry { |
+ SK_DECLARE_NAMED_INTERNAL_LLIST(GrResource, CacheEntryResources, fResources); |
+ |
public: |
- GrResource* resource() const { return fResource; } |
const GrResourceKey& key() const { return fKey; } |
-#ifdef SK_DEBUG |
- void validate() const; |
-#else |
- void validate() const {} |
-#endif |
+ void addResource(GrResource* resource); |
+ /** Returns true if entry should be deleted. */ |
mtklein
2013/12/03 19:02:02
For consistency with the other methods below, it'd
|
+ bool removeResource(GrResource* resource); |
+ /** Returns true if entry should be deleted. */ |
+ bool removeExclusiveResource(GrResource* resource); |
+ |
+ void makeExclusive(GrResource* resource); |
+ void makeNonExclusive(GrResource* resource); |
+ |
+ CacheEntryResourcesInternalLListType& resources() { return fResources; } |
+ |
+ static const GrResourceKey& GetKey(const GrResourceEntry& e) { return e.key(); } |
+ static uint32_t GetKeyHash(const GrResourceKey& key) { return key.getHash(); } |
+ static bool EqualsKey(const GrResourceEntry& a, const GrResourceKey& b) { |
+ return a.key() == b; |
+ } |
private: |
- GrResourceEntry(const GrResourceKey& key, GrResource* resource); |
+ GrResourceEntry(const GrResourceKey& key, GrResource* firstResource); |
~GrResourceEntry(); |
- GrResourceKey fKey; |
- GrResource* fResource; |
+ bool isEmpty() const { return fExclusiveCount == 0 && fResources.isEmpty(); } |
- // we're a linked list |
- SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceEntry); |
+ GrResourceKey fKey; |
+ int fExclusiveCount; |
friend class GrResourceCache; |
- friend class GrDLinkedList; |
}; |
-inline bool GrResourceKey::LessThan(const GrResourceEntry& entry, const GrResourceKey& key) { |
- return entry.key() < key; |
-} |
- |
-inline bool GrResourceKey::Equals(const GrResourceEntry& entry, const GrResourceKey& key) { |
- return entry.key() == key; |
-} |
- |
-#ifdef SK_DEBUG |
-inline bool GrResourceKey::LessThan(const GrResourceEntry& a, const GrResourceEntry& b) { |
- return a.key() < b.key(); |
-} |
- |
-inline bool GrResourceKey::Equals(const GrResourceEntry& a, const GrResourceEntry& b) { |
- return a.key() == b.key(); |
-} |
-#endif |
- |
/////////////////////////////////////////////////////////////////////////////// |
/** |
* Cache of GrResource objects. |
* |
* These have a corresponding GrResourceKey, built from 128bits identifying the |
- * resource. |
+ * resource. Multiple resources can map to same GrResourceKey. |
* |
* The cache stores the entries in a double-linked list, which is its LRU. |
* When an entry is "locked" (i.e. given to the caller), it is moved to the |
* head of the list. If/when we must purge some of the entries, we walk the |
* list backwards from the tail, since those are the least recently used. |
* |
- * For fast searches, we maintain a sorted array (based on the GrResourceKey) |
- * which we can bsearch. When a new entry is added, it is inserted into this |
- * array. |
- * |
- * For even faster searches, a hash is computed from the Key. If there is |
- * a collision between two keys with the same hash, we fall back on the |
- * bsearch, and update the hash to reflect the most recent Key requested. |
+ * For fast searches, we maintain a hash map based on the GrResourceKey. |
* |
* It is a goal to make the GrResourceCache the central repository and bookkeeper |
* of all resources. It should replace the linked list of GrResources that |
@@ -291,23 +265,26 @@ public: |
bool hasKey(const GrResourceKey& key) const { return NULL != fCache.find(key); } |
/** |
- * Hide 'entry' so that future searches will not find it. Such |
- * hidden entries will not be purged. The entry still counts against |
+ * Hide 'resource' so that future searches will not find it. Such |
+ * hidden resources will not be purged. The resource still counts against |
* the cache's budget and should be made non-exclusive when exclusive access |
* is no longer needed. |
*/ |
- void makeExclusive(GrResourceEntry* entry); |
+ void makeExclusive(GrResource* resource); |
/** |
* Restore 'entry' so that it can be found by future searches. 'entry' |
* will also be purgeable (provided its lock count is now 0.) |
*/ |
- void makeNonExclusive(GrResourceEntry* entry); |
+ void makeNonExclusive(GrResource*); |
mtklein
2013/12/03 19:02:02
I don't mind not naming parameters when it's obvio
|
/** |
- * Remove a resource from the cache and delete it! |
+ * Delete a resource from the cache. |
*/ |
- void deleteResource(GrResourceEntry* entry); |
+ void deleteResource(GrResource* resource) { |
+ SkASSERT(1 == resource->getRefCnt()); |
+ this->removeResource(resource); |
+ } |
/** |
* Removes every resource in the cache that isn't locked. |
@@ -343,20 +320,25 @@ private: |
kIgnore_BudgetBehavior |
}; |
- void internalDetach(GrResourceEntry*, BudgetBehaviors behavior = kAccountFor_BudgetBehavior); |
- void attachToHead(GrResourceEntry*, BudgetBehaviors behavior = kAccountFor_BudgetBehavior); |
+ /** Returns true if entry holding the resource is still valid. */ |
+ bool removeResource(GrResource* resource); |
+ |
+ void internalDetach(GrResource*, BudgetBehaviors behavior = kAccountFor_BudgetBehavior); |
+ void attachToHead(GrResource*, BudgetBehaviors behavior = kAccountFor_BudgetBehavior); |
- void removeInvalidResource(GrResourceEntry* entry); |
+ void removeInvalidResource(GrResource* resource); |
- GrTHashTable<GrResourceEntry, GrResourceKey, 8> fCache; |
+ SkTDynamicHash<GrResourceEntry, |
+ GrResourceKey, |
+ GrResourceEntry::GetKey, |
+ GrResourceEntry::GetKeyHash, |
+ GrResourceEntry::EqualsKey> fCache; |
- // We're an internal doubly linked list |
- typedef SkTInternalLList<GrResourceEntry> EntryList; |
- EntryList fList; |
+ SK_DECLARE_NAMED_INTERNAL_LLIST(GrResource, CacheLRU, fList); |
#ifdef SK_DEBUG |
// These objects cannot be returned by a search |
- EntryList fExclusiveList; |
+ CacheLRUInternalLListType fExclusiveList; |
#endif |
// our budget, used in purgeAsNeeded() |
@@ -389,7 +371,7 @@ private: |
void purgeInvalidated(); |
#ifdef SK_DEBUG |
- static size_t countBytes(const SkTInternalLList<GrResourceEntry>& list); |
+ static size_t countBytes(const CacheLRUInternalLListType& list); |
#endif |
}; |