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 15enum ColorPattern { 16 kWhite_ColorPattern, 17 kBlue_ColorPattern, 18 kOpaqueBitmap_ColorPattern, 19 kAlphaBitmap_ColorPattern, 20}; 21 22static 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 34enum DrawType { 35 kRect_DrawType, 36 kPath_DrawType, 37}; 38 39static 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::MakeLinear(kPts0, kColors0, kPos, SK_ARRAY_COUNT(kColors0), 55 SkShader::kClamp_TileMode)); 56 canvas.drawPaint(paint); 57 paint.setShader(SkGradientShader::MakeLinear(kPts1, kColors1, kPos, SK_ARRAY_COUNT(kColors1), 58 SkShader::kClamp_TileMode)); 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 GrDrawOp combining when alternating between 74 * different patterns when on the gpu. 75 */ 76class AlternatingColorPatternBench : public Benchmark { 77public: 78 enum { 79 NX = 5, 80 NY = 5, 81 NUM_DRAWS = NX * NY, 82 }; 83 sk_sp<SkShader> fBmShader; 84 85 SkPath fPaths[NUM_DRAWS]; 86 SkRect fRects[NUM_DRAWS]; 87 SkColor fColors[NUM_DRAWS]; 88 sk_sp<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 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 106protected: 107 const char* onGetName() override { 108 return fName.c_str(); 109 } 110 111 void onDelayedSetup() override { 112 int w = 40; 113 int h = 40; 114 makebm(&fBmp, w, h); 115 fBmShader = SkShader::MakeBitmapShader(fBmp, 116 SkShader::kRepeat_TileMode, 117 SkShader::kRepeat_TileMode); 118 int offset = 2; 119 int count = 0; 120 for (int j = 0; j < NY; ++j) { 121 for (int i = 0; i < NX; ++i) { 122 int x = (w + offset) * i; 123 int y = (h * offset) * j; 124 if (kRect_DrawType == fDrawType) { 125 fRects[count].set(SkIntToScalar(x), SkIntToScalar(y), 126 SkIntToScalar(x + w), SkIntToScalar(y + h)); 127 } else { 128 fPaths[count].moveTo(SkIntToScalar(x), SkIntToScalar(y)); 129 fPaths[count].rLineTo(SkIntToScalar(w), 0); 130 fPaths[count].rLineTo(0, SkIntToScalar(h)); 131 fPaths[count].rLineTo(SkIntToScalar(-w + 1), 0); 132 } 133 if (0 == count % 2) { 134 fColors[count] = fPattern1.fColor; 135 fShaders[count] = fPattern1.fIsBitmap ? fBmShader : nullptr; 136 } else { 137 fColors[count] = fPattern2.fColor; 138 fShaders[count] = fPattern2.fIsBitmap ? fBmShader : nullptr; 139 } 140 ++count; 141 } 142 } 143 } 144 145 void onDraw(int loops, SkCanvas* canvas) override { 146 SkPaint paint; 147 paint.setAntiAlias(false); 148 paint.setFilterQuality(kLow_SkFilterQuality); 149 150 for (int i = 0; i < loops; ++i) { 151 for (int j = 0; j < NUM_DRAWS; ++j) { 152 paint.setColor(fColors[j]); 153 paint.setShader(fShaders[j]); 154 if (kRect_DrawType == fDrawType) { 155 canvas->drawRect(fRects[j], paint); 156 } else { 157 canvas->drawPath(fPaths[j], paint); 158 } 159 } 160 } 161 } 162 163private: 164 typedef Benchmark INHERITED; 165}; 166 167DEF_BENCH(return new AlternatingColorPatternBench(kWhite_ColorPattern, 168 kWhite_ColorPattern, 169 kPath_DrawType);) 170DEF_BENCH(return new AlternatingColorPatternBench(kBlue_ColorPattern, 171 kBlue_ColorPattern, 172 kPath_DrawType);) 173DEF_BENCH(return new AlternatingColorPatternBench(kWhite_ColorPattern, 174 kBlue_ColorPattern, 175 kPath_DrawType);) 176 177DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern, 178 kOpaqueBitmap_ColorPattern, 179 kPath_DrawType);) 180DEF_BENCH(return new AlternatingColorPatternBench(kAlphaBitmap_ColorPattern, 181 kAlphaBitmap_ColorPattern, 182 kPath_DrawType);) 183DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern, 184 kAlphaBitmap_ColorPattern, 185 kPath_DrawType);) 186 187DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern, 188 kOpaqueBitmap_ColorPattern, 189 kRect_DrawType);) 190DEF_BENCH(return new AlternatingColorPatternBench(kAlphaBitmap_ColorPattern, 191 kAlphaBitmap_ColorPattern, 192 kRect_DrawType);) 193DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern, 194 kAlphaBitmap_ColorPattern, 195 kRect_DrawType);) 196