123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- From 6bdf417b37b8b8d50facbb610ab2b936bf5cc626 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] 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 2bc9b3e..b6478a1 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;
|