Skip to content

Commit d7e9d2a

Browse files
Sally QiAndroid (Google) Code Review
authored andcommitted
Merge "[LUT shader] add CIE_Y shader" into main
2 parents d54e589 + c1beabf commit d7e9d2a

4 files changed

Lines changed: 58 additions & 9 deletions

File tree

libs/gui/aidl/android/gui/LutProperties.aidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ parcelable LutProperties {
2727

2828
int size;
2929
@Backing(type="int")
30-
enum SamplingKey { RGB, MAX_RGB }
30+
enum SamplingKey { RGB, MAX_RGB, CIE_Y }
3131
SamplingKey[] samplingKeys;
3232
}

libs/renderengine/skia/SkiaRenderEngine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader(
545545

546546
if (graphicBuffer && parameters.layer.luts) {
547547
shader = mLutShader.lutShader(shader, parameters.layer.luts,
548+
parameters.layer.sourceDataspace,
548549
toSkColorSpace(parameters.outputDataSpace));
549550
}
550551

libs/renderengine/skia/filters/LutShader.cpp

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
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+
113146
sk_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

171217
sk_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 =

libs/renderengine/skia/filters/LutShader.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <aidl/android/hardware/graphics/composer3/LutProperties.h>
2323
#include <gui/DisplayLuts.h>
24+
#include <ui/GraphicTypes.h>
2425

2526
namespace android {
2627
namespace renderengine {
@@ -29,13 +30,13 @@ namespace skia {
2930
class LutShader {
3031
public:
3132
sk_sp<SkShader> lutShader(sk_sp<SkShader>& input, std::shared_ptr<gui::DisplayLuts> displayLuts,
32-
sk_sp<SkColorSpace> outColorSpace);
33+
ui::Dataspace srcDataspace, sk_sp<SkColorSpace> outColorSpace);
3334

3435
private:
3536
sk_sp<SkShader> generateLutShader(sk_sp<SkShader> input, const std::vector<float>& buffers,
3637
const int32_t offset, const int32_t length,
3738
const int32_t dimension, const int32_t size,
38-
const int32_t samplingKey);
39+
const int32_t samplingKey, ui::Dataspace srcDataspace);
3940
std::unique_ptr<SkRuntimeShaderBuilder> mBuilder;
4041
};
4142

0 commit comments

Comments
 (0)