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