Refactored cacheID in preparation for clip mask caching changes
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 8 Aug 2012 10:42:44 +0000 (10:42 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 8 Aug 2012 10:42:44 +0000 (10:42 +0000)
http://codereview.appspot.com/6458089/

git-svn-id: http://skia.googlecode.com/svn/trunk@5002 2bbb7eff-a529-9590-31e7-b0007b416f81

gyp/gpu.gyp
include/gpu/GrTexture.h
src/gpu/GrCacheID.cpp [new file with mode: 0644]
src/gpu/GrCacheID.h [new file with mode: 0644]
src/gpu/GrClipMaskManager.cpp
src/gpu/GrClipMaskManager.h
src/gpu/GrContext.cpp
src/gpu/GrResourceCache.h
src/gpu/GrStencilBuffer.cpp
src/gpu/GrStencilBuffer.h
src/gpu/GrTexture.cpp

index 652708f..20bddbf 100644 (file)
         '../src/gpu/GrBinHashKey.h',
         '../src/gpu/GrBufferAllocPool.cpp',
         '../src/gpu/GrBufferAllocPool.h',
+        '../src/gpu/GrCacheID.h',
+        '../src/gpu/GrCacheID.cpp',
         '../src/gpu/GrClipData.cpp',
         '../src/gpu/GrContext.cpp',
         '../src/gpu/GrCustomStage.cpp',
index d4a7cc6..2ccd301 100644 (file)
@@ -10,6 +10,7 @@
 #define GrTexture_DEFINED
 
 #include "GrSurface.h"
+#include "GrCacheID.h"
 
 class GrRenderTarget;
 class GrResourceKey;
@@ -30,6 +31,7 @@ class GrTexture : public GrSurface {
 
 public:
     SK_DECLARE_INST_COUNT(GrTexture)
+    GR_DECLARE_RESOURCE_CACHE_TYPE()
 
     // from GrResource
     /**
diff --git a/src/gpu/GrCacheID.cpp b/src/gpu/GrCacheID.cpp
new file mode 100644 (file)
index 0000000..5f60d94
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrCacheID.h"
+#include "SkThread.h"       // for sk_atomic_inc
+
+uint8_t GrCacheID::GetNextDomain() {
+    // 0 reserved for kUnrestricted_ResourceDomain
+    static int32_t gNextDomain = 1;     
+
+    int32_t domain = sk_atomic_inc(&gNextDomain);
+    if (domain >= 256) {
+        GrCrash("Too many Cache Domains");
+    }
+
+    return (uint8_t) domain;
+}
+
+uint8_t GrCacheID::GetNextResourceType() {
+    // 0 reserved for kInvalid_ResourceType
+    static int32_t gNextResourceType = 1;       
+
+    int32_t type = sk_atomic_inc(&gNextResourceType);
+    if (type >= 256) {
+        GrCrash("Too many Cache Resource Types");
+    }
+
+    return (uint8_t) type;
+}
+
+void GrCacheID::toRaw(uint32_t v[4]) {
+    GrAssert(4*sizeof(uint32_t) == sizeof(GrCacheID));
+
+    v[0] = (uint32_t) (fPublicID & 0xffffffffUL);
+    v[1] = (uint32_t) ((fPublicID >> 32) & 0xffffffffUL);
+    v[2] = fResourceSpecific32;
+    v[3] = fDomain << 24 |
+           fResourceType << 16 |
+           fResourceSpecific16;
+}
diff --git a/src/gpu/GrCacheID.h b/src/gpu/GrCacheID.h
new file mode 100644 (file)
index 0000000..972ce10
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrCacheID_DEFINED
+#define GrCacheID_DEFINED
+
+#include "GrTypes.h"
+
+///////////////////////////////////////////////////////////////////////////////
+#define GR_DECLARE_RESOURCE_CACHE_TYPE()                         \
+    static int8_t GetResourceType();
+
+#define GR_DEFINE_RESOURCE_CACHE_TYPE(ClassName)                 \
+    int8_t ClassName::GetResourceType() {                        \
+        static int8_t kResourceTypeID = 0;                       \
+        if (0 == kResourceTypeID) {                              \
+            kResourceTypeID = GrCacheID::GetNextResourceType();  \
+        }                                                        \
+        return kResourceTypeID;                                  \
+    }
+
+
+///////////////////////////////////////////////////////////////////////////////
+#define GR_DECLARE_RESOURCE_CACHE_DOMAIN(AccessorName)           \
+    static int8_t AccessorName();
+
+#define GR_DEFINE_RESOURCE_CACHE_DOMAIN(ClassName, AccessorName) \
+    int8_t ClassName::AccessorName() {                           \
+        static int8_t kDomainID = 0;                             \
+        if (0 == kDomainID) {                                    \
+            kDomainID = GrCacheID::GetNextDomain();              \
+        }                                                        \
+        return kDomainID;                                        \
+    }
+
+/**
+ * The cache ID adds structure to the IDs used for caching GPU resources. It
+ * is broken into three portions:
+ *      the public portion - which is filled in by Skia clients
+ *      the private portion - which is used by the cache (domain & type)
+ *      the resource-specific portion - which is filled in by each GrResource-
+ *              derived class.
+ *
+ * For the public portion each client of the cache makes up its own 
+ * unique-per-resource identifier (e.g., bitmap genID). A public ID of 
+ * 'kScratch_CacheID' indicates that the resource is a "scratch" resource. 
+ * When used to acquire a resource it indicates the cache user is 
+ * looking for a resource that matches a resource-subclass-specific set of 
+ * \93dimensions\94 such as width, height, buffer size, or pixel config, but not 
+ * for particular resource contents (e.g., texel or vertex values). The public 
+ * IDs are unique within a private ID value but not necessarily across 
+ * private IDs.
+ *
+ * The domain portion identifies the cache client while the type field
+ * indicates the resource type. When the public portion indicates that the 
+ * resource is a scratch resource, the domain field should be kUnrestricted
+ * so that scratch resources can be recycled across domains.
+ */
+class GrCacheID {
+public:
+    uint64_t     fPublicID;
+
+    uint32_t     fResourceSpecific32;
+
+    uint8_t      fDomain;
+private:
+    uint8_t      fResourceType;
+
+public:
+    uint16_t     fResourceSpecific16;
+
+    GrCacheID(uint8_t resourceType)
+        : fPublicID(kDefaultPublicCacheID)
+        , fDomain(kUnrestricted_ResourceDomain)
+        , fResourceType(resourceType) {
+    }
+
+    void toRaw(uint32_t v[4]);
+
+    uint8_t getResourceType() const { return fResourceType; }
+
+    /*
+     * Default value for public portion of GrCacheID
+     */
+    static const uint64_t kDefaultPublicCacheID = 0;
+
+    static const uint8_t kInvalid_ResourceType = 0;
+    /**
+     * All scratch resources should be Unrestricted so they can be used 
+     * by any domain.
+     */
+    static const uint8_t kUnrestricted_ResourceDomain = 0;
+
+    static uint8_t    GetNextDomain();
+    static uint8_t    GetNextResourceType();
+
+
+};
+
+#endif // GrCacheID_DEFINED
index 0abe862..a424b02 100644 (file)
@@ -16,6 +16,9 @@
 #include "GrAAConvexPathRenderer.h"
 #include "GrAAHairLinePathRenderer.h"
 #include "GrSWMaskHelper.h"
+#include "GrCacheID.h"
+
+GR_DEFINE_RESOURCE_CACHE_DOMAIN(GrClipMaskManager, GetAlphaMaskDomain)
 
 //#define GR_AA_CLIP 1
 //#define GR_SW_CLIP 1
index a8a0074..fed4205 100644 (file)
@@ -262,6 +262,8 @@ private:
  */
 class GrClipMaskManager : public GrNoncopyable {
 public:
+    GR_DECLARE_RESOURCE_CACHE_DOMAIN(GetAlphaMaskDomain)
+
     GrClipMaskManager(GrGpu* gpu)
         : fGpu(gpu)
         , fCurrClipMaskType(kNone_ClipMaskType) {
index 49cbec4..6ea8531 100644 (file)
@@ -177,22 +177,6 @@ GrTexture* GrContext::TextureCacheEntry::texture() const {
 
 namespace {
 
-// we should never have more than one stencil buffer with same combo of
-// (width,height,samplecount)
-void gen_stencil_key_values(int width, int height,
-                            int sampleCnt, uint32_t v[4]) {
-    v[0] = width;
-    v[1] = height;
-    v[2] = sampleCnt;
-    v[3] = GrResourceKey::kStencilBuffer_TypeBit;
-}
-
-void gen_stencil_key_values(const GrStencilBuffer* sb,
-                            uint32_t v[4]) {
-    gen_stencil_key_values(sb->width(), sb->height(),
-                           sb->numSamples(), v);
-}
-
 void scale_rect(SkRect* rect, float xScale, float yScale) {
     rect->fLeft = SkScalarMul(rect->fLeft, SkFloatToScalar(xScale));
     rect->fTop = SkScalarMul(rect->fTop, SkFloatToScalar(yScale));
@@ -268,17 +252,18 @@ bool GrContext::isTextureInCache(const GrTextureDesc& desc,
 
 GrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) {
     ASSERT_OWNED_RESOURCE(sb);
-    uint32_t v[4];
-    gen_stencil_key_values(sb, v);
-    GrResourceKey resourceKey(v);
+
+    GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(sb->width(),
+                                                            sb->height(),
+                                                            sb->numSamples());
     return fTextureCache->createAndLock(resourceKey, sb);
 }
 
 GrStencilBuffer* GrContext::findStencilBuffer(int width, int height,
                                               int sampleCnt) {
-    uint32_t v[4];
-    gen_stencil_key_values(width, height, sampleCnt, v);
-    GrResourceKey resourceKey(v);
+    GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width,
+                                                            height,
+                                                            sampleCnt);
     GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey,
                                             GrResourceCache::kSingle_LockType);
     if (NULL != entry) {
index 24f2b8f..076097d 100644 (file)
@@ -41,16 +41,6 @@ public:
         kHashMask   = kHashCount - 1
     };
 
-    enum TypeBits {
-        // resource types
-        kTexture_TypeBit         = 0x01,
-        kStencilBuffer_TypeBit   = 0x02,
-
-        // Derived classes may add additional bits
-        kDummy_TypeBit,
-        kLastPublic_TypeBit = kDummy_TypeBit-1,
-    };
-
     GrResourceKey(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) {
         fP[0] = p0;
         fP[1] = p1;
index 4b08e23..bacbe78 100644 (file)
@@ -10,6 +10,9 @@
 
 #include "GrContext.h"
 #include "GrGpu.h"
+#include "GrResourceCache.h"
+
+GR_DEFINE_RESOURCE_CACHE_TYPE(GrStencilBuffer)
 
 void GrStencilBuffer::wasDetachedFromRenderTarget(const GrRenderTarget* rt) {
     GrAssert(fRTAttachmentCnt > 0);
@@ -53,3 +56,32 @@ void GrStencilBuffer::unlockInCache() {
         }
     }
 }
+
+namespace {
+// we should never have more than one stencil buffer with same combo of
+// (width,height,samplecount)
+void gen_stencil_key_values(int width, 
+                            int height,
+                            int sampleCnt,
+                            GrCacheID* cacheID) {
+    cacheID->fPublicID = GrCacheID::kDefaultPublicCacheID;
+    cacheID->fResourceSpecific32 = width | (height << 16);
+    cacheID->fDomain = GrCacheID::kUnrestricted_ResourceDomain;
+
+    GrAssert(sampleCnt >= 0 && sampleCnt < 256);
+    cacheID->fResourceSpecific16 = sampleCnt << 8;
+
+    // last 8 bits of 'fResourceSpecific16' is free for flags
+}
+}
+
+GrResourceKey GrStencilBuffer::ComputeKey(int width, 
+                                          int height, 
+                                          int sampleCnt) {
+    GrCacheID id(GrStencilBuffer::GetResourceType());
+    gen_stencil_key_values(width, height, sampleCnt, &id);
+
+    uint32_t v[4];
+    id.toRaw(v);
+    return GrResourceKey(v);
+}
index 9767b17..649e130 100644 (file)
 
 #include "GrClipData.h"
 #include "GrResource.h"
+#include "GrCacheID.h"
 
 class GrRenderTarget;
 class GrResourceEntry;
+class GrResourceKey;
 
 class GrStencilBuffer : public GrResource {
 public:
+    GR_DECLARE_RESOURCE_CACHE_TYPE()
+
     virtual ~GrStencilBuffer() {
         // currently each rt that has attached this sb keeps a ref
         // TODO: allow SB to be purged and detach itself from rts
@@ -67,6 +71,8 @@ public:
 
     void wasDetachedFromRenderTarget(const GrRenderTarget* rt);
 
+    static GrResourceKey ComputeKey(int width, int height, int sampleCnt);
+
 protected:
     GrStencilBuffer(GrGpu* gpu, int width, int height, int bits, int sampleCnt)
         : GrResource(gpu)
index fbc3893..ac17a10 100644 (file)
@@ -15,6 +15,7 @@
 #include "GrResourceCache.h"
 
 SK_DEFINE_INST_COUNT(GrTexture)
+GR_DEFINE_RESOURCE_CACHE_TYPE(GrTexture)
 
 /** 
  * This method allows us to interrupt the normal deletion process and place
@@ -111,26 +112,26 @@ void GrTexture::validateDesc() const {
     }
 }
 
+// These flags need to fit in <= 8 bits so they can be folded into the texture
+// key
 enum TextureBits {
-    kFirst_TextureBit = (GrResourceKey::kLastPublic_TypeBit << 1),
-
     /*
      * The kNPOT bit is set when the texture is NPOT and is being repeated
      * but the hardware doesn't support that feature. 
      */
-    kNPOT_TextureBit            = kFirst_TextureBit,
+    kNPOT_TextureBit            = 0x1,
     /*
      * The kFilter bit can only be set when the kNPOT flag is set and indicates
      * whether the resizing of the texture should use filtering. This is
      * to handle cases where the original texture is indexed to disable
      * filtering.
      */
-    kFilter_TextureBit          = kNPOT_TextureBit << 1,
+    kFilter_TextureBit          = 0x2,
     /*
      * The kScratch bit is set if the texture is being used as a scratch
      * texture.
      */
-    kScratch_TextureBit         = kFilter_TextureBit << 1,
+    kScratch_TextureBit         = 0x4,
 };
 
 namespace {
@@ -138,27 +139,28 @@ void gen_texture_key_values(const GrGpu* gpu,
                             const GrTextureParams* params,
                             const GrTextureDesc& desc,
                             bool scratch,
-                            uint32_t v[4]) {
+                            GrCacheID* cacheID) {
 
     uint64_t clientKey = desc.fClientCacheID;
 
     if (scratch) {
         // Instead of a client-provided key of the texture contents
-        // we create a key of from the descriptor.
+        // we create a key from the descriptor.
         GrAssert(kScratch_CacheID == clientKey);
         clientKey = (desc.fFlags << 8) | ((uint64_t) desc.fConfig << 32);
     }
 
+    cacheID->fPublicID = clientKey;
+    cacheID->fDomain = GrCacheID::kUnrestricted_ResourceDomain;
+
     // we assume we only need 16 bits of width and height
     // assert that texture creation will fail anyway if this assumption
     // would cause key collisions.
     GrAssert(gpu->getCaps().fMaxTextureSize <= SK_MaxU16);
-    v[0] = (uint32_t) (clientKey & 0xffffffffUL);
-    v[1] = (uint32_t) ((clientKey >> 32) & 0xffffffffUL);
-    v[2] = desc.fWidth | (desc.fHeight << 16);
+    cacheID->fResourceSpecific32 = desc.fWidth | (desc.fHeight << 16);
 
-    v[3] = (desc.fSampleCnt << 24);
     GrAssert(desc.fSampleCnt >= 0 && desc.fSampleCnt < 256);
+    cacheID->fResourceSpecific16 = desc.fSampleCnt << 8;
 
     if (!gpu->getCaps().fNPOTTextureTileSupport) {
         bool isPow2 = GrIsPow2(desc.fWidth) && GrIsPow2(desc.fHeight);
@@ -166,18 +168,16 @@ void gen_texture_key_values(const GrGpu* gpu,
         bool tiled = NULL != params && params->isTiled();
 
         if (tiled && !isPow2) {
-            v[3] |= kNPOT_TextureBit;
+            cacheID->fResourceSpecific16 |= kNPOT_TextureBit;
             if (params->isBilerp()) {
-                v[3] |= kFilter_TextureBit;
+                cacheID->fResourceSpecific16 |= kFilter_TextureBit;
             }
         }
     }
 
     if (scratch) {
-        v[3] |= kScratch_TextureBit;
+        cacheID->fResourceSpecific16 |= kScratch_TextureBit;
     }
-
-    v[3] |= GrResourceKey::kTexture_TypeBit;
 }
 }
 
@@ -185,8 +185,11 @@ GrResourceKey GrTexture::ComputeKey(const GrGpu* gpu,
                                     const GrTextureParams* params,
                                     const GrTextureDesc& desc,
                                     bool scratch) {
+    GrCacheID id(GrTexture::GetResourceType());
+    gen_texture_key_values(gpu, params, desc, scratch, &id);
+
     uint32_t v[4];
-    gen_texture_key_values(gpu, params, desc, scratch, v);
+    id.toRaw(v);
     return GrResourceKey(v);
 }