Merge remote branch 'origin/master' into glsl2
[mesa.git] / src / egl / main / eglapi.c
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
131 static 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
146 static 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
160 static 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
174 static 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
191 static 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
205 static 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 */
225 static 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 */
238 static 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 */
249 EGLDisplay EGLAPIENTRY
250 eglGetDisplay(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 */
262 EGLBoolean EGLAPIENTRY
263 eglInitialize(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
290 EGLBoolean EGLAPIENTRY
291 eglTerminate(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
310 const char * EGLAPIENTRY
311 eglQueryString(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
324 EGLBoolean EGLAPIENTRY
325 eglGetConfigs(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
339 EGLBoolean EGLAPIENTRY
340 eglChooseConfig(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
355 EGLBoolean EGLAPIENTRY
356 eglGetConfigAttrib(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
371 EGLContext EGLAPIENTRY
372 eglCreateContext(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
393 EGLBoolean EGLAPIENTRY
394 eglDestroyContext(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
409 EGLBoolean EGLAPIENTRY
410 eglMakeCurrent(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
445 EGLBoolean EGLAPIENTRY
446 eglQueryContext(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
461 EGLSurface EGLAPIENTRY
462 eglCreateWindowSurface(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
482 EGLSurface EGLAPIENTRY
483 eglCreatePixmapSurface(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
503 EGLSurface EGLAPIENTRY
504 eglCreatePbufferSurface(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
522 EGLBoolean EGLAPIENTRY
523 eglDestroySurface(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
537 EGLBoolean EGLAPIENTRY
538 eglQuerySurface(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
552 EGLBoolean EGLAPIENTRY
553 eglSurfaceAttrib(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
568 EGLBoolean EGLAPIENTRY
569 eglBindTexImage(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
583 EGLBoolean EGLAPIENTRY
584 eglReleaseTexImage(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
598 EGLBoolean EGLAPIENTRY
599 eglSwapInterval(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
622 EGLBoolean EGLAPIENTRY
623 eglSwapBuffers(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
643 EGLBoolean EGLAPIENTRY
644 eglCopyBuffers(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
660 EGLBoolean EGLAPIENTRY
661 eglWaitClient(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
687 EGLBoolean EGLAPIENTRY
688 eglWaitGL(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
709 EGLBoolean EGLAPIENTRY
710 eglWaitNative(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
736 EGLDisplay EGLAPIENTRY
737 eglGetCurrentDisplay(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
748 EGLContext EGLAPIENTRY
749 eglGetCurrentContext(void)
750 {
751 _EGLContext *ctx = _eglGetCurrentContext();
752 EGLContext ret;
753
754 ret = _eglGetContextHandle(ctx);
755
756 RETURN_EGL_SUCCESS(NULL, ret);
757 }
758
759
760 EGLSurface EGLAPIENTRY
761 eglGetCurrentSurface(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
790 EGLint EGLAPIENTRY
791 eglGetError(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
802 eglGetProcAddress(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
864 EGLBoolean EGLAPIENTRY
865 eglChooseModeMESA(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
882 EGLBoolean EGLAPIENTRY
883 eglGetModesMESA(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
898 EGLBoolean EGLAPIENTRY
899 eglGetModeAttribMESA(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
914 EGLBoolean EGLAPIENTRY
915 eglCopyContextMESA(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
935 EGLBoolean EGLAPIENTRY
936 eglGetScreensMESA(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
950 EGLSurface EGLAPIENTRY
951 eglCreateScreenSurfaceMESA(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
969 EGLBoolean EGLAPIENTRY
970 eglShowScreenSurfaceMESA(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
992 EGLBoolean EGLAPIENTRY
993 eglScreenPositionMESA(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
1007 EGLBoolean EGLAPIENTRY
1008 eglQueryScreenMESA(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
1023 EGLBoolean EGLAPIENTRY
1024 eglQueryScreenSurfaceMESA(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
1042 EGLBoolean EGLAPIENTRY
1043 eglQueryScreenModeMESA(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
1060 const char * EGLAPIENTRY
1061 eglQueryModeStringMESA(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
1080 EGLDisplay EGLAPIENTRY
1081 eglGetDRMDisplayMESA(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 */
1107 EGLBoolean EGLAPIENTRY
1108 eglBindAPI(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 */
1127 EGLenum EGLAPIENTRY
1128 eglQueryAPI(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
1140 EGLSurface EGLAPIENTRY
1141 eglCreatePbufferFromClientBuffer(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
1161 EGLBoolean EGLAPIENTRY
1162 eglReleaseThread(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
1200 EGLImageKHR EGLAPIENTRY
1201 eglCreateImageKHR(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
1222 EGLBoolean EGLAPIENTRY
1223 eglDestroyImageKHR(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
1246 EGLBoolean EGLAPIENTRY
1247 eglSwapBuffersRegionNOK(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 */