Allow unbudgeted resources to be recycled by the cache as scratch.
Review URL: https://codereview.chromium.org/870743002
This commit is contained in:
parent
4dffede04a
commit
c2f35b750a
@ -263,6 +263,7 @@ private:
|
||||
void notifyIsPurgable() const;
|
||||
void removeScratchKey();
|
||||
void makeBudgeted();
|
||||
void makeUnbudgeted();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
friend class GrGpu; // for assert in GrGpu to access getGpu
|
||||
|
@ -86,8 +86,8 @@ 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());
|
||||
|
||||
// Wrapped resources can never have a key.
|
||||
if (this->isWrapped()) {
|
||||
// Wrapped and uncached resources can never have a content key.
|
||||
if (!this->cacheAccess().isBudgeted()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -138,6 +138,13 @@ void GrGpuResource::makeBudgeted() {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuResource::makeUnbudgeted() {
|
||||
if (GrGpuResource::kCached_LifeCycle == fLifeCycle && !fContentKey.isValid()) {
|
||||
fLifeCycle = kUncached_LifeCycle;
|
||||
get_resource_cache2(fGpu)->resourceAccess().didChangeBudgetStatus(this);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GrGpuResource::CreateUniqueID() {
|
||||
static int32_t gUniqueID = SK_InvalidUniqueID;
|
||||
uint32_t id;
|
||||
|
@ -29,11 +29,12 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the resource currently cached as scratch? This means it has a valid scratch key and does
|
||||
* not have a content key.
|
||||
* Is the resource currently cached as scratch? This means it is cached, has a valid scratch
|
||||
* key, and does not have a content key.
|
||||
*/
|
||||
bool isScratch() const {
|
||||
return !this->getContentKey().isValid() && fResource->fScratchKey.isValid();
|
||||
return !this->getContentKey().isValid() && fResource->fScratchKey.isValid() &&
|
||||
this->isBudgeted();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +63,11 @@ public:
|
||||
/**
|
||||
* Does the resource count against the resource budget?
|
||||
*/
|
||||
bool isBudgeted() const { return GrGpuResource::kCached_LifeCycle == fResource->fLifeCycle; }
|
||||
bool isBudgeted() const {
|
||||
bool ret = GrGpuResource::kCached_LifeCycle == fResource->fLifeCycle;
|
||||
SkASSERT(ret || !this->getContentKey().isValid());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the resource is uncached make it cached. Has no effect on resources that are wrapped or
|
||||
@ -70,6 +75,12 @@ public:
|
||||
*/
|
||||
void makeBudgeted() { fResource->makeBudgeted(); }
|
||||
|
||||
/**
|
||||
* If the resource is cached make it uncached. Has no effect on resources that are wrapped or
|
||||
* already uncached. Furthermore, resources with content keys cannot be made unbudgeted.
|
||||
*/
|
||||
void makeUnbudgeted() { fResource->makeUnbudgeted(); }
|
||||
|
||||
/**
|
||||
* Called by the cache to delete the resource under normal circumstances.
|
||||
*/
|
||||
|
@ -257,23 +257,42 @@ void GrResourceCache2::notifyPurgable(GrGpuResource* resource) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Purge the resource if we're over budget
|
||||
bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes;
|
||||
bool release = false;
|
||||
|
||||
// Also purge if the resource has neither a valid scratch key nor a content key.
|
||||
bool noKey = !resource->cacheAccess().getScratchKey().isValid() &&
|
||||
!resource->cacheAccess().getContentKey().isValid();
|
||||
if (resource->cacheAccess().isWrapped()) {
|
||||
release = true;
|
||||
} else if (!resource->cacheAccess().isBudgeted()) {
|
||||
// Check whether this resource could still be used as a scratch resource.
|
||||
if (resource->cacheAccess().getScratchKey().isValid()) {
|
||||
// We won't purge an existing resource to make room for this one.
|
||||
bool underBudget = fBudgetedCount < fMaxCount &&
|
||||
fBudgetedBytes + resource->gpuMemorySize() <= fMaxBytes;
|
||||
if (underBudget) {
|
||||
resource->cacheAccess().makeBudgeted();
|
||||
} else {
|
||||
release = true;
|
||||
}
|
||||
} else {
|
||||
release = true;
|
||||
}
|
||||
} else {
|
||||
// Purge the resource if we're over budget
|
||||
bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes;
|
||||
|
||||
// Only cached resources should ever have a key.
|
||||
SkASSERT(noKey || resource->cacheAccess().isBudgeted());
|
||||
// Also purge if the resource has neither a valid scratch key nor a content key.
|
||||
bool noKey = !resource->cacheAccess().getScratchKey().isValid() &&
|
||||
!resource->cacheAccess().getContentKey().isValid();
|
||||
if (overBudget || noKey) {
|
||||
release = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (overBudget || noKey) {
|
||||
if (release) {
|
||||
SkDEBUGCODE(int beforeCount = fCount;)
|
||||
resource->cacheAccess().release();
|
||||
// We should at least free this resource, perhaps dependent resources as well.
|
||||
SkASSERT(fCount < beforeCount);
|
||||
}
|
||||
|
||||
this->validate();
|
||||
}
|
||||
|
||||
@ -389,6 +408,13 @@ void GrResourceCache2::purgeAllUnlocked() {
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void GrResourceCache2::validate() const {
|
||||
// Reduce the frequency of validations for large resource counts.
|
||||
static SkRandom gRandom;
|
||||
int mask = (SkNextPow2(fCount + 1) >> 5) - 1;
|
||||
if (~mask && (gRandom.nextU() & mask)) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t bytes = 0;
|
||||
int count = 0;
|
||||
int budgetedCount = 0;
|
||||
@ -414,7 +440,8 @@ void GrResourceCache2::validate() const {
|
||||
SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey()));
|
||||
SkASSERT(!resource->cacheAccess().isWrapped());
|
||||
} else if (resource->cacheAccess().getScratchKey().isValid()) {
|
||||
SkASSERT(resource->cacheAccess().getContentKey().isValid());
|
||||
SkASSERT(!resource->cacheAccess().isBudgeted() ||
|
||||
resource->cacheAccess().getContentKey().isValid());
|
||||
++couldBeScratch;
|
||||
SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey()));
|
||||
SkASSERT(!resource->cacheAccess().isWrapped());
|
||||
@ -424,6 +451,7 @@ void GrResourceCache2::validate() const {
|
||||
++content;
|
||||
SkASSERT(fContentHash.find(contentKey) == resource);
|
||||
SkASSERT(!resource->cacheAccess().isWrapped());
|
||||
SkASSERT(resource->cacheAccess().isBudgeted());
|
||||
}
|
||||
|
||||
if (resource->cacheAccess().isBudgeted()) {
|
||||
|
@ -87,7 +87,7 @@ GrTexture::GrTexture(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc)
|
||||
: INHERITED(gpu, lifeCycle, desc)
|
||||
, fMipMapsStatus(kNotAllocated_MipMapsStatus) {
|
||||
|
||||
if (kCached_LifeCycle == lifeCycle) {
|
||||
if (kWrapped_LifeCycle != lifeCycle) {
|
||||
GrScratchKey key;
|
||||
GrTexturePriv::ComputeScratchKey(desc, &key);
|
||||
this->setScratchKey(key);
|
||||
|
@ -97,8 +97,10 @@ public:
|
||||
this->registerWithCache();
|
||||
}
|
||||
|
||||
static TestResource* CreateScratchTestResource(GrGpu* gpu, SimulatedProperty property) {
|
||||
return SkNEW_ARGS(TestResource, (gpu, property, kScratchConstructor));
|
||||
static TestResource* CreateScratchTestResource(GrGpu* gpu,
|
||||
SimulatedProperty property,
|
||||
bool cached = true) {
|
||||
return SkNEW_ARGS(TestResource, (gpu, property, cached, kScratchConstructor));
|
||||
}
|
||||
|
||||
~TestResource() {
|
||||
@ -132,8 +134,8 @@ public:
|
||||
private:
|
||||
static const int kScratchKeyFieldCnt = 6;
|
||||
|
||||
TestResource(GrGpu* gpu, SimulatedProperty property, ScratchConstructor)
|
||||
: INHERITED(gpu, kCached_LifeCycle)
|
||||
TestResource(GrGpu* gpu, SimulatedProperty property, bool cached, ScratchConstructor)
|
||||
: INHERITED(gpu, cached ? kCached_LifeCycle : kUncached_LifeCycle)
|
||||
, fToDelete(NULL)
|
||||
, fSize(kDefaultSize)
|
||||
, fProperty(property) {
|
||||
@ -154,16 +156,29 @@ private:
|
||||
};
|
||||
int TestResource::fNumAlive = 0;
|
||||
|
||||
static void test_no_key(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
class Mock {
|
||||
public:
|
||||
Mock(int maxCnt, size_t maxBytes) {
|
||||
fContext.reset(GrContext::CreateMockContext());
|
||||
SkASSERT(fContext);
|
||||
fContext->setResourceCacheLimits(maxCnt, maxBytes);
|
||||
GrResourceCache2* cache2 = fContext->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
}
|
||||
context->setResourceCacheLimits(10, 30000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
|
||||
GrResourceCache2* cache() { return fContext->getResourceCache2(); }
|
||||
|
||||
GrContext* context() { return fContext; }
|
||||
|
||||
private:
|
||||
SkAutoTUnref<GrContext> fContext;
|
||||
};
|
||||
|
||||
static void test_no_key(skiatest::Reporter* reporter) {
|
||||
Mock mock(10, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
// Create a bunch of resources with no keys
|
||||
TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
@ -217,16 +232,9 @@ template <int> static void make_content_key(GrContentKey* key, int data) {
|
||||
}
|
||||
|
||||
static void test_budgeting(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
context->setResourceCacheLimits(10, 300);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
SkASSERT(0 == cache2->getBudgetedResourceCount() && 0 == cache2->getBudgetedResourceBytes());
|
||||
Mock mock(10, 300);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
GrContentKey contentKey;
|
||||
make_content_key<0>(&contentKey, 0);
|
||||
@ -310,16 +318,9 @@ static void test_budgeting(skiatest::Reporter* reporter) {
|
||||
}
|
||||
|
||||
static void test_unbudgeted(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
context->setResourceCacheLimits(10, 300);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
SkASSERT(0 == cache2->getBudgetedResourceCount() && 0 == cache2->getBudgetedResourceBytes());
|
||||
Mock mock(10, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
GrContentKey contentKey;
|
||||
make_content_key<0>(&contentKey, 0);
|
||||
@ -382,16 +383,70 @@ static void test_unbudgeted(skiatest::Reporter* reporter) {
|
||||
REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
|
||||
}
|
||||
|
||||
static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
static void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) {
|
||||
Mock mock(10, 300);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
TestResource* resource =
|
||||
TestResource::CreateScratchTestResource(context->getGpu(),
|
||||
TestResource::kProperty1_SimulatedProperty, false);
|
||||
GrScratchKey key;
|
||||
TestResource::ComputeScratchKey(TestResource::kProperty1_SimulatedProperty, &key);
|
||||
|
||||
size_t size = resource->gpuMemorySize();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
// Since this resource is unbudgeted, it should not be reachable as scratch.
|
||||
REPORTER_ASSERT(reporter, resource->cacheAccess().getScratchKey() == key);
|
||||
REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
|
||||
REPORTER_ASSERT(reporter, !resource->cacheAccess().isBudgeted());
|
||||
REPORTER_ASSERT(reporter, NULL == cache2->findAndRefScratchResource(key));
|
||||
REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
|
||||
REPORTER_ASSERT(reporter, size == cache2->getResourceBytes());
|
||||
REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
|
||||
REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
|
||||
|
||||
// Once it is unrefed, it should become available as scratch.
|
||||
resource->unref();
|
||||
REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
|
||||
REPORTER_ASSERT(reporter, size == cache2->getResourceBytes());
|
||||
REPORTER_ASSERT(reporter, 1 == cache2->getBudgetedResourceCount());
|
||||
REPORTER_ASSERT(reporter, size == cache2->getBudgetedResourceBytes());
|
||||
resource = static_cast<TestResource*>(cache2->findAndRefScratchResource(key));
|
||||
REPORTER_ASSERT(reporter, resource);
|
||||
REPORTER_ASSERT(reporter, resource->cacheAccess().getScratchKey() == key);
|
||||
REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch());
|
||||
REPORTER_ASSERT(reporter, resource->cacheAccess().isBudgeted());
|
||||
|
||||
if (0 == i) {
|
||||
// If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try
|
||||
// the above tests again.
|
||||
resource->cacheAccess().makeUnbudgeted();
|
||||
} else {
|
||||
// After the second time around, try removing the scratch key
|
||||
resource->cacheAccess().removeScratchKey();
|
||||
REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
|
||||
REPORTER_ASSERT(reporter, size == cache2->getResourceBytes());
|
||||
REPORTER_ASSERT(reporter, 1 == cache2->getBudgetedResourceCount());
|
||||
REPORTER_ASSERT(reporter, size == cache2->getBudgetedResourceBytes());
|
||||
REPORTER_ASSERT(reporter, !resource->cacheAccess().getScratchKey().isValid());
|
||||
REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
|
||||
REPORTER_ASSERT(reporter, resource->cacheAccess().isBudgeted());
|
||||
|
||||
// now when it is unrefed it should die since it has no key.
|
||||
resource->unref();
|
||||
REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
|
||||
REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
|
||||
REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
|
||||
REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
|
||||
}
|
||||
}
|
||||
context->setResourceCacheLimits(5, 30000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
}
|
||||
|
||||
static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
|
||||
Mock mock(5, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
// Create two resources that have the same scratch key.
|
||||
TestResource* a =
|
||||
@ -436,15 +491,9 @@ static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
|
||||
}
|
||||
|
||||
static void test_remove_scratch_key(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
context->setResourceCacheLimits(5, 30000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
Mock mock(5, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
// Create two resources that have the same scratch key.
|
||||
TestResource* a =
|
||||
@ -504,15 +553,9 @@ static void test_remove_scratch_key(skiatest::Reporter* reporter) {
|
||||
}
|
||||
|
||||
static void test_scratch_key_consistency(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
context->setResourceCacheLimits(5, 30000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
Mock mock(5, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
// Create two resources that have the same scratch key.
|
||||
TestResource* a =
|
||||
@ -571,15 +614,9 @@ static void test_scratch_key_consistency(skiatest::Reporter* reporter) {
|
||||
}
|
||||
|
||||
static void test_duplicate_content_key(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
context->setResourceCacheLimits(5, 30000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
Mock mock(5, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
GrContentKey key;
|
||||
make_content_key<0>(&key, 0);
|
||||
@ -624,22 +661,15 @@ static void test_duplicate_content_key(skiatest::Reporter* reporter) {
|
||||
}
|
||||
|
||||
static void test_purge_invalidated(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
Mock mock(5, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
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();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
|
||||
// Add three resources to the cache.
|
||||
TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
@ -685,67 +715,52 @@ static void test_purge_invalidated(skiatest::Reporter* reporter) {
|
||||
}
|
||||
|
||||
static void test_cache_chained_purge(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
Mock mock(3, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
GrContentKey key1, key2;
|
||||
make_content_key<0>(&key1, 1);
|
||||
make_content_key<0>(&key2, 2);
|
||||
|
||||
{
|
||||
context->setResourceCacheLimits(3, 30000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
|
||||
TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
a->cacheAccess().setContentKey(key1);
|
||||
b->cacheAccess().setContentKey(key2);
|
||||
TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
a->cacheAccess().setContentKey(key1);
|
||||
b->cacheAccess().setContentKey(key2);
|
||||
|
||||
// Make a cycle
|
||||
a->setUnrefWhenDestroyed(b);
|
||||
b->setUnrefWhenDestroyed(a);
|
||||
// Make a cycle
|
||||
a->setUnrefWhenDestroyed(b);
|
||||
b->setUnrefWhenDestroyed(a);
|
||||
|
||||
REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
|
||||
REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
|
||||
|
||||
a->unref();
|
||||
b->unref();
|
||||
a->unref();
|
||||
b->unref();
|
||||
|
||||
REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
|
||||
REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
|
||||
|
||||
cache2->purgeAllUnlocked();
|
||||
REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
|
||||
cache2->purgeAllUnlocked();
|
||||
REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
|
||||
|
||||
// Break the cycle
|
||||
a->setUnrefWhenDestroyed(NULL);
|
||||
REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
|
||||
// Break the cycle
|
||||
a->setUnrefWhenDestroyed(NULL);
|
||||
REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
|
||||
|
||||
cache2->purgeAllUnlocked();
|
||||
REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
|
||||
}
|
||||
cache2->purgeAllUnlocked();
|
||||
REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
|
||||
}
|
||||
|
||||
static void test_resource_size_changed(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrContentKey key1, key2;
|
||||
make_content_key<0>(&key1, 1);
|
||||
make_content_key<0>(&key2, 2);
|
||||
|
||||
// Test changing resources sizes (both increase & decrease).
|
||||
{
|
||||
context->setResourceCacheLimits(3, 30000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
Mock mock(3, 30000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
a->cacheAccess().setContentKey(key1);
|
||||
@ -770,10 +785,9 @@ static void test_resource_size_changed(skiatest::Reporter* reporter) {
|
||||
|
||||
// Test increasing a resources size beyond the cache budget.
|
||||
{
|
||||
context->setResourceCacheLimits(2, 300);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
Mock mock(2, 300);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
|
||||
a->setSize(100);
|
||||
@ -800,21 +814,14 @@ static void test_resource_size_changed(skiatest::Reporter* reporter) {
|
||||
}
|
||||
|
||||
static void test_large_resource_count(skiatest::Reporter* reporter) {
|
||||
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
|
||||
REPORTER_ASSERT(reporter, SkToBool(context));
|
||||
if (NULL == context) {
|
||||
return;
|
||||
}
|
||||
|
||||
static const int kResourceCnt = 2000;
|
||||
// Set the cache size to double the resource count because we're going to create 2x that number
|
||||
// resources, using two different key domains. Add a little slop to the bytes because we resize
|
||||
// down to 1 byte after creating the resource.
|
||||
context->setResourceCacheLimits(2 * kResourceCnt, 2 * kResourceCnt + 1000);
|
||||
GrResourceCache2* cache2 = context->getResourceCache2();
|
||||
cache2->purgeAllUnlocked();
|
||||
SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
|
||||
static const int kResourceCnt = 2000;
|
||||
|
||||
Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000);
|
||||
GrContext* context = mock.context();
|
||||
GrResourceCache2* cache2 = mock.cache();
|
||||
|
||||
for (int i = 0; i < kResourceCnt; ++i) {
|
||||
GrContentKey key1, key2;
|
||||
@ -892,6 +899,7 @@ DEF_GPUTEST(ResourceCache, reporter, factory) {
|
||||
test_no_key(reporter);
|
||||
test_budgeting(reporter);
|
||||
test_unbudgeted(reporter);
|
||||
test_unbudgeted_to_scratch(reporter);
|
||||
test_duplicate_content_key(reporter);
|
||||
test_duplicate_scratch_key(reporter);
|
||||
test_remove_scratch_key(reporter);
|
||||
|
Loading…
Reference in New Issue
Block a user