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() {}
     26 
     27 protected:
     28     void doPreDraw(sk_sp<SkColorFilter> colorFilters[], int nFilters) {
     29         SkASSERT(!fImageFilter);
     30 
     31         // Create a chain of ImageFilters from colorFilters
     32         for(int i = nFilters; i --> 0;) {
     33             fImageFilter = SkColorFilterImageFilter::Make(colorFilters[i], fImageFilter);
     34         }
     35     }
     36 
     37     void onDraw(int loops, SkCanvas* canvas) override {
     38         makeBitmap();
     39 
     40         for(int i = 0; i < loops; i++) {
     41             SkPaint paint;
     42             paint.setImageFilter(fImageFilter);
     43             canvas->drawBitmap(fBitmap, 0, 0, &paint);
     44         }
     45     }
     46 
     47 private:
     48     sk_sp<SkImageFilter> fImageFilter;
     49     SkBitmap fBitmap;
     50 
     51     void makeBitmap() {
     52         int W = 400;
     53         int H = 400;
     54         fBitmap.allocN32Pixels(W, H);
     55         fBitmap.eraseColor(SK_ColorTRANSPARENT);
     56 
     57         SkCanvas canvas(fBitmap);
     58         SkPaint paint;
     59         SkPoint pts[] = { {0, 0}, {SkIntToScalar(W), SkIntToScalar(H)} };
     60         SkColor colors[] = {
     61             SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN,
     62             SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE
     63         };
     64         paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
     65                                                      SkShader::kClamp_TileMode));
     66         canvas.drawPaint(paint);
     67     }
     68 };
     69 
     70 class TableCollapseBench: public BaseImageFilterCollapseBench {
     71 protected:
     72     const char* onGetName() override {
     73         return "image_filter_collapse_table";
     74     }
     75 
     76     void onDelayedSetup() override {
     77         for (int i = 0; i < 256; ++i) {
     78             int n = i >> 5;
     79             table1[i] = (n << 5) | (n << 2) | (n >> 1);
     80 
     81             table2[i] = i * i / 255;
     82 
     83             float fi = i / 255.0f;
     84             table3[i] = static_cast<uint8_t>(sqrtf(fi) * 255);
     85         }
     86 
     87         sk_sp<SkColorFilter> colorFilters[] = {
     88             SkTableColorFilter::Make(table1),
     89             SkTableColorFilter::Make(table2),
     90             SkTableColorFilter::Make(table3),
     91         };
     92 
     93         this->doPreDraw(colorFilters, SK_ARRAY_COUNT(colorFilters));
     94     }
     95 
     96 private:
     97     uint8_t table1[256], table2[256], table3[256];
     98 };
     99 
    100 static sk_sp<SkColorFilter> make_brightness(float amount) {
    101     SkScalar amount255 = amount * 255;
    102     SkScalar matrix[20] = { 1, 0, 0, 0, amount255,
    103                             0, 1, 0, 0, amount255,
    104                             0, 0, 1, 0, amount255,
    105                             0, 0, 0, 1, 0 };
    106     return SkColorFilter::MakeMatrixFilterRowMajor255(matrix);
    107 }
    108 
    109 static sk_sp<SkColorFilter> make_grayscale() {
    110     SkScalar matrix[20];
    111     memset(matrix, 0, 20 * sizeof(SkScalar));
    112     matrix[0] = matrix[5] = matrix[10] = 0.2126f;
    113     matrix[1] = matrix[6] = matrix[11] = 0.7152f;
    114     matrix[2] = matrix[7] = matrix[12] = 0.0722f;
    115     matrix[18] = 1.0f;
    116     return SkColorFilter::MakeMatrixFilterRowMajor255(matrix);
    117 }
    118 
    119 class MatrixCollapseBench: public BaseImageFilterCollapseBench {
    120 protected:
    121     const char* onGetName() override {
    122         return "image_filter_collapse_matrix";
    123     }
    124 
    125     void onDelayedSetup() override {
    126         sk_sp<SkColorFilter> colorFilters[] = {
    127             make_brightness(0.1f),
    128             make_grayscale(),
    129             make_brightness(-0.1f),
    130         };
    131 
    132         this->doPreDraw(colorFilters, SK_ARRAY_COUNT(colorFilters));
    133     }
    134 };
    135 
    136 DEF_BENCH(return new TableCollapseBench;)
    137 DEF_BENCH(return new MatrixCollapseBench;)
    138