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