diff --git a/include/render/color.h b/include/render/color.h index e18f12ee..4ab587be 100644 --- a/include/render/color.h +++ b/include/render/color.h @@ -4,6 +4,18 @@ #include #include +enum wlr_color_transform_type { + COLOR_TRANSFORM_SRGB, + COLOR_TRANSFORM_LUT_3D, +}; + +struct wlr_color_transform { + int ref_count; + struct wlr_addon_set addons; // per-renderer helper state + + enum wlr_color_transform_type type; +}; + /** * The formula is approximated via a 3D look-up table. A 3D LUT is a * three-dimensional array where each element is an RGB triplet. The flat lut_3d @@ -19,21 +31,17 @@ * offset = 3 * (r_index + dim_len * g_index + dim_len * dim_len * b_index) */ struct wlr_color_transform_lut3d { + struct wlr_color_transform base; + float *lut_3d; size_t dim_len; }; -enum wlr_color_transform_type { - COLOR_TRANSFORM_SRGB, - COLOR_TRANSFORM_LUT_3D, -}; - -struct wlr_color_transform { - int ref_count; - struct wlr_addon_set addons; // per-renderer helper state - - enum wlr_color_transform_type type; - struct wlr_color_transform_lut3d lut3d; -}; +/** + * Gets a wlr_color_transform_lut3d from a generic wlr_color_transform. + * Asserts that the base type is COLOR_TRANSFORM_LUT_3D + */ +struct wlr_color_transform_lut3d *wlr_color_transform_lut3d_from_base( + struct wlr_color_transform *tr); #endif diff --git a/render/color.c b/render/color.c index e68c2d50..9f8d76b0 100644 --- a/render/color.c +++ b/render/color.c @@ -15,7 +15,15 @@ struct wlr_color_transform *wlr_color_transform_init_srgb(void) { } static void color_transform_destroy(struct wlr_color_transform *tr) { - free(tr->lut3d.lut_3d); + switch (tr->type) { + case COLOR_TRANSFORM_SRGB: + break; + case COLOR_TRANSFORM_LUT_3D:; + struct wlr_color_transform_lut3d *lut3d = + wlr_color_transform_lut3d_from_base(tr); + free(lut3d->lut_3d); + break; + } wlr_addon_set_finish(&tr->addons); free(tr); } @@ -35,3 +43,10 @@ void wlr_color_transform_unref(struct wlr_color_transform *tr) { color_transform_destroy(tr); } } + +struct wlr_color_transform_lut3d *wlr_color_transform_lut3d_from_base( + struct wlr_color_transform *tr) { + assert(tr->type == COLOR_TRANSFORM_LUT_3D); + struct wlr_color_transform_lut3d *lut3d = wl_container_of(tr, lut3d, base); + return lut3d; +} diff --git a/render/color_lcms2.c b/render/color_lcms2.c index fae4fb6a..c0f4db81 100644 --- a/render/color_lcms2.c +++ b/render/color_lcms2.c @@ -18,7 +18,7 @@ static void handle_lcms_error(cmsContext ctx, cmsUInt32Number code, const char * struct wlr_color_transform *wlr_color_transform_init_linear_to_icc( const void *data, size_t size) { - struct wlr_color_transform *tx = NULL; + struct wlr_color_transform_lut3d *tx = NULL; cmsContext ctx = cmsCreateContext(NULL, NULL); if (ctx == NULL) { @@ -95,15 +95,15 @@ struct wlr_color_transform *wlr_color_transform_init_linear_to_icc( } } - tx = calloc(1, sizeof(struct wlr_color_transform)); + tx = calloc(1, sizeof(struct wlr_color_transform_lut3d)); if (!tx) { goto out_lcms_tr; } - tx->type = COLOR_TRANSFORM_LUT_3D; - tx->lut3d.dim_len = dim_len; - tx->lut3d.lut_3d = lut_3d; - tx->ref_count = 1; - wlr_addon_set_init(&tx->addons); + tx->base.type = COLOR_TRANSFORM_LUT_3D; + tx->dim_len = dim_len; + tx->lut_3d = lut_3d; + tx->base.ref_count = 1; + wlr_addon_set_init(&tx->base.addons); out_lcms_tr: cmsDeleteTransform(lcms_tr); @@ -115,5 +115,5 @@ out_icc_profile: cmsCloseProfile(icc_profile); out_ctx: cmsDeleteContext(ctx); - return tx; + return &tx->base; } diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index 5820cf9d..8e1807df 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -116,7 +116,14 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { .uv_off = { 0, 0 }, .uv_size = { 1, 1 }, }; - size_t dim = pass->color_transform ? pass->color_transform->lut3d.dim_len : 1; + + size_t dim = 1; + if (pass->color_transform && pass->color_transform->type == COLOR_TRANSFORM_LUT_3D) { + struct wlr_color_transform_lut3d *lut3d = + wlr_color_transform_lut3d_from_base(pass->color_transform); + dim = lut3d->dim_len; + } + struct wlr_vk_frag_output_pcr_data frag_pcr_data = { .lut_3d_offset = 0.5f / dim, .lut_3d_scale = (float)(dim - 1) / dim, @@ -894,7 +901,8 @@ static struct wlr_vk_color_transform *vk_color_transform_create( } if (transform->type == COLOR_TRANSFORM_LUT_3D) { - if (!create_3d_lut_image(renderer, &transform->lut3d, + if (!create_3d_lut_image(renderer, + wlr_color_transform_lut3d_from_base(transform), &vk_transform->lut_3d.image, &vk_transform->lut_3d.image_view, &vk_transform->lut_3d.memory,