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"
22 FlagsBuilder(char separator
)
23 : separator_(separator
) {}
25 void addFlag(bool flag_val
, const char flag_name
[]) {
28 if (!oss_
.str().empty())
34 std::string
str() const {
40 std::ostringstream oss_
;
44 scoped_ptr
<base::Value
> AsValue(bool b
) {
45 scoped_ptr
<base::FundamentalValue
> val(new base::FundamentalValue(b
));
51 scoped_ptr
<base::Value
> AsValue(SkScalar scalar
) {
52 scoped_ptr
<base::FundamentalValue
> val(new base::FundamentalValue(scalar
));
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()));
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()));
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
));
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());
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
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
));
122 scoped_ptr
<base::Value
> AsValue(SkXfermode::Mode mode
) {
123 scoped_ptr
<base::StringValue
> val(
124 new base::StringValue(SkXfermode::ModeName(mode
)));
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
]));
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"));
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());
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());
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
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
,
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()));
273 scoped_ptr
<base::Value
> AsValue(SkCanvas::SaveFlags flags
) {
274 FlagsBuilder
builder('|');
275 builder
.addFlag(flags
& SkCanvas::kHasAlphaLayer_SaveFlag
,
277 builder
.addFlag(flags
& SkCanvas::kFullColorLayer_SaveFlag
,
279 builder
.addFlag(flags
& SkCanvas::kClipToLayer_SaveFlag
,
282 scoped_ptr
<base::StringValue
> val(new base::StringValue(builder
.str()));
288 scoped_ptr
<base::Value
> AsValue(SkRegion::Op op
) {
289 static const char* gOpStrings
[] = { "Difference",
296 DCHECK_LT(static_cast<size_t>(op
), SK_ARRAY_COUNT(gOpStrings
));
297 scoped_ptr
<base::StringValue
> val(new base::StringValue(gOpStrings
[op
]));
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())));
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()));
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())));
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())));
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()));
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 };
364 SK_ARRAY_COUNT(gVerbStrings
) == static_cast<size_t>(SkPath::kDone_Verb
+ 1),
365 gVerbStrings_size_mismatch
);
367 SK_ARRAY_COUNT(gVerbStrings
) == SK_ARRAY_COUNT(gPtsPerVerb
),
368 gPtsPerVerb_size_mismatch
);
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);
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());
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());
410 class OverdrawXfermode
: public SkXfermode
{
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)
429 if (SkColorGetR(dst
) < 64) { // 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;
436 idx
= 10 - (SkColorGetG(dst
) + 22) / 45;
440 SkASSERT(idx
< SK_ARRAY_COUNT(gTable
));
445 Factory
getFactory() const override
{ return NULL
; }
446 #ifndef SK_IGNORE_TO_STRING
447 void toString(SkString
* str
) const override
{ str
->set("OverdrawXfermode"); }
455 class BenchmarkingCanvas::AutoOp
{
457 AutoOp(BenchmarkingCanvas
* canvas
, const char op_name
[],
458 const SkPaint
* paint
= nullptr)
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.
469 op_record_
->SetString("cmd_string", op_name
);
470 op_record_
->Set("info", op_params_
);
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();
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_
; }
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())
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 {
533 double BenchmarkingCanvas::GetTime(size_t index
) {
534 const base::DictionaryValue
* op
;
535 if (!op_records_
.GetDictionary(index
, &op
))
539 if (!op
->GetDouble("cmd_time", &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
,
554 AutoOp
op(this, "SaveLayer", paint
);
556 op
.addParam("bounds", AsValue(*rect
));
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
) {
681 AutoOp
op(this, "DrawPicture", paint
);
682 op
.addParam("picture", AsValue(picture
));
684 op
.addParam("matrix", AsValue(*matrix
));
686 INHERITED::onDrawPicture(picture
, matrix
, op
.paint());
689 void BenchmarkingCanvas::onDrawBitmap(const SkBitmap
& bitmap
,
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
,
704 const SkPaint
* paint
,
705 SrcRectConstraint constraint
) {
706 AutoOp
op(this, "DrawBitmapRect", paint
);
707 op
.addParam("bitmap", AsValue(bitmap
));
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
,
718 const SkPaint
* paint
) {
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
) {
732 AutoOp
op(this, "DrawImageRect", paint
);
733 op
.addParam("image", AsValue(*image
));
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
,
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
));
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
) {
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());