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