blob: 3869006c63a6342d43c7a4d777ef6a19fb5bb29d [file] [log] [blame]
/*
* 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