aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkMaskFilter.h3
-rw-r--r--include/effects/SkBlurMaskFilter.h10
-rw-r--r--src/core/SkMaskFilter.cpp2
-rw-r--r--src/effects/SkBlurMaskFilter.cpp163
-rw-r--r--src/effects/SkGpuBlurUtils.cpp7
-rw-r--r--src/effects/SkGpuBlurUtils.h4
-rw-r--r--src/gpu/SkGpuDevice.cpp2
-rw-r--r--src/gpu/SkGpuDevice_drawTexture.cpp2
-rw-r--r--tests/BlurTest.cpp62
9 files changed, 60 insertions, 195 deletions
diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h
index e30fc62548..908226c8ad 100644
--- a/include/core/SkMaskFilter.h
+++ b/include/core/SkMaskFilter.h
@@ -17,7 +17,6 @@
#include "SkStrokeRec.h"
class GrClip;
-class GrContext;
class GrDrawContext;
class GrPaint;
class GrRenderTarget;
@@ -123,7 +122,7 @@ public:
* Try to directly render a rounded rect mask filter into the target. Returns
* true if drawing was successful.
*/
- virtual bool directFilterRRectMaskGPU(GrContext*,
+ virtual bool directFilterRRectMaskGPU(GrTextureProvider* texProvider,
GrDrawContext* drawContext,
GrPaint* grp,
const GrClip&,
diff --git a/include/effects/SkBlurMaskFilter.h b/include/effects/SkBlurMaskFilter.h
index 4b037e70cd..3ba91774f0 100644
--- a/include/effects/SkBlurMaskFilter.h
+++ b/include/effects/SkBlurMaskFilter.h
@@ -65,16 +65,6 @@ public:
SkScalar blurRadius);
#endif
- static bool ComputeBlurredRRectParams(const SkRRect& rrect,
- SkScalar sigma,
- SkRRect* rrectToDraw,
- SkISize* widthHeight,
- SkScalar xs[4],
- int* numXs,
- SkScalar ys[4],
- int* numYs);
-
-
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
private:
diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp
index 352cf71db9..fccce45a77 100644
--- a/src/core/SkMaskFilter.cpp
+++ b/src/core/SkMaskFilter.cpp
@@ -324,7 +324,7 @@ bool SkMaskFilter::canFilterMaskGPU(const SkRRect& devRRect,
}
-bool SkMaskFilter::directFilterRRectMaskGPU(GrContext*,
+bool SkMaskFilter::directFilterRRectMaskGPU(GrTextureProvider* texProvider,
GrDrawContext* drawContext,
GrPaint* grp,
const GrClip&,
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 31433dd2ec..4215733492 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -22,7 +22,7 @@
#include "GrTexture.h"
#include "GrFragmentProcessor.h"
#include "GrInvariantOutput.h"
-#include "GrStyle.h"
+#include "SkDraw.h"
#include "effects/GrSimpleTextureEffect.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
@@ -56,7 +56,7 @@ public:
const SkMatrix& viewMatrix,
const SkStrokeRec& strokeRec,
const SkPath& path) const override;
- bool directFilterRRectMaskGPU(GrContext*,
+ bool directFilterRRectMaskGPU(GrTextureProvider* texProvider,
GrDrawContext* drawContext,
GrPaint* grp,
const GrClip&,
@@ -910,7 +910,7 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrTextureProvider* texProvider,
class GrRRectBlurEffect : public GrFragmentProcessor {
public:
- static sk_sp<GrFragmentProcessor> Make(GrContext*, float sigma, const SkRRect&);
+ static sk_sp<GrFragmentProcessor> Make(GrTextureProvider*, float sigma, const SkRRect&);
virtual ~GrRRectBlurEffect() {};
const char* name() const override { return "GrRRectBlur"; }
@@ -939,110 +939,13 @@ private:
typedef GrFragmentProcessor INHERITED;
};
-bool SkBlurMaskFilter::ComputeBlurredRRectParams(const SkRRect& rrect,
- SkScalar sigma,
- SkRRect* rrectToDraw,
- SkISize* widthHeight,
- SkScalar xs[4],
- int* numXs,
- SkScalar ys[4],
- int* numYs) {
- unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f);
-
- const SkRect& orig = rrect.getBounds();
- const SkVector& radiiUL = rrect.radii(SkRRect::kUpperLeft_Corner);
- const SkVector& radiiUR = rrect.radii(SkRRect::kUpperRight_Corner);
- const SkVector& radiiLR = rrect.radii(SkRRect::kLowerRight_Corner);
- const SkVector& radiiLL = rrect.radii(SkRRect::kLowerLeft_Corner);
-
- const int left = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUL.fX, radiiLL.fX));
- const int top = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUL.fY, radiiUR.fY));
- const int right = SkScalarCeilToInt(SkTMax<SkScalar>(radiiUR.fX, radiiLR.fX));
- const int bot = SkScalarCeilToInt(SkTMax<SkScalar>(radiiLL.fY, radiiLR.fY));
-
- // This is a conservative check for nine-patchability
- if (orig.fLeft + left + blurRadius >= orig.fRight - right - blurRadius ||
- orig.fTop + top + blurRadius >= orig.fBottom - bot - blurRadius) {
- return false;
- }
- int newRRWidth, newRRHeight;
-
- // 3x3 case
- newRRWidth = 2*blurRadius + left + right + 1;
- newRRHeight = 2*blurRadius + top + bot + 1;
- widthHeight->fWidth = newRRWidth + 2 * blurRadius;
- widthHeight->fHeight = newRRHeight + 2 * blurRadius;
- // TODO: need to return non-normalized indices
- xs[0] = 0.0f;
- xs[1] = (blurRadius + left) / (float) widthHeight->fWidth;
- xs[2] = (blurRadius + left + 1.0f) / widthHeight->fWidth;
- xs[3] = 1.0f;
- *numXs = 4;
- ys[0] = 0.0f;
- ys[1] = (blurRadius + top) / (float) widthHeight->fHeight;
- ys[2] = (blurRadius + top + 1.0f) / widthHeight->fHeight;
- ys[3] = 1.0f;
- *numYs = 4;
-
- const SkRect newRect = SkRect::MakeXYWH(SkIntToScalar(blurRadius), SkIntToScalar(blurRadius),
- SkIntToScalar(newRRWidth), SkIntToScalar(newRRHeight));
- SkVector newRadii[4];
- newRadii[0] = { SkScalarCeilToScalar(radiiUL.fX), SkScalarCeilToScalar(radiiUL.fY) };
- newRadii[1] = { SkScalarCeilToScalar(radiiUR.fX), SkScalarCeilToScalar(radiiUR.fY) };
- newRadii[2] = { SkScalarCeilToScalar(radiiLR.fX), SkScalarCeilToScalar(radiiLR.fY) };
- newRadii[3] = { SkScalarCeilToScalar(radiiLL.fX), SkScalarCeilToScalar(radiiLL.fY) };
-
- rrectToDraw->setRectRadii(newRect, newRadii);
- return true;
-}
-
-static sk_sp<GrTexture> make_rrect_blur_mask(GrContext* context,
- const SkRRect& rrect,
- float sigma) {
- SkRRect rrectToDraw;
- SkISize size;
- SkScalar xs[4], ys[4];
- int numXs, numYs;
-
- SkBlurMaskFilter::ComputeBlurredRRectParams(rrect, sigma, &rrectToDraw, &size,
- xs, &numXs, ys, &numYs);
-
- // TODO: this could be approx but the texture coords will need to be updated
- sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kExact,
- size.fWidth, size.fHeight,
- kAlpha_8_GrPixelConfig, nullptr));
- if (!dc) {
- return nullptr;
- }
-
- GrPaint grPaint;
-
- dc->clear(nullptr, SK_ColorTRANSPARENT, true);
- dc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle::SimpleFill());
-
- sk_sp<GrDrawContext> dc2(SkGpuBlurUtils::GaussianBlur(context,
- dc->asTexture().release(),
- nullptr,
- SkIRect::MakeWH(size.fWidth,
- size.fHeight),
- nullptr,
- sigma, sigma, SkBackingFit::kExact));
- if (!dc2) {
- return nullptr;
- }
-
- return dc2->asTexture();
-}
-
-sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, float sigma,
- const SkRRect& rrect) {
+sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrTextureProvider* texProvider, float sigma,
+ const SkRRect& rrect) {
if (rrect.isCircle()) {
- return GrCircleBlurFragmentProcessor::Make(context->textureProvider(),
- rrect.rect(), sigma);
+ return GrCircleBlurFragmentProcessor::Make(texProvider, rrect.rect(), sigma);
}
- // TODO: loosen this up
if (!rrect.isSimpleCircular()) {
return nullptr;
}
@@ -1065,17 +968,55 @@ sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, float sig
builder[1] = cornerRadius;
builder.finish();
- sk_sp<GrTexture> blurNinePatchTexture(
- context->textureProvider()->findAndRefTextureByUniqueKey(key));
+ SkAutoTUnref<GrTexture> blurNinePatchTexture(texProvider->findAndRefTextureByUniqueKey(key));
if (!blurNinePatchTexture) {
- blurNinePatchTexture = make_rrect_blur_mask(context, rrect, sigma);
+ SkMask mask;
+
+ unsigned int smallRectSide = 2*(blurRadius + cornerRadius) + 1;
+
+ mask.fBounds = SkIRect::MakeWH(smallRectSide, smallRectSide);
+ mask.fFormat = SkMask::kA8_Format;
+ mask.fRowBytes = mask.fBounds.width();
+ mask.fImage = SkMask::AllocImage(mask.computeTotalImageSize());
+ SkAutoMaskFreeImage amfi(mask.fImage);
+
+ memset(mask.fImage, 0, mask.computeTotalImageSize());
+
+ SkRect smallRect;
+ smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSide));
+
+ SkRRect smallRRect;
+ smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScalar(cornerRadius));
+
+ SkPath path;
+ path.addRRect(smallRRect);
+
+ SkDraw::DrawToMask(path, &mask.fBounds, nullptr, nullptr, &mask,
+ SkMask::kJustRenderImage_CreateMode, SkStrokeRec::kFill_InitStyle);
+
+ SkMask blurredMask;
+ if (!SkBlurMask::BoxBlur(&blurredMask, mask, sigma, kNormal_SkBlurStyle,
+ kHigh_SkBlurQuality, nullptr, true)) {
+ return nullptr;
+ }
+
+ unsigned int texSide = smallRectSide + 2*blurRadius;
+ GrSurfaceDesc texDesc;
+ texDesc.fWidth = texSide;
+ texDesc.fHeight = texSide;
+ texDesc.fConfig = kAlpha_8_GrPixelConfig;
+ texDesc.fIsMipMapped = false;
+
+ blurNinePatchTexture.reset(
+ texProvider->createTexture(texDesc, SkBudgeted::kYes , blurredMask.fImage, 0));
+ SkMask::FreeImage(blurredMask.fImage);
if (!blurNinePatchTexture) {
return nullptr;
}
- context->textureProvider()->assignUniqueKeyToTexture(key, blurNinePatchTexture.get());
+ texProvider->assignUniqueKeyToTexture(key, blurNinePatchTexture);
}
- return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture.get()));
+ return sk_sp<GrFragmentProcessor>(new GrRRectBlurEffect(sigma, rrect, blurNinePatchTexture));
}
void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
@@ -1109,7 +1050,7 @@ sk_sp<GrFragmentProcessor> GrRRectBlurEffect::TestCreate(GrProcessorTestData* d)
SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f);
SkRRect rrect;
rrect.setRectXY(SkRect::MakeWH(w, h), r, r);
- return GrRRectBlurEffect::Make(d->fContext, sigma, rrect);
+ return GrRRectBlurEffect::Make(d->fContext->textureProvider(), sigma, rrect);
}
//////////////////////////////////////////////////////////////////////////////
@@ -1212,7 +1153,7 @@ GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const {
return new GrGLRRectBlurEffect;
}
-bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
+bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrTextureProvider* texProvider,
GrDrawContext* drawContext,
GrPaint* grp,
const GrClip& clip,
@@ -1231,7 +1172,7 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
- sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(context, xformedSigma, rrect));
+ sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(texProvider, xformedSigma, rrect));
if (!fp) {
return false;
}
diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp
index ebb480d3df..869cd76c5b 100644
--- a/src/effects/SkGpuBlurUtils.cpp
+++ b/src/effects/SkGpuBlurUtils.cpp
@@ -186,8 +186,7 @@ sk_sp<GrDrawContext> GaussianBlur(GrContext* context,
const SkIRect& dstBounds,
const SkIRect* srcBounds,
float sigmaX,
- float sigmaY,
- SkBackingFit fit) {
+ float sigmaY) {
SkASSERT(context);
SkIRect clearRect;
int scaleFactorX, radiusX;
@@ -227,7 +226,7 @@ sk_sp<GrDrawContext> GaussianBlur(GrContext* context,
const int height = dstBounds.height();
const GrPixelConfig config = srcTexture->config();
- sk_sp<GrDrawContext> dstDrawContext(context->makeDrawContext(fit,
+ sk_sp<GrDrawContext> dstDrawContext(context->makeDrawContext(SkBackingFit::kApprox,
width, height, config, colorSpace,
0, kDefault_GrSurfaceOrigin));
if (!dstDrawContext) {
@@ -247,7 +246,7 @@ sk_sp<GrDrawContext> GaussianBlur(GrContext* context,
return dstDrawContext;
}
- sk_sp<GrDrawContext> tmpDrawContext(context->makeDrawContext(fit,
+ sk_sp<GrDrawContext> tmpDrawContext(context->makeDrawContext(SkBackingFit::kApprox,
width, height, config, colorSpace,
0, kDefault_GrSurfaceOrigin));
if (!tmpDrawContext) {
diff --git a/src/effects/SkGpuBlurUtils.h b/src/effects/SkGpuBlurUtils.h
index a12a08873c..a5de6a242a 100644
--- a/src/effects/SkGpuBlurUtils.h
+++ b/src/effects/SkGpuBlurUtils.h
@@ -29,7 +29,6 @@ namespace SkGpuBlurUtils {
* no pixels will be sampled outside of this rectangle.
* @param sigmaX The blur's standard deviation in X.
* @param sigmaY The blur's standard deviation in Y.
- * @param fit backing fit for the returned draw context
* @return The drawContext containing the blurred result.
*/
sk_sp<GrDrawContext> GaussianBlur(GrContext* context,
@@ -38,8 +37,7 @@ namespace SkGpuBlurUtils {
const SkIRect& dstBounds,
const SkIRect* srcBounds,
float sigmaX,
- float sigmaY,
- SkBackingFit fit = SkBackingFit::kApprox);
+ float sigmaY);
};
#endif
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index fb513f4483..cd34b1feba 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -436,7 +436,7 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect,
// clipped out
return;
}
- if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext,
+ if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext->textureProvider(),
fDrawContext.get(),
&grPaint,
fClip,
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index e141cc2d62..2843c31996 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -226,7 +226,7 @@ void SkGpuDevice::drawTextureProducerImpl(GrTextureProducer* producer,
// First see if we can do the draw + mask filter direct to the dst.
SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
- if (mf->directFilterRRectMaskGPU(fContext,
+ if (mf->directFilterRRectMaskGPU(fContext->textureProvider(),
fDrawContext.get(),
&grPaint,
clip,
diff --git a/tests/BlurTest.cpp b/tests/BlurTest.cpp
index 32e2930171..6ccb0471aa 100644
--- a/tests/BlurTest.cpp
+++ b/tests/BlurTest.cpp
@@ -574,66 +574,4 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SmallBoxBlurBug, reporter, ctxInfo) {
#endif
-
-DEF_TEST(BlurredRRectNinePatchComputation, reporter) {
- const SkRect r = SkRect::MakeXYWH(10, 10, 100, 100);
-
- bool ninePatchable;
- SkRRect rrectToDraw;
- SkISize size;
- SkScalar xs[4], ys[4];
- int numXs, numYs;
-
- // not nine-patchable
- {
- SkVector radii[4] = { { 100, 100 }, { 0, 0 }, { 100, 100 }, { 0, 0 } };
-
- SkRRect rr;
- rr.setRectRadii(r, radii);
-
- ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(rr, 3.0f, &rrectToDraw, &size,
- xs, &numXs, ys, &numYs);
- REPORTER_ASSERT(reporter, !ninePatchable);
- }
-
- // simple circular
- {
- SkRRect rr;
- rr.setRectXY(r, 10, 10);
-
- ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(rr, 3.0f, &rrectToDraw, &size,
- xs, &numXs, ys, &numYs);
- REPORTER_ASSERT(reporter, ninePatchable);
- REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fWidth), 57.0f));
- REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fHeight), 57.0));
- REPORTER_ASSERT(reporter, 4 == numXs && 4 == numYs);
- for (int i = 0; i < numXs; ++i) {
- REPORTER_ASSERT(reporter, xs[i] >= 0.0f && xs[i] <= 1.0f);
- }
- for (int i = 0; i < numYs; ++i) {
- REPORTER_ASSERT(reporter, ys[i] >= 0.0f && ys[i] <= 1.0f);
- }
- }
-
- // simple elliptical
- {
- SkRRect rr;
- rr.setRectXY(r, 2, 10);
-
- ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams(rr, 3.0f, &rrectToDraw, &size,
- xs, &numXs, ys, &numYs);
- REPORTER_ASSERT(reporter, ninePatchable);
- REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fWidth), 41.0f));
- REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fHeight), 57.0));
- REPORTER_ASSERT(reporter, 4 == numXs && 4 == numYs);
- for (int i = 0; i < numXs; ++i) {
- REPORTER_ASSERT(reporter, xs[i] >= 0.0f && xs[i] <= 1.0f);
- }
- for (int i = 0; i < numYs; ++i) {
- REPORTER_ASSERT(reporter, ys[i] >= 0.0f && ys[i] <= 1.0f);
- }
- }
-
-}
-
///////////////////////////////////////////////////////////////////////////////////////////