1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright 2012 Google Inc. 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Use of this source code is governed by a BSD-style license that can be 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * found in the LICENSE file. 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "Benchmark.h" 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "SkCanvas.h" 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "SkPaint.h" 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "SkRandom.h" 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "SkShader.h" 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "SkString.h" 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This bench simulates the calls Skia sees from various HTML5 canvas 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// game bench marks 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass GameBench : public Benchmark { 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic: 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov enum Type { 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov kScale_Type, 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov kTranslate_Type, 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov kRotate_Type 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov enum Clear { 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov kFull_Clear, 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov kPartial_Clear 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov GameBench(Type type, Clear clear, 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bool aligned = false, bool useAtlas = false, 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bool useDrawVertices = false) 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : fType(type) 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov , fClear(clear) 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov , fAligned(aligned) 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov , fUseAtlas(useAtlas) 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov , fUseDrawVertices(useDrawVertices) 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov , fName("game") 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov , fNumSaved(0) 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov , fInitialized(false) { 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (fType) { 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case kScale_Type: 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_scale"); 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case kTranslate_Type: 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_trans"); 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case kRotate_Type: 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_rot"); 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (aligned) { 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_aligned"); 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (kPartial_Clear == clear) { 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_partial"); 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_full"); 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (useAtlas) { 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_atlas"); 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (useDrawVertices) { 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_drawVerts"); 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // It's HTML 5 canvas, so always AA 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fName.append("_aa"); 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovprotected: 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov virtual const char* onGetName() SK_OVERRIDE { 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return fName.c_str(); 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov virtual void onPreDraw() SK_OVERRIDE { 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!fInitialized) { 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov this->makeCheckerboard(); 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov this->makeAtlas(); 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fInitialized = true; 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkRandom scaleRand; 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkRandom transRand; 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkRandom rotRand; 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int width, height; 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (fUseAtlas) { 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width = kAtlasCellWidth; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov height = kAtlasCellHeight; 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width = kCheckerboardWidth; 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov height = kCheckerboardHeight; 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkPaint clearPaint; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clearPaint.setColor(0xFF000000); 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clearPaint.setAntiAlias(true); 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkISize size = canvas->getDeviceSize(); 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkScalar maxTransX, maxTransY; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (kScale_Type == fType) { 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxTransX = size.fWidth - (1.5f * width); 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxTransY = size.fHeight - (1.5f * height); 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (kTranslate_Type == fType) { 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxTransX = SkIntToScalar(size.fWidth - width); 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxTransY = SkIntToScalar(size.fHeight - height); 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkASSERT(kRotate_Type == fType); 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Yes, some rotations will be off the top and left sides 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxTransX = size.fWidth - SK_ScalarSqrt2 * height; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov maxTransY = size.fHeight - SK_ScalarSqrt2 * height; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkMatrix mat; 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkRect dst = { 0, 0, SkIntToScalar(width), SkIntToScalar(height) }; 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkRect clearRect = { -1.0f, -1.0f, width+1.0f, height+1.0f }; 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkPoint verts[4] = { // for drawVertices path 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 0, 0 }, 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 0, SkIntToScalar(height) }, 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { SkIntToScalar(width), SkIntToScalar(height) }, 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { SkIntToScalar(width), 0 } 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 }; 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkPaint p; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p.setColor(0xFF000000); 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p.setFilterLevel(SkPaint::kLow_FilterLevel); 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkPaint p2; // for drawVertices path 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p2.setColor(0xFF000000); 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p2.setFilterLevel(SkPaint::kLow_FilterLevel); 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p2.setShader(SkShader::CreateBitmapShader(fAtlas, 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkShader::kClamp_TileMode, 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkShader::kClamp_TileMode))->unref(); 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int i = 0; i < loops; ++i, ++fNumSaved) { 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (0 == i % kNumBeforeClear) { 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (kPartial_Clear == fClear) { 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int j = 0; j < fNumSaved; ++j) { 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov canvas->setMatrix(SkMatrix::I()); 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mat.setTranslate(fSaved[j][0], fSaved[j][1]); 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (kScale_Type == fType) { 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mat.preScale(fSaved[j][2], fSaved[j][2]); 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (kRotate_Type == fType) { 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mat.preRotate(fSaved[j][2]); 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov canvas->concat(mat); 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov canvas->drawRect(clearRect, clearPaint); 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov canvas->clear(0xFF000000); 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fNumSaved = 0; 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SkASSERT(fNumSaved < kNumBeforeClear); 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov canvas->setMatrix(SkMatrix::I()); 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fSaved[fNumSaved][0] = transRand.nextRangeScalar(0.0f, maxTransX); 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fSaved[fNumSaved][1] = transRand.nextRangeScalar(0.0f, maxTransY); 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (fAligned) { 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // make the translations integer aligned 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fSaved[fNumSaved][0] = SkScalarFloorToScalar(fSaved[fNumSaved][0]); 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fSaved[fNumSaved][1] = SkScalarFloorToScalar(fSaved[fNumSaved][1]); 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mat.setTranslate(fSaved[fNumSaved][0], fSaved[fNumSaved][1]); 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (kScale_Type == fType) { 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fSaved[fNumSaved][2] = scaleRand.nextRangeScalar(0.5f, 1.5f); 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mat.preScale(fSaved[fNumSaved][2], fSaved[fNumSaved][2]); 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (kRotate_Type == fType) { 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fSaved[fNumSaved][2] = rotRand.nextRangeScalar(0.0f, 360.0f); 188 mat.preRotate(fSaved[fNumSaved][2]); 189 } 190 191 canvas->concat(mat); 192 if (fUseAtlas) { 193 const int curCell = i % (kNumAtlasedX * kNumAtlasedY); 194 SkIRect src = fAtlasRects[curCell % (kNumAtlasedX)][curCell / (kNumAtlasedX)]; 195 196 if (fUseDrawVertices) { 197 SkPoint uvs[4] = { 198 { SkIntToScalar(src.fLeft), SkIntToScalar(src.fBottom) }, 199 { SkIntToScalar(src.fLeft), SkIntToScalar(src.fTop) }, 200 { SkIntToScalar(src.fRight), SkIntToScalar(src.fTop) }, 201 { SkIntToScalar(src.fRight), SkIntToScalar(src.fBottom) }, 202 }; 203 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, 204 4, verts, uvs, NULL, NULL, 205 indices, 6, p2); 206 } else { 207 canvas->drawBitmapRect(fAtlas, &src, dst, &p, 208 SkCanvas::kBleed_DrawBitmapRectFlag); 209 } 210 } else { 211 canvas->drawBitmapRect(fCheckerboard, NULL, dst, &p); 212 } 213 } 214 } 215 216private: 217 static const int kCheckerboardWidth = 64; 218 static const int kCheckerboardHeight = 128; 219 220 static const int kAtlasCellWidth = 48; 221 static const int kAtlasCellHeight = 36; 222 static const int kNumAtlasedX = 5; 223 static const int kNumAtlasedY = 5; 224 static const int kAtlasSpacer = 2; 225 static const int kTotAtlasWidth = kNumAtlasedX * kAtlasCellWidth + 226 (kNumAtlasedX+1) * kAtlasSpacer; 227 static const int kTotAtlasHeight = kNumAtlasedY * kAtlasCellHeight + 228 (kNumAtlasedY+1) * kAtlasSpacer; 229 static const int kNumBeforeClear = 100; 230 231 Type fType; 232 Clear fClear; 233 bool fAligned; 234 bool fUseAtlas; 235 bool fUseDrawVertices; 236 SkString fName; 237 int fNumSaved; // num draws stored in 'fSaved' 238 bool fInitialized; 239 240 // 0 & 1 are always x & y translate. 2 is either scale or rotate. 241 SkScalar fSaved[kNumBeforeClear][3]; 242 243 SkBitmap fCheckerboard; 244 SkBitmap fAtlas; 245 SkIRect fAtlasRects[kNumAtlasedX][kNumAtlasedY]; 246 247 // Note: the resulting checker board has transparency 248 void makeCheckerboard() { 249 static int kCheckSize = 16; 250 251 fCheckerboard.allocN32Pixels(kCheckerboardWidth, kCheckerboardHeight); 252 SkAutoLockPixels lock(fCheckerboard); 253 for (int y = 0; y < kCheckerboardHeight; ++y) { 254 int even = (y / kCheckSize) % 2; 255 256 SkPMColor* scanline = fCheckerboard.getAddr32(0, y); 257 258 for (int x = 0; x < kCheckerboardWidth; ++x) { 259 if (even == (x / kCheckSize) % 2) { 260 *scanline++ = 0xFFFF0000; 261 } else { 262 *scanline++ = 0x00000000; 263 } 264 } 265 } 266 } 267 268 // Note: the resulting atlas has transparency 269 void makeAtlas() { 270 SkRandom rand; 271 272 SkColor colors[kNumAtlasedX][kNumAtlasedY]; 273 274 for (int y = 0; y < kNumAtlasedY; ++y) { 275 for (int x = 0; x < kNumAtlasedX; ++x) { 276 colors[x][y] = rand.nextU() | 0xff000000; 277 fAtlasRects[x][y] = SkIRect::MakeXYWH(kAtlasSpacer + x * (kAtlasCellWidth + kAtlasSpacer), 278 kAtlasSpacer + y * (kAtlasCellHeight + kAtlasSpacer), 279 kAtlasCellWidth, 280 kAtlasCellHeight); 281 } 282 } 283 284 fAtlas.allocN32Pixels(kTotAtlasWidth, kTotAtlasHeight); 285 SkAutoLockPixels lock(fAtlas); 286 287 for (int y = 0; y < kTotAtlasHeight; ++y) { 288 int colorY = y / (kAtlasCellHeight + kAtlasSpacer); 289 bool inColorY = (y % (kAtlasCellHeight + kAtlasSpacer)) >= kAtlasSpacer; 290 291 SkPMColor* scanline = fAtlas.getAddr32(0, y); 292 293 for (int x = 0; x < kTotAtlasWidth; ++x, ++scanline) { 294 int colorX = x / (kAtlasCellWidth + kAtlasSpacer); 295 bool inColorX = (x % (kAtlasCellWidth + kAtlasSpacer)) >= kAtlasSpacer; 296 297 if (inColorX && inColorY) { 298 SkASSERT(colorX < kNumAtlasedX && colorY < kNumAtlasedY); 299 *scanline = colors[colorX][colorY]; 300 } else { 301 *scanline = 0x00000000; 302 } 303 } 304 } 305 } 306 307 typedef Benchmark INHERITED; 308}; 309 310// Partial clear 311DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kScale_Type, 312 GameBench::kPartial_Clear)); ) 313DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type, 314 GameBench::kPartial_Clear)); ) 315DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type, 316 GameBench::kPartial_Clear, true)); ) 317DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kRotate_Type, 318 GameBench::kPartial_Clear)); ) 319 320// Full clear 321DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kScale_Type, 322 GameBench::kFull_Clear)); ) 323DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type, 324 GameBench::kFull_Clear)); ) 325DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type, 326 GameBench::kFull_Clear, true)); ) 327DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kRotate_Type, 328 GameBench::kFull_Clear)); ) 329 330// Atlased 331DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type, 332 GameBench::kFull_Clear, false, true)); ) 333DEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type, 334 GameBench::kFull_Clear, false, true, true)); ) 335