| // 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 <utility> |
| |
| #include "base/logging.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/time/time.h" |
| #include "third_party/skia/include/core/SkColorFilter.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/SkTLazy.h" |
| #include "third_party/skia/include/core/SkTextBlob.h" |
| #include "third_party/skia/include/core/SkXfermode.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_; |
| }; |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(bool b) { |
| scoped_ptr<base::FundamentalValue> val(new base::FundamentalValue(b)); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(SkScalar scalar) { |
| scoped_ptr<base::FundamentalValue> val(new base::FundamentalValue(scalar)); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkSize& size) { |
| scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
| val->Set("width", AsValue(size.width())); |
| val->Set("height", AsValue(size.height())); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkPoint& point) { |
| scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
| val->Set("x", AsValue(point.x())); |
| val->Set("y", AsValue(point.y())); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkRect& rect) { |
| scoped_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); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkRRect& rrect) { |
| scoped_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))); |
| |
| scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
| val->Set("rect", AsValue(rrect.rect())); |
| val->Set("radii", std::move(radii_val)); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkMatrix& matrix) { |
| scoped_ptr<base::ListValue> val(new base::ListValue()); |
| for (int i = 0; i < 9; ++i) |
| val->Append(AsValue(matrix[i]).release()); // no scoped_ptr-aware Append() variant |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(SkColor color) { |
| scoped_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); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(SkXfermode::Mode mode) { |
| scoped_ptr<base::StringValue> val( |
| new base::StringValue(SkXfermode::ModeName(mode))); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_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)); |
| |
| scoped_ptr<base::StringValue> val(new base::StringValue(gModeStrings[mode])); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkXfermode& xfermode) { |
| SkXfermode::Mode mode; |
| if (xfermode.asMode(&mode)) |
| return AsValue(mode); |
| |
| scoped_ptr<base::StringValue> val(new base::StringValue("unknown")); |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkColorFilter& filter) { |
| scoped_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)) { |
| scoped_ptr<base::ListValue> color_matrix_val(new base::ListValue()); |
| for (unsigned i = 0; i < 20; ++i) |
| color_matrix_val->Append(AsValue(color_matrix[i]).release()); |
| |
| val->Set("color_matrix", std::move(color_matrix_val)); |
| } |
| |
| SkColor color; |
| SkXfermode::Mode mode; |
| if (filter.asColorMode(&color, &mode)) { |
| scoped_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)) { |
| scoped_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); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkImageFilter& filter) { |
| scoped_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); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkPaint& paint) { |
| scoped_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.getXfermode() != default_paint.getXfermode()) { |
| DCHECK(paint.getXfermode()); |
| val->Set("Xfermode", AsValue(*paint.getXfermode())); |
| } |
| |
| if (paint.getFlags()) { |
| FlagsBuilder builder('|'); |
| builder.addFlag(paint.isAntiAlias(), "AntiAlias"); |
| builder.addFlag(paint.isDither(), "Dither"); |
| builder.addFlag(paint.isUnderlineText(), "UnderlineText"); |
| builder.addFlag(paint.isStrikeThruText(), "StrikeThruText"); |
| 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); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> SaveLayerFlagsAsValue(SkCanvas::SaveLayerFlags flags) { |
| FlagsBuilder builder('|'); |
| builder.addFlag(flags & SkCanvas::kIsOpaque_SaveLayerFlag, |
| "kIsOpaque"); |
| builder.addFlag(flags & SkCanvas::kPreserveLCDText_SaveLayerFlag, |
| "kPreserveLCDText"); |
| |
| scoped_ptr<base::StringValue> val(new base::StringValue(builder.str())); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(SkRegion::Op op) { |
| static const char* gOpStrings[] = { "Difference", |
| "Intersect", |
| "Union", |
| "XOR", |
| "ReverseDifference", |
| "Replace" |
| }; |
| DCHECK_LT(static_cast<size_t>(op), SK_ARRAY_COUNT(gOpStrings)); |
| scoped_ptr<base::StringValue> val(new base::StringValue(gOpStrings[op])); |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkRegion& region) { |
| scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
| val->Set("bounds", AsValue(SkRect::Make(region.getBounds()))); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkBitmap& bitmap) { |
| scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
| val->Set("size", AsValue(SkSize::Make(bitmap.width(), bitmap.height()))); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkImage& image) { |
| scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
| val->Set("size", AsValue(SkSize::Make(image.width(), image.height()))); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkTextBlob& blob) { |
| scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
| val->Set("bounds", AsValue(blob.bounds())); |
| |
| return std::move(val); |
| } |
| |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsValue(const SkPath& path) { |
| scoped_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"); |
| |
| scoped_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)); |
| |
| scoped_ptr<base::DictionaryValue> verb_val(new base::DictionaryValue()); |
| scoped_ptr<base::ListValue> pts_val(new base::ListValue()); |
| |
| for (int i = 0; i < gPtsPerVerb[verb]; ++i) |
| pts_val->Append(AsValue(points[i + gPtOffsetPerVerb[verb]]).release()); |
| |
| verb_val->Set(gVerbStrings[verb], std::move(pts_val)); |
| |
| if (SkPath::kConic_Verb == verb) |
| verb_val->Set("weight", AsValue(iter.conicWeight())); |
| |
| verbs_val->Append(verb_val.release()); |
| } |
| val->Set("verbs", std::move(verbs_val)); |
| |
| return std::move(val); |
| } |
| |
| template<typename T> |
| WARN_UNUSED_RESULT |
| scoped_ptr<base::Value> AsListValue(const T array[], size_t count) { |
| scoped_ptr<base::ListValue> val(new base::ListValue()); |
| |
| for (size_t i = 0; i < count; ++i) |
| val->Append(AsValue(array[i]).release()); |
| |
| return std::move(val); |
| } |
| |
| class OverdrawXfermode : public SkXfermode { |
| public: |
| SkPMColor xferColor(SkPMColor src, SkPMColor dst) const override { |
| // This table encodes the color progression of the overdraw visualization |
| static const SkPMColor gTable[] = { |
| SkPackARGB32(0x00, 0x00, 0x00, 0x00), |
| SkPackARGB32(0xFF, 128, 158, 255), |
| SkPackARGB32(0xFF, 170, 185, 212), |
| SkPackARGB32(0xFF, 213, 195, 170), |
| SkPackARGB32(0xFF, 255, 192, 127), |
| SkPackARGB32(0xFF, 255, 185, 85), |
| SkPackARGB32(0xFF, 255, 165, 42), |
| SkPackARGB32(0xFF, 255, 135, 0), |
| SkPackARGB32(0xFF, 255, 95, 0), |
| SkPackARGB32(0xFF, 255, 50, 0), |
| SkPackARGB32(0xFF, 255, 0, 0) |
| }; |
| |
| size_t idx; |
| if (SkColorGetR(dst) < 64) { // 0 |
| idx = 0; |
| } else if (SkColorGetG(dst) < 25) { // 10 |
| idx = 9; // cap at 9 for upcoming increment |
| } else if ((SkColorGetB(dst) + 21) / 42 > 0) { // 1-6 |
| idx = 7 - (SkColorGetB(dst) + 21) / 42; |
| } else { // 7-9 |
| idx = 10 - (SkColorGetG(dst) + 22) / 45; |
| } |
| |
| ++idx; |
| SkASSERT(idx < SK_ARRAY_COUNT(gTable)); |
| |
| return gTable[idx]; |
| } |
| |
| Factory getFactory() const override { return NULL; } |
| #ifndef SK_IGNORE_TO_STRING |
| void toString(SkString* str) const override { str->set("OverdrawXfermode"); } |
| #endif |
| }; |
| |
| } // namespace |
| |
| namespace skia { |
| |
| class BenchmarkingCanvas::AutoOp { |
| public: |
| AutoOp(BenchmarkingCanvas* canvas, const char op_name[], |
| const SkPaint* paint = nullptr) |
| : canvas_(canvas) |
| , op_record_(new base::DictionaryValue()) |
| , op_params_(new base::ListValue()) |
| // AutoOp objects are always scoped within draw call frames, |
| // so the paint is guaranteed to be valid for their lifetime. |
| , paint_(paint) { |
| |
| DCHECK(canvas); |
| DCHECK(op_name); |
| |
| op_record_->SetString("cmd_string", op_name); |
| op_record_->Set("info", op_params_); |
| |
| if (paint) |
| this->addParam("paint", AsValue(*paint)); |
| |
| if (canvas->flags_ & kOverdrawVisualization_Flag) { |
| DCHECK(canvas->overdraw_xfermode_); |
| |
| paint_ = paint ? filtered_paint_.set(*paint) : filtered_paint_.init(); |
| filtered_paint_.get()->setXfermode(canvas->overdraw_xfermode_.get()); |
| filtered_paint_.get()->setAntiAlias(false); |
| } |
| |
| 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(op_record_); |
| } |
| |
| void addParam(const char name[], scoped_ptr<base::Value> value) { |
| scoped_ptr<base::DictionaryValue> param(new base::DictionaryValue()); |
| param->Set(name, std::move(value)); |
| |
| op_params_->Append(param.release()); |
| } |
| |
| const SkPaint* paint() const { return paint_; } |
| |
| private: |
| BenchmarkingCanvas* canvas_; |
| base::DictionaryValue* op_record_; |
| base::ListValue* op_params_; |
| base::TimeTicks start_ticks_; |
| |
| const SkPaint* paint_; |
| SkTLazy<SkPaint> filtered_paint_; |
| }; |
| |
| BenchmarkingCanvas::BenchmarkingCanvas(SkCanvas* canvas, unsigned flags) |
| : INHERITED(canvas->imageInfo().width(), |
| canvas->imageInfo().height()) |
| , flags_(flags) { |
| addCanvas(canvas); |
| |
| if (flags & kOverdrawVisualization_Flag) |
| overdraw_xfermode_ = AdoptRef(new OverdrawXfermode); |
| } |
| |
| BenchmarkingCanvas::~BenchmarkingCanvas() { |
| } |
| |
| 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, |
| SkRegion::Op 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, |
| SkRegion::Op 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, |
| SkRegion::Op 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, |
| SkRegion::Op 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 |