Allow bench_pictures to have its viewport set on the command line.
Instead of drawing the entire (potentially very large) picture, only
draw one viewport's worth.
example:
bench_pictures <skp directory> --viewport 640 480
BUG=https://code.google.com/p/skia/issues/detail?id=1007
Review URL: https://codereview.appspot.com/6943052
git-svn-id: http://skia.googlecode.com/svn/trunk@6799 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/CopyTilesRenderer.cpp b/tools/CopyTilesRenderer.cpp
index 553209c..0df43bb 100644
--- a/tools/CopyTilesRenderer.cpp
+++ b/tools/CopyTilesRenderer.cpp
@@ -38,8 +38,8 @@
int i = 0;
bool success = true;
SkBitmap dst;
- for (int x = 0; x < fPicture->width(); x += fLargeTileWidth) {
- for (int y = 0; y < fPicture->height(); y += fLargeTileHeight) {
+ for (int x = 0; x < this->getViewWidth(); x += fLargeTileWidth) {
+ for (int y = 0; y < this->getViewHeight(); y += fLargeTileHeight) {
SkAutoCanvasRestore autoRestore(fCanvas, true);
fCanvas->translate(SkIntToScalar(-x), SkIntToScalar(-y));
// Draw the picture
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index 034e8fc..ac5e47c 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -98,7 +98,9 @@
}
SkCanvas* PictureRenderer::setupCanvas() {
- return this->setupCanvas(fPicture->width(), fPicture->height());
+ const int width = this->getViewWidth();
+ const int height = this->getViewHeight();
+ return this->setupCanvas(width, height);
}
SkCanvas* PictureRenderer::setupCanvas(int width, int height) {
@@ -133,6 +135,24 @@
fCanvas.reset(NULL);
}
+int PictureRenderer::getViewWidth() {
+ SkASSERT(fPicture != NULL);
+ int width = fPicture->width();
+ if (fViewport.width() > 0) {
+ width = SkMin32(width, fViewport.width());
+ }
+ return width;
+}
+
+int PictureRenderer::getViewHeight() {
+ SkASSERT(fPicture != NULL);
+ int height = fPicture->height();
+ if (fViewport.height() > 0) {
+ height = SkMin32(height, fViewport.height());
+ }
+ return height;
+}
+
/** Converts fPicture to a picture that uses a BBoxHierarchy.
* PictureRenderer subclasses that are used to test picture playback
* should call this method during init.
@@ -336,8 +356,12 @@
}
void TiledPictureRenderer::setupTiles() {
- for (int tile_y_start = 0; tile_y_start < fPicture->height(); tile_y_start += fTileHeight) {
- for (int tile_x_start = 0; tile_x_start < fPicture->width(); tile_x_start += fTileWidth) {
+ // Only use enough tiles to cover the viewport
+ const int width = this->getViewWidth();
+ const int height = this->getViewHeight();
+
+ for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) {
+ for (int tile_x_start = 0; tile_x_start < width; tile_x_start += fTileWidth) {
*fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start),
SkIntToScalar(tile_y_start),
SkIntToScalar(fTileWidth),
@@ -356,17 +380,20 @@
// value gives us the tiles we need: a bit of value one means we need a tile of
// that size.
void TiledPictureRenderer::setupPowerOf2Tiles() {
- int rounded_value = fPicture->width();
- if (fPicture->width() % fTileMinPowerOf2Width != 0) {
- rounded_value = fPicture->width() - (fPicture->width() % fTileMinPowerOf2Width)
- + fTileMinPowerOf2Width;
+ // Only use enough tiles to cover the viewport
+ const int width = this->getViewWidth();
+ const int height = this->getViewHeight();
+
+ int rounded_value = width;
+ if (width % fTileMinPowerOf2Width != 0) {
+ rounded_value = width - (width % fTileMinPowerOf2Width) + fTileMinPowerOf2Width;
}
- int num_bits = SkScalarCeilToInt(SkScalarLog2(SkIntToScalar(fPicture->width())));
+ int num_bits = SkScalarCeilToInt(SkScalarLog2(SkIntToScalar(width)));
int largest_possible_tile_size = 1 << num_bits;
// The tile height is constant for a particular picture.
- for (int tile_y_start = 0; tile_y_start < fPicture->height(); tile_y_start += fTileHeight) {
+ for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) {
int tile_x_start = 0;
int current_width = largest_possible_tile_size;
// Set fTileWidth to be the width of the widest tile, so that each canvas is large enough
@@ -429,12 +456,13 @@
SkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) {
SkCanvas* canvas = this->INHERITED::setupCanvas(width, height);
SkASSERT(fPicture != NULL);
+ const int totalWidth = this->getViewWidth();
+ const int totalHeight = this->getViewHeight();
// Clip the tile to an area that is completely in what the SkPicture says is the
// drawn-to area. This is mostly important for tiles on the right and bottom edges
// as they may go over this area and the picture may have some commands that
// draw outside of this area and so should not actually be written.
- SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
- SkIntToScalar(fPicture->height()));
+ SkRect clip = SkRect::MakeWH(SkIntToScalar(totalWidth), SkIntToScalar(totalHeight));
canvas->clipRect(clip);
return canvas;
}
diff --git a/tools/PictureRenderer.h b/tools/PictureRenderer.h
index 192569c..eda89a0 100644
--- a/tools/PictureRenderer.h
+++ b/tools/PictureRenderer.h
@@ -70,6 +70,11 @@
virtual void init(SkPicture* pict);
/**
+ * Set the viewport so that only the portion listed gets drawn.
+ */
+ void setViewport(SkISize size) { fViewport = size; }
+
+ /**
* Perform any setup that should done prior to each iteration of render() which should not be
* timed.
*/
@@ -168,29 +173,45 @@
#endif
{
sk_bzero(fDrawFilters, sizeof(fDrawFilters));
+ fViewport.set(0, 0);
}
protected:
- void buildBBoxHierarchy();
- SkPicture* createPicture();
- uint32_t recordFlags();
- SkCanvas* setupCanvas();
- virtual SkCanvas* setupCanvas(int width, int height);
-
SkAutoTUnref<SkCanvas> fCanvas;
- SkPicture* fPicture;
- SkDeviceTypes fDeviceType;
- BBoxHierarchyType fBBoxHierarchyType;
- DrawFilterFlags fDrawFilters[SkDrawFilter::kTypeCount];
- SkString fDrawFiltersConfig;
- int fGridWidth, fGridHeight; // used when fBBoxHierarchyType is TileGrid
+ SkPicture* fPicture;
+ SkDeviceTypes fDeviceType;
+ BBoxHierarchyType fBBoxHierarchyType;
+ DrawFilterFlags fDrawFilters[SkDrawFilter::kTypeCount];
+ SkString fDrawFiltersConfig;
+ int fGridWidth, fGridHeight; // used when fBBoxHierarchyType is TileGrid
#if SK_SUPPORT_GPU
GrContextFactory fGrContextFactory;
GrContext* fGrContext;
#endif
+ void buildBBoxHierarchy();
+
+ /**
+ * Return the total width that should be drawn. If the viewport width has been set greater than
+ * 0, this will be the minimum of the current SkPicture's width and the viewport's width.
+ */
+ int getViewWidth();
+
+ /**
+ * Return the total height that should be drawn. If the viewport height has been set greater
+ * than 0, this will be the minimum of the current SkPicture's height and the viewport's height.
+ */
+ int getViewHeight();
+
+ SkPicture* createPicture();
+ uint32_t recordFlags();
+ SkCanvas* setupCanvas();
+ virtual SkCanvas* setupCanvas(int width, int height);
+
private:
+ SkISize fViewport;
+
virtual SkString getConfigNameInternal() = 0;
typedef SkRefCnt INHERITED;
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index 47844f9..ca63807 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -126,6 +126,7 @@
" [--pipe]\n"
" [--bbh bbhType]\n"
" [--multi numThreads]\n"
+" [--viewport width height]\n"
" [--device bitmap"
#if SK_SUPPORT_GPU
" | gpu"
@@ -179,6 +180,7 @@
SkDebugf(
" --multi numThreads : Set the number of threads for multi threaded drawing. Must be greater\n"
" than 1. Only works with tiled rendering.\n"
+" --viewport width height : Set the viewport.\n"
" --pipe: Benchmark SkGPipe rendering. Currently incompatible with \"mode\".\n");
SkDebugf(
" --bbh bbhType [width height]: Set the bounding box hierarchy type to\n"
@@ -289,6 +291,8 @@
sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
sk_tools::PictureRenderer::DrawFilterFlags drawFilters[SkDrawFilter::kTypeCount];
sk_bzero(drawFilters, sizeof(drawFilters));
+ SkISize viewport;
+ viewport.setEmpty();
for (++argv; argv < stop; ++argv) {
if (0 == strcmp(*argv, "--repeat")) {
++argv;
@@ -423,6 +427,19 @@
gLogger.logError(err);
PRINT_USAGE_AND_EXIT;
}
+ } else if (0 == strcmp(*argv, "--viewport")) {
+ ++argv;
+ if (argv >= stop) {
+ gLogger.logError("Missing width for --viewport\n");
+ PRINT_USAGE_AND_EXIT;
+ }
+ viewport.fWidth = atoi(*argv);
+ ++argv;
+ if (argv >= stop) {
+ gLogger.logError("Missing height for --viewport\n");
+ PRINT_USAGE_AND_EXIT;
+ }
+ viewport.fHeight = atoi(*argv);
} else if (0 == strcmp(*argv, "--tiles")) {
++argv;
if (argv >= stop) {
@@ -697,6 +714,7 @@
renderer->setBBoxHierarchyType(bbhType);
renderer->setDrawFilters(drawFilters, filtersName(drawFilters));
renderer->setGridSize(gridWidth, gridHeight);
+ renderer->setViewport(viewport);
benchmark->setRenderer(renderer);
benchmark->setRepeats(repeats);
benchmark->setDeviceType(deviceType);
diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp
index 250058e..d43e1c4 100644
--- a/tools/render_pictures_main.cpp
+++ b/tools/render_pictures_main.cpp
@@ -30,6 +30,7 @@
" | tile width height]\n"
" [--pipe]\n"
" [--multi count]\n"
+" [--viewport width height]\n"
" [--device bitmap"
#if SK_SUPPORT_GPU
" | gpu"
@@ -74,6 +75,7 @@
SkDebugf(
" --multi count : Set the number of threads for multi threaded drawing. Must be greater\n"
" than 1. Only works with tiled rendering.\n"
+" --viewport width height : Set the viewport.\n"
" --pipe: Benchmark SkGPipe rendering. Currently incompatible with \"mode\".\n");
SkDebugf(
" --device bitmap"
@@ -185,7 +187,8 @@
const char* xTilesString = NULL;
const char* yTilesString = NULL;
const char* mode = NULL;
-
+ SkISize viewport;
+ viewport.setEmpty();
for (++argv; argv < stop; ++argv) {
if (0 == strcmp(*argv, "--mode")) {
if (renderer != NULL) {
@@ -237,6 +240,21 @@
usage(argv0);
exit(-1);
}
+ } else if (0 == strcmp(*argv, "--viewport")) {
+ ++argv;
+ if (argv >= stop) {
+ SkDebugf("Missing width for --viewport\n");
+ usage(argv0);
+ exit(-1);
+ }
+ viewport.fWidth = atoi(*argv);
+ ++argv;
+ if (argv >= stop) {
+ SkDebugf("Missing height for --viewport\n");
+ usage(argv0);
+ exit(-1);
+ }
+ viewport.fHeight = atoi(*argv);
} else if (0 == strcmp(*argv, "--tiles")) {
++argv;
if (argv >= stop) {
@@ -441,6 +459,7 @@
renderer = SkNEW(sk_tools::SimplePictureRenderer);
}
+ renderer->setViewport(viewport);
renderer->setDeviceType(deviceType);
}