Optimize GrRRectBlurEffect by computing frag pos branchlessly.
This version computes X and Y in parallel and without branching. Change-Id: I08dd7339f75c6cdd5b4130bf363cac1f527bf6ed Reviewed-on: https://skia-review.googlesource.com/c/skia/+/295572 Commit-Queue: John Stiles <johnstiles@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
85aa42820e
commit
a2d46a1f7d
@ -58,6 +58,8 @@ class SimpleBlurRoundRectGM : public skiagm::GM {
|
||||
|
||||
SkISize onISize() override { return {1000, 500}; }
|
||||
|
||||
bool runAsBench() const override { return true; }
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
canvas->scale(1.5f, 1.5f);
|
||||
canvas->translate(50,50);
|
||||
|
@ -173,26 +173,38 @@ uniform half blurRadius;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// warp the fragment position to the appropriate part of the 9patch blur texture
|
||||
// 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);
|
||||
half edgeSize = 2.0 * blurRadius + cornerRadius + 0.5;
|
||||
|
||||
half2 rectCenter = half2((proxyRect.xy + proxyRect.zw) / 2.0);
|
||||
half2 translatedFragPos = half2(sk_FragCoord.xy - proxyRect.xy);
|
||||
half threshold = cornerRadius + 2.0 * blurRadius;
|
||||
half2 middle = half2(proxyRect.zw - proxyRect.xy - 2.0 * threshold);
|
||||
// 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;
|
||||
|
||||
if (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x + threshold)) {
|
||||
translatedFragPos.x = threshold;
|
||||
} else if (translatedFragPos.x >= (middle.x + threshold)) {
|
||||
translatedFragPos.x -= middle.x - 1.0;
|
||||
}
|
||||
// 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);
|
||||
|
||||
if (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y + threshold)) {
|
||||
translatedFragPos.y = threshold;
|
||||
} else if (translatedFragPos.y >= (middle.y + threshold)) {
|
||||
translatedFragPos.y -= middle.y - 1.0;
|
||||
}
|
||||
// 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 proxyDims = half2(2.0 * threshold + 1.0);
|
||||
// Remove the middle section by clamping to zero.
|
||||
translatedFragPos = max(translatedFragPos, 0);
|
||||
|
||||
// Reapply the fragment's sign, so that negative coordinates once again mean left/top side and
|
||||
// positive means bottom/right side.
|
||||
translatedFragPos *= fragDirection;
|
||||
|
||||
// Offset the fragment so that (0, 0) marks the upper-left again, instead of the center point.
|
||||
translatedFragPos += half2(edgeSize);
|
||||
|
||||
half2 proxyDims = half2(2.0 * edgeSize);
|
||||
half2 texCoord = translatedFragPos / proxyDims;
|
||||
|
||||
half4 inputColor = sample(inputFP, sk_InColor);
|
||||
|
@ -77,32 +77,30 @@ public:
|
||||
blurRadiusVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
|
||||
kHalf_GrSLType, "blurRadius");
|
||||
fragBuilder->codeAppendf(
|
||||
"\nhalf2 translatedFragPos = half2(sk_FragCoord.xy - %s.xy);\nhalf threshold = %s "
|
||||
"+ 2.0 * %s;\nhalf2 middle = half2((%s.zw - %s.xy) - float(2.0 * threshold));\nif "
|
||||
"(translatedFragPos.x >= threshold && translatedFragPos.x < middle.x + threshold) "
|
||||
"{\n translatedFragPos.x = threshold;\n} else if (translatedFragPos.x >= "
|
||||
"middle.x + threshold) {\n translatedFragPos.x -= middle.x - 1.0;\n}\nif "
|
||||
"(translatedFragPos.y > threshold && translatedFragPos.y < middle.y + threshold) "
|
||||
"{\n translatedFragPos.y = threshold;",
|
||||
"half2 translatedFragPos = half2(sk_FragCoord.xy - %s.xy);\nhalf2 proxyCenter = "
|
||||
"half2((%s.zw - %s.xy) * 0.5);\nhalf edgeSize = (2.0 * %s + %s) + "
|
||||
"0.5;\ntranslatedFragPos -= proxyCenter;\nhalf2 fragDirection = "
|
||||
"sign(translatedFragPos);\ntranslatedFragPos = "
|
||||
"abs(translatedFragPos);\ntranslatedFragPos -= proxyCenter - "
|
||||
"edgeSize;\ntranslatedFragPos = max(translatedFragPos, 0.0);\ntranslatedFragPos *= "
|
||||
"fragDirection;\ntranslatedFragPos += half2(edgeSize);\nhalf2 proxyDims = "
|
||||
"half2(2.0 * edgeSize);\nhalf2 texCoord = tra",
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar),
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar),
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar),
|
||||
args.fUniformHandler->getUniformCStr(cornerRadiusVar),
|
||||
args.fUniformHandler->getUniformCStr(blurRadiusVar),
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar),
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar));
|
||||
fragBuilder->codeAppendf(
|
||||
"\n} else if (translatedFragPos.y >= middle.y + threshold) {\n "
|
||||
"translatedFragPos.y -= middle.y - 1.0;\n}\nhalf2 proxyDims = half2(2.0 * "
|
||||
"threshold + 1.0);\nhalf2 texCoord = translatedFragPos / proxyDims;");
|
||||
SkString _input8208 = SkStringPrintf("%s", args.fInputColor);
|
||||
SkString _sample8208;
|
||||
args.fUniformHandler->getUniformCStr(cornerRadiusVar));
|
||||
fragBuilder->codeAppendf("nslatedFragPos / proxyDims;");
|
||||
SkString _input8931 = SkStringPrintf("%s", args.fInputColor);
|
||||
SkString _sample8931;
|
||||
if (_outer.inputFP_index >= 0) {
|
||||
_sample8208 = this->invokeChild(_outer.inputFP_index, _input8208.c_str(), args);
|
||||
_sample8931 = this->invokeChild(_outer.inputFP_index, _input8931.c_str(), args);
|
||||
} else {
|
||||
_sample8208 = _input8208;
|
||||
_sample8931 = _input8931;
|
||||
}
|
||||
fragBuilder->codeAppendf(
|
||||
"\nhalf4 inputColor = %s;\n%s = inputColor * sample(%s, float2(texCoord)).%s;\n",
|
||||
_sample8208.c_str(), args.fOutputColor,
|
||||
_sample8931.c_str(), args.fOutputColor,
|
||||
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
|
||||
fragBuilder->getProgramBuilder()
|
||||
->samplerSwizzle(args.fTexSamplers[0])
|
||||
|
Loading…
Reference in New Issue
Block a user