[RenderEngine] Polish shader pipeline for HDR support.
Previously we applied transform matrix between color spaces together with color
matrix right before applying OETF. With HDR, we need to do transcoding and
apply OOTF. And it's easier if we operate in XYZ color space. This patch
essentially extends the pipeline with two matrices. After applying EOTF, input
matrix will be applied to convert color into XYZ color space, and right before
applying OETF, a combination of output transform matrix and color matrix will
be applied to convert the color from XYZ color space to destination color
space.
Minor: Previously, if wide color gamut is supported and the output is sRGB, we
failed to apply color matrix. This patch also fixes this issue by taking it
into account under wide color gamut platform.
BUG: 73825729
Test: build, flash
Change-Id: I09af39375980a42bd84f387229d54e070f634519
diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp
index e5261c2..fd2c968 100644
--- a/services/surfaceflinger/RenderEngine/Program.cpp
+++ b/services/surfaceflinger/RenderEngine/Program.cpp
@@ -58,13 +58,13 @@
mVertexShader = vertexId;
mFragmentShader = fragmentId;
mInitialized = true;
-
- mColorMatrixLoc = glGetUniformLocation(programId, "colorMatrix");
mProjectionMatrixLoc = glGetUniformLocation(programId, "projection");
mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
mSamplerLoc = glGetUniformLocation(programId, "sampler");
mColorLoc = glGetUniformLocation(programId, "color");
mDisplayMaxLuminanceLoc = glGetUniformLocation(programId, "displayMaxLuminance");
+ mInputTransformMatrixLoc = glGetUniformLocation(programId, "inputTransformMatrix");
+ mOutputTransformMatrixLoc = glGetUniformLocation(programId, "outputTransformMatrix");
// set-up the default values for our uniforms
glUseProgram(programId);
@@ -134,8 +134,16 @@
const float color[4] = {desc.mColor.r, desc.mColor.g, desc.mColor.b, desc.mColor.a};
glUniform4fv(mColorLoc, 1, color);
}
- if (mColorMatrixLoc >= 0) {
- glUniformMatrix4fv(mColorMatrixLoc, 1, GL_FALSE, desc.mColorMatrix.asArray());
+ if (mInputTransformMatrixLoc >= 0) {
+ glUniformMatrix3fv(mInputTransformMatrixLoc, 1, GL_FALSE,
+ desc.mInputTransformMatrix.asArray());
+ }
+ if (mOutputTransformMatrixLoc >= 0) {
+ // The output transform matrix and color matrix can be combined as one matrix
+ // that is applied right before applying OETF.
+ mat4 outputTransformMatrix = desc.mColorMatrix * desc.mOutputTransformMatrix;
+ glUniformMatrix4fv(mOutputTransformMatrixLoc, 1, GL_FALSE,
+ outputTransformMatrix.asArray());
}
if (mDisplayMaxLuminanceLoc >= 0) {
glUniform1f(mDisplayMaxLuminanceLoc, desc.mDisplayMaxLuminance);