Refactored cacheID in preparation for clip mask caching changes

http://codereview.appspot.com/6458089/



git-svn-id: http://skia.googlecode.com/svn/trunk@5002 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
robertphillips@google.com 2012-08-08 10:42:44 +00:00
parent 760be85f9b
commit 46a8600405
11 changed files with 222 additions and 49 deletions

View File

@ -246,6 +246,8 @@
'../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',

View 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
/**

44
src/gpu/GrCacheID.cpp Normal file
View File

@ -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;
}

104
src/gpu/GrCacheID.h Normal file
View File

@ -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
* dimensions 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

View 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

View 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) {

View 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) {

View 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;

View 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);
}

View File

@ -12,12 +12,16 @@
#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)

View 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);
}