Files
fml13v01-buildroot/package/mesa3d/0034-egl-tizen-expose-EXT_yuv_surface-support.patch
T
2022-08-16 17:38:05 +08:00

358 lines
13 KiB
Diff

From 40c0d03cfb2751279b24890d0f752fade968862e Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Tue, 13 Feb 2018 14:47:48 +0000
Subject: [PATCH 34/67] egl/tizen: expose EXT_yuv_surface support
This adds support for NV12 and NV21 configs.
---
src/egl/drivers/dri2/platform_tizen.c | 278 ++++++++++++++++++--------
1 file changed, 200 insertions(+), 78 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c
index 2bc9b3e7c64..b6478a1875b 100644
--- a/src/egl/drivers/dri2/platform_tizen.c
+++ b/src/egl/drivers/dri2/platform_tizen.c
@@ -100,37 +100,93 @@ create_image_from_native(struct dri2_egl_surface *dri2_surf,
{
_EGLSurface *surf = &dri2_surf->base;
struct dri2_egl_display *dri2_dpy = dri2_egl_display(surf->Resource.Display);
+ struct dri2_egl_config *dri2_conf = dri2_egl_config(surf->Config);
+ const __DRIconfig *config =
+ dri2_get_dri_config(dri2_conf, surf->Type, surf->GLColorspace);
tbm_bo tbm_buf;
tbm_surface_info_s info;
- int fd, fourcc, offset, pitch;
+ int fd[TBM_SURF_PLANE_MAX];
+ int offset[TBM_SURF_PLANE_MAX];
+ int pitch[TBM_SURF_PLANE_MAX];
+ int fourcc;
__DRIimage *dri_image;
-
- tbm_buf = tbm_surface_internal_get_bo(tbm_surf, 0);
- if (!tbm_buf) {
- _eglLog(_EGL_DEBUG, "%s: failed to get bo for tbm surface", __func__);
- return NULL;
- }
+ enum __DRIYUVColorSpace color_space;
+ enum __DRISampleRange sample_range;
+ unsigned csc_standard;
+ unsigned depth_range;
+ unsigned create_error;
if (tbm_surface_get_info(tbm_surf, &info)) {
_eglLog(_EGL_DEBUG, "%s: failed to get tbm surface info", __func__);
return NULL;
}
- fd = tbm_bo_export_fd(tbm_buf);
fourcc = dri2_fourcc_from_tbm_format(info.format);
- offset = info.planes[0].offset;
- pitch = info.planes[0].stride;
-
- dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
- info.width,
- info.height,
- fourcc,
- &fd,
- 1,
- &pitch,
- &offset,
- loaderPrivate);
- close(fd);
+
+ for (unsigned i = 0; i < info.num_planes; i++) {
+ int index = tbm_surface_internal_get_plane_bo_idx(tbm_surf, i);
+
+ tbm_buf = tbm_surface_internal_get_bo(tbm_surf, index);
+ if (!tbm_buf) {
+ while (i--)
+ close(fd[i]);
+ _eglLog(_EGL_DEBUG, "%s: failed to get bo %d for tbm surface",
+ __func__, i);
+ return NULL;
+ }
+
+ fd[i] = tbm_bo_export_fd(tbm_buf);
+ offset[i] = info.planes[i].offset;
+ pitch[i] = info.planes[i].stride;
+ }
+
+ dri2_dpy->core->getConfigAttrib(config,
+ __DRI_ATTRIB_YUV_CSC_STANDARD, &csc_standard);
+ switch (csc_standard) {
+ case __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT:
+ color_space = __DRI_YUV_COLOR_SPACE_ITU_REC601;
+ break;
+ case __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT:
+ color_space = __DRI_YUV_COLOR_SPACE_ITU_REC709;
+ break;
+ case __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT:
+ color_space = __DRI_YUV_COLOR_SPACE_ITU_REC2020;
+ break;
+ default:
+ color_space = __DRI_YUV_COLOR_SPACE_UNDEFINED;
+ break;
+ }
+
+ dri2_dpy->core->getConfigAttrib(config,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE, &depth_range);
+ switch (depth_range) {
+ case __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT:
+ sample_range = __DRI_YUV_NARROW_RANGE;
+ break;
+ case __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT:
+ sample_range = __DRI_YUV_FULL_RANGE;
+ break;
+ default:
+ sample_range = __DRI_YUV_RANGE_UNDEFINED;
+ break;
+ }
+
+ dri_image = dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
+ info.width,
+ info.height,
+ fourcc,
+ fd,
+ info.num_planes,
+ pitch,
+ offset,
+ color_space,
+ sample_range,
+ __DRI_YUV_CHROMA_SITING_UNDEFINED,
+ __DRI_YUV_CHROMA_SITING_UNDEFINED,
+ &create_error,
+ loaderPrivate);
+ for (unsigned i = 0; i < info.num_planes; i++)
+ close(fd[i]);
if (!dri_image) {
_eglLog(_EGL_DEBUG, "%s: failed to create dri image from tbm bo", __func__);
@@ -792,10 +848,22 @@ dri2_tizen_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
{
}
+static unsigned
+dri2_tizen_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
+{
+ switch (cap) {
+ case DRI_LOADER_CAP_YUV_SURFACE_IMG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
static const __DRIimageLoaderExtension tizen_image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 1 },
+ .base = { __DRI_IMAGE_LOADER, 2 },
.getBuffers = dri2_tizen_get_buffers,
.flushFrontBuffer = dri2_tizen_flush_front_buffer,
+ .getCapability = dri2_tizen_get_capability,
};
static const __DRIextension *image_loader_extensions[] = {
@@ -804,6 +872,41 @@ static const __DRIextension *image_loader_extensions[] = {
NULL,
};
+static EGLBoolean
+derive_yuv_native_visual_from_config(struct dri2_egl_display *dri2_dpy,
+ const __DRIconfig *dri_config,
+ int *native_visual)
+{
+ unsigned order, subsample, num_planes, plane_bpp;
+
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_ORDER,
+ &order);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_SUBSAMPLE,
+ &subsample);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_NUMBER_OF_PLANES,
+ &num_planes);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_PLANE_BPP,
+ &plane_bpp);
+
+ if ((plane_bpp & __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT) == 0)
+ return EGL_FALSE;
+
+ if (num_planes != 2)
+ return EGL_FALSE;
+
+ if (subsample & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT) {
+ if (order & __DRI_ATTRIB_YUV_ORDER_YUV_BIT) {
+ *native_visual = TBM_FORMAT_NV12;
+ return EGL_TRUE;
+ } else if (order & __DRI_ATTRIB_YUV_ORDER_YVU_BIT) {
+ *native_visual = TBM_FORMAT_NV21;
+ return EGL_TRUE;
+ }
+ }
+
+ return EGL_FALSE;
+}
+
static EGLBoolean
dri2_tizen_add_configs(_EGLDisplay *dpy)
{
@@ -811,83 +914,102 @@ dri2_tizen_add_configs(_EGLDisplay *dpy)
int count = 0;
for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
- static const struct rgba_shifts_and_sizes pbuffer_sasa[] = {
- {
- /* ARGB8888 */
- { 16, 8, 0, 24 },
- { 8, 8, 8, 8 },
- },
- {
- /* RGB888 */
- { 16, 8, 0, -1 },
- { 8, 8, 8, 0 },
- },
- {
- /* RGB565 */
- { 11, 5, 0, -1 },
- { 5, 6, 5, 0 },
- },
- };
struct dri2_egl_config *dri2_cfg;
- int shifts[4];
- unsigned int sizes[4];
+ unsigned int render_type;
unsigned int caveat = 0;
int surface_type = 0;
- tpl_bool_t is_slow;
EGLint attr_list[] = {
EGL_NATIVE_VISUAL_ID, 0,
EGL_CONFIG_CAVEAT, EGL_NONE,
EGL_NONE,
};
- tpl_result_t res;
-
- dri2_get_shifts_and_sizes(dri2_dpy->core, dri2_dpy->driver_configs[i],
- shifts, sizes);
dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
- __DRI_ATTRIB_BUFFER_SIZE, &depth);
+ __DRI_ATTRIB_CONFIG_CAVEAT, &caveat);
dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
- __DRI_ATTRIB_CONFIG_CAVEAT, &caveat);
+ __DRI_ATTRIB_RENDER_TYPE, &render_type);
+
+ if (render_type & __DRI_ATTRIB_RGBA_BIT) {
+ static const struct rgba_shifts_and_sizes pbuffer_sasa[] = {
+ {
+ /* ARGB8888 */
+ { 16, 8, 0, 24 },
+ { 8, 8, 8, 8 },
+ },
+ {
+ /* RGB888 */
+ { 16, 8, 0, -1 },
+ { 8, 8, 8, 0 },
+ },
+ {
+ /* RGB565 */
+ { 11, 5, 0, -1 },
+ { 5, 6, 5, 0 },
+ },
+ };
+ int shifts[4];
+ unsigned int sizes[4];
+ unsigned int depth;
+ tpl_bool_t is_slow;
+ tpl_result_t res;
- res = tpl_display_query_config(dri2_dpy->tpl_dpy, TPL_SURFACE_TYPE_WINDOW,
- sizes[0], sizes[1], sizes[2], sizes[3],
- depth, &attr_list[1], &is_slow);
- if (res != TPL_ERROR_NONE)
- continue;
- surface_type |= EGL_WINDOW_BIT;
+ dri2_get_shifts_and_sizes(dri2_dpy->core, dri2_dpy->driver_configs[i],
+ shifts, sizes);
- if (is_slow)
- caveat |= __DRI_ATTRIB_SLOW_BIT;
+ dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+ __DRI_ATTRIB_BUFFER_SIZE, &depth);
+
+ res = tpl_display_query_config(dri2_dpy->tpl_dpy,
+ TPL_SURFACE_TYPE_WINDOW,
+ sizes[0], sizes[1], sizes[2], sizes[3],
+ depth, &attr_list[1], &is_slow);
+ if (res != TPL_ERROR_NONE)
+ continue;
- res = tpl_display_query_config(dri2_dpy->tpl_dpy, TPL_SURFACE_TYPE_PIXMAP,
- sizes[0], sizes[1], sizes[2], sizes[3],
- depth, NULL, &is_slow);
- if (res == TPL_ERROR_NONE) {
- surface_type |= EGL_PIXMAP_BIT;
+ surface_type |= EGL_WINDOW_BIT;
if (is_slow)
caveat |= __DRI_ATTRIB_SLOW_BIT;
- }
- for (unsigned j = 0; j < ARRAY_SIZE(pbuffer_sasa); j++) {
- const struct rgba_shifts_and_sizes *pbuffer_sas = &pbuffer_sasa[j];
-
- if (shifts[0] == pbuffer_sas->shifts[0] &&
- shifts[1] == pbuffer_sas->shifts[1] &&
- shifts[2] == pbuffer_sas->shifts[2] &&
- shifts[3] == pbuffer_sas->shifts[3] &&
- sizes[0] == pbuffer_sas->sizes[0] &&
- sizes[1] == pbuffer_sas->sizes[1] &&
- sizes[2] == pbuffer_sas->sizes[2] &&
- sizes[3] == pbuffer_sas->sizes[3]) {
- surface_type |= EGL_PBUFFER_BIT;
- break;
+ res = tpl_display_query_config(dri2_dpy->tpl_dpy,
+ TPL_SURFACE_TYPE_PIXMAP,
+ sizes[0], sizes[1], sizes[2], sizes[3],
+ depth, NULL, &is_slow);
+ if (res == TPL_ERROR_NONE) {
+ surface_type |= EGL_PIXMAP_BIT;
+
+ if (is_slow)
+ caveat |= __DRI_ATTRIB_SLOW_BIT;
}
- }
- if (dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
- surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+ for (unsigned j = 0; j < ARRAY_SIZE(pbuffer_sasa); j++) {
+ const struct rgba_shifts_and_sizes *pbuffer_sas = &pbuffer_sasa[j];
+
+ if (shifts[0] == pbuffer_sas->shifts[0] &&
+ shifts[1] == pbuffer_sas->shifts[1] &&
+ shifts[2] == pbuffer_sas->shifts[2] &&
+ shifts[3] == pbuffer_sas->shifts[3] &&
+ sizes[0] == pbuffer_sas->sizes[0] &&
+ sizes[1] == pbuffer_sas->sizes[1] &&
+ sizes[2] == pbuffer_sas->sizes[2] &&
+ sizes[3] == pbuffer_sas->sizes[3]) {
+ surface_type |= EGL_PBUFFER_BIT;
+ break;
+ }
+
+ }
+
+ if (dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
+ surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+ } else if (render_type & __DRI_ATTRIB_YUV_BIT) {
+ if (!derive_yuv_native_visual_from_config(dri2_dpy,
+ dri2_dpy->driver_configs[i],
+ &attr_list[1]))
+ continue;
+ surface_type = EGL_WINDOW_BIT;
+ caveat = 0;
+ }
if (caveat & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
attr_list[3] = EGL_NON_CONFORMANT_CONFIG;
--
2.25.1