mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-14 08:22:25 -04:00
Merge branch 'edid-color-metadata' into 'master'
Draft: output, backend/drm: add wlr_output.color_primaries See merge request wlroots/wlroots!5096
This commit is contained in:
commit
58a9c3b1c2
7 changed files with 60 additions and 3 deletions
|
|
@ -50,6 +50,14 @@ enum wlr_output_mode_aspect_ratio get_picture_aspect_ratio(const drmModeModeInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void copy_chromaticity_cie1931(struct wlr_color_cie1931_xy *dst,
|
||||||
|
const struct di_chromaticity_cie1931 *src) {
|
||||||
|
*dst = (struct wlr_color_cie1931_xy){
|
||||||
|
.x = src->x,
|
||||||
|
.y = src->y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) {
|
void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) {
|
||||||
struct wlr_output *output = &conn->output;
|
struct wlr_output *output = &conn->output;
|
||||||
|
|
||||||
|
|
@ -83,6 +91,15 @@ void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data)
|
||||||
output->model = di_info_get_model(info);
|
output->model = di_info_get_model(info);
|
||||||
output->serial = di_info_get_serial(info);
|
output->serial = di_info_get_serial(info);
|
||||||
|
|
||||||
|
const struct di_color_primaries *primaries = di_info_get_default_color_primaries(info);
|
||||||
|
if (primaries->has_primaries && primaries->has_default_white_point) {
|
||||||
|
copy_chromaticity_cie1931(&conn->color_primaries.red, &primaries->primary[0]);
|
||||||
|
copy_chromaticity_cie1931(&conn->color_primaries.green, &primaries->primary[1]);
|
||||||
|
copy_chromaticity_cie1931(&conn->color_primaries.blue, &primaries->primary[2]);
|
||||||
|
copy_chromaticity_cie1931(&conn->color_primaries.white, &primaries->default_white);
|
||||||
|
output->color_primaries = &conn->color_primaries;
|
||||||
|
}
|
||||||
|
|
||||||
const struct di_supported_signal_colorimetry *colorimetry = di_info_get_supported_signal_colorimetry(info);
|
const struct di_supported_signal_colorimetry *colorimetry = di_info_get_supported_signal_colorimetry(info);
|
||||||
bool has_bt2020 = colorimetry->bt2020_cycc || colorimetry->bt2020_ycc || colorimetry->bt2020_rgb;
|
bool has_bt2020 = colorimetry->bt2020_cycc || colorimetry->bt2020_ycc || colorimetry->bt2020_rgb;
|
||||||
if (conn->props.colorspace != 0 && has_bt2020) {
|
if (conn->props.colorspace != 0 && has_bt2020) {
|
||||||
|
|
@ -93,6 +110,9 @@ void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data)
|
||||||
if (conn->props.hdr_output_metadata != 0 && hdr_static_metadata->type1 && hdr_static_metadata->pq) {
|
if (conn->props.hdr_output_metadata != 0 && hdr_static_metadata->type1 && hdr_static_metadata->pq) {
|
||||||
output->supported_transfer_functions |= WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ;
|
output->supported_transfer_functions |= WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ;
|
||||||
}
|
}
|
||||||
|
output->min_luminance = hdr_static_metadata->desired_content_min_luminance;
|
||||||
|
output->max_luminance = hdr_static_metadata->desired_content_max_luminance;
|
||||||
|
output->max_fall = hdr_static_metadata->desired_content_max_frame_avg_luminance;
|
||||||
|
|
||||||
di_info_destroy(info);
|
di_info_destroy(info);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,7 @@ struct wlr_drm_connector {
|
||||||
drmModeConnection status;
|
drmModeConnection status;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint64_t max_bpc_bounds[2];
|
uint64_t max_bpc_bounds[2];
|
||||||
|
struct wlr_color_primaries color_primaries; // might be zero
|
||||||
struct wlr_drm_lease *lease;
|
struct wlr_drm_lease *lease;
|
||||||
|
|
||||||
struct wlr_drm_crtc *crtc;
|
struct wlr_drm_crtc *crtc;
|
||||||
|
|
|
||||||
|
|
@ -426,6 +426,9 @@ struct wlr_vk_render_pass {
|
||||||
bool has_primaries;
|
bool has_primaries;
|
||||||
struct wlr_color_primaries primaries;
|
struct wlr_color_primaries primaries;
|
||||||
|
|
||||||
|
bool has_luminances;
|
||||||
|
struct wlr_color_luminances luminances;
|
||||||
|
|
||||||
struct wlr_drm_syncobj_timeline *signal_timeline;
|
struct wlr_drm_syncobj_timeline *signal_timeline;
|
||||||
uint64_t signal_point;
|
uint64_t signal_point;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ struct wlr_buffer_pass_options {
|
||||||
struct wlr_color_transform *color_transform;
|
struct wlr_color_transform *color_transform;
|
||||||
/** Primaries describing the color volume of the destination buffer */
|
/** Primaries describing the color volume of the destination buffer */
|
||||||
const struct wlr_color_primaries *primaries;
|
const struct wlr_color_primaries *primaries;
|
||||||
|
/** Luminances for the destination buffer */
|
||||||
|
const struct wlr_color_luminances *luminances;
|
||||||
|
|
||||||
/* Signal a timeline synchronization point when the render pass completes.
|
/* Signal a timeline synchronization point when the render pass completes.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,9 @@ struct wlr_output {
|
||||||
uint32_t supported_primaries; // bitfield of enum wlr_color_named_primaries
|
uint32_t supported_primaries; // bitfield of enum wlr_color_named_primaries
|
||||||
uint32_t supported_transfer_functions; // bitfield of enum wlr_color_transfer_function
|
uint32_t supported_transfer_functions; // bitfield of enum wlr_color_transfer_function
|
||||||
|
|
||||||
|
const struct wlr_color_primaries *color_primaries; // NULL if unset
|
||||||
|
float min_luminance, max_luminance, max_fall; // cd/m², zero if unset
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
float scale;
|
float scale;
|
||||||
enum wl_output_subpixel subpixel;
|
enum wl_output_subpixel subpixel;
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,11 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
||||||
struct wlr_color_luminances srgb_lum, dst_lum;
|
struct wlr_color_luminances srgb_lum, dst_lum;
|
||||||
wlr_color_transfer_function_get_default_luminance(
|
wlr_color_transfer_function_get_default_luminance(
|
||||||
WLR_COLOR_TRANSFER_FUNCTION_SRGB, &srgb_lum);
|
WLR_COLOR_TRANSFER_FUNCTION_SRGB, &srgb_lum);
|
||||||
wlr_color_transfer_function_get_default_luminance(tf, &dst_lum);
|
if (pass->has_luminances) {
|
||||||
|
dst_lum = pass->luminances;
|
||||||
|
} else {
|
||||||
|
wlr_color_transfer_function_get_default_luminance(tf, &dst_lum);
|
||||||
|
}
|
||||||
frag_pcr_data.luminance_multiplier = get_luminance_multiplier(&srgb_lum, &dst_lum);
|
frag_pcr_data.luminance_multiplier = get_luminance_multiplier(&srgb_lum, &dst_lum);
|
||||||
}
|
}
|
||||||
bind_pipeline(pass, pipeline);
|
bind_pipeline(pass, pipeline);
|
||||||
|
|
@ -1243,6 +1247,10 @@ struct wlr_vk_render_pass *vulkan_begin_render_pass(struct wlr_vk_renderer *rend
|
||||||
pass->has_primaries = true;
|
pass->has_primaries = true;
|
||||||
pass->primaries = *options->primaries;
|
pass->primaries = *options->primaries;
|
||||||
}
|
}
|
||||||
|
if (options != NULL && options->luminances != NULL) {
|
||||||
|
pass->has_luminances = true;
|
||||||
|
pass->luminances = *options->luminances;
|
||||||
|
}
|
||||||
|
|
||||||
rect_union_init(&pass->updated_region);
|
rect_union_init(&pass->updated_region);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2359,12 +2359,31 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
|
|
||||||
struct wlr_color_transform *color_transform = NULL;
|
struct wlr_color_transform *color_transform = NULL;
|
||||||
const struct wlr_color_primaries *primaries = NULL;
|
const struct wlr_color_primaries *primaries = NULL;
|
||||||
|
const struct wlr_color_luminances *target_luminances = NULL;
|
||||||
struct wlr_color_primaries primaries_value;
|
struct wlr_color_primaries primaries_value;
|
||||||
|
struct wlr_color_luminances target_luminances_value;
|
||||||
const struct wlr_output_image_description *img_desc = output_pending_image_description(output, state);
|
const struct wlr_output_image_description *img_desc = output_pending_image_description(output, state);
|
||||||
if (img_desc != NULL) {
|
if (img_desc != NULL) {
|
||||||
color_transform = wlr_color_transform_init_linear_to_inverse_eotf(img_desc->transfer_function);
|
color_transform = wlr_color_transform_init_linear_to_inverse_eotf(img_desc->transfer_function);
|
||||||
wlr_color_primaries_from_named(&primaries_value, img_desc->primaries);
|
|
||||||
primaries = &primaries_value;
|
struct wlr_color_primaries zero_primaries = {0};
|
||||||
|
if (memcmp(&img_desc->mastering_display_primaries, &zero_primaries, sizeof(zero_primaries)) != 0) {
|
||||||
|
primaries = &img_desc->mastering_display_primaries;
|
||||||
|
} else {
|
||||||
|
wlr_color_primaries_from_named(&primaries_value, img_desc->primaries);
|
||||||
|
primaries = &primaries_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (img_desc->mastering_luminance.min != 0 || img_desc->mastering_luminance.max != 0) {
|
||||||
|
struct wlr_color_luminances default_lum = {0};
|
||||||
|
wlr_color_transfer_function_get_default_luminance(img_desc->transfer_function, &default_lum);
|
||||||
|
target_luminances_value = (struct wlr_color_luminances){
|
||||||
|
.min = img_desc->mastering_luminance.min,
|
||||||
|
.max = img_desc->mastering_luminance.max,
|
||||||
|
.reference = default_lum.reference, // TODO: make configurable
|
||||||
|
};
|
||||||
|
target_luminances = &target_luminances_value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (options->color_transform != NULL) {
|
if (options->color_transform != NULL) {
|
||||||
assert(color_transform == NULL);
|
assert(color_transform == NULL);
|
||||||
|
|
@ -2388,6 +2407,7 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
.timer = timer ? timer->render_timer : NULL,
|
.timer = timer ? timer->render_timer : NULL,
|
||||||
.color_transform = color_transform,
|
.color_transform = color_transform,
|
||||||
.primaries = primaries,
|
.primaries = primaries,
|
||||||
|
.luminances = target_luminances,
|
||||||
.signal_timeline = scene_output->in_timeline,
|
.signal_timeline = scene_output->in_timeline,
|
||||||
.signal_point = scene_output->in_point,
|
.signal_point = scene_output->in_point,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue