eglapi.c revision 3464ebd5
1/************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 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 90#include "eglcontext.h" 91#include "egldisplay.h" 92#include "egltypedefs.h" 93#include "eglcurrent.h" 94#include "egldriver.h" 95#include "eglsurface.h" 96#include "eglconfig.h" 97#include "eglscreen.h" 98#include "eglmode.h" 99#include "eglimage.h" 100#include "eglsync.h" 101 102 103/** 104 * Macros to help return an API entrypoint. 105 * 106 * These macros will unlock the display and record the error code. 107 */ 108#define RETURN_EGL_ERROR(disp, err, ret) \ 109 do { \ 110 if (disp) \ 111 _eglUnlockDisplay(disp); \ 112 /* EGL error codes are non-zero */ \ 113 if (err) \ 114 _eglError(err, __FUNCTION__); \ 115 return ret; \ 116 } while (0) 117 118#define RETURN_EGL_SUCCESS(disp, ret) \ 119 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret) 120 121/* record EGL_SUCCESS only when ret evaluates to true */ 122#define RETURN_EGL_EVAL(disp, ret) \ 123 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret) 124 125 126/* 127 * A bunch of macros and checks to simplify error checking. 128 */ 129 130#define _EGL_CHECK_DISPLAY(disp, ret, drv) \ 131 do { \ 132 drv = _eglCheckDisplay(disp, __FUNCTION__); \ 133 if (!drv) \ 134 RETURN_EGL_ERROR(disp, 0, ret); \ 135 } while (0) 136 137#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \ 138 do { \ 139 drv = _eglCheck ## type(disp, obj, __FUNCTION__); \ 140 if (!drv) \ 141 RETURN_EGL_ERROR(disp, 0, ret); \ 142 } while (0) 143 144#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \ 145 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv) 146 147#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \ 148 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv) 149 150#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \ 151 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv) 152 153#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \ 154 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv) 155 156#define _EGL_CHECK_MODE(disp, m, ret, drv) \ 157 _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv) 158 159#define _EGL_CHECK_SYNC(disp, s, ret, drv) \ 160 _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv) 161 162 163static INLINE _EGLDriver * 164_eglCheckDisplay(_EGLDisplay *disp, const char *msg) 165{ 166 if (!disp) { 167 _eglError(EGL_BAD_DISPLAY, msg); 168 return NULL; 169 } 170 if (!disp->Initialized) { 171 _eglError(EGL_NOT_INITIALIZED, msg); 172 return NULL; 173 } 174 return disp->Driver; 175} 176 177 178static INLINE _EGLDriver * 179_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg) 180{ 181 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 182 if (!drv) 183 return NULL; 184 if (!surf) { 185 _eglError(EGL_BAD_SURFACE, msg); 186 return NULL; 187 } 188 return drv; 189} 190 191 192static INLINE _EGLDriver * 193_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg) 194{ 195 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 196 if (!drv) 197 return NULL; 198 if (!context) { 199 _eglError(EGL_BAD_CONTEXT, msg); 200 return NULL; 201 } 202 return drv; 203} 204 205 206static INLINE _EGLDriver * 207_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) 208{ 209 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 210 if (!drv) 211 return NULL; 212 if (!conf) { 213 _eglError(EGL_BAD_CONFIG, msg); 214 return NULL; 215 } 216 return drv; 217} 218 219 220#ifdef EGL_KHR_reusable_sync 221 222 223static INLINE _EGLDriver * 224_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg) 225{ 226 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 227 if (!drv) 228 return NULL; 229 if (!s) { 230 _eglError(EGL_BAD_PARAMETER, msg); 231 return NULL; 232 } 233 return drv; 234} 235 236 237#endif /* EGL_KHR_reusable_sync */ 238 239 240#ifdef EGL_MESA_screen_surface 241 242 243static INLINE _EGLDriver * 244_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg) 245{ 246 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 247 if (!drv) 248 return NULL; 249 if (!scrn) { 250 _eglError(EGL_BAD_SCREEN_MESA, msg); 251 return NULL; 252 } 253 return drv; 254} 255 256 257static INLINE _EGLDriver * 258_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) 259{ 260 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 261 if (!drv) 262 return NULL; 263 if (!m) { 264 _eglError(EGL_BAD_MODE_MESA, msg); 265 return NULL; 266 } 267 return drv; 268} 269 270 271#endif /* EGL_MESA_screen_surface */ 272 273 274/** 275 * Lookup and lock a display. 276 */ 277static INLINE _EGLDisplay * 278_eglLockDisplay(EGLDisplay display) 279{ 280 _EGLDisplay *dpy = _eglLookupDisplay(display); 281 if (dpy) 282 _eglLockMutex(&dpy->Mutex); 283 return dpy; 284} 285 286 287/** 288 * Unlock a display. 289 */ 290static INLINE void 291_eglUnlockDisplay(_EGLDisplay *dpy) 292{ 293 _eglUnlockMutex(&dpy->Mutex); 294} 295 296 297/** 298 * This is typically the first EGL function that an application calls. 299 * It associates a private _EGLDisplay object to the native display. 300 */ 301EGLDisplay EGLAPIENTRY 302eglGetDisplay(EGLNativeDisplayType nativeDisplay) 303{ 304 _EGLPlatformType plat = _eglGetNativePlatform(); 305 _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay); 306 return _eglGetDisplayHandle(dpy); 307} 308 309 310/** 311 * This is typically the second EGL function that an application calls. 312 * Here we load/initialize the actual hardware driver. 313 */ 314EGLBoolean EGLAPIENTRY 315eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 316{ 317 _EGLDisplay *disp = _eglLockDisplay(dpy); 318 319 if (!disp) 320 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); 321 322 if (!disp->Initialized) { 323 if (!_eglMatchDriver(disp, EGL_FALSE)) 324 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); 325 326 /* limit to APIs supported by core */ 327 disp->ClientAPIs &= _EGL_API_ALL_BITS; 328 } 329 330 /* Update applications version of major and minor if not NULL */ 331 if ((major != NULL) && (minor != NULL)) { 332 *major = disp->VersionMajor; 333 *minor = disp->VersionMinor; 334 } 335 336 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 337} 338 339 340EGLBoolean EGLAPIENTRY 341eglTerminate(EGLDisplay dpy) 342{ 343 _EGLDisplay *disp = _eglLockDisplay(dpy); 344 345 if (!disp) 346 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); 347 348 if (disp->Initialized) { 349 _EGLDriver *drv = disp->Driver; 350 351 drv->API.Terminate(drv, disp); 352 /* do not reset disp->Driver */ 353 disp->Initialized = EGL_FALSE; 354 } 355 356 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 357} 358 359 360const char * EGLAPIENTRY 361eglQueryString(EGLDisplay dpy, EGLint name) 362{ 363 _EGLDisplay *disp = _eglLockDisplay(dpy); 364 _EGLDriver *drv; 365 const char *ret; 366 367 _EGL_CHECK_DISPLAY(disp, NULL, drv); 368 ret = drv->API.QueryString(drv, disp, name); 369 370 RETURN_EGL_EVAL(disp, ret); 371} 372 373 374EGLBoolean EGLAPIENTRY 375eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, 376 EGLint config_size, EGLint *num_config) 377{ 378 _EGLDisplay *disp = _eglLockDisplay(dpy); 379 _EGLDriver *drv; 380 EGLBoolean ret; 381 382 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 383 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config); 384 385 RETURN_EGL_EVAL(disp, ret); 386} 387 388 389EGLBoolean EGLAPIENTRY 390eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, 391 EGLint config_size, EGLint *num_config) 392{ 393 _EGLDisplay *disp = _eglLockDisplay(dpy); 394 _EGLDriver *drv; 395 EGLBoolean ret; 396 397 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 398 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs, 399 config_size, num_config); 400 401 RETURN_EGL_EVAL(disp, ret); 402} 403 404 405EGLBoolean EGLAPIENTRY 406eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, 407 EGLint attribute, EGLint *value) 408{ 409 _EGLDisplay *disp = _eglLockDisplay(dpy); 410 _EGLConfig *conf = _eglLookupConfig(config, disp); 411 _EGLDriver *drv; 412 EGLBoolean ret; 413 414 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv); 415 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); 416 417 RETURN_EGL_EVAL(disp, ret); 418} 419 420 421EGLContext EGLAPIENTRY 422eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, 423 const EGLint *attrib_list) 424{ 425 _EGLDisplay *disp = _eglLockDisplay(dpy); 426 _EGLConfig *conf = _eglLookupConfig(config, disp); 427 _EGLContext *share = _eglLookupContext(share_list, disp); 428 _EGLDriver *drv; 429 _EGLContext *context; 430 EGLContext ret; 431 432 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv); 433 434 if (!config) { 435 /* config may be NULL if surfaceless */ 436 if (!disp->Extensions.KHR_surfaceless_gles1 && 437 !disp->Extensions.KHR_surfaceless_gles2 && 438 !disp->Extensions.KHR_surfaceless_opengl) 439 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT); 440 } 441 442 if (!share && share_list != EGL_NO_CONTEXT) 443 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT); 444 445 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list); 446 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT; 447 448 RETURN_EGL_EVAL(disp, ret); 449} 450 451 452EGLBoolean EGLAPIENTRY 453eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 454{ 455 _EGLDisplay *disp = _eglLockDisplay(dpy); 456 _EGLContext *context = _eglLookupContext(ctx, disp); 457 _EGLDriver *drv; 458 EGLBoolean ret; 459 460 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); 461 _eglUnlinkContext(context); 462 ret = drv->API.DestroyContext(drv, disp, context); 463 464 RETURN_EGL_EVAL(disp, ret); 465} 466 467 468EGLBoolean EGLAPIENTRY 469eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, 470 EGLContext ctx) 471{ 472 _EGLDisplay *disp = _eglLockDisplay(dpy); 473 _EGLContext *context = _eglLookupContext(ctx, disp); 474 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); 475 _EGLSurface *read_surf = _eglLookupSurface(read, disp); 476 _EGLDriver *drv; 477 EGLBoolean ret; 478 479 if (!disp) 480 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); 481 drv = disp->Driver; 482 483 /* display is allowed to be uninitialized under certain condition */ 484 if (!disp->Initialized) { 485 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE || 486 ctx != EGL_NO_CONTEXT) 487 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); 488 } 489 if (!drv) 490 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 491 492 if (!context && ctx != EGL_NO_CONTEXT) 493 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 494 if (!draw_surf || !read_surf) { 495 /* surfaces may be NULL if surfaceless */ 496 if (!disp->Extensions.KHR_surfaceless_gles1 && 497 !disp->Extensions.KHR_surfaceless_gles2 && 498 !disp->Extensions.KHR_surfaceless_opengl) 499 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 500 501 if ((!draw_surf && draw != EGL_NO_SURFACE) || 502 (!read_surf && read != EGL_NO_SURFACE)) 503 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 504 if (draw_surf || read_surf) 505 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); 506 } 507 508 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); 509 510 RETURN_EGL_EVAL(disp, ret); 511} 512 513 514EGLBoolean EGLAPIENTRY 515eglQueryContext(EGLDisplay dpy, EGLContext ctx, 516 EGLint attribute, EGLint *value) 517{ 518 _EGLDisplay *disp = _eglLockDisplay(dpy); 519 _EGLContext *context = _eglLookupContext(ctx, disp); 520 _EGLDriver *drv; 521 EGLBoolean ret; 522 523 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); 524 ret = drv->API.QueryContext(drv, disp, context, attribute, value); 525 526 RETURN_EGL_EVAL(disp, ret); 527} 528 529 530EGLSurface EGLAPIENTRY 531eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, 532 EGLNativeWindowType window, const EGLint *attrib_list) 533{ 534 _EGLDisplay *disp = _eglLockDisplay(dpy); 535 _EGLConfig *conf = _eglLookupConfig(config, disp); 536 _EGLDriver *drv; 537 _EGLSurface *surf; 538 EGLSurface ret; 539 540 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 541 if (disp->Platform != _eglGetNativePlatform()) 542 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 543 544 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list); 545 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 546 547 RETURN_EGL_EVAL(disp, ret); 548} 549 550 551EGLSurface EGLAPIENTRY 552eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, 553 EGLNativePixmapType pixmap, const EGLint *attrib_list) 554{ 555 _EGLDisplay *disp = _eglLockDisplay(dpy); 556 _EGLConfig *conf = _eglLookupConfig(config, disp); 557 _EGLDriver *drv; 558 _EGLSurface *surf; 559 EGLSurface ret; 560 561 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 562 if (disp->Platform != _eglGetNativePlatform()) 563 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); 564 565 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list); 566 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 567 568 RETURN_EGL_EVAL(disp, ret); 569} 570 571 572EGLSurface EGLAPIENTRY 573eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, 574 const EGLint *attrib_list) 575{ 576 _EGLDisplay *disp = _eglLockDisplay(dpy); 577 _EGLConfig *conf = _eglLookupConfig(config, disp); 578 _EGLDriver *drv; 579 _EGLSurface *surf; 580 EGLSurface ret; 581 582 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 583 584 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); 585 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 586 587 RETURN_EGL_EVAL(disp, ret); 588} 589 590 591EGLBoolean EGLAPIENTRY 592eglDestroySurface(EGLDisplay dpy, EGLSurface surface) 593{ 594 _EGLDisplay *disp = _eglLockDisplay(dpy); 595 _EGLSurface *surf = _eglLookupSurface(surface, disp); 596 _EGLDriver *drv; 597 EGLBoolean ret; 598 599 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 600 _eglUnlinkSurface(surf); 601 ret = drv->API.DestroySurface(drv, disp, surf); 602 603 RETURN_EGL_EVAL(disp, ret); 604} 605 606EGLBoolean EGLAPIENTRY 607eglQuerySurface(EGLDisplay dpy, EGLSurface surface, 608 EGLint attribute, EGLint *value) 609{ 610 _EGLDisplay *disp = _eglLockDisplay(dpy); 611 _EGLSurface *surf = _eglLookupSurface(surface, disp); 612 _EGLDriver *drv; 613 EGLBoolean ret; 614 615 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 616 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value); 617 618 RETURN_EGL_EVAL(disp, ret); 619} 620 621EGLBoolean EGLAPIENTRY 622eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, 623 EGLint attribute, EGLint value) 624{ 625 _EGLDisplay *disp = _eglLockDisplay(dpy); 626 _EGLSurface *surf = _eglLookupSurface(surface, disp); 627 _EGLDriver *drv; 628 EGLBoolean ret; 629 630 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 631 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); 632 633 RETURN_EGL_EVAL(disp, ret); 634} 635 636 637EGLBoolean EGLAPIENTRY 638eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 639{ 640 _EGLDisplay *disp = _eglLockDisplay(dpy); 641 _EGLSurface *surf = _eglLookupSurface(surface, disp); 642 _EGLDriver *drv; 643 EGLBoolean ret; 644 645 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 646 ret = drv->API.BindTexImage(drv, disp, surf, buffer); 647 648 RETURN_EGL_EVAL(disp, ret); 649} 650 651 652EGLBoolean EGLAPIENTRY 653eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 654{ 655 _EGLDisplay *disp = _eglLockDisplay(dpy); 656 _EGLSurface *surf = _eglLookupSurface(surface, disp); 657 _EGLDriver *drv; 658 EGLBoolean ret; 659 660 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 661 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer); 662 663 RETURN_EGL_EVAL(disp, ret); 664} 665 666 667EGLBoolean EGLAPIENTRY 668eglSwapInterval(EGLDisplay dpy, EGLint interval) 669{ 670 _EGLDisplay *disp = _eglLockDisplay(dpy); 671 _EGLContext *ctx = _eglGetCurrentContext(); 672 _EGLSurface *surf; 673 _EGLDriver *drv; 674 EGLBoolean ret; 675 676 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 677 678 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 679 ctx->Resource.Display != disp) 680 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 681 682 surf = ctx->DrawSurface; 683 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE) 684 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 685 686 ret = drv->API.SwapInterval(drv, disp, surf, interval); 687 688 RETURN_EGL_EVAL(disp, ret); 689} 690 691 692EGLBoolean EGLAPIENTRY 693eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) 694{ 695 _EGLContext *ctx = _eglGetCurrentContext(); 696 _EGLDisplay *disp = _eglLockDisplay(dpy); 697 _EGLSurface *surf = _eglLookupSurface(surface, disp); 698 _EGLDriver *drv; 699 EGLBoolean ret; 700 701 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 702 703 /* surface must be bound to current context in EGL 1.4 */ 704 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 705 surf != ctx->DrawSurface) 706 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 707 708 ret = drv->API.SwapBuffers(drv, disp, surf); 709 710 RETURN_EGL_EVAL(disp, ret); 711} 712 713 714EGLBoolean EGLAPIENTRY 715eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) 716{ 717 _EGLDisplay *disp = _eglLockDisplay(dpy); 718 _EGLSurface *surf = _eglLookupSurface(surface, disp); 719 _EGLDriver *drv; 720 EGLBoolean ret; 721 722 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 723 if (disp->Platform != _eglGetNativePlatform()) 724 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE); 725 ret = drv->API.CopyBuffers(drv, disp, surf, target); 726 727 RETURN_EGL_EVAL(disp, ret); 728} 729 730 731EGLBoolean EGLAPIENTRY 732eglWaitClient(void) 733{ 734 _EGLContext *ctx = _eglGetCurrentContext(); 735 _EGLDisplay *disp; 736 _EGLDriver *drv; 737 EGLBoolean ret; 738 739 if (!ctx) 740 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 741 742 disp = ctx->Resource.Display; 743 _eglLockMutex(&disp->Mutex); 744 745 /* let bad current context imply bad current surface */ 746 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 747 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE) 748 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 749 750 /* a valid current context implies an initialized current display */ 751 assert(disp->Initialized); 752 drv = disp->Driver; 753 ret = drv->API.WaitClient(drv, disp, ctx); 754 755 RETURN_EGL_EVAL(disp, ret); 756} 757 758 759EGLBoolean EGLAPIENTRY 760eglWaitGL(void) 761{ 762#ifdef EGL_VERSION_1_2 763 _EGLThreadInfo *t = _eglGetCurrentThread(); 764 EGLint api_index = t->CurrentAPIIndex; 765 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API); 766 EGLBoolean ret; 767 768 if (api_index != es_index && _eglIsCurrentThreadDummy()) 769 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); 770 771 t->CurrentAPIIndex = es_index; 772 ret = eglWaitClient(); 773 t->CurrentAPIIndex = api_index; 774 return ret; 775#else 776 return eglWaitClient(); 777#endif 778} 779 780 781EGLBoolean EGLAPIENTRY 782eglWaitNative(EGLint engine) 783{ 784 _EGLContext *ctx = _eglGetCurrentContext(); 785 _EGLDisplay *disp; 786 _EGLDriver *drv; 787 EGLBoolean ret; 788 789 if (!ctx) 790 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 791 792 disp = ctx->Resource.Display; 793 _eglLockMutex(&disp->Mutex); 794 795 /* let bad current context imply bad current surface */ 796 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 797 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE) 798 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 799 800 /* a valid current context implies an initialized current display */ 801 assert(disp->Initialized); 802 drv = disp->Driver; 803 ret = drv->API.WaitNative(drv, disp, engine); 804 805 RETURN_EGL_EVAL(disp, ret); 806} 807 808 809EGLDisplay EGLAPIENTRY 810eglGetCurrentDisplay(void) 811{ 812 _EGLContext *ctx = _eglGetCurrentContext(); 813 EGLDisplay ret; 814 815 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; 816 817 RETURN_EGL_SUCCESS(NULL, ret); 818} 819 820 821EGLContext EGLAPIENTRY 822eglGetCurrentContext(void) 823{ 824 _EGLContext *ctx = _eglGetCurrentContext(); 825 EGLContext ret; 826 827 ret = _eglGetContextHandle(ctx); 828 829 RETURN_EGL_SUCCESS(NULL, ret); 830} 831 832 833EGLSurface EGLAPIENTRY 834eglGetCurrentSurface(EGLint readdraw) 835{ 836 _EGLContext *ctx = _eglGetCurrentContext(); 837 EGLint err = EGL_SUCCESS; 838 _EGLSurface *surf; 839 EGLSurface ret; 840 841 if (!ctx) 842 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE); 843 844 switch (readdraw) { 845 case EGL_DRAW: 846 surf = ctx->DrawSurface; 847 break; 848 case EGL_READ: 849 surf = ctx->ReadSurface; 850 break; 851 default: 852 surf = NULL; 853 err = EGL_BAD_PARAMETER; 854 break; 855 } 856 857 ret = _eglGetSurfaceHandle(surf); 858 859 RETURN_EGL_ERROR(NULL, err, ret); 860} 861 862 863EGLint EGLAPIENTRY 864eglGetError(void) 865{ 866 _EGLThreadInfo *t = _eglGetCurrentThread(); 867 EGLint e = t->LastError; 868 if (!_eglIsCurrentThreadDummy()) 869 t->LastError = EGL_SUCCESS; 870 return e; 871} 872 873 874__eglMustCastToProperFunctionPointerType EGLAPIENTRY 875eglGetProcAddress(const char *procname) 876{ 877 static const struct { 878 const char *name; 879 _EGLProc function; 880 } egl_functions[] = { 881 /* core functions should not be queryable, but, well... */ 882#ifdef _EGL_GET_CORE_ADDRESSES 883 /* alphabetical order */ 884 { "eglBindAPI", (_EGLProc) eglBindAPI }, 885 { "eglBindTexImage", (_EGLProc) eglBindTexImage }, 886 { "eglChooseConfig", (_EGLProc) eglChooseConfig }, 887 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, 888 { "eglCreateContext", (_EGLProc) eglCreateContext }, 889 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, 890 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, 891 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, 892 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, 893 { "eglDestroyContext", (_EGLProc) eglDestroyContext }, 894 { "eglDestroySurface", (_EGLProc) eglDestroySurface }, 895 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, 896 { "eglGetConfigs", (_EGLProc) eglGetConfigs }, 897 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, 898 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, 899 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, 900 { "eglGetDisplay", (_EGLProc) eglGetDisplay }, 901 { "eglGetError", (_EGLProc) eglGetError }, 902 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, 903 { "eglInitialize", (_EGLProc) eglInitialize }, 904 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, 905 { "eglQueryAPI", (_EGLProc) eglQueryAPI }, 906 { "eglQueryContext", (_EGLProc) eglQueryContext }, 907 { "eglQueryString", (_EGLProc) eglQueryString }, 908 { "eglQuerySurface", (_EGLProc) eglQuerySurface }, 909 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, 910 { "eglReleaseThread", (_EGLProc) eglReleaseThread }, 911 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, 912 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, 913 { "eglSwapInterval", (_EGLProc) eglSwapInterval }, 914 { "eglTerminate", (_EGLProc) eglTerminate }, 915 { "eglWaitClient", (_EGLProc) eglWaitClient }, 916 { "eglWaitGL", (_EGLProc) eglWaitGL }, 917 { "eglWaitNative", (_EGLProc) eglWaitNative }, 918#endif /* _EGL_GET_CORE_ADDRESSES */ 919#ifdef EGL_MESA_screen_surface 920 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, 921 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, 922 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA }, 923 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA }, 924 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA }, 925 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA }, 926 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA }, 927 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA }, 928 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA }, 929 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA }, 930 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, 931 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, 932#endif /* EGL_MESA_screen_surface */ 933#ifdef EGL_MESA_drm_display 934 { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, 935#endif 936#ifdef EGL_KHR_image_base 937 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, 938 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, 939#endif /* EGL_KHR_image_base */ 940#ifdef EGL_NOK_swap_region 941 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, 942#endif 943#ifdef EGL_MESA_drm_image 944 { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, 945 { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, 946#endif 947#ifdef EGL_WL_bind_wayland_display 948 { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL }, 949 { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL }, 950#endif 951 { NULL, NULL } 952 }; 953 EGLint i; 954 _EGLProc ret; 955 956 if (!procname) 957 RETURN_EGL_SUCCESS(NULL, NULL); 958 959 ret = NULL; 960 if (strncmp(procname, "egl", 3) == 0) { 961 for (i = 0; egl_functions[i].name; i++) { 962 if (strcmp(egl_functions[i].name, procname) == 0) { 963 ret = egl_functions[i].function; 964 break; 965 } 966 } 967 } 968 if (!ret) 969 ret = _eglGetDriverProc(procname); 970 971 RETURN_EGL_SUCCESS(NULL, ret); 972} 973 974 975#ifdef EGL_MESA_screen_surface 976 977 978/* 979 * EGL_MESA_screen extension 980 */ 981 982EGLBoolean EGLAPIENTRY 983eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, 984 const EGLint *attrib_list, EGLModeMESA *modes, 985 EGLint modes_size, EGLint *num_modes) 986{ 987 _EGLDisplay *disp = _eglLockDisplay(dpy); 988 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 989 _EGLDriver *drv; 990 EGLBoolean ret; 991 992 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 993 ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, 994 modes, modes_size, num_modes); 995 996 RETURN_EGL_EVAL(disp, ret); 997} 998 999 1000EGLBoolean EGLAPIENTRY 1001eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, 1002 EGLint mode_size, EGLint *num_mode) 1003{ 1004 _EGLDisplay *disp = _eglLockDisplay(dpy); 1005 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 1006 _EGLDriver *drv; 1007 EGLBoolean ret; 1008 1009 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1010 ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); 1011 1012 RETURN_EGL_EVAL(disp, ret); 1013} 1014 1015 1016EGLBoolean EGLAPIENTRY 1017eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, 1018 EGLint attribute, EGLint *value) 1019{ 1020 _EGLDisplay *disp = _eglLockDisplay(dpy); 1021 _EGLMode *m = _eglLookupMode(mode, disp); 1022 _EGLDriver *drv; 1023 EGLBoolean ret; 1024 1025 _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv); 1026 ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); 1027 1028 RETURN_EGL_EVAL(disp, ret); 1029} 1030 1031 1032EGLBoolean EGLAPIENTRY 1033eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, 1034 EGLint mask) 1035{ 1036 _EGLDisplay *disp = _eglLockDisplay(dpy); 1037 _EGLContext *source_context = _eglLookupContext(source, disp); 1038 _EGLContext *dest_context = _eglLookupContext(dest, disp); 1039 _EGLDriver *drv; 1040 EGLBoolean ret; 1041 1042 _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv); 1043 if (!dest_context) 1044 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 1045 1046 ret = drv->API.CopyContextMESA(drv, disp, 1047 source_context, dest_context, mask); 1048 1049 RETURN_EGL_EVAL(disp, ret); 1050} 1051 1052 1053EGLBoolean EGLAPIENTRY 1054eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, 1055 EGLint max_screens, EGLint *num_screens) 1056{ 1057 _EGLDisplay *disp = _eglLockDisplay(dpy); 1058 _EGLDriver *drv; 1059 EGLBoolean ret; 1060 1061 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1062 ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens); 1063 1064 RETURN_EGL_EVAL(disp, ret); 1065} 1066 1067 1068EGLSurface EGLAPIENTRY 1069eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, 1070 const EGLint *attrib_list) 1071{ 1072 _EGLDisplay *disp = _eglLockDisplay(dpy); 1073 _EGLConfig *conf = _eglLookupConfig(config, disp); 1074 _EGLDriver *drv; 1075 _EGLSurface *surf; 1076 EGLSurface ret; 1077 1078 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 1079 1080 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); 1081 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 1082 1083 RETURN_EGL_EVAL(disp, ret); 1084} 1085 1086 1087EGLBoolean EGLAPIENTRY 1088eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, 1089 EGLSurface surface, EGLModeMESA mode) 1090{ 1091 _EGLDisplay *disp = _eglLockDisplay(dpy); 1092 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 1093 _EGLSurface *surf = _eglLookupSurface(surface, disp); 1094 _EGLMode *m = _eglLookupMode(mode, disp); 1095 _EGLDriver *drv; 1096 EGLBoolean ret; 1097 1098 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1099 if (!surf && surface != EGL_NO_SURFACE) 1100 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 1101 if (!m && mode != EGL_NO_MODE_MESA) 1102 RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE); 1103 1104 ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); 1105 1106 RETURN_EGL_EVAL(disp, ret); 1107} 1108 1109 1110EGLBoolean EGLAPIENTRY 1111eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) 1112{ 1113 _EGLDisplay *disp = _eglLockDisplay(dpy); 1114 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 1115 _EGLDriver *drv; 1116 EGLBoolean ret; 1117 1118 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1119 ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); 1120 1121 RETURN_EGL_EVAL(disp, ret); 1122} 1123 1124 1125EGLBoolean EGLAPIENTRY 1126eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, 1127 EGLint attribute, EGLint *value) 1128{ 1129 _EGLDisplay *disp = _eglLockDisplay(dpy); 1130 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 1131 _EGLDriver *drv; 1132 EGLBoolean ret; 1133 1134 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1135 ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); 1136 1137 RETURN_EGL_EVAL(disp, ret); 1138} 1139 1140 1141EGLBoolean EGLAPIENTRY 1142eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, 1143 EGLSurface *surface) 1144{ 1145 _EGLDisplay *disp = _eglLockDisplay(dpy); 1146 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 1147 _EGLDriver *drv; 1148 _EGLSurface *surf; 1149 EGLBoolean ret; 1150 1151 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1152 ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf); 1153 if (ret && surface) 1154 *surface = _eglGetSurfaceHandle(surf); 1155 1156 RETURN_EGL_EVAL(disp, ret); 1157} 1158 1159 1160EGLBoolean EGLAPIENTRY 1161eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) 1162{ 1163 _EGLDisplay *disp = _eglLockDisplay(dpy); 1164 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 1165 _EGLDriver *drv; 1166 _EGLMode *m; 1167 EGLBoolean ret; 1168 1169 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1170 ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m); 1171 if (ret && mode) 1172 *mode = m->Handle; 1173 1174 RETURN_EGL_EVAL(disp, ret); 1175} 1176 1177 1178const char * EGLAPIENTRY 1179eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) 1180{ 1181 _EGLDisplay *disp = _eglLockDisplay(dpy); 1182 _EGLMode *m = _eglLookupMode(mode, disp); 1183 _EGLDriver *drv; 1184 const char *ret; 1185 1186 _EGL_CHECK_MODE(disp, m, NULL, drv); 1187 ret = drv->API.QueryModeStringMESA(drv, disp, m); 1188 1189 RETURN_EGL_EVAL(disp, ret); 1190} 1191 1192 1193#endif /* EGL_MESA_screen_surface */ 1194 1195 1196#ifdef EGL_MESA_drm_display 1197 1198EGLDisplay EGLAPIENTRY 1199eglGetDRMDisplayMESA(int fd) 1200{ 1201 _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd); 1202 return _eglGetDisplayHandle(dpy); 1203} 1204 1205#endif /* EGL_MESA_drm_display */ 1206 1207/** 1208 ** EGL 1.2 1209 **/ 1210 1211#ifdef EGL_VERSION_1_2 1212 1213 1214/** 1215 * Specify the client API to use for subsequent calls including: 1216 * eglCreateContext() 1217 * eglGetCurrentContext() 1218 * eglGetCurrentDisplay() 1219 * eglGetCurrentSurface() 1220 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT) 1221 * eglWaitClient() 1222 * eglWaitNative() 1223 * See section 3.7 "Rendering Context" in the EGL specification for details. 1224 */ 1225EGLBoolean EGLAPIENTRY 1226eglBindAPI(EGLenum api) 1227{ 1228 _EGLThreadInfo *t = _eglGetCurrentThread(); 1229 1230 if (_eglIsCurrentThreadDummy()) 1231 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); 1232 1233 if (!_eglIsApiValid(api)) 1234 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); 1235 1236 t->CurrentAPIIndex = _eglConvertApiToIndex(api); 1237 1238 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1239} 1240 1241 1242/** 1243 * Return the last value set with eglBindAPI(). 1244 */ 1245EGLenum EGLAPIENTRY 1246eglQueryAPI(void) 1247{ 1248 _EGLThreadInfo *t = _eglGetCurrentThread(); 1249 EGLenum ret; 1250 1251 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ 1252 ret = _eglConvertApiFromIndex(t->CurrentAPIIndex); 1253 1254 RETURN_EGL_SUCCESS(NULL, ret); 1255} 1256 1257 1258EGLSurface EGLAPIENTRY 1259eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, 1260 EGLClientBuffer buffer, EGLConfig config, 1261 const EGLint *attrib_list) 1262{ 1263 _EGLDisplay *disp = _eglLockDisplay(dpy); 1264 _EGLConfig *conf = _eglLookupConfig(config, disp); 1265 _EGLDriver *drv; 1266 _EGLSurface *surf; 1267 EGLSurface ret; 1268 1269 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 1270 1271 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, 1272 conf, attrib_list); 1273 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 1274 1275 RETURN_EGL_EVAL(disp, ret); 1276} 1277 1278 1279EGLBoolean EGLAPIENTRY 1280eglReleaseThread(void) 1281{ 1282 /* unbind current contexts */ 1283 if (!_eglIsCurrentThreadDummy()) { 1284 _EGLThreadInfo *t = _eglGetCurrentThread(); 1285 EGLint api_index = t->CurrentAPIIndex; 1286 EGLint i; 1287 1288 for (i = 0; i < _EGL_API_NUM_APIS; i++) { 1289 _EGLContext *ctx = t->CurrentContexts[i]; 1290 if (ctx) { 1291 _EGLDisplay *disp = ctx->Resource.Display; 1292 _EGLDriver *drv; 1293 1294 t->CurrentAPIIndex = i; 1295 1296 _eglLockMutex(&disp->Mutex); 1297 drv = disp->Driver; 1298 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); 1299 _eglUnlockMutex(&disp->Mutex); 1300 } 1301 } 1302 1303 t->CurrentAPIIndex = api_index; 1304 } 1305 1306 _eglDestroyCurrentThread(); 1307 1308 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1309} 1310 1311 1312#endif /* EGL_VERSION_1_2 */ 1313 1314 1315#ifdef EGL_KHR_image_base 1316 1317 1318EGLImageKHR EGLAPIENTRY 1319eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, 1320 EGLClientBuffer buffer, const EGLint *attr_list) 1321{ 1322 _EGLDisplay *disp = _eglLockDisplay(dpy); 1323 _EGLContext *context = _eglLookupContext(ctx, disp); 1324 _EGLDriver *drv; 1325 _EGLImage *img; 1326 EGLImageKHR ret; 1327 1328 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); 1329 if (!disp->Extensions.KHR_image_base) 1330 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); 1331 if (!context && ctx != EGL_NO_CONTEXT) 1332 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); 1333 1334 img = drv->API.CreateImageKHR(drv, 1335 disp, context, target, buffer, attr_list); 1336 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; 1337 1338 RETURN_EGL_EVAL(disp, ret); 1339} 1340 1341 1342EGLBoolean EGLAPIENTRY 1343eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) 1344{ 1345 _EGLDisplay *disp = _eglLockDisplay(dpy); 1346 _EGLImage *img = _eglLookupImage(image, disp); 1347 _EGLDriver *drv; 1348 EGLBoolean ret; 1349 1350 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1351 if (!disp->Extensions.KHR_image_base) 1352 RETURN_EGL_EVAL(disp, EGL_FALSE); 1353 if (!img) 1354 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1355 1356 _eglUnlinkImage(img); 1357 ret = drv->API.DestroyImageKHR(drv, disp, img); 1358 1359 RETURN_EGL_EVAL(disp, ret); 1360} 1361 1362 1363#endif /* EGL_KHR_image_base */ 1364 1365 1366#ifdef EGL_KHR_reusable_sync 1367 1368 1369EGLSyncKHR EGLAPIENTRY 1370eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) 1371{ 1372 _EGLDisplay *disp = _eglLockDisplay(dpy); 1373 _EGLDriver *drv; 1374 _EGLSync *sync; 1375 EGLSyncKHR ret; 1376 1377 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv); 1378 if (!disp->Extensions.KHR_reusable_sync) 1379 RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR); 1380 1381 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list); 1382 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR; 1383 1384 RETURN_EGL_EVAL(disp, ret); 1385} 1386 1387 1388EGLBoolean EGLAPIENTRY 1389eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) 1390{ 1391 _EGLDisplay *disp = _eglLockDisplay(dpy); 1392 _EGLSync *s = _eglLookupSync(sync, disp); 1393 _EGLDriver *drv; 1394 EGLBoolean ret; 1395 1396 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); 1397 assert(disp->Extensions.KHR_reusable_sync); 1398 1399 _eglUnlinkSync(s); 1400 ret = drv->API.DestroySyncKHR(drv, disp, s); 1401 1402 RETURN_EGL_EVAL(disp, ret); 1403} 1404 1405 1406EGLint EGLAPIENTRY 1407eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) 1408{ 1409 _EGLDisplay *disp = _eglLockDisplay(dpy); 1410 _EGLSync *s = _eglLookupSync(sync, disp); 1411 _EGLDriver *drv; 1412 EGLint ret; 1413 1414 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); 1415 assert(disp->Extensions.KHR_reusable_sync); 1416 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout); 1417 1418 RETURN_EGL_EVAL(disp, ret); 1419} 1420 1421 1422EGLBoolean EGLAPIENTRY 1423eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) 1424{ 1425 _EGLDisplay *disp = _eglLockDisplay(dpy); 1426 _EGLSync *s = _eglLookupSync(sync, disp); 1427 _EGLDriver *drv; 1428 EGLBoolean ret; 1429 1430 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); 1431 assert(disp->Extensions.KHR_reusable_sync); 1432 ret = drv->API.SignalSyncKHR(drv, disp, s, mode); 1433 1434 RETURN_EGL_EVAL(disp, ret); 1435} 1436 1437 1438EGLBoolean EGLAPIENTRY 1439eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) 1440{ 1441 _EGLDisplay *disp = _eglLockDisplay(dpy); 1442 _EGLSync *s = _eglLookupSync(sync, disp); 1443 _EGLDriver *drv; 1444 EGLBoolean ret; 1445 1446 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); 1447 assert(disp->Extensions.KHR_reusable_sync); 1448 ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value); 1449 1450 RETURN_EGL_EVAL(disp, ret); 1451} 1452 1453 1454#endif /* EGL_KHR_reusable_sync */ 1455 1456 1457#ifdef EGL_NOK_swap_region 1458 1459EGLBoolean EGLAPIENTRY 1460eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, 1461 EGLint numRects, const EGLint *rects) 1462{ 1463 _EGLContext *ctx = _eglGetCurrentContext(); 1464 _EGLDisplay *disp = _eglLockDisplay(dpy); 1465 _EGLSurface *surf = _eglLookupSurface(surface, disp); 1466 _EGLDriver *drv; 1467 EGLBoolean ret; 1468 1469 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 1470 1471 if (!disp->Extensions.NOK_swap_region) 1472 RETURN_EGL_EVAL(disp, EGL_FALSE); 1473 1474 /* surface must be bound to current context in EGL 1.4 */ 1475 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 1476 surf != ctx->DrawSurface) 1477 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 1478 1479 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects); 1480 1481 RETURN_EGL_EVAL(disp, ret); 1482} 1483 1484#endif /* EGL_NOK_swap_region */ 1485 1486 1487#ifdef EGL_MESA_drm_image 1488 1489EGLImageKHR EGLAPIENTRY 1490eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) 1491{ 1492 _EGLDisplay *disp = _eglLockDisplay(dpy); 1493 _EGLDriver *drv; 1494 _EGLImage *img; 1495 EGLImageKHR ret; 1496 1497 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); 1498 if (!disp->Extensions.MESA_drm_image) 1499 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); 1500 1501 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list); 1502 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; 1503 1504 RETURN_EGL_EVAL(disp, ret); 1505} 1506 1507EGLBoolean EGLAPIENTRY 1508eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, 1509 EGLint *name, EGLint *handle, EGLint *stride) 1510{ 1511 _EGLDisplay *disp = _eglLockDisplay(dpy); 1512 _EGLImage *img = _eglLookupImage(image, disp); 1513 _EGLDriver *drv; 1514 EGLBoolean ret; 1515 1516 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1517 assert(disp->Extensions.MESA_drm_image); 1518 1519 if (!img) 1520 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1521 1522 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride); 1523 1524 RETURN_EGL_EVAL(disp, ret); 1525} 1526 1527#endif 1528 1529#ifdef EGL_WL_bind_wayland_display 1530struct wl_display; 1531 1532EGLBoolean EGLAPIENTRY 1533eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) 1534{ 1535 _EGLDisplay *disp = _eglLockDisplay(dpy); 1536 _EGLDriver *drv; 1537 EGLBoolean ret; 1538 1539 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1540 assert(disp->Extensions.WL_bind_wayland_display); 1541 1542 if (!display) 1543 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1544 1545 ret = drv->API.BindWaylandDisplayWL(drv, disp, display); 1546 1547 RETURN_EGL_EVAL(disp, ret); 1548} 1549 1550EGLBoolean EGLAPIENTRY 1551eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) 1552{ 1553 _EGLDisplay *disp = _eglLockDisplay(dpy); 1554 _EGLDriver *drv; 1555 EGLBoolean ret; 1556 1557 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1558 assert(disp->Extensions.WL_bind_wayland_display); 1559 1560 if (!display) 1561 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1562 1563 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display); 1564 1565 RETURN_EGL_EVAL(disp, ret); 1566} 1567#endif 1568