egl: Replace KHR_surfaceless_* extensions with KHR_surfaceless_context
[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_context)
431 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
432 }
433
434 if (!share && share_list != EGL_NO_CONTEXT)
435 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
436
437 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
438 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
439
440 RETURN_EGL_EVAL(disp, ret);
441 }
442
443
444 EGLBoolean EGLAPIENTRY
445 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
446 {
447 _EGLDisplay *disp = _eglLockDisplay(dpy);
448 _EGLContext *context = _eglLookupContext(ctx, disp);
449 _EGLDriver *drv;
450 EGLBoolean ret;
451
452 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
453 _eglUnlinkContext(context);
454 ret = drv->API.DestroyContext(drv, disp, context);
455
456 RETURN_EGL_EVAL(disp, ret);
457 }
458
459
460 EGLBoolean EGLAPIENTRY
461 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
462 EGLContext ctx)
463 {
464 _EGLDisplay *disp = _eglLockDisplay(dpy);
465 _EGLContext *context = _eglLookupContext(ctx, disp);
466 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
467 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
468 _EGLDriver *drv;
469 EGLBoolean ret;
470
471 if (!disp)
472 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
473 drv = disp->Driver;
474
475 /* display is allowed to be uninitialized under certain condition */
476 if (!disp->Initialized) {
477 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
478 ctx != EGL_NO_CONTEXT)
479 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
480 }
481 if (!drv)
482 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
483
484 if (!context && ctx != EGL_NO_CONTEXT)
485 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
486 if (!draw_surf || !read_surf) {
487 /* surfaces may be NULL if surfaceless */
488 if (!disp->Extensions.KHR_surfaceless_context)
489 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
490
491 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
492 (!read_surf && read != EGL_NO_SURFACE))
493 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
494 if (draw_surf || read_surf)
495 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
496 }
497
498 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
499
500 RETURN_EGL_EVAL(disp, ret);
501 }
502
503
504 EGLBoolean EGLAPIENTRY
505 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
506 EGLint attribute, EGLint *value)
507 {
508 _EGLDisplay *disp = _eglLockDisplay(dpy);
509 _EGLContext *context = _eglLookupContext(ctx, disp);
510 _EGLDriver *drv;
511 EGLBoolean ret;
512
513 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
514 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
515
516 RETURN_EGL_EVAL(disp, ret);
517 }
518
519
520 EGLSurface EGLAPIENTRY
521 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
522 EGLNativeWindowType window, const EGLint *attrib_list)
523 {
524 _EGLDisplay *disp = _eglLockDisplay(dpy);
525 _EGLConfig *conf = _eglLookupConfig(config, disp);
526 _EGLDriver *drv;
527 _EGLSurface *surf;
528 EGLSurface ret;
529
530 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
531 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
532 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
533
534 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
535 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
536
537 RETURN_EGL_EVAL(disp, ret);
538 }
539
540
541 EGLSurface EGLAPIENTRY
542 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
543 EGLNativePixmapType pixmap, const EGLint *attrib_list)
544 {
545 _EGLDisplay *disp = _eglLockDisplay(dpy);
546 _EGLConfig *conf = _eglLookupConfig(config, disp);
547 _EGLDriver *drv;
548 _EGLSurface *surf;
549 EGLSurface ret;
550
551 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
552 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
553 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
554
555 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
556 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
557
558 RETURN_EGL_EVAL(disp, ret);
559 }
560
561
562 EGLSurface EGLAPIENTRY
563 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
564 const EGLint *attrib_list)
565 {
566 _EGLDisplay *disp = _eglLockDisplay(dpy);
567 _EGLConfig *conf = _eglLookupConfig(config, disp);
568 _EGLDriver *drv;
569 _EGLSurface *surf;
570 EGLSurface ret;
571
572 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
573
574 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
575 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
576
577 RETURN_EGL_EVAL(disp, ret);
578 }
579
580
581 EGLBoolean EGLAPIENTRY
582 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
583 {
584 _EGLDisplay *disp = _eglLockDisplay(dpy);
585 _EGLSurface *surf = _eglLookupSurface(surface, disp);
586 _EGLDriver *drv;
587 EGLBoolean ret;
588
589 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
590 _eglUnlinkSurface(surf);
591 ret = drv->API.DestroySurface(drv, disp, surf);
592
593 RETURN_EGL_EVAL(disp, ret);
594 }
595
596 EGLBoolean EGLAPIENTRY
597 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
598 EGLint attribute, EGLint *value)
599 {
600 _EGLDisplay *disp = _eglLockDisplay(dpy);
601 _EGLSurface *surf = _eglLookupSurface(surface, disp);
602 _EGLDriver *drv;
603 EGLBoolean ret;
604
605 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
606 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
607
608 RETURN_EGL_EVAL(disp, ret);
609 }
610
611 EGLBoolean EGLAPIENTRY
612 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
613 EGLint attribute, EGLint value)
614 {
615 _EGLDisplay *disp = _eglLockDisplay(dpy);
616 _EGLSurface *surf = _eglLookupSurface(surface, disp);
617 _EGLDriver *drv;
618 EGLBoolean ret;
619
620 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
621 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
622
623 RETURN_EGL_EVAL(disp, ret);
624 }
625
626
627 EGLBoolean EGLAPIENTRY
628 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
629 {
630 _EGLDisplay *disp = _eglLockDisplay(dpy);
631 _EGLSurface *surf = _eglLookupSurface(surface, disp);
632 _EGLDriver *drv;
633 EGLBoolean ret;
634
635 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
636 ret = drv->API.BindTexImage(drv, disp, surf, buffer);
637
638 RETURN_EGL_EVAL(disp, ret);
639 }
640
641
642 EGLBoolean EGLAPIENTRY
643 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
644 {
645 _EGLDisplay *disp = _eglLockDisplay(dpy);
646 _EGLSurface *surf = _eglLookupSurface(surface, disp);
647 _EGLDriver *drv;
648 EGLBoolean ret;
649
650 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
651 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
652
653 RETURN_EGL_EVAL(disp, ret);
654 }
655
656
657 EGLBoolean EGLAPIENTRY
658 eglSwapInterval(EGLDisplay dpy, EGLint interval)
659 {
660 _EGLDisplay *disp = _eglLockDisplay(dpy);
661 _EGLContext *ctx = _eglGetCurrentContext();
662 _EGLSurface *surf;
663 _EGLDriver *drv;
664 EGLBoolean ret;
665
666 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
667
668 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
669 ctx->Resource.Display != disp)
670 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
671
672 surf = ctx->DrawSurface;
673 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
674 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
675
676 ret = drv->API.SwapInterval(drv, disp, surf, interval);
677
678 RETURN_EGL_EVAL(disp, ret);
679 }
680
681
682 EGLBoolean EGLAPIENTRY
683 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
684 {
685 _EGLContext *ctx = _eglGetCurrentContext();
686 _EGLDisplay *disp = _eglLockDisplay(dpy);
687 _EGLSurface *surf = _eglLookupSurface(surface, disp);
688 _EGLDriver *drv;
689 EGLBoolean ret;
690
691 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
692
693 /* surface must be bound to current context in EGL 1.4 */
694 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
695 surf != ctx->DrawSurface)
696 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
697
698 ret = drv->API.SwapBuffers(drv, disp, surf);
699
700 RETURN_EGL_EVAL(disp, ret);
701 }
702
703
704 EGLBoolean EGLAPIENTRY
705 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
706 {
707 _EGLDisplay *disp = _eglLockDisplay(dpy);
708 _EGLSurface *surf = _eglLookupSurface(surface, disp);
709 _EGLDriver *drv;
710 EGLBoolean ret;
711
712 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
713 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
714 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
715 ret = drv->API.CopyBuffers(drv, disp, surf, target);
716
717 RETURN_EGL_EVAL(disp, ret);
718 }
719
720
721 EGLBoolean EGLAPIENTRY
722 eglWaitClient(void)
723 {
724 _EGLContext *ctx = _eglGetCurrentContext();
725 _EGLDisplay *disp;
726 _EGLDriver *drv;
727 EGLBoolean ret;
728
729 if (!ctx)
730 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
731
732 disp = ctx->Resource.Display;
733 _eglLockMutex(&disp->Mutex);
734
735 /* let bad current context imply bad current surface */
736 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
737 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
738 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
739
740 /* a valid current context implies an initialized current display */
741 assert(disp->Initialized);
742 drv = disp->Driver;
743 ret = drv->API.WaitClient(drv, disp, ctx);
744
745 RETURN_EGL_EVAL(disp, ret);
746 }
747
748
749 EGLBoolean EGLAPIENTRY
750 eglWaitGL(void)
751 {
752 _EGLThreadInfo *t = _eglGetCurrentThread();
753 EGLint api_index = t->CurrentAPIIndex;
754 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
755 EGLBoolean ret;
756
757 if (api_index != es_index && _eglIsCurrentThreadDummy())
758 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
759
760 t->CurrentAPIIndex = es_index;
761 ret = eglWaitClient();
762 t->CurrentAPIIndex = api_index;
763 return ret;
764 }
765
766
767 EGLBoolean EGLAPIENTRY
768 eglWaitNative(EGLint engine)
769 {
770 _EGLContext *ctx = _eglGetCurrentContext();
771 _EGLDisplay *disp;
772 _EGLDriver *drv;
773 EGLBoolean ret;
774
775 if (!ctx)
776 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
777
778 disp = ctx->Resource.Display;
779 _eglLockMutex(&disp->Mutex);
780
781 /* let bad current context imply bad current surface */
782 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
783 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
784 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
785
786 /* a valid current context implies an initialized current display */
787 assert(disp->Initialized);
788 drv = disp->Driver;
789 ret = drv->API.WaitNative(drv, disp, engine);
790
791 RETURN_EGL_EVAL(disp, ret);
792 }
793
794
795 EGLDisplay EGLAPIENTRY
796 eglGetCurrentDisplay(void)
797 {
798 _EGLContext *ctx = _eglGetCurrentContext();
799 EGLDisplay ret;
800
801 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
802
803 RETURN_EGL_SUCCESS(NULL, ret);
804 }
805
806
807 EGLContext EGLAPIENTRY
808 eglGetCurrentContext(void)
809 {
810 _EGLContext *ctx = _eglGetCurrentContext();
811 EGLContext ret;
812
813 ret = _eglGetContextHandle(ctx);
814
815 RETURN_EGL_SUCCESS(NULL, ret);
816 }
817
818
819 EGLSurface EGLAPIENTRY
820 eglGetCurrentSurface(EGLint readdraw)
821 {
822 _EGLContext *ctx = _eglGetCurrentContext();
823 EGLint err = EGL_SUCCESS;
824 _EGLSurface *surf;
825 EGLSurface ret;
826
827 if (!ctx)
828 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
829
830 switch (readdraw) {
831 case EGL_DRAW:
832 surf = ctx->DrawSurface;
833 break;
834 case EGL_READ:
835 surf = ctx->ReadSurface;
836 break;
837 default:
838 surf = NULL;
839 err = EGL_BAD_PARAMETER;
840 break;
841 }
842
843 ret = _eglGetSurfaceHandle(surf);
844
845 RETURN_EGL_ERROR(NULL, err, ret);
846 }
847
848
849 EGLint EGLAPIENTRY
850 eglGetError(void)
851 {
852 _EGLThreadInfo *t = _eglGetCurrentThread();
853 EGLint e = t->LastError;
854 if (!_eglIsCurrentThreadDummy())
855 t->LastError = EGL_SUCCESS;
856 return e;
857 }
858
859
860 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
861 eglGetProcAddress(const char *procname)
862 {
863 static const struct {
864 const char *name;
865 _EGLProc function;
866 } egl_functions[] = {
867 /* core functions should not be queryable, but, well... */
868 #ifdef _EGL_GET_CORE_ADDRESSES
869 /* alphabetical order */
870 { "eglBindAPI", (_EGLProc) eglBindAPI },
871 { "eglBindTexImage", (_EGLProc) eglBindTexImage },
872 { "eglChooseConfig", (_EGLProc) eglChooseConfig },
873 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
874 { "eglCreateContext", (_EGLProc) eglCreateContext },
875 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
876 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
877 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
878 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
879 { "eglDestroyContext", (_EGLProc) eglDestroyContext },
880 { "eglDestroySurface", (_EGLProc) eglDestroySurface },
881 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
882 { "eglGetConfigs", (_EGLProc) eglGetConfigs },
883 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
884 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
885 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
886 { "eglGetDisplay", (_EGLProc) eglGetDisplay },
887 { "eglGetError", (_EGLProc) eglGetError },
888 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
889 { "eglInitialize", (_EGLProc) eglInitialize },
890 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
891 { "eglQueryAPI", (_EGLProc) eglQueryAPI },
892 { "eglQueryContext", (_EGLProc) eglQueryContext },
893 { "eglQueryString", (_EGLProc) eglQueryString },
894 { "eglQuerySurface", (_EGLProc) eglQuerySurface },
895 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
896 { "eglReleaseThread", (_EGLProc) eglReleaseThread },
897 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
898 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
899 { "eglSwapInterval", (_EGLProc) eglSwapInterval },
900 { "eglTerminate", (_EGLProc) eglTerminate },
901 { "eglWaitClient", (_EGLProc) eglWaitClient },
902 { "eglWaitGL", (_EGLProc) eglWaitGL },
903 { "eglWaitNative", (_EGLProc) eglWaitNative },
904 #endif /* _EGL_GET_CORE_ADDRESSES */
905 #ifdef EGL_MESA_screen_surface
906 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
907 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
908 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
909 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
910 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
911 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
912 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
913 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
914 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
915 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
916 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
917 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
918 #endif /* EGL_MESA_screen_surface */
919 #ifdef EGL_MESA_drm_display
920 { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
921 #endif
922 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
923 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
924 { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
925 { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
926 { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
927 { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
928 { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
929 #ifdef EGL_NOK_swap_region
930 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
931 #endif
932 #ifdef EGL_MESA_drm_image
933 { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
934 { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
935 #endif
936 #ifdef EGL_WL_bind_wayland_display
937 { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
938 { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
939 { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
940 #endif
941 { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
942 { NULL, NULL }
943 };
944 EGLint i;
945 _EGLProc ret;
946
947 if (!procname)
948 RETURN_EGL_SUCCESS(NULL, NULL);
949
950 ret = NULL;
951 if (strncmp(procname, "egl", 3) == 0) {
952 for (i = 0; egl_functions[i].name; i++) {
953 if (strcmp(egl_functions[i].name, procname) == 0) {
954 ret = egl_functions[i].function;
955 break;
956 }
957 }
958 }
959 if (!ret)
960 ret = _eglGetDriverProc(procname);
961
962 RETURN_EGL_SUCCESS(NULL, ret);
963 }
964
965
966 #ifdef EGL_MESA_screen_surface
967
968
969 /*
970 * EGL_MESA_screen extension
971 */
972
973 EGLBoolean EGLAPIENTRY
974 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
975 const EGLint *attrib_list, EGLModeMESA *modes,
976 EGLint modes_size, EGLint *num_modes)
977 {
978 _EGLDisplay *disp = _eglLockDisplay(dpy);
979 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
980 _EGLDriver *drv;
981 EGLBoolean ret;
982
983 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
984 ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
985 modes, modes_size, num_modes);
986
987 RETURN_EGL_EVAL(disp, ret);
988 }
989
990
991 EGLBoolean EGLAPIENTRY
992 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
993 EGLint mode_size, EGLint *num_mode)
994 {
995 _EGLDisplay *disp = _eglLockDisplay(dpy);
996 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
997 _EGLDriver *drv;
998 EGLBoolean ret;
999
1000 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1001 ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
1002
1003 RETURN_EGL_EVAL(disp, ret);
1004 }
1005
1006
1007 EGLBoolean EGLAPIENTRY
1008 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
1009 EGLint attribute, EGLint *value)
1010 {
1011 _EGLDisplay *disp = _eglLockDisplay(dpy);
1012 _EGLMode *m = _eglLookupMode(mode, disp);
1013 _EGLDriver *drv;
1014 EGLBoolean ret;
1015
1016 _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
1017 ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
1018
1019 RETURN_EGL_EVAL(disp, ret);
1020 }
1021
1022
1023 EGLBoolean EGLAPIENTRY
1024 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
1025 EGLint mask)
1026 {
1027 _EGLDisplay *disp = _eglLockDisplay(dpy);
1028 _EGLContext *source_context = _eglLookupContext(source, disp);
1029 _EGLContext *dest_context = _eglLookupContext(dest, disp);
1030 _EGLDriver *drv;
1031 EGLBoolean ret;
1032
1033 _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
1034 if (!dest_context)
1035 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
1036
1037 ret = drv->API.CopyContextMESA(drv, disp,
1038 source_context, dest_context, mask);
1039
1040 RETURN_EGL_EVAL(disp, ret);
1041 }
1042
1043
1044 EGLBoolean EGLAPIENTRY
1045 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
1046 EGLint max_screens, EGLint *num_screens)
1047 {
1048 _EGLDisplay *disp = _eglLockDisplay(dpy);
1049 _EGLDriver *drv;
1050 EGLBoolean ret;
1051
1052 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1053 ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
1054
1055 RETURN_EGL_EVAL(disp, ret);
1056 }
1057
1058
1059 EGLSurface EGLAPIENTRY
1060 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
1061 const EGLint *attrib_list)
1062 {
1063 _EGLDisplay *disp = _eglLockDisplay(dpy);
1064 _EGLConfig *conf = _eglLookupConfig(config, disp);
1065 _EGLDriver *drv;
1066 _EGLSurface *surf;
1067 EGLSurface ret;
1068
1069 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1070
1071 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
1072 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1073
1074 RETURN_EGL_EVAL(disp, ret);
1075 }
1076
1077
1078 EGLBoolean EGLAPIENTRY
1079 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
1080 EGLSurface surface, EGLModeMESA mode)
1081 {
1082 _EGLDisplay *disp = _eglLockDisplay(dpy);
1083 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1084 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1085 _EGLMode *m = _eglLookupMode(mode, disp);
1086 _EGLDriver *drv;
1087 EGLBoolean ret;
1088
1089 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1090 if (!surf && surface != EGL_NO_SURFACE)
1091 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1092 if (!m && mode != EGL_NO_MODE_MESA)
1093 RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
1094
1095 ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
1096
1097 RETURN_EGL_EVAL(disp, ret);
1098 }
1099
1100
1101 EGLBoolean EGLAPIENTRY
1102 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
1103 {
1104 _EGLDisplay *disp = _eglLockDisplay(dpy);
1105 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1106 _EGLDriver *drv;
1107 EGLBoolean ret;
1108
1109 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1110 ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
1111
1112 RETURN_EGL_EVAL(disp, ret);
1113 }
1114
1115
1116 EGLBoolean EGLAPIENTRY
1117 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
1118 EGLint attribute, EGLint *value)
1119 {
1120 _EGLDisplay *disp = _eglLockDisplay(dpy);
1121 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1122 _EGLDriver *drv;
1123 EGLBoolean ret;
1124
1125 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1126 ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
1127
1128 RETURN_EGL_EVAL(disp, ret);
1129 }
1130
1131
1132 EGLBoolean EGLAPIENTRY
1133 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
1134 EGLSurface *surface)
1135 {
1136 _EGLDisplay *disp = _eglLockDisplay(dpy);
1137 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1138 _EGLDriver *drv;
1139 _EGLSurface *surf;
1140 EGLBoolean ret;
1141
1142 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1143 ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
1144 if (ret && surface)
1145 *surface = _eglGetSurfaceHandle(surf);
1146
1147 RETURN_EGL_EVAL(disp, ret);
1148 }
1149
1150
1151 EGLBoolean EGLAPIENTRY
1152 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
1153 {
1154 _EGLDisplay *disp = _eglLockDisplay(dpy);
1155 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1156 _EGLDriver *drv;
1157 _EGLMode *m;
1158 EGLBoolean ret;
1159
1160 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1161 ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
1162 if (ret && mode)
1163 *mode = m->Handle;
1164
1165 RETURN_EGL_EVAL(disp, ret);
1166 }
1167
1168
1169 const char * EGLAPIENTRY
1170 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
1171 {
1172 _EGLDisplay *disp = _eglLockDisplay(dpy);
1173 _EGLMode *m = _eglLookupMode(mode, disp);
1174 _EGLDriver *drv;
1175 const char *ret;
1176
1177 _EGL_CHECK_MODE(disp, m, NULL, drv);
1178 ret = drv->API.QueryModeStringMESA(drv, disp, m);
1179
1180 RETURN_EGL_EVAL(disp, ret);
1181 }
1182
1183
1184 #endif /* EGL_MESA_screen_surface */
1185
1186
1187 #ifdef EGL_MESA_drm_display
1188
1189 EGLDisplay EGLAPIENTRY
1190 eglGetDRMDisplayMESA(int fd)
1191 {
1192 _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
1193 return _eglGetDisplayHandle(dpy);
1194 }
1195
1196 #endif /* EGL_MESA_drm_display */
1197
1198 /**
1199 ** EGL 1.2
1200 **/
1201
1202 /**
1203 * Specify the client API to use for subsequent calls including:
1204 * eglCreateContext()
1205 * eglGetCurrentContext()
1206 * eglGetCurrentDisplay()
1207 * eglGetCurrentSurface()
1208 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1209 * eglWaitClient()
1210 * eglWaitNative()
1211 * See section 3.7 "Rendering Context" in the EGL specification for details.
1212 */
1213 EGLBoolean EGLAPIENTRY
1214 eglBindAPI(EGLenum api)
1215 {
1216 _EGLThreadInfo *t = _eglGetCurrentThread();
1217
1218 if (_eglIsCurrentThreadDummy())
1219 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1220
1221 if (!_eglIsApiValid(api))
1222 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1223
1224 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
1225
1226 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1227 }
1228
1229
1230 /**
1231 * Return the last value set with eglBindAPI().
1232 */
1233 EGLenum EGLAPIENTRY
1234 eglQueryAPI(void)
1235 {
1236 _EGLThreadInfo *t = _eglGetCurrentThread();
1237 EGLenum ret;
1238
1239 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1240 ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
1241
1242 RETURN_EGL_SUCCESS(NULL, ret);
1243 }
1244
1245
1246 EGLSurface EGLAPIENTRY
1247 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1248 EGLClientBuffer buffer, EGLConfig config,
1249 const EGLint *attrib_list)
1250 {
1251 _EGLDisplay *disp = _eglLockDisplay(dpy);
1252 _EGLConfig *conf = _eglLookupConfig(config, disp);
1253 _EGLDriver *drv;
1254 _EGLSurface *surf;
1255 EGLSurface ret;
1256
1257 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1258
1259 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1260 conf, attrib_list);
1261 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1262
1263 RETURN_EGL_EVAL(disp, ret);
1264 }
1265
1266
1267 EGLBoolean EGLAPIENTRY
1268 eglReleaseThread(void)
1269 {
1270 /* unbind current contexts */
1271 if (!_eglIsCurrentThreadDummy()) {
1272 _EGLThreadInfo *t = _eglGetCurrentThread();
1273 EGLint api_index = t->CurrentAPIIndex;
1274 EGLint i;
1275
1276 for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1277 _EGLContext *ctx = t->CurrentContexts[i];
1278 if (ctx) {
1279 _EGLDisplay *disp = ctx->Resource.Display;
1280 _EGLDriver *drv;
1281
1282 t->CurrentAPIIndex = i;
1283
1284 _eglLockMutex(&disp->Mutex);
1285 drv = disp->Driver;
1286 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1287 _eglUnlockMutex(&disp->Mutex);
1288 }
1289 }
1290
1291 t->CurrentAPIIndex = api_index;
1292 }
1293
1294 _eglDestroyCurrentThread();
1295
1296 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1297 }
1298
1299
1300 EGLImageKHR EGLAPIENTRY
1301 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1302 EGLClientBuffer buffer, const EGLint *attr_list)
1303 {
1304 _EGLDisplay *disp = _eglLockDisplay(dpy);
1305 _EGLContext *context = _eglLookupContext(ctx, disp);
1306 _EGLDriver *drv;
1307 _EGLImage *img;
1308 EGLImageKHR ret;
1309
1310 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1311 if (!disp->Extensions.KHR_image_base)
1312 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1313 if (!context && ctx != EGL_NO_CONTEXT)
1314 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1315
1316 img = drv->API.CreateImageKHR(drv,
1317 disp, context, target, buffer, attr_list);
1318 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1319
1320 RETURN_EGL_EVAL(disp, ret);
1321 }
1322
1323
1324 EGLBoolean EGLAPIENTRY
1325 eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1326 {
1327 _EGLDisplay *disp = _eglLockDisplay(dpy);
1328 _EGLImage *img = _eglLookupImage(image, disp);
1329 _EGLDriver *drv;
1330 EGLBoolean ret;
1331
1332 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1333 if (!disp->Extensions.KHR_image_base)
1334 RETURN_EGL_EVAL(disp, EGL_FALSE);
1335 if (!img)
1336 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1337
1338 _eglUnlinkImage(img);
1339 ret = drv->API.DestroyImageKHR(drv, disp, img);
1340
1341 RETURN_EGL_EVAL(disp, ret);
1342 }
1343
1344
1345 EGLSyncKHR EGLAPIENTRY
1346 eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1347 {
1348 _EGLDisplay *disp = _eglLockDisplay(dpy);
1349 _EGLDriver *drv;
1350 _EGLSync *sync;
1351 EGLSyncKHR ret;
1352
1353 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
1354 if (!disp->Extensions.KHR_reusable_sync)
1355 RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
1356
1357 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
1358 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
1359
1360 RETURN_EGL_EVAL(disp, ret);
1361 }
1362
1363
1364 EGLBoolean EGLAPIENTRY
1365 eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1366 {
1367 _EGLDisplay *disp = _eglLockDisplay(dpy);
1368 _EGLSync *s = _eglLookupSync(sync, disp);
1369 _EGLDriver *drv;
1370 EGLBoolean ret;
1371
1372 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1373 assert(disp->Extensions.KHR_reusable_sync);
1374
1375 _eglUnlinkSync(s);
1376 ret = drv->API.DestroySyncKHR(drv, disp, s);
1377
1378 RETURN_EGL_EVAL(disp, ret);
1379 }
1380
1381
1382 EGLint EGLAPIENTRY
1383 eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1384 {
1385 _EGLDisplay *disp = _eglLockDisplay(dpy);
1386 _EGLSync *s = _eglLookupSync(sync, disp);
1387 _EGLDriver *drv;
1388 EGLint ret;
1389
1390 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1391 assert(disp->Extensions.KHR_reusable_sync);
1392 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1393
1394 RETURN_EGL_EVAL(disp, ret);
1395 }
1396
1397
1398 EGLBoolean EGLAPIENTRY
1399 eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
1400 {
1401 _EGLDisplay *disp = _eglLockDisplay(dpy);
1402 _EGLSync *s = _eglLookupSync(sync, disp);
1403 _EGLDriver *drv;
1404 EGLBoolean ret;
1405
1406 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1407 assert(disp->Extensions.KHR_reusable_sync);
1408 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
1409
1410 RETURN_EGL_EVAL(disp, ret);
1411 }
1412
1413
1414 EGLBoolean EGLAPIENTRY
1415 eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1416 {
1417 _EGLDisplay *disp = _eglLockDisplay(dpy);
1418 _EGLSync *s = _eglLookupSync(sync, disp);
1419 _EGLDriver *drv;
1420 EGLBoolean ret;
1421
1422 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1423 assert(disp->Extensions.KHR_reusable_sync);
1424 ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
1425
1426 RETURN_EGL_EVAL(disp, ret);
1427 }
1428
1429
1430 #ifdef EGL_NOK_swap_region
1431
1432 EGLBoolean EGLAPIENTRY
1433 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1434 EGLint numRects, const EGLint *rects)
1435 {
1436 _EGLContext *ctx = _eglGetCurrentContext();
1437 _EGLDisplay *disp = _eglLockDisplay(dpy);
1438 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1439 _EGLDriver *drv;
1440 EGLBoolean ret;
1441
1442 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1443
1444 if (!disp->Extensions.NOK_swap_region)
1445 RETURN_EGL_EVAL(disp, EGL_FALSE);
1446
1447 /* surface must be bound to current context in EGL 1.4 */
1448 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1449 surf != ctx->DrawSurface)
1450 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1451
1452 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
1453
1454 RETURN_EGL_EVAL(disp, ret);
1455 }
1456
1457 #endif /* EGL_NOK_swap_region */
1458
1459
1460 #ifdef EGL_MESA_drm_image
1461
1462 EGLImageKHR EGLAPIENTRY
1463 eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
1464 {
1465 _EGLDisplay *disp = _eglLockDisplay(dpy);
1466 _EGLDriver *drv;
1467 _EGLImage *img;
1468 EGLImageKHR ret;
1469
1470 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1471 if (!disp->Extensions.MESA_drm_image)
1472 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1473
1474 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
1475 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1476
1477 RETURN_EGL_EVAL(disp, ret);
1478 }
1479
1480 EGLBoolean EGLAPIENTRY
1481 eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
1482 EGLint *name, EGLint *handle, EGLint *stride)
1483 {
1484 _EGLDisplay *disp = _eglLockDisplay(dpy);
1485 _EGLImage *img = _eglLookupImage(image, disp);
1486 _EGLDriver *drv;
1487 EGLBoolean ret;
1488
1489 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1490 assert(disp->Extensions.MESA_drm_image);
1491
1492 if (!img)
1493 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1494
1495 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
1496
1497 RETURN_EGL_EVAL(disp, ret);
1498 }
1499
1500 #endif
1501
1502 #ifdef EGL_WL_bind_wayland_display
1503 struct wl_display;
1504
1505 EGLBoolean EGLAPIENTRY
1506 eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1507 {
1508 _EGLDisplay *disp = _eglLockDisplay(dpy);
1509 _EGLDriver *drv;
1510 EGLBoolean ret;
1511
1512 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1513 assert(disp->Extensions.WL_bind_wayland_display);
1514
1515 if (!display)
1516 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1517
1518 ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
1519
1520 RETURN_EGL_EVAL(disp, ret);
1521 }
1522
1523 EGLBoolean EGLAPIENTRY
1524 eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1525 {
1526 _EGLDisplay *disp = _eglLockDisplay(dpy);
1527 _EGLDriver *drv;
1528 EGLBoolean ret;
1529
1530 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1531 assert(disp->Extensions.WL_bind_wayland_display);
1532
1533 if (!display)
1534 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1535
1536 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
1537
1538 RETURN_EGL_EVAL(disp, ret);
1539 }
1540
1541 EGLBoolean EGLAPIENTRY
1542 eglQueryWaylandBufferWL(EGLDisplay dpy,struct wl_buffer *buffer,
1543 EGLint attribute, EGLint *value)
1544 {
1545 _EGLDisplay *disp = _eglLockDisplay(dpy);
1546 _EGLDriver *drv;
1547 EGLBoolean ret;
1548
1549 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1550 assert(disp->Extensions.WL_bind_wayland_display);
1551
1552 if (!buffer)
1553 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1554
1555 ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
1556
1557 RETURN_EGL_EVAL(disp, ret);
1558 }
1559 #endif
1560
1561
1562 EGLBoolean EGLAPIENTRY
1563 eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
1564 EGLint x, EGLint y, EGLint width, EGLint height)
1565 {
1566 _EGLDisplay *disp = _eglLockDisplay(dpy);
1567 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1568 _EGLDriver *drv;
1569 EGLBoolean ret;
1570
1571 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1572
1573 if (!disp->Extensions.NV_post_sub_buffer)
1574 RETURN_EGL_EVAL(disp, EGL_FALSE);
1575
1576 ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
1577
1578 RETURN_EGL_EVAL(disp, ret);
1579 }