Index: skia/ext/benchmarking_canvas.cc |
diff --git a/skia/ext/benchmarking_canvas.cc b/skia/ext/benchmarking_canvas.cc |
index 409d56bf186c2398977c2985f92e2f7617b8efaa..0dd6949d5caf7b5a34cb45cd629e651441628821 100644 |
--- a/skia/ext/benchmarking_canvas.cc |
+++ b/skia/ext/benchmarking_canvas.cc |
@@ -2,250 +2,760 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "base/containers/hash_tables.h" |
#include "base/logging.h" |
+#include "base/strings/stringprintf.h" |
#include "base/time/time.h" |
#include "skia/ext/benchmarking_canvas.h" |
-#include "third_party/skia/include/core/SkSurface.h" |
-#include "third_party/skia/include/utils/SkNWayCanvas.h" |
+#include "third_party/skia/include/core/SkColorFilter.h" |
+#include "third_party/skia/include/core/SkImageFilter.h" |
+#include "third_party/skia/include/core/SkPicture.h" |
+#include "third_party/skia/include/core/SkRegion.h" |
+#include "third_party/skia/include/core/SkTextBlob.h" |
+#include "third_party/skia/include/core/SkXfermode.h" |
-namespace skia { |
+namespace { |
-class AutoStamper { |
+class FlagsBuilder { |
public: |
- AutoStamper(TimingCanvas* timing_canvas); |
- ~AutoStamper(); |
+ 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: |
- TimingCanvas* timing_canvas_; |
- base::TimeTicks start_ticks_; |
+ char separator_; |
+ std::ostringstream oss_; |
}; |
-class TimingCanvas : public SkNWayCanvas { |
-public: |
- TimingCanvas(int width, int height, const BenchmarkingCanvas* track_canvas) |
- : SkNWayCanvas(width, height) |
- , tracking_canvas_(track_canvas) { |
- surface_ = skia::AdoptRef(SkSurface::NewRasterN32Premul(width, height)); |
+WARN_UNUSED_RESULT |
+scoped_ptr<base::Value> AsValue(bool b) { |
+ scoped_ptr<base::FundamentalValue> val(new base::FundamentalValue(b)); |
- addCanvas(surface_->getCanvas()); |
- } |
+ return val.Pass(); |
+} |
- ~TimingCanvas() override {} |
+WARN_UNUSED_RESULT |
+scoped_ptr<base::Value> AsValue(SkScalar scalar) { |
+ scoped_ptr<base::FundamentalValue> val(new base::FundamentalValue(scalar)); |
- double GetTime(size_t index) { |
- TimingsMap::const_iterator timing_info = timings_map_.find(index); |
- return timing_info != timings_map_.end() |
- ? timing_info->second.InMillisecondsF() |
- : 0.0; |
- } |
+ return val.Pass(); |
+} |
- // SkCanvas overrides. |
- void willSave() override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::willSave(); |
- } |
+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())); |
- SaveLayerStrategy willSaveLayer(const SkRect* bounds, |
- const SkPaint* paint, |
- SaveFlags flags) override { |
- AutoStamper stamper(this); |
- return SkNWayCanvas::willSaveLayer(bounds, paint, flags); |
- } |
+ return val.Pass(); |
+} |
- void willRestore() override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::willRestore(); |
- } |
+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())); |
- void onDrawPaint(const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawPaint(paint); |
- } |
+ return val.Pass(); |
+} |
- void onDrawPoints(PointMode mode, |
- size_t count, |
- const SkPoint pts[], |
- const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawPoints(mode, count, pts, paint); |
- } |
+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)); |
- void onDrawOval(const SkRect& rect, const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawOval(rect, paint); |
- } |
+ return val.Pass(); |
+} |
- void onDrawRect(const SkRect& rect, const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawRect(rect, paint); |
- } |
+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))); |
- void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawRRect(rrect, paint); |
- } |
+ scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
+ val->Set("rect", AsValue(rrect.rect())); |
+ val->Set("radii", radii_val.Pass()); |
- void onDrawPath(const SkPath& path, const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawPath(path, paint); |
- } |
+ return val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+WARN_UNUSED_RESULT |
+scoped_ptr<base::Value> AsValue(SkXfermode::Mode mode) { |
+ scoped_ptr<base::StringValue> val( |
+ new base::StringValue(SkXfermode::ModeName(mode))); |
+ |
+ return val.Pass(); |
+} |
+ |
+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)); |
- void onDrawBitmap(const SkBitmap& bitmap, |
- SkScalar left, |
- SkScalar top, |
- const SkPaint* paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawBitmap(bitmap, left, top, paint); |
+ scoped_ptr<base::StringValue> val(new base::StringValue(gModeStrings[mode])); |
+ |
+ return val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+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"); |
+ builder.addFlag(flags & SkColorFilter::kHasFilter16_Flag, |
+ "kHasFilter16_Flag"); |
+ |
+ val->SetString("flags", builder.str()); |
} |
- void onDrawBitmapRect(const SkBitmap& bitmap, |
- const SkRect* src, |
- const SkRect& dst, |
- const SkPaint* paint, |
- DrawBitmapRectFlags flags) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawBitmapRect(bitmap, src, dst, paint, flags); |
+ 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", color_matrix_val.Pass()); |
} |
- void onDrawSprite(const SkBitmap& bitmap, |
- int left, |
- int top, |
- const SkPaint* paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawSprite(bitmap, left, top, paint); |
+ 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", color_mode_val.Pass()); |
} |
- void onDrawVertices(VertexMode vmode, |
- int vertexCount, |
- const SkPoint vertices[], |
- const SkPoint texs[], |
- const SkColor colors[], |
- SkXfermode* xmode, |
- const uint16_t indices[], |
- int indexCount, |
- const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawVertices(vmode, vertexCount, vertices, texs, colors, |
- xmode, indices, indexCount, paint); |
+ 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", component_table_val.Pass()); |
} |
-protected: |
- void onDrawText(const void* text, |
- size_t byteLength, |
- SkScalar x, |
- SkScalar y, |
- const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawText(text, byteLength, x, y, paint); |
+ return val.Pass(); |
+} |
+ |
+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 |
} |
- void onDrawPosText(const void* text, |
- size_t byteLength, |
- const SkPoint pos[], |
- const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawPosText(text, byteLength, pos, paint); |
+ return val.Pass(); |
+} |
+ |
+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()]); |
} |
- void onDrawPosTextH(const void* text, |
- size_t byteLength, |
- const SkScalar xpos[], |
- SkScalar constY, |
- const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawPosTextH(text, byteLength, xpos, constY, paint); |
+ if (paint.getXfermode() != default_paint.getXfermode()) { |
+ DCHECK(paint.getXfermode()); |
+ val->Set("Xfermode", AsValue(*paint.getXfermode())); |
} |
- void onDrawTextOnPath(const void* text, |
- size_t byteLength, |
- const SkPath& path, |
- const SkMatrix* matrix, |
- const SkPaint& paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawTextOnPath(text, byteLength, path, matrix, paint); |
+ 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"); |
+ builder.addFlag(paint.getFlags() & SkPaint::kGenA8FromLCD_Flag, |
+ "GenA8FromLCD"); |
+ |
+ val->SetString("Flags", builder.str()); |
} |
- void onClipRect(const SkRect& rect, |
- SkRegion::Op op, |
- ClipEdgeStyle edge_style) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onClipRect(rect, op, edge_style); |
+ if (paint.getFilterLevel() != default_paint.getFilterLevel()) { |
+ static const char* gFilterLevelStrings[] = |
+ { "None", "Low", "Medium", "High" }; |
+ DCHECK_LT(static_cast<size_t>(paint.getFilterLevel()), |
+ SK_ARRAY_COUNT(gFilterLevelStrings)); |
+ val->SetString("FilterLevel", gFilterLevelStrings[paint.getFilterLevel()]); |
} |
- void onClipRRect(const SkRRect& rrect, |
- SkRegion::Op op, |
- ClipEdgeStyle edge_style) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onClipRRect(rrect, op, edge_style); |
+ 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 val.Pass(); |
+} |
+ |
+WARN_UNUSED_RESULT |
+scoped_ptr<base::Value> AsValue(SkCanvas::SaveFlags flags) { |
+ FlagsBuilder builder('|'); |
+ builder.addFlag(flags & SkCanvas::kHasAlphaLayer_SaveFlag, |
+ "kHasAlphaLayer"); |
+ builder.addFlag(flags & SkCanvas::kFullColorLayer_SaveFlag, |
+ "kFullColorLayer"); |
+ builder.addFlag(flags & SkCanvas::kClipToLayer_SaveFlag, |
+ "kClipToLayer"); |
+ |
+ scoped_ptr<base::StringValue> val(new base::StringValue(builder.str())); |
+ |
+ return val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+WARN_UNUSED_RESULT |
+scoped_ptr<base::Value> AsValue(const SkPicture& picture) { |
+ scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue()); |
+ val->Set("cull-rect", AsValue(picture.cullRect())); |
+ |
+ return val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+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 }; |
+ SK_COMPILE_ASSERT( |
+ SK_ARRAY_COUNT(gVerbStrings) == static_cast<size_t>(SkPath::kDone_Verb + 1), |
+ gVerbStrings_size_mismatch); |
+ SK_COMPILE_ASSERT( |
+ SK_ARRAY_COUNT(gVerbStrings) == SK_ARRAY_COUNT(gPtsPerVerb), |
+ gPtsPerVerb_size_mismatch); |
+ SK_COMPILE_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], pts_val.Pass()); |
+ |
+ if (SkPath::kConic_Verb == verb) |
+ verb_val->Set("weight", AsValue(iter.conicWeight())); |
+ |
+ verbs_val->Append(verb_val.release()); |
} |
+ val->Set("verbs", verbs_val.Pass()); |
+ |
+ return val.Pass(); |
+} |
+ |
+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 val.Pass(); |
+} |
+ |
+} // 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()) { |
+ |
+ DCHECK(canvas); |
+ DCHECK(op_name); |
- void onClipPath(const SkPath& path, |
- SkRegion::Op op, |
- ClipEdgeStyle edge_style) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onClipPath(path, op, edge_style); |
+ op_record_->SetString("cmd_string", op_name); |
+ op_record_->Set("info", op_params_); |
+ |
+ if (paint) |
+ this->addParam("paint", AsValue(*paint)); |
+ |
+ start_ticks_ = base::TimeTicks::Now(); |
} |
- void onClipRegion(const SkRegion& region, SkRegion::Op op) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onClipRegion(region, op); |
+ ~AutoOp() { |
+ base::TimeDelta ticks = base::TimeTicks::Now() - start_ticks_; |
+ op_record_->SetDouble("cmd_time", ticks.InMillisecondsF()); |
+ |
+ canvas_->op_records_.Append(op_record_); |
} |
- void onDrawPicture(const SkPicture* picture, |
- const SkMatrix* matrix, |
- const SkPaint* paint) override { |
- AutoStamper stamper(this); |
- SkNWayCanvas::onDrawPicture(picture, matrix, paint); |
+ void addParam(const char name[], scoped_ptr<base::Value> value) { |
+ scoped_ptr<base::DictionaryValue> param(new base::DictionaryValue()); |
+ param->Set(name, value.Pass()); |
+ |
+ op_params_->Append(param.release()); |
} |
private: |
- typedef base::hash_map<size_t, base::TimeDelta> TimingsMap; |
- TimingsMap timings_map_; |
+ BenchmarkingCanvas* canvas_; |
+ base::DictionaryValue* op_record_; |
+ base::ListValue* op_params_; |
+ base::TimeTicks start_ticks_; |
+}; |
- skia::RefPtr<SkSurface> surface_; |
+BenchmarkingCanvas::BenchmarkingCanvas(SkCanvas* canvas, unsigned flags) |
+ : INHERITED(canvas->imageInfo().width(), |
+ canvas->imageInfo().height()) |
+ , flags_(flags) { |
+ addCanvas(canvas); |
+} |
- friend class AutoStamper; |
- const BenchmarkingCanvas* tracking_canvas_; |
-}; |
+BenchmarkingCanvas::~BenchmarkingCanvas() { |
+} |
-AutoStamper::AutoStamper(TimingCanvas *timing_canvas) |
- : timing_canvas_(timing_canvas) { |
- start_ticks_ = base::TimeTicks::Now(); |
+size_t BenchmarkingCanvas::CommandCount() const { |
+ return op_records_.GetSize(); |
} |
-AutoStamper::~AutoStamper() { |
- base::TimeDelta delta = base::TimeTicks::Now() - start_ticks_; |
- int command_index = timing_canvas_->tracking_canvas_->CommandCount() - 1; |
- DCHECK_GE(command_index, 0); |
- timing_canvas_->timings_map_[command_index] = delta; |
+const base::ListValue& BenchmarkingCanvas::Commands() const { |
+ return op_records_; |
} |
-BenchmarkingCanvas::BenchmarkingCanvas(int width, int height) |
- : SkNWayCanvas(width, height) { |
- debug_canvas_ = skia::AdoptRef(SkNEW_ARGS(SkDebugCanvas, (width, height))); |
- timing_canvas_ = skia::AdoptRef(SkNEW_ARGS(TimingCanvas, (width, height, this))); |
+double BenchmarkingCanvas::GetTime(size_t index) { |
+ const base::DictionaryValue* op; |
+ if (!op_records_.GetDictionary(index, &op)) |
+ return 0; |
- addCanvas(debug_canvas_.get()); |
- addCanvas(timing_canvas_.get()); |
+ double t; |
+ if (!op->GetDouble("cmd_time", &t)) |
+ return 0; |
+ |
+ return t; |
} |
-BenchmarkingCanvas::~BenchmarkingCanvas() { |
- removeAll(); |
+void BenchmarkingCanvas::willSave() { |
+ AutoOp op(this, "Save"); |
+ |
+ INHERITED::willSave(); |
} |
-size_t BenchmarkingCanvas::CommandCount() const { |
- return debug_canvas_->getSize(); |
+SkCanvas::SaveLayerStrategy BenchmarkingCanvas::willSaveLayer(const SkRect* rect, |
+ const SkPaint* paint, |
+ SaveFlags flags) { |
+ AutoOp op(this, "SaveLayer", paint); |
+ if (rect) |
+ op.addParam("bounds", AsValue(*rect)); |
+ if (paint) |
+ op.addParam("paint", AsValue(*paint)); |
+ if (flags) |
+ op.addParam("flags", AsValue(flags)); |
+ |
+ return INHERITED::willSaveLayer(rect, paint, flags); |
} |
-SkDrawCommand* BenchmarkingCanvas::GetCommand(size_t index) { |
- DCHECK_LT(index, static_cast<size_t>(debug_canvas_->getSize())); |
- return debug_canvas_->getDrawCommandAt(index); |
+void BenchmarkingCanvas::willRestore() { |
+ AutoOp op(this, "Restore"); |
+ |
+ INHERITED::willRestore(); |
} |
-double BenchmarkingCanvas::GetTime(size_t index) { |
- DCHECK_LT(index, static_cast<size_t>(debug_canvas_->getSize())); |
- return timing_canvas_->GetTime(index); |
+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(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, paint); |
+} |
+ |
+void BenchmarkingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { |
+ AutoOp op(this, "DrawRect", &paint); |
+ op.addParam("rect", AsValue(rect)); |
+ |
+ INHERITED::onDrawRect(rect, paint); |
+} |
+ |
+void BenchmarkingCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { |
+ AutoOp op(this, "DrawOval", &paint); |
+ op.addParam("rect", AsValue(rect)); |
+ |
+ INHERITED::onDrawOval(rect, paint); |
+} |
+ |
+void BenchmarkingCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { |
+ AutoOp op(this, "DrawRRect", &paint); |
+ op.addParam("rrect", AsValue(rrect)); |
+ |
+ INHERITED::onDrawRRect(rrect, 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, paint); |
+} |
+ |
+void BenchmarkingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { |
+ AutoOp op(this, "DrawPath", &paint); |
+ op.addParam("path", AsValue(path)); |
+ |
+ INHERITED::onDrawPath(path, 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::drawPicture(picture, matrix, 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, paint); |
+} |
+ |
+void BenchmarkingCanvas::onDrawBitmapRect(const SkBitmap& bitmap, |
+ const SkRect* src, |
+ const SkRect& dst, |
+ const SkPaint* paint, |
+ DrawBitmapRectFlags flags) { |
+ 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, paint, flags); |
+} |
+ |
+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, paint); |
+} |
+ |
+void BenchmarkingCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, |
+ const SkRect& dst, const SkPaint* paint) { |
+ 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, paint); |
+} |
+ |
+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, paint); |
+} |
+ |
+void BenchmarkingCanvas::onDrawSprite(const SkBitmap& bitmap, int left, int top, |
+ const SkPaint* paint) { |
+ AutoOp op(this, "DrawSprite", paint); |
+ op.addParam("bitmap", AsValue(bitmap)); |
+ op.addParam("left", AsValue(SkIntToScalar(left))); |
+ op.addParam("top", AsValue(SkIntToScalar(top))); |
+ |
+ INHERITED::onDrawSprite(bitmap, left, top, 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, 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, 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, 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, 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, paint); |
} |
} // namespace skia |