diff options
author | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-06-22 12:41:43 +0000 |
---|---|---|
committer | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-06-22 12:41:43 +0000 |
commit | 15c0fea699b25343fe6f49668a5632866e1a0306 (patch) | |
tree | 0616bf4168b4d98e02ae7cabf95623ef7ccb4fa5 /src/gpu | |
parent | 5e2412983183f9c4075a795278f3ca4ffee0ed79 (diff) |
AutoScratchTexture can now release its texture and it will return to the texture cache when freed
http://codereview.appspot.com/6262043/
git-svn-id: http://skia.googlecode.com/svn/trunk@4301 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrContext.cpp | 18 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.cpp | 33 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.h | 26 | ||||
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrTexture.cpp | 29 |
5 files changed, 101 insertions, 10 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 1fda26ba03..fc2b143c60 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -520,6 +520,18 @@ GrContext::TextureCacheEntry GrContext::lockScratchTexture( return TextureCacheEntry(entry); } +void GrContext::addExistingTextureToCache(GrTexture* texture) { + + if (NULL == texture) { + return; + } + + GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, + texture->desc(), + true); + fTextureCache->attach(key, texture); +} + void GrContext::unlockTexture(TextureCacheEntry entry) { ASSERT_OWNED_RESOURCE(entry.texture()); // If this is a scratch texture we detached it from the cache @@ -532,6 +544,12 @@ void GrContext::unlockTexture(TextureCacheEntry entry) { } } +void GrContext::freeEntry(TextureCacheEntry entry) { + ASSERT_OWNED_RESOURCE(entry.texture()); + + fTextureCache->freeEntry(entry.cacheEntry()); +} + GrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn, void* srcData, size_t rowBytes) { diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp index 6a6c16697a..8c939714d3 100644 --- a/src/gpu/GrResourceCache.cpp +++ b/src/gpu/GrResourceCache.cpp @@ -81,6 +81,9 @@ void GrResourceCache::internalDetach(GrResourceEntry* entry, --fUnlockedEntryCount; } + entry->fPrev = NULL; + entry->fNext = NULL; + // update our stats if (clientDetach) { fClientDetachedCount += 1; @@ -165,8 +168,9 @@ bool GrResourceCache::hasKey(const GrResourceKey& key) const { return NULL != fCache.find(key); } -GrResourceEntry* GrResourceCache::createAndLock(const GrResourceKey& key, - GrResource* resource) { +GrResourceEntry* GrResourceCache::create(const GrResourceKey& key, + GrResource* resource, + bool lock) { // we don't expect to create new resources during a purge. In theory // this could cause purgeAsNeeded() into an infinite loop (e.g. // each resource destroyed creates and locks 2 resources and @@ -176,9 +180,11 @@ GrResourceEntry* GrResourceCache::createAndLock(const GrResourceKey& key, GrResourceEntry* entry = new GrResourceEntry(key, resource); - // mark the entry as "busy" so it doesn't get purged - // do this before attach for locked count tracking - entry->lock(); + if (lock) { + // mark the entry as "busy" so it doesn't get purged + // do this before attach for locked count tracking + entry->lock(); + } this->attachToHead(entry, false); fCache.insert(key, entry); @@ -192,12 +198,27 @@ GrResourceEntry* GrResourceCache::createAndLock(const GrResourceKey& key, return entry; } +GrResourceEntry* GrResourceCache::createAndLock(const GrResourceKey& key, + GrResource* resource) { + return this->create(key, resource, true); +} + +void GrResourceCache::attach(const GrResourceKey& key, + GrResource* resource) { + this->create(key, resource, false); +} + void GrResourceCache::detach(GrResourceEntry* entry) { GrAutoResourceCacheValidate atcv(this); - internalDetach(entry, true); + this->internalDetach(entry, true); fCache.remove(entry->fKey, entry); } +void GrResourceCache::freeEntry(GrResourceEntry* entry) { + GrAssert(NULL == entry->fNext && NULL == entry->fPrev); + delete entry; +} + void GrResourceCache::reattachAndUnlock(GrResourceEntry* entry) { GrAutoResourceCacheValidate atcv(this); if (entry->resource()->isValid()) { diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h index ca7ca10a46..ba5ea4ee3d 100644 --- a/src/gpu/GrResourceCache.h +++ b/src/gpu/GrResourceCache.h @@ -231,15 +231,26 @@ public: GrResourceEntry* findAndLock(const GrResourceKey&, LockType style); /** - * Create a new entry, based on the specified key and resource, and return - * its "locked" entry. + * Create a new cache entry, based on the provided key and resource, and + * return it. * - * Ownership of the resource is transferred to the Entry, which will - * unref() it when we are purged or deleted. + * Ownership of the resource is transferred to the resource cache, + * which will unref() it when it is purged or deleted. */ GrResourceEntry* createAndLock(const GrResourceKey&, GrResource*); /** + * Create a new cache entry, based on the provided key and resource. + * + * Ownership of the resource is transferred to the resource cache, + * which will unref() it when it is purged or deleted. + * + * Currently this entry point is only intended for textures "detached" + * from an AutoScratchTexture object. + */ + void attach(const GrResourceKey& key, GrResource* resource); + + /** * Determines if the cache contains an entry matching a key. If a matching * entry exists but was detached then it will not be found. */ @@ -253,6 +264,8 @@ public: */ void detach(GrResourceEntry*); + void freeEntry(GrResourceEntry* entry); + /** * Reattaches a resource to the cache and unlocks it. Allows it to be found * by a subsequent findAndLock or be purged (provided its lock count is @@ -298,6 +311,11 @@ private: // prevents recursive purging bool fPurging; + + GrResourceEntry* create(const GrResourceKey& key, + GrResource* resource, + bool lock); + }; /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 72ad543121..bfad6dfb69 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -336,7 +336,11 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, if (sw_draw_path_to_mask_texture(path, pathBounds, fill, fContext, translate, &ast, antiAlias)) { +#if 1 GrTexture* texture = ast.texture(); +#else + SkAutoTUnref<GrTexture> texture(ast.detach()); +#endif GrAssert(NULL != texture); GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); enum { @@ -351,6 +355,7 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, GrScalar h = GrIntToScalar(pathBounds.height()); GrRect maskRect = GrRect::MakeWH(w / texture->width(), h / texture->height()); + const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; srcRects[kPathMaskStage] = &maskRect; stageMask |= 1 << kPathMaskStage; diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp index 67ce62913e..19dc32220d 100644 --- a/src/gpu/GrTexture.cpp +++ b/src/gpu/GrTexture.cpp @@ -16,6 +16,30 @@ SK_DEFINE_INST_COUNT(GrTexture) +/** + * This method allows us to interrupt the normal deletion process and place + * textures back in the texture cache when their ref count goes to zero. + */ +void GrTexture::internal_dispose() const { + + if (this->isSetFlag((GrTextureFlags) kReturnToCache_FlagBit) && + NULL != this->INHERITED::getContext()) { + GrTexture* nonConstThis = const_cast<GrTexture *>(this); + this->fRefCnt = 1; // restore ref count to initial setting + + nonConstThis->resetFlag((GrTextureFlags) kReturnToCache_FlagBit); + nonConstThis->INHERITED::getContext()->addExistingTextureToCache(nonConstThis); + + // Note: this next assert is only correct for the texture cache's + // current single threaded usage. If we ever start accessing it via + // threads it isn't guaranteed to be correct. + GrAssert(1 == this->INHERITED::getRefCnt()); + return; + } + + this->INHERITED::internal_dispose(); +} + bool GrTexture::readPixels(int left, int top, int width, int height, GrPixelConfig config, void* buffer, size_t rowBytes) { @@ -59,6 +83,11 @@ void GrTexture::releaseRenderTarget() { } } +void GrTexture::onRelease() { + GrAssert(!this->isSetFlag((GrTextureFlags) kReturnToCache_FlagBit)); + this->releaseRenderTarget(); +} + void GrTexture::onAbandon() { if (NULL != fRenderTarget) { fRenderTarget->abandon(); |