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