eglapi.c revision ff318c45ec1fafd0d825a8da5556d2d1e69ff7da
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 60#include "eglstring.h" 61#include "eglcontext.h" 62#include "egldisplay.h" 63#include "egltypedefs.h" 64#include "eglcurrent.h" 65#include "egldriver.h" 66#include "eglsurface.h" 67#include "eglconfig.h" 68#include "eglscreen.h" 69#include "eglmode.h" 70#include "eglimage.h" 71 72 73/** 74 * Macros to help return an API entrypoint. 75 * 76 * These macros will unlock the display and record the error code. 77 */ 78#define RETURN_EGL_ERROR(disp, err, ret) \ 79 do { \ 80 if (disp) \ 81 _eglUnlockDisplay(disp); \ 82 /* EGL error codes are non-zero */ \ 83 if (err) \ 84 _eglError(err, __FUNCTION__); \ 85 return ret; \ 86 } while (0) 87 88#define RETURN_EGL_SUCCESS(disp, ret) \ 89 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret) 90 91/* record EGL_SUCCESS only when ret evaluates to true */ 92#define RETURN_EGL_EVAL(disp, ret) \ 93 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret) 94 95 96/* 97 * A bunch of macros and checks to simplify error checking. 98 */ 99 100#define _EGL_CHECK_DISPLAY(disp, ret, drv) \ 101 do { \ 102 drv = _eglCheckDisplay(disp, __FUNCTION__); \ 103 if (!drv) \ 104 RETURN_EGL_ERROR(disp, 0, ret); \ 105 } while (0) 106 107#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \ 108 do { \ 109 drv = _eglCheck ## type(disp, obj, __FUNCTION__); \ 110 if (!drv) \ 111 RETURN_EGL_ERROR(disp, 0, ret); \ 112 } while (0) 113 114#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \ 115 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv) 116 117#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \ 118 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv) 119 120#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \ 121 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv) 122 123#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \ 124 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv) 125 126#define _EGL_CHECK_MODE(disp, m, ret, drv) \ 127 _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv) 128 129 130 131static INLINE _EGLDriver * 132_eglCheckDisplay(_EGLDisplay *disp, const char *msg) 133{ 134 if (!disp) { 135 _eglError(EGL_BAD_DISPLAY, msg); 136 return NULL; 137 } 138 if (!disp->Initialized) { 139 _eglError(EGL_NOT_INITIALIZED, msg); 140 return NULL; 141 } 142 return disp->Driver; 143} 144 145 146static INLINE _EGLDriver * 147_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg) 148{ 149 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 150 if (!drv) 151 return NULL; 152 if (!surf) { 153 _eglError(EGL_BAD_SURFACE, msg); 154 return NULL; 155 } 156 return drv; 157} 158 159 160static INLINE _EGLDriver * 161_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg) 162{ 163 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 164 if (!drv) 165 return NULL; 166 if (!context) { 167 _eglError(EGL_BAD_CONTEXT, msg); 168 return NULL; 169 } 170 return drv; 171} 172 173 174static INLINE _EGLDriver * 175_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) 176{ 177 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 178 if (!drv) 179 return NULL; 180 if (!conf) { 181 _eglError(EGL_BAD_CONFIG, msg); 182 return NULL; 183 } 184 return drv; 185} 186 187 188#ifdef EGL_MESA_screen_surface 189 190 191static INLINE _EGLDriver * 192_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg) 193{ 194 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 195 if (!drv) 196 return NULL; 197 if (!scrn) { 198 _eglError(EGL_BAD_SCREEN_MESA, msg); 199 return NULL; 200 } 201 return drv; 202} 203 204 205static INLINE _EGLDriver * 206_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) 207{ 208 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 209 if (!drv) 210 return NULL; 211 if (!m) { 212 _eglError(EGL_BAD_MODE_MESA, msg); 213 return NULL; 214 } 215 return drv; 216} 217 218 219#endif /* EGL_MESA_screen_surface */ 220 221 222/** 223 * Lookup and lock a display. 224 */ 225static INLINE _EGLDisplay * 226_eglLockDisplay(EGLDisplay display) 227{ 228 _EGLDisplay *dpy = _eglLookupDisplay(display); 229 if (dpy) 230 _eglLockMutex(&dpy->Mutex); 231 return dpy; 232} 233 234 235/** 236 * Unlock a display. 237 */ 238static INLINE void 239_eglUnlockDisplay(_EGLDisplay *dpy) 240{ 241 _eglUnlockMutex(&dpy->Mutex); 242} 243 244 245/** 246 * This is typically the first EGL function that an application calls. 247 * It associates a private _EGLDisplay object to the native display. 248 */ 249EGLDisplay EGLAPIENTRY 250eglGetDisplay(EGLNativeDisplayType nativeDisplay) 251{ 252 _EGLPlatformType plat = _eglGetNativePlatform(); 253 _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay); 254 return _eglGetDisplayHandle(dpy); 255} 256 257 258/** 259 * This is typically the second EGL function that an application calls. 260 * Here we load/initialize the actual hardware driver. 261 */ 262EGLBoolean EGLAPIENTRY 263eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 264{ 265 _EGLDisplay *disp = _eglLockDisplay(dpy); 266 267 if (!disp) 268 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); 269 270 if (!disp->Initialized) { 271 if (!_eglMatchDriver(disp, EGL_FALSE)) 272 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); 273 274 _eglsnprintf(disp->Version, sizeof(disp->Version), "%d.%d (%s)", 275 disp->APImajor, disp->APIminor, disp->Driver->Name); 276 /* limit to APIs supported by core */ 277 disp->ClientAPIsMask &= _EGL_API_ALL_BITS; 278 } 279 280 /* Update applications version of major and minor if not NULL */ 281 if ((major != NULL) && (minor != NULL)) { 282 *major = disp->APImajor; 283 *minor = disp->APIminor; 284 } 285 286 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 287} 288 289 290EGLBoolean EGLAPIENTRY 291eglTerminate(EGLDisplay dpy) 292{ 293 _EGLDisplay *disp = _eglLockDisplay(dpy); 294 295 if (!disp) 296 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); 297 298 if (disp->Initialized) { 299 _EGLDriver *drv = disp->Driver; 300 301 drv->API.Terminate(drv, disp); 302 /* do not reset disp->Driver */ 303 disp->Initialized = EGL_FALSE; 304 } 305 306 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 307} 308 309 310const char * EGLAPIENTRY 311eglQueryString(EGLDisplay dpy, EGLint name) 312{ 313 _EGLDisplay *disp = _eglLockDisplay(dpy); 314 _EGLDriver *drv; 315 const char *ret; 316 317 _EGL_CHECK_DISPLAY(disp, NULL, drv); 318 ret = drv->API.QueryString(drv, disp, name); 319 320 RETURN_EGL_EVAL(disp, ret); 321} 322 323 324EGLBoolean EGLAPIENTRY 325eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, 326 EGLint config_size, EGLint *num_config) 327{ 328 _EGLDisplay *disp = _eglLockDisplay(dpy); 329 _EGLDriver *drv; 330 EGLBoolean ret; 331 332 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 333 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config); 334 335 RETURN_EGL_EVAL(disp, ret); 336} 337 338 339EGLBoolean EGLAPIENTRY 340eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, 341 EGLint config_size, EGLint *num_config) 342{ 343 _EGLDisplay *disp = _eglLockDisplay(dpy); 344 _EGLDriver *drv; 345 EGLBoolean ret; 346 347 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 348 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs, 349 config_size, num_config); 350 351 RETURN_EGL_EVAL(disp, ret); 352} 353 354 355EGLBoolean EGLAPIENTRY 356eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, 357 EGLint attribute, EGLint *value) 358{ 359 _EGLDisplay *disp = _eglLockDisplay(dpy); 360 _EGLConfig *conf = _eglLookupConfig(config, disp); 361 _EGLDriver *drv; 362 EGLBoolean ret; 363 364 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv); 365 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); 366 367 RETURN_EGL_EVAL(disp, ret); 368} 369 370 371EGLContext EGLAPIENTRY 372eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, 373 const EGLint *attrib_list) 374{ 375 _EGLDisplay *disp = _eglLockDisplay(dpy); 376 _EGLConfig *conf = _eglLookupConfig(config, disp); 377 _EGLContext *share = _eglLookupContext(share_list, disp); 378 _EGLDriver *drv; 379 _EGLContext *context; 380 EGLContext ret; 381 382 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv); 383 if (!share && share_list != EGL_NO_CONTEXT) 384 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT); 385 386 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list); 387 ret = (context) ? _eglLinkContext(context, disp) : EGL_NO_CONTEXT; 388 389 RETURN_EGL_EVAL(disp, ret); 390} 391 392 393EGLBoolean EGLAPIENTRY 394eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 395{ 396 _EGLDisplay *disp = _eglLockDisplay(dpy); 397 _EGLContext *context = _eglLookupContext(ctx, disp); 398 _EGLDriver *drv; 399 EGLBoolean ret; 400 401 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); 402 _eglUnlinkContext(context); 403 ret = drv->API.DestroyContext(drv, disp, context); 404 405 RETURN_EGL_EVAL(disp, ret); 406} 407 408 409EGLBoolean EGLAPIENTRY 410eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, 411 EGLContext ctx) 412{ 413 _EGLDisplay *disp = _eglLockDisplay(dpy); 414 _EGLContext *context = _eglLookupContext(ctx, disp); 415 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); 416 _EGLSurface *read_surf = _eglLookupSurface(read, disp); 417 _EGLDriver *drv; 418 EGLBoolean ret; 419 420 if (!disp) 421 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); 422 drv = disp->Driver; 423 424 /* display is allowed to be uninitialized under certain condition */ 425 if (!disp->Initialized) { 426 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE || 427 ctx != EGL_NO_CONTEXT) 428 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); 429 } 430 if (!drv) 431 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 432 433 if (!context && ctx != EGL_NO_CONTEXT) 434 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 435 if ((!draw_surf && draw != EGL_NO_SURFACE) || 436 (!read_surf && read != EGL_NO_SURFACE)) 437 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 438 439 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); 440 441 RETURN_EGL_EVAL(disp, ret); 442} 443 444 445EGLBoolean EGLAPIENTRY 446eglQueryContext(EGLDisplay dpy, EGLContext ctx, 447 EGLint attribute, EGLint *value) 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 ret = drv->API.QueryContext(drv, disp, context, attribute, value); 456 457 RETURN_EGL_EVAL(disp, ret); 458} 459 460 461EGLSurface EGLAPIENTRY 462eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, 463 EGLNativeWindowType window, const EGLint *attrib_list) 464{ 465 _EGLDisplay *disp = _eglLockDisplay(dpy); 466 _EGLConfig *conf = _eglLookupConfig(config, disp); 467 _EGLDriver *drv; 468 _EGLSurface *surf; 469 EGLSurface ret; 470 471 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 472 if (disp->Platform != _eglGetNativePlatform()) 473 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 474 475 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list); 476 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; 477 478 RETURN_EGL_EVAL(disp, ret); 479} 480 481 482EGLSurface EGLAPIENTRY 483eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, 484 EGLNativePixmapType pixmap, const EGLint *attrib_list) 485{ 486 _EGLDisplay *disp = _eglLockDisplay(dpy); 487 _EGLConfig *conf = _eglLookupConfig(config, disp); 488 _EGLDriver *drv; 489 _EGLSurface *surf; 490 EGLSurface ret; 491 492 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 493 if (disp->Platform != _eglGetNativePlatform()) 494 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); 495 496 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list); 497 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; 498 499 RETURN_EGL_EVAL(disp, ret); 500} 501 502 503EGLSurface EGLAPIENTRY 504eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, 505 const EGLint *attrib_list) 506{ 507 _EGLDisplay *disp = _eglLockDisplay(dpy); 508 _EGLConfig *conf = _eglLookupConfig(config, disp); 509 _EGLDriver *drv; 510 _EGLSurface *surf; 511 EGLSurface ret; 512 513 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 514 515 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); 516 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; 517 518 RETURN_EGL_EVAL(disp, ret); 519} 520 521 522EGLBoolean EGLAPIENTRY 523eglDestroySurface(EGLDisplay dpy, EGLSurface surface) 524{ 525 _EGLDisplay *disp = _eglLockDisplay(dpy); 526 _EGLSurface *surf = _eglLookupSurface(surface, disp); 527 _EGLDriver *drv; 528 EGLBoolean ret; 529 530 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 531 _eglUnlinkSurface(surf); 532 ret = drv->API.DestroySurface(drv, disp, surf); 533 534 RETURN_EGL_EVAL(disp, ret); 535} 536 537EGLBoolean EGLAPIENTRY 538eglQuerySurface(EGLDisplay dpy, EGLSurface surface, 539 EGLint attribute, EGLint *value) 540{ 541 _EGLDisplay *disp = _eglLockDisplay(dpy); 542 _EGLSurface *surf = _eglLookupSurface(surface, disp); 543 _EGLDriver *drv; 544 EGLBoolean ret; 545 546 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 547 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value); 548 549 RETURN_EGL_EVAL(disp, ret); 550} 551 552EGLBoolean EGLAPIENTRY 553eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, 554 EGLint attribute, EGLint value) 555{ 556 _EGLDisplay *disp = _eglLockDisplay(dpy); 557 _EGLSurface *surf = _eglLookupSurface(surface, disp); 558 _EGLDriver *drv; 559 EGLBoolean ret; 560 561 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 562 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); 563 564 RETURN_EGL_EVAL(disp, ret); 565} 566 567 568EGLBoolean EGLAPIENTRY 569eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 570{ 571 _EGLDisplay *disp = _eglLockDisplay(dpy); 572 _EGLSurface *surf = _eglLookupSurface(surface, disp); 573 _EGLDriver *drv; 574 EGLBoolean ret; 575 576 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 577 ret = drv->API.BindTexImage(drv, disp, surf, buffer); 578 579 RETURN_EGL_EVAL(disp, ret); 580} 581 582 583EGLBoolean EGLAPIENTRY 584eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 585{ 586 _EGLDisplay *disp = _eglLockDisplay(dpy); 587 _EGLSurface *surf = _eglLookupSurface(surface, disp); 588 _EGLDriver *drv; 589 EGLBoolean ret; 590 591 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 592 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer); 593 594 RETURN_EGL_EVAL(disp, ret); 595} 596 597 598EGLBoolean EGLAPIENTRY 599eglSwapInterval(EGLDisplay dpy, EGLint interval) 600{ 601 _EGLDisplay *disp = _eglLockDisplay(dpy); 602 _EGLContext *ctx = _eglGetCurrentContext(); 603 _EGLSurface *surf; 604 _EGLDriver *drv; 605 EGLBoolean ret; 606 607 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 608 609 if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp) 610 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 611 612 surf = ctx->DrawSurface; 613 if (!_eglIsSurfaceLinked(surf)) 614 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 615 616 ret = drv->API.SwapInterval(drv, disp, surf, interval); 617 618 RETURN_EGL_EVAL(disp, ret); 619} 620 621 622EGLBoolean EGLAPIENTRY 623eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) 624{ 625 _EGLContext *ctx = _eglGetCurrentContext(); 626 _EGLDisplay *disp = _eglLockDisplay(dpy); 627 _EGLSurface *surf = _eglLookupSurface(surface, disp); 628 _EGLDriver *drv; 629 EGLBoolean ret; 630 631 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 632 633 /* surface must be bound to current context in EGL 1.4 */ 634 if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface) 635 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 636 637 ret = drv->API.SwapBuffers(drv, disp, surf); 638 639 RETURN_EGL_EVAL(disp, ret); 640} 641 642 643EGLBoolean EGLAPIENTRY 644eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) 645{ 646 _EGLDisplay *disp = _eglLockDisplay(dpy); 647 _EGLSurface *surf = _eglLookupSurface(surface, disp); 648 _EGLDriver *drv; 649 EGLBoolean ret; 650 651 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 652 if (disp->Platform != _eglGetNativePlatform()) 653 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE); 654 ret = drv->API.CopyBuffers(drv, disp, surf, target); 655 656 RETURN_EGL_EVAL(disp, ret); 657} 658 659 660EGLBoolean EGLAPIENTRY 661eglWaitClient(void) 662{ 663 _EGLContext *ctx = _eglGetCurrentContext(); 664 _EGLDisplay *disp; 665 _EGLDriver *drv; 666 EGLBoolean ret; 667 668 if (!ctx) 669 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 670 671 disp = ctx->Resource.Display; 672 _eglLockMutex(&disp->Mutex); 673 674 /* let bad current context imply bad current surface */ 675 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) 676 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 677 678 /* a valid current context implies an initialized current display */ 679 assert(disp->Initialized); 680 drv = disp->Driver; 681 ret = drv->API.WaitClient(drv, disp, ctx); 682 683 RETURN_EGL_EVAL(disp, ret); 684} 685 686 687EGLBoolean EGLAPIENTRY 688eglWaitGL(void) 689{ 690#ifdef EGL_VERSION_1_2 691 _EGLThreadInfo *t = _eglGetCurrentThread(); 692 EGLint api_index = t->CurrentAPIIndex; 693 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API); 694 EGLBoolean ret; 695 696 if (api_index != es_index && _eglIsCurrentThreadDummy()) 697 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); 698 699 t->CurrentAPIIndex = es_index; 700 ret = eglWaitClient(); 701 t->CurrentAPIIndex = api_index; 702 return ret; 703#else 704 return eglWaitClient(); 705#endif 706} 707 708 709EGLBoolean EGLAPIENTRY 710eglWaitNative(EGLint engine) 711{ 712 _EGLContext *ctx = _eglGetCurrentContext(); 713 _EGLDisplay *disp; 714 _EGLDriver *drv; 715 EGLBoolean ret; 716 717 if (!ctx) 718 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 719 720 disp = ctx->Resource.Display; 721 _eglLockMutex(&disp->Mutex); 722 723 /* let bad current context imply bad current surface */ 724 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) 725 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 726 727 /* a valid current context implies an initialized current display */ 728 assert(disp->Initialized); 729 drv = disp->Driver; 730 ret = drv->API.WaitNative(drv, disp, engine); 731 732 RETURN_EGL_EVAL(disp, ret); 733} 734 735 736EGLDisplay EGLAPIENTRY 737eglGetCurrentDisplay(void) 738{ 739 _EGLContext *ctx = _eglGetCurrentContext(); 740 EGLDisplay ret; 741 742 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; 743 744 RETURN_EGL_SUCCESS(NULL, ret); 745} 746 747 748EGLContext EGLAPIENTRY 749eglGetCurrentContext(void) 750{ 751 _EGLContext *ctx = _eglGetCurrentContext(); 752 EGLContext ret; 753 754 ret = _eglGetContextHandle(ctx); 755 756 RETURN_EGL_SUCCESS(NULL, ret); 757} 758 759 760EGLSurface EGLAPIENTRY 761eglGetCurrentSurface(EGLint readdraw) 762{ 763 _EGLContext *ctx = _eglGetCurrentContext(); 764 EGLint err = EGL_SUCCESS; 765 _EGLSurface *surf; 766 EGLSurface ret; 767 768 if (!ctx) 769 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE); 770 771 switch (readdraw) { 772 case EGL_DRAW: 773 surf = ctx->DrawSurface; 774 break; 775 case EGL_READ: 776 surf = ctx->ReadSurface; 777 break; 778 default: 779 surf = NULL; 780 err = EGL_BAD_PARAMETER; 781 break; 782 } 783 784 ret = _eglGetSurfaceHandle(surf); 785 786 RETURN_EGL_ERROR(NULL, err, ret); 787} 788 789 790EGLint EGLAPIENTRY 791eglGetError(void) 792{ 793 _EGLThreadInfo *t = _eglGetCurrentThread(); 794 EGLint e = t->LastError; 795 if (!_eglIsCurrentThreadDummy()) 796 t->LastError = EGL_SUCCESS; 797 return e; 798} 799 800 801__eglMustCastToProperFunctionPointerType EGLAPIENTRY 802eglGetProcAddress(const char *procname) 803{ 804 static const struct { 805 const char *name; 806 _EGLProc function; 807 } egl_functions[] = { 808 /* extensions only */ 809#ifdef EGL_MESA_screen_surface 810 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, 811 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, 812 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA }, 813 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA }, 814 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA }, 815 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA }, 816 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA }, 817 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA }, 818 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA }, 819 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA }, 820 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, 821 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, 822#endif /* EGL_MESA_screen_surface */ 823#ifdef EGL_MESA_drm_display 824 { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, 825#endif 826#ifdef EGL_KHR_image_base 827 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, 828 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, 829#endif /* EGL_KHR_image_base */ 830#ifdef EGL_NOK_swap_region 831 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, 832#endif 833 { NULL, NULL } 834 }; 835 EGLint i; 836 _EGLProc ret; 837 838 if (!procname) 839 RETURN_EGL_SUCCESS(NULL, NULL); 840 841 ret = NULL; 842 if (strncmp(procname, "egl", 3) == 0) { 843 for (i = 0; egl_functions[i].name; i++) { 844 if (strcmp(egl_functions[i].name, procname) == 0) { 845 ret = egl_functions[i].function; 846 break; 847 } 848 } 849 } 850 if (!ret) 851 ret = _eglGetDriverProc(procname); 852 853 RETURN_EGL_SUCCESS(NULL, ret); 854} 855 856 857#ifdef EGL_MESA_screen_surface 858 859 860/* 861 * EGL_MESA_screen extension 862 */ 863 864EGLBoolean EGLAPIENTRY 865eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, 866 const EGLint *attrib_list, EGLModeMESA *modes, 867 EGLint modes_size, EGLint *num_modes) 868{ 869 _EGLDisplay *disp = _eglLockDisplay(dpy); 870 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 871 _EGLDriver *drv; 872 EGLBoolean ret; 873 874 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 875 ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, 876 modes, modes_size, num_modes); 877 878 RETURN_EGL_EVAL(disp, ret); 879} 880 881 882EGLBoolean EGLAPIENTRY 883eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, 884 EGLint mode_size, EGLint *num_mode) 885{ 886 _EGLDisplay *disp = _eglLockDisplay(dpy); 887 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 888 _EGLDriver *drv; 889 EGLBoolean ret; 890 891 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 892 ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); 893 894 RETURN_EGL_EVAL(disp, ret); 895} 896 897 898EGLBoolean EGLAPIENTRY 899eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, 900 EGLint attribute, EGLint *value) 901{ 902 _EGLDisplay *disp = _eglLockDisplay(dpy); 903 _EGLMode *m = _eglLookupMode(mode, disp); 904 _EGLDriver *drv; 905 EGLBoolean ret; 906 907 _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv); 908 ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); 909 910 RETURN_EGL_EVAL(disp, ret); 911} 912 913 914EGLBoolean EGLAPIENTRY 915eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, 916 EGLint mask) 917{ 918 _EGLDisplay *disp = _eglLockDisplay(dpy); 919 _EGLContext *source_context = _eglLookupContext(source, disp); 920 _EGLContext *dest_context = _eglLookupContext(dest, disp); 921 _EGLDriver *drv; 922 EGLBoolean ret; 923 924 _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv); 925 if (!dest_context) 926 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 927 928 ret = drv->API.CopyContextMESA(drv, disp, 929 source_context, dest_context, mask); 930 931 RETURN_EGL_EVAL(disp, ret); 932} 933 934 935EGLBoolean EGLAPIENTRY 936eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, 937 EGLint max_screens, EGLint *num_screens) 938{ 939 _EGLDisplay *disp = _eglLockDisplay(dpy); 940 _EGLDriver *drv; 941 EGLBoolean ret; 942 943 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 944 ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens); 945 946 RETURN_EGL_EVAL(disp, ret); 947} 948 949 950EGLSurface EGLAPIENTRY 951eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, 952 const EGLint *attrib_list) 953{ 954 _EGLDisplay *disp = _eglLockDisplay(dpy); 955 _EGLConfig *conf = _eglLookupConfig(config, disp); 956 _EGLDriver *drv; 957 _EGLSurface *surf; 958 EGLSurface ret; 959 960 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 961 962 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); 963 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; 964 965 RETURN_EGL_EVAL(disp, ret); 966} 967 968 969EGLBoolean EGLAPIENTRY 970eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, 971 EGLSurface surface, EGLModeMESA mode) 972{ 973 _EGLDisplay *disp = _eglLockDisplay(dpy); 974 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 975 _EGLSurface *surf = _eglLookupSurface(surface, disp); 976 _EGLMode *m = _eglLookupMode(mode, disp); 977 _EGLDriver *drv; 978 EGLBoolean ret; 979 980 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 981 if (!surf && surface != EGL_NO_SURFACE) 982 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 983 if (!m && mode != EGL_NO_MODE_MESA) 984 RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE); 985 986 ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); 987 988 RETURN_EGL_EVAL(disp, ret); 989} 990 991 992EGLBoolean EGLAPIENTRY 993eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) 994{ 995 _EGLDisplay *disp = _eglLockDisplay(dpy); 996 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 997 _EGLDriver *drv; 998 EGLBoolean ret; 999 1000 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1001 ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); 1002 1003 RETURN_EGL_EVAL(disp, ret); 1004} 1005 1006 1007EGLBoolean EGLAPIENTRY 1008eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, 1009 EGLint attribute, EGLint *value) 1010{ 1011 _EGLDisplay *disp = _eglLockDisplay(dpy); 1012 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 1013 _EGLDriver *drv; 1014 EGLBoolean ret; 1015 1016 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1017 ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); 1018 1019 RETURN_EGL_EVAL(disp, ret); 1020} 1021 1022 1023EGLBoolean EGLAPIENTRY 1024eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, 1025 EGLSurface *surface) 1026{ 1027 _EGLDisplay *disp = _eglLockDisplay(dpy); 1028 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 1029 _EGLDriver *drv; 1030 _EGLSurface *surf; 1031 EGLBoolean ret; 1032 1033 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1034 ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf); 1035 if (ret && surface) 1036 *surface = _eglGetSurfaceHandle(surf); 1037 1038 RETURN_EGL_EVAL(disp, ret); 1039} 1040 1041 1042EGLBoolean EGLAPIENTRY 1043eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) 1044{ 1045 _EGLDisplay *disp = _eglLockDisplay(dpy); 1046 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 1047 _EGLDriver *drv; 1048 _EGLMode *m; 1049 EGLBoolean ret; 1050 1051 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1052 ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m); 1053 if (ret && mode) 1054 *mode = m->Handle; 1055 1056 RETURN_EGL_EVAL(disp, ret); 1057} 1058 1059 1060const char * EGLAPIENTRY 1061eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) 1062{ 1063 _EGLDisplay *disp = _eglLockDisplay(dpy); 1064 _EGLMode *m = _eglLookupMode(mode, disp); 1065 _EGLDriver *drv; 1066 const char *ret; 1067 1068 _EGL_CHECK_MODE(disp, m, NULL, drv); 1069 ret = drv->API.QueryModeStringMESA(drv, disp, m); 1070 1071 RETURN_EGL_EVAL(disp, ret); 1072} 1073 1074 1075#endif /* EGL_MESA_screen_surface */ 1076 1077 1078#ifdef EGL_MESA_drm_display 1079 1080EGLDisplay EGLAPIENTRY 1081eglGetDRMDisplayMESA(int fd) 1082{ 1083 _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) fd); 1084 return _eglGetDisplayHandle(dpy); 1085} 1086 1087#endif /* EGL_MESA_drm_display */ 1088 1089/** 1090 ** EGL 1.2 1091 **/ 1092 1093#ifdef EGL_VERSION_1_2 1094 1095 1096/** 1097 * Specify the client API to use for subsequent calls including: 1098 * eglCreateContext() 1099 * eglGetCurrentContext() 1100 * eglGetCurrentDisplay() 1101 * eglGetCurrentSurface() 1102 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT) 1103 * eglWaitClient() 1104 * eglWaitNative() 1105 * See section 3.7 "Rendering Context" in the EGL specification for details. 1106 */ 1107EGLBoolean EGLAPIENTRY 1108eglBindAPI(EGLenum api) 1109{ 1110 _EGLThreadInfo *t = _eglGetCurrentThread(); 1111 1112 if (_eglIsCurrentThreadDummy()) 1113 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); 1114 1115 if (!_eglIsApiValid(api)) 1116 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); 1117 1118 t->CurrentAPIIndex = _eglConvertApiToIndex(api); 1119 1120 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1121} 1122 1123 1124/** 1125 * Return the last value set with eglBindAPI(). 1126 */ 1127EGLenum EGLAPIENTRY 1128eglQueryAPI(void) 1129{ 1130 _EGLThreadInfo *t = _eglGetCurrentThread(); 1131 EGLenum ret; 1132 1133 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ 1134 ret = _eglConvertApiFromIndex(t->CurrentAPIIndex); 1135 1136 RETURN_EGL_SUCCESS(NULL, ret); 1137} 1138 1139 1140EGLSurface EGLAPIENTRY 1141eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, 1142 EGLClientBuffer buffer, EGLConfig config, 1143 const EGLint *attrib_list) 1144{ 1145 _EGLDisplay *disp = _eglLockDisplay(dpy); 1146 _EGLConfig *conf = _eglLookupConfig(config, disp); 1147 _EGLDriver *drv; 1148 _EGLSurface *surf; 1149 EGLSurface ret; 1150 1151 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 1152 1153 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, 1154 conf, attrib_list); 1155 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; 1156 1157 RETURN_EGL_EVAL(disp, ret); 1158} 1159 1160 1161EGLBoolean EGLAPIENTRY 1162eglReleaseThread(void) 1163{ 1164 /* unbind current contexts */ 1165 if (!_eglIsCurrentThreadDummy()) { 1166 _EGLThreadInfo *t = _eglGetCurrentThread(); 1167 EGLint api_index = t->CurrentAPIIndex; 1168 EGLint i; 1169 1170 for (i = 0; i < _EGL_API_NUM_APIS; i++) { 1171 _EGLContext *ctx = t->CurrentContexts[i]; 1172 if (ctx) { 1173 _EGLDisplay *disp = ctx->Resource.Display; 1174 _EGLDriver *drv; 1175 1176 t->CurrentAPIIndex = i; 1177 1178 _eglLockMutex(&disp->Mutex); 1179 drv = disp->Driver; 1180 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); 1181 _eglUnlockMutex(&disp->Mutex); 1182 } 1183 } 1184 1185 t->CurrentAPIIndex = api_index; 1186 } 1187 1188 _eglDestroyCurrentThread(); 1189 1190 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1191} 1192 1193 1194#endif /* EGL_VERSION_1_2 */ 1195 1196 1197#ifdef EGL_KHR_image_base 1198 1199 1200EGLImageKHR EGLAPIENTRY 1201eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, 1202 EGLClientBuffer buffer, const EGLint *attr_list) 1203{ 1204 _EGLDisplay *disp = _eglLockDisplay(dpy); 1205 _EGLContext *context = _eglLookupContext(ctx, disp); 1206 _EGLDriver *drv; 1207 _EGLImage *img; 1208 EGLImageKHR ret; 1209 1210 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); 1211 if (!context && ctx != EGL_NO_CONTEXT) 1212 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); 1213 1214 img = drv->API.CreateImageKHR(drv, 1215 disp, context, target, buffer, attr_list); 1216 ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR; 1217 1218 RETURN_EGL_EVAL(disp, ret); 1219} 1220 1221 1222EGLBoolean EGLAPIENTRY 1223eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) 1224{ 1225 _EGLDisplay *disp = _eglLockDisplay(dpy); 1226 _EGLImage *img = _eglLookupImage(image, disp); 1227 _EGLDriver *drv; 1228 EGLBoolean ret; 1229 1230 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1231 if (!img) 1232 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1233 1234 _eglUnlinkImage(img); 1235 ret = drv->API.DestroyImageKHR(drv, disp, img); 1236 1237 RETURN_EGL_EVAL(disp, ret); 1238} 1239 1240 1241#endif /* EGL_KHR_image_base */ 1242 1243 1244#ifdef EGL_NOK_swap_region 1245 1246EGLBoolean EGLAPIENTRY 1247eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, 1248 EGLint numRects, const EGLint *rects) 1249{ 1250 _EGLContext *ctx = _eglGetCurrentContext(); 1251 _EGLDisplay *disp = _eglLockDisplay(dpy); 1252 _EGLSurface *surf = _eglLookupSurface(surface, disp); 1253 _EGLDriver *drv; 1254 EGLBoolean ret; 1255 1256 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 1257 1258 /* surface must be bound to current context in EGL 1.4 */ 1259 if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface) 1260 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 1261 1262 if (drv->API.SwapBuffersRegionNOK) 1263 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects); 1264 else 1265 ret = drv->API.SwapBuffers(drv, disp, surf); 1266 1267 RETURN_EGL_EVAL(disp, ret); 1268} 1269 1270#endif /* EGL_NOK_swap_region */ 1271