--- /dev/null
+# Copyright 2016 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+# GYP file to build performance testbench.
+#
+{
+ 'includes': [
+ 'apptype_console.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'kilobench',
+ 'type': 'executable',
+ 'include_dirs': [
+ '../tools/VisualBench',
+ '../bench',
+ '../gm',
+ ],
+ 'sources': [
+ '<!@(python find.py ../tools/kilobench "*.cpp")',
+ '../bench/Benchmark.cpp',
+ '../tools/VisualBench/VisualSKPBench.cpp',
+ ],
+
+ 'dependencies': [
+ 'flags.gyp:flags',
+ 'jsoncpp.gyp:jsoncpp',
+ 'skia_lib.gyp:skia_lib',
+ 'tools.gyp:crash_handler',
+ 'tools.gyp:proc_stats',
+ 'tools.gyp:timer',
+ ],
+ },
+ ],
+}
--- /dev/null
+/*
+ * Copyright 2016 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 "SkCommandLineFlags.h"
+#include "SkOSFile.h"
+#include "SkStream.h"
+#include "VisualSKPBench.h"
+
+/*
+ * This is an experimental GPU only benchmarking program. The initial implementation will only
+ * support SKPs.
+ */
+
+// To get image decoders linked in we have to do the below magic
+#include "SkForceLinking.h"
+#include "SkImageDecoder.h"
+__SK_FORCE_IMAGE_DECODER_LINKING;
+
+DEFINE_string(skps, "skps", "Directory to read skps from.");
+
+DEFINE_string2(match, m, nullptr,
+ "[~][^]substring[$] [...] of GM name to run.\n"
+ "Multiple matches may be separated by spaces.\n"
+ "~ causes a matching bench to always be skipped\n"
+ "^ requires the start of the bench to match\n"
+ "$ requires the end of the bench to match\n"
+ "^ and $ requires an exact match\n"
+ "If a bench does not match any list entry,\n"
+ "it is skipped unless some list entry starts with ~");
+
+namespace kilobench {
+class BenchmarkStream {
+public:
+ BenchmarkStream() : fCurrentSKP(0) {
+ for (int i = 0; i < FLAGS_skps.count(); i++) {
+ if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
+ fSKPs.push_back() = FLAGS_skps[i];
+ } else {
+ SkOSFile::Iter it(FLAGS_skps[i], ".skp");
+ SkString path;
+ while (it.next(&path)) {
+ fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str());
+ }
+ }
+ }
+ }
+
+ Benchmark* next() {
+ Benchmark* bench = nullptr;
+ // skips non matching benches
+ while ((bench = this->innerNext()) &&
+ (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName()) ||
+ !bench->isSuitableFor(Benchmark::kGPU_Backend))) {
+ delete bench;
+ }
+ return bench;
+ }
+
+private:
+ static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) {
+ // Not strictly necessary, as it will be checked again later,
+ // but helps to avoid a lot of pointless work if we're going to skip it.
+ if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) {
+ return false;
+ }
+
+ SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
+ if (stream.get() == nullptr) {
+ SkDebugf("Could not read %s.\n", path);
+ return false;
+ }
+
+ pic->reset(SkPicture::CreateFromStream(stream.get()));
+ if (pic->get() == nullptr) {
+ SkDebugf("Could not read %s as an SkPicture.\n", path);
+ return false;
+ }
+ return true;
+ }
+
+ Benchmark* innerNext() {
+ // Render skps
+ while (fCurrentSKP < fSKPs.count()) {
+ const SkString& path = fSKPs[fCurrentSKP++];
+ SkAutoTUnref<SkPicture> pic;
+ if (!ReadPicture(path.c_str(), &pic)) {
+ continue;
+ }
+
+ SkString name = SkOSPath::Basename(path.c_str());
+ return new VisualSKPBench(name.c_str(), pic.get());
+ }
+
+ return nullptr;
+ }
+
+ SkTArray<SkString> fSKPs;
+ int fCurrentSKP;
+};
+
+} // namespace kilobench
+
+int kilobench_main() {
+ kilobench::BenchmarkStream benchStream;
+ while (Benchmark* b = benchStream.next()) {
+ SkAutoTDelete<Benchmark> bench(b);
+ // TODO actual stuff
+ }
+ return 0;
+}
+
+#if !defined SK_BUILD_FOR_IOS
+int main(int argc, char** argv) {
+ SkCommandLineFlags::Parse(argc, argv);
+ return kilobench_main();
+}
+#endif