diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 01c4e4d7..ceaca6a9 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -247,6 +247,63 @@ struct weston_CIExy { float y; }; +enum weston_hdr_metadata_type1_groups { + /** weston_hdr_metadata_type1::primary is set */ + WESTON_HDR_METADATA_TYPE1_GROUP_PRIMARIES = 0x01, + + /** weston_hdr_metadata_type1::white is set */ + WESTON_HDR_METADATA_TYPE1_GROUP_WHITE = 0x02, + + /** weston_hdr_metadata_type1::maxDML is set */ + WESTON_HDR_METADATA_TYPE1_GROUP_MAXDML = 0x04, + + /** weston_hdr_metadata_type1::minDML is set */ + WESTON_HDR_METADATA_TYPE1_GROUP_MINDML = 0x08, + + /** weston_hdr_metadata_type1::maxCLL is set */ + WESTON_HDR_METADATA_TYPE1_GROUP_MAXCLL = 0x10, + + /** weston_hdr_metadata_type1::maxFALL is set */ + WESTON_HDR_METADATA_TYPE1_GROUP_MAXFALL = 0x20, + + /** all valid bits */ + WESTON_HDR_METADATA_TYPE1_GROUP_ALL_MASK = 0x3f +}; + +/** HDR static metadata type 1 + * + * The fields are defined by CTA-861-G except here they use float encoding. + * + * In Weston used only with HDR display modes. + */ +struct weston_hdr_metadata_type1 { + /** Which fields are valid + * + * A bitmask of values from enum weston_hdr_metadata_type1_groups. + */ + uint32_t group_mask; + + /* EOTF is tracked externally with enum weston_eotf_mode */ + + /** Chromaticities of the primaries, in any order */ + struct weston_CIExy primary[3]; + + /** White point chromaticity */ + struct weston_CIExy white; + + /** Maximum display mastering luminance, 1 - 65535 cd/m² */ + float maxDML; + + /** Minimum display mastering luminance, 0.0001 - 6.5535 cd/m² */ + float minDML; + + /** Maximum content light level, 1 - 65535 cd/m² */ + float maxCLL; + + /** Maximum frame-average light level, 1 - 65535 cd/m² */ + float maxFALL; +}; + enum weston_color_characteristics_groups { /** weston_color_characteristics::primary is set */ WESTON_COLOR_CHARACTERISTICS_GROUP_PRIMARIES = 0x01, @@ -358,6 +415,9 @@ struct weston_output_color_outcome { /** Blending to output color space transformation */ struct weston_color_transform *from_blend_to_output; + + /** HDR Static Metadata Type 1 for WESTON_EOTF_MODE_ST2084 */ + struct weston_hdr_metadata_type1 hdr_meta; }; /** Content producer for heads diff --git a/libweston/backend.h b/libweston/backend.h index 26624cf9..2374b17b 100644 --- a/libweston/backend.h +++ b/libweston/backend.h @@ -32,6 +32,8 @@ #ifndef LIBWESTON_BACKEND_INTERNAL_H #define LIBWESTON_BACKEND_INTERNAL_H +struct weston_hdr_metadata_type1; + struct weston_backend { void (*destroy)(struct weston_compositor *compositor); @@ -173,6 +175,9 @@ void weston_output_region_from_global(struct weston_output *output, pixman_region32_t *region); +const struct weston_hdr_metadata_type1 * +weston_output_get_hdr_metadata_type1(const struct weston_output *output); + /* weston_seat */ void diff --git a/libweston/color-lcms/color-lcms.c b/libweston/color-lcms/color-lcms.c index 005cbc9d..f8d44530 100644 --- a/libweston/color-lcms/color-lcms.c +++ b/libweston/color-lcms/color-lcms.c @@ -208,6 +208,8 @@ cmlcms_create_output_color_outcome(struct weston_color_manager *cm_base, &co->from_sRGB_to_output)) goto out_fail; + co->hdr_meta.group_mask = 0; + return co; out_fail: diff --git a/libweston/color-noop.c b/libweston/color-noop.c index 2e1461f3..4bd1e762 100644 --- a/libweston/color-noop.c +++ b/libweston/color-noop.c @@ -116,6 +116,8 @@ cmnoop_create_output_color_outcome(struct weston_color_manager *cm_base, co->from_sRGB_to_blend = NULL; co->from_sRGB_to_output = NULL; + co->hdr_meta.group_mask = 0; + return co; } diff --git a/libweston/compositor.c b/libweston/compositor.c index e5c4bc70..47cd4ff9 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -6449,6 +6449,57 @@ weston_output_transform_coordinate(struct weston_output *output, *y = p.f[1] / p.f[3]; } +static bool +validate_float_range(float val, float min, float max) +{ + return val >= min && val <= max; +} + +/* Based on CTA-861-G, HDR static metadata type 1 */ +static bool +weston_hdr_metadata_type1_validate(const struct weston_hdr_metadata_type1 *md) +{ + unsigned i; + + if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_PRIMARIES) { + for (i = 0; i < ARRAY_LENGTH(md->primary); i++) { + if (!validate_float_range(md->primary[i].x, 0.0, 1.0)) + return false; + if (!validate_float_range(md->primary[i].y, 0.0, 1.0)) + return false; + } + } + + if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_WHITE) { + if (!validate_float_range(md->white.x, 0.0, 1.0)) + return false; + if (!validate_float_range(md->white.y, 0.0, 1.0)) + return false; + } + + if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXDML) { + if (!validate_float_range(md->maxDML, 1.0, 65535.0)) + return false; + } + + if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MINDML) { + if (!validate_float_range(md->minDML, 0.0001, 6.5535)) + return false; + } + + if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXCLL) { + if (!validate_float_range(md->maxCLL, 1.0, 65535.0)) + return false; + } + + if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXFALL) { + if (!validate_float_range(md->maxFALL, 1.0, 65535.0)) + return false; + } + + return true; +} + WL_EXPORT void weston_output_color_outcome_destroy(struct weston_output_color_outcome **pco) { @@ -6475,10 +6526,15 @@ weston_output_set_color_outcome(struct weston_output *output) if (!colorout) { weston_log("Creating color transformation for output \"%s\" failed.\n", output->name); - return false; } + if (!weston_hdr_metadata_type1_validate(&colorout->hdr_meta)) { + weston_log("Internal color manager error creating Metadata Type 1 for output \"%s\".\n", + output->name); + goto out_error; + } + weston_output_color_outcome_destroy(&output->color_outcome); output->color_outcome = colorout; @@ -6488,6 +6544,11 @@ weston_output_set_color_outcome(struct weston_output *output) weston_color_profile_get_description(output->color_profile)); return true; + +out_error: + weston_output_color_outcome_destroy(&colorout); + + return false; } /** Removes output from compositor's list of enabled outputs @@ -6764,6 +6825,23 @@ weston_output_get_eotf_mode(const struct weston_output *output) return output->eotf_mode; } +/** Get HDR static metadata type 1 + * + * \param output The output to query. + * \return Pointer to the metadata stored in weston_output. + * + * This function is meant to be used by libweston backends. + * + * \ingroup output + * \internal + */ +WL_EXPORT const struct weston_hdr_metadata_type1 * +weston_output_get_hdr_metadata_type1(const struct weston_output *output) +{ + assert(output->color_outcome); + return &output->color_outcome->hdr_meta; +} + /** Set display or monitor basic color characteristics * * \param output The output to modify, must be in disabled state.