diff --git a/include/render/vulkan.h b/include/render/vulkan.h index ac0af65fb..bb56b5534 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -372,7 +372,6 @@ struct wlr_vk_frag_texture_pcr_data { struct wlr_vk_frag_output_pcr_data { float matrix[4][4]; // only a 3x3 subset is used - float luminance_multiplier; float lut_3d_offset; float lut_3d_scale; }; diff --git a/include/wlr/render/pass.h b/include/wlr/render/pass.h index 1ef888f46..61ab77132 100644 --- a/include/wlr/render/pass.h +++ b/include/wlr/render/pass.h @@ -109,6 +109,8 @@ struct wlr_render_texture_options { enum wlr_color_encoding color_encoding; /* Color range of the source texture */ enum wlr_color_range color_range; + /* Default: 1.0 */ + const float *luminance_multiplier; /* Wait for a timeline synchronization point before texturing. * diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index db7a659d6..31f5116bd 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -146,11 +146,6 @@ static VkSemaphore render_pass_wait_sync_file(struct wlr_vk_render_pass *pass, return *sem_ptr; } -static float get_luminance_multiplier(const struct wlr_color_luminances *src_lum, - const struct wlr_color_luminances *dst_lum) { - return (dst_lum->reference / src_lum->reference) * (src_lum->max / dst_lum->max); -} - static bool unwrap_color_transform(struct wlr_color_transform *transform, float matrix[static 9], enum wlr_color_transfer_function *tf) { if (transform == NULL) { @@ -248,7 +243,6 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { } struct wlr_vk_frag_output_pcr_data frag_pcr_data = { - .luminance_multiplier = 1, .lut_3d_offset = 0.5f / dim, .lut_3d_scale = (float)(dim - 1) / dim, }; @@ -276,12 +270,6 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { pipeline = render_buffer->two_pass.render_setup->output_pipe_bt1886; break; } - - struct wlr_color_luminances srgb_lum, dst_lum; - wlr_color_transfer_function_get_default_luminance( - WLR_COLOR_TRANSFER_FUNCTION_SRGB, &srgb_lum); - wlr_color_transfer_function_get_default_luminance(tf, &dst_lum); - frag_pcr_data.luminance_multiplier = get_luminance_multiplier(&srgb_lum, &dst_lum); } bind_pipeline(pass, pipeline); vkCmdPushConstants(render_cb->vk, renderer->output_pipe_layout, @@ -883,13 +871,8 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, } float luminance_multiplier = 1; - if (tf != WLR_COLOR_TRANSFER_FUNCTION_SRGB - && tf != WLR_COLOR_TRANSFER_FUNCTION_GAMMA22) { - struct wlr_color_luminances src_lum, srgb_lum; - wlr_color_transfer_function_get_default_luminance(tf, &src_lum); - wlr_color_transfer_function_get_default_luminance( - WLR_COLOR_TRANSFER_FUNCTION_SRGB, &srgb_lum); - luminance_multiplier = get_luminance_multiplier(&src_lum, &srgb_lum); + if (options->luminance_multiplier != NULL) { + luminance_multiplier = *options->luminance_multiplier; } struct wlr_vk_frag_texture_pcr_data frag_pcr_data = { diff --git a/render/vulkan/shaders/output.frag b/render/vulkan/shaders/output.frag index 0a8d9b855..e63de802f 100644 --- a/render/vulkan/shaders/output.frag +++ b/render/vulkan/shaders/output.frag @@ -10,7 +10,6 @@ layout(location = 0) out vec4 out_color; /* struct wlr_vk_frag_output_pcr_data */ layout(push_constant, row_major) uniform UBO { layout(offset = 80) mat4 matrix; - float luminance_multiplier; float lut_3d_offset; float lut_3d_scale; } data; @@ -71,8 +70,6 @@ void main() { rgb = in_color.rgb / alpha; } - rgb *= data.luminance_multiplier; - rgb = mat3(data.matrix) * rgb; if (OUTPUT_TRANSFORM != OUTPUT_TRANSFORM_IDENTITY) { diff --git a/types/output/cursor.c b/types/output/cursor.c index 8a7f9e92a..11f442cdf 100644 --- a/types/output/cursor.c +++ b/types/output/cursor.c @@ -512,6 +512,15 @@ bool output_cursor_refresh_color_transform(struct wlr_output_cursor *output_curs wlr_color_primaries_from_named(&primaries, img_desc->primaries); float matrix[9]; wlr_color_primaries_transform_absolute_colorimetric(&primaries_srgb, &primaries, matrix); + + // Source is sRGB, which has reference == max + struct wlr_color_luminances dst_lum; + wlr_color_transfer_function_get_default_luminance(img_desc->transfer_function, &dst_lum); + float luminance_multiplier = dst_lum.reference / dst_lum.max; + for (int i = 0; i < 9; ++i) { + matrix[i] *= luminance_multiplier; + } + struct wlr_color_transform *transforms[] = { wlr_color_transform_init_matrix(matrix), wlr_color_transform_init_linear_to_inverse_eotf(img_desc->transfer_function), diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index e7d628d01..19617b11f 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -1435,6 +1435,11 @@ struct render_list_entry { int x, y; }; +static float get_luminance_multiplier(const struct wlr_color_luminances *src_lum, + const struct wlr_color_luminances *dst_lum) { + return (dst_lum->reference / src_lum->reference) * (src_lum->max / dst_lum->max); +} + static void scene_entry_render(struct render_list_entry *entry, const struct render_data *data) { struct wlr_scene_node *node = entry->node; @@ -1518,6 +1523,13 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren wlr_color_primaries_from_named(&primaries, scene_buffer->primaries); } + struct wlr_color_luminances src_lum, srgb_lum; + wlr_color_transfer_function_get_default_luminance( + scene_buffer->transfer_function, &src_lum); + wlr_color_transfer_function_get_default_luminance( + WLR_COLOR_TRANSFER_FUNCTION_SRGB, &srgb_lum); + float luminance_multiplier = get_luminance_multiplier(&src_lum, &srgb_lum); + wlr_render_pass_add_texture(data->render_pass, &(struct wlr_render_texture_options) { .texture = texture, .src_box = scene_buffer->src_box, @@ -1533,6 +1545,7 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren .primaries = scene_buffer->primaries != 0 ? &primaries : NULL, .color_encoding = scene_buffer->color_encoding, .color_range = scene_buffer->color_range, + .luminance_multiplier = &luminance_multiplier, .wait_timeline = scene_buffer->wait_timeline, .wait_point = scene_buffer->wait_point, }); @@ -2208,6 +2221,16 @@ static bool scene_output_combine_color_transforms( wlr_color_primaries_from_named(&primaries, img_desc->primaries); float matrix[9]; wlr_color_primaries_transform_absolute_colorimetric(&primaries_srgb, &primaries, matrix); + + struct wlr_color_luminances srgb_lum, dst_lum; + wlr_color_transfer_function_get_default_luminance( + WLR_COLOR_TRANSFER_FUNCTION_SRGB, &srgb_lum); + wlr_color_transfer_function_get_default_luminance(img_desc->transfer_function, &dst_lum); + float luminance_multiplier = get_luminance_multiplier(&srgb_lum, &dst_lum); + for (int i = 0; i < 9; ++i) { + matrix[i] *= luminance_multiplier; + } + color_matrix = wlr_color_transform_init_matrix(matrix); inv_eotf = wlr_color_transform_init_linear_to_inverse_eotf(img_desc->transfer_function); if (color_matrix == NULL || inv_eotf == NULL) {