blob: 50db49f2dbb61f872840eb99633810cafc616a55 [file] [log] [blame]
Mike Kleinf5d1a552017-03-25 12:32:22 -04001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Florin Malitaab244f02017-05-03 19:16:58 +00008#include "SkImage.h"
Mike Kleine15a7b52017-03-29 12:41:13 -04009#include "SkOSFile.h"
Mike Kleinf5d1a552017-03-25 12:32:22 -040010#include "SkPictureRecorder.h"
Mike Klein39748b22017-05-07 10:52:30 -040011#include "SkPngEncoder.h"
Mike Klein62669ad2017-05-09 16:03:07 -040012#include "Timer.h"
Mike Kleine15a7b52017-03-29 12:41:13 -040013#include "ok.h"
Mike Klein62669ad2017-05-09 16:03:07 -040014#include <chrono>
Mike Kleine15a7b52017-03-29 12:41:13 -040015#include <regex>
Mike Kleinf5d1a552017-03-25 12:32:22 -040016
Mike Kleine15a7b52017-03-29 12:41:13 -040017static std::unique_ptr<Src> proxy(Src* original, std::function<Status(SkCanvas*)> fn) {
Mike Klein0222e702017-03-25 15:53:14 -040018 struct : Src {
Mike Kleine15a7b52017-03-29 12:41:13 -040019 Src* original;
20 std::function<Status(SkCanvas*)> fn;
Mike Klein0222e702017-03-25 15:53:14 -040021
22 std::string name() override { return original->name(); }
23 SkISize size() override { return original->size(); }
Mike Kleine15a7b52017-03-29 12:41:13 -040024 Status draw(SkCanvas* canvas) override { return fn(canvas); }
Mike Klein0222e702017-03-25 15:53:14 -040025 } src;
26 src.original = original;
27 src.fn = fn;
28 return move_unique(src);
29}
30
Mike Kleinf5d1a552017-03-25 12:32:22 -040031struct ViaPic : Dst {
32 std::unique_ptr<Dst> target;
Mike Klein0222e702017-03-25 15:53:14 -040033 bool rtree = false;
Mike Kleinf5d1a552017-03-25 12:32:22 -040034
Mike Klein0222e702017-03-25 15:53:14 -040035 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
36 ViaPic via;
37 via.target = std::move(dst);
38 if (options("bbh") == "rtree") { via.rtree = true; }
39 return move_unique(via);
Mike Kleinf5d1a552017-03-25 12:32:22 -040040 }
41
Mike Kleine15a7b52017-03-29 12:41:13 -040042 Status draw(Src* src) override {
Mike Klein0222e702017-03-25 15:53:14 -040043 SkRTreeFactory factory;
44 SkPictureRecorder rec;
45 rec.beginRecording(SkRect::MakeSize(SkSize::Make(src->size())),
46 rtree ? &factory : nullptr);
Mike Kleinf5d1a552017-03-25 12:32:22 -040047
Mike Kleine15a7b52017-03-29 12:41:13 -040048 for (auto status = src->draw(rec.getRecordingCanvas()); status != Status::OK; ) {
49 return status;
Mike Klein0222e702017-03-25 15:53:14 -040050 }
Mike Kleinf5d1a552017-03-25 12:32:22 -040051 auto pic = rec.finishRecordingAsPicture();
Mike Klein0222e702017-03-25 15:53:14 -040052
53 return target->draw(proxy(src, [=](SkCanvas* canvas) {
54 pic->playback(canvas);
Mike Kleine15a7b52017-03-29 12:41:13 -040055 return Status::OK;
Mike Klein0222e702017-03-25 15:53:14 -040056 }).get());
57 }
58
59 sk_sp<SkImage> image() override {
60 return target->image();
Mike Kleinf5d1a552017-03-25 12:32:22 -040061 }
62};
Mike Kleine15a7b52017-03-29 12:41:13 -040063static Register via_pic{"via_pic", "record then play back an SkPicture", ViaPic::Create};
64
65struct Png : Dst {
66 std::unique_ptr<Dst> target;
67 std::string dir;
68
69 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
70 Png via;
71 via.target = std::move(dst);
72 via.dir = options("dir", "ok");
73 return move_unique(via);
74 }
75
76 Status draw(Src* src) override {
77 for (auto status = target->draw(src); status != Status::OK; ) {
78 return status;
79 }
80
Mike Klein39748b22017-05-07 10:52:30 -040081 SkBitmap bm;
82 SkPixmap pm;
83 if (!target->image()->asLegacyBitmap(&bm, SkImage::kRO_LegacyBitmapMode) ||
84 !bm.peekPixels(&pm)) {
85 return Status::Failed;
86 }
Mike Kleine15a7b52017-03-29 12:41:13 -040087
88 sk_mkdir(dir.c_str());
Mike Klein39748b22017-05-07 10:52:30 -040089 SkFILEWStream dst{(dir + "/" + src->name() + ".png").c_str()};
90
91 SkPngEncoder::Options options;
92 options.fFilterFlags = SkPngEncoder::FilterFlag::kNone;
93 options.fZLibLevel = 1;
94 options.fUnpremulBehavior = pm.colorSpace() ? SkTransferFunctionBehavior::kRespect
95 : SkTransferFunctionBehavior::kIgnore;
96 return SkPngEncoder::Encode(&dst, pm, options) ? Status::OK
97 : Status::Failed;
Mike Kleine15a7b52017-03-29 12:41:13 -040098 }
99
100 sk_sp<SkImage> image() override {
101 return target->image();
102 }
103};
104static Register png{"png", "dump PNGs to dir=ok" , Png::Create};
105
106struct Filter : Dst {
107 std::unique_ptr<Dst> target;
108 std::regex match, search;
109
110 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
111 Filter via;
112 via.target = std::move(dst);
113 via.match = options("match", ".*");
114 via.search = options("search", ".*");
115 return move_unique(via);
116 }
117
118 Status draw(Src* src) override {
119 auto name = src->name();
120 if (!std::regex_match (name, match) ||
121 !std::regex_search(name, search)) {
122 return Status::Skipped;
123 }
124 return target->draw(src);
125 }
126
127 sk_sp<SkImage> image() override {
128 return target->image();
129 }
130};
Mike Klein452a7a22017-05-09 18:04:04 -0400131static Register filter{"filter",
Mike Kleine15a7b52017-03-29 12:41:13 -0400132 "run only srcs matching match=.* exactly and search=.* somewhere",
133 Filter::Create};
Mike Klein62669ad2017-05-09 16:03:07 -0400134
135struct Time : Dst {
136 std::unique_ptr<Dst> target;
137
138 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
139 Time via;
140 via.target = std::move(dst);
141 return move_unique(via);
142 }
143
144 Status draw(Src* src) override {
145 auto start = std::chrono::steady_clock::now();
146 Status status = target->draw(src);
147 std::chrono::duration<double, std::milli> elapsed = std::chrono::steady_clock::now()
148 - start;
149
150 auto msg = HumanizeMs(elapsed.count());
151 ok_log(msg.c_str());
152 return status;
153 }
154
155 sk_sp<SkImage> image() override {
156 return target->image();
157 }
158};
Mike Klein452a7a22017-05-09 18:04:04 -0400159static Register _time{"time",
Mike Klein62669ad2017-05-09 16:03:07 -0400160 "print wall run time",
161 Time::Create};