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/SkPaint.h"
12 #include "third_party/skia/include/core/SkPath.h"
13 #include "third_party/skia/include/core/SkPicture.h"
14 #include "third_party/skia/include/core/SkRegion.h"
15 #include "third_party/skia/include/core/SkRRect.h"
16 #include "third_party/skia/include/core/SkString.h"
17 #include "third_party/skia/include/core/SkTextBlob.h"
18 #include "third_party/skia/include/core/SkTLazy.h"
19 #include "third_party/skia/include/core/SkXfermode.h"
25 FlagsBuilder(char separator
)
26 : separator_(separator
) {}
28 void addFlag(bool flag_val
, const char flag_name
[]) {
31 if (!oss_
.str().empty())
37 std::string
str() const {
43 std::ostringstream oss_
;
47 scoped_ptr
<base::Value
> AsValue(bool b
) {
48 scoped_ptr
<base::FundamentalValue
> val(new base::FundamentalValue(b
));
54 scoped_ptr
<base::Value
> AsValue(SkScalar scalar
) {
55 scoped_ptr
<base::FundamentalValue
> val(new base::FundamentalValue(scalar
));
61 scoped_ptr
<base::Value
> AsValue(const SkSize
& size
) {
62 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
63 val
->Set("width", AsValue(size
.width()));
64 val
->Set("height", AsValue(size
.height()));
70 scoped_ptr
<base::Value
> AsValue(const SkPoint
& point
) {
71 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
72 val
->Set("x", AsValue(point
.x()));
73 val
->Set("y", AsValue(point
.y()));
79 scoped_ptr
<base::Value
> AsValue(const SkRect
& rect
) {
80 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
81 val
->Set("left", AsValue(rect
.fLeft
));
82 val
->Set("top", AsValue(rect
.fTop
));
83 val
->Set("right", AsValue(rect
.fRight
));
84 val
->Set("bottom", AsValue(rect
.fBottom
));
90 scoped_ptr
<base::Value
> AsValue(const SkRRect
& rrect
) {
91 scoped_ptr
<base::DictionaryValue
> radii_val(new base::DictionaryValue());
92 radii_val
->Set("upper-left", AsValue(rrect
.radii(SkRRect::kUpperLeft_Corner
)));
93 radii_val
->Set("upper-right", AsValue(rrect
.radii(SkRRect::kUpperRight_Corner
)));
94 radii_val
->Set("lower-right", AsValue(rrect
.radii(SkRRect::kLowerRight_Corner
)));
95 radii_val
->Set("lower-left", AsValue(rrect
.radii(SkRRect::kLowerLeft_Corner
)));
97 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
98 val
->Set("rect", AsValue(rrect
.rect()));
99 val
->Set("radii", radii_val
.Pass());
105 scoped_ptr
<base::Value
> AsValue(const SkMatrix
& matrix
) {
106 scoped_ptr
<base::ListValue
> val(new base::ListValue());
107 for (int i
= 0; i
< 9; ++i
)
108 val
->Append(AsValue(matrix
[i
]).release()); // no scoped_ptr-aware Append() variant
114 scoped_ptr
<base::Value
> AsValue(SkColor color
) {
115 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
116 val
->SetInteger("a", SkColorGetA(color
));
117 val
->SetInteger("r", SkColorGetR(color
));
118 val
->SetInteger("g", SkColorGetG(color
));
119 val
->SetInteger("b", SkColorGetB(color
));
125 scoped_ptr
<base::Value
> AsValue(SkXfermode::Mode mode
) {
126 scoped_ptr
<base::StringValue
> val(
127 new base::StringValue(SkXfermode::ModeName(mode
)));
133 scoped_ptr
<base::Value
> AsValue(SkCanvas::PointMode mode
) {
134 static const char* gModeStrings
[] = { "Points", "Lines", "Polygon" };
135 DCHECK_LT(static_cast<size_t>(mode
), SK_ARRAY_COUNT(gModeStrings
));
137 scoped_ptr
<base::StringValue
> val(new base::StringValue(gModeStrings
[mode
]));
143 scoped_ptr
<base::Value
> AsValue(const SkXfermode
& xfermode
) {
144 SkXfermode::Mode mode
;
145 if (xfermode
.asMode(&mode
))
146 return AsValue(mode
);
148 scoped_ptr
<base::StringValue
> val(new base::StringValue("unknown"));
153 scoped_ptr
<base::Value
> AsValue(const SkColorFilter
& filter
) {
154 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
156 if (unsigned flags
= filter
.getFlags()) {
157 FlagsBuilder
builder('|');
158 builder
.addFlag(flags
& SkColorFilter::kAlphaUnchanged_Flag
,
159 "kAlphaUnchanged_Flag");
161 val
->SetString("flags", builder
.str());
164 SkScalar color_matrix
[20];
165 if (filter
.asColorMatrix(color_matrix
)) {
166 scoped_ptr
<base::ListValue
> color_matrix_val(new base::ListValue());
167 for (unsigned i
= 0; i
< 20; ++i
)
168 color_matrix_val
->Append(AsValue(color_matrix
[i
]).release());
170 val
->Set("color_matrix", color_matrix_val
.Pass());
174 SkXfermode::Mode mode
;
175 if (filter
.asColorMode(&color
, &mode
)) {
176 scoped_ptr
<base::DictionaryValue
> color_mode_val(
177 new base::DictionaryValue());
178 color_mode_val
->Set("color", AsValue(color
));
179 color_mode_val
->Set("mode", AsValue(mode
));
181 val
->Set("color_mode", color_mode_val
.Pass());
184 if (filter
.asComponentTable(nullptr)) {
185 scoped_ptr
<base::DictionaryValue
> component_table_val(
186 new base::DictionaryValue());
187 // use this as a marker for now
188 val
->Set("component_table", component_table_val
.Pass());
195 scoped_ptr
<base::Value
> AsValue(const SkImageFilter
& filter
) {
196 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
197 val
->SetInteger("inputs", filter
.countInputs());
199 SkColorFilter
* color_filter
;
200 if (filter
.asColorFilter(&color_filter
)) {
201 val
->Set("color_filter", AsValue(*color_filter
));
202 SkSafeUnref(color_filter
); // ref'd in asColorFilter
209 scoped_ptr
<base::Value
> AsValue(const SkPaint
& paint
) {
210 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
211 SkPaint default_paint
;
213 if (paint
.getColor() != default_paint
.getColor())
214 val
->Set("Color", AsValue(paint
.getColor()));
216 if (paint
.getStyle() != default_paint
.getStyle()) {
217 static const char* gStyleStrings
[] = { "Fill", "Stroke", "StrokeFill" };
218 DCHECK_LT(static_cast<size_t>(paint
.getStyle()),
219 SK_ARRAY_COUNT(gStyleStrings
));
220 val
->SetString("Style", gStyleStrings
[paint
.getStyle()]);
223 if (paint
.getXfermode() != default_paint
.getXfermode()) {
224 DCHECK(paint
.getXfermode());
225 val
->Set("Xfermode", AsValue(*paint
.getXfermode()));
228 if (paint
.getFlags()) {
229 FlagsBuilder
builder('|');
230 builder
.addFlag(paint
.isAntiAlias(), "AntiAlias");
231 builder
.addFlag(paint
.isDither(), "Dither");
232 builder
.addFlag(paint
.isUnderlineText(), "UnderlineText");
233 builder
.addFlag(paint
.isStrikeThruText(), "StrikeThruText");
234 builder
.addFlag(paint
.isFakeBoldText(), "FakeBoldText");
235 builder
.addFlag(paint
.isLinearText(), "LinearText");
236 builder
.addFlag(paint
.isSubpixelText(), "SubpixelText");
237 builder
.addFlag(paint
.isDevKernText(), "DevKernText");
238 builder
.addFlag(paint
.isLCDRenderText(), "LCDRenderText");
239 builder
.addFlag(paint
.isEmbeddedBitmapText(), "EmbeddedBitmapText");
240 builder
.addFlag(paint
.isAutohinted(), "Autohinted");
241 builder
.addFlag(paint
.isVerticalText(), "VerticalText");
242 builder
.addFlag(paint
.getFlags() & SkPaint::kGenA8FromLCD_Flag
,
245 val
->SetString("Flags", builder
.str());
248 if (paint
.getFilterQuality() != default_paint
.getFilterQuality()) {
249 static const char* gFilterQualityStrings
[] = {
250 "None", "Low", "Medium", "High"};
251 DCHECK_LT(static_cast<size_t>(paint
.getFilterQuality()),
252 SK_ARRAY_COUNT(gFilterQualityStrings
));
253 val
->SetString("FilterLevel",
254 gFilterQualityStrings
[paint
.getFilterQuality()]);
257 if (paint
.getTextSize() != default_paint
.getTextSize())
258 val
->SetDouble("TextSize", paint
.getTextSize());
260 if (paint
.getTextScaleX() != default_paint
.getTextScaleX())
261 val
->SetDouble("TextScaleX", paint
.getTextScaleX());
263 if (paint
.getTextSkewX() != default_paint
.getTextSkewX())
264 val
->SetDouble("TextSkewX", paint
.getTextSkewX());
266 if (paint
.getColorFilter())
267 val
->Set("ColorFilter", AsValue(*paint
.getColorFilter()));
269 if (paint
.getImageFilter())
270 val
->Set("ImageFilter", AsValue(*paint
.getImageFilter()));
276 scoped_ptr
<base::Value
> AsValue(SkCanvas::SaveFlags flags
) {
277 FlagsBuilder
builder('|');
278 builder
.addFlag(flags
& SkCanvas::kHasAlphaLayer_SaveFlag
,
280 builder
.addFlag(flags
& SkCanvas::kFullColorLayer_SaveFlag
,
282 builder
.addFlag(flags
& SkCanvas::kClipToLayer_SaveFlag
,
285 scoped_ptr
<base::StringValue
> val(new base::StringValue(builder
.str()));
291 scoped_ptr
<base::Value
> AsValue(SkRegion::Op op
) {
292 static const char* gOpStrings
[] = { "Difference",
299 DCHECK_LT(static_cast<size_t>(op
), SK_ARRAY_COUNT(gOpStrings
));
300 scoped_ptr
<base::StringValue
> val(new base::StringValue(gOpStrings
[op
]));
305 scoped_ptr
<base::Value
> AsValue(const SkRegion
& region
) {
306 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
307 val
->Set("bounds", AsValue(SkRect::Make(region
.getBounds())));
313 scoped_ptr
<base::Value
> AsValue(const SkBitmap
& bitmap
) {
314 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
315 val
->Set("size", AsValue(SkSize::Make(bitmap
.width(), bitmap
.height())));
321 scoped_ptr
<base::Value
> AsValue(const SkImage
& image
) {
322 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
323 val
->Set("size", AsValue(SkSize::Make(image
.width(), image
.height())));
329 scoped_ptr
<base::Value
> AsValue(const SkTextBlob
& blob
) {
330 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
331 val
->Set("bounds", AsValue(blob
.bounds()));
337 scoped_ptr
<base::Value
> AsValue(const SkPath
& path
) {
338 scoped_ptr
<base::DictionaryValue
> val(new base::DictionaryValue());
340 static const char* gFillStrings
[] =
341 { "winding", "even-odd", "inverse-winding", "inverse-even-odd" };
342 DCHECK_LT(static_cast<size_t>(path
.getFillType()),
343 SK_ARRAY_COUNT(gFillStrings
));
344 val
->SetString("fill-type", gFillStrings
[path
.getFillType()]);
346 static const char* gConvexityStrings
[] = { "Unknown", "Convex", "Concave" };
347 DCHECK_LT(static_cast<size_t>(path
.getConvexity()),
348 SK_ARRAY_COUNT(gConvexityStrings
));
349 val
->SetString("convexity", gConvexityStrings
[path
.getConvexity()]);
351 val
->SetBoolean("is-rect", path
.isRect(nullptr));
352 val
->Set("bounds", AsValue(path
.getBounds()));
354 static const char* gVerbStrings
[] =
355 { "move", "line", "quad", "conic", "cubic", "close", "done" };
356 static const int gPtsPerVerb
[] = { 1, 1, 2, 2, 3, 0, 0 };
357 static const int gPtOffsetPerVerb
[] = { 0, 1, 1, 1, 1, 0, 0 };
359 SK_ARRAY_COUNT(gVerbStrings
) == static_cast<size_t>(SkPath::kDone_Verb
+ 1),
360 "gVerbStrings size mismatch");
362 SK_ARRAY_COUNT(gVerbStrings
) == SK_ARRAY_COUNT(gPtsPerVerb
),
363 "gPtsPerVerb size mismatch");
365 SK_ARRAY_COUNT(gVerbStrings
) == SK_ARRAY_COUNT(gPtOffsetPerVerb
),
366 "gPtOffsetPerVerb size mismatch");
368 scoped_ptr
<base::ListValue
> verbs_val(new base::ListValue());
369 SkPath::Iter
iter(const_cast<SkPath
&>(path
), false);
372 for(SkPath::Verb verb
= iter
.next(points
, false);
373 verb
!= SkPath::kDone_Verb
; verb
= iter
.next(points
, false)) {
374 DCHECK_LT(static_cast<size_t>(verb
), SK_ARRAY_COUNT(gVerbStrings
));
376 scoped_ptr
<base::DictionaryValue
> verb_val(new base::DictionaryValue());
377 scoped_ptr
<base::ListValue
> pts_val(new base::ListValue());
379 for (int i
= 0; i
< gPtsPerVerb
[verb
]; ++i
)
380 pts_val
->Append(AsValue(points
[i
+ gPtOffsetPerVerb
[verb
]]).release());
382 verb_val
->Set(gVerbStrings
[verb
], pts_val
.Pass());
384 if (SkPath::kConic_Verb
== verb
)
385 verb_val
->Set("weight", AsValue(iter
.conicWeight()));
387 verbs_val
->Append(verb_val
.release());
389 val
->Set("verbs", verbs_val
.Pass());
396 scoped_ptr
<base::Value
> AsListValue(const T array
[], size_t count
) {
397 scoped_ptr
<base::ListValue
> val(new base::ListValue());
399 for (size_t i
= 0; i
< count
; ++i
)
400 val
->Append(AsValue(array
[i
]).release());
405 class OverdrawXfermode
: public SkXfermode
{
407 SkPMColor
xferColor(SkPMColor src
, SkPMColor dst
) const override
{
408 // This table encodes the color progression of the overdraw visualization
409 static const SkPMColor gTable
[] = {
410 SkPackARGB32(0x00, 0x00, 0x00, 0x00),
411 SkPackARGB32(0xFF, 128, 158, 255),
412 SkPackARGB32(0xFF, 170, 185, 212),
413 SkPackARGB32(0xFF, 213, 195, 170),
414 SkPackARGB32(0xFF, 255, 192, 127),
415 SkPackARGB32(0xFF, 255, 185, 85),
416 SkPackARGB32(0xFF, 255, 165, 42),
417 SkPackARGB32(0xFF, 255, 135, 0),
418 SkPackARGB32(0xFF, 255, 95, 0),
419 SkPackARGB32(0xFF, 255, 50, 0),
420 SkPackARGB32(0xFF, 255, 0, 0)
424 if (SkColorGetR(dst
) < 64) { // 0
426 } else if (SkColorGetG(dst
) < 25) { // 10
427 idx
= 9; // cap at 9 for upcoming increment
428 } else if ((SkColorGetB(dst
) + 21) / 42 > 0) { // 1-6
429 idx
= 7 - (SkColorGetB(dst
) + 21) / 42;
431 idx
= 10 - (SkColorGetG(dst
) + 22) / 45;
435 SkASSERT(idx
< SK_ARRAY_COUNT(gTable
));
440 Factory
getFactory() const override
{ return NULL
; }
441 #ifndef SK_IGNORE_TO_STRING
442 void toString(SkString
* str
) const override
{ str
->set("OverdrawXfermode"); }
450 class BenchmarkingCanvas::AutoOp
{
452 AutoOp(BenchmarkingCanvas
* canvas
, const char op_name
[],
453 const SkPaint
* paint
= nullptr)
455 , op_record_(new base::DictionaryValue())
456 , op_params_(new base::ListValue())
457 // AutoOp objects are always scoped within draw call frames,
458 // so the paint is guaranteed to be valid for their lifetime.
464 op_record_
->SetString("cmd_string", op_name
);
465 op_record_
->Set("info", op_params_
);
468 this->addParam("paint", AsValue(*paint
));
470 if (canvas
->flags_
& kOverdrawVisualization_Flag
) {
471 DCHECK(canvas
->overdraw_xfermode_
);
473 paint_
= paint
? filtered_paint_
.set(*paint
) : filtered_paint_
.init();
474 filtered_paint_
.get()->setXfermode(canvas
->overdraw_xfermode_
.get());
475 filtered_paint_
.get()->setAntiAlias(false);
478 start_ticks_
= base::TimeTicks::Now();
482 base::TimeDelta ticks
= base::TimeTicks::Now() - start_ticks_
;
483 op_record_
->SetDouble("cmd_time", ticks
.InMillisecondsF());
485 canvas_
->op_records_
.Append(op_record_
);
488 void addParam(const char name
[], scoped_ptr
<base::Value
> value
) {
489 scoped_ptr
<base::DictionaryValue
> param(new base::DictionaryValue());
490 param
->Set(name
, value
.Pass());
492 op_params_
->Append(param
.release());
495 const SkPaint
* paint() const { return paint_
; }
498 BenchmarkingCanvas
* canvas_
;
499 base::DictionaryValue
* op_record_
;
500 base::ListValue
* op_params_
;
501 base::TimeTicks start_ticks_
;
503 const SkPaint
* paint_
;
504 SkTLazy
<SkPaint
> filtered_paint_
;
507 BenchmarkingCanvas::BenchmarkingCanvas(SkCanvas
* canvas
, unsigned flags
)
508 : INHERITED(canvas
->imageInfo().width(),
509 canvas
->imageInfo().height())
513 if (flags
& kOverdrawVisualization_Flag
)
514 overdraw_xfermode_
= AdoptRef(new OverdrawXfermode
);
517 BenchmarkingCanvas::~BenchmarkingCanvas() {
520 size_t BenchmarkingCanvas::CommandCount() const {
521 return op_records_
.GetSize();
524 const base::ListValue
& BenchmarkingCanvas::Commands() const {
528 double BenchmarkingCanvas::GetTime(size_t index
) {
529 const base::DictionaryValue
* op
;
530 if (!op_records_
.GetDictionary(index
, &op
))
534 if (!op
->GetDouble("cmd_time", &t
))
540 void BenchmarkingCanvas::willSave() {
541 AutoOp
op(this, "Save");
543 INHERITED::willSave();
546 SkCanvas::SaveLayerStrategy
BenchmarkingCanvas::willSaveLayer(const SkRect
* rect
,
547 const SkPaint
* paint
,
549 AutoOp
op(this, "SaveLayer", paint
);
551 op
.addParam("bounds", AsValue(*rect
));
553 op
.addParam("flags", AsValue(flags
));
555 return INHERITED::willSaveLayer(rect
, op
.paint(), flags
);
558 void BenchmarkingCanvas::willRestore() {
559 AutoOp
op(this, "Restore");
561 INHERITED::willRestore();
564 void BenchmarkingCanvas::didConcat(const SkMatrix
& m
) {
565 AutoOp
op(this, "Concat");
566 op
.addParam("matrix", AsValue(m
));
568 INHERITED::didConcat(m
);
571 void BenchmarkingCanvas::didSetMatrix(const SkMatrix
& m
) {
572 AutoOp
op(this, "SetMatrix");
573 op
.addParam("matrix", AsValue(m
));
575 INHERITED::didSetMatrix(m
);
578 void BenchmarkingCanvas::onClipRect(const SkRect
& rect
,
579 SkRegion::Op region_op
,
580 SkCanvas::ClipEdgeStyle style
) {
581 AutoOp
op(this, "ClipRect");
582 op
.addParam("rect", AsValue(rect
));
583 op
.addParam("op", AsValue(region_op
));
584 op
.addParam("anti-alias", AsValue(style
== kSoft_ClipEdgeStyle
));
586 INHERITED::onClipRect(rect
, region_op
, style
);
589 void BenchmarkingCanvas::onClipRRect(const SkRRect
& rrect
,
590 SkRegion::Op region_op
,
591 SkCanvas::ClipEdgeStyle style
) {
592 AutoOp
op(this, "ClipRRect");
593 op
.addParam("rrect", AsValue(rrect
));
594 op
.addParam("op", AsValue(region_op
));
595 op
.addParam("anti-alias", AsValue(style
== kSoft_ClipEdgeStyle
));
597 INHERITED::onClipRRect(rrect
, region_op
, style
);
600 void BenchmarkingCanvas::onClipPath(const SkPath
& path
,
601 SkRegion::Op region_op
,
602 SkCanvas::ClipEdgeStyle style
) {
603 AutoOp
op(this, "ClipPath");
604 op
.addParam("path", AsValue(path
));
605 op
.addParam("op", AsValue(region_op
));
606 op
.addParam("anti-alias", AsValue(style
== kSoft_ClipEdgeStyle
));
608 INHERITED::onClipPath(path
, region_op
, style
);
611 void BenchmarkingCanvas::onClipRegion(const SkRegion
& region
,
612 SkRegion::Op region_op
) {
613 AutoOp
op(this, "ClipRegion");
614 op
.addParam("region", AsValue(region
));
615 op
.addParam("op", AsValue(region_op
));
617 INHERITED::onClipRegion(region
, region_op
);
620 void BenchmarkingCanvas::onDrawPaint(const SkPaint
& paint
) {
621 AutoOp
op(this, "DrawPaint", &paint
);
623 INHERITED::onDrawPaint(*op
.paint());
626 void BenchmarkingCanvas::onDrawPoints(PointMode mode
, size_t count
,
627 const SkPoint pts
[], const SkPaint
& paint
) {
628 AutoOp
op(this, "DrawPoints", &paint
);
629 op
.addParam("mode", AsValue(mode
));
630 op
.addParam("points", AsListValue(pts
, count
));
632 INHERITED::onDrawPoints(mode
, count
, pts
, *op
.paint());
635 void BenchmarkingCanvas::onDrawRect(const SkRect
& rect
, const SkPaint
& paint
) {
636 AutoOp
op(this, "DrawRect", &paint
);
637 op
.addParam("rect", AsValue(rect
));
639 INHERITED::onDrawRect(rect
, *op
.paint());
642 void BenchmarkingCanvas::onDrawOval(const SkRect
& rect
, const SkPaint
& paint
) {
643 AutoOp
op(this, "DrawOval", &paint
);
644 op
.addParam("rect", AsValue(rect
));
646 INHERITED::onDrawOval(rect
, *op
.paint());
649 void BenchmarkingCanvas::onDrawRRect(const SkRRect
& rrect
, const SkPaint
& paint
) {
650 AutoOp
op(this, "DrawRRect", &paint
);
651 op
.addParam("rrect", AsValue(rrect
));
653 INHERITED::onDrawRRect(rrect
, *op
.paint());
656 void BenchmarkingCanvas::onDrawDRRect(const SkRRect
& outer
, const SkRRect
& inner
,
657 const SkPaint
& paint
) {
658 AutoOp
op(this, "DrawDRRect", &paint
);
659 op
.addParam("outer", AsValue(outer
));
660 op
.addParam("inner", AsValue(inner
));
662 INHERITED::onDrawDRRect(outer
, inner
, *op
.paint());
665 void BenchmarkingCanvas::onDrawPath(const SkPath
& path
, const SkPaint
& paint
) {
666 AutoOp
op(this, "DrawPath", &paint
);
667 op
.addParam("path", AsValue(path
));
669 INHERITED::onDrawPath(path
, *op
.paint());
672 void BenchmarkingCanvas::onDrawPicture(const SkPicture
* picture
,
673 const SkMatrix
* matrix
,
674 const SkPaint
* paint
) {
676 AutoOp
op(this, "DrawPicture", paint
);
677 op
.addParam("picture", AsValue(picture
));
679 op
.addParam("matrix", AsValue(*matrix
));
681 INHERITED::onDrawPicture(picture
, matrix
, op
.paint());
684 void BenchmarkingCanvas::onDrawBitmap(const SkBitmap
& bitmap
,
687 const SkPaint
* paint
) {
688 AutoOp
op(this, "DrawBitmap", paint
);
689 op
.addParam("bitmap", AsValue(bitmap
));
690 op
.addParam("left", AsValue(left
));
691 op
.addParam("top", AsValue(top
));
693 INHERITED::onDrawBitmap(bitmap
, left
, top
, op
.paint());
696 void BenchmarkingCanvas::onDrawBitmapRect(const SkBitmap
& bitmap
,
699 const SkPaint
* paint
,
700 SrcRectConstraint constraint
) {
701 AutoOp
op(this, "DrawBitmapRect", paint
);
702 op
.addParam("bitmap", AsValue(bitmap
));
704 op
.addParam("src", AsValue(*src
));
705 op
.addParam("dst", AsValue(dst
));
707 INHERITED::onDrawBitmapRect(bitmap
, src
, dst
, op
.paint(), constraint
);
710 void BenchmarkingCanvas::onDrawImage(const SkImage
* image
,
713 const SkPaint
* paint
) {
715 AutoOp
op(this, "DrawImage", paint
);
716 op
.addParam("image", AsValue(*image
));
717 op
.addParam("left", AsValue(left
));
718 op
.addParam("top", AsValue(top
));
720 INHERITED::onDrawImage(image
, left
, top
, op
.paint());
723 void BenchmarkingCanvas::onDrawImageRect(const SkImage
* image
, const SkRect
* src
,
724 const SkRect
& dst
, const SkPaint
* paint
,
725 SrcRectConstraint constraint
) {
727 AutoOp
op(this, "DrawImageRect", paint
);
728 op
.addParam("image", AsValue(*image
));
730 op
.addParam("src", AsValue(*src
));
731 op
.addParam("dst", AsValue(dst
));
733 INHERITED::onDrawImageRect(image
, src
, dst
, op
.paint(), constraint
);
736 void BenchmarkingCanvas::onDrawBitmapNine(const SkBitmap
& bitmap
,
737 const SkIRect
& center
,
739 const SkPaint
* paint
) {
740 AutoOp
op(this, "DrawBitmapNine", paint
);
741 op
.addParam("bitmap", AsValue(bitmap
));
742 op
.addParam("center", AsValue(SkRect::Make(center
)));
743 op
.addParam("dst", AsValue(dst
));
745 INHERITED::onDrawBitmapNine(bitmap
, center
, dst
, op
.paint());
748 void BenchmarkingCanvas::onDrawSprite(const SkBitmap
& bitmap
, int left
, int top
,
749 const SkPaint
* paint
) {
750 AutoOp
op(this, "DrawSprite", paint
);
751 op
.addParam("bitmap", AsValue(bitmap
));
752 op
.addParam("left", AsValue(SkIntToScalar(left
)));
753 op
.addParam("top", AsValue(SkIntToScalar(top
)));
755 INHERITED::onDrawSprite(bitmap
, left
, top
, op
.paint());
758 void BenchmarkingCanvas::onDrawText(const void* text
, size_t byteLength
,
759 SkScalar x
, SkScalar y
,
760 const SkPaint
& paint
) {
761 AutoOp
op(this, "DrawText", &paint
);
762 op
.addParam("count", AsValue(SkIntToScalar(paint
.countText(text
, byteLength
))));
763 op
.addParam("x", AsValue(x
));
764 op
.addParam("y", AsValue(y
));
766 INHERITED::onDrawText(text
, byteLength
, x
, y
, *op
.paint());
769 void BenchmarkingCanvas::onDrawPosText(const void* text
, size_t byteLength
,
770 const SkPoint pos
[], const SkPaint
& paint
) {
771 AutoOp
op(this, "DrawPosText", &paint
);
773 int count
= paint
.countText(text
, byteLength
);
774 op
.addParam("count", AsValue(SkIntToScalar(count
)));
775 op
.addParam("pos", AsListValue(pos
, count
));
777 INHERITED::onDrawPosText(text
, byteLength
, pos
, *op
.paint());
780 void BenchmarkingCanvas::onDrawPosTextH(const void* text
, size_t byteLength
,
781 const SkScalar xpos
[], SkScalar constY
,
782 const SkPaint
& paint
) {
783 AutoOp
op(this, "DrawPosTextH", &paint
);
784 op
.addParam("constY", AsValue(constY
));
786 int count
= paint
.countText(text
, byteLength
);
787 op
.addParam("count", AsValue(SkIntToScalar(count
)));
788 op
.addParam("pos", AsListValue(xpos
, count
));
790 INHERITED::onDrawPosTextH(text
, byteLength
, xpos
, constY
, *op
.paint());
793 void BenchmarkingCanvas::onDrawTextOnPath(const void* text
, size_t byteLength
,
794 const SkPath
& path
, const SkMatrix
* matrix
,
795 const SkPaint
& paint
) {
796 AutoOp
op(this, "DrawTextOnPath", &paint
);
797 op
.addParam("count", AsValue(SkIntToScalar(paint
.countText(text
, byteLength
))));
798 op
.addParam("path", AsValue(path
));
800 op
.addParam("matrix", AsValue(*matrix
));
802 INHERITED::onDrawTextOnPath(text
, byteLength
, path
, matrix
, *op
.paint());
805 void BenchmarkingCanvas::onDrawTextBlob(const SkTextBlob
* blob
, SkScalar x
, SkScalar y
,
806 const SkPaint
& paint
) {
808 AutoOp
op(this, "DrawTextBlob", &paint
);
809 op
.addParam("blob", AsValue(*blob
));
810 op
.addParam("x", AsValue(x
));
811 op
.addParam("y", AsValue(y
));
813 INHERITED::onDrawTextBlob(blob
, x
, y
, *op
.paint());