Move atlas -> shader conversion up to SkCanvas

This makes the SkDevice interface and code simpler, and also opens the
door to a version of drawAtlas that takes a more complex SkShader (on
the SkPaint), rather than just a single SkImage.

Bug: skia:11942
Change-Id: I557bd2f03b85940b29954cb994916d5566bd7747
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/458980
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/experimental/graphite/src/Device.h b/experimental/graphite/src/Device.h
index baae84c..cd6481c 100644
--- a/experimental/graphite/src/Device.h
+++ b/experimental/graphite/src/Device.h
@@ -91,8 +91,7 @@
                        SkCanvas::SrcRectConstraint) override {}
     void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
                           const SkRect& dst, SkFilterMode, const SkPaint&) override {}
-    void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
-                   const SkColor[], int count, SkBlendMode, const SkSamplingOptions&,
+    void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, SkBlendMode,
                    const SkPaint&) override {}
 
     void drawDrawable(SkDrawable*, const SkMatrix*, SkCanvas*) override {}
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 9eaf54e..a486f51 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -548,16 +548,18 @@
     BDDraw(this).drawVertices(vertices, bmode, paint);
 }
 
-void SkBitmapDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
-                               const SkRect tex[], const SkColor colors[], int count,
-                               SkBlendMode mode, const SkSamplingOptions& sampling,
+void SkBitmapDevice::drawAtlas(const SkRSXform xform[],
+                               const SkRect tex[],
+                               const SkColor colors[],
+                               int count,
+                               SkBlendMode mode,
                                const SkPaint& paint) {
     // set this to true for performance comparisons with the old drawVertices way
     if (false) {
-        this->INHERITED::drawAtlas(atlas, xform, tex, colors, count, mode, sampling, paint);
+        this->INHERITED::drawAtlas(xform, tex, colors, count, mode, paint);
         return;
     }
-    BDDraw(this).drawAtlas(atlas, xform, tex, colors, count, mode, sampling, paint);
+    BDDraw(this).drawAtlas(xform, tex, colors, count, mode, paint);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkBitmapDevice.h b/src/core/SkBitmapDevice.h
index c781ba3..c6aeedc 100644
--- a/src/core/SkBitmapDevice.h
+++ b/src/core/SkBitmapDevice.h
@@ -95,8 +95,8 @@
                        SkCanvas::SrcRectConstraint) override;
 
     void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
-    void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int count,
-                   SkBlendMode, const SkSamplingOptions&, const SkPaint&) override;
+    void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, SkBlendMode,
+                   const SkPaint&) override;
 
     ///////////////////////////////////////////////////////////////////////////
 
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 95a6f2e..1e1dd26 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2422,13 +2422,14 @@
                             const SkPaint* paint) {
     // drawAtlas is a combination of drawVertices and drawImage...
     SkPaint realPaint = clean_paint_for_drawVertices(clean_paint_for_drawImage(paint));
+    realPaint.setShader(atlas->makeShader(sampling));
 
     if (cull && this->internalQuickReject(*cull, realPaint)) {
         return;
     }
 
     AutoLayerForImageFilter layer(this, realPaint);
-    this->topDevice()->drawAtlas(atlas, xform, tex, colors, count, bmode, sampling, layer.paint());
+    this->topDevice()->drawAtlas(xform, tex, colors, count, bmode, layer.paint());
 }
 
 void SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 1625764..8307fee 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -208,9 +208,11 @@
     return tris + 6;
 }
 
-void SkBaseDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
-                             const SkRect tex[], const SkColor colors[], int quadCount,
-                             SkBlendMode mode, const SkSamplingOptions& sampling,
+void SkBaseDevice::drawAtlas(const SkRSXform xform[],
+                             const SkRect tex[],
+                             const SkColor colors[],
+                             int quadCount,
+                             SkBlendMode mode,
                              const SkPaint& paint) {
     const int triCount = quadCount << 1;
     const int vertexCount = triCount * 3;
@@ -236,12 +238,9 @@
             vCol += 6;
         }
     }
-    SkPaint p(paint);
-    p.setShader(atlas->makeShader(sampling));
-    this->drawVertices(builder.detach().get(), mode, p);
+    this->drawVertices(builder.detach().get(), mode, paint);
 }
 
-
 void SkBaseDevice::drawEdgeAAQuad(const SkRect& r, const SkPoint clip[4], SkCanvas::QuadAAFlags aa,
                                   const SkColor4f& color, SkBlendMode mode) {
     SkPaint paint;
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index e98ace4..c61d6bb 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -277,10 +277,9 @@
     virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
                            const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
 
-    // default implementation calls drawPath
-    virtual void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
-                           const SkColor[], int count, SkBlendMode, const SkSamplingOptions&,
-                           const SkPaint&);
+    // default implementation calls drawVertices
+    virtual void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count,
+                           SkBlendMode, const SkPaint&);
 
     virtual void drawAnnotation(const SkRect&, const char[], SkData*) {}
 
diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h
index c08554e..57302aa 100644
--- a/src/core/SkDraw.h
+++ b/src/core/SkDraw.h
@@ -65,8 +65,8 @@
                              const SkPaint& paint,
                              SkGlyphRunListPainter* glyphPainter) const;
     void    drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) const;
-    void  drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int count,
-                    SkBlendMode, const SkSamplingOptions&, const SkPaint&);
+    void  drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count,
+                    SkBlendMode, const SkPaint&);
 
     /**
      *  Overwrite the target with the path's coverage (i.e. its mask).
diff --git a/src/core/SkDraw_atlas.cpp b/src/core/SkDraw_atlas.cpp
index 8ead762..4f5882c 100644
--- a/src/core/SkDraw_atlas.cpp
+++ b/src/core/SkDraw_atlas.cpp
@@ -86,10 +86,13 @@
     mutable float fValues[4];
 };
 
-void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect textures[],
-                       const SkColor colors[], int count, SkBlendMode bmode,
-                       const SkSamplingOptions& sampling, const SkPaint& paint) {
-    sk_sp<SkShader> atlasShader = atlas->makeShader(sampling);
+void SkDraw::drawAtlas(const SkRSXform xform[],
+                       const SkRect textures[],
+                       const SkColor colors[],
+                       int count,
+                       SkBlendMode bmode,
+                       const SkPaint& paint) {
+    sk_sp<SkShader> atlasShader = paint.refShader();
     if (!atlasShader) {
         return;
     }
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 8244179..6dce99d 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -606,22 +606,6 @@
                                    /*shaderProcessor=*/nullptr, &primColorMode, grPaint);
 }
 
-/** Blends the passed-in shader with a per-primitive color which must be setup as a vertex attribute
-    using the specified SkBlendMode. */
-bool SkPaintToGrPaintWithBlendReplaceShader(GrRecordingContext* context,
-                                            const GrColorInfo& dstColorInfo,
-                                            const SkPaint& skPaint,
-                                            const SkMatrixProvider& matrixProvider,
-                                            std::unique_ptr<GrFragmentProcessor> shaderFP,
-                                            SkBlendMode primColorMode,
-                                            GrPaint* grPaint) {
-    if (!shaderFP) {
-        return false;
-    }
-    return skpaint_to_grpaint_impl(context, dstColorInfo, skPaint, matrixProvider, &shaderFP,
-                                   &primColorMode, grPaint);
-}
-
 bool SkPaintToGrPaintWithTexture(GrRecordingContext* context,
                                  const GrColorInfo& dstColorInfo,
                                  const SkPaint& paint,
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index e66cd5d..b1de887 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -108,16 +108,6 @@
                                SkBlendMode primColorMode,
                                GrPaint* grPaint);
 
-/** Blends the passed-in shader with a per-primitive color which must be setup as a vertex attribute
-    using the specified SkBlendMode. */
-bool SkPaintToGrPaintWithBlendReplaceShader(GrRecordingContext* context,
-                                            const GrColorInfo& dstColorInfo,
-                                            const SkPaint& skPaint,
-                                            const SkMatrixProvider& matrixProvider,
-                                            std::unique_ptr<GrFragmentProcessor> shaderFP,
-                                            SkBlendMode primColorMode,
-                                            GrPaint* grPaint);
-
 /** This is used when there is a primitive color, but the shader should be ignored. Currently,
     the expectation is that the primitive color will be premultiplied, though it really should be
     unpremultiplied so that interpolation is done in unpremul space. The paint's alpha will be
diff --git a/src/gpu/v1/Device.cpp b/src/gpu/v1/Device.cpp
index 99997b0..91cde8a 100644
--- a/src/gpu/v1/Device.cpp
+++ b/src/gpu/v1/Device.cpp
@@ -849,38 +849,24 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void Device::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
-                       const SkRect texRect[], const SkColor colors[], int count,
-                       SkBlendMode mode, const SkSamplingOptions& sampling,
+void Device::drawAtlas(const SkRSXform xform[],
+                       const SkRect texRect[],
+                       const SkColor colors[],
+                       int count,
+                       SkBlendMode mode,
                        const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v1::Device", "drawAtlas", fContext.get());
 
-    // Convert atlas to an image shader.
-    sk_sp<SkShader> shader = atlas->makeShader(sampling);
-    if (!shader) {
-        return;
-    }
-
-    // Create a fragment processor for atlas image.
-    GrFPArgs fpArgs(fContext.get(), this->asMatrixProvider(), &fSurfaceDrawContext->colorInfo());
-
-    std::unique_ptr<GrFragmentProcessor> shaderFP = as_SB(shader)->asFragmentProcessor(fpArgs);
-    if (shaderFP == nullptr) {
-        return;
-    }
-
     GrPaint grPaint;
     if (colors) {
-        if (!SkPaintToGrPaintWithBlendReplaceShader(
-                    this->recordingContext(), fSurfaceDrawContext->colorInfo(), paint,
-                    this->asMatrixProvider(), std::move(shaderFP), mode, &grPaint)) {
+        if (!SkPaintToGrPaintWithBlend(this->recordingContext(), fSurfaceDrawContext->colorInfo(),
+                                       paint, this->asMatrixProvider(), mode, &grPaint)) {
             return;
         }
     } else {
-        if (!SkPaintToGrPaintReplaceShader(
-                    this->recordingContext(), fSurfaceDrawContext->colorInfo(), paint,
-                    this->asMatrixProvider(), std::move(shaderFP), &grPaint)) {
+        if (!SkPaintToGrPaint(this->recordingContext(), fSurfaceDrawContext->colorInfo(),
+                              paint, this->asMatrixProvider(), &grPaint)) {
             return;
         }
     }
diff --git a/src/gpu/v1/Device_v1.h b/src/gpu/v1/Device_v1.h
index dbe8c68..3e9aff8 100644
--- a/src/gpu/v1/Device_v1.h
+++ b/src/gpu/v1/Device_v1.h
@@ -115,8 +115,8 @@
     void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override;
     void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
     void drawShadow(const SkPath&, const SkDrawShadowRec&) override;
-    void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[], const SkColor[],
-                   int count, SkBlendMode, const SkSamplingOptions&, const SkPaint&) override;
+    void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, SkBlendMode,
+                   const SkPaint&) override;
 
     void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
                        const SkSamplingOptions&, const SkPaint&,
diff --git a/src/gpu/v2/Device.cpp b/src/gpu/v2/Device.cpp
index 1065780..3219805 100644
--- a/src/gpu/v2/Device.cpp
+++ b/src/gpu/v2/Device.cpp
@@ -263,13 +263,11 @@
     GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v2::Device", "drawShadow", fContext.get());
 }
 
-void Device::drawAtlas(const SkImage* atlas,
-                       const SkRSXform xform[],
+void Device::drawAtlas(const SkRSXform xform[],
                        const SkRect texRect[],
                        const SkColor colors[],
                        int count,
                        SkBlendMode mode,
-                       const SkSamplingOptions& sampling,
                        const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v2::Device", "drawAtlas", fContext.get());
diff --git a/src/gpu/v2/Device_v2.h b/src/gpu/v2/Device_v2.h
index c4629cd..9b2838a 100644
--- a/src/gpu/v2/Device_v2.h
+++ b/src/gpu/v2/Device_v2.h
@@ -109,8 +109,8 @@
     void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
     void drawShadow(const SkPath&, const SkDrawShadowRec&) override;
     /* drawPatch */
-    void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[], const SkColor[],
-                   int count, SkBlendMode, const SkSamplingOptions&, const SkPaint&) override;
+    void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[],
+                   int count, SkBlendMode, const SkPaint&) override;
     /* drawAnnotation */
     void drawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], SkCanvas::QuadAAFlags aaFlags,
                         const SkColor4f& color, SkBlendMode) override;