[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