Perform bounding rect-relative calcs in full float in GrRRectBlurEffect
Add GM that tests very wide/tall SkRRects with blurs Bug: chromium:1138810 Change-Id: Ib5a2e04de50c441f57f5e4b6194c3f9829323dc9 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328383 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
e16eca95f5
commit
f4594d1d5b
@ -101,3 +101,21 @@ class SimpleBlurRoundRectGM : public skiagm::GM {
|
||||
//DEF_GM(return new BlurRoundRectGM(600, 5514, 6);)
|
||||
|
||||
DEF_GM(return new SimpleBlurRoundRectGM();)
|
||||
|
||||
// From crbug.com/1138810
|
||||
DEF_SIMPLE_GM(blur_large_rrects, canvas, 300, 300) {
|
||||
SkPaint paint;
|
||||
paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 20.f));
|
||||
|
||||
auto rect = SkRect::MakeLTRB(5.f, -20000.f, 240.f, 25.f);
|
||||
SkRRect rrect = SkRRect::MakeRectXY(rect, 40.f, 40.f);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
SkColor4f color{(i & 1) ? 1.f : 0.f,
|
||||
(i & 2) ? 1.f : 0.f,
|
||||
(i < 2) ? 1.f : 0.f,
|
||||
1.f};
|
||||
paint.setColor(color);
|
||||
canvas->drawRRect(rrect, paint);
|
||||
canvas->rotate(90.f, 150.f, 150.f);
|
||||
}
|
||||
}
|
||||
|
@ -373,37 +373,37 @@ uniform half blurRadius;
|
||||
void main() {
|
||||
// Warp the fragment position to the appropriate part of the 9-patch blur texture by snipping
|
||||
// out the middle section of the proxy rect.
|
||||
half2 translatedFragPos = half2(sk_FragCoord.xy - proxyRect.LT);
|
||||
half2 proxyCenter = half2((proxyRect.RB - proxyRect.LT) * 0.5);
|
||||
float2 translatedFragPosFloat = sk_FragCoord.xy - proxyRect.LT;
|
||||
float2 proxyCenter = (proxyRect.RB - proxyRect.LT) * 0.5;
|
||||
half edgeSize = 2.0 * blurRadius + cornerRadius + 0.5;
|
||||
|
||||
// Position the fragment so that (0, 0) marks the center of the proxy rectangle.
|
||||
// Negative coordinates are on the left/top side and positive numbers are on the right/bottom.
|
||||
translatedFragPos -= proxyCenter;
|
||||
translatedFragPosFloat -= proxyCenter;
|
||||
|
||||
// Temporarily strip off the fragment's sign. x/y are now strictly increasing as we move away
|
||||
// from the center.
|
||||
half2 fragDirection = sign(translatedFragPos);
|
||||
translatedFragPos = abs(translatedFragPos);
|
||||
half2 fragDirection = half2(sign(translatedFragPosFloat));
|
||||
translatedFragPosFloat = abs(translatedFragPosFloat);
|
||||
|
||||
// Our goal is to snip out the "middle section" of the proxy rect (everything but the edge).
|
||||
// We've repositioned our fragment position so that (0, 0) is the centerpoint and x/y are always
|
||||
// positive, so we can subtract here and interpret negative results as being within the middle
|
||||
// section.
|
||||
translatedFragPos -= proxyCenter - edgeSize;
|
||||
half2 translatedFragPosHalf = half2(translatedFragPosFloat - (proxyCenter - edgeSize));
|
||||
|
||||
// Remove the middle section by clamping to zero.
|
||||
translatedFragPos = max(translatedFragPos, 0);
|
||||
translatedFragPosHalf = max(translatedFragPosHalf, 0);
|
||||
|
||||
// Reapply the fragment's sign, so that negative coordinates once again mean left/top side and
|
||||
// positive means bottom/right side.
|
||||
translatedFragPos *= fragDirection;
|
||||
translatedFragPosHalf *= fragDirection;
|
||||
|
||||
// Offset the fragment so that (0, 0) marks the upper-left again, instead of the center point.
|
||||
translatedFragPos += half2(edgeSize);
|
||||
translatedFragPosHalf += half2(edgeSize);
|
||||
|
||||
half2 proxyDims = half2(2.0 * edgeSize);
|
||||
half2 texCoord = translatedFragPos / proxyDims;
|
||||
half2 texCoord = translatedFragPosHalf / proxyDims;
|
||||
|
||||
half4 inputColor = sample(inputFP);
|
||||
sk_OutColor = inputColor * sample(ninePatchFP, texCoord);
|
||||
|
@ -359,35 +359,35 @@ public:
|
||||
blurRadiusVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
|
||||
kHalf_GrSLType, "blurRadius");
|
||||
fragBuilder->codeAppendf(
|
||||
R"SkSL(half2 translatedFragPos = half2(sk_FragCoord.xy - %s.xy);
|
||||
half2 proxyCenter = half2((%s.zw - %s.xy) * 0.5);
|
||||
R"SkSL(float2 translatedFragPosFloat = sk_FragCoord.xy - %s.xy;
|
||||
float2 proxyCenter = (%s.zw - %s.xy) * 0.5;
|
||||
half edgeSize = (2.0 * %s + %s) + 0.5;
|
||||
translatedFragPos -= proxyCenter;
|
||||
half2 fragDirection = sign(translatedFragPos);
|
||||
translatedFragPos = abs(translatedFragPos);
|
||||
translatedFragPos -= proxyCenter - edgeSize;
|
||||
translatedFragPos = max(translatedFragPos, 0.0);
|
||||
translatedFragPos *= fragDirection;
|
||||
translatedFragPos += half2(edgeSize);
|
||||
translatedFragPosFloat -= proxyCenter;
|
||||
half2 fragDirection = half2(sign(translatedFragPosFloat));
|
||||
translatedFragPosFloat = abs(translatedFragPosFloat);
|
||||
half2 translatedFragPosHalf = half2(translatedFragPosFloat - (proxyCenter - float(edgeSize)));
|
||||
translatedFragPosHalf = max(translatedFragPosHalf, 0.0);
|
||||
translatedFragPosHalf *= fragDirection;
|
||||
translatedFragPosHalf += half2(edgeSize);
|
||||
half2 proxyDims = half2(2.0 * edgeSize);
|
||||
half2 texCoord = translatedFragPos / proxyDims;)SkSL",
|
||||
half2 texCoord = translatedFragPosHalf / proxyDims;)SkSL",
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar),
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar),
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar),
|
||||
args.fUniformHandler->getUniformCStr(blurRadiusVar),
|
||||
args.fUniformHandler->getUniformCStr(cornerRadiusVar));
|
||||
SkString _sample17184 = this->invokeChild(0, args);
|
||||
SkString _sample17267 = this->invokeChild(0, args);
|
||||
fragBuilder->codeAppendf(
|
||||
R"SkSL(
|
||||
half4 inputColor = %s;)SkSL",
|
||||
_sample17184.c_str());
|
||||
SkString _coords17232("float2(texCoord)");
|
||||
SkString _sample17232 = this->invokeChild(1, args, _coords17232.c_str());
|
||||
_sample17267.c_str());
|
||||
SkString _coords17315("float2(texCoord)");
|
||||
SkString _sample17315 = this->invokeChild(1, args, _coords17315.c_str());
|
||||
fragBuilder->codeAppendf(
|
||||
R"SkSL(
|
||||
%s = inputColor * %s;
|
||||
)SkSL",
|
||||
args.fOutputColor, _sample17232.c_str());
|
||||
args.fOutputColor, _sample17315.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user