mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-13 08:22:16 -04:00
color_management_v1: implement set_luminances
v2: Fix coding errors v3: Fall back to default luminances if not set v4: Return luminances, with override max for PQ
This commit is contained in:
parent
fd870f6d27
commit
5994c3d055
5 changed files with 86 additions and 8 deletions
|
|
@ -12,6 +12,7 @@
|
|||
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
|
||||
#include <wlr/util/transform.h>
|
||||
#include "types/wlr_scene.h"
|
||||
#include "render/color.h"
|
||||
|
||||
static double get_surface_preferred_buffer_scale(struct wlr_surface *surface) {
|
||||
double scale = 1;
|
||||
|
|
@ -278,11 +279,14 @@ static void surface_reconfigure(struct wlr_scene_surface *scene_surface) {
|
|||
|
||||
enum wlr_color_transfer_function tf = WLR_COLOR_TRANSFER_FUNCTION_GAMMA22;
|
||||
enum wlr_color_named_primaries primaries = WLR_COLOR_NAMED_PRIMARIES_SRGB;
|
||||
struct wlr_color_luminances luminances;
|
||||
wlr_color_transfer_function_get_default_luminance(tf, &luminances);
|
||||
const struct wlr_image_description_v1_data *img_desc =
|
||||
wlr_surface_get_image_description_v1_data(surface);
|
||||
if (img_desc != NULL) {
|
||||
tf = wlr_color_manager_v1_transfer_function_to_wlr(img_desc->tf_named);
|
||||
primaries = wlr_color_manager_v1_primaries_to_wlr(img_desc->primaries_named);
|
||||
wlr_color_manager_v1_get_luminances(img_desc, &luminances);
|
||||
}
|
||||
|
||||
enum wlr_color_encoding color_encoding = WLR_COLOR_ENCODING_NONE;
|
||||
|
|
@ -307,6 +311,7 @@ static void surface_reconfigure(struct wlr_scene_surface *scene_surface) {
|
|||
wlr_scene_buffer_set_primaries(scene_buffer, primaries);
|
||||
wlr_scene_buffer_set_color_encoding(scene_buffer, color_encoding);
|
||||
wlr_scene_buffer_set_color_range(scene_buffer, color_range);
|
||||
wlr_scene_buffer_set_luminances(scene_buffer, &luminances);
|
||||
|
||||
scene_buffer_unmark_client_buffer(scene_buffer);
|
||||
|
||||
|
|
|
|||
|
|
@ -1148,6 +1148,20 @@ void wlr_scene_buffer_set_color_range(struct wlr_scene_buffer *scene_buffer,
|
|||
scene_node_update(&scene_buffer->node, NULL);
|
||||
}
|
||||
|
||||
void wlr_scene_buffer_set_luminances(struct wlr_scene_buffer *scene_buffer,
|
||||
const struct wlr_color_luminances *lum) {
|
||||
if (scene_buffer->has_luminances &&
|
||||
scene_buffer->luminances.min == lum->min &&
|
||||
scene_buffer->luminances.max == lum->max &&
|
||||
scene_buffer->luminances.reference == lum->reference) {
|
||||
return;
|
||||
}
|
||||
|
||||
scene_buffer->has_luminances = true;
|
||||
scene_buffer->luminances = *lum;
|
||||
scene_node_update(&scene_buffer->node, NULL);
|
||||
}
|
||||
|
||||
static struct wlr_texture *scene_buffer_get_texture(
|
||||
struct wlr_scene_buffer *scene_buffer, struct wlr_renderer *renderer) {
|
||||
if (scene_buffer->buffer == NULL || scene_buffer->texture != NULL) {
|
||||
|
|
@ -1495,8 +1509,12 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren
|
|||
}
|
||||
|
||||
struct wlr_color_luminances src_lum, srgb_lum;
|
||||
wlr_color_transfer_function_get_default_luminance(
|
||||
scene_buffer->transfer_function, &src_lum);
|
||||
if (scene_buffer->has_luminances) {
|
||||
src_lum = scene_buffer->luminances;
|
||||
} else {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ static bool img_desc_data_equal(const struct wlr_image_description_v1_data *a,
|
|||
a->primaries_named != b->primaries_named ||
|
||||
a->has_mastering_display_primaries != b->has_mastering_display_primaries ||
|
||||
a->has_mastering_luminance != b->has_mastering_luminance ||
|
||||
a->has_luminances != b->has_luminances ||
|
||||
a->max_cll != b->max_cll ||
|
||||
a->max_fall != b->max_fall) {
|
||||
return false;
|
||||
|
|
@ -106,6 +107,12 @@ static bool img_desc_data_equal(const struct wlr_image_description_v1_data *a,
|
|||
a->mastering_luminance.max != b->mastering_luminance.max)) {
|
||||
return false;
|
||||
}
|
||||
if (a->has_luminances &&
|
||||
(a->luminances.min != b->luminances.min ||
|
||||
a->luminances.max != b->luminances.max ||
|
||||
a->luminances.reference != b->luminances.reference)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -146,8 +153,7 @@ static void image_desc_handle_get_information(struct wl_client *client,
|
|||
wlr_color_manager_v1_primaries_to_wlr(image_desc->data.primaries_named));
|
||||
|
||||
struct wlr_color_luminances luminances;
|
||||
wlr_color_transfer_function_get_default_luminance(
|
||||
wlr_color_manager_v1_transfer_function_to_wlr(image_desc->data.tf_named), &luminances);
|
||||
wlr_color_manager_v1_get_luminances(&image_desc->data, &luminances);
|
||||
|
||||
wp_image_description_info_v1_send_primaries_named(resource, image_desc->data.primaries_named);
|
||||
wp_image_description_info_v1_send_primaries(resource,
|
||||
|
|
@ -608,9 +614,33 @@ static void image_desc_creator_params_handle_set_primaries(struct wl_client *cli
|
|||
static void image_desc_creator_params_handle_set_luminances(struct wl_client *client,
|
||||
struct wl_resource *params_resource, uint32_t min_lum,
|
||||
uint32_t max_lum, uint32_t reference_lum) {
|
||||
wl_resource_post_error(params_resource,
|
||||
WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_UNSUPPORTED_FEATURE,
|
||||
"set_luminances is not supported");
|
||||
struct wlr_image_description_creator_params_v1 *params =
|
||||
image_desc_creator_params_from_resource(params_resource);
|
||||
if (!params->manager->features.set_luminances) {
|
||||
wl_resource_post_error(params_resource,
|
||||
WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_UNSUPPORTED_FEATURE,
|
||||
"set_luminances is not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params->data.has_luminances) {
|
||||
wl_resource_post_error(params_resource,
|
||||
WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_ALREADY_SET,
|
||||
"luminances already set");
|
||||
return;
|
||||
}
|
||||
|
||||
params->data.has_luminances = true;
|
||||
params->data.luminances.min = (float)min_lum / 10000;
|
||||
params->data.luminances.max = max_lum;
|
||||
params->data.luminances.reference = reference_lum;
|
||||
|
||||
if (params->data.luminances.max <= params->data.luminances.min) {
|
||||
wl_resource_post_error(params_resource,
|
||||
WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_INVALID_LUMINANCE,
|
||||
"max luminance must be greater than min luminance");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void image_desc_creator_params_handle_set_mastering_display_primaries(
|
||||
|
|
@ -972,7 +1002,6 @@ struct wlr_color_manager_v1 *wlr_color_manager_v1_create(struct wl_display *disp
|
|||
assert(!options->features.icc_v2_v4);
|
||||
assert(!options->features.set_primaries);
|
||||
assert(!options->features.set_tf_power);
|
||||
assert(!options->features.set_luminances);
|
||||
assert(!options->features.extended_target_volume);
|
||||
assert(!options->features.windows_scrgb);
|
||||
|
||||
|
|
@ -1159,3 +1188,17 @@ wlr_color_manager_v1_primaries_list_from_renderer(struct wlr_renderer *renderer,
|
|||
*len = sizeof(list) / sizeof(list[0]);
|
||||
return out;
|
||||
}
|
||||
|
||||
void wlr_color_manager_v1_get_luminances(const struct wlr_image_description_v1_data *img_desc,
|
||||
struct wlr_color_luminances *lum) {
|
||||
if (img_desc->has_luminances) {
|
||||
*lum = img_desc->luminances;
|
||||
if (img_desc->tf_named == WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ) {
|
||||
lum->max = lum->min + 10000;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_color_transfer_function_get_default_luminance(
|
||||
wlr_color_manager_v1_transfer_function_to_wlr(img_desc->tf_named), lum);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue