aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-03-29 12:41:13 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-31 03:03:18 +0000
commite15a7b528ee1a630639f7a69b970237c8d97d308 (patch)
treec898962b3aad9001b59278120f302d2a8948c72a /tools
parente0ff6ab272dcc5c4d6f3b509da7e0e97acada814 (diff)
ok, most features can be vias
This refactors most features out of ok's core into vias: -w --> a .png dumping via, "png", opening the door to other types -m/-s --> a filtering via "filter" Everything now can print a brief help message too. Change-Id: I9e653aab98fd57182a6d458c7a80052130980284 Reviewed-on: https://skia-review.googlesource.com/10509 Reviewed-by: Mike Klein <mtklein@chromium.org> Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/ok.cpp133
-rw-r--r--tools/ok.h17
-rw-r--r--tools/ok_dsts.cpp6
-rw-r--r--tools/ok_srcs.cpp12
-rw-r--r--tools/ok_test.cpp10
-rw-r--r--tools/ok_vias.cpp82
6 files changed, 144 insertions, 116 deletions
diff --git a/tools/ok.cpp b/tools/ok.cpp
index 2d4a5df253..de5727b815 100644
--- a/tools/ok.cpp
+++ b/tools/ok.cpp
@@ -10,21 +10,20 @@
// * ok is entirely opt-in. No more maintaining huge --blacklists.
#include "SkGraphics.h"
-#include "SkOSFile.h"
#include "ok.h"
#include <chrono>
#include <future>
#include <list>
-#include <regex>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
+#include <vector>
#if !defined(__has_include)
#define __has_include(x) 0
#endif
-static thread_local const char* tls_name = "";
+static thread_local const char* tls_currently_running = "";
#if __has_include(<execinfo.h>) && __has_include(<fcntl.h>) && __has_include(<signal.h>)
#include <execinfo.h>
@@ -53,7 +52,7 @@ static thread_local const char* tls_name = "";
#undef CASE
}
log(" while running '");
- log(tls_name);
+ log(tls_currently_running);
log("'\n");
void* stack[128];
@@ -81,7 +80,7 @@ static thread_local const char* tls_name = "";
void ok_log(const char* msg) {
lockf(log_fd, F_LOCK, 0);
log("[");
- log(tls_name);
+ log(tls_currently_running);
log("]\t");
log(msg);
log("\n");
@@ -97,8 +96,6 @@ static thread_local const char* tls_name = "";
}
#endif
-enum class Status { OK, Failed, Crashed, Skipped, None };
-
struct Engine {
virtual ~Engine() {}
virtual bool spawn(std::function<Status(void)>) = 0;
@@ -174,55 +171,54 @@ struct ThreadEngine : Engine {
#endif
struct StreamType {
- const char* name;
+ const char *name, *help;
std::unique_ptr<Stream> (*factory)(Options);
};
static std::vector<StreamType> stream_types;
struct DstType {
- const char* name;
+ const char *name, *help;
std::unique_ptr<Dst> (*factory)(Options);
};
static std::vector<DstType> dst_types;
struct ViaType {
- const char* name;
+ const char *name, *help;
std::unique_ptr<Dst> (*factory)(Options, std::unique_ptr<Dst>);
};
static std::vector<ViaType> via_types;
+template <typename T>
+static std::string help_for(std::vector<T> registered) {
+ std::string help;
+ for (auto r : registered) {
+ help += "\n ";
+ help += r.name;
+ help += ": ";
+ help += r.help;
+ }
+ return help;
+}
+
int main(int argc, char** argv) {
SkGraphics::Init();
setup_crash_handler();
- int jobs {1};
- std::regex match {".*"};
- std::regex search {".*"};
- std::string write_dir {""};
-
+ int jobs{1};
std::unique_ptr<Stream> stream;
- std::function<std::unique_ptr<Dst>(void)> dst_factory;
+ std::function<std::unique_ptr<Dst>(void)> dst_factory = []{
+ // A default Dst that's enough for unit tests and not much else.
+ struct : Dst {
+ Status draw(Src* src) override { return src->draw(nullptr); }
+ sk_sp<SkImage> image() override { return nullptr; }
+ } dst;
+ return move_unique(dst);
+ };
auto help = [&] {
- std::string stream_names, dst_names, via_names;
- for (auto s : stream_types) {
- if (!stream_names.empty()) {
- stream_names += ", ";
- }
- stream_names += s.name;
- }
- for (auto d : dst_types) {
- if (!dst_names.empty()) {
- dst_names += ", ";
- }
- dst_names += d.name;
- }
- for (auto v : via_types) {
- if (!via_names.empty()) {
- via_names += ", ";
- }
- via_names += v.name;
- }
+ std::string stream_help = help_for(stream_types),
+ dst_help = help_for( dst_types),
+ via_help = help_for( via_types);
printf("%s [-j N] [-m regex] [-s regex] [-w dir] [-h] \n"
" src[:k=v,...] dst[:k=v,...] [via[:k=v,...] ...] \n"
@@ -230,23 +226,17 @@ int main(int argc, char** argv) {
" If <0, use -N threads instead. \n"
" If 0, use one thread in one process. \n"
" If 1 (default) or -1, auto-detect N. \n"
- " -m: Run only names matching regex exactly. \n"
- " -s: Run only names matching regex anywhere. \n"
- " -w: If set, write .pngs into dir. \n"
" -h: Print this message and exit. \n"
- " src: content to draw: %s \n"
- " dst: how to draw that content: %s \n"
- " via: front-patches to the dst: %s \n"
- " Some srcs, dsts and vias have options, e.g. skp:dir=skps sw:ct=565 \n",
- argv[0], stream_names.c_str(), dst_names.c_str(), via_names.c_str());
+ " src: content to draw%s \n"
+ " dst: how to draw that content%s \n"
+ " via: wrappers around dst%s \n"
+ " Most srcs, dsts and vias have options, e.g. skp:dir=skps sw:ct=565 \n",
+ argv[0], stream_help.c_str(), dst_help.c_str(), via_help.c_str());
return 1;
};
for (int i = 1; i < argc; i++) {
- if (0 == strcmp("-j", argv[i])) { jobs = atoi(argv[++i]); }
- if (0 == strcmp("-m", argv[i])) { match = argv[++i] ; }
- if (0 == strcmp("-s", argv[i])) { search = argv[++i] ; }
- if (0 == strcmp("-w", argv[i])) { write_dir = argv[++i] ; }
+ if (0 == strcmp("-j", argv[i])) { jobs = atoi(argv[++i]); }
if (0 == strcmp("-h", argv[i])) { return help(); }
for (auto s : stream_types) {
@@ -283,16 +273,6 @@ int main(int argc, char** argv) {
}
}
if (!stream) { return help(); }
- if (!dst_factory) {
- // A default Dst that's enough for unit tests and not much else.
- dst_factory = []{
- struct : Dst {
- bool draw(Src* src) override { return src->draw(nullptr); }
- sk_sp<SkImage> image() override { return nullptr; }
- } dst;
- return move_unique(dst);
- };
- }
std::unique_ptr<Engine> engine;
if (jobs == 0) { engine.reset(new SerialEngine); }
@@ -301,10 +281,6 @@ int main(int argc, char** argv) {
if (jobs == 1) { jobs = std::thread::hardware_concurrency(); }
- if (!write_dir.empty()) {
- sk_mkdir(write_dir.c_str());
- }
-
int ok = 0, failed = 0, crashed = 0, skipped = 0;
auto update_stats = [&](Status s) {
@@ -343,25 +319,10 @@ int main(int argc, char** argv) {
spawn([=] {
std::unique_ptr<Src> src{raw};
- auto name = src->name();
- tls_name = name.c_str();
- if (!std::regex_match (name, match) ||
- !std::regex_search(name, search)) {
- return Status::Skipped;
- }
-
- auto dst = dst_factory();
- if (!dst->draw(src.get())) {
- return Status::Failed;
- }
+ std::string name = src->name();
+ tls_currently_running = name.c_str();
- if (!write_dir.empty()) {
- auto image = dst->image();
- sk_sp<SkData> png{image->encode()};
- SkFILEWStream{(write_dir + "/" + name + ".png").c_str()}
- .write(png->data(), png->size());
- }
- return Status::OK;
+ return dst_factory()->draw(src.get());
});
}
@@ -374,15 +335,17 @@ int main(int argc, char** argv) {
}
-Register::Register(const char* name, std::unique_ptr<Stream> (*factory)(Options)) {
- stream_types.push_back(StreamType{name, factory});
+Register::Register(const char* name, const char* help,
+ std::unique_ptr<Stream> (*factory)(Options)) {
+ stream_types.push_back(StreamType{name, help, factory});
}
-Register::Register(const char* name, std::unique_ptr<Dst> (*factory)(Options)) {
- dst_types.push_back(DstType{name, factory});
+Register::Register(const char* name, const char* help,
+ std::unique_ptr<Dst> (*factory)(Options)) {
+ dst_types.push_back(DstType{name, help, factory});
}
-Register::Register(const char* name,
+Register::Register(const char* name, const char* help,
std::unique_ptr<Dst> (*factory)(Options, std::unique_ptr<Dst>)) {
- via_types.push_back(ViaType{name, factory});
+ via_types.push_back(ViaType{name, help, factory});
}
Options::Options(std::string str) {
diff --git a/tools/ok.h b/tools/ok.h
index 345465bada..f55842b3d9 100644
--- a/tools/ok.h
+++ b/tools/ok.h
@@ -22,11 +22,13 @@ static std::unique_ptr<T> move_unique(T& v) {
void ok_log(const char*);
+enum class Status { OK, Failed, Crashed, Skipped, None };
+
struct Src {
virtual ~Src() {}
- virtual std::string name() = 0;
- virtual SkISize size() = 0;
- virtual bool draw(SkCanvas*) = 0;
+ virtual std::string name() = 0;
+ virtual SkISize size() = 0;
+ virtual Status draw(SkCanvas*) = 0;
};
struct Stream {
@@ -36,7 +38,7 @@ struct Stream {
struct Dst {
virtual ~Dst() {}
- virtual bool draw(Src*) = 0;
+ virtual Status draw(Src*) = 0;
virtual sk_sp<SkImage> image() = 0;
};
@@ -50,9 +52,10 @@ public:
// Create globals to register your new type of Stream or Dst.
struct Register {
- Register(const char* name, std::unique_ptr<Stream> (*factory)(Options));
- Register(const char* name, std::unique_ptr<Dst> (*factory)(Options));
- Register(const char* name, std::unique_ptr<Dst> (*factory)(Options, std::unique_ptr<Dst>));
+ Register(const char* name, const char* help, std::unique_ptr<Stream> (*factory)(Options));
+ Register(const char* name, const char* help, std::unique_ptr<Dst> (*factory)(Options));
+ Register(const char* name, const char* help,
+ std::unique_ptr<Dst>(*factory)(Options, std::unique_ptr<Dst>));
};
#endif//ok_DEFINED
diff --git a/tools/ok_dsts.cpp b/tools/ok_dsts.cpp
index 034ca4564d..20b66d5bcf 100644
--- a/tools/ok_dsts.cpp
+++ b/tools/ok_dsts.cpp
@@ -22,7 +22,7 @@ struct SWDst : Dst {
return move_unique(dst);
}
- bool draw(Src* src) override {
+ Status draw(Src* src) override {
auto size = src->size();
surface = SkSurface::MakeRaster(info.makeWH(size.width(), size.height()));
return src->draw(surface->getCanvas());
@@ -32,9 +32,9 @@ struct SWDst : Dst {
return surface->makeImageSnapshot();
}
};
-static Register sw{"sw", SWDst::Create};
+static Register sw{"sw", "draw with the software backend", SWDst::Create};
-static Register _565{"565", [](Options options) {
+static Register _565{"565", "alias for sw:ct=565", [](Options options) {
options["ct"] = "565";
return SWDst::Create(options);
}};
diff --git a/tools/ok_srcs.cpp b/tools/ok_srcs.cpp
index a7d262cd6e..fd5f201cac 100644
--- a/tools/ok_srcs.cpp
+++ b/tools/ok_srcs.cpp
@@ -38,12 +38,12 @@ struct GMStream : Stream {
return gm->getISize();
}
- bool draw(SkCanvas* canvas) override {
+ Status draw(SkCanvas* canvas) override {
this->init();
canvas->clear(0xffffffff);
canvas->concat(gm->getInitialTransform());
gm->draw(canvas);
- return true;
+ return Status::OK;
}
};
@@ -57,7 +57,7 @@ struct GMStream : Stream {
return move_unique(src);
}
};
-static Register gm{"gm", GMStream::Create};
+static Register gm{"gm", "draw GMs linked into this binary", GMStream::Create};
struct SKPStream : Stream {
std::string dir;
@@ -92,11 +92,11 @@ struct SKPStream : Stream {
return pic->cullRect().roundOut().size();
}
- bool draw(SkCanvas* canvas) override {
+ Status draw(SkCanvas* canvas) override {
this->init();
canvas->clear(0xffffffff);
pic->playback(canvas);
- return true;
+ return Status::OK;
}
};
@@ -111,4 +111,4 @@ struct SKPStream : Stream {
return move_unique(src);
}
};
-static Register skp{"skp", SKPStream::Create};
+static Register skp{"skp", "draw SKPs from dir=skps", SKPStream::Create};
diff --git a/tools/ok_test.cpp b/tools/ok_test.cpp
index 5e7f032cc4..f5c4f22489 100644
--- a/tools/ok_test.cpp
+++ b/tools/ok_test.cpp
@@ -31,15 +31,15 @@ struct TestStream : Stream {
std::string name() override { return test.name; }
SkISize size() override { return {0,0}; }
- bool draw(SkCanvas*) override {
+ Status draw(SkCanvas*) override {
struct : public skiatest::Reporter {
- bool ok = true;
+ Status status = Status::OK;
bool extended, verbose_;
void reportFailed(const skiatest::Failure& failure) override {
ok_log(failure.toString().c_str());
- ok = false;
+ status = Status::Failed;
}
bool allowExtendedTest() const override { return extended; }
bool verbose() const override { return verbose_; }
@@ -55,7 +55,7 @@ struct TestStream : Stream {
#endif
test.proc(&reporter, factory);
- return reporter.ok;
+ return reporter.status;
}
};
@@ -71,7 +71,7 @@ struct TestStream : Stream {
return move_unique(src);
}
};
-static Register test{"test", TestStream::Create};
+static Register test{"test", "run unit tests linked into this binary", TestStream::Create};
// Hey, now why were these defined in DM.cpp? That's kind of weird.
namespace skiatest {
diff --git a/tools/ok_vias.cpp b/tools/ok_vias.cpp
index b273d3ce4f..17e117a7f9 100644
--- a/tools/ok_vias.cpp
+++ b/tools/ok_vias.cpp
@@ -5,17 +5,19 @@
* found in the LICENSE file.
*/
-#include "ok.h"
+#include "SkOSFile.h"
#include "SkPictureRecorder.h"
+#include "ok.h"
+#include <regex>
-static std::unique_ptr<Src> proxy(Src* original, std::function<bool(SkCanvas*)> fn) {
+static std::unique_ptr<Src> proxy(Src* original, std::function<Status(SkCanvas*)> fn) {
struct : Src {
- Src* original;
- std::function<bool(SkCanvas*)> fn;
+ Src* original;
+ std::function<Status(SkCanvas*)> fn;
std::string name() override { return original->name(); }
SkISize size() override { return original->size(); }
- bool draw(SkCanvas* canvas) override { return fn(canvas); }
+ Status draw(SkCanvas* canvas) override { return fn(canvas); }
} src;
src.original = original;
src.fn = fn;
@@ -33,20 +35,20 @@ struct ViaPic : Dst {
return move_unique(via);
}
- bool draw(Src* src) override {
+ Status draw(Src* src) override {
SkRTreeFactory factory;
SkPictureRecorder rec;
rec.beginRecording(SkRect::MakeSize(SkSize::Make(src->size())),
rtree ? &factory : nullptr);
- if (!src->draw(rec.getRecordingCanvas())) {
- return false;
+ for (auto status = src->draw(rec.getRecordingCanvas()); status != Status::OK; ) {
+ return status;
}
auto pic = rec.finishRecordingAsPicture();
return target->draw(proxy(src, [=](SkCanvas* canvas) {
pic->playback(canvas);
- return true;
+ return Status::OK;
}).get());
}
@@ -54,4 +56,64 @@ struct ViaPic : Dst {
return target->image();
}
};
-static Register via_pic{"via_pic", ViaPic::Create};
+static Register via_pic{"via_pic", "record then play back an SkPicture", ViaPic::Create};
+
+struct Png : Dst {
+ std::unique_ptr<Dst> target;
+ std::string dir;
+
+ static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
+ Png via;
+ via.target = std::move(dst);
+ via.dir = options("dir", "ok");
+ return move_unique(via);
+ }
+
+ Status draw(Src* src) override {
+ for (auto status = target->draw(src); status != Status::OK; ) {
+ return status;
+ }
+
+ auto image = target->image();
+ sk_sp<SkData> png{image->encode()};
+
+ sk_mkdir(dir.c_str());
+ SkFILEWStream{(dir + "/" + src->name() + ".png").c_str()}
+ .write(png->data(), png->size());
+ return Status::OK;
+ }
+
+ sk_sp<SkImage> image() override {
+ return target->image();
+ }
+};
+static Register png{"png", "dump PNGs to dir=ok" , Png::Create};
+
+struct Filter : Dst {
+ std::unique_ptr<Dst> target;
+ std::regex match, search;
+
+ static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
+ Filter via;
+ via.target = std::move(dst);
+ via.match = options("match", ".*");
+ via.search = options("search", ".*");
+ return move_unique(via);
+ }
+
+ Status draw(Src* src) override {
+ auto name = src->name();
+ if (!std::regex_match (name, match) ||
+ !std::regex_search(name, search)) {
+ return Status::Skipped;
+ }
+ return target->draw(src);
+ }
+
+ sk_sp<SkImage> image() override {
+ return target->image();
+ }
+};
+struct Register filter{"filter",
+ "run only srcs matching match=.* exactly and search=.* somewhere",
+ Filter::Create};