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