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 | |
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>
-rw-r--r-- | docs/specs/EGL_MESA_device_hash.txt | 95 | ||||
-rw-r--r-- | include/EGL/eglmesaext.h | 5 | ||||
-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 |
5 files changed, 171 insertions, 1 deletions
diff --git a/docs/specs/EGL_MESA_device_hash.txt b/docs/specs/EGL_MESA_device_hash.txt new file mode 100644 index 0000000000..910a33e66e --- /dev/null +++ b/docs/specs/EGL_MESA_device_hash.txt @@ -0,0 +1,95 @@ +Name + + EGL_MESA_device_hash + +Name Strings + + EGL_MESA_device_hash + +Contributors + + Jonny Lamb <jonny.lamb@collabora.co.uk> + +Contact + + Jonny Lamb <jonny.lamb@collabora.co.uk> + +Status + + Draft + +Version + + Version 1, 2015-07-22 + +Number + + EGL Extension #XXX + +Extension Type + + EGL device extension + +Dependencies + + This extension is written against the wording of EGL 1.5 as + modified by EGL_EXT_device_query. + + EGL_EXT_device_query is required. + +Overview + + The EGLDeviceEXT object is useful for referring to a particular + device on the system. However, this handle is only valid for the + current process. For referring to devices across different + processes on the same system an integer value is required. + + Additionally, when using functions with EGLint argument types, it + is currently not possible to refer to EGLDeviceEXT objects. An + integer value for said objects is necessary to enable this + functionality. The <attrib_list> argument of eglGetPlatformDisplay + is an example of a function with an argument of type EGLint. + +New Types + + None + +New Procedures and Functions + + None + +New Tokens + + Accepted as a queried <attribute> in eglQueryDeviceAttribEXT: + + EGL_DEVICE_HASH_MESA 0x31E0 + +Additions to the EGL 1.5 Specification + + In section 3.2 "Devices", replace the paragraph immediately + following the prototype for eglQueryDeviceAttribEXT with the + following: + + "On success, EGL_TRUE is returned and the requested attribute + value is returned in <value>. Currently the only valid value for + <attribute> is EGL_DEVICE_HASH_MESA which returns in <value> an + EGLint hash value for the EGLDeviceEXT object given in <device>. + This hash value can be used for comparing EGLDeviceEXT objects + across different processes on the same system and for when an EGL + function argument type is EGLint instead of EGLattrib. With a + successful call using EGL_DEVICE_HASH_MESA as <attribute> the + returned EGLint is always non-zero. + + The method used to calculate the hash for a EGLDeviceEXT is left + up to the implementation. Compatibility between hash values can + only be assumed with the same version of the same implementation + running on the same system." + +Issues + + None + +Revision History + + Version 1, 2015-7-22 (Jonny Lamb) + - Initial draft diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h index 917a2043c7..ea96e97737 100644 --- a/include/EGL/eglmesaext.h +++ b/include/EGL/eglmesaext.h @@ -95,6 +95,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG #define EGL_NO_CONFIG_MESA ((EGLConfig)0) #endif +#ifndef EGL_MESA_device_hash +#define EGL_MESA_device_hash 1 +#define EGL_DEVICE_HASH_MESA 0x31E0 +#endif + #ifdef __cplusplus } #endif 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; }; |