Remove atlas creation from GrResourceProvider

This is pulled out of: https://skia-review.googlesource.com/c/6680/ (Make SkImage_Gpu be deferred) and is only tangentially related to the goal of that CL.

Change-Id: I6b6db4869597070f85ab3b9fea178fc88c104f87
Reviewed-on: https://skia-review.googlesource.com/9106
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index c523ae8..ad5ef4d 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -196,7 +196,7 @@
         GrContext* context = ((SkImage_Gpu*) as_IB(image))->context();
 
         return MakeDeferredFromGpu(context, subset, image->uniqueID(), std::move(proxy),
-                                   sk_ref_sp(as_IB(image)->onImageInfo().colorSpace()), props);
+                                   as_IB(image)->onImageInfo().refColorSpace(), props);
     } else
 #endif
     {
@@ -479,7 +479,7 @@
         if (subset) {
             // TODO: if this becomes a bottle neck we could base this logic on what the size
             // will be when it is finally instantiated - but that is more fraught.
-            if (//fSurfaceProxy->priv().isExact() &&
+            if (fTextureProxy->priv().isExact() &&
                 0 == subset->fLeft && 0 == subset->fTop &&
                 fTextureProxy->width() == subset->width() &&
                 fTextureProxy->height() == subset->height()) {
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index 184640f..e4ea772 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -67,5 +67,5 @@
 
 sk_sp<SkColorSpace> GrBitmapTextureMaker::getColorSpace(SkColorSpace* dstColorSpace) {
     // Color space doesn't depend on destination color space - it's just whatever is in the bitmap
-    return sk_ref_sp(fBitmap.colorSpace());
+    return fBitmap.refColorSpace();
 }
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 375ee8b..0b3089b 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -413,11 +413,11 @@
 // MDB TODO (caching): this side-steps the issue of texture proxies cached by unique ID
 sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context,
                                                            const GrReducedClip& reducedClip) const {
-    GrResourceProvider* resourceProvider = context->resourceProvider();
+    GrTextureProvider* texProvider = context->textureProvider();
     GrUniqueKey key;
     create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key);
 
-    sk_sp<GrTexture> texture(resourceProvider->findAndRefTextureByUniqueKey(key));
+    sk_sp<GrTexture> texture(texProvider->findAndRefTextureByUniqueKey(key));
     if (texture) {
         return GrSurfaceProxy::MakeWrapped(std::move(texture));
     }
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 6661b48..e9fd356 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -10,8 +10,46 @@
 #include "GrContext.h"
 #include "GrOpFlushState.h"
 #include "GrRectanizer.h"
+#include "GrResourceProvider.h"
 #include "GrTracing.h"
 
+std::unique_ptr<GrDrawOpAtlas> GrDrawOpAtlas::Make(GrContext* ctx, GrPixelConfig config,
+                                                   int width, int height,
+                                                   int numPlotsX, int numPlotsY,
+                                                   GrDrawOpAtlas::EvictionFunc func,
+                                                   void* data) {
+    GrSurfaceDesc desc;
+    desc.fFlags = kNone_GrSurfaceFlags;
+    desc.fWidth = width;
+    desc.fHeight = height;
+    desc.fConfig = config;
+
+    // We don't want to flush the context so we claim we're in the middle of flushing so as to
+    // guarantee we do not recieve a texture with pending IO
+    // TODO: Determine how to avoid having to do this. (https://bug.skia.org/4156)
+    static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag;
+    sk_sp<GrTexture> texture(ctx->textureProvider()->createApproxTexture(desc, kFlags));
+    if (!texture) {
+        return nullptr;
+    }
+
+    // MDB TODO: for now, wrap an instantiated texture. Having the deferred instantiation
+    // possess the correct properties (e.g., no pendingIO) should fall out of the system but
+    // should receive special attention.
+    // Note: When switching over to the deferred proxy, use the kExact flag to create
+    // the atlas and assert that the width & height are powers of 2.
+    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(texture));
+    if (!proxy) {
+        return nullptr;
+    }
+
+    std::unique_ptr<GrDrawOpAtlas> atlas(
+            new GrDrawOpAtlas(ctx, std::move(proxy), numPlotsX, numPlotsY));
+    atlas->registerEvictionCallback(func, data);
+    return atlas;
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 
 GrDrawOpAtlas::Plot::Plot(int index, uint64_t genID, int offX, int offY, int width, int height,
@@ -160,7 +198,7 @@
     }
 }
 
-inline void GrDrawOpAtlas::updatePlot(GrDrawOp::Target* target, AtlasID* id, Plot* plot) {
+inline bool GrDrawOpAtlas::updatePlot(GrDrawOp::Target* target, AtlasID* id, Plot* plot) {
     this->makeMRU(plot);
 
     // If our most recent upload has already occurred then we have to insert a new
@@ -169,19 +207,23 @@
     if (target->hasDrawBeenFlushed(plot->lastUploadToken())) {
         // With c+14 we could move sk_sp into lamba to only ref once.
         sk_sp<Plot> plotsp(SkRef(plot));
+
         // MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated.
         // Once it is deferred more care must be taken upon instantiation failure.
         GrTexture* texture = fProxy->instantiate(fContext->textureProvider());
-        if (texture) {
-            GrDrawOpUploadToken lastUploadToken = target->addAsapUpload(
-                [plotsp, texture] (GrDrawOp::WritePixelsFn& writePixels) {
-                   plotsp->uploadToTexture(writePixels, texture);
-                }
-            );
-            plot->setLastUploadToken(lastUploadToken);
+        if (!texture) {
+            return false;
         }
+
+        GrDrawOpUploadToken lastUploadToken = target->addAsapUpload(
+            [plotsp, texture] (GrDrawOp::WritePixelsFn& writePixels) {
+                plotsp->uploadToTexture(writePixels, texture);
+            }
+        );
+        plot->setLastUploadToken(lastUploadToken);
     }
     *id = plot->id();
+    return true;
 }
 
 bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width, int height,
@@ -199,8 +241,7 @@
     while ((plot = plotIter.get())) {
         SkASSERT(GrBytesPerPixel(fProxy->desc().fConfig) == plot->bpp());
         if (plot->addSubImage(width, height, image, loc)) {
-            this->updatePlot(target, id, plot);
-            return true;
+            return this->updatePlot(target, id, plot);
         }
         plotIter.next();
     }
@@ -215,7 +256,10 @@
         SkASSERT(GrBytesPerPixel(fProxy->desc().fConfig) == plot->bpp());
         SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc);
         SkASSERT(verify);
-        this->updatePlot(target, id, plot);
+        if (!this->updatePlot(target, id, plot)) {
+            return false;
+        }
+
         fAtlasGeneration++;
         return true;
     }
@@ -246,15 +290,17 @@
     // MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated.
     // Once it is deferred more care must be taken upon instantiation failure.
     GrTexture* texture = fProxy->instantiate(fContext->textureProvider());
-    if (texture) {
-        GrDrawOpUploadToken lastUploadToken = target->addInlineUpload(
-            [plotsp, texture] (GrDrawOp::WritePixelsFn& writePixels) {
-                plotsp->uploadToTexture(writePixels, texture);
-            }
-        );
-        newPlot->setLastUploadToken(lastUploadToken);
+    if (!texture) {
+        return false;
     }
 
+    GrDrawOpUploadToken lastUploadToken = target->addInlineUpload(
+        [plotsp, texture] (GrDrawOp::WritePixelsFn& writePixels) {
+            plotsp->uploadToTexture(writePixels, texture);
+        }
+    );
+    newPlot->setLastUploadToken(lastUploadToken);
+
     *id = newPlot->id();
 
     fAtlasGeneration++;
diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h
index 917d4ec..c857d07 100644
--- a/src/gpu/GrDrawOpAtlas.h
+++ b/src/gpu/GrDrawOpAtlas.h
@@ -55,7 +55,26 @@
      */
     typedef void (*EvictionFunc)(GrDrawOpAtlas::AtlasID, void*);
 
-    GrDrawOpAtlas(GrContext*, sk_sp<GrTextureProxy>, int numPlotsX, int numPlotsY);
+    /**
+     * Returns a GrDrawOpAtlas. This function can be called anywhere, but the returned atlas
+     * should only be used inside of GrMeshDrawOp::onPrepareDraws.
+     *  @param GrPixelConfig    The pixel config which this atlas will store
+     *  @param width            width in pixels of the atlas
+     *  @param height           height in pixels of the atlas
+     *  @param numPlotsX        The number of plots the atlas should be broken up into in the X
+     *                          direction
+     *  @param numPlotsY        The number of plots the atlas should be broken up into in the Y
+     *                          direction
+     *  @param func             An eviction function which will be called whenever the atlas has to
+     *                          evict data
+     *  @param data             User supplied data which will be passed into func whenver an
+     *                          eviction occurs
+     *  @return                 An initialized GrDrawOpAtlas, or nullptr if creation fails
+     */
+    static std::unique_ptr<GrDrawOpAtlas> Make(GrContext*, GrPixelConfig,
+                                               int width, int height,
+                                               int numPlotsX, int numPlotsY,
+                                               GrDrawOpAtlas::EvictionFunc func, void* data);
 
     /**
      * Adds a width x height subimage to the atlas. Upon success it returns an ID and the subimage's
@@ -158,6 +177,8 @@
     }
 
 private:
+    GrDrawOpAtlas(GrContext*, sk_sp<GrTextureProxy>, int numPlotsX, int numPlotsY);
+
     /**
      * The backing GrTexture for a GrDrawOpAtlas is broken into a spatial grid of Plots. The Plots
      * keep track of subimage placement via their GrRectanizer. A Plot manages the lifetime of its
@@ -253,7 +274,7 @@
         return (id >> 16) & 0xffffffffffff;
     }
 
-    inline void updatePlot(GrDrawOp::Target*, AtlasID*, Plot*);
+    inline bool updatePlot(GrDrawOp::Target*, AtlasID*, Plot*);
 
     inline void makeMRU(Plot* plot) {
         if (fPlotList.head() == plot) {
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index f1164a9..05673d5 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -124,7 +124,7 @@
      * fGammaCorrect          true if gamma-correct rendering is to be used.
      */
     struct DrawPathArgs {
-        GrResourceProvider*          fResourceProvider;
+        GrContext*                   fContext;
         GrPaint&&                    fPaint;
         const GrUserStencilSettings* fUserStencilSettings;
         GrRenderTargetContext*       fRenderTargetContext;
@@ -135,7 +135,7 @@
         bool                         fGammaCorrect;
 #ifdef SK_DEBUG
         void validate() const {
-            SkASSERT(fResourceProvider);
+            SkASSERT(fContext);
             SkASSERT(fUserStencilSettings);
             SkASSERT(fRenderTargetContext);
             SkASSERT(fClip);
@@ -153,7 +153,7 @@
         SkDEBUGCODE(args.validate();)
 #ifdef SK_DEBUG
         CanDrawPathArgs canArgs;
-        canArgs.fShaderCaps = args.fResourceProvider->caps()->shaderCaps();
+        canArgs.fShaderCaps = args.fContext->caps()->shaderCaps();
         canArgs.fViewMatrix = args.fViewMatrix;
         canArgs.fShape = args.fShape;
         canArgs.fAAType = args.fAAType;
@@ -183,7 +183,7 @@
      * fAAType                The type of AA, cannot be kCoverage.
      */
     struct StencilPathArgs {
-        GrResourceProvider*    fResourceProvider;
+        GrContext*             fContext;
         GrRenderTargetContext* fRenderTargetContext;
         const GrClip*          fClip;
         const SkMatrix*        fViewMatrix;
@@ -192,7 +192,7 @@
 
 #ifdef SK_DEBUG
         void validate() const {
-            SkASSERT(fResourceProvider);
+            SkASSERT(fContext);
             SkASSERT(fRenderTargetContext);
             SkASSERT(fViewMatrix);
             SkASSERT(fShape);
@@ -277,7 +277,7 @@
 
         GrPaint paint;
 
-        DrawPathArgs drawArgs{args.fResourceProvider,
+        DrawPathArgs drawArgs{args.fContext,
                               std::move(paint),
                               &kIncrementStencil,
                               args.fRenderTargetContext,
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 4dd81c2..8105ed4 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -781,7 +781,7 @@
                         GrPaint paint;
                         paint.setXPFactory(GrDisableColorXPFactory::Get());
 
-                        GrPathRenderer::DrawPathArgs args{context->resourceProvider(),
+                        GrPathRenderer::DrawPathArgs args{context,
                                                           std::move(paint),
                                                           &kDrawToStencil,
                                                           renderTargetContext,
@@ -793,7 +793,7 @@
                         pr->drawPath(args);
                     } else {
                         GrPathRenderer::StencilPathArgs args;
-                        args.fResourceProvider = context->resourceProvider();
+                        args.fContext = context;
                         args.fRenderTargetContext = renderTargetContext;
                         args.fClip = &stencilClip.fixedClip();
                         args.fViewMatrix = &viewMatrix;
@@ -816,7 +816,7 @@
                     GrShape shape(clipPath, GrStyle::SimpleFill());
                     GrPaint paint;
                     paint.setXPFactory(GrDisableColorXPFactory::Get());
-                    GrPathRenderer::DrawPathArgs args{context->resourceProvider(),
+                    GrPathRenderer::DrawPathArgs args{context,
                                                       std::move(paint),
                                                       *pass,
                                                       renderTargetContext,
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index a980818..8b6de51 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1496,7 +1496,7 @@
     paint.setCoverageSetOpXPFactory(op, invert);
 
     GrPathRenderer::DrawPathArgs args{
-            fRenderTargetContext->drawingManager()->getContext()->resourceProvider(),
+            fRenderTargetContext->drawingManager()->getContext(),
             std::move(paint),
             ss,
             fRenderTargetContext,
@@ -1593,7 +1593,7 @@
         return;
     }
 
-    GrPathRenderer::DrawPathArgs args{this->drawingManager()->getContext()->resourceProvider(),
+    GrPathRenderer::DrawPathArgs args{this->drawingManager()->getContext(),
                                       std::move(paint),
                                       &GrUserStencilSettings::kUnused,
                                       this,
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 2dd17b7..deb400c 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -135,42 +135,6 @@
     return buffer;
 }
 
-std::unique_ptr<GrDrawOpAtlas> GrResourceProvider::makeAtlas(GrContext* context,
-                                                             GrPixelConfig config, int width,
-                                                             int height, int numPlotsX,
-                                                             int numPlotsY,
-                                                             GrDrawOpAtlas::EvictionFunc func,
-                                                             void* data) {
-    GrSurfaceDesc desc;
-    desc.fFlags = kNone_GrSurfaceFlags;
-    desc.fWidth = width;
-    desc.fHeight = height;
-    desc.fConfig = config;
-
-    // We don't want to flush the context so we claim we're in the middle of flushing so as to
-    // guarantee we do not recieve a texture with pending IO
-    // TODO: Determine how to avoid having to do this. (https://bug.skia.org/4156)
-    static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag;
-    sk_sp<GrTexture> texture(this->createApproxTexture(desc, kFlags));
-    if (!texture) {
-        return nullptr;
-    }
-    // MDB TODO: for now, wrap an instantiated texture. Having the deferred instantiation
-    // possess the correct properties (e.g., no pendingIO) should fall out of the system but
-    // should receive special attention.
-    // Note: When switching over to the deferred proxy, use the kExact flag to create
-    // the atlas.
-    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(texture));
-    if (!proxy) {
-        return nullptr;
-    }
-
-    std::unique_ptr<GrDrawOpAtlas> atlas(
-            new GrDrawOpAtlas(context, std::move(proxy), numPlotsX, numPlotsY));
-    atlas->registerEvictionCallback(func, data);
-    return atlas;
-}
-
 GrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
     SkASSERT(rt);
     if (rt->renderTargetPriv().getStencilAttachment()) {
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 091d2db..c0d1a50 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -131,26 +131,6 @@
     }
 
     /**
-     * Returns a GrDrawOpAtlas. This function can be called anywhere, but the returned atlas
-     * should only be used inside of GrMeshDrawOp::onPrepareDraws.
-     *  @param GrPixelConfig    The pixel config which this atlas will store
-     *  @param width            width in pixels of the atlas
-     *  @param height           height in pixels of the atlas
-     *  @param numPlotsX        The number of plots the atlas should be broken up into in the X
-     *                          direction
-     *  @param numPlotsY        The number of plots the atlas should be broken up into in the Y
-     *                          direction
-     *  @param func             An eviction function which will be called whenever the atlas has to
-     *                          evict data
-     *  @param data             User supplied data which will be passed into func whenver an
-     *                          eviction occurs
-     *  @return                 An initialized GrDrawOpAtlas, or nullptr if creation fails
-     */
-    std::unique_ptr<GrDrawOpAtlas> makeAtlas(GrContext*, GrPixelConfig, int width, int height,
-                                             int numPlotsX, int numPlotsY,
-                                             GrDrawOpAtlas::EvictionFunc func, void* data);
-
-    /**
      * If passed in render target already has a stencil buffer, return it. Otherwise attempt to
      * attach one.
      */
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 695796b..5ed9f42 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -206,7 +206,7 @@
 
     sk_sp<GrTexture> texture;
     if (useCache) {
-        texture.reset(args.fResourceProvider->findAndRefTextureByUniqueKey(maskKey));
+        texture.reset(args.fContext->textureProvider()->findAndRefTextureByUniqueKey(maskKey));
     }
     if (!texture) {
         SkBackingFit fit = useCache ? SkBackingFit::kExact : SkBackingFit::kApprox;
diff --git a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
index b4c0c52..a856ba6 100644
--- a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
@@ -746,12 +746,12 @@
     SkASSERT(!args.fShape->isEmpty());
     SkASSERT(args.fShape->hasUnstyledKey());
     if (!fAtlas) {
-        fAtlas = args.fResourceProvider->makeAtlas(args.fResourceProvider->context(),
-                                                   kAlpha_8_GrPixelConfig,
-                                                   ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT,
-                                                   NUM_PLOTS_X, NUM_PLOTS_Y,
-                                                   &GrAADistanceFieldPathRenderer::HandleEviction,
-                                                   (void*)this);
+        fAtlas = GrDrawOpAtlas::Make(args.fContext,
+                                     kAlpha_8_GrPixelConfig,
+                                     ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT,
+                                     NUM_PLOTS_X, NUM_PLOTS_Y,
+                                     &GrAADistanceFieldPathRenderer::HandleEviction,
+                                     (void*)this);
         if (!fAtlas) {
             return false;
         }
@@ -820,12 +820,11 @@
     if (context->uniqueID() != gTestStruct.fContextID) {
         gTestStruct.fContextID = context->uniqueID();
         gTestStruct.reset();
-        gTestStruct.fAtlas =
-                context->resourceProvider()->makeAtlas(context, kAlpha_8_GrPixelConfig,
-                                                       ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT,
-                                                       NUM_PLOTS_X, NUM_PLOTS_Y,
-                                                       &PathTestStruct::HandleEviction,
-                                                       (void*)&gTestStruct);
+        gTestStruct.fAtlas = GrDrawOpAtlas::Make(context, kAlpha_8_GrPixelConfig,
+                                                 ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT,
+                                                 NUM_PLOTS_X, NUM_PLOTS_Y,
+                                                 &PathTestStruct::HandleEviction,
+                                                 (void*)&gTestStruct);
     }
 
     SkMatrix viewMatrix = GrTest::TestMatrix(random);
diff --git a/src/gpu/text/GrAtlasGlyphCache.cpp b/src/gpu/text/GrAtlasGlyphCache.cpp
index cf56c89..213ecfc 100644
--- a/src/gpu/text/GrAtlasGlyphCache.cpp
+++ b/src/gpu/text/GrAtlasGlyphCache.cpp
@@ -26,7 +26,7 @@
         int numPlotsX = fAtlasConfigs[index].numPlotsX();
         int numPlotsY = fAtlasConfigs[index].numPlotsY();
 
-        fAtlases[index] = fContext->resourceProvider()->makeAtlas(
+        fAtlases[index] = GrDrawOpAtlas::Make(
                 fContext, config, width, height, numPlotsX, numPlotsY,
                 &GrAtlasGlyphCache::HandleEviction, (void*)this);
         if (!fAtlases[index]) {