Home | History | Annotate | Download | only in bench
      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 "SkBitmap.h"
     10 #include "SkCanvas.h"
     11 #include "SkColorFilterImageFilter.h"
     12 #include "SkColorMatrixFilter.h"
     13 #include "SkGradientShader.h"
     14 #include "SkImageFilter.h"
     15 #include "SkTableColorFilter.h"
     16 
     17 // Chains several matrix color filters image filter or several
     18 // table filter image filters and draws a bitmap.
     19 // This bench shows an improvement in performance and memory
     20 // when collapsing matrices or tables is implemented since all
     21 // the passes are collapsed in one.
     22 
     23 class BaseImageFilterCollapseBench : public Benchmark {
     24 public:
     25     BaseImageFilterCollapseBench(): fImageFilter(nullptr) {}
     26     ~BaseImageFilterCollapseBench() {
     27         SkSafeUnref(fImageFilter);
     28     }
     29 
     30 protected:
     31     void doPreDraw(SkColorFilter* colorFilters[], int nFilters) {
     32         // Create a chain of ImageFilters from colorFilters
     33         fImageFilter = nullptr;
     34         for(int i = nFilters; i --> 0;) {
     35             SkAutoTUnref<SkImageFilter> filter(
     36                         SkColorFilterImageFilter::Create(colorFilters[i], fImageFilter, nullptr)
     37             );
     38             SkRefCnt_SafeAssign(fImageFilter, filter.get());
     39         }
     40     }
     41 
     42     void onDraw(int loops, SkCanvas* canvas) override {
     43         makeBitmap();
     44 
     45         for(int i = 0; i < loops; i++) {
     46             SkPaint paint;
     47             paint.setImageFilter(fImageFilter);
     48             canvas->drawBitmap(fBitmap, 0, 0, &paint);
     49         }
     50     }
     51 
     52 private:
     53     SkImageFilter* fImageFilter;
     54     SkBitmap fBitmap;
     55 
     56     void makeBitmap() {
     57         int W = 400;
     58         int H = 400;
     59         fBitmap.allocN32Pixels(W, H);
     60         fBitmap.eraseColor(SK_ColorTRANSPARENT);
     61 
     62         SkCanvas canvas(fBitmap);
     63         SkPaint paint;
     64         SkPoint pts[] = { {0, 0}, {SkIntToScalar(W), SkIntToScalar(H)} };
     65         SkColor colors[] = {
     66             SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN,
     67             SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE
     68         };
     69         SkAutoTUnref<SkShader> shader(SkGradientShader::CreateLinear(
     70                     pts, colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode
     71         ));
     72         paint.setShader(shader);
     73         canvas.drawPaint(paint);
     74     }
     75 };
     76 
     77 class TableCollapseBench: public BaseImageFilterCollapseBench {
     78 public:
     79     virtual ~TableCollapseBench() {}
     80 
     81 protected:
     82     virtual const char* onGetName() override {
     83         return "image_filter_collapse_table";
     84     }
     85 
     86     virtual void onDelayedSetup() override {
     87         for (int i = 0; i < 256; ++i) {
     88             int n = i >> 5;
     89             table1[i] = (n << 5) | (n << 2) | (n >> 1);
     90 
     91             table2[i] = i * i / 255;
     92 
     93             float fi = i / 255.0f;
     94             table3[i] = static_cast<uint8_t>(sqrtf(fi) * 255);
     95         }
     96 
     97         SkColorFilter* colorFilters[] = {
     98             SkTableColorFilter::Create(table1),
     99             SkTableColorFilter::Create(table2),
    100             SkTableColorFilter::Create(table3),
    101         };
    102 
    103         doPreDraw(colorFilters, SK_ARRAY_COUNT(colorFilters));
    104 
    105         for(unsigned i = 0; i < SK_ARRAY_COUNT(colorFilters); i++) {
    106             colorFilters[i]->unref();
    107         }
    108     }
    109 
    110 private:
    111     uint8_t table1[256], table2[256], table3[256];
    112 };
    113 
    114 static SkColorFilter* make_brightness(float amount) {
    115     SkScalar amount255 = SkScalarMul(amount, SkIntToScalar(255));
    116     SkScalar matrix[20] = { 1, 0, 0, 0, amount255,
    117                             0, 1, 0, 0, amount255,
    118                             0, 0, 1, 0, amount255,
    119                             0, 0, 0, 1, 0 };
    120     return SkColorMatrixFilter::Create(matrix);
    121 }
    122 
    123 static SkColorFilter* make_grayscale() {
    124     SkScalar matrix[20];
    125     memset(matrix, 0, 20 * sizeof(SkScalar));
    126     matrix[0] = matrix[5] = matrix[10] = 0.2126f;
    127     matrix[1] = matrix[6] = matrix[11] = 0.7152f;
    128     matrix[2] = matrix[7] = matrix[12] = 0.0722f;
    129     matrix[18] = 1.0f;
    130     return SkColorMatrixFilter::Create(matrix);
    131 }
    132 
    133 class MatrixCollapseBench: public BaseImageFilterCollapseBench {
    134 public:
    135     virtual ~MatrixCollapseBench() {}
    136 
    137 protected:
    138     virtual const char* onGetName() override {
    139         return "image_filter_collapse_matrix";
    140     }
    141 
    142     virtual void onDelayedSetup() override {
    143         SkColorFilter* colorFilters[] = {
    144             make_brightness(0.1f),
    145             make_grayscale(),
    146             make_brightness(-0.1f),
    147         };
    148 
    149         doPreDraw(colorFilters, SK_ARRAY_COUNT(colorFilters));
    150 
    151         for(unsigned i = 0; i < SK_ARRAY_COUNT(colorFilters); i++) {
    152             colorFilters[i]->unref();
    153         }
    154     }
    155 };
    156 
    157 DEF_BENCH(return new TableCollapseBench;)
    158 DEF_BENCH(return new MatrixCollapseBench;)
    159