[Mesa-dev] [PATCH] egl: Introduce alternative native display types
Chia-I Wu
olvaffe at gmail.com
Tue May 18 09:41:12 PDT 2010
2010/5/18 Jakob Bornecrantz <wallbraker at gmail.com>:
> 2010/5/17 Kristian Høgsberg <krh at bitplanet.net>:
>> The EGL native platform API is determined at compile time and resolves
>> to Win32, X11 or Symbian at this point. This means that if we want to
>> support XCB or a native DRM implementation, they have to be their platforms
>> and result in different libEGL.so's with identical ABI but different
>> entrypoint semantics. From a distro point of view, and really, any point
>> of view, this is a mess, since the different libraries can't easily co-exist
>> without fiddling with linker paths. And if you get it wrong, an application
>> requiring the X11 platform libEGL.so will happily link against any other
>> libEGL.so and segfault when eglGetDisplay() doesn't do what it expects.
>>
>> We can get around this by overloading the X11 native entrypoints instead.
>> The X Display struct has as its first member a pointer to XExtData. The
>> pointer will always have bits 0 and 1 set to 0, which we can use to
>> distinguish a struct that's not an X display. This lets us pass in a
>> custom struct that can provide initialization data for other platforms
>> in the same libEGL.so.
>>
>> The convention we're establishing is that the first field of such a struct
>> must be a pointer, so as to overlap with the layout of the X display
>> struct. We can then enummerate the different display types using odd
>> numbers cast to a pointer (ensuring bit 0 is set). This patch introduces
>> two new types of displays: EGL_DISPLAY_TYPE_DRM_MESA which lets us
>> initialize EGL directly on a DRM file descriptor or device filename and
>> EGL_DISPLAY_TYPE_XCB_MESA which lets us initialize EGL on X using an
>> xcb_connection_t instead of a classic Xlib Display.
>
> This sounds good to me, there are just some minor nitpicks that would
> be nice to be resolved.
>
> 1. Could you write some docu about EGLDisplayTypeDRMMESA, like that
> the display should return the FD after init in the struct. Also what
> happens if (drm->device_name == null && drm->fd < 0) looking at the
> code it would fail to load is this what we want?
I think the EGL prefix should be dropped. We are defining a new
platform here: a platform whose display can be an xlib display, xcb
connection or drm. It should not have the "EGL" prefix.
Actually, I think this platform should have its own header file.
eglplatform.h will include the header file and typedef the native
types defined there to EGL types.
> 2. A helper function _eglNativeDisplayIsX(EGLNativeDisplay) or
> something like that currently the drivers aren't that future proof if
> we add new displaytypes. But we can add that later.
> 3. See inlined comment. Can also wait.
>
> Other then that you have my Reviewed-by.
>
> Cheers Jakob.
>
>> ---
>> include/EGL/eglplatform.h | 17 ++++++++++++++
>> src/egl/drivers/dri2/egl_dri2.c | 45 ++++++++++++++++++++++++++++++--------
>> 2 files changed, 52 insertions(+), 10 deletions(-)
>>
>> diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h
>> index c625088..f9d0eb3 100644
>> --- a/include/EGL/eglplatform.h
>> +++ b/include/EGL/eglplatform.h
>> @@ -88,6 +88,23 @@ typedef Display *EGLNativeDisplayType;
>> typedef Pixmap EGLNativePixmapType;
>> typedef Window EGLNativeWindowType;
>>
>> +typedef struct EGLDisplayTypeMESA EGLDisplayTypeMESA;
>> +
>> +#define EGL_DISPLAY_TYPE_DRM_MESA ((EGLDisplayTypeMESA *) 1)
>> +
>> +typedef struct EGLDisplayTypeDRMMESA {
>> + const EGLDisplayTypeMESA *type;
>> + const char *device;
>> + int fd;
>> +} EGLDisplayTypeDRMMESA;
>> +
>> +#define EGL_DISPLAY_TYPE_XCB_MESA ((EGLDisplayTypeMESA *) 3)
>> +
>> +typedef struct EGLDisplayTypeXCBMESA {
>> + const EGLDisplayTypeMESA *type;
>> + struct xcb_connection_t *conn;
>> +} EGLDisplayTypeXCBMESA;
>> +
>> #else
>> #error "Platform not recognized"
>> #endif
>> diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
>> index a7030f0..39c90b3 100644
>> --- a/src/egl/drivers/dri2/egl_dri2.c
>> +++ b/src/egl/drivers/dri2/egl_dri2.c
>> @@ -634,6 +634,10 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
>> return EGL_TRUE;
>> }
>>
>> +struct generic_display {
>> + void *pointer;
>> +};
>> +
>> /**
>> * Called via eglInitialize(), GLX_drv->API.Initialize().
>> */
>> @@ -645,25 +649,42 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
>> struct dri2_egl_display *dri2_dpy;
>> char path[PATH_MAX], *search_paths, *p, *next, *end;
>> unsigned int api_mask;
>> + struct generic_display *generic;
>> + EGLDisplayTypeDRMMESA *drm_display;
>> + EGLDisplayTypeXCBMESA *xcb_display;
>
> Couldn't generic just be replaced with:
> EGLDisplayTypeMESA **type = (EGLDisplayTypeMESA **)disp->NativeDisplay;
> if (type && *type == EGL_DISPLAY_TYPE_DRM_MESA) {
> /* stuffzor */
> }
>
>>
>> dri2_dpy = malloc(sizeof *dri2_dpy);
>> if (!dri2_dpy)
>> return _eglError(EGL_BAD_ALLOC, "eglInitialize");
>>
>> + memset(dri2_dpy, 0, sizeof *dri2_dpy);
>> disp->DriverData = (void *) dri2_dpy;
>> + generic = (struct generic_display *) disp->NativeDisplay;
>> +
>> if (disp->NativeDisplay == NULL) {
>> dri2_dpy->conn = xcb_connect(0, 0);
>> if (!dri2_dpy->conn) {
>> _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
>> goto cleanup_dpy;
>> }
>> - } else {
>> + } else if (generic->pointer == EGL_DISPLAY_TYPE_DRM_MESA) {
>> + drm_display = (EGLDisplayTypeDRMMESA *) disp->NativeDisplay;
>> + if (drm_display->device) {
>> + dri2_dpy->device_name = strdup(drm_display->device);
>> + } else {
>> + dri2_dpy->fd = drm_display->fd;
>> + }
>> + dri2_dpy->driver_name = strdup("i965");
>> + } else if (generic->pointer == EGL_DISPLAY_TYPE_XCB_MESA) {
>> + xcb_display = (EGLDisplayTypeXCBMESA *) disp->NativeDisplay;
>> + dri2_dpy->conn = xcb_display->conn;
>> + } else if (((long) generic->pointer & 1) == 0) {
>> dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay);
>> + } else {
>> + _eglLog(_EGL_WARNING,
>> + "DRI2: unknown display type: %d", (long) generic->pointer);
>> }
>>
>> - if (dri2_dpy->conn == NULL)
>> - goto cleanup_conn;
>> -
>> if (dri2_dpy->conn) {
>> if (!dri2_connect(dri2_dpy))
>> goto cleanup_conn;
>> @@ -709,12 +730,13 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
>> if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions))
>> goto cleanup_driver;
>>
>> - dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
>> - if (dri2_dpy->fd == -1) {
>> - _eglLog(_EGL_WARNING,
>> - "DRI2: could not open %s (%s)", dri2_dpy->device_name,
>> - strerror(errno));
>> - goto cleanup_driver;
>> + if (dri2_dpy->device_name != NULL) {
>> + dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
>> + if (dri2_dpy->fd == -1) {
>> + _eglLog(_EGL_WARNING, "DRI2: could not open %s (%s)",
>> + dri2_dpy->device_name, strerror(errno));
>> + goto cleanup_driver;
>> + }
>> }
>>
>> if (dri2_dpy->conn) {
>> @@ -787,6 +809,9 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
>> *major = 1;
>> *minor = 4;
>>
>> + if (generic->pointer == EGL_DISPLAY_TYPE_DRM_MESA)
>> + drm_display->fd = dri2_dpy->fd;
>> +
>> return EGL_TRUE;
>>
>> cleanup_configs:
>> --
>> 1.7.0.1
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
--
olv at LunarG.com
More information about the mesa-dev
mailing list