Split cache-specific fields out of GrTextureDesc
http://codereview.appspot.com/6448143/ git-svn-id: http://skia.googlecode.com/svn/trunk@5065 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
62e41903a7
commit
9c2ea84635
@ -75,7 +75,7 @@ public:
|
||||
|
||||
GrCacheID(uint8_t resourceType)
|
||||
: fPublicID(kDefaultPublicCacheID)
|
||||
, fDomain(kUnrestricted_ResourceDomain)
|
||||
, fDomain(GrCacheData::kScratch_ResourceDomain)
|
||||
, fResourceType(resourceType) {
|
||||
}
|
||||
|
||||
|
@ -125,12 +125,14 @@ public:
|
||||
* for different wrap modes on GPUs with limited NPOT
|
||||
* texture support). NULL implies clamp wrap modes.
|
||||
* @param desc Description of the texture properties.
|
||||
* @param cacheData Cache-specific properties (e.g., texture gen ID)
|
||||
* @param srcData Pointer to the pixel values.
|
||||
* @param rowBytes The number of bytes between rows of the texture. Zero
|
||||
* implies tightly packed rows.
|
||||
*/
|
||||
TextureCacheEntry createAndLockTexture(const GrTextureParams* params,
|
||||
const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
void* srcData, size_t rowBytes);
|
||||
|
||||
/**
|
||||
@ -139,12 +141,14 @@ public:
|
||||
* Must be balanced with an unlockTexture() call.
|
||||
*
|
||||
* @param desc Description of the texture properties.
|
||||
* @param cacheData Cache-specific properties (e.g., texture gen ID)
|
||||
* @param params The tex params used to draw a texture may help determine
|
||||
* the cache entry used. (e.g. different versions may exist
|
||||
* for different wrap modes on GPUs with limited NPOT
|
||||
* texture support). NULL implies clamp wrap modes.
|
||||
*/
|
||||
TextureCacheEntry findAndLockTexture(const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
const GrTextureParams* params);
|
||||
/**
|
||||
* Determines whether a texture is in the cache. If the texture is found it
|
||||
@ -152,6 +156,7 @@ public:
|
||||
* the texture for deletion.
|
||||
*/
|
||||
bool isTextureInCache(const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
const GrTextureParams* params) const;
|
||||
|
||||
/**
|
||||
|
@ -16,17 +16,6 @@ class GrRenderTarget;
|
||||
class GrResourceKey;
|
||||
class GrTextureParams;
|
||||
|
||||
/*
|
||||
* All uncached textures should have this value as their fClientCacheID
|
||||
*/
|
||||
static const uint64_t kUncached_CacheID = 0xAAAAAAAA;
|
||||
|
||||
/*
|
||||
* Scratch textures should all have this value as their fClientCacheID
|
||||
*/
|
||||
static const uint64_t kScratch_CacheID = 0xBBBBBBBB;
|
||||
|
||||
|
||||
class GrTexture : public GrSurface {
|
||||
|
||||
public:
|
||||
@ -166,6 +155,7 @@ public:
|
||||
static GrResourceKey ComputeKey(const GrGpu* gpu,
|
||||
const GrTextureParams* sampler,
|
||||
const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
bool scratch);
|
||||
|
||||
static bool NeedsResizing(const GrResourceKey& key);
|
||||
|
@ -468,17 +468,6 @@ enum {
|
||||
kGrColorTableSize = 256 * 4 //sizeof(GrColor)
|
||||
};
|
||||
|
||||
/*
|
||||
* Default value for fClientCacheID
|
||||
*/
|
||||
static const uint64_t kDefault_CacheID = 0;
|
||||
|
||||
/**
|
||||
* All scratch resources should be Unrestricted so they can be used
|
||||
* by any domain.
|
||||
*/
|
||||
static const uint8_t kUnrestricted_ResourceDomain = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Describes a texture to be created.
|
||||
@ -489,9 +478,7 @@ struct GrTextureDesc {
|
||||
, fWidth(0)
|
||||
, fHeight(0)
|
||||
, fConfig(kUnknown_GrPixelConfig)
|
||||
, fSampleCnt(0)
|
||||
, fClientCacheID(kDefault_CacheID)
|
||||
, fResourceDomain(kUnrestricted_ResourceDomain) {
|
||||
, fSampleCnt(0) {
|
||||
}
|
||||
|
||||
GrTextureFlags fFlags; //!< bitfield of TextureFlags
|
||||
@ -512,6 +499,33 @@ struct GrTextureDesc {
|
||||
* max supportex count.
|
||||
*/
|
||||
int fSampleCnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* GrCacheData holds user-provided cache-specific data. It is used in
|
||||
* combination with the GrTextureDesc to construct a cache key for texture
|
||||
* resources.
|
||||
*/
|
||||
struct GrCacheData {
|
||||
/*
|
||||
* Scratch textures should all have this value as their fClientCacheID
|
||||
*/
|
||||
static const uint64_t kScratch_CacheID = 0xBBBBBBBB;
|
||||
|
||||
/**
|
||||
* Resources in the "scratch" domain can be used by any domain. All
|
||||
* scratch textures will have this as their domain.
|
||||
*/
|
||||
static const uint8_t kScratch_ResourceDomain = 0;
|
||||
|
||||
|
||||
// No default constructor is provided since, if you are creating one
|
||||
// of these, you should definitely have a key (or be using the scratch
|
||||
// key).
|
||||
GrCacheData(uint64_t key)
|
||||
: fClientCacheID(key)
|
||||
, fResourceDomain(kScratch_ResourceDomain) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A user-provided texture ID. It should be unique to the texture data and
|
||||
|
@ -238,15 +238,17 @@ void convolve_gaussian(GrGpu* gpu,
|
||||
}
|
||||
|
||||
GrContext::TextureCacheEntry GrContext::findAndLockTexture(const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
const GrTextureParams* params) {
|
||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false);
|
||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheData, false);
|
||||
return TextureCacheEntry(fTextureCache->findAndLock(resourceKey,
|
||||
GrResourceCache::kNested_LockType));
|
||||
}
|
||||
|
||||
bool GrContext::isTextureInCache(const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
const GrTextureParams* params) const {
|
||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false);
|
||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheData, false);
|
||||
return fTextureCache->hasKey(resourceKey);
|
||||
}
|
||||
|
||||
@ -309,6 +311,7 @@ static void stretchImage(void* dst,
|
||||
GrContext::TextureCacheEntry GrContext::createAndLockTexture(
|
||||
const GrTextureParams* params,
|
||||
const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
void* srcData,
|
||||
size_t rowBytes) {
|
||||
SK_TRACE_EVENT0("GrContext::createAndLockTexture");
|
||||
@ -319,16 +322,16 @@ GrContext::TextureCacheEntry GrContext::createAndLockTexture(
|
||||
|
||||
TextureCacheEntry entry;
|
||||
|
||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false);
|
||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheData, false);
|
||||
|
||||
if (GrTexture::NeedsResizing(resourceKey)) {
|
||||
// The desired texture is NPOT and tiled but that isn't supported by
|
||||
// the current hardware. Resize the texture to be a POT
|
||||
GrAssert(NULL != params);
|
||||
TextureCacheEntry clampEntry = this->findAndLockTexture(desc, NULL);
|
||||
TextureCacheEntry clampEntry = this->findAndLockTexture(desc, cacheData, NULL);
|
||||
|
||||
if (NULL == clampEntry.texture()) {
|
||||
clampEntry = this->createAndLockTexture(NULL, desc, srcData, rowBytes);
|
||||
clampEntry = this->createAndLockTexture(NULL, desc, cacheData, srcData, rowBytes);
|
||||
GrAssert(NULL != clampEntry.texture());
|
||||
if (NULL == clampEntry.texture()) {
|
||||
return entry;
|
||||
@ -411,7 +414,7 @@ GrContext::TextureCacheEntry GrContext::lockScratchTexture(
|
||||
const GrTextureDesc& inDesc,
|
||||
ScratchTexMatch match) {
|
||||
GrTextureDesc desc = inDesc;
|
||||
desc.fClientCacheID = kScratch_CacheID;
|
||||
GrCacheData cacheData(GrCacheData::kScratch_CacheID);
|
||||
|
||||
if (kExact_ScratchTexMatch != match) {
|
||||
// bin by pow2 with a reasonable min
|
||||
@ -427,7 +430,7 @@ GrContext::TextureCacheEntry GrContext::lockScratchTexture(
|
||||
bool doubledH = false;
|
||||
|
||||
do {
|
||||
GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, desc, true);
|
||||
GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, desc, cacheData, true);
|
||||
entry = fTextureCache->findAndLock(key,
|
||||
GrResourceCache::kNested_LockType);
|
||||
// if we miss, relax the fit of the flags...
|
||||
@ -462,6 +465,7 @@ GrContext::TextureCacheEntry GrContext::lockScratchTexture(
|
||||
if (NULL != texture) {
|
||||
GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL,
|
||||
texture->desc(),
|
||||
cacheData,
|
||||
true);
|
||||
entry = fTextureCache->createAndLock(key, texture);
|
||||
}
|
||||
@ -482,8 +486,12 @@ void GrContext::addExistingTextureToCache(GrTexture* texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 'texture' is a scratch texture returning to the fold
|
||||
GrCacheData cacheData(GrCacheData::kScratch_CacheID);
|
||||
|
||||
GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL,
|
||||
texture->desc(),
|
||||
cacheData,
|
||||
true);
|
||||
fTextureCache->attach(key, texture);
|
||||
}
|
||||
@ -510,7 +518,6 @@ GrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn,
|
||||
void* srcData,
|
||||
size_t rowBytes) {
|
||||
GrTextureDesc descCopy = descIn;
|
||||
descCopy.fClientCacheID = kUncached_CacheID;
|
||||
return fGpu->createTexture(descCopy, srcData, rowBytes);
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ void gen_stencil_key_values(int width,
|
||||
GrCacheID* cacheID) {
|
||||
cacheID->fPublicID = GrCacheID::kDefaultPublicCacheID;
|
||||
cacheID->fResourceSpecific32 = width | (height << 16);
|
||||
cacheID->fDomain = kUnrestricted_ResourceDomain;
|
||||
cacheID->fDomain = GrCacheData::kScratch_ResourceDomain;
|
||||
|
||||
GrAssert(sampleCnt >= 0 && sampleCnt < 256);
|
||||
cacheID->fResourceSpecific16 = sampleCnt << 8;
|
||||
|
@ -138,20 +138,21 @@ namespace {
|
||||
void gen_texture_key_values(const GrGpu* gpu,
|
||||
const GrTextureParams* params,
|
||||
const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
bool scratch,
|
||||
GrCacheID* cacheID) {
|
||||
|
||||
uint64_t clientKey = desc.fClientCacheID;
|
||||
uint64_t clientKey = cacheData.fClientCacheID;
|
||||
|
||||
if (scratch) {
|
||||
// Instead of a client-provided key of the texture contents
|
||||
// we create a key from the descriptor.
|
||||
GrAssert(kScratch_CacheID == clientKey);
|
||||
GrAssert(GrCacheData::kScratch_CacheID == clientKey);
|
||||
clientKey = (desc.fFlags << 8) | ((uint64_t) desc.fConfig << 32);
|
||||
}
|
||||
|
||||
cacheID->fPublicID = clientKey;
|
||||
cacheID->fDomain = desc.fResourceDomain;
|
||||
cacheID->fDomain = cacheData.fResourceDomain;
|
||||
|
||||
// we assume we only need 16 bits of width and height
|
||||
// assert that texture creation will fail anyway if this assumption
|
||||
@ -184,9 +185,10 @@ void gen_texture_key_values(const GrGpu* gpu,
|
||||
GrResourceKey GrTexture::ComputeKey(const GrGpu* gpu,
|
||||
const GrTextureParams* params,
|
||||
const GrTextureDesc& desc,
|
||||
const GrCacheData& cacheData,
|
||||
bool scratch) {
|
||||
GrCacheID id(GrTexture::GetResourceType());
|
||||
gen_texture_key_values(gpu, params, desc, scratch, &id);
|
||||
gen_texture_key_values(gpu, params, desc, cacheData, scratch, &id);
|
||||
|
||||
uint32_t v[4];
|
||||
id.toRaw(v);
|
||||
|
@ -1907,9 +1907,10 @@ bool SkGpuDevice::isBitmapInTextureCache(const SkBitmap& bitmap,
|
||||
desc.fWidth = bitmap.width();
|
||||
desc.fHeight = bitmap.height();
|
||||
desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());
|
||||
desc.fClientCacheID = key;
|
||||
|
||||
return this->context()->isTextureInCache(desc, ¶ms);
|
||||
GrCacheData cacheData(key);
|
||||
|
||||
return this->context()->isTextureInCache(desc, cacheData, ¶ms);
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,7 +75,8 @@ static GrContext::TextureCacheEntry sk_gr_create_bitmap_texture(GrContext* ctx,
|
||||
desc.fWidth = bitmap->width();
|
||||
desc.fHeight = bitmap->height();
|
||||
desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap->config());
|
||||
desc.fClientCacheID = key;
|
||||
|
||||
GrCacheData cacheData(key);
|
||||
|
||||
if (SkBitmap::kIndex8_Config == bitmap->config()) {
|
||||
// build_compressed_data doesn't do npot->pot expansion
|
||||
@ -91,8 +92,9 @@ static GrContext::TextureCacheEntry sk_gr_create_bitmap_texture(GrContext* ctx,
|
||||
// our compressed data will be trimmed, so pass width() for its
|
||||
// "rowBytes", since they are the same now.
|
||||
|
||||
if (kUncached_CacheID != key) {
|
||||
return ctx->createAndLockTexture(params, desc, storage.get(),
|
||||
if (GrCacheData::kScratch_CacheID != key) {
|
||||
return ctx->createAndLockTexture(params, desc, cacheData,
|
||||
storage.get(),
|
||||
bitmap->width());
|
||||
} else {
|
||||
entry = ctx->lockScratchTexture(desc,
|
||||
@ -111,11 +113,18 @@ static GrContext::TextureCacheEntry sk_gr_create_bitmap_texture(GrContext* ctx,
|
||||
}
|
||||
|
||||
desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap->config());
|
||||
if (kUncached_CacheID != key) {
|
||||
return ctx->createAndLockTexture(params, desc,
|
||||
if (GrCacheData::kScratch_CacheID != key) {
|
||||
// This texture is likely to be used again so leave it in the cache
|
||||
// but locked.
|
||||
return ctx->createAndLockTexture(params, desc, cacheData,
|
||||
bitmap->getPixels(),
|
||||
bitmap->rowBytes());
|
||||
} else {
|
||||
// This texture is unlikely to be used again (in its present form) so
|
||||
// just use a scratch texture. This will remove the texture from the
|
||||
// cache so no one else can find it. Additionally, once unlocked, the
|
||||
// scratch texture will go to the end of the list for purging so will
|
||||
// likely be available for this volatile bitmap the next time around.
|
||||
entry = ctx->lockScratchTexture(desc,
|
||||
GrContext::kExact_ScratchTexMatch);
|
||||
entry.texture()->writePixels(0, 0,
|
||||
@ -135,6 +144,7 @@ GrContext::TextureCacheEntry GrLockCachedBitmapTexture(GrContext* ctx,
|
||||
GrContext::TextureCacheEntry entry;
|
||||
|
||||
if (!bitmap.isVolatile()) {
|
||||
// If the bitmap isn't changing try to find a cached copy first
|
||||
uint64_t key = bitmap.getGenerationID();
|
||||
key |= ((uint64_t) bitmap.pixelRefOffset()) << 32;
|
||||
|
||||
@ -142,14 +152,15 @@ GrContext::TextureCacheEntry GrLockCachedBitmapTexture(GrContext* ctx,
|
||||
desc.fWidth = bitmap.width();
|
||||
desc.fHeight = bitmap.height();
|
||||
desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());
|
||||
desc.fClientCacheID = key;
|
||||
|
||||
entry = ctx->findAndLockTexture(desc, params);
|
||||
GrCacheData cacheData(key);
|
||||
|
||||
entry = ctx->findAndLockTexture(desc, cacheData, params);
|
||||
if (NULL == entry.texture()) {
|
||||
entry = sk_gr_create_bitmap_texture(ctx, key, params, bitmap);
|
||||
}
|
||||
} else {
|
||||
entry = sk_gr_create_bitmap_texture(ctx, kUncached_CacheID, params, bitmap);
|
||||
entry = sk_gr_create_bitmap_texture(ctx, GrCacheData::kScratch_CacheID, params, bitmap);
|
||||
}
|
||||
if (NULL == entry.texture()) {
|
||||
GrPrintf("---- failed to create texture for cache [%d %d]\n",
|
||||
|
@ -28,15 +28,13 @@ void GrGLRenderTarget::init(const Desc& desc,
|
||||
namespace {
|
||||
GrTextureDesc MakeDesc(GrTextureFlags flags,
|
||||
int width, int height,
|
||||
GrPixelConfig config, int sampleCnt,
|
||||
uint64_t clientCacheID) {
|
||||
GrPixelConfig config, int sampleCnt) {
|
||||
GrTextureDesc temp;
|
||||
temp.fFlags = flags;
|
||||
temp.fWidth = width;
|
||||
temp.fHeight = height;
|
||||
temp.fConfig = config;
|
||||
temp.fSampleCnt = sampleCnt;
|
||||
temp.fClientCacheID = clientCacheID;
|
||||
return temp;
|
||||
}
|
||||
|
||||
@ -51,8 +49,7 @@ GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
|
||||
texture,
|
||||
MakeDesc(kNone_GrTextureFlags,
|
||||
viewport.fWidth, viewport.fHeight,
|
||||
desc.fConfig, desc.fSampleCnt,
|
||||
kDefault_CacheID)) {
|
||||
desc.fConfig, desc.fSampleCnt)) {
|
||||
GrAssert(NULL != texID);
|
||||
GrAssert(NULL != texture);
|
||||
// FBO 0 can't also be a texture, right?
|
||||
@ -73,8 +70,7 @@ GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
|
||||
NULL,
|
||||
MakeDesc(kNone_GrTextureFlags,
|
||||
viewport.fWidth, viewport.fHeight,
|
||||
desc.fConfig, desc.fSampleCnt,
|
||||
kDefault_CacheID)) {
|
||||
desc.fConfig, desc.fSampleCnt)) {
|
||||
this->init(desc, viewport, NULL);
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1014,6 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
|
||||
glTexDesc.fHeight = desc.fHeight;
|
||||
glTexDesc.fConfig = desc.fConfig;
|
||||
glTexDesc.fSampleCnt = desc.fSampleCnt;
|
||||
glTexDesc.fClientCacheID = desc.fClientCacheID;
|
||||
|
||||
glTexDesc.fOwnsID = true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user