[Mesa-dev] [PATCH v2] egl/android: rework device probing
Tapani Pälli
tapani.palli at intel.com
Mon Sep 3 08:07:33 UTC 2018
I've tested that Android Celadon continues to work with these changes ..
Tested-by: Tapani Pälli <tapani.palli at intel.com>
On 08/31/2018 07:59 PM, Emil Velikov wrote:
> From: Emil Velikov <emil.velikov at collabora.com>
>
> Unlike the other platforms, here we aim do guess if the device that we
> somewhat arbitrarily picked, is supported or not.
>
> In particular: when a vendor is _not_ requested we loop through all
> devices, picking the first one which can create a DRI screen.
>
> When a vendor is requested - we use that and do _not_ fall-back to any
> other device.
>
> The former seems a bit fiddly, but considering EGL_EXT_explicit_device and
> EGL_MESA_query_renderer are MIA, this is the best we can do for the
> moment.
>
> With those (proposed) extensions userspace will be able to create a
> separate EGL display for each device, query device details and make the
> conscious decision which one to use.
>
> v2:
> - update droid_open_device_drm_gralloc()
> - set the dri2_dpy->fd before using it
> - return a EGLBoolean for droid_{probe,open}_device*
> - do not warn on droid_load_driver failure (Tomasz)
> - plug mem leak on dri2_create_screen failure (Tomasz)
> - fixup function name typo (Tomasz, Rob)
>
> Cc: Robert Foss <robert.foss at collabora.com>
> Cc: Tomasz Figa <tfiga at chromium.org>
> Cc: Mauro Rossi <issor.oruam at gmail.com>
> Signed-off-by: Emil Velikov <emil.velikov at collabora.com>
> ---
> Rob, I choose not to keep your r-b since the patch has changed quite a
> bit.
>
> Mauro, please check that this version doesn't break the drm_gralloc case.
>
> Thanks
> Emil
> ---
> src/egl/drivers/dri2/platform_android.c | 116 +++++++++++++++---------
> 1 file changed, 73 insertions(+), 43 deletions(-)
>
> diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
> index 1f9fe27ab85..0586633a6db 100644
> --- a/src/egl/drivers/dri2/platform_android.c
> +++ b/src/egl/drivers/dri2/platform_android.c
> @@ -1203,9 +1203,10 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
> }
>
> #ifdef HAVE_DRM_GRALLOC
> -static int
> -droid_open_device_drm_gralloc(struct dri2_egl_display *dri2_dpy)
> +static EGLBoolean
> +droid_open_device_drm_gralloc(_EGLDisplay *disp)
> {
> + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> int fd = -1, err = -EINVAL;
>
> if (dri2_dpy->gralloc->perform)
> @@ -1214,10 +1215,13 @@ droid_open_device_drm_gralloc(struct dri2_egl_display *dri2_dpy)
> &fd);
> if (err || fd < 0) {
> _eglLog(_EGL_WARNING, "fail to get drm fd");
> - fd = -1;
> + return EGL_FALSE;
> }
>
> - return (fd >= 0) ? fcntl(fd, F_DUPFD_CLOEXEC, 3) : -1;
> + if (dri2_dpy->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3) < 0)
> + return EGL_FALSE;
> +
> + return droid_probe_device(disp);
> }
> #endif /* HAVE_DRM_GRALLOC */
>
> @@ -1365,7 +1369,7 @@ static const __DRIextension *droid_image_loader_extensions[] = {
> EGLBoolean
> droid_load_driver(_EGLDisplay *disp)
> {
> - struct dri2_egl_display *dri2_dpy = disp->DriverData;
> + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> const char *err;
>
> dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
> @@ -1404,6 +1408,17 @@ error:
> return false;
> }
>
> +static void
> +droid_unload_driver(_EGLDisplay *disp)
> +{
> + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> +
> + dlclose(dri2_dpy->driver);
> + dri2_dpy->driver = NULL;
> + free(dri2_dpy->driver_name);
> + dri2_dpy->driver_name = NULL;
> +}
> +
> static int
> droid_filter_device(_EGLDisplay *disp, int fd, const char *vendor)
> {
> @@ -1420,13 +1435,31 @@ droid_filter_device(_EGLDisplay *disp, int fd, const char *vendor)
> return 0;
> }
>
> -static int
> +static EGLBoolean
> +droid_probe_device(_EGLDisplay *disp)
> +{
> + /* Check that the device is supported, by attempting to:
> + * - load the dri module
> + * - and, create a screen
> + */
> + if (!droid_load_driver(disp))
> + return EGL_FALSE;
> +
> + if (!dri2_create_screen(disp)) {
> + _eglLog(_EGL_WARNING, "DRI2: failed to create screen");
> + droid_unload_driver(disp);
> + return EGL_FALSE;
> + }
> + return EGL_TRUE;
> +}
> +
> +static EGLBoolean
> droid_open_device(_EGLDisplay *disp)
> {
> #define MAX_DRM_DEVICES 32
> + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
> drmDevicePtr device, devices[MAX_DRM_DEVICES] = { NULL };
> int prop_set, num_devices;
> - int fd = -1, fallback_fd = -1;
>
> char *vendor_name = NULL;
> char vendor_buf[PROPERTY_VALUE_MAX];
> @@ -1436,7 +1469,7 @@ droid_open_device(_EGLDisplay *disp)
>
> num_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
> if (num_devices < 0)
> - return num_devices;
> + return EGL_FALSE;
>
> for (int i = 0; i < num_devices; i++) {
> device = devices[i];
> @@ -1444,41 +1477,49 @@ droid_open_device(_EGLDisplay *disp)
> if (!(device->available_nodes & (1 << DRM_NODE_RENDER)))
> continue;
>
> - fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
> - if (fd < 0) {
> + dri2_dpy->fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
> + if (dri2_dpy->fd < 0) {
> _eglLog(_EGL_WARNING, "%s() Failed to open DRM device %s",
> __func__, device->nodes[DRM_NODE_RENDER]);
> continue;
> }
>
> - if (vendor_name && droid_filter_device(disp, fd, vendor_name)) {
> - /* Match requested, but not found - set as fallback */
> - if (fallback_fd == -1) {
> - fallback_fd = fd;
> - } else {
> - close(fd);
> - fd = -1;
> + /* If a vendor is explicitly provided, we use only that.
> + * Otherwise we fall-back the first device that is supported.
> + */
> + if (vendor_name) {
> + if (droid_filter_device(disp, dri2_dpy->fd, vendor_name)) {
> + /* Device does not match - try next device */
> + close(dri2_dpy->fd);
> + dri2_dpy->fd = -1;
> + continue;
> + }
> + /* If the requested device matches - use it. Regardless if
> + * init fails, do not fall-back to any other device.
> + */
> + if (!droid_probe_device(disp)) {
> + close(dri2_dpy->fd);
> + dri2_dpy->fd = -1;
> }
>
> - continue;
> + break;
> }
> - /* Found a device */
> - break;
> - }
> - drmFreeDevices(devices, num_devices);
> + if (droid_probe_device(disp))
> + break;
>
> - if (fallback_fd < 0 && fd < 0) {
> - _eglLog(_EGL_WARNING, "Failed to open any DRM device");
> - return -1;
> + /* No explicit request - attempt the next device */
> + close(dri2_dpy->fd);
> + dri2_dpy->fd = -1;
> }
> + drmFreeDevices(devices, num_devices);
>
> - if (fd < 0) {
> - _eglLog(_EGL_WARNING, "Failed to open desired DRM device, using fallback");
> - return fallback_fd;
> + if (dri2_dpy->fd < 0) {
> + _eglLog(_EGL_WARNING, "Failed to open %s DRM device",
> + vendor_name ? "desired": "any");
> + return EGL_FALSE;
> }
>
> - close(fallback_fd);
> - return fd;
> + return EGL_TRUE;
> #undef MAX_DRM_DEVICES
> }
>
> @@ -1510,25 +1551,14 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
> disp->DriverData = (void *) dri2_dpy;
>
> #ifdef HAVE_DRM_GRALLOC
> - dri2_dpy->fd = droid_open_device_drm_gralloc(dri2_dpy);
> + if (!droid_open_device_drm_gralloc(disp)) {
> #else
> - dri2_dpy->fd = droid_open_device(disp);
> + if (!droid_open_device(disp)) {
> #endif
> - if (dri2_dpy->fd < 0) {
> err = "DRI2: failed to open device";
> goto cleanup;
> }
>
> - if (!droid_load_driver(disp)) {
> - err = "DRI2: failed to load driver";
> - goto cleanup;
> - }
> -
> - if (!dri2_create_screen(disp)) {
> - err = "DRI2: failed to create screen";
> - goto cleanup;
> - }
> -
> if (!dri2_setup_extensions(disp)) {
> err = "DRI2: failed to setup extensions";
> goto cleanup;
>
More information about the mesa-dev
mailing list