gl-renderer: add post-curve set to identity
Add post-curve support in color.h. Pre-curve and post-curve describe color pipeline components in a single GL shader invocation.The GL shader is supposed to match struct weston_color_transform exactly. We have the following color pipeline: shader A -> blending -> shader B -> KMS. Both A and B shaders using the same source file :fragment.glsl. Each shader has pre and post curve. The typical color pipeline with 3DLUT: Shader A: pre-curve identity->3DLUT->blending->post-curve identity Shader B: pre-curve->3DLUT identity->post-curve identity->KMS The typical color pipeline with matrix (in next commits): Shader A: pre-curve->matrix->blending->post-curve identity Shader B: pre-curve->matrix identity->post-curve identity->KMS The pre-curve plays role of EOTF (shader A) or INV_EOTF (shader B) becouse we are stiching the shaders. We assume that someone in the future may use both pre-curve and post-curve, for example, when it is not possible to combine these curves into 3DLUT and we will do mapping elements based on their location in ICC profile. Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
This commit is contained in:
parent
118ee6674b
commit
96f0fc3974
|
@ -201,7 +201,7 @@ struct weston_color_transform {
|
|||
struct weston_color_mapping mapping;
|
||||
|
||||
/** Step 4: color curve after color mapping */
|
||||
/* struct weston_color_curve post_curve; */
|
||||
struct weston_color_curve post_curve;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -76,10 +76,12 @@ compile_const bool c_input_is_premult = DEF_INPUT_IS_PREMULT;
|
|||
compile_const bool c_green_tint = DEF_GREEN_TINT;
|
||||
compile_const int c_color_pre_curve = DEF_COLOR_PRE_CURVE;
|
||||
compile_const int c_color_mapping = DEF_COLOR_MAPPING;
|
||||
compile_const int c_color_post_curve = DEF_COLOR_POST_CURVE;
|
||||
|
||||
compile_const bool c_need_color_pipeline =
|
||||
c_color_pre_curve != SHADER_COLOR_CURVE_IDENTITY ||
|
||||
c_color_mapping != SHADER_COLOR_MAPPING_IDENTITY;
|
||||
c_color_mapping != SHADER_COLOR_MAPPING_IDENTITY ||
|
||||
c_color_post_curve != SHADER_COLOR_CURVE_IDENTITY;
|
||||
|
||||
vec4
|
||||
yuva2rgba(vec4 yuva)
|
||||
|
@ -123,6 +125,8 @@ uniform float view_alpha;
|
|||
uniform vec4 unicolor;
|
||||
uniform HIGHPRECISION sampler2D color_pre_curve_lut_2d;
|
||||
uniform HIGHPRECISION vec2 color_pre_curve_lut_scale_offset;
|
||||
uniform HIGHPRECISION sampler2D color_post_curve_lut_2d;
|
||||
uniform HIGHPRECISION vec2 color_post_curve_lut_scale_offset;
|
||||
|
||||
#if DEF_COLOR_MAPPING == SHADER_COLOR_MAPPING_3DLUT
|
||||
uniform HIGHPRECISION sampler3D color_mapping_lut_3d;
|
||||
|
@ -246,6 +250,33 @@ color_mapping(vec3 color)
|
|||
return vec3(1.0, 0.3, 1.0);
|
||||
}
|
||||
|
||||
float
|
||||
sample_color_post_curve_lut_2d(float x, compile_const int row)
|
||||
{
|
||||
float tx = lut_texcoord(x, color_post_curve_lut_scale_offset);
|
||||
|
||||
return texture2D(color_post_curve_lut_2d,
|
||||
vec2(tx, (float(row) + 0.5) / 4.0)).x;
|
||||
}
|
||||
|
||||
vec3
|
||||
color_post_curve(vec3 color)
|
||||
{
|
||||
vec3 ret;
|
||||
|
||||
if (c_color_post_curve == SHADER_COLOR_CURVE_IDENTITY) {
|
||||
return color;
|
||||
} else if (c_color_post_curve == SHADER_COLOR_CURVE_LUT_3x1D) {
|
||||
ret.r = sample_color_post_curve_lut_2d(color.r, 0);
|
||||
ret.g = sample_color_post_curve_lut_2d(color.g, 1);
|
||||
ret.b = sample_color_post_curve_lut_2d(color.b, 2);
|
||||
return ret;
|
||||
} else {
|
||||
/* Never reached, bad c_color_post_curve. */
|
||||
return vec3(1.0, 0.3, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
vec4
|
||||
color_pipeline(vec4 color)
|
||||
{
|
||||
|
@ -259,6 +290,7 @@ color_pipeline(vec4 color)
|
|||
|
||||
color.rgb = color_pre_curve(color.rgb);
|
||||
color.rgb = color_mapping(color.rgb);
|
||||
color.rgb = color_post_curve(color.rgb);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
|
|
@ -80,11 +80,12 @@ struct gl_shader_requirements
|
|||
|
||||
unsigned color_pre_curve:1; /* enum gl_shader_color_curve */
|
||||
unsigned color_mapping:1; /* enum gl_shader_color_mapping */
|
||||
unsigned color_post_curve:1; /* enum gl_shader_color_curve */
|
||||
/*
|
||||
* The total size of all bitfields plus pad_bits_ must fill up exactly
|
||||
* how many bytes the compiler allocates for them together.
|
||||
*/
|
||||
unsigned pad_bits_:24;
|
||||
unsigned pad_bits_:23;
|
||||
};
|
||||
static_assert(sizeof(struct gl_shader_requirements) ==
|
||||
4 /* total bitfield size in bytes */,
|
||||
|
@ -110,6 +111,8 @@ struct gl_shader_config {
|
|||
GLfloat scale_offset[2];
|
||||
} lut3d;
|
||||
} color_mapping;
|
||||
GLuint color_post_curve_lut_tex;
|
||||
GLfloat color_post_curve_lut_scale_offset[2];
|
||||
};
|
||||
|
||||
struct gl_renderer {
|
||||
|
|
|
@ -61,6 +61,7 @@ struct gl_renderer_color_transform {
|
|||
struct wl_listener destroy_listener;
|
||||
struct gl_renderer_color_curve pre_curve;
|
||||
struct gl_renderer_color_mapping mapping;
|
||||
struct gl_renderer_color_curve post_curve;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -82,6 +83,7 @@ static void
|
|||
gl_renderer_color_transform_destroy(struct gl_renderer_color_transform *gl_xform)
|
||||
{
|
||||
gl_renderer_color_curve_fini(&gl_xform->pre_curve);
|
||||
gl_renderer_color_curve_fini(&gl_xform->post_curve);
|
||||
gl_renderer_color_mapping_fini(&gl_xform->mapping);
|
||||
wl_list_remove(&gl_xform->destroy_listener.link);
|
||||
free(gl_xform);
|
||||
|
@ -141,6 +143,8 @@ gl_color_curve_lut_3x1d(struct gl_renderer_color_curve *gl_curve,
|
|||
/*
|
||||
* Four rows, see fragment.glsl sample_color_pre_curve_lut_2d().
|
||||
* The fourth row is unused in fragment.glsl color_pre_curve().
|
||||
* Four rows, see fragment.glsl sample_color_post_curve_lut_2d().
|
||||
* The fourth row is unused in fragment.glsl color_post_curve().
|
||||
*/
|
||||
lut = calloc(lut_len * nr_rows, sizeof *lut);
|
||||
if (!lut)
|
||||
|
@ -223,6 +227,10 @@ gl_renderer_color_transform_from(struct weston_color_transform *xform)
|
|||
.pre_curve.scale = 0.0f,
|
||||
.pre_curve.offset = 0.0f,
|
||||
.mapping.type = SHADER_COLOR_MAPPING_IDENTITY,
|
||||
.post_curve.type = SHADER_COLOR_CURVE_IDENTITY,
|
||||
.post_curve.tex = 0,
|
||||
.post_curve.scale = 0.0f,
|
||||
.post_curve.offset = 0.0f,
|
||||
};
|
||||
struct gl_renderer_color_transform *gl_xform;
|
||||
bool ok = false;
|
||||
|
@ -270,6 +278,20 @@ gl_renderer_color_transform_from(struct weston_color_transform *xform)
|
|||
gl_renderer_color_transform_destroy(gl_xform);
|
||||
return NULL;
|
||||
}
|
||||
switch (xform->post_curve.type) {
|
||||
case WESTON_COLOR_CURVE_TYPE_IDENTITY:
|
||||
gl_xform->post_curve = no_op_gl_xform.post_curve;
|
||||
ok = true;
|
||||
break;
|
||||
case WESTON_COLOR_CURVE_TYPE_LUT_3x1D:
|
||||
ok = gl_color_curve_lut_3x1d(&gl_xform->post_curve,
|
||||
&xform->post_curve, xform);
|
||||
break;
|
||||
}
|
||||
if (!ok) {
|
||||
gl_renderer_color_transform_destroy(gl_xform);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gl_xform;
|
||||
}
|
||||
|
@ -290,6 +312,11 @@ gl_shader_config_set_color_transform(struct gl_shader_config *sconf,
|
|||
sconf->color_pre_curve_lut_scale_offset[0] = gl_xform->pre_curve.scale;
|
||||
sconf->color_pre_curve_lut_scale_offset[1] = gl_xform->pre_curve.offset;
|
||||
|
||||
sconf->req.color_post_curve = gl_xform->post_curve.type;
|
||||
sconf->color_post_curve_lut_tex = gl_xform->post_curve.tex;
|
||||
sconf->color_post_curve_lut_scale_offset[0] = gl_xform->post_curve.scale;
|
||||
sconf->color_post_curve_lut_scale_offset[1] = gl_xform->post_curve.offset;
|
||||
|
||||
sconf->req.color_mapping = gl_xform->mapping.type;
|
||||
switch (gl_xform->mapping.type) {
|
||||
case SHADER_COLOR_MAPPING_3DLUT:
|
||||
|
|
|
@ -67,6 +67,8 @@ struct gl_shader {
|
|||
GLint scale_offset_uniform;
|
||||
} lut3d;
|
||||
} color_mapping;
|
||||
GLint color_post_curve_lut_2d_uniform;
|
||||
GLint color_post_curve_lut_scale_offset_uniform;
|
||||
struct wl_list link; /* gl_renderer::shader_list */
|
||||
struct timespec last_used;
|
||||
};
|
||||
|
@ -182,10 +184,11 @@ create_shader_description_string(const struct gl_shader_requirements *req)
|
|||
int size;
|
||||
char *str;
|
||||
|
||||
size = asprintf(&str, "%s %s %s %cinput_is_premult %cgreen",
|
||||
size = asprintf(&str, "%s %s %s %s %cinput_is_premult %cgreen",
|
||||
gl_shader_texture_variant_to_string(req->variant),
|
||||
gl_shader_color_curve_to_string(req->color_pre_curve),
|
||||
gl_shader_color_mapping_to_string(req->color_mapping),
|
||||
gl_shader_color_curve_to_string(req->color_post_curve),
|
||||
req->input_is_premult ? '+' : '-',
|
||||
req->green_tint ? '+' : '-');
|
||||
if (size < 0)
|
||||
|
@ -204,11 +207,13 @@ create_shader_config_string(const struct gl_shader_requirements *req)
|
|||
"#define DEF_INPUT_IS_PREMULT %s\n"
|
||||
"#define DEF_COLOR_PRE_CURVE %s\n"
|
||||
"#define DEF_COLOR_MAPPING %s\n"
|
||||
"#define DEF_COLOR_POST_CURVE %s\n"
|
||||
"#define DEF_VARIANT %s\n",
|
||||
req->green_tint ? "true" : "false",
|
||||
req->input_is_premult ? "true" : "false",
|
||||
gl_shader_color_curve_to_string(req->color_pre_curve),
|
||||
gl_shader_color_mapping_to_string(req->color_mapping),
|
||||
gl_shader_color_curve_to_string(req->color_post_curve),
|
||||
gl_shader_texture_variant_to_string(req->variant));
|
||||
if (size < 0)
|
||||
return NULL;
|
||||
|
@ -291,6 +296,11 @@ gl_shader_create(struct gl_renderer *gr,
|
|||
shader->color_pre_curve_lut_scale_offset_uniform =
|
||||
glGetUniformLocation(shader->program, "color_pre_curve_lut_scale_offset");
|
||||
|
||||
shader->color_post_curve_lut_2d_uniform =
|
||||
glGetUniformLocation(shader->program, "color_post_curve_lut_2d");
|
||||
shader->color_post_curve_lut_scale_offset_uniform =
|
||||
glGetUniformLocation(shader->program, "color_post_curve_lut_scale_offset");
|
||||
|
||||
switch(requirements->color_mapping) {
|
||||
case SHADER_COLOR_MAPPING_3DLUT:
|
||||
shader->color_mapping.lut3d.tex_uniform =
|
||||
|
@ -410,6 +420,7 @@ gl_renderer_create_fallback_shader(struct gl_renderer *gr)
|
|||
.input_is_premult = true,
|
||||
.color_pre_curve = SHADER_COLOR_CURVE_IDENTITY,
|
||||
.color_mapping = SHADER_COLOR_MAPPING_IDENTITY,
|
||||
.color_post_curve = SHADER_COLOR_CURVE_IDENTITY,
|
||||
};
|
||||
struct gl_shader *shader;
|
||||
|
||||
|
@ -560,6 +571,7 @@ gl_shader_load_config(struct gl_shader *shader,
|
|||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glBindTexture(GL_TEXTURE_3D, sconf->color_mapping.lut3d.tex);
|
||||
glUniform1i(shader->color_mapping.lut3d.tex_uniform, i);
|
||||
i++;
|
||||
glUniform2fv(shader->color_mapping.lut3d.scale_offset_uniform,
|
||||
1, sconf->color_mapping.lut3d.scale_offset);
|
||||
break;
|
||||
|
@ -567,6 +579,23 @@ gl_shader_load_config(struct gl_shader *shader,
|
|||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (sconf->req.color_post_curve) {
|
||||
case SHADER_COLOR_CURVE_IDENTITY:
|
||||
assert(sconf->color_post_curve_lut_tex == 0);
|
||||
break;
|
||||
case SHADER_COLOR_CURVE_LUT_3x1D:
|
||||
assert(sconf->color_post_curve_lut_tex != 0);
|
||||
assert(shader->color_post_curve_lut_2d_uniform != -1);
|
||||
assert(shader->color_post_curve_lut_scale_offset_uniform != -1);
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glBindTexture(GL_TEXTURE_2D, sconf->color_post_curve_lut_tex);
|
||||
glUniform1i(shader->color_post_curve_lut_2d_uniform, i);
|
||||
i++;
|
||||
glUniform2fv(shader->color_post_curve_lut_scale_offset_uniform,
|
||||
1, sconf->color_post_curve_lut_scale_offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
Loading…
Reference in New Issue