More GPU blur fixes.
authorsenorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 15 Jul 2011 14:28:16 +0000 (14:28 +0000)
committersenorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 15 Jul 2011 14:28:16 +0000 (14:28 +0000)
- 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
samplecode/SampleBigBlur.cpp [new file with mode: 0644]
samplecode/SampleBlur.cpp
src/gpu/SkGpuDevice.cpp

index 20cde14..4c73857 100644 (file)
@@ -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 (file)
index 0000000..243e0df
--- /dev/null
@@ -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);
+
index d2ea2b0..98cfcfb 100644 (file)
@@ -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);
index 386b409..b39f90e 100644 (file)
@@ -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;
     }