From e36ddf01311802dd5c5fe85d47a9bd84b2b84565 Mon Sep 17 00:00:00 2001 From: "senorblanco@chromium.org" Date: Fri, 15 Jul 2011 14:28:16 +0000 Subject: [PATCH] More GPU blur fixes. - clamp the max. radius to 128, as the software path does - use a more accurate radius-to-sigma conversion (0.6 instead of 0.6666) - make SampleBlur derive from SampleView, not SkView, so benchmark mode ('f') works - implement a new BigBlur sample to test large radii Review URL: http://codereview.appspot.com/4726043 git-svn-id: http://skia.googlecode.com/svn/trunk@1871 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gyp/SampleApp.gyp | 1 + samplecode/SampleBigBlur.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ samplecode/SampleBlur.cpp | 4 ++-- src/gpu/SkGpuDevice.cpp | 22 +++++++++++++++++----- 4 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 samplecode/SampleBigBlur.cpp diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp index 20cde14..4c73857 100644 --- a/gyp/SampleApp.gyp +++ b/gyp/SampleApp.gyp @@ -38,6 +38,7 @@ '../samplecode/SampleApp.cpp', '../samplecode/SampleArc.cpp', '../samplecode/SampleAvoid.cpp', + '../samplecode/SampleBigBlur.cpp', '../samplecode/SampleBigGradient.cpp', '../samplecode/SampleBitmapRect.cpp', '../samplecode/SampleBlur.cpp', diff --git a/samplecode/SampleBigBlur.cpp b/samplecode/SampleBigBlur.cpp new file mode 100644 index 0000000..243e0df --- /dev/null +++ b/samplecode/SampleBigBlur.cpp @@ -0,0 +1,43 @@ +#include "SampleCode.h" +#include "SkBlurMaskFilter.h" +#include "SkView.h" +#include "SkCanvas.h" + +class BigBlurView : public SampleView { +public: + BigBlurView() { + } + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "BigBlur"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + SkPaint paint; + canvas->save(); + paint.setColor(SK_ColorBLUE); + SkMaskFilter* mf = SkBlurMaskFilter::Create( + 128, + SkBlurMaskFilter::kNormal_BlurStyle, + SkBlurMaskFilter::kHighQuality_BlurFlag); + paint.setMaskFilter(mf)->unref(); + canvas->translate(200, 200); + canvas->drawCircle(100, 100, 250, paint); + canvas->restore(); + } + +private: + typedef SkView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new BigBlurView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleBlur.cpp b/samplecode/SampleBlur.cpp index d2ea2b0..98cfcfb 100644 --- a/samplecode/SampleBlur.cpp +++ b/samplecode/SampleBlur.cpp @@ -41,7 +41,7 @@ static SkBitmap make_bitmap() { return bm; } -class BlurView : public SkView { +class BlurView : public SampleView { SkBitmap fBM; public: BlurView() { @@ -61,7 +61,7 @@ protected: canvas->drawColor(0xFFDDDDDD); } - virtual void onDraw(SkCanvas* canvas) { + virtual void onDrawContent(SkCanvas* canvas) { drawBG(canvas); SkBlurMaskFilter::BlurStyle NONE = SkBlurMaskFilter::BlurStyle(-999); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 386b409..b39f90e 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -48,7 +48,18 @@ enum { #define USE_GPU_BLUR 0 -#define MAX_SIGMA 4.0f +#define MAX_BLUR_SIGMA 4.0f +// FIXME: This value comes from from SkBlurMaskFilter.cpp. +// Should probably be put in a common header someplace. +#define MAX_BLUR_RADIUS SkIntToScalar(128) +// This constant approximates the scaling done in the software path's +// "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)). +// IMHO, it actually should be 1: we blur "less" than we should do +// according to the CSS and canvas specs, simply because Safari does the same. +// Firefox used to do the same too, until 4.0 where they fixed it. So at some +// point we should probably get rid of these scaling constants and rebaseline +// all the blur tests. +#define BLUR_SIGMA_SCALE 0.6f /////////////////////////////////////////////////////////////////////////////// SkGpuDevice::SkAutoCachedTexture:: @@ -836,14 +847,15 @@ static bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, if (SkMaskFilter::kNone_BlurType == blurType) { return false; } - float radius = info.fIgnoreTransform ? info.fRadius - : matrix.mapRadius(info.fRadius); - float sigma = radius * 0.6666f; + SkScalar radius = info.fIgnoreTransform ? info.fRadius + : matrix.mapRadius(info.fRadius); + radius = SkMinScalar(radius, MAX_BLUR_RADIUS); + float sigma = SkScalarToFloat(radius) * BLUR_SIGMA_SCALE; SkRect srcRect = path.getBounds(); int scaleFactor = 1; - while (sigma > MAX_SIGMA) { + while (sigma > MAX_BLUR_SIGMA) { scaleFactor *= 2; sigma *= 0.5f; } -- 2.7.4