From 0ddad31012dabfc1267effc8071d37f7d606efbe Mon Sep 17 00:00:00 2001 From: robertphillips Date: Fri, 21 Nov 2014 05:35:54 -0800 Subject: Add MultiPictureDraw to nanobench I would like some guard against performance regressions on our side before turning layer hoisting on in Chromium. TBR=bsalomon@google.com Review URL: https://codereview.chromium.org/731973005 --- bench/SKPBench.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 14 deletions(-) (limited to 'bench/SKPBench.cpp') diff --git a/bench/SKPBench.cpp b/bench/SKPBench.cpp index 5844d8a588..fd8df429c2 100644 --- a/bench/SKPBench.cpp +++ b/bench/SKPBench.cpp @@ -7,15 +7,28 @@ #include "SKPBench.h" #include "SkCommandLineFlags.h" +#include "SkMultiPictureDraw.h" +#include "SkSurface.h" DEFINE_int32(benchTile, 256, "Tile dimension used for SKP playback."); -SKPBench::SKPBench(const char* name, const SkPicture* pic, const SkIRect& clip, SkScalar scale) +SKPBench::SKPBench(const char* name, const SkPicture* pic, const SkIRect& clip, SkScalar scale, + bool useMultiPictureDraw) : fPic(SkRef(pic)) , fClip(clip) , fScale(scale) - , fName(name) { + , fName(name) + , fUseMultiPictureDraw(useMultiPictureDraw) { fUniqueName.printf("%s_%.2g", name, scale); // Scale makes this unqiue for skiaperf.com traces. + if (useMultiPictureDraw) { + fUniqueName.append("_mpd"); + } +} + +SKPBench::~SKPBench() { + for (int i = 0; i < fSurfaces.count(); ++i) { + fSurfaces[i]->unref(); + } } const char* SKPBench::onGetName() { @@ -26,6 +39,49 @@ const char* SKPBench::onGetUniqueName() { return fUniqueName.c_str(); } +void SKPBench::onPerCanvasPreDraw(SkCanvas* canvas) { + if (!fUseMultiPictureDraw) { + return; + } + + SkIRect bounds; + SkAssertResult(canvas->getClipDeviceBounds(&bounds)); + + int xTiles = SkScalarCeilToInt(bounds.width() / SkIntToScalar(FLAGS_benchTile)); + int yTiles = SkScalarCeilToInt(bounds.height() / SkIntToScalar(FLAGS_benchTile)); + + fSurfaces.setReserve(xTiles * yTiles); + fTileRects.setReserve(xTiles * yTiles); + + SkImageInfo ii = canvas->imageInfo().makeWH(FLAGS_benchTile, FLAGS_benchTile); + + for (int y = bounds.fTop; y < bounds.fBottom; y += FLAGS_benchTile) { + for (int x = bounds.fLeft; x < bounds.fRight; x += FLAGS_benchTile) { + *fTileRects.append() = SkIRect::MakeXYWH(x, y, FLAGS_benchTile, FLAGS_benchTile); + *fSurfaces.push() = canvas->newSurface(ii); + fSurfaces.top()->getCanvas()->setMatrix(canvas->getTotalMatrix()); + fSurfaces.top()->getCanvas()->scale(fScale, fScale); + } + } +} + +void SKPBench::onPerCanvasPostDraw(SkCanvas* canvas) { + if (!fUseMultiPictureDraw) { + return; + } + + // Draw the last set of tiles into the master canvas in case we're + // saving the images + for (int i = 0; i < fTileRects.count(); ++i) { + canvas->drawImage(fSurfaces[i]->newImageSnapshot(), + SkIntToScalar(fTileRects[i].fLeft), SkIntToScalar(fTileRects[i].fTop)); + SkSafeSetNull(fSurfaces[i]); + } + + fSurfaces.rewind(); + fTileRects.rewind(); +} + bool SKPBench::isSuitableFor(Backend backend) { return backend != kNonRendering_Backend; } @@ -35,21 +91,41 @@ SkIPoint SKPBench::onGetSize() { } void SKPBench::onDraw(const int loops, SkCanvas* canvas) { - SkIRect bounds; - SkAssertResult(canvas->getClipDeviceBounds(&bounds)); + if (fUseMultiPictureDraw) { + for (int i = 0; i < loops; i++) { + SkMultiPictureDraw mpd; - SkAutoCanvasRestore overall(canvas, true/*save now*/); - canvas->scale(fScale, fScale); + for (int i = 0; i < fTileRects.count(); ++i) { + SkMatrix trans; + trans.setTranslate(-fTileRects[i].fLeft/fScale, + -fTileRects[i].fTop/fScale); + mpd.add(fSurfaces[i]->getCanvas(), fPic, &trans); + } + + mpd.draw(); - for (int i = 0; i < loops; i++) { - for (int y = bounds.fTop; y < bounds.fBottom; y += FLAGS_benchTile) { - for (int x = bounds.fLeft; x < bounds.fRight; x += FLAGS_benchTile) { - SkAutoCanvasRestore perTile(canvas, true/*save now*/); - canvas->clipRect(SkRect::Make( - SkIRect::MakeXYWH(x, y, FLAGS_benchTile, FLAGS_benchTile))); - fPic->playback(canvas); + for (int i = 0; i < fTileRects.count(); ++i) { + fSurfaces[i]->getCanvas()->flush(); } } - canvas->flush(); + } else { + SkIRect bounds; + SkAssertResult(canvas->getClipDeviceBounds(&bounds)); + + SkAutoCanvasRestore overall(canvas, true/*save now*/); + canvas->scale(fScale, fScale); + + for (int i = 0; i < loops; i++) { + for (int y = bounds.fTop; y < bounds.fBottom; y += FLAGS_benchTile) { + for (int x = bounds.fLeft; x < bounds.fRight; x += FLAGS_benchTile) { + SkAutoCanvasRestore perTile(canvas, true/*save now*/); + canvas->clipRect(SkRect::Make( + SkIRect::MakeXYWH(x, y, FLAGS_benchTile, FLAGS_benchTile))); + fPic->playback(canvas); + } + } + + canvas->flush(); + } } } -- cgit v1.2.3