aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-28 14:44:37 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-28 14:44:37 +0000
commit8500322537c5158a4632be6805b0c4210a20558b (patch)
treef0a6cc831a5020c02fffff8fd78118d83f830fe1
parent3672b580a52bd2a9086fb84fd3fe4720c89445b6 (diff)
disable GPU blur on small paths
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
-rw-r--r--gyp/SampleApp.gyp1
-rw-r--r--samplecode/SampleAnimBlur.cpp70
-rw-r--r--samplecode/SampleApp.cpp12
-rw-r--r--samplecode/SampleCode.h4
-rw-r--r--src/gpu/SkGpuDevice.cpp46
5 files changed, 123 insertions, 10 deletions
diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp
index bdd46ed352..3d79c3d4b0 100644
--- a/gyp/SampleApp.gyp
+++ b/gyp/SampleApp.gyp
@@ -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
index 0000000000..74f8811ee2
--- /dev/null
+++ b/samplecode/SampleAnimBlur.cpp
@@ -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);
+
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index b2af16a8f6..ddd33ede32 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -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;
}
diff --git a/samplecode/SampleCode.h b/samplecode/SampleCode.h
index 197e0f1d5a..3d1f2665cb 100644
--- a/samplecode/SampleCode.h
+++ b/samplecode/SampleCode.h
@@ -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();
};
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 703153bbb1..5f9879e8ec 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -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) {