Chromium Code Reviews| Index: src/gpu/GrContext.cpp |
| diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp |
| index 785691dbba8af5e0d1dfcd848fe40f83c29aa22e..7229687bb640d24cc3d55c8680703680865ffe7b 100755 |
| --- a/src/gpu/GrContext.cpp |
| +++ b/src/gpu/GrContext.cpp |
| @@ -230,26 +230,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, |
| @@ -275,20 +255,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; |
| @@ -325,6 +339,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(&drawState, gp, kTriangleFan_GrPrimitiveType, 0, 4); |
| + } else { |
| + texture->unref(); |
| + texture = NULL; |
| } |
| } else { |
| // TODO: Our CPU stretch doesn't filter. But we create separate |
| @@ -356,28 +373,33 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc, |
| 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 false; |
| + } |
| + texture = this->createResizedTexture(desc, origKey, srcData, rowBytes, |
| + SkToBool(flags & kBilerp_ResizeFlag)); |
| + |
| + static const GrContentKey::Domain kResizeDomain = GrContentKey::GenerateDomain(); |
| + GrContentKey::Builder builder(key.writable(), origKey, kResizeDomain, 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(); |
| @@ -388,6 +410,39 @@ 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) { |
|
robertphillips
2015/01/22 16:49:12
Aren't you getting different values here ?
bsalomon
2015/01/22 19:23:17
yikes, surely.
|
| + static const GrContentKey::Domain kResizeDomain = GrContentKey::GenerateDomain(); |
| + GrContentKey::Builder builder(key.writable(), origKey, kResizeDomain, 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) { |
|
robertphillips
2015/01/22 16:49:12
and here ?
|
| + static const GrContentKey::Domain kResizeDomain = GrContentKey::GenerateDomain(); |
| + GrContentKey::Builder builder(key.writable(), origKey, kResizeDomain, 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. |
| @@ -1716,12 +1771,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) { |