Allow Srcs to veto Sinks based on their broad type.

This breaks Sinks down into three auto-detected types:
  - GPU:    anything that requests to be run in the GPU enclave
  - Vector: anything that writes to the stream instead of the bitmap
  - Raster: everything else

Some examples: gpu -> GPU, msaa16 -> GPU, 8888 -> raster, pdf -> vector,
               svg -> vector, pipe-8888 -> raster, tiles_rt-gpu -> GPU

This lets image decoding sinks veto non-raster backends explicitly,
and can let particular GMs veto GPU or non-GPU sinks as they like.

BUG=skia:

Review URL: https://codereview.chromium.org/1239953004
This commit is contained in:
mtklein 2015-07-29 06:37:28 -07:00 committed by Commit bot
parent 636e8024f8
commit e0effd6080
5 changed files with 57 additions and 120 deletions

View File

@ -165,16 +165,21 @@ static void gather_uninteresting_hashes() {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
template <typename T>
struct Tagged : public SkAutoTDelete<T> {
const char* tag;
const char* options;
struct TaggedSrc : public SkAutoTDelete<Src> {
const char* tag;
const char* options;
};
struct TaggedSink : public SkAutoTDelete<Sink> {
const char* tag;
const char* options;
SinkType type;
};
static const bool kMemcpyOK = true;
static SkTArray<Tagged<Src>, kMemcpyOK> gSrcs;
static SkTArray<Tagged<Sink>, kMemcpyOK> gSinks;
static SkTArray<TaggedSrc, kMemcpyOK> gSrcs;
static SkTArray<TaggedSink, kMemcpyOK> gSinks;
static bool in_shard() {
static int N = 0;
@ -186,7 +191,7 @@ static void push_src(const char* tag, const char* options, Src* s) {
if (in_shard() &&
FLAGS_src.contains(tag) &&
!SkCommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) {
Tagged<Src>& s = gSrcs.push_back();
TaggedSrc& s = gSrcs.push_back();
s.reset(src.detach());
s.tag = tag;
s.options = options;
@ -334,25 +339,33 @@ static void push_sink(const char* tag, Sink* s) {
if (!FLAGS_config.contains(tag)) {
return;
}
// Try a noop Src as a canary. If it fails, skip this sink.
// Try a simple Src as a canary. If it fails, skip this sink.
struct : public Src {
Error draw(SkCanvas*) const override { return ""; }
Error draw(SkCanvas* c) const override {
c->drawRect(SkRect::MakeWH(1,1), SkPaint());
return "";
}
SkISize size() const override { return SkISize::Make(16, 16); }
Name name() const override { return "noop"; }
} noop;
Name name() const override { return "justOneRect"; }
} justOneRect;
SkBitmap bitmap;
SkDynamicMemoryWStream stream;
SkString log;
Error err = sink->draw(noop, &bitmap, &stream, &log);
Error err = sink->draw(justOneRect, &bitmap, &stream, &log);
if (err.isFatal()) {
SkDebugf("Could not run %s: %s\n", tag, err.c_str());
exit(1);
}
Tagged<Sink>& ts = gSinks.push_back();
SinkType type = kRaster_SinkType;
if (sink->enclave() == kGPU_Enclave) { type = kGPU_SinkType; }
if (stream.bytesWritten() > 0) { type = kVector_SinkType; }
TaggedSink& ts = gSinks.push_back();
ts.reset(sink.detach());
ts.tag = tag;
ts.type = type;
}
static bool gpu_supported() {
@ -477,22 +490,28 @@ static ImplicitString is_blacklisted(const char* sink, const char* src,
// The finest-grained unit of work we can run: draw a single Src into a single Sink,
// report any errors, and perhaps write out the output: a .png of the bitmap, or a raw stream.
struct Task {
Task(const Tagged<Src>& src, const Tagged<Sink>& sink) : src(src), sink(sink) {}
const Tagged<Src>& src;
const Tagged<Sink>& sink;
Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {}
const TaggedSrc& src;
const TaggedSink& sink;
static void Run(Task* task) {
SkString name = task->src->name();
SkString note;
// We'll skip drawing this Src/Sink pair if:
// - the Src vetoes the Sink;
// - this Src / Sink combination is on the blacklist;
// - it's a dry run.
SkString note(task->src->veto(task->sink.type) ? " (veto)" : "");
SkString whyBlacklisted = is_blacklisted(task->sink.tag, task->src.tag,
task->src.options, name.c_str());
if (!whyBlacklisted.isEmpty()) {
note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
}
SkString log;
WallTimer timer;
timer.start();
if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) {
if (!FLAGS_dryRun && note.isEmpty()) {
SkBitmap bitmap;
SkDynamicMemoryWStream stream;
if (FLAGS_pre_log) {

View File

@ -71,14 +71,14 @@ CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType, float scale)
, fScale(scale)
{}
Error CodecSrc::draw(SkCanvas* canvas) const {
SkImageInfo canvasInfo;
if (NULL == canvas->peekPixels(&canvasInfo, NULL)) {
// TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a deferred decode to
// let the GPU handle it.
return Error::Nonfatal("No need to test decoding to non-raster backend.");
}
bool CodecSrc::veto(SinkType type) const {
// No need to test decoding to non-raster backend.
// TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a deferred decode to
// let the GPU handle it.
return type != kRaster_SinkType;
}
Error CodecSrc::draw(SkCanvas* canvas) const {
SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
if (!encoded) {
return SkStringPrintf("Couldn't read %s.", fPath.c_str());
@ -90,7 +90,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
// Choose the color type to decode to
SkImageInfo decodeInfo = codec->getInfo();
SkColorType canvasColorType = canvasInfo.colorType();
SkColorType canvasColorType = canvas->imageInfo().colorType();
switch (fDstColorType) {
case kIndex8_Always_DstColorType:
decodeInfo = codec->getInfo().makeColorType(kIndex_8_SkColorType);
@ -459,18 +459,18 @@ Name CodecSrc::name() const {
ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {}
Error ImageSrc::draw(SkCanvas* canvas) const {
SkImageInfo canvasInfo;
if (NULL == canvas->peekPixels(&canvasInfo, NULL)) {
// TODO: Instead, use lazy decoding to allow the GPU to handle cases like YUV.
return Error::Nonfatal("No need to test decoding to non-raster backend.");
}
bool ImageSrc::veto(SinkType type) const {
// No need to test decoding to non-raster backend.
// TODO: Instead, use lazy decoding to allow the GPU to handle cases like YUV.
return type != kRaster_SinkType;
}
Error ImageSrc::draw(SkCanvas* canvas) const {
SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
if (!encoded) {
return SkStringPrintf("Couldn't read %s.", fPath.c_str());
}
const SkColorType dstColorType = canvasInfo.colorType();
const SkColorType dstColorType = canvas->imageInfo().colorType();
if (fDivisor == 0) {
// Decode the full image.
SkBitmap bitmap;

View File

@ -53,6 +53,8 @@ private:
bool fFatal;
};
enum SinkType { kGPU_SinkType, kVector_SinkType, kRaster_SinkType };
struct Src {
// All Srcs must be thread safe.
virtual ~Src() {}
@ -60,6 +62,7 @@ struct Src {
virtual SkISize size() const = 0;
virtual Name name() const = 0;
virtual void modifyGrContextOptions(GrContextOptions* options) const {}
virtual bool veto(SinkType) const { return false; }
};
struct Sink {
@ -111,6 +114,7 @@ public:
Error draw(SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkType) const override;
private:
Path fPath;
Mode fMode;
@ -128,6 +132,7 @@ public:
Error draw(SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkType) const override;
private:
Path fPath;
const int fDivisor;

View File

@ -20,14 +20,6 @@
"gm",
"image",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -178,14 +170,6 @@
"--threads",
"0",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -309,14 +293,6 @@
"--threads",
"0",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -438,14 +414,6 @@
"tests",
"gm",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -568,14 +536,6 @@
"tests",
"gm",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -694,14 +654,6 @@
"gm",
"image",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -834,14 +786,6 @@
"gm",
"image",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -972,14 +916,6 @@
"gm",
"image",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -1133,14 +1069,6 @@
"tests",
"gm",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",
@ -1294,14 +1222,6 @@
"tests",
"gm",
"--blacklist",
"msaa",
"image",
"_",
"_",
"gpu",
"_",
"_",
"PANO_20121023_214540.jpg",
"_",
"image",
"decode",

View File

@ -81,13 +81,6 @@ def get_args(bot):
blacklist = []
# We do not draw image sources on msaa anyway, so avoid the creation of
# large canvases. skbug.com/4045
blacklist.extend('msaa image _ _'.split(' '))
# This image is too large to be a texture for many GPUs.
blacklist.extend('gpu _ _ PANO_20121023_214540.jpg'.split(' '))
# Several of the newest version bmps fail on SkImageDecoder
blacklist.extend('_ image decode pal8os2v2.bmp'.split(' '))
blacklist.extend('_ image decode pal8v4.bmp'.split(' '))