Index: src/gpu/GrContext.cpp |
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp |
index b798ef047881fb28493a1c98a46a53882dbfee9c..ea3ea281fef063416f2a97a0f1d8672f58a6b326 100755 |
--- a/src/gpu/GrContext.cpp |
+++ b/src/gpu/GrContext.cpp |
@@ -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) { |