aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2014-12-11 13:10:23 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-12-11 13:10:23 -0800
commit8c508b441331d75fd84d84092a3e725d15972828 (patch)
tree74c95c772c90726d3743d9b4122fc2e8e2ca592a
parent5f975d0fecb5285df57951239d019a4699dfebba (diff)
Update GM to permit correctness testing of MPD on the GMs
-rw-r--r--gm/filterfastbounds.cpp8
-rw-r--r--gm/gmmain.cpp232
-rw-r--r--gm/pictureimagefilter.cpp2
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 |