Update old tools to allow MultiPictureDraw rendering
I'll post a separate patch for nanobench and dm
Review URL: https://codereview.chromium.org/639013003
diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp
index b03b8f3..59bfcca 100644
--- a/debugger/QT/SkDebuggerGUI.cpp
+++ b/debugger/QT/SkDebuggerGUI.cpp
@@ -356,7 +356,7 @@
return;
}
- renderer->init(pict, NULL, NULL, NULL, false);
+ renderer->init(pict, NULL, NULL, NULL, false, false);
renderer->setup();
renderer->render();
diff --git a/tools/CopyTilesRenderer.cpp b/tools/CopyTilesRenderer.cpp
index 30a3256..6f95da7 100644
--- a/tools/CopyTilesRenderer.cpp
+++ b/tools/CopyTilesRenderer.cpp
@@ -10,6 +10,7 @@
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkImageEncoder.h"
+#include "SkMultiPictureDraw.h"
#include "SkPicture.h"
#include "SkPixelRef.h"
#include "SkRect.h"
@@ -28,7 +29,7 @@
#endif
void CopyTilesRenderer::init(const SkPicture* pict, const SkString* writePath,
const SkString* mismatchPath, const SkString* inputFilename,
- bool useChecksumBasedFilenames) {
+ bool useChecksumBasedFilenames, bool useMultiPictureDraw) {
// Do not call INHERITED::init(), which would create a (potentially large) canvas which is
// not used by bench_pictures.
SkASSERT(pict != NULL);
@@ -39,6 +40,7 @@
this->CopyString(&fMismatchPath, mismatchPath);
this->CopyString(&fInputFilename, inputFilename);
fUseChecksumBasedFilenames = useChecksumBasedFilenames;
+ fUseMultiPictureDraw = useMultiPictureDraw;
this->buildBBoxHierarchy();
// In order to avoid allocating a large canvas (particularly important for GPU), create one
// canvas that is a multiple of the tile size, and draw portions of the picture.
@@ -61,7 +63,15 @@
mat.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
fCanvas->setMatrix(mat);
// Draw the picture
- fCanvas->drawPicture(fPicture);
+ if (fUseMultiPictureDraw) {
+ SkMultiPictureDraw mpd;
+
+ mpd.add(fCanvas, fPicture);
+
+ mpd.draw();
+ } else {
+ fCanvas->drawPicture(fPicture);
+ }
// Now extract the picture into tiles
SkBitmap baseBitmap;
fCanvas->readPixels(SkIRect::MakeSize(fCanvas->getBaseLayerSize()), &baseBitmap);
diff --git a/tools/CopyTilesRenderer.h b/tools/CopyTilesRenderer.h
index b244142..92996bb 100644
--- a/tools/CopyTilesRenderer.h
+++ b/tools/CopyTilesRenderer.h
@@ -31,7 +31,8 @@
const SkString* writePath,
const SkString* mismatchPath,
const SkString* inputFilename,
- bool useChecksumBasedFilenames) SK_OVERRIDE;
+ bool useChecksumBasedFilenames,
+ bool useMultiPictureDraw) SK_OVERRIDE;
/**
* Similar to TiledPictureRenderer, this will draw a PNG for each tile. However, the
diff --git a/tools/PictureBenchmark.cpp b/tools/PictureBenchmark.cpp
index 15b6173..f708f53 100644
--- a/tools/PictureBenchmark.cpp
+++ b/tools/PictureBenchmark.cpp
@@ -15,15 +15,14 @@
namespace sk_tools {
PictureBenchmark::PictureBenchmark()
-: fRepeats(1)
-, fRenderer(NULL)
-, fTimerResult(TimerData::kAvg_Result)
-, fTimerTypes(0)
-, fTimeIndividualTiles(false)
-, fPurgeDecodedTex(false)
-, fPreprocess(false)
-, fWriter(NULL)
-{}
+ : fRepeats(1)
+ , fRenderer(NULL)
+ , fTimerResult(TimerData::kAvg_Result)
+ , fTimerTypes(0)
+ , fTimeIndividualTiles(false)
+ , fPurgeDecodedTex(false)
+ , fWriter(NULL) {
+}
PictureBenchmark::~PictureBenchmark() {
SkSafeUnref(fRenderer);
@@ -56,7 +55,7 @@
return renderer;
}
-void PictureBenchmark::run(SkPicture* pict) {
+void PictureBenchmark::run(SkPicture* pict, bool useMultiPictureDraw) {
SkASSERT(pict);
if (NULL == pict) {
return;
@@ -67,17 +66,11 @@
return;
}
- fRenderer->init(pict, NULL, NULL, NULL, false);
+ fRenderer->init(pict, NULL, NULL, NULL, false, useMultiPictureDraw);
// We throw this away to remove first time effects (such as paging in this program)
fRenderer->setup();
- if (fPreprocess) {
- if (fRenderer->getCanvas()) {
- fRenderer->getCanvas()->EXPERIMENTAL_optimize(fRenderer->getPicture());
- }
- }
-
fRenderer->render(NULL);
fRenderer->resetState(true); // flush, swapBuffers and Finish
diff --git a/tools/PictureBenchmark.h b/tools/PictureBenchmark.h
index 2b1ccb5..99eca6b 100644
--- a/tools/PictureBenchmark.h
+++ b/tools/PictureBenchmark.h
@@ -28,7 +28,7 @@
* Draw the provided SkPicture fRepeats times while collecting timing data, and log the output
* via fWriter.
*/
- void run(SkPicture* pict);
+ void run(SkPicture* pict, bool useMultiPictureDraw);
void setRepeats(int repeats) {
fRepeats = repeats;
@@ -45,9 +45,6 @@
void setPurgeDecodedTex(bool purgeDecodedTex) { fPurgeDecodedTex = purgeDecodedTex; }
bool purgeDecodedText() const { return fPurgeDecodedTex; }
- void setPreprocess(bool preprocess) { fPreprocess = preprocess; }
- bool preprocess() const { return fPreprocess; }
-
PictureRenderer* setRenderer(PictureRenderer*);
PictureRenderer* renderer() { return fRenderer; }
@@ -64,7 +61,6 @@
uint32_t fTimerTypes; // bitfield of TimerData::TimerFlags values
bool fTimeIndividualTiles;
bool fPurgeDecodedTex;
- bool fPreprocess;
PictureResultsWriter* fWriter;
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index 705849d..89f2cda 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -22,6 +22,7 @@
#include "SkImageEncoder.h"
#include "SkMaskFilter.h"
#include "SkMatrix.h"
+#include "SkMultiPictureDraw.h"
#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
@@ -30,6 +31,7 @@
#include "SkScalar.h"
#include "SkStream.h"
#include "SkString.h"
+#include "SkSurface.h"
#include "SkTemplates.h"
#include "SkTDArray.h"
#include "SkThreadUtils.h"
@@ -52,11 +54,13 @@
const SkString* writePath,
const SkString* mismatchPath,
const SkString* inputFilename,
- bool useChecksumBasedFilenames) {
+ bool useChecksumBasedFilenames,
+ bool useMultiPictureDraw) {
this->CopyString(&fWritePath, writePath);
this->CopyString(&fMismatchPath, mismatchPath);
this->CopyString(&fInputFilename, inputFilename);
fUseChecksumBasedFilenames = useChecksumBasedFilenames;
+ fUseMultiPictureDraw = useMultiPictureDraw;
SkASSERT(NULL == fPicture);
SkASSERT(NULL == fCanvas.get());
@@ -415,8 +419,9 @@
void SimplePictureRenderer::init(const SkPicture* picture, const SkString* writePath,
const SkString* mismatchPath, const SkString* inputFilename,
- bool useChecksumBasedFilenames) {
- INHERITED::init(picture, writePath, mismatchPath, inputFilename, useChecksumBasedFilenames);
+ bool useChecksumBasedFilenames, bool useMultiPictureDraw) {
+ INHERITED::init(picture, writePath, mismatchPath, inputFilename,
+ useChecksumBasedFilenames, useMultiPictureDraw);
this->buildBBoxHierarchy();
}
@@ -427,7 +432,15 @@
return false;
}
- fCanvas->drawPicture(fPicture);
+ if (fUseMultiPictureDraw) {
+ SkMultiPictureDraw mpd;
+
+ mpd.add(fCanvas, fPicture);
+
+ mpd.draw();
+ } else {
+ fCanvas->drawPicture(fPicture);
+ }
fCanvas->flush();
if (out) {
*out = SkNEW(SkBitmap);
@@ -467,7 +480,7 @@
void TiledPictureRenderer::init(const SkPicture* pict, const SkString* writePath,
const SkString* mismatchPath, const SkString* inputFilename,
- bool useChecksumBasedFilenames) {
+ bool useChecksumBasedFilenames, bool useMultiPictureDraw) {
SkASSERT(pict);
SkASSERT(0 == fTileRects.count());
if (NULL == pict || fTileRects.count() != 0) {
@@ -481,6 +494,7 @@
this->CopyString(&fMismatchPath, mismatchPath);
this->CopyString(&fInputFilename, inputFilename);
fUseChecksumBasedFilenames = useChecksumBasedFilenames;
+ fUseMultiPictureDraw = useMultiPictureDraw;
this->buildBBoxHierarchy();
if (fTileWidthPercentage > 0) {
@@ -519,10 +533,8 @@
// Only count tiles in the X direction on the first pass.
fTilesX++;
}
- *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start),
- SkIntToScalar(tile_y_start),
- SkIntToScalar(fTileWidth),
- SkIntToScalar(fTileHeight));
+ *fTileRects.append() = SkIRect::MakeXYWH(tile_x_start, tile_y_start,
+ fTileWidth, fTileHeight);
}
}
}
@@ -575,10 +587,8 @@
// Only count tiles in the X direction on the first pass.
fTilesX++;
}
- *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start),
- SkIntToScalar(tile_y_start),
- SkIntToScalar(current_width),
- SkIntToScalar(fTileHeight));
+ *fTileRects.append() = SkIRect::MakeXYWH(tile_x_start, tile_y_start,
+ current_width, fTileHeight);
tile_x_start += current_width;
}
@@ -594,13 +604,13 @@
* is called.
*/
static void draw_tile_to_canvas(SkCanvas* canvas,
- const SkRect& tileRect,
+ const SkIRect& tileRect,
const SkPicture* picture) {
int saveCount = canvas->save();
// Translate so that we draw the correct portion of the picture.
// Perform a postTranslate so that the scaleFactor does not interfere with the positioning.
SkMatrix mat(canvas->getTotalMatrix());
- mat.postTranslate(-tileRect.fLeft, -tileRect.fTop);
+ mat.postTranslate(-SkIntToScalar(tileRect.fLeft), -SkIntToScalar(tileRect.fTop));
canvas->setMatrix(mat);
canvas->drawPicture(picture);
canvas->restoreToCount(saveCount);
@@ -643,6 +653,27 @@
draw_tile_to_canvas(fCanvas, fTileRects[fCurrentTileOffset], fPicture);
}
+bool TiledPictureRenderer::postRender(SkCanvas* canvas, const SkIRect& tileRect,
+ SkBitmap* tempBM, SkBitmap** out,
+ int tileNumber) {
+ bool success = true;
+
+ if (fEnableWrites) {
+ success &= write(canvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr,
+ fUseChecksumBasedFilenames, &tileNumber);
+ }
+ if (out) {
+ if (canvas->readPixels(tempBM, 0, 0)) {
+ // Add this tile to the entire bitmap.
+ bitmapCopyAtOffset(*tempBM, *out, tileRect.left(), tileRect.top());
+ } else {
+ success = false;
+ }
+ }
+
+ return success;
+}
+
bool TiledPictureRenderer::render(SkBitmap** out) {
SkASSERT(fPicture != NULL);
if (NULL == fPicture) {
@@ -650,29 +681,59 @@
}
SkBitmap bitmap;
- if (out){
+ if (out) {
*out = SkNEW(SkBitmap);
setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()),
SkScalarCeilToInt(fPicture->cullRect().height()));
setup_bitmap(&bitmap, fTileWidth, fTileHeight);
}
bool success = true;
- for (int i = 0; i < fTileRects.count(); ++i) {
- draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture);
- if (fEnableWrites) {
- success &= write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr,
- fUseChecksumBasedFilenames, &i);
+
+ if (fUseMultiPictureDraw) {
+ SkMultiPictureDraw mpd;
+ SkTDArray<SkSurface*> surfaces;
+ surfaces.setReserve(fTileRects.count());
+
+ // Create a separate SkSurface/SkCanvas for each tile along with a
+ // translated version of the skp (to mimic Chrome's behavior) and
+ // feed all such pairs to the MultiPictureDraw.
+ for (int i = 0; i < fTileRects.count(); ++i) {
+ SkImageInfo ii = fCanvas->imageInfo().makeWH(fTileRects[i].width(),
+ fTileRects[i].height());
+ *surfaces.append() = fCanvas->newSurface(ii);
+ surfaces[i]->getCanvas()->setMatrix(fCanvas->getTotalMatrix());
+
+ SkPictureRecorder recorder;
+ SkCanvas* c = recorder.beginRecording(SkIntToScalar(fTileRects[i].width()),
+ SkIntToScalar(fTileRects[i].height()));
+ c->save();
+ SkMatrix mat;
+ mat.setTranslate(-SkIntToScalar(fTileRects[i].fLeft),
+ -SkIntToScalar(fTileRects[i].fTop));
+ c->setMatrix(mat);
+ c->drawPicture(fPicture);
+ c->restore();
+
+ SkAutoTUnref<SkPicture> xlatedPicture(recorder.endRecording());
+
+ mpd.add(surfaces[i]->getCanvas(), xlatedPicture);
}
- if (out) {
- if (fCanvas->readPixels(&bitmap, 0, 0)) {
- // Add this tile to the entire bitmap.
- bitmapCopyAtOffset(bitmap, *out, SkScalarFloorToInt(fTileRects[i].left()),
- SkScalarFloorToInt(fTileRects[i].top()));
- } else {
- success = false;
- }
+
+ // Render all the buffered SkCanvases/SkPictures
+ mpd.draw();
+
+ // Sort out the results and cleanup the allocated surfaces
+ for (int i = 0; i < fTileRects.count(); ++i) {
+ success &= this->postRender(surfaces[i]->getCanvas(), fTileRects[i], &bitmap, out, i);
+ surfaces[i]->unref();
+ }
+ } else {
+ for (int i = 0; i < fTileRects.count(); ++i) {
+ draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture);
+ success &= this->postRender(fCanvas, fTileRects[i], &bitmap, out, i);
}
}
+
return success;
}
diff --git a/tools/PictureRenderer.h b/tools/PictureRenderer.h
index 04ac20f..3f58b18 100644
--- a/tools/PictureRenderer.h
+++ b/tools/PictureRenderer.h
@@ -88,12 +88,14 @@
* @param inputFilename The name of the input file we are rendering.
* @param useChecksumBasedFilenames Whether to use checksum-based filenames when writing
* bitmap images to disk.
+ * @param useMultiPictureDraw true if MultiPictureDraw should be used for rendering
*/
virtual void init(const SkPicture* pict,
const SkString* writePath,
const SkString* mismatchPath,
const SkString* inputFilename,
- bool useChecksumBasedFilenames);
+ bool useChecksumBasedFilenames,
+ bool useMultiPictureDraw);
/**
* TODO(epoger): Temporary hack, while we work on http://skbug.com/2584 ('bench_pictures is
@@ -445,6 +447,7 @@
SkAutoTUnref<SkCanvas> fCanvas;
SkAutoTUnref<const SkPicture> fPicture;
bool fUseChecksumBasedFilenames;
+ bool fUseMultiPictureDraw;
ImageResultsAndExpectations* fJsonSummaryPtr;
SkDeviceTypes fDeviceType;
bool fEnableWrites;
@@ -548,7 +551,8 @@
const SkString* writePath,
const SkString* mismatchPath,
const SkString* inputFilename,
- bool useChecksumBasedFilenames) SK_OVERRIDE;
+ bool useChecksumBasedFilenames,
+ bool useMultiPictureDraw) SK_OVERRIDE;
virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE;
@@ -570,7 +574,8 @@
const SkString* writePath,
const SkString* mismatchPath,
const SkString* inputFilename,
- bool useChecksumBasedFilenames) SK_OVERRIDE;
+ bool useChecksumBasedFilenames,
+ bool useMultiPictureDraw) SK_OVERRIDE;
/**
* Renders to tiles, rather than a single canvas.
@@ -659,7 +664,7 @@
void drawCurrentTile();
protected:
- SkTDArray<SkRect> fTileRects;
+ SkTDArray<SkIRect> fTileRects;
virtual SkCanvas* setupCanvas(int width, int height) SK_OVERRIDE;
virtual SkString getConfigNameInternal() SK_OVERRIDE;
@@ -681,6 +686,9 @@
void setupTiles();
void setupPowerOf2Tiles();
+ bool postRender(SkCanvas*, const SkIRect& tileRect,
+ SkBitmap* tempBM, SkBitmap** out,
+ int tileNumber);
typedef PictureRenderer INHERITED;
};
diff --git a/tools/bbh_shootout.cpp b/tools/bbh_shootout.cpp
index 2a827fd..d4b290d 100644
--- a/tools/bbh_shootout.cpp
+++ b/tools/bbh_shootout.cpp
@@ -60,13 +60,13 @@
* @param timer The timer used to benchmark the work.
*/
static void do_benchmark_work(sk_tools::PictureRenderer* renderer,
- BBoxType bBoxType,
- SkPicture* pic,
- const int numRepeats,
- Timer* timer) {
+ BBoxType bBoxType,
+ SkPicture* pic,
+ const int numRepeats,
+ Timer* timer) {
renderer->setBBoxHierarchyType(bBoxType);
renderer->setGridSize(FLAGS_tilesize, FLAGS_tilesize);
- renderer->init(pic, NULL, NULL, NULL, false);
+ renderer->init(pic, NULL, NULL, NULL, false, false);
SkDebugf("%s %d times...\n", renderer->getConfigName().c_str(), numRepeats);
for (int i = 0; i < numRepeats; ++i) {
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index ade93fc..93ee308 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -59,7 +59,7 @@
"Report some GPU call statistics.");
#endif
-DEFINE_bool(preprocess, false, "If true, perform device specific preprocessing before timing.");
+DEFINE_bool(mpd, false, "If true, use MultiPictureDraw to render.");
// Buildbot-specific parameters
DEFINE_string(builderName, "", "Name of the builder this is running on.");
@@ -202,23 +202,13 @@
return false;
}
- if (FLAGS_preprocess) {
- // Because the GPU preprocessing step relies on the in-memory picture
- // statistics we need to rerecord the picture here
- SkPictureRecorder recorder;
- picture->playback(recorder.beginRecording(picture->cullRect().width(),
- picture->cullRect().height(),
- NULL, 0));
- picture.reset(recorder.endRecording());
- }
-
SkString filename = SkOSPath::Basename(inputPath.c_str());
gWriter.bench(filename.c_str(),
SkScalarCeilToInt(picture->cullRect().width()),
SkScalarCeilToInt(picture->cullRect().height()));
- benchmark.run(picture);
+ benchmark.run(picture, FLAGS_mpd);
#if SK_LAZY_CACHE_STATS
if (FLAGS_trackDeferredCaching) {
@@ -365,7 +355,6 @@
}
benchmark->setPurgeDecodedTex(FLAGS_purgeDecodedTex);
- benchmark->setPreprocess(FLAGS_preprocess);
if (FLAGS_readPath.count() < 1) {
gLogger.logError(".skp files or directories are required.\n");
diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp
index d7a213c..6faa81a 100644
--- a/tools/render_pictures_main.cpp
+++ b/tools/render_pictures_main.cpp
@@ -40,7 +40,7 @@
DEFINE_bool(gpuStats, false, "Only meaningful with gpu configurations. "
"Report some GPU call statistics.");
#endif
-DEFINE_bool(preprocess, false, "If true, perform device specific preprocessing before rendering.");
+DEFINE_bool(mpd, false, "If true, use MultiPictureDraw for rendering.");
DEFINE_string(readJsonSummaryPath, "", "JSON file to read image expectations from.");
DECLARE_string(readPath);
DEFINE_bool(writeChecksumBasedFilenames, false,
@@ -184,16 +184,6 @@
return false;
}
- if (FLAGS_preprocess) {
- // Because the GPU preprocessing step relies on the in-memory picture
- // statistics we need to rerecord the picture here
- SkPictureRecorder recorder;
- picture->playback(recorder.beginRecording(picture->cullRect().width(),
- picture->cullRect().height(),
- NULL, 0));
- picture.reset(recorder.endRecording());
- }
-
while (FLAGS_bench_record) {
SkPictureRecorder recorder;
picture->playback(recorder.beginRecording(picture->cullRect().width(),
@@ -208,13 +198,7 @@
inputPath.c_str());
renderer.init(picture, &writePathString, &mismatchPathString, &inputFilename,
- FLAGS_writeChecksumBasedFilenames);
-
- if (FLAGS_preprocess) {
- if (renderer.getCanvas()) {
- renderer.getCanvas()->EXPERIMENTAL_optimize(renderer.getPicture());
- }
- }
+ FLAGS_writeChecksumBasedFilenames, FLAGS_mpd);
renderer.setup();
renderer.enableWrites();