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 TaggedSrc : public SkAutoTDelete<Src> {
struct Tagged : public SkAutoTDelete<T> {
const char* tag; const char* tag;
const char* options; const char* options;
}; };
struct TaggedSink : public SkAutoTDelete<Sink> {
const char* tag;
const char* options;
SinkType type;
};
static const bool kMemcpyOK = true; static const bool kMemcpyOK = true;
static SkTArray<Tagged<Src>, kMemcpyOK> gSrcs; static SkTArray<TaggedSrc, kMemcpyOK> gSrcs;
static SkTArray<Tagged<Sink>, kMemcpyOK> gSinks; static SkTArray<TaggedSink, kMemcpyOK> gSinks;
static bool in_shard() { static bool in_shard() {
static int N = 0; static int N = 0;
@ -186,7 +191,7 @@ static void push_src(const char* tag, const char* options, Src* s) {
if (in_shard() && if (in_shard() &&
FLAGS_src.contains(tag) && FLAGS_src.contains(tag) &&
!SkCommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) { !SkCommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) {
Tagged<Src>& s = gSrcs.push_back(); TaggedSrc& s = gSrcs.push_back();
s.reset(src.detach()); s.reset(src.detach());
s.tag = tag; s.tag = tag;
s.options = options; s.options = options;
@ -334,25 +339,33 @@ static void push_sink(const char* tag, Sink* s) {
if (!FLAGS_config.contains(tag)) { if (!FLAGS_config.contains(tag)) {
return; 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 { 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); } SkISize size() const override { return SkISize::Make(16, 16); }
Name name() const override { return "noop"; } Name name() const override { return "justOneRect"; }
} noop; } justOneRect;
SkBitmap bitmap; SkBitmap bitmap;
SkDynamicMemoryWStream stream; SkDynamicMemoryWStream stream;
SkString log; SkString log;
Error err = sink->draw(noop, &bitmap, &stream, &log); Error err = sink->draw(justOneRect, &bitmap, &stream, &log);
if (err.isFatal()) { if (err.isFatal()) {
SkDebugf("Could not run %s: %s\n", tag, err.c_str()); SkDebugf("Could not run %s: %s\n", tag, err.c_str());
exit(1); 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.reset(sink.detach());
ts.tag = tag; ts.tag = tag;
ts.type = type;
} }
static bool gpu_supported() { 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, // 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. // report any errors, and perhaps write out the output: a .png of the bitmap, or a raw stream.
struct Task { struct Task {
Task(const Tagged<Src>& src, const Tagged<Sink>& sink) : src(src), sink(sink) {} Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {}
const Tagged<Src>& src; const TaggedSrc& src;
const Tagged<Sink>& sink; const TaggedSink& sink;
static void Run(Task* task) { static void Run(Task* task) {
SkString name = task->src->name(); 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, SkString whyBlacklisted = is_blacklisted(task->sink.tag, task->src.tag,
task->src.options, name.c_str()); task->src.options, name.c_str());
if (!whyBlacklisted.isEmpty()) { if (!whyBlacklisted.isEmpty()) {
note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
} }
SkString log; SkString log;
WallTimer timer; WallTimer timer;
timer.start(); timer.start();
if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) { if (!FLAGS_dryRun && note.isEmpty()) {
SkBitmap bitmap; SkBitmap bitmap;
SkDynamicMemoryWStream stream; SkDynamicMemoryWStream stream;
if (FLAGS_pre_log) { if (FLAGS_pre_log) {

View File

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

View File

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

View File

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

View File

@ -81,13 +81,6 @@ def get_args(bot):
blacklist = [] 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 # Several of the newest version bmps fail on SkImageDecoder
blacklist.extend('_ image decode pal8os2v2.bmp'.split(' ')) blacklist.extend('_ image decode pal8os2v2.bmp'.split(' '))
blacklist.extend('_ image decode pal8v4.bmp'.split(' ')) blacklist.extend('_ image decode pal8v4.bmp'.split(' '))