Merge GrGpuObject and GrCacheable.

We want to create a new base class for "meta" gr resources as part of the GrResourceCache rewrite and this is an iterim step towards that goal.s

R=robertphillips@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/414013005
diff --git a/bench/GrResourceCacheBench.cpp b/bench/GrResourceCacheBench.cpp
index 93ae356..b8eacd6 100644
--- a/bench/GrResourceCacheBench.cpp
+++ b/bench/GrResourceCacheBench.cpp
@@ -9,7 +9,7 @@
 #if SK_SUPPORT_GPU
 
 #include "Benchmark.h"
-#include "GrCacheable.h"
+#include "GrGpuObject.h"
 #include "GrContext.h"
 #include "GrResourceCache.h"
 #include "GrStencilBuffer.h"
@@ -21,21 +21,20 @@
     CACHE_SIZE_BYTES = 2 * 1024 * 1024,
 };
 
-class StencilResource : public GrCacheable {
+class StencilResource : public GrGpuObject {
 public:
     SK_DECLARE_INST_COUNT(StencilResource);
-    StencilResource(int id)
-        : fID(id) {
+    StencilResource(GrGpu* gpu, int id)
+        : INHERITED(gpu, false)
+        , fID(id) {
     }
 
+    virtual ~StencilResource() { this->release(); }
+
     virtual size_t gpuMemorySize() const SK_OVERRIDE {
         return 100 + ((fID % 1 == 0) ? -5 : 6);
     }
 
-    virtual bool isValidOnGpu() const SK_OVERRIDE {
-        return true;
-    }
-
     static GrResourceKey ComputeKey(int width, int height, int sampleCnt) {
         return GrStencilBuffer::ComputeKey(width, height, sampleCnt);
     }
@@ -43,24 +42,23 @@
     int fID;
 
 private:
-    typedef GrCacheable INHERITED;
+    typedef GrGpuObject INHERITED;
 };
 
-class TextureResource : public GrCacheable {
+class TextureResource : public GrGpuObject {
 public:
     SK_DECLARE_INST_COUNT(TextureResource);
-    TextureResource(int id)
-        : fID(id) {
+    TextureResource(GrGpu* gpu, int id)
+        : INHERITED(gpu, false)
+        , fID(id) {
     }
 
+    virtual ~TextureResource() { this->release(); }
+
     virtual size_t gpuMemorySize() const SK_OVERRIDE {
         return 100 + ((fID % 1 == 0) ? -40 : 33);
     }
 
-    virtual bool isValidOnGpu() const SK_OVERRIDE {
-        return true;
-    }
-
     static GrResourceKey ComputeKey(const GrTextureDesc& desc) {
         return GrTextureImpl::ComputeScratchKey(desc);
     }
@@ -68,7 +66,7 @@
     int fID;
 
 private:
-    typedef GrCacheable INHERITED;
+    typedef GrGpuObject INHERITED;
 };
 
 static void get_stencil(int i, int* w, int* h, int* s) {
@@ -91,7 +89,7 @@
         int w, h, s;
         get_stencil(i, &w, &h, &s);
         GrResourceKey key = GrStencilBuffer::ComputeKey(w, h, s);
-        GrCacheable* resource = SkNEW_ARGS(StencilResource, (i));
+        GrGpuObject* resource = SkNEW_ARGS(StencilResource, (gpu, i));
         cache->purgeAsNeeded(1, resource->gpuMemorySize());
         cache->addResource(key, resource);
         resource->unref();
@@ -101,7 +99,7 @@
         GrTextureDesc desc;
         get_texture_desc(i, &desc);
         GrResourceKey key =  TextureResource::ComputeKey(desc);
-        GrCacheable* resource = SkNEW_ARGS(TextureResource, (i));
+        GrGpuObject* resource = SkNEW_ARGS(TextureResource, (gpu, i));
         cache->purgeAsNeeded(1, resource->gpuMemorySize());
         cache->addResource(key, resource);
         resource->unref();
@@ -114,7 +112,7 @@
         GrTextureDesc desc;
         get_texture_desc(k, &desc);
         GrResourceKey key = TextureResource::ComputeKey(desc);
-        GrCacheable* item = cache->find(key);
+        GrGpuObject* item = cache->find(key);
         if (NULL == item) {
             SkFAIL("cache add does not work as expected");
             return;
@@ -128,7 +126,7 @@
         int w, h, s;
         get_stencil(k, &w, &h, &s);
         GrResourceKey key = StencilResource::ComputeKey(w, h, s);
-        GrCacheable* item = cache->find(key);
+        GrGpuObject* item = cache->find(key);
         if (NULL == item) {
             SkFAIL("cache add does not work as expected");
             return;
@@ -145,7 +143,7 @@
         get_texture_desc(k, &desc);
         desc.fHeight |= 1;
         GrResourceKey key = TextureResource::ComputeKey(desc);
-        GrCacheable* item = cache->find(key);
+        GrGpuObject* item = cache->find(key);
         if (NULL != item) {
             SkFAIL("cache add does not work as expected");
             return;
@@ -156,7 +154,7 @@
         get_stencil(k, &w, &h, &s);
         h |= 1;
         GrResourceKey key = StencilResource::ComputeKey(w, h, s);
-        GrCacheable* item = cache->find(key);
+        GrGpuObject* item = cache->find(key);
         if (NULL != item) {
             SkFAIL("cache add does not work as expected");
             return;
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index bcb124b..64829cc 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -9,7 +9,6 @@
   'variables': {
     'skgpu_sources': [
       '<(skia_include_path)/gpu/GrBackendEffectFactory.h',
-      '<(skia_include_path)/gpu/GrCacheable.h',
       '<(skia_include_path)/gpu/GrClipData.h',
       '<(skia_include_path)/gpu/GrColor.h',
       '<(skia_include_path)/gpu/GrConfig.h',
@@ -57,7 +56,6 @@
       '<(skia_src_path)/gpu/GrBlend.h',
       '<(skia_src_path)/gpu/GrBufferAllocPool.cpp',
       '<(skia_src_path)/gpu/GrBufferAllocPool.h',
-      '<(skia_src_path)/gpu/GrCacheable.cpp',
       '<(skia_src_path)/gpu/GrCacheID.cpp',
       '<(skia_src_path)/gpu/GrClipData.cpp',
       '<(skia_src_path)/gpu/GrClipMaskCache.h',
diff --git a/include/gpu/GrCacheable.h b/include/gpu/GrCacheable.h
deleted file mode 100644
index cacc7e7..0000000
--- a/include/gpu/GrCacheable.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrCacheable_DEFINED
-#define GrCacheable_DEFINED
-
-#include "SkRefCnt.h"
-
-class GrResourceCacheEntry;
-
-/**
- * Base class for objects that can be kept in the GrResourceCache.
- */
-class GrCacheable : public SkNoncopyable {
-public:
-    SK_DECLARE_INST_COUNT_ROOT(GrCacheable)
-
-    // These method signatures are written to mirror SkRefCnt. However, we don't require
-    // thread safety as GrCacheable objects are not intended to cross thread boundaries.
-    // internal_dispose() exists because of GrTexture's reliance on it. It will be removed
-    // soon.
-    void ref() const { ++fRefCnt; }
-    void unref() const { --fRefCnt; if (0 == fRefCnt) { this->internal_dispose(); } }
-    virtual void internal_dispose() const { SkDELETE(this); }
-    bool unique() const { return 1 == fRefCnt; }
-#ifdef SK_DEBUG
-    void validate() const {
-        SkASSERT(fRefCnt > 0);
-    }
-#endif
-
-    virtual ~GrCacheable() { SkASSERT(0 == fRefCnt); }
-
-    /**
-     * Retrieves the amount of GPU memory used by this resource in bytes. It is
-     * approximate since we aren't aware of additional padding or copies made
-     * by the driver.
-     *
-     * @return the amount of GPU memory used in bytes
-     */
-    virtual size_t gpuMemorySize() const = 0;
-
-    /**
-     * Checks whether the GPU memory allocated to this resource is still in effect.
-     * It can become invalid if its context is destroyed or lost, in which case it
-     * should no longer count against the GrResourceCache budget.
-     *
-     * @return true if this resource is still holding GPU memory
-     *         false otherwise.
-     */
-    virtual bool isValidOnGpu() const = 0;
-
-    void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; }
-    GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; }
-
-    /**
-     * Gets an id that is unique for this GrCacheable object. It is static in that it does
-     * not change when the content of the GrCacheable object changes. This will never return
-     * 0.
-     */
-    uint32_t getUniqueID() const { return fUniqueID; }
-
-protected:
-    GrCacheable()
-        : fRefCnt(1)
-        , fCacheEntry(NULL)
-        , fUniqueID(CreateUniqueID()) {}
-
-    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:
-    static uint32_t CreateUniqueID();
-
-    mutable int32_t         fRefCnt;
-    GrResourceCacheEntry*   fCacheEntry;  // NULL if not in cache
-    const uint32_t          fUniqueID;
-
-    typedef SkNoncopyable INHERITED;
-};
-
-#endif
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 92fa881..a379f80 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -20,7 +20,6 @@
 
 class GrAARectRenderer;
 class GrAutoScratchTexture;
-class GrCacheable;
 class GrDrawState;
 class GrDrawTarget;
 class GrEffect;
@@ -186,14 +185,14 @@
     /**
      * Stores a custom resource in the cache, based on the specified key.
      */
-    void addResourceToCache(const GrResourceKey&, GrCacheable*);
+    void addResourceToCache(const GrResourceKey&, GrGpuObject*);
 
     /**
      * Finds a resource in the cache, based on the specified key. This is intended for use in
      * conjunction with addResourceToCache(). The return value will be NULL if not found. The
      * caller must balance with a call to unref().
      */
-    GrCacheable* findAndRefCachedResource(const GrResourceKey&);
+    GrGpuObject* findAndRefCachedResource(const GrResourceKey&);
 
     /**
      * Creates a new text rendering context that is optimal for the
diff --git a/include/gpu/GrGpuObject.h b/include/gpu/GrGpuObject.h
index 0347d44..51cac1c 100644
--- a/include/gpu/GrGpuObject.h
+++ b/include/gpu/GrGpuObject.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011 Google Inc.
+ * Copyright 2014 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
@@ -8,18 +8,33 @@
 #ifndef GrGpuObject_DEFINED
 #define GrGpuObject_DEFINED
 
-#include "GrCacheable.h"
+#include "SkInstCnt.h"
 #include "SkTInternalLList.h"
 
+class GrResourceCacheEntry;
 class GrGpu;
 class GrContext;
 
 /**
- * Base class for the GPU objects created by a GrContext.
+ * Base class for objects that can be kept in the GrResourceCache.
  */
-class GrGpuObject : public GrCacheable {
+class GrGpuObject : public SkNoncopyable {
 public:
-    SK_DECLARE_INST_COUNT(GrGpuObject)
+    SK_DECLARE_INST_COUNT_ROOT(GrGpuObject)
+
+    // These method signatures are written to mirror SkRefCnt. However, we don't require
+    // thread safety as GrCacheable objects are not intended to cross thread boundaries.
+    // internal_dispose() exists because of GrTexture's reliance on it. It will be removed
+    // soon.
+    void ref() const { ++fRefCnt; }
+    void unref() const { --fRefCnt; if (0 == fRefCnt) { this->internal_dispose(); } }
+    virtual void internal_dispose() const { SkDELETE(this); }
+    bool unique() const { return 1 == fRefCnt; }
+#ifdef SK_DEBUG
+    void validate() const {
+        SkASSERT(fRefCnt > 0);
+    }
+#endif
 
     /**
      * Frees the object in the underlying 3D API. It must be safe to call this
@@ -54,17 +69,31 @@
     const GrContext* getContext() const;
     GrContext* getContext();
 
-    virtual bool isValidOnGpu() const SK_OVERRIDE { return !this->wasDestroyed(); }
+    /**
+     * Retrieves the amount of GPU memory used by this resource in bytes. It is
+     * approximate since we aren't aware of additional padding or copies made
+     * by the driver.
+     *
+     * @return the amount of GPU memory used in bytes
+     */
+    virtual size_t gpuMemorySize() const = 0;
+
+    void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; }
+    GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; }
+
+    /**
+     * Gets an id that is unique for this GrCacheable object. It is static in that it does
+     * not change when the content of the GrCacheable object changes. This will never return
+     * 0.
+     */
+    uint32_t getUniqueID() const { return fUniqueID; }
 
 protected:
-    /**
-     * isWrapped indicates we have wrapped a client-created backend object in a GrGpuObject. If it
-     * is true then the client is responsible for the lifetime of the underlying backend object.
-     * Otherwise, our onRelease() should free the object.
-     */
-    GrGpuObject(GrGpu* gpu, bool isWrapped);
+    GrGpuObject(GrGpu*, bool isWrapped);
     virtual ~GrGpuObject();
 
+    bool isInCache() const { return NULL != fCacheEntry; }
+
     GrGpu* getGpu() const { return fGpu; }
 
     // Derived classes should always call their parent class' onRelease
@@ -74,11 +103,21 @@
 
     bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
 
+    /**
+     * 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:
 #ifdef SK_DEBUG
     friend class GrGpu; // for assert in GrGpu to access getGpu
 #endif
 
+    static uint32_t CreateUniqueID();
+
     // We're in an internal doubly linked list
     SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuObject);
 
@@ -93,9 +132,14 @@
          */
         kWrapped_FlagBit         = 0x1,
     };
-    uint32_t         fFlags;
 
-    typedef GrCacheable INHERITED;
+    uint32_t                fFlags;
+
+    mutable int32_t         fRefCnt;
+    GrResourceCacheEntry*   fCacheEntry;  // NULL if not in cache
+    const uint32_t          fUniqueID;
+
+    typedef SkNoncopyable INHERITED;
 };
 
 #endif
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index 14a198f..d76a8cf 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -10,8 +10,9 @@
 #define GrTexture_DEFINED
 
 #include "GrSurface.h"
-#include "SkPoint.h"
 #include "GrRenderTarget.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
 
 class GrResourceKey;
 class GrTextureParams;
diff --git a/src/gpu/GrAtlas.h b/src/gpu/GrAtlas.h
index 2248f67..9ccbc53 100644
--- a/src/gpu/GrAtlas.h
+++ b/src/gpu/GrAtlas.h
@@ -10,9 +10,10 @@
 #define GrAtlas_DEFINED
 
 
-#include "SkPoint.h"
 #include "GrTexture.h"
 #include "GrDrawTarget.h"
+#include "SkPoint.h"
+#include "SkTInternalLList.h"
 
 class GrGpu;
 class GrRectanizer;
diff --git a/src/gpu/GrCacheable.cpp b/src/gpu/GrCacheable.cpp
deleted file mode 100644
index 5dc52581..0000000
--- a/src/gpu/GrCacheable.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#include "GrCacheable.h"
-
-uint32_t GrCacheable::CreateUniqueID() {
-    static int32_t gCacheableID = SK_InvalidUniqueID;
-    uint32_t id;
-    do {
-        id = static_cast<uint32_t>(sk_atomic_inc(&gCacheableID) + 1);
-    } while (id == SK_InvalidUniqueID);
-    return id;
-}
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index a815263..d3edd21 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -257,7 +257,7 @@
                                         const GrCacheID& cacheID,
                                         const GrTextureParams* params) {
     GrResourceKey resourceKey = GrTextureImpl::ComputeKey(fGpu, params, desc, cacheID);
-    GrCacheable* resource = fResourceCache->find(resourceKey);
+    GrGpuObject* resource = fResourceCache->find(resourceKey);
     SkSafeRef(resource);
     return static_cast<GrTexture*>(resource);
 }
@@ -283,7 +283,7 @@
     GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width,
                                                             height,
                                                             sampleCnt);
-    GrCacheable* resource = fResourceCache->find(resourceKey);
+    GrGpuObject* resource = fResourceCache->find(resourceKey);
     return static_cast<GrStencilBuffer*>(resource);
 }
 
@@ -471,7 +471,7 @@
         desc.fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc.fHeight));
     }
 
-    GrCacheable* resource = NULL;
+    GrGpuObject* resource = NULL;
     int origWidth = desc.fWidth;
     int origHeight = desc.fHeight;
 
@@ -1903,13 +1903,13 @@
     return path;
 }
 
-void GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrCacheable* resource) {
+void GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrGpuObject* resource) {
     fResourceCache->purgeAsNeeded(1, resource->gpuMemorySize());
     fResourceCache->addResource(resourceKey, resource);
 }
 
-GrCacheable* GrContext::findAndRefCachedResource(const GrResourceKey& resourceKey) {
-    GrCacheable* resource = fResourceCache->find(resourceKey);
+GrGpuObject* GrContext::findAndRefCachedResource(const GrResourceKey& resourceKey) {
+    GrGpuObject* resource = fResourceCache->find(resourceKey);
     SkSafeRef(resource);
     return resource;
 }
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 17b7b69..822deb1 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -13,7 +13,6 @@
 #include "SkPath.h"
 
 class GrContext;
-class GrGpuObject;
 class GrIndexBufferAllocPool;
 class GrPath;
 class GrPathRange;
diff --git a/src/gpu/GrGpuObject.cpp b/src/gpu/GrGpuObject.cpp
index fff2a2f..4a72a50 100644
--- a/src/gpu/GrGpuObject.cpp
+++ b/src/gpu/GrGpuObject.cpp
@@ -10,7 +10,10 @@
 #include "GrGpuObject.h"
 #include "GrGpu.h"
 
-GrGpuObject::GrGpuObject(GrGpu* gpu, bool isWrapped) {
+GrGpuObject::GrGpuObject(GrGpu* gpu, bool isWrapped)
+    : fRefCnt(1)
+    , fCacheEntry(NULL)
+    , fUniqueID(CreateUniqueID()) {
     fGpu              = gpu;
     if (isWrapped) {
         fFlags = kWrapped_FlagBit;
@@ -21,6 +24,7 @@
 }
 
 GrGpuObject::~GrGpuObject() {
+    SkASSERT(0 == fRefCnt);
     // subclass should have released this.
     SkASSERT(this->wasDestroyed());
 }
@@ -56,3 +60,12 @@
         return NULL;
     }
 }
+
+uint32_t GrGpuObject::CreateUniqueID() {
+    static int32_t gUniqueID = SK_InvalidUniqueID;
+    uint32_t id;
+    do {
+        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
+    } while (id == SK_InvalidUniqueID);
+    return id;
+}
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index ac10ebc..13568e4 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -9,13 +9,13 @@
 
 
 #include "GrResourceCache.h"
-#include "GrCacheable.h"
+#include "GrGpuObject.h"
 
 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrCacheable::didChangeGpuMemorySize() const {
+void GrGpuObject::didChangeGpuMemorySize() const {
     if (this->isInCache()) {
         fCacheEntry->didChangeResourceSize();
     }
@@ -38,7 +38,7 @@
 
 GrResourceCacheEntry::GrResourceCacheEntry(GrResourceCache* resourceCache,
                                            const GrResourceKey& key,
-                                           GrCacheable* resource)
+                                           GrGpuObject* resource)
         : fResourceCache(resourceCache),
           fKey(key),
           fResource(resource),
@@ -197,7 +197,7 @@
     }
 };
 
-GrCacheable* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipFlags) {
+GrGpuObject* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipFlags) {
     GrAutoResourceCacheValidate atcv(this);
 
     GrResourceCacheEntry* entry = NULL;
@@ -226,7 +226,7 @@
 }
 
 void GrResourceCache::addResource(const GrResourceKey& key,
-                                  GrCacheable* resource,
+                                  GrGpuObject* resource,
                                   uint32_t ownershipFlags) {
     SkASSERT(NULL == resource->getCacheEntry());
     // we don't expect to create new resources during a purge. In theory
@@ -285,7 +285,7 @@
     fExclusiveList.remove(entry);
 #endif
 
-    if (entry->resource()->isValidOnGpu()) {
+    if (!entry->resource()->wasDestroyed()) {
         // Since scratch textures still count against the cache budget even
         // when they have been removed from the cache, re-adding them doesn't
         // alter the budget information.
diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
index ccfe7fa..63a7a67 100644
--- a/src/gpu/GrResourceCache.h
+++ b/src/gpu/GrResourceCache.h
@@ -18,7 +18,7 @@
 #include "SkMessageBus.h"
 #include "SkTInternalLList.h"
 
-class GrCacheable;
+class GrGpuObject;
 class GrResourceCache;
 class GrResourceCacheEntry;
 
@@ -29,11 +29,11 @@
         return gDomain;
     }
 
-    /** Uniquely identifies the GrCacheable subclass in the key to avoid collisions
+    /** Uniquely identifies the GrGpuObject subclass in the key to avoid collisions
         across resource types. */
     typedef uint8_t ResourceType;
 
-    /** Flags set by the GrCacheable subclass. */
+    /** Flags set by the GrGpuObject subclass. */
     typedef uint8_t ResourceFlags;
 
     /** Generate a unique ResourceType */
@@ -118,7 +118,7 @@
 
 class GrResourceCacheEntry {
 public:
-    GrCacheable* resource() const { return fResource; }
+    GrGpuObject* resource() const { return fResource; }
     const GrResourceKey& key() const { return fKey; }
 
     static const GrResourceKey& GetKey(const GrResourceCacheEntry& e) { return e.key(); }
@@ -131,7 +131,7 @@
 
     /**
      *  Update the cached size for this entry and inform the resource cache that
-     *  it has changed. Usually invoked from GrCacheable::didChangeGpuMemorySize,
+     *  it has changed. Usually invoked from GrGpuObject::didChangeGpuMemorySize,
      *  not directly from here.
      */
     void didChangeResourceSize();
@@ -139,12 +139,12 @@
 private:
     GrResourceCacheEntry(GrResourceCache* resourceCache,
                          const GrResourceKey& key,
-                         GrCacheable* resource);
+                         GrGpuObject* resource);
     ~GrResourceCacheEntry();
 
     GrResourceCache* fResourceCache;
     GrResourceKey    fKey;
-    GrCacheable*     fResource;
+    GrGpuObject*     fResource;
     size_t           fCachedSize;
     bool             fIsExclusive;
 
@@ -157,7 +157,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
- *  Cache of GrCacheable objects.
+ *  Cache of GrGpuObject objects.
  *
  *  These have a corresponding GrResourceKey, built from 128bits identifying the
  *  resource. Multiple resources can map to same GrResourceKey.
@@ -246,7 +246,7 @@
      *  For a resource to be completely exclusive to a caller both kNoOtherOwners
      *  and kHide must be specified.
      */
-    GrCacheable* find(const GrResourceKey& key,
+    GrGpuObject* find(const GrResourceKey& key,
                       uint32_t ownershipFlags = 0);
 
     /**
@@ -261,7 +261,7 @@
      *  is called.
      */
     void addResource(const GrResourceKey& key,
-                     GrCacheable* resource,
+                     GrGpuObject* resource,
                      uint32_t ownershipFlags = 0);
 
     /**
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index 65c2642..0867f2e 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -18,7 +18,7 @@
 #include "SkPath.h"
 #include "SkTextMapStateProc.h"
 
-class GrStencilAndCoverTextContext::GlyphPathRange : public GrCacheable {
+class GrStencilAndCoverTextContext::GlyphPathRange : public GrGpuObject {
     static const int kMaxGlyphCount = 1 << 16; // Glyph IDs are uint16_t's
     static const int kGlyphGroupSize = 16; // Glyphs get tracked in groups of 16
 
@@ -75,13 +75,13 @@
         this->didChangeGpuMemorySize();
     }
 
-    // GrCacheable overrides
+    // GrGpuObject overrides
     virtual size_t gpuMemorySize() const SK_OVERRIDE { return fPathRange->gpuMemorySize(); }
-    virtual bool isValidOnGpu() const SK_OVERRIDE { return fPathRange->isValidOnGpu(); }
 
 private:
     GlyphPathRange(GrContext* context, const SkDescriptor& desc, const SkStrokeRec& stroke)
-        : fDesc(desc.copy())
+        : INHERITED(context->getGpu(), false)
+        , fDesc(desc.copy())
         // We reserve a range of kMaxGlyphCount paths because of fallbacks fonts. We
         // can't know exactly how many glyphs we might need without preloading every
         // fallback, which we don't want to do at this point.
@@ -90,15 +90,28 @@
     }
 
     ~GlyphPathRange() {
+        this->release();
         SkDescriptor::Free(fDesc);
     }
 
+    virtual void onRelease() SK_OVERRIDE {
+        INHERITED::onRelease();
+        fPathRange.reset(NULL);
+    }
+
+    virtual void onAbandon() SK_OVERRIDE {
+        INHERITED::onAbandon();
+        fPathRange->abandon();
+        fPathRange.reset(NULL);
+    }
+
+
     static const int kMaxGroupCount = (kMaxGlyphCount + (kGlyphGroupSize - 1)) / kGlyphGroupSize;
     SkDescriptor* const fDesc;
     uint8_t fLoadedGlyphs[(kMaxGroupCount + 7) >> 3]; // One bit per glyph group
     SkAutoTUnref<GrPathRange> fPathRange;
 
-    typedef GrCacheable INHERITED;
+    typedef GrGpuObject INHERITED;
 };
 
 
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 78c1124..b4aab5f 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -58,13 +58,14 @@
     context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
 }
 
-class TestResource : public GrCacheable {
+class TestResource : public GrGpuObject {
     static const size_t kDefaultSize = 100;
 
 public:
     SK_DECLARE_INST_COUNT(TestResource);
-    TestResource(size_t size = kDefaultSize)
-        : fCache(NULL)
+    TestResource(GrGpu* gpu, size_t size = kDefaultSize)
+        : INHERITED(gpu, false)
+        , fCache(NULL)
         , fToDelete(NULL)
         , fSize(size) {
         ++fAlive;
@@ -77,6 +78,7 @@
             fToDelete->setDeleteWhenDestroyed(NULL, NULL);
             fCache->deleteResource(fToDelete->getCacheEntry());
         }
+        this->release();
     }
 
     void setSize(size_t size) {
@@ -86,8 +88,6 @@
 
     size_t gpuMemorySize() const SK_OVERRIDE { return fSize; }
 
-    bool isValidOnGpu() const SK_OVERRIDE { return true; }
-
     static int alive() { return fAlive; }
 
     void setDeleteWhenDestroyed(GrResourceCache* cache, TestResource* resource) {
@@ -101,7 +101,7 @@
     size_t fSize;
     static int fAlive;
 
-    typedef GrCacheable INHERITED;
+    typedef GrGpuObject INHERITED;
 };
 int TestResource::fAlive = 0;
 
@@ -116,8 +116,8 @@
     GrResourceCache cache(5, 30000);
 
     // Add two resources with the same key that delete each other from the cache when destroyed.
-    TestResource* a = new TestResource();
-    TestResource* b = new TestResource();
+    TestResource* a = new TestResource(context->getGpu());
+    TestResource* b = new TestResource(context->getGpu());
     cache.addResource(key, a);
     cache.addResource(key, b);
     // Circle back.
@@ -127,7 +127,7 @@
     b->unref();
 
     // Add a third independent resource also with the same key.
-    GrCacheable* r = new TestResource();
+    GrGpuObject* r = new TestResource(context->getGpu());
     cache.addResource(key, r);
     r->unref();
 
@@ -152,8 +152,8 @@
     {
         {
             GrResourceCache cache(3, 30000);
-            TestResource* a = new TestResource();
-            TestResource* b = new TestResource();
+            TestResource* a = new TestResource(context->getGpu());
+            TestResource* b = new TestResource(context->getGpu());
             cache.addResource(key, a);
             cache.addResource(key, b);
 
@@ -168,8 +168,8 @@
     }
     {
         GrResourceCache cache(3, 30000);
-        TestResource* a = new TestResource();
-        TestResource* b = new TestResource();
+        TestResource* a = new TestResource(context->getGpu());
+        TestResource* b = new TestResource(context->getGpu());
         cache.addResource(key, a);
         cache.addResource(key, b);
 
@@ -204,12 +204,12 @@
     {
         GrResourceCache cache(2, 300);
 
-        TestResource* a = new TestResource(0);
+        TestResource* a = new TestResource(context->getGpu());
         a->setSize(100); // Test didChangeGpuMemorySize() when not in the cache.
         cache.addResource(key1, a);
         a->unref();
 
-        TestResource* b = new TestResource(0);
+        TestResource* b = new TestResource(context->getGpu());
         b->setSize(100);
         cache.addResource(key2, b);
         b->unref();
@@ -228,11 +228,11 @@
     {
         GrResourceCache cache(2, 300);
 
-        TestResource* a = new TestResource(100);
+        TestResource* a = new TestResource(context->getGpu(), 100);
         cache.addResource(key1, a);
         a->unref();
 
-        TestResource* b = new TestResource(100);
+        TestResource* b = new TestResource(context->getGpu(), 100);
         cache.addResource(key2, b);
         b->unref();
 
@@ -250,11 +250,11 @@
     {
         GrResourceCache cache(2, 300);
 
-        TestResource* a = new TestResource(100);
+        TestResource* a = new TestResource(context->getGpu(), 100);
         cache.addResource(key1, a);
         cache.makeExclusive(a->getCacheEntry());
 
-        TestResource* b = new TestResource(100);
+        TestResource* b = new TestResource(context->getGpu(), 100);
         cache.addResource(key2, b);
         b->unref();