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
8// Provides tiling for the repeat or mirror modes.
9
10in fragmentProcessor colorizer;
11in fragmentProcessor gradLayout;
12
13layout(key) in bool mirror;
14layout(key) in bool makePremul;
15// Trust the creator that this matches the color spec of the gradient
16in bool colorsAreOpaque;
17
18void main() {
19    half4 t = sample(gradLayout);
20
21    if (!gradLayout.preservesOpaqueInput && t.y < 0) {
22        // layout has rejected this fragment (rely on sksl to remove this branch if the layout FP
23        // preserves opacity is false)
24        sk_OutColor = half4(0);
25    } else {
26        @if(mirror) {
27            half t_1 = t.x - 1;
28            half tiled_t = t_1 - 2 * floor(t_1 * 0.5) - 1;
29            if (sk_Caps.mustDoOpBetweenFloorAndAbs) {
30                // At this point the expected value of tiled_t should between -1 and 1, so this
31                // clamp has no effect other than to break up the floor and abs calls and make sure
32                // the compiler doesn't merge them back together.
33                tiled_t = clamp(tiled_t, -1, 1);
34            }
35            t.x = abs(tiled_t);
36        } else {
37            // Simple repeat mode
38            t.x = fract(t.x);
39        }
40
41        // t.x has been tiled (repeat or mirrored), but pass through remaining 3 components
42        // unmodified.
43        sk_OutColor = sample(colorizer, t);
44    }
45
46    @if (makePremul) {
47        sk_OutColor.xyz *= sk_OutColor.w;
48    }
49}
50
51//////////////////////////////////////////////////////////////////////////////
52
53// If the layout does not preserve opacity, remove the opaque optimization,
54// but otherwise respect the provided color opacity state.
55@optimizationFlags {
56    kCompatibleWithCoverageAsAlpha_OptimizationFlag |
57    (colorsAreOpaque && gradLayout->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
58                                                           : kNone_OptimizationFlags)
59}
60