diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2015-07-22 11:14:16 +0200 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2015-07-22 17:05:17 +0200 |
commit | 7e7f9d25c2cac6b6e1dd980f263eb34165462299 (patch) | |
tree | dd32559e51c60188532fe919416082057774cc60 | |
parent | 3cc2f1e83aa9a17c51e40da825fa102c2b4fe017 (diff) |
egldevice: implement eglQueryDisplayAttribEXT
This adds a new vfunc to _EGLDriver, QueryDeviceName, which should
return a const string of the device name (usually in the format
'/dev/dri/cardN').
The EGLDevice could perhaps be cached in the EGLDisplay but there
usually aren't loads of devices and this lookup isn't particularly
costly so leave it as is for now.
Right now this only works with the egl_dri2 driver.
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 9 | ||||
-rw-r--r-- | src/egl/main/eglapi.c | 13 | ||||
-rw-r--r-- | src/egl/main/egldevice.c | 74 | ||||
-rw-r--r-- | src/egl/main/egldevice.h | 5 | ||||
-rw-r--r-- | src/egl/main/egldriver.h | 2 |
5 files changed, 102 insertions, 1 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 65194cb990..d899cb9ebe 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -2351,6 +2351,14 @@ dri2_server_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync) return EGL_TRUE; } +static const char * +dri2_query_device_name(_EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy = disp->DriverData; + + return dri2_dpy->device_name; +} + static void dri2_unload(_EGLDriver *drv) { @@ -2472,6 +2480,7 @@ _eglBuiltInDriverDRI2(const char *args) dri2_drv->base.Name = "DRI2"; dri2_drv->base.Unload = dri2_unload; + dri2_drv->base.QueryDeviceName = dri2_query_device_name; return &dri2_drv->base; } diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 1da4829478..35025cc4ec 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -1860,7 +1860,18 @@ eglQueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, EGLAttrib *value) { - RETURN_EGL_SUCCESS(NULL, EGL_TRUE); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + + if (!disp->Initialized) + RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); + + ret = _eglQueryDisplayAttribEXT(drv, disp, attribute, value); + + RETURN_EGL_EVAL(disp, ret); } #endif diff --git a/src/egl/main/egldevice.c b/src/egl/main/egldevice.c index 10f1ddcb22..8a717a6c6a 100644 --- a/src/egl/main/egldevice.c +++ b/src/egl/main/egldevice.c @@ -31,8 +31,12 @@ #include <libudev.h> #endif +#include <assert.h> +#include <string.h> + #include "eglcurrent.h" #include "egldevice.h" +#include "egldriver.h" #include "eglglobals.h" #include "egllog.h" #include "egltypedefs.h" @@ -257,6 +261,76 @@ _eglQueryDeviceStringEXT(_EGLDevice *device, EGLint name) } static EGLBoolean +_eglQueryDeviceFromDisplay(_EGLDeviceInfo *info, + _EGLDriver *drv, + _EGLDisplay *disp, + EGLAttrib *value) +{ +#ifdef HAVE_LIBUDEV + const char *device_name = NULL; + _EGLDevice *dev; + UDEV_SYMBOL(const char *, udev_device_get_property_value, + (struct udev_device *, const char *)); + + if (dlsym_failed) + return EGL_FALSE; + + if (!drv->QueryDeviceName) + return EGL_FALSE; + + device_name = drv->QueryDeviceName(disp); + + mtx_lock(_eglGlobal.Mutex); + + assert(info->got_devices); + + for (dev = info->devices; dev; dev = dev->Next) { + const char *devname = udev_device_get_property_value( + dev->Info, "DEVNAME"); + + if (!devname) + continue; + + if (!strcmp(devname, device_name)) + break; + } + + mtx_unlock(_eglGlobal.Mutex); + + *value = (EGLAttrib) dev; + + return (dev) ? EGL_TRUE : EGL_FALSE; +#else + return EGL_FALSE; +#endif +} + +EGLBoolean +_eglQueryDisplayAttribEXT(_EGLDriver *drv, + _EGLDisplay *disp, + EGLint attribute, + EGLAttrib *value) +{ + _EGLDeviceInfo *info; + + info = _eglEnsureDeviceInfo(EGL_TRUE); + if (!info) + return _eglError(EGL_BAD_ALLOC, "eglQueryDisplayAttribEXT"); + + if (!value) + return _eglError(EGL_BAD_PARAMETER, "eglQueryDisplayAttribEXT"); + + switch (attribute) { + case EGL_DEVICE_EXT: + return _eglQueryDeviceFromDisplay(info, drv, disp, value); + break; + default: + return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryDisplayAttribEXT"); + break; + } +} + +static EGLBoolean _eglFillDeviceList(_EGLDeviceInfo *info) { #ifdef HAVE_LIBUDEV diff --git a/src/egl/main/egldevice.h b/src/egl/main/egldevice.h index 14f0c1ff65..2c7986acb7 100644 --- a/src/egl/main/egldevice.h +++ b/src/egl/main/egldevice.h @@ -62,4 +62,9 @@ _eglQueryDevicesEXT(EGLint max_devices, _EGLDevice **devices, EGLint *num_devices); +EGLBoolean +_eglQueryDisplayAttribEXT(_EGLDriver *drv, _EGLDisplay *disp, + EGLint attribute, EGLAttrib *value); + + #endif /* EGLDEVICE_INCLUDED */ diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 1cf6628446..5e5c7b635f 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -87,6 +87,8 @@ struct _egl_driver */ void (*Unload)(_EGLDriver *drv); + const char * (*QueryDeviceName)(_EGLDisplay *disp); + _EGLAPI API; /**< EGL API dispatch table */ }; |