summaryrefslogtreecommitdiff
path: root/glew/auto/EGL-Registry/extensions/MESA/EGL_MESA_platform_gbm.txt
blob: e40a77449d646c8d3e20aa0f4c3f41b6ea982ae0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
Name

    MESA_platform_gbm

Name Strings

    EGL_MESA_platform_gbm

Contributors

    Chad Versace <chad.versace@intel.com>
    Kristian Høgsberg <krh@bitplanet.org>

Contacts

    Chad Versace <chad.versace@intel.com>

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 <platform> 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
    <platform> set to EGL_PLATFORM_GBM_MESA. The <native_display> parameter
    specifies the GBM device to use and must either point to a `struct
    gbm_device` or be NULL. If <native_display> 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 <dpy> that belongs to the GBM
    platform and a <native_window> that points to a `struct gbm_surface`.  If
    <native_window> was created without the GBM_BO_USE_RENDERING flag, or if
    the color format of <native_window> differs from the EGL_NATIVE_VISUAL_ID
    of <config>, then the function fails and generates EGL_BAD_MATCH.

    It is not valid to call eglCreatePlatformPixmapSurfaceEXT with a <dpy> 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 <stdlib.h>
    #include <string.h>

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    #include <EGL/egl.h>
    #include <gbm.h>

    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