Adds a mechanism for GrCacheable objects to notify the resource cache
when their size has changed. GrResourceCacheEntry now holds a
reference to the cache, and a cached value of the resource's most
recent size.

Also utilizes this new functionality for mipmaps, and adds a test for
changing resource sizes.

R=bsalomon@google.com, robertphillips@google.com

Author: cdalton@nvidia.com

Review URL: https://codereview.chromium.org/257093002

git-svn-id: http://skia.googlecode.com/svn/trunk/include@14576 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/GrCacheable.h b/gpu/GrCacheable.h
index 75dec16..39c62b1 100644
--- a/gpu/GrCacheable.h
+++ b/gpu/GrCacheable.h
@@ -46,6 +46,14 @@
 
     bool isInCache() const { return NULL != fCacheEntry; }
 
+    /**
+     * This entry point should be called whenever gpuMemorySize() begins
+     * reporting a different size. If the object is in the cache, it will call
+     * gpuMemorySize() immediately and pass the new size on to the resource
+     * cache.
+     */
+    void didChangeGpuMemorySize() const;
+
 private:
     GrResourceCacheEntry* fCacheEntry;  // NULL if not in cache
 
diff --git a/gpu/GrTexture.h b/gpu/GrTexture.h
index 1b9f7b7..ac31f51 100644
--- a/gpu/GrTexture.h
+++ b/gpu/GrTexture.h
@@ -44,22 +44,16 @@
         return 0 != (fDesc.fFlags & flags);
     }
 
-    void dirtyMipMaps(bool mipMapsDirty) {
-        fMipMapsDirty = mipMapsDirty;
-    }
+    void dirtyMipMaps(bool mipMapsDirty);
 
     bool mipMapsAreDirty() const {
-        return fMipMapsDirty;
+        return kValid_MipMapsStatus != fMipMapsStatus;
     }
 
     /**
      *  Approximate number of bytes used by the texture
      */
-    virtual size_t gpuMemorySize() const SK_OVERRIDE {
-        return (size_t) fDesc.fWidth *
-                        fDesc.fHeight *
-                        GrBytesPerPixel(fDesc.fConfig);
-    }
+    virtual size_t gpuMemorySize() const SK_OVERRIDE;
 
     // GrSurface overrides
     virtual bool readPixels(int left, int top, int width, int height,
@@ -144,7 +138,7 @@
     GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
     : INHERITED(gpu, isWrapped, desc)
     , fRenderTarget(NULL)
-    , fMipMapsDirty(true) {
+    , fMipMapsStatus(kNotAllocated_MipMapsStatus) {
 
         // only make sense if alloc size is pow2
         fShiftFixedX = 31 - SkCLZ(fDesc.fWidth);
@@ -159,12 +153,18 @@
     void validateDesc() const;
 
 private:
+    enum MipMapsStatus {
+        kNotAllocated_MipMapsStatus,
+        kAllocated_MipMapsStatus,
+        kValid_MipMapsStatus
+    };
+
     // these two shift a fixed-point value into normalized coordinates
     // for this texture if the texture is power of two sized.
     int                 fShiftFixedX;
     int                 fShiftFixedY;
 
-    bool                fMipMapsDirty;
+    MipMapsStatus       fMipMapsStatus;
 
     virtual void internal_dispose() const SK_OVERRIDE;