• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    EXT_platform_x11
4
5Name Strings
6
7    EGL_EXT_platform_x11
8
9Contributors
10
11    Chad Versace <chad.versace@intel.com>
12    James Jones <jajones@nvidia.com>
13
14Contacts
15
16    Chad Versace <chad.versace@intel.com>
17
18Status
19
20    Complete
21
22Version
23
24    Version 13, 2014-03-10
25
26Number
27
28    EGL Extension #59
29
30Extension Type
31
32    EGL client extension
33
34Dependencies
35
36    Requires EGL_EXT_client_extensions to query its existence without
37    a display.
38
39    Requires EGL_EXT_platform_base.
40
41    This extension is written against the wording of version 7 of the
42    EGL_EXT_platform_base specification.
43
44Overview
45
46    This extension defines how to create EGL resources from native X11
47    resources using the functions defined by EGL_EXT_platform_base.
48
49    This extension defines only 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 eglGetPlatformDisplayEXT:
64
65        EGL_PLATFORM_X11_EXT                    0x31D5
66
67    Accepted as an attribute name in the <attrib_list> argument of
68    eglGetPlatformDisplayEXT:
69
70        EGL_PLATFORM_X11_SCREEN_EXT             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
88    eglGetPlatformDisplayEXT with <platform> set to EGL_PLATFORM_X11_EXT. The
89    <native_display> parameter specifies the X11 display connection to use, and
90    must point to a valid X11 `Display` or be NULL.  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_EXT 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    eglCreatePlatformWindowSurfaceEXT 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    eglCreatePlatformPixmapSurfaceEXT 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       eglGetPlatformDisplayEXT()?
116
117       RESOLVED. Yes. When given EGL_DEFAULT_DISPLAY, eglGetPlatformDisplayEXT
118       returns an EGLDisplay backed by the default X11 display.
119
120    2. When given EGL_DEFAULT_DISPLAY, does eglGetPlatformDisplayEXT reuse an
121       existing X11 display connection or create a new one?
122
123       RESOLVED. eglGetPlatformDisplayEXT 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
127
128Example Code
129
130    // This example program creates two EGL surfaces: one from an X11 Window
131    // and the other from an X11 Pixmap.
132    //
133    // If the macro USE_EGL_EXT_PLATFORM_X11 is defined, then the program
134    // creates the surfaces using the methods defined in this specification.
135    // Otherwise, it uses the methods defined by the EGL 1.4 specification.
136    //
137    // Compile with `cc -std=c99 example.c -lX11 -lEGL`.
138
139    #include <stdlib.h>
140    #include <string.h>
141
142    #include <EGL/egl.h>
143    #include <X11/Xlib.h>
144
145    struct my_display {
146        Display *x11;
147        EGLDisplay egl;
148    };
149
150    struct my_config {
151        struct my_display dpy;
152        XVisualInfo *x11;
153        Colormap colormap;
154        EGLConfig egl;
155    };
156
157    struct my_window {
158        struct my_config config;
159        Window x11;
160        EGLSurface egl;
161    };
162
163    struct my_pixmap {
164        struct my_config config;
165        Pixmap x11;
166        EGLSurface egl;
167    };
168
169    static void
170    check_extensions(void)
171    {
172    #ifdef USE_EGL_EXT_PLATFORM_X11
173        const char *client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
174
175        if (!client_extensions) {
176            // EGL_EXT_client_extensions is unsupported.
177            abort();
178        }
179        if (!strstr(client_extensions, "EGL_EXT_platform_x11")) {
180            abort();
181        }
182    #endif
183    }
184
185    static struct my_display
186    get_display(void)
187    {
188        struct my_display dpy;
189
190        dpy.x11 = XOpenDisplay(NULL);
191        if (!dpy.x11) {
192            abort();
193        }
194
195    #ifdef USE_EGL_EXT_PLATFORM_X11
196        dpy.egl = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT, dpy.x11,
197                                           NULL);
198    #else
199        dpy.egl = eglGetDisplay(dpy.x11);
200    #endif
201
202        if (dpy.egl == EGL_NO_DISPLAY) {
203            abort();
204        }
205
206        EGLint major, minor;
207        if (!eglInitialize(dpy.egl, &major, &minor)) {
208            abort();
209        }
210
211        return dpy;
212    }
213
214    static struct my_config
215    get_config(struct my_display dpy)
216    {
217        struct my_config config = {
218            .dpy = dpy,
219        };
220
221        EGLint egl_config_attribs[] = {
222            EGL_BUFFER_SIZE,        32,
223            EGL_RED_SIZE,            8,
224            EGL_GREEN_SIZE,          8,
225            EGL_BLUE_SIZE,           8,
226            EGL_ALPHA_SIZE,          8,
227
228            EGL_DEPTH_SIZE,         EGL_DONT_CARE,
229            EGL_STENCIL_SIZE,       EGL_DONT_CARE,
230
231            EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
232            EGL_SURFACE_TYPE,       EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
233            EGL_NONE,
234        };
235
236        EGLint num_configs;
237        if (!eglChooseConfig(dpy.egl,
238                             egl_config_attribs,
239                             &config.egl, 1,
240                             &num_configs)) {
241            abort();
242        }
243        if (num_configs == 0) {
244            abort();
245        }
246
247        XVisualInfo x11_visual_info_template;
248        if (!eglGetConfigAttrib(dpy.egl,
249                                config.egl,
250                                EGL_NATIVE_VISUAL_ID,
251                                (EGLint*) &x11_visual_info_template.visualid)) {
252            abort();
253        }
254
255        int num_visuals;
256        config.x11 = XGetVisualInfo(dpy.x11,
257                                    VisualIDMask,
258                                    &x11_visual_info_template,
259                                    &num_visuals);
260        if (!config.x11) {
261            abort();
262        }
263
264        config.colormap = XCreateColormap(dpy.x11,
265                                          RootWindow(dpy.x11, 0),
266                                          config.x11->visual,
267                                          AllocNone);
268        if (config.colormap == None) {
269            abort();
270        }
271
272        return config;
273    }
274
275    static struct my_window
276    get_window(struct my_config config)
277    {
278        XSetWindowAttributes attr;
279        unsigned long mask;
280
281        struct my_window window = {
282            .config = config,
283        };
284
285        attr.colormap = config.colormap;
286        mask = CWColormap;
287
288        window.x11 = XCreateWindow(config.dpy.x11,
289                                   DefaultRootWindow(config.dpy.x11), // parent
290                                   0, 0, // x, y
291                                   256, 256, // width, height
292                                   0, // border_width
293                                   config.x11->depth,
294                                   InputOutput, // class
295                                   config.x11->visual,
296                                   mask, // valuemask
297                                   &attr); // attributes
298        if (!window.x11) {
299            abort();
300        }
301
302    #ifdef USE_EGL_EXT_PLATFORM_X11
303        window.egl = eglCreatePlatformWindowSurfaceEXT(config.dpy.egl,
304                                                       config.egl,
305                                                       &window.x11,
306                                                       NULL);
307    #else
308        window.egl = eglCreateWindowSurface(config.dpy.egl,
309                                            config.egl,
310                                            window.x11,
311                                            NULL);
312    #endif
313
314        if (window.egl == EGL_NO_SURFACE) {
315            abort();
316        }
317
318        return window;
319    }
320
321    static struct my_pixmap
322    get_pixmap(struct my_config config)
323    {
324        struct my_pixmap pixmap = {
325            .config = config,
326        };
327
328        pixmap.x11 = XCreatePixmap(config.dpy.x11,
329                                   DefaultRootWindow(config.dpy.x11),
330                                   256, 256, // width, height
331                                   config.x11->depth);
332        if (!pixmap.x11) {
333            abort();
334        }
335
336    #ifdef USE_EGL_EXT_PLATFORM_X11
337        pixmap.egl = eglCreatePlatformPixmapSurfaceEXT(config.dpy.egl,
338                                                       config.egl,
339                                                       &pixmap.x11,
340                                                       NULL);
341    #else
342        pixmap.egl = eglCreatePixmapSurface(config.dpy.egl,
343                                            config.egl,
344                                            pixmap.x11,
345                                            NULL);
346    #endif
347
348        if (pixmap.egl == EGL_NO_SURFACE) {
349            abort();
350        }
351
352        return pixmap;
353    }
354
355    int
356    main(void)
357    {
358        check_extensions();
359
360        struct my_display dpy = get_display();
361        struct my_config config = get_config(dpy);
362        struct my_window window = get_window(config);
363        struct my_pixmap pixmap = get_pixmap(config);
364
365        return 0;
366    }
367
368Revision History
369
370    Version 13, 2014-03-10 (Chad Versace)
371        - Update text to reflect resolution of issue #1. State that
372          <native_display> may be EGL_DEFAULT_DISPLAY.
373        - Explain in more detail how EGL connects to the default X11 display.
374        - Add and resolve issue #2.
375
376    Version 12, 2014-02-11 (Chad Versace)
377        - Fix 2nd argument to XCreatePixmap in example code.
378
379    Version 11, 2013-07-10 (Jon Leech)
380        - Fix enumerant values and assign extension number for publication
381          (Bug 10240).
382
383    Version 10, 2013-07-03 (Chad Versace)
384        - Add "Extension Type" section, required by EGL_EXT_client_extensions v9.
385
386    Version 9, 2013-06-11 (Chad Versace)
387        - Replace reference to version 5 of EGL_EXT_platform_base to version 7.
388        - Add James Jones as contributor.
389
390    Version 8, 2013-06-07 (Chad Versace)
391        - Assign enum values to new tokens.
392
393    Version 7, 2013-06-07 (Chad Versace)
394        - Explicitly require EGL_EXT_client_extensions in the Dependencies
395          section.
396
397    Version 6, 2013-06-07 (Chad Versace)
398        - Add attribute EGL_PLATFORM_X11_SCREEN_EXT.
399
400    Version 5, 2013-06-07 (Chad Versace)
401        - Rephrase against version 7 of EGL_EXT_platform_base.
402
403    Version 4, 2013-06-07 (Chad Versace)
404        - Fix compilation of example code.
405
406    Version 3, 2013-04-26 (Chad Versace)
407        - Add missing EXT suffix to new token.
408
409    Version 2, 2013-04-22 (Chad Versace)
410        - Discuss EGL_DEFAULT_DISPLAY.
411        - Fix minor typographical and grammatical errors.
412
413    Version 1, 2013.03.24 (Chad Versace)
414        - First draft
415