Ethan Nicholas | 130fb3f | 2018-02-01 12:14:34 -0500 | [diff] [blame] | 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 | |
Ethan Nicholas | 8dca18a | 2017-11-15 15:33:33 -0500 | [diff] [blame] | 8 | layout(key) in GrClipEdgeType edgeType; |
| 9 | layout(ctype=SkRect) in float4 rect; |
| 10 | layout(ctype=SkRect) float4 prevRect = float4(-1); |
| 11 | uniform float4 rectUniform; |
| 12 | |
| 13 | @optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag } |
| 14 | |
| 15 | void 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 | } |