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