1/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8layout(key) in GrClipEdgeType edgeType;
9layout(ctype=SkRect) in float4 rect;
10layout(ctype=SkRect) float4 prevRect = float4(-1);
11uniform float4 rectUniform;
12
13@optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag }
14
15void main() {
16    half alpha;
17    @switch (edgeType) {
18        case GrClipEdgeType::kFillBW: // fall through
19        case GrClipEdgeType::kInverseFillBW:
20            // non-AA
21            alpha = all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw),
22                                    float4(rectUniform.xy, sk_FragCoord.xy))) ? 1 : 0;
23            break;
24        default:
25            // The amount of coverage removed in x and y by the edges is computed as a pair of
26            // negative numbers, xSub and ySub.
27            half xSub, ySub;
28            xSub = min(sk_FragCoord.x - rectUniform.x, 0.0);
29            xSub += min(rectUniform.z - sk_FragCoord.x, 0.0);
30            ySub = min(sk_FragCoord.y - rectUniform.y, 0.0);
31            ySub += min(rectUniform.w - sk_FragCoord.y, 0.0);
32            // Now compute coverage in x and y and multiply them to get the fraction of the pixel
33            // covered.
34            alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));
35    }
36
37    @if (edgeType == GrClipEdgeType::kInverseFillBW || edgeType == GrClipEdgeType::kInverseFillAA) {
38        alpha = 1.0 - alpha;
39    }
40    sk_OutColor = sk_InColor * alpha;
41}
42
43@setData(pdman) {
44    const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ?
45                            rect.makeInset(.5f, .5f) : rect;
46    if (newRect != prevRect) {
47        pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom);
48        prevRect = newRect;
49    }
50}
51
52@test(d) {
53    SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
54                                   d->fRandom->nextSScalar1(),
55                                   d->fRandom->nextSScalar1(),
56                                   d->fRandom->nextSScalar1());
57    std::unique_ptr<GrFragmentProcessor> fp;
58    do {
59        GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
60                d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
61
62        fp = GrAARectEffect::Make(edgeType, rect);
63    } while (nullptr == fp);
64    return fp;
65}
66