@ -51,6 +51,7 @@
# include <libweston/backend-drm.h>
# include <libweston/backend-drm.h>
# include <libweston/weston-log.h>
# include <libweston/weston-log.h>
# include "drm-internal.h"
# include "drm-internal.h"
# include "libdrm-updates.h"
# include "shared/helpers.h"
# include "shared/helpers.h"
# include "shared/timespec-util.h"
# include "shared/timespec-util.h"
# include "shared/string-helpers.h"
# include "shared/string-helpers.h"
@ -440,6 +441,71 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
pixman_region32_fini ( & scanout_damage ) ;
pixman_region32_fini ( & scanout_damage ) ;
}
}
static int
drm_output_ensure_hdr_output_metadata_blob ( struct drm_output * output )
{
struct hdr_output_metadata meta ;
uint32_t blob_id = 0 ;
int ret ;
if ( output - > hdr_output_metadata_blob_id )
return 0 ;
/*
* Set up the data for Dynamic Range and Mastering InfoFrame ,
* CTA - 861 - G , a . k . a the static HDR metadata .
*/
memset ( & meta , 0 , sizeof meta ) ;
meta . metadata_type = 0 ; /* Static Metadata Type 1 */
/* Duplicated field in UABI struct */
meta . hdmi_metadata_type1 . metadata_type = meta . metadata_type ;
switch ( output - > base . eotf_mode ) {
case WESTON_EOTF_MODE_NONE :
assert ( 0 & & " bad eotf_mode: none " ) ;
return - 1 ;
case WESTON_EOTF_MODE_SDR :
/*
* Do not send any static HDR metadata . Video sinks should
* respond by switching to traditional SDR mode . If they
* do not , the kernel should fix that up .
*/
assert ( output - > hdr_output_metadata_blob_id = = 0 ) ;
return 0 ;
case WESTON_EOTF_MODE_TRADITIONAL_HDR :
meta . hdmi_metadata_type1 . eotf = 1 ; /* from CTA-861-G */
break ;
case WESTON_EOTF_MODE_ST2084 :
meta . hdmi_metadata_type1 . eotf = 2 ; /* from CTA-861-G */
break ;
case WESTON_EOTF_MODE_HLG :
meta . hdmi_metadata_type1 . eotf = 3 ; /* from CTA-861-G */
break ;
}
if ( meta . hdmi_metadata_type1 . eotf = = 0 ) {
assert ( 0 & & " bad eotf_mode " ) ;
return - 1 ;
}
/* The other fields are intentionally left as zeroes. */
ret = drmModeCreatePropertyBlob ( output - > backend - > drm . fd ,
& meta , sizeof meta , & blob_id ) ;
if ( ret ! = 0 ) {
weston_log ( " Error: failed to create KMS blob for HDR metadata on output '%s': %s \n " ,
output - > base . name , strerror ( - ret ) ) ;
return - 1 ;
}
output - > hdr_output_metadata_blob_id = blob_id ;
return 0 ;
}
static int
static int
drm_output_repaint ( struct weston_output * output_base , pixman_region32_t * damage )
drm_output_repaint ( struct weston_output * output_base , pixman_region32_t * damage )
{
{
@ -474,6 +540,9 @@ drm_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
else
else
state - > protection = WESTON_HDCP_DISABLE ;
state - > protection = WESTON_HDCP_DISABLE ;
if ( drm_output_ensure_hdr_output_metadata_blob ( output ) < 0 )
goto err ;
drm_output_render ( state , damage ) ;
drm_output_render ( state , damage ) ;
scanout_state = drm_output_state_get_plane ( state ,
scanout_state = drm_output_state_get_plane ( state ,
output - > scanout_plane ) ;
output - > scanout_plane ) ;
@ -1845,6 +1914,12 @@ drm_output_deinit(struct weston_output *base)
drm_output_deinit_planes ( output ) ;
drm_output_deinit_planes ( output ) ;
drm_output_detach_crtc ( output ) ;
drm_output_detach_crtc ( output ) ;
if ( output - > hdr_output_metadata_blob_id ) {
drmModeDestroyPropertyBlob ( b - > drm . fd ,
output - > hdr_output_metadata_blob_id ) ;
output - > hdr_output_metadata_blob_id = 0 ;
}
}
}
static void
static void
@ -1879,6 +1954,8 @@ drm_output_destroy(struct weston_output *base)
assert ( ! output - > state_last ) ;
assert ( ! output - > state_last ) ;
drm_output_state_free ( output - > state_cur ) ;
drm_output_state_free ( output - > state_cur ) ;
assert ( output - > hdr_output_metadata_blob_id = = 0 ) ;
free ( output ) ;
free ( output ) ;
}
}