Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / skia / ext / benchmarking_canvas.cc
blob924ce28020376f9e80828f59bb9094d7a393ab76
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/logging.h"
6 #include "base/strings/stringprintf.h"
7 #include "base/time/time.h"
8 #include "skia/ext/benchmarking_canvas.h"
9 #include "third_party/skia/include/core/SkColorFilter.h"
10 #include "third_party/skia/include/core/SkImageFilter.h"
11 #include "third_party/skia/include/core/SkTLazy.h"
12 #include "third_party/skia/include/core/SkPicture.h"
13 #include "third_party/skia/include/core/SkRegion.h"
14 #include "third_party/skia/include/core/SkString.h"
15 #include "third_party/skia/include/core/SkTextBlob.h"
16 #include "third_party/skia/include/core/SkXfermode.h"
18 namespace {
20 class FlagsBuilder {
21 public:
22 FlagsBuilder(char separator)
23 : separator_(separator) {}
25 void addFlag(bool flag_val, const char flag_name[]) {
26 if (!flag_val)
27 return;
28 if (!oss_.str().empty())
29 oss_ << separator_;
31 oss_ << flag_name;
34 std::string str() const {
35 return oss_.str();
38 private:
39 char separator_;
40 std::ostringstream oss_;
43 WARN_UNUSED_RESULT
44 scoped_ptr<base::Value> AsValue(bool b) {
45 scoped_ptr<base::FundamentalValue> val(new base::FundamentalValue(b));
47 return val.Pass();
50 WARN_UNUSED_RESULT
51 scoped_ptr<base::Value> AsValue(SkScalar scalar) {
52 scoped_ptr<base::FundamentalValue> val(new base::FundamentalValue(scalar));
54 return val.Pass();
57 WARN_UNUSED_RESULT
58 scoped_ptr<base::Value> AsValue(const SkSize& size) {
59 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
60 val->Set("width", AsValue(size.width()));
61 val->Set("height", AsValue(size.height()));
63 return val.Pass();
66 WARN_UNUSED_RESULT
67 scoped_ptr<base::Value> AsValue(const SkPoint& point) {
68 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
69 val->Set("x", AsValue(point.x()));
70 val->Set("y", AsValue(point.y()));
72 return val.Pass();
75 WARN_UNUSED_RESULT
76 scoped_ptr<base::Value> AsValue(const SkRect& rect) {
77 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
78 val->Set("left", AsValue(rect.fLeft));
79 val->Set("top", AsValue(rect.fTop));
80 val->Set("right", AsValue(rect.fRight));
81 val->Set("bottom", AsValue(rect.fBottom));
83 return val.Pass();
86 WARN_UNUSED_RESULT
87 scoped_ptr<base::Value> AsValue(const SkRRect& rrect) {
88 scoped_ptr<base::DictionaryValue> radii_val(new base::DictionaryValue());
89 radii_val->Set("upper-left", AsValue(rrect.radii(SkRRect::kUpperLeft_Corner)));
90 radii_val->Set("upper-right", AsValue(rrect.radii(SkRRect::kUpperRight_Corner)));
91 radii_val->Set("lower-right", AsValue(rrect.radii(SkRRect::kLowerRight_Corner)));
92 radii_val->Set("lower-left", AsValue(rrect.radii(SkRRect::kLowerLeft_Corner)));
94 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
95 val->Set("rect", AsValue(rrect.rect()));
96 val->Set("radii", radii_val.Pass());
98 return val.Pass();
101 WARN_UNUSED_RESULT
102 scoped_ptr<base::Value> AsValue(const SkMatrix& matrix) {
103 scoped_ptr<base::ListValue> val(new base::ListValue());
104 for (int i = 0; i < 9; ++i)
105 val->Append(AsValue(matrix[i]).release()); // no scoped_ptr-aware Append() variant
107 return val.Pass();
110 WARN_UNUSED_RESULT
111 scoped_ptr<base::Value> AsValue(SkColor color) {
112 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
113 val->SetInteger("a", SkColorGetA(color));
114 val->SetInteger("r", SkColorGetR(color));
115 val->SetInteger("g", SkColorGetG(color));
116 val->SetInteger("b", SkColorGetB(color));
118 return val.Pass();
121 WARN_UNUSED_RESULT
122 scoped_ptr<base::Value> AsValue(SkXfermode::Mode mode) {
123 scoped_ptr<base::StringValue> val(
124 new base::StringValue(SkXfermode::ModeName(mode)));
126 return val.Pass();
129 WARN_UNUSED_RESULT
130 scoped_ptr<base::Value> AsValue(SkCanvas::PointMode mode) {
131 static const char* gModeStrings[] = { "Points", "Lines", "Polygon" };
132 DCHECK_LT(static_cast<size_t>(mode), SK_ARRAY_COUNT(gModeStrings));
134 scoped_ptr<base::StringValue> val(new base::StringValue(gModeStrings[mode]));
136 return val.Pass();
139 WARN_UNUSED_RESULT
140 scoped_ptr<base::Value> AsValue(const SkXfermode& xfermode) {
141 SkXfermode::Mode mode;
142 if (xfermode.asMode(&mode))
143 return AsValue(mode);
145 scoped_ptr<base::StringValue> val(new base::StringValue("unknown"));
146 return val.Pass();
149 WARN_UNUSED_RESULT
150 scoped_ptr<base::Value> AsValue(const SkColorFilter& filter) {
151 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
153 if (unsigned flags = filter.getFlags()) {
154 FlagsBuilder builder('|');
155 builder.addFlag(flags & SkColorFilter::kAlphaUnchanged_Flag,
156 "kAlphaUnchanged_Flag");
158 val->SetString("flags", builder.str());
161 SkScalar color_matrix[20];
162 if (filter.asColorMatrix(color_matrix)) {
163 scoped_ptr<base::ListValue> color_matrix_val(new base::ListValue());
164 for (unsigned i = 0; i < 20; ++i)
165 color_matrix_val->Append(AsValue(color_matrix[i]).release());
167 val->Set("color_matrix", color_matrix_val.Pass());
170 SkColor color;
171 SkXfermode::Mode mode;
172 if (filter.asColorMode(&color, &mode)) {
173 scoped_ptr<base::DictionaryValue> color_mode_val(
174 new base::DictionaryValue());
175 color_mode_val->Set("color", AsValue(color));
176 color_mode_val->Set("mode", AsValue(mode));
178 val->Set("color_mode", color_mode_val.Pass());
181 if (filter.asComponentTable(nullptr)) {
182 scoped_ptr<base::DictionaryValue> component_table_val(
183 new base::DictionaryValue());
184 // use this as a marker for now
185 val->Set("component_table", component_table_val.Pass());
188 return val.Pass();
191 WARN_UNUSED_RESULT
192 scoped_ptr<base::Value> AsValue(const SkImageFilter& filter) {
193 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
194 val->SetInteger("inputs", filter.countInputs());
196 SkColorFilter* color_filter;
197 if (filter.asColorFilter(&color_filter)) {
198 val->Set("color_filter", AsValue(*color_filter));
199 SkSafeUnref(color_filter); // ref'd in asColorFilter
202 return val.Pass();
205 WARN_UNUSED_RESULT
206 scoped_ptr<base::Value> AsValue(const SkPaint& paint) {
207 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
208 SkPaint default_paint;
210 if (paint.getColor() != default_paint.getColor())
211 val->Set("Color", AsValue(paint.getColor()));
213 if (paint.getStyle() != default_paint.getStyle()) {
214 static const char* gStyleStrings[] = { "Fill", "Stroke", "StrokeFill" };
215 DCHECK_LT(static_cast<size_t>(paint.getStyle()),
216 SK_ARRAY_COUNT(gStyleStrings));
217 val->SetString("Style", gStyleStrings[paint.getStyle()]);
220 if (paint.getXfermode() != default_paint.getXfermode()) {
221 DCHECK(paint.getXfermode());
222 val->Set("Xfermode", AsValue(*paint.getXfermode()));
225 if (paint.getFlags()) {
226 FlagsBuilder builder('|');
227 builder.addFlag(paint.isAntiAlias(), "AntiAlias");
228 builder.addFlag(paint.isDither(), "Dither");
229 builder.addFlag(paint.isUnderlineText(), "UnderlineText");
230 builder.addFlag(paint.isStrikeThruText(), "StrikeThruText");
231 builder.addFlag(paint.isFakeBoldText(), "FakeBoldText");
232 builder.addFlag(paint.isLinearText(), "LinearText");
233 builder.addFlag(paint.isSubpixelText(), "SubpixelText");
234 builder.addFlag(paint.isDevKernText(), "DevKernText");
235 builder.addFlag(paint.isLCDRenderText(), "LCDRenderText");
236 builder.addFlag(paint.isEmbeddedBitmapText(), "EmbeddedBitmapText");
237 builder.addFlag(paint.isAutohinted(), "Autohinted");
238 builder.addFlag(paint.isVerticalText(), "VerticalText");
239 builder.addFlag(paint.getFlags() & SkPaint::kGenA8FromLCD_Flag,
240 "GenA8FromLCD");
242 val->SetString("Flags", builder.str());
245 if (paint.getFilterQuality() != default_paint.getFilterQuality()) {
246 static const char* gFilterQualityStrings[] = {
247 "None", "Low", "Medium", "High"};
248 DCHECK_LT(static_cast<size_t>(paint.getFilterQuality()),
249 SK_ARRAY_COUNT(gFilterQualityStrings));
250 val->SetString("FilterLevel",
251 gFilterQualityStrings[paint.getFilterQuality()]);
254 if (paint.getTextSize() != default_paint.getTextSize())
255 val->SetDouble("TextSize", paint.getTextSize());
257 if (paint.getTextScaleX() != default_paint.getTextScaleX())
258 val->SetDouble("TextScaleX", paint.getTextScaleX());
260 if (paint.getTextSkewX() != default_paint.getTextSkewX())
261 val->SetDouble("TextSkewX", paint.getTextSkewX());
263 if (paint.getColorFilter())
264 val->Set("ColorFilter", AsValue(*paint.getColorFilter()));
266 if (paint.getImageFilter())
267 val->Set("ImageFilter", AsValue(*paint.getImageFilter()));
269 return val.Pass();
272 WARN_UNUSED_RESULT
273 scoped_ptr<base::Value> AsValue(SkCanvas::SaveFlags flags) {
274 FlagsBuilder builder('|');
275 builder.addFlag(flags & SkCanvas::kHasAlphaLayer_SaveFlag,
276 "kHasAlphaLayer");
277 builder.addFlag(flags & SkCanvas::kFullColorLayer_SaveFlag,
278 "kFullColorLayer");
279 builder.addFlag(flags & SkCanvas::kClipToLayer_SaveFlag,
280 "kClipToLayer");
282 scoped_ptr<base::StringValue> val(new base::StringValue(builder.str()));
284 return val.Pass();
287 WARN_UNUSED_RESULT
288 scoped_ptr<base::Value> AsValue(SkRegion::Op op) {
289 static const char* gOpStrings[] = { "Difference",
290 "Intersect",
291 "Union",
292 "XOR",
293 "ReverseDifference",
294 "Replace"
296 DCHECK_LT(static_cast<size_t>(op), SK_ARRAY_COUNT(gOpStrings));
297 scoped_ptr<base::StringValue> val(new base::StringValue(gOpStrings[op]));
298 return val.Pass();
301 WARN_UNUSED_RESULT
302 scoped_ptr<base::Value> AsValue(const SkRegion& region) {
303 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
304 val->Set("bounds", AsValue(SkRect::Make(region.getBounds())));
306 return val.Pass();
309 WARN_UNUSED_RESULT
310 scoped_ptr<base::Value> AsValue(const SkPicture& picture) {
311 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
312 val->Set("cull-rect", AsValue(picture.cullRect()));
314 return val.Pass();
317 WARN_UNUSED_RESULT
318 scoped_ptr<base::Value> AsValue(const SkBitmap& bitmap) {
319 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
320 val->Set("size", AsValue(SkSize::Make(bitmap.width(), bitmap.height())));
322 return val.Pass();
325 WARN_UNUSED_RESULT
326 scoped_ptr<base::Value> AsValue(const SkImage& image) {
327 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
328 val->Set("size", AsValue(SkSize::Make(image.width(), image.height())));
330 return val.Pass();
333 WARN_UNUSED_RESULT
334 scoped_ptr<base::Value> AsValue(const SkTextBlob& blob) {
335 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
336 val->Set("bounds", AsValue(blob.bounds()));
338 return val.Pass();
341 WARN_UNUSED_RESULT
342 scoped_ptr<base::Value> AsValue(const SkPath& path) {
343 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
345 static const char* gFillStrings[] =
346 { "winding", "even-odd", "inverse-winding", "inverse-even-odd" };
347 DCHECK_LT(static_cast<size_t>(path.getFillType()),
348 SK_ARRAY_COUNT(gFillStrings));
349 val->SetString("fill-type", gFillStrings[path.getFillType()]);
351 static const char* gConvexityStrings[] = { "Unknown", "Convex", "Concave" };
352 DCHECK_LT(static_cast<size_t>(path.getConvexity()),
353 SK_ARRAY_COUNT(gConvexityStrings));
354 val->SetString("convexity", gConvexityStrings[path.getConvexity()]);
356 val->SetBoolean("is-rect", path.isRect(nullptr));
357 val->Set("bounds", AsValue(path.getBounds()));
359 static const char* gVerbStrings[] =
360 { "move", "line", "quad", "conic", "cubic", "close", "done" };
361 static const int gPtsPerVerb[] = { 1, 1, 2, 2, 3, 0, 0 };
362 static const int gPtOffsetPerVerb[] = { 0, 1, 1, 1, 1, 0, 0 };
363 SK_COMPILE_ASSERT(
364 SK_ARRAY_COUNT(gVerbStrings) == static_cast<size_t>(SkPath::kDone_Verb + 1),
365 gVerbStrings_size_mismatch);
366 SK_COMPILE_ASSERT(
367 SK_ARRAY_COUNT(gVerbStrings) == SK_ARRAY_COUNT(gPtsPerVerb),
368 gPtsPerVerb_size_mismatch);
369 SK_COMPILE_ASSERT(
370 SK_ARRAY_COUNT(gVerbStrings) == SK_ARRAY_COUNT(gPtOffsetPerVerb),
371 gPtOffsetPerVerb_size_mismatch);
373 scoped_ptr<base::ListValue> verbs_val(new base::ListValue());
374 SkPath::Iter iter(const_cast<SkPath&>(path), false);
375 SkPoint points[4];
377 for(SkPath::Verb verb = iter.next(points, false);
378 verb != SkPath::kDone_Verb; verb = iter.next(points, false)) {
379 DCHECK_LT(static_cast<size_t>(verb), SK_ARRAY_COUNT(gVerbStrings));
381 scoped_ptr<base::DictionaryValue> verb_val(new base::DictionaryValue());
382 scoped_ptr<base::ListValue> pts_val(new base::ListValue());
384 for (int i = 0; i < gPtsPerVerb[verb]; ++i)
385 pts_val->Append(AsValue(points[i + gPtOffsetPerVerb[verb]]).release());
387 verb_val->Set(gVerbStrings[verb], pts_val.Pass());
389 if (SkPath::kConic_Verb == verb)
390 verb_val->Set("weight", AsValue(iter.conicWeight()));
392 verbs_val->Append(verb_val.release());
394 val->Set("verbs", verbs_val.Pass());
396 return val.Pass();
399 template<typename T>
400 WARN_UNUSED_RESULT
401 scoped_ptr<base::Value> AsListValue(const T array[], size_t count) {
402 scoped_ptr<base::ListValue> val(new base::ListValue());
404 for (size_t i = 0; i < count; ++i)
405 val->Append(AsValue(array[i]).release());
407 return val.Pass();
410 class OverdrawXfermode : public SkXfermode {
411 public:
412 SkPMColor xferColor(SkPMColor src, SkPMColor dst) const override {
413 // This table encodes the color progression of the overdraw visualization
414 static const SkPMColor gTable[] = {
415 SkPackARGB32(0x00, 0x00, 0x00, 0x00),
416 SkPackARGB32(0xFF, 128, 158, 255),
417 SkPackARGB32(0xFF, 170, 185, 212),
418 SkPackARGB32(0xFF, 213, 195, 170),
419 SkPackARGB32(0xFF, 255, 192, 127),
420 SkPackARGB32(0xFF, 255, 185, 85),
421 SkPackARGB32(0xFF, 255, 165, 42),
422 SkPackARGB32(0xFF, 255, 135, 0),
423 SkPackARGB32(0xFF, 255, 95, 0),
424 SkPackARGB32(0xFF, 255, 50, 0),
425 SkPackARGB32(0xFF, 255, 0, 0)
428 size_t idx;
429 if (SkColorGetR(dst) < 64) { // 0
430 idx = 0;
431 } else if (SkColorGetG(dst) < 25) { // 10
432 idx = 9; // cap at 9 for upcoming increment
433 } else if ((SkColorGetB(dst) + 21) / 42 > 0) { // 1-6
434 idx = 7 - (SkColorGetB(dst) + 21) / 42;
435 } else { // 7-9
436 idx = 10 - (SkColorGetG(dst) + 22) / 45;
439 ++idx;
440 SkASSERT(idx < SK_ARRAY_COUNT(gTable));
442 return gTable[idx];
445 Factory getFactory() const override { return NULL; }
446 #ifndef SK_IGNORE_TO_STRING
447 void toString(SkString* str) const override { str->set("OverdrawXfermode"); }
448 #endif
451 } // namespace
453 namespace skia {
455 class BenchmarkingCanvas::AutoOp {
456 public:
457 AutoOp(BenchmarkingCanvas* canvas, const char op_name[],
458 const SkPaint* paint = nullptr)
459 : canvas_(canvas)
460 , op_record_(new base::DictionaryValue())
461 , op_params_(new base::ListValue())
462 // AutoOp objects are always scoped within draw call frames,
463 // so the paint is guaranteed to be valid for their lifetime.
464 , paint_(paint) {
466 DCHECK(canvas);
467 DCHECK(op_name);
469 op_record_->SetString("cmd_string", op_name);
470 op_record_->Set("info", op_params_);
472 if (paint)
473 this->addParam("paint", AsValue(*paint));
475 if (canvas->flags_ & kOverdrawVisualization_Flag) {
476 DCHECK(canvas->overdraw_xfermode_);
478 paint_ = paint ? filtered_paint_.set(*paint) : filtered_paint_.init();
479 filtered_paint_.get()->setXfermode(canvas->overdraw_xfermode_.get());
480 filtered_paint_.get()->setAntiAlias(false);
483 start_ticks_ = base::TimeTicks::Now();
486 ~AutoOp() {
487 base::TimeDelta ticks = base::TimeTicks::Now() - start_ticks_;
488 op_record_->SetDouble("cmd_time", ticks.InMillisecondsF());
490 canvas_->op_records_.Append(op_record_);
493 void addParam(const char name[], scoped_ptr<base::Value> value) {
494 scoped_ptr<base::DictionaryValue> param(new base::DictionaryValue());
495 param->Set(name, value.Pass());
497 op_params_->Append(param.release());
500 const SkPaint* paint() const { return paint_; }
502 private:
503 BenchmarkingCanvas* canvas_;
504 base::DictionaryValue* op_record_;
505 base::ListValue* op_params_;
506 base::TimeTicks start_ticks_;
508 const SkPaint* paint_;
509 SkTLazy<SkPaint> filtered_paint_;
512 BenchmarkingCanvas::BenchmarkingCanvas(SkCanvas* canvas, unsigned flags)
513 : INHERITED(canvas->imageInfo().width(),
514 canvas->imageInfo().height())
515 , flags_(flags) {
516 addCanvas(canvas);
518 if (flags & kOverdrawVisualization_Flag)
519 overdraw_xfermode_ = AdoptRef(new OverdrawXfermode);
522 BenchmarkingCanvas::~BenchmarkingCanvas() {
525 size_t BenchmarkingCanvas::CommandCount() const {
526 return op_records_.GetSize();
529 const base::ListValue& BenchmarkingCanvas::Commands() const {
530 return op_records_;
533 double BenchmarkingCanvas::GetTime(size_t index) {
534 const base::DictionaryValue* op;
535 if (!op_records_.GetDictionary(index, &op))
536 return 0;
538 double t;
539 if (!op->GetDouble("cmd_time", &t))
540 return 0;
542 return t;
545 void BenchmarkingCanvas::willSave() {
546 AutoOp op(this, "Save");
548 INHERITED::willSave();
551 SkCanvas::SaveLayerStrategy BenchmarkingCanvas::willSaveLayer(const SkRect* rect,
552 const SkPaint* paint,
553 SaveFlags flags) {
554 AutoOp op(this, "SaveLayer", paint);
555 if (rect)
556 op.addParam("bounds", AsValue(*rect));
557 if (flags)
558 op.addParam("flags", AsValue(flags));
560 return INHERITED::willSaveLayer(rect, op.paint(), flags);
563 void BenchmarkingCanvas::willRestore() {
564 AutoOp op(this, "Restore");
566 INHERITED::willRestore();
569 void BenchmarkingCanvas::didConcat(const SkMatrix& m) {
570 AutoOp op(this, "Concat");
571 op.addParam("matrix", AsValue(m));
573 INHERITED::didConcat(m);
576 void BenchmarkingCanvas::didSetMatrix(const SkMatrix& m) {
577 AutoOp op(this, "SetMatrix");
578 op.addParam("matrix", AsValue(m));
580 INHERITED::didSetMatrix(m);
583 void BenchmarkingCanvas::onClipRect(const SkRect& rect,
584 SkRegion::Op region_op,
585 SkCanvas::ClipEdgeStyle style) {
586 AutoOp op(this, "ClipRect");
587 op.addParam("rect", AsValue(rect));
588 op.addParam("op", AsValue(region_op));
589 op.addParam("anti-alias", AsValue(style == kSoft_ClipEdgeStyle));
591 INHERITED::onClipRect(rect, region_op, style);
594 void BenchmarkingCanvas::onClipRRect(const SkRRect& rrect,
595 SkRegion::Op region_op,
596 SkCanvas::ClipEdgeStyle style) {
597 AutoOp op(this, "ClipRRect");
598 op.addParam("rrect", AsValue(rrect));
599 op.addParam("op", AsValue(region_op));
600 op.addParam("anti-alias", AsValue(style == kSoft_ClipEdgeStyle));
602 INHERITED::onClipRRect(rrect, region_op, style);
605 void BenchmarkingCanvas::onClipPath(const SkPath& path,
606 SkRegion::Op region_op,
607 SkCanvas::ClipEdgeStyle style) {
608 AutoOp op(this, "ClipPath");
609 op.addParam("path", AsValue(path));
610 op.addParam("op", AsValue(region_op));
611 op.addParam("anti-alias", AsValue(style == kSoft_ClipEdgeStyle));
613 INHERITED::onClipPath(path, region_op, style);
616 void BenchmarkingCanvas::onClipRegion(const SkRegion& region,
617 SkRegion::Op region_op) {
618 AutoOp op(this, "ClipRegion");
619 op.addParam("region", AsValue(region));
620 op.addParam("op", AsValue(region_op));
622 INHERITED::onClipRegion(region, region_op);
625 void BenchmarkingCanvas::onDrawPaint(const SkPaint& paint) {
626 AutoOp op(this, "DrawPaint", &paint);
628 INHERITED::onDrawPaint(*op.paint());
631 void BenchmarkingCanvas::onDrawPoints(PointMode mode, size_t count,
632 const SkPoint pts[], const SkPaint& paint) {
633 AutoOp op(this, "DrawPoints", &paint);
634 op.addParam("mode", AsValue(mode));
635 op.addParam("points", AsListValue(pts, count));
637 INHERITED::onDrawPoints(mode, count, pts, *op.paint());
640 void BenchmarkingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
641 AutoOp op(this, "DrawRect", &paint);
642 op.addParam("rect", AsValue(rect));
644 INHERITED::onDrawRect(rect, *op.paint());
647 void BenchmarkingCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
648 AutoOp op(this, "DrawOval", &paint);
649 op.addParam("rect", AsValue(rect));
651 INHERITED::onDrawOval(rect, *op.paint());
654 void BenchmarkingCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
655 AutoOp op(this, "DrawRRect", &paint);
656 op.addParam("rrect", AsValue(rrect));
658 INHERITED::onDrawRRect(rrect, *op.paint());
661 void BenchmarkingCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
662 const SkPaint& paint) {
663 AutoOp op(this, "DrawDRRect", &paint);
664 op.addParam("outer", AsValue(outer));
665 op.addParam("inner", AsValue(inner));
667 INHERITED::onDrawDRRect(outer, inner, *op.paint());
670 void BenchmarkingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
671 AutoOp op(this, "DrawPath", &paint);
672 op.addParam("path", AsValue(path));
674 INHERITED::onDrawPath(path, *op.paint());
677 void BenchmarkingCanvas::onDrawPicture(const SkPicture* picture,
678 const SkMatrix* matrix,
679 const SkPaint* paint) {
680 DCHECK(picture);
681 AutoOp op(this, "DrawPicture", paint);
682 op.addParam("picture", AsValue(picture));
683 if (matrix)
684 op.addParam("matrix", AsValue(*matrix));
686 INHERITED::onDrawPicture(picture, matrix, op.paint());
689 void BenchmarkingCanvas::onDrawBitmap(const SkBitmap& bitmap,
690 SkScalar left,
691 SkScalar top,
692 const SkPaint* paint) {
693 AutoOp op(this, "DrawBitmap", paint);
694 op.addParam("bitmap", AsValue(bitmap));
695 op.addParam("left", AsValue(left));
696 op.addParam("top", AsValue(top));
698 INHERITED::onDrawBitmap(bitmap, left, top, op.paint());
701 void BenchmarkingCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
702 const SkRect* src,
703 const SkRect& dst,
704 const SkPaint* paint,
705 SrcRectConstraint constraint) {
706 AutoOp op(this, "DrawBitmapRect", paint);
707 op.addParam("bitmap", AsValue(bitmap));
708 if (src)
709 op.addParam("src", AsValue(*src));
710 op.addParam("dst", AsValue(dst));
712 INHERITED::onDrawBitmapRect(bitmap, src, dst, op.paint(), constraint);
715 void BenchmarkingCanvas::onDrawImage(const SkImage* image,
716 SkScalar left,
717 SkScalar top,
718 const SkPaint* paint) {
719 DCHECK(image);
720 AutoOp op(this, "DrawImage", paint);
721 op.addParam("image", AsValue(*image));
722 op.addParam("left", AsValue(left));
723 op.addParam("top", AsValue(top));
725 INHERITED::onDrawImage(image, left, top, op.paint());
728 void BenchmarkingCanvas::onDrawImageRect(const SkImage* image, const SkRect* src,
729 const SkRect& dst, const SkPaint* paint,
730 SrcRectConstraint constraint) {
731 DCHECK(image);
732 AutoOp op(this, "DrawImageRect", paint);
733 op.addParam("image", AsValue(*image));
734 if (src)
735 op.addParam("src", AsValue(*src));
736 op.addParam("dst", AsValue(dst));
738 INHERITED::onDrawImageRect(image, src, dst, op.paint(), constraint);
741 void BenchmarkingCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
742 const SkIRect& center,
743 const SkRect& dst,
744 const SkPaint* paint) {
745 AutoOp op(this, "DrawBitmapNine", paint);
746 op.addParam("bitmap", AsValue(bitmap));
747 op.addParam("center", AsValue(SkRect::Make(center)));
748 op.addParam("dst", AsValue(dst));
750 INHERITED::onDrawBitmapNine(bitmap, center, dst, op.paint());
753 void BenchmarkingCanvas::onDrawSprite(const SkBitmap& bitmap, int left, int top,
754 const SkPaint* paint) {
755 AutoOp op(this, "DrawSprite", paint);
756 op.addParam("bitmap", AsValue(bitmap));
757 op.addParam("left", AsValue(SkIntToScalar(left)));
758 op.addParam("top", AsValue(SkIntToScalar(top)));
760 INHERITED::onDrawSprite(bitmap, left, top, op.paint());
763 void BenchmarkingCanvas::onDrawText(const void* text, size_t byteLength,
764 SkScalar x, SkScalar y,
765 const SkPaint& paint) {
766 AutoOp op(this, "DrawText", &paint);
767 op.addParam("count", AsValue(SkIntToScalar(paint.countText(text, byteLength))));
768 op.addParam("x", AsValue(x));
769 op.addParam("y", AsValue(y));
771 INHERITED::onDrawText(text, byteLength, x, y, *op.paint());
774 void BenchmarkingCanvas::onDrawPosText(const void* text, size_t byteLength,
775 const SkPoint pos[], const SkPaint& paint) {
776 AutoOp op(this, "DrawPosText", &paint);
778 int count = paint.countText(text, byteLength);
779 op.addParam("count", AsValue(SkIntToScalar(count)));
780 op.addParam("pos", AsListValue(pos, count));
782 INHERITED::onDrawPosText(text, byteLength, pos, *op.paint());
785 void BenchmarkingCanvas::onDrawPosTextH(const void* text, size_t byteLength,
786 const SkScalar xpos[], SkScalar constY,
787 const SkPaint& paint) {
788 AutoOp op(this, "DrawPosTextH", &paint);
789 op.addParam("constY", AsValue(constY));
791 int count = paint.countText(text, byteLength);
792 op.addParam("count", AsValue(SkIntToScalar(count)));
793 op.addParam("pos", AsListValue(xpos, count));
795 INHERITED::onDrawPosTextH(text, byteLength, xpos, constY, *op.paint());
798 void BenchmarkingCanvas::onDrawTextOnPath(const void* text, size_t byteLength,
799 const SkPath& path, const SkMatrix* matrix,
800 const SkPaint& paint) {
801 AutoOp op(this, "DrawTextOnPath", &paint);
802 op.addParam("count", AsValue(SkIntToScalar(paint.countText(text, byteLength))));
803 op.addParam("path", AsValue(path));
804 if (matrix)
805 op.addParam("matrix", AsValue(*matrix));
807 INHERITED::onDrawTextOnPath(text, byteLength, path, matrix, *op.paint());
810 void BenchmarkingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
811 const SkPaint& paint) {
812 DCHECK(blob);
813 AutoOp op(this, "DrawTextBlob", &paint);
814 op.addParam("blob", AsValue(*blob));
815 op.addParam("x", AsValue(x));
816 op.addParam("y", AsValue(y));
818 INHERITED::onDrawTextBlob(blob, x, y, *op.paint());
821 } // namespace skia