blob: 9fb124a3c9e9f8c5de5a9f72ab65ab103a0fe2a1 [file] [log] [blame]
/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// Convert HSLA -> RGBA (including clamp and premul).
//
// Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3].
//
// [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
// [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
// [3] http://www.chilliant.com/rgb2hsv.html
in fragmentProcessor inputFP;
half4 main() {
half4 color = sample(inputFP);
half3 hsl = color.rgb;
half C = (1 - abs(2 * hsl.z - 1)) * hsl.y;
half3 p = hsl.xxx + half3(0, 2/3.0, 1/3.0);
half3 q = saturate(abs(fract(p) * 6 - 3) - 1);
half3 rgb = (q - 0.5) * C + hsl.z;
color = saturate(half4(rgb, color.a));
color.rgb *= color.a;
return color;
}
@optimizationFlags {
ProcessorOptimizationFlags(inputFP.get()) & (kConstantOutputForConstantInput_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag)
}
@class {
#include "include/private/SkColorData.h"
#include "include/private/SkNx.h"
SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
SkPMColor4f c = ConstantOutputForConstantInput(this->childProcessor(0), inColor);
const auto H = c[0],
S = c[1],
L = c[2],
C = (1 - std::abs(2 * L - 1)) * S;
const auto p = H + Sk4f(0, 2/3.f, 1/3.f, 0),
q = Sk4f::Min(Sk4f::Max(((p - p.floor()) * 6 - 3).abs() - 1, 0), 1),
rgb = (q - 0.5f) * C + L,
rgba = Sk4f::Min(Sk4f::Max(Sk4f(rgb[0], rgb[1], rgb[2], c.fA), 0), 1);
return SkColor4f{rgba[0], rgba[1], rgba[2], rgba[3]}.premul();
}
}