diff --git a/idd/LGIdd/CIndirectDeviceContext.cpp b/idd/LGIdd/CIndirectDeviceContext.cpp index 47d9d162..64a8e49a 100644 --- a/idd/LGIdd/CIndirectDeviceContext.cpp +++ b/idd/LGIdd/CIndirectDeviceContext.cpp @@ -1336,59 +1336,6 @@ CIndirectDeviceContext::GetColorTransform() const return transform; } -#ifdef HAS_IDDCX_110 -void CIndirectDeviceContext::SetHDRActive(const struct IDDCX_HDR10_METADATA * hdrMeta) -{ - AcquireSRWLockExclusive(&m_hdrLock); - - if (!hdrMeta) - { - m_hdrActive = false; - ReleaseSRWLockExclusive(&m_hdrLock); - return; - } - - m_hdrActive = true; - - m_hdrDisplayPrimary[0][0] = hdrMeta->RedPrimary [0]; - m_hdrDisplayPrimary[0][1] = hdrMeta->RedPrimary [1]; - m_hdrDisplayPrimary[1][0] = hdrMeta->GreenPrimary[0]; - m_hdrDisplayPrimary[1][1] = hdrMeta->GreenPrimary[1]; - m_hdrDisplayPrimary[2][0] = hdrMeta->BluePrimary [0]; - m_hdrDisplayPrimary[2][1] = hdrMeta->BluePrimary [1]; - m_hdrWhitePoint [0] = hdrMeta->WhitePoint [0]; - m_hdrWhitePoint [1] = hdrMeta->WhitePoint [1]; - - m_hdrMaxDisplayLuminance = hdrMeta->MaxMasteringLuminance; - m_hdrMinDisplayLuminance = hdrMeta->MinMasteringLuminance; - m_hdrMaxContentLightLevel = hdrMeta->MaxContentLightLevel; - m_hdrMaxFrameAverageLightLevel = hdrMeta->MaxFrameAverageLightLevel; - - ReleaseSRWLockExclusive(&m_hdrLock); -} -#endif - -bool CIndirectDeviceContext::GetHDRMetadata(D12FrameFormat & format) const -{ - AcquireSRWLockShared(&m_hdrLock); - - if (!m_hdrActive) - { - ReleaseSRWLockShared(&m_hdrLock); - return false; - } - - memcpy(format.displayPrimary, m_hdrDisplayPrimary, sizeof(format.displayPrimary)); - memcpy(format.whitePoint , m_hdrWhitePoint , sizeof(format.whitePoint )); - format.maxDisplayLuminance = m_hdrMaxDisplayLuminance; - format.minDisplayLuminance = m_hdrMinDisplayLuminance; - format.maxContentLightLevel = m_hdrMaxContentLightLevel; - format.maxFrameAverageLightLevel = m_hdrMaxFrameAverageLightLevel; - - ReleaseSRWLockShared(&m_hdrLock); - return true; -} - void CIndirectDeviceContext::SendColorTransform() { if (!m_pointerQueue || !m_pointerTransformMemory[0]) diff --git a/idd/LGIdd/CIndirectDeviceContext.h b/idd/LGIdd/CIndirectDeviceContext.h index 4e352c09..3119cba4 100644 --- a/idd/LGIdd/CIndirectDeviceContext.h +++ b/idd/LGIdd/CIndirectDeviceContext.h @@ -119,18 +119,6 @@ private: bool m_canProcessFP16 = false; bool m_softwareMode = true; - // HDR state from EvtIddCxMonitorSetDefaultHdrMetadata (IddCx 1.10+) - // Protected by m_hdrLock - accessed from both the IDD callback thread - // (SetHDRActive) and the swap-chain thread (PrepareFrameBuffer, GetHDRMetadata). - mutable SRWLOCK m_hdrLock = SRWLOCK_INIT; - bool m_hdrActive = false; - uint16_t m_hdrDisplayPrimary[3][2] = {}; - uint16_t m_hdrWhitePoint[2] = {}; - uint32_t m_hdrMaxDisplayLuminance = 0; - uint32_t m_hdrMinDisplayLuminance = 0; - uint32_t m_hdrMaxContentLightLevel = 0; - uint32_t m_hdrMaxFrameAverageLightLevel = 0; - // Previous HDR metadata used to detect changes for formatVer bumps uint16_t m_lastHDRDisplayPrimary[3][2] = {}; uint16_t m_lastHDRWhitePoint[2] = {}; @@ -231,25 +219,9 @@ public: void SendCursor(const IDARG_OUT_QUERY_HWCURSOR & info, const BYTE * data, UINT sdrWhiteLevel); - // Tracks HDR state from EvtIddCxMonitorSetDefaultHdrMetadata - void SetHDRActive(const struct IDDCX_HDR10_METADATA * hdrMeta); - void SetColorTransform(std::shared_ptr transform); std::shared_ptr GetColorTransform() const; - // Returns true if the display is currently in HDR mode - bool IsHDRActive() const - { - AcquireSRWLockShared(&m_hdrLock); - bool result = m_hdrActive; - ReleaseSRWLockShared(&m_hdrLock); - return result; - } - - // Copies current HDR metadata into the provided D12FrameFormat. - // Returns true if HDR is active and metadata was copied. - bool GetHDRMetadata(D12FrameFormat & format) const; - CIVSHMEM &GetIVSHMEM() { return m_ivshmem; } }; diff --git a/idd/LGIdd/CSwapChainProcessor.cpp b/idd/LGIdd/CSwapChainProcessor.cpp index a04cad09..7cb5107b 100644 --- a/idd/LGIdd/CSwapChainProcessor.cpp +++ b/idd/LGIdd/CSwapChainProcessor.cpp @@ -25,6 +25,9 @@ #include "CDebug.h" #include "CPipeServer.h" +static const uint32_t HDR_PQ_MIN_LUMINANCE = 50; +static const uint32_t HDR_PQ_MAX_LUMINANCE = 10000; + CSwapChainProcessor::CSwapChainProcessor(CIndirectMonitorContext * monitorContext, UINT64 assignmentGeneration, IDDCX_MONITOR monitor, CIndirectDeviceContext* devContext, IDDCX_SWAPCHAIN hSwapChain, @@ -439,13 +442,12 @@ void CSwapChainProcessor::UpdateHDRMetadata(const IDDCX_METADATA2& metadata) } #endif -bool CSwapChainProcessor::GetHDRMetadata(D12FrameFormat& format) const +bool CSwapChainProcessor::GetContentHDRMetadata(D12FrameFormat& format) const { #ifdef HAS_IDDCX_110 - if (m_useDefaultHDRMetadata) - return m_devContext->GetHDRMetadata(format); - - if (!m_hasNewHDRMetadata) + // The monitor default describes the virtual display, not the content. Only + // publish an explicit per-frame metadata block to downstream consumers. + if (m_useDefaultHDRMetadata || !m_hasNewHDRMetadata) return false; const IDDCX_HDR10_METADATA& metadata = m_newHDRMetadata; @@ -551,12 +553,11 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer // already applied to the pixel data. srcFormat.hdr = true; srcFormat.hdrPQ = true; - if (!GetHDRMetadata(srcFormat)) + if (!GetContentHDRMetadata(srcFormat)) { - // HDR is active but the OS has not delivered static metadata yet - // (e.g. a brief window during a mode switch). The pixels are still - // PQ-encoded, so keep the PQ flag and supply BT.2020/PQ defaults - // rather than mislabel the frame as SDR. + // No per-content metadata is active. The pixels are still PQ-encoded, + // so keep the PQ flag and use BT.2020/PQ defaults internally rather + // than publishing the virtual monitor metadata as content metadata. // BT.2020 primaries (in 0.00002 units): srcFormat.displayPrimary[0][0] = 35400; // Rx srcFormat.displayPrimary[0][1] = 14600; // Ry @@ -567,10 +568,9 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer // D65 white point (in 0.00002 units): srcFormat.whitePoint[0] = 15635; srcFormat.whitePoint[1] = 16450; - // Mastering luminances follow SMPTE ST 2086 units: max in whole cd/m², - // min in 0.0001 cd/m². 1000 cd/m² display, 0.0001 cd/m² black: - srcFormat.maxDisplayLuminance = 1000; - srcFormat.minDisplayLuminance = 1; + // Cover the complete PQ signal range. + srcFormat.maxDisplayLuminance = HDR_PQ_MAX_LUMINANCE; + srcFormat.minDisplayLuminance = HDR_PQ_MIN_LUMINANCE; // Content light levels unknown: srcFormat.maxContentLightLevel = 0; srcFormat.maxFrameAverageLightLevel = 0; @@ -584,10 +584,10 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer // curve has not been applied. srcFormat.hdr = true; srcFormat.hdrPQ = false; - if (!GetHDRMetadata(srcFormat)) + if (!GetContentHDRMetadata(srcFormat)) { - // No HDR metadata from the OS; provide reasonable defaults - // so downstream consumers have valid primaries and luminances. + // No per-content metadata is active. Use reasonable internal defaults + // without publishing the virtual monitor metadata downstream. // BT.709/sRGB primaries (in 0.00002 units): srcFormat.displayPrimary[0][0] = 13250; // Rx srcFormat.displayPrimary[0][1] = 34500; // Ry diff --git a/idd/LGIdd/CSwapChainProcessor.h b/idd/LGIdd/CSwapChainProcessor.h index 0b79d01b..e17f92a7 100644 --- a/idd/LGIdd/CSwapChainProcessor.h +++ b/idd/LGIdd/CSwapChainProcessor.h @@ -100,7 +100,7 @@ private: #ifdef HAS_IDDCX_110 void UpdateHDRMetadata(const IDDCX_METADATA2& metadata); #endif - bool GetHDRMetadata(D12FrameFormat& format) const; + bool GetContentHDRMetadata(D12FrameFormat& format) const; bool SwapChainNewFrame(ComPtr acquiredBuffer, unsigned dirtyRectCount, DXGI_COLOR_SPACE_TYPE colorSpace, UINT sdrWhiteLevel); diff --git a/idd/LGIdd/Device.cpp b/idd/LGIdd/Device.cpp index b26b6fb9..8c149a57 100644 --- a/idd/LGIdd/Device.cpp +++ b/idd/LGIdd/Device.cpp @@ -191,17 +191,11 @@ NTSTATUS LGIddAdapterCommitModes2(IDDCX_ADAPTER adapter, const IDARG_IN_COMMITMO NTSTATUS LGIddMonitorSetDefaultHdrMetadata(IDDCX_MONITOR monitor, const IDARG_IN_MONITOR_SET_DEFAULT_HDR_METADATA* inArgs) { - auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor); - auto* ctx = wrapper->context->GetDeviceContext(); - - if (ctx->IsSoftwareMode()) - { - ctx->SetHDRActive(nullptr); - return STATUS_SUCCESS; - } - - ctx->SetHDRActive(inArgs->Data.pHdr10); + UNREFERENCED_PARAMETER(monitor); + UNREFERENCED_PARAMETER(inArgs); + // This metadata describes the virtual monitor. Explicit per-content HDR10 + // metadata is obtained from the swap chain and forwarded separately. return STATUS_SUCCESS; }