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.
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"
15 AutoStamper(TimingCanvas
* timing_canvas
);
19 TimingCanvas
* timing_canvas_
;
20 base::TimeTicks start_ticks_
;
23 class TimingCanvas
: public SkProxyCanvas
{
25 TimingCanvas(int width
, int height
, const BenchmarkingCanvas
* track_canvas
)
26 : tracking_canvas_(track_canvas
) {
27 canvas_
= skia::AdoptRef(SkCanvas::NewRasterN32(width
, height
));
29 setProxy(canvas_
.get());
32 virtual ~TimingCanvas() {
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()
42 // SkCanvas overrides.
43 virtual void willSave() OVERRIDE
{
44 AutoStamper
stamper(this);
45 SkProxyCanvas::willSave();
48 virtual SaveLayerStrategy
willSaveLayer(const SkRect
* bounds
,
50 SaveFlags flags
) OVERRIDE
{
51 AutoStamper
stamper(this);
52 return SkProxyCanvas::willSaveLayer(bounds
, paint
, flags
);
55 virtual void willRestore() OVERRIDE
{
56 AutoStamper
stamper(this);
57 SkProxyCanvas::willRestore();
60 virtual void drawPaint(const SkPaint
& paint
) OVERRIDE
{
61 AutoStamper
stamper(this);
62 SkProxyCanvas::drawPaint(paint
);
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
);
71 virtual void drawOval(const SkRect
& rect
, const SkPaint
& paint
) OVERRIDE
{
72 AutoStamper
stamper(this);
73 SkProxyCanvas::drawOval(rect
, paint
);
76 virtual void drawRect(const SkRect
& rect
, const SkPaint
& paint
) OVERRIDE
{
77 AutoStamper
stamper(this);
78 SkProxyCanvas::drawRect(rect
, paint
);
81 virtual void drawRRect(const SkRRect
& rrect
, const SkPaint
& paint
) OVERRIDE
{
82 AutoStamper
stamper(this);
83 SkProxyCanvas::drawRRect(rrect
, paint
);
86 virtual void drawPath(const SkPath
& path
, const SkPaint
& paint
) OVERRIDE
{
87 AutoStamper
stamper(this);
88 SkProxyCanvas::drawPath(path
, paint
);
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
);
97 virtual void drawBitmapRectToRect(const SkBitmap
& bitmap
, const SkRect
* src
,
100 DrawBitmapRectFlags flags
) OVERRIDE
{
101 AutoStamper
stamper(this);
102 SkProxyCanvas::drawBitmapRectToRect(bitmap
, src
, dst
, paint
, flags
);
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
);
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
);
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
);
127 virtual void drawData(const void* data
, size_t length
) OVERRIDE
{
128 AutoStamper
stamper(this);
129 SkProxyCanvas::drawData(data
, length
);
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
);
139 virtual void onDrawPosText(const void* text
, size_t byteLength
,
141 const SkPaint
& paint
) OVERRIDE
{
142 AutoStamper
stamper(this);
143 SkProxyCanvas::onDrawPosText(text
, byteLength
, pos
, paint
);
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
);
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
);
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
);
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
);
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
);
178 virtual void onClipRegion(const SkRegion
& region
,
179 SkRegion::Op op
) OVERRIDE
{
180 AutoStamper
stamper(this);
181 SkProxyCanvas::onClipRegion(region
, op
);
184 virtual void onDrawPicture(const SkPicture
* picture
, const SkMatrix
* matrix
,
185 const SkPaint
* paint
) OVERRIDE
{
186 AutoStamper
stamper(this);
187 SkProxyCanvas::onDrawPicture(picture
, matrix
, paint
);
191 typedef base::hash_map
<size_t, base::TimeDelta
> TimingsMap
;
192 TimingsMap timings_map_
;
194 skia::RefPtr
<SkCanvas
> canvas_
;
196 friend class AutoStamper
;
197 const BenchmarkingCanvas
* tracking_canvas_
;
200 AutoStamper::AutoStamper(TimingCanvas
*timing_canvas
)
201 : timing_canvas_(timing_canvas
) {
202 start_ticks_
= base::TimeTicks::HighResNow();
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
;
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)));
217 addCanvas(debug_canvas_
.get());
218 addCanvas(timing_canvas_
.get());
221 BenchmarkingCanvas::~BenchmarkingCanvas() {
225 size_t BenchmarkingCanvas::CommandCount() const {
226 return debug_canvas_
->getSize();
229 SkDrawCommand
* BenchmarkingCanvas::GetCommand(size_t index
) {
230 DCHECK_LT(index
, static_cast<size_t>(debug_canvas_
->getSize()));
231 return debug_canvas_
->getDrawCommandAt(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
);