Revert "Remove SkRuntimeShader::makeImage."

This reverts commit 65967ab2c9f6e9f3e667901bf86f4b791e0f782b.

Reason for revert: used in Android - http://screen/3fk6K3RUWZG8x5f

Original change's description:
> Remove SkRuntimeShader::makeImage.
>
> We don't have any known users, and it no longer exposes anything that
> a user can't just do directly.
>
> Change-Id: Id653a6be3f265a2847b1670f3e6c054cf2d094a2
> Bug: skia:12482
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/453142
> Auto-Submit: John Stiles <johnstiles@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>

Bug: skia:12482
Change-Id: I6cc2e79796f53c42e9f53b7d9927c853e7e2d71c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/453317
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Owners-Override: Kevin Lubick <kjlubick@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index bf943bb..f184ee3 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -7,9 +7,6 @@
   * Minimum supported iOS raised from 8 to 11. Skia may build back to iOS 9 but versions older
     than 11 are not tested. Community contributions to support versions 9 and 10 of iOS may be
     considered, but they may not be complex as they cannot be tested.
-  * Removed SkRuntimeEffect::makeImage. This didn't end up providing any useful benefit compared
-    to the general-case SkRuntimeEffect::makeShader API.
-    https://review.skia.org/453142
 
 * * *
 
diff --git a/include/effects/SkRuntimeEffect.h b/include/effects/SkRuntimeEffect.h
index 270abfb..b3f21b1 100644
--- a/include/effects/SkRuntimeEffect.h
+++ b/include/effects/SkRuntimeEffect.h
@@ -192,6 +192,13 @@
                                const SkMatrix* localMatrix,
                                bool isOpaque) const;
 
+    sk_sp<SkImage> makeImage(GrRecordingContext*,
+                             sk_sp<SkData> uniforms,
+                             SkSpan<ChildPtr> children,
+                             const SkMatrix* localMatrix,
+                             SkImageInfo resultInfo,
+                             bool mipmapped) const;
+
     sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> uniforms) const;
     sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> uniforms,
                                          sk_sp<SkColorFilter> children[],
@@ -443,6 +450,10 @@
     ~SkRuntimeShaderBuilder();
 
     sk_sp<SkShader> makeShader(const SkMatrix* localMatrix, bool isOpaque);
+    sk_sp<SkImage> makeImage(GrRecordingContext*,
+                             const SkMatrix* localMatrix,
+                             SkImageInfo resultInfo,
+                             bool mipmapped);
 
 private:
     using INHERITED = SkRuntimeEffectBuilder;
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index ad14f97..d6fddb2 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -1254,6 +1254,88 @@
                                           children, isOpaque));
 }
 
+sk_sp<SkImage> SkRuntimeEffect::makeImage(GrRecordingContext* rContext,
+                                          sk_sp<SkData> uniforms,
+                                          SkSpan<ChildPtr> children,
+                                          const SkMatrix* localMatrix,
+                                          SkImageInfo resultInfo,
+                                          bool mipmapped) const {
+    if (rContext) {
+#if SK_SUPPORT_GPU
+        if (!rContext->priv().caps()->mipmapSupport()) {
+            mipmapped = false;
+        }
+        auto fillContext = rContext->priv().makeSFC(resultInfo,
+                                                    SkBackingFit::kExact,
+                                                    /*sample count*/ 1,
+                                                    GrMipmapped(mipmapped));
+        if (!fillContext) {
+            return nullptr;
+        }
+        uniforms = get_xformed_uniforms(this, std::move(uniforms), resultInfo.colorSpace());
+        SkASSERT(uniforms);
+
+        SkSimpleMatrixProvider matrixProvider(SkMatrix::I());
+        GrColorInfo colorInfo(resultInfo.colorInfo());
+        GrFPArgs args(rContext, matrixProvider, &colorInfo);
+        SkSTArray<8, std::unique_ptr<GrFragmentProcessor>> childFPs;
+        for (size_t i = 0; i < children.size(); ++i) {
+            // TODO: add support for other types of child effects
+            if (SkShader* shader = children[i].shader()) {
+                childFPs.push_back(as_SB(shader)->asFragmentProcessor(args));
+            } else {
+                return nullptr;
+            }
+        }
+        auto fp = GrSkSLFP::MakeWithData(sk_ref_sp(this),
+                                         "runtime_image",
+                                         /*inputFP=*/nullptr,
+                                         /*destColorFP=*/nullptr,
+                                         std::move(uniforms),
+                                         SkMakeSpan(childFPs));
+
+        if (localMatrix) {
+            SkMatrix invLM;
+            if (!localMatrix->invert(&invLM)) {
+                return nullptr;
+            }
+            fillContext->fillWithFP(invLM, std::move(fp));
+        } else {
+            fillContext->fillWithFP(std::move(fp));
+        }
+        return sk_sp<SkImage>(new SkImage_Gpu(sk_ref_sp(rContext),
+                                              kNeedNewImageUniqueID,
+                                              fillContext->readSurfaceView(),
+                                              resultInfo.colorInfo()));
+#else
+        return nullptr;
+#endif
+    }
+    if (resultInfo.alphaType() == kUnpremul_SkAlphaType) {
+        // We don't have a good way of supporting this right now. In this case the runtime effect
+        // will produce a unpremul value. The shader generated from it is assumed to produce
+        // premul and RGB get pinned to A. Moreover, after the blend in premul the new dst is
+        // unpremul'ed, producing a double unpremul result.
+        return nullptr;
+    }
+    auto surf = SkSurface::MakeRaster(resultInfo);
+    if (!surf) {
+        return nullptr;
+    }
+    SkCanvas* canvas = surf->getCanvas();
+    SkTLazy<SkCanvas> tempCanvas;
+    auto shader = this->makeShader(std::move(uniforms), children, localMatrix, false);
+    if (!shader) {
+        return nullptr;
+    }
+    SkPaint paint;
+    paint.setShader(std::move(shader));
+    paint.setBlendMode(SkBlendMode::kSrc);
+    canvas->drawPaint(paint);
+    // TODO: Specify snapshot should have mip levels if mipmapped is true.
+    return surf->makeImageSnapshot();
+}
+
 sk_sp<SkColorFilter> SkRuntimeEffect::makeColorFilter(sk_sp<SkData> uniforms,
                                                       sk_sp<SkColorFilter> childColorFilters[],
                                                       size_t childCount) const {
@@ -1352,6 +1434,18 @@
 
 SkRuntimeShaderBuilder::~SkRuntimeShaderBuilder() = default;
 
+sk_sp<SkImage> SkRuntimeShaderBuilder::makeImage(GrRecordingContext* recordingContext,
+                                                 const SkMatrix* localMatrix,
+                                                 SkImageInfo resultInfo,
+                                                 bool mipmapped) {
+    return this->effect()->makeImage(recordingContext,
+                                     this->uniforms(),
+                                     SkMakeSpan(this->children(), this->numChildren()),
+                                     localMatrix,
+                                     resultInfo,
+                                     mipmapped);
+}
+
 sk_sp<SkShader> SkRuntimeShaderBuilder::makeShader(const SkMatrix* localMatrix, bool isOpaque) {
     return this->effect()->makeShader(this->uniforms(),
                                       SkMakeSpan(this->children(), this->numChildren()),