diff options
author | robertphillips <robertphillips@google.com> | 2014-12-11 13:10:23 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-11 13:10:23 -0800 |
commit | 8c508b441331d75fd84d84092a3e725d15972828 (patch) | |
tree | 74c95c772c90726d3743d9b4122fc2e8e2ca592a | |
parent | 5f975d0fecb5285df57951239d019a4699dfebba (diff) |
Update GM to permit correctness testing of MPD on the GMs
Review URL: https://codereview.chromium.org/794273003
-rw-r--r-- | gm/filterfastbounds.cpp | 8 | ||||
-rw-r--r-- | gm/gmmain.cpp | 232 | ||||
-rw-r--r-- | gm/pictureimagefilter.cpp | 2 |
3 files changed, 158 insertions, 84 deletions
diff --git a/gm/filterfastbounds.cpp b/gm/filterfastbounds.cpp index 6d4d3f1aa2..def7b37833 100644 --- a/gm/filterfastbounds.cpp +++ b/gm/filterfastbounds.cpp @@ -162,10 +162,10 @@ protected: // SkPictureImageFilter doesn't support serialization yet. uint32_t onGetFlags() const SK_OVERRIDE { - return kSkipPicture_Flag | - kSkipPipe_Flag | - kSkipPipeCrossProcess_Flag | - kSkipTiled_Flag | + return kSkipPicture_Flag | + kSkipPipe_Flag | + kSkipPipeCrossProcess_Flag | + kSkipTiled_Flag | kSkipScaledReplay_Flag; } diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp index 46b039d164..da4184db67 100644 --- a/gm/gmmain.cpp +++ b/gm/gmmain.cpp @@ -35,6 +35,7 @@ #include "SkImageDecoder.h" #include "SkImageEncoder.h" #include "SkJSONCPP.h" +#include "SkMultiPictureDraw.h" #include "SkOSFile.h" #include "SkPDFRasterizer.h" #include "SkPicture.h" @@ -481,7 +482,7 @@ public: * (logically a noop for rasters, if wasted time), and thus collapse the * GPU special case and also let this be used for SkPicture testing. */ - static void setup_bitmap(const ConfigData& gRec, SkISize& size, + static void setup_bitmap(const ConfigData& gRec, const SkISize& size, SkBitmap* bitmap) { bitmap->allocPixels(SkImageInfo::Make(size.width(), size.height(), gRec.fColorType, kPremul_SkAlphaType)); @@ -548,7 +549,7 @@ public: force_all_opaque(*bitmap); } - static void installFilter(SkCanvas* canvas); + static void InstallFilter(SkCanvas* canvas); static void invokeGM(GM* gm, SkCanvas* canvas, bool isPDF, bool isDeferred) { SkAutoCanvasRestore acr(canvas, true); @@ -556,7 +557,7 @@ public: if (!isPDF) { canvas->concat(gm->getInitialTransform()); } - installFilter(canvas); + InstallFilter(canvas); gm->setCanvasIsDeferred(isDeferred); gm->draw(canvas); canvas->setDrawFilter(NULL); @@ -566,46 +567,92 @@ public: GrSurface* gpuTarget, SkBitmap* bitmap, bool deferred) { - SkISize size (gm->getISize()); - setup_bitmap(gRec, size, bitmap); - const SkImageInfo info = bitmap->info(); + const SkISize size (gm->getISize()); - SkAutoTUnref<SkSurface> surface; + SkAutoTUnref<SkSurface> surface(CreateSurface(gRec, size, gpuTarget)); SkAutoTUnref<SkCanvas> canvas; - if (gRec.fBackend == kRaster_Backend) { - surface.reset(SkSurface::NewRasterDirect(info, - bitmap->getPixels(), - bitmap->rowBytes())); - if (deferred) { - canvas.reset(SkDeferredCanvas::Create(surface)); - } else { - canvas.reset(SkRef(surface->getCanvas())); - } - invokeGM(gm, canvas, false, deferred); - canvas->flush(); + if (deferred) { + canvas.reset(SkDeferredCanvas::Create(surface)); + } else { + canvas.reset(SkRef(surface->getCanvas())); } -#if SK_SUPPORT_GPU - else { // GPU - uint32_t flags = (gRec.fFlags & kDFText_ConfigFlag) ? - SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0; - SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); - surface.reset(SkSurface::NewRenderTargetDirect(gpuTarget->asRenderTarget(), &props)); - if (deferred) { - canvas.reset(SkDeferredCanvas::Create(surface)); + invokeGM(gm, canvas, false, deferred); + canvas->flush(); + + setup_bitmap(gRec, size, bitmap); + surface->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0); + complete_bitmap(bitmap); + return kEmpty_ErrorCombination; + } + + static void DrawPictureToSurface(SkSurface* surf, + const SkPicture* pict, + SkScalar scale, + bool tile, + bool useMPD) { + SkASSERT(surf->width() == pict->cullRect().width() && + surf->height() == pict->cullRect().height()); + + if (tile) { + SkMultiPictureDraw mpd; + SkTDArray<SkSurface*> surfaces; + + const SkISize tileSize = SkISize::Make(16, 16); + + const SkImageInfo ii = surf->getCanvas()->imageInfo().makeWH(tileSize.width(), + tileSize.height()); + + for (int tileY = 0; tileY < pict->cullRect().height(); tileY += tileSize.height()) { + for (int tileX = 0; tileX < pict->cullRect().width(); tileX += tileSize.width()) { + + *surfaces.append() = surf->getCanvas()->newSurface(ii); + + InstallFilter(surfaces.top()->getCanvas()); + + SkMatrix matrix; + matrix.setTranslate(-pict->cullRect().fLeft, -pict->cullRect().fTop); + matrix.postTranslate(-SkIntToScalar(tileX), -SkIntToScalar(tileY)); + matrix.postScale(scale, scale); + + if (useMPD) { + mpd.add(surfaces.top()->getCanvas(), pict, &matrix, NULL); + } else { + surfaces.top()->getCanvas()->drawPicture(pict, &matrix, NULL); + } + } + } + + mpd.draw(); + + SkPaint gatherPaint; + gatherPaint.setXfermodeMode(SkXfermode::kSrc_Mode); + + int tileIndex = 0; + for (int tileY = 0; tileY < pict->cullRect().height(); tileY += tileSize.height()) { + for (int tileX = 0; tileX < pict->cullRect().width(); tileX += tileSize.width()) { + surf->getCanvas()->drawImage(surfaces[tileIndex]->newImageSnapshot(), + SkIntToScalar(tileX), SkIntToScalar(tileY), + &gatherPaint); + surfaces[tileIndex]->unref(); + tileIndex++; + } + } + } else { + InstallFilter(surf->getCanvas()); + + SkMatrix matrix; + matrix.setTranslate(-pict->cullRect().fLeft, -pict->cullRect().fTop); + matrix.postScale(scale, scale); + + if (useMPD) { + SkMultiPictureDraw mpd; + mpd.add(surf->getCanvas(), pict, &matrix, NULL); + mpd.draw(); } else { - canvas.reset(SkRef(surface->getCanvas())); + surf->getCanvas()->drawPicture(pict, &matrix, NULL); } - invokeGM(gm, canvas, false, deferred); - // the device is as large as the current rendertarget, so - // we explicitly only readback the amount we expect (in - // size) overwrite our previous allocation - bitmap->setInfo(SkImageInfo::MakeN32Premul(size.fWidth, size.fHeight)); - canvas->readPixels(bitmap, 0, 0); } -#endif - complete_bitmap(bitmap); - return kEmpty_ErrorCombination; } static void generate_image_from_picture(GM* gm, const ConfigData& gRec, @@ -615,46 +662,12 @@ public: SkISize size = gm->getISize(); setup_bitmap(gRec, size, bitmap); - if (tile) { - // Generate the result image by rendering to tiles and accumulating - // the results in 'bitmap' - - // This 16x16 tiling matches the settings applied to 'pict' in - // 'generate_new_picture' - SkISize tileSize = SkISize::Make(16, 16); - - SkBitmap tileBM; - setup_bitmap(gRec, tileSize, &tileBM); - SkCanvas tileCanvas(tileBM); - installFilter(&tileCanvas); - - SkCanvas bmpCanvas(*bitmap); - SkPaint bmpPaint; - bmpPaint.setXfermodeMode(SkXfermode::kSrc_Mode); - - for (int yTile = 0; yTile < (size.height()+15)/16; ++yTile) { - for (int xTile = 0; xTile < (size.width()+15)/16; ++xTile) { - int saveCount = tileCanvas.save(); - SkMatrix mat(tileCanvas.getTotalMatrix()); - mat.postTranslate(SkIntToScalar(-xTile*tileSize.width()), - SkIntToScalar(-yTile*tileSize.height())); - tileCanvas.setMatrix(mat); - pict->playback(&tileCanvas); - tileCanvas.flush(); - tileCanvas.restoreToCount(saveCount); - bmpCanvas.drawBitmap(tileBM, - SkIntToScalar(xTile * tileSize.width()), - SkIntToScalar(yTile * tileSize.height()), - &bmpPaint); - } - } - } else { - SkCanvas canvas(*bitmap); - installFilter(&canvas); - canvas.scale(scale, scale); - canvas.drawPicture(pict); - complete_bitmap(bitmap); - } + SkAutoTUnref<SkSurface> surf(SkSurface::NewRasterDirect(bitmap->info(), + bitmap->getPixels(), + bitmap->rowBytes())); + + DrawPictureToSurface(surf, pict, scale, tile, false); + complete_bitmap(bitmap); } static bool generate_pdf(GM* gm, SkDynamicMemoryWStream& pdf) { @@ -1169,6 +1182,52 @@ public: return kEmpty_ErrorCombination; } + static SkSurface* CreateSurface(const ConfigData& config, + const SkISize& size, + GrSurface* gpuTarget) { + if (config.fBackend == kRaster_Backend) { + SkImageInfo ii = SkImageInfo::Make(size.width(), size.height(), + config.fColorType, kPremul_SkAlphaType); + + return SkSurface::NewRaster(ii); + } +#if SK_SUPPORT_GPU + else { + uint32_t flags = (config.fFlags & kDFText_ConfigFlag) ? + SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0; + SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); + return SkSurface::NewRenderTargetDirect(gpuTarget->asRenderTarget(), &props); + } +#endif + + return NULL; + } + + ErrorCombination testMPDDrawing(GM* gm, + const ConfigData& config, + GrSurface* gpuTarget, + const SkBitmap& referenceBitmap) { + SkASSERT(kRaster_Backend == config.fBackend || kGPU_Backend == config.fBackend); + + static const uint32_t kMPDFlags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; + + SkAutoTUnref<SkPicture> pict(generate_new_picture(gm, kRTree_BbhType, kMPDFlags)); + + SkAutoTUnref<SkSurface> surf(CreateSurface(config, gm->getISize(), gpuTarget)); + + DrawPictureToSurface(surf, pict, SK_Scalar1, false, true); + + SkBitmap bitmap; + + setup_bitmap(config, gm->getISize(), &bitmap); + + surf->readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), 0, 0); + complete_bitmap(&bitmap); + + return compare_test_results_to_reference_bitmap( + gm->getName(), config.fName, "-mpd", bitmap, &referenceBitmap); + } + ErrorCombination test_pipe_playback(GM* gm, const ConfigData& gRec, const SkBitmap& referenceBitmap, bool simulateFailure) { const SkString shortNamePlusConfig = make_shortname_plus_config(gm->getName(), @@ -1189,7 +1248,7 @@ public: SkISize size = gm->getISize(); setup_bitmap(gRec, size, &bitmap); SkCanvas canvas(bitmap); - installFilter(&canvas); + InstallFilter(&canvas); // Pass a decoding function so the factory GM (which has an SkBitmap // with encoded data) will not fail playback. PipeController pipeController(&canvas, &SkImageDecoder::DecodeMemory); @@ -1232,7 +1291,7 @@ public: SkISize size = gm->getISize(); setup_bitmap(gRec, size, &bitmap); SkCanvas canvas(bitmap); - installFilter(&canvas); + InstallFilter(&canvas); TiledPipeController pipeController(bitmap, &SkImageDecoder::DecodeMemory); SkGPipeWriter writer; SkCanvas* pipeCanvas = writer.startRecording(&pipeController, @@ -1432,6 +1491,8 @@ DEFINE_string(config, "", configUsage().c_str()); DEFINE_bool(cpu, true, "Allows non-GPU configs to be run. Applied after --config."); DEFINE_string(pdfRasterizers, "default", pdfRasterizerUsage().c_str()); DEFINE_bool(deferred, false, "Exercise the deferred rendering test pass."); +DEFINE_bool(mpd, false, "Exercise MultiPictureDraw."); + DEFINE_bool(dryRun, false, "Don't actually run the tests, just print what would have been done."); DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); @@ -1823,6 +1884,19 @@ ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, gpuTarget)); } + if (FLAGS_mpd && (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBackend)) { + + if (gmFlags & GM::kSkipPicture_Flag) { + gmmain.RecordSkippedTest(shortNamePlusConfig, + renderModeDescriptor, + config.fBackend); + errorsForThisConfig.add(kIntentionallySkipped_ErrorType); + } else if (!(gmFlags & GM::kGPUOnly_Flag)) { + errorsForThisConfig.add(gmmain.testMPDDrawing(gm, config, gpuTarget, + comparisonBitmap)); + } + } + errorsForAllConfigs.add(errorsForThisConfig); } return errorsForAllConfigs; @@ -2486,7 +2560,7 @@ int tool_main(int argc, char** argv) { return (reportError) ? -1 : 0; } -void GMMain::installFilter(SkCanvas* canvas) { +void GMMain::InstallFilter(SkCanvas* canvas) { if (FLAGS_forceBWtext) { canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); } diff --git a/gm/pictureimagefilter.cpp b/gm/pictureimagefilter.cpp index bae94f58f5..5f29a34b79 100644 --- a/gm/pictureimagefilter.cpp +++ b/gm/pictureimagefilter.cpp @@ -102,7 +102,7 @@ protected: } // SkPictureImageFilter doesn't support serialization yet. - virtual uint32_t onGetFlags() const SK_OVERRIDE { + uint32_t onGetFlags() const SK_OVERRIDE { return kSkipPicture_Flag | kSkipPipe_Flag | kSkipPipeCrossProcess_Flag | |