diff options
-rw-r--r-- | src/effects/shadows/SkAmbientShadowMaskFilter.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.h | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrShadowGeoProc.cpp | 6 | ||||
-rw-r--r-- | src/gpu/ops/GrShadowRRectOp.cpp | 47 | ||||
-rw-r--r-- | src/gpu/ops/GrShadowRRectOp.h | 3 |
6 files changed, 58 insertions, 14 deletions
diff --git a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp index 34168357ac..66218cd96f 100644 --- a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp +++ b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp @@ -221,8 +221,12 @@ bool SkAmbientShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*, devSpaceInsetWidth = ambientRRect.width(); } + // the fraction of the blur we want to apply is devSpaceInsetWidth/devSpaceAmbientBlur, + // which is just 1/umbraAlpha. + SkScalar blurClamp = SkScalarInvert(umbraAlpha); rtContext->drawShadowRRect(clip, std::move(newPaint), viewMatrix, ambientRRect, - devSpaceAmbientBlur, devSpaceInsetWidth); + devSpaceAmbientBlur, devSpaceInsetWidth, + blurClamp); return true; } diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 12ddb96450..56e2c2f937 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -986,7 +986,8 @@ void GrRenderTargetContext::drawShadowRRect(const GrClip& clip, const SkMatrix& viewMatrix, const SkRRect& rrect, SkScalar blurWidth, - SkScalar insetWidth) { + SkScalar insetWidth, + SkScalar blurClamp) { ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED SkDEBUGCODE(this->validate();) @@ -999,7 +1000,8 @@ void GrRenderTargetContext::drawShadowRRect(const GrClip& clip, // TODO: add instancing support? std::unique_ptr<GrLegacyMeshDrawOp> op = GrShadowRRectOp::Make(paint.getColor(), viewMatrix, - rrect, blurWidth, insetWidth); + rrect, blurWidth, insetWidth, + blurClamp); if (op) { GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone); this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index b3ff137919..5aef96a65b 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -161,13 +161,15 @@ public: * @param blurWidth amount of shadow blur to apply (in device space) * @param insetWidth minimum amount to inset from the rrect edge (in local space). * We may inset more depending on the blur radius and geometry. + * @param blurClamp Optional parameter used to indicate fraction of blur to actually apply */ void drawShadowRRect(const GrClip&, GrPaint&&, const SkMatrix& viewMatrix, const SkRRect& rrect, SkScalar blurRadius, - SkScalar insetWidth); + SkScalar insetWidth, + SkScalar blurClamp = 1); /** * Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp index 4e33e4ba39..5ff7ec1caf 100644 --- a/src/gpu/effects/GrShadowGeoProc.cpp +++ b/src/gpu/effects/GrShadowGeoProc.cpp @@ -26,7 +26,7 @@ public: // emit attributes varyingHandler->emitAttributes(rsgp); - fragBuilder->codeAppend("vec3 shadowParams;"); + fragBuilder->codeAppend("vec4 shadowParams;"); varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams"); // setup pass through color @@ -47,7 +47,7 @@ public: fragBuilder->codeAppend("float d = length(shadowParams.xy);"); fragBuilder->codeAppend("float distance = shadowParams.z * (1.0 - d);"); - fragBuilder->codeAppend("float factor = 1.0 - clamp(distance, 0.0, 1.0);"); + fragBuilder->codeAppend("float factor = 1.0 - clamp(distance, 0.0, shadowParams.w);"); fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;"); fragBuilder->codeAppendf("%s = vec4(factor);", args.fOutputCoverage); @@ -81,7 +81,7 @@ GrRRectShadowGeoProc::GrRRectShadowGeoProc(const SkMatrix& localMatrix) fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision); fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType); - fInShadowParams = &this->addVertexAttrib("inShadowParams", kVec3f_GrVertexAttribType); + fInShadowParams = &this->addVertexAttrib("inShadowParams", kVec4f_GrVertexAttribType); } void GrRRectShadowGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps, diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp index 77cd5ef297..43c8839c5a 100644 --- a/src/gpu/ops/GrShadowRRectOp.cpp +++ b/src/gpu/ops/GrShadowRRectOp.cpp @@ -190,7 +190,8 @@ public: // An insetWidth > 1/2 rect width or height indicates a simple fill. ShadowCircularRRectOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& devRect, - float devRadius, bool isCircle, float blurRadius, float insetWidth) + float devRadius, bool isCircle, float blurRadius, float insetWidth, + float blurClamp) : INHERITED(ClassID()), fViewMatrixIfUsingLocalCoords(viewMatrix) { SkRect bounds = devRect; SkASSERT(insetWidth > 0); @@ -226,7 +227,7 @@ public: this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); fGeoData.emplace_back(Geometry{color, outerRadius, umbraInset, innerRadius, - blurRadius, bounds, type, isCircle}); + blurRadius, blurClamp, bounds, type, isCircle}); if (isCircle) { fVertCount = circle_type_to_vert_count(kStroke_RRectType == type); fIndexCount = circle_type_to_index_count(kStroke_RRectType == type); @@ -274,6 +275,7 @@ private: SkScalar fUmbraInset; SkScalar fInnerRadius; SkScalar fBlurRadius; + SkScalar fClampValue; SkRect fDevBounds; RRectType fType; bool fIsCircle; @@ -284,6 +286,7 @@ private: GrColor fColor; SkPoint fOffset; SkScalar fDistanceCorrection; + SkScalar fClampValue; }; void fillInCircleVerts(const Geometry& args, bool isStroked, CircleVertex** verts) const { @@ -293,6 +296,7 @@ private: SkScalar innerRadius = args.fInnerRadius; SkScalar blurRadius = args.fBlurRadius; SkScalar distanceCorrection = outerRadius / blurRadius; + SkScalar clampValue = args.fClampValue; const SkRect& bounds = args.fDevBounds; @@ -307,48 +311,56 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(-octOffset, -1); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, -halfWidth); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(octOffset, -1); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(halfWidth, -octOffset * halfWidth); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(1, -octOffset); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(halfWidth, octOffset * halfWidth); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(1, octOffset); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, halfWidth); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(octOffset, 1); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(-octOffset * halfWidth, halfWidth); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(-octOffset, 1); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(-halfWidth, octOffset * halfWidth); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(-1, octOffset); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(-halfWidth, -octOffset * halfWidth); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(-1, -octOffset); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; if (isStroked) { @@ -363,48 +375,56 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(-s * innerRadius, -c * innerRadius); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(s * r, -c * r); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(s * innerRadius, -c * innerRadius); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(c * r, -s * r); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(c * innerRadius, -s * innerRadius); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(c * r, s * r); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(c * innerRadius, s * innerRadius); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(s * r, c * r); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(s * innerRadius, c * innerRadius); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(-s * r, c * r); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(-s * innerRadius, c * innerRadius); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(-c * r, s * r); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(-c * innerRadius, s * innerRadius); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = center + SkPoint::Make(-c * r, -s * r); (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(-c * innerRadius, -s * innerRadius); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; } else { // filled @@ -412,6 +432,7 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(0, 0); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; } } @@ -454,6 +475,7 @@ private: outerVec.fX + outerVec.fY); diagVec *= umbraInset / (2 * umbraInset - outerRadius); SkScalar distanceCorrection = umbraInset / blurRadius; + SkScalar clampValue = args.fClampValue; // build corner by corner for (int i = 0; i < 4; ++i) { @@ -462,6 +484,7 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkVector::Make(0, 0); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; // outer points @@ -469,30 +492,35 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkVector::Make(0, -1); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = SkPoint::Make(xOuter[i], yMid[i]); (*verts)->fColor = color; (*verts)->fOffset = outerVec; (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = SkPoint::Make(xOuter[i], yOuter[i]); (*verts)->fColor = color; (*verts)->fOffset = diagVec; (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = SkPoint::Make(xMid[i], yOuter[i]); (*verts)->fColor = color; (*verts)->fOffset = outerVec; (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; (*verts)->fPos = SkPoint::Make(xInner[i], yOuter[i]); (*verts)->fColor = color; (*verts)->fOffset = SkVector::Make(0, -1); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; } @@ -510,6 +538,7 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(0, 0); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; // TR @@ -517,6 +546,7 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(0, 0); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; // BL @@ -524,6 +554,7 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(0, 0); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; // BR @@ -531,6 +562,7 @@ private: (*verts)->fColor = color; (*verts)->fOffset = SkPoint::Make(0, 0); (*verts)->fDistanceCorrection = distanceCorrection; + (*verts)->fClampValue = clampValue; (*verts)++; } @@ -640,7 +672,8 @@ std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, const SkRRect& rrect, SkScalar blurWidth, - SkScalar insetWidth) { + SkScalar insetWidth, + SkScalar blurClamp) { // Shadow rrect ops only handle simple circular rrects. SkASSERT(viewMatrix.isSimilarity() && (rrect.isSimpleCircular() || rrect.isRect() || rrect.isCircle())); @@ -660,7 +693,8 @@ std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, scaledRadius, rrect.isOval(), blurWidth, - scaledInsetWidth)); + scaledInsetWidth, + blurClamp)); } } @@ -681,14 +715,15 @@ DRAW_OP_TEST_DEFINE(ShadowRRectOp) { GrColor color = GrRandomColor(random); SkScalar insetWidth = random->nextSScalar1() * 72.f; SkScalar blurWidth = random->nextSScalar1() * 72.f; + SkScalar blurClamp = random->nextSScalar1(); bool isCircle = random->nextBool(); if (isCircle) { SkRect circle = GrTest::TestSquare(random); SkRRect rrect = SkRRect::MakeOval(circle); - return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth); + return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth, blurClamp); } else { const SkRRect& rrect = GrTest::TestRRectSimple(random); - return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth); + return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth, blurClamp); } } diff --git a/src/gpu/ops/GrShadowRRectOp.h b/src/gpu/ops/GrShadowRRectOp.h index f9727883e8..126009558e 100644 --- a/src/gpu/ops/GrShadowRRectOp.h +++ b/src/gpu/ops/GrShadowRRectOp.h @@ -20,7 +20,8 @@ class SkStrokeRec; namespace GrShadowRRectOp { std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor, const SkMatrix& viewMatrix, const SkRRect& rrect, - SkScalar blurWidth, SkScalar insetWidth); + SkScalar blurWidth, SkScalar insetWidth, + SkScalar blurClamp = 1); } #endif |