From f865be37868430ab75e3c787afc2869ba18216c3 Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Fri, 31 May 2013 13:27:02 +0000 Subject: Add atlasing option to GameBench bench https://codereview.chromium.org/15660012/ git-svn-id: http://skia.googlecode.com/svn/trunk@9363 2bbb7eff-a529-9590-31e7-b0007b416f81 --- bench/GameBench.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 120 insertions(+), 26 deletions(-) (limited to 'bench/GameBench.cpp') 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)); ) -- cgit v1.2.3