[Maintenance] Feed SkSerialProcs to SkBinaryWriteBuffer

Instead of passing an empty SkSerialProcs struct, create one that encodes images as pngs to SkBinaryWriteBuffer

Change-Id: Icaf529db67f3f46c8e4e454b50b704c1e13a5780
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1279256
Reviewed-by: Kaylee Lubick <kjlubick@google.com>
Commit-Queue: Alexis Cruz-Ayala <alexisdavidc@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 88bdd46..13d8427 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2102,12 +2102,14 @@
     public_configs = [ ":skia_public" ]
 
     sources = [
+      "tools/ProcsUtils.cpp",
       "tools/SkSharingProc.cpp",
       "tools/UrlDataManager.cpp",
       "tools/debugger/DebugCanvas.cpp",
       "tools/debugger/DebugLayerManager.cpp",
       "tools/debugger/DrawCommand.cpp",
       "tools/debugger/JsonWriteBuffer.cpp",
+      "tools/fonts/FontToolUtils.cpp",
     ]
   }
 }
@@ -2601,14 +2603,14 @@
       "tools/AutoreleasePool.h",
       "tools/DecodeUtils.cpp",
       "tools/DecodeUtils.h",
-      "tools/DeserialProcsUtils.cpp",
-      "tools/DeserialProcsUtils.h",
       "tools/EncodeUtils.cpp",
       "tools/EncodeUtils.h",
       "tools/GpuToolUtils.h",
       "tools/LsanSuppressions.cpp",
       "tools/ProcStats.cpp",
       "tools/ProcStats.h",
+      "tools/ProcsUtils.cpp",
+      "tools/ProcsUtils.h",
       "tools/Resources.cpp",
       "tools/Resources.h",
       "tools/RuntimeBlendUtils.cpp",
@@ -3170,6 +3172,7 @@
         "fuzz/oss_fuzz/FuzzSkRuntimeColorFilter.cpp",
         "fuzz/oss_fuzz/FuzzSkRuntimeEffect.cpp",
         "fuzz/oss_fuzz/FuzzTextBlobDeserialize.cpp",
+        "tools/ProcsUtils.cpp",
         "tools/UrlDataManager.cpp",
         "tools/debugger/DebugCanvas.cpp",
         "tools/debugger/DebugLayerManager.cpp",
diff --git a/bench/ResultsWriter.h b/bench/ResultsWriter.h
index cb33915..ee2a090 100644
--- a/bench/ResultsWriter.h
+++ b/bench/ResultsWriter.h
@@ -13,6 +13,7 @@
 #include "include/core/SkString.h"
 #include "include/core/SkTypes.h"
 #include "src/utils/SkJSONWriter.h"
+
 #include <cmath>
 
 /**
@@ -38,7 +39,8 @@
 */
 class NanoJSONResultsWriter : public SkJSONWriter {
 public:
-    NanoJSONResultsWriter(SkWStream* stream, Mode mode) : SkJSONWriter(stream, mode) {}
+    NanoJSONResultsWriter(SkWStream* stream, SkSerialProcs serialProcs, Mode mode)
+            : SkJSONWriter(stream, serialProcs, mode) {}
 
     void beginBench(const char* name, int32_t x, int32_t y) {
         SkString id = SkStringPrintf("%s_%d_%d", name, x, y);
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index 5e2bb8e..36e6f0d 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -5,8 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include <ctype.h>
-
 #include "bench/nanobench.h"
 
 #include "bench/AndroidCodecBench.h"
@@ -48,9 +46,9 @@
 #include "src/utils/SkShaderUtils.h"
 #include "tools/AutoreleasePool.h"
 #include "tools/CrashHandler.h"
-#include "tools/DeserialProcsUtils.h"
 #include "tools/MSKPPlayer.h"
 #include "tools/ProcStats.h"
+#include "tools/ProcsUtils.h"
 #include "tools/Stats.h"
 #include "tools/ToolUtils.h"
 #include "tools/flags/CommonFlags.h"
@@ -61,6 +59,8 @@
 #include "tools/trace/EventTracingPriv.h"
 #include "tools/trace/SkDebugfTracer.h"
 
+#include <ctype.h>
+
 #if defined(SK_ENABLE_SVG)
 #include "modules/skshaper/utils/FactoryHelpers.h"
 #include "modules/svg/include/SkSVGDOM.h"
@@ -875,7 +875,7 @@
             SkDebugf("Could not read %s.\n", path);
             return nullptr;
         }
-        SkDeserialProcs procs = ToolUtils::get_default_skp_deserial_procs();
+        SkDeserialProcs procs = ToolUtils::default_deserial_procs();
         return SkPicture::MakeFromStream(stream.get(), &procs);
     }
 
@@ -1433,7 +1433,8 @@
         return 1;
 #endif
     }
-    NanoJSONResultsWriter log(logStream.get(), SkJSONWriter::Mode::kPretty);
+    NanoJSONResultsWriter log(
+            logStream.get(), ToolUtils::default_serial_procs(), SkJSONWriter::Mode::kPretty);
     log.beginObject(); // root
 
     if (1 == FLAGS_properties.size() % 2) {
diff --git a/dm/DMJsonWriter.cpp b/dm/DMJsonWriter.cpp
index 13d61a2..5e0b9c2 100644
--- a/dm/DMJsonWriter.cpp
+++ b/dm/DMJsonWriter.cpp
@@ -16,6 +16,7 @@
 #include "src/utils/SkJSONWriter.h"
 #include "src/utils/SkOSPath.h"
 #include "tools/ProcStats.h"
+#include "tools/ProcsUtils.h"
 
 using namespace skia_private;
 
@@ -43,7 +44,7 @@
     SkString path = SkOSPath::Join(dir, "dm.json");
     sk_mkdir(dir);
     SkFILEWStream stream(path.c_str());
-    SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
+    SkJSONWriter  writer(&stream, ToolUtils::default_serial_procs(), SkJSONWriter::Mode::kPretty);
 
     writer.beginObject(); // root
 
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 08ec5c1..c0d1f42 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "dm/DMSrcSink.h"
+
 #include "include/codec/SkAndroidCodec.h"
 #include "include/codec/SkCodec.h"
 #include "include/codec/SkPixmapUtils.h"
@@ -57,9 +58,9 @@
 #include "src/utils/SkJSONWriter.h"
 #include "src/utils/SkMultiPictureDocumentPriv.h"
 #include "src/utils/SkOSPath.h"
-#include "tools/DeserialProcsUtils.h"
 #include "tools/EncodeUtils.h"
 #include "tools/GpuToolUtils.h"
+#include "tools/ProcsUtils.h"
 #include "tools/Resources.h"
 #include "tools/RuntimeBlendUtils.h"
 #include "tools/ToolUtils.h"
@@ -1174,7 +1175,7 @@
 #endif
     };
 
-    SkDeserialProcs procs = ToolUtils::get_default_skp_deserial_procs();
+    SkDeserialProcs procs = ToolUtils::default_deserial_procs();
 
     // We override the default fImageDataProc set above
     procs.fImageDataProc =
@@ -1484,7 +1485,7 @@
         if (!stream) {
             return Result::Fatal("Unable to open file: %s", fPath.c_str());
         }
-        SkDeserialProcs dprocs = ToolUtils::get_default_skp_deserial_procs();
+        SkDeserialProcs dprocs = ToolUtils::default_deserial_procs();
         if (!SkMultiPictureDocument::Read(stream.get(), &fPages[0], fPages.size(), &dprocs)) {
             return Result::Fatal("SkMultiPictureDocument reader failed on page %d: %s", i,
                                  fPath.c_str());
@@ -2090,34 +2091,6 @@
 }
 #endif
 
-static SkSerialProcs serial_procs_using_png() {
-    static SkSerialProcs procs{.fImageProc = [](SkImage* img, void*) -> sk_sp<const SkData> {
-#if defined(SK_CODEC_ENCODES_PNG_WITH_LIBPNG)
-        return SkPngEncoder::Encode(as_IB(img)->directContext(), img, {});
-#elif defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
-        return SkPngRustEncoder::Encode(as_IB(img)->directContext(), img, {});
-#else
-        // TODO: This catches SkImageEncoder_NDK (or other).
-        return SkPngEncoder::Encode(as_IB(img)->directContext(), img, {});
-#endif
-    }};
-    return procs;
-}
-
-static SkDeserialProcs deserial_procs_using_png() {
-    static SkDeserialProcs procs{.fImageDataProc = [](sk_sp<SkData> data,
-                                                      std::optional<SkAlphaType> alphaType,
-                                                      void*) -> sk_sp<SkImage> {
-#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
-        std::unique_ptr<SkStream> stream = SkMemoryStream::Make(data);
-        auto codec = SkPngRustDecoder::Decode(std::move(stream), nullptr, nullptr);
-#else
-        auto codec = SkPngDecoder::Decode(data, nullptr, nullptr);
-#endif
-        return SkCodecs::DeferredImage(std::move(codec), alphaType);
-    }};
-    return procs;
-}
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
@@ -2131,7 +2104,7 @@
     if (!result.isOk()) {
         return result;
     }
-    SkSerialProcs procs = serial_procs_using_png();
+    SkSerialProcs procs = ToolUtils::default_serial_procs();
     recorder.finishRecordingAsPicture()->serialize(dst, &procs);
     return Result::Ok();
 }
@@ -2146,7 +2119,7 @@
     }
     std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
     UrlDataManager dataManager(SkString("data"));
-    SkJSONWriter writer(dst, SkJSONWriter::Mode::kPretty);
+    SkJSONWriter              writer(dst, ToolUtils::default_serial_procs(), SkJSONWriter::Mode::kPretty);
     writer.beginObject(); // root
     debugCanvas.toJSON(writer, dataManager, nullCanvas.get());
     writer.endObject(); // root
@@ -2725,8 +2698,8 @@
     }
     sk_sp<SkPicture> pic(recorder.finishRecordingAsPicture());
 
-    SkSerialProcs procs = serial_procs_using_png();
-    SkDeserialProcs dProcs = deserial_procs_using_png();
+    SkSerialProcs procs = ToolUtils::default_serial_procs();
+    SkDeserialProcs dProcs = ToolUtils::default_deserial_procs();
     // Serialize it and then deserialize it.
     sk_sp<SkPicture> deserialized = SkPicture::MakeFromData(pic->serialize(&procs).get(), &dProcs);
 
diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp
index 8a4623e..d989fe2 100644
--- a/fuzz/FuzzCanvas.cpp
+++ b/fuzz/FuzzCanvas.cpp
@@ -225,7 +225,7 @@
     std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
     UrlDataManager dataManager(SkString("data"));
     SkDynamicMemoryWStream stream;
-    SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
+    SkJSONWriter writer(&stream, SkSerialProcs{}, SkJSONWriter::Mode::kPretty);
     writer.beginObject(); // root
     debugCanvas.toJSON(writer, dataManager, nullCanvas.get());
     writer.endObject(); // root
diff --git a/modules/canvaskit/debugger_bindings.cpp b/modules/canvaskit/debugger_bindings.cpp
index 518d007..0f26513 100644
--- a/modules/canvaskit/debugger_bindings.cpp
+++ b/modules/canvaskit/debugger_bindings.cpp
@@ -25,6 +25,7 @@
 #include "src/core/SkPicturePriv.h"
 #include "src/ports/SkTypeface_FreeType.h"
 #include "src/utils/SkJSONWriter.h"
+#include "tools/ProcsUtils.h"
 #include "tools/SkSharingProc.h"
 #include "tools/UrlDataManager.h"
 #include "tools/debugger/DebugCanvas.h"
@@ -248,7 +249,7 @@
     // Return the command list in JSON representation as a string
     std::string jsonCommandList(sk_sp<SkSurface> surface) {
       SkDynamicMemoryWStream stream;
-      SkJSONWriter writer(&stream, SkJSONWriter::Mode::kFast);
+      SkJSONWriter           writer(&stream, ToolUtils::default_serial_procs(), SkJSONWriter::Mode::kFast);
       writer.beginObject(); // root
       visibleCanvas()->toJSON(writer, udm, surface->getCanvas());
       writer.endObject(); // root
@@ -266,7 +267,7 @@
       SkIRect clip = visibleCanvas()->getCurrentClip();
 
       SkDynamicMemoryWStream stream;
-      SkJSONWriter writer(&stream, SkJSONWriter::Mode::kFast);
+      SkJSONWriter           writer(&stream, SkSerialProcs{}, SkJSONWriter::Mode::kFast);
       writer.beginObject(); // root
 
       writer.appendName("ViewMatrix");
@@ -454,6 +455,7 @@
           // Make debug canvas using bounds from SkPicture
           fBoundsArray.push_back(page.fPicture->cullRect().roundOut());
           std::unique_ptr<DebugCanvas> debugCanvas = std::make_unique<DebugCanvas>(fBoundsArray.back());
+
           debugCanvas->setLayerManagerAndFrame(fLayerManager.get(), i);
 
           // Only draw picture to the debug canvas once.
diff --git a/src/gpu/ganesh/GrDirectContext.cpp b/src/gpu/ganesh/GrDirectContext.cpp
index 6d0144b..5a6a89c 100644
--- a/src/gpu/ganesh/GrDirectContext.cpp
+++ b/src/gpu/ganesh/GrDirectContext.cpp
@@ -1156,7 +1156,7 @@
 
 SkString GrDirectContext::dump() const {
     SkDynamicMemoryWStream stream;
-    SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
+    SkJSONWriter           writer(&stream, SkSerialProcs{}, SkJSONWriter::Mode::kPretty);
     writer.beginObject();
 
     writer.appendCString("backend", GrBackendApiToStr(this->backend()));
diff --git a/src/utils/SkJSONWriter.h b/src/utils/SkJSONWriter.h
index 1d3862e..06c3061 100644
--- a/src/utils/SkJSONWriter.h
+++ b/src/utils/SkJSONWriter.h
@@ -8,6 +8,7 @@
 #ifndef SkJSONWriter_DEFINED
 #define SkJSONWriter_DEFINED
 
+#include "include/core/SkSerialProcs.h"
 #include "include/core/SkStream.h"
 #include "include/core/SkString.h"
 #include "include/core/SkTypes.h"
@@ -15,8 +16,8 @@
 #include "include/private/SkTArray.h"
 #include "src/core/SkUTF.h"
 
-#include <cstring>
 #include <cstdint>
+#include <cstring>
 #include <string>
 #include <type_traits>
 
@@ -54,13 +55,14 @@
     /**
      *  Construct a JSON writer that will serialize all the generated JSON to 'stream'.
      */
-    SkJSONWriter(SkWStream* stream, Mode mode = Mode::kFast)
+    SkJSONWriter(SkWStream* stream, SkSerialProcs serialProcs, Mode mode = Mode::kFast)
             : fBlock(new char[kBlockSize])
             , fWrite(fBlock)
             , fBlockEnd(fBlock + kBlockSize)
             , fStream(stream)
             , fMode(mode)
-            , fState(State::kStart) {
+            , fState(State::kStart)
+            , fSerialProcs(serialProcs) {
         fScopeStack.push_back(Scope::kNone);
         fNewlineStack.push_back(true);
     }
@@ -303,6 +305,8 @@
         this->appendDoubleDigits(value, digits);
     }
 
+    SkSerialProcs getSerialProcs() const { return fSerialProcs; }
+
 private:
     enum {
         // Using a 32k scratch block gives big performance wins, but we diminishing returns going
@@ -414,6 +418,8 @@
     State fState;
     skia_private::STArray<16, Scope, true> fScopeStack;
     skia_private::STArray<16, bool, true> fNewlineStack;
+
+    SkSerialProcs fSerialProcs;
 };
 
 #endif
diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel
index bed489a..c246377 100644
--- a/tools/BUILD.bazel
+++ b/tools/BUILD.bazel
@@ -200,10 +200,10 @@
     name = "deserial_procs_utils",
     testonly = True,
     srcs = [
-        "DeserialProcsUtils.cpp",
+        "ProcsUtils.cpp",
     ],
     hdrs = [
-        "DeserialProcsUtils.h",
+        "ProcsUtils.h",
     ],
     visibility = [
         "//bench:__subpackages__",
diff --git a/tools/DeserialProcsUtils.cpp b/tools/ProcsUtils.cpp
similarity index 71%
rename from tools/DeserialProcsUtils.cpp
rename to tools/ProcsUtils.cpp
index 10fe24b..fc8be68 100644
--- a/tools/DeserialProcsUtils.cpp
+++ b/tools/ProcsUtils.cpp
@@ -5,14 +5,20 @@
  * found in the LICENSE file.
  */
 
-#include "tools/DeserialProcsUtils.h"
+#include "tools/ProcsUtils.h"
 
 #include "include/codec/SkCodec.h"
 #include "include/core/SkFontMgr.h"
 #include "include/core/SkImage.h"
 #include "include/core/SkStream.h"
+#include "src/image/SkImage_Base.h"
 #include "tools/fonts/FontToolUtils.h"
 
+#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
+#include "include/encode/SkPngRustEncoder.h"
+#else
+#include "include/encode/SkPngEncoder.h"
+#endif
 #if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
 #include "include/codec/SkPngRustDecoder.h"
 #else
@@ -21,7 +27,7 @@
 
 namespace ToolUtils {
 
-SkDeserialProcs get_default_skp_deserial_procs() {
+SkDeserialProcs default_deserial_procs() {
     SkDeserialProcs procs;
     procs.fImageDataProc =
             [](sk_sp<SkData> data, std::optional<SkAlphaType> at, void*) -> sk_sp<SkImage> {
@@ -49,5 +55,19 @@
     return procs;
 }
 
-}  // namespace ToolUtils
+SkSerialProcs default_serial_procs() {
+    static SkSerialProcs procs;
 
+    procs.fImageProc = [](SkImage* img, void*) -> sk_sp<const SkData> {
+#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
+        return SkPngRustEncoder::Encode(nullptr, img, {});
+#else
+        // TODO: This catches SkImageEncoder_NDK (or other).
+        return SkPngEncoder::Encode(nullptr, img, {});
+#endif
+    };
+
+    return procs;
+}
+
+}  // namespace ToolUtils
diff --git a/tools/DeserialProcsUtils.h b/tools/ProcsUtils.h
similarity index 60%
rename from tools/DeserialProcsUtils.h
rename to tools/ProcsUtils.h
index 6f49c2d..d9013d1 100644
--- a/tools/DeserialProcsUtils.h
+++ b/tools/ProcsUtils.h
@@ -5,16 +5,20 @@
  * found in the LICENSE file.
  */
 
-#ifndef DeserialProcsUtils_DEFINED
-#define DeserialProcsUtils_DEFINED
+#ifndef ProcsUtils_DEFINED
+#define ProcsUtils_DEFINED
 
 #include "include/core/SkSerialProcs.h"
 
 namespace ToolUtils {
 
 // Returns the default SkDeserialProcs used by Skia's tools when Deserializing Skps. This adds
-// default values for the SkDeserialImageProc and SkDeserialTypefaceProc..
-SkDeserialProcs get_default_skp_deserial_procs();
+// default values for the SkDeserialImageProc and SkDeserialTypefaceProc.
+SkDeserialProcs default_deserial_procs();
+
+// Returns the default SkSerialProcs used by Skia's tools when serializing Skps. This adds
+// default values for the SkSerialImageProc.
+SkSerialProcs default_serial_procs();
 
 }  // namespace ToolUtils
 
diff --git a/tools/debugger/DrawCommand.cpp b/tools/debugger/DrawCommand.cpp
index 354ecb0..e63a02b 100644
--- a/tools/debugger/DrawCommand.cpp
+++ b/tools/debugger/DrawCommand.cpp
@@ -31,7 +31,6 @@
 #include "include/core/SkSize.h"
 #include "include/core/SkStream.h"
 #include "include/core/SkTypeface.h"
-#include "include/encode/SkPngEncoder.h"
 #include "include/private/SkDebug.h"
 #include "include/private/SkMalloc.h"
 #include "include/private/SkTo.h"
@@ -48,6 +47,7 @@
 #include "src/core/SkWriteBuffer.h"
 #include "src/image/SkImage_Base.h"
 #include "src/utils/SkJSONWriter.h"
+#include "tools/ProcsUtils.h"
 #include "tools/UrlDataManager.h"
 #include "tools/debugger/DebugLayerManager.h"
 #include "tools/debugger/JsonWriteBuffer.h"
@@ -608,7 +608,7 @@
 void DrawCommand::flatten(const SkFlattenable* flattenable,
                           SkJSONWriter&        writer,
                           UrlDataManager&      urlDataManager) {
-    SkBinaryWriteBuffer buffer({});  // TODO(kjlubick, bungeman) feed SkSerialProcs through API
+    SkBinaryWriteBuffer buffer(writer.getSerialProcs());
     flattenable->flatten(buffer);
     sk_sp<SkData> data = buffer.snapshotAsData();
     SkString url = encode_data(data, "application/octet-stream", urlDataManager);
@@ -621,16 +621,6 @@
     writer.endObject();  // values
 }
 
-void DrawCommand::WritePNG(const SkBitmap& bitmap, SkWStream& out) {
-    SkPixmap pm;
-    SkAssertResult(bitmap.peekPixels(&pm));
-
-    SkPngEncoder::Options options;
-    options.fZLibLevel   = 1;
-    options.fFilterFlags = SkPngEncoder::FilterFlag::kNone;
-    SkPngEncoder::Encode(&out, pm, options);
-}
-
 // flattens an image to a Json stream, also called from shader flatten
 bool DrawCommand::flatten(const SkImage&  image,
                           SkJSONWriter&   writer,
@@ -662,11 +652,14 @@
     SkBitmap bm;
     bm.installPixels(dstInfo, buffer.get(), rowBytes);
 
-    SkDynamicMemoryWStream out;
-    DrawCommand::WritePNG(bm, out);
-    sk_sp<SkData> encoded = out.detachAsData();
-    if (encoded == nullptr) {
-        SkDebugf("DrawCommand::flatten SkImage: could not encode image as PNG\n");
+    SkSerialProcs procs = writer.getSerialProcs();
+    sk_sp<const SkData> encoded;
+    if (procs.fImageProc) {
+        sk_sp<SkImage> rasterImage = bm.asImage();
+        encoded = procs.fImageProc(rasterImage.get(), procs.fImageCtx);
+    }
+    if (encoded == nullptr || encoded->isEmpty()) {
+        SkDebugf("DrawCommand::flatten SkImage: could not encode image\n");
         writer.endObject();
         return false;
     }
diff --git a/tools/debugger/DrawCommand.h b/tools/debugger/DrawCommand.h
index b77d129..08b07ca 100644
--- a/tools/debugger/DrawCommand.h
+++ b/tools/debugger/DrawCommand.h
@@ -99,8 +99,6 @@
 
     static const int kOpTypeCount = kLast_OpType + 1;
 
-    static void WritePNG(const SkBitmap& bitmap, SkWStream& out);
-
     explicit DrawCommand(OpType opType);
 
     virtual ~DrawCommand() {}
diff --git a/tools/get_images_from_skps.cpp b/tools/get_images_from_skps.cpp
index 7b966e7..15b9980 100644
--- a/tools/get_images_from_skps.cpp
+++ b/tools/get_images_from_skps.cpp
@@ -188,7 +188,7 @@
     unsigned int totalFailures = 0,
               totalUnsupported = 0;
     SkDynamicMemoryWStream memStream;
-    SkJSONWriter writer(&memStream, SkJSONWriter::Mode::kPretty);
+    SkJSONWriter writer(&memStream, SkSerialProcs{}, SkJSONWriter::Mode::kPretty);
     writer.beginObject();
     {
         writer.beginObject("failures");
diff --git a/tools/skp_parser.cpp b/tools/skp_parser.cpp
index f21e921..bd2f427 100644
--- a/tools/skp_parser.cpp
+++ b/tools/skp_parser.cpp
@@ -10,7 +10,7 @@
 #include "include/core/SkStream.h"
 #include "include/utils/SkNullCanvas.h"
 #include "src/utils/SkJSONWriter.h"
-#include "tools/DeserialProcsUtils.h"
+#include "tools/ProcsUtils.h"
 #include "tools/UrlDataManager.h"
 #include "tools/debugger/DebugCanvas.h"
 
@@ -49,7 +49,7 @@
         SkDebugf("Bad file: '%s'\n", argv[1]);
         return 2;
     }
-    SkDeserialProcs procs = ToolUtils::get_default_skp_deserial_procs();
+    SkDeserialProcs procs = ToolUtils::default_deserial_procs();
     sk_sp<SkPicture> pic = SkPicture::MakeFromStream(&input, &procs);
     if (!pic) {
         SkDebugf("Bad skp: '%s'\n", argv[1]);
@@ -61,7 +61,7 @@
     std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
     UrlDataManager dataManager(SkString("data"));
     SkDynamicMemoryWStream stream;
-    SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
+    SkJSONWriter writer(&stream, ToolUtils::default_serial_procs(), SkJSONWriter::Mode::kPretty);
     writer.beginObject(); // root
     debugCanvas.toJSON(writer, dataManager, nullCanvas.get());
     writer.endObject(); // root
diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp
index 2d65c99..03278aa 100644
--- a/tools/skpbench/skpbench.cpp
+++ b/tools/skpbench/skpbench.cpp
@@ -27,8 +27,8 @@
 #include "src/gpu/ganesh/SkGr.h"
 #include "src/gpu/ganesh/image/GrImageUtils.h"
 #include "src/utils/SkOSPath.h"
-#include "tools/DeserialProcsUtils.h"
 #include "tools/EncodeUtils.h"
+#include "tools/ProcsUtils.h"
 #include "tools/SkSharingProc.h"
 #include "tools/flags/CommandLineFlags.h"
 #include "tools/flags/CommonFlags.h"
@@ -557,7 +557,7 @@
             // populate skp with it's first frame, for width height determination.
             skp = mskp->frame(0);
         } else {
-            SkDeserialProcs procs = ToolUtils::get_default_skp_deserial_procs();
+            SkDeserialProcs procs = ToolUtils::default_deserial_procs();
             skp = SkPicture::MakeFromStream(srcstream.get(), &procs);
         }
         if (!skp) {
diff --git a/tools/sksltrace/SkSLTraceUtils.cpp b/tools/sksltrace/SkSLTraceUtils.cpp
index ec6ec4a..ae2b559 100644
--- a/tools/sksltrace/SkSLTraceUtils.cpp
+++ b/tools/sksltrace/SkSLTraceUtils.cpp
@@ -26,7 +26,7 @@
 namespace SkSLTraceUtils {
 
 void WriteTrace(const SkSL::DebugTracePriv& src, SkWStream* w) {
-    SkJSONWriter json(w);
+    SkJSONWriter json(w, SkSerialProcs{});
 
     json.beginObject();  // root
     json.appendNString("version", kTraceVersion);
diff --git a/tools/trace/ChromeTracingTracer.cpp b/tools/trace/ChromeTracingTracer.cpp
index 9bc69e1..2899db4 100644
--- a/tools/trace/ChromeTracingTracer.cpp
+++ b/tools/trace/ChromeTracingTracer.cpp
@@ -11,6 +11,7 @@
 #include "src/core/SkTraceEvent.h"
 #include "src/utils/SkJSONWriter.h"
 #include "src/utils/SkOSPath.h"
+#include "tools/ProcsUtils.h"
 #include "tools/trace/ChromeTracingTracer.h"
 
 #include <chrono>
@@ -278,7 +279,7 @@
     }
 
     SkFILEWStream fileStream(fFilename.c_str());
-    SkJSONWriter  writer(&fileStream, SkJSONWriter::Mode::kFast);
+    SkJSONWriter  writer(&fileStream, ToolUtils::default_serial_procs(), SkJSONWriter::Mode::kFast);
     writer.beginArray();
 
     uint64_t clockOffset = 0;
diff --git a/tools/viewer/CaptureSlide.cpp b/tools/viewer/CaptureSlide.cpp
index 3686c24..53f0b73 100644
--- a/tools/viewer/CaptureSlide.cpp
+++ b/tools/viewer/CaptureSlide.cpp
@@ -7,8 +7,6 @@
 
 #include "tools/viewer/CaptureSlide.h"
 
-#include <string>
-
 #include "imgui.h"
 #include "include/core/SkCanvas.h"
 #include "include/core/SkClipOp.h"
@@ -22,10 +20,13 @@
 #include "src/core/SkBigPicture.h"
 #include "src/core/SkRecord.h"
 #include "src/utils/SkJSONWriter.h"
+#include "tools/ProcsUtils.h"
 #include "tools/UrlDataManager.h"
 #include "tools/debugger/DebugCanvas.h"
 #include "tools/debugger/DrawCommand.h"
 
+#include <string>
+
 const char* RecordTypeNames[] = {
 #define CASE(T) #T,
         SK_RECORD_TYPES(CASE)
@@ -87,7 +88,7 @@
         DrawCommand* cmd = debugCanvas->getDrawCommandAt(currentCommandIdx);
 
         SkDynamicMemoryWStream stream;
-        SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
+        SkJSONWriter   writer(&stream, ToolUtils::default_serial_procs(), SkJSONWriter::Mode::kPretty);
         UrlDataManager urlDataManager(SkString("data"));
         writer.beginObject();
         cmd->toJSON(writer, urlDataManager);
diff --git a/tools/viewer/SKPSlide.cpp b/tools/viewer/SKPSlide.cpp
index b7dc7c8..d4b1d6f 100644
--- a/tools/viewer/SKPSlide.cpp
+++ b/tools/viewer/SKPSlide.cpp
@@ -14,7 +14,7 @@
 #include "include/core/SkString.h"
 #include "include/private/SkDebug.h"
 #include "include/private/SkTo.h"
-#include "tools/DeserialProcsUtils.h"
+#include "tools/ProcsUtils.h"
 
 #include <utility>
 
@@ -52,7 +52,7 @@
     }
     fStream->rewind();
 
-    SkDeserialProcs procs = ToolUtils::get_default_skp_deserial_procs();
+    SkDeserialProcs procs = ToolUtils::default_deserial_procs();
 
     fPic = SkPicture::MakeFromStream(fStream.get(), &procs);
     if (!fPic) {
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index c77ab76..6af308e 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -58,7 +58,7 @@
 #include "src/utils/SkShaderUtils.h"
 #include "tools/CodecUtils.h"
 #include "tools/DecodeUtils.h"
-#include "tools/DeserialProcsUtils.h"
+#include "tools/ProcsUtils.h"
 #include "tools/Resources.h"
 #include "tools/RuntimeBlendUtils.h"
 #include "tools/SkMetaData.h"
@@ -1899,18 +1899,6 @@
     Viewer::SkFontFields* fFontOverrides;
 };
 
-static SkSerialProcs serial_procs_using_png() {
-    SkSerialProcs sProcs;
-    sProcs.fImageProc = [](SkImage* img, void*) -> SkSerialReturnType {
-#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
-        return SkPngRustEncoder::Encode(
-                as_IB(img)->directContext(), img, SkPngRustEncoder::Options{});
-#else
-        return SkPngEncoder::Encode(as_IB(img)->directContext(), img, SkPngEncoder::Options{});
-#endif
-    };
-    return sProcs;
-}
 
 void Viewer::drawSlide(SkSurface* surface) {
     if (fCurrentSlide < 0) {
@@ -1938,7 +1926,7 @@
         fSlides[fCurrentSlide]->draw(recorderCanvas);
         sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
         SkFILEWStream stream("sample_app.skp");
-        SkSerialProcs sProcs = serial_procs_using_png();
+        SkSerialProcs    sProcs = ToolUtils::default_serial_procs();
         picture->serialize(&stream, &sProcs);
         fSaveToSKP = false;
     }
@@ -2053,10 +2041,10 @@
 
     if (recorderRestoreCanvas) {
         sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
-        SkSerialProcs sProcs = serial_procs_using_png();
+        SkSerialProcs sProcs = ToolUtils::default_serial_procs();
         auto data = picture->serialize(&sProcs);
         slideCanvas = recorderRestoreCanvas;
-        SkDeserialProcs dProcs = ToolUtils::get_default_skp_deserial_procs();
+        SkDeserialProcs dProcs = ToolUtils::default_deserial_procs();
         slideCanvas->drawPicture(SkPicture::MakeFromData(data.get(), &dProcs));
     }
 
@@ -3532,7 +3520,7 @@
     }
 
     SkDynamicMemoryWStream memStream;
-    SkJSONWriter writer(&memStream);
+    SkJSONWriter writer(&memStream, ToolUtils::default_serial_procs());
     writer.beginArray();
 
     // Slide state