Add specialized content key class for resources.
Review URL: https://codereview.chromium.org/858123002
This commit is contained in:
parent
f98f2bb0e7
commit
24db3b1c35
@ -28,15 +28,12 @@ public:
|
||||
this->registerWithCache();
|
||||
}
|
||||
|
||||
static GrResourceKey ComputeKey(int i) {
|
||||
GrCacheID::Key key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.fData32[0] = i;
|
||||
static int gDomain = GrCacheID::GenerateDomain();
|
||||
return GrResourceKey(GrCacheID(gDomain, key), 0);
|
||||
static void ComputeKey(int i, GrContentKey* key) {
|
||||
static GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey::Builder builder(key, kDomain, 1);
|
||||
builder[0] = i;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
size_t onGpuMemorySize() const SK_OVERRIDE { return 100; }
|
||||
|
||||
@ -45,7 +42,8 @@ private:
|
||||
|
||||
static void populate_cache(GrGpu* gpu, int resourceCount) {
|
||||
for (int i = 0; i < resourceCount; ++i) {
|
||||
GrResourceKey key = BenchResource::ComputeKey(i);
|
||||
GrContentKey key;
|
||||
BenchResource::ComputeKey(i, &key);
|
||||
GrGpuResource* resource = SkNEW_ARGS(BenchResource, (gpu));
|
||||
resource->cacheAccess().setContentKey(key);
|
||||
resource->unref();
|
||||
@ -127,7 +125,8 @@ protected:
|
||||
SkASSERT(CACHE_SIZE_COUNT == cache2->getResourceCount());
|
||||
for (int i = 0; i < loops; ++i) {
|
||||
for (int k = 0; k < CACHE_SIZE_COUNT; ++k) {
|
||||
GrResourceKey key = BenchResource::ComputeKey(k);
|
||||
GrContentKey key;
|
||||
BenchResource::ComputeKey(k, &key);
|
||||
SkAutoTUnref<GrGpuResource> resource(cache2->findAndRefContentResource(key));
|
||||
SkASSERT(resource);
|
||||
}
|
||||
|
@ -62,7 +62,6 @@
|
||||
'<(skia_src_path)/gpu/GrBlend.h',
|
||||
'<(skia_src_path)/gpu/GrBufferAllocPool.cpp',
|
||||
'<(skia_src_path)/gpu/GrBufferAllocPool.h',
|
||||
'<(skia_src_path)/gpu/GrCacheID.cpp',
|
||||
'<(skia_src_path)/gpu/GrClipData.cpp',
|
||||
'<(skia_src_path)/gpu/GrClipMaskCache.h',
|
||||
'<(skia_src_path)/gpu/GrClipMaskCache.cpp',
|
||||
|
@ -172,14 +172,14 @@ public:
|
||||
/**
|
||||
* Stores a custom resource in the cache, based on the specified key.
|
||||
*/
|
||||
void addResourceToCache(const GrResourceKey&, GrGpuResource*);
|
||||
void addResourceToCache(const GrContentKey&, GrGpuResource*);
|
||||
|
||||
/**
|
||||
* Finds a resource in the cache, based on the specified key. This is intended for use in
|
||||
* conjunction with addResourceToCache(). The return value will be NULL if not found. The
|
||||
* caller must balance with a call to unref().
|
||||
*/
|
||||
GrGpuResource* findAndRefCachedResource(const GrResourceKey&);
|
||||
GrGpuResource* findAndRefCachedResource(const GrContentKey&);
|
||||
|
||||
/**
|
||||
* Creates a new text rendering context that is optimal for the
|
||||
@ -198,45 +198,53 @@ public:
|
||||
* Creates a new entry, based on the specified key and texture and returns it. The caller owns a
|
||||
* ref on the returned texture which must be balanced by a call to unref.
|
||||
*
|
||||
* TODO: Move resizing logic out of GrContext and have the caller set the content key on the
|
||||
* returned texture rather than take it as a param.
|
||||
*
|
||||
* @param params The texture 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.
|
||||
* @param desc Description of the texture properties.
|
||||
* @param cacheID Cache-specific properties (e.g., texture gen ID)
|
||||
* @param key Key to associate with the texture.
|
||||
* @param srcData Pointer to the pixel values.
|
||||
* @param rowBytes The number of bytes between rows of the texture. Zero
|
||||
* implies tightly packed rows. For compressed pixel configs, this
|
||||
* field is ignored.
|
||||
* @param cacheKey (optional) If non-NULL, we'll write the cache key we used to cacheKey.
|
||||
* @param outKey (optional) If non-NULL, we'll write the cache key we used to cacheKey. this
|
||||
* may differ from key on GPUs that don't support tiling NPOT textures.
|
||||
*/
|
||||
GrTexture* createTexture(const GrTextureParams* params,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrContentKey& key,
|
||||
const void* srcData,
|
||||
size_t rowBytes,
|
||||
GrResourceKey* cacheKey = NULL);
|
||||
GrContentKey* outKey = NULL);
|
||||
/**
|
||||
* Search for an entry based on key and dimensions. If found, ref it and return it. The return
|
||||
* value will be NULL if not found. The caller must balance with a call to unref.
|
||||
*
|
||||
* TODO: Remove this function and do lookups generically.
|
||||
*
|
||||
* @param desc Description of the texture properties.
|
||||
* @param cacheID Cache-specific properties (e.g., texture gen ID)
|
||||
* @param key key to use for texture look up.
|
||||
* @param params The texture 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.
|
||||
*/
|
||||
GrTexture* findAndRefTexture(const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrContentKey& key,
|
||||
const GrTextureParams* params);
|
||||
/**
|
||||
* Determines whether a texture is in the cache. If the texture is found it
|
||||
* will not be locked or returned. This call does not affect the priority of
|
||||
* the texture for deletion.
|
||||
*
|
||||
* TODO: Remove this function and do cache checks generically.
|
||||
*/
|
||||
bool isTextureInCache(const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrContentKey& key,
|
||||
const GrTextureParams* params) const;
|
||||
|
||||
/**
|
||||
@ -871,8 +879,9 @@ private:
|
||||
const SkPath&,
|
||||
const GrStrokeInfo&);
|
||||
|
||||
GrTexture* createResizedTexture(const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
// TODO: Move this out of GrContext.
|
||||
GrTexture* createResizedTexture(const GrSurfaceDesc&,
|
||||
const GrContentKey& origKey,
|
||||
const void* srcData,
|
||||
size_t rowBytes,
|
||||
bool filter);
|
||||
|
@ -259,7 +259,7 @@ private:
|
||||
virtual size_t onGpuMemorySize() const = 0;
|
||||
|
||||
// See comments in CacheAccess.
|
||||
bool setContentKey(const GrResourceKey& contentKey);
|
||||
bool setContentKey(const GrContentKey& contentKey);
|
||||
void notifyIsPurgable() const;
|
||||
void removeScratchKey();
|
||||
void makeBudgeted();
|
||||
@ -275,27 +275,18 @@ private:
|
||||
|
||||
|
||||
static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
|
||||
enum Flags {
|
||||
/**
|
||||
* If set then fContentKey is valid and the resource is cached based on its content.
|
||||
*/
|
||||
kContentKeySet_Flag = 0x1,
|
||||
};
|
||||
|
||||
GrScratchKey fScratchKey;
|
||||
// TODO(bsalomon): Remove GrResourceKey and use different simpler type for content keys.
|
||||
GrResourceKey fContentKey;
|
||||
GrScratchKey fScratchKey;
|
||||
GrContentKey fContentKey;
|
||||
|
||||
// This is not ref'ed but abandon() or release() will be called before the GrGpu object
|
||||
// is destroyed. Those calls set will this to NULL.
|
||||
GrGpu* fGpu;
|
||||
mutable size_t fGpuMemorySize;
|
||||
GrGpu* fGpu;
|
||||
mutable size_t fGpuMemorySize;
|
||||
|
||||
uint32_t fFlags;
|
||||
LifeCycle fLifeCycle;
|
||||
const uint32_t fUniqueID;
|
||||
LifeCycle fLifeCycle;
|
||||
const uint32_t fUniqueID;
|
||||
|
||||
SkAutoTUnref<const SkData> fData;
|
||||
SkAutoTUnref<const SkData> fData;
|
||||
|
||||
typedef GrIORef<GrGpuResource> INHERITED;
|
||||
friend class GrIORef<GrGpuResource>; // to access notifyIsPurgable.
|
||||
|
@ -13,149 +13,212 @@
|
||||
#include "SkTemplates.h"
|
||||
#include "GrBinHashKey.h"
|
||||
|
||||
/**
|
||||
* A key used for scratch resources. The key consists of a resource type (subclass) identifier, a
|
||||
* hash, a data length, and type-specific data. A Builder object is used to initialize the
|
||||
* key contents. The contents must be initialized before the key can be used.
|
||||
*/
|
||||
class GrScratchKey {
|
||||
public:
|
||||
/** Uniquely identifies the type of resource that is cached as scratch. */
|
||||
typedef uint32_t ResourceType;
|
||||
/** Generate a unique ResourceType. */
|
||||
static ResourceType GenerateResourceType();
|
||||
uint32_t GrResourceKeyHash(const uint32_t* data, size_t size);
|
||||
|
||||
GrScratchKey() { this->reset(); }
|
||||
GrScratchKey(const GrScratchKey& that) { *this = that; }
|
||||
class GrResourceKey {
|
||||
public:
|
||||
uint32_t hash() const {
|
||||
this->validate();
|
||||
return fKey[kHash_MetaDataIdx];
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
this->validate();
|
||||
return this->internalSize();
|
||||
}
|
||||
|
||||
const uint32_t* data() const {
|
||||
this->validate();
|
||||
return &fKey[kMetaDataCnt];
|
||||
}
|
||||
|
||||
protected:
|
||||
static const uint32_t kInvalidDomain = 0;
|
||||
|
||||
GrResourceKey() { this->reset(); }
|
||||
|
||||
/** Reset to an invalid key. */
|
||||
void reset() {
|
||||
GR_STATIC_ASSERT((uint16_t)kInvalidDomain == kInvalidDomain);
|
||||
fKey.reset(kMetaDataCnt);
|
||||
fKey[kHash_MetaDataIdx] = 0;
|
||||
fKey[kTypeAndSize_MetaDataIdx] = kInvalidResourceType;
|
||||
fKey[kDomainAndSize_MetaDataIdx] = kInvalidDomain;
|
||||
}
|
||||
|
||||
bool isValid() const { return kInvalidResourceType != this->resourceType(); }
|
||||
bool operator==(const GrResourceKey& that) const {
|
||||
return 0 == memcmp(fKey.get(), that.fKey.get(), this->size());
|
||||
}
|
||||
|
||||
ResourceType resourceType() const { return fKey[kTypeAndSize_MetaDataIdx] & 0xffff; }
|
||||
|
||||
uint32_t hash() const { return fKey[kHash_MetaDataIdx]; }
|
||||
|
||||
size_t size() const { return SkToInt(fKey[kTypeAndSize_MetaDataIdx] >> 16); }
|
||||
|
||||
const uint32_t* data() const { return &fKey[kMetaDataCnt]; }
|
||||
|
||||
GrScratchKey& operator=(const GrScratchKey& that) {
|
||||
GrResourceKey& operator=(const GrResourceKey& that) {
|
||||
size_t bytes = that.size();
|
||||
SkASSERT(SkIsAlign4(bytes));
|
||||
fKey.reset(SkToInt(bytes / sizeof(uint32_t)));
|
||||
memcpy(fKey.get(), that.fKey.get(), bytes);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const GrScratchKey& that) const {
|
||||
return 0 == memcmp(fKey.get(), that.fKey.get(), this->size());
|
||||
}
|
||||
bool operator!=(const GrScratchKey& that) const { return !(*this == that); }
|
||||
bool isValid() const { return kInvalidDomain != this->domain(); }
|
||||
|
||||
/** Used to initialize scratch key. */
|
||||
uint32_t domain() const { return fKey[kDomainAndSize_MetaDataIdx] & 0xffff; }
|
||||
|
||||
/** Used to initialize a key. */
|
||||
class Builder {
|
||||
public:
|
||||
Builder(GrScratchKey* key, ResourceType type, int data32Count) : fKey(key) {
|
||||
Builder(GrResourceKey* key, uint32_t domain, int data32Count) : fKey(key) {
|
||||
SkASSERT(data32Count >= 0);
|
||||
SkASSERT(type != kInvalidResourceType);
|
||||
SkASSERT(domain != kInvalidDomain);
|
||||
key->fKey.reset(kMetaDataCnt + data32Count);
|
||||
SkASSERT(type <= SK_MaxU16);
|
||||
int size = (data32Count + kMetaDataCnt) * sizeof(uint32_t);
|
||||
SkASSERT(size <= SK_MaxU16);
|
||||
key->fKey[kTypeAndSize_MetaDataIdx] = type | (size << 16);
|
||||
SkASSERT(SkToU16(size) == size);
|
||||
SkASSERT(SkToU16(domain) == domain);
|
||||
key->fKey[kDomainAndSize_MetaDataIdx] = domain | (size << 16);
|
||||
}
|
||||
|
||||
~Builder() { this->finish(); }
|
||||
|
||||
void finish();
|
||||
void finish() {
|
||||
if (NULL == fKey) {
|
||||
return;
|
||||
}
|
||||
GR_STATIC_ASSERT(0 == kHash_MetaDataIdx);
|
||||
uint32_t* hash = &fKey->fKey[kHash_MetaDataIdx];
|
||||
*hash = GrResourceKeyHash(hash + 1, fKey->internalSize() - sizeof(uint32_t));
|
||||
fKey->validate();
|
||||
fKey = NULL;
|
||||
}
|
||||
|
||||
uint32_t& operator[](int dataIdx) {
|
||||
SkASSERT(fKey);
|
||||
SkDEBUGCODE(size_t dataCount = fKey->size() / sizeof(uint32_t) - kMetaDataCnt;)
|
||||
SkDEBUGCODE(size_t dataCount = fKey->internalSize() / sizeof(uint32_t) - kMetaDataCnt;)
|
||||
SkASSERT(SkToU32(dataIdx) < dataCount);
|
||||
return fKey->fKey[kMetaDataCnt + dataIdx];
|
||||
}
|
||||
|
||||
private:
|
||||
GrScratchKey* fKey;
|
||||
GrResourceKey* fKey;
|
||||
};
|
||||
|
||||
private:
|
||||
size_t internalSize() const {
|
||||
return fKey[kDomainAndSize_MetaDataIdx] >> 16;
|
||||
}
|
||||
|
||||
void validate() const {
|
||||
SkASSERT(fKey[kHash_MetaDataIdx] ==
|
||||
GrResourceKeyHash(&fKey[kHash_MetaDataIdx] + 1,
|
||||
this->internalSize() - sizeof(uint32_t)));
|
||||
}
|
||||
|
||||
enum MetaDataIdx {
|
||||
kHash_MetaDataIdx,
|
||||
// The resource type and size are packed into a single uint32_t.
|
||||
kTypeAndSize_MetaDataIdx,
|
||||
// The key domain and size are packed into a single uint32_t.
|
||||
kDomainAndSize_MetaDataIdx,
|
||||
|
||||
kLastMetaDataIdx = kTypeAndSize_MetaDataIdx
|
||||
kLastMetaDataIdx = kDomainAndSize_MetaDataIdx
|
||||
};
|
||||
static const uint32_t kInvalidResourceType = 0;
|
||||
static const uint32_t kMetaDataCnt = kLastMetaDataIdx + 1;
|
||||
|
||||
friend class TestResource; // For unit test to access kMetaDataCnt.
|
||||
|
||||
// Stencil and textures each require 2 uint32_t values.
|
||||
SkAutoSTArray<kMetaDataCnt + 2, uint32_t> fKey;
|
||||
// bmp textures require 4 uint32_t values.
|
||||
SkAutoSTArray<kMetaDataCnt + 4, uint32_t> fKey;
|
||||
};
|
||||
|
||||
class GrResourceKey {
|
||||
public:
|
||||
/** Flags set by the GrGpuResource subclass. */
|
||||
typedef uint8_t ResourceFlags;
|
||||
|
||||
/** Creates a key for resource */
|
||||
GrResourceKey(const GrCacheID& id, ResourceFlags flags) {
|
||||
this->init(id.getDomain(), id.getKey(), flags);
|
||||
};
|
||||
|
||||
GrResourceKey(const GrResourceKey& src) { fKey = src.fKey; }
|
||||
|
||||
GrResourceKey() { fKey.reset(); }
|
||||
|
||||
void reset(const GrCacheID& id, ResourceFlags flags) {
|
||||
this->init(id.getDomain(), id.getKey(), flags);
|
||||
}
|
||||
|
||||
uint32_t getHash() const { return fKey.getHash(); }
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* A key used for scratch resources. The key consists of a resource type (subclass) identifier, a
|
||||
* hash, a data length, and type-specific data. A Builder object is used to initialize the
|
||||
* key contents. The contents must be initialized before the key can be used.
|
||||
*/
|
||||
class GrScratchKey : public GrResourceKey {
|
||||
private:
|
||||
enum {
|
||||
kCacheIDKeyOffset = 0,
|
||||
kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key),
|
||||
kResourceFlagsOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain),
|
||||
kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags),
|
||||
kKeySize = SkAlign4(kPadOffset),
|
||||
kPadSize = kKeySize - kPadOffset
|
||||
};
|
||||
typedef GrResourceKey INHERITED;
|
||||
|
||||
void init(const GrCacheID::Domain domain, const GrCacheID::Key& key, ResourceFlags flags) {
|
||||
union {
|
||||
uint8_t fKey8[kKeySize];
|
||||
uint32_t fKey32[kKeySize / 4];
|
||||
} keyData;
|
||||
public:
|
||||
/** Uniquely identifies the type of resource that is cached as scratch. */
|
||||
typedef uint32_t ResourceType;
|
||||
|
||||
uint8_t* k = keyData.fKey8;
|
||||
memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key));
|
||||
memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain));
|
||||
memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags));
|
||||
memset(k + kPadOffset, 0, kPadSize);
|
||||
fKey.setKeyData(keyData.fKey32);
|
||||
/** Generate a unique ResourceType. */
|
||||
static ResourceType GenerateResourceType();
|
||||
|
||||
/** Creates an invalid scratch key. It must be initialized using a Builder object before use. */
|
||||
GrScratchKey() {}
|
||||
|
||||
GrScratchKey(const GrScratchKey& that) { *this = that; }
|
||||
|
||||
/** reset() returns the key to the invalid state. */
|
||||
using INHERITED::reset;
|
||||
|
||||
using INHERITED::isValid;
|
||||
|
||||
ResourceType resourceType() const { return this->domain(); }
|
||||
|
||||
GrScratchKey& operator=(const GrScratchKey& that) {
|
||||
this->INHERITED::operator=(that);
|
||||
return *this;
|
||||
}
|
||||
GrBinHashKey<kKeySize> fKey;
|
||||
|
||||
bool operator==(const GrScratchKey& that) const {
|
||||
return this->INHERITED::operator==(that);
|
||||
}
|
||||
bool operator!=(const GrScratchKey& that) const { return !(*this == that); }
|
||||
|
||||
class Builder : public INHERITED::Builder {
|
||||
public:
|
||||
Builder(GrScratchKey* key, ResourceType type, int data32Count)
|
||||
: INHERITED::Builder(key, type, data32Count) {}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* A key used to cache resources based on their content. The key consists of a domain type (use
|
||||
* case for the cache), a hash, a data length, and domain-specific data. A Builder object is used to
|
||||
* initialize the key contents. The contents must be initialized before the key can be used.
|
||||
*/
|
||||
class GrContentKey : public GrResourceKey {
|
||||
private:
|
||||
typedef GrResourceKey INHERITED;
|
||||
|
||||
public:
|
||||
typedef uint32_t Domain;
|
||||
/** Generate a unique Domain of content keys. */
|
||||
static Domain GenerateDomain();
|
||||
|
||||
/** Creates an invalid content key. It must be initialized using a Builder object before use. */
|
||||
GrContentKey() {}
|
||||
|
||||
GrContentKey(const GrContentKey& that) { *this = that; }
|
||||
|
||||
/** reset() returns the key to the invalid state. */
|
||||
using INHERITED::reset;
|
||||
|
||||
using INHERITED::isValid;
|
||||
|
||||
GrContentKey& operator=(const GrContentKey& that) {
|
||||
this->INHERITED::operator=(that);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const GrContentKey& that) const {
|
||||
return this->INHERITED::operator==(that);
|
||||
}
|
||||
bool operator!=(const GrContentKey& that) const { return !(*this == that); }
|
||||
|
||||
class Builder : public INHERITED::Builder {
|
||||
public:
|
||||
Builder(GrContentKey* key, Domain domain, int data32Count)
|
||||
: INHERITED::Builder(key, domain, data32Count) {}
|
||||
|
||||
/** Used to build a key that wraps another key and adds additional data. */
|
||||
Builder(GrContentKey* key, const GrContentKey& innerKey, Domain domain,
|
||||
int extraData32Cnt)
|
||||
: INHERITED::Builder(key, domain, (SkToInt(innerKey.size()) >> 2) + extraData32Cnt) {
|
||||
int innerKeyCnt = SkToInt(innerKey.size()) >> 2;
|
||||
// add the inner key to the end of the key so that op[] can be indexed normally.
|
||||
for (int i = 0; i < innerKeyCnt; ++i) {
|
||||
this->operator[](extraData32Cnt + i) = innerKey.data()[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "SkPoint.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class GrResourceKey;
|
||||
class GrTextureParams;
|
||||
class GrTexturePriv;
|
||||
|
||||
|
@ -472,58 +472,6 @@ struct GrSurfaceDesc {
|
||||
// Legacy alias
|
||||
typedef GrSurfaceDesc GrTextureDesc;
|
||||
|
||||
/**
|
||||
* GrCacheID is used create and find cached GrResources (e.g. GrTextures). The ID has two parts:
|
||||
* the domain and the key. Domains simply allow multiple clients to use 0-based indices as their
|
||||
* cache key without colliding. The key uniquely identifies a GrResource within the domain.
|
||||
* Users of the cache must obtain a domain via GenerateDomain().
|
||||
*/
|
||||
struct GrCacheID {
|
||||
public:
|
||||
typedef uint8_t Domain;
|
||||
|
||||
struct Key {
|
||||
union {
|
||||
uint8_t fData8[16];
|
||||
uint32_t fData32[4];
|
||||
uint64_t fData64[2];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* A default cache ID is invalid; a set method must be called before the object is used.
|
||||
*/
|
||||
GrCacheID() { fDomain = kInvalid_Domain; }
|
||||
|
||||
/**
|
||||
* Initialize the cache ID to a domain and key.
|
||||
*/
|
||||
GrCacheID(Domain domain, const Key& key) {
|
||||
SkASSERT(kInvalid_Domain != domain);
|
||||
this->reset(domain, key);
|
||||
}
|
||||
|
||||
void reset(Domain domain, const Key& key) {
|
||||
fDomain = domain;
|
||||
memcpy(&fKey, &key, sizeof(Key));
|
||||
}
|
||||
|
||||
/** Has this been initialized to a valid domain */
|
||||
bool isValid() const { return kInvalid_Domain != fDomain; }
|
||||
|
||||
const Key& getKey() const { SkASSERT(this->isValid()); return fKey; }
|
||||
Domain getDomain() const { SkASSERT(this->isValid()); return fDomain; }
|
||||
|
||||
/** Creates a new unique ID domain. */
|
||||
static Domain GenerateDomain();
|
||||
|
||||
private:
|
||||
Key fKey;
|
||||
Domain fDomain;
|
||||
|
||||
static const Domain kInvalid_Domain = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clips are composed from these objects.
|
||||
*/
|
||||
|
@ -70,7 +70,7 @@ static inline GrColor SkColor2GrColorJustAlpha(SkColor c) {
|
||||
|
||||
// The cache listens for these messages to purge junk resources proactively.
|
||||
struct GrResourceInvalidatedMessage {
|
||||
GrResourceKey key;
|
||||
GrContentKey fKey;
|
||||
};
|
||||
|
||||
bool GrIsBitmapInCache(const GrContext*, const SkBitmap&, const GrTextureParams*);
|
||||
|
@ -753,31 +753,29 @@ bool GrRectBlurEffect::CreateBlurProfileTexture(GrContext *context, float sigma,
|
||||
GrTextureParams params;
|
||||
GrSurfaceDesc texDesc;
|
||||
|
||||
unsigned int profile_size = SkScalarCeilToInt(6*sigma);
|
||||
unsigned int profileSize = SkScalarCeilToInt(6*sigma);
|
||||
|
||||
texDesc.fWidth = profile_size;
|
||||
texDesc.fWidth = profileSize;
|
||||
texDesc.fHeight = 1;
|
||||
texDesc.fConfig = kAlpha_8_GrPixelConfig;
|
||||
|
||||
static const GrCacheID::Domain gBlurProfileDomain = GrCacheID::GenerateDomain();
|
||||
GrCacheID::Key key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.fData32[0] = profile_size;
|
||||
key.fData32[1] = 1;
|
||||
GrCacheID blurProfileKey(gBlurProfileDomain, key);
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey key;
|
||||
GrContentKey::Builder builder(&key, kDomain, 1);
|
||||
builder[0] = profileSize;
|
||||
builder.finish();
|
||||
|
||||
uint8_t *profile = NULL;
|
||||
SkAutoTDeleteArray<uint8_t> ada(NULL);
|
||||
|
||||
*blurProfileTexture = context->findAndRefTexture(texDesc, blurProfileKey, ¶ms);
|
||||
*blurProfileTexture = context->findAndRefTexture(texDesc, key, ¶ms);
|
||||
|
||||
if (NULL == *blurProfileTexture) {
|
||||
|
||||
SkBlurMask::ComputeBlurProfile(sigma, &profile);
|
||||
ada.reset(profile);
|
||||
|
||||
*blurProfileTexture = context->createTexture(¶ms, texDesc, blurProfileKey,
|
||||
profile, 0);
|
||||
*blurProfileTexture = context->createTexture(¶ms, texDesc, key, profile, 0);
|
||||
|
||||
if (NULL == *blurProfileTexture) {
|
||||
return false;
|
||||
@ -920,12 +918,12 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const GrCacheID::Domain gRRectBlurDomain = GrCacheID::GenerateDomain();
|
||||
GrCacheID::Key key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.fData32[0] = blurRadius;
|
||||
key.fData32[1] = cornerRadius;
|
||||
GrCacheID blurRRectNinePatchID(gRRectBlurDomain, key);
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey key;
|
||||
GrContentKey::Builder builder(&key, kDomain, 2);
|
||||
builder[0] = blurRadius;
|
||||
builder[1] = cornerRadius;
|
||||
builder.finish();
|
||||
|
||||
GrTextureParams params;
|
||||
params.setFilterMode(GrTextureParams::kBilerp_FilterMode);
|
||||
@ -937,7 +935,7 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
|
||||
texDesc.fHeight = texSide;
|
||||
texDesc.fConfig = kAlpha_8_GrPixelConfig;
|
||||
|
||||
GrTexture *blurNinePatchTexture = context->findAndRefTexture(texDesc, blurRRectNinePatchID, ¶ms);
|
||||
GrTexture *blurNinePatchTexture = context->findAndRefTexture(texDesc, key, ¶ms);
|
||||
|
||||
if (NULL == blurNinePatchTexture) {
|
||||
SkMask mask;
|
||||
@ -964,7 +962,7 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
|
||||
SkMask blurred_mask;
|
||||
SkBlurMask::BoxBlur(&blurred_mask, mask, sigma, kNormal_SkBlurStyle, kHigh_SkBlurQuality, NULL, true );
|
||||
|
||||
blurNinePatchTexture = context->createTexture(¶ms, texDesc, blurRRectNinePatchID, blurred_mask.fImage, 0);
|
||||
blurNinePatchTexture = context->createTexture(¶ms, texDesc, key, blurred_mask.fImage, 0);
|
||||
SkMask::FreeImage(blurred_mask.fImage);
|
||||
}
|
||||
|
||||
|
@ -342,26 +342,24 @@ void GrColorCubeEffect::GLProcessor::GenKey(const GrProcessor& proc,
|
||||
}
|
||||
|
||||
GrFragmentProcessor* SkColorCubeFilter::asFragmentProcessor(GrContext* context) const {
|
||||
static const GrCacheID::Domain gCubeDomain = GrCacheID::GenerateDomain();
|
||||
|
||||
GrCacheID::Key key;
|
||||
key.fData32[0] = fUniqueID;
|
||||
key.fData32[1] = fCache.cubeDimension();
|
||||
key.fData64[1] = 0;
|
||||
GrCacheID cacheID(gCubeDomain, key);
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey key;
|
||||
GrContentKey::Builder builder(&key, kDomain, 2);
|
||||
builder[0] = fUniqueID;
|
||||
builder[1] = fCache.cubeDimension();
|
||||
builder.finish();
|
||||
|
||||
GrSurfaceDesc desc;
|
||||
desc.fWidth = fCache.cubeDimension();
|
||||
desc.fHeight = fCache.cubeDimension() * fCache.cubeDimension();
|
||||
desc.fConfig = kRGBA_8888_GrPixelConfig;
|
||||
|
||||
GrResourceKey rkey = GrTexturePriv::ComputeKey(context->getGpu(), NULL, desc, cacheID);
|
||||
GrSurface* surface = static_cast<GrSurface*>(context->findAndRefCachedResource(rkey));
|
||||
GrSurface* surface = static_cast<GrSurface*>(context->findAndRefCachedResource(key));
|
||||
SkAutoTUnref<GrTexture> textureCube;
|
||||
if (surface) {
|
||||
textureCube.reset(surface->asTexture());
|
||||
} else {
|
||||
textureCube.reset(context->createTexture(NULL, desc, cacheID, fCubeData->data(), 0));
|
||||
textureCube.reset(context->createTexture(NULL, desc, key, fCubeData->data(), 0));
|
||||
}
|
||||
|
||||
return textureCube ? GrColorCubeEffect::Create(textureCube) : NULL;
|
||||
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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 "GrTypes.h"
|
||||
#include "SkThread.h" // for sk_atomic_inc
|
||||
|
||||
// Well, the dummy_ "fix" caused a warning on windows, so hiding all of it
|
||||
// until we can find a universal fix.
|
||||
#if 0
|
||||
// This used to be a global scope, but we got a warning about unused variable
|
||||
// so we moved it into here. We just want it to compile, so we can test the
|
||||
// static asserts.
|
||||
static inline void dummy_function_to_avoid_unused_var_warning() {
|
||||
GrCacheID::Key kAssertKey;
|
||||
GR_STATIC_ASSERT(sizeof(kAssertKey.fData8) == sizeof(kAssertKey.fData32));
|
||||
GR_STATIC_ASSERT(sizeof(kAssertKey.fData8) == sizeof(kAssertKey.fData64));
|
||||
GR_STATIC_ASSERT(sizeof(kAssertKey.fData8) == sizeof(kAssertKey));
|
||||
}
|
||||
#endif
|
||||
|
||||
GrCacheID::Domain GrCacheID::GenerateDomain() {
|
||||
static int32_t gNextDomain = kInvalid_Domain + 1;
|
||||
|
||||
int32_t domain = sk_atomic_inc(&gNextDomain);
|
||||
if (domain >= 1 << (8 * sizeof(Domain))) {
|
||||
SkFAIL("Too many Cache Domains");
|
||||
}
|
||||
|
||||
return static_cast<Domain>(domain);
|
||||
}
|
@ -223,26 +223,6 @@ GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrTexture* GrContext::findAndRefTexture(const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrTextureParams* params) {
|
||||
GrResourceKey resourceKey = GrTexturePriv::ComputeKey(fGpu, params, desc, cacheID);
|
||||
|
||||
GrGpuResource* resource = this->findAndRefCachedResource(resourceKey);
|
||||
if (resource) {
|
||||
SkASSERT(static_cast<GrSurface*>(resource)->asTexture());
|
||||
return static_cast<GrSurface*>(resource)->asTexture();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool GrContext::isTextureInCache(const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrTextureParams* params) const {
|
||||
GrResourceKey resourceKey = GrTexturePriv::ComputeKey(fGpu, params, desc, cacheID);
|
||||
return fResourceCache2->hasContentKey(resourceKey);
|
||||
}
|
||||
|
||||
static void stretch_image(void* dst,
|
||||
int dstW,
|
||||
int dstH,
|
||||
@ -268,20 +248,54 @@ static void stretch_image(void* dst,
|
||||
}
|
||||
}
|
||||
|
||||
enum ResizeFlags {
|
||||
/**
|
||||
* The kStretchToPOT bit is set when the texture is NPOT and is being repeated or mipped but the
|
||||
* hardware doesn't support that feature.
|
||||
*/
|
||||
kStretchToPOT_ResizeFlag = 0x1,
|
||||
/**
|
||||
* The kBilerp bit can only be set when the kStretchToPOT flag is set and indicates whether the
|
||||
* stretched texture should be bilerped.
|
||||
*/
|
||||
kBilerp_ResizeFlag = 0x2,
|
||||
};
|
||||
|
||||
static uint32_t get_texture_flags(const GrGpu* gpu,
|
||||
const GrTextureParams* params,
|
||||
const GrSurfaceDesc& desc) {
|
||||
uint32_t flags = 0;
|
||||
bool tiled = params && params->isTiled();
|
||||
if (tiled && !gpu->caps()->npotTextureTileSupport()) {
|
||||
if (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight)) {
|
||||
flags |= kStretchToPOT_ResizeFlag;
|
||||
switch(params->filterMode()) {
|
||||
case GrTextureParams::kNone_FilterMode:
|
||||
break;
|
||||
case GrTextureParams::kBilerp_FilterMode:
|
||||
case GrTextureParams::kMipMap_FilterMode:
|
||||
flags |= kBilerp_ResizeFlag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
// The desired texture is NPOT and tiled but that isn't supported by
|
||||
// the current hardware. Resize the texture to be a POT
|
||||
GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrContentKey& origKey,
|
||||
const void* srcData,
|
||||
size_t rowBytes,
|
||||
bool filter) {
|
||||
SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, cacheID, NULL));
|
||||
SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, origKey, NULL));
|
||||
if (NULL == clampedTexture) {
|
||||
clampedTexture.reset(this->createTexture(NULL, desc, cacheID, srcData, rowBytes));
|
||||
clampedTexture.reset(this->createTexture(NULL, desc, origKey, srcData, rowBytes));
|
||||
|
||||
if (NULL == clampedTexture) {
|
||||
return NULL;
|
||||
}
|
||||
clampedTexture->cacheAccess().setContentKey(origKey);
|
||||
}
|
||||
|
||||
GrSurfaceDesc rtDesc = desc;
|
||||
@ -318,6 +332,9 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
|
||||
verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(SkPoint));
|
||||
verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint));
|
||||
fDrawBuffer->drawNonIndexed(&pipelineBuilder, gp, kTriangleFan_GrPrimitiveType, 0, 4);
|
||||
} else {
|
||||
texture->unref();
|
||||
texture = NULL;
|
||||
}
|
||||
} else {
|
||||
// TODO: Our CPU stretch doesn't filter. But we create separate
|
||||
@ -347,30 +364,39 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
|
||||
return texture;
|
||||
}
|
||||
|
||||
static GrContentKey::Domain ResizeDomain() {
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
return kDomain;
|
||||
}
|
||||
|
||||
GrTexture* GrContext::createTexture(const GrTextureParams* params,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrContentKey& origKey,
|
||||
const void* srcData,
|
||||
size_t rowBytes,
|
||||
GrResourceKey* cacheKey) {
|
||||
GrResourceKey resourceKey = GrTexturePriv::ComputeKey(fGpu, params, desc, cacheID);
|
||||
|
||||
GrContentKey* outKey) {
|
||||
GrTexture* texture;
|
||||
if (GrTexturePriv::NeedsResizing(resourceKey)) {
|
||||
// We do not know how to resize compressed textures.
|
||||
SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig));
|
||||
uint32_t flags = get_texture_flags(fGpu, params, desc);
|
||||
SkTCopyOnFirstWrite<GrContentKey> key(origKey);
|
||||
if (flags) {
|
||||
// We don't have a code path to resize compressed textures.
|
||||
if (GrPixelConfigIsCompressed(desc.fConfig)) {
|
||||
return NULL;
|
||||
}
|
||||
texture = this->createResizedTexture(desc, origKey, srcData, rowBytes,
|
||||
SkToBool(flags & kBilerp_ResizeFlag));
|
||||
|
||||
GrContentKey::Builder builder(key.writable(), origKey, ResizeDomain(), 1);
|
||||
builder[0] = flags;
|
||||
|
||||
texture = this->createResizedTexture(desc, cacheID,
|
||||
srcData, rowBytes,
|
||||
GrTexturePriv::NeedsBilerp(resourceKey));
|
||||
} else {
|
||||
texture = fGpu->createTexture(desc, true, srcData, rowBytes);
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
if (texture->cacheAccess().setContentKey(resourceKey)) {
|
||||
if (cacheKey) {
|
||||
*cacheKey = resourceKey;
|
||||
if (texture->cacheAccess().setContentKey(*key)) {
|
||||
if (outKey) {
|
||||
*outKey = *key;
|
||||
}
|
||||
} else {
|
||||
texture->unref();
|
||||
@ -381,6 +407,37 @@ GrTexture* GrContext::createTexture(const GrTextureParams* params,
|
||||
return texture;
|
||||
}
|
||||
|
||||
GrTexture* GrContext::findAndRefTexture(const GrSurfaceDesc& desc,
|
||||
const GrContentKey& origKey,
|
||||
const GrTextureParams* params) {
|
||||
uint32_t flags = get_texture_flags(fGpu, params, desc);
|
||||
SkTCopyOnFirstWrite<GrContentKey> key(origKey);
|
||||
if (flags) {
|
||||
GrContentKey::Builder builder(key.writable(), origKey, ResizeDomain(), 1);
|
||||
builder[0] = flags;
|
||||
}
|
||||
|
||||
GrGpuResource* resource = this->findAndRefCachedResource(*key);
|
||||
if (resource) {
|
||||
SkASSERT(static_cast<GrSurface*>(resource)->asTexture());
|
||||
return static_cast<GrSurface*>(resource)->asTexture();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool GrContext::isTextureInCache(const GrSurfaceDesc& desc,
|
||||
const GrContentKey& origKey,
|
||||
const GrTextureParams* params) const {
|
||||
uint32_t flags = get_texture_flags(fGpu, params, desc);
|
||||
SkTCopyOnFirstWrite<GrContentKey> key(origKey);
|
||||
if (flags) {
|
||||
GrContentKey::Builder builder(key.writable(), origKey, ResizeDomain(), 1);
|
||||
builder[0] = flags;
|
||||
}
|
||||
|
||||
return fResourceCache2->hasContentKey(*key);
|
||||
}
|
||||
|
||||
GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexMatch match,
|
||||
bool calledDuringFlush) {
|
||||
// kNoStencil has no meaning if kRT isn't set.
|
||||
@ -1703,12 +1760,12 @@ const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture,
|
||||
}
|
||||
}
|
||||
|
||||
void GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrGpuResource* resource) {
|
||||
resource->cacheAccess().setContentKey(resourceKey);
|
||||
void GrContext::addResourceToCache(const GrContentKey& key, GrGpuResource* resource) {
|
||||
resource->cacheAccess().setContentKey(key);
|
||||
}
|
||||
|
||||
GrGpuResource* GrContext::findAndRefCachedResource(const GrResourceKey& resourceKey) {
|
||||
return fResourceCache2->findAndRefContentResource(resourceKey);
|
||||
GrGpuResource* GrContext::findAndRefCachedResource(const GrContentKey& key) {
|
||||
return fResourceCache2->findAndRefContentResource(key);
|
||||
}
|
||||
|
||||
void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
|
||||
|
@ -20,7 +20,6 @@ static inline GrResourceCache2* get_resource_cache2(GrGpu* gpu) {
|
||||
GrGpuResource::GrGpuResource(GrGpu* gpu, LifeCycle lifeCycle)
|
||||
: fGpu(gpu)
|
||||
, fGpuMemorySize(kInvalidGpuMemorySize)
|
||||
, fFlags(0)
|
||||
, fLifeCycle(lifeCycle)
|
||||
, fUniqueID(CreateUniqueID()) {
|
||||
}
|
||||
@ -83,7 +82,7 @@ void GrGpuResource::didChangeGpuMemorySize() const {
|
||||
get_resource_cache2(fGpu)->resourceAccess().didChangeGpuMemorySize(this, oldSize);
|
||||
}
|
||||
|
||||
bool GrGpuResource::setContentKey(const GrResourceKey& contentKey) {
|
||||
bool GrGpuResource::setContentKey(const GrContentKey& key) {
|
||||
// Currently this can only be called once and can't be called when the resource is scratch.
|
||||
SkASSERT(this->internalHasRef());
|
||||
|
||||
@ -92,15 +91,14 @@ bool GrGpuResource::setContentKey(const GrResourceKey& contentKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((fFlags & kContentKeySet_Flag) || this->wasDestroyed()) {
|
||||
if (fContentKey.isValid() || this->wasDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fContentKey = contentKey;
|
||||
fFlags |= kContentKeySet_Flag;
|
||||
fContentKey = key;
|
||||
|
||||
if (!get_resource_cache2(fGpu)->resourceAccess().didSetContentKey(this)) {
|
||||
fFlags &= ~kContentKeySet_Flag;
|
||||
fContentKey.reset();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
* 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) {
|
||||
bool setContentKey(const GrContentKey& contentKey) {
|
||||
return fResource->setContentKey(contentKey);
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ public:
|
||||
* not have a content key.
|
||||
*/
|
||||
bool isScratch() const {
|
||||
return NULL == this->getContentKey() && fResource->fScratchKey.isValid();
|
||||
return !this->getContentKey().isValid() && fResource->fScratchKey.isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,12 +52,7 @@ public:
|
||||
/**
|
||||
* If the resource is currently cached by a content key, the key is returned, otherwise NULL.
|
||||
*/
|
||||
const GrResourceKey* getContentKey() const {
|
||||
if (fResource->fFlags & GrGpuResource::kContentKeySet_Flag) {
|
||||
return &fResource->fContentKey;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
const GrContentKey& getContentKey() const { return fResource->fContentKey; }
|
||||
|
||||
/**
|
||||
* Is the resource object wrapping an externally allocated GPU resource?
|
||||
|
@ -13,15 +13,11 @@ template<int NumBits> static uint64_t get_top_n_float_bits(float f) {
|
||||
return floatBits >> (32 - NumBits);
|
||||
}
|
||||
|
||||
GrResourceKey GrPath::ComputeKey(const SkPath& path, const SkStrokeRec& stroke) {
|
||||
static const GrCacheID::Domain gPathDomain = GrCacheID::GenerateDomain();
|
||||
|
||||
GrCacheID::Key key;
|
||||
uint64_t* keyData = key.fData64;
|
||||
keyData[0] = path.getGenerationID();
|
||||
keyData[1] = ComputeStrokeKey(stroke);
|
||||
|
||||
return GrResourceKey(GrCacheID(gPathDomain, key), 0);
|
||||
void GrPath::ComputeKey(const SkPath& path, const SkStrokeRec& stroke, GrContentKey* key) {
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey::Builder builder(key, kDomain, 3);
|
||||
*reinterpret_cast<uint64_t*>(&builder[0]) = ComputeStrokeKey(stroke);
|
||||
builder[2] = path.getGenerationID();
|
||||
}
|
||||
|
||||
uint64_t GrPath::ComputeStrokeKey(const SkStrokeRec& stroke) {
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
fBounds(skPath.getBounds()) {
|
||||
}
|
||||
|
||||
static GrResourceKey ComputeKey(const SkPath& path, const SkStrokeRec& stroke);
|
||||
static void ComputeKey(const SkPath& path, const SkStrokeRec& stroke, GrContentKey* key);
|
||||
static uint64_t ComputeStrokeKey(const SkStrokeRec&);
|
||||
|
||||
bool isEqualTo(const SkPath& path, const SkStrokeRec& stroke) {
|
||||
|
@ -19,7 +19,7 @@ DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrScratchKey::ResourceType GrScratchKey::GenerateResourceType() {
|
||||
static int32_t gType = kInvalidResourceType + 1;
|
||||
static int32_t gType = INHERITED::kInvalidDomain + 1;
|
||||
|
||||
int32_t type = sk_atomic_inc(&gType);
|
||||
if (type > SK_MaxU16) {
|
||||
@ -29,15 +29,18 @@ GrScratchKey::ResourceType GrScratchKey::GenerateResourceType() {
|
||||
return static_cast<ResourceType>(type);
|
||||
}
|
||||
|
||||
GrContentKey::Domain GrContentKey::GenerateDomain() {
|
||||
static int32_t gDomain = INHERITED::kInvalidDomain + 1;
|
||||
|
||||
void GrScratchKey::Builder::finish() {
|
||||
if (NULL == fKey) {
|
||||
return;
|
||||
int32_t domain = sk_atomic_inc(&gDomain);
|
||||
if (kInvalidDomain == gDomain) {
|
||||
SkFAIL("Too many Content Key Domains");
|
||||
}
|
||||
GR_STATIC_ASSERT(0 == kHash_MetaDataIdx);
|
||||
fKey->fKey[kHash_MetaDataIdx] =
|
||||
SkChecksum::Compute(&fKey->fKey[kHash_MetaDataIdx + 1], fKey->size() - sizeof(uint32_t));
|
||||
fKey = NULL;
|
||||
|
||||
return static_cast<Domain>(domain);
|
||||
}
|
||||
uint32_t GrResourceKeyHash(const uint32_t* data, size_t size) {
|
||||
return SkChecksum::Compute(data, size);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -129,8 +132,8 @@ void GrResourceCache2::removeResource(GrGpuResource* resource) {
|
||||
if (resource->cacheAccess().getScratchKey().isValid()) {
|
||||
fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource);
|
||||
}
|
||||
if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey()) {
|
||||
fContentHash.remove(*contentKey);
|
||||
if (resource->cacheAccess().getContentKey().isValid()) {
|
||||
fContentHash.remove(resource->cacheAccess().getContentKey());
|
||||
}
|
||||
this->validate();
|
||||
}
|
||||
@ -222,9 +225,9 @@ bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) {
|
||||
SkASSERT(!fPurging);
|
||||
SkASSERT(resource);
|
||||
SkASSERT(this->isInCache(resource));
|
||||
SkASSERT(resource->cacheAccess().getContentKey());
|
||||
SkASSERT(resource->cacheAccess().getContentKey().isValid());
|
||||
|
||||
GrGpuResource* res = fContentHash.find(*resource->cacheAccess().getContentKey());
|
||||
GrGpuResource* res = fContentHash.find(resource->cacheAccess().getContentKey());
|
||||
if (NULL != res) {
|
||||
return false;
|
||||
}
|
||||
@ -258,8 +261,8 @@ void GrResourceCache2::notifyPurgable(GrGpuResource* resource) {
|
||||
bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes;
|
||||
|
||||
// Also purge if the resource has neither a valid scratch key nor a content key.
|
||||
bool noKey = !resource->cacheAccess().isScratch() &&
|
||||
(NULL == resource->cacheAccess().getContentKey());
|
||||
bool noKey = !resource->cacheAccess().getScratchKey().isValid() &&
|
||||
!resource->cacheAccess().getContentKey().isValid();
|
||||
|
||||
// Only cached resources should ever have a key.
|
||||
SkASSERT(noKey || resource->cacheAccess().isBudgeted());
|
||||
@ -406,20 +409,20 @@ void GrResourceCache2::validate() const {
|
||||
}
|
||||
|
||||
if (resource->cacheAccess().isScratch()) {
|
||||
SkASSERT(NULL == resource->cacheAccess().getContentKey());
|
||||
SkASSERT(!resource->cacheAccess().getContentKey().isValid());
|
||||
++scratch;
|
||||
SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey()));
|
||||
SkASSERT(!resource->cacheAccess().isWrapped());
|
||||
} else if (resource->cacheAccess().getScratchKey().isValid()) {
|
||||
SkASSERT(NULL != resource->cacheAccess().getContentKey());
|
||||
SkASSERT(resource->cacheAccess().getContentKey().isValid());
|
||||
++couldBeScratch;
|
||||
SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey()));
|
||||
SkASSERT(!resource->cacheAccess().isWrapped());
|
||||
}
|
||||
|
||||
if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey()) {
|
||||
const GrContentKey& contentKey = resource->cacheAccess().getContentKey();
|
||||
if (contentKey.isValid()) {
|
||||
++content;
|
||||
SkASSERT(fContentHash.find(*contentKey) == resource);
|
||||
SkASSERT(fContentHash.find(contentKey) == resource);
|
||||
SkASSERT(!resource->cacheAccess().isWrapped());
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
/**
|
||||
* Find a resource that matches a content key.
|
||||
*/
|
||||
GrGpuResource* findAndRefContentResource(const GrResourceKey& contentKey) {
|
||||
GrGpuResource* findAndRefContentResource(const GrContentKey& contentKey) {
|
||||
GrGpuResource* resource = fContentHash.find(contentKey);
|
||||
if (resource) {
|
||||
resource->ref();
|
||||
@ -122,7 +122,7 @@ public:
|
||||
/**
|
||||
* Query whether a content key exists in the cache.
|
||||
*/
|
||||
bool hasContentKey(const GrResourceKey& contentKey) const {
|
||||
bool hasContentKey(const GrContentKey& contentKey) const {
|
||||
return SkToBool(fContentHash.find(contentKey));
|
||||
}
|
||||
|
||||
@ -193,13 +193,13 @@ private:
|
||||
typedef SkTMultiMap<GrGpuResource, GrScratchKey, ScratchMapTraits> ScratchMap;
|
||||
|
||||
struct ContentHashTraits {
|
||||
static const GrResourceKey& GetKey(const GrGpuResource& r) {
|
||||
return *r.cacheAccess().getContentKey();
|
||||
static const GrContentKey& GetKey(const GrGpuResource& r) {
|
||||
return r.cacheAccess().getContentKey();
|
||||
}
|
||||
|
||||
static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); }
|
||||
static uint32_t Hash(const GrContentKey& key) { return key.hash(); }
|
||||
};
|
||||
typedef SkTDynamicHash<GrGpuResource, GrResourceKey, ContentHashTraits> ContentHash;
|
||||
typedef SkTDynamicHash<GrGpuResource, GrContentKey, ContentHashTraits> ContentHash;
|
||||
|
||||
typedef SkTInternalLList<GrGpuResource> ResourceList;
|
||||
|
||||
|
@ -72,11 +72,12 @@ GrStencilAndCoverPathRenderer::onGetStencilSupport(const GrDrawTarget*,
|
||||
|
||||
static GrPath* get_gr_path(GrGpu* gpu, const SkPath& skPath, const SkStrokeRec& stroke) {
|
||||
GrContext* ctx = gpu->getContext();
|
||||
GrResourceKey resourceKey = GrPath::ComputeKey(skPath, stroke);
|
||||
SkAutoTUnref<GrPath> path(static_cast<GrPath*>(ctx->findAndRefCachedResource(resourceKey)));
|
||||
GrContentKey key;
|
||||
GrPath::ComputeKey(skPath, stroke, &key);
|
||||
SkAutoTUnref<GrPath> path(static_cast<GrPath*>(ctx->findAndRefCachedResource(key)));
|
||||
if (NULL == path || !path->isEqualTo(skPath, stroke)) {
|
||||
path.reset(gpu->pathRendering()->createPath(skPath, stroke));
|
||||
ctx->addResourceToCache(resourceKey, path);
|
||||
ctx->addResourceToCache(key, path);
|
||||
}
|
||||
return path.detach();
|
||||
}
|
||||
|
@ -205,20 +205,25 @@ static GrPathRange* get_gr_glyphs(GrContext* ctx,
|
||||
const SkTypeface* typeface,
|
||||
const SkDescriptor* desc,
|
||||
const SkStrokeRec& stroke) {
|
||||
static const GrCacheID::Domain gGlyphsDomain = GrCacheID::GenerateDomain();
|
||||
|
||||
GrCacheID::Key key;
|
||||
uint64_t* keyData = key.fData64;
|
||||
keyData[0] = desc ? desc->getChecksum() : 0;
|
||||
keyData[0] = (keyData[0] << 32) | (typeface ? typeface->uniqueID() : 0);
|
||||
keyData[1] = GrPath::ComputeStrokeKey(stroke);
|
||||
GrResourceKey resourceKey = GrResourceKey(GrCacheID(gGlyphsDomain, key), 0);
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey key;
|
||||
GrContentKey::Builder builder(&key, kDomain, 4);
|
||||
struct GlyphKey {
|
||||
uint32_t fChecksum;
|
||||
uint32_t fTypeface;
|
||||
uint64_t fStroke;
|
||||
};
|
||||
GlyphKey* glyphKey = reinterpret_cast<GlyphKey*>(&builder[0]);
|
||||
glyphKey->fChecksum = desc ? desc->getChecksum() : 0;
|
||||
glyphKey->fTypeface = typeface ? typeface->uniqueID() : 0;
|
||||
glyphKey->fStroke = GrPath::ComputeStrokeKey(stroke);
|
||||
builder.finish();
|
||||
|
||||
SkAutoTUnref<GrPathRange> glyphs(
|
||||
static_cast<GrPathRange*>(ctx->findAndRefCachedResource(resourceKey)));
|
||||
static_cast<GrPathRange*>(ctx->findAndRefCachedResource(key)));
|
||||
if (NULL == glyphs || (NULL != desc && !glyphs->isEqualTo(*desc))) {
|
||||
glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc, stroke));
|
||||
ctx->addResourceToCache(resourceKey, glyphs);
|
||||
ctx->addResourceToCache(key, glyphs);
|
||||
}
|
||||
|
||||
return glyphs.detach();
|
||||
|
@ -66,42 +66,7 @@ void GrTexture::validateDesc() const {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// These flags need to fit in a GrResourceKey::ResourceFlags so they can be folded into the texture
|
||||
// key
|
||||
enum TextureFlags {
|
||||
/**
|
||||
* The kStretchToPOT bit is set when the texture is NPOT and is being repeated but the
|
||||
* hardware doesn't support that feature.
|
||||
*/
|
||||
kStretchToPOT_TextureFlag = 0x1,
|
||||
/**
|
||||
* The kBilerp bit can only be set when the kStretchToPOT flag is set and indicates whether the
|
||||
* stretched texture should be bilerped.
|
||||
*/
|
||||
kBilerp_TextureFlag = 0x2,
|
||||
};
|
||||
|
||||
namespace {
|
||||
GrResourceKey::ResourceFlags get_texture_flags(const GrGpu* gpu,
|
||||
const GrTextureParams* params,
|
||||
const GrSurfaceDesc& desc) {
|
||||
GrResourceKey::ResourceFlags flags = 0;
|
||||
bool tiled = params && params->isTiled();
|
||||
if (tiled && !gpu->caps()->npotTextureTileSupport()) {
|
||||
if (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight)) {
|
||||
flags |= kStretchToPOT_TextureFlag;
|
||||
switch(params->filterMode()) {
|
||||
case GrTextureParams::kNone_FilterMode:
|
||||
break;
|
||||
case GrTextureParams::kBilerp_FilterMode:
|
||||
case GrTextureParams::kMipMap_FilterMode:
|
||||
flags |= kBilerp_TextureFlag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
// FIXME: This should be refactored with the code in gl/GrGLGpu.cpp.
|
||||
GrSurfaceOrigin resolve_origin(const GrSurfaceDesc& desc) {
|
||||
@ -132,14 +97,6 @@ GrTexture::GrTexture(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc)
|
||||
fShiftFixedY = 31 - SkCLZ(fDesc.fHeight);
|
||||
}
|
||||
|
||||
GrResourceKey GrTexturePriv::ComputeKey(const GrGpu* gpu,
|
||||
const GrTextureParams* params,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID) {
|
||||
GrResourceKey::ResourceFlags flags = get_texture_flags(gpu, params, desc);
|
||||
return GrResourceKey(cacheID, flags);
|
||||
}
|
||||
|
||||
void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrScratchKey* key) {
|
||||
static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();
|
||||
|
||||
@ -158,11 +115,3 @@ void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrScratchKey* k
|
||||
builder[0] = desc.fWidth | (desc.fHeight << 16);
|
||||
builder[1] = desc.fConfig | (desc.fSampleCnt << 6) | (flags << 14) | (origin << 24);
|
||||
}
|
||||
|
||||
bool GrTexturePriv::NeedsResizing(const GrResourceKey& key) {
|
||||
return SkToBool(key.getResourceFlags() & kStretchToPOT_TextureFlag);
|
||||
}
|
||||
|
||||
bool GrTexturePriv::NeedsBilerp(const GrResourceKey& key) {
|
||||
return SkToBool(key.getResourceFlags() & kBilerp_TextureFlag);
|
||||
}
|
||||
|
@ -39,14 +39,7 @@ public:
|
||||
return GrTexture::kNotAllocated_MipMapsStatus != fTexture->fMipMapsStatus;
|
||||
}
|
||||
|
||||
static GrResourceKey ComputeKey(const GrGpu* gpu,
|
||||
const GrTextureParams* params,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrCacheID& cacheID);
|
||||
static void ComputeScratchKey(const GrSurfaceDesc&, GrScratchKey*);
|
||||
static bool NeedsResizing(const GrResourceKey& key);
|
||||
static bool NeedsBilerp(const GrResourceKey& key);
|
||||
|
||||
|
||||
// TODO: Move this logic and the shift values out of here and to the callers.
|
||||
SkFixed normalizeFixedX(SkFixed x) const {
|
||||
|
@ -86,25 +86,20 @@ static void build_index8_data(void* buffer, const SkBitmap& bitmap) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void generate_bitmap_cache_id(const SkBitmap& bitmap, GrCacheID* id) {
|
||||
static void generate_bitmap_key(const SkBitmap& bitmap, GrContentKey* key) {
|
||||
// Our id includes the offset, width, and height so that bitmaps created by extractSubset()
|
||||
// are unique.
|
||||
uint32_t genID = bitmap.getGenerationID();
|
||||
SkIPoint origin = bitmap.pixelRefOrigin();
|
||||
int16_t width = SkToS16(bitmap.width());
|
||||
int16_t height = SkToS16(bitmap.height());
|
||||
uint32_t width = SkToU16(bitmap.width());
|
||||
uint32_t height = SkToU16(bitmap.height());
|
||||
|
||||
GrCacheID::Key key;
|
||||
memcpy(key.fData8 + 0, &genID, 4);
|
||||
memcpy(key.fData8 + 4, &origin.fX, 4);
|
||||
memcpy(key.fData8 + 8, &origin.fY, 4);
|
||||
memcpy(key.fData8 + 12, &width, 2);
|
||||
memcpy(key.fData8 + 14, &height, 2);
|
||||
static const size_t kKeyDataSize = 16;
|
||||
memset(key.fData8 + kKeyDataSize, 0, sizeof(key) - kKeyDataSize);
|
||||
GR_STATIC_ASSERT(sizeof(key) >= kKeyDataSize);
|
||||
static const GrCacheID::Domain gBitmapTextureDomain = GrCacheID::GenerateDomain();
|
||||
id->reset(gBitmapTextureDomain, key);
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey::Builder builder(key, kDomain, 4);
|
||||
builder[0] = genID;
|
||||
builder[1] = origin.fX;
|
||||
builder[2] = origin.fY;
|
||||
builder[3] = width | (height << 16);
|
||||
}
|
||||
|
||||
static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) {
|
||||
@ -120,9 +115,9 @@ namespace {
|
||||
// When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key.
|
||||
class GrResourceInvalidator : public SkPixelRef::GenIDChangeListener {
|
||||
public:
|
||||
explicit GrResourceInvalidator(GrResourceKey key) : fKey(key) {}
|
||||
explicit GrResourceInvalidator(const GrContentKey& key) : fKey(key) {}
|
||||
private:
|
||||
GrResourceKey fKey;
|
||||
GrContentKey fKey;
|
||||
|
||||
void onChange() SK_OVERRIDE {
|
||||
const GrResourceInvalidatedMessage message = { fKey };
|
||||
@ -132,7 +127,7 @@ private:
|
||||
|
||||
} // namespace
|
||||
|
||||
static void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) {
|
||||
static void add_genID_listener(const GrContentKey& key, SkPixelRef* pixelRef) {
|
||||
SkASSERT(pixelRef);
|
||||
pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key)));
|
||||
}
|
||||
@ -147,11 +142,10 @@ static GrTexture* sk_gr_allocate_texture(GrContext* ctx,
|
||||
GrTexture* result;
|
||||
if (cache) {
|
||||
// This texture is likely to be used again so leave it in the cache
|
||||
GrCacheID cacheID;
|
||||
generate_bitmap_cache_id(bm, &cacheID);
|
||||
GrContentKey key;
|
||||
generate_bitmap_key(bm, &key);
|
||||
|
||||
GrResourceKey key;
|
||||
result = ctx->createTexture(params, desc, cacheID, pixels, rowBytes, &key);
|
||||
result = ctx->createTexture(params, desc, key, pixels, rowBytes, &key);
|
||||
if (result) {
|
||||
add_genID_listener(key, bm.pixelRef());
|
||||
}
|
||||
@ -399,12 +393,12 @@ bool GrIsBitmapInCache(const GrContext* ctx,
|
||||
return true;
|
||||
}
|
||||
|
||||
GrCacheID cacheID;
|
||||
generate_bitmap_cache_id(bitmap, &cacheID);
|
||||
GrContentKey key;
|
||||
generate_bitmap_key(bitmap, &key);
|
||||
|
||||
GrSurfaceDesc desc;
|
||||
generate_bitmap_texture_desc(bitmap, &desc);
|
||||
return ctx->isTextureInCache(desc, cacheID, params);
|
||||
return ctx->isTextureInCache(desc, key, params);
|
||||
}
|
||||
|
||||
GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
|
||||
@ -420,13 +414,13 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
|
||||
if (cache) {
|
||||
// If the bitmap isn't changing try to find a cached copy first.
|
||||
|
||||
GrCacheID cacheID;
|
||||
generate_bitmap_cache_id(bitmap, &cacheID);
|
||||
GrContentKey key;
|
||||
generate_bitmap_key(bitmap, &key);
|
||||
|
||||
GrSurfaceDesc desc;
|
||||
generate_bitmap_texture_desc(bitmap, &desc);
|
||||
|
||||
result = ctx->findAndRefTexture(desc, cacheID, params);
|
||||
result = ctx->findAndRefTexture(desc, key, params);
|
||||
}
|
||||
if (NULL == result) {
|
||||
result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap);
|
||||
|
@ -196,15 +196,15 @@ void GrTextureStripAtlas::lockTexture() {
|
||||
texDesc.fHeight = fDesc.fHeight;
|
||||
texDesc.fConfig = fDesc.fConfig;
|
||||
|
||||
static const GrCacheID::Domain gTextureStripAtlasDomain = GrCacheID::GenerateDomain();
|
||||
GrCacheID::Key key;
|
||||
*key.fData32 = fCacheKey;
|
||||
memset(key.fData32 + 1, 0, sizeof(key) - sizeof(uint32_t));
|
||||
GrCacheID cacheID(gTextureStripAtlasDomain, key);
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey key;
|
||||
GrContentKey::Builder builder(&key, kDomain, 1);
|
||||
builder[0] = static_cast<uint32_t>(fCacheKey);
|
||||
builder.finish();
|
||||
|
||||
fTexture = fDesc.fContext->findAndRefTexture(texDesc, cacheID, ¶ms);
|
||||
fTexture = fDesc.fContext->findAndRefTexture(texDesc, key, ¶ms);
|
||||
if (NULL == fTexture) {
|
||||
fTexture = fDesc.fContext->createTexture(¶ms, texDesc, cacheID, NULL, 0);
|
||||
fTexture = fDesc.fContext->createTexture(¶ms, texDesc, key, NULL, 0);
|
||||
// This is a new texture, so all of our cache info is now invalid
|
||||
this->initLRU();
|
||||
fKeyTable.rewind();
|
||||
|
@ -98,9 +98,7 @@ GrFragmentProcessor* BigKeyProcessor::TestCreate(SkRandom*,
|
||||
static const int kRenderTargetHeight = 1;
|
||||
static const int kRenderTargetWidth = 1;
|
||||
|
||||
static GrRenderTarget* random_render_target(GrContext* context,
|
||||
const GrCacheID& cacheId,
|
||||
SkRandom* random) {
|
||||
static GrRenderTarget* random_render_target(GrContext* context, SkRandom* random) {
|
||||
// setup render target
|
||||
GrTextureParams params;
|
||||
GrSurfaceDesc texDesc;
|
||||
@ -110,10 +108,15 @@ static GrRenderTarget* random_render_target(GrContext* context,
|
||||
texDesc.fConfig = kRGBA_8888_GrPixelConfig;
|
||||
texDesc.fOrigin = random->nextBool() == true ? kTopLeft_GrSurfaceOrigin :
|
||||
kBottomLeft_GrSurfaceOrigin;
|
||||
GrContentKey key;
|
||||
static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
|
||||
GrContentKey::Builder builder(&key, kDomain, 1);
|
||||
builder[0] = texDesc.fOrigin;
|
||||
builder.finish();
|
||||
|
||||
SkAutoTUnref<GrTexture> texture(context->findAndRefTexture(texDesc, cacheId, ¶ms));
|
||||
SkAutoTUnref<GrTexture> texture(context->findAndRefTexture(texDesc, key, ¶ms));
|
||||
if (!texture) {
|
||||
texture.reset(context->createTexture(¶ms, texDesc, cacheId, 0, 0));
|
||||
texture.reset(context->createTexture(¶ms, texDesc, key, 0, 0));
|
||||
if (!texture) {
|
||||
return NULL;
|
||||
}
|
||||
@ -237,14 +240,6 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
|
||||
// dummy scissor state
|
||||
GrScissorState scissor;
|
||||
|
||||
// Setup texture cache id key
|
||||
const GrCacheID::Domain glProgramsDomain = GrCacheID::GenerateDomain();
|
||||
GrCacheID::Key key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.fData32[0] = kRenderTargetWidth;
|
||||
key.fData32[1] = kRenderTargetHeight;
|
||||
GrCacheID glProgramsCacheID(glProgramsDomain, key);
|
||||
|
||||
// setup clip
|
||||
SkRect screen = SkRect::MakeWH(SkIntToScalar(kRenderTargetWidth),
|
||||
SkIntToScalar(kRenderTargetHeight));
|
||||
@ -261,7 +256,7 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
|
||||
static const int NUM_TESTS = 512;
|
||||
for (int t = 0; t < NUM_TESTS;) {
|
||||
// setup random render target(can fail)
|
||||
SkAutoTUnref<GrRenderTarget> rt(random_render_target(fContext, glProgramsCacheID, &random));
|
||||
SkAutoTUnref<GrRenderTarget> rt(random_render_target(fContext, &random));
|
||||
if (!rt.get()) {
|
||||
SkDebugf("Could not allocate render target");
|
||||
return false;
|
||||
|
@ -120,8 +120,8 @@ public:
|
||||
static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) {
|
||||
static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType();
|
||||
GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt);
|
||||
for (size_t i = 0; i < kScratchKeyFieldCnt; ++i) {
|
||||
builder[i] = i + static_cast<int>(property);
|
||||
for (int i = 0; i < kScratchKeyFieldCnt; ++i) {
|
||||
builder[i] = static_cast<uint32_t>(i + property);
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t kScratchKeyFieldCnt = 6;
|
||||
static const int kScratchKeyFieldCnt = 6;
|
||||
|
||||
TestResource(GrGpu* gpu, SimulatedProperty property, ScratchConstructor)
|
||||
: INHERITED(gpu, kCached_LifeCycle)
|
||||
@ -209,6 +209,13 @@ static void test_no_key(skiatest::Reporter* reporter) {
|
||||
REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
|
||||
}
|
||||
|
||||
// Each integer passed as a template param creates a new domain.
|
||||
template <int> static void make_content_key(GrContentKey* key, int data) {
|
||||
static GrContentKey::Domain d = GrContentKey::GenerateDomain();
|
||||
GrContentKey::Builder builder(key, d, 1);
|
||||
builder[0] = data;
|
||||
}
|
||||
|
||||
static void test_budgeting(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
@ -221,9 +228,8 @@ static void test_budgeting(skiatest::Reporter* reporter) {
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
SkASSERT(0 == cache2->getBudgetedResourceCount() && 0 == cache2->getBudgetedResourceBytes());
|
||||
|
||||
GrCacheID::Key keyData;
|
||||
memset(&keyData, 0, sizeof(keyData));
|
||||
GrResourceKey contentKey(GrCacheID(GrCacheID::GenerateDomain(), keyData), 0);
|
||||
GrContentKey contentKey;
|
||||
make_content_key<0>(&contentKey, 0);
|
||||
|
||||
// Create a scratch, a content, and a wrapped resource
|
||||
TestResource* scratch =
|
||||
@ -241,8 +247,8 @@ static void test_budgeting(skiatest::Reporter* reporter) {
|
||||
unbudgeted->setSize(13);
|
||||
|
||||
// Make sure we can't add a content key to the wrapped resource
|
||||
keyData.fData8[0] = 1;
|
||||
GrResourceKey contentKey2(GrCacheID(GrCacheID::GenerateDomain(), keyData), 0);
|
||||
GrContentKey contentKey2;
|
||||
make_content_key<0>(&contentKey2, 1);
|
||||
REPORTER_ASSERT(reporter, !wrapped->cacheAccess().setContentKey(contentKey2));
|
||||
REPORTER_ASSERT(reporter, NULL == cache2->findAndRefContentResource(contentKey2));
|
||||
|
||||
@ -315,9 +321,8 @@ static void test_unbudgeted(skiatest::Reporter* reporter) {
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
SkASSERT(0 == cache2->getBudgetedResourceCount() && 0 == cache2->getBudgetedResourceBytes());
|
||||
|
||||
GrCacheID::Key keyData;
|
||||
memset(&keyData, 0, sizeof(keyData));
|
||||
GrResourceKey contentKey(GrCacheID(GrCacheID::GenerateDomain(), keyData), 0);
|
||||
GrContentKey contentKey;
|
||||
make_content_key<0>(&contentKey, 0);
|
||||
|
||||
TestResource* scratch;
|
||||
TestResource* content;
|
||||
@ -576,10 +581,8 @@ static void test_duplicate_content_key(skiatest::Reporter* reporter) {
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
|
||||
GrCacheID::Domain domain = GrCacheID::GenerateDomain();
|
||||
GrCacheID::Key keyData;
|
||||
memset(&keyData, 0, sizeof(keyData));
|
||||
GrResourceKey key(GrCacheID(domain, keyData), 0);
|
||||
GrContentKey key;
|
||||
make_content_key<0>(&key, 0);
|
||||
|
||||
// Create two resources that we will attempt to register with the same content key.
|
||||
TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
@ -627,16 +630,10 @@ static void test_purge_invalidated(skiatest::Reporter* reporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrCacheID::Domain domain = GrCacheID::GenerateDomain();
|
||||
GrCacheID::Key keyData;
|
||||
memset(&keyData, 0, sizeof(keyData));
|
||||
|
||||
keyData.fData64[0] = 1;
|
||||
GrResourceKey key1(GrCacheID(domain, keyData), 0);
|
||||
keyData.fData64[0] = 2;
|
||||
GrResourceKey key2(GrCacheID(domain, keyData), 0);
|
||||
keyData.fData64[0] = 3;
|
||||
GrResourceKey key3(GrCacheID(domain, keyData), 0);
|
||||
GrContentKey key1, key2, key3;
|
||||
make_content_key<0>(&key1, 1);
|
||||
make_content_key<0>(&key2, 2);
|
||||
make_content_key<0>(&key3, 3);
|
||||
|
||||
context->setResourceCacheLimits(5, 30000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
@ -694,15 +691,9 @@ static void test_cache_chained_purge(skiatest::Reporter* reporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrCacheID::Domain domain = GrCacheID::GenerateDomain();
|
||||
GrCacheID::Key keyData;
|
||||
memset(&keyData, 0, sizeof(keyData));
|
||||
|
||||
keyData.fData64[0] = 1;
|
||||
GrResourceKey key1(GrCacheID(domain, keyData), 0);
|
||||
|
||||
keyData.fData64[0] = 2;
|
||||
GrResourceKey key2(GrCacheID(domain, keyData), 0);
|
||||
GrContentKey key1, key2;
|
||||
make_content_key<0>(&key1, 1);
|
||||
make_content_key<0>(&key2, 2);
|
||||
|
||||
{
|
||||
context->setResourceCacheLimits(3, 30000);
|
||||
@ -745,17 +736,9 @@ static void test_resource_size_changed(skiatest::Reporter* reporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrCacheID::Domain domain = GrCacheID::GenerateDomain();
|
||||
|
||||
GrCacheID::Key key1Data;
|
||||
key1Data.fData64[0] = 0;
|
||||
key1Data.fData64[1] = 0;
|
||||
GrResourceKey key1(GrCacheID(domain, key1Data), 0);
|
||||
|
||||
GrCacheID::Key key2Data;
|
||||
key2Data.fData64[0] = 1;
|
||||
key2Data.fData64[1] = 0;
|
||||
GrResourceKey key2(GrCacheID(domain, key2Data), 0);
|
||||
GrContentKey key1, key2;
|
||||
make_content_key<0>(&key1, 1);
|
||||
make_content_key<0>(&key2, 2);
|
||||
|
||||
// Test changing resources sizes (both increase & decrease).
|
||||
{
|
||||
@ -832,25 +815,21 @@ static void test_large_resource_count(skiatest::Reporter* reporter) {
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
|
||||
GrCacheID::Domain domain0 = GrCacheID::GenerateDomain();
|
||||
GrCacheID::Domain domain1 = GrCacheID::GenerateDomain();
|
||||
|
||||
GrCacheID::Key keyData;
|
||||
memset(&keyData, 0, sizeof(keyData));
|
||||
|
||||
for (int i = 0; i < kResourceCnt; ++i) {
|
||||
TestResource* resource;
|
||||
keyData.fData32[0] = i;
|
||||
GrContentKey key1, key2;
|
||||
make_content_key<1>(&key1, i);
|
||||
make_content_key<2>(&key2, i);
|
||||
|
||||
TestResource* resource;
|
||||
|
||||
GrResourceKey key0(GrCacheID(domain0, keyData), 0);
|
||||
resource = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
resource->cacheAccess().setContentKey(key0);
|
||||
resource->cacheAccess().setContentKey(key1);
|
||||
resource->setSize(1);
|
||||
resource->unref();
|
||||
|
||||
GrResourceKey key1(GrCacheID(domain1, keyData), 0);
|
||||
resource = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
resource->cacheAccess().setContentKey(key1);
|
||||
resource->cacheAccess().setContentKey(key2);
|
||||
resource->setSize(1);
|
||||
resource->unref();
|
||||
}
|
||||
@ -861,11 +840,12 @@ static void test_large_resource_count(skiatest::Reporter* reporter) {
|
||||
REPORTER_ASSERT(reporter, cache2->getResourceBytes() == 2 * kResourceCnt);
|
||||
REPORTER_ASSERT(reporter, cache2->getResourceCount() == 2 * kResourceCnt);
|
||||
for (int i = 0; i < kResourceCnt; ++i) {
|
||||
keyData.fData32[0] = i;
|
||||
GrResourceKey key0(GrCacheID(domain0, keyData), 0);
|
||||
REPORTER_ASSERT(reporter, cache2->hasContentKey(key0));
|
||||
GrResourceKey key1(GrCacheID(domain0, keyData), 0);
|
||||
GrContentKey key1, key2;
|
||||
make_content_key<1>(&key1, i);
|
||||
make_content_key<2>(&key2, i);
|
||||
|
||||
REPORTER_ASSERT(reporter, cache2->hasContentKey(key1));
|
||||
REPORTER_ASSERT(reporter, cache2->hasContentKey(key2));
|
||||
}
|
||||
|
||||
cache2->purgeAllUnlocked();
|
||||
@ -876,11 +856,12 @@ static void test_large_resource_count(skiatest::Reporter* reporter) {
|
||||
REPORTER_ASSERT(reporter, cache2->getResourceCount() == 0);
|
||||
|
||||
for (int i = 0; i < kResourceCnt; ++i) {
|
||||
keyData.fData32[0] = i;
|
||||
GrResourceKey key0(GrCacheID(domain0, keyData), 0);
|
||||
REPORTER_ASSERT(reporter, !cache2->hasContentKey(key0));
|
||||
GrResourceKey key1(GrCacheID(domain0, keyData), 0);
|
||||
GrContentKey key1, key2;
|
||||
make_content_key<1>(&key1, i);
|
||||
make_content_key<2>(&key2, i);
|
||||
|
||||
REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1));
|
||||
REPORTER_ASSERT(reporter, !cache2->hasContentKey(key2));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user