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