Home | History | Annotate | Download | only in gradients
      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 // This master effect implements clamping on the layout coordinate and requires specifying the
      9 // border colors that are used when outside the clamped boundary. Gradients with the
     10 // SkShader::kClamp_TileMode should use the colors at their first and last stop (after adding dummy
     11 // stops for t=0,t=1) as the border color. This will automatically replicate the edge color, even if
     12 // when there is a hard stop.
     13 //
     14 // The SkShader::kDecal_TileMode can be produced by specifying transparent black as the border
     15 // colors, regardless of the gradient's stop colors.
     16 
     17 in fragmentProcessor colorizer;
     18 in fragmentProcessor gradLayout;
     19 
     20 layout(ctype=SkPMColor4f, tracked) in uniform half4 leftBorderColor;  // t < 0.0
     21 layout(ctype=SkPMColor4f, tracked) in uniform half4 rightBorderColor; // t > 1.0
     22 
     23 layout(key) in bool makePremul;
     24 // Trust the creator that this matches the color spec of the gradient
     25 in bool colorsAreOpaque;
     26 
     27 void main() {
     28     half4 t = process(gradLayout);
     29     // If t.x is below 0, use the left border color without invoking the child processor. If any t.x
     30     // is above 1, use the right border color. Otherwise, t is in the [0, 1] range assumed by the
     31     // colorizer FP, so delegate to the child processor.
     32     if (!gradLayout.preservesOpaqueInput && t.y < 0) {
     33         // layout has rejected this fragment (rely on sksl to remove this branch if the layout FP
     34         // preserves opacity is false)
     35         sk_OutColor = half4(0);
     36     } else if (t.x < 0) {
     37         sk_OutColor = leftBorderColor;
     38     } else if (t.x > 1.0) {
     39         sk_OutColor = rightBorderColor;
     40     } else {
     41         sk_OutColor = process(colorizer, t);
     42     }
     43 
     44     @if(makePremul) {
     45         sk_OutColor.xyz *= sk_OutColor.w;
     46     }
     47 }
     48 
     49 //////////////////////////////////////////////////////////////////////////////
     50 
     51 // If the layout does not preserve opacity, remove the opaque optimization,
     52 // but otherwise respect the provided color opacity state (which should take
     53 // into account the opacity of the border colors).
     54 @optimizationFlags {
     55     kCompatibleWithCoverageAsAlpha_OptimizationFlag |
     56     (colorsAreOpaque && gradLayout->preservesOpaqueInput() ? kPreservesOpaqueInput_OptimizationFlag
     57                                                            : kNone_OptimizationFlags)
     58 }
     59