1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "DirectXHelper.h" 12 #include "HDRStatus.h" 13 #include "guilib/D3DResource.h" 14 15 #include <functional> 16 #include <memory> 17 18 #include <concrt.h> 19 #include <dxgi1_5.h> 20 #include <wrl.h> 21 #include <wrl/client.h> 22 23 struct RESOLUTION_INFO; 24 struct DEBUG_INFO_RENDER; 25 26 namespace DX 27 { 28 interface IDeviceNotify 29 { 30 virtual void OnDXDeviceLost() = 0; 31 virtual void OnDXDeviceRestored() = 0; 32 }; 33 34 // Controls all the DirectX device resources. 35 class DeviceResources 36 { 37 public: 38 static std::shared_ptr<DX::DeviceResources> Get(); 39 40 DeviceResources(); 41 virtual ~DeviceResources(); 42 void Release(); 43 44 void ValidateDevice(); 45 void HandleDeviceLost(bool removed); 46 bool Begin(); 47 void Present(); 48 49 // The size of the render target, in pixels. GetOutputSize()50 winrt::Windows::Foundation::Size GetOutputSize() const { return m_outputSize; } 51 // The size of the render target, in dips. GetLogicalSize()52 winrt::Windows::Foundation::Size GetLogicalSize() const { return m_logicalSize; } 53 void SetLogicalSize(float width, float height); GetDpi()54 float GetDpi() const { return m_effectiveDpi; } 55 void SetDpi(float dpi); 56 57 // D3D Accessors. HasValidDevice()58 bool HasValidDevice() const { return m_bDeviceCreated; } GetD3DDevice()59 ID3D11Device1* GetD3DDevice() const { return m_d3dDevice.Get(); } GetD3DContext()60 ID3D11DeviceContext1* GetD3DContext() const { return m_deferrContext.Get(); } GetImmediateContext()61 ID3D11DeviceContext1* GetImmediateContext() const { return m_d3dContext.Get(); } GetSwapChain()62 IDXGISwapChain1* GetSwapChain() const { return m_swapChain.Get(); } GetIDXGIFactory2()63 IDXGIFactory2* GetIDXGIFactory2() const { return m_dxgiFactory.Get(); } GetAdapter()64 IDXGIAdapter1* GetAdapter() const { return m_adapter.Get(); } GetDSV()65 ID3D11DepthStencilView* GetDSV() const { return m_d3dDepthStencilView.Get(); } GetDeviceFeatureLevel()66 D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return m_d3dFeatureLevel; } GetBackBuffer()67 CD3DTexture& GetBackBuffer() { return m_backBufferTex; } 68 69 void GetOutput(IDXGIOutput** ppOutput) const; 70 void GetAdapterDesc(DXGI_ADAPTER_DESC *desc) const; 71 void GetDisplayMode(DXGI_MODE_DESC *mode) const; 72 GetScreenViewport()73 D3D11_VIEWPORT GetScreenViewport() const { return m_screenViewport; } 74 void SetViewPort(D3D11_VIEWPORT& viewPort) const; 75 76 void ReleaseBackBuffer(); 77 void CreateBackBuffer(); 78 void ResizeBuffers(); 79 80 bool SetFullScreen(bool fullscreen, RESOLUTION_INFO& res); 81 82 // HDR display support 83 HDR_STATUS ToggleHDR(); 84 void SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const; 85 void SetHdrColorSpace(const DXGI_COLOR_SPACE_TYPE colorSpace); IsHDROutput()86 bool IsHDROutput() const { return m_IsHDROutput; } IsTransferPQ()87 bool IsTransferPQ() const { return m_IsTransferPQ; } 88 89 // DX resources registration 90 void Register(ID3DResource *resource); 91 void Unregister(ID3DResource *resource); 92 93 void FinishCommandList(bool bExecute = true) const; 94 void ClearDepthStencil() const; 95 void ClearRenderTarget(ID3D11RenderTargetView* pRTView, float color[4]) const; 96 void RegisterDeviceNotify(IDeviceNotify* deviceNotify); 97 98 bool IsStereoAvailable() const; IsStereoEnabled()99 bool IsStereoEnabled() const { return m_stereoEnabled; } SetStereoIdx(byte idx)100 void SetStereoIdx(byte idx) { m_backBufferTex.SetViewIdx(idx); } 101 102 void SetMonitor(HMONITOR monitor); 103 HMONITOR GetMonitor() const; 104 #if defined(TARGET_WINDOWS_DESKTOP) 105 void SetWindow(HWND window); 106 #elif defined(TARGET_WINDOWS_STORE) 107 void Trim() const; 108 void SetWindow(const winrt::Windows::UI::Core::CoreWindow& window); 109 void SetWindowPos(winrt::Windows::Foundation::Rect rect); 110 #endif // TARGET_WINDOWS_STORE IsNV12SharedTexturesSupported()111 bool IsNV12SharedTexturesSupported() const { return m_NV12SharedTexturesSupport; } 112 113 // Gets debug info from swapchain 114 DEBUG_INFO_RENDER GetDebugInfo() const; 115 116 private: 117 class CBackBuffer : public CD3DTexture 118 { 119 public: CBackBuffer()120 CBackBuffer() : CD3DTexture() {} SetViewIdx(unsigned idx)121 void SetViewIdx(unsigned idx) { m_viewIdx = idx; } 122 bool Acquire(ID3D11Texture2D* pTexture); 123 }; 124 125 HRESULT CreateSwapChain(DXGI_SWAP_CHAIN_DESC1 &desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC &fsDesc, IDXGISwapChain1 **ppSwapChain) const; 126 void DestroySwapChain(); 127 void CreateDeviceIndependentResources(); 128 void CreateDeviceResources(); 129 void CreateWindowSizeDependentResources(); 130 void UpdateRenderTargetSize(); 131 void OnDeviceLost(bool removed); 132 void OnDeviceRestored(); 133 void HandleOutputChange(const std::function<bool(DXGI_OUTPUT_DESC)>& cmpFunc); 134 bool CreateFactory(); 135 void CheckNV12SharedTexturesSupport(); 136 137 HWND m_window{ nullptr }; 138 #if defined(TARGET_WINDOWS_STORE) 139 winrt::Windows::UI::Core::CoreWindow m_coreWindow = nullptr; 140 #endif 141 Microsoft::WRL::ComPtr<IDXGIFactory2> m_dxgiFactory; 142 Microsoft::WRL::ComPtr<IDXGIAdapter1> m_adapter; 143 Microsoft::WRL::ComPtr<IDXGIOutput1> m_output; 144 145 Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice; 146 Microsoft::WRL::ComPtr<ID3D11DeviceContext1> m_d3dContext; 147 Microsoft::WRL::ComPtr<ID3D11DeviceContext1> m_deferrContext; 148 Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain; 149 #ifdef _DEBUG 150 Microsoft::WRL::ComPtr<ID3D11Debug> m_d3dDebug; 151 #endif 152 153 CBackBuffer m_backBufferTex; 154 Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_d3dDepthStencilView; 155 D3D11_VIEWPORT m_screenViewport; 156 157 // Cached device properties. 158 D3D_FEATURE_LEVEL m_d3dFeatureLevel; 159 winrt::Windows::Foundation::Size m_outputSize; 160 winrt::Windows::Foundation::Size m_logicalSize; 161 float m_dpi; 162 163 // This is the DPI that will be reported back to the app. It takes into account whether the app supports high resolution screens or not. 164 float m_effectiveDpi; 165 // The IDeviceNotify can be held directly as it owns the DeviceResources. 166 IDeviceNotify* m_deviceNotify; 167 168 // scritical section 169 Concurrency::critical_section m_criticalSection; 170 Concurrency::critical_section m_resourceSection; 171 std::vector<ID3DResource*> m_resources; 172 173 bool m_stereoEnabled; 174 bool m_bDeviceCreated; 175 bool m_IsHDROutput; 176 bool m_IsTransferPQ; 177 bool m_NV12SharedTexturesSupport{false}; 178 }; 179 } 180