diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-03-28 14:44:37 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-03-28 14:44:37 +0000 |
commit | 8500322537c5158a4632be6805b0c4210a20558b (patch) | |
tree | f0a6cc831a5020c02fffff8fd78118d83f830fe1 | |
parent | 3672b580a52bd2a9086fb84fd3fe4720c89445b6 (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.gyp | 1 | ||||
-rw-r--r-- | samplecode/SampleAnimBlur.cpp | 70 | ||||
-rw-r--r-- | samplecode/SampleApp.cpp | 12 | ||||
-rw-r--r-- | samplecode/SampleCode.h | 4 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 46 |
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) { |