358 lines
13 KiB
Diff
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
|
|
|