| Index: src/gpu/GrResourceCache.h
|
| diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..80e4b3f1e40d0e499f7d67def7a8b7c2ce1f7c8c
|
| --- /dev/null
|
| +++ b/src/gpu/GrResourceCache.h
|
| @@ -0,0 +1,251 @@
|
| +
|
| +/*
|
| + * Copyright 2011 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#ifndef GrResourceCache_DEFINED
|
| +#define GrResourceCache_DEFINED
|
| +
|
| +#include "GrDrawTargetCaps.h"
|
| +#include "GrResourceKey.h"
|
| +#include "SkTMultiMap.h"
|
| +#include "SkMessageBus.h"
|
| +#include "SkTInternalLList.h"
|
| +
|
| +class GrGpuResource;
|
| +class GrResourceCache;
|
| +class GrResourceCacheEntry;
|
| +
|
| +
|
| +// The cache listens for these messages to purge junk resources proactively.
|
| +struct GrResourceInvalidatedMessage {
|
| + GrResourceKey key;
|
| +};
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +class GrResourceCacheEntry {
|
| +public:
|
| + GrGpuResource* resource() const { return fResource; }
|
| +
|
| + static uint32_t Hash(const GrGpuResource* resource) {
|
| + return static_cast<uint32_t>(reinterpret_cast<intptr_t>(resource));
|
| + }
|
| +#ifdef SK_DEBUG
|
| + void validate() const;
|
| +#else
|
| + void validate() const {}
|
| +#endif
|
| +
|
| + /**
|
| + * Update the cached size for this entry and inform the resource cache that
|
| + * it has changed. Usually invoked from GrGpuResource::didChangeGpuMemorySize,
|
| + * not directly from here.
|
| + */
|
| + void didChangeResourceSize();
|
| +
|
| +private:
|
| + GrResourceCacheEntry(GrResourceCache*, GrGpuResource*);
|
| + ~GrResourceCacheEntry();
|
| +
|
| + GrResourceCache* fResourceCache;
|
| + GrGpuResource* fResource;
|
| + size_t fCachedSize;
|
| +
|
| + // Linked list for the LRU ordering.
|
| + SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceCacheEntry);
|
| +
|
| + friend class GrResourceCache;
|
| + friend class GrContext;
|
| +};
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +/**
|
| + * Cache of GrGpuResource objects.
|
| + *
|
| + * These have a corresponding GrResourceKey, built from 128bits identifying the
|
| + * 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 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 GrGpuResources that
|
| + * GrGpu uses to call abandon/release.
|
| + */
|
| +class GrResourceCache {
|
| +public:
|
| + GrResourceCache(const GrDrawTargetCaps*, int maxCount, size_t maxBytes);
|
| + ~GrResourceCache();
|
| +
|
| + /**
|
| + * Return the current resource cache limits.
|
| + *
|
| + * @param maxResource If non-null, returns maximum number of resources
|
| + * that can be held in the cache.
|
| + * @param maxBytes If non-null, returns maximum number of bytes of
|
| + * gpu memory that can be held in the cache.
|
| + */
|
| + void getLimits(int* maxResources, size_t* maxBytes) const;
|
| +
|
| + /**
|
| + * Specify the resource cache limits. If the current cache exceeds either
|
| + * of these, it will be purged (LRU) to keep the cache within these limits.
|
| + *
|
| + * @param maxResources The maximum number of resources that can be held in
|
| + * the cache.
|
| + * @param maxBytes The maximum number of bytes of resource memory that
|
| + * can be held in the cache.
|
| + */
|
| + void setLimits(int maxResources, size_t maxResourceBytes);
|
| +
|
| + /**
|
| + * The callback function used by the cache when it is still over budget
|
| + * after a purge. The passed in 'data' is the same 'data' handed to
|
| + * setOverbudgetCallback. The callback returns true if some resources
|
| + * have been freed.
|
| + */
|
| + typedef bool (*PFOverbudgetCB)(void* data);
|
| +
|
| + /**
|
| + * Set the callback the cache should use when it is still over budget
|
| + * after a purge. The 'data' provided here will be passed back to the
|
| + * callback. Note that the cache will attempt to purge any resources newly
|
| + * freed by the callback.
|
| + */
|
| + void setOverbudgetCallback(PFOverbudgetCB overbudgetCB, void* data) {
|
| + fOverbudgetCB = overbudgetCB;
|
| + fOverbudgetData = data;
|
| + }
|
| +
|
| + /**
|
| + * Returns the number of bytes consumed by cached resources.
|
| + */
|
| + size_t getCachedResourceBytes() const { return fEntryBytes; }
|
| +
|
| + /**
|
| + * Returns the number of cached resources.
|
| + */
|
| + int getCachedResourceCount() const { return fEntryCount; }
|
| +
|
| + void makeResourceMRU(GrGpuResource*);
|
| +
|
| + /** Called by GrGpuResources when they detects that they are newly purgable. */
|
| + void notifyPurgable(const GrGpuResource*);
|
| +
|
| + /**
|
| + * Add the new resource to the cache (by creating a new cache entry based
|
| + * on the provided key and resource).
|
| + *
|
| + * Ownership of the resource is transferred to the resource cache,
|
| + * which will unref() it when it is purged or deleted.
|
| + *
|
| + * This can fail if the key is already taken, or the resource is already in
|
| + * the cache.
|
| + */
|
| + bool addResource(const GrResourceKey& key, GrGpuResource* resource);
|
| +
|
| + /**
|
| + * Notify the cache that the size of a resource has changed.
|
| + */
|
| + void didIncreaseResourceSize(const GrResourceCacheEntry*, size_t amountInc);
|
| + void didDecreaseResourceSize(const GrResourceCacheEntry*, size_t amountDec);
|
| +
|
| + /**
|
| + * Remove a resource from the cache and delete it!
|
| + */
|
| + void deleteResource(GrResourceCacheEntry* entry);
|
| +
|
| + /**
|
| + * Removes every resource in the cache that isn't locked.
|
| + */
|
| + void purgeAllUnlocked();
|
| +
|
| + /**
|
| + * Allow cache to purge unused resources to obey resource limitations
|
| + * Note: this entry point will be hidden (again) once totally ref-driven
|
| + * cache maintenance is implemented. Note that the overbudget callback
|
| + * will be called if the initial purge doesn't get the cache under
|
| + * its budget.
|
| + *
|
| + * extraCount and extraBytes are added to the current resource allocation
|
| + * to make sure enough room is available for future additions (e.g,
|
| + * 10MB across 10 textures is about to be added).
|
| + */
|
| + void purgeAsNeeded(int extraCount = 0, size_t extraBytes = 0);
|
| +
|
| +#ifdef SK_DEBUG
|
| + void validate() const;
|
| +#else
|
| + void validate() const {}
|
| +#endif
|
| +
|
| +#if GR_CACHE_STATS
|
| + void printStats();
|
| +#endif
|
| +
|
| +private:
|
| + void internalDetach(GrResourceCacheEntry*);
|
| + void attachToHead(GrResourceCacheEntry*);
|
| + void purgeInvalidated();
|
| + void internalPurge(int extraCount, size_t extraBytes);
|
| +#ifdef SK_DEBUG
|
| + static size_t countBytes(const SkTInternalLList<GrResourceCacheEntry>& list);
|
| +#endif
|
| +
|
| + // We're an internal doubly linked list
|
| + typedef SkTInternalLList<GrResourceCacheEntry> EntryList;
|
| + EntryList fList;
|
| +
|
| + // our budget, used in purgeAsNeeded()
|
| + int fMaxCount;
|
| + size_t fMaxBytes;
|
| +
|
| + // our current stats, related to our budget
|
| +#if GR_CACHE_STATS
|
| + int fHighWaterEntryCount;
|
| + size_t fHighWaterEntryBytes;
|
| +#endif
|
| +
|
| + int fEntryCount;
|
| + size_t fEntryBytes;
|
| +
|
| + // prevents recursive purging
|
| + bool fPurging;
|
| +
|
| + PFOverbudgetCB fOverbudgetCB;
|
| + void* fOverbudgetData;
|
| +
|
| + SkAutoTUnref<const GrDrawTargetCaps> fCaps;
|
| +};
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +#ifdef SK_DEBUG
|
| + class GrAutoResourceCacheValidate {
|
| + public:
|
| + GrAutoResourceCacheValidate(GrResourceCache* cache) : fCache(cache) {
|
| + cache->validate();
|
| + }
|
| + ~GrAutoResourceCacheValidate() {
|
| + fCache->validate();
|
| + }
|
| + private:
|
| + GrResourceCache* fCache;
|
| + };
|
| +#else
|
| + class GrAutoResourceCacheValidate {
|
| + public:
|
| + GrAutoResourceCacheValidate(GrResourceCache*) {}
|
| + };
|
| +#endif
|
| +
|
| +#endif
|
|
|