Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Unified Diff: src/gpu/GrContext.cpp

Issue 608883003: GrResourceCache2 manages scratch texture. (Closed) Base URL: https://skia.googlesource.com/skia.git@surfimpl
Patch Set: remove todo Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrClipMaskCache.h ('k') | src/gpu/GrDrawState.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrContext.cpp
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index d0f3cc56713226f7f432f6dbd4a90c19d6e94526..a722eed88ac5cac8a663adbe9f7fc14ac1d6315d 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -70,25 +70,6 @@ static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4;
#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
-GrTexture* GrAutoScratchTexture::detach() {
- if (NULL == fTexture) {
- return NULL;
- }
- GrTexture* texture = fTexture;
- fTexture = NULL;
-
- // This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now.
- // The cache also has a ref which we are lending to the caller of detach(). When the caller
- // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is
- // set and re-ref the texture, thereby restoring the cache's ref.
- SkASSERT(!texture->unique());
- texture->texturePriv().setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
- texture->unref();
- SkASSERT(texture->getCacheEntry());
-
- return texture;
-}
-
// Glorified typedef to avoid including GrDrawState.h in GrContext.h
class GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {};
@@ -153,7 +134,8 @@ bool GrContext::init(GrBackend backend, GrBackendContext backendContext) {
fDrawState = SkNEW(GrDrawState);
fGpu->setDrawState(fDrawState);
- fResourceCache = SkNEW_ARGS(GrResourceCache, (MAX_RESOURCE_CACHE_COUNT,
+ fResourceCache = SkNEW_ARGS(GrResourceCache, (fGpu->caps(),
+ MAX_RESOURCE_CACHE_COUNT,
MAX_RESOURCE_CACHE_BYTES));
fResourceCache->setOverbudgetCallback(OverbudgetCB, this);
fResourceCache2 = SkNEW(GrResourceCache2);
@@ -446,9 +428,6 @@ GrTexture* GrContext::createTexture(const GrTextureParams* params,
}
if (texture) {
- // Adding a resource could put us overbudget. Try to free up the
- // necessary space before adding it.
- fResourceCache->purgeAsNeeded(1, texture->gpuMemorySize());
fResourceCache->addResource(resourceKey, texture);
if (cacheKey) {
@@ -459,157 +438,71 @@ GrTexture* GrContext::createTexture(const GrTextureParams* params,
return texture;
}
-static GrTexture* create_scratch_texture(GrGpu* gpu,
- GrResourceCache* resourceCache,
- const GrTextureDesc& desc) {
- GrTexture* texture = gpu->createTexture(desc, NULL, 0);
- if (texture) {
- GrResourceKey key = GrTexturePriv::ComputeScratchKey(texture->desc());
- // Adding a resource could put us overbudget. Try to free up the
- // necessary space before adding it.
- resourceCache->purgeAsNeeded(1, texture->gpuMemorySize());
- // Make the resource exclusive so future 'find' calls don't return it
- resourceCache->addResource(key, texture, GrResourceCache::kHide_OwnershipFlag);
+GrTexture* GrContext::createNewScratchTexture(const GrTextureDesc& desc) {
+ GrTexture* texture = fGpu->createTexture(desc, NULL, 0);
+ if (!texture) {
+ return NULL;
}
+ fResourceCache->addResource(texture->getScratchKey(), texture);
+ texture->fIsScratch = GrGpuResource::kYes_IsScratch;
return texture;
}
-GrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match) {
+GrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match,
+ bool calledDuringFlush) {
+ // kNoStencil has no meaning if kRT isn't set.
SkASSERT((inDesc.fFlags & kRenderTarget_GrTextureFlagBit) ||
!(inDesc.fFlags & kNoStencil_GrTextureFlagBit));
- // Renderable A8 targets are not universally supported (e.g., not on ANGLE)
- SkASSERT(this->isConfigRenderable(kAlpha_8_GrPixelConfig, inDesc.fSampleCnt > 0) ||
- !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit) ||
- (inDesc.fConfig != kAlpha_8_GrPixelConfig));
+ // Make sure caller has checked for renderability if kRT is set.
+ SkASSERT(!(inDesc.fFlags & kRenderTarget_GrTextureFlagBit) ||
+ this->isConfigRenderable(inDesc.fConfig, inDesc.fSampleCnt > 0));
- if (!fGpu->caps()->reuseScratchTextures() &&
- !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit)) {
- // If we're never recycling this texture we can always make it the right size
- return create_scratch_texture(fGpu, fResourceCache, inDesc);
- }
-
- GrTextureDesc desc = inDesc;
+ SkTCopyOnFirstWrite<GrTextureDesc> desc(inDesc);
- if (kApprox_ScratchTexMatch == match) {
- // bin by pow2 with a reasonable min
- static const int MIN_SIZE = 16;
- desc.fWidth = SkTMax(MIN_SIZE, GrNextPow2(desc.fWidth));
- desc.fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc.fHeight));
- }
-
- GrGpuResource* resource = NULL;
- int origWidth = desc.fWidth;
- int origHeight = desc.fHeight;
-
- do {
- GrResourceKey key = GrTexturePriv::ComputeScratchKey(desc);
- // Ensure we have exclusive access to the texture so future 'find' calls don't return it
- resource = fResourceCache->find(key, GrResourceCache::kHide_OwnershipFlag);
- if (resource) {
- resource->ref();
- break;
- }
- if (kExact_ScratchTexMatch == match) {
- break;
- }
- // We had a cache miss and we are in approx mode, relax the fit of the flags.
-
- // We no longer try to reuse textures that were previously used as render targets in
- // situations where no RT is needed; doing otherwise can confuse the video driver and
- // cause significant performance problems in some cases.
- if (desc.fFlags & kNoStencil_GrTextureFlagBit) {
- desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit;
- } else {
- break;
+ if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrTextureFlagBit)) {
+ GrTextureFlags origFlags = desc->fFlags;
+ if (kApprox_ScratchTexMatch == match) {
+ // bin by pow2 with a reasonable min
+ static const int MIN_SIZE = 16;
+ GrTextureDesc* wdesc = desc.writable();
+ wdesc->fWidth = SkTMax(MIN_SIZE, GrNextPow2(desc->fWidth));
+ wdesc->fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc->fHeight));
}
- } while (true);
-
- if (NULL == resource) {
- desc.fFlags = inDesc.fFlags;
- desc.fWidth = origWidth;
- desc.fHeight = origHeight;
- resource = create_scratch_texture(fGpu, fResourceCache, desc);
- }
-
- return static_cast<GrTexture*>(resource);
-}
-
-void GrContext::addExistingTextureToCache(GrTexture* texture) {
-
- if (NULL == texture) {
- return;
- }
-
- // This texture should already have a cache entry since it was once
- // attached
- SkASSERT(texture->getCacheEntry());
-
- // Conceptually, the cache entry is going to assume responsibility
- // for the creation ref. Assert refcnt == 1.
- // Except that this also gets called when the texture is prematurely
- // abandoned. In that case the ref count may be > 1.
- // SkASSERT(texture->unique());
+ do {
+ GrResourceKey key = GrTexturePriv::ComputeScratchKey(*desc);
+ GrGpuResource* resource = fResourceCache2->findAndRefScratchResource(key,
+ calledDuringFlush);
+ if (resource) {
+ fResourceCache->makeResourceMRU(resource);
+ return static_cast<GrTexture*>(resource);
+ }
- if (fGpu->caps()->reuseScratchTextures() || texture->asRenderTarget()) {
- // Since this texture came from an AutoScratchTexture it should
- // still be in the exclusive pile. Recycle it.
- fResourceCache->makeNonExclusive(texture->getCacheEntry());
- this->purgeCache();
- } else {
- // When we aren't reusing textures we know this scratch texture
- // will never be reused and would be just wasting time in the cache
- fResourceCache->makeNonExclusive(texture->getCacheEntry());
- fResourceCache->deleteResource(texture->getCacheEntry());
- }
-}
+ if (kExact_ScratchTexMatch == match) {
+ break;
+ }
+ // We had a cache miss and we are in approx mode, relax the fit of the flags.
+
+ // We no longer try to reuse textures that were previously used as render targets in
+ // situations where no RT is needed; doing otherwise can confuse the video driver and
+ // cause significant performance problems in some cases.
+ if (desc->fFlags & kNoStencil_GrTextureFlagBit) {
+ desc.writable()->fFlags = desc->fFlags & ~kNoStencil_GrTextureFlagBit;
+ } else {
+ break;
+ }
-void GrContext::unlockScratchTexture(GrTexture* texture) {
- if (texture->wasDestroyed()) {
- if (texture->getCacheEntry()->key().isScratch()) {
- // This texture was detached from the cache but the cache still had a ref to it but
- // not a pointer to it. This will unref the texture and delete its resource cache
- // entry.
- delete texture->getCacheEntry();
- }
- return;
- }
+ } while (true);
- ASSERT_OWNED_RESOURCE(texture);
- SkASSERT(texture->getCacheEntry());
-
- // If this is a scratch texture we detached it from the cache
- // while it was locked (to avoid two callers simultaneously getting
- // the same texture).
- if (texture->getCacheEntry()->key().isScratch()) {
- if (fGpu->caps()->reuseScratchTextures() || texture->asRenderTarget()) {
- fResourceCache->makeNonExclusive(texture->getCacheEntry());
- this->purgeCache();
- } else if (texture->unique()) {
- // Only the cache now knows about this texture. Since we're never
- // reusing scratch textures (in this code path) it would just be
- // wasting time sitting in the cache.
- fResourceCache->makeNonExclusive(texture->getCacheEntry());
- fResourceCache->deleteResource(texture->getCacheEntry());
- } else {
- // In this case (there is still a non-cache ref) but we don't really
- // want to readd it to the cache (since it will never be reused).
- // Instead, give up the cache's ref and leave the decision up to
- // addExistingTextureToCache once its ref count reaches 0. For
- // this to work we need to leave it in the exclusive list.
- texture->texturePriv().setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
- // Give up the cache's ref to the texture
- texture->unref();
- }
+ desc.writable()->fFlags = origFlags;
}
-}
-void GrContext::purgeCache() {
- if (fResourceCache) {
- fResourceCache->purgeAsNeeded();
- }
+ GrTexture* texture = this->createNewScratchTexture(*desc);
+ SkASSERT(NULL == texture ||
+ texture->getScratchKey() == GrTexturePriv::ComputeScratchKey(*desc));
+ return texture;
}
bool GrContext::OverbudgetCB(void* data) {
@@ -1349,6 +1242,7 @@ void GrContext::flush(int flagsBitfield) {
} else {
fDrawBuffer->flush();
}
+ fResourceCache->purgeAsNeeded();
fFlushToReduceCacheSize = false;
}
@@ -1941,7 +1835,6 @@ const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture,
}
void GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrGpuResource* resource) {
- fResourceCache->purgeAsNeeded(1, resource->gpuMemorySize());
fResourceCache->addResource(resourceKey, resource);
}
« no previous file with comments | « src/gpu/GrClipMaskCache.h ('k') | src/gpu/GrDrawState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698