diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2015-07-22 15:26:42 +0200 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2015-07-22 17:09:00 +0200 |
commit | dfade75f321293425582441142741b1d20493ba5 (patch) | |
tree | 47c69f604e7414a8d45e869af8b2abb0a6c8abe7 /src | |
parent | 7e7f9d25c2cac6b6e1dd980f263eb34165462299 (diff) |
egldevice: implement EGL_MESA_device_hashdevice-hash
Use the hash table string hashing function as it's probably fine. The
hash is taken of the string of the vendor and device IDs from the PCI
bus.
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/egl/main/Makefile.am | 2 | ||||
-rw-r--r-- | src/egl/main/egldevice.c | 69 | ||||
-rw-r--r-- | src/egl/main/egldevice.h | 1 |
3 files changed, 71 insertions, 1 deletions
diff --git a/src/egl/main/Makefile.am b/src/egl/main/Makefile.am index 9030d272b5..e2811371de 100644 --- a/src/egl/main/Makefile.am +++ b/src/egl/main/Makefile.am @@ -23,6 +23,7 @@ include Makefile.sources AM_CFLAGS = \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/src \ -I$(top_srcdir)/src/gbm/main \ $(DEFINES) \ $(VISIBILITY_CFLAGS) \ @@ -37,6 +38,7 @@ libEGL_la_SOURCES = \ ${LIBEGL_C_FILES} libEGL_la_LIBADD = \ + $(top_builddir)/src/util/libmesautil.la $(EGL_LIB_DEPS) libEGL_la_LDFLAGS = \ -no-undefined \ diff --git a/src/egl/main/egldevice.c b/src/egl/main/egldevice.c index 8a717a6c6a..69121e6812 100644 --- a/src/egl/main/egldevice.c +++ b/src/egl/main/egldevice.c @@ -34,6 +34,8 @@ #include <assert.h> #include <string.h> +#include "util/hash_table.h" + #include "eglcurrent.h" #include "egldevice.h" #include "egldriver.h" @@ -79,7 +81,7 @@ _eglEnsureDeviceInfo(EGLBoolean get_devices) /* update this string like in eglglobals.c to add support for a device * extension */ - info->extensions = ""; + info->extensions = "EGL_MESA_device_hash"; #ifdef HAVE_LIBUDEV info->udev = NULL; @@ -216,6 +218,64 @@ _eglFiniDeviceInfo(void) _eglGlobal.DeviceInfo = NULL; } +static EGLBoolean +_eglQueryDeviceHash(_EGLDevice *device, + EGLAttrib *value) +{ +#ifdef HAVE_LIBUDEV + struct udev_device *parent; + EGLBoolean ret = EGL_TRUE; + const char *subsystem_vendor, *subsystem_device; + char *str; + int len; + UDEV_SYMBOL(struct udev_device *, udev_device_get_parent_with_subsystem_devtype, + (struct udev_device *, const char *, const char *)); + UDEV_SYMBOL(const char *, udev_device_get_sysattr_value, + (struct udev_device *, const char *)); + + if (dlsym_failed) + return EGL_FALSE; + + assert(device->Hash == 0); + + mtx_lock(_eglGlobal.Mutex); + + parent = udev_device_get_parent_with_subsystem_devtype( + device->Info, "pci", NULL); + + if (!parent) { + ret = EGL_FALSE; + goto out; + } + + subsystem_vendor = udev_device_get_sysattr_value(parent, "subsystem_vendor"); + subsystem_device = udev_device_get_sysattr_value(parent, "subsystem_device"); + + if (!subsystem_vendor || !subsystem_device) { + ret = EGL_FALSE; + goto out; + } + + len = strlen(subsystem_vendor) + strlen(subsystem_device); + str = calloc(len + 1, sizeof(char)); + + str = strdup(subsystem_vendor); + strcat(str, subsystem_device); + + *value = _mesa_hash_string(str); + + device->Hash = *value; + + free(str); + +out: + mtx_unlock(_eglGlobal.Mutex); + return ret; +#else + return EGL_FALSE; +#endif +} + /** * Get attribute about specific device */ @@ -228,6 +288,13 @@ _eglQueryDeviceAttribEXT(_EGLDevice *device, return _eglError(EGL_BAD_PARAMETER, "eglQueryDeviceAttribEXT"); switch (attribute) { + case EGL_DEVICE_HASH_MESA: + if (device->Hash > 0) { + return device->Hash; + } else { + return _eglQueryDeviceHash(device, value); + } + break; default: return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryDeviceAttribEXT"); break; diff --git a/src/egl/main/egldevice.h b/src/egl/main/egldevice.h index 2c7986acb7..fb30bd2050 100644 --- a/src/egl/main/egldevice.h +++ b/src/egl/main/egldevice.h @@ -37,6 +37,7 @@ struct _egl_device { _EGLDevice *Next; void *Info; + EGLint Hash; }; |