1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "Benchmark.h" 9 #include "SkCanvas.h" 10 #include "SkGradientShader.h" 11 #include "SkPaint.h" 12 #include "SkString.h" 13 14 enum ColorPattern { 15 kWhite_ColorPattern, 16 kBlue_ColorPattern, 17 kOpaqueBitmap_ColorPattern, 18 kAlphaBitmap_ColorPattern, 19 }; 20 21 static const struct ColorPatternData{ 22 SkColor fColor; 23 bool fIsBitmap; 24 const char* fName; 25 } gColorPatterns[] = { 26 // Keep this in same order as ColorPattern enum 27 { SK_ColorWHITE, false, "white" }, // kWhite_ColorPattern 28 { SK_ColorBLUE, false, "blue" }, // kBlue_ColorPattern 29 { SK_ColorWHITE, true, "obaqueBitMap" }, // kOpaqueBitmap_ColorPattern 30 { 0x10000000, true, "alphaBitmap" }, // kAlphaBitmap_ColorPattern 31 }; 32 33 enum DrawType { 34 kRect_DrawType, 35 kPath_DrawType, 36 }; 37 38 static void makebm(SkBitmap* bm, int w, int h) { 39 bm->allocN32Pixels(w, h); 40 bm->eraseColor(SK_ColorTRANSPARENT); 41 42 SkCanvas canvas(*bm); 43 SkScalar s = SkIntToScalar(SkMin32(w, h)); 44 static const SkPoint kPts0[] = { { 0, 0 }, { s, s } }; 45 static const SkPoint kPts1[] = { { s/2, 0 }, { s/2, s } }; 46 static const SkScalar kPos[] = { 0, SK_Scalar1/2, SK_Scalar1 }; 47 static const SkColor kColors0[] = {0x80F00080, 0xF0F08000, 0x800080F0 }; 48 static const SkColor kColors1[] = {0xF08000F0, 0x8080F000, 0xF000F080 }; 49 50 51 SkPaint paint; 52 53 paint.setShader(SkGradientShader::CreateLinear(kPts0, kColors0, kPos, 54 SK_ARRAY_COUNT(kColors0), SkShader::kClamp_TileMode))->unref(); 55 canvas.drawPaint(paint); 56 paint.setShader(SkGradientShader::CreateLinear(kPts1, kColors1, kPos, 57 SK_ARRAY_COUNT(kColors1), SkShader::kClamp_TileMode))->unref(); 58 canvas.drawPaint(paint); 59 } 60 61 /** 62 * This bench draws a grid of either rects or filled paths, with two alternating color patterns. 63 * This color patterns are passed in as enums to the class. The options are: 64 * 1) solid white color 65 * 2) solid blue color 66 * 3) opaque bitmap 67 * 4) partial alpha bitmap 68 * The same color pattern can be set for both arguments to create a uniform pattern on all draws. 69 * 70 * The bench is used to test a few things. First it can test any optimizations made for a specific 71 * color pattern (for example drawing an opaque bitmap versus one with partial alpha). Also it can 72 * be used to test the cost of program switching and/or batching when alternating between different 73 * patterns when on the gpu. 74 */ 75 class AlternatingColorPatternBench : public Benchmark { 76 public: 77 enum { 78 NX = 5, 79 NY = 5, 80 NUM_DRAWS = NX * NY, 81 }; 82 SkShader* fBmShader; 83 84 SkPath fPaths[NUM_DRAWS]; 85 SkRect fRects[NUM_DRAWS]; 86 SkColor fColors[NUM_DRAWS]; 87 SkShader* fShaders[NUM_DRAWS]; 88 89 SkString fName; 90 ColorPatternData fPattern1; 91 ColorPatternData fPattern2; 92 DrawType fDrawType; 93 SkBitmap fBmp; 94 95 96 AlternatingColorPatternBench(ColorPattern pattern1, ColorPattern pattern2, DrawType drawType) 97 : fBmShader(NULL) { 98 fPattern1 = gColorPatterns[pattern1]; 99 fPattern2 = gColorPatterns[pattern2]; 100 fName.printf("colorPattern_%s_%s_%s", 101 fPattern1.fName, fPattern2.fName, 102 kRect_DrawType == drawType ? "rect" : "path"); 103 fDrawType = drawType; 104 } 105 106 virtual ~AlternatingColorPatternBench() { 107 SkSafeUnref(fBmShader); 108 } 109 110 protected: 111 virtual const char* onGetName() SK_OVERRIDE { 112 return fName.c_str(); 113 } 114 115 virtual void onPreDraw() { 116 int w = 40; 117 int h = 40; 118 makebm(&fBmp, w, h); 119 fBmShader = SkShader::CreateBitmapShader(fBmp, 120 SkShader::kRepeat_TileMode, 121 SkShader::kRepeat_TileMode); 122 int offset = 2; 123 int count = 0; 124 for (int j = 0; j < NY; ++j) { 125 for (int i = 0; i < NX; ++i) { 126 int x = (w + offset) * i; 127 int y = (h * offset) * j; 128 if (kRect_DrawType == fDrawType) { 129 fRects[count].set(SkIntToScalar(x), SkIntToScalar(y), 130 SkIntToScalar(x + w), SkIntToScalar(y + h)); 131 } else { 132 fPaths[count].moveTo(SkIntToScalar(x), SkIntToScalar(y)); 133 fPaths[count].rLineTo(SkIntToScalar(w), 0); 134 fPaths[count].rLineTo(0, SkIntToScalar(h)); 135 fPaths[count].rLineTo(SkIntToScalar(-w + 1), 0); 136 } 137 if (0 == count % 2) { 138 fColors[count] = fPattern1.fColor; 139 fShaders[count] = fPattern1.fIsBitmap ? fBmShader : NULL; 140 } else { 141 fColors[count] = fPattern2.fColor; 142 fShaders[count] = fPattern2.fIsBitmap ? fBmShader : NULL; 143 } 144 ++count; 145 } 146 } 147 } 148 149 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 150 SkPaint paint; 151 paint.setAntiAlias(false); 152 paint.setFilterLevel(SkPaint::kLow_FilterLevel); 153 154 for (int i = 0; i < loops; ++i) { 155 for (int j = 0; j < NUM_DRAWS; ++j) { 156 paint.setColor(fColors[j]); 157 paint.setShader(fShaders[j]); 158 if (kRect_DrawType == fDrawType) { 159 canvas->drawRect(fRects[j], paint); 160 } else { 161 canvas->drawPath(fPaths[j], paint); 162 } 163 } 164 } 165 } 166 167 private: 168 typedef Benchmark INHERITED; 169 }; 170 171 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 172 (kWhite_ColorPattern, kWhite_ColorPattern, 173 kPath_DrawType)); ) 174 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 175 (kBlue_ColorPattern, kBlue_ColorPattern, 176 kPath_DrawType)); ) 177 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 178 (kWhite_ColorPattern, kBlue_ColorPattern, 179 kPath_DrawType)); ) 180 181 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 182 (kOpaqueBitmap_ColorPattern, kOpaqueBitmap_ColorPattern, 183 kPath_DrawType)); ) 184 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 185 (kAlphaBitmap_ColorPattern, kAlphaBitmap_ColorPattern, 186 kPath_DrawType)); ) 187 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 188 (kOpaqueBitmap_ColorPattern, kAlphaBitmap_ColorPattern, 189 kPath_DrawType)); ) 190 191 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 192 (kOpaqueBitmap_ColorPattern, kOpaqueBitmap_ColorPattern, 193 kRect_DrawType)); ) 194 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 195 (kAlphaBitmap_ColorPattern, kAlphaBitmap_ColorPattern, 196 kRect_DrawType)); ) 197 DEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench, 198 (kOpaqueBitmap_ColorPattern, kAlphaBitmap_ColorPattern, 199 kRect_DrawType)); ) 200 201