aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn2
-rw-r--r--tools/ok.cpp243
-rw-r--r--tools/ok.h54
-rw-r--r--tools/ok_dsts.cpp33
-rw-r--r--tools/ok_srcs.cpp99
5 files changed, 241 insertions, 190 deletions
diff --git a/BUILD.gn b/BUILD.gn
index e187644944..ed8b07bc2f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1152,6 +1152,8 @@ if (skia_enable_tools) {
test_app("ok") {
sources = [
"tools/ok.cpp",
+ "tools/ok_dsts.cpp",
+ "tools/ok_srcs.cpp",
]
deps = [
":gm",
diff --git a/tools/ok.cpp b/tools/ok.cpp
index db82b2f028..bfef28f0a5 100644
--- a/tools/ok.cpp
+++ b/tools/ok.cpp
@@ -11,17 +11,11 @@
#include "SkGraphics.h"
#include "SkOSFile.h"
-#include "SkPicture.h"
-#include "SkSurface.h"
-#include "gm.h"
+#include "ok.h"
#include <chrono>
-#include <functional>
#include <future>
#include <list>
-#include <map>
-#include <memory>
#include <regex>
-#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
@@ -161,178 +155,17 @@ struct ThreadEngine : Engine {
};
#endif
-struct Src {
- virtual ~Src() {}
- virtual std::string name() = 0;
- virtual SkISize size() = 0;
- virtual void draw(SkCanvas*) = 0;
-};
-
-struct Stream {
- virtual ~Stream() {}
- virtual std::unique_ptr<Src> next() = 0;
-};
-
-struct Options {
- std::map<std::string, std::string> kv;
-
- explicit Options(std::string str = "") {
- std::string k,v, *curr = &k;
- for (auto c : str) {
- switch(c) {
- case ',': kv[k] = v;
- curr = &(k = "");
- break;
- case '=': curr = &(v = "");
- break;
- default: *curr += c;
- }
- }
- kv[k] = v;
- }
-
- std::string lookup(std::string k, std::string fallback = "") {
- for (auto it = kv.find(k); it != kv.end(); ) {
- return it->second;
- }
- return fallback;
- }
-};
-
-template <typename T>
-static std::unique_ptr<T> move_unique(T& v) {
- return std::unique_ptr<T>{new T{std::move(v)}};
-}
-
-struct GMStream : Stream {
- const skiagm::GMRegistry* registry = skiagm::GMRegistry::Head();
-
- static std::unique_ptr<Stream> Create(Options) {
- GMStream stream;
- return move_unique(stream);
- }
-
- struct GMSrc : Src {
- skiagm::GM* (*factory)(void*);
- std::unique_ptr<skiagm::GM> gm;
-
- std::string name() override {
- gm.reset(factory(nullptr));
- return gm->getName();
- }
-
- SkISize size() override {
- return gm->getISize();
- }
-
- void draw(SkCanvas* canvas) override {
- canvas->clear(0xffffffff);
- canvas->concat(gm->getInitialTransform());
- gm->draw(canvas);
- }
- };
-
- std::unique_ptr<Src> next() override {
- if (!registry) {
- return nullptr;
- }
- GMSrc src;
- src.factory = registry->factory();
- registry = registry->next();
- return move_unique(src);
- }
-};
-
-struct SKPStream : Stream {
- std::string dir;
- std::vector<std::string> skps;
-
- static std::unique_ptr<Stream> Create(Options options) {
- SKPStream stream;
- stream.dir = options.lookup("dir", "skps");
- SkOSFile::Iter it{stream.dir.c_str(), ".skp"};
- for (SkString path; it.next(&path); ) {
- stream.skps.push_back(path.c_str());
- }
- return move_unique(stream);
- }
-
- struct SKPSrc : Src {
- std::string dir, path;
- sk_sp<SkPicture> pic;
-
- std::string name() override {
- return path;
- }
-
- SkISize size() override {
- auto skp = SkData::MakeFromFileName((dir+"/"+path).c_str());
- pic = SkPicture::MakeFromData(skp.get());
- return pic->cullRect().roundOut().size();
- }
-
- void draw(SkCanvas* canvas) override {
- canvas->clear(0xffffffff);
- pic->playback(canvas);
- }
- };
-
- std::unique_ptr<Src> next() override {
- if (skps.empty()) {
- return nullptr;
- }
- SKPSrc src;
- src.dir = dir;
- src.path = skps.back();
- skps.pop_back();
- return move_unique(src);
- }
-};
-
-struct Dst {
- virtual ~Dst() {}
- virtual SkCanvas* canvas() = 0;
- virtual void write(std::string path_prefix) = 0;
-};
-
-struct SWDst : Dst {
- sk_sp<SkSurface> surface;
-
- static std::unique_ptr<Dst> Create(SkISize size, Options options) {
- SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
- if (options.lookup("ct") == "565") { info = info.makeColorType(kRGB_565_SkColorType); }
- if (options.lookup("ct") == "f16") { info = info.makeColorType(kRGBA_F16_SkColorType); }
- SWDst dst;
- dst.surface = SkSurface::MakeRaster(info);
- return move_unique(dst);
- }
-
- SkCanvas* canvas() override {
- return surface->getCanvas();
- }
-
- void write(std::string path_prefix) override {
- auto image = surface->makeImageSnapshot();
- sk_sp<SkData> png{image->encode()};
- SkFILEWStream{(path_prefix + ".png").c_str()}.write(png->data(), png->size());
- }
-};
-
-struct {
+struct StreamType {
const char* name;
std::unique_ptr<Stream> (*factory)(Options);
-} streams[] = {
- {"gm", GMStream::Create },
- {"skp", SKPStream::Create },
};
+static std::vector<StreamType> stream_types;
-struct {
+struct DstType {
const char* name;
std::unique_ptr<Dst> (*factory)(SkISize, Options);
-} dsts[] = {
- {"sw", SWDst::Create },
};
-
+static std::vector<DstType> dst_types;
int main(int argc, char** argv) {
SkGraphics::Init();
@@ -343,23 +176,22 @@ int main(int argc, char** argv) {
std::regex search {".*"};
std::string write_dir {""};
- std::unique_ptr<Stream> stream;
- std::unique_ptr<Dst> (*dst_factory)(SkISize, Options) = nullptr;
- Options dst_options;
+ std::unique_ptr<Stream> stream;
+ std::function<std::unique_ptr<Dst> (SkISize)> dst_factory;
auto help = [&] {
- std::string stream_types, dst_types;
- for (auto s : streams) {
- if (!stream_types.empty()) {
- stream_types += ", ";
+ std::string stream_names, dst_names;
+ for (auto s : stream_types) {
+ if (!stream_names.empty()) {
+ stream_names += ", ";
}
- stream_types += s.name;
+ stream_names += s.name;
}
- for (auto d : dsts) {
- if (!dst_types.empty()) {
- dst_types += ", ";
+ for (auto d : dst_types) {
+ if (!dst_names.empty()) {
+ dst_names += ", ";
}
- dst_types += d.name;
+ dst_names += d.name;
}
printf("%s [-j N] [-m regex] [-s regex] [-w dir] [-h] src[:k=v,...] dst[:k=v,...] \n"
@@ -374,7 +206,7 @@ int main(int argc, char** argv) {
" src: content to draw: %s \n"
" dst: how to draw that content: %s \n"
" Some srcs and dsts have options, e.g. skp:dir=skps sw:ct=565 \n",
- argv[0], stream_types.c_str(), dst_types.c_str());
+ argv[0], stream_names.c_str(), dst_names.c_str());
return 1;
};
@@ -385,7 +217,7 @@ int main(int argc, char** argv) {
if (0 == strcmp("-w", argv[i])) { write_dir = argv[++i] ; }
if (0 == strcmp("-h", argv[i])) { return help(); }
- for (auto s : streams) {
+ for (auto s : stream_types) {
size_t len = strlen(s.name);
if (0 == strncmp(s.name, argv[i], len)) {
switch (argv[i][len]) {
@@ -394,13 +226,14 @@ int main(int argc, char** argv) {
}
}
}
- for (auto d : dsts) {
+ for (auto d : dst_types) {
size_t len = strlen(d.name);
if (0 == strncmp(d.name, argv[i], len)) {
switch (argv[i][len]) {
case ':': len++;
- case '\0': dst_factory = d.factory;
- dst_options = Options{argv[i]+len};
+ case '\0': dst_factory = [=](SkISize size){
+ return d.factory(size, Options{argv[i]+len});
+ };
}
}
}
@@ -463,7 +296,7 @@ int main(int argc, char** argv) {
return Status::Skipped;
}
- auto dst = dst_factory(src->size(), dst_options);
+ auto dst = dst_factory(src->size());
auto canvas = dst->canvas();
src->draw(canvas);
@@ -483,3 +316,33 @@ int main(int argc, char** argv) {
printf("\n");
return (failed || crashed) ? 1 : 0;
}
+
+
+Register::Register(const char* name, std::unique_ptr<Stream> (*factory)(Options)) {
+ stream_types.push_back(StreamType{name, factory});
+}
+Register::Register(const char* name, std::unique_ptr<Dst> (*factory)(SkISize, Options)) {
+ dst_types.push_back(DstType{name, factory});
+}
+
+Options::Options(std::string str) {
+ std::string k,v, *curr = &k;
+ for (auto c : str) {
+ switch(c) {
+ case ',': this->kv[k] = v;
+ curr = &(k = "");
+ break;
+ case '=': curr = &(v = "");
+ break;
+ default: *curr += c;
+ }
+ }
+ this->kv[k] = v;
+}
+
+std::string Options::operator()(std::string k, std::string fallback) const {
+ for (auto it = kv.find(k); it != kv.end(); ) {
+ return it->second;
+ }
+ return fallback;
+}
diff --git a/tools/ok.h b/tools/ok.h
new file mode 100644
index 0000000000..ab05074aac
--- /dev/null
+++ b/tools/ok.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef ok_DEFINED
+#define ok_DEFINED
+
+#include "SkCanvas.h"
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+
+// Not really ok-specific, but just kind of generally handy.
+template <typename T>
+static std::unique_ptr<T> move_unique(T& v) {
+ return std::unique_ptr<T>{new T{std::move(v)}};
+}
+
+struct Src {
+ virtual ~Src() {}
+ virtual std::string name() = 0; // ok always calls Src methods in order:
+ virtual SkISize size() = 0; // name() -> size() -> draw(), possibly
+ virtual void draw(SkCanvas*) = 0; // stopping after calling name().
+};
+
+struct Stream {
+ virtual ~Stream() {}
+ virtual std::unique_ptr<Src> next() = 0;
+};
+
+struct Dst {
+ virtual ~Dst() {}
+ virtual SkCanvas* canvas() = 0;
+ virtual void write(std::string path_prefix) = 0; // All but the file extension.
+};
+
+class Options {
+ std::map<std::string, std::string> kv;
+public:
+ explicit Options(std::string str = "");
+ std::string operator()(std::string k, std::string fallback = "") const;
+};
+
+// 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)(SkISize, Options));
+};
+
+#endif//ok_DEFINED
diff --git a/tools/ok_dsts.cpp b/tools/ok_dsts.cpp
new file mode 100644
index 0000000000..143650c4d4
--- /dev/null
+++ b/tools/ok_dsts.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "ok.h"
+#include "SkSurface.h"
+
+struct SWDst : Dst {
+ sk_sp<SkSurface> surface;
+
+ static std::unique_ptr<Dst> Create(SkISize size, Options options) {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
+ if (options("ct") == "565") { info = info.makeColorType(kRGB_565_SkColorType); }
+ if (options("ct") == "f16") { info = info.makeColorType(kRGBA_F16_SkColorType); }
+ SWDst dst;
+ dst.surface = SkSurface::MakeRaster(info);
+ return move_unique(dst);
+ }
+
+ SkCanvas* canvas() override {
+ return surface->getCanvas();
+ }
+
+ void write(std::string path_prefix) override {
+ auto image = surface->makeImageSnapshot();
+ sk_sp<SkData> png{image->encode()};
+ SkFILEWStream{(path_prefix + ".png").c_str()}.write(png->data(), png->size());
+ }
+};
+static Register sw{"sw", SWDst::Create};
diff --git a/tools/ok_srcs.cpp b/tools/ok_srcs.cpp
new file mode 100644
index 0000000000..ce3e653d92
--- /dev/null
+++ b/tools/ok_srcs.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "ok.h"
+#include "gm.h"
+#include "SkOSFile.h"
+#include "SkPicture.h"
+#include <vector>
+
+struct GMStream : Stream {
+ const skiagm::GMRegistry* registry = skiagm::GMRegistry::Head();
+
+ static std::unique_ptr<Stream> Create(Options) {
+ GMStream stream;
+ return move_unique(stream);
+ }
+
+ struct GMSrc : Src {
+ skiagm::GM* (*factory)(void*);
+ std::unique_ptr<skiagm::GM> gm;
+
+ std::string name() override {
+ gm.reset(factory(nullptr));
+ return gm->getName();
+ }
+
+ SkISize size() override {
+ return gm->getISize();
+ }
+
+ void draw(SkCanvas* canvas) override {
+ canvas->clear(0xffffffff);
+ canvas->concat(gm->getInitialTransform());
+ gm->draw(canvas);
+ }
+ };
+
+ std::unique_ptr<Src> next() override {
+ if (!registry) {
+ return nullptr;
+ }
+ GMSrc src;
+ src.factory = registry->factory();
+ registry = registry->next();
+ return move_unique(src);
+ }
+};
+static Register gm{"gm", GMStream::Create};
+
+struct SKPStream : Stream {
+ std::string dir;
+ std::vector<std::string> skps;
+
+ static std::unique_ptr<Stream> Create(Options options) {
+ SKPStream stream;
+ stream.dir = options("dir", "skps");
+ SkOSFile::Iter it{stream.dir.c_str(), ".skp"};
+ for (SkString path; it.next(&path); ) {
+ stream.skps.push_back(path.c_str());
+ }
+ return move_unique(stream);
+ }
+
+ struct SKPSrc : Src {
+ std::string dir, path;
+ sk_sp<SkPicture> pic;
+
+ std::string name() override {
+ return path;
+ }
+
+ SkISize size() override {
+ auto skp = SkData::MakeFromFileName((dir+"/"+path).c_str());
+ pic = SkPicture::MakeFromData(skp.get());
+ return pic->cullRect().roundOut().size();
+ }
+
+ void draw(SkCanvas* canvas) override {
+ canvas->clear(0xffffffff);
+ pic->playback(canvas);
+ }
+ };
+
+ std::unique_ptr<Src> next() override {
+ if (skps.empty()) {
+ return nullptr;
+ }
+ SKPSrc src;
+ src.dir = dir;
+ src.path = skps.back();
+ skps.pop_back();
+ return move_unique(src);
+ }
+};
+static Register skp{"skp", SKPStream::Create};