Home | History | Annotate | Download | only in ext
      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.
      4 
      5 #include "base/containers/hash_tables.h"
      6 #include "base/logging.h"
      7 #include "base/time/time.h"
      8 #include "skia/ext/benchmarking_canvas.h"
      9 #include "third_party/skia/include/core/SkDevice.h"
     10 #include "third_party/skia/include/utils/SkProxyCanvas.h"
     11 
     12 namespace skia {
     13 
     14 class AutoStamper {
     15 public:
     16   AutoStamper(TimingCanvas* timing_canvas);
     17   ~AutoStamper();
     18 
     19 private:
     20   TimingCanvas* timing_canvas_;
     21   base::TimeTicks start_ticks_;
     22 };
     23 
     24 class TimingCanvas : public SkProxyCanvas {
     25 public:
     26   TimingCanvas(int width, int height, const BenchmarkingCanvas* track_canvas)
     27       : tracking_canvas_(track_canvas) {
     28     skia::RefPtr<SkDevice> device = skia::AdoptRef(
     29         SkNEW_ARGS(SkDevice, (SkBitmap::kARGB_8888_Config, width, height)));
     30     canvas_ = skia::AdoptRef(SkNEW_ARGS(SkCanvas, (device.get())));
     31 
     32     setProxy(canvas_.get());
     33   }
     34 
     35   virtual ~TimingCanvas() {
     36   }
     37 
     38   double GetTime(size_t index) {
     39     TimingsMap::const_iterator timing_info = timings_map_.find(index);
     40     return timing_info != timings_map_.end()
     41         ? timing_info->second.InMillisecondsF()
     42         : 0.0;
     43   }
     44 
     45   // SkCanvas overrides.
     46   virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) OVERRIDE {
     47     AutoStamper stamper(this);
     48     return SkProxyCanvas::save(flags);
     49   }
     50 
     51   virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
     52                         SaveFlags flags = kARGB_ClipLayer_SaveFlag) OVERRIDE {
     53     AutoStamper stamper(this);
     54     return SkProxyCanvas::saveLayer(bounds, paint, flags);
     55   }
     56 
     57   virtual void restore() OVERRIDE {
     58     AutoStamper stamper(this);
     59     SkProxyCanvas::restore();
     60   }
     61 
     62   virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
     63                         bool doAa) OVERRIDE {
     64     AutoStamper stamper(this);
     65     return SkProxyCanvas::clipRect(rect, op, doAa);
     66   }
     67 
     68   virtual bool clipRRect(const SkRRect& rrect, SkRegion::Op op,
     69                          bool doAa) OVERRIDE {
     70     AutoStamper stamper(this);
     71     return SkProxyCanvas::clipRRect(rrect, op, doAa);
     72   }
     73 
     74   virtual bool clipPath(const SkPath& path, SkRegion::Op op,
     75                         bool doAa) OVERRIDE {
     76     AutoStamper stamper(this);
     77     return SkProxyCanvas::clipPath(path, op, doAa);
     78   }
     79 
     80   virtual bool clipRegion(const SkRegion& region,
     81                           SkRegion::Op op = SkRegion::kIntersect_Op) OVERRIDE {
     82     AutoStamper stamper(this);
     83     return SkProxyCanvas::clipRegion(region, op);
     84   }
     85 
     86   virtual void drawPaint(const SkPaint& paint) OVERRIDE {
     87     AutoStamper stamper(this);
     88     SkProxyCanvas::drawPaint(paint);
     89   }
     90 
     91   virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
     92                           const SkPaint& paint) OVERRIDE {
     93     AutoStamper stamper(this);
     94     SkProxyCanvas::drawPoints(mode, count, pts, paint);
     95   }
     96 
     97   virtual void drawOval(const SkRect& rect, const SkPaint& paint) OVERRIDE {
     98     AutoStamper stamper(this);
     99     SkProxyCanvas::drawOval(rect, paint);
    100   }
    101 
    102   virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE {
    103     AutoStamper stamper(this);
    104     SkProxyCanvas::drawRect(rect, paint);
    105   }
    106 
    107   virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint) OVERRIDE {
    108     AutoStamper stamper(this);
    109     SkProxyCanvas::drawRRect(rrect, paint);
    110   }
    111 
    112   virtual void drawPath(const SkPath& path, const SkPaint& paint) OVERRIDE {
    113     AutoStamper stamper(this);
    114     SkProxyCanvas::drawPath(path, paint);
    115   }
    116 
    117   virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
    118                           const SkPaint* paint = NULL) OVERRIDE {
    119     AutoStamper stamper(this);
    120     SkProxyCanvas::drawBitmap(bitmap, left, top, paint);
    121   }
    122 
    123   virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
    124                                     const SkRect& dst,
    125                                     const SkPaint* paint = NULL) OVERRIDE {
    126     AutoStamper stamper(this);
    127     SkProxyCanvas::drawBitmapRectToRect(bitmap, src, dst, paint);
    128   }
    129 
    130   virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
    131                                 const SkPaint* paint = NULL) OVERRIDE {
    132     AutoStamper stamper(this);
    133     SkProxyCanvas::drawBitmapMatrix(bitmap, m, paint);
    134   }
    135 
    136   virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
    137                           const SkPaint* paint = NULL) OVERRIDE {
    138     AutoStamper stamper(this);
    139     SkProxyCanvas::drawSprite(bitmap, left, top, paint);
    140   }
    141 
    142   virtual void drawText(const void* text, size_t byteLength, SkScalar x,
    143                         SkScalar y, const SkPaint& paint) OVERRIDE {
    144     AutoStamper stamper(this);
    145     SkProxyCanvas::drawText(text, byteLength, x, y, paint);
    146   }
    147 
    148   virtual void drawPosText(const void* text, size_t byteLength,
    149                            const SkPoint pos[],
    150                            const SkPaint& paint) OVERRIDE {
    151     AutoStamper stamper(this);
    152     SkProxyCanvas::drawPosText(text, byteLength, pos, paint);
    153   }
    154 
    155   virtual void drawPosTextH(const void* text, size_t byteLength,
    156                             const SkScalar xpos[], SkScalar constY,
    157                             const SkPaint& paint) OVERRIDE {
    158     AutoStamper stamper(this);
    159     SkProxyCanvas::drawPosTextH(text, byteLength, xpos, constY, paint);
    160   }
    161 
    162   virtual void drawTextOnPath(const void* text, size_t byteLength,
    163                               const SkPath& path, const SkMatrix* matrix,
    164                               const SkPaint& paint) OVERRIDE {
    165     AutoStamper stamper(this);
    166     SkProxyCanvas::drawTextOnPath(text, byteLength, path, matrix, paint);
    167   }
    168 
    169   virtual void drawPicture(SkPicture& picture) OVERRIDE {
    170     AutoStamper stamper(this);
    171     SkProxyCanvas::drawPicture(picture);
    172   }
    173 
    174   virtual void drawVertices(VertexMode vmode, int vertexCount,
    175                             const SkPoint vertices[], const SkPoint texs[],
    176                             const SkColor colors[], SkXfermode* xmode,
    177                             const uint16_t indices[], int indexCount,
    178                             const SkPaint& paint) OVERRIDE {
    179     AutoStamper stamper(this);
    180     SkProxyCanvas::drawVertices(vmode, vertexCount, vertices, texs, colors,
    181                                 xmode, indices, indexCount, paint);
    182   }
    183 
    184   virtual void drawData(const void* data, size_t length) OVERRIDE {
    185     AutoStamper stamper(this);
    186     SkProxyCanvas::drawData(data, length);
    187   }
    188 
    189 private:
    190   typedef base::hash_map<size_t, base::TimeDelta> TimingsMap;
    191   TimingsMap timings_map_;
    192 
    193   skia::RefPtr<SkCanvas> canvas_;
    194 
    195   friend class AutoStamper;
    196   const BenchmarkingCanvas* tracking_canvas_;
    197 };
    198 
    199 AutoStamper::AutoStamper(TimingCanvas *timing_canvas)
    200     : timing_canvas_(timing_canvas) {
    201   start_ticks_ = base::TimeTicks::HighResNow();
    202 }
    203 
    204 AutoStamper::~AutoStamper() {
    205   base::TimeDelta delta = base::TimeTicks::HighResNow() - start_ticks_;
    206   int command_index = timing_canvas_->tracking_canvas_->CommandCount() - 1;
    207   DCHECK_GE(command_index, 0);
    208   timing_canvas_->timings_map_[command_index] = delta;
    209 }
    210 
    211 BenchmarkingCanvas::BenchmarkingCanvas(int width, int height)
    212     : SkNWayCanvas(width, height) {
    213   debug_canvas_ = skia::AdoptRef(SkNEW_ARGS(SkDebugCanvas, (width, height)));
    214   timing_canvas_ = skia::AdoptRef(SkNEW_ARGS(TimingCanvas, (width, height, this)));
    215 
    216   addCanvas(debug_canvas_.get());
    217   addCanvas(timing_canvas_.get());
    218 }
    219 
    220 BenchmarkingCanvas::~BenchmarkingCanvas() {
    221   removeAll();
    222 }
    223 
    224 size_t BenchmarkingCanvas::CommandCount() const {
    225   return debug_canvas_->getSize();
    226 }
    227 
    228 SkDrawCommand* BenchmarkingCanvas::GetCommand(size_t index) {
    229   DCHECK_LT(index, static_cast<size_t>(debug_canvas_->getSize()));
    230   return debug_canvas_->getDrawCommandAt(index);
    231 }
    232 
    233 double BenchmarkingCanvas::GetTime(size_t index) {
    234   DCHECK_LT(index,  static_cast<size_t>(debug_canvas_->getSize()));
    235   return timing_canvas_->GetTime(index);
    236 }
    237 
    238 } // namespace skia
    239