Index: src/gpu/GrContext.cpp |
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp |
index 5b157d2a8e83880f13cf55beff320558b46a4b2f..7a910c5744662626cc0b0f7eed5eb0aa44468cbe 100755 |
--- a/src/gpu/GrContext.cpp |
+++ b/src/gpu/GrContext.cpp |
@@ -222,6 +222,11 @@ GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget, |
} |
//////////////////////////////////////////////////////////////////////////////// |
+enum ScratchTextureFlags { |
+ kExact_ScratchTextureFlag = 0x1, |
+ kNoPendingIO_ScratchTextureFlag = 0x2, |
+ kNoCreate_ScratchTextureFlag = 0x4, |
+}; |
bool GrContext::isConfigTexturable(GrPixelConfig config) const { |
return fGpu->caps()->isConfigTexturable(config); |
@@ -231,31 +236,57 @@ bool GrContext::npotTextureTileSupport() const { |
return fGpu->caps()->npotTextureTileSupport(); |
} |
-GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, const void* srcData, |
+GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, bool budgeted, const void* srcData, |
size_t rowBytes) { |
- return fGpu->createTexture(desc, true, srcData, rowBytes); |
+ if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) && |
+ !this->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { |
+ return NULL; |
+ } |
+ if (!GrPixelConfigIsCompressed(desc.fConfig)) { |
+ static const uint32_t kFlags = kExact_ScratchTextureFlag | |
+ kNoCreate_ScratchTextureFlag; |
+ if (GrTexture* texture = this->internalRefScratchTexture(desc, kFlags)) { |
+ if (!srcData || texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, |
+ srcData, rowBytes)) { |
+ if (!budgeted) { |
+ texture->cacheAccess().makeUnbudgeted(); |
+ } |
+ return texture; |
+ } |
+ texture->unref(); |
+ } |
+ } |
+ return fGpu->createTexture(desc, budgeted, srcData, rowBytes); |
} |
-GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexMatch match, |
+GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match, |
bool calledDuringFlush) { |
// Currently we don't recycle compressed textures as scratch. |
- if (GrPixelConfigIsCompressed(inDesc.fConfig)) { |
+ if (GrPixelConfigIsCompressed(desc.fConfig)) { |
return NULL; |
+ } else { |
+ uint32_t flags = 0; |
+ if (kExact_ScratchTexMatch == match) { |
+ flags |= kExact_ScratchTextureFlag; |
+ } |
+ if (calledDuringFlush) { |
+ flags |= kNoPendingIO_ScratchTextureFlag; |
+ } |
+ return this->internalRefScratchTexture(desc, flags); |
} |
+} |
+GrTexture* GrContext::internalRefScratchTexture(const GrSurfaceDesc& inDesc, uint32_t flags) { |
+ SkASSERT(!GrPixelConfigIsCompressed(inDesc.fConfig)); |
// kNoStencil has no meaning if kRT isn't set. |
SkASSERT((inDesc.fFlags & kRenderTarget_GrSurfaceFlag) || |
!(inDesc.fFlags & kNoStencil_GrSurfaceFlag)); |
- // Make sure caller has checked for renderability if kRT is set. |
- SkASSERT(!(inDesc.fFlags & kRenderTarget_GrSurfaceFlag) || |
- this->isConfigRenderable(inDesc.fConfig, inDesc.fSampleCnt > 0)); |
- |
SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc); |
if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) { |
GrSurfaceFlags origFlags = desc->fFlags; |
- if (kApprox_ScratchTexMatch == match) { |
+ if (!(kExact_ScratchTextureFlag & flags)) { |
// bin by pow2 with a reasonable min |
static const int MIN_SIZE = 16; |
GrSurfaceDesc* wdesc = desc.writable(); |
@@ -267,7 +298,7 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM |
GrScratchKey key; |
GrTexturePriv::ComputeScratchKey(*desc, &key); |
uint32_t scratchFlags = 0; |
- if (calledDuringFlush) { |
+ if (kNoPendingIO_ScratchTextureFlag & flags) { |
scratchFlags = GrResourceCache2::kRequireNoPendingIO_ScratchFlag; |
} else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) { |
// If it is not a render target then it will most likely be populated by |
@@ -284,7 +315,7 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM |
return surface->asTexture(); |
} |
- if (kExact_ScratchTexMatch == match) { |
+ if (kExact_ScratchTextureFlag & flags) { |
break; |
} |
// We had a cache miss and we are in approx mode, relax the fit of the flags. |
@@ -303,15 +334,19 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexM |
desc.writable()->fFlags = origFlags; |
} |
- GrTexture* texture = fGpu->createTexture(*desc, true, NULL, 0); |
-#ifdef SK_DEBUG |
- if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) { |
- GrScratchKey key; |
- GrTexturePriv::ComputeScratchKey(*desc, &key); |
- SkASSERT(NULL == texture || texture->cacheAccess().getScratchKey() == key); |
+ if (!(kNoCreate_ScratchTextureFlag & flags)) { |
+ GrTexture* texture = fGpu->createTexture(*desc, true, NULL, 0); |
+ #ifdef SK_DEBUG |
+ if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) { |
+ GrScratchKey key; |
+ GrTexturePriv::ComputeScratchKey(*desc, &key); |
+ SkASSERT(NULL == texture || texture->cacheAccess().getScratchKey() == key); |
+ } |
+ #endif |
+ return texture; |
} |
-#endif |
- return texture; |
+ |
+ return NULL; |
} |
void GrContext::OverBudgetCB(void* data) { |
@@ -323,12 +358,6 @@ void GrContext::OverBudgetCB(void* data) { |
context->fFlushToReduceCacheSize = true; |
} |
-GrTexture* GrContext::createUncachedTexture(const GrSurfaceDesc& desc, |
- void* srcData, |
- size_t rowBytes) { |
- return fGpu->createTexture(desc, false, srcData, rowBytes); |
-} |
- |
int GrContext::getMaxTextureSize() const { |
return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); |
} |