SKPBench.cpp revision a3e52724ac8b9fa7b48507bff4fa8e558a213e49
1/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SKPBench.h"
9#include "SkCommandLineFlags.h"
10#include "SkMultiPictureDraw.h"
11#include "SkSurface.h"
12
13DEFINE_int32(benchTile, 256, "Tile dimension used for SKP playback.");
14
15SKPBench::SKPBench(const char* name, const SkPicture* pic, const SkIRect& clip, SkScalar scale,
16                   bool useMultiPictureDraw)
17    : fPic(SkRef(pic))
18    , fClip(clip)
19    , fScale(scale)
20    , fName(name)
21    , fUseMultiPictureDraw(useMultiPictureDraw) {
22    fUniqueName.printf("%s_%.2g", name, scale);  // Scale makes this unqiue for skiaperf.com traces.
23    if (useMultiPictureDraw) {
24        fUniqueName.append("_mpd");
25    }
26}
27
28SKPBench::~SKPBench() {
29    for (int i = 0; i < fSurfaces.count(); ++i) {
30        fSurfaces[i]->unref();
31    }
32}
33
34const char* SKPBench::onGetName() {
35    return fName.c_str();
36}
37
38const char* SKPBench::onGetUniqueName() {
39    return fUniqueName.c_str();
40}
41
42void SKPBench::onPerCanvasPreDraw(SkCanvas* canvas) {
43    SkIRect bounds;
44    SkAssertResult(canvas->getClipDeviceBounds(&bounds));
45
46    int xTiles = SkScalarCeilToInt(bounds.width()  / SkIntToScalar(FLAGS_benchTile));
47    int yTiles = SkScalarCeilToInt(bounds.height() / SkIntToScalar(FLAGS_benchTile));
48
49    fSurfaces.setReserve(xTiles * yTiles);
50    fTileRects.setReserve(xTiles * yTiles);
51
52    SkImageInfo ii = canvas->imageInfo().makeWH(FLAGS_benchTile, FLAGS_benchTile);
53
54    for (int y = bounds.fTop; y < bounds.fBottom; y += FLAGS_benchTile) {
55        for (int x = bounds.fLeft; x < bounds.fRight; x += FLAGS_benchTile) {
56            const SkIRect tileRect = SkIRect::MakeXYWH(x, y, FLAGS_benchTile, FLAGS_benchTile);
57            *fTileRects.append() = tileRect;
58            *fSurfaces.push() = canvas->newSurface(ii);
59
60            // Never want the contents of a tile to include stuff the parent
61            // canvas clips out
62            SkRect clip = SkRect::Make(bounds);
63            clip.offset(-SkIntToScalar(tileRect.fLeft), -SkIntToScalar(tileRect.fTop));
64            fSurfaces.top()->getCanvas()->clipRect(clip);
65
66            fSurfaces.top()->getCanvas()->setMatrix(canvas->getTotalMatrix());
67            fSurfaces.top()->getCanvas()->scale(fScale, fScale);
68        }
69    }
70}
71
72void SKPBench::onPerCanvasPostDraw(SkCanvas* canvas) {
73    // Draw the last set of tiles into the master canvas in case we're
74    // saving the images
75    for (int i = 0; i < fTileRects.count(); ++i) {
76        SkAutoTUnref<SkImage> image(fSurfaces[i]->newImageSnapshot());
77        canvas->drawImage(image,
78                          SkIntToScalar(fTileRects[i].fLeft), SkIntToScalar(fTileRects[i].fTop));
79        SkSafeSetNull(fSurfaces[i]);
80    }
81
82    fSurfaces.rewind();
83    fTileRects.rewind();
84}
85
86bool SKPBench::isSuitableFor(Backend backend) {
87    return backend != kNonRendering_Backend;
88}
89
90SkIPoint SKPBench::onGetSize() {
91    return SkIPoint::Make(fClip.width(), fClip.height());
92}
93
94void SKPBench::onDraw(const int loops, SkCanvas* canvas) {
95    if (fUseMultiPictureDraw) {
96        for (int i = 0; i < loops; i++) {
97            SkMultiPictureDraw mpd;
98
99            for (int j = 0; j < fTileRects.count(); ++j) {
100                SkMatrix trans;
101                trans.setTranslate(-fTileRects[j].fLeft/fScale,
102                                   -fTileRects[j].fTop/fScale);
103                mpd.add(fSurfaces[j]->getCanvas(), fPic, &trans);
104            }
105
106            mpd.draw();
107
108            for (int j = 0; j < fTileRects.count(); ++j) {
109                fSurfaces[j]->getCanvas()->flush();
110            }
111        }
112    } else {
113        for (int i = 0; i < loops; i++) {
114            for (int j = 0; j < fTileRects.count(); ++j) {
115                SkMatrix trans;
116                trans.setTranslate(-fTileRects[j].fLeft / fScale,
117                                   -fTileRects[j].fTop / fScale);
118                fSurfaces[j]->getCanvas()->drawPicture(fPic, &trans, NULL);
119            }
120
121            for (int j = 0; j < fTileRects.count(); ++j) {
122                fSurfaces[j]->getCanvas()->flush();
123            }
124        }
125    }
126}
127