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
This commit is contained in:
parent
ddb9331443
commit
90b5a2a653
33
dm/DM.cpp
33
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<TestRegistry::Factory>& 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<SkStream> stream(SkStream::NewFromFile(path.c_str()));
|
||||
if (stream.get() == NULL) {
|
||||
SkDebugf("Could not read %s.\n", path.c_str());
|
||||
exit(1);
|
||||
}
|
||||
SkAutoTUnref<SkPicture> 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<SkString> 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");
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<SkPicture> fPicture;
|
||||
SkAutoTDelete<skiagm::GM> fGM;
|
||||
const SkBitmap fReference;
|
||||
bool fOptimize;
|
||||
};
|
||||
|
||||
} // namespace DM
|
||||
|
@ -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() {
|
||||
|
@ -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<skiagm::GM> fGM;
|
||||
const SkBitmap fReference;
|
||||
const bool fUseRTree;
|
||||
};
|
||||
|
||||
} // namespace DM
|
||||
|
23
dm/DMSKPTask.cpp
Normal file
23
dm/DMSKPTask.cpp
Normal file
@ -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
|
30
dm/DMSKPTask.h
Normal file
30
dm/DMSKPTask.h
Normal file
@ -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<SkPicture> fPicture;
|
||||
const SkString fName;
|
||||
};
|
||||
|
||||
} // namespace DM
|
||||
|
||||
#endif // DMSKPTask_DEFINED
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -26,11 +26,16 @@ static int split_suffixes(int N, const char* name, SkTArray<SkString>* 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) {
|
||||
|
@ -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;
|
||||
|
@ -38,6 +38,7 @@
|
||||
'../dm/DMReplayTask.cpp',
|
||||
'../dm/DMReporter.cpp',
|
||||
'../dm/DMSerializeTask.cpp',
|
||||
'../dm/DMSKPTask.cpp',
|
||||
'../dm/DMTask.cpp',
|
||||
'../dm/DMTaskRunner.cpp',
|
||||
'../dm/DMTestTask.cpp',
|
||||
|
@ -17,7 +17,8 @@ void SkRecordOptimize(SkRecord* record) {
|
||||
// TODO(mtklein): fuse independent optimizations to reduce number of passes?
|
||||
SkRecordNoopCulls(record);
|
||||
SkRecordNoopSaveRestores(record);
|
||||
SkRecordNoopSaveLayerDrawRestores(record);
|
||||
// TODO(mtklein): figure out why we draw differently and reenable
|
||||
//SkRecordNoopSaveLayerDrawRestores(record);
|
||||
|
||||
SkRecordAnnotateCullingPairs(record);
|
||||
SkRecordReduceDrawPosTextStrength(record); // Helpful to run this before BoundDrawPosTextH.
|
||||
|
Loading…
Reference in New Issue
Block a user