Allow GMs to be used as benchmarks. Make convex_poly_clip opt in.
R=reed@google.com
Author: bsalomon@google.com
Review URL: https://codereview.chromium.org/151843002
git-svn-id: http://skia.googlecode.com/svn/trunk@13279 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/bench/SkBenchmark.h b/bench/SkBenchmark.h
index bf44d2c..f1e317d 100644
--- a/bench/SkBenchmark.h
+++ b/bench/SkBenchmark.h
@@ -13,9 +13,13 @@
#include "SkString.h"
#include "SkTRegistry.h"
-#define DEF_BENCH(code) \
-static SkBenchmark* SK_MACRO_APPEND_LINE(F_)() { code; } \
-static BenchRegistry SK_MACRO_APPEND_LINE(R_)(SK_MACRO_APPEND_LINE(F_));
+#define DEF_BENCH(code) \
+namespace { \
+class SK_MACRO_APPEND_LINE(F_CLASS) : public SkBenchmarkFactory { \
+ virtual SkBenchmark* operator()() const SK_OVERRIDE { code; } \
+} SK_MACRO_APPEND_LINE(g_F_); \
+BenchRegistry SK_MACRO_APPEND_LINE(g_R_)(&SK_MACRO_APPEND_LINE(g_F_)); \
+}
/*
* With the above macros, you can register benches as follows (at the bottom
@@ -132,6 +136,13 @@
typedef SkRefCnt INHERITED;
};
-typedef SkTRegistry<SkBenchmark*(*)()> BenchRegistry;
+class SkBenchmarkFactory : public SkRefCnt {
+public:
+ // Creates a new SkBenchmark that is owned by the caller on each call.
+ virtual SkBenchmark* operator()() const = 0;
+ virtual ~SkBenchmarkFactory() {}
+};
+
+typedef SkTRegistry<SkBenchmarkFactory*> BenchRegistry;
#endif
diff --git a/bench/SkGMBench.cpp b/bench/SkGMBench.cpp
new file mode 100644
index 0000000..e1d8124
--- /dev/null
+++ b/bench/SkGMBench.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkGMBench.h"
+
+SkGMBench::SkGMBench(skiagm::GM* gm) : fGM(gm) {
+ fName.printf("GM:%s", gm->shortName());
+}
+
+SkGMBench::~SkGMBench() { delete fGM; }
+
+const char* SkGMBench::onGetName() {
+ return fName.c_str();
+}
+
+bool SkGMBench::isSuitableFor(Backend backend) {
+ uint32_t flags = fGM->getFlags();
+ switch (backend) {
+ case kGPU_Backend:
+ return !(skiagm::GM::kSkipGPU_Flag & flags);
+ case kPDF_Backend:
+ return !(skiagm::GM::kSkipPDF_Flag & flags);
+ case kRaster_Backend:
+ // GM doesn't have an equivalent flag. If the GM has known issues with 565 then
+ // we skip it for ALL raster configs in bench.
+ return !(skiagm::GM::kSkip565_Flag & flags);
+ case kNonRendering_Backend:
+ return false;
+ default:
+ SkDEBUGFAIL("Unexpected backend type.");
+ return false;
+ }
+}
+
+void SkGMBench::onDraw(const int loops, SkCanvas* canvas) {
+ // Do we care about timing the draw of the background (once)?
+ // Does the GM ever rely on drawBackground to lazily compute something?
+ fGM->drawBackground(canvas);
+ for (int i = 0; i < loops; ++i) {
+ fGM->drawContent(canvas);
+ }
+}
+
+SkIPoint SkGMBench::onGetSize() {
+ SkISize size = fGM->getISize();
+ return SkIPoint::Make(size.fWidth, size.fHeight);
+}
diff --git a/bench/SkGMBench.h b/bench/SkGMBench.h
new file mode 100644
index 0000000..925a875
--- /dev/null
+++ b/bench/SkGMBench.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkBenchmark.h"
+#include "gm.h"
+#include "SkCanvas.h"
+
+/**
+ * Runs a GM as a benchmark by repeatedly drawing the GM.
+ */
+class SkGMBench : public SkBenchmark {
+public:
+ // Constructor takes ownership of the GM param.
+ SkGMBench(skiagm::GM* gm);
+ virtual ~SkGMBench();
+
+protected:
+ virtual const char* onGetName() SK_OVERRIDE;
+ virtual bool isSuitableFor(Backend backend) SK_OVERRIDE;
+ virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE;
+ virtual SkIPoint onGetSize() SK_OVERRIDE;
+
+private:
+ skiagm::GM* fGM;
+ SkString fName;
+ typedef SkBenchmark INHERITED;
+};
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
index 12c9820..80aed1c 100644
--- a/bench/benchmain.cpp
+++ b/bench/benchmain.cpp
@@ -14,6 +14,7 @@
#include "SkColorPriv.h"
#include "SkCommandLineFlags.h"
#include "SkDeferredCanvas.h"
+#include "SkGMBench.h"
#include "SkGraphics.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
@@ -32,6 +33,52 @@
#include <limits>
+// Note that ~SkTDArray is not virtual. This inherits privately to bar using this as a SkTDArray*.
+class RefCntArray : private SkTDArray<SkRefCnt*> {
+public:
+ SkRefCnt** append() { return this->INHERITED::append(); }
+ ~RefCntArray() { this->unrefAll(); }
+private:
+ typedef SkTDArray<SkRefCnt*> INHERITED;
+};
+
+class GMBenchFactory : public SkBenchmarkFactory {
+public:
+ GMBenchFactory(const skiagm::GMRegistry* gmreg)
+ : fGMFactory(gmreg->factory()) {
+ fSelfRegistry = SkNEW_ARGS(BenchRegistry, (this));
+ }
+
+ virtual ~GMBenchFactory() { SkDELETE(fSelfRegistry); }
+
+ virtual SkBenchmark* operator()() const SK_OVERRIDE {
+ skiagm::GM* gm = fGMFactory(NULL);
+ return SkNEW_ARGS(SkGMBench, (gm));
+ }
+
+private:
+ skiagm::GMRegistry::Factory fGMFactory;
+ BenchRegistry* fSelfRegistry;
+};
+
+static void register_gm_benches() {
+ static bool gOnce;
+ static RefCntArray gGMBenchFactories;
+
+ if (!gOnce) {
+ const skiagm::GMRegistry* gmreg = skiagm::GMRegistry::Head();
+ while (gmreg) {
+ skiagm::GM* gm = gmreg->factory()(NULL);
+ if (NULL != gm && skiagm::GM::kAsBench_Flag & gm->getFlags()) {
+ *gGMBenchFactories.append() = SkNEW_ARGS(GMBenchFactory, (gmreg));
+ }
+ SkDELETE(gm);
+ gmreg = gmreg->next();
+ }
+ gOnce = true;
+ }
+}
+
enum BenchMode {
kNormal_BenchMode,
kDeferred_BenchMode,
@@ -63,7 +110,7 @@
if (fBench) {
BenchRegistry::Factory f = fBench->factory();
fBench = fBench->next();
- return f();
+ return (*f)();
}
return NULL;
}
@@ -295,6 +342,7 @@
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
+ register_gm_benches();
SkCommandLineFlags::Parse(argc, argv);
#if SK_ENABLE_INST_COUNT
if (FLAGS_leaks) {
diff --git a/gm/convexpolyclip.cpp b/gm/convexpolyclip.cpp
index db357bb..18b99a7 100644
--- a/gm/convexpolyclip.cpp
+++ b/gm/convexpolyclip.cpp
@@ -182,6 +182,10 @@
}
}
+ virtual uint32_t onGetFlags() const {
+ return kAsBench_Flag;
+ }
+
private:
SkTLList<SkPath> fPaths;
SkBitmap fBmp;
diff --git a/gm/gm.h b/gm/gm.h
index e69cfc0..bb20c9c 100644
--- a/gm/gm.h
+++ b/gm/gm.h
@@ -49,6 +49,8 @@
kSkipPDFRasterization_Flag = 1 << 8,
kGPUOnly_Flag = 1 << 9,
+
+ kAsBench_Flag = 1 << 10, // Run the GM as a benchmark in the bench tool
};
void draw(SkCanvas*);
diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp
index 43c5d89..5d71748 100644
--- a/gyp/SampleApp.gyp
+++ b/gyp/SampleApp.gyp
@@ -23,16 +23,6 @@
'gmslides.gypi',
],
'sources': [
- '../src/utils/debugger/SkDrawCommand.h',
- '../src/utils/debugger/SkDrawCommand.cpp',
- '../src/utils/debugger/SkDebugCanvas.h',
- '../src/utils/debugger/SkDebugCanvas.cpp',
- '../src/utils/debugger/SkObjectParser.h',
- '../src/utils/debugger/SkObjectParser.cpp',
-
- '../gm/gm.cpp',
- '../gm/gm.h',
-
'../samplecode/GMSampleView.h',
'../samplecode/ClockFaceView.cpp',
'../samplecode/OverView.cpp',
diff --git a/gyp/bench.gyp b/gyp/bench.gyp
index d404000..c408d7c 100644
--- a/gyp/bench.gyp
+++ b/gyp/bench.gyp
@@ -97,6 +97,9 @@
'../bench/SkBenchLogger.h',
'../bench/SkBenchmark.cpp',
'../bench/SkBenchmark.h',
+ '../bench/SkGMBench.cpp',
+ '../bench/SkGMBench.h',
+
'../bench/benchmain.cpp',
],
'conditions': [
@@ -111,6 +114,9 @@
},
],
],
+ 'includes': [
+ 'gmslides.gypi',
+ ],
},
{
'target_name' : 'bench_timer',
diff --git a/gyp/gm.gyp b/gyp/gm.gyp
index 971fce5..3533aa5 100644
--- a/gyp/gm.gyp
+++ b/gyp/gm.gyp
@@ -30,29 +30,19 @@
'include_dirs' : [
'../src/core',
'../src/images',
- '../src/lazy',
'../src/effects',
'../src/pipe/utils/',
'../src/utils/',
- '../src/utils/debugger',
],
'includes': [
'gmslides.gypi',
],
'sources': [
- '../gm/gm.cpp',
'../gm/gmmain.cpp',
'../gm/system_preferences_default.cpp',
'../src/pipe/utils/SamplePipeControllers.h',
'../src/pipe/utils/SamplePipeControllers.cpp',
-
- '../src/utils/debugger/SkDrawCommand.h',
- '../src/utils/debugger/SkDrawCommand.cpp',
- '../src/utils/debugger/SkDebugCanvas.h',
- '../src/utils/debugger/SkDebugCanvas.cpp',
- '../src/utils/debugger/SkObjectParser.h',
- '../src/utils/debugger/SkObjectParser.cpp',
],
'dependencies': [
'skia_lib.gyp:skia_lib',
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index 2ba0140..c6c11e3 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -1,6 +1,17 @@
# include this gypi to include all the golden master slides.
{
+ 'include_dirs': [
+ '../gm',
+ # include dirs needed by particular GMs
+ '../src/utils/debugger',
+ '../src/images',
+ '../src/lazy',
+ ],
'sources': [
+ # base class for GMs
+ '../gm/gm.cpp',
+ '../gm/gm.h',
+
'../gm/aaclip.cpp',
'../gm/aarectmodes.cpp',
'../gm/alphagradients.cpp',
@@ -156,5 +167,14 @@
'../gm/xfermodes.cpp',
'../gm/xfermodes2.cpp',
'../gm/xfermodes3.cpp',
+
+ # Files needed by particular GMs
+ '../src/utils/debugger/SkDrawCommand.h',
+ '../src/utils/debugger/SkDrawCommand.cpp',
+ '../src/utils/debugger/SkDebugCanvas.h',
+ '../src/utils/debugger/SkDebugCanvas.cpp',
+ '../src/utils/debugger/SkObjectParser.h',
+ '../src/utils/debugger/SkObjectParser.cpp',
+
],
}