0034-egl-tizen-expose-EXT_yuv_surface-support.patch 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. From 6bdf417b37b8b8d50facbb610ab2b936bf5cc626 Mon Sep 17 00:00:00 2001
  2. From: Frank Binns <frank.binns@imgtec.com>
  3. Date: Tue, 13 Feb 2018 14:47:48 +0000
  4. Subject: [PATCH] egl/tizen: expose EXT_yuv_surface support
  5. This adds support for NV12 and NV21 configs.
  6. ---
  7. src/egl/drivers/dri2/platform_tizen.c | 278 ++++++++++++++++++--------
  8. 1 file changed, 200 insertions(+), 78 deletions(-)
  9. diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c
  10. index 2bc9b3e..b6478a1 100644
  11. --- a/src/egl/drivers/dri2/platform_tizen.c
  12. +++ b/src/egl/drivers/dri2/platform_tizen.c
  13. @@ -100,37 +100,93 @@ create_image_from_native(struct dri2_egl_surface *dri2_surf,
  14. {
  15. _EGLSurface *surf = &dri2_surf->base;
  16. struct dri2_egl_display *dri2_dpy = dri2_egl_display(surf->Resource.Display);
  17. + struct dri2_egl_config *dri2_conf = dri2_egl_config(surf->Config);
  18. + const __DRIconfig *config =
  19. + dri2_get_dri_config(dri2_conf, surf->Type, surf->GLColorspace);
  20. tbm_bo tbm_buf;
  21. tbm_surface_info_s info;
  22. - int fd, fourcc, offset, pitch;
  23. + int fd[TBM_SURF_PLANE_MAX];
  24. + int offset[TBM_SURF_PLANE_MAX];
  25. + int pitch[TBM_SURF_PLANE_MAX];
  26. + int fourcc;
  27. __DRIimage *dri_image;
  28. -
  29. - tbm_buf = tbm_surface_internal_get_bo(tbm_surf, 0);
  30. - if (!tbm_buf) {
  31. - _eglLog(_EGL_DEBUG, "%s: failed to get bo for tbm surface", __func__);
  32. - return NULL;
  33. - }
  34. + enum __DRIYUVColorSpace color_space;
  35. + enum __DRISampleRange sample_range;
  36. + unsigned csc_standard;
  37. + unsigned depth_range;
  38. + unsigned create_error;
  39. if (tbm_surface_get_info(tbm_surf, &info)) {
  40. _eglLog(_EGL_DEBUG, "%s: failed to get tbm surface info", __func__);
  41. return NULL;
  42. }
  43. - fd = tbm_bo_export_fd(tbm_buf);
  44. fourcc = dri2_fourcc_from_tbm_format(info.format);
  45. - offset = info.planes[0].offset;
  46. - pitch = info.planes[0].stride;
  47. -
  48. - dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
  49. - info.width,
  50. - info.height,
  51. - fourcc,
  52. - &fd,
  53. - 1,
  54. - &pitch,
  55. - &offset,
  56. - loaderPrivate);
  57. - close(fd);
  58. +
  59. + for (unsigned i = 0; i < info.num_planes; i++) {
  60. + int index = tbm_surface_internal_get_plane_bo_idx(tbm_surf, i);
  61. +
  62. + tbm_buf = tbm_surface_internal_get_bo(tbm_surf, index);
  63. + if (!tbm_buf) {
  64. + while (i--)
  65. + close(fd[i]);
  66. + _eglLog(_EGL_DEBUG, "%s: failed to get bo %d for tbm surface",
  67. + __func__, i);
  68. + return NULL;
  69. + }
  70. +
  71. + fd[i] = tbm_bo_export_fd(tbm_buf);
  72. + offset[i] = info.planes[i].offset;
  73. + pitch[i] = info.planes[i].stride;
  74. + }
  75. +
  76. + dri2_dpy->core->getConfigAttrib(config,
  77. + __DRI_ATTRIB_YUV_CSC_STANDARD, &csc_standard);
  78. + switch (csc_standard) {
  79. + case __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT:
  80. + color_space = __DRI_YUV_COLOR_SPACE_ITU_REC601;
  81. + break;
  82. + case __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT:
  83. + color_space = __DRI_YUV_COLOR_SPACE_ITU_REC709;
  84. + break;
  85. + case __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT:
  86. + color_space = __DRI_YUV_COLOR_SPACE_ITU_REC2020;
  87. + break;
  88. + default:
  89. + color_space = __DRI_YUV_COLOR_SPACE_UNDEFINED;
  90. + break;
  91. + }
  92. +
  93. + dri2_dpy->core->getConfigAttrib(config,
  94. + __DRI_ATTRIB_YUV_DEPTH_RANGE, &depth_range);
  95. + switch (depth_range) {
  96. + case __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT:
  97. + sample_range = __DRI_YUV_NARROW_RANGE;
  98. + break;
  99. + case __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT:
  100. + sample_range = __DRI_YUV_FULL_RANGE;
  101. + break;
  102. + default:
  103. + sample_range = __DRI_YUV_RANGE_UNDEFINED;
  104. + break;
  105. + }
  106. +
  107. + dri_image = dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
  108. + info.width,
  109. + info.height,
  110. + fourcc,
  111. + fd,
  112. + info.num_planes,
  113. + pitch,
  114. + offset,
  115. + color_space,
  116. + sample_range,
  117. + __DRI_YUV_CHROMA_SITING_UNDEFINED,
  118. + __DRI_YUV_CHROMA_SITING_UNDEFINED,
  119. + &create_error,
  120. + loaderPrivate);
  121. + for (unsigned i = 0; i < info.num_planes; i++)
  122. + close(fd[i]);
  123. if (!dri_image) {
  124. _eglLog(_EGL_DEBUG, "%s: failed to create dri image from tbm bo", __func__);
  125. @@ -792,10 +848,22 @@ dri2_tizen_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
  126. {
  127. }
  128. +static unsigned
  129. +dri2_tizen_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
  130. +{
  131. + switch (cap) {
  132. + case DRI_LOADER_CAP_YUV_SURFACE_IMG:
  133. + return 1;
  134. + default:
  135. + return 0;
  136. + }
  137. +}
  138. +
  139. static const __DRIimageLoaderExtension tizen_image_loader_extension = {
  140. - .base = { __DRI_IMAGE_LOADER, 1 },
  141. + .base = { __DRI_IMAGE_LOADER, 2 },
  142. .getBuffers = dri2_tizen_get_buffers,
  143. .flushFrontBuffer = dri2_tizen_flush_front_buffer,
  144. + .getCapability = dri2_tizen_get_capability,
  145. };
  146. static const __DRIextension *image_loader_extensions[] = {
  147. @@ -804,6 +872,41 @@ static const __DRIextension *image_loader_extensions[] = {
  148. NULL,
  149. };
  150. +static EGLBoolean
  151. +derive_yuv_native_visual_from_config(struct dri2_egl_display *dri2_dpy,
  152. + const __DRIconfig *dri_config,
  153. + int *native_visual)
  154. +{
  155. + unsigned order, subsample, num_planes, plane_bpp;
  156. +
  157. + dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_ORDER,
  158. + &order);
  159. + dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_SUBSAMPLE,
  160. + &subsample);
  161. + dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_NUMBER_OF_PLANES,
  162. + &num_planes);
  163. + dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_PLANE_BPP,
  164. + &plane_bpp);
  165. +
  166. + if ((plane_bpp & __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT) == 0)
  167. + return EGL_FALSE;
  168. +
  169. + if (num_planes != 2)
  170. + return EGL_FALSE;
  171. +
  172. + if (subsample & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT) {
  173. + if (order & __DRI_ATTRIB_YUV_ORDER_YUV_BIT) {
  174. + *native_visual = TBM_FORMAT_NV12;
  175. + return EGL_TRUE;
  176. + } else if (order & __DRI_ATTRIB_YUV_ORDER_YVU_BIT) {
  177. + *native_visual = TBM_FORMAT_NV21;
  178. + return EGL_TRUE;
  179. + }
  180. + }
  181. +
  182. + return EGL_FALSE;
  183. +}
  184. +
  185. static EGLBoolean
  186. dri2_tizen_add_configs(_EGLDisplay *dpy)
  187. {
  188. @@ -811,83 +914,102 @@ dri2_tizen_add_configs(_EGLDisplay *dpy)
  189. int count = 0;
  190. for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
  191. - static const struct rgba_shifts_and_sizes pbuffer_sasa[] = {
  192. - {
  193. - /* ARGB8888 */
  194. - { 16, 8, 0, 24 },
  195. - { 8, 8, 8, 8 },
  196. - },
  197. - {
  198. - /* RGB888 */
  199. - { 16, 8, 0, -1 },
  200. - { 8, 8, 8, 0 },
  201. - },
  202. - {
  203. - /* RGB565 */
  204. - { 11, 5, 0, -1 },
  205. - { 5, 6, 5, 0 },
  206. - },
  207. - };
  208. struct dri2_egl_config *dri2_cfg;
  209. - int shifts[4];
  210. - unsigned int sizes[4];
  211. + unsigned int render_type;
  212. unsigned int caveat = 0;
  213. int surface_type = 0;
  214. - tpl_bool_t is_slow;
  215. EGLint attr_list[] = {
  216. EGL_NATIVE_VISUAL_ID, 0,
  217. EGL_CONFIG_CAVEAT, EGL_NONE,
  218. EGL_NONE,
  219. };
  220. - tpl_result_t res;
  221. -
  222. - dri2_get_shifts_and_sizes(dri2_dpy->core, dri2_dpy->driver_configs[i],
  223. - shifts, sizes);
  224. dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
  225. - __DRI_ATTRIB_BUFFER_SIZE, &depth);
  226. + __DRI_ATTRIB_CONFIG_CAVEAT, &caveat);
  227. dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
  228. - __DRI_ATTRIB_CONFIG_CAVEAT, &caveat);
  229. + __DRI_ATTRIB_RENDER_TYPE, &render_type);
  230. +
  231. + if (render_type & __DRI_ATTRIB_RGBA_BIT) {
  232. + static const struct rgba_shifts_and_sizes pbuffer_sasa[] = {
  233. + {
  234. + /* ARGB8888 */
  235. + { 16, 8, 0, 24 },
  236. + { 8, 8, 8, 8 },
  237. + },
  238. + {
  239. + /* RGB888 */
  240. + { 16, 8, 0, -1 },
  241. + { 8, 8, 8, 0 },
  242. + },
  243. + {
  244. + /* RGB565 */
  245. + { 11, 5, 0, -1 },
  246. + { 5, 6, 5, 0 },
  247. + },
  248. + };
  249. + int shifts[4];
  250. + unsigned int sizes[4];
  251. + unsigned int depth;
  252. + tpl_bool_t is_slow;
  253. + tpl_result_t res;
  254. - res = tpl_display_query_config(dri2_dpy->tpl_dpy, TPL_SURFACE_TYPE_WINDOW,
  255. - sizes[0], sizes[1], sizes[2], sizes[3],
  256. - depth, &attr_list[1], &is_slow);
  257. - if (res != TPL_ERROR_NONE)
  258. - continue;
  259. - surface_type |= EGL_WINDOW_BIT;
  260. + dri2_get_shifts_and_sizes(dri2_dpy->core, dri2_dpy->driver_configs[i],
  261. + shifts, sizes);
  262. - if (is_slow)
  263. - caveat |= __DRI_ATTRIB_SLOW_BIT;
  264. + dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
  265. + __DRI_ATTRIB_BUFFER_SIZE, &depth);
  266. +
  267. + res = tpl_display_query_config(dri2_dpy->tpl_dpy,
  268. + TPL_SURFACE_TYPE_WINDOW,
  269. + sizes[0], sizes[1], sizes[2], sizes[3],
  270. + depth, &attr_list[1], &is_slow);
  271. + if (res != TPL_ERROR_NONE)
  272. + continue;
  273. - res = tpl_display_query_config(dri2_dpy->tpl_dpy, TPL_SURFACE_TYPE_PIXMAP,
  274. - sizes[0], sizes[1], sizes[2], sizes[3],
  275. - depth, NULL, &is_slow);
  276. - if (res == TPL_ERROR_NONE) {
  277. - surface_type |= EGL_PIXMAP_BIT;
  278. + surface_type |= EGL_WINDOW_BIT;
  279. if (is_slow)
  280. caveat |= __DRI_ATTRIB_SLOW_BIT;
  281. - }
  282. - for (unsigned j = 0; j < ARRAY_SIZE(pbuffer_sasa); j++) {
  283. - const struct rgba_shifts_and_sizes *pbuffer_sas = &pbuffer_sasa[j];
  284. -
  285. - if (shifts[0] == pbuffer_sas->shifts[0] &&
  286. - shifts[1] == pbuffer_sas->shifts[1] &&
  287. - shifts[2] == pbuffer_sas->shifts[2] &&
  288. - shifts[3] == pbuffer_sas->shifts[3] &&
  289. - sizes[0] == pbuffer_sas->sizes[0] &&
  290. - sizes[1] == pbuffer_sas->sizes[1] &&
  291. - sizes[2] == pbuffer_sas->sizes[2] &&
  292. - sizes[3] == pbuffer_sas->sizes[3]) {
  293. - surface_type |= EGL_PBUFFER_BIT;
  294. - break;
  295. + res = tpl_display_query_config(dri2_dpy->tpl_dpy,
  296. + TPL_SURFACE_TYPE_PIXMAP,
  297. + sizes[0], sizes[1], sizes[2], sizes[3],
  298. + depth, NULL, &is_slow);
  299. + if (res == TPL_ERROR_NONE) {
  300. + surface_type |= EGL_PIXMAP_BIT;
  301. +
  302. + if (is_slow)
  303. + caveat |= __DRI_ATTRIB_SLOW_BIT;
  304. }
  305. - }
  306. - if (dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
  307. - surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
  308. + for (unsigned j = 0; j < ARRAY_SIZE(pbuffer_sasa); j++) {
  309. + const struct rgba_shifts_and_sizes *pbuffer_sas = &pbuffer_sasa[j];
  310. +
  311. + if (shifts[0] == pbuffer_sas->shifts[0] &&
  312. + shifts[1] == pbuffer_sas->shifts[1] &&
  313. + shifts[2] == pbuffer_sas->shifts[2] &&
  314. + shifts[3] == pbuffer_sas->shifts[3] &&
  315. + sizes[0] == pbuffer_sas->sizes[0] &&
  316. + sizes[1] == pbuffer_sas->sizes[1] &&
  317. + sizes[2] == pbuffer_sas->sizes[2] &&
  318. + sizes[3] == pbuffer_sas->sizes[3]) {
  319. + surface_type |= EGL_PBUFFER_BIT;
  320. + break;
  321. + }
  322. +
  323. + }
  324. +
  325. + if (dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
  326. + surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
  327. + } else if (render_type & __DRI_ATTRIB_YUV_BIT) {
  328. + if (!derive_yuv_native_visual_from_config(dri2_dpy,
  329. + dri2_dpy->driver_configs[i],
  330. + &attr_list[1]))
  331. + continue;
  332. + surface_type = EGL_WINDOW_BIT;
  333. + caveat = 0;
  334. + }
  335. if (caveat & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
  336. attr_list[3] = EGL_NON_CONFORMANT_CONFIG;