| /* |
| * Copyright 2013 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "bench/Benchmark.h" |
| #include "include/core/SkBitmap.h" |
| #include "include/core/SkCanvas.h" |
| #include "include/core/SkPaint.h" |
| #include "include/core/SkShader.h" |
| #include "include/core/SkString.h" |
| #include "include/effects/SkImageFilters.h" |
| #include "src/base/SkRandom.h" |
| |
| #define FILTER_WIDTH_SMALL 32 |
| #define FILTER_HEIGHT_SMALL 32 |
| #define FILTER_WIDTH_LARGE 256 |
| #define FILTER_HEIGHT_LARGE 256 |
| #define BLUR_SIGMA_MINI 0.5f |
| #define BLUR_SIGMA_SMALL 1.0f |
| #define BLUR_SIGMA_LARGE 10.0f |
| #define BLUR_SIGMA_HUGE 80.0f |
| |
| |
| // When 'cropped' is set we apply a cropRect to the blurImageFilter. The crop rect is an inset of |
| // the source's natural dimensions. This is intended to exercise blurring a larger source bitmap |
| // to a smaller destination bitmap. |
| |
| // When 'expanded' is set we apply a cropRect to the input of the blurImageFilter (a noOp |
| // offsetImageFilter). The crop rect in this case is an inset of the source's natural dimensions. |
| // An additional crop rect is applied to the blurImageFilter that is just the natural dimensions |
| // of the source (not inset). This is intended to exercise blurring a smaller source bitmap to a |
| // larger destination. |
| |
| static sk_sp<SkImage> make_checkerboard(int width, int height) { |
| SkBitmap bm; |
| bm.allocN32Pixels(width, height); |
| SkCanvas canvas(bm); |
| canvas.clear(0x00000000); |
| SkPaint darkPaint; |
| darkPaint.setColor(0xFF804020); |
| SkPaint lightPaint; |
| lightPaint.setColor(0xFF244484); |
| for (int y = 0; y < height; y += 16) { |
| for (int x = 0; x < width; x += 16) { |
| canvas.save(); |
| canvas.translate(SkIntToScalar(x), SkIntToScalar(y)); |
| canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint); |
| canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint); |
| canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint); |
| canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint); |
| canvas.restore(); |
| } |
| } |
| |
| return bm.asImage(); |
| } |
| |
| class BlurImageFilterBench : public Benchmark { |
| public: |
| BlurImageFilterBench(SkScalar sigmaX, SkScalar sigmaY, bool small, bool cropped, |
| bool expanded) |
| : fIsSmall(small) |
| , fIsCropped(cropped) |
| , fIsExpanded(expanded) |
| , fInitialized(false) |
| , fSigmaX(sigmaX) |
| , fSigmaY(sigmaY) { |
| fName.printf("blur_image_filter_%s%s%s_%.2f_%.2f", |
| fIsSmall ? "small" : "large", |
| fIsCropped ? "_cropped" : "", |
| fIsExpanded ? "_expanded" : "", |
| sigmaX, sigmaY); |
| SkASSERT(!fIsExpanded || fIsCropped); // never want expansion w/o cropping |
| } |
| |
| protected: |
| const char* onGetName() override { |
| return fName.c_str(); |
| } |
| |
| void onDelayedSetup() override { |
| if (!fInitialized) { |
| fCheckerboard = make_checkerboard(fIsSmall ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE, |
| fIsSmall ? FILTER_HEIGHT_SMALL : FILTER_HEIGHT_LARGE); |
| fInitialized = true; |
| } |
| } |
| |
| void onDraw(int loops, SkCanvas* canvas) override { |
| static const int kX = 0; |
| static const int kY = 0; |
| const SkIRect bmpRect = SkIRect::MakeXYWH(kX, kY, fCheckerboard->width(), |
| fCheckerboard->height()); |
| const SkIRect bmpRectInset = bmpRect.makeInset(10, 10); |
| |
| sk_sp<SkImageFilter> input = fIsExpanded |
| ? SkImageFilters::Offset(0, 0, nullptr, &bmpRectInset) |
| : nullptr; |
| |
| const SkIRect* crop = |
| fIsExpanded ? &bmpRect : fIsCropped ? &bmpRectInset : nullptr; |
| SkPaint paint; |
| paint.setImageFilter(SkImageFilters::Blur(fSigmaX, fSigmaY, std::move(input), crop)); |
| SkSamplingOptions sampling; |
| |
| for (int i = 0; i < loops; i++) { |
| canvas->drawImage(fCheckerboard, kX, kY, sampling, &paint); |
| } |
| } |
| |
| private: |
| |
| SkString fName; |
| bool fIsSmall; |
| bool fIsCropped; |
| bool fIsExpanded; |
| bool fInitialized; |
| sk_sp<SkImage> fCheckerboard; |
| SkScalar fSigmaX, fSigmaY; |
| using INHERITED = Benchmark; |
| }; |
| |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, 0, false, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, 0, false, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_LARGE, false, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_SMALL, false, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_MINI, BLUR_SIGMA_MINI, true, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_MINI, BLUR_SIGMA_MINI, false, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, true, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, false, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, true, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, false, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_HUGE, BLUR_SIGMA_HUGE, true, false, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_HUGE, BLUR_SIGMA_HUGE, false, false, false);) |
| |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, 0, false, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, 0, false, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_LARGE, false, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_SMALL, false, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_MINI, BLUR_SIGMA_MINI, true, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_MINI, BLUR_SIGMA_MINI, false, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, true, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, false, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, true, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, false, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_HUGE, BLUR_SIGMA_HUGE, true, true, false);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_HUGE, BLUR_SIGMA_HUGE, false, true, false);) |
| |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, 0, false, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, 0, false, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_LARGE, false, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_SMALL, false, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_MINI, BLUR_SIGMA_MINI, true, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_MINI, BLUR_SIGMA_MINI, false, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, true, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, false, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, true, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, false, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_HUGE, BLUR_SIGMA_HUGE, true, true, true);) |
| DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_HUGE, BLUR_SIGMA_HUGE, false, true, true);) |