aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-29 15:39:54 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-29 15:39:54 +0000
commitef77ec210416733e38072175cc948dcbdb831685 (patch)
tree4b0cb879a55a4277e1e0247dd223be9daf7853f6
parentdc8e6e8503e08ad0c03f81d2624aa5d499dfe2be (diff)
extend SkBenchmark to allow a bench to return a durationScale, which allows it to perform fewer actual interations, but report a scale factor to account for that. Thus a very slow bench can be compared head-to-head with a faster one, w/o actually forcing the tool to run for the full duration of the slower test.
Extend BitmapBench to time bicubic filtering, and use this durationScale for it. Extend SkBenchmark to have setBitmapFlags(or, clear), allowing it to request a set of paint flags to be cleared, and set to be set. BUG= R=robertphillips@google.com Review URL: https://codereview.chromium.org/16069010 git-svn-id: http://skia.googlecode.com/svn/trunk@9315 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--bench/BenchTimer.cpp14
-rw-r--r--bench/BenchTimer.h3
-rw-r--r--bench/BitmapBench.cpp119
-rw-r--r--bench/SkBenchmark.cpp3
-rw-r--r--bench/SkBenchmark.h24
-rw-r--r--bench/benchmain.cpp2
6 files changed, 113 insertions, 52 deletions
diff --git a/bench/BenchTimer.cpp b/bench/BenchTimer.cpp
index ab9dfdaf18..3617f9de58 100644
--- a/bench/BenchTimer.cpp
+++ b/bench/BenchTimer.cpp
@@ -46,7 +46,9 @@ BenchTimer::~BenchTimer() {
#endif
}
-void BenchTimer::start() {
+void BenchTimer::start(double durationScale) {
+ fDurationScale = durationScale;
+
fSysTimer->startWall();
fTruncatedSysTimer->startWall();
#if SK_SUPPORT_GPU
@@ -59,18 +61,18 @@ void BenchTimer::start() {
}
void BenchTimer::end() {
- fCpu = fSysTimer->endCpu();
+ fCpu = fSysTimer->endCpu() * fDurationScale;
#if SK_SUPPORT_GPU
//It is important to stop the cpu clocks first,
//as the following will cpu wait for the gpu to finish.
if (fGpuTimer) {
- fGpu = fGpuTimer->endGpu();
+ fGpu = fGpuTimer->endGpu() * fDurationScale;
}
#endif
- fWall = fSysTimer->endWall();
+ fWall = fSysTimer->endWall() * fDurationScale;
}
void BenchTimer::truncatedEnd() {
- fTruncatedCpu = fTruncatedSysTimer->endCpu();
- fTruncatedWall = fTruncatedSysTimer->endWall();
+ fTruncatedCpu = fTruncatedSysTimer->endCpu() * fDurationScale;
+ fTruncatedWall = fTruncatedSysTimer->endWall() * fDurationScale;
}
diff --git a/bench/BenchTimer.h b/bench/BenchTimer.h
index 79e1036c52..09950a734b 100644
--- a/bench/BenchTimer.h
+++ b/bench/BenchTimer.h
@@ -29,7 +29,7 @@ class BenchTimer {
public:
BenchTimer(SkGLContextHelper* gl = NULL);
~BenchTimer();
- void start();
+ void start(double durationScale = 1);
void end();
void truncatedEnd();
double fCpu;
@@ -44,6 +44,7 @@ private:
#if SK_SUPPORT_GPU
BenchGpuTimer *fGpuTimer;
#endif
+ double fDurationScale; // for this start/end session
};
#endif
diff --git a/bench/BitmapBench.cpp b/bench/BitmapBench.cpp
index eba55f50da..a6d20966ea 100644
--- a/bench/BitmapBench.cpp
+++ b/bench/BitmapBench.cpp
@@ -13,10 +13,6 @@
#include "SkRandom.h"
#include "SkString.h"
-static const char* gTileName[] = {
- "clamp", "repeat", "mirror"
-};
-
static const char* gConfigName[] = {
"ERROR", "a1", "a8", "index8", "565", "4444", "8888"
};
@@ -82,22 +78,19 @@ class BitmapBench : public SkBenchmark {
SkPaint fPaint;
bool fIsOpaque;
bool fForceUpdate; //bitmap marked as dirty before each draw. forces bitmap to be updated on device cache
- int fTileX, fTileY; // -1 means don't use shader
bool fIsVolatile;
SkBitmap::Config fConfig;
SkString fName;
- enum { N = SkBENCHLOOP(300) };
+ enum { BICUBIC_DUR_SCALE = 20 };
+ enum { N = SkBENCHLOOP(15 * BICUBIC_DUR_SCALE) };
enum { W = 128 };
enum { H = 128 };
public:
BitmapBench(void* param, bool isOpaque, SkBitmap::Config c,
- bool forceUpdate = false, bool bitmapVolatile = false,
- int tx = -1, int ty = -1)
+ bool forceUpdate = false, bool bitmapVolatile = false)
: INHERITED(param)
, fIsOpaque(isOpaque)
, fForceUpdate(forceUpdate)
- , fTileX(tx)
- , fTileY(ty)
, fIsVolatile(bitmapVolatile)
, fConfig(c) {
}
@@ -105,12 +98,6 @@ public:
protected:
virtual const char* onGetName() {
fName.set("bitmap");
- if (fTileX >= 0) {
- fName.appendf("_%s", gTileName[fTileX]);
- if (fTileY != fTileX) {
- fName.appendf("_%s", gTileName[fTileY]);
- }
- }
fName.appendf("_%s%s", gConfigName[fConfig],
fIsOpaque ? "" : "_A");
if (fForceUpdate)
@@ -159,7 +146,14 @@ protected:
const SkScalar x0 = SkIntToScalar(-bitmap.width() / 2);
const SkScalar y0 = SkIntToScalar(-bitmap.height() / 2);
- for (int i = 0; i < N; i++) {
+ int count = N;
+#ifdef SK_RELEASE
+ // in DEBUG, N is always 1
+ if (paint.getFlags() & SkPaint::kBicubicFilterBitmap_Flag) {
+ count /= BICUBIC_DUR_SCALE;
+ }
+#endif
+ for (int i = 0; i < count; i++) {
SkScalar x = x0 + rand.nextUScalar1() * dim.fX;
SkScalar y = y0 + rand.nextUScalar1() * dim.fY;
@@ -170,6 +164,17 @@ protected:
}
}
+ virtual float onGetDurationScale() SK_OVERRIDE {
+ SkPaint paint;
+ this->setupPaint(&paint);
+#ifdef SK_DEBUG
+ return 1;
+#else
+ return (paint.getFlags() & SkPaint::kBicubicFilterBitmap_Flag) ?
+ BICUBIC_DUR_SCALE : 1;
+#endif
+ }
+
virtual void onDrawIntoBitmap(const SkBitmap& bm) {
const int w = bm.width();
const int h = bm.height();
@@ -196,38 +201,53 @@ private:
/** Explicitly invoke some filter types to improve coverage of acceleration
procs. */
+enum Flags {
+ kScale_Flag = 1 << 0,
+ kRotate_Flag = 1 << 1,
+ kBilerp_Flag = 1 << 2,
+ kBicubic_Flag = 1 << 3,
+};
+
+static bool isBilerp(uint32_t flags) {
+ return (flags & (kBilerp_Flag | kBicubic_Flag)) == (kBilerp_Flag);
+}
+
+static bool isBicubic(uint32_t flags) {
+ return (flags & (kBilerp_Flag | kBicubic_Flag)) == (kBilerp_Flag | kBicubic_Flag);
+}
+
class FilterBitmapBench : public BitmapBench {
- bool fScale;
- bool fRotate;
- bool fFilter;
+ uint32_t fFlags;
SkString fFullName;
enum { N = SkBENCHLOOP(300) };
public:
FilterBitmapBench(void* param, bool isOpaque, SkBitmap::Config c,
- bool forceUpdate = false, bool bitmapVolatile = false,
- int tx = -1, int ty = -1, bool addScale = false,
- bool addRotate = false, bool addFilter = false)
- : INHERITED(param, isOpaque, c, forceUpdate, bitmapVolatile, tx, ty)
- , fScale(addScale), fRotate(addRotate), fFilter(addFilter) {
-
+ bool forceUpdate, bool isVolitile, uint32_t flags)
+ : INHERITED(param, isOpaque, c, forceUpdate, isVolitile)
+ , fFlags(flags) {
}
protected:
virtual const char* onGetName() {
fFullName.set(INHERITED::onGetName());
- if (fScale)
+ if (fFlags & kScale_Flag) {
fFullName.append("_scale");
- if (fRotate)
+ }
+ if (fFlags & kRotate_Flag) {
fFullName.append("_rotate");
- if (fFilter)
- fFullName.append("_filter");
+ }
+ if (isBilerp(fFlags)) {
+ fFullName.append("_bilerp");
+ } else if (isBicubic(fFlags)) {
+ fFullName.append("_bicubic");
+ }
return fFullName.c_str();
}
virtual void onDraw(SkCanvas* canvas) {
SkISize dim = canvas->getDeviceSize();
- if (fScale) {
+ if (fFlags & kScale_Flag) {
const SkScalar x = SkIntToScalar(dim.fWidth) / 2;
const SkScalar y = SkIntToScalar(dim.fHeight) / 2;
@@ -236,7 +256,7 @@ protected:
canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
canvas->translate(-x, -y);
}
- if (fRotate) {
+ if (fFlags & kRotate_Flag) {
const SkScalar x = SkIntToScalar(dim.fWidth) / 2;
const SkScalar y = SkIntToScalar(dim.fHeight) / 2;
@@ -245,7 +265,16 @@ protected:
canvas->translate(-x, -y);
}
- this->setForceFilter(fFilter);
+ uint32_t orMask = 0;
+ uint32_t clearMask = SkPaint::kFilterBitmap_Flag | SkPaint::kBicubicFilterBitmap_Flag;
+ if (fFlags & kBilerp_Flag) {
+ orMask |= SkPaint::kFilterBitmap_Flag;
+ }
+ if (fFlags & kBicubic_Flag) {
+ orMask |= SkPaint::kBicubicFilterBitmap_Flag;
+ }
+ this->setPaintMasks(orMask, clearMask);
+
INHERITED::onDraw(canvas);
}
@@ -264,9 +293,8 @@ private:
SourceAlpha fSourceAlpha;
public:
SourceAlphaBitmapBench(void* param, SourceAlpha alpha, SkBitmap::Config c,
- bool forceUpdate = false, bool bitmapVolatile = false,
- int tx = -1, int ty = -1)
- : INHERITED(param, false, c, forceUpdate, bitmapVolatile, tx, ty)
+ bool forceUpdate = false, bool bitmapVolatile = false)
+ : INHERITED(param, false, c, forceUpdate, bitmapVolatile)
, fSourceAlpha(alpha) {
}
@@ -354,16 +382,19 @@ DEF_BENCH( return new BitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, tr
DEF_BENCH( return new BitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, false); )
// scale filter -> S32_opaque_D32_filter_DX_{SSE2,SSSE3} and Fact9 is also for S32_D16_filter_DX_SSE2
-DEF_BENCH( return new FilterBitmapBench(p, false, SkBitmap::kARGB_8888_Config, false, false, -1, -1, true, false, true); )
-DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, false, false, -1, -1, true, false, true); )
-DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, true, -1, -1, true, false, true); )
-DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, false, -1, -1, true, false, true); )
+DEF_BENCH( return new FilterBitmapBench(p, false, SkBitmap::kARGB_8888_Config, false, false, kScale_Flag | kBilerp_Flag); )
+DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, false, false, kScale_Flag | kBilerp_Flag); )
+DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, true, kScale_Flag | kBilerp_Flag); )
+DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, false, kScale_Flag | kBilerp_Flag); )
// scale rotate filter -> S32_opaque_D32_filter_DXDY_{SSE2,SSSE3}
-DEF_BENCH( return new FilterBitmapBench(p, false, SkBitmap::kARGB_8888_Config, false, false, -1, -1, true, true, true); )
-DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, false, false, -1, -1, true, true, true); )
-DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, true, -1, -1, true, true, true); )
-DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, false, -1, -1, true, true, true); )
+DEF_BENCH( return new FilterBitmapBench(p, false, SkBitmap::kARGB_8888_Config, false, false, kScale_Flag | kRotate_Flag | kBilerp_Flag); )
+DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, false, false, kScale_Flag | kRotate_Flag | kBilerp_Flag); )
+DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, true, kScale_Flag | kRotate_Flag | kBilerp_Flag); )
+DEF_BENCH( return new FilterBitmapBench(p, true, SkBitmap::kARGB_8888_Config, true, false, kScale_Flag | kRotate_Flag | kBilerp_Flag); )
+
+DEF_BENCH( return new FilterBitmapBench(p, false, SkBitmap::kARGB_8888_Config, false, false, kScale_Flag | kBilerp_Flag | kBicubic_Flag); )
+DEF_BENCH( return new FilterBitmapBench(p, false, SkBitmap::kARGB_8888_Config, false, false, kScale_Flag | kRotate_Flag | kBilerp_Flag | kBicubic_Flag); )
// source alpha tests -> S32A_Opaque_BlitRow32_{arm,neon}
DEF_BENCH( return new SourceAlphaBitmapBench(p, SourceAlphaBitmapBench::kOpaque_SourceAlpha, SkBitmap::kARGB_8888_Config); )
diff --git a/bench/SkBenchmark.cpp b/bench/SkBenchmark.cpp
index 6afcd8e9f3..43f78b0f2d 100644
--- a/bench/SkBenchmark.cpp
+++ b/bench/SkBenchmark.cpp
@@ -20,6 +20,7 @@ SkBenchmark::SkBenchmark(void* defineDict) {
fDither = SkTriState::kDefault;
fHasStrokeWidth = false;
fIsRendering = true;
+ fOrMask = fClearMask = 0;
}
const char* SkBenchmark::getName() {
@@ -47,6 +48,8 @@ void SkBenchmark::setupPaint(SkPaint* paint) {
paint->setAntiAlias(fForceAA);
paint->setFilterBitmap(fForceFilter);
+ paint->setFlags((paint->getFlags() & ~fClearMask) | fOrMask);
+
if (SkTriState::kDefault != fDither) {
paint->setDither(SkTriState::kTrue == fDither);
}
diff --git a/bench/SkBenchmark.h b/bench/SkBenchmark.h
index 001b3ab679..404d4c3e7e 100644
--- a/bench/SkBenchmark.h
+++ b/bench/SkBenchmark.h
@@ -106,6 +106,22 @@ public:
bool findDefine32(const char* key, int32_t* value) const;
bool findDefineScalar(const char* key, SkScalar* value) const;
+ /** Assign masks for paint-flags. These will be applied when setupPaint()
+ * is called.
+ *
+ * Performs the following on the paint:
+ * uint32_t flags = paint.getFlags();
+ * flags &= ~clearMask;
+ * flags |= orMask;
+ * paint.setFlags(flags);
+ */
+ void setPaintMasks(uint32_t orMask, uint32_t clearMask) {
+ fOrMask = orMask;
+ fClearMask = clearMask;
+ }
+
+ float getDurationScale() { return this->onGetDurationScale(); }
+
protected:
virtual void setupPaint(SkPaint* paint);
@@ -113,6 +129,13 @@ protected:
virtual void onPreDraw() {}
virtual void onDraw(SkCanvas*) = 0;
virtual void onPostDraw() {}
+ // the caller will scale the computed duration by this value. It allows a
+ // slow bench to run fewer inner loops, but return the corresponding scale
+ // so that its reported duration can be compared against other benches.
+ // e.g.
+ // if I run 10x slower, I can run 1/10 the number of inner-loops, but
+ // return 10.0 for my durationScale, so I "report" the honest duration.
+ virtual float onGetDurationScale() { return 1; }
virtual SkIPoint onGetSize();
/// Defaults to true.
@@ -126,6 +149,7 @@ private:
SkTriState::State fDither;
bool fHasStrokeWidth;
SkScalar strokeWidth;
+ uint32_t fOrMask, fClearMask;
typedef SkRefCnt INHERITED;
};
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
index 865b771cfd..7aeeba63e8 100644
--- a/bench/benchmain.cpp
+++ b/bench/benchmain.cpp
@@ -915,7 +915,7 @@ int tool_main(int argc, char** argv) {
SkPicture::kUsePathBoundsForClip_RecordingFlag);
}
- timer->start();
+ timer->start(bench->getDurationScale());
if (NULL != canvas) {
canvas->save();
}