| /* | |
| * Copyright 2018 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| layout(key) in GrClipEdgeType edgeType; | |
| layout(ctype=SkRect) in float4 rect; | |
| layout(ctype=SkRect) float4 prevRect = float4(-1); | |
| uniform float4 rectUniform; | |
| @optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag } | |
| void main() { | |
| half alpha; | |
| @switch (edgeType) { | |
| case GrClipEdgeType::kFillBW: // fall through | |
| case GrClipEdgeType::kInverseFillBW: | |
| // non-AA | |
| alpha = all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw), | |
| float4(rectUniform.xy, sk_FragCoord.xy))) ? 1 : 0; | |
| break; | |
| default: | |
| // The amount of coverage removed in x and y by the edges is computed as a pair of | |
| // negative numbers, xSub and ySub. | |
| half xSub, ySub; | |
| xSub = min(sk_FragCoord.x - rectUniform.x, 0.0); | |
| xSub += min(rectUniform.z - sk_FragCoord.x, 0.0); | |
| ySub = min(sk_FragCoord.y - rectUniform.y, 0.0); | |
| ySub += min(rectUniform.w - sk_FragCoord.y, 0.0); | |
| // Now compute coverage in x and y and multiply them to get the fraction of the pixel | |
| // covered. | |
| alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0)); | |
| } | |
| @if (edgeType == GrClipEdgeType::kInverseFillBW || edgeType == GrClipEdgeType::kInverseFillAA) { | |
| alpha = 1.0 - alpha; | |
| } | |
| sk_OutColor = sk_InColor * alpha; | |
| } | |
| @setData(pdman) { | |
| const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ? | |
| rect.makeInset(.5f, .5f) : rect; | |
| if (newRect != prevRect) { | |
| pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom); | |
| prevRect = newRect; | |
| } | |
| } | |
| @test(d) { | |
| SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(), | |
| d->fRandom->nextSScalar1(), | |
| d->fRandom->nextSScalar1(), | |
| d->fRandom->nextSScalar1()); | |
| std::unique_ptr<GrFragmentProcessor> fp; | |
| do { | |
| GrClipEdgeType edgeType = static_cast<GrClipEdgeType>( | |
| d->fRandom->nextULessThan(kGrClipEdgeTypeCnt)); | |
| fp = GrAARectEffect::Make(edgeType, rect); | |
| } while (nullptr == fp); | |
| return fp; | |
| } |