102f4aeb0Sopenharmony_ciName 202f4aeb0Sopenharmony_ci 302f4aeb0Sopenharmony_ci KHR_platform_gbm 402f4aeb0Sopenharmony_ci 502f4aeb0Sopenharmony_ciName Strings 602f4aeb0Sopenharmony_ci 702f4aeb0Sopenharmony_ci EGL_KHR_platform_gbm 802f4aeb0Sopenharmony_ci 902f4aeb0Sopenharmony_ciContributors 1002f4aeb0Sopenharmony_ci 1102f4aeb0Sopenharmony_ci Chad Versace <chad.versace@intel.com> 1202f4aeb0Sopenharmony_ci Jon Leech (oddhack 'at' sonic.net) 1302f4aeb0Sopenharmony_ci Kristian Høgsberg <krh@bitplanet.org> 1402f4aeb0Sopenharmony_ci 1502f4aeb0Sopenharmony_ciContacts 1602f4aeb0Sopenharmony_ci 1702f4aeb0Sopenharmony_ci Chad Versace <chad.versace@intel.com> 1802f4aeb0Sopenharmony_ci 1902f4aeb0Sopenharmony_ciStatus 2002f4aeb0Sopenharmony_ci 2102f4aeb0Sopenharmony_ci Complete. 2202f4aeb0Sopenharmony_ci Approved by the EGL Working Group on January 31, 2014. 2302f4aeb0Sopenharmony_ci Ratified by the Khronos Board of Promoters on March 14, 2014. 2402f4aeb0Sopenharmony_ci 2502f4aeb0Sopenharmony_ciVersion 2602f4aeb0Sopenharmony_ci 2702f4aeb0Sopenharmony_ci Version 3, 2016/01/04 2802f4aeb0Sopenharmony_ci 2902f4aeb0Sopenharmony_ciNumber 3002f4aeb0Sopenharmony_ci 3102f4aeb0Sopenharmony_ci EGL Extension #69 3202f4aeb0Sopenharmony_ci 3302f4aeb0Sopenharmony_ciExtension Type 3402f4aeb0Sopenharmony_ci 3502f4aeb0Sopenharmony_ci EGL client extension 3602f4aeb0Sopenharmony_ci 3702f4aeb0Sopenharmony_ciDependencies 3802f4aeb0Sopenharmony_ci 3902f4aeb0Sopenharmony_ci EGL 1.5 is required. 4002f4aeb0Sopenharmony_ci 4102f4aeb0Sopenharmony_ci This extension is written against the EGL 1.5 Specification (draft 4202f4aeb0Sopenharmony_ci 20140122). 4302f4aeb0Sopenharmony_ci 4402f4aeb0Sopenharmony_ciOverview 4502f4aeb0Sopenharmony_ci 4602f4aeb0Sopenharmony_ci This extension defines how to create EGL resources from native GBM 4702f4aeb0Sopenharmony_ci resources using the EGL 1.5 platform functionality (GBM is a Generic 4802f4aeb0Sopenharmony_ci 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 eglGetPlatformDisplay: 6102f4aeb0Sopenharmony_ci 6202f4aeb0Sopenharmony_ci EGL_PLATFORM_GBM_KHR 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 eglGetPlatformDisplay with 7402f4aeb0Sopenharmony_ci <platform> set to EGL_PLATFORM_GBM_KHR. 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 EGL_DEFAULT_DISPLAY. If <native_display> is 7702f4aeb0Sopenharmony_ci EGL_DEFAULT_DISPLAY, then the resultant EGLDisplay will be backed by some 7802f4aeb0Sopenharmony_ci implementation-chosen GBM device. 7902f4aeb0Sopenharmony_ci 8002f4aeb0Sopenharmony_ci For each EGLConfig that belongs to the GBM platform, the 8102f4aeb0Sopenharmony_ci EGL_NATIVE_VISUAL_ID attribute is a GBM color format, such as 8202f4aeb0Sopenharmony_ci GBM_FORMAT_XRGB8888. 8302f4aeb0Sopenharmony_ci 8402f4aeb0Sopenharmony_ci To obtain a rendering surface from a GBM surface, call 8502f4aeb0Sopenharmony_ci eglCreatePlatformWindowSurface with a <dpy> that belongs to the GBM 8602f4aeb0Sopenharmony_ci platform and a <native_window> that points to a `struct gbm_surface`. If 8702f4aeb0Sopenharmony_ci <native_window> was created without the GBM_BO_USE_RENDERING flag, or if 8802f4aeb0Sopenharmony_ci the color format of <native_window> differs from the EGL_NATIVE_VISUAL_ID 8902f4aeb0Sopenharmony_ci of <config>, then the function fails and generates EGL_BAD_MATCH. 9002f4aeb0Sopenharmony_ci 9102f4aeb0Sopenharmony_ci It is not valid to call eglCreatePlatformPixmapSurface with a <dpy> that 9202f4aeb0Sopenharmony_ci belongs to the GBM platform. Any such call fails and generates 9302f4aeb0Sopenharmony_ci an EGL_BAD_PARAMETER error. 9402f4aeb0Sopenharmony_ci 9502f4aeb0Sopenharmony_ciIssues 9602f4aeb0Sopenharmony_ci 9702f4aeb0Sopenharmony_ci 1. Should this extension permit EGL_DEFAULT_DISPLAY as input to 9802f4aeb0Sopenharmony_ci eglGetPlatformDisplay? 9902f4aeb0Sopenharmony_ci 10002f4aeb0Sopenharmony_ci RESOLUTION: Yes. When given EGL_DEFAULT_DISPLAY, eglGetPlatformDisplay 10102f4aeb0Sopenharmony_ci returns an EGLDisplay backed by an implementation-chosen GBM device. 10202f4aeb0Sopenharmony_ci 10302f4aeb0Sopenharmony_ciExample Code 10402f4aeb0Sopenharmony_ci 10502f4aeb0Sopenharmony_ci // This example program creates an EGL surface from a GBM surface. 10602f4aeb0Sopenharmony_ci // 10702f4aeb0Sopenharmony_ci // If the macro EGL_KHR_platform_gbm is defined, then the program 10802f4aeb0Sopenharmony_ci // creates the surfaces using the methods defined in this specification. 10902f4aeb0Sopenharmony_ci // Otherwise, it uses the methods defined by the EGL 1.4 specification. 11002f4aeb0Sopenharmony_ci // 11102f4aeb0Sopenharmony_ci // Compile with `cc -std=c99 example.c -lgbm -lEGL`. 11202f4aeb0Sopenharmony_ci 11302f4aeb0Sopenharmony_ci #include <stdlib.h> 11402f4aeb0Sopenharmony_ci #include <string.h> 11502f4aeb0Sopenharmony_ci 11602f4aeb0Sopenharmony_ci #include <sys/types.h> 11702f4aeb0Sopenharmony_ci #include <sys/stat.h> 11802f4aeb0Sopenharmony_ci #include <fcntl.h> 11902f4aeb0Sopenharmony_ci 12002f4aeb0Sopenharmony_ci #include <EGL/egl.h> 12102f4aeb0Sopenharmony_ci #include <gbm.h> 12202f4aeb0Sopenharmony_ci 12302f4aeb0Sopenharmony_ci struct my_display { 12402f4aeb0Sopenharmony_ci struct gbm_device *gbm; 12502f4aeb0Sopenharmony_ci EGLDisplay egl; 12602f4aeb0Sopenharmony_ci }; 12702f4aeb0Sopenharmony_ci 12802f4aeb0Sopenharmony_ci struct my_config { 12902f4aeb0Sopenharmony_ci struct my_display dpy; 13002f4aeb0Sopenharmony_ci EGLConfig egl; 13102f4aeb0Sopenharmony_ci }; 13202f4aeb0Sopenharmony_ci 13302f4aeb0Sopenharmony_ci struct my_window { 13402f4aeb0Sopenharmony_ci struct my_config config; 13502f4aeb0Sopenharmony_ci struct gbm_surface *gbm; 13602f4aeb0Sopenharmony_ci EGLSurface egl; 13702f4aeb0Sopenharmony_ci }; 13802f4aeb0Sopenharmony_ci 13902f4aeb0Sopenharmony_ci static void 14002f4aeb0Sopenharmony_ci check_extensions(void) 14102f4aeb0Sopenharmony_ci { 14202f4aeb0Sopenharmony_ci #ifdef EGL_KHR_platform_gbm 14302f4aeb0Sopenharmony_ci const char *client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); 14402f4aeb0Sopenharmony_ci 14502f4aeb0Sopenharmony_ci if (!client_extensions) { 14602f4aeb0Sopenharmony_ci // No client extensions string available 14702f4aeb0Sopenharmony_ci abort(); 14802f4aeb0Sopenharmony_ci } 14902f4aeb0Sopenharmony_ci if (!strstr(client_extensions, "EGL_KHR_platform_gbm")) { 15002f4aeb0Sopenharmony_ci abort(); 15102f4aeb0Sopenharmony_ci } 15202f4aeb0Sopenharmony_ci #endif 15302f4aeb0Sopenharmony_ci } 15402f4aeb0Sopenharmony_ci 15502f4aeb0Sopenharmony_ci static struct my_display 15602f4aeb0Sopenharmony_ci get_display(void) 15702f4aeb0Sopenharmony_ci { 15802f4aeb0Sopenharmony_ci struct my_display dpy; 15902f4aeb0Sopenharmony_ci 16002f4aeb0Sopenharmony_ci int fd = open("/dev/dri/card0", O_RDWR | FD_CLOEXEC); 16102f4aeb0Sopenharmony_ci if (fd < 0) { 16202f4aeb0Sopenharmony_ci abort(); 16302f4aeb0Sopenharmony_ci } 16402f4aeb0Sopenharmony_ci 16502f4aeb0Sopenharmony_ci dpy.gbm = gbm_create_device(fd); 16602f4aeb0Sopenharmony_ci if (!dpy.gbm) { 16702f4aeb0Sopenharmony_ci abort(); 16802f4aeb0Sopenharmony_ci } 16902f4aeb0Sopenharmony_ci 17002f4aeb0Sopenharmony_ci 17102f4aeb0Sopenharmony_ci #ifdef EGL_KHR_platform_gbm 17202f4aeb0Sopenharmony_ci dpy.egl = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, dpy.gbm, NULL); 17302f4aeb0Sopenharmony_ci #else 17402f4aeb0Sopenharmony_ci dpy.egl = eglGetDisplay(dpy.gbm); 17502f4aeb0Sopenharmony_ci #endif 17602f4aeb0Sopenharmony_ci 17702f4aeb0Sopenharmony_ci if (dpy.egl == EGL_NO_DISPLAY) { 17802f4aeb0Sopenharmony_ci abort(); 17902f4aeb0Sopenharmony_ci } 18002f4aeb0Sopenharmony_ci 18102f4aeb0Sopenharmony_ci EGLint major, minor; 18202f4aeb0Sopenharmony_ci if (!eglInitialize(dpy.egl, &major, &minor)) { 18302f4aeb0Sopenharmony_ci abort(); 18402f4aeb0Sopenharmony_ci } 18502f4aeb0Sopenharmony_ci 18602f4aeb0Sopenharmony_ci return dpy; 18702f4aeb0Sopenharmony_ci } 18802f4aeb0Sopenharmony_ci 18902f4aeb0Sopenharmony_ci static struct my_config 19002f4aeb0Sopenharmony_ci get_config(struct my_display dpy) 19102f4aeb0Sopenharmony_ci { 19202f4aeb0Sopenharmony_ci struct my_config config = { 19302f4aeb0Sopenharmony_ci .dpy = dpy, 19402f4aeb0Sopenharmony_ci }; 19502f4aeb0Sopenharmony_ci 19602f4aeb0Sopenharmony_ci EGLint egl_config_attribs[] = { 19702f4aeb0Sopenharmony_ci EGL_BUFFER_SIZE, 32, 19802f4aeb0Sopenharmony_ci EGL_DEPTH_SIZE, EGL_DONT_CARE, 19902f4aeb0Sopenharmony_ci EGL_STENCIL_SIZE, EGL_DONT_CARE, 20002f4aeb0Sopenharmony_ci EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 20102f4aeb0Sopenharmony_ci EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 20202f4aeb0Sopenharmony_ci EGL_NONE, 20302f4aeb0Sopenharmony_ci }; 20402f4aeb0Sopenharmony_ci 20502f4aeb0Sopenharmony_ci EGLint num_configs; 20602f4aeb0Sopenharmony_ci if (!eglGetConfigs(dpy.egl, NULL, 0, &num_configs)) { 20702f4aeb0Sopenharmony_ci abort(); 20802f4aeb0Sopenharmony_ci } 20902f4aeb0Sopenharmony_ci 21002f4aeb0Sopenharmony_ci EGLConfig *configs = malloc(num_configs * sizeof(EGLConfig)); 21102f4aeb0Sopenharmony_ci if (!eglChooseConfig(dpy.egl, egl_config_attribs, 21202f4aeb0Sopenharmony_ci configs, num_configs, &num_configs)) { 21302f4aeb0Sopenharmony_ci abort(); 21402f4aeb0Sopenharmony_ci } 21502f4aeb0Sopenharmony_ci if (num_configs == 0) { 21602f4aeb0Sopenharmony_ci abort(); 21702f4aeb0Sopenharmony_ci } 21802f4aeb0Sopenharmony_ci 21902f4aeb0Sopenharmony_ci // Find a config whose native visual ID is the desired GBM format. 22002f4aeb0Sopenharmony_ci for (int i = 0; i < num_configs; ++i) { 22102f4aeb0Sopenharmony_ci EGLint gbm_format; 22202f4aeb0Sopenharmony_ci 22302f4aeb0Sopenharmony_ci if (!eglGetConfigAttrib(dpy.egl, configs[i], 22402f4aeb0Sopenharmony_ci EGL_NATIVE_VISUAL_ID, &gbm_format)) { 22502f4aeb0Sopenharmony_ci abort(); 22602f4aeb0Sopenharmony_ci } 22702f4aeb0Sopenharmony_ci 22802f4aeb0Sopenharmony_ci if (gbm_format == GBM_FORMAT_XRGB8888) { 22902f4aeb0Sopenharmony_ci config.egl = configs[i]; 23002f4aeb0Sopenharmony_ci free(configs); 23102f4aeb0Sopenharmony_ci return config; 23202f4aeb0Sopenharmony_ci } 23302f4aeb0Sopenharmony_ci } 23402f4aeb0Sopenharmony_ci 23502f4aeb0Sopenharmony_ci // Failed to find a config with matching GBM format. 23602f4aeb0Sopenharmony_ci abort(); 23702f4aeb0Sopenharmony_ci } 23802f4aeb0Sopenharmony_ci 23902f4aeb0Sopenharmony_ci static struct my_window 24002f4aeb0Sopenharmony_ci get_window(struct my_config config) 24102f4aeb0Sopenharmony_ci { 24202f4aeb0Sopenharmony_ci struct my_window window = { 24302f4aeb0Sopenharmony_ci .config = config, 24402f4aeb0Sopenharmony_ci }; 24502f4aeb0Sopenharmony_ci 24602f4aeb0Sopenharmony_ci window.gbm = gbm_surface_create(config.dpy.gbm, 24702f4aeb0Sopenharmony_ci 256, 256, 24802f4aeb0Sopenharmony_ci GBM_FORMAT_XRGB8888, 24902f4aeb0Sopenharmony_ci GBM_BO_USE_RENDERING); 25002f4aeb0Sopenharmony_ci if (!window.gbm) { 25102f4aeb0Sopenharmony_ci abort(); 25202f4aeb0Sopenharmony_ci } 25302f4aeb0Sopenharmony_ci 25402f4aeb0Sopenharmony_ci #ifdef EGL_KHR_platform_gbm 25502f4aeb0Sopenharmony_ci window.egl = eglCreatePlatformWindowSurface(config.dpy.egl, 25602f4aeb0Sopenharmony_ci config.egl, 25702f4aeb0Sopenharmony_ci window.gbm, 25802f4aeb0Sopenharmony_ci NULL); 25902f4aeb0Sopenharmony_ci #else 26002f4aeb0Sopenharmony_ci window.egl = eglCreateWindowSurface(config.dpy.egl, 26102f4aeb0Sopenharmony_ci config.egl, 26202f4aeb0Sopenharmony_ci window.gbm, 26302f4aeb0Sopenharmony_ci NULL); 26402f4aeb0Sopenharmony_ci #endif 26502f4aeb0Sopenharmony_ci 26602f4aeb0Sopenharmony_ci if (window.egl == EGL_NO_SURFACE) { 26702f4aeb0Sopenharmony_ci abort(); 26802f4aeb0Sopenharmony_ci } 26902f4aeb0Sopenharmony_ci 27002f4aeb0Sopenharmony_ci return window; 27102f4aeb0Sopenharmony_ci } 27202f4aeb0Sopenharmony_ci 27302f4aeb0Sopenharmony_ci int 27402f4aeb0Sopenharmony_ci main(void) 27502f4aeb0Sopenharmony_ci { 27602f4aeb0Sopenharmony_ci check_extensions(); 27702f4aeb0Sopenharmony_ci 27802f4aeb0Sopenharmony_ci struct my_display dpy = get_display(); 27902f4aeb0Sopenharmony_ci struct my_config config = get_config(dpy); 28002f4aeb0Sopenharmony_ci struct my_window window = get_window(config); 28102f4aeb0Sopenharmony_ci 28202f4aeb0Sopenharmony_ci return 0; 28302f4aeb0Sopenharmony_ci } 28402f4aeb0Sopenharmony_ci 28502f4aeb0Sopenharmony_ciRevision History 28602f4aeb0Sopenharmony_ci 28702f4aeb0Sopenharmony_ci Version 3, 2016-01-04 (Jon Leech) 28802f4aeb0Sopenharmony_ci - Free config memory allocated in sample code (Public Bug 1445). 28902f4aeb0Sopenharmony_ci 29002f4aeb0Sopenharmony_ci Version 2, 2014/02/12 (Chad Versace) 29102f4aeb0Sopenharmony_ci - Change resolution of issue #1 from "no" to "yes". Now 29202f4aeb0Sopenharmony_ci eglGetPlatformDisplay accepts EGL_DEFAULT_DISPLAY for GBM. 29302f4aeb0Sopenharmony_ci 29402f4aeb0Sopenharmony_ci Version 1, 2014/01/22 (Jon Leech) 29502f4aeb0Sopenharmony_ci - Promote EGL_MESA_platform_gbm to KHR to go with EGL 1.5. 296