Name MESA_platform_gbm Name Strings EGL_MESA_platform_gbm Contributors Chad Versace Kristian Høgsberg Contacts Chad Versace Status Complete Version Version 7, 2016/01/04 Number EGL Extension #62 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 GBM resources using the functions defined by EGL_EXT_platform_base. (GBM is a Generic Buffer Manager for Linux). New Types None New Procedures and Functions None New Tokens Accepted as the argument of eglGetPlatformDisplayEXT: EGL_PLATFORM_GBM_MESA 0x31D7 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. To obtain an EGLDisplay from an GBM device, call eglGetPlatformDisplayEXT with set to EGL_PLATFORM_GBM_MESA. The parameter specifies the GBM device to use and must either point to a `struct gbm_device` or be NULL. If is NULL, then the resultant EGLDisplay will be backed by some implementation-chosen GBM device. For each EGLConfig that belongs to the GBM platform, the EGL_NATIVE_VISUAL_ID attribute is a GBM color format, such as GBM_FORMAT_XRGB8888. To obtain a rendering surface from a GBM surface, call eglCreatePlatformWindowSurfaceEXT with a that belongs to the GBM platform and a that points to a `struct gbm_surface`. If was created without the GBM_BO_USE_RENDERING flag, or if the color format of differs from the EGL_NATIVE_VISUAL_ID of , then the function fails and generates EGL_BAD_MATCH. It is not valid to call eglCreatePlatformPixmapSurfaceEXT with a that belongs to the GBM platform. Any such call fails and generates EGL_BAD_PARAMETER. Issues 1. Should this extension permit NULL as input to eglGetPlatformDisplayEXT? RESOLUTION: Yes. When given NULL, eglGetPlatformDisplayEXT returns an EGLDisplay backed by an implementation-chosen GBM device. Example Code // This example program creates an EGL surface from a GBM surface. // // If the macro EGL_MESA_platform_gbm 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 -lgbm -lEGL`. #include #include #include #include #include #include #include struct my_display { struct gbm_device *gbm; EGLDisplay egl; }; struct my_config { struct my_display dpy; EGLConfig egl; }; struct my_window { struct my_config config; struct gbm_surface *gbm; EGLSurface egl; }; static void check_extensions(void) { #ifdef EGL_MESA_platform_gbm 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_MESA_platform_gbm")) { abort(); } #endif } static struct my_display get_display(void) { struct my_display dpy; int fd = open("/dev/dri/card0", O_RDWR | FD_CLOEXEC); if (fd < 0) { abort(); } dpy.gbm = gbm_create_device(fd); if (!dpy.gbm) { abort(); } #ifdef EGL_MESA_platform_gbm dpy.egl = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, dpy.gbm, NULL); #else dpy.egl = eglGetDisplay(dpy.gbm); #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_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_NONE, }; EGLint num_configs; if (!eglGetConfigs(dpy.egl, NULL, 0, &num_configs)) { abort(); } EGLConfig *configs = malloc(num_configs * sizeof(EGLConfig)); if (!eglChooseConfig(dpy.egl, egl_config_attribs, configs, num_configs, &num_configs)) { abort(); } if (num_configs == 0) { abort(); } // Find a config whose native visual ID is the desired GBM format. for (int i = 0; i < num_configs; ++i) { EGLint gbm_format; if (!eglGetConfigAttrib(dpy.egl, configs[i], EGL_NATIVE_VISUAL_ID, &gbm_format)) { abort(); } if (gbm_format == GBM_FORMAT_XRGB8888) { config.egl = configs[i]; free(configs); return config; } } // Failed to find a config with matching GBM format. abort(); } static struct my_window get_window(struct my_config config) { struct my_window window = { .config = config, }; window.gbm = gbm_surface_create(config.dpy.gbm, 256, 256, GBM_FORMAT_XRGB8888, GBM_BO_USE_RENDERING); if (!window.gbm) { abort(); } #ifdef EGL_MESA_platform_gbm window.egl = eglCreatePlatformWindowSurfaceEXT(config.dpy.egl, config.egl, window.gbm, NULL); #else window.egl = eglCreateWindowSurface(config.dpy.egl, config.egl, window.gbm, NULL); #endif if (window.egl == EGL_NO_SURFACE) { abort(); } return window; } 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); return 0; } Revision History Version 8, 2018-05-25 (Krzysztof Kosiński) - Corrected EGL_DEFAULT_DISPLAY to NULL. The second argument to eglGetPlatformDisplayEXT has type void*, while EGL_DEFAULT_DISPLAY has type EGLNativeDisplayType, which is not guaranteed to be convertible to void* - it could be int, long or intptr_t. Version 7, 2016-01-04 (Jon Leech) - Free config memory allocated in sample code (Public Bug 1445). Version 6, 2014-02-12 (Chad Versace) - Change resolution of issue #1 from "no" to "yes". Now eglGetPlatformDisplayEXT accepts EGL_DEFAULT_DISPLAY for GBM. Version 5, 2013-010-15 (Chad Versace) - Specify that EGL_NATIVE_VISUAL_ID is a GBM color format. - Require for eglCreatePlatformWindowSurfaceEXT that the GBM color format not differ between the EGLConfig and gbm_surface. (Suggested by Kristian). - Update example code to find matching EGL_NATIVE_VISUAL_ID. Version 4, 2013-09-13 (Chad Versace) - Update the text and example code to wording of version 7 of EGL_EXT_platform_base spec. - Add section "Extension Type". - Resolve issue #1 to "No". - Add issue #2. Version 3, 2013-04-26 (Chad Versace) - Add missing MESA suffix to new token. Version 2, 2013-04-23 (Chad Versace) - Add issue #1 regarding EGL_DEFAULT_DISPLAY. Version 1, 2013.03.24 (Chad Versace) - First draft