Chromium Code Reviews| Index: content/renderer/skia_benchmarking/skia_benchmarking_canvas.cc |
| diff --git a/content/renderer/skia_benchmarking/skia_benchmarking_canvas.cc b/content/renderer/skia_benchmarking/skia_benchmarking_canvas.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ccfa257401a36ec484b2d1e4d173fba878facb71 |
| --- /dev/null |
| +++ b/content/renderer/skia_benchmarking/skia_benchmarking_canvas.cc |
| @@ -0,0 +1,245 @@ |
| +// 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 "base/containers/hash_tables.h" |
| +#include "base/logging.h" |
| +#include "base/time/time.h" |
| +#include "content/renderer/skia_benchmarking/skia_benchmarking_canvas.h" |
| +#include "third_party/skia/include/utils/SkProxyCanvas.h" |
| +#include "ui/gfx/rect.h" |
| + |
| +namespace content { |
| + |
| +class AutoStamper { |
| +public: |
| + AutoStamper(SkiaTimingCanvas* timing_canvas); |
| + ~AutoStamper(); |
| + |
| +private: |
| + SkiaTimingCanvas* timing_canvas_; |
| + base::TimeTicks start_ticks_; |
| +}; |
| + |
| +class SkiaTimingCanvas : public SkProxyCanvas { |
| +public: |
| + SkiaTimingCanvas(const gfx::Rect& rect, |
| + const content::SkiaBenchmarkingCanvas* tracking_canvas) |
| + : canvas_(bitmap_) |
| + , tracking_canvas_(tracking_canvas) { |
| + bitmap_.setConfig(SkBitmap::kARGB_8888_Config, |
| + rect.width(), rect.height()); |
| + // If pixel allocation fails, we can still continue with a null canvas |
| + // (but timing information will be inaccurate). |
|
pdr.
2013/07/18 20:57:11
Why not just bail?
f(malita)
2013/07/19 14:07:30
Bailing from the constructor is tricky. We could c
|
| + if (!bitmap_.allocPixels()) |
| + bitmap_.setConfig(SkBitmap::kNo_Config, rect.width(), rect.height()); |
| + else |
| + bitmap_.eraseARGB(0, 0, 0, 0); |
| + |
| + setProxy(&canvas_); |
| + } |
| + |
| + virtual ~SkiaTimingCanvas() { |
| + } |
| + |
| + int64 GetTime(size_t index) { |
| + TimingsMap::const_iterator timing_info = timings_map_.find(index); |
| + return timing_info != timings_map_.end() |
| + ? timing_info->second.InMicroseconds() |
| + : 0; |
| + } |
| + |
| + // SkCanvas overrides. |
| + virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) OVERRIDE { |
| + AutoStamper stamper(this); |
| + return SkProxyCanvas::save(flags); |
| + } |
| + |
| + virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, |
| + SaveFlags flags = kARGB_ClipLayer_SaveFlag) OVERRIDE { |
| + AutoStamper(this); |
| + return SkProxyCanvas::saveLayer(bounds, paint, flags); |
| + } |
| + |
| + virtual void restore() OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::restore(); |
| + } |
| + |
| + virtual bool clipRect(const SkRect& rect, SkRegion::Op op, |
| + bool doAa) OVERRIDE { |
| + AutoStamper(this); |
| + return SkProxyCanvas::clipRect(rect, op, doAa); |
| + } |
| + |
| + virtual bool clipRRect(const SkRRect& rrect, SkRegion::Op op, |
| + bool doAa) OVERRIDE { |
| + AutoStamper(this); |
| + return SkProxyCanvas::clipRRect(rrect, op, doAa); |
| + } |
| + |
| + virtual bool clipPath(const SkPath& path, SkRegion::Op op, |
| + bool doAa) OVERRIDE { |
| + AutoStamper(this); |
| + return SkProxyCanvas::clipPath(path, op, doAa); |
| + } |
| + |
| + virtual bool clipRegion(const SkRegion& region, |
| + SkRegion::Op op = SkRegion::kIntersect_Op) OVERRIDE { |
| + AutoStamper(this); |
| + return SkProxyCanvas::clipRegion(region, op); |
| + } |
| + |
| + virtual void drawPaint(const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawPaint(paint); |
| + } |
| + |
| + virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], |
| + const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawPoints(mode, count, pts, paint); |
| + } |
| + |
| + virtual void drawOval(const SkRect& rect, const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawOval(rect, paint); |
| + } |
| + |
| + virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawRect(rect, paint); |
| + } |
| + |
| + virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawRRect(rrect, paint); |
| + } |
| + |
| + virtual void drawPath(const SkPath& path, const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawPath(path, paint); |
| + } |
| + |
| + virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, |
| + const SkPaint* paint = NULL) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawBitmap(bitmap, left, top, paint); |
| + } |
| + |
| + virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, |
| + const SkRect& dst, |
| + const SkPaint* paint = NULL) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawBitmapRectToRect(bitmap, src, dst, paint); |
| + } |
| + |
| + virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, |
| + const SkPaint* paint = NULL) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawBitmapMatrix(bitmap, m, paint); |
| + } |
| + |
| + virtual void drawSprite(const SkBitmap& bitmap, int left, int top, |
| + const SkPaint* paint = NULL) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawSprite(bitmap, left, top, paint); |
| + } |
| + |
| + virtual void drawText(const void* text, size_t byteLength, SkScalar x, |
| + SkScalar y, const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawText(text, byteLength, x, y, paint); |
| + } |
| + |
| + virtual void drawPosText(const void* text, size_t byteLength, |
| + const SkPoint pos[], |
| + const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawPosText(text, byteLength, pos, paint); |
| + } |
| + |
| + virtual void drawPosTextH(const void* text, size_t byteLength, |
| + const SkScalar xpos[], SkScalar constY, |
| + const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawPosTextH(text, byteLength, xpos, constY, paint); |
| + } |
| + |
| + virtual void drawTextOnPath(const void* text, size_t byteLength, |
| + const SkPath& path, const SkMatrix* matrix, |
| + const SkPaint& paint) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawTextOnPath(text, byteLength, path, matrix, paint); |
| + } |
| + |
| + virtual void drawPicture(SkPicture& picture) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawPicture(picture); |
| + } |
| + |
| + virtual void drawVertices(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(this); |
| + SkProxyCanvas::drawVertices(vmode, vertexCount, vertices, texs, colors, |
| + xmode, indices, indexCount, paint); |
| + } |
| + |
| + virtual void drawData(const void* data, size_t length) OVERRIDE { |
| + AutoStamper(this); |
| + SkProxyCanvas::drawData(data, length); |
| + } |
| + |
| +private: |
| + typedef base::hash_map<size_t, base::TimeDelta> TimingsMap; |
| + TimingsMap timings_map_; |
| + |
| + SkBitmap bitmap_; |
| + SkCanvas canvas_; |
| + |
| + friend class AutoStamper; |
| + const content::SkiaBenchmarkingCanvas* tracking_canvas_; |
| +}; |
| + |
| +AutoStamper::AutoStamper(SkiaTimingCanvas *timing_canvas) |
| + : timing_canvas_(timing_canvas) { |
| + start_ticks_ = base::TimeTicks::HighResNow(); |
| +} |
| + |
| +AutoStamper::~AutoStamper() { |
| + base::TimeDelta delta = base::TimeTicks::HighResNow() - start_ticks_; |
| + int command_index = timing_canvas_->tracking_canvas_->CommandCount(); |
| + timing_canvas_->timings_map_[command_index] = delta; |
| +} |
| + |
| +SkiaBenchmarkingCanvas::SkiaBenchmarkingCanvas(const gfx::Rect& rect) |
| + : SkNWayCanvas(rect.width(), rect.height()) |
| + , debug_canvas_(SkNEW_ARGS(SkDebugCanvas, (rect.width(), rect.height()))) |
| + , timing_canvas_(SkNEW_ARGS(SkiaTimingCanvas, (rect, this))) { |
| + addCanvas(debug_canvas_.get()); |
| + addCanvas(timing_canvas_.get()); |
| +} |
| + |
| +SkiaBenchmarkingCanvas::~SkiaBenchmarkingCanvas() { |
| + removeAll(); |
| +} |
| + |
| +size_t SkiaBenchmarkingCanvas::CommandCount() const { |
| + return debug_canvas_->getSize(); |
| +} |
| + |
| +SkDrawCommand* SkiaBenchmarkingCanvas::GetCommand(size_t index) { |
| + DCHECK_LT(index, static_cast<size_t>(debug_canvas_->getSize())); |
| + return debug_canvas_->getDrawCommandAt(index); |
| +} |
| + |
| +int64 SkiaBenchmarkingCanvas::GetTime(size_t index) { |
| + DCHECK_LT(index, static_cast<size_t>(debug_canvas_->getSize())); |
|
pdr.
2013/07/18 20:57:11
extra space
|
| + return timing_canvas_->GetTime(index); |
| +} |
| + |
| +} // namespace content |
| + |