[Mesa-dev] [PATCH v3 15/22] egl/tizen: add support of dri_image_loader (v2)
Gwan-gyeong Mun
elongbug at gmail.com
Wed Oct 4 06:50:27 UTC 2017
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_egl_surface_destroy_image_back() helper
b) Use dri2_egl_surface_destroy_image_front() helper
c) Use dri2_egl_surface_get_image_front() helper
- Use get_stride helper on get_back_bo()
Signed-off-by: Mun Gwan-gyeong <elongbug at gmail.com>
---
src/egl/drivers/dri2/egl_dri2.h | 2 +
src/egl/drivers/dri2/platform_tizen.c | 143 +++++++++++++++++++++++++++++++++-
2 files changed, 142 insertions(+), 3 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index d24425dba1..d9215ea06e 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -340,6 +340,8 @@ struct dri2_egl_surface
tpl_surface_t *tpl_surface;
tbm_surface_h tbm_surface;
tbm_format tbm_format;
+ __DRIimage *dri_image_back;
+ __DRIimage *dri_image_front;
/* Used to record all the tbm_surface created by tpl_surface and their ages.
* Usually Tizen uses at most triple buffers in tpl_surface (tbm_surface_queue)
diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c
index 091ae4dcef..87c7e1e6a2 100644
--- a/src/egl/drivers/dri2/platform_tizen.c
+++ b/src/egl/drivers/dri2/platform_tizen.c
@@ -225,6 +225,8 @@ tizen_window_enqueue_buffer_with_damage(_EGLDisplay *disp,
mtx_lock(&disp->Mutex);
+ dri2_egl_surface_destroy_image_back(dri2_surf);
+
return EGL_TRUE;
cleanup:
@@ -329,7 +331,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;
@@ -380,6 +384,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_egl_surface_destroy_image_back(dri2_surf);
+ dri2_egl_surface_destroy_image_front(dri2_surf);
+
dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
tpl_object_unreference((tpl_object_t *)dri2_surf->tpl_surface);
@@ -404,6 +411,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_egl_surface_get_image_front(dri2_surf, 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)
{
@@ -1042,6 +1162,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 },
@@ -1058,6 +1185,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,
@@ -1224,8 +1358,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
More information about the mesa-dev
mailing list