[Mesa-dev] [PATCH 07/10] egl/android: Make drm_gralloc headers optional

Tomasz Figa tfiga at chromium.org
Fri Jul 15 07:53:53 UTC 2016


We can support render nodes alone without any private headers, so let's
make support for control nodes depend on presence of private drm_gralloc
headers.

Signed-off-by: Tomasz Figa <tfiga at chromium.org>
---
 src/egl/Android.mk                      |   1 +
 src/egl/drivers/dri2/egl_dri2.h         |   2 +
 src/egl/drivers/dri2/platform_android.c | 194 ++++++++++++++++++++++----------
 3 files changed, 138 insertions(+), 59 deletions(-)

diff --git a/src/egl/Android.mk b/src/egl/Android.mk
index bfd56a7..72ec02a 100644
--- a/src/egl/Android.mk
+++ b/src/egl/Android.mk
@@ -41,6 +41,7 @@ LOCAL_SRC_FILES := \
 LOCAL_CFLAGS := \
 	-D_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_ANDROID \
 	-D_EGL_BUILT_IN_DRIVER_DRI2 \
+	-DHAS_GRALLOC_DRM_HEADERS \
 	-DHAVE_ANDROID_PLATFORM
 
 LOCAL_C_INCLUDES := \
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 3ffc177..6f9623b 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -65,7 +65,9 @@
 #endif
 
 #include <hardware/gralloc.h>
+#ifdef HAS_GRALLOC_DRM_HEADERS
 #include <gralloc_drm_handle.h>
+#endif
 #include <cutils/log.h>
 
 #endif /* HAVE_ANDROID_PLATFORM */
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 0f707dd..4473400 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -38,7 +38,10 @@
 #include "loader.h"
 #include "egl_dri2.h"
 #include "egl_dri2_fallbacks.h"
+
+#ifdef HAS_GRALLOC_DRM_HEADERS
 #include "gralloc_drm.h"
+#endif
 
 static int
 get_format_bpp(int native)
@@ -104,11 +107,13 @@ get_native_buffer_fd(struct ANativeWindowBuffer *buf)
    return (handle && handle->numFds) ? handle->data[0] : -1;
 }
 
+#ifdef HAS_GRALLOC_DRM_HEADERS
 static int
 get_native_buffer_name(struct ANativeWindowBuffer *buf)
 {
    return gralloc_drm_get_gem_handle(buf->handle);
 }
+#endif
 
 static EGLBoolean
 droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
@@ -210,6 +215,7 @@ droid_window_cancel_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf
    droid_window_enqueue_buffer(disp, dri2_surf);
 }
 
+#ifdef HAS_GRALLOC_DRM_HEADERS
 static __DRIbuffer *
 droid_alloc_local_buffer(struct dri2_egl_surface *dri2_surf,
                          unsigned int att, unsigned int format)
@@ -228,6 +234,7 @@ droid_alloc_local_buffer(struct dri2_egl_surface *dri2_surf,
 
    return dri2_surf->local_buffers[att];
 }
+#endif
 
 static void
 droid_free_local_buffers(struct dri2_egl_surface *dri2_surf)
@@ -509,53 +516,43 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
 }
 
 static _EGLImage *
-dri2_create_image_android_native_buffer(_EGLDisplay *disp,
-                                        _EGLContext *ctx,
-                                        struct ANativeWindowBuffer *buf)
+droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx,
+                                 struct ANativeWindowBuffer *buf)
 {
-   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
-   struct dri2_egl_image *dri2_img;
-   int name, fd;
-   int format;
-
-   if (ctx != NULL) {
-      /* From the EGL_ANDROID_image_native_buffer spec:
-       *
-       *     * If <target> is EGL_NATIVE_BUFFER_ANDROID and <ctx> is not
-       *       EGL_NO_CONTEXT, the error EGL_BAD_CONTEXT is generated.
-       */
-      _eglError(EGL_BAD_CONTEXT, "eglCreateEGLImageKHR: for "
-                "EGL_NATIVE_BUFFER_ANDROID, the context must be "
-                "EGL_NO_CONTEXT");
-      return NULL;
-   }
-
-   if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
-       buf->common.version != sizeof(*buf)) {
-      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
-      return NULL;
-   }
+   int fd;
 
    fd = get_native_buffer_fd(buf);
-   if (fd >= 0) {
-      const int fourcc = get_fourcc(get_format(buf->format));
-      const int pitch = buf->stride * get_format_bpp(buf->format);
+   if (fd < 0)
+	   return NULL;
+
+   const int fourcc = get_fourcc(get_format(buf->format));
+   const int pitch = buf->stride * get_format_bpp(buf->format);
+
+   const EGLint attr_list[14] = {
+      EGL_WIDTH, buf->width,
+      EGL_HEIGHT, buf->height,
+      EGL_LINUX_DRM_FOURCC_EXT, fourcc,
+      EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+      EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch,
+      EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
+      EGL_NONE, 0
+   };
 
-      const EGLint attr_list[14] = {
-         EGL_WIDTH, buf->width,
-         EGL_HEIGHT, buf->height,
-         EGL_LINUX_DRM_FOURCC_EXT, fourcc,
-         EGL_DMA_BUF_PLANE0_FD_EXT, fd,
-         EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch,
-         EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
-         EGL_NONE, 0
-      };
+   if (fourcc == -1 || pitch == 0)
+      return NULL;
 
-      if (fourcc == -1 || pitch == 0)
-         return NULL;
+   return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list);
+}
 
-      return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list);
-   }
+static _EGLImage *
+droid_create_image_from_name(_EGLDisplay *disp, _EGLContext *ctx,
+                             struct ANativeWindowBuffer *buf)
+{
+#ifdef HAS_GRALLOC_DRM_HEADERS
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_image *dri2_img;
+   int name;
+   int format;
 
    name = get_native_buffer_name(buf);
    if (!name) {
@@ -593,6 +590,42 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp,
    }
 
    return &dri2_img->base;
+#else
+   _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR: Only PRIME buffers are supported");
+   return NULL;
+#endif
+}
+
+static _EGLImage *
+dri2_create_image_android_native_buffer(_EGLDisplay *disp,
+                                        _EGLContext *ctx,
+                                        struct ANativeWindowBuffer *buf)
+{
+   _EGLImage *image;
+
+   if (ctx != NULL) {
+      /* From the EGL_ANDROID_image_native_buffer spec:
+       *
+       *     * If <target> is EGL_NATIVE_BUFFER_ANDROID and <ctx> is not
+       *       EGL_NO_CONTEXT, the error EGL_BAD_CONTEXT is generated.
+       */
+      _eglError(EGL_BAD_CONTEXT, "eglCreateEGLImageKHR: for "
+                "EGL_NATIVE_BUFFER_ANDROID, the context must be "
+                "EGL_NO_CONTEXT");
+      return NULL;
+   }
+
+   if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
+       buf->common.version != sizeof(*buf)) {
+      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+      return NULL;
+   }
+
+   image = droid_create_image_from_prime_fd(disp, ctx, buf);
+   if (image)
+      return image;
+
+   return droid_create_image_from_name(disp, ctx, buf);
 }
 
 static _EGLImage *
@@ -614,6 +647,7 @@ droid_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
 {
 }
 
+#ifdef HAS_GRALLOC_DRM_HEADERS
 static int
 droid_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf,
                                     unsigned int *attachments, int count)
@@ -695,6 +729,7 @@ droid_get_buffers_with_format(__DRIdrawable * driDrawable,
 
    return dri2_surf->buffers;
 }
+#endif
 
 static EGLBoolean
 droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
@@ -773,7 +808,28 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
 }
 
 static int
-droid_open_device(void)
+droid_probe_device(_EGLDisplay *dpy, int fd)
+{
+   struct dri2_egl_display *dri2_dpy = dpy->DriverData;
+
+   dri2_dpy->driver_name = loader_get_driver_for_fd(fd, 0);
+   if (!dri2_dpy->driver_name)
+      return -1;
+
+   dri2_dpy->fd = fd;
+   if (!dri2_load_driver(dpy)) {
+      dri2_dpy->fd = -1;
+      free(dri2_dpy->driver_name);
+      dri2_dpy->driver_name = NULL;
+      return -1;
+   }
+
+   return 0;
+}
+
+#ifdef HAS_GRALLOC_DRM_HEADERS
+static int
+droid_open_device(_EGLDisplay *dpy)
 {
    const hw_module_t *mod;
    int fd = -1, err;
@@ -788,11 +844,40 @@ droid_open_device(void)
    }
    if (err || fd < 0) {
       _eglLog(_EGL_WARNING, "fail to get drm fd");
-      fd = -1;
+      return -1;
    }
 
-   return (fd >= 0) ? dup(fd) : -1;
+   return droid_probe_device(dpy, fd);
 }
+#else
+#define DRM_RENDER_DEV_NAME  "%s/renderD%d"
+
+static int
+droid_open_device(_EGLDisplay *dpy)
+{
+   struct dri2_egl_display *dri2_dpy = dpy->DriverData;
+   const int limit = 64;
+   const int base = 128;
+   int fd;
+   int i;
+
+   for (i = 0; i < limit; ++i) {
+      char *card_path;
+      if (asprintf(&card_path, DRM_RENDER_DEV_NAME, DRM_DIR_NAME, base + i) < 0)
+         continue;
+
+      fd = loader_open_device(card_path);
+      free(card_path);
+      if (fd < 0)
+         continue;
+
+      if (!droid_probe_device(dpy, fd))
+         return 0;
+   }
+
+   return -1;
+}
+#endif
 
 /* support versions < JellyBean */
 #ifndef ALOGW
@@ -868,28 +953,17 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy)
 
    dpy->DriverData = (void *) dri2_dpy;
 
-   dri2_dpy->fd = droid_open_device();
-   if (dri2_dpy->fd < 0) {
+   if (droid_open_device(dpy) < 0) {
       err = "DRI2: failed to open device";
       goto cleanup_display;
    }
 
-   dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
-   if (dri2_dpy->driver_name == NULL) {
-      err = "DRI2: failed to get driver name";
-      goto cleanup_device;
-   }
-
-   if (!dri2_load_driver(dpy)) {
-      err = "DRI2: failed to load driver";
-      goto cleanup_driver_name;
-   }
-
    dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
 
    /* render nodes cannot use Gem names, and thus do not support
     * the __DRI_DRI2_LOADER extension */
    if (!dri2_dpy->is_render_node) {
+#ifdef HAS_GRALLOC_DRM_HEADERS
       dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
       dri2_dpy->dri2_loader_extension.base.version = 3;
       dri2_dpy->dri2_loader_extension.getBuffers = NULL;
@@ -897,6 +971,10 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy)
       dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
         droid_get_buffers_with_format;
       dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
+#else
+      err = "DRI2: only render nodes are supported";
+      goto cleanup_driver;
+#endif
    } else {
       dri2_dpy->extensions[0] = &droid_image_loader_extension.base;
    }
@@ -931,9 +1009,7 @@ cleanup_screen:
    dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
 cleanup_driver:
    dlclose(dri2_dpy->driver);
-cleanup_driver_name:
    free(dri2_dpy->driver_name);
-cleanup_device:
    close(dri2_dpy->fd);
 cleanup_display:
    free(dri2_dpy);
-- 
2.8.0.rc3.226.g39d4020



More information about the mesa-dev mailing list