Cherry-pick 'rm ok' to skqp/dev.

Seems that https://skia-review.googlesource.com/c/skia/+/117086 depends
on this CL. Original description below.

-----

rm ok

I'm not really using it much anymore.
Time to dedup and fold its ideas into DM.

No-Tree-Checks: true
No-Try: true
No-Presubmit: true
Change-Id: I40a238c9083460e1b7aee459757f867dfd3d79af
Reviewed-On: https://skia-review.googlesource.com/107800
Reviewed-By: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/117728
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Ben Wagner <benjaminwagner@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 3d52019..c7bf566 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1549,24 +1549,6 @@
     }
   }
 
-  test_app("ok") {
-    sources = [
-      "dm/DMFontMgr.cpp",
-      "tools/ok.cpp",
-      "tools/ok_dsts.cpp",
-      "tools/ok_engines.cpp",
-      "tools/ok_srcs.cpp",
-      "tools/ok_test.cpp",
-      "tools/ok_vias.cpp",
-    ]
-    deps = [
-      ":bench",
-      ":gm",
-      ":skia",
-      ":tests",
-      ":tool_utils",
-    ]
-  }
   test_app("nanobench") {
     sources = [
       "bench/nanobench.cpp",
diff --git a/tools/ok.cpp b/tools/ok.cpp
deleted file mode 100644
index 29c2a22..0000000
--- a/tools/ok.cpp
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-// ok is an experimental test harness, maybe to replace DM.  Key features:
-//   * work is balanced across separate processes for stability and isolation;
-//   * ok is entirely opt-in.  No more maintaining huge --blacklists.
-
-#include "SkGraphics.h"
-#include "SkImage.h"
-#include "ok.h"
-#include <chrono>
-#include <list>
-#include <stdio.h>
-#include <stdlib.h>
-#include <vector>
-
-#if !defined(__has_include)
-    #define  __has_include(x) 0
-#endif
-
-static thread_local const char* tls_currently_running = "";
-
-#if __has_include(<execinfo.h>)
-    #include <execinfo.h>
-
-    #define CAN_BACKTRACE
-    static void backtrace(int fd) {
-        void* stack[128];
-        int frames = backtrace(stack, sizeof(stack)/sizeof(*stack));
-        backtrace_symbols_fd(stack, frames, fd);
-    }
-
-#elif __has_include(<dlfcn.h>) && __has_include(<unwind.h>)
-    #include <cxxabi.h>
-    #include <dlfcn.h>
-    #include <unwind.h>
-
-    #define CAN_BACKTRACE
-    static void backtrace(int fd) {
-        FILE* file = fdopen(fd, "a");
-        _Unwind_Backtrace([](_Unwind_Context* ctx, void* arg) {
-            auto file = (FILE*)arg;
-            if (auto ip = (void*)_Unwind_GetIP(ctx)) {
-                const char* name = "[unknown]";
-                void*       addr = nullptr;
-                Dl_info info;
-                if (dladdr(ip, &info) && info.dli_sname && info.dli_saddr) {
-                    name = info.dli_sname;
-                    addr = info.dli_saddr;
-                }
-
-                int ok;
-                char* demangled = abi::__cxa_demangle(name, nullptr,0, &ok);
-                if (ok == 0 && demangled) {
-                    name = demangled;
-                }
-
-                fprintf(file, "\t%p %s+%zu\n", ip, name, (size_t)ip - (size_t)addr);
-                free(demangled);
-            }
-            return _URC_NO_REASON;
-        }, file);
-        fflush(file);
-    }
-#endif
-
-#if defined(CAN_BACKTRACE) && __has_include(<fcntl.h>) && __has_include(<signal.h>)
-    #include <fcntl.h>
-    #include <signal.h>
-
-    // We'd ordinarily just use lockf(), but fcntl() is more portable to older Android NDK APIs.
-    static void lock_or_unlock_fd(int fd, short type) {
-        struct flock fl{};
-        fl.l_type   = type;
-        fl.l_whence = SEEK_CUR;
-        fl.l_start  = 0;
-        fl.l_len    = 0;  // 0 == the entire file
-        fcntl(fd, F_SETLKW, &fl);
-    }
-    static void   lock_fd(int fd) { lock_or_unlock_fd(fd, F_WRLCK); }
-    static void unlock_fd(int fd) { lock_or_unlock_fd(fd, F_UNLCK); }
-
-    static int log_fd = 2/*stderr*/;
-
-    static void log(const char* msg) {
-        write(log_fd, msg, strlen(msg));
-    }
-
-    static void setup_crash_handler() {
-        static void (*original_handlers[32])(int);
-        for (int sig : std::vector<int>{ SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV }) {
-            original_handlers[sig] = signal(sig, [](int sig) {
-                lock_fd(log_fd);
-                    log("\ncaught signal ");
-                    switch (sig) {
-                    #define CASE(s) case s: log(#s); break
-                        CASE(SIGABRT);
-                        CASE(SIGBUS);
-                        CASE(SIGFPE);
-                        CASE(SIGILL);
-                        CASE(SIGSEGV);
-                    #undef CASE
-                    }
-                    log(" while running '");
-                    log(tls_currently_running);
-                    log("'\n");
-                    backtrace(log_fd);
-                unlock_fd(log_fd);
-
-                signal(sig, original_handlers[sig]);
-                raise(sig);
-            });
-        }
-    }
-
-    static void defer_logging() {
-        log_fd = fileno(tmpfile());
-        atexit([] {
-            lseek(log_fd, 0, SEEK_SET);
-            char buf[1024];
-            while (size_t bytes = read(log_fd, buf, sizeof(buf))) {
-                write(2, buf, bytes);
-            }
-        });
-    }
-
-    void ok_log(const char* msg) {
-        lock_fd(log_fd);
-            log("[");
-            log(tls_currently_running);
-            log("]\t");
-            log(msg);
-            log("\n");
-        unlock_fd(log_fd);
-    }
-
-#else
-    static void setup_crash_handler() {}
-    static void defer_logging() {}
-
-    void ok_log(const char* msg) {
-        fprintf(stderr, "[%s]\t%s\n", tls_currently_running, msg);
-    }
-#endif
-
-struct EngineType {
-    const char *name, *help;
-    std::unique_ptr<Engine> (*factory)(Options);
-};
-static std::vector<EngineType> engine_types;
-
-struct StreamType {
-    const char *name, *help;
-    std::unique_ptr<Stream> (*factory)(Options);
-};
-static std::vector<StreamType> stream_types;
-
-struct DstType {
-    const char *name, *help;
-    std::unique_ptr<Dst> (*factory)(Options);
-};
-static std::vector<DstType> dst_types;
-
-struct ViaType {
-    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();
-
-    std::unique_ptr<Engine>                   engine;
-    std::unique_ptr<Stream>                   stream;
-    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 engine_help = help_for(engine_types),
-                    stream_help = help_for(stream_types),
-                       dst_help = help_for(   dst_types),
-                       via_help = help_for(   via_types);
-
-        printf("%s [engine] src[:k=v,...] dst[:k=v,...] [via[:k=v,...] ...]          \n"
-                " engine: how to execute tasks%s                                     \n"
-                " 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],
-                engine_help.c_str(), stream_help.c_str(), dst_help.c_str(), via_help.c_str());
-        return 1;
-    };
-
-    for (int i = 1; i < argc; i++) {
-        if (0 == strcmp("-h",     argv[i])) { return help(); }
-        if (0 == strcmp("--help", argv[i])) { return help(); }
-
-        for (auto e : engine_types) {
-            size_t len = strlen(e.name);
-            if (0 == strncmp(e.name, argv[i], len)) {
-                switch (argv[i][len]) {
-                    case  ':': len++;
-                    case '\0': engine = e.factory(Options{argv[i]+len});
-                }
-            }
-        }
-
-        for (auto s : stream_types) {
-            size_t len = strlen(s.name);
-            if (0 == strncmp(s.name, argv[i], len)) {
-                switch (argv[i][len]) {
-                    case  ':': len++;
-                    case '\0': stream = s.factory(Options{argv[i]+len});
-                }
-            }
-        }
-        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 = [=]{
-                                   return d.factory(Options{argv[i]+len});
-                               };
-                }
-            }
-        }
-        for (auto v : via_types) {
-            size_t len = strlen(v.name);
-            if (0 == strncmp(v.name, argv[i], len)) {
-                if (!dst_factory) { return help(); }
-                switch (argv[i][len]) {
-                    case  ':': len++;
-                    case '\0': dst_factory = [=]{
-                                   return v.factory(Options{argv[i]+len}, dst_factory());
-                               };
-                }
-            }
-        }
-    }
-    if (!stream) { return help(); }
-
-    if (!engine) { engine = engine_types.back().factory(Options{}); }
-
-    // If we know engine->spawn() will never crash, we can defer logging until we exit.
-    if (engine->crashproof()) {
-        defer_logging();
-    }
-
-    int ok = 0, failed = 0, crashed = 0, skipped = 0;
-
-    auto update_stats = [&](Status s) {
-        switch (s) {
-            case Status::OK:      ok++;      break;
-            case Status::Failed:  failed++;  break;
-            case Status::Crashed: crashed++; break;
-            case Status::Skipped: skipped++; break;
-            case Status::None:              return;
-        }
-        const char* leader = "\r";
-        auto print = [&](int count, const char* label) {
-            if (count) {
-                printf("%s%d %s", leader, count, label);
-                leader = ", ";
-            }
-        };
-        print(ok,      "ok");
-        print(failed,  "failed");
-        print(crashed, "crashed");
-        print(skipped, "skipped");
-        fflush(stdout);
-    };
-
-    std::list<std::future<Status>> live;
-    const auto the_past = std::chrono::steady_clock::now();
-
-    auto wait_one = [&] {
-        if (live.empty()) {
-            return Status::None;
-        }
-
-        for (;;) {
-            for (auto it = live.begin(); it != live.end(); it++) {
-                if (it->wait_until(the_past) != std::future_status::timeout) {
-                    Status s = it->get();
-                    live.erase(it);
-                    return s;
-                }
-            }
-        }
-    };
-
-    auto spawn = [&](std::function<Status(void)> fn) {
-        std::future<Status> status;
-        for (;;) {
-            status = engine->spawn(fn);
-            if (status.valid()) {
-                break;
-            }
-            update_stats(wait_one());
-        }
-        live.push_back(std::move(status));
-    };
-
-    for (std::unique_ptr<Src> owned = stream->next(); owned; owned = stream->next()) {
-        Src* raw = owned.release();  // Can't move std::unique_ptr into a lambda in C++11. :(
-        spawn([=] {
-            std::unique_ptr<Src> src{raw};
-
-            std::string name = src->name();
-            tls_currently_running = name.c_str();
-
-            return dst_factory()->draw(src.get());
-        });
-    }
-
-    for (Status s = Status::OK; s != Status::None; ) {
-        s = wait_one();
-        update_stats(s);
-    }
-    printf("\n");
-    return (failed || crashed) ? 1 : 0;
-}
-
-
-Register::Register(const char* name, const char* help,
-                   std::unique_ptr<Engine> (*factory)(Options)) {
-    engine_types.push_back(EngineType{name, help, 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, const char* help,
-                   std::unique_ptr<Dst> (*factory)(Options)) {
-    dst_types.push_back(DstType{name, help, factory});
-}
-Register::Register(const char* name, const char* help,
-                   std::unique_ptr<Dst> (*factory)(Options, std::unique_ptr<Dst>)) {
-    via_types.push_back(ViaType{name, help, factory});
-}
-
-Options::Options(std::string str) {
-    std::string k,v, *curr = &k;
-    for (auto c : str) {
-        switch(c) {
-            case ',': (*this)[k] = v;
-                      curr = &(k = "");
-                      break;
-            case '=': curr = &(v = "");
-                      break;
-            default: *curr += c;
-        }
-    }
-    (*this)[k] = v;
-}
-
-std::string& Options::operator[](std::string k) { return this->kv[k]; }
-
-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
deleted file mode 100644
index 502df23..0000000
--- a/tools/ok.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 <future>
-#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)}};
-}
-
-void ok_log(const char*);
-
-enum class Status { OK, Failed, Crashed, Skipped, None };
-
-struct Engine {
-    virtual ~Engine() {}
-    virtual bool                crashproof()                       = 0;
-    virtual std::future<Status> spawn(std::function<Status(void)>) = 0;
-};
-
-struct Src {
-    virtual ~Src() {}
-    virtual std::string name()     = 0;
-    virtual SkISize     size()     = 0;
-    virtual Status draw(SkCanvas*) = 0;
-};
-
-struct Stream {
-    virtual ~Stream() {}
-    virtual std::unique_ptr<Src> next() = 0;
-};
-
-struct Dst {
-    virtual ~Dst() {}
-    virtual Status draw(Src*)      = 0;
-    virtual sk_sp<SkImage> image() = 0;
-};
-
-class Options {
-    std::map<std::string, std::string> kv;
-public:
-    explicit Options(std::string = "");
-    std::string& operator[](std::string k);
-    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, const char* help, std::unique_ptr<Engine> (*factory)(Options));
-    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
deleted file mode 100644
index 1f4fe42..0000000
--- a/tools/ok_dsts.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 {
-    SkImageInfo      info;
-    sk_sp<SkSurface> surface;
-
-    static std::unique_ptr<Dst> Create(Options options) {
-        SkImageInfo info = SkImageInfo::MakeN32Premul(0,0);
-        if (options("ct") == "a8")  { info = info.makeColorType(kAlpha_8_SkColorType); }
-        if (options("ct") == "565") { info = info.makeColorType(kRGB_565_SkColorType); }
-        if (options("ct") == "f16") { info = info.makeColorType(kRGBA_F16_SkColorType); }
-
-        if (options("cs") == "srgb") {
-            auto cs = info.colorType() == kRGBA_F16_SkColorType ? SkColorSpace::MakeSRGBLinear()
-                                                                : SkColorSpace::MakeSRGB();
-            info = info.makeColorSpace(std::move(cs));
-        }
-
-        SWDst dst;
-        dst.info = info;
-        return move_unique(dst);
-    }
-
-    Status draw(Src* src) override {
-        auto size = src->size();
-        surface = SkSurface::MakeRaster(info.makeWH(size.width(), size.height()));
-        return src->draw(surface->getCanvas());
-    }
-
-    sk_sp<SkImage> image() override {
-        return surface->makeImageSnapshot();
-    }
-};
-static Register sw{"sw", "draw with the software backend", SWDst::Create};
-static Register _8888{"8888", "alias for sw", SWDst::Create};
-
-static Register a8{"a8", "alias for sw:ct=a8", [](Options options) {
-    options["ct"] = "a8";
-    return SWDst::Create(options);
-}};
-
-static Register _565{"565", "alias for sw:ct=565", [](Options options) {
-    options["ct"] = "565";
-    return SWDst::Create(options);
-}};
-
-static Register srgb{"srgb", "alias for sw:cs=srgb", [](Options options) {
-    options["cs"] = "srgb";
-    return SWDst::Create(options);
-}};
-
-static Register f16{"f16", "alias for sw:ct=f16,cs=srgb", [](Options options) {
-    options["ct"] = "f16";
-    options["cs"] = "srgb";
-    return SWDst::Create(options);
-}};
-
-extern bool gSkForceRasterPipelineBlitter;
-static Register rp{"rp", "draw forcing SkRasterPipelineBlitter", [](Options options) {
-    gSkForceRasterPipelineBlitter = true;
-    return SWDst::Create(options);
-}};
diff --git a/tools/ok_engines.cpp b/tools/ok_engines.cpp
deleted file mode 100644
index 3304f3e..0000000
--- a/tools/ok_engines.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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 <stdlib.h>
-
-struct SerialEngine : Engine {
-    static std::unique_ptr<Engine> Factory(Options) {
-        SerialEngine engine;
-        return move_unique(engine);
-    }
-
-    bool crashproof() override { return false; }
-
-    std::future<Status> spawn(std::function<Status(void)> fn) override {
-        return std::async(std::launch::deferred, fn);
-    }
-};
-static Register serial("serial",
-                       "Run tasks serially on the main thread of a single process.",
-                       SerialEngine::Factory);
-
-struct ThreadEngine : Engine {
-    static std::unique_ptr<Engine> Factory(Options) {
-        ThreadEngine engine;
-        return move_unique(engine);
-    }
-
-    bool crashproof() override { return false; }
-
-    std::future<Status> spawn(std::function<Status(void)> fn) override {
-        return std::async(std::launch::async, fn);
-    }
-};
-static Register thread("thread",
-                       "Run each task on its own thread of a single process.",
-                       ThreadEngine::Factory);
-
-#if !defined(_MSC_VER)
-    #include <sys/wait.h>
-    #include <unistd.h>
-
-    struct ForkEngine : Engine {
-        int limit;      // How many concurrent subprocesses do we allow to run at max?
-        int alive = 0;  // How many concurrent subprocesses do we have running right now?
-
-        static std::unique_ptr<Engine> Factory(Options options) {
-            ForkEngine engine;
-            engine.limit = atoi(options("limit", "0").c_str());
-            if (engine.limit < 1) {
-                engine.limit = std::thread::hardware_concurrency();
-            }
-            return move_unique(engine);
-        }
-
-        bool crashproof() override { return true; }
-
-        std::future<Status> spawn(std::function<Status(void)> fn) override {
-            if (alive == limit) {
-                // The caller will wait for a child process to finish then try again.
-                return std::future<Status>();
-            }
-
-            switch (fork()) {
-                case  0:
-                    // We are the spawned child process.
-                    // Run fn() and exit() with its Status as our return code.
-                    _exit((int)fn());
-
-                case -1:
-                    // The OS won't let us fork() another process right now.
-                    // We'll need to wait for at least one live task to finish and try again.
-                    return std::future<Status>();
-
-                default:
-                    // We succesfully spawned a child process!
-                    // This will wait for any spawned process to finish and return its Status.
-                    alive++;
-                    return std::async(std::launch::deferred, [&] {
-                        do {
-                            int status;
-                            if (wait(&status) > 0) {
-                                alive--;
-                                return WIFEXITED(status) ? (Status)WEXITSTATUS(status)
-                                                         : Status::Crashed;
-                            }
-                        } while (errno == EINTR);
-                        return Status::None;
-                    });
-            }
-        }
-    };
-    static Register _fork("fork",
-                          "Run each task in an independent process with fork(), limit=ncpus.",
-                          ForkEngine::Factory);
-#endif
diff --git a/tools/ok_srcs.cpp b/tools/ok_srcs.cpp
deleted file mode 100644
index b909be8..0000000
--- a/tools/ok_srcs.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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 "Benchmark.h"
-#include "SkData.h"
-#include "SkOSFile.h"
-#include "SkPicture.h"
-#include "Timer.h"
-#include "gm.h"
-#include "ok.h"
-#include <algorithm>
-#include <chrono>
-#include <limits>
-#include <stdlib.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;
-
-        void init() {
-            if (gm) { return; }
-            gm.reset(factory(nullptr));
-        }
-
-        std::string name() override {
-            this->init();
-            return gm->getName();
-        }
-
-        SkISize size() override {
-            this->init();
-            return gm->getISize();
-        }
-
-        Status draw(SkCanvas* canvas) override {
-            this->init();
-            canvas->clear(0xffffffff);
-            gm->draw(canvas);
-            return Status::OK;
-        }
-    };
-
-    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", "draw GMs linked into this binary", 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;
-
-        void init() {
-            if (pic) { return; }
-            auto skp = SkData::MakeFromFileName((dir+"/"+path).c_str());
-            pic = SkPicture::MakeFromData(skp.get());
-        }
-
-        std::string name() override {
-            return path;
-        }
-
-        SkISize size() override {
-            this->init();
-            return pic->cullRect().roundOut().size();
-        }
-
-        Status draw(SkCanvas* canvas) override {
-            this->init();
-            canvas->clear(0xffffffff);
-            pic->playback(canvas);
-            return Status::OK;
-        }
-    };
-
-    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", "draw SKPs from dir=skps", SKPStream::Create};
-
-struct BenchStream : Stream {
-    const BenchRegistry* registry = BenchRegistry::Head();
-    int samples;
-
-    static std::unique_ptr<Stream> Create(Options options) {
-        BenchStream stream;
-        stream.samples = std::max(1, atoi(options("samples", "20").c_str()));
-        return move_unique(stream);
-    }
-
-    struct BenchSrc : Src {
-        Benchmark* (*factory)(void*);
-        std::unique_ptr<Benchmark> bench;
-        int samples;
-
-        void init() {
-            if (bench) { return; }
-            bench.reset(factory(nullptr));
-        }
-
-        std::string name() override {
-            this->init();
-            return bench->getName();
-        }
-
-        SkISize size() override {
-            this->init();
-            return { bench->getSize().x(), bench->getSize().y() };
-        }
-
-        Status draw(SkCanvas* canvas) override {
-            this->init();
-
-            using ms = std::chrono::duration<double, std::milli>;
-            std::vector<ms> sample(samples);
-
-            bench->delayedSetup();
-            if (canvas) {
-                bench->perCanvasPreDraw(canvas);
-            }
-            for (int i = 0; i < samples; i++) {
-                using clock = std::chrono::high_resolution_clock;
-                for (int loops = 1; loops < 1000000000; loops *= 2) {
-                    bench->preDraw(canvas);
-                    auto start = clock::now();
-                        bench->draw(loops, canvas);
-                    ms elapsed = clock::now() - start;
-                    bench->postDraw(canvas);
-
-                    if (elapsed.count() < 10) {
-                        continue;
-                    }
-
-                    sample[i] = elapsed / loops;
-                    break;
-                }
-            }
-            if (canvas) {
-                bench->perCanvasPostDraw(canvas);
-            }
-
-            std::sort(sample.begin(), sample.end());
-
-            SkString msg = SkStringPrintf("%s\t@0", HumanizeMs(sample[0].count()).c_str());
-            if (samples > 2) {
-                msg.appendf("\t%s\t@%g", HumanizeMs(sample[samples-2].count()).c_str()
-                                       , 100.0*(samples-1) / samples);
-            }
-            if (samples > 1) {
-                msg.appendf("\t%s\t@100", HumanizeMs(sample[samples-1].count()).c_str());
-            }
-            ok_log(msg.c_str());
-
-            return Status::OK;
-        }
-    };
-
-    std::unique_ptr<Src> next() override {
-        if (!registry) {
-            return nullptr;
-        }
-        BenchSrc src;
-        src.factory = registry->factory();
-        src.samples = samples;
-        registry = registry->next();
-        return move_unique(src);
-    }
-};
-static Register bench{
-    "bench",
-    "time benchmarks linked into this binary samples=20 times each",
-    BenchStream::Create,
-};
diff --git a/tools/ok_test.cpp b/tools/ok_test.cpp
deleted file mode 100644
index 2329042..0000000
--- a/tools/ok_test.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 "Test.h"
-
-#if SK_SUPPORT_GPU
-    #include "GrContextFactory.h"
-#else
-struct GrContextOptions {};
-#endif
-
-struct TestStream : Stream {
-    const skiatest::TestRegistry* registry = skiatest::TestRegistry::Head();
-    bool extended = false, verbose = false;
-
-    static std::unique_ptr<Stream> Create(Options options) {
-        TestStream stream;
-        if (options("extended") != "") { stream.extended = true; }
-        if (options("verbose" ) != "") { stream.verbose  = true; }
-
-        return move_unique(stream);
-    }
-
-    struct TestSrc : Src {
-        skiatest::Test test {"", false, nullptr};
-        bool extended, verbose;
-
-        std::string name() override { return test.name; }
-        SkISize     size() override { return {0,0}; }
-
-        Status draw(SkCanvas*) override {
-            struct : public skiatest::Reporter {
-                Status status = Status::OK;
-                bool extended, verbose_;
-
-                void reportFailed(const skiatest::Failure& failure) override {
-                    ok_log(failure.toString().c_str());
-                    status = Status::Failed;
-                }
-                bool allowExtendedTest() const override { return extended; }
-                bool           verbose() const override { return verbose_; }
-            } reporter;
-            reporter.extended = extended;
-            reporter.verbose_ = verbose;
-
-            GrContextOptions options;
-            test.run(&reporter, options);
-            return reporter.status;
-        }
-    };
-
-    std::unique_ptr<Src> next() override {
-        if (!registry) {
-            return nullptr;
-        }
-        TestSrc src;
-        src.test = registry->factory();
-        src.extended = extended;
-        src.verbose  = verbose;
-        registry = registry->next();
-        return move_unique(src);
-    }
-};
-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 {
-#if SK_SUPPORT_GPU
-    bool IsGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-        return kOpenGL_GrBackend == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
-    }
-    bool IsVulkanContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-        return kVulkan_GrBackend == sk_gpu_test::GrContextFactory::ContextTypeBackend(type);
-    }
-    bool IsRenderingGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-        return IsGLContextType(type) && sk_gpu_test::GrContextFactory::IsRenderingContext(type);
-    }
-    bool IsNullGLContextType(sk_gpu_test::GrContextFactory::ContextType type) {
-        return type == sk_gpu_test::GrContextFactory::kNullGL_ContextType;
-    }
-#else
-    bool IsGLContextType         (int) { return false; }
-    bool IsVulkanContextType     (int) { return false; }
-    bool IsRenderingGLContextType(int) { return false; }
-    bool IsNullGLContextType     (int) { return false; }
-#endif
-
-    void RunWithGPUTestContexts(GrContextTestFn* test, GrContextTypeFilterFn* contextTypeFilter,
-                                Reporter* reporter, const GrContextOptions& options) {
-        // TODO(bsalomon)
-    }
-}
diff --git a/tools/ok_vias.cpp b/tools/ok_vias.cpp
deleted file mode 100644
index c1f8d93..0000000
--- a/tools/ok_vias.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * 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 "../dm/DMFontMgr.h"
-#include "../src/core/SkFontMgrPriv.h"
-#include "ProcStats.h"
-#include "SkColorFilter.h"
-#include "SkEventTracingPriv.h"
-#include "SkImage.h"
-#include "SkOSFile.h"
-#include "SkPictureRecorder.h"
-#include "SkPngEncoder.h"
-#include "SkTraceEvent.h"
-#include "SkTypeface.h"
-#include "Timer.h"
-#include "ok.h"
-#include "sk_tool_utils.h"
-#include <chrono>
-#include <regex>
-
-static std::unique_ptr<Src> proxy(Src* original, std::function<Status(SkCanvas*)> fn) {
-    struct : Src {
-        Src*                             original;
-        std::function<Status(SkCanvas*)> fn;
-
-        std::string name() override { return original->name(); }
-        SkISize     size() override { return original->size(); }
-        Status draw(SkCanvas* canvas) override { return fn(canvas); }
-    } src;
-    src.original = original;
-    src.fn       = fn;
-    return move_unique(src);
-}
-
-struct ViaPic : Dst {
-    std::unique_ptr<Dst> target;
-    bool                 rtree = false;
-
-    static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
-        ViaPic via;
-        via.target = std::move(dst);
-        if (options("bbh") == "rtree") { via.rtree = true; }
-        return move_unique(via);
-    }
-
-    Status draw(Src* src) override {
-        TRACE_EVENT0("ok", TRACE_FUNC);
-        SkRTreeFactory factory;
-        SkPictureRecorder rec;
-        rec.beginRecording(SkRect::MakeSize(SkSize::Make(src->size())),
-                           rtree ? &factory : nullptr);
-
-        for (Status status = src->draw(rec.getRecordingCanvas()); status != Status::OK; ) {
-            return status;
-        }
-        sk_sp<SkPicture> pic = rec.finishRecordingAsPicture();
-
-        return target->draw(proxy(src, [=](SkCanvas* canvas) {
-            pic->playback(canvas);
-            return Status::OK;
-        }).get());
-    }
-
-    sk_sp<SkImage> image() override {
-        return target->image();
-    }
-};
-static Register via_pic{"via_pic", "record then play back an SkPicture", ViaPic::Create};
-
-// When deserializing, we need to hook this to intercept "Toy Liberation ..."
-// typefaces and return our portable test typeface.
-extern sk_sp<SkTypeface> (*gCreateTypefaceDelegate)(const char[], SkFontStyle);
-
-struct ViaSkp : Dst {
-    std::unique_ptr<Dst> target;
-    bool                 rtree = false;
-
-    static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
-        gCreateTypefaceDelegate = [](const char name[], SkFontStyle style) -> sk_sp<SkTypeface> {
-            if (name == strstr(name, "Toy Liberation")) {
-                return sk_tool_utils::create_portable_typeface(name, style);
-            }
-            return nullptr;
-        };
-
-        ViaSkp via;
-        via.target = std::move(dst);
-        if (options("bbh") == "rtree") { via.rtree = true; }
-        return move_unique(via);
-    }
-
-    Status draw(Src* src) override {
-        TRACE_EVENT0("ok", TRACE_FUNC);
-        SkRTreeFactory factory;
-        SkPictureRecorder rec;
-        rec.beginRecording(SkRect::MakeSize(SkSize::Make(src->size())),
-                           rtree ? &factory : nullptr);
-
-        for (Status status = src->draw(rec.getRecordingCanvas()); status != Status::OK; ) {
-            return status;
-        }
-        sk_sp<SkPicture> pic = rec.finishRecordingAsPicture();
-
-        // Serialize and deserialize.
-        pic = SkPicture::MakeFromData(pic->serialize().get());
-
-        return target->draw(proxy(src, [=](SkCanvas* canvas) {
-            pic->playback(canvas);
-            return Status::OK;
-        }).get());
-    }
-
-    sk_sp<SkImage> image() override {
-        return target->image();
-    }
-};
-static Register via_skp{"via_skp", "serialize and deserialize an .skp", ViaSkp::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 {
-        TRACE_EVENT0("ok", TRACE_FUNC);
-        for (auto status = target->draw(src); status != Status::OK; ) {
-            return status;
-        }
-
-        SkBitmap bm;
-        if (!target->image()->asLegacyBitmap(&bm, SkImage::kRO_LegacyBitmapMode)) {
-            return Status::Failed;
-        }
-
-        // SkPngEncoder can't encode A8 .pngs, and even if it could, they'd be a pain to look at.
-        if (bm.colorType() == kAlpha_8_SkColorType) {
-            SkPaint paint;
-            SkScalar alpha_to_opaque_gray[20] = {
-                0,0,0,1,  0,  // red   = alpha
-                0,0,0,1,  0,  // green = alpha
-                0,0,0,1,  0,  // blue  = alpha
-                0,0,0,0,255,  // alpha = 255
-            };
-            paint.setColorFilter(SkColorFilter::MakeMatrixFilterRowMajor255(alpha_to_opaque_gray));
-            paint.setBlendMode(SkBlendMode::kSrc);
-
-            SkBitmap dst;
-            dst.allocN32Pixels(bm.width(), bm.height(), /*isOpaque=*/true);
-            SkCanvas canvas(dst);
-            canvas.drawBitmap(bm, 0,0, &paint);
-
-            bm = dst;
-        }
-
-        SkPixmap pm;
-        if (!bm.peekPixels(&pm)) {
-            return Status::Failed;
-        }
-
-        sk_mkdir(dir.c_str());
-        SkFILEWStream dst{(dir + "/" + src->name() + ".png").c_str()};
-
-        SkPngEncoder::Options options;
-        options.fFilterFlags      = SkPngEncoder::FilterFlag::kNone;
-        options.fZLibLevel        = 1;
-        options.fUnpremulBehavior = pm.colorSpace() ? SkTransferFunctionBehavior::kRespect
-                                                    : SkTransferFunctionBehavior::kIgnore;
-        return SkPngEncoder::Encode(&dst, pm, options) ? Status::OK
-                                                       : Status::Failed;
-    }
-
-    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();
-    }
-};
-static Register filter{"filter",
-                       "run only srcs matching match=.* exactly and search=.* somewhere",
-                       Filter::Create};
-
-struct Time : Dst {
-    std::unique_ptr<Dst> target;
-
-    static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
-        Time via;
-        via.target = std::move(dst);
-        return move_unique(via);
-    }
-
-    Status draw(Src* src) override {
-        auto start = std::chrono::steady_clock::now();
-            Status status = target->draw(src);
-        std::chrono::duration<double, std::milli> elapsed = std::chrono::steady_clock::now()
-                                                          - start;
-
-        if (status != Status::Skipped) {
-            auto msg = HumanizeMs(elapsed.count());
-            ok_log(msg.c_str());
-        }
-        return status;
-    }
-
-    sk_sp<SkImage> image() override {
-        return target->image();
-    }
-};
-static Register _time{"time", "print wall run time", Time::Create};
-
-struct Memory : Dst {
-    std::unique_ptr<Dst> target;
-
-    static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
-        Memory via;
-        via.target = std::move(dst);
-        return move_unique(via);
-    }
-
-    Status draw(Src* src) override {
-        Status status = target->draw(src);
-
-        if (status != Status::Skipped) {
-            auto msg = SkStringPrintf("%dMB", sk_tools::getMaxResidentSetSizeMB());
-            ok_log(msg.c_str());
-        }
-
-        return status;
-    }
-
-    sk_sp<SkImage> image() override {
-        return target->image();
-    }
-};
-static Register memory{"memory", "print process maximum memory usage", Memory::Create};
-
-struct Trace : Dst {
-    std::unique_ptr<Dst> target;
-    std::string trace_mode;
-
-    static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
-        Trace via;
-        via.target = std::move(dst);
-        via.trace_mode = options("mode", "trace.json");
-        return move_unique(via);
-    }
-
-    Status draw(Src* src) override {
-        static SkOnce once;
-        once([&] { initializeEventTracingForTools(trace_mode.c_str()); });
-        return target->draw(src);
-    }
-
-    sk_sp<SkImage> image() override {
-        return target->image();
-    }
-};
-static Register trace{"trace",
-                      "enable tracing in mode=atrace, mode=debugf, or mode=trace.json",
-                      Trace::Create};
-
-struct PortableFonts : Dst {
-    std::unique_ptr<Dst> target;
-
-    static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
-        PortableFonts via;
-        via.target = std::move(dst);
-        return move_unique(via);
-    }
-
-    Status draw(Src* src) override {
-        static SkOnce once;
-        once([]{ gSkFontMgr_DefaultFactory = &DM::MakeFontMgr; });
-        return target->draw(src);
-    }
-
-    sk_sp<SkImage> image() override {
-        return target->image();
-    }
-};
-static Register portable_fonts{"portable_fonts",
-                               "use DM::FontMgr to make fonts more portable",
-                               PortableFonts::Create};