skia2/bench/BlurImageFilterBench.cpp
commit-bot@chromium.org c45ece5f7f NEON fast path for box blur
Calculate 8 channels in parallel by using 16-bits to store each channel. Due to the limitation of VQRDMULH, (int16 * int16 * 2 + 0x8000) >> 16, the fast path can only support kernelSize < 128.
8 significant bits are kept at least in each stage, the final error should less-equal than 1.

Pre-fetching memory for X-direction read. In fact pre-fetching memory doesn't help much for Y direction read, since it is a waste to load a cache line for only read 8 bytes.(I left it there to keep the symmetry. pre-fetch is cheap :) )

bench data on Nexus 10
before:
running bench [640 480]      blur_image_filter_large_10.00_10.00   8888:  cmsecs =  25081.48
running bench [640 480]      blur_image_filter_small_10.00_10.00   8888:  cmsecs =  25038.04
running bench [640 480]        blur_image_filter_large_1.00_1.00   8888:  cmsecs =  25209.04
running bench [640 480]        blur_image_filter_small_1.00_1.00   8888:  cmsecs =  24928.01
running bench [640 480]        blur_image_filter_large_0.00_1.00   8888:  cmsecs =  17160.98
running bench [640 480]       blur_image_filter_large_0.00_10.00   8888:  cmsecs =  17924.11
running bench [640 480]        blur_image_filter_large_1.00_0.00   8888:  cmsecs =  14609.19
running bench [640 480]       blur_image_filter_large_10.00_0.00   8888:  cmsecs =  14625.91

after:
running bench [640 480]      blur_image_filter_large_10.00_10.00   8888:  cmsecs =  14848.42
running bench [640 480]      blur_image_filter_small_10.00_10.00   8888:  cmsecs =  16037.29
running bench [640 480]        blur_image_filter_large_1.00_1.00   8888:  cmsecs =  14819.55
running bench [640 480]        blur_image_filter_small_1.00_1.00   8888:  cmsecs =  14563.69
running bench [640 480]        blur_image_filter_large_0.00_1.00   8888:  cmsecs =  11905.34
running bench [640 480]       blur_image_filter_large_0.00_10.00   8888:  cmsecs =  11883.85
running bench [640 480]        blur_image_filter_large_1.00_0.00   8888:  cmsecs =   9576.51
running bench [640 480]       blur_image_filter_large_10.00_0.00   8888:  cmsecs =   9793.84

BUG=
R=senorblanco@chromium.org, mtklein@google.com, reed@google.com, kevin.petit@arm.com, kevin.petit.arm@gmail.com

Author: zheng.xu@arm.com

Review URL: https://codereview.chromium.org/105893003

git-svn-id: http://skia.googlecode.com/svn/trunk@13036 2bbb7eff-a529-9590-31e7-b0007b416f81
2014-01-13 08:16:45 +00:00

98 lines
3.5 KiB
C++

/*
* 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 "SkBenchmark.h"
#include "SkBitmapDevice.h"
#include "SkBlurImageFilter.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkShader.h"
#include "SkString.h"
#define FILTER_WIDTH_SMALL 32
#define FILTER_HEIGHT_SMALL 32
#define FILTER_WIDTH_LARGE 256
#define FILTER_HEIGHT_LARGE 256
#define BLUR_SIGMA_SMALL 1.0f
#define BLUR_SIGMA_LARGE 10.0f
#define BLUR_SIGMA_HUGE 80.0f
class BlurImageFilterBench : public SkBenchmark {
public:
BlurImageFilterBench(SkScalar sigmaX, SkScalar sigmaY, bool small) :
fIsSmall(small), fInitialized(false), fSigmaX(sigmaX), fSigmaY(sigmaY) {
fName.printf("blur_image_filter_%s_%.2f_%.2f", fIsSmall ? "small" : "large",
SkScalarToFloat(sigmaX), SkScalarToFloat(sigmaY));
}
protected:
virtual const char* onGetName() SK_OVERRIDE {
return fName.c_str();
}
virtual void onPreDraw() SK_OVERRIDE {
if (!fInitialized) {
make_checkerboard();
fInitialized = true;
}
}
virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
SkPaint paint;
paint.setImageFilter(new SkBlurImageFilter(fSigmaX, fSigmaY))->unref();
for (int i = 0; i < loops; i++) {
canvas->drawBitmap(fCheckerboard, 0, 0, &paint);
}
}
private:
void make_checkerboard() {
const int w = fIsSmall ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
const int h = fIsSmall ? FILTER_HEIGHT_LARGE : FILTER_HEIGHT_LARGE;
fCheckerboard.setConfig(SkBitmap::kARGB_8888_Config, w, h);
fCheckerboard.allocPixels();
SkBitmapDevice device(fCheckerboard);
SkCanvas canvas(&device);
canvas.clear(0x00000000);
SkPaint darkPaint;
darkPaint.setColor(0xFF804020);
SkPaint lightPaint;
lightPaint.setColor(0xFF244484);
for (int y = 0; y < h; y += 16) {
for (int x = 0; x < w; 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();
}
}
}
SkString fName;
bool fIsSmall;
bool fInitialized;
SkBitmap fCheckerboard;
SkScalar fSigmaX, fSigmaY;
typedef SkBenchmark INHERITED;
};
DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, 0, false);)
DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, 0, false);)
DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_LARGE, false);)
DEF_BENCH(return new BlurImageFilterBench(0, BLUR_SIGMA_SMALL, false);)
DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, true);)
DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_SMALL, BLUR_SIGMA_SMALL, false);)
DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, true);)
DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_LARGE, BLUR_SIGMA_LARGE, false);)
DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_HUGE, BLUR_SIGMA_HUGE, true);)
DEF_BENCH(return new BlurImageFilterBench(BLUR_SIGMA_HUGE, BLUR_SIGMA_HUGE, false);)