mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-28 05:40:11 -04:00
render/color: add wlr_color_transform_pipeline
Useful to apply multiple transforms in sequence, e.g. sRGB inverse EOTF followed by gamma LUTs.
This commit is contained in:
parent
3d36ab9211
commit
0b58bddf13
3 changed files with 60 additions and 0 deletions
|
|
@ -9,6 +9,7 @@ enum wlr_color_transform_type {
|
||||||
COLOR_TRANSFORM_INVERSE_EOTF,
|
COLOR_TRANSFORM_INVERSE_EOTF,
|
||||||
COLOR_TRANSFORM_LCMS2,
|
COLOR_TRANSFORM_LCMS2,
|
||||||
COLOR_TRANSFORM_LUT_3X1D,
|
COLOR_TRANSFORM_LUT_3X1D,
|
||||||
|
COLOR_TRANSFORM_PIPELINE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_color_transform {
|
struct wlr_color_transform {
|
||||||
|
|
@ -39,6 +40,13 @@ struct wlr_color_transform_lut_3x1d {
|
||||||
size_t dim;
|
size_t dim;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wlr_color_transform_pipeline {
|
||||||
|
struct wlr_color_transform base;
|
||||||
|
|
||||||
|
struct wlr_color_transform **transforms;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
void wlr_color_transform_init(struct wlr_color_transform *tr,
|
void wlr_color_transform_init(struct wlr_color_transform *tr,
|
||||||
enum wlr_color_transform_type type);
|
enum wlr_color_transform_type type);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,13 @@ struct wlr_color_transform *wlr_color_transform_init_linear_to_inverse_eotf(
|
||||||
struct wlr_color_transform *wlr_color_transform_init_lut_3x1d(size_t dim,
|
struct wlr_color_transform *wlr_color_transform_init_lut_3x1d(size_t dim,
|
||||||
const uint16_t *r, const uint16_t *g, const uint16_t *b);
|
const uint16_t *r, const uint16_t *g, const uint16_t *b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a color transformation to apply a sequence of color transforms
|
||||||
|
* one after another.
|
||||||
|
*/
|
||||||
|
struct wlr_color_transform *wlr_color_transform_init_pipeline(
|
||||||
|
struct wlr_color_transform **transforms, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increase the reference count of the color transform by 1.
|
* Increase the reference count of the color transform by 1.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,33 @@ struct wlr_color_transform *wlr_color_transform_init_lut_3x1d(size_t dim,
|
||||||
return &tx->base;
|
return &tx->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_color_transform *wlr_color_transform_init_pipeline(
|
||||||
|
struct wlr_color_transform **transforms, size_t len) {
|
||||||
|
assert(len > 0);
|
||||||
|
|
||||||
|
struct wlr_color_transform **copy = calloc(len, sizeof(copy[0]));
|
||||||
|
if (copy == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_color_transform_pipeline *tx = calloc(1, sizeof(*tx));
|
||||||
|
if (!tx) {
|
||||||
|
free(copy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wlr_color_transform_init(&tx->base, COLOR_TRANSFORM_PIPELINE);
|
||||||
|
|
||||||
|
// TODO: flatten nested pipeline transforms
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
copy[i] = wlr_color_transform_ref(transforms[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
tx->transforms = copy;
|
||||||
|
tx->len = len;
|
||||||
|
|
||||||
|
return &tx->base;
|
||||||
|
}
|
||||||
|
|
||||||
static void color_transform_destroy(struct wlr_color_transform *tr) {
|
static void color_transform_destroy(struct wlr_color_transform *tr) {
|
||||||
switch (tr->type) {
|
switch (tr->type) {
|
||||||
case COLOR_TRANSFORM_INVERSE_EOTF:
|
case COLOR_TRANSFORM_INVERSE_EOTF:
|
||||||
|
|
@ -73,6 +100,14 @@ static void color_transform_destroy(struct wlr_color_transform *tr) {
|
||||||
struct wlr_color_transform_lut_3x1d *lut_3x1d = color_transform_lut_3x1d_from_base(tr);
|
struct wlr_color_transform_lut_3x1d *lut_3x1d = color_transform_lut_3x1d_from_base(tr);
|
||||||
free(lut_3x1d->lut_3x1d);
|
free(lut_3x1d->lut_3x1d);
|
||||||
break;
|
break;
|
||||||
|
case COLOR_TRANSFORM_PIPELINE:;
|
||||||
|
struct wlr_color_transform_pipeline *pipeline =
|
||||||
|
wl_container_of(tr, pipeline, base);
|
||||||
|
for (size_t i = 0; i < pipeline->len; i++) {
|
||||||
|
wlr_color_transform_unref(pipeline->transforms[i]);
|
||||||
|
}
|
||||||
|
free(pipeline->transforms);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
wlr_addon_set_finish(&tr->addons);
|
wlr_addon_set_finish(&tr->addons);
|
||||||
free(tr);
|
free(tr);
|
||||||
|
|
@ -203,6 +238,16 @@ void wlr_color_transform_eval(struct wlr_color_transform *tr,
|
||||||
case COLOR_TRANSFORM_LUT_3X1D:
|
case COLOR_TRANSFORM_LUT_3X1D:
|
||||||
color_transform_lut_3x1d_eval(color_transform_lut_3x1d_from_base(tr), out, in);
|
color_transform_lut_3x1d_eval(color_transform_lut_3x1d_from_base(tr), out, in);
|
||||||
break;
|
break;
|
||||||
|
case COLOR_TRANSFORM_PIPELINE:;
|
||||||
|
struct wlr_color_transform_pipeline *pipeline =
|
||||||
|
wl_container_of(tr, pipeline, base);
|
||||||
|
float color[3];
|
||||||
|
memcpy(color, in, sizeof(color));
|
||||||
|
for (size_t i = 0; i < pipeline->len; i++) {
|
||||||
|
wlr_color_transform_eval(pipeline->transforms[i], color, color);
|
||||||
|
}
|
||||||
|
memcpy(out, color, sizeof(color));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue