egl: Add EGL_WAYLAND_PLANE_WL attribute
[mesa.git] / src / egl / main / eglapi.c
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010-2011 LunarG, Inc.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 **************************************************************************/
29
30
31 /**
32 * Public EGL API entrypoints
33 *
34 * Generally, we use the EGLDisplay parameter as a key to lookup the
35 * appropriate device driver handle, then jump though the driver's
36 * dispatch table to handle the function.
37 *
38 * That allows us the option of supporting multiple, simultaneous,
39 * heterogeneous hardware devices in the future.
40 *
41 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
42 * opaque handles. Internal objects are linked to a display to
43 * create the handles.
44 *
45 * For each public API entry point, the opaque handles are looked up
46 * before being dispatched to the drivers. When it fails to look up
47 * a handle, one of
48 *
49 * EGL_BAD_DISPLAY
50 * EGL_BAD_CONFIG
51 * EGL_BAD_CONTEXT
52 * EGL_BAD_SURFACE
53 * EGL_BAD_SCREEN_MESA
54 * EGL_BAD_MODE_MESA
55 *
56 * is generated and the driver function is not called. An
57 * uninitialized EGLDisplay has no driver associated with it. When
58 * such display is detected,
59 *
60 * EGL_NOT_INITIALIZED
61 *
62 * is generated.
63 *
64 * Some of the entry points use current display, context, or surface
65 * implicitly. For such entry points, the implicit objects are also
66 * checked before calling the driver function. Other than the
67 * errors listed above,
68 *
69 * EGL_BAD_CURRENT_SURFACE
70 *
71 * may also be generated.
72 *
73 * Notes on naming conventions:
74 *
75 * eglFooBar - public EGL function
76 * EGL_FOO_BAR - public EGL token
77 * EGLDatatype - public EGL datatype
78 *
79 * _eglFooBar - private EGL function
80 * _EGLDatatype - private EGL datatype, typedef'd struct
81 * _egl_struct - private EGL struct, non-typedef'd
82 *
83 */
84
85
86 #include <stdio.h>
87 #include <stdlib.h>
88 #include <string.h>
89
90 #include "eglcontext.h"
91 #include "egldisplay.h"
92 #include "egltypedefs.h"
93 #include "eglcurrent.h"
94 #include "egldriver.h"
95 #include "eglsurface.h"
96 #include "eglconfig.h"
97 #include "eglscreen.h"
98 #include "eglmode.h"
99 #include "eglimage.h"
100 #include "eglsync.h"
101
102
103 /**
104 * Macros to help return an API entrypoint.
105 *
106 * These macros will unlock the display and record the error code.
107 */
108 #define RETURN_EGL_ERROR(disp, err, ret) \
109 do { \
110 if (disp) \
111 _eglUnlockDisplay(disp); \
112 /* EGL error codes are non-zero */ \
113 if (err) \
114 _eglError(err, __FUNCTION__); \
115 return ret; \
116 } while (0)
117
118 #define RETURN_EGL_SUCCESS(disp, ret) \
119 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
120
121 /* record EGL_SUCCESS only when ret evaluates to true */
122 #define RETURN_EGL_EVAL(disp, ret) \
123 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
124
125
126 /*
127 * A bunch of macros and checks to simplify error checking.
128 */
129
130 #define _EGL_CHECK_DISPLAY(disp, ret, drv) \
131 do { \
132 drv = _eglCheckDisplay(disp, __FUNCTION__); \
133 if (!drv) \
134 RETURN_EGL_ERROR(disp, 0, ret); \
135 } while (0)
136
137 #define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
138 do { \
139 drv = _eglCheck ## type(disp, obj, __FUNCTION__); \
140 if (!drv) \
141 RETURN_EGL_ERROR(disp, 0, ret); \
142 } while (0)
143
144 #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
145 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
146
147 #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
148 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
149
150 #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
151 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
152
153 #define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
154 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
155
156 #define _EGL_CHECK_MODE(disp, m, ret, drv) \
157 _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
158
159 #define _EGL_CHECK_SYNC(disp, s, ret, drv) \
160 _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
161
162
163 static INLINE _EGLDriver *
164 _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
165 {
166 if (!disp) {
167 _eglError(EGL_BAD_DISPLAY, msg);
168 return NULL;
169 }
170 if (!disp->Initialized) {
171 _eglError(EGL_NOT_INITIALIZED, msg);
172 return NULL;
173 }
174 return disp->Driver;
175 }
176
177
178 static INLINE _EGLDriver *
179 _eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
180 {
181 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
182 if (!drv)
183 return NULL;
184 if (!surf) {
185 _eglError(EGL_BAD_SURFACE, msg);
186 return NULL;
187 }
188 return drv;
189 }
190
191
192 static INLINE _EGLDriver *
193 _eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
194 {
195 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
196 if (!drv)
197 return NULL;
198 if (!context) {
199 _eglError(EGL_BAD_CONTEXT, msg);
200 return NULL;
201 }
202 return drv;
203 }
204
205
206 static INLINE _EGLDriver *
207 _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
208 {
209 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
210 if (!drv)
211 return NULL;
212 if (!conf) {
213 _eglError(EGL_BAD_CONFIG, msg);
214 return NULL;
215 }
216 return drv;
217 }
218
219
220 static INLINE _EGLDriver *
221 _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
222 {
223 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
224 if (!drv)
225 return NULL;
226 if (!s) {
227 _eglError(EGL_BAD_PARAMETER, msg);
228 return NULL;
229 }
230 return drv;
231 }
232
233
234 #ifdef EGL_MESA_screen_surface
235
236
237 static INLINE _EGLDriver *
238 _eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
239 {
240 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
241 if (!drv)
242 return NULL;
243 if (!scrn) {
244 _eglError(EGL_BAD_SCREEN_MESA, msg);
245 return NULL;
246 }
247 return drv;
248 }
249
250
251 static INLINE _EGLDriver *
252 _eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
253 {
254 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
255 if (!drv)
256 return NULL;
257 if (!m) {
258 _eglError(EGL_BAD_MODE_MESA, msg);
259 return NULL;
260 }
261 return drv;
262 }
263
264
265 #endif /* EGL_MESA_screen_surface */
266
267
268 /**
269 * Lookup and lock a display.
270 */
271 static INLINE _EGLDisplay *
272 _eglLockDisplay(EGLDisplay display)
273 {
274 _EGLDisplay *dpy = _eglLookupDisplay(display);
275 if (dpy)
276 _eglLockMutex(&dpy->Mutex);
277 return dpy;
278 }
279
280
281 /**
282 * Unlock a display.
283 */
284 static INLINE void
285 _eglUnlockDisplay(_EGLDisplay *dpy)
286 {
287 _eglUnlockMutex(&dpy->Mutex);
288 }
289
290
291 /**
292 * This is typically the first EGL function that an application calls.
293 * It associates a private _EGLDisplay object to the native display.
294 */
295 EGLDisplay EGLAPIENTRY
296 eglGetDisplay(EGLNativeDisplayType nativeDisplay)
297 {
298 _EGLPlatformType plat = _eglGetNativePlatform(nativeDisplay);
299 _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);
300 return _eglGetDisplayHandle(dpy);
301 }
302
303
304 /**
305 * This is typically the second EGL function that an application calls.
306 * Here we load/initialize the actual hardware driver.
307 */
308 EGLBoolean EGLAPIENTRY
309 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
310 {
311 _EGLDisplay *disp = _eglLockDisplay(dpy);
312
313 if (!disp)
314 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
315
316 if (!disp->Initialized) {
317 if (!_eglMatchDriver(disp, EGL_FALSE))
318 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
319
320 /* limit to APIs supported by core */
321 disp->ClientAPIs &= _EGL_API_ALL_BITS;
322 }
323
324 /* Update applications version of major and minor if not NULL */
325 if ((major != NULL) && (minor != NULL)) {
326 *major = disp->VersionMajor;
327 *minor = disp->VersionMinor;
328 }
329
330 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
331 }
332
333
334 EGLBoolean EGLAPIENTRY
335 eglTerminate(EGLDisplay dpy)
336 {
337 _EGLDisplay *disp = _eglLockDisplay(dpy);
338
339 if (!disp)
340 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
341
342 if (disp->Initialized) {
343 _EGLDriver *drv = disp->Driver;
344
345 drv->API.Terminate(drv, disp);
346 /* do not reset disp->Driver */
347 disp->Initialized = EGL_FALSE;
348 }
349
350 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
351 }
352
353
354 const char * EGLAPIENTRY
355 eglQueryString(EGLDisplay dpy, EGLint name)
356 {
357 _EGLDisplay *disp = _eglLockDisplay(dpy);
358 _EGLDriver *drv;
359 const char *ret;
360
361 _EGL_CHECK_DISPLAY(disp, NULL, drv);
362 ret = drv->API.QueryString(drv, disp, name);
363
364 RETURN_EGL_EVAL(disp, ret);
365 }
366
367
368 EGLBoolean EGLAPIENTRY
369 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
370 EGLint config_size, EGLint *num_config)
371 {
372 _EGLDisplay *disp = _eglLockDisplay(dpy);
373 _EGLDriver *drv;
374 EGLBoolean ret;
375
376 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
377 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
378
379 RETURN_EGL_EVAL(disp, ret);
380 }
381
382
383 EGLBoolean EGLAPIENTRY
384 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
385 EGLint config_size, EGLint *num_config)
386 {
387 _EGLDisplay *disp = _eglLockDisplay(dpy);
388 _EGLDriver *drv;
389 EGLBoolean ret;
390
391 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
392 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
393 config_size, num_config);
394
395 RETURN_EGL_EVAL(disp, ret);
396 }
397
398
399 EGLBoolean EGLAPIENTRY
400 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
401 EGLint attribute, EGLint *value)
402 {
403 _EGLDisplay *disp = _eglLockDisplay(dpy);
404 _EGLConfig *conf = _eglLookupConfig(config, disp);
405 _EGLDriver *drv;
406 EGLBoolean ret;
407
408 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
409 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
410
411 RETURN_EGL_EVAL(disp, ret);
412 }
413
414
415 EGLContext EGLAPIENTRY
416 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
417 const EGLint *attrib_list)
418 {
419 _EGLDisplay *disp = _eglLockDisplay(dpy);
420 _EGLConfig *conf = _eglLookupConfig(config, disp);
421 _EGLContext *share = _eglLookupContext(share_list, disp);
422 _EGLDriver *drv;
423 _EGLContext *context;
424 EGLContext ret;
425
426 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
427
428 if (!config) {
429 /* config may be NULL if surfaceless */
430 if (!disp->Extensions.KHR_surfaceless_gles1 &&
431 !disp->Extensions.KHR_surfaceless_gles2 &&
432 !disp->Extensions.KHR_surfaceless_opengl)
433 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
434 }
435
436 if (!share && share_list != EGL_NO_CONTEXT)
437 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
438
439 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
440 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
441
442 RETURN_EGL_EVAL(disp, ret);
443 }
444
445
446 EGLBoolean EGLAPIENTRY
447 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
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 _eglUnlinkContext(context);
456 ret = drv->API.DestroyContext(drv, disp, context);
457
458 RETURN_EGL_EVAL(disp, ret);
459 }
460
461
462 EGLBoolean EGLAPIENTRY
463 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
464 EGLContext ctx)
465 {
466 _EGLDisplay *disp = _eglLockDisplay(dpy);
467 _EGLContext *context = _eglLookupContext(ctx, disp);
468 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
469 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
470 _EGLDriver *drv;
471 EGLBoolean ret;
472
473 if (!disp)
474 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
475 drv = disp->Driver;
476
477 /* display is allowed to be uninitialized under certain condition */
478 if (!disp->Initialized) {
479 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
480 ctx != EGL_NO_CONTEXT)
481 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
482 }
483 if (!drv)
484 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
485
486 if (!context && ctx != EGL_NO_CONTEXT)
487 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
488 if (!draw_surf || !read_surf) {
489 /* surfaces may be NULL if surfaceless */
490 if (!disp->Extensions.KHR_surfaceless_gles1 &&
491 !disp->Extensions.KHR_surfaceless_gles2 &&
492 !disp->Extensions.KHR_surfaceless_opengl)
493 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
494
495 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
496 (!read_surf && read != EGL_NO_SURFACE))
497 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
498 if (draw_surf || read_surf)
499 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
500 }
501
502 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
503
504 RETURN_EGL_EVAL(disp, ret);
505 }
506
507
508 EGLBoolean EGLAPIENTRY
509 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
510 EGLint attribute, EGLint *value)
511 {
512 _EGLDisplay *disp = _eglLockDisplay(dpy);
513 _EGLContext *context = _eglLookupContext(ctx, disp);
514 _EGLDriver *drv;
515 EGLBoolean ret;
516
517 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
518 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
519
520 RETURN_EGL_EVAL(disp, ret);
521 }
522
523
524 EGLSurface EGLAPIENTRY
525 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
526 EGLNativeWindowType window, const EGLint *attrib_list)
527 {
528 _EGLDisplay *disp = _eglLockDisplay(dpy);
529 _EGLConfig *conf = _eglLookupConfig(config, disp);
530 _EGLDriver *drv;
531 _EGLSurface *surf;
532 EGLSurface ret;
533
534 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
535 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
536 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
537
538 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
539 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
540
541 RETURN_EGL_EVAL(disp, ret);
542 }
543
544
545 EGLSurface EGLAPIENTRY
546 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
547 EGLNativePixmapType pixmap, const EGLint *attrib_list)
548 {
549 _EGLDisplay *disp = _eglLockDisplay(dpy);
550 _EGLConfig *conf = _eglLookupConfig(config, disp);
551 _EGLDriver *drv;
552 _EGLSurface *surf;
553 EGLSurface ret;
554
555 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
556 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
557 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
558
559 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
560 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
561
562 RETURN_EGL_EVAL(disp, ret);
563 }
564
565
566 EGLSurface EGLAPIENTRY
567 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
568 const EGLint *attrib_list)
569 {
570 _EGLDisplay *disp = _eglLockDisplay(dpy);
571 _EGLConfig *conf = _eglLookupConfig(config, disp);
572 _EGLDriver *drv;
573 _EGLSurface *surf;
574 EGLSurface ret;
575
576 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
577
578 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
579 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
580
581 RETURN_EGL_EVAL(disp, ret);
582 }
583
584
585 EGLBoolean EGLAPIENTRY
586 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
587 {
588 _EGLDisplay *disp = _eglLockDisplay(dpy);
589 _EGLSurface *surf = _eglLookupSurface(surface, disp);
590 _EGLDriver *drv;
591 EGLBoolean ret;
592
593 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
594 _eglUnlinkSurface(surf);
595 ret = drv->API.DestroySurface(drv, disp, surf);
596
597 RETURN_EGL_EVAL(disp, ret);
598 }
599
600 EGLBoolean EGLAPIENTRY
601 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
602 EGLint attribute, EGLint *value)
603 {
604 _EGLDisplay *disp = _eglLockDisplay(dpy);
605 _EGLSurface *surf = _eglLookupSurface(surface, disp);
606 _EGLDriver *drv;
607 EGLBoolean ret;
608
609 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
610 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
611
612 RETURN_EGL_EVAL(disp, ret);
613 }
614
615 EGLBoolean EGLAPIENTRY
616 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
617 EGLint attribute, EGLint value)
618 {
619 _EGLDisplay *disp = _eglLockDisplay(dpy);
620 _EGLSurface *surf = _eglLookupSurface(surface, disp);
621 _EGLDriver *drv;
622 EGLBoolean ret;
623
624 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
625 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
626
627 RETURN_EGL_EVAL(disp, ret);
628 }
629
630
631 EGLBoolean EGLAPIENTRY
632 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
633 {
634 _EGLDisplay *disp = _eglLockDisplay(dpy);
635 _EGLSurface *surf = _eglLookupSurface(surface, disp);
636 _EGLDriver *drv;
637 EGLBoolean ret;
638
639 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
640 ret = drv->API.BindTexImage(drv, disp, surf, buffer);
641
642 RETURN_EGL_EVAL(disp, ret);
643 }
644
645
646 EGLBoolean EGLAPIENTRY
647 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
648 {
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 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
656
657 RETURN_EGL_EVAL(disp, ret);
658 }
659
660
661 EGLBoolean EGLAPIENTRY
662 eglSwapInterval(EGLDisplay dpy, EGLint interval)
663 {
664 _EGLDisplay *disp = _eglLockDisplay(dpy);
665 _EGLContext *ctx = _eglGetCurrentContext();
666 _EGLSurface *surf;
667 _EGLDriver *drv;
668 EGLBoolean ret;
669
670 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
671
672 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
673 ctx->Resource.Display != disp)
674 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
675
676 surf = ctx->DrawSurface;
677 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
678 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
679
680 ret = drv->API.SwapInterval(drv, disp, surf, interval);
681
682 RETURN_EGL_EVAL(disp, ret);
683 }
684
685
686 EGLBoolean EGLAPIENTRY
687 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
688 {
689 _EGLContext *ctx = _eglGetCurrentContext();
690 _EGLDisplay *disp = _eglLockDisplay(dpy);
691 _EGLSurface *surf = _eglLookupSurface(surface, disp);
692 _EGLDriver *drv;
693 EGLBoolean ret;
694
695 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
696
697 /* surface must be bound to current context in EGL 1.4 */
698 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
699 surf != ctx->DrawSurface)
700 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
701
702 ret = drv->API.SwapBuffers(drv, disp, surf);
703
704 RETURN_EGL_EVAL(disp, ret);
705 }
706
707
708 EGLBoolean EGLAPIENTRY
709 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
710 {
711 _EGLDisplay *disp = _eglLockDisplay(dpy);
712 _EGLSurface *surf = _eglLookupSurface(surface, disp);
713 _EGLDriver *drv;
714 EGLBoolean ret;
715
716 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
717 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
718 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
719 ret = drv->API.CopyBuffers(drv, disp, surf, target);
720
721 RETURN_EGL_EVAL(disp, ret);
722 }
723
724
725 EGLBoolean EGLAPIENTRY
726 eglWaitClient(void)
727 {
728 _EGLContext *ctx = _eglGetCurrentContext();
729 _EGLDisplay *disp;
730 _EGLDriver *drv;
731 EGLBoolean ret;
732
733 if (!ctx)
734 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
735
736 disp = ctx->Resource.Display;
737 _eglLockMutex(&disp->Mutex);
738
739 /* let bad current context imply bad current surface */
740 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
741 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
742 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
743
744 /* a valid current context implies an initialized current display */
745 assert(disp->Initialized);
746 drv = disp->Driver;
747 ret = drv->API.WaitClient(drv, disp, ctx);
748
749 RETURN_EGL_EVAL(disp, ret);
750 }
751
752
753 EGLBoolean EGLAPIENTRY
754 eglWaitGL(void)
755 {
756 _EGLThreadInfo *t = _eglGetCurrentThread();
757 EGLint api_index = t->CurrentAPIIndex;
758 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
759 EGLBoolean ret;
760
761 if (api_index != es_index && _eglIsCurrentThreadDummy())
762 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
763
764 t->CurrentAPIIndex = es_index;
765 ret = eglWaitClient();
766 t->CurrentAPIIndex = api_index;
767 return ret;
768 }
769
770
771 EGLBoolean EGLAPIENTRY
772 eglWaitNative(EGLint engine)
773 {
774 _EGLContext *ctx = _eglGetCurrentContext();
775 _EGLDisplay *disp;
776 _EGLDriver *drv;
777 EGLBoolean ret;
778
779 if (!ctx)
780 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
781
782 disp = ctx->Resource.Display;
783 _eglLockMutex(&disp->Mutex);
784
785 /* let bad current context imply bad current surface */
786 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
787 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
788 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
789
790 /* a valid current context implies an initialized current display */
791 assert(disp->Initialized);
792 drv = disp->Driver;
793 ret = drv->API.WaitNative(drv, disp, engine);
794
795 RETURN_EGL_EVAL(disp, ret);
796 }
797
798
799 EGLDisplay EGLAPIENTRY
800 eglGetCurrentDisplay(void)
801 {
802 _EGLContext *ctx = _eglGetCurrentContext();
803 EGLDisplay ret;
804
805 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
806
807 RETURN_EGL_SUCCESS(NULL, ret);
808 }
809
810
811 EGLContext EGLAPIENTRY
812 eglGetCurrentContext(void)
813 {
814 _EGLContext *ctx = _eglGetCurrentContext();
815 EGLContext ret;
816
817 ret = _eglGetContextHandle(ctx);
818
819 RETURN_EGL_SUCCESS(NULL, ret);
820 }
821
822
823 EGLSurface EGLAPIENTRY
824 eglGetCurrentSurface(EGLint readdraw)
825 {
826 _EGLContext *ctx = _eglGetCurrentContext();
827 EGLint err = EGL_SUCCESS;
828 _EGLSurface *surf;
829 EGLSurface ret;
830
831 if (!ctx)
832 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
833
834 switch (readdraw) {
835 case EGL_DRAW:
836 surf = ctx->DrawSurface;
837 break;
838 case EGL_READ:
839 surf = ctx->ReadSurface;
840 break;
841 default:
842 surf = NULL;
843 err = EGL_BAD_PARAMETER;
844 break;
845 }
846
847 ret = _eglGetSurfaceHandle(surf);
848
849 RETURN_EGL_ERROR(NULL, err, ret);
850 }
851
852
853 EGLint EGLAPIENTRY
854 eglGetError(void)
855 {
856 _EGLThreadInfo *t = _eglGetCurrentThread();
857 EGLint e = t->LastError;
858 if (!_eglIsCurrentThreadDummy())
859 t->LastError = EGL_SUCCESS;
860 return e;
861 }
862
863
864 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
865 eglGetProcAddress(const char *procname)
866 {
867 static const struct {
868 const char *name;
869 _EGLProc function;
870 } egl_functions[] = {
871 /* core functions should not be queryable, but, well... */
872 #ifdef _EGL_GET_CORE_ADDRESSES
873 /* alphabetical order */
874 { "eglBindAPI", (_EGLProc) eglBindAPI },
875 { "eglBindTexImage", (_EGLProc) eglBindTexImage },
876 { "eglChooseConfig", (_EGLProc) eglChooseConfig },
877 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
878 { "eglCreateContext", (_EGLProc) eglCreateContext },
879 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
880 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
881 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
882 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
883 { "eglDestroyContext", (_EGLProc) eglDestroyContext },
884 { "eglDestroySurface", (_EGLProc) eglDestroySurface },
885 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
886 { "eglGetConfigs", (_EGLProc) eglGetConfigs },
887 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
888 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
889 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
890 { "eglGetDisplay", (_EGLProc) eglGetDisplay },
891 { "eglGetError", (_EGLProc) eglGetError },
892 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
893 { "eglInitialize", (_EGLProc) eglInitialize },
894 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
895 { "eglQueryAPI", (_EGLProc) eglQueryAPI },
896 { "eglQueryContext", (_EGLProc) eglQueryContext },
897 { "eglQueryString", (_EGLProc) eglQueryString },
898 { "eglQuerySurface", (_EGLProc) eglQuerySurface },
899 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
900 { "eglReleaseThread", (_EGLProc) eglReleaseThread },
901 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
902 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
903 { "eglSwapInterval", (_EGLProc) eglSwapInterval },
904 { "eglTerminate", (_EGLProc) eglTerminate },
905 { "eglWaitClient", (_EGLProc) eglWaitClient },
906 { "eglWaitGL", (_EGLProc) eglWaitGL },
907 { "eglWaitNative", (_EGLProc) eglWaitNative },
908 #endif /* _EGL_GET_CORE_ADDRESSES */
909 #ifdef EGL_MESA_screen_surface
910 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
911 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
912 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
913 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
914 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
915 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
916 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
917 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
918 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
919 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
920 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
921 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
922 #endif /* EGL_MESA_screen_surface */
923 #ifdef EGL_MESA_drm_display
924 { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
925 #endif
926 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
927 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
928 { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
929 { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
930 { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
931 { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
932 { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
933 #ifdef EGL_NOK_swap_region
934 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
935 #endif
936 #ifdef EGL_MESA_drm_image
937 { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
938 { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
939 #endif
940 #ifdef EGL_WL_bind_wayland_display
941 { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
942 { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
943 { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
944 #endif
945 { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
946 { NULL, NULL }
947 };
948 EGLint i;
949 _EGLProc ret;
950
951 if (!procname)
952 RETURN_EGL_SUCCESS(NULL, NULL);
953
954 ret = NULL;
955 if (strncmp(procname, "egl", 3) == 0) {
956 for (i = 0; egl_functions[i].name; i++) {
957 if (strcmp(egl_functions[i].name, procname) == 0) {
958 ret = egl_functions[i].function;
959 break;
960 }
961 }
962 }
963 if (!ret)
964 ret = _eglGetDriverProc(procname);
965
966 RETURN_EGL_SUCCESS(NULL, ret);
967 }
968
969
970 #ifdef EGL_MESA_screen_surface
971
972
973 /*
974 * EGL_MESA_screen extension
975 */
976
977 EGLBoolean EGLAPIENTRY
978 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
979 const EGLint *attrib_list, EGLModeMESA *modes,
980 EGLint modes_size, EGLint *num_modes)
981 {
982 _EGLDisplay *disp = _eglLockDisplay(dpy);
983 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
984 _EGLDriver *drv;
985 EGLBoolean ret;
986
987 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
988 ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
989 modes, modes_size, num_modes);
990
991 RETURN_EGL_EVAL(disp, ret);
992 }
993
994
995 EGLBoolean EGLAPIENTRY
996 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
997 EGLint mode_size, EGLint *num_mode)
998 {
999 _EGLDisplay *disp = _eglLockDisplay(dpy);
1000 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1001 _EGLDriver *drv;
1002 EGLBoolean ret;
1003
1004 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1005 ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
1006
1007 RETURN_EGL_EVAL(disp, ret);
1008 }
1009
1010
1011 EGLBoolean EGLAPIENTRY
1012 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
1013 EGLint attribute, EGLint *value)
1014 {
1015 _EGLDisplay *disp = _eglLockDisplay(dpy);
1016 _EGLMode *m = _eglLookupMode(mode, disp);
1017 _EGLDriver *drv;
1018 EGLBoolean ret;
1019
1020 _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
1021 ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
1022
1023 RETURN_EGL_EVAL(disp, ret);
1024 }
1025
1026
1027 EGLBoolean EGLAPIENTRY
1028 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
1029 EGLint mask)
1030 {
1031 _EGLDisplay *disp = _eglLockDisplay(dpy);
1032 _EGLContext *source_context = _eglLookupContext(source, disp);
1033 _EGLContext *dest_context = _eglLookupContext(dest, disp);
1034 _EGLDriver *drv;
1035 EGLBoolean ret;
1036
1037 _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
1038 if (!dest_context)
1039 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
1040
1041 ret = drv->API.CopyContextMESA(drv, disp,
1042 source_context, dest_context, mask);
1043
1044 RETURN_EGL_EVAL(disp, ret);
1045 }
1046
1047
1048 EGLBoolean EGLAPIENTRY
1049 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
1050 EGLint max_screens, EGLint *num_screens)
1051 {
1052 _EGLDisplay *disp = _eglLockDisplay(dpy);
1053 _EGLDriver *drv;
1054 EGLBoolean ret;
1055
1056 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1057 ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
1058
1059 RETURN_EGL_EVAL(disp, ret);
1060 }
1061
1062
1063 EGLSurface EGLAPIENTRY
1064 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
1065 const EGLint *attrib_list)
1066 {
1067 _EGLDisplay *disp = _eglLockDisplay(dpy);
1068 _EGLConfig *conf = _eglLookupConfig(config, disp);
1069 _EGLDriver *drv;
1070 _EGLSurface *surf;
1071 EGLSurface ret;
1072
1073 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1074
1075 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
1076 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1077
1078 RETURN_EGL_EVAL(disp, ret);
1079 }
1080
1081
1082 EGLBoolean EGLAPIENTRY
1083 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
1084 EGLSurface surface, EGLModeMESA mode)
1085 {
1086 _EGLDisplay *disp = _eglLockDisplay(dpy);
1087 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1088 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1089 _EGLMode *m = _eglLookupMode(mode, disp);
1090 _EGLDriver *drv;
1091 EGLBoolean ret;
1092
1093 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1094 if (!surf && surface != EGL_NO_SURFACE)
1095 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1096 if (!m && mode != EGL_NO_MODE_MESA)
1097 RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
1098
1099 ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
1100
1101 RETURN_EGL_EVAL(disp, ret);
1102 }
1103
1104
1105 EGLBoolean EGLAPIENTRY
1106 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
1107 {
1108 _EGLDisplay *disp = _eglLockDisplay(dpy);
1109 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1110 _EGLDriver *drv;
1111 EGLBoolean ret;
1112
1113 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1114 ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
1115
1116 RETURN_EGL_EVAL(disp, ret);
1117 }
1118
1119
1120 EGLBoolean EGLAPIENTRY
1121 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
1122 EGLint attribute, EGLint *value)
1123 {
1124 _EGLDisplay *disp = _eglLockDisplay(dpy);
1125 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1126 _EGLDriver *drv;
1127 EGLBoolean ret;
1128
1129 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1130 ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
1131
1132 RETURN_EGL_EVAL(disp, ret);
1133 }
1134
1135
1136 EGLBoolean EGLAPIENTRY
1137 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
1138 EGLSurface *surface)
1139 {
1140 _EGLDisplay *disp = _eglLockDisplay(dpy);
1141 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1142 _EGLDriver *drv;
1143 _EGLSurface *surf;
1144 EGLBoolean ret;
1145
1146 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1147 ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
1148 if (ret && surface)
1149 *surface = _eglGetSurfaceHandle(surf);
1150
1151 RETURN_EGL_EVAL(disp, ret);
1152 }
1153
1154
1155 EGLBoolean EGLAPIENTRY
1156 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
1157 {
1158 _EGLDisplay *disp = _eglLockDisplay(dpy);
1159 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1160 _EGLDriver *drv;
1161 _EGLMode *m;
1162 EGLBoolean ret;
1163
1164 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1165 ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
1166 if (ret && mode)
1167 *mode = m->Handle;
1168
1169 RETURN_EGL_EVAL(disp, ret);
1170 }
1171
1172
1173 const char * EGLAPIENTRY
1174 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
1175 {
1176 _EGLDisplay *disp = _eglLockDisplay(dpy);
1177 _EGLMode *m = _eglLookupMode(mode, disp);
1178 _EGLDriver *drv;
1179 const char *ret;
1180
1181 _EGL_CHECK_MODE(disp, m, NULL, drv);
1182 ret = drv->API.QueryModeStringMESA(drv, disp, m);
1183
1184 RETURN_EGL_EVAL(disp, ret);
1185 }
1186
1187
1188 #endif /* EGL_MESA_screen_surface */
1189
1190
1191 #ifdef EGL_MESA_drm_display
1192
1193 EGLDisplay EGLAPIENTRY
1194 eglGetDRMDisplayMESA(int fd)
1195 {
1196 _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
1197 return _eglGetDisplayHandle(dpy);
1198 }
1199
1200 #endif /* EGL_MESA_drm_display */
1201
1202 /**
1203 ** EGL 1.2
1204 **/
1205
1206 /**
1207 * Specify the client API to use for subsequent calls including:
1208 * eglCreateContext()
1209 * eglGetCurrentContext()
1210 * eglGetCurrentDisplay()
1211 * eglGetCurrentSurface()
1212 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1213 * eglWaitClient()
1214 * eglWaitNative()
1215 * See section 3.7 "Rendering Context" in the EGL specification for details.
1216 */
1217 EGLBoolean EGLAPIENTRY
1218 eglBindAPI(EGLenum api)
1219 {
1220 _EGLThreadInfo *t = _eglGetCurrentThread();
1221
1222 if (_eglIsCurrentThreadDummy())
1223 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1224
1225 if (!_eglIsApiValid(api))
1226 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1227
1228 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
1229
1230 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1231 }
1232
1233
1234 /**
1235 * Return the last value set with eglBindAPI().
1236 */
1237 EGLenum EGLAPIENTRY
1238 eglQueryAPI(void)
1239 {
1240 _EGLThreadInfo *t = _eglGetCurrentThread();
1241 EGLenum ret;
1242
1243 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1244 ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
1245
1246 RETURN_EGL_SUCCESS(NULL, ret);
1247 }
1248
1249
1250 EGLSurface EGLAPIENTRY
1251 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1252 EGLClientBuffer buffer, EGLConfig config,
1253 const EGLint *attrib_list)
1254 {
1255 _EGLDisplay *disp = _eglLockDisplay(dpy);
1256 _EGLConfig *conf = _eglLookupConfig(config, disp);
1257 _EGLDriver *drv;
1258 _EGLSurface *surf;
1259 EGLSurface ret;
1260
1261 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1262
1263 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1264 conf, attrib_list);
1265 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1266
1267 RETURN_EGL_EVAL(disp, ret);
1268 }
1269
1270
1271 EGLBoolean EGLAPIENTRY
1272 eglReleaseThread(void)
1273 {
1274 /* unbind current contexts */
1275 if (!_eglIsCurrentThreadDummy()) {
1276 _EGLThreadInfo *t = _eglGetCurrentThread();
1277 EGLint api_index = t->CurrentAPIIndex;
1278 EGLint i;
1279
1280 for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1281 _EGLContext *ctx = t->CurrentContexts[i];
1282 if (ctx) {
1283 _EGLDisplay *disp = ctx->Resource.Display;
1284 _EGLDriver *drv;
1285
1286 t->CurrentAPIIndex = i;
1287
1288 _eglLockMutex(&disp->Mutex);
1289 drv = disp->Driver;
1290 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1291 _eglUnlockMutex(&disp->Mutex);
1292 }
1293 }
1294
1295 t->CurrentAPIIndex = api_index;
1296 }
1297
1298 _eglDestroyCurrentThread();
1299
1300 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1301 }
1302
1303
1304 EGLImageKHR EGLAPIENTRY
1305 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1306 EGLClientBuffer buffer, const EGLint *attr_list)
1307 {
1308 _EGLDisplay *disp = _eglLockDisplay(dpy);
1309 _EGLContext *context = _eglLookupContext(ctx, disp);
1310 _EGLDriver *drv;
1311 _EGLImage *img;
1312 EGLImageKHR ret;
1313
1314 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1315 if (!disp->Extensions.KHR_image_base)
1316 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1317 if (!context && ctx != EGL_NO_CONTEXT)
1318 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1319
1320 img = drv->API.CreateImageKHR(drv,
1321 disp, context, target, buffer, attr_list);
1322 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1323
1324 RETURN_EGL_EVAL(disp, ret);
1325 }
1326
1327
1328 EGLBoolean EGLAPIENTRY
1329 eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1330 {
1331 _EGLDisplay *disp = _eglLockDisplay(dpy);
1332 _EGLImage *img = _eglLookupImage(image, disp);
1333 _EGLDriver *drv;
1334 EGLBoolean ret;
1335
1336 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1337 if (!disp->Extensions.KHR_image_base)
1338 RETURN_EGL_EVAL(disp, EGL_FALSE);
1339 if (!img)
1340 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1341
1342 _eglUnlinkImage(img);
1343 ret = drv->API.DestroyImageKHR(drv, disp, img);
1344
1345 RETURN_EGL_EVAL(disp, ret);
1346 }
1347
1348
1349 EGLSyncKHR EGLAPIENTRY
1350 eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1351 {
1352 _EGLDisplay *disp = _eglLockDisplay(dpy);
1353 _EGLDriver *drv;
1354 _EGLSync *sync;
1355 EGLSyncKHR ret;
1356
1357 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
1358 if (!disp->Extensions.KHR_reusable_sync)
1359 RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
1360
1361 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
1362 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
1363
1364 RETURN_EGL_EVAL(disp, ret);
1365 }
1366
1367
1368 EGLBoolean EGLAPIENTRY
1369 eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1370 {
1371 _EGLDisplay *disp = _eglLockDisplay(dpy);
1372 _EGLSync *s = _eglLookupSync(sync, disp);
1373 _EGLDriver *drv;
1374 EGLBoolean ret;
1375
1376 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1377 assert(disp->Extensions.KHR_reusable_sync);
1378
1379 _eglUnlinkSync(s);
1380 ret = drv->API.DestroySyncKHR(drv, disp, s);
1381
1382 RETURN_EGL_EVAL(disp, ret);
1383 }
1384
1385
1386 EGLint EGLAPIENTRY
1387 eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1388 {
1389 _EGLDisplay *disp = _eglLockDisplay(dpy);
1390 _EGLSync *s = _eglLookupSync(sync, disp);
1391 _EGLDriver *drv;
1392 EGLint ret;
1393
1394 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1395 assert(disp->Extensions.KHR_reusable_sync);
1396 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1397
1398 RETURN_EGL_EVAL(disp, ret);
1399 }
1400
1401
1402 EGLBoolean EGLAPIENTRY
1403 eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
1404 {
1405 _EGLDisplay *disp = _eglLockDisplay(dpy);
1406 _EGLSync *s = _eglLookupSync(sync, disp);
1407 _EGLDriver *drv;
1408 EGLBoolean ret;
1409
1410 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1411 assert(disp->Extensions.KHR_reusable_sync);
1412 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
1413
1414 RETURN_EGL_EVAL(disp, ret);
1415 }
1416
1417
1418 EGLBoolean EGLAPIENTRY
1419 eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1420 {
1421 _EGLDisplay *disp = _eglLockDisplay(dpy);
1422 _EGLSync *s = _eglLookupSync(sync, disp);
1423 _EGLDriver *drv;
1424 EGLBoolean ret;
1425
1426 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1427 assert(disp->Extensions.KHR_reusable_sync);
1428 ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
1429
1430 RETURN_EGL_EVAL(disp, ret);
1431 }
1432
1433
1434 #ifdef EGL_NOK_swap_region
1435
1436 EGLBoolean EGLAPIENTRY
1437 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1438 EGLint numRects, const EGLint *rects)
1439 {
1440 _EGLContext *ctx = _eglGetCurrentContext();
1441 _EGLDisplay *disp = _eglLockDisplay(dpy);
1442 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1443 _EGLDriver *drv;
1444 EGLBoolean ret;
1445
1446 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1447
1448 if (!disp->Extensions.NOK_swap_region)
1449 RETURN_EGL_EVAL(disp, EGL_FALSE);
1450
1451 /* surface must be bound to current context in EGL 1.4 */
1452 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1453 surf != ctx->DrawSurface)
1454 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1455
1456 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
1457
1458 RETURN_EGL_EVAL(disp, ret);
1459 }
1460
1461 #endif /* EGL_NOK_swap_region */
1462
1463
1464 #ifdef EGL_MESA_drm_image
1465
1466 EGLImageKHR EGLAPIENTRY
1467 eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
1468 {
1469 _EGLDisplay *disp = _eglLockDisplay(dpy);
1470 _EGLDriver *drv;
1471 _EGLImage *img;
1472 EGLImageKHR ret;
1473
1474 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1475 if (!disp->Extensions.MESA_drm_image)
1476 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1477
1478 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
1479 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1480
1481 RETURN_EGL_EVAL(disp, ret);
1482 }
1483
1484 EGLBoolean EGLAPIENTRY
1485 eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
1486 EGLint *name, EGLint *handle, EGLint *stride)
1487 {
1488 _EGLDisplay *disp = _eglLockDisplay(dpy);
1489 _EGLImage *img = _eglLookupImage(image, disp);
1490 _EGLDriver *drv;
1491 EGLBoolean ret;
1492
1493 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1494 assert(disp->Extensions.MESA_drm_image);
1495
1496 if (!img)
1497 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1498
1499 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
1500
1501 RETURN_EGL_EVAL(disp, ret);
1502 }
1503
1504 #endif
1505
1506 #ifdef EGL_WL_bind_wayland_display
1507 struct wl_display;
1508
1509 EGLBoolean EGLAPIENTRY
1510 eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1511 {
1512 _EGLDisplay *disp = _eglLockDisplay(dpy);
1513 _EGLDriver *drv;
1514 EGLBoolean ret;
1515
1516 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1517 assert(disp->Extensions.WL_bind_wayland_display);
1518
1519 if (!display)
1520 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1521
1522 ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
1523
1524 RETURN_EGL_EVAL(disp, ret);
1525 }
1526
1527 EGLBoolean EGLAPIENTRY
1528 eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1529 {
1530 _EGLDisplay *disp = _eglLockDisplay(dpy);
1531 _EGLDriver *drv;
1532 EGLBoolean ret;
1533
1534 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1535 assert(disp->Extensions.WL_bind_wayland_display);
1536
1537 if (!display)
1538 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1539
1540 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
1541
1542 RETURN_EGL_EVAL(disp, ret);
1543 }
1544
1545 EGLBoolean EGLAPIENTRY
1546 eglQueryWaylandBufferWL(EGLDisplay dpy,struct wl_buffer *buffer,
1547 EGLint attribute, EGLint *value)
1548 {
1549 _EGLDisplay *disp = _eglLockDisplay(dpy);
1550 _EGLDriver *drv;
1551 EGLBoolean ret;
1552
1553 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1554 assert(disp->Extensions.WL_bind_wayland_display);
1555
1556 if (!buffer)
1557 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1558
1559 ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
1560
1561 RETURN_EGL_EVAL(disp, ret);
1562 }
1563 #endif
1564
1565
1566 EGLBoolean EGLAPIENTRY
1567 eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
1568 EGLint x, EGLint y, EGLint width, EGLint height)
1569 {
1570 _EGLDisplay *disp = _eglLockDisplay(dpy);
1571 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1572 _EGLDriver *drv;
1573 EGLBoolean ret;
1574
1575 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1576
1577 if (!disp->Extensions.NV_post_sub_buffer)
1578 RETURN_EGL_EVAL(disp, EGL_FALSE);
1579
1580 ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
1581
1582 RETURN_EGL_EVAL(disp, ret);
1583 }