1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "src/gpu/effects/GrSDFBlurEffect.h"
17 #include "src/gpu/effects/GrMatrixEffect.h"
18 
Make(GrRecordingContext* context, float noxFormedSigma, const SkRRect& srcRRect)19 std::unique_ptr<GrFragmentProcessor> GrSDFBlurEffect::Make(GrRecordingContext* context,
20     float noxFormedSigma, const SkRRect& srcRRect)
21 {
22     float blurRadius = noxFormedSigma;
23     SkV2 wh = {srcRRect.width(), srcRRect.height()};
24     SkVector rr = srcRRect.getSimpleRadii();
25     float r = rr.x();
26 
27     static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
28         "uniform half blurRadius;"
29         "uniform vec2 wh;"
30         "uniform half r;"
31 
32         "float myRoundBoxSDF(vec2 p, vec2 a, float r) {"
33             "vec2 q = abs(p)-a + r;"
34             "return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - r;"
35         "}"
36 
37         "half4 main(float2 pos) {"
38             "vec2 a = vec2(wh.x / 2, wh.y / 2);"
39             "float d = myRoundBoxSDF(pos, a, r);"
40             "float alpha = smoothstep( blurRadius / 2, -blurRadius / 2, d );"
41 
42             "return half4(alpha);"
43         "}"
44     );
45 
46     std::unique_ptr<GrFragmentProcessor> fp = GrSkSLFP::Make(effect, "RRectSDFBlur", nullptr,
47         GrSkSLFP::OptFlags::kCompatibleWithCoverageAsAlpha, "blurRadius", blurRadius, "wh", wh, "r", r);
48 
49     if (!fp) {
50         return nullptr;
51     }
52 
53     SkMatrix matrix;
54     matrix.setTranslateX(-noxFormedSigma - srcRRect.rect().fLeft - srcRRect.width() / kHalfFactor);
55     matrix.setTranslateY(-noxFormedSigma - srcRRect.rect().fTop - srcRRect.height() / kHalfFactor);
56 
57     fp = GrMatrixEffect::Make(matrix, std::move(fp));
58 
59     return fp;
60 }