aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2016-08-10 08:40:35 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-10 08:40:35 -0700
commit3f0e6945f89036068fc3cb36f4ac9e9e0631d245 (patch)
tree99a4a304bd3dfa28f6cd27f6de9c87251527738a /src/effects
parent3ff2cc81a58b3fe5287980cf618147c84a6c81f6 (diff)
Revert of Create blurred RRect mask on GPU (rather than uploading it) (patchset #5 id:80001 of https://codereview.chromium.org/2222083004/ )
Reason for revert: No NoGPU bot on commit queue ? Original issue's description: > Create blurred RRect mask on GPU (rather than uploading it) > > This CL doesn't try to resolve any of the larger issues. It just moves the computation of the blurred RRect to the gpu and sets up to start using vertex attributes for a nine patch draw (i.e., returning the texture coordinates) > > All blurred rrects using the "analytic" path will change slightly with this CL. > > GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2222083004 > > Committed: https://skia.googlesource.com/skia/+/75ccdc77a70ec2083141bf9ba98eb2f01ece2479 > Committed: https://skia.googlesource.com/skia/+/94b5c5a41160e0f55e267fc3d830df65736fac50 TBR=bsalomon@google.com # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Review-Url: https://codereview.chromium.org/2232953002
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/SkBlurMaskFilter.cpp163
-rw-r--r--src/effects/SkGpuBlurUtils.cpp7
-rw-r--r--src/effects/SkGpuBlurUtils.h4
3 files changed, 56 insertions, 118 deletions
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