gl-renderer: Add coefficients and range support to internal shader

Add matrix-coefficients and range tracking to more gl-renderer structures
and get the relevant values from the color-representation implementation
instead of hard-coding them in the shader.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
This commit is contained in:
Robert Mader 2025-01-31 13:39:17 +01:00
parent 32f6148afd
commit 2613db2426
4 changed files with 50 additions and 18 deletions

View file

@ -95,29 +95,16 @@ compile_const bool c_need_color_pipeline =
compile_const bool c_need_straight_alpha =
c_need_color_pipeline || c_color_effect != SHADER_COLOR_EFFECT_NONE;
uniform HIGHPRECISION mat3 yuv_coefficients;
uniform HIGHPRECISION vec3 yuv_offsets;
vec4
yuva2rgba(vec4 yuva)
{
vec4 color_out;
float Y, su, sv;
/* ITU-R BT.601 & BT.709 quantization (limited range) */
Y = 255.0/219.0 * (yuva.x - 16.0/255.0);
/* Remove offset 128/255, but the 255/224 multiplier comes later */
su = yuva.y - 128.0/255.0;
sv = yuva.z - 128.0/255.0;
/*
* ITU-R BT.709 encoding coefficients (inverse), with the
* 255/224 limited range multiplier already included in the
* factors for su (Cb) and sv (Cr).
*/
color_out.r = Y + 1.79274107 * sv;
color_out.g = Y - 0.21324861 * su - 0.53290933 * sv;
color_out.b = Y + 2.11240179 * su;
color_out.rgb = yuv_coefficients * (yuva.xyz - yuv_offsets);
color_out.rgb *= yuva.w;
color_out.a = yuva.w;
return color_out;

View file

@ -390,6 +390,9 @@ struct gl_shader_config {
union gl_shader_config_color_curve color_pre_curve;
union gl_shader_config_color_mapping color_mapping;
union gl_shader_config_color_curve color_post_curve;
enum weston_color_matrix_coef yuv_coefficients;
enum weston_color_quant_range yuv_range;
};
struct gl_renderer {

View file

@ -49,6 +49,7 @@
#include "timeline.h"
#include "color.h"
#include "color-representation.h"
#include "gl-renderer.h"
#include "gl-renderer-internal.h"
#include "vertex-clipping.h"
@ -63,6 +64,7 @@
#include "shared/platform.h"
#include "shared/string-helpers.h"
#include "shared/timespec-util.h"
#include "shared/weston-assert.h"
#include "shared/weston-drm-fourcc.h"
#include "shared/weston-egl-ext.h"
#include "shared/xalloc.h"
@ -1464,6 +1466,7 @@ prepare_textured_draw(struct gl_shader_config *sconf,
struct gl_buffer_state *gb = gs->buffer;
struct gl_output_state *go = get_output_state(pnode->output);
struct weston_buffer *buffer = gs->buffer_ref.buffer;
struct weston_color_representation color_rep;
GLint filter;
int i;
@ -1508,6 +1511,12 @@ prepare_textured_draw(struct gl_shader_config *sconf,
return false;
}
color_rep =
weston_fill_color_representation(&pnode->surface->color_representation,
buffer->pixel_format);
sconf->yuv_coefficients = color_rep.matrix_coefficients;
sconf->yuv_range = color_rep.quant_range;
return true;
}

View file

@ -34,6 +34,7 @@
#include <string.h>
#include <assert.h>
#include <libweston/color-representation.h>
#include <libweston/libweston.h>
#include <libweston/weston-log.h>
@ -99,6 +100,8 @@ struct gl_shader {
union gl_shader_color_curve_uniforms color_pre_curve;
union gl_shader_color_mapping_uniforms color_mapping;
union gl_shader_color_curve_uniforms color_post_curve;
GLint yuv_offsets_uniform;
GLint yuv_coefficients_uniform;
};
static const char *
@ -503,6 +506,12 @@ gl_shader_create(struct gl_renderer *gr,
case SHADER_COLOR_MAPPING_IDENTITY:
break;
}
shader->yuv_coefficients_uniform =
glGetUniformLocation(shader->program, "yuv_coefficients");
shader->yuv_offsets_uniform = glGetUniformLocation(shader->program,
"yuv_offsets");
free(conf);
wl_list_insert(&gr->shader_list, &shader->link);
@ -752,6 +761,28 @@ gl_shader_load_config_mapping(struct weston_compositor *compositor,
weston_assert_not_reached(compositor, "unknown enum gl_shader_color_mapping value");
}
static void
gl_shader_load_config_representation(struct weston_compositor *compositor,
struct gl_shader *shader,
const struct gl_shader_config *sconf)
{
struct weston_color_representation_matrix cr_matrix;
if (sconf->yuv_coefficients == WESTON_COLOR_MATRIX_COEF_UNSET ||
sconf->yuv_coefficients == WESTON_COLOR_MATRIX_COEF_IDENTITY) {
assert(shader->yuv_coefficients_uniform == -1);
assert(shader->yuv_offsets_uniform == -1);
return;
}
weston_get_color_representation_matrix(compositor,
sconf->yuv_coefficients, sconf->yuv_range, &cr_matrix);
glUniformMatrix3fv(shader->yuv_coefficients_uniform, 1, GL_FALSE,
cr_matrix.matrix.colmaj);
glUniform3fv(shader->yuv_offsets_uniform, 1, cr_matrix.offset.el);
}
bool
gl_shader_texture_variant_can_be_premult(enum gl_shader_texture_variant v)
{
@ -859,6 +890,8 @@ gl_shader_load_config(struct gl_renderer *gr,
&sconf->color_post_curve, &shader->color_post_curve,
TEX_UNIT_COLOR_POST_CURVE);
gl_shader_load_config_representation(gr->compositor, shader, sconf);
if (sconf->req.wireframe)
glUniform1i(shader->tex_uniform_wireframe, TEX_UNIT_WIREFRAME);