egl: add EGL 1.5 functions that don't need any changes from extensions
[mesa.git] / src / egl / main / eglapi.c
1 /**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010-2011 LunarG, Inc.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 **************************************************************************/
29
30
31 /**
32 * Public EGL API entrypoints
33 *
34 * Generally, we use the EGLDisplay parameter as a key to lookup the
35 * appropriate device driver handle, then jump though the driver's
36 * dispatch table to handle the function.
37 *
38 * That allows us the option of supporting multiple, simultaneous,
39 * heterogeneous hardware devices in the future.
40 *
41 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
42 * opaque handles. Internal objects are linked to a display to
43 * create the handles.
44 *
45 * For each public API entry point, the opaque handles are looked up
46 * before being dispatched to the drivers. When it fails to look up
47 * a handle, one of
48 *
49 * EGL_BAD_DISPLAY
50 * EGL_BAD_CONFIG
51 * EGL_BAD_CONTEXT
52 * EGL_BAD_SURFACE
53 * EGL_BAD_SCREEN_MESA
54 * EGL_BAD_MODE_MESA
55 *
56 * is generated and the driver function is not called. An
57 * uninitialized EGLDisplay has no driver associated with it. When
58 * such display is detected,
59 *
60 * EGL_NOT_INITIALIZED
61 *
62 * is generated.
63 *
64 * Some of the entry points use current display, context, or surface
65 * implicitly. For such entry points, the implicit objects are also
66 * checked before calling the driver function. Other than the
67 * errors listed above,
68 *
69 * EGL_BAD_CURRENT_SURFACE
70 *
71 * may also be generated.
72 *
73 * Notes on naming conventions:
74 *
75 * eglFooBar - public EGL function
76 * EGL_FOO_BAR - public EGL token
77 * EGLDatatype - public EGL datatype
78 *
79 * _eglFooBar - private EGL function
80 * _EGLDatatype - private EGL datatype, typedef'd struct
81 * _egl_struct - private EGL struct, non-typedef'd
82 *
83 */
84
85
86 #include <stdio.h>
87 #include <stdlib.h>
88 #include <string.h>
89 #include "c99_compat.h"
90 #include "c11/threads.h"
91 #include "eglcompiler.h"
92
93 #include "eglglobals.h"
94 #include "eglcontext.h"
95 #include "egldisplay.h"
96 #include "egltypedefs.h"
97 #include "eglcurrent.h"
98 #include "egldriver.h"
99 #include "eglsurface.h"
100 #include "eglconfig.h"
101 #include "eglimage.h"
102 #include "eglsync.h"
103 #include "eglstring.h"
104
105
106 /**
107 * Macros to help return an API entrypoint.
108 *
109 * These macros will unlock the display and record the error code.
110 */
111 #define RETURN_EGL_ERROR(disp, err, ret) \
112 do { \
113 if (disp) \
114 _eglUnlockDisplay(disp); \
115 /* EGL error codes are non-zero */ \
116 if (err) \
117 _eglError(err, __func__); \
118 return ret; \
119 } while (0)
120
121 #define RETURN_EGL_SUCCESS(disp, ret) \
122 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
123
124 /* record EGL_SUCCESS only when ret evaluates to true */
125 #define RETURN_EGL_EVAL(disp, ret) \
126 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
127
128
129 /*
130 * A bunch of macros and checks to simplify error checking.
131 */
132
133 #define _EGL_CHECK_DISPLAY(disp, ret, drv) \
134 do { \
135 drv = _eglCheckDisplay(disp, __func__); \
136 if (!drv) \
137 RETURN_EGL_ERROR(disp, 0, ret); \
138 } while (0)
139
140 #define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
141 do { \
142 drv = _eglCheck ## type(disp, obj, __func__); \
143 if (!drv) \
144 RETURN_EGL_ERROR(disp, 0, ret); \
145 } while (0)
146
147 #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
148 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
149
150 #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
151 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
152
153 #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
154 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
155
156 #define _EGL_CHECK_SYNC(disp, s, ret, drv) \
157 _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
158
159
160 static inline _EGLDriver *
161 _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
162 {
163 if (!disp) {
164 _eglError(EGL_BAD_DISPLAY, msg);
165 return NULL;
166 }
167 if (!disp->Initialized) {
168 _eglError(EGL_NOT_INITIALIZED, msg);
169 return NULL;
170 }
171 return disp->Driver;
172 }
173
174
175 static inline _EGLDriver *
176 _eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
177 {
178 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
179 if (!drv)
180 return NULL;
181 if (!surf) {
182 _eglError(EGL_BAD_SURFACE, msg);
183 return NULL;
184 }
185 return drv;
186 }
187
188
189 static inline _EGLDriver *
190 _eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
191 {
192 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
193 if (!drv)
194 return NULL;
195 if (!context) {
196 _eglError(EGL_BAD_CONTEXT, msg);
197 return NULL;
198 }
199 return drv;
200 }
201
202
203 static inline _EGLDriver *
204 _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
205 {
206 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
207 if (!drv)
208 return NULL;
209 if (!conf) {
210 _eglError(EGL_BAD_CONFIG, msg);
211 return NULL;
212 }
213 return drv;
214 }
215
216
217 static inline _EGLDriver *
218 _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
219 {
220 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
221 if (!drv)
222 return NULL;
223 if (!s) {
224 _eglError(EGL_BAD_PARAMETER, msg);
225 return NULL;
226 }
227 return drv;
228 }
229
230
231 /**
232 * Lookup and lock a display.
233 */
234 static inline _EGLDisplay *
235 _eglLockDisplay(EGLDisplay display)
236 {
237 _EGLDisplay *dpy = _eglLookupDisplay(display);
238 if (dpy)
239 mtx_lock(&dpy->Mutex);
240 return dpy;
241 }
242
243
244 /**
245 * Unlock a display.
246 */
247 static inline void
248 _eglUnlockDisplay(_EGLDisplay *dpy)
249 {
250 mtx_unlock(&dpy->Mutex);
251 }
252
253
254 /**
255 * This is typically the first EGL function that an application calls.
256 * It associates a private _EGLDisplay object to the native display.
257 */
258 EGLDisplay EGLAPIENTRY
259 eglGetDisplay(EGLNativeDisplayType nativeDisplay)
260 {
261 _EGLPlatformType plat;
262 _EGLDisplay *dpy;
263 void *native_display_ptr;
264
265 STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
266 native_display_ptr = (void*) nativeDisplay;
267
268 plat = _eglGetNativePlatform(native_display_ptr);
269 dpy = _eglFindDisplay(plat, native_display_ptr);
270 return _eglGetDisplayHandle(dpy);
271 }
272
273 static EGLDisplay EGLAPIENTRY
274 eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
275 const EGLint *attrib_list)
276 {
277 _EGLDisplay *dpy;
278
279 switch (platform) {
280 #ifdef HAVE_X11_PLATFORM
281 case EGL_PLATFORM_X11_EXT:
282 dpy = _eglGetX11Display((Display*) native_display, attrib_list);
283 break;
284 #endif
285 #ifdef HAVE_DRM_PLATFORM
286 case EGL_PLATFORM_GBM_MESA:
287 dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
288 attrib_list);
289 break;
290 #endif
291 #ifdef HAVE_WAYLAND_PLATFORM
292 case EGL_PLATFORM_WAYLAND_EXT:
293 dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
294 attrib_list);
295 break;
296 #endif
297 default:
298 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
299 }
300
301 return _eglGetDisplayHandle(dpy);
302 }
303
304 /**
305 * Copy the extension into the string and update the string pointer.
306 */
307 static EGLint
308 _eglAppendExtension(char **str, const char *ext)
309 {
310 char *s = *str;
311 size_t len = strlen(ext);
312
313 if (s) {
314 memcpy(s, ext, len);
315 s[len++] = ' ';
316 s[len] = '\0';
317
318 *str += len;
319 }
320 else {
321 len++;
322 }
323
324 return (EGLint) len;
325 }
326
327 /**
328 * Examine the individual extension enable/disable flags and recompute
329 * the driver's Extensions string.
330 */
331 static void
332 _eglCreateExtensionsString(_EGLDisplay *dpy)
333 {
334 #define _EGL_CHECK_EXTENSION(ext) \
335 do { \
336 if (dpy->Extensions.ext) { \
337 _eglAppendExtension(&exts, "EGL_" #ext); \
338 assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
339 } \
340 } while (0)
341
342 char *exts = dpy->ExtensionsString;
343
344 _EGL_CHECK_EXTENSION(MESA_drm_display);
345 _EGL_CHECK_EXTENSION(MESA_drm_image);
346 _EGL_CHECK_EXTENSION(MESA_configless_context);
347
348 _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
349 _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
350
351 _EGL_CHECK_EXTENSION(KHR_image_base);
352 _EGL_CHECK_EXTENSION(KHR_image_pixmap);
353 if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
354 _eglAppendExtension(&exts, "EGL_KHR_image");
355
356 _EGL_CHECK_EXTENSION(KHR_vg_parent_image);
357 _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
358 _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
359 _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
360 _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
361 _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
362
363 _EGL_CHECK_EXTENSION(KHR_reusable_sync);
364 _EGL_CHECK_EXTENSION(KHR_fence_sync);
365 _EGL_CHECK_EXTENSION(KHR_wait_sync);
366 _EGL_CHECK_EXTENSION(KHR_cl_event2);
367
368 _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
369 _EGL_CHECK_EXTENSION(KHR_create_context);
370
371 _EGL_CHECK_EXTENSION(NOK_swap_region);
372 _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
373
374 _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
375
376 _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
377
378 _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
379 _EGL_CHECK_EXTENSION(EXT_buffer_age);
380 _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
381 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
382
383 _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
384
385 _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
386 #undef _EGL_CHECK_EXTENSION
387 }
388
389 static void
390 _eglCreateAPIsString(_EGLDisplay *dpy)
391 {
392 if (dpy->ClientAPIs & EGL_OPENGL_BIT)
393 strcat(dpy->ClientAPIsString, "OpenGL ");
394
395 if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT)
396 strcat(dpy->ClientAPIsString, "OpenGL_ES ");
397
398 if (dpy->ClientAPIs & EGL_OPENGL_ES2_BIT)
399 strcat(dpy->ClientAPIsString, "OpenGL_ES2 ");
400
401 if (dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR)
402 strcat(dpy->ClientAPIsString, "OpenGL_ES3 ");
403
404 if (dpy->ClientAPIs & EGL_OPENVG_BIT)
405 strcat(dpy->ClientAPIsString, "OpenVG ");
406
407 assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
408 }
409
410 static void
411 _eglComputeVersion(_EGLDisplay *disp)
412 {
413 disp->Version = 14;
414 }
415
416 /**
417 * This is typically the second EGL function that an application calls.
418 * Here we load/initialize the actual hardware driver.
419 */
420 EGLBoolean EGLAPIENTRY
421 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
422 {
423 _EGLDisplay *disp = _eglLockDisplay(dpy);
424
425 if (!disp)
426 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
427
428 if (!disp->Initialized) {
429 if (!_eglMatchDriver(disp, EGL_FALSE))
430 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
431
432 /* limit to APIs supported by core */
433 disp->ClientAPIs &= _EGL_API_ALL_BITS;
434
435 /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
436 * classifies it as an EGL display extension, though conceptually it's an
437 * EGL client extension.
438 *
439 * From the EGL_KHR_get_all_proc_addresses spec:
440 *
441 * The EGL implementation must expose the name
442 * EGL_KHR_client_get_all_proc_addresses if and only if it exposes
443 * EGL_KHR_get_all_proc_addresses and supports
444 * EGL_EXT_client_extensions.
445 *
446 * Mesa unconditionally exposes both client extensions mentioned above,
447 * so the spec requires that each EGLDisplay unconditionally expose
448 * EGL_KHR_get_all_proc_addresses also.
449 */
450 disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
451
452 _eglComputeVersion(disp);
453 _eglCreateExtensionsString(disp);
454 _eglCreateAPIsString(disp);
455 _eglsnprintf(disp->VersionString, sizeof(disp->VersionString),
456 "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
457 disp->Driver->Name);
458 }
459
460 /* Update applications version of major and minor if not NULL */
461 if ((major != NULL) && (minor != NULL)) {
462 *major = disp->Version / 10;
463 *minor = disp->Version % 10;
464 }
465
466 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
467 }
468
469
470 EGLBoolean EGLAPIENTRY
471 eglTerminate(EGLDisplay dpy)
472 {
473 _EGLDisplay *disp = _eglLockDisplay(dpy);
474
475 if (!disp)
476 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
477
478 if (disp->Initialized) {
479 _EGLDriver *drv = disp->Driver;
480
481 drv->API.Terminate(drv, disp);
482 /* do not reset disp->Driver */
483 disp->ClientAPIsString[0] = 0;
484 disp->Initialized = EGL_FALSE;
485 }
486
487 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
488 }
489
490
491 const char * EGLAPIENTRY
492 eglQueryString(EGLDisplay dpy, EGLint name)
493 {
494 _EGLDisplay *disp;
495 _EGLDriver *drv;
496
497 if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
498 RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
499 }
500
501 disp = _eglLockDisplay(dpy);
502 _EGL_CHECK_DISPLAY(disp, NULL, drv);
503
504 switch (name) {
505 case EGL_VENDOR:
506 RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
507 case EGL_VERSION:
508 RETURN_EGL_SUCCESS(disp, disp->VersionString);
509 case EGL_EXTENSIONS:
510 RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
511 case EGL_CLIENT_APIS:
512 RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
513 default:
514 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
515 }
516 }
517
518
519 EGLBoolean EGLAPIENTRY
520 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
521 EGLint config_size, EGLint *num_config)
522 {
523 _EGLDisplay *disp = _eglLockDisplay(dpy);
524 _EGLDriver *drv;
525 EGLBoolean ret;
526
527 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
528 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
529
530 RETURN_EGL_EVAL(disp, ret);
531 }
532
533
534 EGLBoolean EGLAPIENTRY
535 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
536 EGLint config_size, EGLint *num_config)
537 {
538 _EGLDisplay *disp = _eglLockDisplay(dpy);
539 _EGLDriver *drv;
540 EGLBoolean ret;
541
542 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
543 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
544 config_size, num_config);
545
546 RETURN_EGL_EVAL(disp, ret);
547 }
548
549
550 EGLBoolean EGLAPIENTRY
551 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
552 EGLint attribute, EGLint *value)
553 {
554 _EGLDisplay *disp = _eglLockDisplay(dpy);
555 _EGLConfig *conf = _eglLookupConfig(config, disp);
556 _EGLDriver *drv;
557 EGLBoolean ret;
558
559 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
560 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
561
562 RETURN_EGL_EVAL(disp, ret);
563 }
564
565
566 EGLContext EGLAPIENTRY
567 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
568 const EGLint *attrib_list)
569 {
570 _EGLDisplay *disp = _eglLockDisplay(dpy);
571 _EGLConfig *conf = _eglLookupConfig(config, disp);
572 _EGLContext *share = _eglLookupContext(share_list, disp);
573 _EGLDriver *drv;
574 _EGLContext *context;
575 EGLContext ret;
576
577 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
578
579 if (!config && !disp->Extensions.MESA_configless_context)
580 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
581
582 if (!share && share_list != EGL_NO_CONTEXT)
583 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
584
585 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
586 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
587
588 RETURN_EGL_EVAL(disp, ret);
589 }
590
591
592 EGLBoolean EGLAPIENTRY
593 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
594 {
595 _EGLDisplay *disp = _eglLockDisplay(dpy);
596 _EGLContext *context = _eglLookupContext(ctx, disp);
597 _EGLDriver *drv;
598 EGLBoolean ret;
599
600 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
601 _eglUnlinkContext(context);
602 ret = drv->API.DestroyContext(drv, disp, context);
603
604 RETURN_EGL_EVAL(disp, ret);
605 }
606
607
608 EGLBoolean EGLAPIENTRY
609 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
610 EGLContext ctx)
611 {
612 _EGLDisplay *disp = _eglLockDisplay(dpy);
613 _EGLContext *context = _eglLookupContext(ctx, disp);
614 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
615 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
616 _EGLDriver *drv;
617 EGLBoolean ret;
618
619 if (!disp)
620 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
621 drv = disp->Driver;
622
623 /* display is allowed to be uninitialized under certain condition */
624 if (!disp->Initialized) {
625 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
626 ctx != EGL_NO_CONTEXT)
627 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
628 }
629 if (!drv)
630 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
631
632 if (!context && ctx != EGL_NO_CONTEXT)
633 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
634 if (!draw_surf || !read_surf) {
635 /* From the EGL 1.4 (20130211) spec:
636 *
637 * To release the current context without assigning a new one, set ctx
638 * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
639 */
640 if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
641 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
642
643 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
644 (!read_surf && read != EGL_NO_SURFACE))
645 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
646 if (draw_surf || read_surf)
647 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
648 }
649
650 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
651
652 RETURN_EGL_EVAL(disp, ret);
653 }
654
655
656 EGLBoolean EGLAPIENTRY
657 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
658 EGLint attribute, EGLint *value)
659 {
660 _EGLDisplay *disp = _eglLockDisplay(dpy);
661 _EGLContext *context = _eglLookupContext(ctx, disp);
662 _EGLDriver *drv;
663 EGLBoolean ret;
664
665 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
666 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
667
668 RETURN_EGL_EVAL(disp, ret);
669 }
670
671
672 static EGLSurface
673 _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
674 void *native_window, const EGLint *attrib_list)
675 {
676 _EGLConfig *conf = _eglLookupConfig(config, disp);
677 _EGLDriver *drv;
678 _EGLSurface *surf;
679 EGLSurface ret;
680
681 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
682
683 if (native_window == NULL)
684 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
685
686 surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
687 attrib_list);
688 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
689
690 RETURN_EGL_EVAL(disp, ret);
691 }
692
693
694 EGLSurface EGLAPIENTRY
695 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
696 EGLNativeWindowType window, const EGLint *attrib_list)
697 {
698 _EGLDisplay *disp = _eglLockDisplay(dpy);
699 STATIC_ASSERT(sizeof(void*) == sizeof(window));
700 return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
701 attrib_list);
702 }
703
704
705 static EGLSurface EGLAPIENTRY
706 eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
707 void *native_window,
708 const EGLint *attrib_list)
709 {
710 _EGLDisplay *disp = _eglLockDisplay(dpy);
711
712 #ifdef HAVE_X11_PLATFORM
713 if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
714 /* The `native_window` parameter for the X11 platform differs between
715 * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
716 * eglCreateWindowSurface(), the type of `native_window` is an Xlib
717 * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
718 * `Window*`. Convert `Window*` to `Window` because that's what
719 * dri2_x11_create_window_surface() expects.
720 */
721 native_window = (void*) (* (Window*) native_window);
722 }
723 #endif
724
725 return _eglCreateWindowSurfaceCommon(disp, config, native_window,
726 attrib_list);
727 }
728
729
730 static EGLSurface
731 _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
732 void *native_pixmap, const EGLint *attrib_list)
733 {
734 _EGLConfig *conf = _eglLookupConfig(config, disp);
735 _EGLDriver *drv;
736 _EGLSurface *surf;
737 EGLSurface ret;
738
739 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
740 surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
741 attrib_list);
742 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
743
744 RETURN_EGL_EVAL(disp, ret);
745 }
746
747
748 EGLSurface EGLAPIENTRY
749 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
750 EGLNativePixmapType pixmap, const EGLint *attrib_list)
751 {
752 _EGLDisplay *disp = _eglLockDisplay(dpy);
753 STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
754 return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
755 attrib_list);
756 }
757
758 static EGLSurface EGLAPIENTRY
759 eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
760 void *native_pixmap,
761 const EGLint *attrib_list)
762 {
763 _EGLDisplay *disp = _eglLockDisplay(dpy);
764
765 #ifdef HAVE_X11_PLATFORM
766 /* The `native_pixmap` parameter for the X11 platform differs between
767 * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
768 * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
769 * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
770 * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
771 * dri2_x11_create_pixmap_surface() expects.
772 */
773 if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) {
774 native_pixmap = (void*) (* (Pixmap*) native_pixmap);
775 }
776 #endif
777
778 return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
779 attrib_list);
780 }
781
782
783 EGLSurface EGLAPIENTRY
784 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
785 const EGLint *attrib_list)
786 {
787 _EGLDisplay *disp = _eglLockDisplay(dpy);
788 _EGLConfig *conf = _eglLookupConfig(config, disp);
789 _EGLDriver *drv;
790 _EGLSurface *surf;
791 EGLSurface ret;
792
793 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
794
795 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
796 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
797
798 RETURN_EGL_EVAL(disp, ret);
799 }
800
801
802 EGLBoolean EGLAPIENTRY
803 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
804 {
805 _EGLDisplay *disp = _eglLockDisplay(dpy);
806 _EGLSurface *surf = _eglLookupSurface(surface, disp);
807 _EGLDriver *drv;
808 EGLBoolean ret;
809
810 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
811 _eglUnlinkSurface(surf);
812 ret = drv->API.DestroySurface(drv, disp, surf);
813
814 RETURN_EGL_EVAL(disp, ret);
815 }
816
817 EGLBoolean EGLAPIENTRY
818 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
819 EGLint attribute, EGLint *value)
820 {
821 _EGLDisplay *disp = _eglLockDisplay(dpy);
822 _EGLSurface *surf = _eglLookupSurface(surface, disp);
823 _EGLDriver *drv;
824 EGLBoolean ret;
825
826 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
827 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
828
829 RETURN_EGL_EVAL(disp, ret);
830 }
831
832 EGLBoolean EGLAPIENTRY
833 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
834 EGLint attribute, EGLint value)
835 {
836 _EGLDisplay *disp = _eglLockDisplay(dpy);
837 _EGLSurface *surf = _eglLookupSurface(surface, disp);
838 _EGLDriver *drv;
839 EGLBoolean ret;
840
841 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
842 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
843
844 RETURN_EGL_EVAL(disp, ret);
845 }
846
847
848 EGLBoolean EGLAPIENTRY
849 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
850 {
851 _EGLDisplay *disp = _eglLockDisplay(dpy);
852 _EGLSurface *surf = _eglLookupSurface(surface, disp);
853 _EGLDriver *drv;
854 EGLBoolean ret;
855
856 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
857 ret = drv->API.BindTexImage(drv, disp, surf, buffer);
858
859 RETURN_EGL_EVAL(disp, ret);
860 }
861
862
863 EGLBoolean EGLAPIENTRY
864 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
865 {
866 _EGLDisplay *disp = _eglLockDisplay(dpy);
867 _EGLSurface *surf = _eglLookupSurface(surface, disp);
868 _EGLDriver *drv;
869 EGLBoolean ret;
870
871 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
872 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
873
874 RETURN_EGL_EVAL(disp, ret);
875 }
876
877
878 EGLBoolean EGLAPIENTRY
879 eglSwapInterval(EGLDisplay dpy, EGLint interval)
880 {
881 _EGLDisplay *disp = _eglLockDisplay(dpy);
882 _EGLContext *ctx = _eglGetCurrentContext();
883 _EGLSurface *surf;
884 _EGLDriver *drv;
885 EGLBoolean ret;
886
887 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
888
889 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
890 ctx->Resource.Display != disp)
891 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
892
893 surf = ctx->DrawSurface;
894 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
895 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
896
897 ret = drv->API.SwapInterval(drv, disp, surf, interval);
898
899 RETURN_EGL_EVAL(disp, ret);
900 }
901
902
903 EGLBoolean EGLAPIENTRY
904 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
905 {
906 _EGLContext *ctx = _eglGetCurrentContext();
907 _EGLDisplay *disp = _eglLockDisplay(dpy);
908 _EGLSurface *surf = _eglLookupSurface(surface, disp);
909 _EGLDriver *drv;
910 EGLBoolean ret;
911
912 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
913
914 /* surface must be bound to current context in EGL 1.4 */
915 #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
916 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
917 surf != ctx->DrawSurface)
918 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
919 #endif
920
921 ret = drv->API.SwapBuffers(drv, disp, surf);
922
923 RETURN_EGL_EVAL(disp, ret);
924 }
925
926
927 #ifdef EGL_EXT_swap_buffers_with_damage
928
929 static EGLBoolean EGLAPIENTRY
930 eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
931 EGLint *rects, EGLint n_rects)
932 {
933 _EGLContext *ctx = _eglGetCurrentContext();
934 _EGLDisplay *disp = _eglLockDisplay(dpy);
935 _EGLSurface *surf = _eglLookupSurface(surface, disp);
936 _EGLDriver *drv;
937 EGLBoolean ret;
938
939 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
940
941 /* surface must be bound to current context in EGL 1.4 */
942 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
943 surf != ctx->DrawSurface)
944 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
945
946 if ((n_rects > 0 && rects == NULL) || n_rects < 0)
947 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
948
949 ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
950
951 RETURN_EGL_EVAL(disp, ret);
952 }
953
954 #endif /* EGL_EXT_swap_buffers_with_damage */
955
956 EGLBoolean EGLAPIENTRY
957 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
958 {
959 _EGLDisplay *disp = _eglLockDisplay(dpy);
960 _EGLSurface *surf = _eglLookupSurface(surface, disp);
961 _EGLDriver *drv;
962 EGLBoolean ret;
963 void *native_pixmap_ptr;
964
965 STATIC_ASSERT(sizeof(void*) == sizeof(target));
966 native_pixmap_ptr = (void*) target;
967
968 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
969 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
970 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
971 ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
972
973 RETURN_EGL_EVAL(disp, ret);
974 }
975
976
977 EGLBoolean EGLAPIENTRY
978 eglWaitClient(void)
979 {
980 _EGLContext *ctx = _eglGetCurrentContext();
981 _EGLDisplay *disp;
982 _EGLDriver *drv;
983 EGLBoolean ret;
984
985 if (!ctx)
986 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
987
988 disp = ctx->Resource.Display;
989 mtx_lock(&disp->Mutex);
990
991 /* let bad current context imply bad current surface */
992 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
993 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
994 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
995
996 /* a valid current context implies an initialized current display */
997 assert(disp->Initialized);
998 drv = disp->Driver;
999 ret = drv->API.WaitClient(drv, disp, ctx);
1000
1001 RETURN_EGL_EVAL(disp, ret);
1002 }
1003
1004
1005 EGLBoolean EGLAPIENTRY
1006 eglWaitGL(void)
1007 {
1008 _EGLThreadInfo *t = _eglGetCurrentThread();
1009 EGLint api_index = t->CurrentAPIIndex;
1010 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
1011 EGLBoolean ret;
1012
1013 if (api_index != es_index && _eglIsCurrentThreadDummy())
1014 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1015
1016 t->CurrentAPIIndex = es_index;
1017 ret = eglWaitClient();
1018 t->CurrentAPIIndex = api_index;
1019 return ret;
1020 }
1021
1022
1023 EGLBoolean EGLAPIENTRY
1024 eglWaitNative(EGLint engine)
1025 {
1026 _EGLContext *ctx = _eglGetCurrentContext();
1027 _EGLDisplay *disp;
1028 _EGLDriver *drv;
1029 EGLBoolean ret;
1030
1031 if (!ctx)
1032 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1033
1034 disp = ctx->Resource.Display;
1035 mtx_lock(&disp->Mutex);
1036
1037 /* let bad current context imply bad current surface */
1038 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1039 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
1040 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
1041
1042 /* a valid current context implies an initialized current display */
1043 assert(disp->Initialized);
1044 drv = disp->Driver;
1045 ret = drv->API.WaitNative(drv, disp, engine);
1046
1047 RETURN_EGL_EVAL(disp, ret);
1048 }
1049
1050
1051 EGLDisplay EGLAPIENTRY
1052 eglGetCurrentDisplay(void)
1053 {
1054 _EGLContext *ctx = _eglGetCurrentContext();
1055 EGLDisplay ret;
1056
1057 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
1058
1059 RETURN_EGL_SUCCESS(NULL, ret);
1060 }
1061
1062
1063 EGLContext EGLAPIENTRY
1064 eglGetCurrentContext(void)
1065 {
1066 _EGLContext *ctx = _eglGetCurrentContext();
1067 EGLContext ret;
1068
1069 ret = _eglGetContextHandle(ctx);
1070
1071 RETURN_EGL_SUCCESS(NULL, ret);
1072 }
1073
1074
1075 EGLSurface EGLAPIENTRY
1076 eglGetCurrentSurface(EGLint readdraw)
1077 {
1078 _EGLContext *ctx = _eglGetCurrentContext();
1079 EGLint err = EGL_SUCCESS;
1080 _EGLSurface *surf;
1081 EGLSurface ret;
1082
1083 if (!ctx)
1084 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
1085
1086 switch (readdraw) {
1087 case EGL_DRAW:
1088 surf = ctx->DrawSurface;
1089 break;
1090 case EGL_READ:
1091 surf = ctx->ReadSurface;
1092 break;
1093 default:
1094 surf = NULL;
1095 err = EGL_BAD_PARAMETER;
1096 break;
1097 }
1098
1099 ret = _eglGetSurfaceHandle(surf);
1100
1101 RETURN_EGL_ERROR(NULL, err, ret);
1102 }
1103
1104
1105 EGLint EGLAPIENTRY
1106 eglGetError(void)
1107 {
1108 _EGLThreadInfo *t = _eglGetCurrentThread();
1109 EGLint e = t->LastError;
1110 if (!_eglIsCurrentThreadDummy())
1111 t->LastError = EGL_SUCCESS;
1112 return e;
1113 }
1114
1115
1116 #ifdef EGL_MESA_drm_display
1117
1118 static EGLDisplay EGLAPIENTRY
1119 eglGetDRMDisplayMESA(int fd)
1120 {
1121 _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
1122 return _eglGetDisplayHandle(dpy);
1123 }
1124
1125 #endif /* EGL_MESA_drm_display */
1126
1127 /**
1128 ** EGL 1.2
1129 **/
1130
1131 /**
1132 * Specify the client API to use for subsequent calls including:
1133 * eglCreateContext()
1134 * eglGetCurrentContext()
1135 * eglGetCurrentDisplay()
1136 * eglGetCurrentSurface()
1137 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1138 * eglWaitClient()
1139 * eglWaitNative()
1140 * See section 3.7 "Rendering Context" in the EGL specification for details.
1141 */
1142 EGLBoolean EGLAPIENTRY
1143 eglBindAPI(EGLenum api)
1144 {
1145 _EGLThreadInfo *t = _eglGetCurrentThread();
1146
1147 if (_eglIsCurrentThreadDummy())
1148 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1149
1150 if (!_eglIsApiValid(api))
1151 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1152
1153 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
1154
1155 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1156 }
1157
1158
1159 /**
1160 * Return the last value set with eglBindAPI().
1161 */
1162 EGLenum EGLAPIENTRY
1163 eglQueryAPI(void)
1164 {
1165 _EGLThreadInfo *t = _eglGetCurrentThread();
1166 EGLenum ret;
1167
1168 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1169 ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
1170
1171 RETURN_EGL_SUCCESS(NULL, ret);
1172 }
1173
1174
1175 EGLSurface EGLAPIENTRY
1176 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1177 EGLClientBuffer buffer, EGLConfig config,
1178 const EGLint *attrib_list)
1179 {
1180 _EGLDisplay *disp = _eglLockDisplay(dpy);
1181 _EGLConfig *conf = _eglLookupConfig(config, disp);
1182 _EGLDriver *drv;
1183 _EGLSurface *surf;
1184 EGLSurface ret;
1185
1186 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1187
1188 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1189 conf, attrib_list);
1190 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1191
1192 RETURN_EGL_EVAL(disp, ret);
1193 }
1194
1195
1196 EGLBoolean EGLAPIENTRY
1197 eglReleaseThread(void)
1198 {
1199 /* unbind current contexts */
1200 if (!_eglIsCurrentThreadDummy()) {
1201 _EGLThreadInfo *t = _eglGetCurrentThread();
1202 EGLint api_index = t->CurrentAPIIndex;
1203 EGLint i;
1204
1205 for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1206 _EGLContext *ctx = t->CurrentContexts[i];
1207 if (ctx) {
1208 _EGLDisplay *disp = ctx->Resource.Display;
1209 _EGLDriver *drv;
1210
1211 t->CurrentAPIIndex = i;
1212
1213 mtx_lock(&disp->Mutex);
1214 drv = disp->Driver;
1215 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1216 mtx_unlock(&disp->Mutex);
1217 }
1218 }
1219
1220 t->CurrentAPIIndex = api_index;
1221 }
1222
1223 _eglDestroyCurrentThread();
1224
1225 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1226 }
1227
1228
1229 static EGLImage EGLAPIENTRY
1230 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1231 EGLClientBuffer buffer, const EGLint *attr_list)
1232 {
1233 _EGLDisplay *disp = _eglLockDisplay(dpy);
1234 _EGLContext *context = _eglLookupContext(ctx, disp);
1235 _EGLDriver *drv;
1236 _EGLImage *img;
1237 EGLImage ret;
1238
1239 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1240 if (!disp->Extensions.KHR_image_base)
1241 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1242 if (!context && ctx != EGL_NO_CONTEXT)
1243 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1244 /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
1245 * <ctx> must be EGL_NO_CONTEXT..."
1246 */
1247 if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
1248 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1249
1250 img = drv->API.CreateImageKHR(drv,
1251 disp, context, target, buffer, attr_list);
1252 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1253
1254 RETURN_EGL_EVAL(disp, ret);
1255 }
1256
1257
1258 EGLBoolean EGLAPIENTRY
1259 eglDestroyImage(EGLDisplay dpy, EGLImage image)
1260 {
1261 _EGLDisplay *disp = _eglLockDisplay(dpy);
1262 _EGLImage *img = _eglLookupImage(image, disp);
1263 _EGLDriver *drv;
1264 EGLBoolean ret;
1265
1266 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1267 if (!disp->Extensions.KHR_image_base)
1268 RETURN_EGL_EVAL(disp, EGL_FALSE);
1269 if (!img)
1270 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1271
1272 _eglUnlinkImage(img);
1273 ret = drv->API.DestroyImageKHR(drv, disp, img);
1274
1275 RETURN_EGL_EVAL(disp, ret);
1276 }
1277
1278
1279 static EGLSync
1280 _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
1281 const EGLAttrib *attrib_list64, EGLBoolean is64)
1282 {
1283 _EGLDisplay *disp = _eglLockDisplay(dpy);
1284 _EGLContext *ctx = _eglGetCurrentContext();
1285 _EGLDriver *drv;
1286 _EGLSync *sync;
1287 EGLSync ret;
1288
1289 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
1290
1291 if (!disp->Extensions.KHR_cl_event2 && is64)
1292 RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
1293
1294 /* return an error if the client API doesn't support GL_OES_EGL_sync */
1295 if (!ctx || ctx->Resource.Display != dpy ||
1296 ctx->ClientAPI != EGL_OPENGL_ES_API)
1297 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1298
1299 switch (type) {
1300 case EGL_SYNC_FENCE_KHR:
1301 if (!disp->Extensions.KHR_fence_sync)
1302 RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
1303 break;
1304 case EGL_SYNC_REUSABLE_KHR:
1305 if (!disp->Extensions.KHR_reusable_sync)
1306 RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
1307 break;
1308 case EGL_SYNC_CL_EVENT_KHR:
1309 if (!disp->Extensions.KHR_cl_event2)
1310 RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
1311 break;
1312 default:
1313 RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
1314 }
1315
1316 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64);
1317 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
1318
1319 RETURN_EGL_EVAL(disp, ret);
1320 }
1321
1322
1323 static EGLSync EGLAPIENTRY
1324 eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1325 {
1326 return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE);
1327 }
1328
1329
1330 EGLSync EGLAPIENTRY
1331 eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1332 {
1333 return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE);
1334 }
1335
1336
1337 EGLBoolean EGLAPIENTRY
1338 eglDestroySync(EGLDisplay dpy, EGLSync sync)
1339 {
1340 _EGLDisplay *disp = _eglLockDisplay(dpy);
1341 _EGLSync *s = _eglLookupSync(sync, disp);
1342 _EGLDriver *drv;
1343 EGLBoolean ret;
1344
1345 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1346 assert(disp->Extensions.KHR_reusable_sync ||
1347 disp->Extensions.KHR_fence_sync);
1348
1349 _eglUnlinkSync(s);
1350 ret = drv->API.DestroySyncKHR(drv, disp, s);
1351
1352 RETURN_EGL_EVAL(disp, ret);
1353 }
1354
1355
1356 EGLint EGLAPIENTRY
1357 eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
1358 {
1359 _EGLDisplay *disp = _eglLockDisplay(dpy);
1360 _EGLSync *s = _eglLookupSync(sync, disp);
1361 _EGLDriver *drv;
1362 EGLint ret;
1363
1364 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1365 assert(disp->Extensions.KHR_reusable_sync ||
1366 disp->Extensions.KHR_fence_sync);
1367
1368 if (s->SyncStatus == EGL_SIGNALED_KHR)
1369 RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
1370
1371 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1372
1373 RETURN_EGL_EVAL(disp, ret);
1374 }
1375
1376
1377 static EGLint EGLAPIENTRY
1378 eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
1379 {
1380 _EGLDisplay *disp = _eglLockDisplay(dpy);
1381 _EGLSync *s = _eglLookupSync(sync, disp);
1382 _EGLContext *ctx = _eglGetCurrentContext();
1383 _EGLDriver *drv;
1384 EGLint ret;
1385
1386 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1387 assert(disp->Extensions.KHR_wait_sync);
1388
1389 /* return an error if the client API doesn't support GL_OES_EGL_sync */
1390 if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
1391 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1392
1393 /* the API doesn't allow any flags yet */
1394 if (flags != 0)
1395 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1396
1397 ret = drv->API.WaitSyncKHR(drv, disp, s);
1398
1399 RETURN_EGL_EVAL(disp, ret);
1400 }
1401
1402
1403 static EGLBoolean EGLAPIENTRY
1404 eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
1405 {
1406 _EGLDisplay *disp = _eglLockDisplay(dpy);
1407 _EGLSync *s = _eglLookupSync(sync, disp);
1408 _EGLDriver *drv;
1409 EGLBoolean ret;
1410
1411 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1412 assert(disp->Extensions.KHR_reusable_sync);
1413 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
1414
1415 RETURN_EGL_EVAL(disp, ret);
1416 }
1417
1418
1419 static EGLBoolean EGLAPIENTRY
1420 eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
1421 {
1422 _EGLDisplay *disp = _eglLockDisplay(dpy);
1423 _EGLSync *s = _eglLookupSync(sync, disp);
1424 _EGLDriver *drv;
1425 EGLBoolean ret;
1426
1427 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1428 assert(disp->Extensions.KHR_reusable_sync ||
1429 disp->Extensions.KHR_fence_sync);
1430 ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
1431
1432 RETURN_EGL_EVAL(disp, ret);
1433 }
1434
1435
1436 #ifdef EGL_NOK_swap_region
1437
1438 static EGLBoolean EGLAPIENTRY
1439 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1440 EGLint numRects, const EGLint *rects)
1441 {
1442 _EGLContext *ctx = _eglGetCurrentContext();
1443 _EGLDisplay *disp = _eglLockDisplay(dpy);
1444 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1445 _EGLDriver *drv;
1446 EGLBoolean ret;
1447
1448 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1449
1450 if (!disp->Extensions.NOK_swap_region)
1451 RETURN_EGL_EVAL(disp, EGL_FALSE);
1452
1453 /* surface must be bound to current context in EGL 1.4 */
1454 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1455 surf != ctx->DrawSurface)
1456 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1457
1458 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
1459
1460 RETURN_EGL_EVAL(disp, ret);
1461 }
1462
1463 #endif /* EGL_NOK_swap_region */
1464
1465
1466 #ifdef EGL_MESA_drm_image
1467
1468 static EGLImage EGLAPIENTRY
1469 eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
1470 {
1471 _EGLDisplay *disp = _eglLockDisplay(dpy);
1472 _EGLDriver *drv;
1473 _EGLImage *img;
1474 EGLImage ret;
1475
1476 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1477 if (!disp->Extensions.MESA_drm_image)
1478 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1479
1480 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
1481 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1482
1483 RETURN_EGL_EVAL(disp, ret);
1484 }
1485
1486 static EGLBoolean EGLAPIENTRY
1487 eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
1488 EGLint *name, EGLint *handle, EGLint *stride)
1489 {
1490 _EGLDisplay *disp = _eglLockDisplay(dpy);
1491 _EGLImage *img = _eglLookupImage(image, disp);
1492 _EGLDriver *drv;
1493 EGLBoolean ret;
1494
1495 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1496 assert(disp->Extensions.MESA_drm_image);
1497
1498 if (!img)
1499 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1500
1501 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
1502
1503 RETURN_EGL_EVAL(disp, ret);
1504 }
1505
1506 #endif
1507
1508 #ifdef EGL_WL_bind_wayland_display
1509 struct wl_display;
1510
1511 static EGLBoolean EGLAPIENTRY
1512 eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1513 {
1514 _EGLDisplay *disp = _eglLockDisplay(dpy);
1515 _EGLDriver *drv;
1516 EGLBoolean ret;
1517
1518 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1519 assert(disp->Extensions.WL_bind_wayland_display);
1520
1521 if (!display)
1522 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1523
1524 ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
1525
1526 RETURN_EGL_EVAL(disp, ret);
1527 }
1528
1529 static EGLBoolean EGLAPIENTRY
1530 eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1531 {
1532 _EGLDisplay *disp = _eglLockDisplay(dpy);
1533 _EGLDriver *drv;
1534 EGLBoolean ret;
1535
1536 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1537 assert(disp->Extensions.WL_bind_wayland_display);
1538
1539 if (!display)
1540 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1541
1542 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
1543
1544 RETURN_EGL_EVAL(disp, ret);
1545 }
1546
1547 static EGLBoolean EGLAPIENTRY
1548 eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
1549 EGLint attribute, EGLint *value)
1550 {
1551 _EGLDisplay *disp = _eglLockDisplay(dpy);
1552 _EGLDriver *drv;
1553 EGLBoolean ret;
1554
1555 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1556 assert(disp->Extensions.WL_bind_wayland_display);
1557
1558 if (!buffer)
1559 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1560
1561 ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
1562
1563 RETURN_EGL_EVAL(disp, ret);
1564 }
1565 #endif
1566
1567 #ifdef EGL_WL_create_wayland_buffer_from_image
1568 static struct wl_buffer * EGLAPIENTRY
1569 eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
1570 {
1571 _EGLDisplay *disp = _eglLockDisplay(dpy);
1572 _EGLImage *img;
1573 _EGLDriver *drv;
1574 struct wl_buffer *ret;
1575
1576 _EGL_CHECK_DISPLAY(disp, NULL, drv);
1577 assert(disp->Extensions.WL_create_wayland_buffer_from_image);
1578
1579 img = _eglLookupImage(image, disp);
1580
1581 if (!img)
1582 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
1583
1584 ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
1585
1586 RETURN_EGL_EVAL(disp, ret);
1587 }
1588 #endif
1589
1590 static EGLBoolean EGLAPIENTRY
1591 eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
1592 EGLint x, EGLint y, EGLint width, EGLint height)
1593 {
1594 _EGLDisplay *disp = _eglLockDisplay(dpy);
1595 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1596 _EGLDriver *drv;
1597 EGLBoolean ret;
1598
1599 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1600
1601 if (!disp->Extensions.NV_post_sub_buffer)
1602 RETURN_EGL_EVAL(disp, EGL_FALSE);
1603
1604 ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
1605
1606 RETURN_EGL_EVAL(disp, ret);
1607 }
1608
1609 static EGLBoolean EGLAPIENTRY
1610 eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
1611 EGLuint64KHR *ust, EGLuint64KHR *msc,
1612 EGLuint64KHR *sbc)
1613 {
1614 _EGLDisplay *disp = _eglLockDisplay(display);
1615 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1616 _EGLDriver *drv;
1617 EGLBoolean ret;
1618
1619 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1620 if (!disp->Extensions.CHROMIUM_sync_control)
1621 RETURN_EGL_EVAL(disp, EGL_FALSE);
1622
1623 if (!ust || !msc || !sbc)
1624 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1625
1626 ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
1627
1628 RETURN_EGL_EVAL(disp, ret);
1629 }
1630
1631 #ifdef EGL_MESA_image_dma_buf_export
1632 static EGLBoolean EGLAPIENTRY
1633 eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
1634 EGLint *fourcc, EGLint *nplanes,
1635 EGLuint64KHR *modifiers)
1636 {
1637 _EGLDisplay *disp = _eglLockDisplay(dpy);
1638 _EGLImage *img = _eglLookupImage(image, disp);
1639 _EGLDriver *drv;
1640 EGLBoolean ret;
1641
1642 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1643 assert(disp->Extensions.MESA_image_dma_buf_export);
1644
1645 if (!img)
1646 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1647
1648 ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
1649 modifiers);
1650
1651 RETURN_EGL_EVAL(disp, ret);
1652 }
1653
1654 static EGLBoolean EGLAPIENTRY
1655 eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
1656 int *fds, EGLint *strides, EGLint *offsets)
1657 {
1658 _EGLDisplay *disp = _eglLockDisplay(dpy);
1659 _EGLImage *img = _eglLookupImage(image, disp);
1660 _EGLDriver *drv;
1661 EGLBoolean ret;
1662
1663 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1664 assert(disp->Extensions.MESA_image_dma_buf_export);
1665
1666 if (!img)
1667 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1668
1669 ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
1670
1671 RETURN_EGL_EVAL(disp, ret);
1672 }
1673 #endif
1674
1675 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
1676 eglGetProcAddress(const char *procname)
1677 {
1678 static const struct {
1679 const char *name;
1680 _EGLProc function;
1681 } egl_functions[] = {
1682 /* core functions queryable in the presence of
1683 * EGL_KHR_get_all_proc_addresses or EGL 1.5
1684 */
1685 /* alphabetical order */
1686 { "eglBindAPI", (_EGLProc) eglBindAPI },
1687 { "eglBindTexImage", (_EGLProc) eglBindTexImage },
1688 { "eglChooseConfig", (_EGLProc) eglChooseConfig },
1689 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
1690 { "eglCreateContext", (_EGLProc) eglCreateContext },
1691 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
1692 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
1693 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
1694 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
1695 { "eglDestroyContext", (_EGLProc) eglDestroyContext },
1696 { "eglDestroySurface", (_EGLProc) eglDestroySurface },
1697 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
1698 { "eglGetConfigs", (_EGLProc) eglGetConfigs },
1699 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
1700 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
1701 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
1702 { "eglGetDisplay", (_EGLProc) eglGetDisplay },
1703 { "eglGetError", (_EGLProc) eglGetError },
1704 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
1705 { "eglInitialize", (_EGLProc) eglInitialize },
1706 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
1707 { "eglQueryAPI", (_EGLProc) eglQueryAPI },
1708 { "eglQueryContext", (_EGLProc) eglQueryContext },
1709 { "eglQueryString", (_EGLProc) eglQueryString },
1710 { "eglQuerySurface", (_EGLProc) eglQuerySurface },
1711 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
1712 { "eglReleaseThread", (_EGLProc) eglReleaseThread },
1713 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
1714 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
1715 { "eglSwapInterval", (_EGLProc) eglSwapInterval },
1716 { "eglTerminate", (_EGLProc) eglTerminate },
1717 { "eglWaitClient", (_EGLProc) eglWaitClient },
1718 { "eglWaitGL", (_EGLProc) eglWaitGL },
1719 { "eglWaitNative", (_EGLProc) eglWaitNative },
1720 { "eglCreateSync", (_EGLProc) eglCreateSync },
1721 { "eglDestroySync", (_EGLProc) eglDestroySync },
1722 { "eglClientWaitSync", (_EGLProc) eglClientWaitSync },
1723 { "eglDestroyImage", (_EGLProc) eglDestroyImage },
1724 #ifdef EGL_MESA_drm_display
1725 { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
1726 #endif
1727 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
1728 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImage },
1729 { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
1730 { "eglCreateSync64KHR", (_EGLProc) eglCreateSync },
1731 { "eglDestroySyncKHR", (_EGLProc) eglDestroySync },
1732 { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSync },
1733 { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR },
1734 { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
1735 { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
1736 #ifdef EGL_NOK_swap_region
1737 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
1738 #endif
1739 #ifdef EGL_MESA_drm_image
1740 { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
1741 { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
1742 #endif
1743 #ifdef EGL_WL_bind_wayland_display
1744 { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
1745 { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
1746 { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
1747 #endif
1748 #ifdef EGL_WL_create_wayland_buffer_from_image
1749 { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
1750 #endif
1751 { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
1752 #ifdef EGL_EXT_swap_buffers_with_damage
1753 { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
1754 #endif
1755 { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
1756 { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
1757 { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
1758 { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
1759 #ifdef EGL_MESA_image_dma_buf_export
1760 { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
1761 { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
1762 #endif
1763 { NULL, NULL }
1764 };
1765 EGLint i;
1766 _EGLProc ret;
1767
1768 if (!procname)
1769 RETURN_EGL_SUCCESS(NULL, NULL);
1770
1771 ret = NULL;
1772 if (strncmp(procname, "egl", 3) == 0) {
1773 for (i = 0; egl_functions[i].name; i++) {
1774 if (strcmp(egl_functions[i].name, procname) == 0) {
1775 ret = egl_functions[i].function;
1776 break;
1777 }
1778 }
1779 }
1780 if (!ret)
1781 ret = _eglGetDriverProc(procname);
1782
1783 RETURN_EGL_SUCCESS(NULL, ret);
1784 }