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/utils/SkProxyCanvas.h"
     10 
     11 namespace skia {
     12 
     13 class AutoStamper {
     14 public:
     15   AutoStamper(TimingCanvas* timing_canvas);
     16   ~AutoStamper();
     17 
     18 private:
     19   TimingCanvas* timing_canvas_;
     20   base::TimeTicks start_ticks_;
     21 };
     22 
     23 class TimingCanvas : public SkProxyCanvas {
     24 public:
     25   TimingCanvas(int width, int height, const BenchmarkingCanvas* track_canvas)
     26       : tracking_canvas_(track_canvas) {
     27     canvas_ = skia::AdoptRef(SkCanvas::NewRasterN32(width, height));
     28 
     29     setProxy(canvas_.get());
     30   }
     31 
     32   virtual ~TimingCanvas() {
     33   }
     34 
     35   double GetTime(size_t index) {
     36     TimingsMap::const_iterator timing_info = timings_map_.find(index);
     37     return timing_info != timings_map_.end()
     38         ? timing_info->second.InMillisecondsF()
     39         : 0.0;
     40   }
     41 
     42   // SkCanvas overrides.
     43   virtual void willSave() OVERRIDE {
     44     AutoStamper stamper(this);
     45     SkProxyCanvas::willSave();
     46   }
     47 
     48   virtual SaveLayerStrategy willSaveLayer(const SkRect* bounds,
     49                                           const SkPaint* paint,
     50                                           SaveFlags flags) OVERRIDE {
     51     AutoStamper stamper(this);
     52     return SkProxyCanvas::willSaveLayer(bounds, paint, flags);
     53   }
     54 
     55   virtual void willRestore() OVERRIDE {
     56     AutoStamper stamper(this);
     57     SkProxyCanvas::willRestore();
     58   }
     59 
     60   virtual void drawPaint(const SkPaint& paint) OVERRIDE {
     61     AutoStamper stamper(this);
     62     SkProxyCanvas::drawPaint(paint);
     63   }
     64 
     65   virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
     66                           const SkPaint& paint) OVERRIDE {
     67     AutoStamper stamper(this);
     68     SkProxyCanvas::drawPoints(mode, count, pts, paint);
     69   }
     70 
     71   virtual void drawOval(const SkRect& rect, const SkPaint& paint) OVERRIDE {
     72     AutoStamper stamper(this);
     73     SkProxyCanvas::drawOval(rect, paint);
     74   }
     75 
     76   virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE {
     77     AutoStamper stamper(this);
     78     SkProxyCanvas::drawRect(rect, paint);
     79   }
     80 
     81   virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint) OVERRIDE {
     82     AutoStamper stamper(this);
     83     SkProxyCanvas::drawRRect(rrect, paint);
     84   }
     85 
     86   virtual void drawPath(const SkPath& path, const SkPaint& paint) OVERRIDE {
     87     AutoStamper stamper(this);
     88     SkProxyCanvas::drawPath(path, paint);
     89   }
     90 
     91   virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
     92                           const SkPaint* paint = NULL) OVERRIDE {
     93     AutoStamper stamper(this);
     94     SkProxyCanvas::drawBitmap(bitmap, left, top, paint);
     95   }
     96 
     97   virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
     98                                     const SkRect& dst,
     99                                     const SkPaint* paint,
    100                                     DrawBitmapRectFlags flags) OVERRIDE {
    101     AutoStamper stamper(this);
    102     SkProxyCanvas::drawBitmapRectToRect(bitmap, src, dst, paint, flags);
    103   }
    104 
    105   virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
    106                                 const SkPaint* paint = NULL) OVERRIDE {
    107     AutoStamper stamper(this);
    108     SkProxyCanvas::drawBitmapMatrix(bitmap, m, paint);
    109   }
    110 
    111   virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
    112                           const SkPaint* paint = NULL) OVERRIDE {
    113     AutoStamper stamper(this);
    114     SkProxyCanvas::drawSprite(bitmap, left, top, paint);
    115   }
    116 
    117   virtual void drawVertices(VertexMode vmode, int vertexCount,
    118                             const SkPoint vertices[], const SkPoint texs[],
    119                             const SkColor colors[], SkXfermode* xmode,
    120                             const uint16_t indices[], int indexCount,
    121                             const SkPaint& paint) OVERRIDE {
    122     AutoStamper stamper(this);
    123     SkProxyCanvas::drawVertices(vmode, vertexCount, vertices, texs, colors,
    124                                 xmode, indices, indexCount, paint);
    125   }
    126 
    127   virtual void drawData(const void* data, size_t length) OVERRIDE {
    128     AutoStamper stamper(this);
    129     SkProxyCanvas::drawData(data, length);
    130   }
    131 
    132 protected:
    133   virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
    134                           SkScalar y, const SkPaint& paint) OVERRIDE {
    135     AutoStamper stamper(this);
    136     SkProxyCanvas::onDrawText(text, byteLength, x, y, paint);
    137   }
    138 
    139   virtual void onDrawPosText(const void* text, size_t byteLength,
    140                              const SkPoint pos[],
    141                              const SkPaint& paint) OVERRIDE {
    142     AutoStamper stamper(this);
    143     SkProxyCanvas::onDrawPosText(text, byteLength, pos, paint);
    144   }
    145 
    146   virtual void onDrawPosTextH(const void* text, size_t byteLength,
    147                               const SkScalar xpos[], SkScalar constY,
    148                               const SkPaint& paint) OVERRIDE {
    149     AutoStamper stamper(this);
    150     SkProxyCanvas::onDrawPosTextH(text, byteLength, xpos, constY, paint);
    151   }
    152 
    153   virtual void onDrawTextOnPath(const void* text, size_t byteLength,
    154                                 const SkPath& path, const SkMatrix* matrix,
    155                                 const SkPaint& paint) OVERRIDE {
    156     AutoStamper stamper(this);
    157     SkProxyCanvas::onDrawTextOnPath(text, byteLength, path, matrix, paint);
    158   }
    159 
    160   virtual void onClipRect(const SkRect& rect, SkRegion::Op op,
    161                           ClipEdgeStyle edge_style) OVERRIDE {
    162     AutoStamper stamper(this);
    163     SkProxyCanvas::onClipRect(rect, op, edge_style);
    164   }
    165 
    166   virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op,
    167                           ClipEdgeStyle edge_style) OVERRIDE {
    168     AutoStamper stamper(this);
    169     SkProxyCanvas::onClipRRect(rrect, op, edge_style);
    170   }
    171 
    172   virtual void onClipPath(const SkPath& path, SkRegion::Op op,
    173                           ClipEdgeStyle edge_style) OVERRIDE {
    174     AutoStamper stamper(this);
    175     SkProxyCanvas::onClipPath(path, op, edge_style);
    176   }
    177 
    178   virtual void onClipRegion(const SkRegion& region,
    179                             SkRegion::Op op) OVERRIDE {
    180     AutoStamper stamper(this);
    181     SkProxyCanvas::onClipRegion(region, op);
    182   }
    183 
    184   virtual void onDrawPicture(const SkPicture* picture) OVERRIDE {
    185     AutoStamper stamper(this);
    186     SkProxyCanvas::onDrawPicture(picture);
    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