Make textures register with GrResourceCache2 as scratch.
authorbsalomon <bsalomon@google.com>
Thu, 28 Aug 2014 16:54:34 +0000 (09:54 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 28 Aug 2014 16:54:34 +0000 (09:54 -0700)
R=robertphillips@google.com

Author: bsalomon@google.com

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

13 files changed:
gyp/gpu.gypi
include/gpu/GrBinHashKey.h [moved from src/gpu/GrBinHashKey.h with 63% similarity]
include/gpu/GrGpuResource.h
include/gpu/GrResourceKey.h [new file with mode: 0644]
include/gpu/GrTexture.h
src/gpu/GrGpuResource.cpp
src/gpu/GrMurmur3HashKey.h [new file with mode: 0644]
src/gpu/GrResourceCache.h
src/gpu/GrResourceCache2.cpp
src/gpu/GrResourceCache2.h
src/gpu/GrTexture.cpp
src/gpu/effects/GrTextureStripAtlas.h
tests/GrBinHashKeyTest.cpp

index 4668ac4..e8d3dfa 100644 (file)
@@ -9,6 +9,7 @@
   'variables': {
     'skgpu_sources': [
       '<(skia_include_path)/gpu/GrBackendEffectFactory.h',
+      '<(skia_include_path)/gpu/GrBinHashKey.h',
       '<(skia_include_path)/gpu/GrClipData.h',
       '<(skia_include_path)/gpu/GrColor.h',
       '<(skia_include_path)/gpu/GrConfig.h',
@@ -25,6 +26,7 @@
       '<(skia_include_path)/gpu/GrPathRendererChain.h',
       '<(skia_include_path)/gpu/GrRect.h',
       '<(skia_include_path)/gpu/GrRenderTarget.h',
+      '<(skia_include_path)/gpu/GrResourceKey.h',
       '<(skia_include_path)/gpu/GrSurface.h',
       '<(skia_include_path)/gpu/GrTBackendEffectFactory.h',
       '<(skia_include_path)/gpu/GrTexture.h',
@@ -50,7 +52,6 @@
       '<(skia_src_path)/gpu/GrAllocPool.cpp',
       '<(skia_src_path)/gpu/GrAtlas.cpp',
       '<(skia_src_path)/gpu/GrAtlas.h',
-      '<(skia_src_path)/gpu/GrBinHashKey.h',
       '<(skia_src_path)/gpu/GrBitmapTextContext.cpp',
       '<(skia_src_path)/gpu/GrBitmapTextContext.h',
       '<(skia_src_path)/gpu/GrBlend.cpp',
@@ -87,6 +88,7 @@
       '<(skia_src_path)/gpu/GrLayerCache.h',
       '<(skia_src_path)/gpu/GrMemoryPool.cpp',
       '<(skia_src_path)/gpu/GrMemoryPool.h',
+      '<(skia_src_path)/gpu/GrMurmur3HashKey.h',
       '<(skia_src_path)/gpu/GrOrderedSet.h',
       '<(skia_src_path)/gpu/GrOvalRenderer.cpp',
       '<(skia_src_path)/gpu/GrOvalRenderer.h',
similarity index 63%
rename from src/gpu/GrBinHashKey.h
rename to include/gpu/GrBinHashKey.h
index 06ff931..585a1a1 100644 (file)
 #ifndef GrBinHashKey_DEFINED
 #define GrBinHashKey_DEFINED
 
-#include "SkChecksum.h"
 #include "GrTypes.h"
 
 /**
- *  GrMurmur3HashKey is a hash key class that can take a data chunk of any predetermined
- *  length. It uses the Murmur3 hash function. It is intended to be used with
- *  SkTDynamicHash (where GrBinHashKey is for GrTHashTable).
- */
-template<size_t KEY_SIZE_IN_BYTES>
-class GrMurmur3HashKey {
-public:
-    GrMurmur3HashKey() {
-        this->reset();
-    }
-
-    void reset() {
-        fHash = 0;
-#ifdef SK_DEBUG
-        fIsValid = false;
-#endif
-    }
-
-    void setKeyData(const uint32_t* data) {
-        SK_COMPILE_ASSERT(KEY_SIZE_IN_BYTES % 4 == 0, key_size_mismatch);
-        memcpy(fData, data, KEY_SIZE_IN_BYTES);
-
-        fHash = SkChecksum::Murmur3(fData, KEY_SIZE_IN_BYTES);
-#ifdef SK_DEBUG
-        fIsValid = true;
-#endif
-    }
-
-    bool operator==(const GrMurmur3HashKey& other) const {
-        if (fHash != other.fHash) {
-            return false;
-        }
-
-        return !memcmp(fData, other.fData, KEY_SIZE_IN_BYTES);
-    }
-
-    uint32_t getHash() const {
-        SkASSERT(fIsValid);
-        return fHash;
-    }
-
-    const uint8_t* getData() const {
-        SkASSERT(fIsValid);
-        return reinterpret_cast<const uint8_t*>(fData);
-    }
-
-private:
-    uint32_t fHash;
-    uint32_t fData[KEY_SIZE_IN_BYTES / sizeof(uint32_t)];  // Buffer for key storage.
-
-#ifdef SK_DEBUG
-public:
-    bool                fIsValid;
-#endif
-};
-
-/**
  *  GrBinHashKey is a hash key class that can take a data chunk of any predetermined
  *  length. The hash function used is the One-at-a-Time Hash
  *  (http://burtleburtle.net/bob/hash/doobs.html).
index 17cdfc9..5e852a9 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "SkInstCnt.h"
 #include "SkTInternalLList.h"
+#include "GrResourceKey.h"
 
 class GrResourceCacheEntry;
 class GrResourceCache2;
@@ -82,6 +83,12 @@ public:
     void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; }
     GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; }
 
+    /** 
+     * 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.
+     */
+    const GrResourceKey& getScratchKey() const { return fScratchKey; }
+
     /**
      * 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
@@ -90,7 +97,6 @@ public:
     uint32_t getUniqueID() const { return fUniqueID; }
 
 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).
     void registerWithCache();
@@ -117,6 +123,12 @@ protected:
      */
     void didChangeGpuMemorySize() const;
 
+    /**
+     * Optionally called by the GrGpuResource subclass if the resource can be used as scratch.
+     * By default resources are not usable as scratch. This should only be called once.
+     **/
+    void setScratchKey(const GrResourceKey& scratchKey);
+
 private:
 #ifdef SK_DEBUG
     friend class GrGpu; // for assert in GrGpu to access getGpu
@@ -146,6 +158,8 @@ private:
     GrResourceCacheEntry*   fCacheEntry;  // NULL if not in cache
     const uint32_t          fUniqueID;
 
+    GrResourceKey           fScratchKey;
+
     typedef SkNoncopyable INHERITED;
 };
 
diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h
new file mode 100644 (file)
index 0000000..d3e82c8
--- /dev/null
@@ -0,0 +1,113 @@
+
+/*
+ * 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 GrResourceKey_DEFINED
+#define GrResourceKey_DEFINED
+
+#include "GrTypes.h"
+#include "GrBinHashKey.h"
+
+class GrResourceKey {
+public:
+    static GrCacheID::Domain ScratchDomain() {
+        static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain();
+        return gDomain;
+    }
+
+    /** Uniquely identifies the GrGpuResource subclass in the key to avoid collisions
+        across resource types. */
+    typedef uint8_t ResourceType;
+
+    /** Flags set by the GrGpuResource subclass. */
+    typedef uint8_t ResourceFlags;
+
+    /** Generate a unique ResourceType */
+    static ResourceType GenerateResourceType();
+
+    /** Creates a key for resource */
+    GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
+        this->init(id.getDomain(), id.getKey(), type, flags);
+    };
+
+    GrResourceKey(const GrResourceKey& src) { fKey = src.fKey; }
+
+    GrResourceKey() { fKey.reset(); }
+
+    void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
+        this->init(id.getDomain(), id.getKey(), type, flags);
+    }
+
+    uint32_t getHash() const { return fKey.getHash(); }
+
+    bool isScratch() const {
+        return ScratchDomain() ==
+            *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() +
+                                                        kCacheIDDomainOffset);
+    }
+
+    ResourceType getResourceType() const {
+        return *reinterpret_cast<const ResourceType*>(fKey.getData() +
+                                                      kResourceTypeOffset);
+    }
+
+    ResourceFlags getResourceFlags() const {
+        return *reinterpret_cast<const ResourceFlags*>(fKey.getData() +
+                                                       kResourceFlagsOffset);
+    }
+
+    bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; }
+
+    // A key indicating that the resource is not usable as a scratch resource.
+    static GrResourceKey& NullScratchKey() {
+        static const GrCacheID::Key kBogusKey = { { {0} } };
+        static GrCacheID kBogusID(ScratchDomain(), kBogusKey);
+        static GrResourceKey kNullScratchKey(kBogusID, NoneResourceType(), 0);
+        return kNullScratchKey;
+    }
+
+    bool isNullScratch() const {
+        return this->isScratch() && NoneResourceType() == this->getResourceType();
+    }
+
+private:
+    enum {
+        kCacheIDKeyOffset = 0,
+        kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key),
+        kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain),
+        kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType),
+        kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags),
+        kKeySize = SkAlign4(kPadOffset),
+        kPadSize = kKeySize - kPadOffset
+    };
+
+    static ResourceType NoneResourceType() {
+        static const ResourceType gNoneResourceType = GenerateResourceType();
+        return gNoneResourceType;
+    }
+
+    void init(const GrCacheID::Domain domain,
+              const GrCacheID::Key& key,
+              ResourceType type,
+              ResourceFlags flags) {
+        union {
+            uint8_t  fKey8[kKeySize];
+            uint32_t fKey32[kKeySize / 4];
+        } keyData;
+
+        uint8_t* k = keyData.fKey8;
+        memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key));
+        memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain));
+        memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType));
+        memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags));
+        memset(k + kPadOffset, 0, kPadSize);
+        fKey.setKeyData(keyData.fKey32);
+    }
+    GrBinHashKey<kKeySize> fKey;
+};
+
+#endif
index 0284c91..06ba2e4 100644 (file)
@@ -163,10 +163,7 @@ public:
     static bool NeedsBilerp(const GrResourceKey& key);
 
 protected:
-    GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
-    : INHERITED(gpu, isWrapped, desc)
-    , fMipMapsStatus(kNotAllocated_MipMapsStatus) {
-    }
+    GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc);
 
 private:
     enum MipMapsStatus {
index a0a7278..bce7d2c 100644 (file)
@@ -22,7 +22,8 @@ GrGpuResource::GrGpuResource(GrGpu* gpu, bool isWrapped)
     : fGpu(gpu)
     , fRefCnt(1)
     , fCacheEntry(NULL)
-    , fUniqueID(CreateUniqueID()) {
+    , fUniqueID(CreateUniqueID())
+    , fScratchKey(GrResourceKey::NullScratchKey()) {
     if (isWrapped) {
         fFlags = kWrapped_FlagBit;
     } else {
@@ -72,6 +73,13 @@ GrContext* GrGpuResource::getContext() {
     }
 }
 
+void GrGpuResource::setScratchKey(const GrResourceKey& scratchKey) {
+    SkASSERT(fScratchKey.isNullScratch());
+    SkASSERT(scratchKey.isScratch());
+    SkASSERT(!scratchKey.isNullScratch());
+    fScratchKey = scratchKey;
+}
+
 uint32_t GrGpuResource::CreateUniqueID() {
     static int32_t gUniqueID = SK_InvalidUniqueID;
     uint32_t id;
diff --git a/src/gpu/GrMurmur3HashKey.h b/src/gpu/GrMurmur3HashKey.h
new file mode 100644 (file)
index 0000000..ad1fa7c
--- /dev/null
@@ -0,0 +1,73 @@
+
+/*
+ * 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 GrMurmur3HashKey_DEFINED
+#define GrMurmur3HashKey_DEFINED
+
+#include "SkChecksum.h"
+#include "GrTypes.h"
+
+/**
+ *  GrMurmur3HashKey is a hash key class that can take a data chunk of any predetermined
+ *  length. It uses the Murmur3 hash function. It is intended to be used with
+ *  SkTDynamicHash (where GrBinHashKey is for GrTHashTable).
+ */
+template<size_t KEY_SIZE_IN_BYTES>
+class GrMurmur3HashKey {
+public:
+    GrMurmur3HashKey() {
+        this->reset();
+    }
+
+    void reset() {
+        fHash = 0;
+#ifdef SK_DEBUG
+        fIsValid = false;
+#endif
+    }
+
+    void setKeyData(const uint32_t* data) {
+        SK_COMPILE_ASSERT(KEY_SIZE_IN_BYTES % 4 == 0, key_size_mismatch);
+        memcpy(fData, data, KEY_SIZE_IN_BYTES);
+
+        fHash = SkChecksum::Murmur3(fData, KEY_SIZE_IN_BYTES);
+#ifdef SK_DEBUG
+        fIsValid = true;
+#endif
+    }
+
+    bool operator==(const GrMurmur3HashKey& other) const {
+        if (fHash != other.fHash) {
+            return false;
+        }
+
+        return !memcmp(fData, other.fData, KEY_SIZE_IN_BYTES);
+    }
+
+    uint32_t getHash() const {
+        SkASSERT(fIsValid);
+        return fHash;
+    }
+
+    const uint8_t* getData() const {
+        SkASSERT(fIsValid);
+        return reinterpret_cast<const uint8_t*>(fData);
+    }
+
+private:
+    uint32_t fHash;
+    uint32_t fData[KEY_SIZE_IN_BYTES / sizeof(uint32_t)];  // Buffer for key storage.
+
+#ifdef SK_DEBUG
+public:
+    bool                fIsValid;
+#endif
+};
+
+#endif
index 82ffbea..460387f 100644 (file)
 #ifndef GrResourceCache_DEFINED
 #define GrResourceCache_DEFINED
 
-#include "GrConfig.h"
-#include "GrTypes.h"
+#include "GrResourceKey.h"
 #include "SkTMultiMap.h"
-#include "GrBinHashKey.h"
 #include "SkMessageBus.h"
 #include "SkTInternalLList.h"
 
@@ -22,92 +20,6 @@ class GrGpuResource;
 class GrResourceCache;
 class GrResourceCacheEntry;
 
-class GrResourceKey {
-public:
-    static GrCacheID::Domain ScratchDomain() {
-        static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain();
-        return gDomain;
-    }
-
-    /** Uniquely identifies the GrGpuResource subclass in the key to avoid collisions
-        across resource types. */
-    typedef uint8_t ResourceType;
-
-    /** Flags set by the GrGpuResource subclass. */
-    typedef uint8_t ResourceFlags;
-
-    /** Generate a unique ResourceType */
-    static ResourceType GenerateResourceType();
-
-    /** Creates a key for resource */
-    GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
-        this->init(id.getDomain(), id.getKey(), type, flags);
-    };
-
-    GrResourceKey(const GrResourceKey& src) {
-        fKey = src.fKey;
-    }
-
-    GrResourceKey() {
-        fKey.reset();
-    }
-
-    void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
-        this->init(id.getDomain(), id.getKey(), type, flags);
-    }
-
-    uint32_t getHash() const {
-        return fKey.getHash();
-    }
-
-    bool isScratch() const {
-        return ScratchDomain() ==
-            *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() +
-                                                        kCacheIDDomainOffset);
-    }
-
-    ResourceType getResourceType() const {
-        return *reinterpret_cast<const ResourceType*>(fKey.getData() +
-                                                      kResourceTypeOffset);
-    }
-
-    ResourceFlags getResourceFlags() const {
-        return *reinterpret_cast<const ResourceFlags*>(fKey.getData() +
-                                                       kResourceFlagsOffset);
-    }
-
-    bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; }
-
-private:
-    enum {
-        kCacheIDKeyOffset = 0,
-        kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key),
-        kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain),
-        kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType),
-        kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags),
-        kKeySize = SkAlign4(kPadOffset),
-        kPadSize = kKeySize - kPadOffset
-    };
-
-    void init(const GrCacheID::Domain domain,
-              const GrCacheID::Key& key,
-              ResourceType type,
-              ResourceFlags flags) {
-        union {
-            uint8_t  fKey8[kKeySize];
-            uint32_t fKey32[kKeySize / 4];
-        } keyData;
-
-        uint8_t* k = keyData.fKey8;
-        memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key));
-        memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain));
-        memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType));
-        memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags));
-        memset(k + kPadOffset, 0, kPadSize);
-        fKey.setKeyData(keyData.fKey32);
-    }
-    GrBinHashKey<kKeySize> fKey;
-};
 
 // The cache listens for these messages to purge junk resources proactively.
 struct GrResourceInvalidatedMessage {
index c325efd..a5732f7 100644 (file)
@@ -20,11 +20,17 @@ void GrResourceCache2::insertResource(GrGpuResource* resource) {
     SkASSERT(!this->isInCache(resource));
     fResources.addToHead(resource);
     ++fCount;
+    if (!resource->getScratchKey().isNullScratch()) {
+        fScratchMap.insert(resource->getScratchKey(), resource);
+    }
 }
 
 void GrResourceCache2::removeResource(GrGpuResource* resource) {
     SkASSERT(this->isInCache(resource));
-    fResources.remove(resource);
+    fResources.remove(resource);    
+    if (!resource->getScratchKey().isNullScratch()) {
+        fScratchMap.remove(resource->getScratchKey(), resource);
+    }
     --fCount;
 }
 
@@ -35,6 +41,7 @@ void GrResourceCache2::abandonAll() {
         // abandon should have already removed this from the list.
         SkASSERT(head != fResources.head());
     }
+    SkASSERT(!fScratchMap.count());
     SkASSERT(!fCount);
 }
 
@@ -45,5 +52,6 @@ void GrResourceCache2::releaseAll() {
         // release should have already removed this from the list.
         SkASSERT(head != fResources.head());
     }
+    SkASSERT(!fScratchMap.count());
     SkASSERT(!fCount);
 }
index 8e79c09..e05efd7 100644 (file)
@@ -9,10 +9,10 @@
 #ifndef GrResourceCache2_DEFINED
 #define GrResourceCache2_DEFINED
 
-#include "GrTypes.h"
+#include "GrGpuResource.h"
+#include "GrResourceKey.h"
 #include "SkTInternalLList.h"
-
-class GrGpuResource;
+#include "SkTMultiMap.h"
 
 /**
  *  Eventual replacement for GrResourceCache. Currently it simply holds a list
@@ -39,8 +39,21 @@ private:
     }
 #endif
 
-    int                             fCount;
-    SkTInternalLList<GrGpuResource> fResources;
+
+    void removeScratch(const GrGpuResource* resource);
+    struct ScratchMapTraits {
+        static const GrResourceKey& GetKey(const GrGpuResource& r) {
+            return r.getScratchKey();
+        }
+
+        static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); }
+    };
+    typedef SkTMultiMap<GrGpuResource, GrResourceKey, ScratchMapTraits> ScratchMap;
+
+    int                                 fCount;
+    SkTInternalLList<GrGpuResource>     fResources;
+    // This map holds all resources that can be used as scratch resources.
+    ScratchMap                          fScratchMap; 
 };
 
 #endif
index fdde9a3..bcff356 100644 (file)
@@ -207,6 +207,11 @@ GrSurfaceOrigin resolve_origin(const GrTextureDesc& desc) {
 }
 
 //////////////////////////////////////////////////////////////////////////////
+GrTextureImpl::GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
+    : INHERITED(gpu, isWrapped, desc)
+    , fMipMapsStatus(kNotAllocated_MipMapsStatus) {
+    this->setScratchKey(ComputeScratchKey(desc));
+}
 
 GrResourceKey GrTextureImpl::ComputeKey(const GrGpu* gpu,
                                     const GrTextureParams* params,
index 6d2fb8f..58539fc 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef GrTextureStripAtlas_DEFINED
 #define GrTextureStripAtlas_DEFINED
 
-#include "GrBinHashKey.h"
+#include "GrMurmur3HashKey.h"
 #include "SkBitmap.h"
 #include "SkGr.h"
 #include "SkTDArray.h"
index 2efd2f9..605fd9f 100644 (file)
@@ -8,6 +8,7 @@
 // This is a GPU-backend specific test
 #if SK_SUPPORT_GPU
 
+#include "GrMurmur3HashKey.h"
 #include "GrBinHashKey.h"
 
 #include "Test.h"