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/SkBitmapDevice.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<SkBaseDevice> device = skia::AdoptRef(
     29         SkNEW_ARGS(SkBitmapDevice, (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,
    126                                     DrawBitmapRectFlags flags) OVERRIDE {
    127     AutoStamper stamper(this);
    128     SkProxyCanvas::drawBitmapRectToRect(bitmap, src, dst, paint, flags);
    129   }
    130 
    131   virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
    132                                 const SkPaint* paint = NULL) OVERRIDE {
    133     AutoStamper stamper(this);
    134     SkProxyCanvas::drawBitmapMatrix(bitmap, m, paint);
    135   }
    136 
    137   virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
    138                           const SkPaint* paint = NULL) OVERRIDE {
    139     AutoStamper stamper(this);
    140     SkProxyCanvas::drawSprite(bitmap, left, top, paint);
    141   }
    142 
    143   virtual void drawText(const void* text, size_t byteLength, SkScalar x,
    144                         SkScalar y, const SkPaint& paint) OVERRIDE {
    145     AutoStamper stamper(this);
    146     SkProxyCanvas::drawText(text, byteLength, x, y, paint);
    147   }
    148 
    149   virtual void drawPosText(const void* text, size_t byteLength,
    150                            const SkPoint pos[],
    151                            const SkPaint& paint) OVERRIDE {
    152     AutoStamper stamper(this);
    153     SkProxyCanvas::drawPosText(text, byteLength, pos, paint);
    154   }
    155 
    156   virtual void drawPosTextH(const void* text, size_t byteLength,
    157                             const SkScalar xpos[], SkScalar constY,
    158                             const SkPaint& paint) OVERRIDE {
    159     AutoStamper stamper(this);
    160     SkProxyCanvas::drawPosTextH(text, byteLength, xpos, constY, paint);
    161   }
    162 
    163   virtual void drawTextOnPath(const void* text, size_t byteLength,
    164                               const SkPath& path, const SkMatrix* matrix,
    165                               const SkPaint& paint) OVERRIDE {
    166     AutoStamper stamper(this);
    167     SkProxyCanvas::drawTextOnPath(text, byteLength, path, matrix, paint);
    168   }
    169 
    170   virtual void drawPicture(SkPicture& picture) OVERRIDE {
    171     AutoStamper stamper(this);
    172     SkProxyCanvas::drawPicture(picture);
    173   }
    174 
    175   virtual void drawVertices(VertexMode vmode, int vertexCount,
    176                             const SkPoint vertices[], const SkPoint texs[],
    177                             const SkColor colors[], SkXfermode* xmode,
    178                             const uint16_t indices[], int indexCount,
    179                             const SkPaint& paint) OVERRIDE {
    180     AutoStamper stamper(this);
    181     SkProxyCanvas::drawVertices(vmode, vertexCount, vertices, texs, colors,
    182                                 xmode, indices, indexCount, paint);
    183   }
    184 
    185   virtual void drawData(const void* data, size_t length) OVERRIDE {
    186     AutoStamper stamper(this);
    187     SkProxyCanvas::drawData(data, length);
    188   }
    189 
    190 private:
    191   typedef base::hash_map<size_t, base::TimeDelta> TimingsMap;
    192   TimingsMap timings_map_;
    193 
    194   skia::RefPtr<SkCanvas> canvas_;
    195 
    196   friend class AutoStamper;
    197   const BenchmarkingCanvas* tracking_canvas_;
    198 };
    199 
    200 AutoStamper::AutoStamper(TimingCanvas *timing_canvas)
    201     : timing_canvas_(timing_canvas) {
    202   start_ticks_ = base::TimeTicks::HighResNow();
    203 }
    204 
    205 AutoStamper::~AutoStamper() {
    206   base::TimeDelta delta = base::TimeTicks::HighResNow() - start_ticks_;
    207   int command_index = timing_canvas_->tracking_canvas_->CommandCount() - 1;
    208   DCHECK_GE(command_index, 0);
    209   timing_canvas_->timings_map_[command_index] = delta;
    210 }
    211 
    212 BenchmarkingCanvas::BenchmarkingCanvas(int width, int height)
    213     : SkNWayCanvas(width, height) {
    214   debug_canvas_ = skia::AdoptRef(SkNEW_ARGS(SkDebugCanvas, (width, height)));
    215   timing_canvas_ = skia::AdoptRef(SkNEW_ARGS(TimingCanvas, (width, height, this)));
    216 
    217   addCanvas(debug_canvas_.get());
    218   addCanvas(timing_canvas_.get());
    219 }
    220 
    221 BenchmarkingCanvas::~BenchmarkingCanvas() {
    222   removeAll();
    223 }
    224 
    225 size_t BenchmarkingCanvas::CommandCount() const {
    226   return debug_canvas_->getSize();
    227 }
    228 
    229 SkDrawCommand* BenchmarkingCanvas::GetCommand(size_t index) {
    230   DCHECK_LT(index, static_cast<size_t>(debug_canvas_->getSize()));
    231   return debug_canvas_->getDrawCommandAt(index);
    232 }
    233 
    234 double BenchmarkingCanvas::GetTime(size_t index) {
    235   DCHECK_LT(index,  static_cast<size_t>(debug_canvas_->getSize()));
    236   return timing_canvas_->GetTime(index);
    237 }
    238 
    239 } // namespace skia
    240