It adds support of dri_image_loader to egl dri2 tizen backend. - referenced a basic buffer flow and management implementation from android's.
It adds dri_image_back/dri_image_back member variables to dri_egl_surface for a management of back/front buffers. v2: - Fixes from Emil's review: a) Use dri2_surface_destroy_back_image() helper b) Use dri2_surface_destroy_front_image() helper c) Use dri2_surface_get_front_image() helper - Use get_stride helper on get_back_bo() v3: - Use dri2_egl_surface's default dri_image_back and dri_image_front Signed-off-by: Mun Gwan-gyeong <elong...@gmail.com> --- src/egl/drivers/dri2/platform_tizen.c | 143 +++++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 3 deletions(-) diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c index 16a0c7c00d..e43691b7e5 100644 --- a/src/egl/drivers/dri2/platform_tizen.c +++ b/src/egl/drivers/dri2/platform_tizen.c @@ -224,6 +224,8 @@ tizen_window_enqueue_buffer_with_damage(_EGLDisplay *disp, mtx_lock(&disp->Mutex); + dri2_surface_destroy_back_image(&dri2_surf->base); + return EGL_TRUE; cleanup: @@ -328,7 +330,9 @@ tizen_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, if (!dri2_surf->tpl_surface) goto cleanup_surface; - if (dri2_dpy->dri2) + if (dri2_dpy->image_driver) + createNewDrawable = dri2_dpy->image_driver->createNewDrawable; + else if (dri2_dpy->dri2) createNewDrawable = dri2_dpy->dri2->createNewDrawable; else createNewDrawable = dri2_dpy->swrast->createNewDrawable; @@ -379,6 +383,9 @@ tizen_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->tbm_surface) tizen_window_cancel_buffer(disp, dri2_surf); + dri2_surface_destroy_back_image(surf); + dri2_surface_destroy_front_image(surf); + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); tpl_object_unreference((tpl_object_t *)dri2_surf->tpl_surface); @@ -403,6 +410,119 @@ update_buffers(struct dri2_egl_surface *dri2_surf) return 0; } +static int +get_back_bo(struct dri2_egl_surface *dri2_surf) +{ + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + int fourcc, pitch; + int offset = 0, fd; + tbm_surface_info_s surf_info; + + if (dri2_surf->dri_image_back) + return 0; + + if (dri2_surf->base.Type == EGL_WINDOW_BIT) { + if (!dri2_surf->tbm_surface) { + _eglLog(_EGL_WARNING, "Could not get native buffer"); + return -1; + } + + fd = get_native_buffer_fd(dri2_surf->tbm_surface); + if (fd < 0) { + _eglLog(_EGL_WARNING, "Could not get native buffer FD"); + return -1; + } + + pitch = get_stride(dri2_surf->tbm_surface); + fourcc = get_fourcc(dri2_surf->tbm_format); + + if (fourcc == -1 || pitch == 0) { + _eglLog(_EGL_WARNING, "Invalid buffer fourcc(%x) or pitch(%d)", + fourcc, pitch); + return -1; + } + + dri2_surf->base.Width = surf_info.width; + dri2_surf->base.Height = surf_info.height; + + dri2_surf->dri_image_back = + dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, + dri2_surf->base.Width, + dri2_surf->base.Height, + fourcc, + &fd, + 1, + &pitch, + &offset, + dri2_surf); + + if (!dri2_surf->dri_image_back) { + _eglLog(_EGL_WARNING, "failed to create DRI image from FD"); + return -1; + } + } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) { + /* The EGL 1.5 spec states that pbuffers are single-buffered. Specifically, + * the spec states that they have a back buffer but no front buffer, in + * contrast to pixmaps, which have a front buffer but no back buffer. + * + * Single-buffered surfaces with no front buffer confuse Mesa; so we deviate + * from the spec, following the precedent of Mesa's EGL X11 platform. The + * X11 platform correctly assigns pbuffers to single-buffered configs, but + * assigns the pbuffer a front buffer instead of a back buffer. + * + * Pbuffers in the X11 platform mostly work today, so let's just copy its + * behavior instead of trying to fix (and hence potentially breaking) the + * world. + */ + _eglLog(_EGL_DEBUG, "DRI driver requested unsupported back buffer for pbuffer surface"); + } + + return 0; +} + +/* Some drivers will pass multiple bits in buffer_mask. + * For such case, will go through all the bits, and + * will not return error when unsupported buffer is requested, only + * return error when the allocation for supported buffer failed. + */ +static int +tizen_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format, + uint32_t *stamp, void *loaderPrivate, + uint32_t buffer_mask, struct __DRIimageList *images) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + + images->image_mask = 0; + images->front = NULL; + images->back = NULL; + + if (update_buffers(dri2_surf) < 0) + return 0; + + if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) { + if (dri2_surface_get_front_image(&dri2_surf->base, format) < 0) + return 0; + + if (dri2_surf->dri_image_front) { + images->front = dri2_surf->dri_image_front; + images->image_mask |= __DRI_IMAGE_BUFFER_FRONT; + } + } + + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) { + if (get_back_bo(dri2_surf) < 0) + return 0; + + if (dri2_surf->dri_image_back) { + images->back = dri2_surf->dri_image_back; + images->image_mask |= __DRI_IMAGE_BUFFER_BACK; + } + } + + return 1; +} + static EGLint tizen_query_buffer_age(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface) { @@ -1041,6 +1161,13 @@ static const __DRIdri2LoaderExtension tizen_dri2_loader_extension = { .flushFrontBuffer = tizen_flush_front_buffer, }; +static const __DRIimageLoaderExtension tizen_image_loader_extension = { + .base = { __DRI_IMAGE_LOADER, 1 }, + + .getBuffers = tizen_image_get_buffers, + .flushFrontBuffer = tizen_flush_front_buffer, +}; + static const __DRIswrastLoaderExtension tizen_swrast_loader_extension = { .base = { __DRI_SWRAST_LOADER, 2 }, @@ -1057,6 +1184,13 @@ static const __DRIextension *tizen_dri2_loader_extensions[] = { NULL, }; +static const __DRIextension *tizen_image_loader_extensions[] = { + &tizen_image_loader_extension.base, + &image_lookup_extension.base, + &use_invalidate.base, + NULL, +}; + static const __DRIextension *tizen_swrast_loader_extensions[] = { &tizen_swrast_loader_extension.base, &image_lookup_extension.base, @@ -1223,8 +1357,11 @@ dri2_initialize_tizen(_EGLDriver *drv, _EGLDisplay *dpy) goto cleanup; } } else { - err = "DRI2: render node is not suppported"; - goto cleanup; + dri2_dpy->loader_extensions = tizen_image_loader_extensions; + if (!dri2_load_driver_dri3(dpy)) { + err = "DRI3: failed to load driver"; + goto cleanup; + } } } else { -- 2.14.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev