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/core/SkBitmapDevice.h"
10 #include "third_party/skia/include/utils/SkProxyCanvas.h"
16 AutoStamper(TimingCanvas
* timing_canvas
);
20 TimingCanvas
* timing_canvas_
;
21 base::TimeTicks start_ticks_
;
24 class TimingCanvas
: public SkProxyCanvas
{
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())));
32 setProxy(canvas_
.get());
35 virtual ~TimingCanvas() {
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()
45 // SkCanvas overrides.
46 virtual int save(SaveFlags flags
= kMatrixClip_SaveFlag
) OVERRIDE
{
47 AutoStamper
stamper(this);
48 return SkProxyCanvas::save(flags
);
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
);
57 virtual void restore() OVERRIDE
{
58 AutoStamper
stamper(this);
59 SkProxyCanvas::restore();
62 virtual bool clipRect(const SkRect
& rect
, SkRegion::Op op
,
64 AutoStamper
stamper(this);
65 return SkProxyCanvas::clipRect(rect
, op
, doAa
);
68 virtual bool clipRRect(const SkRRect
& rrect
, SkRegion::Op op
,
70 AutoStamper
stamper(this);
71 return SkProxyCanvas::clipRRect(rrect
, op
, doAa
);
74 virtual bool clipPath(const SkPath
& path
, SkRegion::Op op
,
76 AutoStamper
stamper(this);
77 return SkProxyCanvas::clipPath(path
, op
, doAa
);
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
);
86 virtual void drawPaint(const SkPaint
& paint
) OVERRIDE
{
87 AutoStamper
stamper(this);
88 SkProxyCanvas::drawPaint(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
);
97 virtual void drawOval(const SkRect
& rect
, const SkPaint
& paint
) OVERRIDE
{
98 AutoStamper
stamper(this);
99 SkProxyCanvas::drawOval(rect
, paint
);
102 virtual void drawRect(const SkRect
& rect
, const SkPaint
& paint
) OVERRIDE
{
103 AutoStamper
stamper(this);
104 SkProxyCanvas::drawRect(rect
, paint
);
107 virtual void drawRRect(const SkRRect
& rrect
, const SkPaint
& paint
) OVERRIDE
{
108 AutoStamper
stamper(this);
109 SkProxyCanvas::drawRRect(rrect
, paint
);
112 virtual void drawPath(const SkPath
& path
, const SkPaint
& paint
) OVERRIDE
{
113 AutoStamper
stamper(this);
114 SkProxyCanvas::drawPath(path
, paint
);
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
);
123 virtual void drawBitmapRectToRect(const SkBitmap
& bitmap
, const SkRect
* src
,
125 const SkPaint
* paint
,
126 DrawBitmapRectFlags flags
) OVERRIDE
{
127 AutoStamper
stamper(this);
128 SkProxyCanvas::drawBitmapRectToRect(bitmap
, src
, dst
, paint
, flags
);
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
);
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
);
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
);
149 virtual void drawPosText(const void* text
, size_t byteLength
,
151 const SkPaint
& paint
) OVERRIDE
{
152 AutoStamper
stamper(this);
153 SkProxyCanvas::drawPosText(text
, byteLength
, pos
, 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
);
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
);
170 virtual void drawPicture(SkPicture
& picture
) OVERRIDE
{
171 AutoStamper
stamper(this);
172 SkProxyCanvas::drawPicture(picture
);
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
);
185 virtual void drawData(const void* data
, size_t length
) OVERRIDE
{
186 AutoStamper
stamper(this);
187 SkProxyCanvas::drawData(data
, length
);
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
);