aboutsummaryrefslogtreecommitdiffhomepage
path: root/bench/GameBench.cpp
diff options
context:
space:
mode:
authorGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-31 13:27:02 +0000
committerGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-31 13:27:02 +0000
commitf865be37868430ab75e3c787afc2869ba18216c3 (patch)
tree25312484dabdf43ab8b25d127ec96f3505bb2bdb /bench/GameBench.cpp
parent6dce11368ad6368fb9cb117d70cf8220f0b6f368 (diff)
Add atlasing option to GameBench bench
Diffstat (limited to 'bench/GameBench.cpp')
-rw-r--r--bench/GameBench.cpp146
1 files changed, 120 insertions, 26 deletions
diff --git a/bench/GameBench.cpp b/bench/GameBench.cpp
index 4998bd8414..ba7f76550e 100644
--- a/bench/GameBench.cpp
+++ b/bench/GameBench.cpp
@@ -11,7 +11,6 @@
#include "SkRandom.h"
#include "SkString.h"
-
// This bench simulates the calls Skia sees from various HTML5 canvas
// game bench marks
class GameBench : public SkBenchmark {
@@ -22,11 +21,18 @@ public:
kRotate_Type
};
- GameBench(void* param, Type type, bool partialClear, bool aligned = false)
+ enum Clear {
+ kFull_Clear,
+ kPartial_Clear
+ };
+
+ GameBench(void* param, Type type, Clear clear,
+ bool aligned = false, bool useAtlas = false)
: INHERITED(param)
, fType(type)
- , fPartialClear(partialClear)
+ , fClear(clear)
, fAligned(aligned)
+ , fUseAtlas(useAtlas)
, fName("game")
, fNumSaved(0)
, fInitialized(false) {
@@ -47,24 +53,29 @@ public:
fName.append("_aligned");
}
- if (partialClear) {
+ if (kPartial_Clear == clear) {
fName.append("_partial");
} else {
fName.append("_full");
}
+ if (useAtlas) {
+ fName.append("_atlas");
+ }
+
// It's HTML 5 canvas, so always AA
fName.append("_aa");
}
protected:
virtual const char* onGetName() SK_OVERRIDE {
- return fName.c_str();;
+ return fName.c_str();
}
virtual void onPreDraw() SK_OVERRIDE {
if (!fInitialized) {
this->makeCheckerboard();
+ this->makeAtlas();
fInitialized = true;
}
}
@@ -74,6 +85,15 @@ protected:
static SkMWCRandom transRand;
static SkMWCRandom rotRand;
+ int width, height;
+ if (fUseAtlas) {
+ width = kAtlasCellWidth;
+ height = kAtlasCellHeight;
+ } else {
+ width = kCheckerboardWidth;
+ height = kCheckerboardHeight;
+ }
+
SkPaint clearPaint;
clearPaint.setColor(0xFF000000);
clearPaint.setAntiAlias(true);
@@ -83,23 +103,22 @@ protected:
SkScalar maxTransX, maxTransY;
if (kScale_Type == fType) {
- maxTransX = size.fWidth - (1.5f * kCheckerboardWidth);
- maxTransY = size.fHeight - (1.5f * kCheckerboardHeight);
+ maxTransX = size.fWidth - (1.5f * width);
+ maxTransY = size.fHeight - (1.5f * height);
} else if (kTranslate_Type == fType) {
- maxTransX = SkIntToScalar(size.fWidth - kCheckerboardWidth);
- maxTransY = SkIntToScalar(size.fHeight - kCheckerboardHeight);
+ maxTransX = SkIntToScalar(size.fWidth - width);
+ maxTransY = SkIntToScalar(size.fHeight - height);
} else {
SkASSERT(kRotate_Type == fType);
// Yes, some rotations will be off the top and left sides
- maxTransX = size.fWidth - SK_ScalarSqrt2 * kCheckerboardHeight;
- maxTransY = size.fHeight - SK_ScalarSqrt2 * kCheckerboardHeight;
+ maxTransX = size.fWidth - SK_ScalarSqrt2 * height;
+ maxTransY = size.fHeight - SK_ScalarSqrt2 * height;
}
SkMatrix mat;
- SkIRect src = { 0, 0, kCheckerboardWidth, kCheckerboardHeight };
- SkRect dst = { 0, 0, kCheckerboardWidth, kCheckerboardHeight };
- SkRect clearRect = { -1.0f, -1.0f,
- kCheckerboardWidth+1.0f, kCheckerboardHeight+1.0f };
+ SkIRect src = { 0, 0, width, height };
+ SkRect dst = { 0, 0, SkIntToScalar(width), SkIntToScalar(height) };
+ SkRect clearRect = { -1.0f, -1.0f, width+1.0f, height+1.0f };
SkPaint p;
p.setColor(0xFF000000);
@@ -108,7 +127,7 @@ protected:
for (int i = 0; i < kNumRects; ++i, ++fNumSaved) {
if (0 == i % kNumBeforeClear) {
- if (fPartialClear) {
+ if (kPartial_Clear == fClear) {
for (int j = 0; j < fNumSaved; ++j) {
canvas->setMatrix(SkMatrix::I());
mat.setTranslate(fSaved[j][0], fSaved[j][1]);
@@ -152,13 +171,31 @@ protected:
}
canvas->concat(mat);
- canvas->drawBitmapRect(fCheckerboard, &src, dst, &p);
+ if (fUseAtlas) {
+ static int curCell = 0;
+ src = fAtlasRects[curCell % (kNumAtlasedX)][curCell / (kNumAtlasedX)];
+ curCell = (curCell + 1) % (kNumAtlasedX*kNumAtlasedY);
+ canvas->drawBitmapRect(fAtlas, &src, dst, &p);
+ } else {
+ canvas->drawBitmapRect(fCheckerboard, &src, dst, &p);
+ }
}
}
private:
static const int kCheckerboardWidth = 64;
static const int kCheckerboardHeight = 128;
+
+ static const int kAtlasCellWidth = 48;
+ static const int kAtlasCellHeight = 36;
+ static const int kNumAtlasedX = 5;
+ static const int kNumAtlasedY = 5;
+ static const int kAtlasSpacer = 2;
+ static const int kTotAtlasWidth = kNumAtlasedX * kAtlasCellWidth +
+ (kNumAtlasedX+1) * kAtlasSpacer;
+ static const int kTotAtlasHeight = kNumAtlasedY * kAtlasCellHeight +
+ (kNumAtlasedY+1) * kAtlasSpacer;
+
#ifdef SK_DEBUG
static const int kNumRects = 100;
static const int kNumBeforeClear = 10;
@@ -169,15 +206,19 @@ private:
Type fType;
- bool fPartialClear;
+ Clear fClear;
bool fAligned;
+ bool fUseAtlas;
SkString fName;
int fNumSaved; // num draws stored in 'fSaved'
bool fInitialized;
// 0 & 1 are always x & y translate. 2 is either scale or rotate.
SkScalar fSaved[kNumBeforeClear][3];
+
SkBitmap fCheckerboard;
+ SkBitmap fAtlas;
+ SkIRect fAtlasRects[kNumAtlasedX][kNumAtlasedY];
// Note: the resulting checker board has transparency
void makeCheckerboard() {
@@ -202,17 +243,70 @@ private:
}
}
+ // Note: the resulting atlas has transparency
+ void makeAtlas() {
+ SkMWCRandom rand;
+
+ SkColor colors[kNumAtlasedX][kNumAtlasedY];
+
+ for (int y = 0; y < kNumAtlasedY; ++y) {
+ for (int x = 0; x < kNumAtlasedX; ++x) {
+ colors[x][y] = rand.nextU() | 0xff000000;
+ fAtlasRects[x][y] = SkIRect::MakeXYWH(kAtlasSpacer + x * (kAtlasCellWidth + kAtlasSpacer),
+ kAtlasSpacer + y * (kAtlasCellHeight + kAtlasSpacer),
+ kAtlasCellWidth,
+ kAtlasCellHeight);
+ }
+ }
+
+
+ fAtlas.setConfig(SkBitmap::kARGB_8888_Config, kTotAtlasWidth, kTotAtlasHeight);
+ fAtlas.allocPixels();
+ SkAutoLockPixels lock(fAtlas);
+
+ for (int y = 0; y < kTotAtlasHeight; ++y) {
+ int colorY = y / (kAtlasCellHeight + kAtlasSpacer);
+ bool inColorY = (y % (kAtlasCellHeight + kAtlasSpacer)) >= kAtlasSpacer;
+
+ SkPMColor* scanline = fAtlas.getAddr32(0, y);
+
+ for (int x = 0; x < kTotAtlasWidth; ++x, ++scanline) {
+ int colorX = x / (kAtlasCellWidth + kAtlasSpacer);
+ bool inColorX = (x % (kAtlasCellWidth + kAtlasSpacer)) >= kAtlasSpacer;
+
+ if (inColorX && inColorY) {
+ SkASSERT(colorX < kNumAtlasedX && colorY < kNumAtlasedY);
+ *scanline = colors[colorX][colorY];
+ } else {
+ *scanline = 0x00000000;
+ }
+ }
+ }
+ }
+
typedef SkBenchmark INHERITED;
};
// Partial clear
-DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kScale_Type, false)); )
-DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, false)); )
-DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, false, true)); )
-DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kRotate_Type, false)); )
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kScale_Type,
+ GameBench::kPartial_Clear)); )
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type,
+ GameBench::kPartial_Clear)); )
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type,
+ GameBench::kPartial_Clear, true)); )
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kRotate_Type,
+ GameBench::kPartial_Clear)); )
// Full clear
-DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kScale_Type, true)); )
-DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, true)); )
-DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, true, true)); )
-DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kRotate_Type, true)); )
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kScale_Type,
+ GameBench::kFull_Clear)); )
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type,
+ GameBench::kFull_Clear)); )
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type,
+ GameBench::kFull_Clear, true)); )
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kRotate_Type,
+ GameBench::kFull_Clear)); )
+
+// Atlased
+DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type,
+ GameBench::kFull_Clear, false, true)); )