aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/skpbench
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-06-26 10:13:06 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-26 18:01:02 +0000
commita4f5ce0c9879ebce8d46e2823311c193a514d93b (patch)
tree831db5d368503e4b91441c8b4dd8cb2deef71baf /tools/skpbench
parentc0fb3c8b9fea2f60062819e92a1fa7f0a1966fba (diff)
skpbench: Support .svg files
Bug: skia: Change-Id: I0337757f635c631870c02a65f8784fc190d1435e Reviewed-on: https://skia-review.googlesource.com/137540 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'tools/skpbench')
-rw-r--r--tools/skpbench/skpbench.cpp74
-rwxr-xr-xtools/skpbench/skpbench.py30
2 files changed, 70 insertions, 34 deletions
diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp
index 399bf6cdb2..55fbc00980 100644
--- a/tools/skpbench/skpbench.cpp
+++ b/tools/skpbench/skpbench.cpp
@@ -37,10 +37,17 @@
#include "picture_utils.h"
#include "sk_tool_utils.h"
+#ifdef SK_XML
+#include "SkDOM.h"
+#include "../experimental/svg/model/SkSVGDOM.h"
+#endif
+
+
/**
- * This is a minimalist program whose sole purpose is to open an skp file, benchmark it on a single
- * config, and exit. It is intended to be used through skpbench.py rather than invoked directly.
- * Limiting the entire process to a single config/skp pair helps to keep the results repeatable.
+ * This is a minimalist program whose sole purpose is to open a .skp or .svg file, benchmark it on a
+ * single config, and exit. It is intended to be used through skpbench.py rather than invoked
+ * directly. Limiting the entire process to a single config/skp pair helps to keep the results
+ * repeatable.
*
* No tiling, looping, or other fanciness is used; it just draws the skp whole into a size-matched
* render target and syncs the GPU after each draw.
@@ -57,7 +64,7 @@ DEFINE_int32(duration, 5000, "number of milliseconds to run the benchmark");
DEFINE_int32(sampleMs, 50, "minimum duration of a sample");
DEFINE_bool(gpuClock, false, "time on the gpu clock (gpu work only)");
DEFINE_bool(fps, false, "use fps instead of ms");
-DEFINE_string(skp, "", "path to a single .skp file, or 'warmup' for a builtin warmup run");
+DEFINE_string(src, "", "path to a single .skp or .svg file, or 'warmup' for a builtin warmup run");
DEFINE_string(png, "", "if set, save a .png proof to disk at this file location");
DEFINE_int32(verbosity, 4, "level of verbosity (0=none to 5=debug)");
DEFINE_bool(suppressHeader, false, "don't print a header row before the results");
@@ -108,6 +115,7 @@ enum class ExitErr {
static void draw_skp_and_flush(SkCanvas*, const SkPicture*);
static sk_sp<SkPicture> create_warmup_skp();
+static sk_sp<SkPicture> create_skp_from_svg(SkStream*, const char* filename);
static bool mkdir_p(const SkString& name);
static SkString join(const SkCommandLineFlags::StringArray&);
static void exitf(ExitErr, const char* format, ...);
@@ -337,36 +345,41 @@ int main(int argc, char** argv) {
}
// Parse the skp.
- if (FLAGS_skp.count() != 1) {
- exitf(ExitErr::kUsage, "invalid skp '%s': must specify a single skp file, or 'warmup'",
- join(FLAGS_skp).c_str());
+ if (FLAGS_src.count() != 1) {
+ exitf(ExitErr::kUsage,
+ "invalid input '%s': must specify a single .skp or .svg file, or 'warmup'",
+ join(FLAGS_src).c_str());
}
SkGraphics::Init();
sk_sp<SkPicture> skp;
- SkString skpname;
- if (0 == strcmp(FLAGS_skp[0], "warmup")) {
+ SkString srcname;
+ if (0 == strcmp(FLAGS_src[0], "warmup")) {
skp = create_warmup_skp();
- skpname = "warmup";
+ srcname = "warmup";
} else {
- const char* skpfile = FLAGS_skp[0];
- std::unique_ptr<SkStream> skpstream(SkStream::MakeFromFile(skpfile));
- if (!skpstream) {
- exitf(ExitErr::kIO, "failed to open skp file %s", skpfile);
+ SkString srcfile(FLAGS_src[0]);
+ std::unique_ptr<SkStream> srcstream(SkStream::MakeFromFile(srcfile.c_str()));
+ if (!srcstream) {
+ exitf(ExitErr::kIO, "failed to open file %s", srcfile.c_str());
+ }
+ if (srcfile.endsWith(".svg")) {
+ skp = create_skp_from_svg(srcstream.get(), srcfile.c_str());
+ } else {
+ skp = SkPicture::MakeFromStream(srcstream.get());
}
- skp = SkPicture::MakeFromStream(skpstream.get());
if (!skp) {
- exitf(ExitErr::kData, "failed to parse skp file %s", skpfile);
+ exitf(ExitErr::kData, "failed to parse file %s", srcfile.c_str());
}
- skpname = SkOSPath::Basename(skpfile);
+ srcname = SkOSPath::Basename(srcfile.c_str());
}
int width = SkTMin(SkScalarCeilToInt(skp->cullRect().width()), 2048),
height = SkTMin(SkScalarCeilToInt(skp->cullRect().height()), 2048);
if (FLAGS_verbosity >= 3 &&
(width != skp->cullRect().width() || height != skp->cullRect().height())) {
fprintf(stderr, "%s is too large (%ix%i), cropping to %ix%i.\n",
- skpname.c_str(), SkScalarCeilToInt(skp->cullRect().width()),
+ srcname.c_str(), SkScalarCeilToInt(skp->cullRect().width()),
SkScalarCeilToInt(skp->cullRect().height()), width, height);
}
@@ -448,7 +461,7 @@ int main(int argc, char** argv) {
run_gpu_time_benchmark(testCtx->gpuTimer(), testCtx->fenceSync(), canvas, skp.get(),
&samples);
}
- print_result(samples, config->getTag().c_str(), skpname.c_str());
+ print_result(samples, config->getTag().c_str(), srcname.c_str());
// Save a proof (if one was requested).
if (!FLAGS_png.isEmpty()) {
@@ -499,6 +512,29 @@ static sk_sp<SkPicture> create_warmup_skp() {
return recorder.finishRecordingAsPicture();
}
+static sk_sp<SkPicture> create_skp_from_svg(SkStream* stream, const char* filename) {
+#ifdef SK_XML
+ SkDOM xml;
+ if (!xml.build(*stream)) {
+ exitf(ExitErr::kData, "failed to parse xml in file %s", filename);
+ }
+ sk_sp<SkSVGDOM> svg = SkSVGDOM::MakeFromDOM(xml);
+ if (!svg) {
+ exitf(ExitErr::kData, "failed to build svg dom from file %s", filename);
+ }
+
+ static constexpr SkRect bounds{0, 0, 1200, 1200};
+ SkPictureRecorder recorder;
+ SkCanvas* recording = recorder.beginRecording(bounds);
+
+ svg->setContainerSize(SkSize::Make(recording->getBaseLayerSize()));
+ svg->render(recording);
+
+ return recorder.finishRecordingAsPicture();
+#endif
+ exitf(ExitErr::kData, "SK_XML is disabled; cannot open svg file %s", filename);
+}
+
bool mkdir_p(const SkString& dirname) {
if (dirname.isEmpty()) {
return true;
diff --git a/tools/skpbench/skpbench.py b/tools/skpbench/skpbench.py
index 0477db2227..9d111f0ff0 100755
--- a/tools/skpbench/skpbench.py
+++ b/tools/skpbench/skpbench.py
@@ -79,9 +79,9 @@ __argparse.add_argument('--gpuThreads',
type=int, default=-1,
help="Create this many extra threads to assist with GPU work, including"
" software path rendering. Defaults to two.")
-__argparse.add_argument('skps',
+__argparse.add_argument('srcs',
nargs='+',
- help=".skp files or directories to expand for .skp files")
+ help=".skp files or directories to expand for .skp files, and/or .svg files")
FLAGS = __argparse.parse_args()
if FLAGS.adb:
@@ -167,7 +167,7 @@ class SKPBench:
print('running %i second warmup...' % warmup_time, file=sys.stderr)
commandline = cls.ARGV + ['--duration', str(warmup_time * 1000),
'--config', config,
- '--skp', 'warmup']
+ '--src', 'warmup']
dump_commandline_if_verbose(commandline)
output = subprocess.check_output(commandline, stderr=subprocess.STDOUT)
@@ -178,8 +178,8 @@ class SKPBench:
return
raise Exception('Invalid warmup output:\n%s' % output)
- def __init__(self, skp, config, max_stddev, best_result=None):
- self.skp = skp
+ def __init__(self, src, config, max_stddev, best_result=None):
+ self.src = src
self.config = config
self.max_stddev = max_stddev
self.best_result = best_result
@@ -202,11 +202,11 @@ class SKPBench:
self._schedule_hardware_poll()
commandline = self.ARGV + ['--config', self.config,
- '--skp', self.skp,
+ '--src', self.src,
'--suppressHeader', 'true']
if FLAGS.write_path:
pngfile = _path.join(FLAGS.write_path, self.config,
- _path.basename(self.skp) + '.png')
+ _path.basename(self.src) + '.png')
commandline.extend(['--png', pngfile])
dump_commandline_if_verbose(commandline)
self._proc = subprocess.Popen(commandline, stdout=subprocess.PIPE,
@@ -269,10 +269,10 @@ def emit_result(line, resultsfile=None):
print(line, file=resultsfile)
resultsfile.flush()
-def run_benchmarks(configs, skps, hardware, resultsfile=None):
+def run_benchmarks(configs, srcs, hardware, resultsfile=None):
hasheader = False
- benches = collections.deque([(skp, config, FLAGS.max_stddev)
- for skp in skps
+ benches = collections.deque([(src, config, FLAGS.max_stddev)
+ for src in srcs
for config in configs])
while benches:
try:
@@ -291,7 +291,7 @@ def run_benchmarks(configs, skps, hardware, resultsfile=None):
resultsfile)
else:
print("WARNING: no result for %s with config %s" %
- (skpbench.skp, skpbench.config), file=sys.stderr)
+ (skpbench.src, skpbench.config), file=sys.stderr)
except StddevException:
retry_max_stddev = skpbench.max_stddev * math.sqrt(2)
@@ -302,7 +302,7 @@ def run_benchmarks(configs, skps, hardware, resultsfile=None):
skpbench.best_result.stddev, skpbench.max_stddev,
retry_max_stddev),
file=sys.stderr)
- benches.append((skpbench.skp, skpbench.config, retry_max_stddev,
+ benches.append((skpbench.src, skpbench.config, retry_max_stddev,
skpbench.best_result))
except HardwareException as exception:
@@ -322,7 +322,7 @@ def main():
# Delimiter is ',' or ' ', skip if nested inside parens (e.g. gpu(a=b,c=d)).
DELIMITER = r'[, ](?!(?:[^(]*\([^)]*\))*[^()]*\))'
configs = re.split(DELIMITER, FLAGS.config)
- skps = _path.find_skps(FLAGS.skps)
+ srcs = _path.find_skps(FLAGS.srcs)
if FLAGS.adb:
adb = Adb(FLAGS.device_serial, FLAGS.adb_binary,
@@ -350,9 +350,9 @@ def main():
if FLAGS.resultsfile:
with open(FLAGS.resultsfile, mode='a+') as resultsfile:
- run_benchmarks(configs, skps, hardware, resultsfile=resultsfile)
+ run_benchmarks(configs, srcs, hardware, resultsfile=resultsfile)
else:
- run_benchmarks(configs, skps, hardware)
+ run_benchmarks(configs, srcs, hardware)
if __name__ == '__main__':