eglapi.c revision a933259daa98615ad7473c53623a96f612e9a311
1/** 2 * Public EGL API entrypoints 3 * 4 * Generally, we use the EGLDisplay parameter as a key to lookup the 5 * appropriate device driver handle, then jump though the driver's 6 * dispatch table to handle the function. 7 * 8 * That allows us the option of supporting multiple, simultaneous, 9 * heterogeneous hardware devices in the future. 10 * 11 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are 12 * opaque handles. Internal objects are linked to a display to 13 * create the handles. 14 * 15 * For each public API entry point, the opaque handles are looked up 16 * before being dispatched to the drivers. When it fails to look up 17 * a handle, one of 18 * 19 * EGL_BAD_DISPLAY 20 * EGL_BAD_CONFIG 21 * EGL_BAD_CONTEXT 22 * EGL_BAD_SURFACE 23 * EGL_BAD_SCREEN_MESA 24 * EGL_BAD_MODE_MESA 25 * 26 * is generated and the driver function is not called. An 27 * uninitialized EGLDisplay has no driver associated with it. When 28 * such display is detected, 29 * 30 * EGL_NOT_INITIALIZED 31 * 32 * is generated. 33 * 34 * Some of the entry points use current display, context, or surface 35 * implicitly. For such entry points, the implicit objects are also 36 * checked before calling the driver function. Other than the 37 * errors listed above, 38 * 39 * EGL_BAD_CURRENT_SURFACE 40 * 41 * may also be generated. 42 * 43 * Notes on naming conventions: 44 * 45 * eglFooBar - public EGL function 46 * EGL_FOO_BAR - public EGL token 47 * EGLDatatype - public EGL datatype 48 * 49 * _eglFooBar - private EGL function 50 * _EGLDatatype - private EGL datatype, typedef'd struct 51 * _egl_struct - private EGL struct, non-typedef'd 52 * 53 */ 54 55 56#include <stdio.h> 57#include <stdlib.h> 58#include <string.h> 59#include "eglcontext.h" 60#include "egldisplay.h" 61#include "egltypedefs.h" 62#include "eglglobals.h" 63#include "egldriver.h" 64#include "eglsurface.h" 65#include "eglconfig.h" 66#include "eglscreen.h" 67#include "eglmode.h" 68#include "eglimage.h" 69 70 71/** 72 * This is typically the first EGL function that an application calls. 73 * We initialize our global vars and create a private _EGLDisplay object. 74 */ 75EGLDisplay EGLAPIENTRY 76eglGetDisplay(EGLNativeDisplayType nativeDisplay) 77{ 78 _EGLDisplay *dpy; 79 dpy = _eglFindDisplay(nativeDisplay); 80 if (!dpy) { 81 dpy = _eglNewDisplay(nativeDisplay); 82 if (dpy) 83 _eglLinkDisplay(dpy); 84 } 85 return _eglGetDisplayHandle(dpy); 86} 87 88 89/** 90 * This is typically the second EGL function that an application calls. 91 * Here we load/initialize the actual hardware driver. 92 */ 93EGLBoolean EGLAPIENTRY 94eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 95{ 96 _EGLDisplay *disp = _eglLookupDisplay(dpy); 97 EGLint major_int, minor_int; 98 99 if (!disp) 100 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); 101 102 if (!disp->Initialized) { 103 _EGLDriver *drv = disp->Driver; 104 105 if (!drv) { 106 _eglPreloadDrivers(); 107 drv = _eglMatchDriver(disp); 108 if (!drv) 109 return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); 110 } 111 112 /* Initialize the particular display now */ 113 if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) 114 return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); 115 116 disp->APImajor = major_int; 117 disp->APIminor = minor_int; 118 snprintf(disp->Version, sizeof(disp->Version), 119 "%d.%d (%s)", major_int, minor_int, drv->Name); 120 121 /* limit to APIs supported by core */ 122 disp->ClientAPIsMask &= _EGL_API_ALL_BITS; 123 124 disp->Driver = drv; 125 disp->Initialized = EGL_TRUE; 126 } else { 127 major_int = disp->APImajor; 128 minor_int = disp->APIminor; 129 } 130 131 /* Update applications version of major and minor if not NULL */ 132 if ((major != NULL) && (minor != NULL)) { 133 *major = major_int; 134 *minor = minor_int; 135 } 136 137 return EGL_TRUE; 138} 139 140 141EGLBoolean EGLAPIENTRY 142eglTerminate(EGLDisplay dpy) 143{ 144 _EGLDisplay *disp = _eglLookupDisplay(dpy); 145 146 if (!disp) 147 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); 148 149 if (disp->Initialized) { 150 _EGLDriver *drv = disp->Driver; 151 152 drv->API.Terminate(drv, disp); 153 /* do not reset disp->Driver */ 154 disp->Initialized = EGL_FALSE; 155 } 156 157 return EGL_TRUE; 158} 159 160 161/** 162 * A bunch of check functions and declare macros to simply error checking. 163 */ 164static INLINE _EGLDriver * 165_eglCheckDisplay(_EGLDisplay *disp, const char *msg) 166{ 167 if (!disp) { 168 _eglError(EGL_BAD_DISPLAY, msg); 169 return NULL; 170 } 171 if (!disp->Initialized) { 172 _eglError(EGL_NOT_INITIALIZED, msg); 173 return NULL; 174 } 175 return disp->Driver; 176} 177 178 179static INLINE _EGLDriver * 180_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg) 181{ 182 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 183 if (!drv) 184 return NULL; 185 if (!surf) { 186 _eglError(EGL_BAD_SURFACE, msg); 187 return NULL; 188 } 189 return drv; 190} 191 192 193static INLINE _EGLDriver * 194_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg) 195{ 196 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 197 if (!drv) 198 return NULL; 199 if (!context) { 200 _eglError(EGL_BAD_CONTEXT, msg); 201 return NULL; 202 } 203 return drv; 204} 205 206 207static INLINE _EGLDriver * 208_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) 209{ 210 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 211 if (!drv) 212 return NULL; 213 if (!conf) { 214 _eglError(EGL_BAD_CONFIG, msg); 215 return NULL; 216 } 217 return drv; 218} 219 220 221#define _EGL_DECLARE_DD(dpy) \ 222 _EGLDisplay *disp = _eglLookupDisplay(dpy); \ 223 _EGLDriver *drv; \ 224 do { \ 225 drv = _eglCheckDisplay(disp, __FUNCTION__); \ 226 if (!drv) \ 227 return EGL_FALSE; \ 228 } while (0) 229 230 231#define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \ 232 _EGLDisplay *disp = _eglLookupDisplay(dpy); \ 233 _EGLSurface *surf = _eglLookupSurface((surface), disp); \ 234 _EGLDriver *drv; \ 235 do { \ 236 drv = _eglCheckSurface(disp, surf, __FUNCTION__); \ 237 if (!drv) \ 238 return EGL_FALSE; \ 239 } while (0) 240 241 242#define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \ 243 _EGLDisplay *disp = _eglLookupDisplay(dpy); \ 244 _EGLContext *context = _eglLookupContext((ctx), disp); \ 245 _EGLDriver *drv; \ 246 do { \ 247 drv = _eglCheckContext(disp, context, __FUNCTION__); \ 248 if (!drv) \ 249 return EGL_FALSE; \ 250 } while (0) 251 252 253#ifdef EGL_MESA_screen_surface 254 255 256static INLINE _EGLDriver * 257_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg) 258{ 259 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 260 if (!drv) 261 return NULL; 262 if (!scrn) { 263 _eglError(EGL_BAD_SCREEN_MESA, msg); 264 return NULL; 265 } 266 return drv; 267} 268 269 270static INLINE _EGLDriver * 271_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) 272{ 273 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 274 if (!drv) 275 return NULL; 276 if (!m) { 277 _eglError(EGL_BAD_MODE_MESA, msg); 278 return NULL; 279 } 280 return drv; 281} 282 283 284#define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \ 285 _EGLDisplay *disp = _eglLookupDisplay(dpy); \ 286 _EGLScreen *scrn = _eglLookupScreen((screen), disp); \ 287 _EGLDriver *drv; \ 288 do { \ 289 drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \ 290 if (!drv) \ 291 return EGL_FALSE; \ 292 } while (0) 293 294 295#define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \ 296 _EGLDisplay *disp = _eglLookupDisplay(dpy); \ 297 _EGLMode *m = _eglLookupMode((mode), disp); \ 298 _EGLDriver *drv; \ 299 do { \ 300 drv = _eglCheckMode(disp, m, __FUNCTION__); \ 301 if (!drv) \ 302 return EGL_FALSE; \ 303 } while (0) 304 305 306#endif /* EGL_MESA_screen_surface */ 307 308 309const char * EGLAPIENTRY 310eglQueryString(EGLDisplay dpy, EGLint name) 311{ 312 _EGL_DECLARE_DD(dpy); 313 return drv->API.QueryString(drv, disp, name); 314} 315 316 317EGLBoolean EGLAPIENTRY 318eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, 319 EGLint config_size, EGLint *num_config) 320{ 321 _EGL_DECLARE_DD(dpy); 322 return drv->API.GetConfigs(drv, disp, configs, config_size, num_config); 323} 324 325 326EGLBoolean EGLAPIENTRY 327eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, 328 EGLint config_size, EGLint *num_config) 329{ 330 _EGL_DECLARE_DD(dpy); 331 return drv->API.ChooseConfig(drv, disp, attrib_list, configs, 332 config_size, num_config); 333} 334 335 336EGLBoolean EGLAPIENTRY 337eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, 338 EGLint attribute, EGLint *value) 339{ 340 _EGLDisplay *disp = _eglLookupDisplay(dpy); 341 _EGLConfig *conf = _eglLookupConfig(config, disp); 342 _EGLDriver *drv; 343 344 drv = _eglCheckConfig(disp, conf, __FUNCTION__); 345 if (!drv) 346 return EGL_FALSE; 347 348 return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); 349} 350 351 352EGLContext EGLAPIENTRY 353eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, 354 const EGLint *attrib_list) 355{ 356 _EGLDisplay *disp = _eglLookupDisplay(dpy); 357 _EGLConfig *conf = _eglLookupConfig(config, disp); 358 _EGLContext *share = _eglLookupContext(share_list, disp); 359 _EGLDriver *drv; 360 _EGLContext *context; 361 362 drv = _eglCheckConfig(disp, conf, __FUNCTION__); 363 if (!drv) 364 return EGL_NO_CONTEXT; 365 if (!share && share_list != EGL_NO_CONTEXT) { 366 _eglError(EGL_BAD_CONTEXT, __FUNCTION__); 367 return EGL_NO_CONTEXT; 368 } 369 370 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list); 371 if (context) 372 return _eglLinkContext(context, disp); 373 else 374 return EGL_NO_CONTEXT; 375} 376 377 378EGLBoolean EGLAPIENTRY 379eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 380{ 381 _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx); 382 _eglUnlinkContext(context); 383 return drv->API.DestroyContext(drv, disp, context); 384} 385 386 387EGLBoolean EGLAPIENTRY 388eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, 389 EGLContext ctx) 390{ 391 _EGLDisplay *disp = _eglLookupDisplay(dpy); 392 _EGLContext *context = _eglLookupContext(ctx, disp); 393 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); 394 _EGLSurface *read_surf = _eglLookupSurface(read, disp); 395 _EGLDriver *drv; 396 397 drv = _eglCheckDisplay(disp, __FUNCTION__); 398 if (!drv) 399 return EGL_FALSE; 400 if (!context && ctx != EGL_NO_CONTEXT) 401 return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); 402 if ((!draw_surf && draw != EGL_NO_SURFACE) || 403 (!read_surf && read != EGL_NO_SURFACE)) 404 return _eglError(EGL_BAD_SURFACE, __FUNCTION__); 405 406 return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); 407} 408 409 410EGLBoolean EGLAPIENTRY 411eglQueryContext(EGLDisplay dpy, EGLContext ctx, 412 EGLint attribute, EGLint *value) 413{ 414 _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx); 415 return drv->API.QueryContext(drv, disp, context, attribute, value); 416} 417 418 419EGLSurface EGLAPIENTRY 420eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, 421 EGLNativeWindowType window, const EGLint *attrib_list) 422{ 423 _EGLDisplay *disp = _eglLookupDisplay(dpy); 424 _EGLConfig *conf = _eglLookupConfig(config, disp); 425 _EGLDriver *drv; 426 _EGLSurface *surf; 427 428 drv = _eglCheckConfig(disp, conf, __FUNCTION__); 429 if (!drv) 430 return EGL_NO_SURFACE; 431 432 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list); 433 if (surf) 434 return _eglLinkSurface(surf, disp); 435 else 436 return EGL_NO_SURFACE; 437} 438 439 440EGLSurface EGLAPIENTRY 441eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, 442 EGLNativePixmapType pixmap, const EGLint *attrib_list) 443{ 444 _EGLDisplay *disp = _eglLookupDisplay(dpy); 445 _EGLConfig *conf = _eglLookupConfig(config, disp); 446 _EGLDriver *drv; 447 _EGLSurface *surf; 448 449 drv = _eglCheckConfig(disp, conf, __FUNCTION__); 450 if (!drv) 451 return EGL_NO_SURFACE; 452 453 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list); 454 if (surf) 455 return _eglLinkSurface(surf, disp); 456 else 457 return EGL_NO_SURFACE; 458} 459 460 461EGLSurface EGLAPIENTRY 462eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, 463 const EGLint *attrib_list) 464{ 465 _EGLDisplay *disp = _eglLookupDisplay(dpy); 466 _EGLConfig *conf = _eglLookupConfig(config, disp); 467 _EGLDriver *drv; 468 _EGLSurface *surf; 469 470 drv = _eglCheckConfig(disp, conf, __FUNCTION__); 471 if (!drv) 472 return EGL_NO_SURFACE; 473 474 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); 475 if (surf) 476 return _eglLinkSurface(surf, disp); 477 else 478 return EGL_NO_SURFACE; 479} 480 481 482EGLBoolean EGLAPIENTRY 483eglDestroySurface(EGLDisplay dpy, EGLSurface surface) 484{ 485 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); 486 _eglUnlinkSurface(surf); 487 return drv->API.DestroySurface(drv, disp, surf); 488} 489 490EGLBoolean EGLAPIENTRY 491eglQuerySurface(EGLDisplay dpy, EGLSurface surface, 492 EGLint attribute, EGLint *value) 493{ 494 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); 495 return drv->API.QuerySurface(drv, disp, surf, attribute, value); 496} 497 498EGLBoolean EGLAPIENTRY 499eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, 500 EGLint attribute, EGLint value) 501{ 502 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); 503 return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); 504} 505 506 507EGLBoolean EGLAPIENTRY 508eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 509{ 510 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); 511 return drv->API.BindTexImage(drv, disp, surf, buffer); 512} 513 514 515EGLBoolean EGLAPIENTRY 516eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 517{ 518 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); 519 return drv->API.ReleaseTexImage(drv, disp, surf, buffer); 520} 521 522 523EGLBoolean EGLAPIENTRY 524eglSwapInterval(EGLDisplay dpy, EGLint interval) 525{ 526 _EGLContext *ctx = _eglGetCurrentContext(); 527 _EGLSurface *surf; 528 _EGL_DECLARE_DD(dpy); 529 530 if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp) 531 return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); 532 533 surf = ctx->DrawSurface; 534 if (!_eglIsSurfaceLinked(surf)) 535 return _eglError(EGL_BAD_SURFACE, __FUNCTION__); 536 537 return drv->API.SwapInterval(drv, disp, surf, interval); 538} 539 540 541EGLBoolean EGLAPIENTRY 542eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) 543{ 544 _EGLContext *ctx = _eglGetCurrentContext(); 545 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); 546 547 /* surface must be bound to current context in EGL 1.4 */ 548 if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface) 549 return _eglError(EGL_BAD_SURFACE, __FUNCTION__); 550 551 return drv->API.SwapBuffers(drv, disp, surf); 552} 553 554 555EGLBoolean EGLAPIENTRY 556eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) 557{ 558 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); 559 return drv->API.CopyBuffers(drv, disp, surf, target); 560} 561 562 563EGLBoolean EGLAPIENTRY 564eglWaitClient(void) 565{ 566 _EGLContext *ctx = _eglGetCurrentContext(); 567 _EGLDisplay *disp; 568 _EGLDriver *drv; 569 570 if (!ctx) 571 return EGL_TRUE; 572 /* let bad current context imply bad current surface */ 573 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) 574 return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); 575 576 /* a valid current context implies an initialized current display */ 577 disp = ctx->Resource.Display; 578 assert(disp->Initialized); 579 drv = disp->Driver; 580 581 return drv->API.WaitClient(drv, disp, ctx); 582} 583 584 585EGLBoolean EGLAPIENTRY 586eglWaitGL(void) 587{ 588#ifdef EGL_VERSION_1_2 589 _EGLThreadInfo *t = _eglGetCurrentThread(); 590 EGLint api_index = t->CurrentAPIIndex; 591 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API); 592 EGLBoolean ret; 593 594 if (api_index != es_index && _eglIsCurrentThreadDummy()) 595 return _eglError(EGL_BAD_ALLOC, "eglWaitGL"); 596 597 t->CurrentAPIIndex = es_index; 598 ret = eglWaitClient(); 599 t->CurrentAPIIndex = api_index; 600 return ret; 601#else 602 return eglWaitClient(); 603#endif 604} 605 606 607EGLBoolean EGLAPIENTRY 608eglWaitNative(EGLint engine) 609{ 610 _EGLContext *ctx = _eglGetCurrentContext(); 611 _EGLDisplay *disp; 612 _EGLDriver *drv; 613 614 if (!ctx) 615 return EGL_TRUE; 616 /* let bad current context imply bad current surface */ 617 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) 618 return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); 619 620 /* a valid current context implies an initialized current display */ 621 disp = ctx->Resource.Display; 622 assert(disp->Initialized); 623 drv = disp->Driver; 624 625 return drv->API.WaitNative(drv, disp, engine); 626} 627 628 629EGLDisplay EGLAPIENTRY 630eglGetCurrentDisplay(void) 631{ 632 _EGLContext *ctx = _eglGetCurrentContext(); 633 return (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; 634} 635 636 637EGLContext EGLAPIENTRY 638eglGetCurrentContext(void) 639{ 640 _EGLContext *ctx = _eglGetCurrentContext(); 641 return _eglGetContextHandle(ctx); 642} 643 644 645EGLSurface EGLAPIENTRY 646eglGetCurrentSurface(EGLint readdraw) 647{ 648 _EGLContext *ctx = _eglGetCurrentContext(); 649 _EGLSurface *surf; 650 651 if (!ctx) 652 return EGL_NO_SURFACE; 653 654 switch (readdraw) { 655 case EGL_DRAW: 656 surf = ctx->DrawSurface; 657 break; 658 case EGL_READ: 659 surf = ctx->ReadSurface; 660 break; 661 default: 662 _eglError(EGL_BAD_PARAMETER, __FUNCTION__); 663 surf = NULL; 664 break; 665 } 666 667 return _eglGetSurfaceHandle(surf); 668} 669 670 671EGLint EGLAPIENTRY 672eglGetError(void) 673{ 674 _EGLThreadInfo *t = _eglGetCurrentThread(); 675 EGLint e = t->LastError; 676 if (!_eglIsCurrentThreadDummy()) 677 t->LastError = EGL_SUCCESS; 678 return e; 679} 680 681 682__eglMustCastToProperFunctionPointerType EGLAPIENTRY 683eglGetProcAddress(const char *procname) 684{ 685 static const struct { 686 const char *name; 687 _EGLProc function; 688 } egl_functions[] = { 689 /* extensions only */ 690#ifdef EGL_MESA_screen_surface 691 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, 692 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, 693 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA }, 694 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA }, 695 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA }, 696 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA }, 697 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA }, 698 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA }, 699 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA }, 700 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA }, 701 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, 702 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, 703#endif /* EGL_MESA_screen_surface */ 704#ifdef EGL_KHR_image_base 705 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, 706 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, 707#endif /* EGL_KHR_image_base */ 708 { NULL, NULL } 709 }; 710 EGLint i; 711 712 if (!procname) 713 return NULL; 714 if (strncmp(procname, "egl", 3) == 0) { 715 for (i = 0; egl_functions[i].name; i++) { 716 if (strcmp(egl_functions[i].name, procname) == 0) 717 return egl_functions[i].function; 718 } 719 } 720 721 _eglPreloadDrivers(); 722 723 /* now loop over drivers to query their procs */ 724 for (i = 0; i < _eglGlobal.NumDrivers; i++) { 725 _EGLDriver *drv = _eglGlobal.Drivers[i]; 726 _EGLProc p = drv->API.GetProcAddress(drv, procname); 727 if (p) 728 return p; 729 } 730 731 return NULL; 732} 733 734 735#ifdef EGL_MESA_screen_surface 736 737 738/* 739 * EGL_MESA_screen extension 740 */ 741 742EGLBoolean EGLAPIENTRY 743eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, 744 const EGLint *attrib_list, EGLModeMESA *modes, 745 EGLint modes_size, EGLint *num_modes) 746{ 747 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); 748 return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, 749 modes, modes_size, num_modes); 750} 751 752 753EGLBoolean EGLAPIENTRY 754eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, 755 EGLint mode_size, EGLint *num_mode) 756{ 757 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); 758 return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); 759} 760 761 762EGLBoolean EGLAPIENTRY 763eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, 764 EGLint attribute, EGLint *value) 765{ 766 _EGL_DECLARE_DD_AND_MODE(dpy, mode); 767 return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); 768} 769 770 771EGLBoolean EGLAPIENTRY 772eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, 773 EGLint mask) 774{ 775 _EGLDisplay *disp = _eglLookupDisplay(dpy); 776 _EGLContext *source_context = _eglLookupContext(source, disp); 777 _EGLContext *dest_context = _eglLookupContext(dest, disp); 778 _EGLDriver *drv; 779 780 drv = _eglCheckContext(disp, source_context, __FUNCTION__); 781 if (!drv || !dest_context) { 782 if (drv) 783 _eglError(EGL_BAD_CONTEXT, __FUNCTION__); 784 return EGL_FALSE; 785 } 786 787 return drv->API.CopyContextMESA(drv, disp, source_context, dest_context, 788 mask); 789} 790 791 792EGLBoolean 793eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, 794 EGLint max_screens, EGLint *num_screens) 795{ 796 _EGL_DECLARE_DD(dpy); 797 return drv->API.GetScreensMESA(drv, disp, screens, 798 max_screens, num_screens); 799} 800 801 802EGLSurface 803eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, 804 const EGLint *attrib_list) 805{ 806 _EGLDisplay *disp = _eglLookupDisplay(dpy); 807 _EGLConfig *conf = _eglLookupConfig(config, disp); 808 _EGLDriver *drv; 809 _EGLSurface *surf; 810 811 drv = _eglCheckConfig(disp, conf, __FUNCTION__); 812 if (!drv) 813 return EGL_NO_SURFACE; 814 815 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); 816 if (surf) 817 return _eglLinkSurface(surf, disp); 818 else 819 return EGL_NO_SURFACE; 820} 821 822 823EGLBoolean 824eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, 825 EGLSurface surface, EGLModeMESA mode) 826{ 827 _EGLDisplay *disp = _eglLookupDisplay(dpy); 828 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 829 _EGLSurface *surf = _eglLookupSurface(surface, disp); 830 _EGLMode *m = _eglLookupMode(mode, disp); 831 _EGLDriver *drv; 832 833 drv = _eglCheckScreen(disp, scrn, __FUNCTION__); 834 if (!drv) 835 return EGL_FALSE; 836 if (!surf && surface != EGL_NO_SURFACE) 837 return _eglError(EGL_BAD_SURFACE, __FUNCTION__); 838 if (!m && mode != EGL_NO_MODE_MESA) 839 return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__); 840 841 return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); 842} 843 844 845EGLBoolean 846eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) 847{ 848 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); 849 return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); 850} 851 852 853EGLBoolean 854eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, 855 EGLint attribute, EGLint *value) 856{ 857 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); 858 return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); 859} 860 861 862EGLBoolean 863eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, 864 EGLSurface *surface) 865{ 866 _EGLDisplay *disp = _eglLookupDisplay(dpy); 867 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 868 _EGLDriver *drv; 869 _EGLSurface *surf; 870 871 drv = _eglCheckScreen(disp, scrn, __FUNCTION__); 872 if (!drv) 873 return EGL_FALSE; 874 875 if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE) 876 surf = NULL; 877 if (surface) 878 *surface = _eglGetSurfaceHandle(surf); 879 return (surf != NULL); 880} 881 882 883EGLBoolean 884eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) 885{ 886 _EGLDisplay *disp = _eglLookupDisplay(dpy); 887 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 888 _EGLDriver *drv; 889 _EGLMode *m; 890 891 drv = _eglCheckScreen(disp, scrn, __FUNCTION__); 892 if (!drv) 893 return EGL_FALSE; 894 895 if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE) 896 m = NULL; 897 if (mode) 898 *mode = m->Handle; 899 900 return (m != NULL); 901} 902 903 904const char * 905eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) 906{ 907 _EGL_DECLARE_DD_AND_MODE(dpy, mode); 908 return drv->API.QueryModeStringMESA(drv, disp, m); 909} 910 911 912#endif /* EGL_MESA_screen_surface */ 913 914 915/** 916 ** EGL 1.2 917 **/ 918 919#ifdef EGL_VERSION_1_2 920 921 922/** 923 * Specify the client API to use for subsequent calls including: 924 * eglCreateContext() 925 * eglGetCurrentContext() 926 * eglGetCurrentDisplay() 927 * eglGetCurrentSurface() 928 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT) 929 * eglWaitClient() 930 * eglWaitNative() 931 * See section 3.7 "Rendering Context" in the EGL specification for details. 932 */ 933EGLBoolean 934eglBindAPI(EGLenum api) 935{ 936 _EGLThreadInfo *t = _eglGetCurrentThread(); 937 938 if (_eglIsCurrentThreadDummy()) 939 return _eglError(EGL_BAD_ALLOC, "eglBindAPI"); 940 941 if (!_eglIsApiValid(api)) 942 return _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); 943 944 t->CurrentAPIIndex = _eglConvertApiToIndex(api); 945 return EGL_TRUE; 946} 947 948 949/** 950 * Return the last value set with eglBindAPI(). 951 */ 952EGLenum 953eglQueryAPI(void) 954{ 955 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ 956 _EGLThreadInfo *t = _eglGetCurrentThread(); 957 return _eglConvertApiFromIndex(t->CurrentAPIIndex); 958} 959 960 961EGLSurface 962eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, 963 EGLClientBuffer buffer, EGLConfig config, 964 const EGLint *attrib_list) 965{ 966 _EGLDisplay *disp = _eglLookupDisplay(dpy); 967 _EGLConfig *conf = _eglLookupConfig(config, disp); 968 _EGLDriver *drv; 969 _EGLSurface *surf; 970 971 drv = _eglCheckConfig(disp, conf, __FUNCTION__); 972 if (!drv) 973 return EGL_NO_SURFACE; 974 975 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, 976 conf, attrib_list); 977 if (surf) 978 return _eglLinkSurface(surf, disp); 979 else 980 return EGL_NO_SURFACE; 981} 982 983 984EGLBoolean 985eglReleaseThread(void) 986{ 987 /* unbind current contexts */ 988 if (!_eglIsCurrentThreadDummy()) { 989 _EGLThreadInfo *t = _eglGetCurrentThread(); 990 EGLint i; 991 992 for (i = 0; i < _EGL_API_NUM_APIS; i++) { 993 _EGLContext *ctx = t->CurrentContexts[i]; 994 if (ctx) { 995 _EGLDisplay *disp = ctx->Resource.Display; 996 _EGLDriver *drv = disp->Driver; 997 /* what if display is not initialized? */ 998 if (disp->Initialized) 999 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); 1000 } 1001 } 1002 } 1003 1004 _eglDestroyCurrentThread(); 1005 return EGL_TRUE; 1006} 1007 1008 1009#endif /* EGL_VERSION_1_2 */ 1010 1011 1012#ifdef EGL_KHR_image_base 1013 1014 1015EGLImageKHR 1016eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, 1017 EGLClientBuffer buffer, const EGLint *attr_list) 1018{ 1019 _EGLDisplay *disp = _eglLookupDisplay(dpy); 1020 _EGLContext *context = _eglLookupContext(ctx, disp); 1021 _EGLDriver *drv; 1022 _EGLImage *img; 1023 1024 drv = _eglCheckDisplay(disp, __FUNCTION__); 1025 if (!drv) 1026 return EGL_NO_IMAGE_KHR; 1027 if (!context && ctx != EGL_NO_CONTEXT) { 1028 _eglError(EGL_BAD_CONTEXT, __FUNCTION__); 1029 return EGL_NO_IMAGE_KHR; 1030 } 1031 1032 img = drv->API.CreateImageKHR(drv, 1033 disp, context, target, buffer, attr_list); 1034 if (img) 1035 return _eglLinkImage(img, disp); 1036 else 1037 return EGL_NO_IMAGE_KHR; 1038} 1039 1040 1041EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) 1042{ 1043 _EGLDisplay *disp = _eglLookupDisplay(dpy); 1044 _EGLImage *img = _eglLookupImage(image, disp); 1045 _EGLDriver *drv; 1046 1047 drv = _eglCheckDisplay(disp, __FUNCTION__); 1048 if (!drv) 1049 return EGL_FALSE; 1050 if (!img) 1051 return _eglError(EGL_BAD_PARAMETER, __FUNCTION__); 1052 1053 _eglUnlinkImage(img); 1054 return drv->API.DestroyImageKHR(drv, disp, img); 1055} 1056 1057 1058#endif /* EGL_KHR_image_base */ 1059