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