diff --git a/tools/CopyTilesRenderer.cpp b/tools/CopyTilesRenderer.cpp index 0df43bbef..e5cbdbd74 100644 --- a/tools/CopyTilesRenderer.cpp +++ b/tools/CopyTilesRenderer.cpp @@ -41,7 +41,12 @@ namespace sk_tools { 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)); + // 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(fCanvas->getTotalMatrix()); + mat.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); + fCanvas->setMatrix(mat); // Draw the picture fCanvas->drawPicture(*fPicture); // Now extract the picture into tiles diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp index 32c19e877..102216d59 100644 --- a/tools/PictureRenderer.cpp +++ b/tools/PictureRenderer.cpp @@ -87,14 +87,13 @@ private: PictureRenderer::DrawFilterFlags* fFlags; }; -static SkCanvas* setUpFilter(SkCanvas* canvas, PictureRenderer::DrawFilterFlags* drawFilters) { +static void setUpFilter(SkCanvas* canvas, PictureRenderer::DrawFilterFlags* drawFilters) { if (drawFilters && !canvas->getDrawFilter()) { canvas->setDrawFilter(SkNEW_ARGS(FlagsDrawFilter, (drawFilters)))->unref(); if (drawFilters[0] & PictureRenderer::kAAClip_DrawFilterFlag) { canvas->setAllowSoftClip(false); } } - return canvas; } SkCanvas* PictureRenderer::setupCanvas() { @@ -110,22 +109,31 @@ SkCanvas* PictureRenderer::setupCanvas(int width, int height) { SkBitmap bitmap; sk_tools::setup_bitmap(&bitmap, width, height); canvas = SkNEW_ARGS(SkCanvas, (bitmap)); - return setUpFilter(canvas, fDrawFilters); } + break; #if SK_SUPPORT_GPU case kGPU_DeviceType: { SkAutoTUnref device(SkNEW_ARGS(SkGpuDevice, (fGrContext, SkBitmap::kARGB_8888_Config, width, height))); canvas = SkNEW_ARGS(SkCanvas, (device.get())); - return setUpFilter(canvas, fDrawFilters); } + break; #endif default: SkASSERT(0); + return NULL; } + setUpFilter(canvas, fDrawFilters); + this->scaleToScaleFactor(canvas); + return canvas; +} - return NULL; +void PictureRenderer::scaleToScaleFactor(SkCanvas* canvas) { + SkASSERT(canvas != NULL); + if (fScaleFactor != SK_Scalar1) { + canvas->scale(fScaleFactor, fScaleFactor); + } } void PictureRenderer::end() { @@ -243,8 +251,9 @@ static bool PNGEncodeBitmapToStream(SkWStream* wStream, const SkBitmap& bm) { bool RecordPictureRenderer::render(const SkString* path) { SkAutoTUnref replayer(this->createPicture()); - SkCanvas* recorder = replayer->beginRecording(fPicture->width(), fPicture->height(), + SkCanvas* recorder = replayer->beginRecording(this->getViewWidth(), this->getViewHeight(), this->recordFlags()); + this->scaleToScaleFactor(recorder); fPicture->draw(recorder); replayer->endRecording(); if (path != NULL) { @@ -452,8 +461,11 @@ void TiledPictureRenderer::setupPowerOf2Tiles() { template static void DrawTileToCanvas(SkCanvas* canvas, const SkRect& tileRect, T* playback) { int saveCount = canvas->save(); - // Translate so that we draw the correct portion of the picture - canvas->translate(-tileRect.fLeft, -tileRect.fTop); + // 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); + canvas->setMatrix(mat); playback->draw(canvas); canvas->restoreToCount(saveCount); canvas->flush(); @@ -494,14 +506,15 @@ bool TiledPictureRenderer::render(const SkString* path) { 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(totalWidth), SkIntToScalar(totalHeight)); - canvas->clipRect(clip); + // Clip the tile to an area that is completely inside both the SkPicture and the viewport. 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. + // Uses a clipRegion so that it will be unaffected by the scale factor, which may have been set + // by INHERITED::setupCanvas. + SkRegion clipRegion; + clipRegion.setRect(0, 0, this->getViewWidth(), this->getViewHeight()); + canvas->clipRegion(clipRegion); return canvas; } @@ -660,8 +673,9 @@ SkString MultiCorePictureRenderer::getConfigNameInternal() { void PlaybackCreationRenderer::setup() { fReplayer.reset(this->createPicture()); - SkCanvas* recorder = fReplayer->beginRecording(fPicture->width(), fPicture->height(), + SkCanvas* recorder = fReplayer->beginRecording(this->getViewWidth(), this->getViewHeight(), this->recordFlags()); + this->scaleToScaleFactor(recorder); fPicture->draw(recorder); } diff --git a/tools/PictureRenderer.h b/tools/PictureRenderer.h index 284f0684f..ada7bd422 100644 --- a/tools/PictureRenderer.h +++ b/tools/PictureRenderer.h @@ -77,6 +77,11 @@ public: */ void setViewport(SkISize size) { fViewport = size; } + /** + * Set the scale factor at which draw the picture. + */ + void setScaleFactor(SkScalar scale) { fScaleFactor = scale; } + /** * Perform any setup that should done prior to each iteration of render() which should not be * timed. @@ -180,6 +185,7 @@ public: , fBBoxHierarchyType(kNone_BBoxHierarchyType) , fGridWidth(0) , fGridHeight(0) + , fScaleFactor(SK_Scalar1) #if SK_SUPPORT_GPU , fGrContext(fGrContextFactory.get(GrContextFactory::kNative_GLContextType)) #endif @@ -216,6 +222,11 @@ protected: */ int getViewHeight(); + /** + * Scales the provided canvas to the scale factor set by setScaleFactor. + */ + void scaleToScaleFactor(SkCanvas*); + SkPicture* createPicture(); uint32_t recordFlags(); SkCanvas* setupCanvas(); @@ -223,6 +234,7 @@ protected: private: SkISize fViewport; + SkScalar fScaleFactor; virtual SkString getConfigNameInternal() = 0; diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp index 0bfbb2841..3e3bc33ad 100644 --- a/tools/bench_pictures_main.cpp +++ b/tools/bench_pictures_main.cpp @@ -126,7 +126,7 @@ static void usage(const char* argv0) { " [--pipe]\n" " [--bbh bbhType]\n" " [--multi numThreads]\n" -" [--viewport width height]\n" +" [--viewport width height][--scale sf]\n" " [--device bitmap" #if SK_SUPPORT_GPU " | gpu" @@ -184,6 +184,7 @@ static void usage(const char* argv0) { " --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" +" --scale sf : Scale drawing by sf.\n" " --pipe: Benchmark SkGPipe rendering. Currently incompatible with \"mode\".\n"); SkDebugf( " --bbh bbhType [width height]: Set the bounding box hierarchy type to\n" @@ -296,6 +297,7 @@ static void parse_commandline(int argc, char* const argv[], SkTArray* sk_bzero(drawFilters, sizeof(drawFilters)); SkISize viewport; viewport.setEmpty(); + SkScalar scaleFactor = SK_Scalar1; for (++argv; argv < stop; ++argv) { if (0 == strcmp(*argv, "--repeat")) { ++argv; @@ -443,6 +445,13 @@ static void parse_commandline(int argc, char* const argv[], SkTArray* PRINT_USAGE_AND_EXIT; } viewport.fHeight = atoi(*argv); + } else if (0 == strcmp(*argv, "--scale")) { + ++argv; + if (argv >= stop) { + gLogger.logError("Missing scaleFactor for --scale\n"); + PRINT_USAGE_AND_EXIT; + } + scaleFactor = atof(*argv); } else if (0 == strcmp(*argv, "--tiles")) { ++argv; if (argv >= stop) { @@ -730,6 +739,7 @@ static void parse_commandline(int argc, char* const argv[], SkTArray* renderer->setDrawFilters(drawFilters, filtersName(drawFilters)); renderer->setGridSize(gridWidth, gridHeight); renderer->setViewport(viewport); + renderer->setScaleFactor(scaleFactor); benchmark->setRenderer(renderer); benchmark->setRepeats(repeats); benchmark->setDeviceType(deviceType); diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp index d43e1c439..3a58eeaaf 100644 --- a/tools/render_pictures_main.cpp +++ b/tools/render_pictures_main.cpp @@ -30,7 +30,7 @@ static void usage(const char* argv0) { " | tile width height]\n" " [--pipe]\n" " [--multi count]\n" -" [--viewport width height]\n" +" [--viewport width height][--scale sf]\n" " [--device bitmap" #if SK_SUPPORT_GPU " | gpu" @@ -76,6 +76,7 @@ static void usage(const char* argv0) { " --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" +" --scale sf : Scale drawing by sf.\n" " --pipe: Benchmark SkGPipe rendering. Currently incompatible with \"mode\".\n"); SkDebugf( " --device bitmap" @@ -189,6 +190,7 @@ static void parse_commandline(int argc, char* const argv[], SkTArray* const char* mode = NULL; SkISize viewport; viewport.setEmpty(); + SkScalar scaleFactor = SK_Scalar1; for (++argv; argv < stop; ++argv) { if (0 == strcmp(*argv, "--mode")) { if (renderer != NULL) { @@ -255,6 +257,14 @@ static void parse_commandline(int argc, char* const argv[], SkTArray* exit(-1); } viewport.fHeight = atoi(*argv); + } else if (0 == strcmp(*argv, "--scale")) { + ++argv; + if (argv >= stop) { + SkDebugf("Missing scaleFactor for --scale\n"); + usage(argv0); + exit(-1); + } + scaleFactor = atof(*argv); } else if (0 == strcmp(*argv, "--tiles")) { ++argv; if (argv >= stop) { @@ -460,6 +470,7 @@ static void parse_commandline(int argc, char* const argv[], SkTArray* } renderer->setViewport(viewport); + renderer->setScaleFactor(scaleFactor); renderer->setDeviceType(deviceType); }