[Mesa-dev] [PATCH] egl: Introduce alternative native display types

Chia-I Wu olvaffe at gmail.com
Wed May 19 04:04:31 PDT 2010


2010/5/18 Kristian Høgsberg <krh at bitplanet.net>:
> 2010/5/18 Chia-I Wu <olvaffe at gmail.com>:
>> 2010/5/18 Kristian Høgsberg <krh at bitplanet.net>:
>>> On Tue, May 18, 2010 at 12:41 PM, Chia-I Wu <olvaffe at gmail.com> wrote:
>>>> 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.
>>>
>>> That is a good point - so we'll call it MesaDisplayTypeDRM and
>>> MESA_DISPLAY_TYPE_DRM and similar for XCB.
>>>
>>>> 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.
>>> You mean that the native types for the other platforms are defined in
>>> their respective header files and so should these new types?  I can
>>> see that point of view, but from a more pragmatic point of view, I
>>> don't think it's worth the trouble. Also, the types are specific to
>>> the mesa implementation, they are not data types from another display
>>> system or platform, and the Khronos implementors guide suggests that
>>> the vendor/implementor can modify eglplatform.h.
>> I just figured that if an application uses xcb_connection_t for the
>> display, it might as well use xcb types for windows and pixmaps.
> That's the expected behaviour.  When using XCB, windows and pixmaps
> are still just uint32_t handles on the client side and passing them to
> eglCreateWindowSurface() or eglCreatePixmapSurface() will work just
> fine.  The way Xlib on XCB works, they share the same client ID
> allocator, so you could even initialize EGL with an XCB connection and
> pass it windows created using Xlib or the other way around.
What do you think if these platform details are moved to a header file
of its own, and the header is distributed with Mesa EGL?  I'd like to
see eglplatform.h have less platform details.  We may then put some
macros into the new platform header that ease the access of the native
display.
>> Things could get really complex.  Do you have in mind how/when
>> xcb_connection_t will be used?
>
> Using the xcb_connection_t display makes sense if your toolkit or
> application is using XCB already and you want to avoid the Xlib
> dependency.  It was easy for me to add to egl_dri2, since it already
> uses XCB for DRI2 protocol, which avoids another copy of the DRI2
> protocol code.
>
> What is a little complex though is how to define/use the window/pixmap
> surface constructors under EGL on DRM.  I don't think we can really
> use them in that kind of setting.  First of all, on the "unix
> platform" they take an XID (uint32_t), not a pointer as
> eglGetDisplay() does, so we can't pass a pointer to a struct like what
> I'm suggesting for eglGetDisplay() in this patch.  That would break on
> 64 bit platforms.
>
> One option is to add a new entrypoint to create some kind of native
> window or pixmap under a DRM display, which returns a uint32_t, which
> we can then pass to eglCreateWindowSurface().  Or we can do as the
> EGL_MESA_screen_surface extension does and just define a new
> EGLSurface constructor.  That is certainly a simpler and more elegant
> approach, but it leaves the eglCreateWindowSurface() and
> eglCreatePixmapSurface() entrypoints useless.  But maybe they were
> useless all along and we would have been better off with strongly
> typed, platform specific surface constructors instead of this pseudo
> generic mess we have now (oops, I fell into one of my old rants [1]).
>
> The last option I can think of is to avoid EGLSurfaces alltogether and
> just use FBOs.  My plan for EGL on KMS is to add an extension that
> lets us create an EGLImage from scratch (that is, not lifted from a
> client API object) and adds eglQueryImageMESA() to get the kernel mm
> handle and stride of the buffer so we can use it directly with the DRM
> KMS API.  Then set that EGLImage as a renderbuffer for your FBO,
> render to it and then use libdrm to configure scanout from that
> EGLImage.  It's more complex than the mesa extension, but it give the
> application all the control over double/triple/n buffering,
> preserve/discard backbuffer contents, throttling and page flipping.
> It lets applications use the libdrm KMS API directly, which, while
> complex, is the only real option if you want to base a display server
> on DRM on KMS and expose all the features there.  Of course, this
> option can co-exist with the mesa extension, so we can expose both the
> easy-to-use, non-drm-specific extension and the more complex but
> full-featured libdrm API.
Yeah, I had a look at your branch some time ago and I liked the idea.
Though I'd like to see eglCreatePbufferSurface be used to create a
"system pbuffer", and eglQuerySurface be used to query the buffer
handle and stride.  EGLImages are then created from the system
pbuffers.  This is just some ideas and I haven't verified if they
work.

-- 
olv at LunarG.com


More information about the mesa-dev mailing list