add getter/setter for TextureCache, so that clients can make their budget
decisions at runtime or per-context, rather than just at compile-time. Leaving
in the default values as is.



git-svn-id: http://skia.googlecode.com/svn/trunk@709 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 905fe50..fdf0e9f 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -287,6 +287,29 @@
         GrRenderTarget* fPrevTarget;

     };

 

+    ///////////////////////////////////////////////////////////////////////////

+

+    /**

+     *  Return the current texture cache limits.

+     *

+     *  @param maxTextures If non-null, returns maximum number of textures that

+     *                     can be held in the cache.

+     *  @param maxTextureBytes If non-null, returns maximum number of bytes of

+     *                         texture memory that can be held in the cache.

+     */

+    void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;

+

+    /**

+     *  Specify the texture cache limits. If the current cache exceeds either

+     *  of these, it will be purged (LRU) to keep the cache within these limits.

+     *

+     *  @param maxTextures The maximum number of textures that can be held in

+     *                     the cache.

+     *  @param maxTextureBytes The maximum number of bytes of texture memory

+     *                         that can be held in the cache.

+     */

+    void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);

+

     /* -------------------------------------------------------

      */

 

diff --git a/gpu/include/GrTextureCache.h b/gpu/include/GrTextureCache.h
index e3d4f0a..68e1daa 100644
--- a/gpu/include/GrTextureCache.h
+++ b/gpu/include/GrTextureCache.h
@@ -67,7 +67,7 @@
 
     friend bool operator==(const GrTextureKey& a, const GrTextureKey& b) {
         GR_DEBUGASSERT(-1 != a.fHashIndex && -1 != b.fHashIndex);
-        return a.fP0 == b.fP0 && a.fP1 == b.fP1 && a.fP2 == b.fP2 && 
+        return a.fP0 == b.fP0 && a.fP1 == b.fP1 && a.fP2 == b.fP2 &&
                a.fPrivateBits == b.fPrivateBits;
     }
 
@@ -82,16 +82,16 @@
         RET_IF_LT_OR_GT(a.fP2, b.fP2);
         return a.fPrivateBits < b.fPrivateBits;
     }
-    
+
 private:
-    void finalize(uint32_t privateBits) { 
+    void finalize(uint32_t privateBits) {
         fPrivateBits = privateBits;
         this->computeHashIndex();
     }
-    
+
     uint16_t width() const { return fP2 & 0xffff; }
     uint16_t height() const { return (fP2 >> 16); }
-    
+
     static uint32_t rol(uint32_t x) {
         return (x >> 24) | (x << 8);
     }
@@ -101,7 +101,7 @@
     static uint32_t rohalf(uint32_t x) {
         return (x >> 16) | (x << 16);
     }
-    
+
     void computeHashIndex() {
         uint32_t hash = fP0 ^ rol(fP1) ^ ror(fP2) ^ rohalf(fPrivateBits);
         // this way to mix and reduce hash to its index may have to change
@@ -118,7 +118,7 @@
 
     // this is computed from the fP... fields
     int         fHashIndex;
-    
+
     friend class GrContext;
 };
 
@@ -194,6 +194,27 @@
     ~GrTextureCache();  // uses kFreeTexture_DeleteMode
 
     /**
+     *  Return the current texture cache limits.
+     *
+     *  @param maxTextures If non-null, returns maximum number of textures that
+     *                     can be held in the cache.
+     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
+     *                         texture memory that can be held in the cache.
+     */
+    void getLimits(int* maxTextures, size_t* maxTextureBytes) const;
+
+    /**
+     *  Specify the texture cache limits. If the current cache exceeds either
+     *  of these, it will be purged (LRU) to keep the cache within these limits.
+     *
+     *  @param maxTextures The maximum number of textures that can be held in
+     *                     the cache.
+     *  @param maxTextureBytes The maximum number of bytes of texture memory
+     *                         that can be held in the cache.
+     */
+    void setLimits(int maxTextures, size_t maxTextureBytes);
+
+    /**
      *  Search for an entry with the same Key. If found, "lock" it and return it.
      *  If not found, return null.
      */
@@ -207,18 +228,18 @@
      *  it when we are purged or deleted.
      */
     GrTextureEntry* createAndLock(const GrTextureKey&, GrTexture*);
-    
+
     /**
-     * Detach removes an entry from the cache. This prevents the entry from 
-     * being found by a subsequent findAndLock() until it is reattached. The 
+     * Detach removes an entry from the cache. This prevents the entry from
+     * being found by a subsequent findAndLock() until it is reattached. The
      * entry still counts against the cache's budget and should be reattached
      * when exclusive access is no longer needed.
      */
     void detach(GrTextureEntry*);
-    
+
     /**
-     * Reattaches a texture to the cache and unlocks it. Allows it to be found 
-     * by a subsequent findAndLock or be purged (provided its lock count is 
+     * Reattaches a texture to the cache and unlocks it. Allows it to be found
+     * by a subsequent findAndLock or be purged (provided its lock count is
      * now 0.)
      */
     void reattachAndUnlock(GrTextureEntry*);
@@ -254,8 +275,8 @@
     GrTextureEntry* fTail;
 
     // our budget, used in purgeAsNeeded()
-    const int fMaxCount;
-    const size_t fMaxBytes;
+    int fMaxCount;
+    size_t fMaxBytes;
 
     // our current stats, related to our budget
     int fEntryCount;
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 5128602..ee78848 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -232,6 +232,17 @@
     return fGpu->createTexture(desc, srcData, rowBytes);

 }

 

+void GrContext::getTextureCacheLimits(int* maxTextures,

+                                      size_t* maxTextureBytes) const {

+    fTextureCache->getLimits(maxTextures, maxTextureBytes);

+}

+

+void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {

+    fTextureCache->setLimits(maxTextures, maxTextureBytes);

+}

+

+///////////////////////////////////////////////////////////////////////////////

+

 GrRenderTarget* GrContext::createPlatformRenderTarget(intptr_t platformRenderTarget,

                                                       int width, int height) {

     return fGpu->createPlatformRenderTarget(platformRenderTarget,

diff --git a/gpu/src/GrTextureCache.cpp b/gpu/src/GrTextureCache.cpp
index 3ba3339..bc2a904 100644
--- a/gpu/src/GrTextureCache.cpp
+++ b/gpu/src/GrTextureCache.cpp
@@ -41,7 +41,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrTextureCache::GrTextureCache(int maxCount, size_t maxBytes) : 
+GrTextureCache::GrTextureCache(int maxCount, size_t maxBytes) :
         fMaxCount(maxCount),
         fMaxBytes(maxBytes) {
     fEntryCount          = 0;
@@ -54,11 +54,31 @@
 
 GrTextureCache::~GrTextureCache() {
     GrAutoTextureCacheValidate atcv(this);
-    
+
     this->deleteAll(kFreeTexture_DeleteMode);
 }
 
-void GrTextureCache::internalDetach(GrTextureEntry* entry, 
+void GrTextureCache::getLimits(int* maxTextures, size_t* maxTextureBytes) const{
+    if (maxTextures) {
+        *maxTextures = fMaxCount;
+    }
+    if (maxTextureBytes) {
+        *maxTextureBytes = fMaxBytes;
+    }
+}
+
+void GrTextureCache::setLimits(int maxTextures, size_t maxTextureBytes) {
+    bool smaller = (maxTextures < fMaxCount) || (maxTextureBytes < fMaxBytes);
+
+    fMaxCount = maxTextures;
+    fMaxBytes = maxTextureBytes;
+
+    if (smaller) {
+        this->purgeAsNeeded();
+    }
+}
+
+void GrTextureCache::internalDetach(GrTextureEntry* entry,
                                     bool clientDetach) {
     GrTextureEntry* prev = entry->fPrev;
     GrTextureEntry* next = entry->fNext;
@@ -84,7 +104,7 @@
     }
 }
 
-void GrTextureCache::attachToHead(GrTextureEntry* entry, 
+void GrTextureCache::attachToHead(GrTextureEntry* entry,
                                   bool clientReattach) {
     entry->fPrev = NULL;
     entry->fNext = fHead;
@@ -114,7 +134,7 @@
     Key(const GrTextureKey& key) : fKey(key) {}
 
     uint32_t getHash() const { return fKey.hashIndex(); }
-    
+
     static bool LT(const T& entry, const Key& key) {
         return entry.key() < key.fKey;
     }
@@ -180,7 +200,7 @@
 
 void GrTextureCache::unlock(GrTextureEntry* entry) {
     GrAutoTextureCacheValidate atcv(this);
-    
+
     GrAssert(entry);
     GrAssert(entry->isLocked());
     GrAssert(fCache.find(entry->key()));
@@ -191,7 +211,7 @@
 
 void GrTextureCache::purgeAsNeeded() {
     GrAutoTextureCacheValidate atcv(this);
-    
+
     GrTextureEntry* entry = fTail;
     while (entry) {
         if (fEntryCount <= fMaxCount && fEntryBytes <= fMaxBytes) {
@@ -202,7 +222,7 @@
         if (!entry->isLocked()) {
             // remove from our cache
             fCache.remove(entry->fKey, entry);
-            
+
             // remove from our llist
             this->internalDetach(entry, false);
 
@@ -220,7 +240,7 @@
 void GrTextureCache::deleteAll(DeleteMode mode) {
     GrAssert(!fClientDetachedCount);
     GrAssert(!fClientDetachedBytes);
-    
+
     GrTextureEntry* entry = fHead;
     while (entry) {
         GrAssert(!entry->isLocked());
@@ -257,7 +277,7 @@
 void GrTextureCache::validate() const {
     GrAssert(!fHead == !fTail);
     GrAssert(!fEntryCount == !fEntryBytes);
-    GrAssert(!fClientDetachedBytes == !fClientDetachedBytes); 
+    GrAssert(!fClientDetachedBytes == !fClientDetachedBytes);
     GrAssert(fClientDetachedBytes <= fEntryBytes);
     GrAssert(fClientDetachedCount <= fEntryCount);
     GrAssert((fEntryCount - fClientDetachedCount) == fCache.count());
@@ -265,7 +285,7 @@
     GrAssert(fEntryCount >= 0);
     GrAssert(fClientDetachedCount >= 0);
     GrAssert(fClientDetachedBytes >= 0);
-    
+
     fCache.validate();
 
     GrTextureEntry* entry = fHead;