disable GPU blur on small paths
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 28 Mar 2012 14:44:37 +0000 (14:44 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 28 Mar 2012 14:44:37 +0000 (14:44 +0000)
Change originally by Guanqun.Lu@gmail.com with minor edits and sample added by me

COULD POSSIBLY CHANGE GPU RESULTS OF GM SLIDES WITH BLUR, WILL REBASILINE IF SO.

Review URL: https://codereview.appspot.com/5940045/

git-svn-id: http://skia.googlecode.com/svn/trunk@3514 2bbb7eff-a529-9590-31e7-b0007b416f81

gyp/SampleApp.gyp
samplecode/SampleAnimBlur.cpp [new file with mode: 0644]
samplecode/SampleApp.cpp
samplecode/SampleCode.h
src/gpu/SkGpuDevice.cpp

index bdd46ed352c5706652a6ded4156a2c5297591b44..3d79c3d4b07d6eaffc911abd3dfc4237136288d7 100644 (file)
@@ -28,6 +28,7 @@
         '../samplecode/SampleAARectModes.cpp',
         '../samplecode/SampleAll.cpp',
         '../samplecode/SampleAnimator.cpp',
+        '../samplecode/SampleAnimBlur.cpp',
         '../samplecode/SampleApp.cpp',
         '../samplecode/SampleArc.cpp',
         '../samplecode/SampleAvoid.cpp',
diff --git a/samplecode/SampleAnimBlur.cpp b/samplecode/SampleAnimBlur.cpp
new file mode 100644 (file)
index 0000000..74f8811
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SampleCode.h"
+#include "SkBlurMaskFilter.h"
+#include "SkColorPriv.h"
+#include "SkCanvas.h"
+#include "SkRandom.h"
+
+class AnimBlurView : public SampleView {
+public:
+    AnimBlurView() {
+    }
+
+protected:
+    // overrides from SkEventSink
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "AnimBlur");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+
+    virtual void onDrawContent(SkCanvas* canvas) {
+
+        SkScalar blurRadius = SampleCode::GetAnimSinScalar(100 * SK_Scalar1,
+                                                           4 * SK_Scalar1,
+                                                           5 * SK_Scalar1);
+
+        SkScalar circleRadius = 3 * SK_Scalar1 +
+                                SampleCode::GetAnimSinScalar(150 * SK_Scalar1,
+                                                             25 * SK_Scalar1,
+                                                             3 * SK_Scalar1);
+
+        static const SkBlurMaskFilter::BlurStyle gStyles[] = {
+            SkBlurMaskFilter::kNormal_BlurStyle,
+            SkBlurMaskFilter::kInner_BlurStyle,
+            SkBlurMaskFilter::kSolid_BlurStyle,
+            SkBlurMaskFilter::kOuter_BlurStyle,
+        };
+        SkRandom random;
+
+        for (int i = 0; i < SK_ARRAY_COUNT(gStyles); ++i) {
+            SkMaskFilter* mf = SkBlurMaskFilter::Create(blurRadius,
+                                       gStyles[i],
+                                       SkBlurMaskFilter::kHighQuality_BlurFlag);
+            SkPaint paint;
+            paint.setMaskFilter(mf)->unref();
+            paint.setColor(random.nextU() | 0xff000000);
+            canvas->drawCircle(200 * SK_Scalar1 + 400 * (i % 2) * SK_Scalar1,
+                               200 * SK_Scalar1 + i / 2 * 400 * SK_Scalar1,
+                               circleRadius, paint);
+        }
+        this->inval(NULL);
+    }
+
+private:
+    typedef SkView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new AnimBlurView; }
+static SkViewRegister reg(MyFactory);
+
index b2af16a8f6699e79191be596f6595767c5b1d381..ddd33ede32d85ed2daf23aa2e51435f24a90519e 100644 (file)
@@ -520,6 +520,18 @@ SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
     return SkDoubleToScalar(value);
 }
 
+SkScalar SampleCode::GetAnimSinScalar(SkScalar amplitude,
+                                      SkScalar periodInSec,
+                                      SkScalar phaseInSec) {
+    if (!periodInSec) {
+        return 0;
+    }
+    double t = (double)gAnimTime / 1000.0 + phaseInSec;
+    t *= SkScalarToFloat(2 * SK_ScalarPI) / periodInSec;
+    amplitude = SK_ScalarHalf * amplitude;
+    return SkScalarMul(amplitude, SkDoubleToScalar(sin(t))) + amplitude;
+}
+
 GrContext* SampleCode::GetGr() {
     return gSampleWindow ? gSampleWindow->getGrContext() : NULL;
 }
index 197e0f1d5a0122ae906537cb3d8df4f1c046630a..3d1f2665cba5b57f924dbf273659972db2cec973 100644 (file)
@@ -35,6 +35,10 @@ public:
     static SkMSec GetAnimTimeDelta();
     static SkScalar GetAnimSecondsDelta();
     static SkScalar GetAnimScalar(SkScalar speedPerSec, SkScalar period = 0);
+    // gives a sinusoidal value between 0 and amplitude
+    static SkScalar GetAnimSinScalar(SkScalar amplitude,
+                                     SkScalar periodInSec,
+                                     SkScalar phaseInSec = 0);
 
     static GrContext* GetGr();
 };
index 703153bbb1bebe21b809ebaaa2717667fdde5dfe..5f9879e8ec3420bf5878de38b00d3beb472d8b79 100644 (file)
@@ -716,7 +716,12 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
 #include "SkMaskFilter.h"
 #include "SkBounder.h"
 
-static GrPathFill skToGrFillType(SkPath::FillType fillType) {
+///////////////////////////////////////////////////////////////////////////////
+
+// helpers for applying mask filters
+namespace {
+
+GrPathFill skToGrFillType(SkPath::FillType fillType) {
     switch (fillType) {
         case SkPath::kWinding_FillType:
             return kWinding_PathFill;
@@ -732,10 +737,22 @@ static GrPathFill skToGrFillType(SkPath::FillType fillType) {
     }
 }
 
-static bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
-                                  SkMaskFilter* filter, const SkMatrix& matrix,
-                                  const SkRegion& clip, SkBounder* bounder,
-                                  GrPaint* grp) {
+// We prefer to blur small rect with small radius via CPU.
+#define MIN_GPU_BLUR_SIZE SkIntToScalar(64)
+#define MIN_GPU_BLUR_RADIUS SkIntToScalar(32)
+inline bool shouldDrawBlurWithCPU(const SkRect& rect, SkScalar radius) {
+    if (rect.width() <= MIN_GPU_BLUR_SIZE &&
+        rect.height() <= MIN_GPU_BLUR_SIZE &&
+        radius <= MIN_GPU_BLUR_RADIUS) {
+        return true;
+    }
+    return false;
+}
+
+bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
+                           SkMaskFilter* filter, const SkMatrix& matrix,
+                           const SkRegion& clip, SkBounder* bounder,
+                           GrPaint* grp) {
 #ifdef SK_DISABLE_GPU_BLUR
     return false;
 #endif
@@ -750,10 +767,15 @@ static bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
     if (radius <= 0) {
         return false;
     }
+
+    SkRect srcRect = path.getBounds();
+    if (shouldDrawBlurWithCPU(srcRect, radius)) {
+        return false;
+    }
+
     float sigma = SkScalarToFloat(radius) * BLUR_SIGMA_SCALE;
     float sigma3 = sigma * 3.0f;
 
-    SkRect srcRect = path.getBounds();
     SkRect clipRect;
     clipRect.set(clip.getBounds());
 
@@ -872,10 +894,10 @@ static bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
     return true;
 }
 
-static bool drawWithMaskFilter(GrContext* context, const SkPath& path,
-                               SkMaskFilter* filter, const SkMatrix& matrix,
-                               const SkRegion& clip, SkBounder* bounder,
-                               GrPaint* grp) {
+bool drawWithMaskFilter(GrContext* context, const SkPath& path,
+                        SkMaskFilter* filter, const SkMatrix& matrix,
+                        const SkRegion& clip, SkBounder* bounder,
+                        GrPaint* grp) {
     SkMask  srcM, dstM;
 
     if (!SkDraw::DrawToMask(path, &clip.getBounds(), filter, &matrix, &srcM,
@@ -946,6 +968,10 @@ static bool drawWithMaskFilter(GrContext* context, const SkPath& path,
     return true;
 }
 
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
                            const SkPaint& paint, const SkMatrix* prePathMatrix,
                            bool pathIsMutable) {