1/* 2 * Copyright 2013 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#include "Benchmark.h" 8#include "SkCanvas.h" 9#include "SkColorFilterImageFilter.h" 10#include "SkColorMatrixFilter.h" 11#include "SkLumaColorFilter.h" 12#include "SkTableColorFilter.h" 13 14#define FILTER_WIDTH_SMALL SkIntToScalar(32) 15#define FILTER_HEIGHT_SMALL SkIntToScalar(32) 16#define FILTER_WIDTH_LARGE SkIntToScalar(256) 17#define FILTER_HEIGHT_LARGE SkIntToScalar(256) 18 19class ColorFilterBaseBench : public Benchmark { 20 21public: 22 ColorFilterBaseBench(bool small) : fIsSmall(small) { } 23 24protected: 25 SkRect getFilterRect() const { 26 return isSmall() ? SkRect::MakeWH(FILTER_WIDTH_SMALL, FILTER_HEIGHT_SMALL) : 27 SkRect::MakeWH(FILTER_WIDTH_LARGE, FILTER_HEIGHT_LARGE); 28 } 29 30 static SkImageFilter* make_brightness(float amount, SkImageFilter* input = NULL) { 31 SkScalar amount255 = SkScalarMul(amount, SkIntToScalar(255)); 32 SkScalar matrix[20] = { 1, 0, 0, 0, amount255, 33 0, 1, 0, 0, amount255, 34 0, 0, 1, 0, amount255, 35 0, 0, 0, 1, 0 }; 36 SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix)); 37 return SkColorFilterImageFilter::Create(filter, input); 38 } 39 40 static SkImageFilter* make_grayscale(SkImageFilter* input = NULL) { 41 SkScalar matrix[20]; 42 memset(matrix, 0, 20 * sizeof(SkScalar)); 43 matrix[0] = matrix[5] = matrix[10] = 0.2126f; 44 matrix[1] = matrix[6] = matrix[11] = 0.7152f; 45 matrix[2] = matrix[7] = matrix[12] = 0.0722f; 46 matrix[18] = 1.0f; 47 SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix)); 48 return SkColorFilterImageFilter::Create(filter, input); 49 } 50 51 static SkImageFilter* make_mode_blue(SkImageFilter* input = NULL) { 52 SkAutoTUnref<SkColorFilter> filter( 53 SkColorFilter::CreateModeFilter(SK_ColorBLUE, SkXfermode::kSrcIn_Mode)); 54 return SkColorFilterImageFilter::Create(filter, input); 55 } 56 57 inline bool isSmall() const { return fIsSmall; } 58private: 59 bool fIsSmall; 60 61 typedef Benchmark INHERITED; 62}; 63 64class ColorFilterDimBrightBench : public ColorFilterBaseBench { 65 66public: 67 ColorFilterDimBrightBench(bool small) : INHERITED(small) { 68 } 69 70protected: 71 virtual const char* onGetName() SK_OVERRIDE { 72 return isSmall() ? "colorfilter_dim_bright_small" : "colorfilter_dim_bright_large"; 73 } 74 75 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 76 SkRect r = getFilterRect(); 77 SkPaint paint; 78 paint.setColor(SK_ColorRED); 79 80 for (int i = 0; i < loops; i++) { 81 for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.4f) { 82 SkAutoTUnref<SkImageFilter> dim(make_brightness(-brightness)); 83 SkAutoTUnref<SkImageFilter> bright(make_brightness(brightness, dim)); 84 paint.setImageFilter(bright); 85 canvas->drawRect(r, paint); 86 } 87 } 88 } 89 90private: 91 typedef ColorFilterBaseBench INHERITED; 92}; 93 94class ColorFilterBrightGrayBench : public ColorFilterBaseBench { 95 96public: 97 ColorFilterBrightGrayBench(bool small) : INHERITED(small) { 98 } 99 100protected: 101 virtual const char* onGetName() SK_OVERRIDE { 102 return isSmall() ? "colorfilter_bright_gray_small" : "colorfilter_bright_gray_large"; 103 } 104 105 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 106 SkRect r = getFilterRect(); 107 SkPaint paint; 108 paint.setColor(SK_ColorRED); 109 for (int i = 0; i < loops; i++) { 110 SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f)); 111 SkAutoTUnref<SkImageFilter> grayscale(make_grayscale(brightness)); 112 paint.setImageFilter(grayscale); 113 canvas->drawRect(r, paint); 114 } 115 } 116 117private: 118 typedef ColorFilterBaseBench INHERITED; 119}; 120 121class ColorFilterGrayBrightBench : public ColorFilterBaseBench { 122 123public: 124 ColorFilterGrayBrightBench(bool small) : INHERITED(small) { 125 } 126 127protected: 128 virtual const char* onGetName() SK_OVERRIDE { 129 return isSmall() ? "colorfilter_gray_bright_small" : "colorfilter_gray_bright_large"; 130 } 131 132 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 133 SkRect r = getFilterRect(); 134 SkPaint paint; 135 paint.setColor(SK_ColorRED); 136 for (int i = 0; i < loops; i++) { 137 SkAutoTUnref<SkImageFilter> grayscale(make_grayscale()); 138 SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f, grayscale)); 139 paint.setImageFilter(brightness); 140 canvas->drawRect(r, paint); 141 } 142 } 143 144private: 145 typedef ColorFilterBaseBench INHERITED; 146}; 147 148class ColorFilterBlueBrightBench : public ColorFilterBaseBench { 149 150public: 151 ColorFilterBlueBrightBench(bool small) : INHERITED(small) { 152 } 153 154protected: 155 virtual const char* onGetName() SK_OVERRIDE { 156 return isSmall() ? "colorfilter_blue_bright_small" : "colorfilter_blue_bright_large"; 157 } 158 159 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 160 SkRect r = getFilterRect(); 161 SkPaint paint; 162 paint.setColor(SK_ColorRED); 163 for (int i = 0; i < loops; i++) { 164 SkAutoTUnref<SkImageFilter> blue(make_mode_blue()); 165 SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f, blue)); 166 paint.setImageFilter(brightness); 167 canvas->drawRect(r, paint); 168 } 169 } 170 171private: 172 typedef ColorFilterBaseBench INHERITED; 173}; 174 175class ColorFilterBrightBlueBench : public ColorFilterBaseBench { 176 177public: 178 ColorFilterBrightBlueBench(bool small) : INHERITED(small) { 179 } 180 181protected: 182 virtual const char* onGetName() SK_OVERRIDE { 183 return isSmall() ? "colorfilter_bright_blue_small" : "colorfilter_bright_blue_large"; 184 } 185 186 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 187 SkRect r = getFilterRect(); 188 SkPaint paint; 189 paint.setColor(SK_ColorRED); 190 for (int i = 0; i < loops; i++) { 191 SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f)); 192 SkAutoTUnref<SkImageFilter> blue(make_mode_blue(brightness)); 193 paint.setImageFilter(blue); 194 canvas->drawRect(r, paint); 195 } 196 } 197 198private: 199 typedef ColorFilterBaseBench INHERITED; 200}; 201 202class ColorFilterBrightBench : public ColorFilterBaseBench { 203 204public: 205 ColorFilterBrightBench(bool small) : INHERITED(small) { 206 } 207 208protected: 209 virtual const char* onGetName() SK_OVERRIDE { 210 return isSmall() ? "colorfilter_bright_small" : "colorfilter_bright_large"; 211 } 212 213 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 214 SkRect r = getFilterRect(); 215 SkPaint paint; 216 paint.setColor(SK_ColorRED); 217 for (int i = 0; i < loops; i++) { 218 SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f)); 219 paint.setImageFilter(brightness); 220 canvas->drawRect(r, paint); 221 } 222 } 223 224private: 225 typedef ColorFilterBaseBench INHERITED; 226}; 227 228class ColorFilterBlueBench : public ColorFilterBaseBench { 229 230public: 231 ColorFilterBlueBench(bool small) : INHERITED(small) { 232 } 233 234protected: 235 virtual const char* onGetName() SK_OVERRIDE { 236 return isSmall() ? "colorfilter_blue_small" : "colorfilter_blue_large"; 237 } 238 239 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 240 SkRect r = getFilterRect(); 241 SkPaint paint; 242 paint.setColor(SK_ColorRED); 243 for (int i = 0; i < loops; i++) { 244 SkAutoTUnref<SkImageFilter> blue(make_mode_blue()); 245 paint.setImageFilter(blue); 246 canvas->drawRect(r, paint); 247 } 248 } 249 250private: 251 typedef ColorFilterBaseBench INHERITED; 252}; 253 254class ColorFilterGrayBench : public ColorFilterBaseBench { 255 256public: 257 ColorFilterGrayBench(bool small) : INHERITED(small) { 258 } 259 260protected: 261 virtual const char* onGetName() SK_OVERRIDE { 262 return isSmall() ? "colorfilter_gray_small" : "colorfilter_gray_large"; 263 } 264 265 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 266 SkRect r = getFilterRect(); 267 SkPaint paint; 268 paint.setColor(SK_ColorRED); 269 for (int i = 0; i < loops; i++) { 270 SkAutoTUnref<SkImageFilter> grayscale(make_grayscale()); 271 paint.setImageFilter(grayscale); 272 canvas->drawRect(r, paint); 273 } 274 } 275 276private: 277 typedef ColorFilterBaseBench INHERITED; 278}; 279 280class TableColorFilterBench : public ColorFilterBaseBench { 281 282public: 283 TableColorFilterBench(bool small) : INHERITED(small) { 284 } 285 286protected: 287 virtual const char* onGetName() SK_OVERRIDE { 288 return isSmall() ? "table_colorfilter_small" : "table_colorfilter_large"; 289 } 290 291 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 292 SkRect r = getFilterRect(); 293 SkPaint paint; 294 paint.setColor(SK_ColorRED); 295 for (int i = 0; i < loops; i++) { 296 SkAutoTUnref<SkColorFilter> table_filter(make_table_filter()); 297 paint.setColorFilter(table_filter); 298 canvas->drawRect(r, paint); 299 } 300 } 301 302private: 303 static void fill_table_data(uint8_t table[]) { 304 for (int i = 0; i < 256; ++i) { 305 int n = i >> 5; 306 table[i] = (n << 5) | (n << 2) | (n >> 1); 307 } 308 } 309 310 static SkColorFilter* make_table_filter() { 311 uint8_t table[256]; fill_table_data(table); 312 return SkTableColorFilter::Create(table); 313 } 314 315 typedef ColorFilterBaseBench INHERITED; 316}; 317 318class LumaColorFilterBench : public ColorFilterBaseBench { 319 320public: 321 LumaColorFilterBench(bool small) : INHERITED(small) { 322 } 323 324protected: 325 virtual const char* onGetName() SK_OVERRIDE { 326 return isSmall() ? "luma_colorfilter_small" : "luma_colorfilter_large"; 327 } 328 329 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 330 SkRect r = getFilterRect(); 331 SkPaint paint; 332 paint.setColor(SK_ColorRED); 333 334 for (int i = 0; i < loops; i++) { 335 SkAutoTUnref<SkColorFilter> luma_filter(SkLumaColorFilter::Create()); 336 paint.setColorFilter(luma_filter); 337 canvas->drawRect(r, paint); 338 } 339 } 340 341private: 342 typedef ColorFilterBaseBench INHERITED; 343}; 344 345/////////////////////////////////////////////////////////////////////////////// 346 347DEF_BENCH( return new ColorFilterDimBrightBench(true); ) 348DEF_BENCH( return new ColorFilterBrightGrayBench(true); ) 349DEF_BENCH( return new ColorFilterGrayBrightBench(true); ) 350DEF_BENCH( return new ColorFilterBlueBrightBench(true); ) 351DEF_BENCH( return new ColorFilterBrightBlueBench(true); ) 352DEF_BENCH( return new ColorFilterBrightBench(true); ) 353DEF_BENCH( return new ColorFilterBlueBench(true); ) 354DEF_BENCH( return new ColorFilterGrayBench(true); ) 355DEF_BENCH( return new TableColorFilterBench(true); ) 356DEF_BENCH( return new LumaColorFilterBench(true); ) 357 358DEF_BENCH( return new ColorFilterDimBrightBench(false); ) 359DEF_BENCH( return new ColorFilterBrightGrayBench(false); ) 360DEF_BENCH( return new ColorFilterGrayBrightBench(false); ) 361DEF_BENCH( return new ColorFilterBlueBrightBench(false); ) 362DEF_BENCH( return new ColorFilterBrightBlueBench(false); ) 363DEF_BENCH( return new ColorFilterBrightBench(false); ) 364DEF_BENCH( return new ColorFilterBlueBench(false); ) 365DEF_BENCH( return new ColorFilterGrayBench(false); ) 366DEF_BENCH( return new TableColorFilterBench(false); ) 367DEF_BENCH( return new LumaColorFilterBench(false); ) 368