Move npot resizing out of GrContext and simplify GrContext texture functions.

Committed: https://skia.googlesource.com/skia/+/8a8100349105c8c6de39fcb34e47679da7a67f54

Committed: https://skia.googlesource.com/skia/+/6c96672491b04cb782bce8fee778124df66524a0

Review URL: https://codereview.chromium.org/882223003
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 13b0bfa..07073a5 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -223,219 +223,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static void stretch_image(void* dst,
-                          int dstW,
-                          int dstH,
-                          const void* src,
-                          int srcW,
-                          int srcH,
-                          size_t bpp) {
-    SkFixed dx = (srcW << 16) / dstW;
-    SkFixed dy = (srcH << 16) / dstH;
-
-    SkFixed y = dy >> 1;
-
-    size_t dstXLimit = dstW*bpp;
-    for (int j = 0; j < dstH; ++j) {
-        SkFixed x = dx >> 1;
-        const uint8_t* srcRow = reinterpret_cast<const uint8_t *>(src) + (y>>16)*srcW*bpp;
-        uint8_t* dstRow = reinterpret_cast<uint8_t *>(dst) + j*dstW*bpp;
-        for (size_t i = 0; i < dstXLimit; i += bpp) {
-            memcpy(dstRow + i, srcRow + (x>>16)*bpp, bpp);
-            x += dx;
-        }
-        y += dy;
-    }
-}
-
-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 GrContentKey& origKey,
-                                           const void* srcData,
-                                           size_t rowBytes,
-                                           bool filter) {
-    SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, origKey, NULL));
-    if (NULL == clampedTexture) {
-        clampedTexture.reset(this->createTexture(NULL, desc, origKey, srcData, rowBytes));
-
-        if (NULL == clampedTexture) {
-            return NULL;
-        }
-        clampedTexture->cacheAccess().setContentKey(origKey);
-    }
-
-    GrSurfaceDesc rtDesc = desc;
-    rtDesc.fFlags =  rtDesc.fFlags |
-                     kRenderTarget_GrSurfaceFlag |
-                     kNoStencil_GrSurfaceFlag;
-    rtDesc.fWidth  = GrNextPow2(desc.fWidth);
-    rtDesc.fHeight = GrNextPow2(desc.fHeight);
-
-    GrTexture* texture = fGpu->createTexture(rtDesc, true, NULL, 0);
-
-    if (texture) {
-        GrPipelineBuilder pipelineBuilder;
-        pipelineBuilder.setRenderTarget(texture->asRenderTarget());
-
-        // if filtering is not desired then we want to ensure all
-        // texels in the resampled image are copies of texels from
-        // the original.
-        GrTextureParams params(SkShader::kClamp_TileMode,
-                               filter ? GrTextureParams::kBilerp_FilterMode :
-                                        GrTextureParams::kNone_FilterMode);
-        pipelineBuilder.addColorTextureProcessor(clampedTexture, SkMatrix::I(), params);
-
-        uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
-                         GrDefaultGeoProcFactory::kLocalCoord_GPType;
-        SkAutoTUnref<const GrGeometryProcessor> gp(
-                GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE));
-
-        GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, gp->getVertexStride(),  0);
-        SkASSERT(gp->getVertexStride() == 2 * sizeof(SkPoint));
-
-        if (arg.succeeded()) {
-            SkPoint* verts = (SkPoint*) arg.vertices();
-            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
-        // stretched textures when the texture params is either filtered or
-        // not. Either implement filtered stretch blit on CPU or just create
-        // one when FBO case fails.
-
-        rtDesc.fFlags = kNone_GrSurfaceFlags;
-        // no longer need to clamp at min RT size.
-        rtDesc.fWidth  = GrNextPow2(desc.fWidth);
-        rtDesc.fHeight = GrNextPow2(desc.fHeight);
-
-        // We shouldn't be resizing a compressed texture.
-        SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig));
-
-        size_t bpp = GrBytesPerPixel(desc.fConfig);
-        GrAutoMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHeight);
-        stretch_image(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
-                      srcData, desc.fWidth, desc.fHeight, bpp);
-
-        size_t stretchedRowBytes = rtDesc.fWidth * bpp;
-
-        texture = fGpu->createTexture(rtDesc, true, stretchedPixels.get(), stretchedRowBytes);
-        SkASSERT(texture);
-    }
-
-    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 GrContentKey& origKey,
-                                    const void* srcData,
-                                    size_t rowBytes,
-                                    GrContentKey* outKey) {
-    GrTexture* texture;
-    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;
-
-    } else {
-        texture = fGpu->createTexture(desc, true, srcData, rowBytes);
-    }
-
-    if (texture) {
-        if (texture->cacheAccess().setContentKey(*key)) {
-            if (outKey) {
-                *outKey = *key;
-            }
-        } else {
-            texture->unref();
-            texture = NULL;
-        }
-    }
-
-    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::createTexture(const GrSurfaceDesc& desc, const void* srcData,
+                                    size_t rowBytes) {
+    return fGpu->createTexture(desc, true, srcData, rowBytes);
 }
 
 GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& inDesc, ScratchTexMatch match,
@@ -526,19 +316,6 @@
     return fGpu->createTexture(desc, false, srcData, rowBytes);
 }
 
-void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
-    if (maxTextures) {
-        *maxTextures = fResourceCache2->getMaxResourceCount();
-    }
-    if (maxTextureBytes) {
-        *maxTextureBytes = fResourceCache2->getMaxResourceBytes();
-    }
-}
-
-void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
-    fResourceCache2->setLimits(maxTextures, maxTextureBytes);
-}
-
 int GrContext::getMaxTextureSize() const {
     return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride);
 }
@@ -563,22 +340,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-bool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params,
-                                          int width, int height) const {
+bool GrContext::supportsIndex8PixelConfig() const {
     const GrDrawTargetCaps* caps = fGpu->caps();
-    if (!caps->isConfigTexturable(kIndex_8_GrPixelConfig)) {
-        return false;
-    }
-
-    bool isPow2 = SkIsPow2(width) && SkIsPow2(height);
-
-    if (!isPow2) {
-        bool tiled = params && params->isTiled();
-        if (tiled && !caps->npotTextureTileSupport()) {
-            return false;
-        }
-    }
-    return true;
+    return caps->isConfigTexturable(kIndex_8_GrPixelConfig);
 }
 
 
@@ -1767,14 +1531,39 @@
     }
 }
 
-void GrContext::addResourceToCache(const GrContentKey& key, GrGpuResource* resource) {
-    resource->cacheAccess().setContentKey(key);
+//////////////////////////////////////////////////////////////////////////////
+
+void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
+    if (maxTextures) {
+        *maxTextures = fResourceCache2->getMaxResourceCount();
+    }
+    if (maxTextureBytes) {
+        *maxTextureBytes = fResourceCache2->getMaxResourceBytes();
+    }
+}
+
+void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
+    fResourceCache2->setLimits(maxTextures, maxTextureBytes);
+}
+
+bool GrContext::addResourceToCache(const GrContentKey& key, GrGpuResource* resource) {
+    ASSERT_OWNED_RESOURCE(resource);
+    if (!resource || resource->wasDestroyed()) {
+        return false;
+    }
+    return resource->cacheAccess().setContentKey(key);
+}
+
+bool GrContext::isResourceInCache(const GrContentKey& key) const {
+    return fResourceCache2->hasContentKey(key);
 }
 
 GrGpuResource* GrContext::findAndRefCachedResource(const GrContentKey& key) {
     return fResourceCache2->findAndRefContentResource(key);
 }
 
+//////////////////////////////////////////////////////////////////////////////
+
 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
     fGpu->addGpuTraceMarker(marker);
     if (fDrawBuffer) {