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