From 90b5a2a653b312ff9bcd7102412da2dbeb52368c Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 14 May 2014 17:55:32 +0000 Subject: DM: Add --skps. This does render_pictures, plus checks SkRecord optimizations. Disable an SkRecord optimization that draws several bot SKPs wrong. (To be investigated.) BUG=skia:2378 R=reed@google.com, mtklein@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/270543004 git-svn-id: http://skia.googlecode.com/svn/trunk@14739 2bbb7eff-a529-9590-31e7-b0007b416f81 --- dm/DM.cpp | 33 +++++++++++++++++++++++++++++++++ dm/DMCpuGMTask.cpp | 14 +++++++------- dm/DMPipeTask.cpp | 18 ++++++++---------- dm/DMPipeTask.h | 9 +++++++-- dm/DMRecordTask.cpp | 32 +++++++++++++++++++++++++------- dm/DMRecordTask.h | 13 ++++++++++--- dm/DMReplayTask.cpp | 6 +++--- dm/DMReplayTask.h | 8 ++++++-- dm/DMSKPTask.cpp | 23 +++++++++++++++++++++++ dm/DMSKPTask.h | 30 ++++++++++++++++++++++++++++++ dm/DMUtil.cpp | 8 ++++++-- dm/DMUtil.h | 7 ++++--- dm/DMWriteTask.cpp | 15 ++++++++++----- dm/DMWriteTask.h | 9 +++++++-- 14 files changed, 179 insertions(+), 46 deletions(-) create mode 100644 dm/DMSKPTask.cpp create mode 100644 dm/DMSKPTask.h (limited to 'dm') diff --git a/dm/DM.cpp b/dm/DM.cpp index becdc50bcd..f4eefa685c 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -5,6 +5,7 @@ #include "SkCommandLineFlags.h" #include "SkForceLinking.h" #include "SkGraphics.h" +#include "SkPicture.h" #include "SkString.h" #include "Test.h" #include "gm.h" @@ -14,6 +15,7 @@ #include "DMGpuGMTask.h" #include "DMGpuSupport.h" #include "DMReporter.h" +#include "DMSKPTask.h" #include "DMTask.h" #include "DMTaskRunner.h" #include "DMTestTask.h" @@ -43,6 +45,7 @@ DEFINE_string(match, "", "[~][^]substring[$] [...] of GM name to run.\n" DEFINE_string(config, "565 8888 gpu nonrendering", "Options: 565 8888 gpu nonrendering msaa4 msaa16 nvprmsaa4 nvprmsaa16 gpunull gpudebug angle mesa"); DEFINE_bool(leaks, false, "Print leaked instance-counted objects at exit?"); +DEFINE_string(skps, "", "Directory to read skps from."); DEFINE_bool(gms, true, "Run GMs?"); DEFINE_bool(benches, true, "Run benches? Does not run GMs-as-benches."); @@ -143,6 +146,35 @@ static void kick_off_tests(const SkTDArray& tests, } } +static void kick_off_skps(DM::Reporter* reporter, DM::TaskRunner* tasks) { + if (FLAGS_skps.isEmpty()) { + return; + } + + SkOSFile::Iter it(FLAGS_skps[0], ".skp"); + SkString filename; + while (it.next(&filename)) { + if (SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) { + continue; + } + + const SkString path = SkOSPath::SkPathJoin(FLAGS_skps[0], filename.c_str()); + + SkAutoTDelete stream(SkStream::NewFromFile(path.c_str())); + if (stream.get() == NULL) { + SkDebugf("Could not read %s.\n", path.c_str()); + exit(1); + } + SkAutoTUnref pic(SkPicture::CreateFromStream(stream.get())); + if (pic.get() == NULL) { + SkDebugf("Could not read %s as an SkPicture.\n", path.c_str()); + exit(1); + } + + tasks->add(SkNEW_ARGS(DM::SKPTask, (reporter, tasks, pic.detach(), filename))); + } +} + static void report_failures(const DM::Reporter& reporter) { SkTArray failures; reporter.getFailures(&failures); @@ -215,6 +247,7 @@ int tool_main(int argc, char** argv) { kick_off_gms(gms, configs, *expectations, &reporter, &tasks); kick_off_benches(benches, configs, &reporter, &tasks); kick_off_tests(tests, &reporter, &tasks); + kick_off_skps(&reporter, &tasks); tasks.wait(); SkDebugf("\n"); diff --git a/dm/DMCpuGMTask.cpp b/dm/DMCpuGMTask.cpp index 071697b8c4..eb7ed99048 100644 --- a/dm/DMCpuGMTask.cpp +++ b/dm/DMCpuGMTask.cpp @@ -36,14 +36,14 @@ void CpuGMTask::draw() { #define SPAWN(ChildTask, ...) this->spawnChild(SkNEW_ARGS(ChildTask, (*this, __VA_ARGS__))) SPAWN(ExpectationsTask, fExpectations, bitmap); - SPAWN(PipeTask, fGMFactory(NULL), bitmap, false, false); - SPAWN(PipeTask, fGMFactory(NULL), bitmap, true, false); - SPAWN(PipeTask, fGMFactory(NULL), bitmap, true, true); + SPAWN(PipeTask, fGMFactory(NULL), bitmap, PipeTask::kInProcess_Mode); + SPAWN(PipeTask, fGMFactory(NULL), bitmap, PipeTask::kCrossProcess_Mode); + SPAWN(PipeTask, fGMFactory(NULL), bitmap, PipeTask::kSharedAddress_Mode); SPAWN(QuiltTask, fGMFactory(NULL), bitmap); - SPAWN(RecordTask, fGMFactory(NULL), bitmap, true); - SPAWN(RecordTask, fGMFactory(NULL), bitmap, false); - SPAWN(ReplayTask, fGMFactory(NULL), bitmap, false); - SPAWN(ReplayTask, fGMFactory(NULL), bitmap, true); + SPAWN(RecordTask, fGMFactory(NULL), bitmap, RecordTask::kOptimize_Mode); + SPAWN(RecordTask, fGMFactory(NULL), bitmap, RecordTask::kNoOptimize_Mode); + SPAWN(ReplayTask, fGMFactory(NULL), bitmap, ReplayTask::kNormal_Mode); + SPAWN(ReplayTask, fGMFactory(NULL), bitmap, ReplayTask::kRTree_Mode); SPAWN(SerializeTask, fGMFactory(NULL), bitmap); SPAWN(WriteTask, bitmap); diff --git a/dm/DMPipeTask.cpp b/dm/DMPipeTask.cpp index 513594e0ea..13636d67d6 100644 --- a/dm/DMPipeTask.cpp +++ b/dm/DMPipeTask.cpp @@ -10,14 +10,13 @@ DEFINE_bool(pipe, true, "If true, check several pipe variants against the refere namespace DM { -static uint32_t get_flags(bool crossProcess, bool sharedAddressSpace) { - SkASSERT(!(!crossProcess && sharedAddressSpace)); +static uint32_t get_flags(PipeTask::Mode mode) { uint32_t flags = 0; - if (crossProcess) { + if (mode != PipeTask::kInProcess_Mode) { flags |= SkGPipeWriter::kCrossProcess_Flag; - if (sharedAddressSpace) { - flags |= SkGPipeWriter::kSharedAddressSpace_Flag; - } + } + if (mode == PipeTask::kSharedAddress_Mode) { + flags |= SkGPipeWriter::kSharedAddressSpace_Flag; } return flags; } @@ -25,7 +24,7 @@ static uint32_t get_flags(bool crossProcess, bool sharedAddressSpace) { static const char* get_name(const uint32_t flags) { if (flags & SkGPipeWriter::kCrossProcess_Flag && flags & SkGPipeWriter::kSharedAddressSpace_Flag) { - return "cross_process_shared_address_space_pipe"; + return "shared_address_space_pipe"; } else if (flags & SkGPipeWriter::kCrossProcess_Flag) { return "cross_process_pipe"; } else { @@ -36,10 +35,9 @@ static const char* get_name(const uint32_t flags) { PipeTask::PipeTask(const Task& parent, skiagm::GM* gm, SkBitmap reference, - bool crossProcess, - bool sharedAddressSpace) + Mode mode) : CpuTask(parent) - , fFlags(get_flags(crossProcess, sharedAddressSpace)) + , fFlags(get_flags(mode)) , fName(UnderJoin(parent.name().c_str(), get_name(fFlags))) , fGM(gm) , fReference(reference) diff --git a/dm/DMPipeTask.h b/dm/DMPipeTask.h index c251d08328..bca74e0b0c 100644 --- a/dm/DMPipeTask.h +++ b/dm/DMPipeTask.h @@ -14,11 +14,16 @@ namespace DM { class PipeTask : public CpuTask { public: + enum Mode { + kInProcess_Mode, + kCrossProcess_Mode, + kSharedAddress_Mode, + }; + PipeTask(const Task& parent, // PipeTask must be a child task. Pass its parent here. skiagm::GM*, // GM to run through a pipe. Takes ownership. SkBitmap reference, // Bitmap to compare pipe results to. - bool crossProcess, // Should we set up a cross process pipe? - bool sharedAddressSpace); // If cross process, should it assume shared address space? + Mode); virtual void draw() SK_OVERRIDE; virtual bool shouldSkip() const SK_OVERRIDE; diff --git a/dm/DMRecordTask.cpp b/dm/DMRecordTask.cpp index 531fe57f94..ce27aaa6f9 100644 --- a/dm/DMRecordTask.cpp +++ b/dm/DMRecordTask.cpp @@ -11,21 +11,35 @@ DEFINE_bool(skr, true, "If true, run SKR tests."); namespace DM { -RecordTask::RecordTask(const Task& parent, skiagm::GM* gm, SkBitmap reference, bool optimize) +RecordTask::RecordTask(const Task& parent, skiagm::GM* gm, SkBitmap reference, Mode mode) : CpuTask(parent) - , fName(UnderJoin(parent.name().c_str(), optimize ? "skr" : "skr-noopt")) + , fOptimize(mode == kOptimize_Mode) + , fName(UnderJoin(parent.name().c_str(), fOptimize ? "skr" : "skr-noopt")) , fGM(gm) , fReference(reference) - , fOptimize(optimize) + {} + +RecordTask::RecordTask(const Task& parent, SkPicture* pic, SkBitmap reference, Mode mode) + : CpuTask(parent) + , fOptimize(mode == kOptimize_Mode) + , fName(UnderJoin(parent.name().c_str(), fOptimize ? "skr" : "skr-noopt")) + , fPicture(SkRef(pic)) + , fReference(reference) {} void RecordTask::draw() { - // Record the GM into an SkRecord. + // Record into an SkRecord. SkRecord record; SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, fReference.width(), fReference.height()); - recorder.concat(fGM->getInitialTransform()); - fGM->draw(&recorder); + + if (fGM.get()) { + recorder.concat(fGM->getInitialTransform()); + fGM->draw(&recorder); + } else { + fPicture->draw(&recorder); + } + if (fOptimize) { SkRecordOptimize(&record); @@ -33,7 +47,11 @@ void RecordTask::draw() { // Draw the SkRecord back into a bitmap. SkBitmap bitmap; - SetupBitmap(fReference.colorType(), fGM.get(), &bitmap); + if (fGM.get()) { + SetupBitmap(fReference.colorType(), fGM.get(), &bitmap); + } else { + SetupBitmap(fReference.colorType(), *fPicture, &bitmap); + } SkCanvas target(bitmap); SkRecordDraw(record, &target); diff --git a/dm/DMRecordTask.h b/dm/DMRecordTask.h index 94ac412e42..1420724bb0 100644 --- a/dm/DMRecordTask.h +++ b/dm/DMRecordTask.h @@ -3,28 +3,35 @@ #include "DMTask.h" #include "SkBitmap.h" +#include "SkPicture.h" #include "SkString.h" #include "SkTemplates.h" #include "gm.h" -// Records a GM through an SkRecord, draws it, and compares against the reference bitmap. +// Records a GM or SKP through an SkRecord, draws it, and compares against the reference bitmap. namespace DM { class RecordTask : public CpuTask { public: - RecordTask(const Task& parent, skiagm::GM*, SkBitmap reference, bool optimize); + enum Mode { + kNoOptimize_Mode, + kOptimize_Mode, + }; + RecordTask(const Task& parent, skiagm::GM*, SkBitmap reference, Mode); + RecordTask(const Task& parent, SkPicture*, SkBitmap reference, Mode); virtual void draw() SK_OVERRIDE; virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } private: + bool fOptimize; const SkString fName; + SkAutoTUnref fPicture; SkAutoTDelete fGM; const SkBitmap fReference; - bool fOptimize; }; } // namespace DM diff --git a/dm/DMReplayTask.cpp b/dm/DMReplayTask.cpp index e4a9e4427b..a126f2cfe2 100644 --- a/dm/DMReplayTask.cpp +++ b/dm/DMReplayTask.cpp @@ -14,12 +14,12 @@ namespace DM { ReplayTask::ReplayTask(const Task& parent, skiagm::GM* gm, SkBitmap reference, - bool useRTree) + Mode mode) : CpuTask(parent) - , fName(UnderJoin(parent.name().c_str(), useRTree ? "rtree" : "replay")) + , fUseRTree(mode == kRTree_Mode) + , fName(UnderJoin(parent.name().c_str(), fUseRTree ? "rtree" : "replay")) , fGM(gm) , fReference(reference) - , fUseRTree(useRTree) {} void ReplayTask::draw() { diff --git a/dm/DMReplayTask.h b/dm/DMReplayTask.h index 78bef0dfd8..de28172000 100644 --- a/dm/DMReplayTask.h +++ b/dm/DMReplayTask.h @@ -14,20 +14,24 @@ namespace DM { class ReplayTask : public CpuTask { public: + enum Mode { + kNormal_Mode, + kRTree_Mode, + }; ReplayTask(const Task& parent, // ReplayTask must be a child task. Pass its parent here. skiagm::GM*, // GM to run through a picture. Takes ownership. SkBitmap reference, // Bitmap to compare picture replay results to. - bool useRTree); // Record with an RTree? + Mode); virtual void draw() SK_OVERRIDE; virtual bool shouldSkip() const SK_OVERRIDE; virtual SkString name() const SK_OVERRIDE { return fName; } private: + const bool fUseRTree; const SkString fName; SkAutoTDelete fGM; const SkBitmap fReference; - const bool fUseRTree; }; } // namespace DM diff --git a/dm/DMSKPTask.cpp b/dm/DMSKPTask.cpp new file mode 100644 index 0000000000..3eb4c5d6f1 --- /dev/null +++ b/dm/DMSKPTask.cpp @@ -0,0 +1,23 @@ +#include "DMRecordTask.h" +#include "DMSKPTask.h" +#include "DMUtil.h" +#include "DMWriteTask.h" + +namespace DM { + +SKPTask::SKPTask(Reporter* r, TaskRunner* tr, SkPicture* pic, SkString name) + : CpuTask(r, tr), fPicture(SkRef(pic)), fName(name) {} + +void SKPTask::draw() { + SkBitmap bitmap; + SetupBitmap(kN32_SkColorType, *fPicture, &bitmap); + DrawPicture(fPicture, &bitmap); + + this->spawnChild(SkNEW_ARGS(RecordTask, + (*this, fPicture, bitmap, RecordTask::kNoOptimize_Mode))); + this->spawnChild(SkNEW_ARGS(RecordTask, + (*this, fPicture, bitmap, RecordTask::kOptimize_Mode))); + this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap, WriteTask::kVerbatim_Mode))); +} + +} // namespace DM diff --git a/dm/DMSKPTask.h b/dm/DMSKPTask.h new file mode 100644 index 0000000000..ef465af06a --- /dev/null +++ b/dm/DMSKPTask.h @@ -0,0 +1,30 @@ +#ifndef DMSKPTask_DEFINED +#define DMSKPTask_DEFINED + +#include "DMReporter.h" +#include "DMTask.h" +#include "DMTaskRunner.h" +#include "SkPicture.h" +#include "SkString.h" +#include "SkTemplates.h" + +// Draws an SKP to a raster canvas, then compares it with some other modes. + +namespace DM { + +class SKPTask : public CpuTask { +public: + SKPTask(Reporter*, TaskRunner*, SkPicture*, SkString name); + + virtual void draw() SK_OVERRIDE; + virtual bool shouldSkip() const SK_OVERRIDE { return false; } + virtual SkString name() const SK_OVERRIDE { return fName; } + +private: + SkAutoTUnref fPicture; + const SkString fName; +}; + +} // namespace DM + +#endif // DMSKPTask_DEFINED diff --git a/dm/DMUtil.cpp b/dm/DMUtil.cpp index 9a4765abb0..5c7517147a 100644 --- a/dm/DMUtil.cpp +++ b/dm/DMUtil.cpp @@ -26,14 +26,18 @@ static void setup_bitmap(SkColorType ct, int width, int height, SkBitmap* bitmap bitmap->eraseColor(0x00000000); } -void SetupBitmap(const SkColorType ct, skiagm::GM* gm, SkBitmap* bitmap) { +void SetupBitmap(SkColorType ct, skiagm::GM* gm, SkBitmap* bitmap) { setup_bitmap(ct, gm->getISize().width(), gm->getISize().height(), bitmap); } -void SetupBitmap(const SkColorType ct, SkBenchmark* bench, SkBitmap* bitmap) { +void SetupBitmap(SkColorType ct, SkBenchmark* bench, SkBitmap* bitmap) { setup_bitmap(ct, bench->getSize().x(), bench->getSize().y(), bitmap); } +void SetupBitmap(SkColorType ct, const SkPicture& pic, SkBitmap* bitmap) { + setup_bitmap(ct, pic.width(), pic.height(), bitmap); +} + void DrawPicture(SkPicture* picture, SkBitmap* bitmap) { SkASSERT(picture != NULL); SkASSERT(bitmap != NULL); diff --git a/dm/DMUtil.h b/dm/DMUtil.h index 1145f28221..c2083ba0cb 100644 --- a/dm/DMUtil.h +++ b/dm/DMUtil.h @@ -20,10 +20,11 @@ SkPicture* RecordPicture(skiagm::GM* gm, uint32_t recordFlags = 0, SkBBHFactory* factory = NULL); -// Prepare bitmap to have gm or bench draw into it with this config. +// Prepare bitmap to have gm, bench or picture draw into it with this config. // TODO(mtklein): make SkBenchmark::getSize()/GM::getISize() const. -void SetupBitmap(const SkColorType, skiagm::GM* gm, SkBitmap* bitmap); -void SetupBitmap(const SkColorType, SkBenchmark* bench, SkBitmap* bitmap); +void SetupBitmap(SkColorType, skiagm::GM* gm, SkBitmap* bitmap); +void SetupBitmap(SkColorType, SkBenchmark* bench, SkBitmap* bitmap); +void SetupBitmap(SkColorType, const SkPicture& picture, SkBitmap* bitmap); // Draw picture to bitmap. void DrawPicture(SkPicture* picture, SkBitmap* bitmap); diff --git a/dm/DMWriteTask.cpp b/dm/DMWriteTask.cpp index f7fa014ea4..cfac4152e3 100644 --- a/dm/DMWriteTask.cpp +++ b/dm/DMWriteTask.cpp @@ -26,11 +26,16 @@ static int split_suffixes(int N, const char* name, SkTArray* out) { return consumed; } -WriteTask::WriteTask(const Task& parent, SkBitmap bitmap) : CpuTask(parent), fBitmap(bitmap) { - const int suffixes = parent.depth() + 1; - const SkString& name = parent.name(); - const int totalSuffixLength = split_suffixes(suffixes, name.c_str(), &fSuffixes); - fGmName.set(name.c_str(), name.size()-totalSuffixLength); +WriteTask::WriteTask(const Task& parent, SkBitmap bitmap, Mode mode) + : CpuTask(parent), fBitmap(bitmap) { + if (mode == kVerbatim_Mode) { + fGmName.set(parent.name()); + } else { + const int suffixes = parent.depth() + 1; + const SkString& name = parent.name(); + const int totalSuffixLength = split_suffixes(suffixes, name.c_str(), &fSuffixes); + fGmName.set(name.c_str(), name.size()-totalSuffixLength); + } } void WriteTask::makeDirOrFail(SkString dir) { diff --git a/dm/DMWriteTask.h b/dm/DMWriteTask.h index 839abd7ef1..121dc0d13e 100644 --- a/dm/DMWriteTask.h +++ b/dm/DMWriteTask.h @@ -15,8 +15,13 @@ namespace DM { class WriteTask : public CpuTask { public: - WriteTask(const Task& parent, // WriteTask must be a child Task. Pass its parent here. - SkBitmap bitmap); // Bitmap to write. + enum Mode { + kParseName_Mode, // Parse the parent's name into directories by underscores. + kVerbatim_Mode, // Don't parse the name at all. + }; + WriteTask(const Task& parent, // WriteTask must be a child Task. Pass its parent here. + SkBitmap bitmap, // Bitmap to write. + Mode = kParseName_Mode); virtual void draw() SK_OVERRIDE; virtual bool shouldSkip() const SK_OVERRIDE; -- cgit v1.2.3