One binary serialization path for SkSamplingOptions

Bug: skia:13036
Change-Id: I31ccc3d1cfb271a2c2000476b91a695390cef4a6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/526518
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/core/BUILD.bazel b/src/core/BUILD.bazel
index e061f5d..a230fde 100644
--- a/src/core/BUILD.bazel
+++ b/src/core/BUILD.bazel
@@ -5383,6 +5383,7 @@
     deps = [
         ":SkMatrixPriv_hdr",
         ":SkWriter32_hdr",
+        "//include/core:SkSamplingOptions_hdr",
         "//include/private:SkTo_hdr",
     ],
 )
diff --git a/src/core/SkMatrixImageFilter.cpp b/src/core/SkMatrixImageFilter.cpp
index 665dcd4..a7f6d2d 100644
--- a/src/core/SkMatrixImageFilter.cpp
+++ b/src/core/SkMatrixImageFilter.cpp
@@ -48,7 +48,7 @@
         if (buffer.isVersionLT(SkPicturePriv::kMatrixImageFilterSampling_Version)) {
             return SkSamplingPriv::FromFQ(buffer.read32LE(kLast_SkLegacyFQ), kLinear_SkMediumAs);
         } else {
-            return SkSamplingPriv::Read(buffer);
+            return buffer.readSampling();
         }
     }();
     return Make(matrix, sampling, common.getInput(0));
@@ -57,7 +57,7 @@
 void SkMatrixImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writeMatrix(fTransform);
-    SkSamplingPriv::Write(buffer, fSampling);
+    buffer.writeSampling(fSampling);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 3c8a807..55681e7 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -921,14 +921,7 @@
 }
 
 void SkPictureRecord::addSampling(const SkSamplingOptions& sampling) {
-    fWriter.writeBool(sampling.useCubic);
-    if (sampling.useCubic) {
-        fWriter.writeScalar(sampling.cubic.B);
-        fWriter.writeScalar(sampling.cubic.C);
-    } else {
-        fWriter.writeInt(static_cast<uint32_t>(sampling.filter));
-        fWriter.writeInt(static_cast<uint32_t>(sampling.mipmap));
-    }
+    fWriter.writeSampling(sampling);
 }
 
 void SkPictureRecord::addText(const void* text, size_t byteLength) {
diff --git a/src/core/SkSamplingPriv.h b/src/core/SkSamplingPriv.h
index e42d2df..ae8385c 100644
--- a/src/core/SkSamplingPriv.h
+++ b/src/core/SkSamplingPriv.h
@@ -43,9 +43,6 @@
         return !sampling.useCubic || sampling.cubic.B == 0;
     }
 
-    static SkSamplingOptions Read(SkReadBuffer&);
-    static void Write(SkWriteBuffer&, const SkSamplingOptions&);
-
     static SkSamplingOptions FromFQ(SkLegacyFQ, SkMediumAs = kNearest_SkMediumAs);
 };
 
diff --git a/src/core/SkWriteBuffer.cpp b/src/core/SkWriteBuffer.cpp
index eb10f71..c942ef7 100644
--- a/src/core/SkWriteBuffer.cpp
+++ b/src/core/SkWriteBuffer.cpp
@@ -124,6 +124,10 @@
     fWriter.writeRegion(region);
 }
 
+void SkBinaryWriteBuffer::writeSampling(const SkSamplingOptions& sampling) {
+    fWriter.writeSampling(sampling);
+}
+
 void SkBinaryWriteBuffer::writePath(const SkPath& path) {
     fWriter.writePath(path);
 }
diff --git a/src/core/SkWriteBuffer.h b/src/core/SkWriteBuffer.h
index ac1fcdd..b942733 100644
--- a/src/core/SkWriteBuffer.h
+++ b/src/core/SkWriteBuffer.h
@@ -60,6 +60,7 @@
     virtual void writeIRect(const SkIRect& rect) = 0;
     virtual void writeRect(const SkRect& rect) = 0;
     virtual void writeRegion(const SkRegion& region) = 0;
+    virtual void writeSampling(const SkSamplingOptions&) = 0;
     virtual void writePath(const SkPath& path) = 0;
     virtual size_t writeStream(SkStream* stream, size_t length) = 0;
     virtual void writeImage(const SkImage*) = 0;
@@ -122,6 +123,7 @@
     void writeIRect(const SkIRect& rect) override;
     void writeRect(const SkRect& rect) override;
     void writeRegion(const SkRegion& region) override;
+    void writeSampling(const SkSamplingOptions&) override;
     void writePath(const SkPath& path) override;
     size_t writeStream(SkStream* stream, size_t length) override;
     void writeImage(const SkImage*) override;
diff --git a/src/core/SkWriter32.cpp b/src/core/SkWriter32.cpp
index aa96531..3632457 100644
--- a/src/core/SkWriter32.cpp
+++ b/src/core/SkWriter32.cpp
@@ -5,9 +5,11 @@
  * found in the LICENSE file.
  */
 
+#include "src/core/SkWriter32.h"
+
+#include "include/core/SkSamplingOptions.h"
 #include "include/private/SkTo.h"
 #include "src/core/SkMatrixPriv.h"
-#include "src/core/SkWriter32.h"
 
 void SkWriter32::writeMatrix(const SkMatrix& matrix) {
     size_t size = SkMatrixPriv::WriteToMemory(matrix, nullptr);
@@ -15,6 +17,17 @@
     SkMatrixPriv::WriteToMemory(matrix, this->reserve(size));
 }
 
+void SkWriter32::writeSampling(const SkSamplingOptions& sampling) {
+    this->writeBool(sampling.useCubic);
+    if (sampling.useCubic) {
+        this->writeScalar(sampling.cubic.B);
+        this->writeScalar(sampling.cubic.C);
+    } else {
+        this->write32((unsigned)sampling.filter);
+        this->write32((unsigned)sampling.mipmap);
+    }
+}
+
 void SkWriter32::writeString(const char str[], size_t len) {
     if (nullptr == str) {
         str = "";
diff --git a/src/core/SkWriter32.h b/src/core/SkWriter32.h
index 54b06b7..e719825 100644
--- a/src/core/SkWriter32.h
+++ b/src/core/SkWriter32.h
@@ -23,6 +23,8 @@
 #include "include/private/SkTemplates.h"
 #include "include/private/SkTo.h"
 
+struct SkSamplingOptions;
+
 class SkWriter32 : SkNoncopyable {
 public:
     /**
@@ -148,6 +150,8 @@
         rgn.writeToMemory(this->reserve(size));
     }
 
+    void writeSampling(const SkSamplingOptions& sampling);
+
     // write count bytes (must be a multiple of 4)
     void writeMul4(const void* values, size_t size) {
         this->write(values, size);
diff --git a/src/effects/imagefilters/SkImageImageFilter.cpp b/src/effects/imagefilters/SkImageImageFilter.cpp
index f71009e..16b10f8 100644
--- a/src/effects/imagefilters/SkImageImageFilter.cpp
+++ b/src/effects/imagefilters/SkImageImageFilter.cpp
@@ -92,7 +92,7 @@
 }
 
 void SkImageImageFilter::flatten(SkWriteBuffer& buffer) const {
-    SkSamplingPriv::Write(buffer, fSampling);
+    buffer.writeSampling(fSampling);
     buffer.writeRect(fSrcRect);
     buffer.writeRect(fDstRect);
     buffer.writeImage(fImage.get());
diff --git a/src/image/BUILD.bazel b/src/image/BUILD.bazel
index af2e701..176f524 100644
--- a/src/image/BUILD.bazel
+++ b/src/image/BUILD.bazel
@@ -294,10 +294,8 @@
         "//src/core:SkMipmapBuilder_hdr",
         "//src/core:SkMipmap_hdr",
         "//src/core:SkNextID_hdr",
-        "//src/core:SkReadBuffer_hdr",
         "//src/core:SkSamplingPriv_hdr",
         "//src/core:SkSpecialImage_hdr",
-        "//src/core:SkWriteBuffer_hdr",
         "//src/gpu:GrDirectContextPriv_hdr",
         "//src/gpu:GrFragmentProcessor_hdr",
         "//src/gpu:GrImageContextPriv_hdr",
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 2d484ba..6b564fb 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -21,6 +21,7 @@
 #include "src/core/SkMipmap.h"
 #include "src/core/SkMipmapBuilder.h"
 #include "src/core/SkNextID.h"
+#include "src/core/SkSamplingPriv.h"
 #include "src/core/SkSpecialImage.h"
 #include "src/image/SkImage_Base.h"
 #include "src/image/SkReadPixelsRec.h"
@@ -738,10 +739,6 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-#include "src/core/SkReadBuffer.h"
-#include "src/core/SkSamplingPriv.h"
-#include "src/core/SkWriteBuffer.h"
-
 SkSamplingOptions SkSamplingPriv::FromFQ(SkLegacyFQ fq, SkMediumAs behavior) {
     switch (fq) {
         case kHigh_SkLegacyFQ:
@@ -757,26 +754,3 @@
     }
     return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
 }
-
-SkSamplingOptions SkSamplingPriv::Read(SkReadBuffer& buffer) {
-    if (buffer.readBool()) {
-        SkScalar B = buffer.readScalar(),
-                 C = buffer.readScalar();
-        return SkSamplingOptions({B,C});
-    } else {
-        auto filter = buffer.read32LE<SkFilterMode>(SkFilterMode::kLinear);
-        auto mipmap = buffer.read32LE<SkMipmapMode>(SkMipmapMode::kLinear);
-        return SkSamplingOptions(filter, mipmap);
-    }
-}
-
-void SkSamplingPriv::Write(SkWriteBuffer& buffer, const SkSamplingOptions& sampling) {
-    buffer.writeBool(sampling.useCubic);
-    if (sampling.useCubic) {
-        buffer.writeScalar(sampling.cubic.B);
-        buffer.writeScalar(sampling.cubic.C);
-    } else {
-        buffer.writeUInt((unsigned)sampling.filter);
-        buffer.writeUInt((unsigned)sampling.mipmap);
-    }
-}
diff --git a/src/shaders/BUILD.bazel b/src/shaders/BUILD.bazel
index 0f3936f..10c17f2 100644
--- a/src/shaders/BUILD.bazel
+++ b/src/shaders/BUILD.bazel
@@ -183,8 +183,6 @@
         "//src/core:SkOpts_hdr",
         "//src/core:SkRasterPipeline_hdr",
         "//src/core:SkReadBuffer_hdr",
-        "//src/core:SkSamplingPriv_hdr",
-        "//src/core:SkScopeExit_hdr",
         "//src/core:SkVM_hdr",
         "//src/core:SkWriteBuffer_hdr",
         "//src/gpu:GrColorInfo_hdr",
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp
index 4663ff0..c66f9dc 100755
--- a/src/shaders/SkImageShader.cpp
+++ b/src/shaders/SkImageShader.cpp
@@ -17,8 +17,6 @@
 #include "src/core/SkOpts.h"
 #include "src/core/SkRasterPipeline.h"
 #include "src/core/SkReadBuffer.h"
-#include "src/core/SkSamplingPriv.h"
-#include "src/core/SkScopeExit.h"
 #include "src/core/SkVM.h"
 #include "src/core/SkWriteBuffer.h"
 #include "src/image/SkImage_Base.h"
@@ -138,7 +136,7 @@
         // we just default to Nearest in sampling
     }
     if (readSampling) {
-        sampling = SkSamplingPriv::Read(buffer);
+        sampling = buffer.readSampling();
     }
 
     SkMatrix localMatrix;
@@ -162,7 +160,7 @@
     buffer.writeUInt((unsigned)fTileModeX);
     buffer.writeUInt((unsigned)fTileModeY);
 
-    SkSamplingPriv::Write(buffer, fSampling);
+    buffer.writeSampling(fSampling);
 
     buffer.writeMatrix(this->getLocalMatrix());
     buffer.writeImage(fImage.get());
diff --git a/tools/debugger/BUILD.bazel b/tools/debugger/BUILD.bazel
index 0a008f7..2f05e87 100644
--- a/tools/debugger/BUILD.bazel
+++ b/tools/debugger/BUILD.bazel
@@ -165,6 +165,7 @@
         "//include/core:SkPixmap_hdr",
         "//include/core:SkPoint3_hdr",
         "//include/core:SkRSXform_hdr",
+        "//include/core:SkSamplingOptions_hdr",
         "//include/core:SkSize_hdr",
         "//include/core:SkStream_hdr",
         "//include/core:SkTypeface_hdr",
diff --git a/tools/debugger/DrawCommand.cpp b/tools/debugger/DrawCommand.cpp
index 6849671..0943d9e 100644
--- a/tools/debugger/DrawCommand.cpp
+++ b/tools/debugger/DrawCommand.cpp
@@ -25,6 +25,7 @@
 #include "include/core/SkPixmap.h"
 #include "include/core/SkPoint3.h"
 #include "include/core/SkRSXform.h"
+#include "include/core/SkSamplingOptions.h"
 #include "include/core/SkSize.h"
 #include "include/core/SkStream.h"
 #include "include/core/SkTypeface.h"
@@ -74,6 +75,7 @@
 #define DEBUGCANVAS_ATTRIBUTE_COLOR "color"
 #define DEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
 #define DEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
+#define DEBUGCANVAS_ATTRIBUTE_SAMPLING "sampling"
 #define DEBUGCANVAS_ATTRIBUTE_STYLE "style"
 #define DEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
 #define DEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
@@ -568,6 +570,16 @@
     MakeJsonPath(writer, path);
 }
 
+void DrawCommand::MakeJsonSampling(SkJSONWriter& writer, const SkSamplingOptions& sampling) {
+    writer.beginObject();
+    writer.appendBool("useCubic", sampling.useCubic);
+    writer.appendS32("filter", (int)sampling.filter);
+    writer.appendS32("mipmap", (int)sampling.mipmap);
+    writer.appendFloat("cubic.B", sampling.cubic.B);
+    writer.appendFloat("cubic.C", sampling.cubic.C);
+    writer.endObject();
+}
+
 static const char* clipop_name(SkClipOp op) {
     switch (op) {
         case SkClipOp::kDifference: return DEBUGCANVAS_CLIPOP_DIFFERENCE;
@@ -1213,6 +1225,8 @@
         writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
         MakeJsonPaint(writer, *fPaint, urlDataManager);
     }
+    writer.appendName(DEBUGCANVAS_ATTRIBUTE_SAMPLING);
+    MakeJsonSampling(writer, fSampling);
 
     writer.appendU32(DEBUGCANVAS_ATTRIBUTE_UNIQUE_ID, fImage->uniqueID());
     writer.appendS32(DEBUGCANVAS_ATTRIBUTE_WIDTH, fImage->width());
@@ -1318,6 +1332,8 @@
     MakeJsonRect(writer, fSrc);
     writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
     MakeJsonRect(writer, fDst);
+    writer.appendName(DEBUGCANVAS_ATTRIBUTE_SAMPLING);
+    MakeJsonSampling(writer, fSampling);
     if (fPaint.isValid()) {
         writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
         MakeJsonPaint(writer, *fPaint, urlDataManager);
@@ -1377,6 +1393,8 @@
 
     writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
     MakeJsonRect(writer, fDst);
+    writer.appendName(DEBUGCANVAS_ATTRIBUTE_SAMPLING);
+    MakeJsonSampling(writer, fSampling);
     if (fPaint.isValid()) {
         writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
         MakeJsonPaint(writer, *fPaint, urlDataManager);
diff --git a/tools/debugger/DrawCommand.h b/tools/debugger/DrawCommand.h
index 4ec6b1c..8e47e3d 100644
--- a/tools/debugger/DrawCommand.h
+++ b/tools/debugger/DrawCommand.h
@@ -126,6 +126,7 @@
     static void MakeJsonMatrix44(SkJSONWriter&, const SkM44&);
     static void MakeJsonPath(SkJSONWriter&, const SkPath& path);
     static void MakeJsonRegion(SkJSONWriter&, const SkRegion& region);
+    static void MakeJsonSampling(SkJSONWriter&, const SkSamplingOptions& sampling);
     static void MakeJsonPaint(SkJSONWriter&, const SkPaint& paint, UrlDataManager& urlDataManager);
     static void MakeJsonLattice(SkJSONWriter&, const SkCanvas::Lattice& lattice);
 
diff --git a/tools/debugger/JsonWriteBuffer.cpp b/tools/debugger/JsonWriteBuffer.cpp
index 8030e71..71fb2a8 100644
--- a/tools/debugger/JsonWriteBuffer.cpp
+++ b/tools/debugger/JsonWriteBuffer.cpp
@@ -192,6 +192,11 @@
     DrawCommand::MakeJsonPath(*fWriter, path);
 }
 
+void JsonWriteBuffer::writeSampling(const SkSamplingOptions& sampling) {
+    this->append("sampling");
+    DrawCommand::MakeJsonSampling(*fWriter, sampling);
+}
+
 size_t JsonWriteBuffer::writeStream(SkStream* stream, size_t length) {
     // Contents not supported
     this->append("stream");
diff --git a/tools/debugger/JsonWriteBuffer.h b/tools/debugger/JsonWriteBuffer.h
index bbd896e..ba16057 100644
--- a/tools/debugger/JsonWriteBuffer.h
+++ b/tools/debugger/JsonWriteBuffer.h
@@ -21,6 +21,7 @@
 class SkPaint;
 class SkPath;
 class SkRegion;
+struct SkSamplingOptions;
 class SkStream;
 class SkTypeface;
 class UrlDataManager;
@@ -58,6 +59,7 @@
     void   writeRect(const SkRect& rect) override;
     void   writeRegion(const SkRegion& region) override;
     void   writePath(const SkPath& path) override;
+    void   writeSampling(const SkSamplingOptions&) override;
     size_t writeStream(SkStream* stream, size_t length) override;
     void   writeImage(const SkImage*) override;
     void   writeTypeface(SkTypeface* typeface) override;
diff --git a/tools/viewer/SKPSlide.cpp b/tools/viewer/SKPSlide.cpp
index 87e3fc6..1bad11e 100644
--- a/tools/viewer/SKPSlide.cpp
+++ b/tools/viewer/SKPSlide.cpp
@@ -46,7 +46,7 @@
     fStream->rewind();
     fPic = SkPicture::MakeFromStream(fStream.get());
     if (!fPic) {
-        SkDebugf("Could parse SkPicture from skp stream for slide %s.\n", fName.c_str());
+        SkDebugf("Could not parse SkPicture from skp stream for slide %s.\n", fName.c_str());
         return;
     }
     fCullRect = fPic->cullRect().roundOut();