text: /*
   * Copyright 2018 Google Inc.
   *
   * Use of this source code is governed by a BSD-style license that can be
   * found in the LICENSE file.
   */
  
  // Provides tiling for the repeat or mirror modes.
  
  in fragmentProcessor colorizer;
  in fragmentProcessor gradLayout;
  
  layout(key) in bool mirror;
  layout(key) in bool makePremul;
  // Trust the creator that this matches the color spec of the gradient
  in bool colorsAreOpaque;
  
  void main() {
      half4 t = process(gradLayout);
  
      if (!gradLayout.preservesOpaqueInput && t.y < 0) {
          // layout has rejected this fragment (rely on sksl to remove this branch if the layout FP
          // preserves opacity is false)
          sk_OutColor = half4(0);
      } else {
          @if(mirror) {
              half t_1 = t.x - 1;
              half tiled_t = t_1 - 2 * floor(t_1 * 0.5) - 1;
              if (sk_Caps.mustDoOpBetweenFloorAndAbs) {
                  // At this point the expected value of tiled_t should between -1 and 1, so this
                  // clamp has no effect other than to break up the floor and abs calls and make sure
                  // the compiler doesn't merge them back together.
                  tiled_t = clamp(tiled_t, -1, 1);
              }
              t.x = abs(tiled_t);
          } else {
              // Simple repeat mode
              t.x = fract(t.x);
          }
  
          // t.x has been tiled (repeat or mirrored), but pass through remaining 3 components
          // unmodified.
          sk_OutColor = process(colorizer, t);
      }
  
      @if (makePremul) {
          sk_OutColor.xyz *= sk_OutColor.w;
      }
  }
  
  //////////////////////////////////////////////////////////////////////////////
  
  // If the layout does not preserve opacity, remove the opaque optimization,
  // but otherwise respect the provided color opacity state.
  @optimizationFlags {
      kCompatibleWithCoverageAsAlpha_OptimizationFlag |
      (colorsAreOpaque && gradLayout->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
                                                             : kNone_OptimizationFlags)
  }
  