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