kodi
RPRenderManager.h
1 /*
2  * Copyright (C) 2017-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 "IRenderManager.h"
12 #include "RenderVideoSettings.h"
13 #include "cores/RetroPlayer/guibridge/IRenderCallback.h"
14 #include "threads/CriticalSection.h"
15 
16 extern "C"
17 {
18 #include <libavutil/pixfmt.h>
19 }
20 
21 #include <atomic>
22 #include <future>
23 #include <map>
24 #include <memory>
25 #include <set>
26 #include <string>
27 #include <vector>
28 
29 struct SwsContext;
30 
31 namespace KODI
32 {
33 namespace RETRO
34 {
35 class CGUIRenderTargetFactory;
36 class CRenderContext;
37 class CRenderSettings;
38 class CRPBaseRenderer;
39 class CRPProcessInfo;
40 class IGUIRenderSettings;
41 class IRenderBuffer;
42 class IRenderBufferPool;
43 class ISavestate;
44 struct VideoStreamBuffer;
45 
68 {
69 public:
70  CRPRenderManager(CRPProcessInfo& processInfo);
71  ~CRPRenderManager() override = default;
72 
73  void Initialize();
74  void Deinitialize();
75 
79  CGUIRenderTargetFactory* GetGUIRenderTargetFactory() { return m_renderControlFactory.get(); }
80 
81  // Stream properties, set upon configuration
82  AVPixelFormat GetPixelFormat() const { return m_format; }
83  unsigned int GetNominalWidth() const { return m_nominalWidth; }
84  unsigned int GetNominalHeight() const { return m_nominalHeight; }
85  unsigned int GetMaxWidth() const { return m_maxWidth; }
86  unsigned int GetMaxHeight() const { return m_maxHeight; }
87  float GetPixelAspectRatio() const { return m_pixelAspectRatio; }
88 
89  // Functions called from game loop
90  bool Configure(AVPixelFormat format,
91  unsigned int nominalWidth,
92  unsigned int nominalHeight,
93  unsigned int maxWidth,
94  unsigned int maxHeight,
95  float pixelAspectRatio);
96  bool GetVideoBuffer(unsigned int width, unsigned int height, VideoStreamBuffer& buffer);
97  void AddFrame(const uint8_t* data,
98  size_t size,
99  unsigned int width,
100  unsigned int height,
101  unsigned int orientationDegCW);
102  void Flush();
103 
104  // Functions called from the player
105  void SetSpeed(double speed);
106 
107  // Functions called from render thread
108  void FrameMove();
109 
110  // Implementation of IRenderManager
111  void RenderWindow(bool bClear, const RESOLUTION_INFO& coordsRes) override;
112  void RenderControl(bool bClear,
113  bool bUseAlpha,
114  const CRect& renderRegion,
115  const IGUIRenderSettings* renderSettings) override;
116  void ClearBackground() override;
117 
118  // Implementation of IRenderCallback
119  bool SupportsRenderFeature(RENDERFEATURE feature) const override;
120  bool SupportsScalingMethod(SCALINGMETHOD method) const override;
121 
122  // Savestate functions
123  void SaveThumbnail(const std::string& thumbnailPath);
124 
125  // Savestate functions
126  void CacheVideoFrame(const std::string& savestatePath);
127  void SaveVideoFrame(const std::string& savestatePath, ISavestate& savestate);
128  void ClearVideoFrame(const std::string& savestatePath);
129 
130 private:
134  std::shared_ptr<CRPBaseRenderer> GetRendererForSettings(const IGUIRenderSettings* renderSettings);
135 
139  std::shared_ptr<CRPBaseRenderer> GetRendererForPool(IRenderBufferPool* bufferPool,
140  const CRenderSettings& renderSettings);
141 
145  void RenderInternal(const std::shared_ptr<CRPBaseRenderer>& renderer,
146  IRenderBuffer* renderBuffer,
147  bool bClear,
148  uint32_t alpha);
149 
153  bool HasRenderBuffer(IRenderBufferPool* bufferPool);
154 
158  IRenderBuffer* GetRenderBuffer(IRenderBufferPool* bufferPool);
159 
163  IRenderBuffer* GetRenderBufferForSavestate(const std::string& savestatePath,
164  const IRenderBufferPool* bufferPool);
165 
169  void CreateRenderBuffer(IRenderBufferPool* bufferPool);
170 
194  IRenderBuffer* CreateFromCache(std::vector<uint8_t>& cachedFrame,
195  unsigned int width,
196  unsigned int height,
197  IRenderBufferPool* bufferPool,
198  CCriticalSection& mutex);
199 
203  void CopyFrame(IRenderBuffer* renderBuffer,
204  AVPixelFormat format,
205  const uint8_t* data,
206  size_t size,
207  unsigned int width,
208  unsigned int height);
209 
210  CRenderVideoSettings GetEffectiveSettings(const IGUIRenderSettings* settings) const;
211 
212  void CheckFlush();
213 
214  void GetVideoFrame(IRenderBuffer*& readableBuffer, std::vector<uint8_t>& cachedFrame);
215  void FreeVideoFrame(IRenderBuffer* readableBuffer, std::vector<uint8_t> cachedFrame);
216  void LoadVideoFrameAsync(const std::string& savestatePath);
217  void LoadVideoFrameSync(const std::string& savestatePath);
218 
219  // Construction parameters
220  CRPProcessInfo& m_processInfo;
221  CRenderContext& m_renderContext;
222 
223  // Subsystems
224  std::shared_ptr<IGUIRenderSettings> m_renderSettings;
225  std::shared_ptr<CGUIRenderTargetFactory> m_renderControlFactory;
226 
227  // Stream properties
228  AVPixelFormat m_format = AV_PIX_FMT_NONE;
229  unsigned int m_nominalWidth{0};
230  unsigned int m_nominalHeight{0};
231  unsigned int m_maxWidth = 0;
232  unsigned int m_maxHeight = 0;
233  float m_pixelAspectRatio{1.0f};
234 
235  // Render resources
236  std::set<std::shared_ptr<CRPBaseRenderer>> m_renderers;
237  std::vector<IRenderBuffer*> m_pendingBuffers; // Only access from game thread
238  std::vector<IRenderBuffer*> m_renderBuffers;
239  std::map<AVPixelFormat, std::map<AVPixelFormat, SwsContext*>> m_scalers; // From -> to -> context
240  std::vector<uint8_t> m_cachedFrame;
241  unsigned int m_cachedWidth = 0;
242  unsigned int m_cachedHeight = 0;
243  unsigned int m_cachedRotationCCW{0};
244  std::map<std::string, std::vector<IRenderBuffer*>>
245  m_savestateBuffers; // Render buffers for savestates
246  std::vector<std::future<void>> m_savestateThreads;
247 
248  // State parameters
249  enum class RENDER_STATE
250  {
251  UNCONFIGURED,
252  CONFIGURING,
253  CONFIGURED,
254  };
255  RENDER_STATE m_state = RENDER_STATE::UNCONFIGURED;
256  bool m_bHasCachedFrame = false; // Invariant: m_cachedFrame is empty if false
257  std::set<std::string> m_failedShaderPresets;
258  std::atomic<bool> m_bFlush = {false};
259 
260  // Windowing state
261  bool m_bDisplayScaleSet = false;
262 
263  // Playback parameters
264  std::atomic<double> m_speed = {1.0};
265 
266  // Synchronization parameters
267  CCriticalSection m_stateMutex;
268  CCriticalSection m_bufferMutex;
269 };
270 } // namespace RETRO
271 } // namespace KODI
Renders video frames provided by the game loop.
Definition: RPRenderManager.h:67
Interface to pass render settings from the GUI to the renderer.
Definition: IGUIRenderSettings.h:21
bool SupportsScalingMethod(SCALINGMETHOD method) const override
Definition: RPRenderManager.cpp:461
Definition: ISavestate.h:28
Definition: IRenderBuffer.h:27
void RenderControl(bool bClear, bool bUseAlpha, const CRect &renderRegion, const IGUIRenderSettings *renderSettings) override
Render a game control.
Definition: RPRenderManager.cpp:380
void ClearBackground() override
Clear the background of a fullscreen window.
Definition: RPRenderManager.cpp:444
void SaveThumbnail(const std::string &thumbnailPath)
Definition: RPRenderManager.cpp:790
Definition: IRenderCallback.h:17
Provide info of a resolution.
Definition: Resolution.h:66
Definition: AudioDecoder.h:18
Definition: IRenderBufferPool.h:30
Definition: RetroPlayerVideo.h:51
Definition: RenderContext.h:43
Definition: GUIRenderTargetFactory.h:20
Definition: settings.py:1
CGUIRenderTargetFactory * GetGUIRenderTargetFactory()
Access the factory for creating GUI render targets.
Definition: RPRenderManager.h:79
Video settings provided by the rendering system.
Definition: RenderVideoSettings.h:22
Interface to expose rendering functions to GUI components.
Definition: IRenderManager.h:24
Player process info.
Definition: RPProcessInfo.h:80
Definition: RenderSettings.h:17
bool SupportsRenderFeature(RENDERFEATURE feature) const override
Definition: RPRenderManager.cpp:449
bool GetVideoBuffer(unsigned int width, unsigned int height, VideoStreamBuffer &buffer)
Definition: RPRenderManager.cpp:126
void RenderWindow(bool bClear, const RESOLUTION_INFO &coordsRes) override
Render a fullscreen window.
Definition: RPRenderManager.cpp:331