• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    KHR_platform_x11
4
5Name Strings
6
7    EGL_KHR_platform_x11
8
9Contributors
10
11    Chad Versace <chad.versace@intel.com>
12    James Jones <jajones@nvidia.com>
13    Jon Leech (oddhack 'at' sonic.net)
14
15Contacts
16
17    Chad Versace <chad.versace@intel.com>
18
19Status
20
21    Complete.
22    Approved by the EGL Working Group on January 31, 2014.
23    Ratified by the Khronos Board of Promoters on March 14, 2014.
24
25Version
26
27    Version 3, 2014/02/18
28
29Number
30
31    EGL Extension #71
32
33Extension Type
34
35    EGL client extension
36
37Dependencies
38
39    EGL 1.5 is required.
40
41    This extension is written against the EGL 1.5 Specification (draft
42    20140122).
43
44Overview
45
46    This extension defines how to create EGL resources from native X11
47    resources using the EGL 1.5 platform functionality.
48
49    This extension only defines how to create EGL resources from Xlib
50    resources. It does not define how to do so from xcb resources. All X11
51    types discussed here are defined by the header `Xlib.h`.
52
53New Types
54
55    None
56
57New Procedures and Functions
58
59    None
60
61New Tokens
62
63    Accepted as the <platform> argument of eglGetPlatformDisplay:
64
65        EGL_PLATFORM_X11_KHR                    0x31D5
66
67    Accepted as an attribute name in the <attrib_list> argument of
68    eglGetPlatformDisplay:
69
70        EGL_PLATFORM_X11_SCREEN_KHR             0x31D6
71
72Additions to the EGL Specification
73
74    None.
75
76New Behavior
77
78    To determine if the EGL implementation supports this extension, clients
79    should query the EGL_EXTENSIONS string of EGL_NO_DISPLAY.
80
81    On the X11 platform, an EGLDisplay refers to a specific X11 screen rather
82    than an X11 display connection. This is the case because separate X11
83    screens, even when belonging to the same X11 display connection, may
84    reside on different GPUs and/or be driven by different drivers. Therefore,
85    different X11 screens may have different EGL capabilities.
86
87    To obtain an EGLDisplay backed by an X11 screen, call eglGetPlatformDisplay
88    with <platform> set to EGL_PLATFORM_X11_KHR. The <native_display> parameter
89    specifies the X11 display connection to use, and must either point to
90    a valid X11 `Display` or be EGL_DEFAULT_DISPLAY.  If <native_display> is
91    EGL_DEFAULT_DISPLAY, then EGL will create [1] a connection to the default
92    X11 display. The environment variable DISPLAY determines the default X11
93    display as described in the manual page for XOpenDisplay(3).  The value of
94    attribute EGL_PLATFORM_X11_SCREEN_KHR specifies the X11 screen to use. If
95    the attribute is omitted from <attrib_list>, then the display connection's
96    default screen is used.  Otherwise, the attribute's value must be a valid
97    screen on the display connection. If the attribute's value is not a valid
98    screen, then an EGL_BAD_ATTRIBUTE error is generated.
99
100    [fn1] The method by which EGL creates a connection to the default X11
101    display is an internal implementation detail. The implementation may use
102    XOpenDisplay, xcb_connect, or any other method.
103
104    To obtain an on-screen rendering surface from an X11 Window, call
105    eglCreatePlatformWindowSurface with a <dpy> that belongs to X11 and
106    a <native_window> that points to an X11 Window.
107
108    To obtain an offscreen rendering surface from an X11 Pixmap, call
109    eglCreatePlatformPixmapSurface with a <dpy> that belongs to X11 and
110    a <native_pixmap> that points to an X11 Pixmap.
111
112Issues
113
114    1. Should this extension permit EGL_DEFAULT_DISPLAY as input to
115       eglGetPlatformDisplay()?
116
117       RESOLVED. Yes. When given EGL_DEFAULT_DISPLAY, eglGetPlatformDisplay
118       returns an EGLDisplay backed by the default X11 display.
119
120    2. When given EGL_DEFAULT_DISPLAY, does eglGetPlatformDisplay reuse an
121       existing X11 display connection or create a new one?
122
123       RESOLVED. eglGetPlatformDisplay creates a new connection because the
124       alternative is infeasible. EGL cannot reliably detect if the client
125       process already has a X11 display connection.
126
127Example Code
128
129    // This example program creates two EGL surfaces: one from an X11 Window
130    // and the other from an X11 Pixmap.
131    //
132    // If the macro USE_EGL_KHR_PLATFORM_X11 is defined, then the program
133    // creates the surfaces using the methods defined in this specification.
134    // Otherwise, it uses the methods defined by the EGL 1.4 specification.
135    //
136    // Compile with `cc -std=c99 example.c -lX11 -lEGL`.
137
138    #include <stdlib.h>
139    #include <string.h>
140
141    #include <EGL/egl.h>
142    #include <X11/Xlib.h>
143
144    struct my_display {
145        Display *x11;
146        EGLDisplay egl;
147    };
148
149    struct my_config {
150        struct my_display dpy;
151        XVisualInfo *x11;
152        Colormap colormap;
153        EGLConfig egl;
154    };
155
156    struct my_window {
157        struct my_config config;
158        Window x11;
159        EGLSurface egl;
160    };
161
162    struct my_pixmap {
163        struct my_config config;
164        Pixmap x11;
165        EGLSurface egl;
166    };
167
168    static void
169    check_extensions(void)
170    {
171    #ifdef USE_EGL_KHR_PLATFORM_X11
172        const char *client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
173
174        if (!client_extensions) {
175            // No client extensions string available
176            abort();
177        }
178        if (!strstr(client_extensions, "EGL_KHR_platform_x11")) {
179            abort();
180        }
181    #endif
182    }
183
184    static struct my_display
185    get_display(void)
186    {
187        struct my_display dpy;
188
189        dpy.x11 = XOpenDisplay(NULL);
190        if (!dpy.x11) {
191            abort();
192        }
193
194    #ifdef USE_EGL_KHR_PLATFORM_X11
195        dpy.egl = eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, dpy.x11, NULL);
196    #else
197        dpy.egl = eglGetDisplay(dpy.x11);
198    #endif
199
200        if (dpy.egl == EGL_NO_DISPLAY) {
201            abort();
202        }
203
204        EGLint major, minor;
205        if (!eglInitialize(dpy.egl, &major, &minor)) {
206            abort();
207        }
208
209        return dpy;
210    }
211
212    static struct my_config
213    get_config(struct my_display dpy)
214    {
215        struct my_config config = {
216            .dpy = dpy,
217        };
218
219        EGLint egl_config_attribs[] = {
220            EGL_BUFFER_SIZE,        32,
221            EGL_RED_SIZE,            8,
222            EGL_GREEN_SIZE,          8,
223            EGL_BLUE_SIZE,           8,
224            EGL_ALPHA_SIZE,          8,
225
226            EGL_DEPTH_SIZE,         EGL_DONT_CARE,
227            EGL_STENCIL_SIZE,       EGL_DONT_CARE,
228
229            EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
230            EGL_SURFACE_TYPE,       EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
231            EGL_NONE,
232        };
233
234        EGLint num_configs;
235        if (!eglChooseConfig(dpy.egl,
236                             egl_config_attribs,
237                             &config.egl, 1,
238                             &num_configs)) {
239            abort();
240        }
241        if (num_configs == 0) {
242            abort();
243        }
244
245        XVisualInfo x11_visual_info_template;
246        if (!eglGetConfigAttrib(dpy.egl,
247                                config.egl,
248                                EGL_NATIVE_VISUAL_ID,
249                                (EGLint*) &x11_visual_info_template.visualid)) {
250            abort();
251        }
252
253        int num_visuals;
254        config.x11 = XGetVisualInfo(dpy.x11,
255                                    VisualIDMask,
256                                    &x11_visual_info_template,
257                                    &num_visuals);
258        if (!config.x11) {
259            abort();
260        }
261
262        config.colormap = XCreateColormap(dpy.x11,
263                                          RootWindow(dpy.x11, 0),
264                                          config.x11->visual,
265                                          AllocNone);
266        if (config.colormap == None) {
267            abort();
268        }
269
270        return config;
271    }
272
273    static struct my_window
274    get_window(struct my_config config)
275    {
276        XSetWindowAttributes attr;
277        unsigned long mask;
278
279        struct my_window window = {
280            .config = config,
281        };
282
283        attr.colormap = config.colormap;
284        mask = CWColormap;
285
286        window.x11 = XCreateWindow(config.dpy.x11,
287                                   DefaultRootWindow(config.dpy.x11), // parent
288                                   0, 0, // x, y
289                                   256, 256, // width, height
290                                   0, // border_width
291                                   config.x11->depth,
292                                   InputOutput, // class
293                                   config.x11->visual,
294                                   mask, // valuemask
295                                   &attr); // attributes
296        if (!window.x11) {
297            abort();
298        }
299
300    #ifdef USE_EGL_KHR_PLATFORM_X11
301        window.egl = eglCreatePlatformWindowSurface(config.dpy.egl,
302                                                    config.egl,
303                                                    &window.x11,
304                                                    NULL);
305    #else
306        window.egl = eglCreateWindowSurface(config.dpy.egl,
307                                            config.egl,
308                                            window.x11,
309                                            NULL);
310    #endif
311
312        if (window.egl == EGL_NO_SURFACE) {
313            abort();
314        }
315
316        return window;
317    }
318
319    static struct my_pixmap
320    get_pixmap(struct my_config config)
321    {
322        struct my_pixmap pixmap = {
323            .config = config,
324        };
325
326        pixmap.x11 = XCreatePixmap(config.dpy.x11,
327                                   DefaultRootWindow(config.dpy.x11),
328                                   256, 256, // width, height
329                                   config.x11->depth);
330        if (!pixmap.x11) {
331            abort();
332        }
333
334    #ifdef USE_EGL_KHR_PLATFORM_X11
335        pixmap.egl = eglCreatePlatformPixmapSurface(config.dpy.egl,
336                                                    config.egl,
337                                                    &pixmap.x11,
338                                                    NULL);
339    #else
340        pixmap.egl = eglCreatePixmapSurface(config.dpy.egl,
341                                            config.egl,
342                                            pixmap.x11,
343                                            NULL);
344    #endif
345
346        if (pixmap.egl == EGL_NO_SURFACE) {
347            abort();
348        }
349
350        return pixmap;
351    }
352
353    int
354    main(void)
355    {
356        check_extensions();
357
358        struct my_display dpy = get_display();
359        struct my_config config = get_config(dpy);
360        struct my_window window = get_window(config);
361        struct my_pixmap pixmap = get_pixmap(config);
362
363        return 0;
364    }
365
366Revision History
367
368    Version 3, 2014/02/18 (Chad Versace)
369        - Update text to reflect resolution of issue #1. State that
370          <native_display> may be EGL_DEFAULT_DISPLAY.
371        - Explain in more detail how EGL connects to the default X11 display.
372        - Add and resolve issue #2.
373
374    Version 2, 2014/02/11 (Chad Versace)
375        - Fix 2nd argument to XCreatePixmap in example code.
376
377    Version 1, 2014/01/22 (Jon Leech)
378        - Promote EGL_EXT_platform_x11 to KHR to go with EGL 1.5.
379