////----------------------------------------------------------------------------------
// File:        CDX1x_Common.h
// SDK Version: 1.0.2
//
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.
//
//----------------------------------------------------------------------------------

///////////////////////////////////////////
// CDX1x_Common.h
//
// convenience items used by DX11 and DX12 classes
//


#pragma once

#include <dxgi1_6.h>

class CDx1xCommon
{
public:
    CDx1xCommon() {}

    bool IsMonitorHDR();
    UINT GetMonitorMaxLuminance();
    RECT GetMonitorRect();

    bool FindMonitorRect(UINT head, RECT* pMonRect);
    IDXGIAdapter4* GetDxgiAdapterForWnd(HWND hWndDisplay);
    void SetWindowOnNonNV(bool bWindowOnNonNV) { m_bWindowOnNonNV = bWindowOnNonNV; }

    DXGI_COLOR_SPACE_TYPE UpdateSwapChainColorSpace(HWND hWndDisplay, IDXGISwapChain4* pSwapChain, DXGI_FORMAT SwapFormat, bool bSupportHDR);

private:
    HMONITOR                                m_hMonitor = nullptr;
    UINT                                    m_uMaxLuminance = 1000;
    RECT                                    m_rcMonitor = {};
    DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO   m_colorInfo = {};
    
    bool                                    m_bWindowOnNonNV = false;

    bool UpdateMonitorIDs(WCHAR* szMonitor, LUID* pLUID, UINT32* pID);
    UINT GetMonitorStaticInfo(HMONITOR hMon, RECT* pRcMon);
};


//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

#define ROUNDUP(a, b)                (((a) + (b) - 1) & ~((b)-1))   // watch out, b is only power of 2 number

template <class T> inline void SafeRelease(T*& pT)
{
    if (pT != NULL)
    {
        pT->Release();
        pT = NULL;
    }
}

template <class T> inline void SafeDelete(T*& pT)
{
    if (pT != NULL)
    {
        delete pT;
        pT = NULL;
    }
}

template <class T> inline void SafeDeleteA(T*& pT)
{
    if (pT != NULL)
    {
        delete[] pT;
        pT = NULL;
    }
}

template <class T> inline void SafeCloseHandle(T*& pT)
{
    if (pT != NULL)
    {
        CloseHandle(pT);
        pT = NULL;
    }
}


//////////////////////////////////////////////////////////////////////////////
// Convenience class for auto-locking a CRITICAL_SECTION object upon entering
// scope and auto-unlocking when exiting.
//////////////////////////////////////////////////////////////////////////////
class CAutoCS
{
public:
    CAutoCS(CRITICAL_SECTION& cs, bool bSkip = false)
        : m_CS(cs), m_bSkip(bSkip)
    {
        if (!m_bSkip)
            EnterCriticalSection(&m_CS);
    }
    ~CAutoCS()
    {
        if (!m_bSkip)
            LeaveCriticalSection(&m_CS);
    }
private:
    CRITICAL_SECTION& m_CS;
    bool m_bSkip;
};

