102f4aeb0Sopenharmony_ciName 202f4aeb0Sopenharmony_ci 302f4aeb0Sopenharmony_ci MESA_platform_gbm 402f4aeb0Sopenharmony_ci 502f4aeb0Sopenharmony_ciName Strings 602f4aeb0Sopenharmony_ci 702f4aeb0Sopenharmony_ci EGL_MESA_platform_gbm 802f4aeb0Sopenharmony_ci 902f4aeb0Sopenharmony_ciContributors 1002f4aeb0Sopenharmony_ci 1102f4aeb0Sopenharmony_ci Chad Versace <chad.versace@intel.com> 1202f4aeb0Sopenharmony_ci Kristian Høgsberg <krh@bitplanet.org> 1302f4aeb0Sopenharmony_ci 1402f4aeb0Sopenharmony_ciContacts 1502f4aeb0Sopenharmony_ci 1602f4aeb0Sopenharmony_ci Chad Versace <chad.versace@intel.com> 1702f4aeb0Sopenharmony_ci 1802f4aeb0Sopenharmony_ciStatus 1902f4aeb0Sopenharmony_ci 2002f4aeb0Sopenharmony_ci Complete 2102f4aeb0Sopenharmony_ci 2202f4aeb0Sopenharmony_ciVersion 2302f4aeb0Sopenharmony_ci 2402f4aeb0Sopenharmony_ci Version 7, 2016/01/04 2502f4aeb0Sopenharmony_ci 2602f4aeb0Sopenharmony_ciNumber 2702f4aeb0Sopenharmony_ci 2802f4aeb0Sopenharmony_ci EGL Extension #62 2902f4aeb0Sopenharmony_ci 3002f4aeb0Sopenharmony_ciExtension Type 3102f4aeb0Sopenharmony_ci 3202f4aeb0Sopenharmony_ci EGL client extension 3302f4aeb0Sopenharmony_ci 3402f4aeb0Sopenharmony_ciDependencies 3502f4aeb0Sopenharmony_ci 3602f4aeb0Sopenharmony_ci Requires EGL_EXT_client_extensions to query its existence without 3702f4aeb0Sopenharmony_ci a display. 3802f4aeb0Sopenharmony_ci 3902f4aeb0Sopenharmony_ci Requires EGL_EXT_platform_base. 4002f4aeb0Sopenharmony_ci 4102f4aeb0Sopenharmony_ci This extension is written against the wording of version 7 of the 4202f4aeb0Sopenharmony_ci EGL_EXT_platform_base specification. 4302f4aeb0Sopenharmony_ci 4402f4aeb0Sopenharmony_ciOverview 4502f4aeb0Sopenharmony_ci 4602f4aeb0Sopenharmony_ci This extension defines how to create EGL resources from native GBM 4702f4aeb0Sopenharmony_ci resources using the functions defined by EGL_EXT_platform_base. (GBM is 4802f4aeb0Sopenharmony_ci a Generic Buffer Manager for Linux). 4902f4aeb0Sopenharmony_ci 5002f4aeb0Sopenharmony_ciNew Types 5102f4aeb0Sopenharmony_ci 5202f4aeb0Sopenharmony_ci None 5302f4aeb0Sopenharmony_ci 5402f4aeb0Sopenharmony_ciNew Procedures and Functions 5502f4aeb0Sopenharmony_ci 5602f4aeb0Sopenharmony_ci None 5702f4aeb0Sopenharmony_ci 5802f4aeb0Sopenharmony_ciNew Tokens 5902f4aeb0Sopenharmony_ci 6002f4aeb0Sopenharmony_ci Accepted as the <platform> argument of eglGetPlatformDisplayEXT: 6102f4aeb0Sopenharmony_ci 6202f4aeb0Sopenharmony_ci EGL_PLATFORM_GBM_MESA 0x31D7 6302f4aeb0Sopenharmony_ci 6402f4aeb0Sopenharmony_ciAdditions to the EGL Specification 6502f4aeb0Sopenharmony_ci 6602f4aeb0Sopenharmony_ci None. 6702f4aeb0Sopenharmony_ci 6802f4aeb0Sopenharmony_ciNew Behavior 6902f4aeb0Sopenharmony_ci 7002f4aeb0Sopenharmony_ci To determine if the EGL implementation supports this extension, clients 7102f4aeb0Sopenharmony_ci should query the EGL_EXTENSIONS string of EGL_NO_DISPLAY. 7202f4aeb0Sopenharmony_ci 7302f4aeb0Sopenharmony_ci To obtain an EGLDisplay from an GBM device, call eglGetPlatformDisplayEXT with 7402f4aeb0Sopenharmony_ci <platform> set to EGL_PLATFORM_GBM_MESA. The <native_display> parameter 7502f4aeb0Sopenharmony_ci specifies the GBM device to use and must either point to a `struct 7602f4aeb0Sopenharmony_ci gbm_device` or be NULL. If <native_display> is NULL, then the resultant 7702f4aeb0Sopenharmony_ci EGLDisplay will be backed by some implementation-chosen GBM device. 7802f4aeb0Sopenharmony_ci 7902f4aeb0Sopenharmony_ci For each EGLConfig that belongs to the GBM platform, the 8002f4aeb0Sopenharmony_ci EGL_NATIVE_VISUAL_ID attribute is a GBM color format, such as 8102f4aeb0Sopenharmony_ci GBM_FORMAT_XRGB8888. 8202f4aeb0Sopenharmony_ci 8302f4aeb0Sopenharmony_ci To obtain a rendering surface from a GBM surface, call 8402f4aeb0Sopenharmony_ci eglCreatePlatformWindowSurfaceEXT with a <dpy> that belongs to the GBM 8502f4aeb0Sopenharmony_ci platform and a <native_window> that points to a `struct gbm_surface`. If 8602f4aeb0Sopenharmony_ci <native_window> was created without the GBM_BO_USE_RENDERING flag, or if 8702f4aeb0Sopenharmony_ci the color format of <native_window> differs from the EGL_NATIVE_VISUAL_ID 8802f4aeb0Sopenharmony_ci of <config>, then the function fails and generates EGL_BAD_MATCH. 8902f4aeb0Sopenharmony_ci 9002f4aeb0Sopenharmony_ci It is not valid to call eglCreatePlatformPixmapSurfaceEXT with a <dpy> that 9102f4aeb0Sopenharmony_ci belongs to the GBM platform. Any such call fails and generates 9202f4aeb0Sopenharmony_ci EGL_BAD_PARAMETER. 9302f4aeb0Sopenharmony_ci 9402f4aeb0Sopenharmony_ciIssues 9502f4aeb0Sopenharmony_ci 9602f4aeb0Sopenharmony_ci 1. Should this extension permit NULL as input to eglGetPlatformDisplayEXT? 9702f4aeb0Sopenharmony_ci 9802f4aeb0Sopenharmony_ci RESOLUTION: Yes. When given NULL, eglGetPlatformDisplayEXT returns an 9902f4aeb0Sopenharmony_ci EGLDisplay backed by an implementation-chosen GBM device. 10002f4aeb0Sopenharmony_ci 10102f4aeb0Sopenharmony_ciExample Code 10202f4aeb0Sopenharmony_ci 10302f4aeb0Sopenharmony_ci // This example program creates an EGL surface from a GBM surface. 10402f4aeb0Sopenharmony_ci // 10502f4aeb0Sopenharmony_ci // If the macro EGL_MESA_platform_gbm is defined, then the program 10602f4aeb0Sopenharmony_ci // creates the surfaces using the methods defined in this specification. 10702f4aeb0Sopenharmony_ci // Otherwise, it uses the methods defined by the EGL 1.4 specification. 10802f4aeb0Sopenharmony_ci // 10902f4aeb0Sopenharmony_ci // Compile with `cc -std=c99 example.c -lgbm -lEGL`. 11002f4aeb0Sopenharmony_ci 11102f4aeb0Sopenharmony_ci #include <stdlib.h> 11202f4aeb0Sopenharmony_ci #include <string.h> 11302f4aeb0Sopenharmony_ci 11402f4aeb0Sopenharmony_ci #include <sys/types.h> 11502f4aeb0Sopenharmony_ci #include <sys/stat.h> 11602f4aeb0Sopenharmony_ci #include <fcntl.h> 11702f4aeb0Sopenharmony_ci 11802f4aeb0Sopenharmony_ci #include <EGL/egl.h> 11902f4aeb0Sopenharmony_ci #include <gbm.h> 12002f4aeb0Sopenharmony_ci 12102f4aeb0Sopenharmony_ci struct my_display { 12202f4aeb0Sopenharmony_ci struct gbm_device *gbm; 12302f4aeb0Sopenharmony_ci EGLDisplay egl; 12402f4aeb0Sopenharmony_ci }; 12502f4aeb0Sopenharmony_ci 12602f4aeb0Sopenharmony_ci struct my_config { 12702f4aeb0Sopenharmony_ci struct my_display dpy; 12802f4aeb0Sopenharmony_ci EGLConfig egl; 12902f4aeb0Sopenharmony_ci }; 13002f4aeb0Sopenharmony_ci 13102f4aeb0Sopenharmony_ci struct my_window { 13202f4aeb0Sopenharmony_ci struct my_config config; 13302f4aeb0Sopenharmony_ci struct gbm_surface *gbm; 13402f4aeb0Sopenharmony_ci EGLSurface egl; 13502f4aeb0Sopenharmony_ci }; 13602f4aeb0Sopenharmony_ci 13702f4aeb0Sopenharmony_ci static void 13802f4aeb0Sopenharmony_ci check_extensions(void) 13902f4aeb0Sopenharmony_ci { 14002f4aeb0Sopenharmony_ci #ifdef EGL_MESA_platform_gbm 14102f4aeb0Sopenharmony_ci const char *client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); 14202f4aeb0Sopenharmony_ci 14302f4aeb0Sopenharmony_ci if (!client_extensions) { 14402f4aeb0Sopenharmony_ci // EGL_EXT_client_extensions is unsupported. 14502f4aeb0Sopenharmony_ci abort(); 14602f4aeb0Sopenharmony_ci } 14702f4aeb0Sopenharmony_ci if (!strstr(client_extensions, "EGL_MESA_platform_gbm")) { 14802f4aeb0Sopenharmony_ci abort(); 14902f4aeb0Sopenharmony_ci } 15002f4aeb0Sopenharmony_ci #endif 15102f4aeb0Sopenharmony_ci } 15202f4aeb0Sopenharmony_ci 15302f4aeb0Sopenharmony_ci static struct my_display 15402f4aeb0Sopenharmony_ci get_display(void) 15502f4aeb0Sopenharmony_ci { 15602f4aeb0Sopenharmony_ci struct my_display dpy; 15702f4aeb0Sopenharmony_ci 15802f4aeb0Sopenharmony_ci int fd = open("/dev/dri/card0", O_RDWR | FD_CLOEXEC); 15902f4aeb0Sopenharmony_ci if (fd < 0) { 16002f4aeb0Sopenharmony_ci abort(); 16102f4aeb0Sopenharmony_ci } 16202f4aeb0Sopenharmony_ci 16302f4aeb0Sopenharmony_ci dpy.gbm = gbm_create_device(fd); 16402f4aeb0Sopenharmony_ci if (!dpy.gbm) { 16502f4aeb0Sopenharmony_ci abort(); 16602f4aeb0Sopenharmony_ci } 16702f4aeb0Sopenharmony_ci 16802f4aeb0Sopenharmony_ci 16902f4aeb0Sopenharmony_ci #ifdef EGL_MESA_platform_gbm 17002f4aeb0Sopenharmony_ci dpy.egl = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, dpy.gbm, NULL); 17102f4aeb0Sopenharmony_ci #else 17202f4aeb0Sopenharmony_ci dpy.egl = eglGetDisplay(dpy.gbm); 17302f4aeb0Sopenharmony_ci #endif 17402f4aeb0Sopenharmony_ci 17502f4aeb0Sopenharmony_ci if (dpy.egl == EGL_NO_DISPLAY) { 17602f4aeb0Sopenharmony_ci abort(); 17702f4aeb0Sopenharmony_ci } 17802f4aeb0Sopenharmony_ci 17902f4aeb0Sopenharmony_ci EGLint major, minor; 18002f4aeb0Sopenharmony_ci if (!eglInitialize(dpy.egl, &major, &minor)) { 18102f4aeb0Sopenharmony_ci abort(); 18202f4aeb0Sopenharmony_ci } 18302f4aeb0Sopenharmony_ci 18402f4aeb0Sopenharmony_ci return dpy; 18502f4aeb0Sopenharmony_ci } 18602f4aeb0Sopenharmony_ci 18702f4aeb0Sopenharmony_ci static struct my_config 18802f4aeb0Sopenharmony_ci get_config(struct my_display dpy) 18902f4aeb0Sopenharmony_ci { 19002f4aeb0Sopenharmony_ci struct my_config config = { 19102f4aeb0Sopenharmony_ci .dpy = dpy, 19202f4aeb0Sopenharmony_ci }; 19302f4aeb0Sopenharmony_ci 19402f4aeb0Sopenharmony_ci EGLint egl_config_attribs[] = { 19502f4aeb0Sopenharmony_ci EGL_BUFFER_SIZE, 32, 19602f4aeb0Sopenharmony_ci EGL_DEPTH_SIZE, EGL_DONT_CARE, 19702f4aeb0Sopenharmony_ci EGL_STENCIL_SIZE, EGL_DONT_CARE, 19802f4aeb0Sopenharmony_ci EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 19902f4aeb0Sopenharmony_ci EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 20002f4aeb0Sopenharmony_ci EGL_NONE, 20102f4aeb0Sopenharmony_ci }; 20202f4aeb0Sopenharmony_ci 20302f4aeb0Sopenharmony_ci EGLint num_configs; 20402f4aeb0Sopenharmony_ci if (!eglGetConfigs(dpy.egl, NULL, 0, &num_configs)) { 20502f4aeb0Sopenharmony_ci abort(); 20602f4aeb0Sopenharmony_ci } 20702f4aeb0Sopenharmony_ci 20802f4aeb0Sopenharmony_ci EGLConfig *configs = malloc(num_configs * sizeof(EGLConfig)); 20902f4aeb0Sopenharmony_ci if (!eglChooseConfig(dpy.egl, egl_config_attribs, 21002f4aeb0Sopenharmony_ci configs, num_configs, &num_configs)) { 21102f4aeb0Sopenharmony_ci abort(); 21202f4aeb0Sopenharmony_ci } 21302f4aeb0Sopenharmony_ci if (num_configs == 0) { 21402f4aeb0Sopenharmony_ci abort(); 21502f4aeb0Sopenharmony_ci } 21602f4aeb0Sopenharmony_ci 21702f4aeb0Sopenharmony_ci // Find a config whose native visual ID is the desired GBM format. 21802f4aeb0Sopenharmony_ci for (int i = 0; i < num_configs; ++i) { 21902f4aeb0Sopenharmony_ci EGLint gbm_format; 22002f4aeb0Sopenharmony_ci 22102f4aeb0Sopenharmony_ci if (!eglGetConfigAttrib(dpy.egl, configs[i], 22202f4aeb0Sopenharmony_ci EGL_NATIVE_VISUAL_ID, &gbm_format)) { 22302f4aeb0Sopenharmony_ci abort(); 22402f4aeb0Sopenharmony_ci } 22502f4aeb0Sopenharmony_ci 22602f4aeb0Sopenharmony_ci if (gbm_format == GBM_FORMAT_XRGB8888) { 22702f4aeb0Sopenharmony_ci config.egl = configs[i]; 22802f4aeb0Sopenharmony_ci free(configs); 22902f4aeb0Sopenharmony_ci return config; 23002f4aeb0Sopenharmony_ci } 23102f4aeb0Sopenharmony_ci } 23202f4aeb0Sopenharmony_ci 23302f4aeb0Sopenharmony_ci // Failed to find a config with matching GBM format. 23402f4aeb0Sopenharmony_ci abort(); 23502f4aeb0Sopenharmony_ci } 23602f4aeb0Sopenharmony_ci 23702f4aeb0Sopenharmony_ci static struct my_window 23802f4aeb0Sopenharmony_ci get_window(struct my_config config) 23902f4aeb0Sopenharmony_ci { 24002f4aeb0Sopenharmony_ci struct my_window window = { 24102f4aeb0Sopenharmony_ci .config = config, 24202f4aeb0Sopenharmony_ci }; 24302f4aeb0Sopenharmony_ci 24402f4aeb0Sopenharmony_ci window.gbm = gbm_surface_create(config.dpy.gbm, 24502f4aeb0Sopenharmony_ci 256, 256, 24602f4aeb0Sopenharmony_ci GBM_FORMAT_XRGB8888, 24702f4aeb0Sopenharmony_ci GBM_BO_USE_RENDERING); 24802f4aeb0Sopenharmony_ci if (!window.gbm) { 24902f4aeb0Sopenharmony_ci abort(); 25002f4aeb0Sopenharmony_ci } 25102f4aeb0Sopenharmony_ci 25202f4aeb0Sopenharmony_ci #ifdef EGL_MESA_platform_gbm 25302f4aeb0Sopenharmony_ci window.egl = eglCreatePlatformWindowSurfaceEXT(config.dpy.egl, 25402f4aeb0Sopenharmony_ci config.egl, 25502f4aeb0Sopenharmony_ci window.gbm, 25602f4aeb0Sopenharmony_ci NULL); 25702f4aeb0Sopenharmony_ci #else 25802f4aeb0Sopenharmony_ci window.egl = eglCreateWindowSurface(config.dpy.egl, 25902f4aeb0Sopenharmony_ci config.egl, 26002f4aeb0Sopenharmony_ci window.gbm, 26102f4aeb0Sopenharmony_ci NULL); 26202f4aeb0Sopenharmony_ci #endif 26302f4aeb0Sopenharmony_ci 26402f4aeb0Sopenharmony_ci if (window.egl == EGL_NO_SURFACE) { 26502f4aeb0Sopenharmony_ci abort(); 26602f4aeb0Sopenharmony_ci } 26702f4aeb0Sopenharmony_ci 26802f4aeb0Sopenharmony_ci return window; 26902f4aeb0Sopenharmony_ci } 27002f4aeb0Sopenharmony_ci 27102f4aeb0Sopenharmony_ci int 27202f4aeb0Sopenharmony_ci main(void) 27302f4aeb0Sopenharmony_ci { 27402f4aeb0Sopenharmony_ci check_extensions(); 27502f4aeb0Sopenharmony_ci 27602f4aeb0Sopenharmony_ci struct my_display dpy = get_display(); 27702f4aeb0Sopenharmony_ci struct my_config config = get_config(dpy); 27802f4aeb0Sopenharmony_ci struct my_window window = get_window(config); 27902f4aeb0Sopenharmony_ci 28002f4aeb0Sopenharmony_ci return 0; 28102f4aeb0Sopenharmony_ci } 28202f4aeb0Sopenharmony_ci 28302f4aeb0Sopenharmony_ciRevision History 28402f4aeb0Sopenharmony_ci 28502f4aeb0Sopenharmony_ci Version 8, 2018-05-25 (Krzysztof Kosiński) 28602f4aeb0Sopenharmony_ci - Corrected EGL_DEFAULT_DISPLAY to NULL. The second argument to 28702f4aeb0Sopenharmony_ci eglGetPlatformDisplayEXT has type void*, while EGL_DEFAULT_DISPLAY has 28802f4aeb0Sopenharmony_ci type EGLNativeDisplayType, which is not guaranteed to be convertible 28902f4aeb0Sopenharmony_ci to void* - it could be int, long or intptr_t. 29002f4aeb0Sopenharmony_ci 29102f4aeb0Sopenharmony_ci Version 7, 2016-01-04 (Jon Leech) 29202f4aeb0Sopenharmony_ci - Free config memory allocated in sample code (Public Bug 1445). 29302f4aeb0Sopenharmony_ci 29402f4aeb0Sopenharmony_ci Version 6, 2014-02-12 (Chad Versace) 29502f4aeb0Sopenharmony_ci - Change resolution of issue #1 from "no" to "yes". Now 29602f4aeb0Sopenharmony_ci eglGetPlatformDisplayEXT accepts EGL_DEFAULT_DISPLAY for GBM. 29702f4aeb0Sopenharmony_ci 29802f4aeb0Sopenharmony_ci Version 5, 2013-010-15 (Chad Versace) 29902f4aeb0Sopenharmony_ci - Specify that EGL_NATIVE_VISUAL_ID is a GBM color format. 30002f4aeb0Sopenharmony_ci - Require for eglCreatePlatformWindowSurfaceEXT that the GBM color 30102f4aeb0Sopenharmony_ci format not differ between the EGLConfig and gbm_surface. (Suggested 30202f4aeb0Sopenharmony_ci by Kristian). 30302f4aeb0Sopenharmony_ci - Update example code to find matching EGL_NATIVE_VISUAL_ID. 30402f4aeb0Sopenharmony_ci 30502f4aeb0Sopenharmony_ci Version 4, 2013-09-13 (Chad Versace) 30602f4aeb0Sopenharmony_ci - Update the text and example code to wording of version 7 of 30702f4aeb0Sopenharmony_ci EGL_EXT_platform_base spec. 30802f4aeb0Sopenharmony_ci - Add section "Extension Type". 30902f4aeb0Sopenharmony_ci - Resolve issue #1 to "No". 31002f4aeb0Sopenharmony_ci - Add issue #2. 31102f4aeb0Sopenharmony_ci 31202f4aeb0Sopenharmony_ci Version 3, 2013-04-26 (Chad Versace) 31302f4aeb0Sopenharmony_ci - Add missing MESA suffix to new token. 31402f4aeb0Sopenharmony_ci 31502f4aeb0Sopenharmony_ci Version 2, 2013-04-23 (Chad Versace) 31602f4aeb0Sopenharmony_ci - Add issue #1 regarding EGL_DEFAULT_DISPLAY. 31702f4aeb0Sopenharmony_ci 31802f4aeb0Sopenharmony_ci Version 1, 2013.03.24 (Chad Versace) 31902f4aeb0Sopenharmony_ci - First draft 320