1515 */
1616#include " LutShader.h"
1717
18+ #include < SkM44.h>
1819#include < SkTileMode.h>
1920#include < common/trace.h>
2021#include < cutils/ashmem.h>
2122#include < math/half.h>
2223#include < sys/mman.h>
24+ #include < ui/ColorSpace.h>
2325
2426#include " include/core/SkColorSpace.h"
2527#include " src/core/SkColorFilterPriv.h"
@@ -36,6 +38,8 @@ static const SkString kShader = SkString(R"(
3638 uniform int size;
3739 uniform int key;
3840 uniform int dimension;
41+ uniform vec3 luminanceCoefficients; // for CIE_Y
42+
3943 vec4 main(vec2 xy) {
4044 float4 rgba = image.eval(xy);
4145 float3 linear = toLinearSrgb(rgba.rgb);
@@ -51,12 +55,16 @@ static const SkString kShader = SkString(R"(
5155 return float4(linear.r * gainR, linear.g * gainG, linear.b * gainB, rgba.a);
5256 // MAX_RGB
5357 } else if (key == 1) {
54- float4 rgba = image.eval(xy);
55- float3 linear = toLinearSrgb(rgba.rgb);
5658 float maxRGB = max(linear.r, max(linear.g, linear.b));
5759 float index = maxRGB * float(size - 1);
5860 float gain = lut.eval(vec2(index, 0.0) + 0.5).r;
5961 return float4(linear * gain, rgba.a);
62+ // CIE_Y
63+ } else if (key == 2) {
64+ float y = dot(linear, luminanceCoefficients) / 3.0;
65+ float index = y * float(size - 1);
66+ float gain = lut.eval(vec2(index, 0.0) + 0.5).r;
67+ return float4(linear * gain, rgba.a);
6068 }
6169 } else if (dimension == 3) {
6270 if (key == 0) {
@@ -110,11 +118,37 @@ static const SkString kShader = SkString(R"(
110118 return rgba;
111119 })" );
112120
121+ // same as shader::toColorSpace function
122+ // TODO: put this function in a general place
123+ static ColorSpace toColorSpace (ui::Dataspace dataspace) {
124+ switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
125+ case HAL_DATASPACE_STANDARD_BT709:
126+ return ColorSpace::sRGB ();
127+ case HAL_DATASPACE_STANDARD_DCI_P3:
128+ return ColorSpace::DisplayP3 ();
129+ case HAL_DATASPACE_STANDARD_BT2020:
130+ case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
131+ return ColorSpace::BT2020 ();
132+ case HAL_DATASPACE_STANDARD_ADOBE_RGB:
133+ return ColorSpace::AdobeRGB ();
134+ case HAL_DATASPACE_STANDARD_BT601_625:
135+ case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
136+ case HAL_DATASPACE_STANDARD_BT601_525:
137+ case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
138+ case HAL_DATASPACE_STANDARD_BT470M:
139+ case HAL_DATASPACE_STANDARD_FILM:
140+ case HAL_DATASPACE_STANDARD_UNSPECIFIED:
141+ default :
142+ return ColorSpace::sRGB ();
143+ }
144+ }
145+
113146sk_sp<SkShader> LutShader::generateLutShader (sk_sp<SkShader> input,
114147 const std::vector<float >& buffers,
115148 const int32_t offset, const int32_t length,
116149 const int32_t dimension, const int32_t size,
117- const int32_t samplingKey) {
150+ const int32_t samplingKey,
151+ ui::Dataspace srcDataspace) {
118152 SFTRACE_NAME (" lut shader" );
119153 std::vector<half> buffer (length * 4 ); // 4 is for RGBA
120154 auto d = static_cast <LutProperties::Dimension>(dimension);
@@ -133,12 +167,16 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input,
133167 }
134168 }
135169 /* *
136- * 1D Lut(rgba)
170+ * 1D Lut RGB/MAX_RGB
137171 * (R0, 0, 0, 0)
138172 * (R1, 0, 0, 0)
173+ *
174+ * 1D Lut CIE_Y
175+ * (Y0, 0, 0, 0)
176+ * (Y1, 0, 0, 0)
139177 * ...
140178 *
141- * 3D Lut
179+ * 3D Lut MAX_RGB
142180 * (R0, G0, B0, 0)
143181 * (R1, G1, B1, 0)
144182 * ...
@@ -162,6 +200,14 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input,
162200 const int uSize = static_cast <int >(size);
163201 const int uKey = static_cast <int >(samplingKey);
164202 const int uDimension = static_cast <int >(dimension);
203+ if (static_cast <LutProperties::SamplingKey>(samplingKey) == LutProperties::SamplingKey::CIE_Y) {
204+ // Use predefined colorspaces of input dataspace so that we can get D65 illuminant
205+ mat3 toXYZMatrix (toColorSpace (srcDataspace).getRGBtoXYZ ());
206+ mBuilder ->uniform (" luminanceCoefficients" ) =
207+ SkV3{toXYZMatrix[0 ][1 ], toXYZMatrix[1 ][1 ], toXYZMatrix[2 ][1 ]};
208+ } else {
209+ mBuilder ->uniform (" luminanceCoefficients" ) = SkV3{1 .f , 1 .f , 1 .f };
210+ }
165211 mBuilder ->uniform (" size" ) = uSize;
166212 mBuilder ->uniform (" key" ) = uKey;
167213 mBuilder ->uniform (" dimension" ) = uDimension;
@@ -170,6 +216,7 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input,
170216
171217sk_sp<SkShader> LutShader::lutShader (sk_sp<SkShader>& input,
172218 std::shared_ptr<gui::DisplayLuts> displayLuts,
219+ ui::Dataspace srcDataspace,
173220 sk_sp<SkColorSpace> outColorSpace) {
174221 if (mBuilder == nullptr ) {
175222 const static SkRuntimeEffect::Result instance = SkRuntimeEffect::MakeForShader (kShader );
@@ -218,7 +265,7 @@ sk_sp<SkShader> LutShader::lutShader(sk_sp<SkShader>& input,
218265 }
219266 input = generateLutShader (input, buffers, offsets[i], bufferSizePerLut,
220267 lutProperties[i].dimension , lutProperties[i].size ,
221- lutProperties[i].samplingKey );
268+ lutProperties[i].samplingKey , srcDataspace );
222269 }
223270
224271 auto colorXformLutToDst =
0 commit comments