blob: 19bfc35123cd237b5c05b2679f052b4930c22340 [file] [log] [blame]
Name
EXT_platform_x11
Name Strings
EGL_EXT_platform_x11
Contributors
Chad Versace <chad.versace@intel.com>
James Jones <jajones@nvidia.com>
Contacts
Chad Versace <chad.versace@intel.com>
Status
Complete
Version
Version 13, 2014-03-10
Number
EGL Extension #59
Extension Type
EGL client extension
Dependencies
Requires EGL_EXT_client_extensions to query its existence without
a display.
Requires EGL_EXT_platform_base.
This extension is written against the wording of version 7 of the
EGL_EXT_platform_base specification.
Overview
This extension defines how to create EGL resources from native X11
resources using the functions defined by EGL_EXT_platform_base.
This extension defines only how to create EGL resources from Xlib
resources. It does not define how to do so from xcb resources. All X11
types discussed here are defined by the header `Xlib.h`.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted as the <platform> argument of eglGetPlatformDisplayEXT:
EGL_PLATFORM_X11_EXT 0x31D5
Accepted as an attribute name in the <attrib_list> argument of
eglGetPlatformDisplayEXT:
EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
Additions to the EGL Specification
None.
New Behavior
To determine if the EGL implementation supports this extension, clients
should query the EGL_EXTENSIONS string of EGL_NO_DISPLAY.
On the X11 platform, an EGLDisplay refers to a specific X11 screen rather
than an X11 display connection. This is the case because separate X11
screens, even when belonging to the same X11 display connection, may
reside on different GPUs and/or be driven by different drivers. Therefore,
different X11 screens may have different EGL capabilities.
To obtain an EGLDisplay backed by an X11 screen, call
eglGetPlatformDisplayEXT with <platform> set to EGL_PLATFORM_X11_EXT. The
<native_display> parameter specifies the X11 display connection to use, and
must point to a valid X11 `Display` or be NULL. If <native_display> is
EGL_DEFAULT_DISPLAY, then EGL will create [1] a connection to the default
X11 display. The environment variable DISPLAY determines the default X11
display as described in the manual page for XOpenDisplay(3). The value of
attribute EGL_PLATFORM_X11_SCREEN_EXT specifies the X11 screen to use. If
the attribute is omitted from <attrib_list>, then the display connection's
default screen is used. Otherwise, the attribute's value must be a valid
screen on the display connection. If the attribute's value is not a valid
screen, then an EGL_BAD_ATTRIBUTE error is generated.
[fn1] The method by which EGL creates a connection to the default X11
display is an internal implementation detail. The implementation may use
XOpenDisplay, xcb_connect, or any other method.
To obtain an on-screen rendering surface from an X11 Window, call
eglCreatePlatformWindowSurfaceEXT with a <dpy> that belongs to X11 and
a <native_window> that points to an X11 Window.
To obtain an offscreen rendering surface from an X11 Pixmap, call
eglCreatePlatformPixmapSurfaceEXT with a <dpy> that belongs to X11 and
a <native_pixmap> that points to an X11 Pixmap.
Issues
1. Should this extension permit EGL_DEFAULT_DISPLAY as input to
eglGetPlatformDisplayEXT()?
RESOLVED. Yes. When given EGL_DEFAULT_DISPLAY, eglGetPlatformDisplayEXT
returns an EGLDisplay backed by the default X11 display.
2. When given EGL_DEFAULT_DISPLAY, does eglGetPlatformDisplayEXT reuse an
existing X11 display connection or create a new one?
RESOLVED. eglGetPlatformDisplayEXT creates a new connection because the
alternative is infeasible. EGL cannot reliably detect if the client
process already has a X11 display connection.
Example Code
// This example program creates two EGL surfaces: one from an X11 Window
// and the other from an X11 Pixmap.
//
// If the macro USE_EGL_EXT_PLATFORM_X11 is defined, then the program
// creates the surfaces using the methods defined in this specification.
// Otherwise, it uses the methods defined by the EGL 1.4 specification.
//
// Compile with `cc -std=c99 example.c -lX11 -lEGL`.
#include <stdlib.h>
#include <string.h>
#include <EGL/egl.h>
#include <X11/Xlib.h>
struct my_display {
Display *x11;
EGLDisplay egl;
};
struct my_config {
struct my_display dpy;
XVisualInfo *x11;
Colormap colormap;
EGLConfig egl;
};
struct my_window {
struct my_config config;
Window x11;
EGLSurface egl;
};
struct my_pixmap {
struct my_config config;
Pixmap x11;
EGLSurface egl;
};
static void
check_extensions(void)
{
#ifdef USE_EGL_EXT_PLATFORM_X11
const char *client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (!client_extensions) {
// EGL_EXT_client_extensions is unsupported.
abort();
}
if (!strstr(client_extensions, "EGL_EXT_platform_x11")) {
abort();
}
#endif
}
static struct my_display
get_display(void)
{
struct my_display dpy;
dpy.x11 = XOpenDisplay(NULL);
if (!dpy.x11) {
abort();
}
#ifdef USE_EGL_EXT_PLATFORM_X11
dpy.egl = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT, dpy.x11,
NULL);
#else
dpy.egl = eglGetDisplay(dpy.x11);
#endif
if (dpy.egl == EGL_NO_DISPLAY) {
abort();
}
EGLint major, minor;
if (!eglInitialize(dpy.egl, &major, &minor)) {
abort();
}
return dpy;
}
static struct my_config
get_config(struct my_display dpy)
{
struct my_config config = {
.dpy = dpy,
};
EGLint egl_config_attribs[] = {
EGL_BUFFER_SIZE, 32,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, EGL_DONT_CARE,
EGL_STENCIL_SIZE, EGL_DONT_CARE,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
EGL_NONE,
};
EGLint num_configs;
if (!eglChooseConfig(dpy.egl,
egl_config_attribs,
&config.egl, 1,
&num_configs)) {
abort();
}
if (num_configs == 0) {
abort();
}
XVisualInfo x11_visual_info_template;
if (!eglGetConfigAttrib(dpy.egl,
config.egl,
EGL_NATIVE_VISUAL_ID,
(EGLint*) &x11_visual_info_template.visualid)) {
abort();
}
int num_visuals;
config.x11 = XGetVisualInfo(dpy.x11,
VisualIDMask,
&x11_visual_info_template,
&num_visuals);
if (!config.x11) {
abort();
}
config.colormap = XCreateColormap(dpy.x11,
RootWindow(dpy.x11, 0),
config.x11->visual,
AllocNone);
if (config.colormap == None) {
abort();
}
return config;
}
static struct my_window
get_window(struct my_config config)
{
XSetWindowAttributes attr;
unsigned long mask;
struct my_window window = {
.config = config,
};
attr.colormap = config.colormap;
mask = CWColormap;
window.x11 = XCreateWindow(config.dpy.x11,
DefaultRootWindow(config.dpy.x11), // parent
0, 0, // x, y
256, 256, // width, height
0, // border_width
config.x11->depth,
InputOutput, // class
config.x11->visual,
mask, // valuemask
&attr); // attributes
if (!window.x11) {
abort();
}
#ifdef USE_EGL_EXT_PLATFORM_X11
window.egl = eglCreatePlatformWindowSurfaceEXT(config.dpy.egl,
config.egl,
&window.x11,
NULL);
#else
window.egl = eglCreateWindowSurface(config.dpy.egl,
config.egl,
window.x11,
NULL);
#endif
if (window.egl == EGL_NO_SURFACE) {
abort();
}
return window;
}
static struct my_pixmap
get_pixmap(struct my_config config)
{
struct my_pixmap pixmap = {
.config = config,
};
pixmap.x11 = XCreatePixmap(config.dpy.x11,
DefaultRootWindow(config.dpy.x11),
256, 256, // width, height
config.x11->depth);
if (!pixmap.x11) {
abort();
}
#ifdef USE_EGL_EXT_PLATFORM_X11
pixmap.egl = eglCreatePlatformPixmapSurfaceEXT(config.dpy.egl,
config.egl,
&pixmap.x11,
NULL);
#else
pixmap.egl = eglCreatePixmapSurface(config.dpy.egl,
config.egl,
pixmap.x11,
NULL);
#endif
if (pixmap.egl == EGL_NO_SURFACE) {
abort();
}
return pixmap;
}
int
main(void)
{
check_extensions();
struct my_display dpy = get_display();
struct my_config config = get_config(dpy);
struct my_window window = get_window(config);
struct my_pixmap pixmap = get_pixmap(config);
return 0;
}
Revision History
Version 13, 2014-03-10 (Chad Versace)
- Update text to reflect resolution of issue #1. State that
<native_display> may be EGL_DEFAULT_DISPLAY.
- Explain in more detail how EGL connects to the default X11 display.
- Add and resolve issue #2.
Version 12, 2014-02-11 (Chad Versace)
- Fix 2nd argument to XCreatePixmap in example code.
Version 11, 2013-07-10 (Jon Leech)
- Fix enumerant values and assign extension number for publication
(Bug 10240).
Version 10, 2013-07-03 (Chad Versace)
- Add "Extension Type" section, required by EGL_EXT_client_extensions v9.
Version 9, 2013-06-11 (Chad Versace)
- Replace reference to version 5 of EGL_EXT_platform_base to version 7.
- Add James Jones as contributor.
Version 8, 2013-06-07 (Chad Versace)
- Assign enum values to new tokens.
Version 7, 2013-06-07 (Chad Versace)
- Explicitly require EGL_EXT_client_extensions in the Dependencies
section.
Version 6, 2013-06-07 (Chad Versace)
- Add attribute EGL_PLATFORM_X11_SCREEN_EXT.
Version 5, 2013-06-07 (Chad Versace)
- Rephrase against version 7 of EGL_EXT_platform_base.
Version 4, 2013-06-07 (Chad Versace)
- Fix compilation of example code.
Version 3, 2013-04-26 (Chad Versace)
- Add missing EXT suffix to new token.
Version 2, 2013-04-22 (Chad Versace)
- Discuss EGL_DEFAULT_DISPLAY.
- Fix minor typographical and grammatical errors.
Version 1, 2013.03.24 (Chad Versace)
- First draft