1 /*
2  *  Copyright (C) 2017-2019 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 #pragma once
9 
10 #include "VideoRenderers/ColorManager.h"
11 #include "VideoRenderers/DebugInfo.h"
12 #include "VideoRenderers/RenderInfo.h"
13 #include "VideoRenderers/VideoShaders/WinVideoFilter.h"
14 #include "cores/VideoSettings.h"
15 #include "guilib/D3DResource.h"
16 
17 #include <vector>
18 
19 #include <d3d11_4.h>
20 #include <dxgi1_5.h>
21 extern "C" {
22 #include <libavutil/mastering_display_metadata.h>
23 #include <libavutil/pixdesc.h>
24 }
25 
26 struct VideoPicture;
27 class CVideoBuffer;
28 
29 namespace win
30 {
31   namespace helpers
32   {
33     template<typename T>
contains(std::vector<T> vector,T item)34     bool contains(std::vector<T> vector, T item)
35     {
36       return find(vector.begin(), vector.end(), item) != vector.end();
37     }
38   }
39 }
40 
41 enum RenderMethod
42 {
43   RENDER_INVALID = 0,
44   RENDER_DXVA = 1,
45   RENDER_PS = 2,
46   RENDER_SW = 3
47 };
48 
49 enum class HDR_TYPE
50 {
51   HDR_NONE_SDR = 0,
52   HDR_HDR10 = 1,
53   HDR_HLG = 2
54 };
55 
56 class CRenderBuffer
57 {
58 public:
59   virtual ~CRenderBuffer() = default;
60 
GetWidth()61   unsigned GetWidth() const { return m_widthTex; }
GetHeight()62   unsigned GetHeight() const { return m_heightTex; }
IsLoaded()63   bool IsLoaded() { return m_bLoaded; }
64 
65   virtual void AppendPicture(const VideoPicture& picture);
66   virtual void ReleasePicture();
UploadBuffer()67   virtual bool UploadBuffer() { return false; }
68   virtual HRESULT GetResource(ID3D11Resource** ppResource, unsigned* index) const;
69 
70   // implementation specified
GetDataPlanes(uint8_t * (& planes)[3],int (& strides)[3])71   virtual bool GetDataPlanes(uint8_t*(&planes)[3], int(&strides)[3]) { return false; }
GetViewCount()72   virtual unsigned GetViewCount() const { return 0; }
GetView(unsigned viewIdx)73   virtual ID3D11View* GetView(unsigned viewIdx) { return nullptr; }
74 
75   AVPixelFormat av_format;
76   CVideoBuffer* videoBuffer = nullptr;
77   unsigned int pictureFlags = 0;
78   AVColorPrimaries primaries = AVCOL_PRI_BT709;
79   AVColorSpace color_space = AVCOL_SPC_BT709;
80   AVColorTransferCharacteristic color_transfer = AVCOL_TRC_BT709;
81   bool full_range = false;
82   int bits = 8;
83   uint8_t texBits = 8;
84   AVPixelFormat pixelFormat = AV_PIX_FMT_NONE; // source pixel format
85   bool hasDisplayMetadata = false;
86   bool hasLightMetadata = false;
87   AVMasteringDisplayMetadata displayMetadata = {};
88   AVContentLightMetadata lightMetadata = {};
89   std::string stereoMode;
90   uint64_t frameIdx = 0;
91 
92 protected:
93   CRenderBuffer(AVPixelFormat av_pix_format, unsigned width, unsigned height);
94   void QueueCopyFromGPU();
95 
96   // video buffer size
97   unsigned int m_width;
98   unsigned int m_height;
99   // real texture size
100   unsigned int m_widthTex;
101   unsigned int m_heightTex;
102   // copy from GPU mem
103   Microsoft::WRL::ComPtr<ID3D11Texture2D> m_staging;
104   D3D11_TEXTURE2D_DESC m_sDesc{};
105   bool m_bPending = false;
106   bool m_bLoaded = false;
107 };
108 
109 class CRendererBase
110 {
111 public:
112   virtual ~CRendererBase();
113 
114   virtual CRenderInfo GetRenderInfo();
115   virtual bool Configure(const VideoPicture &picture, float fps, unsigned int orientation);
116   virtual bool Supports(ESCALINGMETHOD method) = 0;
WantsDoublePass()117   virtual bool WantsDoublePass() { return false; };
NeedBuffer(int idx)118   virtual bool NeedBuffer(int idx) { return false; }
119 
120   void AddVideoPicture(const VideoPicture &picture, int index);
121   void Render(int index, int index2, CD3DTexture& target, const CRect& sourceRect,
122               const CRect& destRect, const CRect& viewRect, unsigned flags);
123   void Render(CD3DTexture& target, const CRect& sourceRect, const CRect& destRect,
124               const CRect& viewRect, unsigned flags = 0);
125 
126   void ManageTextures();
127   int NextBuffer() const;
128   void ReleaseBuffer(int idx);
129   bool Flush(bool saveBuffers);
SetBufferSize(int numBuffers)130   void SetBufferSize(int numBuffers) { m_iBuffersRequired = numBuffers; }
131 
132   DEBUG_INFO_VIDEO GetDebugInfo(int idx);
133 
134   static DXGI_FORMAT GetDXGIFormat(const VideoPicture &picture);
135   static DXGI_FORMAT GetDXGIFormat(CVideoBuffer* videoBuffer);
136   static AVPixelFormat GetAVFormat(DXGI_FORMAT dxgi_format);
137   static DXGI_HDR_METADATA_HDR10 GetDXGIHDR10MetaData(CRenderBuffer* rb);
138 
139 protected:
140   explicit CRendererBase(CVideoSettings& videoSettings);
141 
142   bool CreateIntermediateTarget(unsigned int width, unsigned int height, bool dynamic = false);
143   void OnCMSConfigChanged(AVColorPrimaries srcPrimaries);
144   void ReorderDrawPoints(const CRect& destRect, CPoint(&rotatedPoints)[4]) const;
145   bool CreateRenderBuffer(int index);
146   void DeleteRenderBuffer(int index);
147 
148   void ProcessHDR(CRenderBuffer* rb);
149 
150   virtual void RenderImpl(CD3DTexture& target, CRect& sourceRect, CPoint (&destPoints)[4], uint32_t flags) = 0;
151   virtual void FinalOutput(CD3DTexture& source, CD3DTexture& target, const CRect& sourceRect, const CPoint(&destPoints)[4]);
152 
153   virtual CRenderBuffer* CreateBuffer() = 0;
154   virtual void UpdateVideoFilters();
155   virtual void CheckVideoParameters();
OnViewSizeChanged()156   virtual void OnViewSizeChanged() {}
OnOutputReset()157   virtual void OnOutputReset() {}
158 
159   bool m_toneMapping = false;
160   bool m_useDithering = false;
161   bool m_cmsOn = false;
162   bool m_clutLoaded = false;
163   bool m_useHLGtoPQ = false;
164   int m_toneMapMethod = 0;
165 
166   int m_iBufferIndex = 0;
167   int m_iNumBuffers = 0;
168   int m_iBuffersRequired = 0;
169   int m_ditherDepth = 0;
170   int m_cmsToken = -1;
171   int m_lutSize = 0;
172   unsigned m_sourceWidth = 0;
173   unsigned m_sourceHeight = 0;
174   unsigned m_viewWidth = 0;
175   unsigned m_viewHeight = 0;
176   unsigned m_renderOrientation = 0;
177   float m_fps = 0.0f;
178   uint64_t m_frameIdx = 0;
179 
180   AVPixelFormat m_format = AV_PIX_FMT_NONE;
181   CD3DTexture m_IntermediateTarget;
182   std::shared_ptr<COutputShader> m_outputShader;
183   std::unique_ptr<CColorManager> m_colorManager;
184   Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_pLUTView;
185   CVideoSettings& m_videoSettings;
186   std::map<int, CRenderBuffer*> m_renderBuffers;
187 
188   DXGI_HDR_METADATA_HDR10 m_lastHdr10 = {};
189   HDR_TYPE m_HdrType = HDR_TYPE::HDR_NONE_SDR;
190   bool m_AutoSwitchHDR = false;
191 };
192