Index: tools/skpbench/skpbench.cpp |
diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp |
index 6d0381a28d75dcd3cfde5658bb737ea75b584930..f452d9d025e8716b4fca01f36bf08abbeb450add 100644 |
--- a/tools/skpbench/skpbench.cpp |
+++ b/tools/skpbench/skpbench.cpp |
@@ -9,11 +9,14 @@ |
#include "GrContextFactory.h" |
#include "SkCanvas.h" |
#include "SkOSFile.h" |
+#include "SkPerlinNoiseShader.h" |
#include "SkPicture.h" |
+#include "SkPictureRecorder.h" |
#include "SkStream.h" |
#include "SkSurface.h" |
#include "SkSurfaceProps.h" |
#include "picture_utils.h" |
+#include "sk_tool_utils.h" |
#include "flags/SkCommandLineFlags.h" |
#include "flags/SkCommonFlagsConfig.h" |
#include <stdlib.h> |
@@ -38,7 +41,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 to benchmark"); |
+DEFINE_string(skp, "", "path to a single .skp 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"); |
@@ -86,6 +89,7 @@ enum class ExitErr { |
}; |
static void draw_skp_and_flush(SkCanvas*, const SkPicture*); |
+static sk_sp<SkPicture> create_warmup_skp(); |
static bool mkdir_p(const SkString& name); |
static SkString join(const SkCommandLineFlags::StringArray&); |
static void exitf(ExitErr, const char* format, ...); |
@@ -230,31 +234,38 @@ int main(int argc, char** argv) { |
SkCommandLineConfigArray configs; |
ParseConfigs(FLAGS_config, &configs); |
if (configs.count() != 1 || !(config = configs[0]->asConfigGpu())) { |
- exitf(ExitErr::kUsage, "invalid config %s, must specify one (and only one) GPU config", |
+ exitf(ExitErr::kUsage, "invalid config '%s': must specify one (and only one) GPU config", |
join(FLAGS_config).c_str()); |
} |
// Parse the skp. |
if (FLAGS_skp.count() != 1) { |
- exitf(ExitErr::kUsage, "invalid skp %s, must specify (and only one) skp path name.", |
+ exitf(ExitErr::kUsage, "invalid skp '%s': must specify a single skp file, or 'warmup'", |
join(FLAGS_skp).c_str()); |
} |
- 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); |
- } |
- sk_sp<SkPicture> skp = SkPicture::MakeFromStream(skpstream.get()); |
- if (!skp) { |
- exitf(ExitErr::kData, "failed to parse skp file %s", skpfile); |
+ sk_sp<SkPicture> skp; |
+ SkString skpname; |
+ if (0 == strcmp(FLAGS_skp[0], "warmup")) { |
+ skp = create_warmup_skp(); |
+ skpname = "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); |
+ } |
+ skp = SkPicture::MakeFromStream(skpstream.get()); |
+ if (!skp) { |
+ exitf(ExitErr::kData, "failed to parse skp file %s", skpfile); |
+ } |
+ skpname = SkOSPath::Basename(skpfile); |
} |
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", |
- SkOSPath::Basename(skpfile).c_str(), |
- SkScalarCeilToInt(skp->cullRect().width()), |
+ skpname.c_str(), SkScalarCeilToInt(skp->cullRect().width()), |
SkScalarCeilToInt(skp->cullRect().height()), width, height); |
} |
@@ -295,6 +306,7 @@ int main(int argc, char** argv) { |
width, height, config->getTag().c_str()); |
} |
+ // Run the benchmark. |
std::vector<Sample> samples; |
if (FLAGS_sampleMs > 0) { |
// +1 because we might take one more sample in order to have an odd number. |
@@ -302,8 +314,6 @@ int main(int argc, char** argv) { |
} else { |
samples.reserve(2 * FLAGS_duration); |
} |
- |
- // Run the benchmark. |
SkCanvas* canvas = surface->getCanvas(); |
canvas->translate(-skp->cullRect().x(), -skp->cullRect().y()); |
if (!FLAGS_gpuClock) { |
@@ -315,7 +325,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(), SkOSPath::Basename(skpfile).c_str()); |
+ print_result(samples, config->getTag().c_str(), skpname.c_str()); |
// Save a proof (if one was requested). |
if (!FLAGS_png.isEmpty()) { |
@@ -342,6 +352,30 @@ static void draw_skp_and_flush(SkCanvas* canvas, const SkPicture* skp) { |
canvas->flush(); |
} |
+static sk_sp<SkPicture> create_warmup_skp() { |
+ static constexpr SkRect bounds{0, 0, 500, 500}; |
+ SkPictureRecorder recorder; |
+ SkCanvas* recording = recorder.beginRecording(bounds); |
+ |
+ recording->clear(SK_ColorWHITE); |
+ |
+ SkPaint stroke; |
+ stroke.setStyle(SkPaint::kStroke_Style); |
+ stroke.setStrokeWidth(2); |
+ |
+ // Use a big path to (theoretically) warmup the CPU. |
+ SkPath bigPath; |
+ sk_tool_utils::make_big_path(bigPath); |
+ recording->drawPath(bigPath, stroke); |
+ |
+ // Use a perlin shader to warmup the GPU. |
+ SkPaint perlin; |
+ perlin.setShader(SkPerlinNoiseShader::MakeTurbulence(0.1f, 0.1f, 1, 0, nullptr)); |
+ recording->drawRect(bounds, perlin); |
+ |
+ return recorder.finishRecordingAsPicture(); |
+} |
+ |
bool mkdir_p(const SkString& dirname) { |
if (dirname.isEmpty()) { |
return true; |
@@ -351,8 +385,8 @@ bool mkdir_p(const SkString& dirname) { |
static SkString join(const SkCommandLineFlags::StringArray& stringArray) { |
SkString joined; |
- for (int i = 0; i < FLAGS_config.count(); ++i) { |
- joined.appendf(i ? " %s" : "%s", FLAGS_config[i]); |
+ for (int i = 0; i < stringArray.count(); ++i) { |
+ joined.appendf(i ? " %s" : "%s", stringArray[i]); |
} |
return joined; |
} |