so, export EGL_PLATFORM=drm, is still working, right?<br><br><div class="gmail_quote">On Mon, Aug 15, 2011 at 3:47 PM, Benjamin Franzke <span dir="ltr"><<a href="mailto:bnf@kemper.freedesktop.org">bnf@kemper.freedesktop.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Module: Mesa<br>
Branch: master<br>
Commit: 85fe9484945cb57ffd49df248b0e5057eba6af04<br>
URL: <a href="http://cgit.freedesktop.org/mesa/mesa/commit/?id=85fe9484945cb57ffd49df248b0e5057eba6af04" target="_blank">http://cgit.freedesktop.org/mesa/mesa/commit/?id=85fe9484945cb57ffd49df248b0e5057eba6af04</a><br>
<br>
Author: Benjamin Franzke <<a href="mailto:benjaminfranzke@googlemail.com">benjaminfranzke@googlemail.com</a>><br>
Date: Tue Aug 9 14:23:18 2011 +0200<br>
<br>
egl: Native Display autodetection<br>
<br>
EGL doesnt define howto manage different native platforms.<br>
So mesa has a builtime configurable default platform,<br>
whith non-standard envvar (EGL_PLATFORM) overwrites.<br>
This caused unneeded bugreports, when EGL_PLATFORM was forgotten.<br>
<br>
Detection is grouped into basic types of NativeDisplays (which itself<br>
needs to be detected). The final decision is based on characteristcs<br>
of these basic types:<br>
<br>
File Desciptor based platforms (fbdev):<br>
- fstat(2) to check for being a fd that belongs to a character device<br>
- check kernel subsystem (todo)<br>
<br>
Pointer to structuctures (x11, wayland, drm/gbm):<br>
- mincore(2) to check whether its valid pointer to some memory.<br>
- magic elements (e.g. pointers to exported symbols):<br>
o wayland display stores interface type pointer (first elm.)<br>
o gbm stores pointer to its constructor (first elm.)<br>
o x11 as a fallback (FIXME?)<br>
<br>
Reviewed-by: Kristian Høgsberg <<a href="mailto:krh@bitplanet.net">krh@bitplanet.net</a>><br>
<br>
---<br>
<br>
<a href="http://configure.ac" target="_blank">configure.ac</a> | 2 +<br>
src/egl/main/Makefile | 13 ++++++<br>
src/egl/main/eglapi.c | 8 ++--<br>
src/egl/main/egldisplay.c | 100 +++++++++++++++++++++++++++++++++++++++++++-<br>
src/egl/main/egldisplay.h | 2 +-<br>
5 files changed, 117 insertions(+), 8 deletions(-)<br>
<br>
diff --git a/<a href="http://configure.ac" target="_blank">configure.ac</a> b/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
index 1b1823a..9195da9 100644<br>
--- a/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
+++ b/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
@@ -1370,6 +1370,8 @@ if test "x$enable_egl" = xyes; then<br>
EGL_LIB_DEPS="$DLOPEN_LIBS $SELINUX_LIBS -lpthread"<br>
EGL_DRIVERS_DIRS=""<br>
<br>
+ AC_CHECK_FUNC(mincore, [DEFINES="$DEFINES -DHAVE_MINCORE"])<br>
+<br>
if test "$enable_static" != yes; then<br>
# build egl_glx when libGL is built<br>
if test "x$enable_glx" = xyes; then<br>
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile<br>
index 775fbbe..c100fbf 100644<br>
--- a/src/egl/main/Makefile<br>
+++ b/src/egl/main/Makefile<br>
@@ -93,6 +93,19 @@ ifeq ($(firstword $(EGL_PLATFORMS)),fbdev)<br>
EGL_NATIVE_PLATFORM=_EGL_PLATFORM_FBDEV<br>
endif<br>
<br>
+ifneq ($(findstring x11, $(EGL_PLATFORMS)),)<br>
+LOCAL_CFLAGS += -DHAVE_X11_PLATFORM<br>
+endif<br>
+ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)<br>
+LOCAL_CFLAGS += -DHAVE_WAYLAND_PLATFORM<br>
+endif<br>
+ifneq ($(findstring drm, $(EGL_PLATFORMS)),)<br>
+LOCAL_CFLAGS += -DHAVE_DRM_PLATFORM<br>
+endif<br>
+ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),)<br>
+LOCAL_CFLAGS += -DHAVE_FBDEV_PLATFORM<br>
+endif<br>
+<br>
LOCAL_CFLAGS += \<br>
-D_EGL_NATIVE_PLATFORM=$(EGL_NATIVE_PLATFORM) \<br>
-D_EGL_DRIVER_SEARCH_DIR=\"$(EGL_DRIVER_INSTALL_DIR)\"<br>
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c<br>
index 0ba7794..5d186c6 100644<br>
--- a/src/egl/main/eglapi.c<br>
+++ b/src/egl/main/eglapi.c<br>
@@ -301,7 +301,7 @@ _eglUnlockDisplay(_EGLDisplay *dpy)<br>
EGLDisplay EGLAPIENTRY<br>
eglGetDisplay(EGLNativeDisplayType nativeDisplay)<br>
{<br>
- _EGLPlatformType plat = _eglGetNativePlatform();<br>
+ _EGLPlatformType plat = _eglGetNativePlatform(nativeDisplay);<br>
_EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);<br>
return _eglGetDisplayHandle(dpy);<br>
}<br>
@@ -538,7 +538,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,<br>
EGLSurface ret;<br>
<br>
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);<br>
- if (disp->Platform != _eglGetNativePlatform())<br>
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))<br>
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);<br>
<br>
surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);<br>
@@ -559,7 +559,7 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,<br>
EGLSurface ret;<br>
<br>
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);<br>
- if (disp->Platform != _eglGetNativePlatform())<br>
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))<br>
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);<br>
<br>
surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);<br>
@@ -720,7 +720,7 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)<br>
EGLBoolean ret;<br>
<br>
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);<br>
- if (disp->Platform != _eglGetNativePlatform())<br>
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))<br>
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);<br>
ret = drv->API.CopyBuffers(drv, disp, surf, target);<br>
<br>
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c<br>
index 60f3177..2849dd9 100644<br>
--- a/src/egl/main/egldisplay.c<br>
+++ b/src/egl/main/egldisplay.c<br>
@@ -43,6 +43,23 @@<br>
#include "eglmutex.h"<br>
#include "egllog.h"<br>
<br>
+/* Includes for _eglNativePlatformDetectNativeDisplay */<br>
+#ifdef HAVE_MINCORE<br>
+#include <unistd.h><br>
+#include <sys/mman.h><br>
+#endif<br>
+#ifdef HAVE_WAYLAND_PLATFORM<br>
+#include <wayland-client.h><br>
+#endif<br>
+#ifdef HAVE_DRM_PLATFORM<br>
+#include <gbm.h><br>
+#endif<br>
+#ifdef HAVE_FBDEV_PLATFORM<br>
+#include <stdint.h><br>
+#include <sys/types.h><br>
+#include <sys/stat.h><br>
+#endif<br>
+<br>
<br>
/**<br>
* Return the native platform by parsing EGL_PLATFORM.<br>
@@ -84,17 +101,94 @@ _eglGetNativePlatformFromEnv(void)<br>
<br>
<br>
/**<br>
+ * Perform validity checks on a generic pointer.<br>
+ */<br>
+static EGLBoolean<br>
+_eglPointerIsDereferencable(void *p)<br>
+{<br>
+#ifdef HAVE_MINCORE<br>
+ uintptr_t addr = (uintptr_t) p;<br>
+ unsigned char valid = 0;<br>
+ const long page_size = getpagesize();<br>
+<br>
+ if (p == NULL)<br>
+ return EGL_FALSE;<br>
+<br>
+ /* align addr to page_size */<br>
+ addr &= ~(page_size - 1);<br>
+<br>
+ if (mincore((void *) addr, page_size, &valid) < 0) {<br>
+ _eglLog(_EGL_DEBUG, "mincore failed: %m");<br>
+ return EGL_FALSE;<br>
+ }<br>
+<br>
+ return (valid & 0x01) == 0x01;<br>
+#else<br>
+ return p != NULL;<br>
+#endif<br>
+}<br>
+<br>
+<br>
+/**<br>
+ * Try detecting native platform with the help of native display characteristcs.<br>
+ */<br>
+static _EGLPlatformType<br>
+_eglNativePlatformDetectNativeDisplay(EGLNativeDisplayType nativeDisplay)<br>
+{<br>
+#ifdef HAVE_FBDEV_PLATFORM<br>
+ struct stat buf;<br>
+#endif<br>
+<br>
+ if (nativeDisplay == EGL_DEFAULT_DISPLAY)<br>
+ return _EGL_INVALID_PLATFORM;<br>
+<br>
+#ifdef HAVE_FBDEV_PLATFORM<br>
+ /* fbdev is the only platform that can be a file descriptor. */<br>
+ if (fstat((intptr_t) nativeDisplay, &buf) == 0 && S_ISCHR(buf.st_mode))<br>
+ return _EGL_PLATFORM_FBDEV;<br>
+#endif<br>
+<br>
+ if (_eglPointerIsDereferencable(nativeDisplay)) {<br>
+ void *first_pointer = *(void **) nativeDisplay;<br>
+<br>
+#ifdef HAVE_WAYLAND_PLATFORM<br>
+ /* wl_display is a wl_proxy, which is a wl_object.<br>
+ * wl_object's first element points to the interfacetype. */<br>
+ if (first_pointer == &wl_display_interface)<br>
+ return _EGL_PLATFORM_WAYLAND;<br>
+#endif<br>
+<br>
+#ifdef HAVE_DRM_PLATFORM<br>
+ /* gbm has a pointer to its constructor as first element. */<br>
+ if (first_pointer == gbm_create_device)<br>
+ return _EGL_PLATFORM_DRM;<br>
+#endif<br>
+<br>
+#ifdef HAVE_X11_PLATFORM<br>
+ /* If not matched to any other platform, fallback to x11. */<br>
+ return _EGL_PLATFORM_X11;<br>
+#endif<br>
+ }<br>
+<br>
+ return _EGL_INVALID_PLATFORM;<br>
+}<br>
+<br>
+<br>
+/**<br>
* Return the native platform. It is the platform of the EGL native types.<br>
*/<br>
_EGLPlatformType<br>
-_eglGetNativePlatform(void)<br>
+_eglGetNativePlatform(EGLNativeDisplayType nativeDisplay)<br>
{<br>
static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM;<br>
<br>
if (native_platform == _EGL_INVALID_PLATFORM) {<br>
native_platform = _eglGetNativePlatformFromEnv();<br>
- if (native_platform == _EGL_INVALID_PLATFORM)<br>
- native_platform = _EGL_NATIVE_PLATFORM;<br>
+ if (native_platform == _EGL_INVALID_PLATFORM) {<br>
+ native_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay);<br>
+ if (native_platform == _EGL_INVALID_PLATFORM)<br>
+ native_platform = _EGL_NATIVE_PLATFORM;<br>
+ }<br>
}<br>
<br>
return native_platform;<br>
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h<br>
index 9cd4dbf..05335ad 100644<br>
--- a/src/egl/main/egldisplay.h<br>
+++ b/src/egl/main/egldisplay.h<br>
@@ -150,7 +150,7 @@ struct _egl_display<br>
<br>
<br>
extern _EGLPlatformType<br>
-_eglGetNativePlatform(void);<br>
+_eglGetNativePlatform(EGLNativeDisplayType nativeDisplay);<br>
<br>
<br>
extern void<br>
<br>
_______________________________________________<br>
mesa-commit mailing list<br>
<a href="mailto:mesa-commit@lists.freedesktop.org">mesa-commit@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-commit" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-commit</a><br>
</blockquote></div><br>