/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tools/debugger/DrawCommand.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkBlurTypes.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorType.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkFlattenable.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPicture.h"
#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"
#include "include/encode/SkPngEncoder.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkTo.h"
#include "include/private/gpu/ganesh/GrImageContext.h"
#include "include/utils/SkShadowUtils.h"
#include "src/base/SkAutoMalloc.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkPaintDefaults.h"
#include "src/core/SkRectPriv.h"
#include "src/core/SkTextBlobPriv.h"
#include "src/core/SkWriteBuffer.h"
#include "src/image/SkImage_Base.h"
#include "src/utils/SkJSONWriter.h"
#include "tools/UrlDataManager.h"
#include "tools/debugger/DebugLayerManager.h"
#include "tools/debugger/JsonWriteBuffer.h"

#include <algorithm>
#include <cstring>
#include <utility>

class GrDirectContext;

#if defined(SK_GANESH)
#include "include/gpu/ganesh/GrRecordingContext.h"
#endif

#define DEBUGCANVAS_ATTRIBUTE_DUMP "dump"
#define DEBUGCANVAS_ATTRIBUTE_COMMAND "command"
#define DEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
#define DEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
#define DEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
#define DEBUGCANVAS_ATTRIBUTE_COORDS "coords"
#define DEBUGCANVAS_ATTRIBUTE_EDGING "edging"
#define DEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
#define DEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
#define DEBUGCANVAS_ATTRIBUTE_PAINT "paint"
#define DEBUGCANVAS_ATTRIBUTE_OUTER "outer"
#define DEBUGCANVAS_ATTRIBUTE_INNER "inner"
#define DEBUGCANVAS_ATTRIBUTE_MODE "mode"
#define DEBUGCANVAS_ATTRIBUTE_POINTS "points"
#define DEBUGCANVAS_ATTRIBUTE_PATH "path"
#define DEBUGCANVAS_ATTRIBUTE_CLUSTERS "clusters"
#define DEBUGCANVAS_ATTRIBUTE_TEXT "text"
#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"
#define DEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
#define DEBUGCANVAS_ATTRIBUTE_CAP "cap"
#define DEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
#define DEBUGCANVAS_ATTRIBUTE_DITHER "dither"
#define DEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT "fakeBoldText"
#define DEBUGCANVAS_ATTRIBUTE_LINEARTEXT "linearText"
#define DEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT "subpixelText"
#define DEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT "devKernText"
#define DEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT "lcdRenderText"
#define DEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT "embeddedBitmapText"
#define DEBUGCANVAS_ATTRIBUTE_AUTOHINTING "forceAutoHinting"
#define DEBUGCANVAS_ATTRIBUTE_REGION "region"
#define DEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
#define DEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
#define DEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
#define DEBUGCANVAS_ATTRIBUTE_BLUR "blur"
#define DEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
#define DEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
#define DEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
#define DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
#define DEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
#define DEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
#define DEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
#define DEBUGCANVAS_ATTRIBUTE_PHASE "phase"
#define DEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
#define DEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
#define DEBUGCANVAS_ATTRIBUTE_NAME "name"
#define DEBUGCANVAS_ATTRIBUTE_DATA "data"
#define DEBUGCANVAS_ATTRIBUTE_VALUES "values"
#define DEBUGCANVAS_ATTRIBUTE_SHADER "shader"
#define DEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
#define DEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
#define DEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
#define DEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
#define DEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
#define DEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
#define DEBUGCANVAS_ATTRIBUTE_IMAGE "image"
#define DEBUGCANVAS_ATTRIBUTE_IMAGE_INDEX "imageIndex"
#define DEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
#define DEBUGCANVAS_ATTRIBUTE_SRC "src"
#define DEBUGCANVAS_ATTRIBUTE_DST "dst"
#define DEBUGCANVAS_ATTRIBUTE_CENTER "center"
#define DEBUGCANVAS_ATTRIBUTE_STRICT "strict"
#define DEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
#define DEBUGCANVAS_ATTRIBUTE_X "x"
#define DEBUGCANVAS_ATTRIBUTE_Y "y"
#define DEBUGCANVAS_ATTRIBUTE_RUNS "runs"
#define DEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
#define DEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
#define DEBUGCANVAS_ATTRIBUTE_FONT "font"
#define DEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
#define DEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
#define DEBUGCANVAS_ATTRIBUTE_COLORS "colors"
#define DEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
#define DEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
#define DEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
#define DEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
#define DEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
#define DEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
#define DEBUGCANVAS_ATTRIBUTE_WIDTH "width"
#define DEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
#define DEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
#define DEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
#define DEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
#define DEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
#define DEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
#define DEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
#define DEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
#define DEBUGCANVAS_ATTRIBUTE_ZPLANE "zPlane"
#define DEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION "lightPositions"
#define DEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR "ambientColor"
#define DEBUGCANVAS_ATTRIBUTE_SPOTCOLOR "spotColor"
#define DEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS "lightRadius"
#define DEBUGCANVAS_ATTRIBUTE_LAYERNODEID "layerNodeId"

#define DEBUGCANVAS_VERB_MOVE "move"
#define DEBUGCANVAS_VERB_LINE "line"
#define DEBUGCANVAS_VERB_QUAD "quad"
#define DEBUGCANVAS_VERB_CUBIC "cubic"
#define DEBUGCANVAS_VERB_CONIC "conic"
#define DEBUGCANVAS_VERB_CLOSE "close"

#define DEBUGCANVAS_STYLE_FILL "fill"
#define DEBUGCANVAS_STYLE_STROKE "stroke"
#define DEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"

#define DEBUGCANVAS_POINTMODE_POINTS "points"
#define DEBUGCANVAS_POINTMODE_LINES "lines"
#define DEBUGCANVAS_POINTMODE_POLYGON "polygon"

#define DEBUGCANVAS_CLIPOP_DIFFERENCE "difference"
#define DEBUGCANVAS_CLIPOP_INTERSECT "intersect"

#define DEBUGCANVAS_BLURSTYLE_NORMAL "normal"
#define DEBUGCANVAS_BLURSTYLE_SOLID "solid"
#define DEBUGCANVAS_BLURSTYLE_OUTER "outer"
#define DEBUGCANVAS_BLURSTYLE_INNER "inner"

#define DEBUGCANVAS_BLURQUALITY_LOW "low"
#define DEBUGCANVAS_BLURQUALITY_HIGH "high"

#define DEBUGCANVAS_FILLTYPE_WINDING "winding"
#define DEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
#define DEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
#define DEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"

#define DEBUGCANVAS_CAP_BUTT "butt"
#define DEBUGCANVAS_CAP_ROUND "round"
#define DEBUGCANVAS_CAP_SQUARE "square"

#define DEBUGCANVAS_MITER_JOIN "miter"
#define DEBUGCANVAS_ROUND_JOIN "round"
#define DEBUGCANVAS_BEVEL_JOIN "bevel"

#define DEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
#define DEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
#define DEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
#define DEBUGCANVAS_COLORTYPE_565 "565"
#define DEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
#define DEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
#define DEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"

#define DEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
#define DEBUGCANVAS_ALPHATYPE_PREMUL "premul"
#define DEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
#define DEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"

#define DEBUGCANVAS_HINTING_NONE "none"
#define DEBUGCANVAS_HINTING_SLIGHT "slight"
#define DEBUGCANVAS_HINTING_NORMAL "normal"
#define DEBUGCANVAS_HINTING_FULL "full"

#define DEBUGCANVAS_EDGING_ALIAS "alias"
#define DEBUGCANVAS_EDGING_ANTIALIAS "antialias"
#define DEBUGCANVAS_EDGING_SUBPIXELANTIALIAS "subpixelantialias"

#define DEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC "transparentOccluder"
#define DEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY "geometricOnly"

static SkString* str_append(SkString* str, const SkRect& r) {
    str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
    return str;
}

DrawCommand::DrawCommand(OpType type) : fOpType(type), fVisible(true) {}

const char* DrawCommand::GetCommandString(OpType type) {
    switch (type) {
        case kBeginDrawPicture_OpType: return "BeginDrawPicture";
        case kClear_OpType: return "DrawClear";
        case kClipPath_OpType: return "ClipPath";
        case kClipRegion_OpType: return "ClipRegion";
        case kClipRect_OpType: return "ClipRect";
        case kClipRRect_OpType: return "ClipRRect";
        case kResetClip_OpType: return "ResetClip";
        case kConcat_OpType: return "Concat";
        case kConcat44_OpType: return "Concat44";
        case kDrawAnnotation_OpType: return "DrawAnnotation";
        case kDrawBitmap_OpType: return "DrawBitmap";
        case kDrawBitmapRect_OpType: return "DrawBitmapRect";
        case kDrawDRRect_OpType: return "DrawDRRect";
        case kDrawImage_OpType: return "DrawImage";
        case kDrawImageLattice_OpType: return "DrawImageLattice";
        case kDrawImageRect_OpType: return "DrawImageRect";
        case kDrawImageRectLayer_OpType: return "DrawImageRectLayer";
        case kDrawOval_OpType: return "DrawOval";
        case kDrawPaint_OpType: return "DrawPaint";
        case kDrawPatch_OpType: return "DrawPatch";
        case kDrawPath_OpType: return "DrawPath";
        case kDrawArc_OpType: return "DrawArc";
        case kDrawPoints_OpType: return "DrawPoints";
        case kDrawRect_OpType: return "DrawRect";
        case kDrawRRect_OpType: return "DrawRRect";
        case kDrawRegion_OpType: return "DrawRegion";
        case kDrawShadow_OpType: return "DrawShadow";
        case kDrawTextBlob_OpType: return "DrawTextBlob";
        case kDrawVertices_OpType: return "DrawVertices";
        case kDrawAtlas_OpType: return "DrawAtlas";
        case kDrawDrawable_OpType: return "DrawDrawable";
        case kDrawEdgeAAQuad_OpType: return "DrawEdgeAAQuad";
        case kDrawEdgeAAImageSet_OpType: return "DrawEdgeAAImageSet";
        case kEndDrawPicture_OpType: return "EndDrawPicture";
        case kRestore_OpType: return "Restore";
        case kSave_OpType: return "Save";
        case kSaveLayer_OpType: return "SaveLayer";
        case kSetMatrix_OpType: return "SetMatrix";
        case kSetM44_OpType: return "SetM44";
        default:
            SkDebugf("OpType error 0x%08x\n", type);
            SkASSERT(0);
            break;
    }
    SkDEBUGFAIL("DrawType UNUSED\n");
    return nullptr;
}

void DrawCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_COMMAND, this->GetCommandString(fOpType));
    writer.appendBool(DEBUGCANVAS_ATTRIBUTE_VISIBLE, this->isVisible());
}

namespace {

void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
    const SkISize& size = canvas->getBaseLayerSize();

    static const SkScalar kInsetFrac = 0.9f;  // Leave a border around object

    canvas->translate(size.fWidth / 2.0f, size.fHeight / 2.0f);
    if (bounds.width() > bounds.height()) {
        canvas->scale(SkDoubleToScalar((kInsetFrac * size.fWidth) / bounds.width()),
                      SkDoubleToScalar((kInsetFrac * size.fHeight) / bounds.width()));
    } else {
        canvas->scale(SkDoubleToScalar((kInsetFrac * size.fWidth) / bounds.height()),
                      SkDoubleToScalar((kInsetFrac * size.fHeight) / bounds.height()));
    }
    canvas->translate(-bounds.centerX(), -bounds.centerY());
}

void render_path(SkCanvas* canvas, const SkPath& path) {
    canvas->clear(0xFFFFFFFF);

    const SkRect& bounds = path.getBounds();
    if (bounds.isEmpty()) {
        return;
    }

    SkAutoCanvasRestore acr(canvas, true);
    xlate_and_scale_to_bounds(canvas, bounds);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawPath(path, p);
}

void render_region(SkCanvas* canvas, const SkRegion& region) {
    canvas->clear(0xFFFFFFFF);

    const SkIRect& bounds = region.getBounds();
    if (bounds.isEmpty()) {
        return;
    }

    SkAutoCanvasRestore acr(canvas, true);
    xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawRegion(region, p);
}

void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    const SkRect& bounds = rrect.getBounds();

    xlate_and_scale_to_bounds(canvas, bounds);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawRRect(rrect, p);
    canvas->restore();
}

void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    const SkRect& bounds = outer.getBounds();

    xlate_and_scale_to_bounds(canvas, bounds);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawDRRect(outer, inner, p);
    canvas->restore();
}

void render_shadow(SkCanvas* canvas, const SkPath& path, SkDrawShadowRec rec) {
    canvas->clear(0xFFFFFFFF);

    const SkRect& bounds = path.getBounds();
    if (bounds.isEmpty()) {
        return;
    }

    SkAutoCanvasRestore acr(canvas, true);
    xlate_and_scale_to_bounds(canvas, bounds);

    rec.fAmbientColor = SK_ColorBLACK;
    rec.fSpotColor    = SK_ColorBLACK;
    canvas->private_draw_shadow_rec(path, rec);
}

void apply_paint_blend_mode(const SkPaint& paint, SkJSONWriter& writer) {
    const auto mode = paint.getBlendMode_or(SkBlendMode::kSrcOver);
    if (mode != SkBlendMode::kSrcOver) {
        writer.appendCString(DEBUGCANVAS_ATTRIBUTE_BLENDMODE, SkBlendMode_Name(mode));
    }
}

}  // namespace

void DrawCommand::MakeJsonColor(SkJSONWriter& writer, const SkColor color) {
    writer.beginArray(nullptr, false);
    writer.appendS32(SkColorGetA(color));
    writer.appendS32(SkColorGetR(color));
    writer.appendS32(SkColorGetG(color));
    writer.appendS32(SkColorGetB(color));
    writer.endArray();
}

void DrawCommand::MakeJsonColor4f(SkJSONWriter& writer, const SkColor4f& color) {
    writer.beginArray(nullptr, false);
    writer.appendFloat(color.fA);
    writer.appendFloat(color.fR);
    writer.appendFloat(color.fG);
    writer.appendFloat(color.fB);
    writer.endArray();
}

void DrawCommand::MakeJsonPoint(SkJSONWriter& writer, const SkPoint& point) {
    writer.beginArray(nullptr, false);
    writer.appendFloat(point.x());
    writer.appendFloat(point.y());
    writer.endArray();
}

void DrawCommand::MakeJsonPoint(SkJSONWriter& writer, SkScalar x, SkScalar y) {
    writer.beginArray(nullptr, false);
    writer.appendFloat(x);
    writer.appendFloat(y);
    writer.endArray();
}

void DrawCommand::MakeJsonPoint3(SkJSONWriter& writer, const SkPoint3& point) {
    writer.beginArray(nullptr, false);
    writer.appendFloat(point.x());
    writer.appendFloat(point.y());
    writer.appendFloat(point.z());
    writer.endArray();
}

void DrawCommand::MakeJsonRect(SkJSONWriter& writer, const SkRect& rect) {
    writer.beginArray(nullptr, false);
    writer.appendFloat(rect.left());
    writer.appendFloat(rect.top());
    writer.appendFloat(rect.right());
    writer.appendFloat(rect.bottom());
    writer.endArray();
}

void DrawCommand::MakeJsonIRect(SkJSONWriter& writer, const SkIRect& rect) {
    writer.beginArray(nullptr, false);
    writer.appendS32(rect.left());
    writer.appendS32(rect.top());
    writer.appendS32(rect.right());
    writer.appendS32(rect.bottom());
    writer.endArray();
}

static void make_json_rrect(SkJSONWriter& writer, const SkRRect& rrect) {
    writer.beginArray(nullptr, false);
    DrawCommand::MakeJsonRect(writer, rrect.rect());
    DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kUpperLeft_Corner));
    DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kUpperRight_Corner));
    DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kLowerRight_Corner));
    DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kLowerLeft_Corner));
    writer.endArray();
}

void DrawCommand::MakeJsonMatrix(SkJSONWriter& writer, const SkMatrix& matrix) {
    writer.beginArray();
    for (int r = 0; r < 3; ++r) {
        writer.beginArray(nullptr, false);
        for (int c = 0; c < 3; ++c) {
            writer.appendFloat(matrix[r * 3 + c]);
        }
        writer.endArray();
    }
    writer.endArray();
}

void DrawCommand::MakeJsonMatrix44(SkJSONWriter& writer, const SkM44& matrix) {
    writer.beginArray();
    for (int r = 0; r < 4; ++r) {
        writer.beginArray(nullptr, false);
        for (int c = 0; c < 4; ++c) {
            writer.appendFloat(matrix.rc(r, c));
        }
        writer.endArray();
    }
    writer.endArray();
}

void DrawCommand::MakeJsonPath(SkJSONWriter& writer, const SkPath& path) {
    writer.beginObject();

    SkDynamicMemoryWStream wstream;
    path.dump(&wstream, false);
    auto data = wstream.detachAsData();
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_DUMP,
                        static_cast<const char*>(data->data()), data->size());

    switch (path.getFillType()) {
        case SkPathFillType::kWinding:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE, DEBUGCANVAS_FILLTYPE_WINDING);
            break;
        case SkPathFillType::kEvenOdd:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE, DEBUGCANVAS_FILLTYPE_EVENODD);
            break;
        case SkPathFillType::kInverseWinding:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE,
                                 DEBUGCANVAS_FILLTYPE_INVERSEWINDING);
            break;
        case SkPathFillType::kInverseEvenOdd:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE,
                                 DEBUGCANVAS_FILLTYPE_INVERSEEVENODD);
            break;
    }
    writer.beginArray(DEBUGCANVAS_ATTRIBUTE_VERBS);
    SkPath::Iter iter(path, false);
    SkPoint      pts[4];
    SkPath::Verb verb;
    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        if (verb == SkPath::kClose_Verb) {
            writer.appendNString(DEBUGCANVAS_VERB_CLOSE);
            continue;
        }
        writer.beginObject();  // verb
        switch (verb) {
            case SkPath::kLine_Verb: {
                writer.appendName(DEBUGCANVAS_VERB_LINE);
                MakeJsonPoint(writer, pts[1]);
                break;
            }
            case SkPath::kQuad_Verb: {
                writer.beginArray(DEBUGCANVAS_VERB_QUAD);
                MakeJsonPoint(writer, pts[1]);
                MakeJsonPoint(writer, pts[2]);
                writer.endArray();  // quad coords
                break;
            }
            case SkPath::kCubic_Verb: {
                writer.beginArray(DEBUGCANVAS_VERB_CUBIC);
                MakeJsonPoint(writer, pts[1]);
                MakeJsonPoint(writer, pts[2]);
                MakeJsonPoint(writer, pts[3]);
                writer.endArray();  // cubic coords
                break;
            }
            case SkPath::kConic_Verb: {
                writer.beginArray(DEBUGCANVAS_VERB_CONIC);
                MakeJsonPoint(writer, pts[1]);
                MakeJsonPoint(writer, pts[2]);
                writer.appendFloat(iter.conicWeight());
                writer.endArray();  // conic coords
                break;
            }
            case SkPath::kMove_Verb: {
                writer.appendName(DEBUGCANVAS_VERB_MOVE);
                MakeJsonPoint(writer, pts[0]);
                break;
            }
            case SkPath::kClose_Verb:
            case SkPath::kDone_Verb:
                // Unreachable
                break;
        }
        writer.endObject();  // verb
    }
    writer.endArray();   // verbs
    writer.endObject();  // path
}

void DrawCommand::MakeJsonRegion(SkJSONWriter& writer, const SkRegion& region) {
    // TODO: Actually serialize the rectangles, rather than just devolving to path
    SkPath path;
    region.getBoundaryPath(&path);
    MakeJsonPath(writer, path);
}

void DrawCommand::MakeJsonSampling(SkJSONWriter& writer, const SkSamplingOptions& sampling) {
    writer.beginObject();
    writer.appendS32("maxAniso", sampling.maxAniso);
    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;
        case SkClipOp::kIntersect: return DEBUGCANVAS_CLIPOP_INTERSECT;
        default: SkASSERT(false); return "<invalid region op>";
    }
}

static const char* pointmode_name(SkCanvas::PointMode mode) {
    switch (mode) {
        case SkCanvas::kPoints_PointMode: return DEBUGCANVAS_POINTMODE_POINTS;
        case SkCanvas::kLines_PointMode: return DEBUGCANVAS_POINTMODE_LINES;
        case SkCanvas::kPolygon_PointMode: return DEBUGCANVAS_POINTMODE_POLYGON;
        default: SkASSERT(false); return "<invalid point mode>";
    }
}

static void store_scalar(SkJSONWriter& writer,
                         const char*   key,
                         SkScalar      value,
                         SkScalar      defaultValue) {
    if (value != defaultValue) {
        writer.appendFloat(key, value);
    }
}

static void store_bool(SkJSONWriter& writer, const char* key, bool value, bool defaultValue) {
    if (value != defaultValue) {
        writer.appendBool(key, value);
    }
}

static SkString encode_data(const void*     bytes,
                            size_t          count,
                            const char*     contentType,
                            UrlDataManager& urlDataManager) {
    sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
    return urlDataManager.addData(data.get(), contentType);
}

void DrawCommand::flatten(const SkFlattenable* flattenable,
                          SkJSONWriter&        writer,
                          UrlDataManager&      urlDataManager) {
    SkBinaryWriteBuffer buffer({});  // TODO(kjlubick, bungeman) feed SkSerialProcs through API
    flattenable->flatten(buffer);
    void* data = sk_malloc_throw(buffer.bytesWritten());
    buffer.writeToMemory(data);
    SkString url =
            encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager);
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_NAME, flattenable->getTypeName());
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url);

    writer.beginObject(DEBUGCANVAS_ATTRIBUTE_VALUES);
    JsonWriteBuffer jsonBuffer(&writer, &urlDataManager);
    flattenable->flatten(jsonBuffer);
    writer.endObject();  // values

    sk_free(data);
}

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,
                          UrlDataManager& urlDataManager) {
    // For MSKP files, there is no need to encode the image,
    // just report its id.
    if (urlDataManager.hasImageIndex()) {
        writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_INDEX);
        writer.appendU64(urlDataManager.lookupImage(&image));
        return true;
    }

    writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
    size_t       rowBytes = 4 * image.width();
    SkAutoMalloc buffer(rowBytes * image.height());
    SkImageInfo  dstInfo =
            SkImageInfo::Make(image.dimensions(), kN32_SkColorType, kPremul_SkAlphaType);
    // "cheat" for this debug tool and use image's context
    GrDirectContext* dContext = nullptr;
#if defined(SK_GANESH)
    dContext = GrAsDirectContext(as_IB(&image)->context());
#endif
    if (!image.readPixels(dContext, dstInfo, buffer.get(), rowBytes, 0, 0)) {
        SkDebugf("DrawCommand::flatten SkImage: readPixels failed\n");
        writer.endObject();
        return false;
    }

    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");
        writer.endObject();
        return false;
    }
    auto dataPtr = encoded->data();
    if (!dataPtr) {
      SkDebugf("DrawCommand::flatten SkImage: encoding as PNG produced zero length data\n");
      writer.endObject();
      return false;
    }
    SkString url = encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager);
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url);
    writer.endObject();
    return true;
}

static const char* color_type_name(SkColorType colorType) {
    switch (colorType) {
        case kARGB_4444_SkColorType: return DEBUGCANVAS_COLORTYPE_ARGB4444;
        case kRGBA_8888_SkColorType: return DEBUGCANVAS_COLORTYPE_RGBA8888;
        case kBGRA_8888_SkColorType: return DEBUGCANVAS_COLORTYPE_BGRA8888;
        case kRGB_565_SkColorType: return DEBUGCANVAS_COLORTYPE_565;
        case kGray_8_SkColorType: return DEBUGCANVAS_COLORTYPE_GRAY8;
        case kAlpha_8_SkColorType: return DEBUGCANVAS_COLORTYPE_ALPHA8;
        default: SkASSERT(false); return DEBUGCANVAS_COLORTYPE_RGBA8888;
    }
}

static const char* alpha_type_name(SkAlphaType alphaType) {
    switch (alphaType) {
        case kOpaque_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_OPAQUE;
        case kPremul_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_PREMUL;
        case kUnpremul_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_UNPREMUL;
        default: SkASSERT(false); return DEBUGCANVAS_ALPHATYPE_OPAQUE;
    }
}

bool DrawCommand::flatten(const SkBitmap& bitmap,
                          SkJSONWriter&   writer,
                          UrlDataManager& urlDataManager) {
    sk_sp<SkImage> image(bitmap.asImage());
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_COLOR, color_type_name(bitmap.colorType()));
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_ALPHA, alpha_type_name(bitmap.alphaType()));
    // Image will appear to have no uses, TODO(nifong): provide the user with a useful explanation
    bool success = flatten(*image, writer, urlDataManager);
    return success;
}

static void apply_font_hinting(const SkFont& font, SkJSONWriter& writer) {
    SkFontHinting hinting = font.getHinting();
    if (hinting != SkPaintDefaults_Hinting) {
        switch (hinting) {
            case SkFontHinting::kNone:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_NONE);
                break;
            case SkFontHinting::kSlight:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_SLIGHT);
                break;
            case SkFontHinting::kNormal:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_NORMAL);
                break;
            case SkFontHinting::kFull:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_FULL);
                break;
        }
    }
}

static void apply_font_edging(const SkFont& font, SkJSONWriter& writer) {
    switch (font.getEdging()) {
        case SkFont::Edging::kAlias:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_EDGING, DEBUGCANVAS_EDGING_ALIAS);
            break;
        case SkFont::Edging::kAntiAlias:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_EDGING, DEBUGCANVAS_EDGING_ANTIALIAS);
            break;
        case SkFont::Edging::kSubpixelAntiAlias:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_EDGING,
                                 DEBUGCANVAS_EDGING_SUBPIXELANTIALIAS);
            break;
    }
}

static void apply_paint_color(const SkPaint& paint, SkJSONWriter& writer) {
    SkColor color = paint.getColor();
    if (color != SK_ColorBLACK) {
        writer.appendName(DEBUGCANVAS_ATTRIBUTE_COLOR);
        DrawCommand::MakeJsonColor(writer, color);
    }
}

static void apply_paint_style(const SkPaint& paint, SkJSONWriter& writer) {
    SkPaint::Style style = paint.getStyle();
    if (style != SkPaint::kFill_Style) {
        switch (style) {
            case SkPaint::kStroke_Style: {
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_STYLE_STROKE);
                break;
            }
            case SkPaint::kStrokeAndFill_Style: {
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_STYLE_STROKEANDFILL);
                break;
            }
            default: SkASSERT(false);
        }
    }
}

static void apply_paint_cap(const SkPaint& paint, SkJSONWriter& writer) {
    SkPaint::Cap cap = paint.getStrokeCap();
    if (cap != SkPaint::kDefault_Cap) {
        switch (cap) {
            case SkPaint::kButt_Cap:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_BUTT);
                break;
            case SkPaint::kRound_Cap:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_ROUND);
                break;
            case SkPaint::kSquare_Cap:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_SQUARE);
                break;
            default: SkASSERT(false);
        }
    }
}

static void apply_paint_join(const SkPaint& paint, SkJSONWriter& writer) {
    SkPaint::Join join = paint.getStrokeJoin();
    if (join != SkPaint::kDefault_Join) {
        switch (join) {
            case SkPaint::kMiter_Join:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_MITER_JOIN);
                break;
            case SkPaint::kRound_Join:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_ROUND_JOIN);
                break;
            case SkPaint::kBevel_Join:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_BEVEL_JOIN);
                break;
            default: SkASSERT(false);
        }
    }
}

static void apply_paint_maskfilter(const SkPaint&  paint,
                                   SkJSONWriter&   writer,
                                   UrlDataManager& urlDataManager) {
    SkMaskFilter* maskFilter = paint.getMaskFilter();
    if (maskFilter != nullptr) {
        SkMaskFilterBase::BlurRec blurRec;
        if (as_MFB(maskFilter)->asABlur(&blurRec)) {
            writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BLUR);
            writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_SIGMA, blurRec.fSigma);
            switch (blurRec.fStyle) {
                case SkBlurStyle::kNormal_SkBlurStyle:
                    writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_NORMAL);
                    break;
                case SkBlurStyle::kSolid_SkBlurStyle:
                    writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_SOLID);
                    break;
                case SkBlurStyle::kOuter_SkBlurStyle:
                    writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_OUTER);
                    break;
                case SkBlurStyle::kInner_SkBlurStyle:
                    writer.appendNString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_INNER);
                    break;
                default: SkASSERT(false);
            }
            writer.endObject();  // blur
        } else {
            writer.beginObject(DEBUGCANVAS_ATTRIBUTE_MASKFILTER);
            DrawCommand::flatten(maskFilter, writer, urlDataManager);
            writer.endObject();  // maskFilter
        }
    }
}

static void apply_paint_patheffect(const SkPaint&  paint,
                                   SkJSONWriter&   writer,
                                   UrlDataManager& urlDataManager) {
    SkPathEffect* pathEffect = paint.getPathEffect();
    if (pathEffect != nullptr) {
        SkPathEffect::DashInfo dashInfo;
        SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
        if (dashType == SkPathEffect::kDash_DashType) {
            dashInfo.fIntervals = (SkScalar*)sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
            pathEffect->asADash(&dashInfo);
            writer.beginObject(DEBUGCANVAS_ATTRIBUTE_DASHING);
            writer.beginArray(DEBUGCANVAS_ATTRIBUTE_INTERVALS, false);
            for (int32_t i = 0; i < dashInfo.fCount; i++) {
                writer.appendFloat(dashInfo.fIntervals[i]);
            }
            writer.endArray();  // intervals
            sk_free(dashInfo.fIntervals);
            writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_PHASE, dashInfo.fPhase);
            writer.endObject();  // dashing
        } else {
            writer.beginObject(DEBUGCANVAS_ATTRIBUTE_PATHEFFECT);
            DrawCommand::flatten(pathEffect, writer, urlDataManager);
            writer.endObject();  // pathEffect
        }
    }
}

static void apply_font_typeface(const SkFont&   font,
                                SkJSONWriter&   writer,
                                UrlDataManager& urlDataManager) {
    SkTypeface* typeface = font.getTypeface();
    if (typeface != nullptr) {
        writer.beginObject(DEBUGCANVAS_ATTRIBUTE_TYPEFACE);
        SkDynamicMemoryWStream buffer;
        typeface->serialize(&buffer);
        void* data = sk_malloc_throw(buffer.bytesWritten());
        buffer.copyTo(data);
        SkString url = encode_data(
                data, buffer.bytesWritten(), "application/octet-stream", urlDataManager);
        writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url);
        sk_free(data);
        writer.endObject();
    }
}

static void apply_flattenable(const char*     key,
                              SkFlattenable*  flattenable,
                              SkJSONWriter&   writer,
                              UrlDataManager& urlDataManager) {
    if (flattenable != nullptr) {
        writer.beginObject(key);
        DrawCommand::flatten(flattenable, writer, urlDataManager);
        writer.endObject();
    }
}

void DrawCommand::MakeJsonPaint(SkJSONWriter&   writer,
                                const SkPaint&  paint,
                                UrlDataManager& urlDataManager) {
    writer.beginObject();
    store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
    store_scalar(writer,
                 DEBUGCANVAS_ATTRIBUTE_STROKEMITER,
                 paint.getStrokeMiter(),
                 SkPaintDefaults_MiterLimit);
    store_bool(writer, DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
    store_bool(writer, DEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);

    apply_paint_color(paint, writer);
    apply_paint_style(paint, writer);
    apply_paint_blend_mode(paint, writer);
    apply_paint_cap(paint, writer);
    apply_paint_join(paint, writer);
    apply_paint_patheffect(paint, writer, urlDataManager);
    apply_paint_maskfilter(paint, writer, urlDataManager);
    apply_flattenable(DEBUGCANVAS_ATTRIBUTE_SHADER, paint.getShader(), writer, urlDataManager);
    apply_flattenable(
            DEBUGCANVAS_ATTRIBUTE_IMAGEFILTER, paint.getImageFilter(), writer, urlDataManager);
    apply_flattenable(
            DEBUGCANVAS_ATTRIBUTE_COLORFILTER, paint.getColorFilter(), writer, urlDataManager);
    writer.endObject();  // paint
}

static void MakeJsonFont(const SkFont& font, SkJSONWriter& writer, UrlDataManager& urlDataManager) {
    writer.beginObject();
    store_bool(writer, DEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, font.isEmbolden(), false);
    store_bool(writer, DEBUGCANVAS_ATTRIBUTE_LINEARTEXT, font.isLinearMetrics(), false);
    store_bool(writer, DEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, font.isSubpixel(), false);
    store_bool(writer, DEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, font.isEmbeddedBitmaps(), false);
    store_bool(writer, DEBUGCANVAS_ATTRIBUTE_AUTOHINTING, font.isForceAutoHinting(), false);

    store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSIZE, font.getSize(), SkPaintDefaults_TextSize);
    store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, font.getScaleX(), SK_Scalar1);
    store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, font.getSkewX(), 0.0f);
    apply_font_edging(font, writer);
    apply_font_hinting(font, writer);
    apply_font_typeface(font, writer, urlDataManager);
    writer.endObject();  // font
}

void DrawCommand::MakeJsonLattice(SkJSONWriter& writer, const SkCanvas::Lattice& lattice) {
    writer.beginObject();
    writer.appendS32(DEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT, lattice.fXCount);
    writer.appendS32(DEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT, lattice.fYCount);
    if (nullptr != lattice.fBounds) {
        writer.appendName(DEBUGCANVAS_ATTRIBUTE_BOUNDS);
        MakeJsonIRect(writer, *lattice.fBounds);
    }
    writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS);
    for (int i = 0; i < lattice.fXCount; i++) {
        writer.appendS32(lattice.fXDivs[i]);
    }
    writer.endArray();  // xdivs
    writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS);
    for (int i = 0; i < lattice.fYCount; i++) {
        writer.appendS32(lattice.fYDivs[i]);
    }
    writer.endArray();  // ydivs
    if (nullptr != lattice.fRectTypes) {
        writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS);
        int flagCount = 0;
        for (int row = 0; row < lattice.fYCount + 1; row++) {
            writer.beginArray();
            for (int column = 0; column < lattice.fXCount + 1; column++) {
                writer.appendS32(lattice.fRectTypes[flagCount++]);
            }
            writer.endArray();  // row
        }
        writer.endArray();
    }
    writer.endObject();
}

ClearCommand::ClearCommand(SkColor color) : INHERITED(kClear_OpType) { fColor = color; }

void ClearCommand::execute(SkCanvas* canvas) const { canvas->clear(fColor); }

void ClearCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COLOR);
    MakeJsonColor(writer, fColor);
}

ClipPathCommand::ClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
        : INHERITED(kClipPath_OpType) {
    fPath = path;
    fOp   = op;
    fDoAA = doAA;
}

void ClipPathCommand::execute(SkCanvas* canvas) const { canvas->clipPath(fPath, fOp, fDoAA); }

bool ClipPathCommand::render(SkCanvas* canvas) const {
    render_path(canvas, fPath);
    return true;
}

void ClipPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
    MakeJsonPath(writer, fPath);
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
    writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
}

ClipRegionCommand::ClipRegionCommand(const SkRegion& region, SkClipOp op)
        : INHERITED(kClipRegion_OpType) {
    fRegion = region;
    fOp     = op;
}

void ClipRegionCommand::execute(SkCanvas* canvas) const { canvas->clipRegion(fRegion, fOp); }

void ClipRegionCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_REGION);
    MakeJsonRegion(writer, fRegion);
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
}

ClipRectCommand::ClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
        : INHERITED(kClipRect_OpType) {
    fRect = rect;
    fOp   = op;
    fDoAA = doAA;
}

void ClipRectCommand::execute(SkCanvas* canvas) const { canvas->clipRect(fRect, fOp, fDoAA); }

void ClipRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
    MakeJsonRect(writer, fRect);
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
    writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);

    SkString desc;
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, *str_append(&desc, fRect));
}

ClipRRectCommand::ClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
        : INHERITED(kClipRRect_OpType) {
    fRRect = rrect;
    fOp    = op;
    fDoAA  = doAA;
}

void ClipRRectCommand::execute(SkCanvas* canvas) const { canvas->clipRRect(fRRect, fOp, fDoAA); }

bool ClipRRectCommand::render(SkCanvas* canvas) const {
    render_rrect(canvas, fRRect);
    return true;
}

void ClipRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
    make_json_rrect(writer, fRRect);
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
    writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
}

ClipShaderCommand::ClipShaderCommand(sk_sp<SkShader> cs, SkClipOp op)
        : INHERITED(kClipShader_OpType) {
    fShader = std::move(cs);
    fOp     = op;
}

void ClipShaderCommand::execute(SkCanvas* canvas) const { canvas->clipShader(fShader, fOp); }

bool ClipShaderCommand::render(SkCanvas* canvas) const {
    SkPaint paint;
    paint.setShader(fShader);
    canvas->drawPaint(paint);
    return true;
}

void ClipShaderCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    apply_flattenable(DEBUGCANVAS_ATTRIBUTE_SHADER, fShader.get(), writer, urlDataManager);
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, clipop_name(fOp));
}

ResetClipCommand::ResetClipCommand() : INHERITED(kResetClip_OpType) {}

void ResetClipCommand::execute(SkCanvas* canvas) const { SkCanvasPriv::ResetClip(canvas); }

ConcatCommand::ConcatCommand(const SkMatrix& matrix) : INHERITED(kConcat_OpType) {
    fMatrix = matrix;
}

void ConcatCommand::execute(SkCanvas* canvas) const { canvas->concat(fMatrix); }

namespace {
    void writeMatrixType(SkJSONWriter& writer, const SkMatrix& m) {
        switch (m.getType()) {
            case SkMatrix::kTranslate_Mask:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, " (translate)");
                break;
            case SkMatrix::kScale_Mask:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, " (scale)");
                break;
            case SkMatrix::kAffine_Mask:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, " (rotation or skew)");
                break;
            case SkMatrix::kPerspective_Mask:
                writer.appendNString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, " (perspective)");
                break;
            default:
                break;
        }
    }
}

void ConcatCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_MATRIX);
    MakeJsonMatrix(writer, fMatrix);
    writeMatrixType(writer, fMatrix);
}

Concat44Command::Concat44Command(const SkM44& matrix) : INHERITED(kConcat44_OpType) {
    fMatrix = matrix;
}

void Concat44Command::execute(SkCanvas* canvas) const { canvas->concat(fMatrix); }

void Concat44Command::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_MATRIX);
    MakeJsonMatrix44(writer, fMatrix);
}

////

DrawAnnotationCommand::DrawAnnotationCommand(const SkRect& rect,
                                             const char    key[],
                                             sk_sp<SkData> value)
        : INHERITED(kDrawAnnotation_OpType), fRect(rect), fKey(key), fValue(std::move(value)) {}

void DrawAnnotationCommand::execute(SkCanvas* canvas) const {
    canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
}

void DrawAnnotationCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);

    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
    MakeJsonRect(writer, fRect);
    writer.appendString("key", fKey);
    if (fValue) {
        writer.appendString("value", static_cast<const char*>(fValue->data()), fValue->size());
    }

    SkString desc;
    str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, desc);
}

////

DrawImageCommand::DrawImageCommand(const SkImage*           image,
                                   SkScalar                 left,
                                   SkScalar                 top,
                                   const SkSamplingOptions& sampling,
                                   const SkPaint*           paint)
        : INHERITED(kDrawImage_OpType)
        , fImage(SkRef(image))
        , fLeft(left)
        , fTop(top)
        , fSampling(sampling)
        , fPaint(paint) {}

void DrawImageCommand::execute(SkCanvas* canvas) const {
    canvas->drawImage(fImage.get(), fLeft, fTop, fSampling, fPaint.getMaybeNull());
}

bool DrawImageCommand::render(SkCanvas* canvas) const {
    SkAutoCanvasRestore acr(canvas, true);
    canvas->clear(0xFFFFFFFF);

    xlate_and_scale_to_bounds(
            canvas,
            SkRect::MakeXYWH(
                    fLeft, fTop, SkIntToScalar(fImage->width()), SkIntToScalar(fImage->height())));
    this->execute(canvas);
    return true;
}

uint64_t DrawImageCommand::imageId(UrlDataManager& udm) const {
    return udm.lookupImage(fImage.get());
}

void DrawImageCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    flatten(*fImage, writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
    MakeJsonPoint(writer, fLeft, fTop);
    if (fPaint.isValid()) {
        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());
    writer.appendS32(DEBUGCANVAS_ATTRIBUTE_HEIGHT, fImage->height());
    switch (fImage->alphaType()) {
        case kOpaque_SkAlphaType:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_OPAQUE);
            break;
        case kPremul_SkAlphaType:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_PREMUL);
            break;
        case kUnpremul_SkAlphaType:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_UNPREMUL);
            break;
        default:
            writer.appendNString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_UNKNOWN);
            break;
    }
}

DrawImageLatticeCommand::DrawImageLatticeCommand(const SkImage*           image,
                                                 const SkCanvas::Lattice& lattice,
                                                 const SkRect&            dst,
                                                 SkFilterMode             filter,
                                                 const SkPaint*           paint)
        : INHERITED(kDrawImageLattice_OpType)
        , fImage(SkRef(image))
        , fLattice(lattice)
        , fDst(dst)
        , fFilter(filter)
        , fPaint(paint) {}

void DrawImageLatticeCommand::execute(SkCanvas* canvas) const {
    canvas->drawImageLattice(fImage.get(), fLattice, fDst, fFilter, fPaint.getMaybeNull());
}

bool DrawImageLatticeCommand::render(SkCanvas* canvas) const {
    SkAutoCanvasRestore acr(canvas, true);
    canvas->clear(0xFFFFFFFF);

    xlate_and_scale_to_bounds(canvas, fDst);

    this->execute(canvas);
    return true;
}

uint64_t DrawImageLatticeCommand::imageId(UrlDataManager& udm) const {
    return udm.lookupImage(fImage.get());
}

void DrawImageLatticeCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    flatten(*fImage, writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_LATTICE);
    MakeJsonLattice(writer, fLattice);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
    MakeJsonRect(writer, fDst);
    if (fPaint.isValid()) {
        writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
        MakeJsonPaint(writer, *fPaint, urlDataManager);
    }

    SkString desc;
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, *str_append(&desc, fDst));
}

DrawImageRectCommand::DrawImageRectCommand(const SkImage*              image,
                                           const SkRect&               src,
                                           const SkRect&               dst,
                                           const SkSamplingOptions&    sampling,
                                           const SkPaint*              paint,
                                           SkCanvas::SrcRectConstraint constraint)
        : INHERITED(kDrawImageRect_OpType)
        , fImage(SkRef(image))
        , fSrc(src)
        , fDst(dst)
        , fSampling(sampling)
        , fPaint(paint)
        , fConstraint(constraint) {}

void DrawImageRectCommand::execute(SkCanvas* canvas) const {
    canvas->drawImageRect(fImage.get(), fSrc, fDst, fSampling, fPaint.getMaybeNull(), fConstraint);
}

bool DrawImageRectCommand::render(SkCanvas* canvas) const {
    SkAutoCanvasRestore acr(canvas, true);
    canvas->clear(0xFFFFFFFF);

    xlate_and_scale_to_bounds(canvas, fDst);

    this->execute(canvas);
    return true;
}

uint64_t DrawImageRectCommand::imageId(UrlDataManager& udm) const {
    return udm.lookupImage(fImage.get());
}

void DrawImageRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    flatten(*fImage, writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_SRC);
    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);
    }
    if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
        writer.appendBool(DEBUGCANVAS_ATTRIBUTE_STRICT, true);
    }

    SkString desc;
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, *str_append(&desc, fDst));
}

DrawImageRectLayerCommand::DrawImageRectLayerCommand(DebugLayerManager*    layerManager,
                                                     const int                   nodeId,
                                                     const int                   frame,
                                                     const SkRect&               src,
                                                     const SkRect&               dst,
                                                     const SkSamplingOptions&    sampling,
                                                     const SkPaint*              paint,
                                                     SkCanvas::SrcRectConstraint constraint)
        : INHERITED(kDrawImageRectLayer_OpType)
        , fLayerManager(layerManager)
        , fNodeId(nodeId)
        , fFrame(frame)
        , fSrc(src)
        , fDst(dst)
        , fSampling(sampling)
        , fPaint(paint)
        , fConstraint(constraint) {}

void DrawImageRectLayerCommand::execute(SkCanvas* canvas) const {
    sk_sp<SkImage> snapshot = fLayerManager->getLayerAsImage(fNodeId, fFrame);
    canvas->drawImageRect(snapshot.get(), fSrc, fDst, SkSamplingOptions(), fPaint.getMaybeNull(), fConstraint);
}

bool DrawImageRectLayerCommand::render(SkCanvas* canvas) const {
    SkAutoCanvasRestore acr(canvas, true);
    canvas->clear(0xFFFFFFFF);

    xlate_and_scale_to_bounds(canvas, fDst);

    this->execute(canvas);
    return true;
}

void DrawImageRectLayerCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);

    // Don't append an image attribute here, the image can be rendered in as many different ways
    // as there are commands in the layer, at least. the urlDataManager would save each one under
    // a different URL.
    // Append the node id, and the layer inspector of the debugger will know what to do with it.
    writer.appendS64(DEBUGCANVAS_ATTRIBUTE_LAYERNODEID, fNodeId);

    writer.appendName(DEBUGCANVAS_ATTRIBUTE_SRC);
    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);
    }
    if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
        writer.appendBool(DEBUGCANVAS_ATTRIBUTE_STRICT, true);
    }

    SkString desc;
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, *str_append(&desc, fDst));
}

DrawOvalCommand::DrawOvalCommand(const SkRect& oval, const SkPaint& paint)
        : INHERITED(kDrawOval_OpType) {
    fOval  = oval;
    fPaint = paint;
}

void DrawOvalCommand::execute(SkCanvas* canvas) const { canvas->drawOval(fOval, fPaint); }

bool DrawOvalCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    xlate_and_scale_to_bounds(canvas, fOval);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawOval(fOval, p);
    canvas->restore();

    return true;
}

void DrawOvalCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
    MakeJsonRect(writer, fOval);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

DrawArcCommand::DrawArcCommand(const SkRect&  oval,
                               SkScalar       startAngle,
                               SkScalar       sweepAngle,
                               bool           useCenter,
                               const SkPaint& paint)
        : INHERITED(kDrawArc_OpType) {
    fOval       = oval;
    fStartAngle = startAngle;
    fSweepAngle = sweepAngle;
    fUseCenter  = useCenter;
    fPaint      = paint;
}

void DrawArcCommand::execute(SkCanvas* canvas) const {
    canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
}

bool DrawArcCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    xlate_and_scale_to_bounds(canvas, fOval);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
    canvas->restore();

    return true;
}

void DrawArcCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
    MakeJsonRect(writer, fOval);
    writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_STARTANGLE, fStartAngle);
    writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_SWEEPANGLE, fSweepAngle);
    writer.appendBool(DEBUGCANVAS_ATTRIBUTE_USECENTER, fUseCenter);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

DrawPaintCommand::DrawPaintCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
    fPaint = paint;
}

void DrawPaintCommand::execute(SkCanvas* canvas) const { canvas->drawPaint(fPaint); }

bool DrawPaintCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->drawPaint(fPaint);
    return true;
}

void DrawPaintCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

DrawBehindCommand::DrawBehindCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
    fPaint = paint;
}

void DrawBehindCommand::execute(SkCanvas* canvas) const {
    SkCanvasPriv::DrawBehind(canvas, fPaint);
}

bool DrawBehindCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    SkCanvasPriv::DrawBehind(canvas, fPaint);
    return true;
}

void DrawBehindCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

DrawPathCommand::DrawPathCommand(const SkPath& path, const SkPaint& paint)
        : INHERITED(kDrawPath_OpType) {
    fPath  = path;
    fPaint = paint;
}

void DrawPathCommand::execute(SkCanvas* canvas) const { canvas->drawPath(fPath, fPaint); }

bool DrawPathCommand::render(SkCanvas* canvas) const {
    render_path(canvas, fPath);
    return true;
}

void DrawPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
    MakeJsonPath(writer, fPath);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

DrawRegionCommand::DrawRegionCommand(const SkRegion& region, const SkPaint& paint)
        : INHERITED(kDrawRegion_OpType) {
    fRegion = region;
    fPaint  = paint;
}

void DrawRegionCommand::execute(SkCanvas* canvas) const { canvas->drawRegion(fRegion, fPaint); }

bool DrawRegionCommand::render(SkCanvas* canvas) const {
    render_region(canvas, fRegion);
    return true;
}

void DrawRegionCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_REGION);
    MakeJsonRegion(writer, fRegion);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

BeginDrawPictureCommand::BeginDrawPictureCommand(const SkPicture* picture,
                                                 const SkMatrix*  matrix,
                                                 const SkPaint*   paint)
        : INHERITED(kBeginDrawPicture_OpType)
        , fPicture(SkRef(picture))
        , fMatrix(matrix)
        , fPaint(paint) {}

void BeginDrawPictureCommand::execute(SkCanvas* canvas) const {
    if (fPaint.isValid()) {
        SkRect bounds = fPicture->cullRect();
        if (fMatrix.isValid()) {
            fMatrix->mapRect(&bounds);
        }
        canvas->saveLayer(&bounds, fPaint.get());
    }

    if (fMatrix.isValid()) {
        if (!fPaint.isValid()) {
            canvas->save();
        }
        canvas->concat(*fMatrix);
    }
}

bool BeginDrawPictureCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    xlate_and_scale_to_bounds(canvas, fPicture->cullRect());

    canvas->drawPicture(fPicture.get());

    canvas->restore();

    return true;
}

EndDrawPictureCommand::EndDrawPictureCommand(bool restore)
        : INHERITED(kEndDrawPicture_OpType), fRestore(restore) {}

void EndDrawPictureCommand::execute(SkCanvas* canvas) const {
    if (fRestore) {
        canvas->restore();
    }
}

DrawPointsCommand::DrawPointsCommand(SkCanvas::PointMode mode,
                                     size_t              count,
                                     const SkPoint       pts[],
                                     const SkPaint&      paint)
        : INHERITED(kDrawPoints_OpType), fMode(mode), fPts(pts, count), fPaint(paint) {}

void DrawPointsCommand::execute(SkCanvas* canvas) const {
    canvas->drawPoints(fMode, fPts.size(), fPts.begin(), fPaint);
}

bool DrawPointsCommand::render(SkCanvas* canvas) const {
    canvas->clear(0xFFFFFFFF);
    canvas->save();

    SkRect bounds;

    bounds.setEmpty();
    for (int i = 0; i < fPts.size(); ++i) {
        SkRectPriv::GrowToInclude(&bounds, fPts[i]);
    }

    xlate_and_scale_to_bounds(canvas, bounds);

    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setStyle(SkPaint::kStroke_Style);

    canvas->drawPoints(fMode, fPts.size(), fPts.begin(), p);
    canvas->restore();

    return true;
}

void DrawPointsCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendCString(DEBUGCANVAS_ATTRIBUTE_MODE, pointmode_name(fMode));
    writer.beginArray(DEBUGCANVAS_ATTRIBUTE_POINTS);
    for (int i = 0; i < fPts.size(); i++) {
        MakeJsonPoint(writer, fPts[i]);
    }
    writer.endArray();  // points
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

DrawTextBlobCommand::DrawTextBlobCommand(sk_sp<SkTextBlob> blob,
                                         SkScalar          x,
                                         SkScalar          y,
                                         const SkPaint&    paint)
        : INHERITED(kDrawTextBlob_OpType)
        , fBlob(std::move(blob))
        , fXPos(x)
        , fYPos(y)
        , fPaint(paint) {}

void DrawTextBlobCommand::execute(SkCanvas* canvas) const {
    canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
}

bool DrawTextBlobCommand::render(SkCanvas* canvas) const {
    canvas->clear(SK_ColorWHITE);
    canvas->save();

    SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
    xlate_and_scale_to_bounds(canvas, bounds);

    canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);

    canvas->restore();

    return true;
}

void DrawTextBlobCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_X, fXPos);
    writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_Y, fYPos);
    SkRect bounds = fBlob->bounds();
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_BOUNDS);
    MakeJsonRect(writer, bounds);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);

    writer.beginArray(DEBUGCANVAS_ATTRIBUTE_RUNS);
    SkTextBlobRunIterator iter(fBlob.get());
    while (!iter.done()) {
        writer.beginObject();  // run
        if (iter.textSize()) {
            writer.appendString(DEBUGCANVAS_ATTRIBUTE_TEXT, iter.text(), iter.textSize());
        }
        writer.appendName(DEBUGCANVAS_ATTRIBUTE_FONT);
        MakeJsonFont(iter.font(), writer, urlDataManager);
        writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
        MakeJsonPoint(writer, iter.offset());
        writer.beginArray(DEBUGCANVAS_ATTRIBUTE_GLYPHS);
        for (uint32_t i = 0; i < iter.glyphCount(); i++) {
            writer.appendU32(iter.glyphs()[i]);
        }
        writer.endArray();  // glyphs
        if (iter.positioning() != SkTextBlobRunIterator::kDefault_Positioning) {
            writer.beginArray(DEBUGCANVAS_ATTRIBUTE_POSITIONS);
            const SkScalar* iterPositions = iter.pos();
            for (uint32_t i = 0; i < iter.glyphCount(); i++) {
                switch (iter.positioning()) {
                    case SkTextBlobRunIterator::kFull_Positioning:
                        MakeJsonPoint(writer, iterPositions[i * 2], iterPositions[i * 2 + 1]);
                        break;
                    case SkTextBlobRunIterator::kHorizontal_Positioning:
                        writer.appendFloat(iterPositions[i]);
                        break;
                    case SkTextBlobRunIterator::kDefault_Positioning: break;
                    case SkTextBlobRunIterator::kRSXform_Positioning:
                        // TODO_RSXFORM_BLOB
                        break;
                }
            }
            writer.endArray();  // positions
        }
        if (iter.clusters()) {
            writer.beginArray(DEBUGCANVAS_ATTRIBUTE_CLUSTERS);
            for (uint32_t i = 0; i < iter.glyphCount(); i++) {
                writer.appendU32(iter.clusters()[i]);
            }
            writer.endArray();  // clusters
        }
        writer.endObject();  // run
        iter.next();
    }
    writer.endArray();  // runs

    SkString desc;
    // make the bounds local by applying the x,y
    bounds.offset(fXPos, fYPos);
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, *str_append(&desc, bounds));
}

DrawPatchCommand::DrawPatchCommand(const SkPoint  cubics[12],
                                   const SkColor  colors[4],
                                   const SkPoint  texCoords[4],
                                   SkBlendMode    bmode,
                                   const SkPaint& paint)
        : INHERITED(kDrawPatch_OpType), fBlendMode(bmode) {
    memcpy(fCubics, cubics, sizeof(fCubics));
    if (colors != nullptr) {
        memcpy(fColors, colors, sizeof(fColors));
        fColorsPtr = fColors;
    } else {
        fColorsPtr = nullptr;
    }
    if (texCoords != nullptr) {
        memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
        fTexCoordsPtr = fTexCoords;
    } else {
        fTexCoordsPtr = nullptr;
    }
    fPaint = paint;
}

void DrawPatchCommand::execute(SkCanvas* canvas) const {
    canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
}

void DrawPatchCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.beginArray(DEBUGCANVAS_ATTRIBUTE_CUBICS);
    for (int i = 0; i < 12; i++) {
        MakeJsonPoint(writer, fCubics[i]);
    }
    writer.endArray();  // cubics
    if (fColorsPtr != nullptr) {
        writer.beginArray(DEBUGCANVAS_ATTRIBUTE_COLORS);
        for (int i = 0; i < 4; i++) {
            MakeJsonColor(writer, fColorsPtr[i]);
        }
        writer.endArray();  // colors
    }
    if (fTexCoordsPtr != nullptr) {
        writer.beginArray(DEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS);
        for (int i = 0; i < 4; i++) {
            MakeJsonPoint(writer, fTexCoords[i]);
        }
        writer.endArray();  // texCoords
    }
    // fBlendMode
}

DrawRectCommand::DrawRectCommand(const SkRect& rect, const SkPaint& paint)
        : INHERITED(kDrawRect_OpType) {
    fRect  = rect;
    fPaint = paint;
}

void DrawRectCommand::execute(SkCanvas* canvas) const { canvas->drawRect(fRect, fPaint); }

void DrawRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
    MakeJsonRect(writer, fRect);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);

    SkString desc;
    writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, *str_append(&desc, fRect));
}

DrawRRectCommand::DrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
        : INHERITED(kDrawRRect_OpType) {
    fRRect = rrect;
    fPaint = paint;
}

void DrawRRectCommand::execute(SkCanvas* canvas) const { canvas->drawRRect(fRRect, fPaint); }

bool DrawRRectCommand::render(SkCanvas* canvas) const {
    render_rrect(canvas, fRRect);
    return true;
}

void DrawRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
    make_json_rrect(writer, fRRect);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

DrawDRRectCommand::DrawDRRectCommand(const SkRRect& outer,
                                     const SkRRect& inner,
                                     const SkPaint& paint)
        : INHERITED(kDrawDRRect_OpType) {
    fOuter = outer;
    fInner = inner;
    fPaint = paint;
}

void DrawDRRectCommand::execute(SkCanvas* canvas) const {
    canvas->drawDRRect(fOuter, fInner, fPaint);
}

bool DrawDRRectCommand::render(SkCanvas* canvas) const {
    render_drrect(canvas, fOuter, fInner);
    return true;
}

void DrawDRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_OUTER);
    make_json_rrect(writer, fOuter);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_INNER);
    make_json_rrect(writer, fInner);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
    MakeJsonPaint(writer, fPaint, urlDataManager);
}

DrawShadowCommand::DrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
        : INHERITED(kDrawShadow_OpType) {
    fPath      = path;
    fShadowRec = rec;
}

void DrawShadowCommand::execute(SkCanvas* canvas) const {
    canvas->private_draw_shadow_rec(fPath, fShadowRec);
}

bool DrawShadowCommand::render(SkCanvas* canvas) const {
    render_shadow(canvas, fPath, fShadowRec);
    return true;
}

void DrawShadowCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);

    bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
    bool transparentOccluder =
            SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);

    writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
    MakeJsonPath(writer, fPath);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_ZPLANE);
    MakeJsonPoint3(writer, fShadowRec.fZPlaneParams);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION);
    MakeJsonPoint3(writer, fShadowRec.fLightPos);
    writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS, fShadowRec.fLightRadius);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR);
    MakeJsonColor(writer, fShadowRec.fAmbientColor);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_SPOTCOLOR);
    MakeJsonColor(writer, fShadowRec.fSpotColor);
    store_bool(writer, DEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
    store_bool(writer, DEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
}

///////////////////////////////////////////////////////////////////////////////////////////////////

DrawEdgeAAQuadCommand::DrawEdgeAAQuadCommand(const SkRect&         rect,
                                             const SkPoint         clip[4],
                                             SkCanvas::QuadAAFlags aa,
                                             const SkColor4f&      color,
                                             SkBlendMode           mode)
        : INHERITED(kDrawEdgeAAQuad_OpType)
        , fRect(rect)
        , fHasClip(clip != nullptr)
        , fAA(aa)
        , fColor(color)
        , fMode(mode) {
    if (clip) {
        for (int i = 0; i < 4; ++i) {
            fClip[i] = clip[i];
        }
    }
}

void DrawEdgeAAQuadCommand::execute(SkCanvas* canvas) const {
    canvas->experimental_DrawEdgeAAQuad(fRect, fHasClip ? fClip : nullptr, fAA, fColor, fMode);
}

DrawEdgeAAImageSetCommand::DrawEdgeAAImageSetCommand(const SkCanvas::ImageSetEntry set[],
                                                     int                           count,
                                                     const SkPoint                 dstClips[],
                                                     const SkMatrix              preViewMatrices[],
                                                     const SkSamplingOptions&    sampling,
                                                     const SkPaint*              paint,
                                                     SkCanvas::SrcRectConstraint constraint)
        : INHERITED(kDrawEdgeAAImageSet_OpType)
        , fSet(count)
        , fCount(count)
        , fSampling(sampling)
        , fPaint(paint)
        , fConstraint(constraint) {
    int totalDstClipCount, totalMatrixCount;
    SkCanvasPriv::GetDstClipAndMatrixCounts(set, count, &totalDstClipCount, &totalMatrixCount);

    std::copy_n(set, count, fSet.get());
    fDstClips.reset(totalDstClipCount);
    std::copy_n(dstClips, totalDstClipCount, fDstClips.get());
    fPreViewMatrices.reset(totalMatrixCount);
    std::copy_n(preViewMatrices, totalMatrixCount, fPreViewMatrices.get());
}

void DrawEdgeAAImageSetCommand::execute(SkCanvas* canvas) const {
    canvas->experimental_DrawEdgeAAImageSet(fSet.get(),
                                            fCount,
                                            fDstClips.get(),
                                            fPreViewMatrices.get(),
                                            fSampling,
                                            fPaint.getMaybeNull(),
                                            fConstraint);
}

///////////////////////////////////////////////////////////////////////////////////////////////////

DrawDrawableCommand::DrawDrawableCommand(SkDrawable* drawable, const SkMatrix* matrix)
        : INHERITED(kDrawDrawable_OpType), fDrawable(SkRef(drawable)), fMatrix(matrix) {}

void DrawDrawableCommand::execute(SkCanvas* canvas) const {
    canvas->drawDrawable(fDrawable.get(), fMatrix.getMaybeNull());
}

///////////////////////////////////////////////////////////////////////////////////////////////////

DrawVerticesCommand::DrawVerticesCommand(sk_sp<SkVertices> vertices,
                                         SkBlendMode       bmode,
                                         const SkPaint&    paint)
        : INHERITED(kDrawVertices_OpType)
        , fVertices(std::move(vertices))
        , fBlendMode(bmode)
        , fPaint(paint) {}

void DrawVerticesCommand::execute(SkCanvas* canvas) const {
    canvas->drawVertices(fVertices, fBlendMode, fPaint);
}

///////////////////////////////////////////////////////////////////////////////////////////////////

DrawAtlasCommand::DrawAtlasCommand(const SkImage*  image,
                                   const SkRSXform xform[],
                                   const SkRect    tex[],
                                   const SkColor   colors[],
                                   int             count,
                                   SkBlendMode     bmode,
                                   const SkSamplingOptions& sampling,
                                   const SkRect*   cull,
                                   const SkPaint*  paint)
        : INHERITED(kDrawAtlas_OpType)
        , fImage(SkRef(image))
        , fXform(xform, count)
        , fTex(tex, count)
        , fColors(colors, colors ? count : 0)
        , fBlendMode(bmode)
        , fSampling(sampling)
        , fCull(cull)
        , fPaint(paint) {}

void DrawAtlasCommand::execute(SkCanvas* canvas) const {
    canvas->drawAtlas(fImage.get(),
                      fXform.begin(),
                      fTex.begin(),
                      fColors.empty() ? nullptr : fColors.begin(),
                      fXform.size(),
                      fBlendMode,
                      fSampling,
                      fCull.getMaybeNull(),
                      fPaint.getMaybeNull());
}

///////////////////////////////////////////////////////////////////////////////////////////////////

RestoreCommand::RestoreCommand() : INHERITED(kRestore_OpType) {}

void RestoreCommand::execute(SkCanvas* canvas) const { canvas->restore(); }

SaveCommand::SaveCommand() : INHERITED(kSave_OpType) {}

void SaveCommand::execute(SkCanvas* canvas) const { canvas->save(); }

SaveLayerCommand::SaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
        : INHERITED(kSaveLayer_OpType)
        , fBounds(rec.fBounds)
        , fPaint(rec.fPaint)
        , fBackdrop(SkSafeRef(rec.fBackdrop))
        , fSaveLayerFlags(rec.fSaveLayerFlags)
        , fBackdropScale(SkCanvasPriv::GetBackdropScaleFactor(rec)) {}

void SaveLayerCommand::execute(SkCanvas* canvas) const {
    // In the common case fBackdropScale == 1.f and then this is no different than a regular Rec
    canvas->saveLayer(SkCanvasPriv::ScaledBackdropLayer(fBounds.getMaybeNull(),
                                                        fPaint.getMaybeNull(),
                                                        fBackdrop.get(),
                                                        fBackdropScale,
                                                        fSaveLayerFlags));
}

void SaveLayerCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    if (fBounds.isValid()) {
        writer.appendName(DEBUGCANVAS_ATTRIBUTE_BOUNDS);
        MakeJsonRect(writer, *fBounds);
    }
    if (fPaint.isValid()) {
        writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
        MakeJsonPaint(writer, *fPaint, urlDataManager);
    }
    if (fBackdrop != nullptr) {
        writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BACKDROP);
        flatten(fBackdrop.get(), writer, urlDataManager);
        writer.endObject();  // backdrop
    }
    if (fSaveLayerFlags != 0) {
        SkDebugf("unsupported: saveLayer flags\n");
        SkASSERT(false);
    }
}

SetMatrixCommand::SetMatrixCommand(const SkMatrix& matrix) : INHERITED(kSetMatrix_OpType) {
    fMatrix = matrix;
}

void SetMatrixCommand::execute(SkCanvas* canvas) const { canvas->setMatrix(fMatrix); }

void SetMatrixCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_MATRIX);
    MakeJsonMatrix(writer, fMatrix);
    writeMatrixType(writer, fMatrix);
}

SetM44Command::SetM44Command(const SkM44& matrix) : INHERITED(kSetM44_OpType) {
    fMatrix = matrix;
}

void SetM44Command::execute(SkCanvas* canvas) const { canvas->setMatrix(fMatrix); }

void SetM44Command::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
    INHERITED::toJSON(writer, urlDataManager);
    writer.appendName(DEBUGCANVAS_ATTRIBUTE_MATRIX);
    MakeJsonMatrix44(writer, fMatrix);
}
