From 33ee2c9fb4c9bc6c7b41d32299ba7d9b554bfdbe Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 30 Sep 2025 16:30:42 +0300 Subject: [PATCH] color: make 3x1d.fill_in populate a vec3 array This removes the API impedance mismatch between weston_color_curve_sample() and weston_color_curve_to_3x1D_LUT() that was temporarily introduced in the previous commit. That mismatch is now limited to gl_color_curve_lut_3x1d(). Signed-off-by: Pekka Paalanen --- libweston/backend-drm/drm.c | 14 ++++---- libweston/color-lcms/color-transform.c | 15 ++++---- libweston/color.c | 35 ++++++++----------- libweston/color.h | 10 +++--- .../gl-shader-config-color-transformation.c | 17 ++++++--- 5 files changed, 45 insertions(+), 46 deletions(-) diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index ea12d761c..759b3091f 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -2171,10 +2171,10 @@ drm_colorop_3x1d_lut_create(struct weston_color_transform *xform, return lut; } -static float * +static struct weston_vec3f * lut_3x1d_from_blend_to_output(struct weston_compositor *compositor, struct weston_color_transform *xform, - uint32_t len_lut, char **err_msg) + size_t len_lut, char **err_msg) { /** * We expect steps to be valid for blend-to-output, as LittleCMS is @@ -2220,9 +2220,9 @@ drm_output_pick_blend_to_output(struct drm_output *output) struct drm_colorop_3x1d_lut *colorop_lut; struct weston_color_transform *xform; struct drm_color_lut *drm_lut; - uint64_t lut_size; + size_t lut_size; uint32_t gamma_lut_blob_id; - float *cm_lut; + struct weston_vec3f *cm_lut; char *err_msg; unsigned int i; int ret; @@ -2259,9 +2259,9 @@ drm_output_pick_blend_to_output(struct drm_output *output) drm_lut = xzalloc(lut_size * sizeof(*drm_lut)); for (i = 0; i < lut_size; i++) { - drm_lut[i].red = cm_lut[i] * 0xffff; - drm_lut[i].green = cm_lut[i + lut_size] * 0xffff; - drm_lut[i].blue = cm_lut[i + 2 * lut_size] * 0xffff; + drm_lut[i].red = cm_lut[i].r * 0xffff; + drm_lut[i].green = cm_lut[i].g * 0xffff; + drm_lut[i].blue = cm_lut[i].b * 0xffff; } free(cm_lut); ret = drmModeCreatePropertyBlob(device->drm.fd, drm_lut, lut_size * sizeof(*drm_lut), diff --git a/libweston/color-lcms/color-transform.c b/libweston/color-lcms/color-transform.c index 431f41dae..3321fa262 100644 --- a/libweston/color-lcms/color-transform.c +++ b/libweston/color-lcms/color-transform.c @@ -63,11 +63,8 @@ cmlcms_reasonable_1D_points(void) } static void -fill_in_curves(cmsToneCurve *curves[3], float *values, unsigned len) +fill_in_curves(cmsToneCurve *curves[3], struct weston_vec3f *values, unsigned len) { - float *R_lut = values; - float *G_lut = R_lut + len; - float *B_lut = G_lut + len; unsigned i; cmsFloat32Number x; @@ -77,15 +74,15 @@ fill_in_curves(cmsToneCurve *curves[3], float *values, unsigned len) for (i = 0; i < len; i++) { x = (double)i / (len - 1); - R_lut[i] = cmsEvalToneCurveFloat(curves[0], x); - G_lut[i] = cmsEvalToneCurveFloat(curves[1], x); - B_lut[i] = cmsEvalToneCurveFloat(curves[2], x); + values[i].r = cmsEvalToneCurveFloat(curves[0], x); + values[i].g = cmsEvalToneCurveFloat(curves[1], x); + values[i].b = cmsEvalToneCurveFloat(curves[2], x); } } static void cmlcms_fill_in_pre_curve(struct weston_color_transform *xform_base, - float *values, unsigned len) + struct weston_vec3f *values, unsigned len) { struct cmlcms_color_transform *xform = to_cmlcms_xform(xform_base); @@ -94,7 +91,7 @@ cmlcms_fill_in_pre_curve(struct weston_color_transform *xform_base, static void cmlcms_fill_in_post_curve(struct weston_color_transform *xform_base, - float *values, unsigned len) + struct weston_vec3f *values, unsigned len) { struct cmlcms_color_transform *xform = to_cmlcms_xform(xform_base); diff --git a/libweston/color.c b/libweston/color.c index d2da16e00..5fbe403a3 100644 --- a/libweston/color.c +++ b/libweston/color.c @@ -330,9 +330,9 @@ curve_to_lut_has_good_precision(struct weston_color_curve *curve) * returns a 3x1D LUT that corresponds to such curve. This only works for * transformations such that xform->steps_valid. * - * The 3x1D LUT returned looks like this: the first lut_size elements compose - * the LUT for the R channel, the next lut_size elements compose the LUT for the - * G channel and the last lut_size elements compose the LUT for the B channel. + * The 3x1D LUT is returned as an array of vec3, where each 1D LUT occupies + * one channel of each vector. The first element corresponds to input value + * 0.0, and the last element corresponds to input value 1.0. * * @param compositor The Weston compositor. * @param xform The color transformation that owns the curve. @@ -340,23 +340,24 @@ curve_to_lut_has_good_precision(struct weston_color_curve *curve) * @param precision_mode If WESTON_COLOR_PRECISION_CAREFUL, this fails if we * detect that we can't create a LUT from the curve without resulting in * precision issues. If WESTON_COLOR_PRECISION_CARELESS, we simply log a warning. - * @param lut_size The size of each LUT. + * @param lut_size The length of each LUT, that is, + * the number of vec3 in the returned array. * @param err_msg Set on failure, untouched otherwise. Must be free()'d by caller. - * @return NULL on failure, the 3x1D LUT on success. + * @return NULL on failure, newly allocate array of vec3 on success. Caller must + * free the array. */ -WL_EXPORT float * +WL_EXPORT struct weston_vec3f * weston_color_curve_to_3x1D_LUT(struct weston_compositor *compositor, struct weston_color_transform *xform, enum weston_color_curve_step step, enum weston_color_precision precision_mode, - uint32_t lut_size, char **err_msg) + size_t lut_size, char **err_msg) { struct weston_color_curve *curve; float divider = lut_size - 1; const char *step_str; - float *lut; - struct weston_vec3f *tmp; - unsigned int i; + struct weston_vec3f *lut; + size_t i; switch(step) { case WESTON_COLOR_CURVE_STEP_PRE: @@ -389,12 +390,9 @@ weston_color_curve_to_3x1D_LUT(struct weston_compositor *compositor, "result in bad precision\n", xform->id, step_str); } - lut = calloc(lut_size, 3 * sizeof *lut); - tmp = calloc(lut_size, sizeof *tmp); - if (!lut || !tmp) { + lut = calloc(lut_size, sizeof *lut); + if (!lut) { /* lut_size could be big. */ - free(lut); - free(tmp); str_printf(err_msg, "Out of memory"); return NULL; } @@ -402,17 +400,14 @@ weston_color_curve_to_3x1D_LUT(struct weston_compositor *compositor, switch(curve->type) { case WESTON_COLOR_CURVE_TYPE_LUT_3x1D: curve->u.lut_3x1d.fill_in(xform, lut, lut_size); - free(tmp); return lut; case WESTON_COLOR_CURVE_TYPE_ENUM: case WESTON_COLOR_CURVE_TYPE_PARAMETRIC: for (i = 0; i < lut_size; i++) { float x = (float)i / divider; - tmp[i] = WESTON_VEC3F(x, x, x); + lut[i] = WESTON_VEC3F(x, x, x); } - weston_color_curve_sample(compositor, curve, tmp, tmp, lut_size); - weston_v3f_array_to_planar(lut, tmp, lut_size); - free(tmp); + weston_color_curve_sample(compositor, curve, lut, lut, lut_size); return lut; case WESTON_COLOR_CURVE_TYPE_IDENTITY: weston_assert_not_reached(compositor, diff --git a/libweston/color.h b/libweston/color.h index deef06b01..ac09ae9e1 100644 --- a/libweston/color.h +++ b/libweston/color.h @@ -245,12 +245,12 @@ struct weston_color_curve_lut_3x1d { * * \param xform This color transformation object. * \param len The number of elements in each 1D LUT. - * \param values Array of 3 x len elements. First R channel - * LUT, immediately followed by G channel LUT, and then B channel LUT. + * \param values The destination array of length \c len for + * receiving the three 1D LUTs. */ void (*fill_in)(struct weston_color_transform *xform, - float *values, unsigned len); + struct weston_vec3f *values, unsigned len); /** Optimal 1D LUT length for storage vs. precision */ unsigned optimal_len; @@ -673,12 +673,12 @@ enum weston_color_precision { WESTON_COLOR_PRECISION_CAREFUL, }; -float * +struct weston_vec3f * weston_color_curve_to_3x1D_LUT(struct weston_compositor *compositor, struct weston_color_transform *xform, enum weston_color_curve_step step, enum weston_color_precision precision_mode, - uint32_t lut_size, char **err_msg); + size_t lut_size, char **err_msg); void find_neighbors(struct weston_compositor *compositor, uint32_t len, float *array, diff --git a/libweston/renderer-gl/gl-shader-config-color-transformation.c b/libweston/renderer-gl/gl-shader-config-color-transformation.c index 26fbac6e5..d2fab8e40 100644 --- a/libweston/renderer-gl/gl-shader-config-color-transformation.c +++ b/libweston/renderer-gl/gl-shader-config-color-transformation.c @@ -244,19 +244,26 @@ gl_color_curve_lut_3x1d(struct gl_renderer *gr, const struct weston_color_curve *curve, struct weston_color_transform *xform) { - const unsigned lut_len = curve->u.lut_3x1d.optimal_len; + const size_t lut_len = curve->u.lut_3x1d.optimal_len; + struct weston_vec3f *tmp; float *lut; bool ret; - lut = calloc(lut_len * 3, sizeof *lut); - if (!lut) - return false; + tmp = calloc(lut_len, sizeof *tmp); + lut = calloc(lut_len, 3 * sizeof *lut); + if (!tmp || !lut) { + ret = false; + goto out; + } - curve->u.lut_3x1d.fill_in(xform, lut, lut_len); + curve->u.lut_3x1d.fill_in(xform, tmp, lut_len); + weston_v3f_array_to_planar(lut, tmp, lut_len); ret = gl_color_curve_lut_3x1d_init(gr, gl_curve, lut_len, lut); +out: free(lut); + free(tmp); return ret; }