blob: 37d371f7977f843ee707717f124800457bb7ca77 [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 Klein99609bb2017-06-19 12:05:31 -070012#include "ProcStats.h"
Mike Klein62669ad2017-05-09 16:03:07 -040013#include "Timer.h"
Mike Kleine15a7b52017-03-29 12:41:13 -040014#include "ok.h"
Mike Klein62669ad2017-05-09 16:03:07 -040015#include <chrono>
Mike Kleine15a7b52017-03-29 12:41:13 -040016#include <regex>
Mike Kleinf5d1a552017-03-25 12:32:22 -040017
Mike Kleine15a7b52017-03-29 12:41:13 -040018static std::unique_ptr<Src> proxy(Src* original, std::function<Status(SkCanvas*)> fn) {
Mike Klein0222e702017-03-25 15:53:14 -040019 struct : Src {
Mike Kleine15a7b52017-03-29 12:41:13 -040020 Src* original;
21 std::function<Status(SkCanvas*)> fn;
Mike Klein0222e702017-03-25 15:53:14 -040022
23 std::string name() override { return original->name(); }
24 SkISize size() override { return original->size(); }
Mike Kleine15a7b52017-03-29 12:41:13 -040025 Status draw(SkCanvas* canvas) override { return fn(canvas); }
Mike Klein0222e702017-03-25 15:53:14 -040026 } src;
27 src.original = original;
28 src.fn = fn;
29 return move_unique(src);
30}
31
Mike Kleinf5d1a552017-03-25 12:32:22 -040032struct ViaPic : Dst {
33 std::unique_ptr<Dst> target;
Mike Klein0222e702017-03-25 15:53:14 -040034 bool rtree = false;
Mike Kleinf5d1a552017-03-25 12:32:22 -040035
Mike Klein0222e702017-03-25 15:53:14 -040036 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
37 ViaPic via;
38 via.target = std::move(dst);
39 if (options("bbh") == "rtree") { via.rtree = true; }
40 return move_unique(via);
Mike Kleinf5d1a552017-03-25 12:32:22 -040041 }
42
Mike Kleine15a7b52017-03-29 12:41:13 -040043 Status draw(Src* src) override {
Mike Klein0222e702017-03-25 15:53:14 -040044 SkRTreeFactory factory;
45 SkPictureRecorder rec;
46 rec.beginRecording(SkRect::MakeSize(SkSize::Make(src->size())),
47 rtree ? &factory : nullptr);
Mike Kleinf5d1a552017-03-25 12:32:22 -040048
Mike Kleine15a7b52017-03-29 12:41:13 -040049 for (auto status = src->draw(rec.getRecordingCanvas()); status != Status::OK; ) {
50 return status;
Mike Klein0222e702017-03-25 15:53:14 -040051 }
Mike Kleinf5d1a552017-03-25 12:32:22 -040052 auto pic = rec.finishRecordingAsPicture();
Mike Klein0222e702017-03-25 15:53:14 -040053
54 return target->draw(proxy(src, [=](SkCanvas* canvas) {
55 pic->playback(canvas);
Mike Kleine15a7b52017-03-29 12:41:13 -040056 return Status::OK;
Mike Klein0222e702017-03-25 15:53:14 -040057 }).get());
58 }
59
60 sk_sp<SkImage> image() override {
61 return target->image();
Mike Kleinf5d1a552017-03-25 12:32:22 -040062 }
63};
Mike Kleine15a7b52017-03-29 12:41:13 -040064static Register via_pic{"via_pic", "record then play back an SkPicture", ViaPic::Create};
65
66struct Png : Dst {
67 std::unique_ptr<Dst> target;
68 std::string dir;
69
70 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
71 Png via;
72 via.target = std::move(dst);
73 via.dir = options("dir", "ok");
74 return move_unique(via);
75 }
76
77 Status draw(Src* src) override {
78 for (auto status = target->draw(src); status != Status::OK; ) {
79 return status;
80 }
81
Mike Klein39748b22017-05-07 10:52:30 -040082 SkBitmap bm;
83 SkPixmap pm;
84 if (!target->image()->asLegacyBitmap(&bm, SkImage::kRO_LegacyBitmapMode) ||
85 !bm.peekPixels(&pm)) {
86 return Status::Failed;
87 }
Mike Kleine15a7b52017-03-29 12:41:13 -040088
89 sk_mkdir(dir.c_str());
Mike Klein39748b22017-05-07 10:52:30 -040090 SkFILEWStream dst{(dir + "/" + src->name() + ".png").c_str()};
91
92 SkPngEncoder::Options options;
93 options.fFilterFlags = SkPngEncoder::FilterFlag::kNone;
94 options.fZLibLevel = 1;
95 options.fUnpremulBehavior = pm.colorSpace() ? SkTransferFunctionBehavior::kRespect
96 : SkTransferFunctionBehavior::kIgnore;
97 return SkPngEncoder::Encode(&dst, pm, options) ? Status::OK
98 : Status::Failed;
Mike Kleine15a7b52017-03-29 12:41:13 -040099 }
100
101 sk_sp<SkImage> image() override {
102 return target->image();
103 }
104};
105static Register png{"png", "dump PNGs to dir=ok" , Png::Create};
106
107struct Filter : Dst {
108 std::unique_ptr<Dst> target;
109 std::regex match, search;
110
111 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
112 Filter via;
113 via.target = std::move(dst);
114 via.match = options("match", ".*");
115 via.search = options("search", ".*");
116 return move_unique(via);
117 }
118
119 Status draw(Src* src) override {
120 auto name = src->name();
121 if (!std::regex_match (name, match) ||
122 !std::regex_search(name, search)) {
123 return Status::Skipped;
124 }
125 return target->draw(src);
126 }
127
128 sk_sp<SkImage> image() override {
129 return target->image();
130 }
131};
Mike Klein452a7a22017-05-09 18:04:04 -0400132static Register filter{"filter",
Mike Kleine15a7b52017-03-29 12:41:13 -0400133 "run only srcs matching match=.* exactly and search=.* somewhere",
134 Filter::Create};
Mike Klein62669ad2017-05-09 16:03:07 -0400135
136struct Time : Dst {
137 std::unique_ptr<Dst> target;
138
139 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
140 Time via;
141 via.target = std::move(dst);
142 return move_unique(via);
143 }
144
145 Status draw(Src* src) override {
146 auto start = std::chrono::steady_clock::now();
147 Status status = target->draw(src);
148 std::chrono::duration<double, std::milli> elapsed = std::chrono::steady_clock::now()
149 - start;
150
151 auto msg = HumanizeMs(elapsed.count());
152 ok_log(msg.c_str());
153 return status;
154 }
155
156 sk_sp<SkImage> image() override {
157 return target->image();
158 }
159};
Mike Klein99609bb2017-06-19 12:05:31 -0700160static Register _time{"time", "print wall run time", Time::Create};
161
162struct Memory : Dst {
163 std::unique_ptr<Dst> target;
164
165 static std::unique_ptr<Dst> Create(Options options, std::unique_ptr<Dst> dst) {
166 Memory via;
167 via.target = std::move(dst);
168 return move_unique(via);
169 }
170
171 Status draw(Src* src) override {
172 Status status = target->draw(src);
173
174 auto msg = SkStringPrintf("%dMB", sk_tools::getMaxResidentSetSizeMB());
175 ok_log(msg.c_str());
176
177 return status;
178 }
179
180 sk_sp<SkImage> image() override {
181 return target->image();
182 }
183};
184static Register memory{"memory", "print process maximum memory usage", Memory::Create};