From 9e46c89ffc56c0bc6359ef4269274804f0c9d382 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 29 Jan 2024 02:35:16 +0000 Subject: [PATCH] drm: Refactor HDR10 decisionmaking --- src/drm.cpp | 42 +++++++++++++++++++++--------------------- src/drm.hpp | 30 +++++++++++++++++++----------- src/steamcompmgr.cpp | 8 -------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/drm.cpp b/src/drm.cpp index 000633fbc1..dc232620fd 100644 --- a/src/drm.cpp +++ b/src/drm.cpp @@ -55,6 +55,10 @@ const char *g_sOutputName = nullptr; #define DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP 0x15 #endif +bool drm_update_color_mgmt(struct drm_t *drm); +bool drm_supports_color_mgmt(struct drm_t *drm); +bool drm_set_connector( struct drm_t *drm, gamescope::CDRMConnector *conn ); + struct drm_color_ctm2 { /* * Conversion matrix in S31.32 sign-magnitude @@ -2545,27 +2549,35 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI drm->needs_modeset = true; } - drm->fbids_in_req.clear(); - - bool needs_modeset = drm->needs_modeset.exchange(false); - - assert( drm->req == nullptr ); - drm->req = drmModeAtomicAlloc(); + uint32_t uColorimetry = DRM_MODE_COLORIMETRY_DEFAULT; + const bool bWantsHDR10 = g_bOutputHDREnabled && frameInfo->outputEncodingEOTF == EOTF_PQ; wlserver_hdr_metadata *pHDRMetadata = nullptr; - if ( drm->pConnector && drm->pConnector->GetHDRInfo().IsHDR10() ) + if ( drm->pConnector && drm->pConnector->SupportsHDR10() ) { - if ( g_bOutputHDREnabled ) + if ( bWantsHDR10 ) { wlserver_vk_swapchain_feedback* pFeedback = steamcompmgr_get_base_layer_swapchain_feedback(); pHDRMetadata = pFeedback ? pFeedback->hdr_metadata_blob.get() : drm->pConnector->GetHDRInfo().pDefaultMetadataBlob.get(); + uColorimetry = DRM_MODE_COLORIMETRY_BT2020_RGB; } else { pHDRMetadata = drm->sdr_static_metadata.get(); + uColorimetry = DRM_MODE_COLORIMETRY_DEFAULT; } + + if ( uColorimetry != drm->pConnector->GetProperties().Colorspace->GetCurrentValue() ) + drm->needs_modeset = true; } + drm->fbids_in_req.clear(); + + bool needs_modeset = drm->needs_modeset.exchange(false); + + assert( drm->req == nullptr ); + drm->req = drmModeAtomicAlloc(); + bool bSinglePlane = frameInfo->layerCount < 2 && g_bSinglePlaneOptimizations; if ( drm_supports_color_mgmt( &g_DRM ) && frameInfo->applyOutputColorMgmt ) @@ -2657,12 +2669,7 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI drm->pConnector->GetProperties().CRTC_ID->SetPendingValue( drm->req, drm->pCRTC->GetObjectId(), bForceInRequest ); if ( drm->pConnector->GetProperties().Colorspace ) - { - uint32_t uColorimetry = g_bOutputHDREnabled && drm->pConnector->GetHDRInfo().IsHDR10() - ? DRM_MODE_COLORIMETRY_BT2020_RGB - : DRM_MODE_COLORIMETRY_DEFAULT; drm->pConnector->GetProperties().Colorspace->SetPendingValue( drm->req, uColorimetry, bForceInRequest ); - } } if ( drm->pCRTC ) @@ -3004,7 +3011,7 @@ bool drm_get_vrr_capable(struct drm_t *drm) bool drm_supports_hdr( struct drm_t *drm, uint16_t *maxCLL, uint16_t *maxFALL ) { - if ( drm->pConnector && drm->pConnector->GetHDRInfo().SupportsHDR() ) + if ( drm->pConnector && drm->pConnector->SupportsHDR() ) { if ( maxCLL ) *maxCLL = drm->pConnector->GetHDRInfo().uMaxContentLightLevel; @@ -3016,13 +3023,6 @@ bool drm_supports_hdr( struct drm_t *drm, uint16_t *maxCLL, uint16_t *maxFALL ) return false; } -void drm_set_hdr_state(struct drm_t *drm, bool enabled) { - if (drm->enable_hdr != enabled) { - drm->needs_modeset = true; - drm->enable_hdr = enabled; - } -} - const char *drm_get_connector_name(struct drm_t *drm) { if ( !drm->pConnector ) diff --git a/src/drm.hpp b/src/drm.hpp index 3271c088df..79c88050a3 100644 --- a/src/drm.hpp +++ b/src/drm.hpp @@ -269,23 +269,21 @@ namespace gamescope uint16_t uMinContentLightLevel = 0; // Nits / 10000 std::shared_ptr pDefaultMetadataBlob; - bool ShouldPatchEDID() const + bool IsHDRG22() const { return bExposeHDRSupport && eOutputEncodingEOTF == EOTF_Gamma22; } - bool SupportsHDR() const + bool ShouldPatchEDID() const { - // Note: Different to IsHDR10, as we can expose HDR10 on G2.2 displays - // using LUTs and CTMs. - return bExposeHDRSupport; + return IsHDRG22(); } bool IsHDR10() const { // PQ output encoding is always HDR10 (PQ + 2020) for us. // If that assumption changes, update me. - return eOutputEncodingEOTF == EOTF_PQ; + return bExposeHDRSupport && eOutputEncodingEOTF == EOTF_PQ; } }; @@ -317,6 +315,21 @@ namespace gamescope // TODO: Remove void SetBaseRefresh( int nRefresh ) { m_nBaseRefresh = nRefresh; } int GetBaseRefresh() const { return m_nBaseRefresh; } + + bool SupportsHDR10() const + { + return !!GetProperties().Colorspace && !!GetProperties().HDR_OUTPUT_METADATA && GetHDRInfo().IsHDR10(); + } + + bool SupportsHDRG22() const + { + return GetHDRInfo().IsHDRG22(); + } + + bool SupportsHDR() const + { + return SupportsHDR10() || SupportsHDRG22(); + } private: void ParseEDID(); @@ -433,7 +446,6 @@ struct drm_t { std::unordered_map< std::string, int > connector_priorities; bool force_internal = false; - bool enable_hdr = false; char *device_name = nullptr; }; @@ -480,12 +492,9 @@ uint32_t drm_fbid_from_dmabuf( struct drm_t *drm, struct wlr_buffer *buf, struct void drm_lock_fbid( struct drm_t *drm, uint32_t fbid ); void drm_unlock_fbid( struct drm_t *drm, uint32_t fbid ); void drm_drop_fbid( struct drm_t *drm, uint32_t fbid ); -bool drm_set_connector( struct drm_t *drm, gamescope::CDRMConnector *conn ); bool drm_set_mode( struct drm_t *drm, const drmModeModeInfo *mode ); bool drm_set_refresh( struct drm_t *drm, int refresh ); bool drm_set_resolution( struct drm_t *drm, int width, int height ); -bool drm_update_color_mgmt(struct drm_t *drm); -bool drm_update_vrr_state(struct drm_t *drm); gamescope::GamescopeScreenType drm_get_screen_type(struct drm_t *drm); char *find_drm_node_by_devid(dev_t devid); @@ -502,7 +511,6 @@ const char *drm_get_connector_name(struct drm_t *drm); const char *drm_get_device_name(struct drm_t *drm); std::pair drm_get_connector_identifier(struct drm_t *drm); -void drm_set_hdr_state(struct drm_t *drm, bool enabled); void drm_get_native_colorimetry( struct drm_t *drm, displaycolorimetry_t *displayColorimetry, EOTF *displayEOTF, diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp index d3f0ef42c9..49aa6fbd3c 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp @@ -8032,14 +8032,6 @@ steamcompmgr_main(int argc, char **argv) } else { - if ( !BIsNested() ) - { - if (g_bOutputHDREnabled != currentHDROutput) - { - drm_set_hdr_state(&g_DRM, g_bOutputHDREnabled); - } - } - vulkan_remake_output_images(); }