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 ~TimingCanvas() override
{}
34 double GetTime(size_t index
) {
35 TimingsMap::const_iterator timing_info
= timings_map_
.find(index
);
36 return timing_info
!= timings_map_
.end()
37 ? timing_info
->second
.InMillisecondsF()
41 // SkCanvas overrides.
42 void willSave() override
{
43 AutoStamper
stamper(this);
44 SkProxyCanvas::willSave();
47 SaveLayerStrategy
willSaveLayer(const SkRect
* bounds
,
49 SaveFlags flags
) override
{
50 AutoStamper
stamper(this);
51 return SkProxyCanvas::willSaveLayer(bounds
, paint
, flags
);
54 void willRestore() override
{
55 AutoStamper
stamper(this);
56 SkProxyCanvas::willRestore();
59 void drawPaint(const SkPaint
& paint
) override
{
60 AutoStamper
stamper(this);
61 SkProxyCanvas::drawPaint(paint
);
64 void drawPoints(PointMode mode
,
67 const SkPaint
& paint
) override
{
68 AutoStamper
stamper(this);
69 SkProxyCanvas::drawPoints(mode
, count
, pts
, paint
);
72 void drawOval(const SkRect
& rect
, const SkPaint
& paint
) override
{
73 AutoStamper
stamper(this);
74 SkProxyCanvas::drawOval(rect
, paint
);
77 void drawRect(const SkRect
& rect
, const SkPaint
& paint
) override
{
78 AutoStamper
stamper(this);
79 SkProxyCanvas::drawRect(rect
, paint
);
82 void drawRRect(const SkRRect
& rrect
, const SkPaint
& paint
) override
{
83 AutoStamper
stamper(this);
84 SkProxyCanvas::drawRRect(rrect
, paint
);
87 void drawPath(const SkPath
& path
, const SkPaint
& paint
) override
{
88 AutoStamper
stamper(this);
89 SkProxyCanvas::drawPath(path
, paint
);
92 void drawBitmap(const SkBitmap
& bitmap
,
95 const SkPaint
* paint
= NULL
) override
{
96 AutoStamper
stamper(this);
97 SkProxyCanvas::drawBitmap(bitmap
, left
, top
, paint
);
100 void drawBitmapRectToRect(const SkBitmap
& bitmap
,
103 const SkPaint
* paint
,
104 DrawBitmapRectFlags flags
) override
{
105 AutoStamper
stamper(this);
106 SkProxyCanvas::drawBitmapRectToRect(bitmap
, src
, dst
, paint
, flags
);
109 void drawBitmapMatrix(const SkBitmap
& bitmap
,
111 const SkPaint
* paint
= NULL
) override
{
112 AutoStamper
stamper(this);
113 SkProxyCanvas::drawBitmapMatrix(bitmap
, m
, paint
);
116 void drawSprite(const SkBitmap
& bitmap
,
119 const SkPaint
* paint
= NULL
) override
{
120 AutoStamper
stamper(this);
121 SkProxyCanvas::drawSprite(bitmap
, left
, top
, paint
);
124 void drawVertices(VertexMode vmode
,
126 const SkPoint vertices
[],
127 const SkPoint texs
[],
128 const SkColor colors
[],
130 const uint16_t indices
[],
132 const SkPaint
& paint
) override
{
133 AutoStamper
stamper(this);
134 SkProxyCanvas::drawVertices(vmode
, vertexCount
, vertices
, texs
, colors
,
135 xmode
, indices
, indexCount
, paint
);
138 void drawData(const void* data
, size_t length
) override
{
139 AutoStamper
stamper(this);
140 SkProxyCanvas::drawData(data
, length
);
144 void onDrawText(const void* text
,
148 const SkPaint
& paint
) override
{
149 AutoStamper
stamper(this);
150 SkProxyCanvas::onDrawText(text
, byteLength
, x
, y
, paint
);
153 void onDrawPosText(const void* text
,
156 const SkPaint
& paint
) override
{
157 AutoStamper
stamper(this);
158 SkProxyCanvas::onDrawPosText(text
, byteLength
, pos
, paint
);
161 void onDrawPosTextH(const void* text
,
163 const SkScalar xpos
[],
165 const SkPaint
& paint
) override
{
166 AutoStamper
stamper(this);
167 SkProxyCanvas::onDrawPosTextH(text
, byteLength
, xpos
, constY
, paint
);
170 void onDrawTextOnPath(const void* text
,
173 const SkMatrix
* matrix
,
174 const SkPaint
& paint
) override
{
175 AutoStamper
stamper(this);
176 SkProxyCanvas::onDrawTextOnPath(text
, byteLength
, path
, matrix
, paint
);
179 void onClipRect(const SkRect
& rect
,
181 ClipEdgeStyle edge_style
) override
{
182 AutoStamper
stamper(this);
183 SkProxyCanvas::onClipRect(rect
, op
, edge_style
);
186 void onClipRRect(const SkRRect
& rrect
,
188 ClipEdgeStyle edge_style
) override
{
189 AutoStamper
stamper(this);
190 SkProxyCanvas::onClipRRect(rrect
, op
, edge_style
);
193 void onClipPath(const SkPath
& path
,
195 ClipEdgeStyle edge_style
) override
{
196 AutoStamper
stamper(this);
197 SkProxyCanvas::onClipPath(path
, op
, edge_style
);
200 void onClipRegion(const SkRegion
& region
, SkRegion::Op op
) override
{
201 AutoStamper
stamper(this);
202 SkProxyCanvas::onClipRegion(region
, op
);
205 void onDrawPicture(const SkPicture
* picture
,
206 const SkMatrix
* matrix
,
207 const SkPaint
* paint
) override
{
208 AutoStamper
stamper(this);
209 SkProxyCanvas::onDrawPicture(picture
, matrix
, paint
);
213 typedef base::hash_map
<size_t, base::TimeDelta
> TimingsMap
;
214 TimingsMap timings_map_
;
216 skia::RefPtr
<SkCanvas
> canvas_
;
218 friend class AutoStamper
;
219 const BenchmarkingCanvas
* tracking_canvas_
;
222 AutoStamper::AutoStamper(TimingCanvas
*timing_canvas
)
223 : timing_canvas_(timing_canvas
) {
224 start_ticks_
= base::TimeTicks::HighResNow();
227 AutoStamper::~AutoStamper() {
228 base::TimeDelta delta
= base::TimeTicks::HighResNow() - start_ticks_
;
229 int command_index
= timing_canvas_
->tracking_canvas_
->CommandCount() - 1;
230 DCHECK_GE(command_index
, 0);
231 timing_canvas_
->timings_map_
[command_index
] = delta
;
234 BenchmarkingCanvas::BenchmarkingCanvas(int width
, int height
)
235 : SkNWayCanvas(width
, height
) {
236 debug_canvas_
= skia::AdoptRef(SkNEW_ARGS(SkDebugCanvas
, (width
, height
)));
237 timing_canvas_
= skia::AdoptRef(SkNEW_ARGS(TimingCanvas
, (width
, height
, this)));
239 addCanvas(debug_canvas_
.get());
240 addCanvas(timing_canvas_
.get());
243 BenchmarkingCanvas::~BenchmarkingCanvas() {
247 size_t BenchmarkingCanvas::CommandCount() const {
248 return debug_canvas_
->getSize();
251 SkDrawCommand
* BenchmarkingCanvas::GetCommand(size_t index
) {
252 DCHECK_LT(index
, static_cast<size_t>(debug_canvas_
->getSize()));
253 return debug_canvas_
->getDrawCommandAt(index
);
256 double BenchmarkingCanvas::GetTime(size_t index
) {
257 DCHECK_LT(index
, static_cast<size_t>(debug_canvas_
->getSize()));
258 return timing_canvas_
->GetTime(index
);