NvDrmRenderer.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
  3. * NVIDIA CORPORATION and its licensors retain all intellectual property
  4. * and proprietary rights in and to this software, related documentation
  5. * and any modifications thereto. Any use, reproduction, disclosure or
  6. * distribution of this software and related documentation without an express
  7. * license agreement from NVIDIA CORPORATION is strictly prohibited.
  8. */
  9. /**
  10. * @file
  11. *
  12. * <b>NVIDIA Multimedia API: DRM Renderer API</b>
  13. *
  14. * @b Description: Helper class for rendering using LibDRM.
  15. */
  16. #ifndef __NV_DRM_RENDERER_H__
  17. #define __NV_DRM_RENDERER_H__
  18. #include "NvElement.h"
  19. #include <stdint.h>
  20. #include <pthread.h>
  21. #include <queue>
  22. #include <unordered_map>
  23. /**
  24. *
  25. * @defgroup l4t_mm_nvdrmrenderer_group DRM Renderer API
  26. *
  27. * @ingroup aa_framework_api_group
  28. * @{
  29. */
  30. /** Holds a buffer object handle. */
  31. typedef struct _NvDrmBO {
  32. uint32_t bo_handle; /**< Holds DRM buffer index. */
  33. int width; /**< Holds width of the DRM buffer, in pixels. */
  34. int height; /**< Holds height of the DRM buffer, in pixels. */
  35. int pitch; /**< Holds stride/pitch of the DRM buffer. */
  36. uint8_t* data; /**< Holds mapped CPU accessible address. */
  37. } NvDrmBO;
  38. /** Holds information about the frame. */
  39. typedef struct _NvDrmFB {
  40. uint32_t fb_id; /**< Holds the frame ID. */
  41. int width; /**< Holds width of the frame, in pixels. */
  42. int height; /**< Holds height of the frame, in pixels. */
  43. int format; /**< Holds frame format, such as @c DRM_FORMAT_RGB332.
  44. This class supports a subset of the formats defined
  45. in @c drm_fourcc.h, the standard DRM header. */
  46. NvDrmBO bo[4]; /**< Holds DRM buffer handles. */
  47. int num_buffers; /**< Holds the number of DRM buffers, which depends on
  48. the buffer format. */
  49. } NvDrmFB;
  50. /**
  51. * @brief Helper class for rendering using LibDRM.
  52. *
  53. * The renderer requires the file descriptor of a buffer as an input. The caller
  54. * must set the rendering rate in terms of frames per second (FPS).
  55. *
  56. * The caller specifies the width, height connector, and CRTC index.
  57. * Based on the connector and CRTC index, the renderer finds a suitable encoder
  58. * and configures the CRTC mode.
  59. */
  60. class NvDrmRenderer:public NvElement
  61. {
  62. public:
  63. /**
  64. * Creates a new DRM based renderer named @a name.
  65. *
  66. * @param[in] name Unique name to identity the element instance.
  67. * @param[in] width Width of the window in pixels.
  68. * @param[in] height Height of the window in pixels.
  69. * @param[in] w_x x offset of window location.
  70. * @param[in] w_y y offset of window location.
  71. * @param[in] connector Index of connector to use.
  72. * @param[in] crtc Index of CRTC to use.
  73. * @param[in] metadata Contains HDR metadata.
  74. * @param[in] streamHDR Flag indicating that the current stream has HDR
  75. * metadata, and hence @a metadata is set.
  76. * @returns Reference to the newly created renderer object if successful,
  77. * or NULL if initialization failed.
  78. */
  79. static NvDrmRenderer *createDrmRenderer(const char *name, uint32_t width,
  80. uint32_t height, uint32_t w_x, uint32_t w_y,
  81. uint32_t connector, uint32_t crtc,
  82. struct drm_tegra_hdr_metadata_smpte_2086 metadata,
  83. bool streamHDR);
  84. ~NvDrmRenderer();
  85. /**
  86. * Enqueues a buffer file descriptor for rendering.
  87. *
  88. * This is a non-blocking call. The function waits for the estimated
  89. * rendering time of the next buffer. The estimated rendering time is
  90. * calculated based on the rendering time of the last buffer and the
  91. * rendering rate.
  92. *
  93. * @param[in] fd File descriptor of the exported buffer to render.
  94. * @returns 0 for success, or -1 otherwise.
  95. */
  96. int enqueBuffer(int fd);
  97. /**
  98. * Dequeues a previously rendered buffer.
  99. *
  100. * This is blocking function that waits until a free buffer is available.
  101. * The renderer retains one buffer, which must not be overwritten
  102. * by any other component. This buffer can be used when the renderer
  103. * is closed or after sending an EOS to the component.
  104. *
  105. * @returns File descriptor of the previously rendered buffer.
  106. */
  107. int dequeBuffer();
  108. /**
  109. * Sets the rendering rate in terms of frames per second.
  110. *
  111. * \warning @a fps may not be set to zero.
  112. *
  113. * @param[in] fps Rendering rate in frames per second.
  114. * @returns 0 for success, or -1 otherwise.
  115. */
  116. int setFPS(float fps);
  117. /**
  118. * Enables/disables DRM universal planes client caps,
  119. * such as @c DRM_CLIENT_CAP_UNIVERSAL_PLANES.
  120. *
  121. * @param[in] enable 1 to enable the caps, or 0 to disable them.
  122. * @returns true if successful, or false otherwise.
  123. */
  124. bool enableUniversalPlanes(int enable);
  125. /**
  126. * Allocates a framebuffer of size (w, h).
  127. *
  128. * @post If the call is successful, the application must remove (free) the
  129. * framebuffer by calling removeFB().
  130. *
  131. * @param[in] width Framebuffer width in pixels.
  132. * @param[in] height Framebuffer height in pixels.
  133. * @param[in] drm_format DRM format of @a _NvDrmBO::bo_handle in @a *fb.
  134. * @param[out] fb A pointer to an \ref NvDrmFB structure that
  135. * contains the framebuffer ID and the buffer
  136. * mapping.
  137. *
  138. * @return 1 if successful, or 0 otherwise.
  139. */
  140. uint32_t createDumbFB(uint32_t width, uint32_t height, uint32_t drm_format, NvDrmFB *fb);
  141. /**
  142. * Destroys (frees) a framebuffer previously allocated by createDumbFB().
  143. *
  144. * @param fb_id The ID of the framebuffer to destroy.
  145. * @return 0 if the framebuffer is successfully destroyed, or @c -ENOENT
  146. * if the framebuffer is not found.
  147. */
  148. int removeFB(uint32_t fb_id);
  149. /**
  150. * Close GEM (Graphics Execution Manager) handles.
  151. *
  152. * @param fd FD of the buffer.
  153. * @param bo_handle the gem-handle to be closed.
  154. *
  155. * @return 1 for success, 0 for failure.
  156. */
  157. int drmUtilCloseGemBo(int fd, uint32_t bo_handle);
  158. /**
  159. * Changes a plane's framebuffer and position.
  160. *
  161. * @note The @a crtc_... and @a src_... parameters accept the special input
  162. * value -1, which indicates that the hardware offset value is not to be
  163. * changed. (Kernel-based DRM drivers return the error code @c -ERANGE when
  164. * given this value.)
  165. *
  166. * @note All @c %setPlane() operations are synced to vblank and are
  167. * blocking.
  168. *
  169. * @param pl_index Plane index of the plane to be changed.
  170. * @param fb_id Framebuffer ID of the framebuffer to display on the
  171. * plane, or -1 to leave the framebuffer unchanged.
  172. * @param crtc_x Offset from left of active display region to show plane.
  173. * @param crtc_y Offset from top of active display region to show plane.
  174. * @param crtc_w Width of output rectangle on display.
  175. * @param crtc_h Height of output rectangle on display.
  176. * @param src_x Clip offset from left of source framebuffer
  177. * (Q16.16 fixed point).
  178. * @param src_y Clip offset from top of source framebuffer
  179. * (Q16.16 fixed point).
  180. * @param src_w Width of source rectangle (Q16.16 fixed point).
  181. * @param src_h Height of source rectangle (Q16.16 fixed point).
  182. * @retval 0 if successful.
  183. * @retval -EINVAL if @a pl_index is invalid.
  184. * @retval -errno otherwise.
  185. */
  186. int setPlane(uint32_t pl_index,
  187. uint32_t fb_id,
  188. uint32_t crtc_x,
  189. uint32_t crtc_y,
  190. uint32_t crtc_w,
  191. uint32_t crtc_h,
  192. uint32_t src_x,
  193. uint32_t src_y,
  194. uint32_t src_w,
  195. uint32_t src_h);
  196. /**
  197. * Gets total number of planes available.
  198. *
  199. * By default, the count returned includes only "Overlay" type (regular)
  200. * planes -- not "Primary" and "Cursor" planes. If
  201. * @c DRM_CLIENT_CAP_UNIVERSAL_PLANES has been enabled with
  202. * enableUniversalPlanes(), the count returned includes "Primary"
  203. * and "Cursor" planes as well.
  204. *
  205. * @return Count of total planes available.
  206. */
  207. int getPlaneCount();
  208. /**
  209. * Gets the plane indexes supported by the given
  210. * crtc index.
  211. *
  212. * @param[in] crtc_index Index of crtc for which the
  213. * plane indexes to be found.
  214. * @param[in,out] plane_index Pointer to an array which
  215. * contains plane indexes. This array should be allocated
  216. * by the caller for the size of plane count returned
  217. * by getPlaneCount() API.
  218. *
  219. * @return Count of the indexes written in the given array.
  220. * */
  221. int getPlaneIndex(uint32_t crtc_index,
  222. int32_t* plane_index);
  223. /**
  224. * Gets count of available CRTCs.
  225. *
  226. * @return Count of available CRTCs.
  227. */
  228. int getCrtcCount();
  229. /**
  230. * Gets count of available encoders.
  231. *
  232. * @return Count of available encoders.
  233. */
  234. int getEncoderCount();
  235. /**
  236. * Checks whether the DRM renderer supports HDR mode.
  237. *
  238. * @return True if the DRM renderer supports HDR mode, or FALSE otherwise.
  239. */
  240. bool hdrSupported();
  241. /**
  242. * Sets the HDR metadata retrieved from the decoder.
  243. *
  244. * @return 0 if successful, or -1 otherwise.
  245. */
  246. int setHDRMetadataSmpte2086(struct drm_tegra_hdr_metadata_smpte_2086);
  247. private:
  248. struct timespec last_render_time; /**< Rendering time of the last buffer. */
  249. int drm_fd; /**< File descriptor of opened DRM device. */
  250. int conn, crtc;
  251. uint32_t width, height;
  252. uint32_t drm_conn_id; /**< DRM connector ID. */
  253. uint32_t drm_enc_id; /**< DRM encoder ID. */
  254. uint32_t drm_crtc_id; /**< DRM CRTC ID. */
  255. uint32_t last_fb;
  256. int activeFd;
  257. int flippedFd;
  258. bool flipPending;
  259. bool renderingStarted;
  260. bool is_nvidia_drm;
  261. uint32_t hdrBlobId;
  262. bool hdrBlobCreated;
  263. std::queue<int> freeBuffers;
  264. std::queue<int> pendingBuffers;
  265. std::unordered_map <int, int> map_list;
  266. bool stop_thread; /**< Boolean variable used to signal rendering thread
  267. to stop. */
  268. pthread_t render_thread; /**< pthread ID of the rendering thread. */
  269. pthread_mutex_t render_lock; /**< Used for synchronization. */
  270. pthread_cond_t render_cond; /**< Used for synchronization. */
  271. pthread_mutex_t enqueue_lock; /**< Used for synchronization. */
  272. pthread_cond_t enqueue_cond; /**< Used for synchronization. */
  273. pthread_mutex_t dequeue_lock; /**< Used for synchronization. */
  274. pthread_cond_t dequeue_cond; /**< Used for synchronization. */
  275. float fps; /**< Rendering rate in frames per second. */
  276. uint64_t render_time_sec; /**< Seconds part of the time for which
  277. a frame should be displayed. */
  278. uint64_t render_time_nsec; /**< Nanoseconds part of the time for which
  279. a frame should be displayed. */
  280. /**
  281. * Constructor called by the wrapper createDrmRenderer().
  282. *
  283. * \param[in] name A pointer to a unique name that identifies
  284. * the element instance.
  285. * \param[in] width Width of the window in pixels.
  286. * \param[in] height Height of the window in pixels.
  287. * \param[in] w_x X coordinate of the window's upper left corner.
  288. * \param[in] w_y Y coordinate of the window's upper left corner.
  289. * \param[in] connector Index of the connector to use.
  290. * \param[in] crtc Index of the CRTC to use.
  291. * \param[in] metadata A pointer to HDR metadata.
  292. * \param[in] streamHDR TRUE if the current stream has HDR metadata,
  293. * or FALSE otherwise. If TRUE,
  294. * @a metadata must be set.
  295. */
  296. NvDrmRenderer(const char *name, uint32_t width, uint32_t height,
  297. uint32_t w_x, uint32_t w_y, uint32_t connector, uint32_t crtc,
  298. struct drm_tegra_hdr_metadata_smpte_2086 metadata, bool streamHDR);
  299. /**
  300. * Function executed by the renderThread.
  301. *
  302. * This function is executed repeatedly until signalled to stop
  303. * by the @c stop_thread variable. The function contains a while loop
  304. * which calls renderInternal().
  305. *
  306. * \param[in] arg A pointer to an NvDrmRenderer object.
  307. */
  308. static void * renderThread(void *arg);
  309. static void * renderThreadOrin(void *arg);
  310. /**
  311. * Callback function for DRM flip event.
  312. */
  313. static void page_flip_handler(int fd, unsigned int frame,
  314. unsigned int sec, unsigned int usec, void *data);
  315. /**
  316. * Implements the logic of rendering a buffer
  317. * and waiting until the buffer render time.
  318. *
  319. * \param[in] fd Identifier for the buffer to be rendered.
  320. */
  321. int renderInternal(int fd);
  322. /*
  323. * Returns a DRM buffer_object handle.
  324. *
  325. * \param[in] w Width of the window in pixels.
  326. * \param[in] h Height of the window in pixels.
  327. * \param[in] bpp Bits per pixel in the window.
  328. * \param[in] bo A pointer to a buffer object handle.
  329. * \return An allocated DRM buffer_object handle of size (w,h)
  330. */
  331. int createDumbBO(int w, int h, int bpp, NvDrmBO *bo);
  332. static const NvElementProfiler::ProfilerField valid_fields =
  333. NvElementProfiler::PROFILER_FIELD_TOTAL_UNITS |
  334. NvElementProfiler::PROFILER_FIELD_FPS |
  335. NvElementProfiler::PROFILER_FIELD_LATE_UNITS;
  336. };
  337. /** @} */
  338. #endif