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
19std::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}