aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2014-10-09 04:59:19 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-10-09 04:59:19 -0700
commit78c71272fb26852bf3d2ca31785e61d4a598af82 (patch)
tree0c31e62d2abe366f2f0127d201c4914ad28c885c /tools
parent17bfe0d670678b705a08532008a6145c1fb69a63 (diff)
Update old tools to allow MultiPictureDraw rendering
I'll post a separate patch for nanobench and dm Review URL: https://codereview.chromium.org/639013003
Diffstat (limited to 'tools')
-rw-r--r--tools/CopyTilesRenderer.cpp14
-rw-r--r--tools/CopyTilesRenderer.h3
-rw-r--r--tools/PictureBenchmark.cpp27
-rw-r--r--tools/PictureBenchmark.h6
-rw-r--r--tools/PictureRenderer.cpp119
-rw-r--r--tools/PictureRenderer.h16
-rw-r--r--tools/bbh_shootout.cpp10
-rw-r--r--tools/bench_pictures_main.cpp15
-rw-r--r--tools/render_pictures_main.cpp20
9 files changed, 136 insertions, 94 deletions
diff --git a/tools/CopyTilesRenderer.cpp b/tools/CopyTilesRenderer.cpp
index 30a3256d63..6f95da758b 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 @@ namespace sk_tools {
#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 @@ namespace sk_tools {
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 @@ namespace sk_tools {
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 b24414223c..92996bbea8 100644
--- a/tools/CopyTilesRenderer.h
+++ b/tools/CopyTilesRenderer.h
@@ -31,7 +31,8 @@ namespace sk_tools {
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 15b6173aa1..f708f53613 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 @@ PictureRenderer* PictureBenchmark::setRenderer(sk_tools::PictureRenderer* render
return renderer;
}
-void PictureBenchmark::run(SkPicture* pict) {
+void PictureBenchmark::run(SkPicture* pict, bool useMultiPictureDraw) {
SkASSERT(pict);
if (NULL == pict) {
return;
@@ -67,17 +66,11 @@ void PictureBenchmark::run(SkPicture* pict) {
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 2b1ccb5383..99eca6bcc0 100644
--- a/tools/PictureBenchmark.h
+++ b/tools/PictureBenchmark.h
@@ -28,7 +28,7 @@ public:
* 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 @@ public:
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 @@ private:
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 705849d01a..89f2cda3dd 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 @@ void PictureRenderer::init(const SkPicture* pict,
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 @@ SkString PipePictureRenderer::getConfigNameInternal() {
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 @@ bool SimplePictureRenderer::render(SkBitmap** out) {
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 @@ TiledPictureRenderer::TiledPictureRenderer()
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 @@ void TiledPictureRenderer::init(const SkPicture* pict, const SkString* writePath
this->CopyString(&fMismatchPath, mismatchPath);
this->CopyString(&fInputFilename, inputFilename);
fUseChecksumBasedFilenames = useChecksumBasedFilenames;
+ fUseMultiPictureDraw = useMultiPictureDraw;
this->buildBBoxHierarchy();
if (fTileWidthPercentage > 0) {
@@ -519,10 +533,8 @@ void TiledPictureRenderer::setupTiles() {
// 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 @@ void TiledPictureRenderer::setupPowerOf2Tiles() {
// 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 @@ void TiledPictureRenderer::setupPowerOf2Tiles() {
* 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 @@ void TiledPictureRenderer::drawCurrentTile() {
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 @@ bool TiledPictureRenderer::render(SkBitmap** out) {
}
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 04ac20fcb6..3f58b18121 100644
--- a/tools/PictureRenderer.h
+++ b/tools/PictureRenderer.h
@@ -88,12 +88,14 @@ public:
* @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 @@ protected:
SkAutoTUnref<SkCanvas> fCanvas;
SkAutoTUnref<const SkPicture> fPicture;
bool fUseChecksumBasedFilenames;
+ bool fUseMultiPictureDraw;
ImageResultsAndExpectations* fJsonSummaryPtr;
SkDeviceTypes fDeviceType;
bool fEnableWrites;
@@ -548,7 +551,8 @@ public:
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 @@ public:
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 @@ public:
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 @@ private:
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 2a827fd896..d4b290d06b 100644
--- a/tools/bbh_shootout.cpp
+++ b/tools/bbh_shootout.cpp
@@ -60,13 +60,13 @@ static SkPicture* pic_from_path(const char path[]) {
* @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 ade93fc3e6..93ee308ae1 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -59,7 +59,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 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 @@ static bool run_single_benchmark(const SkString& inputPath,
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 @@ static void setup_benchmark(sk_tools::PictureBenchmark* benchmark) {
}
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 d7a213cb47..6faa81ac0e 100644
--- a/tools/render_pictures_main.cpp
+++ b/tools/render_pictures_main.cpp
@@ -40,7 +40,7 @@ DEFINE_string(mismatchPath, "", "Write images for tests that failed due to "
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 @@ static bool render_picture_internal(const SkString& inputPath, const SkString* w
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 @@ static bool render_picture_internal(const SkString& inputPath, const SkString* w
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();