GrClampedGradientEffect.fp 2.4 KB

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