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/SkSurface.h"
10 #include "third_party/skia/include/utils/SkNWayCanvas.h"
16 AutoStamper(TimingCanvas
* timing_canvas
);
20 TimingCanvas
* timing_canvas_
;
21 base::TimeTicks start_ticks_
;
24 class TimingCanvas
: public SkNWayCanvas
{
26 TimingCanvas(int width
, int height
, const BenchmarkingCanvas
* track_canvas
)
27 : SkNWayCanvas(width
, height
)
28 , tracking_canvas_(track_canvas
) {
29 surface_
= skia::AdoptRef(SkSurface::NewRasterN32Premul(width
, height
));
31 addCanvas(surface_
->getCanvas());
34 ~TimingCanvas() override
{}
36 double GetTime(size_t index
) {
37 TimingsMap::const_iterator timing_info
= timings_map_
.find(index
);
38 return timing_info
!= timings_map_
.end()
39 ? timing_info
->second
.InMillisecondsF()
43 // SkCanvas overrides.
44 void willSave() override
{
45 AutoStamper
stamper(this);
46 SkNWayCanvas::willSave();
49 SaveLayerStrategy
willSaveLayer(const SkRect
* bounds
,
51 SaveFlags flags
) override
{
52 AutoStamper
stamper(this);
53 return SkNWayCanvas::willSaveLayer(bounds
, paint
, flags
);
56 void willRestore() override
{
57 AutoStamper
stamper(this);
58 SkNWayCanvas::willRestore();
61 void onDrawPaint(const SkPaint
& paint
) override
{
62 AutoStamper
stamper(this);
63 SkNWayCanvas::onDrawPaint(paint
);
66 void onDrawPoints(PointMode mode
,
69 const SkPaint
& paint
) override
{
70 AutoStamper
stamper(this);
71 SkNWayCanvas::onDrawPoints(mode
, count
, pts
, paint
);
74 void onDrawOval(const SkRect
& rect
, const SkPaint
& paint
) override
{
75 AutoStamper
stamper(this);
76 SkNWayCanvas::onDrawOval(rect
, paint
);
79 void onDrawRect(const SkRect
& rect
, const SkPaint
& paint
) override
{
80 AutoStamper
stamper(this);
81 SkNWayCanvas::onDrawRect(rect
, paint
);
84 void onDrawRRect(const SkRRect
& rrect
, const SkPaint
& paint
) override
{
85 AutoStamper
stamper(this);
86 SkNWayCanvas::onDrawRRect(rrect
, paint
);
89 void onDrawPath(const SkPath
& path
, const SkPaint
& paint
) override
{
90 AutoStamper
stamper(this);
91 SkNWayCanvas::onDrawPath(path
, paint
);
94 void onDrawBitmap(const SkBitmap
& bitmap
,
97 const SkPaint
* paint
) override
{
98 AutoStamper
stamper(this);
99 SkNWayCanvas::onDrawBitmap(bitmap
, left
, top
, paint
);
102 void onDrawBitmapRect(const SkBitmap
& bitmap
,
105 const SkPaint
* paint
,
106 DrawBitmapRectFlags flags
) override
{
107 AutoStamper
stamper(this);
108 SkNWayCanvas::onDrawBitmapRect(bitmap
, src
, dst
, paint
, flags
);
111 void onDrawSprite(const SkBitmap
& bitmap
,
114 const SkPaint
* paint
) override
{
115 AutoStamper
stamper(this);
116 SkNWayCanvas::onDrawSprite(bitmap
, left
, top
, paint
);
119 void onDrawVertices(VertexMode vmode
,
121 const SkPoint vertices
[],
122 const SkPoint texs
[],
123 const SkColor colors
[],
125 const uint16_t indices
[],
127 const SkPaint
& paint
) override
{
128 AutoStamper
stamper(this);
129 SkNWayCanvas::onDrawVertices(vmode
, vertexCount
, vertices
, texs
, colors
,
130 xmode
, indices
, indexCount
, paint
);
134 void onDrawText(const void* text
,
138 const SkPaint
& paint
) override
{
139 AutoStamper
stamper(this);
140 SkNWayCanvas::onDrawText(text
, byteLength
, x
, y
, paint
);
143 void onDrawPosText(const void* text
,
146 const SkPaint
& paint
) override
{
147 AutoStamper
stamper(this);
148 SkNWayCanvas::onDrawPosText(text
, byteLength
, pos
, paint
);
151 void onDrawPosTextH(const void* text
,
153 const SkScalar xpos
[],
155 const SkPaint
& paint
) override
{
156 AutoStamper
stamper(this);
157 SkNWayCanvas::onDrawPosTextH(text
, byteLength
, xpos
, constY
, paint
);
160 void onDrawTextOnPath(const void* text
,
163 const SkMatrix
* matrix
,
164 const SkPaint
& paint
) override
{
165 AutoStamper
stamper(this);
166 SkNWayCanvas::onDrawTextOnPath(text
, byteLength
, path
, matrix
, paint
);
169 void onClipRect(const SkRect
& rect
,
171 ClipEdgeStyle edge_style
) override
{
172 AutoStamper
stamper(this);
173 SkNWayCanvas::onClipRect(rect
, op
, edge_style
);
176 void onClipRRect(const SkRRect
& rrect
,
178 ClipEdgeStyle edge_style
) override
{
179 AutoStamper
stamper(this);
180 SkNWayCanvas::onClipRRect(rrect
, op
, edge_style
);
183 void onClipPath(const SkPath
& path
,
185 ClipEdgeStyle edge_style
) override
{
186 AutoStamper
stamper(this);
187 SkNWayCanvas::onClipPath(path
, op
, edge_style
);
190 void onClipRegion(const SkRegion
& region
, SkRegion::Op op
) override
{
191 AutoStamper
stamper(this);
192 SkNWayCanvas::onClipRegion(region
, op
);
195 void onDrawPicture(const SkPicture
* picture
,
196 const SkMatrix
* matrix
,
197 const SkPaint
* paint
) override
{
198 AutoStamper
stamper(this);
199 SkNWayCanvas::onDrawPicture(picture
, matrix
, paint
);
203 typedef base::hash_map
<size_t, base::TimeDelta
> TimingsMap
;
204 TimingsMap timings_map_
;
206 skia::RefPtr
<SkSurface
> surface_
;
208 friend class AutoStamper
;
209 const BenchmarkingCanvas
* tracking_canvas_
;
212 AutoStamper::AutoStamper(TimingCanvas
*timing_canvas
)
213 : timing_canvas_(timing_canvas
) {
214 start_ticks_
= base::TimeTicks::Now();
217 AutoStamper::~AutoStamper() {
218 base::TimeDelta delta
= base::TimeTicks::Now() - start_ticks_
;
219 int command_index
= timing_canvas_
->tracking_canvas_
->CommandCount() - 1;
220 DCHECK_GE(command_index
, 0);
221 timing_canvas_
->timings_map_
[command_index
] = delta
;
224 BenchmarkingCanvas::BenchmarkingCanvas(int width
, int height
)
225 : SkNWayCanvas(width
, height
) {
226 debug_canvas_
= skia::AdoptRef(SkNEW_ARGS(SkDebugCanvas
, (width
, height
)));
227 timing_canvas_
= skia::AdoptRef(SkNEW_ARGS(TimingCanvas
, (width
, height
, this)));
229 addCanvas(debug_canvas_
.get());
230 addCanvas(timing_canvas_
.get());
233 BenchmarkingCanvas::~BenchmarkingCanvas() {
237 size_t BenchmarkingCanvas::CommandCount() const {
238 return debug_canvas_
->getSize();
241 SkDrawCommand
* BenchmarkingCanvas::GetCommand(size_t index
) {
242 DCHECK_LT(index
, static_cast<size_t>(debug_canvas_
->getSize()));
243 return debug_canvas_
->getDrawCommandAt(index
);
246 double BenchmarkingCanvas::GetTime(size_t index
) {
247 DCHECK_LT(index
, static_cast<size_t>(debug_canvas_
->getSize()));
248 return timing_canvas_
->GetTime(index
);