/*
 * 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/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 = SkFontPriv::GetTypefaceOrDefault(font);
    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);
}
