Chromium Code Reviews| Index: bench/GameBench.cpp |
| =================================================================== |
| --- bench/GameBench.cpp (revision 9351) |
| +++ bench/GameBench.cpp (working copy) |
| @@ -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 @@ |
| 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 @@ |
| 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 @@ |
| 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 @@ |
| 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 @@ |
| 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 @@ |
| } |
| 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 @@ |
| 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 @@ |
| } |
| } |
| + // 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), |
|
bsalomon
2013/05/30 18:32:17
long lines (if you care).
|
| + 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)); ) |