Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Unified Diff: src/effects/SkBlurMaskFilter.cpp

Issue 2201133002: Implement GPU occluded blur mask filter (Closed) Base URL: https://skia.googlesource.com/skia.git@occluded-blur
Patch Set: update to ToT Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkMaskFilter.cpp ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/SkBlurMaskFilter.cpp
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 421573349260ac7d03c2d09a768dd15502fdd371..1c8ca52071e4680d2a648f88690fa0e07a0068d8 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -37,7 +37,7 @@ SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) {
class SkBlurMaskFilterImpl : public SkMaskFilter {
public:
- SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, uint32_t flags);
+ SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, const SkRect& occluder, uint32_t flags);
// overrides from SkMaskFilter
SkMask::Format getFormat() const override;
@@ -62,7 +62,8 @@ public:
const GrClip&,
const SkMatrix& viewMatrix,
const SkStrokeRec& strokeRec,
- const SkRRect& rrect) const override;
+ const SkRRect& rrect,
+ const SkRRect& devRRect) const override;
bool filterMaskGPU(GrTexture* src,
const SkMatrix& ctm,
const SkIRect& maskRect,
@@ -99,8 +100,12 @@ private:
// a request like 10,000)
static const SkScalar kMAX_BLUR_SIGMA;
+ // This flag should never escape from serialization
+ static const int kInternalFlag_HasOccluder = 0x08;
+
SkScalar fSigma;
SkBlurStyle fBlurStyle;
+ SkRect fOccluder;
uint32_t fBlurFlags;
SkBlurQuality getQuality() const {
@@ -123,7 +128,8 @@ private:
const SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128);
-sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma, uint32_t flags) {
+sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma,
+ const SkRect& occluder, uint32_t flags) {
if (!SkScalarIsFinite(sigma) || sigma <= 0) {
return nullptr;
}
@@ -133,17 +139,20 @@ sk_sp<SkMaskFilter> SkBlurMaskFilter::Make(SkBlurStyle style, SkScalar sigma, ui
SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
flags &= SkBlurMaskFilter::kAll_BlurFlag;
- return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, flags));
+ return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, occluder, flags));
}
///////////////////////////////////////////////////////////////////////////////
-SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, uint32_t flags)
+SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style,
+ const SkRect& occluder, uint32_t flags)
: fSigma(sigma)
, fBlurStyle(style)
+ , fOccluder(occluder)
, fBlurFlags(flags) {
SkASSERT(fSigma > 0);
SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle);
+ fOccluder.sort();
reed1 2016/08/09 14:04:54 Lets do this (or reject it) in the factory, rather
robertphillips 2016/08/09 14:46:35 Done. If the user passes in an inverted rect it wi
SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
}
@@ -587,8 +596,17 @@ sk_sp<SkFlattenable> SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
const SkScalar sigma = buffer.readScalar();
const unsigned style = buffer.readUInt();
const unsigned flags = buffer.readUInt();
+
+ SkRect occluder;
+ if (flags & kInternalFlag_HasOccluder) {
+ buffer.readRect(&occluder);
+ } else {
+ occluder.setEmpty();
+ }
+
if (style <= kLastEnum_SkBlurStyle) {
- return SkBlurMaskFilter::Make((SkBlurStyle)style, sigma, flags);
+ return SkBlurMaskFilter::Make((SkBlurStyle)style, sigma, occluder,
+ flags & ~kInternalFlag_HasOccluder);
}
return nullptr;
}
@@ -596,7 +614,11 @@ sk_sp<SkFlattenable> SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
buffer.writeScalar(fSigma);
buffer.writeUInt(fBlurStyle);
- buffer.writeUInt(fBlurFlags);
+
+ SkASSERT(!(fBlurFlags & kInternalFlag_HasOccluder));
+ buffer.writeUInt(fBlurFlags | kInternalFlag_HasOccluder);
+
+ buffer.writeRect(fOccluder);
}
#if SK_SUPPORT_GPU
@@ -1153,13 +1175,21 @@ GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const {
return new GrGLRRectBlurEffect;
}
+static void to_points(const SkRect& r, SkPoint* points) {
bsalomon 2016/08/09 14:05:56 SkRect::toQuad?
robertphillips 2016/08/09 14:46:35 Done.
+ points[0] = SkPoint::Make(r.fLeft, r.fTop);
+ points[1] = SkPoint::Make(r.fRight, r.fTop);
+ points[2] = SkPoint::Make(r.fRight, r.fBottom);
+ points[3] = SkPoint::Make(r.fLeft, r.fBottom);
+}
+
bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrTextureProvider* texProvider,
GrDrawContext* drawContext,
GrPaint* grp,
const GrClip& clip,
const SkMatrix& viewMatrix,
const SkStrokeRec& strokeRec,
- const SkRRect& rrect) const {
+ const SkRRect& srcRRect,
+ const SkRRect& devRRect) const {
SkASSERT(drawContext);
if (fBlurStyle != kNormal_SkBlurStyle) {
@@ -1172,7 +1202,7 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrTextureProvider* texProvid
SkScalar xformedSigma = this->computeXformedSigma(viewMatrix);
- sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(texProvider, xformedSigma, rrect));
+ sk_sp<GrFragmentProcessor> fp(GrRRectBlurEffect::Make(texProvider, xformedSigma, devRRect));
if (!fp) {
return false;
}
@@ -1184,12 +1214,49 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrTextureProvider* texProvid
return false;
}
- float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
+ if (!this->ignoreXform()) {
+ SkRect srcProxyRect = srcRRect.rect();
+ srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
+
+ SkPoint points[8];
+ uint16_t indices[24];
+ int numPoints, numIndices;
+
+ SkRect temp = fOccluder;
- SkRect proxyRect = rrect.rect();
- proxyRect.outset(extra, extra);
+ if (!temp.isEmpty() && (srcProxyRect.contains(temp) || temp.intersect(srcProxyRect))) {
+ to_points(srcProxyRect, &points[0]);
+ to_points(temp, &points[4]);
+ numPoints = 8;
+
+ static const uint16_t ringI[24] = { 0, 1, 5, 5, 4, 0,
+ 1, 2, 6, 6, 5, 1,
+ 2, 3, 7, 7, 6, 2,
+ 3, 0, 4, 4, 7, 3 };
+ memcpy(indices, ringI, sizeof(ringI));
+ numIndices = 24;
+ } else {
+ // full rect case
+ to_points(srcProxyRect, &points[0]);
+ numPoints = 4;
+
+ static const uint16_t fullI[6] = { 0, 1, 2, 0, 2, 3 };
+ memcpy(indices, fullI, sizeof(fullI));
+ numIndices = 6;
+ }
+
+ drawContext->drawVertices(clip, *grp, viewMatrix, kTriangles_GrPrimitiveType,
+ numPoints, points, nullptr, nullptr, indices, numIndices);
+
+ } else {
+ float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
+ SkRect proxyRect = devRRect.rect();
+ proxyRect.outset(extra, extra);
+
+
+ drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), proxyRect, inverse);
+ }
- drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), proxyRect, inverse);
return true;
}
@@ -1207,7 +1274,8 @@ bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64);
static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32);
- if (devRRect.width() <= kMIN_GPU_BLUR_SIZE &&
+ if (!devRRect.allCornersCircular() &&
+ devRRect.width() <= kMIN_GPU_BLUR_SIZE &&
devRRect.height() <= kMIN_GPU_BLUR_SIZE &&
xformedSigma <= kMIN_GPU_BLUR_SIGMA) {
// We prefer to blur small rects with small radii on the CPU.
@@ -1304,9 +1372,7 @@ void SkBlurMaskFilterImpl::toString(SkString* str) const {
str->append("flags: (");
if (fBlurFlags) {
bool needSeparator = false;
- SkAddFlagToString(str,
- SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag),
- "IgnoreXform", &needSeparator);
+ SkAddFlagToString(str, this->ignoreXform(), "IgnoreXform", &needSeparator);
SkAddFlagToString(str,
SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag),
"HighQuality", &needSeparator);
« no previous file with comments | « src/core/SkMaskFilter.cpp ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698