Add GrGpuResource::CacheAccess
authorbsalomon <bsalomon@google.com>
Tue, 11 Nov 2014 22:15:57 +0000 (14:15 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 11 Nov 2014 22:15:57 +0000 (14:15 -0800)
Internal only helper class for manipulating and accessing cache keys.

BUG=skia:2889

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

gyp/gpu.gypi
include/gpu/GrGpuResource.h
src/gpu/GrContext.cpp
src/gpu/GrGpuResource.cpp
src/gpu/GrGpuResourceCacheAccess.h [new file with mode: 0644]
src/gpu/GrResourceCache.cpp
src/gpu/GrResourceCache2.cpp
src/gpu/GrResourceCache2.h
src/gpu/GrStencilBuffer.cpp
tests/ResourceCacheTest.cpp

index cf3bdf7..7b84365 100644 (file)
@@ -87,6 +87,7 @@
       '<(skia_src_path)/gpu/GrGeometryBuffer.h',
       '<(skia_src_path)/gpu/GrGpu.cpp',
       '<(skia_src_path)/gpu/GrGpu.h',
+      '<(skia_src_path)/gpu/GrGpuResourceCacheAccess.h',
       '<(skia_src_path)/gpu/GrGpuResource.cpp',
       '<(skia_src_path)/gpu/GrGpuFactory.cpp',
       '<(skia_src_path)/gpu/GrIndexBuffer.h',
index 315e491..3d6701a 100644 (file)
@@ -174,24 +174,6 @@ public:
      */
     virtual size_t gpuMemorySize() const = 0;
 
-    // TODO(bsalomon): Move this stuff to GrGpuResourcePriv.
-    bool setContentKey(const GrResourceKey& contentKey);
-    void setCacheEntry(GrResourceCacheEntry* cacheEntry);
-    GrResourceCacheEntry* getCacheEntry() const { return fCacheEntry; }
-    bool isScratch() const;
-    /** 
-     * If this resource can be used as a scratch resource this returns a valid
-     * scratch key. Otherwise it returns a key for which isNullScratch is true.
-     * The resource may currently be used as content resource rather than scratch.
-     * Check isScratch().
-     */
-    const GrResourceKey& getScratchKey() const { return fScratchKey; }
-    /** 
-     * If this resource is currently cached by its contents then this will return
-     * the content key. Otherwise, NULL is returned.
-     */
-    const GrResourceKey* getContentKey() const;
-
     /**
      * Gets an id that is unique for this GrGpuResource object. It is static in that it does
      * not change when the content of the GrGpuResource object changes. This will never return
@@ -199,6 +181,13 @@ public:
      */
     uint32_t getUniqueID() const { return fUniqueID; }
 
+    /**
+     * Internal-only helper class used for cache manipulations of the reosurce.
+     */
+    class CacheAccess;
+    inline CacheAccess cacheAccess();
+    inline const CacheAccess cacheAccess() const;
+
 protected:
     // This must be called by every GrGpuObject. It should be called once the object is fully
     // initialized (i.e. not in a base class constructor).
@@ -207,8 +196,6 @@ protected:
     GrGpuResource(GrGpu*, bool isWrapped);
     virtual ~GrGpuResource();
 
-    bool isInCache() const { return SkToBool(fCacheEntry); }
-
     GrGpu* getGpu() const { return fGpu; }
 
     // Derived classes should always call their parent class' onRelease
@@ -233,6 +220,9 @@ protected:
     void setScratchKey(const GrResourceKey& scratchKey);
 
 private:
+    // See comments in CacheAccess.
+    bool setContentKey(const GrResourceKey& contentKey);
+
     void notifyIsPurgable() const;
 
 #ifdef SK_DEBUG
index fee62a8..da35033 100755 (executable)
@@ -15,6 +15,8 @@
 #include "GrAARectRenderer.h"
 #include "GrBufferAllocPool.h"
 #include "GrGpu.h"
+#include "GrGpuResource.h"
+#include "GrGpuResourceCacheAccess.h"
 #include "GrDistanceFieldTextContext.h"
 #include "GrDrawTargetCaps.h"
 #include "GrIndexBuffer.h"
@@ -433,7 +435,7 @@ GrTexture* GrContext::createNewScratchTexture(const GrSurfaceDesc& desc) {
     if (!texture) {
         return NULL;
     }
-    fResourceCache->addResource(texture->getScratchKey(), texture);
+    fResourceCache->addResource(texture->cacheAccess().getScratchKey(), texture);
     return texture;
 }
 
@@ -496,7 +498,7 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM
 
     GrTexture* texture = this->createNewScratchTexture(*desc);
     SkASSERT(NULL == texture || 
-             texture->getScratchKey() == GrTexturePriv::ComputeScratchKey(*desc));
+             texture->cacheAccess().getScratchKey() == GrTexturePriv::ComputeScratchKey(*desc));
     return texture;
 }
 
index d472845..79ea52f 100644 (file)
@@ -98,12 +98,6 @@ bool GrGpuResource::setContentKey(const GrResourceKey& contentKey) {
     return true;
 }
 
-void GrGpuResource::setCacheEntry(GrResourceCacheEntry* cacheEntry) {
-    // GrResourceCache never changes the cacheEntry once one has been added.
-    SkASSERT(NULL == cacheEntry || NULL == fCacheEntry);
-    fCacheEntry = cacheEntry;
-}
-
 void GrGpuResource::notifyIsPurgable() const {
     if (fCacheEntry && !this->wasDestroyed()) {
         get_resource_cache(fGpu)->notifyPurgable(this);
@@ -117,18 +111,6 @@ void GrGpuResource::setScratchKey(const GrResourceKey& scratchKey) {
     fScratchKey = scratchKey;
 }
 
-const GrResourceKey* GrGpuResource::getContentKey() const {
-    if (fContentKeySet) {
-        return &fContentKey;
-    }
-    return NULL;
-}
-
-bool GrGpuResource::isScratch() const {
-    SkASSERT(fScratchKey.isScratch());
-    return NULL == this->getContentKey() && !fScratchKey.isNullScratch();
-}
-
 uint32_t GrGpuResource::CreateUniqueID() {
     static int32_t gUniqueID = SK_InvalidUniqueID;
     uint32_t id;
diff --git a/src/gpu/GrGpuResourceCacheAccess.h b/src/gpu/GrGpuResourceCacheAccess.h
new file mode 100644 (file)
index 0000000..af5c054
--- /dev/null
@@ -0,0 +1,96 @@
+
+/*
+ * 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 GrGpuResourceCacheAccess_DEFINED
+#define GrGpuResourceCacheAccess_DEFINED
+
+#include "GrGpuResource.h"
+
+/**
+ * This class allows code internal to Skia privileged access to manage the cache keys of a
+ * GrGpuResource object.
+ */
+class GrGpuResource::CacheAccess {
+public:
+    /**
+     * Sets a content key for the resource. If the resource was previously cached as scratch it will
+     * be converted to a content resource. Currently this may only be called once per resource. It
+     * fails if there is already a resource with the same content key. TODO: make this supplant the
+     * resource that currently is using the content key, allow resources' content keys to change,
+     * and allow removal of a content key to convert a resource back to scratch.
+     */
+    bool setContentKey(const GrResourceKey& contentKey) {
+        return fResource->setContentKey(contentKey);
+    }
+
+    /**
+     * Used by legacy cache to attach a cache entry. This is to be removed soon.
+     */
+    void setCacheEntry(GrResourceCacheEntry* cacheEntry) {
+        // GrResourceCache never changes the cacheEntry once one has been added.
+        SkASSERT(NULL == cacheEntry || NULL == fResource->fCacheEntry);
+        fResource->fCacheEntry = cacheEntry;
+    }
+
+    /**
+     * Is the resource in the legacy cache? This is to be removed soon.
+     */
+    bool isInCache() const { return SkToBool(fResource->fCacheEntry); }
+
+    /**
+     * Returns the cache entry for the legacy cache. This is to be removed soon.
+     */
+    GrResourceCacheEntry* getCacheEntry() const { return fResource->fCacheEntry; }
+
+    /**
+     * Is the resource currently cached as scratch? This means it has a valid scratch key and does
+     * not have a content key.
+     */
+    bool isScratch() const {
+        SkASSERT(fResource->fScratchKey.isScratch());
+        return NULL == this->getContentKey() && !fResource->fScratchKey.isNullScratch();
+    }
+
+    /** 
+     * If this resource can be used as a scratch resource this returns a valid scratch key.
+     * Otherwise it returns a key for which isNullScratch is true. The resource may currently be
+     * used as content resource rather than scratch. Check isScratch().
+     */
+    const GrResourceKey& getScratchKey() const { return fResource->fScratchKey; }
+
+    /**
+     * If the resource is currently cached by a content key, the key is returned, otherwise NULL.
+     */
+    const GrResourceKey* getContentKey() const {
+        if (fResource->fContentKeySet) {
+            return &fResource->fContentKey;
+        }
+        return NULL;
+    }
+
+private:
+    CacheAccess(GrGpuResource* resource) : fResource(resource) { }
+    CacheAccess(const CacheAccess& that) : fResource(that.fResource) { }
+    CacheAccess& operator=(const CacheAccess&); // unimpl
+
+    // No taking addresses of this type.
+    const CacheAccess* operator&() const;
+    CacheAccess* operator&();
+
+    GrGpuResource* fResource;
+
+    friend class GrGpuResource; // to construct/copy this type.
+};
+
+inline GrGpuResource::CacheAccess GrGpuResource::cacheAccess() { return CacheAccess(this); }
+
+inline const GrGpuResource::CacheAccess GrGpuResource::cacheAccess() const {
+    return CacheAccess(const_cast<GrGpuResource*>(this));
+}
+
+#endif
index 20b82ec..7083cf3 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "GrResourceCache.h"
 #include "GrGpuResource.h"
+#include "GrGpuResourceCacheAccess.h"
 #include "GrTexturePriv.h"
 
 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);
@@ -15,7 +16,7 @@ DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);
 ///////////////////////////////////////////////////////////////////////////////
 
 void GrGpuResource::didChangeGpuMemorySize() const {
-    if (this->isInCache()) {
+    if (this->cacheAccess().isInCache()) {
         fCacheEntry->didChangeResourceSize();
     }
 }
@@ -54,7 +55,7 @@ GrResourceCacheEntry::~GrResourceCacheEntry() {
 void GrResourceCacheEntry::validate() const {
     SkASSERT(fResourceCache);
     SkASSERT(fResource);
-    SkASSERT(fResource->getCacheEntry() == this);
+    SkASSERT(fResource->cacheAccess().getCacheEntry() == this);
     SkASSERT(fResource->gpuMemorySize() == fCachedSize);
     fResource->validate();
 }
@@ -150,7 +151,7 @@ void GrResourceCache::attachToHead(GrResourceCacheEntry* entry) {
 
 
 void GrResourceCache::makeResourceMRU(GrGpuResource* resource) {
-    GrResourceCacheEntry* entry = resource->getCacheEntry();
+    GrResourceCacheEntry* entry = resource->cacheAccess().getCacheEntry();
     if (entry) {
         this->internalDetach(entry);
         this->attachToHead(entry);
@@ -160,26 +161,27 @@ void GrResourceCache::makeResourceMRU(GrGpuResource* resource) {
 void GrResourceCache::notifyPurgable(const GrGpuResource* resource) {
     // Remove scratch textures from the cache the moment they become purgeable if
     // scratch texture reuse is turned off.
-    SkASSERT(resource->getCacheEntry());
-    if (resource->isScratch()) {
-        const GrResourceKey& key = resource->getScratchKey();
+    SkASSERT(resource->cacheAccess().getCacheEntry());
+    if (resource->cacheAccess().isScratch()) {
+        const GrResourceKey& key = resource->cacheAccess().getScratchKey();
         if (key.getResourceType() == GrTexturePriv::ResourceType() &&
             !fCaps->reuseScratchTextures() &&
             !(static_cast<const GrSurface*>(resource)->desc().fFlags & kRenderTarget_GrSurfaceFlag)) {
-            this->deleteResource(resource->getCacheEntry());
+            this->deleteResource(resource->cacheAccess().getCacheEntry());
         }
     }
 }
 
 bool GrResourceCache::addResource(const GrResourceKey& key, GrGpuResource* resource) {
-    if (NULL != resource->getCacheEntry()) {
+    if (NULL != resource->cacheAccess().getCacheEntry()) {
         return false;
     }
     
     if (key.isScratch()) {
-        SkASSERT(resource->isScratch() && key == resource->getScratchKey());
+        SkASSERT(resource->cacheAccess().isScratch());
+        SkASSERT(key == resource->cacheAccess().getScratchKey());
     } else {
-        if (!resource->setContentKey(key)) {
+        if (!resource->cacheAccess().setContentKey(key)) {
             return false;
         }
     }
@@ -192,7 +194,7 @@ bool GrResourceCache::addResource(const GrResourceKey& key, GrGpuResource* resou
     GrAutoResourceCacheValidate atcv(this);
 
     GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (this, resource));
-    resource->setCacheEntry(entry);
+    resource->cacheAccess().setCacheEntry(entry);
 
     this->attachToHead(entry);
     this->purgeAsNeeded();
@@ -370,7 +372,7 @@ void GrResourceCache::printStats() {
         if (!entry->fResource->isPurgable()) {
             ++locked;
         }
-        if (entry->fResource->isScratch()) {
+        if (entry->fResource->cacheAccess().isScratch()) {
             ++scratch;
         }
     }
index 70d854c..83143d7 100644 (file)
@@ -39,20 +39,20 @@ void GrResourceCache2::insertResource(GrGpuResource* resource) {
     SkASSERT(!this->isInCache(resource));
     fResources.addToHead(resource);
     ++fCount;
-    if (!resource->getScratchKey().isNullScratch()) {
+    if (!resource->cacheAccess().getScratchKey().isNullScratch()) {
         // TODO(bsalomon): Make this assertion possible.
         // SkASSERT(!resource->isWrapped());
-        fScratchMap.insert(resource->getScratchKey(), resource);
+        fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource);
     }
 }
 
 void GrResourceCache2::removeResource(GrGpuResource* resource) {
     SkASSERT(this->isInCache(resource));
     fResources.remove(resource);    
-    if (!resource->getScratchKey().isNullScratch()) {
-        fScratchMap.remove(resource->getScratchKey(), resource);
+    if (!resource->cacheAccess().getScratchKey().isNullScratch()) {
+        fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource);
     }
-    if (const GrResourceKey* contentKey = resource->getContentKey()) {
+    if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey()) {
         fContentHash.remove(*contentKey);
     }
     --fCount;
@@ -86,7 +86,7 @@ public:
     AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendingIO) { }
 
     bool operator()(const GrGpuResource* resource) const {
-        if (!resource->reffedOnlyByCache() || !resource->isScratch()) {
+        if (!resource->reffedOnlyByCache() || !resource->cacheAccess().isScratch()) {
             return false;
         }
 
@@ -114,23 +114,12 @@ GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrResourceKey&
     return SkSafeRef(fScratchMap.find(scratchKey, AvailableForScratchUse(false)));
 }
 
-#if 0
-void GrResourceCache2::willRemoveContentKey(const GrGpuResource* resource) {
-    SkASSERT(resource);
-    SkASSERT(resource->getContentKey());
-    SkDEBUGCODE(GrGpuResource* res = fContentHash.find(*resource->getContentKey()));
-    SkASSERT(res == resource);
-
-    fContentHash.remove(*resource->getContentKey());
-}
-#endif
-
 bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) {
     SkASSERT(resource);
-    SkASSERT(resource->getContentKey());
-    SkASSERT(!resource->getContentKey()->isScratch());
+    SkASSERT(resource->cacheAccess().getContentKey());
+    SkASSERT(!resource->cacheAccess().getContentKey()->isScratch());
 
-    GrGpuResource* res = fContentHash.find(*resource->getContentKey());
+    GrGpuResource* res = fContentHash.find(*resource->cacheAccess().getContentKey());
     if (NULL != res) {
         return false;
     }
index ba07c20..1cc9587 100644 (file)
@@ -10,6 +10,7 @@
 #define GrResourceCache2_DEFINED
 
 #include "GrGpuResource.h"
+#include "GrGpuResourceCacheAccess.h"
 #include "GrResourceKey.h"
 #include "SkRefCnt.h"
 #include "SkTInternalLList.h"
@@ -74,7 +75,7 @@ private:
 
     struct ScratchMapTraits {
         static const GrResourceKey& GetKey(const GrGpuResource& r) {
-            return r.getScratchKey();
+            return r.cacheAccess().getScratchKey();
         }
 
         static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); }
@@ -83,7 +84,7 @@ private:
 
     struct ContentHashTraits {
         static const GrResourceKey& GetKey(const GrGpuResource& r) {
-            return *r.getContentKey();
+            return *r.cacheAccess().getContentKey();
         }
 
         static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); }
index ea7b4fa..b288415 100644 (file)
 
 #include "GrContext.h"
 #include "GrGpu.h"
-#include "GrResourceCache.h"
+#include "GrResourceCache2.h"
 
 void GrStencilBuffer::transferToCache() {
-    SkASSERT(NULL == this->getCacheEntry());
+    SkASSERT(!this->cacheAccess().isInCache());
 
     this->getGpu()->getContext()->addStencilBuffer(this);
 }
index 9800093..45e53af 100644 (file)
@@ -89,7 +89,7 @@ public:
         if (fToDelete) {
             // Breaks our little 2-element cycle below.
             fToDelete->setDeleteWhenDestroyed(NULL, NULL);
-            fCache->deleteResource(fToDelete->getCacheEntry());
+            fCache->deleteResource(fToDelete->cacheAccess().getCacheEntry());
         }
         this->release();
     }
@@ -345,7 +345,7 @@ static void test_cache_delete_on_destruction(skiatest::Reporter* reporter) {
         a->unref();
         b->unref();
 
-        cache->deleteResource(a->getCacheEntry());
+        cache->deleteResource(a->cacheAccess().getCacheEntry());
         REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
     }
 }