diff options
author | cwallez <cwallez@google.com> | 2015-01-26 07:45:53 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-26 07:45:53 -0800 |
commit | c12b74dc413ef024b13e0ed478491c4b1bafe6b1 (patch) | |
tree | 706b76c6b014f84ca982a58686720bb47f8cdeb2 /bench/ImageFilterCollapse.cpp | |
parent | 9ec0ffb77dfb2c7337daadd4d88736c3e1ebe28b (diff) |
Collapse consecutive SkTableColorFilters
BUG=skia:1366
For the added bench, the collapsing makes the bench take:
- 70% of the time for CPU rendering of 3 consecutive matrix filters
- almost no change in the GPU rendering of the matrix filters
- 50% of the time for CPU and GPU rendering of 3 consecutive table filters
Review URL: https://codereview.chromium.org/776673002
Diffstat (limited to 'bench/ImageFilterCollapse.cpp')
-rw-r--r-- | bench/ImageFilterCollapse.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/bench/ImageFilterCollapse.cpp b/bench/ImageFilterCollapse.cpp new file mode 100644 index 0000000000..6cda6ac389 --- /dev/null +++ b/bench/ImageFilterCollapse.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Benchmark.h" +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkColorFilterImageFilter.h" +#include "SkColorMatrixFilter.h" +#include "SkGradientShader.h" +#include "SkImageFilter.h" +#include "SkTableColorFilter.h" + +// Chains several matrix color filters image filter or several +// table filter image filters and draws a bitmap. +// This bench shows an improvement in performance and memory +// when collapsing matrices or tables is implemented since all +// the passes are collapsed in one. + +class BaseImageFilterCollapseBench : public Benchmark { +public: + BaseImageFilterCollapseBench(): fImageFilter(NULL) {} + ~BaseImageFilterCollapseBench() { + SkSafeUnref(fImageFilter); + } + +protected: + void doPreDraw(SkColorFilter* colorFilters[], int nFilters) { + // Create a chain of ImageFilters from colorFilters + fImageFilter = NULL; + for(int i = nFilters; i --> 0;) { + SkAutoTUnref<SkImageFilter> filter( + SkColorFilterImageFilter::Create(colorFilters[i], fImageFilter, NULL, 0) + ); + SkRefCnt_SafeAssign(fImageFilter, filter.get()); + } + } + + void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { + makeBitmap(); + + for(int i = 0; i < loops; i++) { + SkPaint paint; + paint.setImageFilter(fImageFilter); + canvas->drawBitmap(fBitmap, 0, 0, &paint); + } + } + +private: + SkImageFilter* fImageFilter; + SkBitmap fBitmap; + + void makeBitmap() { + int W = 400; + int H = 400; + fBitmap.allocN32Pixels(W, H); + fBitmap.eraseColor(SK_ColorTRANSPARENT); + + SkCanvas canvas(fBitmap); + SkPaint paint; + SkPoint pts[] = { {0, 0}, {SkIntToScalar(W), SkIntToScalar(H)} }; + SkColor colors[] = { + SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN, + SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE + }; + SkAutoTUnref<SkShader> shader(SkGradientShader::CreateLinear( + pts, colors, NULL, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode + )); + paint.setShader(shader); + canvas.drawPaint(paint); + } +}; + +class TableCollapseBench: public BaseImageFilterCollapseBench { +public: + virtual ~TableCollapseBench() {} + +protected: + virtual const char* onGetName() SK_OVERRIDE { + return "image_filter_collapse_table"; + } + + virtual void onPreDraw() SK_OVERRIDE { + for (int i = 0; i < 256; ++i) { + int n = i >> 5; + table1[i] = (n << 5) | (n << 2) | (n >> 1); + + table2[i] = i * i / 255; + + float fi = i / 255.0f; + table3[i] = static_cast<uint8_t>(sqrtf(fi) * 255); + } + + SkColorFilter* colorFilters[] = { + SkTableColorFilter::Create(table1), + SkTableColorFilter::Create(table2), + SkTableColorFilter::Create(table3), + }; + + doPreDraw(colorFilters, SK_ARRAY_COUNT(colorFilters)); + + for(unsigned i = 0; i < SK_ARRAY_COUNT(colorFilters); i++) { + colorFilters[i]->unref(); + } + } + +private: + uint8_t table1[256], table2[256], table3[256]; +}; + +static SkColorFilter* make_brightness(float amount) { + SkScalar amount255 = SkScalarMul(amount, SkIntToScalar(255)); + SkScalar matrix[20] = { 1, 0, 0, 0, amount255, + 0, 1, 0, 0, amount255, + 0, 0, 1, 0, amount255, + 0, 0, 0, 1, 0 }; + return SkColorMatrixFilter::Create(matrix); +} + +static SkColorFilter* make_grayscale() { + SkScalar matrix[20]; + memset(matrix, 0, 20 * sizeof(SkScalar)); + matrix[0] = matrix[5] = matrix[10] = 0.2126f; + matrix[1] = matrix[6] = matrix[11] = 0.7152f; + matrix[2] = matrix[7] = matrix[12] = 0.0722f; + matrix[18] = 1.0f; + return SkColorMatrixFilter::Create(matrix); +} + +class MatrixCollapseBench: public BaseImageFilterCollapseBench { +public: + virtual ~MatrixCollapseBench() {} + +protected: + virtual const char* onGetName() SK_OVERRIDE { + return "image_filter_collapse_matrix"; + } + + virtual void onPreDraw() SK_OVERRIDE { + SkColorFilter* colorFilters[] = { + make_brightness(0.1f), + make_grayscale(), + make_brightness(-0.1f), + }; + + doPreDraw(colorFilters, SK_ARRAY_COUNT(colorFilters)); + + for(unsigned i = 0; i < SK_ARRAY_COUNT(colorFilters); i++) { + colorFilters[i]->unref(); + } + } +}; + +DEF_BENCH(return new TableCollapseBench;) +DEF_BENCH(return new MatrixCollapseBench;) |