@ -29,13 +29,86 @@
# include <libweston/libweston.h>
# include <libweston/libweston.h>
# include <assert.h>
# include <assert.h>
# include <string.h>
# include <string.h>
# include <math.h>
# include "drm-internal.h"
# include "drm-internal.h"
# include "libdrm-updates.h"
# include "libdrm-updates.h"
static inline uint16_t
color_xy_to_u16 ( float v )
{
assert ( v > = 0.0f ) ;
assert ( v < = 1.0f ) ;
/*
* CTA - 861 - G
* 6.9 .1 Static Metadata Type 1
* chromaticity coordinate encoding
*/
return ( uint16_t ) round ( v * 50000.0 ) ;
}
static inline uint16_t
nits_to_u16 ( float nits )
{
assert ( nits > = 1.0f ) ;
assert ( nits < = 65535.0f ) ;
/*
* CTA - 861 - G
* 6.9 .1 Static Metadata Type 1
* max display mastering luminance , max content light level ,
* max frame - average light level
*/
return ( uint16_t ) round ( nits ) ;
}
static inline uint16_t
nits_to_u16_dark ( float nits )
{
assert ( nits > = 0.0001f ) ;
assert ( nits < = 6.5535f ) ;
/*
* CTA - 861 - G
* 6.9 .1 Static Metadata Type 1
* min display mastering luminance
*/
return ( uint16_t ) round ( nits * 10000.0 ) ;
}
static void
weston_hdr_metadata_type1_to_kms ( struct hdr_metadata_infoframe * dst ,
const struct weston_hdr_metadata_type1 * src )
{
if ( src - > group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_PRIMARIES ) {
unsigned i ;
for ( i = 0 ; i < 3 ; i + + ) {
dst - > display_primaries [ i ] . x = color_xy_to_u16 ( src - > primary [ i ] . x ) ;
dst - > display_primaries [ i ] . y = color_xy_to_u16 ( src - > primary [ i ] . y ) ;
}
}
if ( src - > group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_WHITE ) {
dst - > white_point . x = color_xy_to_u16 ( src - > white . x ) ;
dst - > white_point . y = color_xy_to_u16 ( src - > white . y ) ;
}
if ( src - > group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXDML )
dst - > max_display_mastering_luminance = nits_to_u16 ( src - > maxDML ) ;
if ( src - > group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MINDML )
dst - > min_display_mastering_luminance = nits_to_u16_dark ( src - > minDML ) ;
if ( src - > group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXCLL )
dst - > max_cll = nits_to_u16 ( src - > maxCLL ) ;
if ( src - > group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXFALL )
dst - > max_fall = nits_to_u16 ( src - > maxFALL ) ;
}
int
int
drm_output_ensure_hdr_output_metadata_blob ( struct drm_output * output )
drm_output_ensure_hdr_output_metadata_blob ( struct drm_output * output )
{
{
const struct weston_hdr_metadata_type1 * src ;
struct hdr_output_metadata meta ;
struct hdr_output_metadata meta ;
uint32_t blob_id = 0 ;
uint32_t blob_id = 0 ;
int ret ;
int ret ;
@ -43,6 +116,8 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
if ( output - > hdr_output_metadata_blob_id )
if ( output - > hdr_output_metadata_blob_id )
return 0 ;
return 0 ;
src = weston_output_get_hdr_metadata_type1 ( & output - > base ) ;
/*
/*
* Set up the data for Dynamic Range and Mastering InfoFrame ,
* Set up the data for Dynamic Range and Mastering InfoFrame ,
* CTA - 861 - G , a . k . a the static HDR metadata .
* CTA - 861 - G , a . k . a the static HDR metadata .
@ -72,6 +147,7 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
break ;
break ;
case WESTON_EOTF_MODE_ST2084 :
case WESTON_EOTF_MODE_ST2084 :
meta . hdmi_metadata_type1 . eotf = 2 ; /* from CTA-861-G */
meta . hdmi_metadata_type1 . eotf = 2 ; /* from CTA-861-G */
weston_hdr_metadata_type1_to_kms ( & meta . hdmi_metadata_type1 , src ) ;
break ;
break ;
case WESTON_EOTF_MODE_HLG :
case WESTON_EOTF_MODE_HLG :
meta . hdmi_metadata_type1 . eotf = 3 ; /* from CTA-861-G */
meta . hdmi_metadata_type1 . eotf = 3 ; /* from CTA-861-G */
@ -83,8 +159,6 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
return - 1 ;
return - 1 ;
}
}
/* The other fields are intentionally left as zeroes. */
ret = drmModeCreatePropertyBlob ( output - > backend - > drm . fd ,
ret = drmModeCreatePropertyBlob ( output - > backend - > drm . fd ,
& meta , sizeof meta , & blob_id ) ;
& meta , sizeof meta , & blob_id ) ;
if ( ret ! = 0 ) {
if ( ret ! = 0 ) {