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