[Mesa-dev] [PATCH] egl: Introduce alternative native display types
Kristian Høgsberg
krh at bitplanet.net
Tue May 18 14:16:01 PDT 2010
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.
> 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.
Kristian
[1] http://hoegsberg.blogspot.com/2009/07/eagle-egl-loader.html
More information about the mesa-dev
mailing list