Prototype code that turns any/every flattenable into JSON
authorbrianosman <brianosman@google.com>
Wed, 4 May 2016 18:06:28 +0000 (11:06 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 4 May 2016 18:06:28 +0000 (11:06 -0700)
This makes inspecting things in SkDebugger far more useful - any filter
or other complex object on the paint is ultimately visible. You still
have to do some guess work to figure out what the fields actually mean,
but you can at least cross-reference with the code in flatten().

Screenshots:
Before: https://screenshot.googleplex.com/a6JM5HBBe6G.png
After : https://screenshot.googleplex.com/XQfr4YJ6mnH.png

Changes to public API are just removals and changes to make
some functions virtual.

TBR=reed@google.com

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1920423002

Review-Url: https://codereview.chromium.org/1920423002

21 files changed:
gyp/debugger.gyp
gyp/dm.gypi
gyp/gmslides.gypi
gyp/skiaserve.gyp
gyp/tests.gypi
include/core/SkBitmap.h
include/core/SkWriteBuffer.h
src/core/SkFlattenableSerialization.cpp
src/core/SkPaint.cpp
src/core/SkPictureData.cpp
src/core/SkWriteBuffer.cpp
tests/ColorFilterTest.cpp
tests/FlattenDrawableTest.cpp
tests/FlattenableCustomFactory.cpp
tests/ImageIsOpaqueTest.cpp
tests/PaintTest.cpp
tests/SerializationTest.cpp
tools/debugger/SkDrawCommand.cpp
tools/debugger/SkDrawCommand.h
tools/debugger/SkJsonWriteBuffer.cpp [new file with mode: 0644]
tools/debugger/SkJsonWriteBuffer.h [new file with mode: 0644]

index 8ad570284ff2481509e4ada090edb18dcac05ff5..9a460dbbe459556525329a233c44d9eeed44e123 100644 (file)
@@ -99,6 +99,8 @@
         '../tools/debugger/SkDebugCanvas.cpp',
         '../tools/debugger/SkDrawCommand.h',
         '../tools/debugger/SkDrawCommand.cpp',
+        '../tools/debugger/SkJsonWriteBuffer.h',
+        '../tools/debugger/SkJsonWriteBuffer.cpp',
         '../tools/debugger/SkObjectParser.h',
         '../tools/debugger/SkObjectParser.cpp',
         '../tools/debugger/SkOverdrawMode.h',
index b14c87e5c6b41934f2e7f72396d9beecbf8a94ea..4a4f8ba313ad1c6dffed15904a02f665ef90a9db 100644 (file)
@@ -45,6 +45,7 @@
 
     '../tools/debugger/SkDebugCanvas.cpp',
     '../tools/debugger/SkDrawCommand.cpp',
+    '../tools/debugger/SkJsonWriteBuffer.cpp',
     '../tools/debugger/SkObjectParser.cpp',
     '../tools/debugger/SkOverdrawMode.h',
     '../tools/debugger/SkOverdrawMode.cpp',
index 94800ba96ff3cd75dc11c0832e7b3c214bd56687..7412ba71ca779ed4a42a8951ec9eaa16d3c417df 100644 (file)
@@ -27,6 +27,8 @@
         '../tools/debugger/SkDrawCommand.cpp',
         '../tools/debugger/SkDebugCanvas.h',
         '../tools/debugger/SkDebugCanvas.cpp',
+        '../tools/debugger/SkJsonWriteBuffer.h',
+        '../tools/debugger/SkJsonWriteBuffer.cpp',
         '../tools/debugger/SkObjectParser.h',
         '../tools/debugger/SkObjectParser.cpp',
         '../tools/debugger/SkOverdrawMode.h',
index 658b4d168b9590d8d3bcd6a762984d3404c42c73..079876ca28a78e955f6004a6a5047d48a2d44872 100644 (file)
@@ -25,6 +25,8 @@
         '../tools/debugger/SkDrawCommand.cpp',
         '../tools/debugger/SkDebugCanvas.h',
         '../tools/debugger/SkDebugCanvas.cpp',
+        '../tools/debugger/SkJsonWriteBuffer.h',
+        '../tools/debugger/SkJsonWriteBuffer.cpp',
         '../tools/debugger/SkObjectParser.h',
         '../tools/debugger/SkObjectParser.cpp',
         '../tools/debugger/SkOverdrawMode.h',
index f8e4095c300fe5fa60a1fbd6d0d26b5a7ad73e33..b1ce798c0dcfd63ee105f34e362aee25f167e7e5 100644 (file)
@@ -50,6 +50,8 @@
     '../tools/debugger/SkDrawCommand.cpp',
     '../tools/debugger/SkDebugCanvas.h',
     '../tools/debugger/SkDebugCanvas.cpp',
+    '../tools/debugger/SkJsonWriteBuffer.h',
+    '../tools/debugger/SkJsonWriteBuffer.cpp',
     '../tools/debugger/SkObjectParser.h',
     '../tools/debugger/SkObjectParser.cpp',
     '../tools/debugger/SkOverdrawMode.h',
index 27a00f977e0ecc9f8382acc14975d6d57f9032fa..664686619f2766fc60ce2eb02912e0fb52776a99 100644 (file)
@@ -774,8 +774,8 @@ private:
     static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
     static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
 
-    friend class SkReadBuffer;      // unflatten, rawpixels
-    friend class SkWriteBuffer;     // rawpixels
+    friend class SkReadBuffer;        // unflatten, rawpixels
+    friend class SkBinaryWriteBuffer; // rawpixels
     friend struct SkBitmapProcState;
 };
 
index b69a75ab12ae32570fbc36deed75327cf1a9b194..87ac8bf21494aa3ea8ec2aec7823a03bf74a0bea 100644 (file)
@@ -24,16 +24,58 @@ class SkFlattenable;
 class SkRefCntSet;
 
 class SkWriteBuffer {
+public:
+    SkWriteBuffer() {}
+    virtual ~SkWriteBuffer() {}
+
+    virtual bool isCrossProcess() const = 0;
+
+    virtual void writeByteArray(const void* data, size_t size) = 0;
+    void writeDataAsByteArray(SkData* data) {
+        this->writeByteArray(data->data(), data->size());
+    }
+    virtual void writeBool(bool value) = 0;
+    virtual void writeScalar(SkScalar value) = 0;
+    virtual void writeScalarArray(const SkScalar* value, uint32_t count) = 0;
+    virtual void writeInt(int32_t value) = 0;
+    virtual void writeIntArray(const int32_t* value, uint32_t count) = 0;
+    virtual void writeUInt(uint32_t value) = 0;
+    void write32(int32_t value) {
+        this->writeInt(value);
+    }
+    virtual void writeString(const char* value) = 0;
+
+    virtual void writeFlattenable(const SkFlattenable* flattenable) = 0;
+    virtual void writeColor(SkColor color) = 0;
+    virtual void writeColorArray(const SkColor* color, uint32_t count) = 0;
+    virtual void writePoint(const SkPoint& point) = 0;
+    virtual void writePointArray(const SkPoint* point, uint32_t count) = 0;
+    virtual void writeMatrix(const SkMatrix& matrix) = 0;
+    virtual void writeIRect(const SkIRect& rect) = 0;
+    virtual void writeRect(const SkRect& rect) = 0;
+    virtual void writeRegion(const SkRegion& region) = 0;
+    virtual void writePath(const SkPath& path) = 0;
+    virtual size_t writeStream(SkStream* stream, size_t length) = 0;
+    virtual void writeBitmap(const SkBitmap& bitmap) = 0;
+    virtual void writeImage(const SkImage*) = 0;
+    virtual void writeTypeface(SkTypeface* typeface) = 0;
+    virtual void writePaint(const SkPaint& paint) = 0;
+};
+
+/**
+ * Concrete implementation that serializes to a flat binary blob.
+ */
+class SkBinaryWriteBuffer final : public SkWriteBuffer {
 public:
     enum Flags {
-        kCrossProcess_Flag  = 1 << 0,
+        kCrossProcess_Flag = 1 << 0,
     };
 
-    SkWriteBuffer(uint32_t flags = 0);
-    SkWriteBuffer(void* initialStorage, size_t storageSize, uint32_t flags = 0);
-    ~SkWriteBuffer();
+    SkBinaryWriteBuffer(uint32_t flags = 0);
+    SkBinaryWriteBuffer(void* initialStorage, size_t storageSize, uint32_t flags = 0);
+    ~SkBinaryWriteBuffer();
 
-    bool isCrossProcess() const {
+    bool isCrossProcess() const override {
         return SkToBool(fFlags & kCrossProcess_Flag);
     }
 
@@ -43,39 +85,35 @@ public:
 
     size_t bytesWritten() const { return fWriter.bytesWritten(); }
 
-    void writeByteArray(const void* data, size_t size);
-    void writeDataAsByteArray(SkData* data) { this->writeByteArray(data->data(), data->size()); }
-    void writeBool(bool value);
-    void writeScalar(SkScalar value);
-    void writeScalarArray(const SkScalar* value, uint32_t count);
-    void writeInt(int32_t value);
-    void writeIntArray(const int32_t* value, uint32_t count);
-    void writeUInt(uint32_t value);
-    void write32(int32_t value);
-    void writeString(const char* value);
-
-    void writeFlattenable(const SkFlattenable* flattenable);
-    void writeColor(const SkColor& color);
-    void writeColorArray(const SkColor* color, uint32_t count);
-    void writePoint(const SkPoint& point);
-    void writePointArray(const SkPoint* point, uint32_t count);
-    void writeMatrix(const SkMatrix& matrix);
-    void writeIRect(const SkIRect& rect);
-    void writeRect(const SkRect& rect);
-    void writeRegion(const SkRegion& region);
-    void writePath(const SkPath& path);
-    size_t writeStream(SkStream* stream, size_t length);
-    void writeBitmap(const SkBitmap& bitmap);
-    void writeImage(const SkImage*);
-    void writeTypeface(SkTypeface* typeface);
-    void writePaint(const SkPaint& paint) { paint.flatten(*this); }
+    void writeByteArray(const void* data, size_t size) override;
+    void writeBool(bool value) override;
+    void writeScalar(SkScalar value) override;
+    void writeScalarArray(const SkScalar* value, uint32_t count) override;
+    void writeInt(int32_t value) override;
+    void writeIntArray(const int32_t* value, uint32_t count) override;
+    void writeUInt(uint32_t value) override;
+    void writeString(const char* value) override;
+
+    void writeFlattenable(const SkFlattenable* flattenable) override;
+    void writeColor(SkColor color) override;
+    void writeColorArray(const SkColor* color, uint32_t count) override;
+    void writePoint(const SkPoint& point) override;
+    void writePointArray(const SkPoint* point, uint32_t count) override;
+    void writeMatrix(const SkMatrix& matrix) override;
+    void writeIRect(const SkIRect& rect) override;
+    void writeRect(const SkRect& rect) override;
+    void writeRegion(const SkRegion& region) override;
+    void writePath(const SkPath& path) override;
+    size_t writeStream(SkStream* stream, size_t length) override;
+    void writeBitmap(const SkBitmap& bitmap) override;
+    void writeImage(const SkImage*) override;
+    void writeTypeface(SkTypeface* typeface) override;
+    void writePaint(const SkPaint& paint) override;
 
     bool writeToStream(SkWStream*);
     void writeToMemory(void* dst) { fWriter.flatten(dst); }
 
     SkFactorySet* setFactoryRecorder(SkFactorySet*);
-
-    SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
     SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
 
     /**
index 06e8c1070616c1dc2aa76cf3720389a2abbdef93..704526673da994d35eeaebcb9fc289bf34d3fba6 100644 (file)
@@ -12,7 +12,7 @@
 #include "SkWriteBuffer.h"
 
 SkData* SkValidatingSerializeFlattenable(SkFlattenable* flattenable) {
-    SkWriteBuffer writer;
+    SkBinaryWriteBuffer writer;
     writer.writeFlattenable(flattenable);
     size_t size = writer.bytesWritten();
     auto data = SkData::MakeUninitialized(size);
index 3fd25b48e165ab20d10cc0040cf469b0fcfa0e01..67bbda16652ca13e043aab6d2b1bc7336e8dbc2c 100644 (file)
@@ -1198,7 +1198,7 @@ SkRect SkPaint::getFontBounds() const {
 }
 
 static void add_flattenable(SkDescriptor* desc, uint32_t tag,
-                            SkWriteBuffer* buffer) {
+                            SkBinaryWriteBuffer* buffer) {
     buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), nullptr));
 }
 
@@ -1528,9 +1528,9 @@ void SkScalerContext::PostMakeRec(const SkPaint&, SkScalerContext::Rec* rec) {
 #endif
 
 static void write_out_descriptor(SkDescriptor* desc, const SkScalerContext::Rec& rec,
-                                 const SkPathEffect* pe, SkWriteBuffer* peBuffer,
-                                 const SkMaskFilter* mf, SkWriteBuffer* mfBuffer,
-                                 const SkRasterizer* ra, SkWriteBuffer* raBuffer,
+                                 const SkPathEffect* pe, SkBinaryWriteBuffer* peBuffer,
+                                 const SkMaskFilter* mf, SkBinaryWriteBuffer* mfBuffer,
+                                 const SkRasterizer* ra, SkBinaryWriteBuffer* raBuffer,
                                  size_t descSize) {
     desc->init();
     desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
@@ -1552,9 +1552,9 @@ static size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec,
                            const SkSurfaceProps* surfaceProps,
                            bool fakeGamma, bool boostContrast,
                            const SkMatrix* deviceMatrix,
-                           const SkPathEffect* pe, SkWriteBuffer* peBuffer,
-                           const SkMaskFilter* mf, SkWriteBuffer* mfBuffer,
-                           const SkRasterizer* ra, SkWriteBuffer* raBuffer) {
+                           const SkPathEffect* pe, SkBinaryWriteBuffer* peBuffer,
+                           const SkMaskFilter* mf, SkBinaryWriteBuffer* mfBuffer,
+                           const SkRasterizer* ra, SkBinaryWriteBuffer* raBuffer) {
     SkScalerContext::MakeRec(paint, surfaceProps, deviceMatrix, rec);
     if (!fakeGamma) {
         rec->ignoreGamma();
@@ -1601,9 +1601,9 @@ static size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec,
 
 #ifdef TEST_DESC
 static void test_desc(const SkScalerContext::Rec& rec,
-                      const SkPathEffect* pe, SkWriteBuffer* peBuffer,
-                      const SkMaskFilter* mf, SkWriteBuffer* mfBuffer,
-                      const SkRasterizer* ra, SkWriteBuffer* raBuffer,
+                      const SkPathEffect* pe, SkBinaryWriteBuffer* peBuffer,
+                      const SkMaskFilter* mf, SkBinaryWriteBuffer* mfBuffer,
+                      const SkRasterizer* ra, SkBinaryWriteBuffer* raBuffer,
                       const SkDescriptor* desc, size_t descSize) {
     // Check that we completely write the bytes in desc (our key), and that
     // there are no uninitialized bytes. If there were, then we would get
@@ -1658,7 +1658,7 @@ void SkPaint::getScalerContextDescriptor(SkScalerContextEffects* effects,
     SkMaskFilter*   mf = this->getMaskFilter();
     SkRasterizer*   ra = this->getRasterizer();
 
-    SkWriteBuffer   peBuffer, mfBuffer, raBuffer;
+    SkBinaryWriteBuffer   peBuffer, mfBuffer, raBuffer;
     size_t descSize = fill_out_rec(*this, &rec, &surfaceProps,
                                    SkToBool(scalerContextFlags & kFakeGamma_ScalerContextFlag),
                                    SkToBool(scalerContextFlags & kBoostContrast_ScalerContextFlag),
@@ -1697,7 +1697,7 @@ void SkPaint::descriptorProc(const SkSurfaceProps* surfaceProps,
     SkMaskFilter*   mf = this->getMaskFilter();
     SkRasterizer*   ra = this->getRasterizer();
 
-    SkWriteBuffer   peBuffer, mfBuffer, raBuffer;
+    SkBinaryWriteBuffer   peBuffer, mfBuffer, raBuffer;
     size_t descSize = fill_out_rec(*this, &rec, surfaceProps,
                                    SkToBool(scalerContextFlags & kFakeGamma_ScalerContextFlag),
                                    SkToBool(scalerContextFlags & kBoostContrast_ScalerContextFlag),
index 43e0793cfb4996a7230fb84ef1d5ec866eeecd5b..ed32c6c029f498e45aa1d06859043d70b2e7c7e7 100644 (file)
@@ -274,7 +274,7 @@ void SkPictureData::serialize(SkWStream* stream,
     // We delay serializing the bulk of our data until after we've serialized
     // factories and typefaces by first serializing to an in-memory write buffer.
     SkFactorySet factSet;  // buffer refs factSet, so factSet must come first.
-    SkWriteBuffer buffer(SkWriteBuffer::kCrossProcess_Flag);
+    SkBinaryWriteBuffer buffer(SkBinaryWriteBuffer::kCrossProcess_Flag);
     buffer.setFactoryRecorder(&factSet);
     buffer.setPixelSerializer(pixelSerializer);
     buffer.setTypefaceRecorder(typefaceSet);
index 8ef23c62af2e5f53d6c7ad29d9f716c4489ff58b..060bd43c6f2697e8f9583e8f4f2e016dc92236cc 100644 (file)
 #include "SkStream.h"
 #include "SkTypeface.h"
 
-SkWriteBuffer::SkWriteBuffer(uint32_t flags)
+SkBinaryWriteBuffer::SkBinaryWriteBuffer(uint32_t flags)
     : fFlags(flags)
     , fFactorySet(nullptr)
     , fTFSet(nullptr) {
 }
 
-SkWriteBuffer::SkWriteBuffer(void* storage, size_t storageSize, uint32_t flags)
+SkBinaryWriteBuffer::SkBinaryWriteBuffer(void* storage, size_t storageSize, uint32_t flags)
     : fFlags(flags)
     , fFactorySet(nullptr)
     , fWriter(storage, storageSize)
     , fTFSet(nullptr) {
 }
 
-SkWriteBuffer::~SkWriteBuffer() {
+SkBinaryWriteBuffer::~SkBinaryWriteBuffer() {
     SkSafeUnref(fFactorySet);
     SkSafeUnref(fTFSet);
 }
 
-void SkWriteBuffer::writeByteArray(const void* data, size_t size) {
+void SkBinaryWriteBuffer::writeByteArray(const void* data, size_t size) {
     fWriter.write32(SkToU32(size));
     fWriter.writePad(data, size);
 }
 
-void SkWriteBuffer::writeBool(bool value) {
+void SkBinaryWriteBuffer::writeBool(bool value) {
     fWriter.writeBool(value);
 }
 
-void SkWriteBuffer::writeScalar(SkScalar value) {
+void SkBinaryWriteBuffer::writeScalar(SkScalar value) {
     fWriter.writeScalar(value);
 }
 
-void SkWriteBuffer::writeScalarArray(const SkScalar* value, uint32_t count) {
+void SkBinaryWriteBuffer::writeScalarArray(const SkScalar* value, uint32_t count) {
     fWriter.write32(count);
     fWriter.write(value, count * sizeof(SkScalar));
 }
 
-void SkWriteBuffer::writeInt(int32_t value) {
+void SkBinaryWriteBuffer::writeInt(int32_t value) {
     fWriter.write32(value);
 }
 
-void SkWriteBuffer::writeIntArray(const int32_t* value, uint32_t count) {
+void SkBinaryWriteBuffer::writeIntArray(const int32_t* value, uint32_t count) {
     fWriter.write32(count);
     fWriter.write(value, count * sizeof(int32_t));
 }
 
-void SkWriteBuffer::writeUInt(uint32_t value) {
+void SkBinaryWriteBuffer::writeUInt(uint32_t value) {
     fWriter.write32(value);
 }
 
-void SkWriteBuffer::write32(int32_t value) {
-    fWriter.write32(value);
-}
-
-void SkWriteBuffer::writeString(const char* value) {
+void SkBinaryWriteBuffer::writeString(const char* value) {
     fWriter.writeString(value);
 }
 
-void SkWriteBuffer::writeColor(const SkColor& color) {
+void SkBinaryWriteBuffer::writeColor(SkColor color) {
     fWriter.write32(color);
 }
 
-void SkWriteBuffer::writeColorArray(const SkColor* color, uint32_t count) {
+void SkBinaryWriteBuffer::writeColorArray(const SkColor* color, uint32_t count) {
     fWriter.write32(count);
     fWriter.write(color, count * sizeof(SkColor));
 }
 
-void SkWriteBuffer::writePoint(const SkPoint& point) {
+void SkBinaryWriteBuffer::writePoint(const SkPoint& point) {
     fWriter.writeScalar(point.fX);
     fWriter.writeScalar(point.fY);
 }
 
-void SkWriteBuffer::writePointArray(const SkPoint* point, uint32_t count) {
+void SkBinaryWriteBuffer::writePointArray(const SkPoint* point, uint32_t count) {
     fWriter.write32(count);
     fWriter.write(point, count * sizeof(SkPoint));
 }
 
-void SkWriteBuffer::writeMatrix(const SkMatrix& matrix) {
+void SkBinaryWriteBuffer::writeMatrix(const SkMatrix& matrix) {
     fWriter.writeMatrix(matrix);
 }
 
-void SkWriteBuffer::writeIRect(const SkIRect& rect) {
+void SkBinaryWriteBuffer::writeIRect(const SkIRect& rect) {
     fWriter.write(&rect, sizeof(SkIRect));
 }
 
-void SkWriteBuffer::writeRect(const SkRect& rect) {
+void SkBinaryWriteBuffer::writeRect(const SkRect& rect) {
     fWriter.writeRect(rect);
 }
 
-void SkWriteBuffer::writeRegion(const SkRegion& region) {
+void SkBinaryWriteBuffer::writeRegion(const SkRegion& region) {
     fWriter.writeRegion(region);
 }
 
-void SkWriteBuffer::writePath(const SkPath& path) {
+void SkBinaryWriteBuffer::writePath(const SkPath& path) {
     fWriter.writePath(path);
 }
 
-size_t SkWriteBuffer::writeStream(SkStream* stream, size_t length) {
+size_t SkBinaryWriteBuffer::writeStream(SkStream* stream, size_t length) {
     fWriter.write32(SkToU32(length));
     size_t bytesWritten = fWriter.readFromStream(stream, length);
     if (bytesWritten < length) {
@@ -118,18 +114,18 @@ size_t SkWriteBuffer::writeStream(SkStream* stream, size_t length) {
     return bytesWritten;
 }
 
-bool SkWriteBuffer::writeToStream(SkWStream* stream) {
+bool SkBinaryWriteBuffer::writeToStream(SkWStream* stream) {
     return fWriter.writeToStream(stream);
 }
 
-static void write_encoded_bitmap(SkWriteBuffer* buffer, SkData* data,
+static void write_encoded_bitmap(SkBinaryWriteBuffer* buffer, SkData* data,
                                  const SkIPoint& origin) {
     buffer->writeDataAsByteArray(data);
     buffer->write32(origin.fX);
     buffer->write32(origin.fY);
 }
 
-void SkWriteBuffer::writeBitmap(const SkBitmap& bitmap) {
+void SkBinaryWriteBuffer::writeBitmap(const SkBitmap& bitmap) {
     // Record the width and height. This way if readBitmap fails a dummy bitmap can be drawn at the
     // right size.
     this->writeInt(bitmap.width());
@@ -176,7 +172,7 @@ void SkWriteBuffer::writeBitmap(const SkBitmap& bitmap) {
     SkBitmap::WriteRawPixels(this, bitmap);
 }
 
-void SkWriteBuffer::writeImage(const SkImage* image) {
+void SkBinaryWriteBuffer::writeImage(const SkImage* image) {
     this->writeInt(image->width());
     this->writeInt(image->height());
 
@@ -189,7 +185,7 @@ void SkWriteBuffer::writeImage(const SkImage* image) {
     this->writeUInt(0); // signal no pixels (in place of the size of the encoded data)
 }
 
-void SkWriteBuffer::writeTypeface(SkTypeface* obj) {
+void SkBinaryWriteBuffer::writeTypeface(SkTypeface* obj) {
     if (nullptr == obj || nullptr == fTFSet) {
         fWriter.write32(0);
     } else {
@@ -197,24 +193,28 @@ void SkWriteBuffer::writeTypeface(SkTypeface* obj) {
     }
 }
 
-SkFactorySet* SkWriteBuffer::setFactoryRecorder(SkFactorySet* rec) {
+void SkBinaryWriteBuffer::writePaint(const SkPaint& paint) {
+    paint.flatten(*this);
+}
+
+SkFactorySet* SkBinaryWriteBuffer::setFactoryRecorder(SkFactorySet* rec) {
     SkRefCnt_SafeAssign(fFactorySet, rec);
     return rec;
 }
 
-SkRefCntSet* SkWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) {
+SkRefCntSet* SkBinaryWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) {
     SkRefCnt_SafeAssign(fTFSet, rec);
     return rec;
 }
 
-void SkWriteBuffer::setPixelSerializer(SkPixelSerializer* serializer) {
+void SkBinaryWriteBuffer::setPixelSerializer(SkPixelSerializer* serializer) {
     fPixelSerializer.reset(serializer);
     if (serializer) {
         serializer->ref();
     }
 }
 
-void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) {
+void SkBinaryWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) {
     /*
      *  The first 32 bits tell us...
      *       0: failure to write the flattenable
index cf542db9fa2060233cbb93cb0719b138873ed165..9dfadbbb840b56928783ef773c795337e26b4b57 100644 (file)
@@ -16,7 +16,7 @@
 #include "Test.h"
 
 static sk_sp<SkColorFilter> reincarnate_colorfilter(SkFlattenable* obj) {
-    SkWriteBuffer wb;
+    SkBinaryWriteBuffer wb;
     wb.writeFlattenable(obj);
 
     size_t size = wb.bytesWritten();
index 2132729330870905d934a399af9f0eb605b15d54..e70404b6399ca603b80d2309c163ad0cf3ed75fb 100644 (file)
@@ -210,7 +210,7 @@ DEF_TEST(FlattenDrawable, r) {
     SkPaint paint;
     paint.setColor(SK_ColorBLUE);
     SkAutoTUnref<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable));
-    SkWriteBuffer writeBuffer;
+    SkBinaryWriteBuffer writeBuffer;
     writeBuffer.writeFlattenable(root);
 
     // Copy the contents of the write buffer into a read buffer
@@ -270,7 +270,7 @@ DEF_TEST(FlattenRecordedDrawable, r) {
 
     // Serialize the recorded drawable
     sk_sp<SkDrawable> recordedDrawable = recorder.finishRecordingAsDrawable();
-    SkWriteBuffer writeBuffer;
+    SkBinaryWriteBuffer writeBuffer;
     writeBuffer.writeFlattenable(recordedDrawable.get());
 
     // Copy the contents of the write buffer into a read buffer
index 794f76872a4759c8c39d444f0e78431ec335d171..567331c89257dc87ffc8d4030c20d10bd7228925 100644 (file)
@@ -52,7 +52,7 @@ static sk_sp<SkFlattenable> custom_create_proc(SkReadBuffer& buffer) {
 
 DEF_TEST(UnflattenWithCustomFactory, r) {
     // Create and flatten the test flattenable
-    SkWriteBuffer writeBuffer;
+    SkBinaryWriteBuffer writeBuffer;
     SkAutoTUnref<SkFlattenable> flattenable1(new IntFlattenable(1, 2, 3, 4));
     writeBuffer.writeFlattenable(flattenable1);
     SkAutoTUnref<SkFlattenable> flattenable2(new IntFlattenable(2, 3, 4, 5));
index 3c08e48bec717541a7b050ded88f4c20ddfd2820..95a9d59aede7af749a6b75042e7cc798daf40922 100644 (file)
@@ -19,7 +19,7 @@
 static void test_flatten(skiatest::Reporter* reporter, const SkImageInfo& info) {
     // just need a safe amount of storage, but ensure that it is 4-byte aligned.
     int32_t storage[(sizeof(SkImageInfo)*2) / sizeof(int32_t)];
-    SkWriteBuffer wb(storage, sizeof(storage));
+    SkBinaryWriteBuffer wb(storage, sizeof(storage));
     info.flatten(wb);
     SkASSERT(wb.bytesWritten() < sizeof(storage));
 
index 98653449474bd43c2c1c6c1561a31612de3d9f1f..bd00adb18d288fce132a75435261f29be6a9868e 100644 (file)
@@ -255,7 +255,7 @@ DEF_TEST(Paint_flattening, reporter) {
     FOR_SETUP(n, encodings, setTextEncoding)
     FOR_SETUP(p, styles, setStyle)
 
-    SkWriteBuffer writer;
+    SkBinaryWriteBuffer writer;
     paint.flatten(writer);
 
     SkAutoMalloc buf(writer.bytesWritten());
@@ -295,7 +295,7 @@ DEF_TEST(Paint_MoreFlattening, r) {
     paint.setXfermode(SkXfermode::Make(SkXfermode::kModulate_Mode));
     paint.setLooper(nullptr);  // Default value, ignored.
 
-    SkWriteBuffer writer;
+    SkBinaryWriteBuffer writer;
     paint.flatten(writer);
 
     SkAutoMalloc buf(writer.bytesWritten());
index a8f253f0257eebe4c9cf0c025fddd177a67e4352..4750bbe25d436a13de76f62ede826487c719efb4 100644 (file)
@@ -139,7 +139,7 @@ template<> struct SerializationTestUtils<SkString, true> {
 
 template<typename T, bool testInvalid>
 static void TestObjectSerializationNoAlign(T* testObj, skiatest::Reporter* reporter) {
-    SkWriteBuffer writer;
+    SkBinaryWriteBuffer writer;
     SerializationUtils<T>::Write(writer, testObj);
     size_t bytesWritten = writer.bytesWritten();
     REPORTER_ASSERT(reporter, SkAlign4(bytesWritten) == bytesWritten);
@@ -177,7 +177,7 @@ static void TestObjectSerialization(T* testObj, skiatest::Reporter* reporter) {
 template<typename T>
 static T* TestFlattenableSerialization(T* testObj, bool shouldSucceed,
                                        skiatest::Reporter* reporter) {
-    SkWriteBuffer writer;
+    SkBinaryWriteBuffer writer;
     SerializationUtils<T>::Write(writer, testObj);
     size_t bytesWritten = writer.bytesWritten();
     REPORTER_ASSERT(reporter, SkAlign4(bytesWritten) == bytesWritten);
@@ -215,7 +215,7 @@ static T* TestFlattenableSerialization(T* testObj, bool shouldSucceed,
 
 template<typename T>
 static void TestArraySerialization(T* data, skiatest::Reporter* reporter) {
-    SkWriteBuffer writer;
+    SkBinaryWriteBuffer writer;
     SerializationUtils<T>::Write(writer, data, kArraySize);
     size_t bytesWritten = writer.bytesWritten();
     // This should write the length (in 4 bytes) and the array
@@ -533,7 +533,7 @@ DEF_TEST(Serialization, reporter) {
         sk_sp<SkPicture> pict(recorder.finishRecordingAsPicture());
 
         // Serialize picture
-        SkWriteBuffer writer;
+        SkBinaryWriteBuffer writer;
         pict->flatten(writer);
         size_t size = writer.bytesWritten();
         SkAutoTMalloc<unsigned char> data(size);
index 985f7d5cc3705de219d2b7620e69e1fd0456b941..4a88fa1b33142c582ecb502955bfde18e79d3a5e 100644 (file)
@@ -12,6 +12,7 @@
 #include "SkColorFilter.h"
 #include "SkDashPathEffect.h"
 #include "SkImageFilter.h"
+#include "SkJsonWriteBuffer.h"
 #include "SkMaskFilter.h"
 #include "SkObjectParser.h"
 #include "SkPaintDefaults.h"
@@ -63,6 +64,7 @@
 #define SKDEBUGCANVAS_ATTRIBUTE_VERBS             "verbs"
 #define SKDEBUGCANVAS_ATTRIBUTE_NAME              "name"
 #define SKDEBUGCANVAS_ATTRIBUTE_DATA              "data"
+#define SKDEBUGCANVAS_ATTRIBUTE_VALUES            "values"
 #define SKDEBUGCANVAS_ATTRIBUTE_SHADER            "shader"
 #define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT        "pathEffect"
 #define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER        "maskFilter"
@@ -386,7 +388,7 @@ void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner)
 
 };
 
-static Json::Value make_json_color(const SkColor color) {
+Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
     Json::Value result(Json::arrayValue);
     result.append(Json::Value(SkColorGetA(color)));
     result.append(Json::Value(SkColorGetR(color)));
@@ -395,22 +397,21 @@ static Json::Value make_json_color(const SkColor color) {
     return result;
 }
 
-
-static Json::Value make_json_point(const SkPoint& point) {
+Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
     Json::Value result(Json::arrayValue);
     result.append(Json::Value(point.x()));
     result.append(Json::Value(point.y()));
     return result;
 }
 
-static Json::Value make_json_point(SkScalar x, SkScalar y) {
+Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
     Json::Value result(Json::arrayValue);
     result.append(Json::Value(x));
     result.append(Json::Value(y));
     return result;
 }
 
-static Json::Value make_json_rect(const SkRect& rect) {
+Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
     Json::Value result(Json::arrayValue);
     result.append(Json::Value(rect.left()));
     result.append(Json::Value(rect.top()));
@@ -430,11 +431,11 @@ Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
 
 static Json::Value make_json_rrect(const SkRRect& rrect) {
     Json::Value result(Json::arrayValue);
-    result.append(make_json_rect(rrect.rect()));
-    result.append(make_json_point(rrect.radii(SkRRect::kUpperLeft_Corner)));
-    result.append(make_json_point(rrect.radii(SkRRect::kUpperRight_Corner)));
-    result.append(make_json_point(rrect.radii(SkRRect::kLowerRight_Corner)));
-    result.append(make_json_point(rrect.radii(SkRRect::kLowerLeft_Corner)));
+    result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
+    result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
+    result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
+    result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
+    result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
     return result;
 }
 
@@ -458,7 +459,7 @@ Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
     return result;
 }
 
-static Json::Value make_json_path(const SkPath& path) {
+Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
     Json::Value result(Json::objectValue);
     switch (path.getFillType()) {
         case SkPath::kWinding_FillType:
@@ -482,15 +483,15 @@ static Json::Value make_json_path(const SkPath& path) {
         switch (verb) {
             case SkPath::kLine_Verb: {
                 Json::Value line(Json::objectValue);
-                line[SKDEBUGCANVAS_VERB_LINE] = make_json_point(pts[1]);
+                line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
                 verbs.append(line);
                 break;
             }
             case SkPath::kQuad_Verb: {
                 Json::Value quad(Json::objectValue);
                 Json::Value coords(Json::arrayValue);
-                coords.append(make_json_point(pts[1]));
-                coords.append(make_json_point(pts[2]));
+                coords.append(MakeJsonPoint(pts[1]));
+                coords.append(MakeJsonPoint(pts[2]));
                 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
                 verbs.append(quad);
                 break;
@@ -498,9 +499,9 @@ static Json::Value make_json_path(const SkPath& path) {
             case SkPath::kCubic_Verb: {
                 Json::Value cubic(Json::objectValue);
                 Json::Value coords(Json::arrayValue);
-                coords.append(make_json_point(pts[1]));
-                coords.append(make_json_point(pts[2]));
-                coords.append(make_json_point(pts[3]));
+                coords.append(MakeJsonPoint(pts[1]));
+                coords.append(MakeJsonPoint(pts[2]));
+                coords.append(MakeJsonPoint(pts[3]));
                 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
                 verbs.append(cubic);
                 break;
@@ -508,8 +509,8 @@ static Json::Value make_json_path(const SkPath& path) {
             case SkPath::kConic_Verb: {
                 Json::Value conic(Json::objectValue);
                 Json::Value coords(Json::arrayValue);
-                coords.append(make_json_point(pts[1]));
-                coords.append(make_json_point(pts[2]));
+                coords.append(MakeJsonPoint(pts[1]));
+                coords.append(MakeJsonPoint(pts[2]));
                 coords.append(Json::Value(iter.conicWeight()));
                 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
                 verbs.append(conic);
@@ -517,7 +518,7 @@ static Json::Value make_json_path(const SkPath& path) {
             }
             case SkPath::kMove_Verb: {
                 Json::Value move(Json::objectValue);
-                move[SKDEBUGCANVAS_VERB_MOVE] = make_json_point(pts[0]);
+                move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
                 verbs.append(move);
                 break;
             }
@@ -532,7 +533,7 @@ static Json::Value make_json_path(const SkPath& path) {
     return result;
 }
 
-static Json::Value make_json_region(const SkRegion& region) {
+Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
     return Json::Value("<unimplemented>");
 }
 
@@ -590,9 +591,9 @@ static void encode_data(const void* bytes, size_t count, const char* contentType
     *target = Json::Value(url.c_str());
 }
 
-static void flatten(const SkFlattenable* flattenable, Json::Value* target,
-                    UrlDataManager& urlDataManager) {
-    SkWriteBuffer buffer;
+void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
+                            UrlDataManager& urlDataManager) {
+    SkBinaryWriteBuffer buffer;
     flattenable->flatten(buffer);
     void* data = sk_malloc_throw(buffer.bytesWritten());
     buffer.writeToMemory(data);
@@ -601,6 +602,11 @@ static void flatten(const SkFlattenable* flattenable, Json::Value* target,
     Json::Value jsonFlattenable;
     jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
     jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
+
+    SkJsonWriteBuffer jsonBuffer(&urlDataManager);
+    flattenable->flatten(jsonBuffer);
+    jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
+
     (*target) = jsonFlattenable;
     sk_free(data);
 }
@@ -643,8 +649,8 @@ void SkDrawCommand::WritePNG(const png_bytep rgba, png_uint_32 width, png_uint_3
     sk_free(pixels);
 }
 
-static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* target,
-                                          UrlDataManager& urlDataManager) {
+bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
+                            UrlDataManager& urlDataManager) {
     size_t rowBytes = 4 * image.width();
     SkAutoFree buffer(sk_malloc_throw(rowBytes * image.height()));
     SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
@@ -815,8 +821,8 @@ static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& u
     return result;
 }
 
-static bool SK_WARN_UNUSED_RESULT flatten(const SkBitmap& bitmap, Json::Value* target,
-                                          UrlDataManager& urlDataManager) {
+bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
+                            UrlDataManager& urlDataManager) {
     bitmap.lockPixels();
     sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
     bitmap.unlockPixels();
@@ -959,7 +965,7 @@ static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
             (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
         } else {
             Json::Value jsonMaskFilter;
-            flatten(maskFilter, &jsonMaskFilter, urlDataManager);
+            SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
             (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
         }
     }
@@ -985,7 +991,7 @@ static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
             (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
         } else {
             Json::Value jsonPathEffect;
-            flatten(pathEffect, &jsonPathEffect, urlDataManager);
+            SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
             (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
         }
     }
@@ -1031,7 +1037,7 @@ static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
     SkFlattenable* shader = paint.getShader();
     if (shader != nullptr) {
         Json::Value jsonShader;
-        flatten(shader, &jsonShader, urlDataManager);
+        SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
         (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
     }
 }
@@ -1041,7 +1047,7 @@ static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target,
     SkFlattenable* xfermode = paint.getXfermode();
     if (xfermode != nullptr) {
         Json::Value jsonXfermode;
-        flatten(xfermode, &jsonXfermode, urlDataManager);
+        SkDrawCommand::flatten(xfermode, &jsonXfermode, urlDataManager);
         (*target)[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode;
     }
 }
@@ -1051,7 +1057,7 @@ static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
     SkFlattenable* imageFilter = paint.getImageFilter();
     if (imageFilter != nullptr) {
         Json::Value jsonImageFilter;
-        flatten(imageFilter, &jsonImageFilter, urlDataManager);
+        SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
         (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
     }
 }
@@ -1061,7 +1067,7 @@ static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
     SkFlattenable* colorFilter = paint.getColorFilter();
     if (colorFilter != nullptr) {
         Json::Value jsonColorFilter;
-        flatten(colorFilter, &jsonColorFilter, urlDataManager);
+        SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
         (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
     }
 }
@@ -1071,12 +1077,12 @@ static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
     SkFlattenable* looper = paint.getLooper();
     if (looper != nullptr) {
         Json::Value jsonLooper;
-        flatten(looper, &jsonLooper, urlDataManager);
+        SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
         (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
     }
 }
 
-Json::Value make_json_paint(const SkPaint& paint, UrlDataManager& urlDataManager) {
+Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
     Json::Value result(Json::objectValue);
     store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
     store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
@@ -1545,7 +1551,7 @@ void SkClearCommand::execute(SkCanvas* canvas) const {
 
 Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
-    result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = make_json_color(fColor);
+    result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
     return result;
 }
 
@@ -1576,7 +1582,7 @@ bool SkClipPathCommand::render(SkCanvas* canvas) const {
 
 Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
     result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
     result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
     return result;
@@ -1605,7 +1611,7 @@ void SkClipRegionCommand::execute(SkCanvas* canvas) const {
 
 Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
-    result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = make_json_region(fRegion);
+    result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
     result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
     return result;
 }
@@ -1633,7 +1639,7 @@ void SkClipRectCommand::execute(SkCanvas* canvas) const {
 
 Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
-    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fRect);
+    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
     result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
     result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
     return result;
@@ -1743,9 +1749,9 @@ Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
     if (flatten(fBitmap, &encoded, urlDataManager)) {
         Json::Value command(Json::objectValue);
         result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
-        result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fLeft, fTop);
+        result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
         if (fPaintPtr != nullptr) {
-            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, urlDataManager);
+            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
         }
     }
     return result;
@@ -1810,9 +1816,9 @@ Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) cons
     if (flatten(fBitmap, &encoded, urlDataManager)) {
         result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
         result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
-        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
+        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
         if (fPaintPtr != nullptr) {
-            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, urlDataManager);
+            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
         }
     }
     return result;
@@ -1888,11 +1894,11 @@ Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) cons
     if (flatten(fBitmap, &encoded, urlDataManager)) {
         result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
         if (!fSrc.isEmpty()) {
-            result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = make_json_rect(fSrc);
+            result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
         }
-        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
+        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
         if (fPaintPtr != nullptr) {
-            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, urlDataManager);
+            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
         }
         if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
             result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
@@ -1978,9 +1984,9 @@ Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value encoded;
     if (flatten(*fImage, &encoded, urlDataManager)) {
         result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
-        result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fLeft, fTop);
+        result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
         if (fPaint.isValid()) {
-            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaint.get(), urlDataManager);
+            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
         }
     }
     return result;
@@ -2055,11 +2061,11 @@ Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const
     if (flatten(*fImage.get(), &encoded, urlDataManager)) {
         result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
         if (fSrc.isValid()) {
-            result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = make_json_rect(*fSrc.get());
+            result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
         }
-        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
+        result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
         if (fPaint.isValid()) {
-            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaint.get(), urlDataManager);
+            result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
         }
         if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
             result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
@@ -2138,8 +2144,8 @@ bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
 
 Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
-    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fOval);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2171,7 +2177,7 @@ bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
 
 Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2202,8 +2208,8 @@ bool SkDrawPathCommand::render(SkCanvas* canvas) const {
 
 Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2327,10 +2333,10 @@ Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
     result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
     Json::Value points(Json::arrayValue);
     for (size_t i = 0; i < fCount; i++) {
-        points.append(make_json_point(fPts[i]));
+        points.append(MakeJsonPoint(fPts[i]));
     }
     result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2395,10 +2401,10 @@ Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value coords(Json::arrayValue);
     size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
     for (size_t i = 0; i < numCoords; i++) {
-        coords.append(make_json_point(fPos[i]));
+        coords.append(MakeJsonPoint(fPos[i]));
     }
     result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2453,7 +2459,7 @@ Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const
         xpos.append(Json::Value(fXpos[i]));
     }
     result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2548,8 +2554,8 @@ Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const
         for (uint32_t i = 0; i < iter.glyphCount(); i++) {
             switch (iter.positioning()) {
                 case SkTextBlob::kFull_Positioning:
-                    jsonPositions.append(make_json_point(iterPositions[i * 2],
-                                                         iterPositions[i * 2 + 1]));
+                    jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
+                                                       iterPositions[i * 2 + 1]));
                     break;
                 case SkTextBlob::kHorizontal_Positioning:
                     jsonPositions.append(Json::Value(iterPositions[i]));
@@ -2565,15 +2571,15 @@ Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const
         run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
         SkPaint fontPaint;
         iter.applyFontToPaint(&fontPaint);
-        run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = make_json_paint(fontPaint, urlDataManager);
-        run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(iter.offset());
+        run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
+        run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
         runs.append(run);
         iter.next();
     }
     result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
     result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
     result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2656,20 +2662,20 @@ Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
     Json::Value cubics = Json::Value(Json::arrayValue);
     for (int i = 0; i < 12; i++) {
-        cubics.append(make_json_point(fCubics[i]));
+        cubics.append(MakeJsonPoint(fCubics[i]));
     }
     result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
     if (fColorsPtr != nullptr) {
         Json::Value colors = Json::Value(Json::arrayValue);
         for (int i = 0; i < 4; i++) {
-            colors.append(make_json_color(fColorsPtr[i]));
+            colors.append(MakeJsonColor(fColorsPtr[i]));
         }
         result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
     }
     if (fTexCoordsPtr != nullptr) {
         Json::Value texCoords = Json::Value(Json::arrayValue);
         for (int i = 0; i < 4; i++) {
-            texCoords.append(make_json_point(fTexCoords[i]));
+            texCoords.append(MakeJsonPoint(fTexCoords[i]));
         }
         result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
     }
@@ -2737,8 +2743,8 @@ void SkDrawRectCommand::execute(SkCanvas* canvas) const {
 
 Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
-    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fRect);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2772,7 +2778,7 @@ bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
 Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
     result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2811,7 +2817,7 @@ Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
     result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
     result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2851,8 +2857,8 @@ Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
     result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
                                                        ((const char*) fText) + fByteLength);
     Json::Value coords(Json::arrayValue);
-    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fX, fY);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -2900,11 +2906,11 @@ Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) cons
     result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
                                                        ((const char*) fText) + fByteLength);
     Json::Value coords(Json::arrayValue);
-    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
     if (!fMatrix.isIdentity()) {
         result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
     }
-    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, urlDataManager);
+    result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
     return result;
 }
 
@@ -3064,10 +3070,10 @@ void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
 Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
     Json::Value result = INHERITED::toJSON(urlDataManager);
     if (!fBounds.isEmpty()) {
-        result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = make_json_rect(fBounds);
+        result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
     }
     if (fPaintPtr != nullptr) {
-        result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr,
+        result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
                                                                 urlDataManager);
     }
     if (fBackdrop != nullptr) {
index ac9e476a9aefb6decf481b47ba21115c4d6efd7b..9b81adad3fa6be4eda1e0d7b8130364fcaa9bc76 100644 (file)
@@ -116,8 +116,22 @@ public:
     static const char* GetCommandString(OpType type);
 
     // Helper methods for converting things to JSON
+    static Json::Value MakeJsonColor(const SkColor color);
+    static Json::Value MakeJsonPoint(const SkPoint& point);
+    static Json::Value MakeJsonPoint(SkScalar x, SkScalar y);
+    static Json::Value MakeJsonRect(const SkRect& rect);
     static Json::Value MakeJsonIRect(const SkIRect&);
     static Json::Value MakeJsonMatrix(const SkMatrix&);
+    static Json::Value MakeJsonPath(const SkPath& path);
+    static Json::Value MakeJsonRegion(const SkRegion& region);
+    static Json::Value MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager);
+
+    static void flatten(const SkFlattenable* flattenable, Json::Value* target,
+                        UrlDataManager& urlDataManager);
+    static bool flatten(const SkImage& image, Json::Value* target,
+                        UrlDataManager& urlDataManager);
+    static bool flatten(const SkBitmap& bitmap, Json::Value* target,
+                        UrlDataManager& urlDataManager);
 
 protected:
     SkTDArray<SkString*> fInfo;
diff --git a/tools/debugger/SkJsonWriteBuffer.cpp b/tools/debugger/SkJsonWriteBuffer.cpp
new file mode 100644 (file)
index 0000000..1b5a962
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkJsonWriteBuffer.h"
+
+#include "SkDrawCommand.h"
+#include "SkObjectParser.h"
+
+void SkJsonWriteBuffer::append(const char* type, const Json::Value& value) {
+    SkString fullName = SkStringPrintf("%02d_%s", fJson.size(), type);
+    fJson[fullName.c_str()] = value;
+}
+
+void SkJsonWriteBuffer::writeByteArray(const void* data, size_t size) {
+    Json::Value jsonArray(Json::arrayValue);
+    const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
+    for (size_t i = 0; i < size; ++i) {
+        SkString hexByte = SkStringPrintf("%02x", bytes[i]);
+        jsonArray.append(hexByte.c_str());
+    }
+    this->append("byteArray", jsonArray);
+}
+
+void SkJsonWriteBuffer::writeBool(bool value) {
+    this->append("bool", value);
+}
+
+void SkJsonWriteBuffer::writeScalar(SkScalar value) {
+    this->append("scalar", value);
+}
+
+void SkJsonWriteBuffer::writeScalarArray(const SkScalar* value, uint32_t count) {
+    Json::Value jsonArray(Json::arrayValue);
+    for (uint32_t i = 0; i < count; ++i) {
+        jsonArray.append(value[i]);
+    }
+    this->append("scalarArray", jsonArray);
+}
+
+void SkJsonWriteBuffer::writeInt(int32_t value) {
+    this->append("int", value);
+}
+
+void SkJsonWriteBuffer::writeIntArray(const int32_t* value, uint32_t count) {
+    Json::Value jsonArray(Json::arrayValue);
+    for (uint32_t i = 0; i < count; ++i) {
+        jsonArray.append(value[i]);
+    }
+    this->append("intArray", jsonArray);
+}
+
+void SkJsonWriteBuffer::writeUInt(uint32_t value) {
+    this->append("uint", value);
+}
+
+void SkJsonWriteBuffer::writeString(const char* value) {
+    this->append("string", value);
+}
+
+void SkJsonWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) {
+    if (flattenable) {
+        SkJsonWriteBuffer flattenableBuffer(fUrlDataManager);
+        flattenable->flatten(flattenableBuffer);
+        this->append(flattenable->getTypeName(), flattenableBuffer.getValue());
+    } else {
+        this->append("flattenable", Json::Value());
+    }
+}
+
+void SkJsonWriteBuffer::writeColor(SkColor color) {
+    this->append("color", SkDrawCommand::MakeJsonColor(color));
+}
+
+void SkJsonWriteBuffer::writeColorArray(const SkColor* color, uint32_t count) {
+    Json::Value jsonArray(Json::arrayValue);
+    for (uint32_t i = 0; i < count; ++i) {
+        jsonArray.append(SkDrawCommand::MakeJsonColor(color[i]));
+    }
+    this->append("colorArray", jsonArray);
+}
+
+void SkJsonWriteBuffer::writePoint(const SkPoint& point) {
+    this->append("point", SkDrawCommand::MakeJsonPoint(point));
+}
+
+void SkJsonWriteBuffer::writePointArray(const SkPoint* point, uint32_t count) {
+    Json::Value jsonArray(Json::arrayValue);
+    for (uint32_t i = 0; i < count; ++i) {
+        jsonArray.append(SkDrawCommand::MakeJsonPoint(point[i]));
+    }
+    this->append("pointArray", jsonArray);
+}
+
+void SkJsonWriteBuffer::writeMatrix(const SkMatrix& matrix) {
+    this->append("matrix", SkDrawCommand::MakeJsonMatrix(matrix));
+}
+
+void SkJsonWriteBuffer::writeIRect(const SkIRect& rect) {
+    this->append("irect", SkDrawCommand::MakeJsonIRect(rect));
+}
+
+void SkJsonWriteBuffer::writeRect(const SkRect& rect) {
+    this->append("rect", SkDrawCommand::MakeJsonRect(rect));
+}
+
+void SkJsonWriteBuffer::writeRegion(const SkRegion& region) {
+    this->append("region", SkDrawCommand::MakeJsonRegion(region));
+}
+
+void SkJsonWriteBuffer::writePath(const SkPath& path) {
+    this->append("path", SkDrawCommand::MakeJsonPath(path));
+}
+
+size_t SkJsonWriteBuffer::writeStream(SkStream* stream, size_t length) {
+    // Contents not supported
+    SkASSERT(length < Json::Value::maxUInt);
+    this->append("stream", static_cast<Json::UInt>(length));
+    return 0;
+}
+
+void SkJsonWriteBuffer::writeBitmap(const SkBitmap& bitmap) {
+    Json::Value jsonBitmap;
+    SkDrawCommand::flatten(bitmap, &jsonBitmap, *fUrlDataManager);
+    this->append("bitmap", jsonBitmap);
+}
+
+void SkJsonWriteBuffer::writeImage(const SkImage* image) {
+    Json::Value jsonImage;
+    SkDrawCommand::flatten(*image, &jsonImage, *fUrlDataManager);
+    this->append("image", jsonImage);
+}
+
+void SkJsonWriteBuffer::writeTypeface(SkTypeface* typeface) {
+    // Unsupported
+    this->append("typeface", Json::Value());
+}
+
+void SkJsonWriteBuffer::writePaint(const SkPaint& paint) {
+    this->append("paint", SkDrawCommand::MakeJsonPaint(paint, *fUrlDataManager));
+}
diff --git a/tools/debugger/SkJsonWriteBuffer.h b/tools/debugger/SkJsonWriteBuffer.h
new file mode 100644 (file)
index 0000000..068b650
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkJsonWriteBuffer_DEFINED
+#define SkJsonWriteBuffer_DEFINED
+
+#include "SkWriteBuffer.h"
+
+#include "SkJSONCPP.h"
+
+class SkPath;
+class UrlDataManager;
+
+class SkJsonWriteBuffer final : public SkWriteBuffer {
+public:
+    SkJsonWriteBuffer(UrlDataManager* urlDataManager)
+        : fUrlDataManager(urlDataManager)
+        , fJson(Json::objectValue) {}
+
+    bool isCrossProcess() const override { return false; }
+
+    void writeByteArray(const void* data, size_t size) override;
+    void writeBool(bool value) override;
+    void writeScalar(SkScalar value) override;
+    void writeScalarArray(const SkScalar* value, uint32_t count) override;
+    void writeInt(int32_t value) override;
+    void writeIntArray(const int32_t* value, uint32_t count) override;
+    void writeUInt(uint32_t value) override;
+    void writeString(const char* value) override;
+
+    void writeFlattenable(const SkFlattenable* flattenable) override;
+    void writeColor(SkColor color) override;
+    void writeColorArray(const SkColor* color, uint32_t count) override;
+    void writePoint(const SkPoint& point) override;
+    void writePointArray(const SkPoint* point, uint32_t count) override;
+    void writeMatrix(const SkMatrix& matrix) override;
+    void writeIRect(const SkIRect& rect) override;
+    void writeRect(const SkRect& rect) override;
+    void writeRegion(const SkRegion& region) override;
+    void writePath(const SkPath& path) override;
+    size_t writeStream(SkStream* stream, size_t length) override;
+    void writeBitmap(const SkBitmap& bitmap) override;
+    void writeImage(const SkImage*) override;
+    void writeTypeface(SkTypeface* typeface) override;
+    void writePaint(const SkPaint& paint) override;
+
+    const Json::Value& getValue() const { return fJson; }
+
+private:
+    void append(const char* type, const Json::Value& value);
+
+    UrlDataManager* fUrlDataManager;
+    Json::Value fJson;
+};
+
+#endif