// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "skia/ext/benchmarking_canvas.h"

#include <memory>
#include <utility>

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "third_party/skia/include/core/SkString.h"
#include "third_party/skia/include/core/SkTextBlob.h"

namespace {

class FlagsBuilder {
public:
  FlagsBuilder(char separator)
      : separator_(separator) {}

  void addFlag(bool flag_val, const char flag_name[]) {
    if (!flag_val)
      return;
    if (!oss_.str().empty())
      oss_ << separator_;

    oss_ << flag_name;
  }

  std::string str() const {
    return oss_.str();
  }

private:
  char separator_;
  std::ostringstream oss_;
};

std::unique_ptr<base::Value> AsValue(bool b) {
  std::unique_ptr<base::Value> val(new base::Value(b));

  return val;
}

std::unique_ptr<base::Value> AsValue(SkScalar scalar) {
  std::unique_ptr<base::Value> val(new base::Value(scalar));

  return val;
}

std::unique_ptr<base::Value> AsValue(const SkSize& size) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->Set("width",  AsValue(size.width()));
  val->Set("height", AsValue(size.height()));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkPoint& point) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->Set("x", AsValue(point.x()));
  val->Set("y", AsValue(point.y()));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkRect& rect) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->Set("left", AsValue(rect.fLeft));
  val->Set("top", AsValue(rect.fTop));
  val->Set("right", AsValue(rect.fRight));
  val->Set("bottom", AsValue(rect.fBottom));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkRRect& rrect) {
  std::unique_ptr<base::DictionaryValue> radii_val(new base::DictionaryValue());
  radii_val->Set("upper-left", AsValue(rrect.radii(SkRRect::kUpperLeft_Corner)));
  radii_val->Set("upper-right", AsValue(rrect.radii(SkRRect::kUpperRight_Corner)));
  radii_val->Set("lower-right", AsValue(rrect.radii(SkRRect::kLowerRight_Corner)));
  radii_val->Set("lower-left", AsValue(rrect.radii(SkRRect::kLowerLeft_Corner)));

  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->Set("rect", AsValue(rrect.rect()));
  val->Set("radii", std::move(radii_val));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkMatrix& matrix) {
  std::unique_ptr<base::ListValue> val(new base::ListValue());
  for (int i = 0; i < 9; ++i)
    val->Append(AsValue(matrix[i]));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(SkColor color) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->SetInteger("a", SkColorGetA(color));
  val->SetInteger("r", SkColorGetR(color));
  val->SetInteger("g", SkColorGetG(color));
  val->SetInteger("b", SkColorGetB(color));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(SkBlendMode mode) {
  std::unique_ptr<base::Value> val(new base::Value(SkBlendMode_Name(mode)));

  return val;
}

std::unique_ptr<base::Value> AsValue(SkCanvas::PointMode mode) {
  static const char* gModeStrings[] = { "Points", "Lines", "Polygon" };
  DCHECK_LT(static_cast<size_t>(mode), SK_ARRAY_COUNT(gModeStrings));

  std::unique_ptr<base::Value> val(new base::Value(gModeStrings[mode]));

  return val;
}

std::unique_ptr<base::Value> AsValue(const SkColorFilter& filter) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());

  if (unsigned flags = filter.getFlags()) {
    FlagsBuilder builder('|');
    builder.addFlag(flags & SkColorFilter::kAlphaUnchanged_Flag,
                    "kAlphaUnchanged_Flag");

    val->SetString("flags", builder.str());
  }

  SkScalar color_matrix[20];
  if (filter.asColorMatrix(color_matrix)) {
    std::unique_ptr<base::ListValue> color_matrix_val(new base::ListValue());
    for (unsigned i = 0; i < 20; ++i)
      color_matrix_val->Append(AsValue(color_matrix[i]));

    val->Set("color_matrix", std::move(color_matrix_val));
  }

  SkColor color;
  SkBlendMode mode;
  if (filter.asColorMode(&color, &mode)) {
    std::unique_ptr<base::DictionaryValue> color_mode_val(
        new base::DictionaryValue());
    color_mode_val->Set("color", AsValue(color));
    color_mode_val->Set("mode", AsValue(mode));

    val->Set("color_mode", std::move(color_mode_val));
  }

  if (filter.asComponentTable(nullptr)) {
    std::unique_ptr<base::DictionaryValue> component_table_val(
        new base::DictionaryValue());
    // use this as a marker for now
    val->Set("component_table", std::move(component_table_val));
  }

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkImageFilter& filter) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->SetInteger("inputs", filter.countInputs());

  SkColorFilter* color_filter;
  if (filter.asColorFilter(&color_filter)) {
    val->Set("color_filter", AsValue(*color_filter));
    SkSafeUnref(color_filter); // ref'd in asColorFilter
  }

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkPaint& paint) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  SkPaint default_paint;

  if (paint.getColor() != default_paint.getColor())
    val->Set("Color", AsValue(paint.getColor()));

  if (paint.getStyle() != default_paint.getStyle()) {
    static const char* gStyleStrings[] = { "Fill", "Stroke", "StrokeFill" };
    DCHECK_LT(static_cast<size_t>(paint.getStyle()),
              SK_ARRAY_COUNT(gStyleStrings));
    val->SetString("Style", gStyleStrings[paint.getStyle()]);
  }

  if (paint.getBlendMode() != default_paint.getBlendMode()) {
    val->Set("Xfermode", AsValue(paint.getBlendMode()));
  }

  if (paint.getFlags()) {
    FlagsBuilder builder('|');
    builder.addFlag(paint.isAntiAlias(), "AntiAlias");
    builder.addFlag(paint.isDither(), "Dither");
    builder.addFlag(paint.isFakeBoldText(), "FakeBoldText");
    builder.addFlag(paint.isLinearText(), "LinearText");
    builder.addFlag(paint.isSubpixelText(), "SubpixelText");
    builder.addFlag(paint.isDevKernText(), "DevKernText");
    builder.addFlag(paint.isLCDRenderText(), "LCDRenderText");
    builder.addFlag(paint.isEmbeddedBitmapText(), "EmbeddedBitmapText");
    builder.addFlag(paint.isAutohinted(), "Autohinted");
    builder.addFlag(paint.isVerticalText(), "VerticalText");

    val->SetString("Flags", builder.str());
  }

  if (paint.getFilterQuality() != default_paint.getFilterQuality()) {
    static const char* gFilterQualityStrings[] = {
        "None", "Low", "Medium", "High"};
    DCHECK_LT(static_cast<size_t>(paint.getFilterQuality()),
              SK_ARRAY_COUNT(gFilterQualityStrings));
    val->SetString("FilterLevel",
                   gFilterQualityStrings[paint.getFilterQuality()]);
  }

  if (paint.getTextSize() != default_paint.getTextSize())
    val->SetDouble("TextSize", paint.getTextSize());

  if (paint.getTextScaleX() != default_paint.getTextScaleX())
    val->SetDouble("TextScaleX", paint.getTextScaleX());

  if (paint.getTextSkewX() != default_paint.getTextSkewX())
    val->SetDouble("TextSkewX", paint.getTextSkewX());

  if (paint.getColorFilter())
    val->Set("ColorFilter", AsValue(*paint.getColorFilter()));

  if (paint.getImageFilter())
    val->Set("ImageFilter", AsValue(*paint.getImageFilter()));

  return std::move(val);
}

std::unique_ptr<base::Value> SaveLayerFlagsAsValue(
    SkCanvas::SaveLayerFlags flags) {
  FlagsBuilder builder('|');
  builder.addFlag(flags & SkCanvas::kIsOpaque_SaveLayerFlag,
                  "kIsOpaque");
  builder.addFlag(flags & SkCanvas::kPreserveLCDText_SaveLayerFlag,
                  "kPreserveLCDText");

  std::unique_ptr<base::Value> val(new base::Value(builder.str()));

  return val;
}

std::unique_ptr<base::Value> AsValue(SkClipOp op) {
  static const char* gOpStrings[] = { "Difference",
                                      "Intersect",
                                      "Union",
                                      "XOR",
                                      "ReverseDifference",
                                      "Replace"
                                    };
  size_t index = static_cast<size_t>(op);
  DCHECK_LT(index, SK_ARRAY_COUNT(gOpStrings));
  std::unique_ptr<base::Value> val(new base::Value(gOpStrings[index]));
  return val;
}

std::unique_ptr<base::Value> AsValue(const SkRegion& region) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->Set("bounds", AsValue(SkRect::Make(region.getBounds())));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkBitmap& bitmap) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->Set("size", AsValue(SkSize::Make(bitmap.width(), bitmap.height())));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkImage& image) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->Set("size", AsValue(SkSize::Make(image.width(), image.height())));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkTextBlob& blob) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
  val->Set("bounds", AsValue(blob.bounds()));

  return std::move(val);
}

std::unique_ptr<base::Value> AsValue(const SkPath& path) {
  std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());

  static const char* gFillStrings[] =
      { "winding", "even-odd", "inverse-winding", "inverse-even-odd" };
  DCHECK_LT(static_cast<size_t>(path.getFillType()),
      SK_ARRAY_COUNT(gFillStrings));
  val->SetString("fill-type", gFillStrings[path.getFillType()]);

  static const char* gConvexityStrings[] = { "Unknown", "Convex", "Concave" };
  DCHECK_LT(static_cast<size_t>(path.getConvexity()),
      SK_ARRAY_COUNT(gConvexityStrings));
  val->SetString("convexity", gConvexityStrings[path.getConvexity()]);

  val->SetBoolean("is-rect", path.isRect(nullptr));
  val->Set("bounds", AsValue(path.getBounds()));

  static const char* gVerbStrings[] =
      { "move", "line", "quad", "conic", "cubic", "close", "done" };
  static const int gPtsPerVerb[] = { 1, 1, 2, 2, 3, 0, 0 };
  static const int gPtOffsetPerVerb[] = { 0, 1, 1, 1, 1, 0, 0 };
  static_assert(
      SK_ARRAY_COUNT(gVerbStrings) == static_cast<size_t>(SkPath::kDone_Verb + 1),
      "gVerbStrings size mismatch");
  static_assert(
      SK_ARRAY_COUNT(gVerbStrings) == SK_ARRAY_COUNT(gPtsPerVerb),
      "gPtsPerVerb size mismatch");
  static_assert(
      SK_ARRAY_COUNT(gVerbStrings) == SK_ARRAY_COUNT(gPtOffsetPerVerb),
      "gPtOffsetPerVerb size mismatch");

  std::unique_ptr<base::ListValue> verbs_val(new base::ListValue());
  SkPath::Iter iter(const_cast<SkPath&>(path), false);
  SkPoint points[4];

  for(SkPath::Verb verb = iter.next(points, false);
      verb != SkPath::kDone_Verb; verb = iter.next(points, false)) {
      DCHECK_LT(static_cast<size_t>(verb), SK_ARRAY_COUNT(gVerbStrings));

      std::unique_ptr<base::DictionaryValue> verb_val(
          new base::DictionaryValue());
      std::unique_ptr<base::ListValue> pts_val(new base::ListValue());

      for (int i = 0; i < gPtsPerVerb[verb]; ++i)
        pts_val->Append(AsValue(points[i + gPtOffsetPerVerb[verb]]));

      verb_val->Set(gVerbStrings[verb], std::move(pts_val));

      if (SkPath::kConic_Verb == verb)
        verb_val->Set("weight", AsValue(iter.conicWeight()));

      verbs_val->Append(std::move(verb_val));
  }
  val->Set("verbs", std::move(verbs_val));

  return std::move(val);
}

template <typename T>
std::unique_ptr<base::Value> AsListValue(const T array[], size_t count) {
  std::unique_ptr<base::ListValue> val(new base::ListValue());

  for (size_t i = 0; i < count; ++i)
    val->Append(AsValue(array[i]));

  return std::move(val);
}

} // namespace

namespace skia {

class BenchmarkingCanvas::AutoOp {
public:
  // AutoOp objects are always scoped within draw call frames,
  // so the paint is guaranteed to be valid for their lifetime.
 AutoOp(BenchmarkingCanvas* canvas,
        const char op_name[],
        const SkPaint* paint = nullptr)
     : canvas_(canvas), op_record_(new base::DictionaryValue()) {
   DCHECK(canvas);
   DCHECK(op_name);

   op_record_->SetString("cmd_string", op_name);
   op_params_ =
       op_record_->SetList("info", base::MakeUnique<base::ListValue>());

   if (paint) {
     this->addParam("paint", AsValue(*paint));
     filtered_paint_ = *paint;
   }

   start_ticks_ = base::TimeTicks::Now();
  }

  ~AutoOp() {
    base::TimeDelta ticks = base::TimeTicks::Now() - start_ticks_;
    op_record_->SetDouble("cmd_time", ticks.InMillisecondsF());

    canvas_->op_records_.Append(std::move(op_record_));
  }

  void addParam(const char name[], std::unique_ptr<base::Value> value) {
    std::unique_ptr<base::DictionaryValue> param(new base::DictionaryValue());
    param->Set(name, std::move(value));

    op_params_->Append(std::move(param));
  }

  const SkPaint* paint() const { return &filtered_paint_; }

private:
  BenchmarkingCanvas* canvas_;
  std::unique_ptr<base::DictionaryValue> op_record_;
  base::ListValue* op_params_;
  base::TimeTicks start_ticks_;

  SkPaint filtered_paint_;
};

BenchmarkingCanvas::BenchmarkingCanvas(SkCanvas* canvas)
    : INHERITED(canvas->imageInfo().width(),
                canvas->imageInfo().height()) {
  addCanvas(canvas);
}

BenchmarkingCanvas::~BenchmarkingCanvas() = default;

size_t BenchmarkingCanvas::CommandCount() const {
  return op_records_.GetSize();
}

const base::ListValue& BenchmarkingCanvas::Commands() const {
  return op_records_;
}

double BenchmarkingCanvas::GetTime(size_t index) {
  const base::DictionaryValue* op;
  if (!op_records_.GetDictionary(index, &op))
    return 0;

  double t;
  if (!op->GetDouble("cmd_time", &t))
    return 0;

  return t;
}

void BenchmarkingCanvas::willSave() {
  AutoOp op(this, "Save");

  INHERITED::willSave();
}

SkCanvas::SaveLayerStrategy BenchmarkingCanvas::getSaveLayerStrategy(
    const SaveLayerRec& rec) {
  AutoOp op(this, "SaveLayer", rec.fPaint);
  if (rec.fBounds)
    op.addParam("bounds", AsValue(*rec.fBounds));
  if (rec.fSaveLayerFlags)
    op.addParam("flags", SaveLayerFlagsAsValue(rec.fSaveLayerFlags));

  return INHERITED::getSaveLayerStrategy(rec);
}

void BenchmarkingCanvas::willRestore() {
  AutoOp op(this, "Restore");

  INHERITED::willRestore();
}

void BenchmarkingCanvas::didConcat(const SkMatrix& m) {
  AutoOp op(this, "Concat");
  op.addParam("matrix", AsValue(m));

  INHERITED::didConcat(m);
}

void BenchmarkingCanvas::didSetMatrix(const SkMatrix& m) {
  AutoOp op(this, "SetMatrix");
  op.addParam("matrix", AsValue(m));

  INHERITED::didSetMatrix(m);
}

void BenchmarkingCanvas::onClipRect(const SkRect& rect,
                                    SkClipOp region_op,
                                    SkCanvas::ClipEdgeStyle style) {
  AutoOp op(this, "ClipRect");
  op.addParam("rect", AsValue(rect));
  op.addParam("op", AsValue(region_op));
  op.addParam("anti-alias", AsValue(style == kSoft_ClipEdgeStyle));

  INHERITED::onClipRect(rect, region_op, style);
}

void BenchmarkingCanvas::onClipRRect(const SkRRect& rrect,
                                     SkClipOp region_op,
                                     SkCanvas::ClipEdgeStyle style) {
  AutoOp op(this, "ClipRRect");
  op.addParam("rrect", AsValue(rrect));
  op.addParam("op", AsValue(region_op));
  op.addParam("anti-alias", AsValue(style == kSoft_ClipEdgeStyle));

  INHERITED::onClipRRect(rrect, region_op, style);
}

void BenchmarkingCanvas::onClipPath(const SkPath& path,
                                    SkClipOp region_op,
                                    SkCanvas::ClipEdgeStyle style) {
  AutoOp op(this, "ClipPath");
  op.addParam("path", AsValue(path));
  op.addParam("op", AsValue(region_op));
  op.addParam("anti-alias", AsValue(style == kSoft_ClipEdgeStyle));

  INHERITED::onClipPath(path, region_op, style);
}

void BenchmarkingCanvas::onClipRegion(const SkRegion& region,
                                      SkClipOp region_op) {
  AutoOp op(this, "ClipRegion");
  op.addParam("region", AsValue(region));
  op.addParam("op", AsValue(region_op));

  INHERITED::onClipRegion(region, region_op);
}

void BenchmarkingCanvas::onDrawPaint(const SkPaint& paint) {
  AutoOp op(this, "DrawPaint", &paint);

  INHERITED::onDrawPaint(*op.paint());
}

void BenchmarkingCanvas::onDrawPoints(PointMode mode, size_t count,
                                      const SkPoint pts[], const SkPaint& paint) {
  AutoOp op(this, "DrawPoints", &paint);
  op.addParam("mode", AsValue(mode));
  op.addParam("points", AsListValue(pts, count));

  INHERITED::onDrawPoints(mode, count, pts, *op.paint());
}

void BenchmarkingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
  AutoOp op(this, "DrawRect", &paint);
  op.addParam("rect", AsValue(rect));

  INHERITED::onDrawRect(rect, *op.paint());
}

void BenchmarkingCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
  AutoOp op(this, "DrawOval", &paint);
  op.addParam("rect", AsValue(rect));

  INHERITED::onDrawOval(rect, *op.paint());
}

void BenchmarkingCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
  AutoOp op(this, "DrawRRect", &paint);
  op.addParam("rrect", AsValue(rrect));

  INHERITED::onDrawRRect(rrect, *op.paint());
}

void BenchmarkingCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
                                      const SkPaint& paint) {
  AutoOp op(this, "DrawDRRect", &paint);
  op.addParam("outer", AsValue(outer));
  op.addParam("inner", AsValue(inner));

  INHERITED::onDrawDRRect(outer, inner, *op.paint());
}

void BenchmarkingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
  AutoOp op(this, "DrawPath", &paint);
  op.addParam("path", AsValue(path));

  INHERITED::onDrawPath(path, *op.paint());
}

void BenchmarkingCanvas::onDrawPicture(const SkPicture* picture,
                                       const SkMatrix* matrix,
                                       const SkPaint* paint) {
  DCHECK(picture);
  AutoOp op(this, "DrawPicture", paint);
  op.addParam("picture", AsValue(picture));
  if (matrix)
    op.addParam("matrix", AsValue(*matrix));

  INHERITED::onDrawPicture(picture, matrix, op.paint());
}

void BenchmarkingCanvas::onDrawBitmap(const SkBitmap& bitmap,
                                      SkScalar left,
                                      SkScalar top,
                                      const SkPaint* paint) {
  AutoOp op(this, "DrawBitmap", paint);
  op.addParam("bitmap", AsValue(bitmap));
  op.addParam("left", AsValue(left));
  op.addParam("top", AsValue(top));

  INHERITED::onDrawBitmap(bitmap, left, top, op.paint());
}

void BenchmarkingCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
                                          const SkRect* src,
                                          const SkRect& dst,
                                          const SkPaint* paint,
                                          SrcRectConstraint constraint) {
  AutoOp op(this, "DrawBitmapRect", paint);
  op.addParam("bitmap", AsValue(bitmap));
  if (src)
    op.addParam("src", AsValue(*src));
  op.addParam("dst", AsValue(dst));

  INHERITED::onDrawBitmapRect(bitmap, src, dst, op.paint(), constraint);
}

void BenchmarkingCanvas::onDrawImage(const SkImage* image,
                                     SkScalar left,
                                     SkScalar top,
                                     const SkPaint* paint) {
  DCHECK(image);
  AutoOp op(this, "DrawImage", paint);
  op.addParam("image", AsValue(*image));
  op.addParam("left", AsValue(left));
  op.addParam("top", AsValue(top));

  INHERITED::onDrawImage(image, left, top, op.paint());
}

void BenchmarkingCanvas::onDrawImageRect(const SkImage* image, const SkRect* src,
                                         const SkRect& dst, const SkPaint* paint,
                                         SrcRectConstraint constraint) {
  DCHECK(image);
  AutoOp op(this, "DrawImageRect", paint);
  op.addParam("image", AsValue(*image));
  if (src)
    op.addParam("src", AsValue(*src));
  op.addParam("dst", AsValue(dst));

  INHERITED::onDrawImageRect(image, src, dst, op.paint(), constraint);
}

void BenchmarkingCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
                                          const SkIRect& center,
                                          const SkRect& dst,
                                          const SkPaint* paint) {
  AutoOp op(this, "DrawBitmapNine", paint);
  op.addParam("bitmap", AsValue(bitmap));
  op.addParam("center", AsValue(SkRect::Make(center)));
  op.addParam("dst", AsValue(dst));

  INHERITED::onDrawBitmapNine(bitmap, center, dst, op.paint());
}

void BenchmarkingCanvas::onDrawText(const void* text, size_t byteLength,
                                    SkScalar x, SkScalar y,
                                    const SkPaint& paint) {
  AutoOp op(this, "DrawText", &paint);
  op.addParam("count", AsValue(SkIntToScalar(paint.countText(text, byteLength))));
  op.addParam("x", AsValue(x));
  op.addParam("y", AsValue(y));

  INHERITED::onDrawText(text, byteLength, x, y, *op.paint());
}

void BenchmarkingCanvas::onDrawPosText(const void* text, size_t byteLength,
                                       const SkPoint pos[], const SkPaint& paint) {
  AutoOp op(this, "DrawPosText", &paint);

  int count = paint.countText(text, byteLength);
  op.addParam("count", AsValue(SkIntToScalar(count)));
  op.addParam("pos", AsListValue(pos, count));

  INHERITED::onDrawPosText(text, byteLength, pos, *op.paint());
}

void BenchmarkingCanvas::onDrawPosTextH(const void* text, size_t byteLength,
                                        const SkScalar xpos[], SkScalar constY,
                                        const SkPaint& paint)  {
  AutoOp op(this, "DrawPosTextH", &paint);
  op.addParam("constY", AsValue(constY));

  int count = paint.countText(text, byteLength);
  op.addParam("count", AsValue(SkIntToScalar(count)));
  op.addParam("pos", AsListValue(xpos, count));

  INHERITED::onDrawPosTextH(text, byteLength, xpos, constY, *op.paint());
}

void BenchmarkingCanvas::onDrawTextOnPath(const void* text, size_t byteLength,
                                          const SkPath& path, const SkMatrix* matrix,
                                          const SkPaint& paint) {
  AutoOp op(this, "DrawTextOnPath", &paint);
  op.addParam("count", AsValue(SkIntToScalar(paint.countText(text, byteLength))));
  op.addParam("path", AsValue(path));
  if (matrix)
    op.addParam("matrix", AsValue(*matrix));

  INHERITED::onDrawTextOnPath(text, byteLength, path, matrix, *op.paint());
}

void BenchmarkingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                        const SkPaint& paint) {
  DCHECK(blob);
  AutoOp op(this, "DrawTextBlob", &paint);
  op.addParam("blob", AsValue(*blob));
  op.addParam("x", AsValue(x));
  op.addParam("y", AsValue(y));

  INHERITED::onDrawTextBlob(blob, x, y, *op.paint());
}

} // namespace skia
