• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TimingCanvas(int width,int height,const BenchmarkingCanvas * track_canvas)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 
~TimingCanvas()35   virtual ~TimingCanvas() {
36   }
37 
GetTime(size_t index)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.
save(SaveFlags flags=kMatrixClip_SaveFlag)46   virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) OVERRIDE {
47     AutoStamper stamper(this);
48     return SkProxyCanvas::save(flags);
49   }
50 
saveLayer(const SkRect * bounds,const SkPaint * paint,SaveFlags flags=kARGB_ClipLayer_SaveFlag)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 
restore()57   virtual void restore() OVERRIDE {
58     AutoStamper stamper(this);
59     SkProxyCanvas::restore();
60   }
61 
clipRect(const SkRect & rect,SkRegion::Op op,bool doAa)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 
clipRRect(const SkRRect & rrect,SkRegion::Op op,bool doAa)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 
clipPath(const SkPath & path,SkRegion::Op op,bool doAa)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 
clipRegion(const SkRegion & region,SkRegion::Op op=SkRegion::kIntersect_Op)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 
drawPaint(const SkPaint & paint)86   virtual void drawPaint(const SkPaint& paint) OVERRIDE {
87     AutoStamper stamper(this);
88     SkProxyCanvas::drawPaint(paint);
89   }
90 
drawPoints(PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)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 
drawOval(const SkRect & rect,const SkPaint & paint)97   virtual void drawOval(const SkRect& rect, const SkPaint& paint) OVERRIDE {
98     AutoStamper stamper(this);
99     SkProxyCanvas::drawOval(rect, paint);
100   }
101 
drawRect(const SkRect & rect,const SkPaint & paint)102   virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE {
103     AutoStamper stamper(this);
104     SkProxyCanvas::drawRect(rect, paint);
105   }
106 
drawRRect(const SkRRect & rrect,const SkPaint & paint)107   virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint) OVERRIDE {
108     AutoStamper stamper(this);
109     SkProxyCanvas::drawRRect(rrect, paint);
110   }
111 
drawPath(const SkPath & path,const SkPaint & paint)112   virtual void drawPath(const SkPath& path, const SkPaint& paint) OVERRIDE {
113     AutoStamper stamper(this);
114     SkProxyCanvas::drawPath(path, paint);
115   }
116 
drawBitmap(const SkBitmap & bitmap,SkScalar left,SkScalar top,const SkPaint * paint=NULL)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 
drawBitmapRectToRect(const SkBitmap & bitmap,const SkRect * src,const SkRect & dst,const SkPaint * paint,DrawBitmapRectFlags flags)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 
drawBitmapMatrix(const SkBitmap & bitmap,const SkMatrix & m,const SkPaint * paint=NULL)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 
drawSprite(const SkBitmap & bitmap,int left,int top,const SkPaint * paint=NULL)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 
drawText(const void * text,size_t byteLength,SkScalar x,SkScalar y,const SkPaint & paint)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 
drawPosText(const void * text,size_t byteLength,const SkPoint pos[],const SkPaint & paint)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 
drawPosTextH(const void * text,size_t byteLength,const SkScalar xpos[],SkScalar constY,const SkPaint & paint)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 
drawTextOnPath(const void * text,size_t byteLength,const SkPath & path,const SkMatrix * matrix,const SkPaint & paint)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 
drawPicture(SkPicture & picture)170   virtual void drawPicture(SkPicture& picture) OVERRIDE {
171     AutoStamper stamper(this);
172     SkProxyCanvas::drawPicture(picture);
173   }
174 
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)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 
drawData(const void * data,size_t length)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 
AutoStamper(TimingCanvas * timing_canvas)200 AutoStamper::AutoStamper(TimingCanvas *timing_canvas)
201     : timing_canvas_(timing_canvas) {
202   start_ticks_ = base::TimeTicks::HighResNow();
203 }
204 
~AutoStamper()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 
BenchmarkingCanvas(int width,int height)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 
~BenchmarkingCanvas()221 BenchmarkingCanvas::~BenchmarkingCanvas() {
222   removeAll();
223 }
224 
CommandCount() const225 size_t BenchmarkingCanvas::CommandCount() const {
226   return debug_canvas_->getSize();
227 }
228 
GetCommand(size_t index)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 
GetTime(size_t index)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