egl: Update headers.
[mesa.git] / src / egl / main / eglapi.c
1 /**
2 * Public EGL API entrypoints
3 *
4 * Generally, we use the EGLDisplay parameter as a key to lookup the
5 * appropriate device driver handle, then jump though the driver's
6 * dispatch table to handle the function.
7 *
8 * That allows us the option of supporting multiple, simultaneous,
9 * heterogeneous hardware devices in the future.
10 *
11 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
12 * opaque handles. Internal objects are linked to a display to
13 * create the handles.
14 *
15 * For each public API entry point, the opaque handles are looked up
16 * before being dispatched to the drivers. When it fails to look up
17 * a handle, one of
18 *
19 * EGL_BAD_DISPLAY
20 * EGL_BAD_CONFIG
21 * EGL_BAD_CONTEXT
22 * EGL_BAD_SURFACE
23 * EGL_BAD_SCREEN_MESA
24 * EGL_BAD_MODE_MESA
25 *
26 * is generated and the driver function is not called. An
27 * uninitialized EGLDisplay has no driver associated with it. When
28 * such display is detected,
29 *
30 * EGL_NOT_INITIALIZED
31 *
32 * is generated.
33 *
34 * Some of the entry points use current display, context, or surface
35 * implicitly. For such entry points, the implicit objects are also
36 * checked before calling the driver function. Other than the
37 * errors listed above,
38 *
39 * EGL_BAD_CURRENT_SURFACE
40 *
41 * may also be generated.
42 *
43 * Notes on naming conventions:
44 *
45 * eglFooBar - public EGL function
46 * EGL_FOO_BAR - public EGL token
47 * EGLDatatype - public EGL datatype
48 *
49 * _eglFooBar - private EGL function
50 * _EGLDatatype - private EGL datatype, typedef'd struct
51 * _egl_struct - private EGL struct, non-typedef'd
52 *
53 */
54
55
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include "eglcontext.h"
60 #include "egldisplay.h"
61 #include "egltypedefs.h"
62 #include "eglglobals.h"
63 #include "egldriver.h"
64 #include "eglsurface.h"
65 #include "eglconfig.h"
66 #include "eglscreen.h"
67 #include "eglmode.h"
68
69
70 /**
71 * This is typically the first EGL function that an application calls.
72 * We initialize our global vars and create a private _EGLDisplay object.
73 */
74 EGLDisplay EGLAPIENTRY
75 eglGetDisplay(NativeDisplayType nativeDisplay)
76 {
77 _EGLDisplay *dpy;
78 dpy = _eglFindDisplay(nativeDisplay);
79 if (!dpy) {
80 dpy = _eglNewDisplay(nativeDisplay);
81 if (dpy)
82 _eglLinkDisplay(dpy);
83 }
84 return _eglGetDisplayHandle(dpy);
85 }
86
87
88 /**
89 * This is typically the second EGL function that an application calls.
90 * Here we load/initialize the actual hardware driver.
91 */
92 EGLBoolean EGLAPIENTRY
93 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
94 {
95 _EGLDisplay *disp = _eglLookupDisplay(dpy);
96 _EGLDriver *drv;
97 EGLint major_int, minor_int;
98
99 if (!disp)
100 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
101
102 drv = disp->Driver;
103 if (!drv) {
104 _eglPreloadDrivers();
105
106 drv = _eglOpenDriver(disp);
107 if (!drv)
108 return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
109
110 /* Initialize the particular display now */
111 if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) {
112 _eglCloseDriver(drv, disp);
113 return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
114 }
115
116 disp->APImajor = major_int;
117 disp->APIminor = minor_int;
118 snprintf(disp->Version, sizeof(disp->Version),
119 "%d.%d (%s)", major_int, minor_int, drv->Name);
120
121 /* limit to APIs supported by core */
122 disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
123
124 disp->Driver = drv;
125 } else {
126 major_int = disp->APImajor;
127 minor_int = disp->APIminor;
128 }
129
130 /* Update applications version of major and minor if not NULL */
131 if ((major != NULL) && (minor != NULL)) {
132 *major = major_int;
133 *minor = minor_int;
134 }
135
136 return EGL_TRUE;
137 }
138
139
140 EGLBoolean EGLAPIENTRY
141 eglTerminate(EGLDisplay dpy)
142 {
143 _EGLDisplay *disp = _eglLookupDisplay(dpy);
144 _EGLDriver *drv;
145
146 if (!disp)
147 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
148
149 drv = disp->Driver;
150 if (drv) {
151 drv->API.Terminate(drv, disp);
152 _eglCloseDriver(drv, disp);
153 disp->Driver = NULL;
154 }
155
156 return EGL_TRUE;
157 }
158
159
160 /**
161 * A bunch of check functions and declare macros to simply error checking.
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->Driver) {
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 #define _EGL_DECLARE_DD(dpy) \
221 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
222 _EGLDriver *drv; \
223 do { \
224 drv = _eglCheckDisplay(disp, __FUNCTION__); \
225 if (!drv) \
226 return EGL_FALSE; \
227 } while (0)
228
229
230 #define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \
231 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
232 _EGLSurface *surf = _eglLookupSurface((surface), disp); \
233 _EGLDriver *drv; \
234 do { \
235 drv = _eglCheckSurface(disp, surf, __FUNCTION__); \
236 if (!drv) \
237 return EGL_FALSE; \
238 } while (0)
239
240
241 #define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \
242 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
243 _EGLContext *context = _eglLookupContext((ctx), disp); \
244 _EGLDriver *drv; \
245 do { \
246 drv = _eglCheckContext(disp, context, __FUNCTION__); \
247 if (!drv) \
248 return EGL_FALSE; \
249 } while (0)
250
251
252 #ifdef EGL_MESA_screen_surface
253
254
255 static INLINE _EGLDriver *
256 _eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
257 {
258 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
259 if (!drv)
260 return NULL;
261 if (!scrn) {
262 _eglError(EGL_BAD_SCREEN_MESA, msg);
263 return NULL;
264 }
265 return drv;
266 }
267
268
269 static INLINE _EGLDriver *
270 _eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
271 {
272 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
273 if (!drv)
274 return NULL;
275 if (!m) {
276 _eglError(EGL_BAD_MODE_MESA, msg);
277 return NULL;
278 }
279 return drv;
280 }
281
282
283 #define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \
284 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
285 _EGLScreen *scrn = _eglLookupScreen((screen), disp); \
286 _EGLDriver *drv; \
287 do { \
288 drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \
289 if (!drv) \
290 return EGL_FALSE; \
291 } while (0)
292
293
294 #define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \
295 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
296 _EGLMode *m = _eglLookupMode((mode), disp); \
297 _EGLDriver *drv; \
298 do { \
299 drv = _eglCheckMode(disp, m, __FUNCTION__); \
300 if (!drv) \
301 return EGL_FALSE; \
302 } while (0)
303
304
305 #endif /* EGL_MESA_screen_surface */
306
307
308 const char * EGLAPIENTRY
309 eglQueryString(EGLDisplay dpy, EGLint name)
310 {
311 _EGL_DECLARE_DD(dpy);
312 return drv->API.QueryString(drv, disp, name);
313 }
314
315
316 EGLBoolean EGLAPIENTRY
317 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
318 EGLint config_size, EGLint *num_config)
319 {
320 _EGL_DECLARE_DD(dpy);
321 return drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
322 }
323
324
325 EGLBoolean EGLAPIENTRY
326 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
327 EGLint config_size, EGLint *num_config)
328 {
329 _EGL_DECLARE_DD(dpy);
330 return drv->API.ChooseConfig(drv, disp, attrib_list, configs,
331 config_size, num_config);
332 }
333
334
335 EGLBoolean EGLAPIENTRY
336 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
337 EGLint attribute, EGLint *value)
338 {
339 _EGLDisplay *disp = _eglLookupDisplay(dpy);
340 _EGLConfig *conf = _eglLookupConfig(config, disp);
341 _EGLDriver *drv;
342
343 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
344 if (!drv)
345 return EGL_FALSE;
346
347 return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
348 }
349
350
351 EGLContext EGLAPIENTRY
352 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
353 const EGLint *attrib_list)
354 {
355 _EGLDisplay *disp = _eglLookupDisplay(dpy);
356 _EGLConfig *conf = _eglLookupConfig(config, disp);
357 _EGLContext *share = _eglLookupContext(share_list, disp);
358 _EGLDriver *drv;
359 _EGLContext *context;
360
361 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
362 if (!drv)
363 return EGL_NO_CONTEXT;
364 if (!share && share_list != EGL_NO_CONTEXT) {
365 _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
366 return EGL_NO_CONTEXT;
367 }
368
369 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
370 if (context)
371 return _eglLinkContext(context, disp);
372 else
373 return EGL_NO_CONTEXT;
374 }
375
376
377 EGLBoolean EGLAPIENTRY
378 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
379 {
380 _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
381 _eglUnlinkContext(context);
382 return drv->API.DestroyContext(drv, disp, context);
383 }
384
385
386 EGLBoolean EGLAPIENTRY
387 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
388 EGLContext ctx)
389 {
390 _EGLDisplay *disp = _eglLookupDisplay(dpy);
391 _EGLContext *context = _eglLookupContext(ctx, disp);
392 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
393 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
394 _EGLDriver *drv;
395
396 drv = _eglCheckDisplay(disp, __FUNCTION__);
397 if (!drv)
398 return EGL_FALSE;
399 if (!context && ctx != EGL_NO_CONTEXT)
400 return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
401 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
402 (!read_surf && read != EGL_NO_SURFACE))
403 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
404
405 return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
406 }
407
408
409 EGLBoolean EGLAPIENTRY
410 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
411 EGLint attribute, EGLint *value)
412 {
413 _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
414 return drv->API.QueryContext(drv, disp, context, attribute, value);
415 }
416
417
418 EGLSurface EGLAPIENTRY
419 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
420 NativeWindowType window, const EGLint *attrib_list)
421 {
422 _EGLDisplay *disp = _eglLookupDisplay(dpy);
423 _EGLConfig *conf = _eglLookupConfig(config, disp);
424 _EGLDriver *drv;
425 _EGLSurface *surf;
426
427 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
428 if (!drv)
429 return EGL_NO_SURFACE;
430
431 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
432 if (surf)
433 return _eglLinkSurface(surf, disp);
434 else
435 return EGL_NO_SURFACE;
436 }
437
438
439 EGLSurface EGLAPIENTRY
440 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
441 NativePixmapType pixmap, const EGLint *attrib_list)
442 {
443 _EGLDisplay *disp = _eglLookupDisplay(dpy);
444 _EGLConfig *conf = _eglLookupConfig(config, disp);
445 _EGLDriver *drv;
446 _EGLSurface *surf;
447
448 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
449 if (!drv)
450 return EGL_NO_SURFACE;
451
452 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
453 if (surf)
454 return _eglLinkSurface(surf, disp);
455 else
456 return EGL_NO_SURFACE;
457 }
458
459
460 EGLSurface EGLAPIENTRY
461 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
462 const EGLint *attrib_list)
463 {
464 _EGLDisplay *disp = _eglLookupDisplay(dpy);
465 _EGLConfig *conf = _eglLookupConfig(config, disp);
466 _EGLDriver *drv;
467 _EGLSurface *surf;
468
469 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
470 if (!drv)
471 return EGL_NO_SURFACE;
472
473 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
474 if (surf)
475 return _eglLinkSurface(surf, disp);
476 else
477 return EGL_NO_SURFACE;
478 }
479
480
481 EGLBoolean EGLAPIENTRY
482 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
483 {
484 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
485 _eglUnlinkSurface(surf);
486 return drv->API.DestroySurface(drv, disp, surf);
487 }
488
489 EGLBoolean EGLAPIENTRY
490 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
491 EGLint attribute, EGLint *value)
492 {
493 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
494 return drv->API.QuerySurface(drv, disp, surf, attribute, value);
495 }
496
497 EGLBoolean EGLAPIENTRY
498 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
499 EGLint attribute, EGLint value)
500 {
501 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
502 return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
503 }
504
505
506 EGLBoolean EGLAPIENTRY
507 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
508 {
509 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
510 return drv->API.BindTexImage(drv, disp, surf, buffer);
511 }
512
513
514 EGLBoolean EGLAPIENTRY
515 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
516 {
517 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
518 return drv->API.ReleaseTexImage(drv, disp, surf, buffer);
519 }
520
521
522 EGLBoolean EGLAPIENTRY
523 eglSwapInterval(EGLDisplay dpy, EGLint interval)
524 {
525 _EGLContext *ctx = _eglGetCurrentContext();
526 _EGLSurface *surf;
527 _EGL_DECLARE_DD(dpy);
528
529 if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp)
530 return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
531
532 surf = ctx->DrawSurface;
533 if (!_eglIsSurfaceLinked(surf))
534 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
535
536 return drv->API.SwapInterval(drv, disp, surf, interval);
537 }
538
539
540 EGLBoolean EGLAPIENTRY
541 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
542 {
543 _EGLContext *ctx = _eglGetCurrentContext();
544 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
545
546 /* surface must be bound to current context in EGL 1.4 */
547 if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
548 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
549
550 return drv->API.SwapBuffers(drv, disp, surf);
551 }
552
553
554 EGLBoolean EGLAPIENTRY
555 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
556 {
557 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
558 return drv->API.CopyBuffers(drv, disp, surf, target);
559 }
560
561
562 EGLBoolean EGLAPIENTRY
563 eglWaitClient(void)
564 {
565 _EGLContext *ctx = _eglGetCurrentContext();
566 _EGLDisplay *disp;
567 _EGLDriver *drv;
568
569 if (!ctx)
570 return EGL_TRUE;
571 /* let bad current context imply bad current surface */
572 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
573 return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__);
574
575 /* a valid current context implies an initialized current display */
576 disp = ctx->Resource.Display;
577 drv = disp->Driver;
578 assert(drv);
579
580 return drv->API.WaitClient(drv, disp, ctx);
581 }
582
583
584 EGLBoolean EGLAPIENTRY
585 eglWaitGL(void)
586 {
587 #ifdef EGL_VERSION_1_2
588 _EGLThreadInfo *t = _eglGetCurrentThread();
589 EGLint api_index = t->CurrentAPIIndex;
590 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
591 EGLBoolean ret;
592
593 if (api_index != es_index && _eglIsCurrentThreadDummy())
594 return _eglError(EGL_BAD_ALLOC, "eglWaitGL");
595
596 t->CurrentAPIIndex = es_index;
597 ret = eglWaitClient();
598 t->CurrentAPIIndex = api_index;
599 return ret;
600 #else
601 return eglWaitClient();
602 #endif
603 }
604
605
606 EGLBoolean EGLAPIENTRY
607 eglWaitNative(EGLint engine)
608 {
609 _EGLContext *ctx = _eglGetCurrentContext();
610 _EGLDisplay *disp;
611 _EGLDriver *drv;
612
613 if (!ctx)
614 return EGL_TRUE;
615 /* let bad current context imply bad current surface */
616 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
617 return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__);
618
619 /* a valid current context implies an initialized current display */
620 disp = ctx->Resource.Display;
621 drv = disp->Driver;
622 assert(drv);
623
624 return drv->API.WaitNative(drv, disp, engine);
625 }
626
627
628 EGLDisplay EGLAPIENTRY
629 eglGetCurrentDisplay(void)
630 {
631 _EGLDisplay *dpy = _eglGetCurrentDisplay();
632 return _eglGetDisplayHandle(dpy);
633 }
634
635
636 EGLContext EGLAPIENTRY
637 eglGetCurrentContext(void)
638 {
639 _EGLContext *ctx = _eglGetCurrentContext();
640 return _eglGetContextHandle(ctx);
641 }
642
643
644 EGLSurface EGLAPIENTRY
645 eglGetCurrentSurface(EGLint readdraw)
646 {
647 _EGLContext *ctx = _eglGetCurrentContext();
648 _EGLSurface *surf;
649
650 if (!ctx)
651 return EGL_NO_SURFACE;
652
653 switch (readdraw) {
654 case EGL_DRAW:
655 surf = ctx->DrawSurface;
656 break;
657 case EGL_READ:
658 surf = ctx->ReadSurface;
659 break;
660 default:
661 _eglError(EGL_BAD_PARAMETER, __FUNCTION__);
662 surf = NULL;
663 break;
664 }
665
666 return _eglGetSurfaceHandle(surf);
667 }
668
669
670 EGLint EGLAPIENTRY
671 eglGetError(void)
672 {
673 _EGLThreadInfo *t = _eglGetCurrentThread();
674 EGLint e = t->LastError;
675 if (!_eglIsCurrentThreadDummy())
676 t->LastError = EGL_SUCCESS;
677 return e;
678 }
679
680
681 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
682 eglGetProcAddress(const char *procname)
683 {
684 static const struct {
685 const char *name;
686 _EGLProc function;
687 } egl_functions[] = {
688 /* extensions only */
689 #ifdef EGL_MESA_screen_surface
690 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
691 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
692 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
693 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
694 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
695 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
696 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
697 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
698 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
699 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
700 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
701 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
702 #endif /* EGL_MESA_screen_surface */
703 { NULL, NULL }
704 };
705 EGLint i;
706
707 if (!procname)
708 return NULL;
709 if (strncmp(procname, "egl", 3) == 0) {
710 for (i = 0; egl_functions[i].name; i++) {
711 if (strcmp(egl_functions[i].name, procname) == 0)
712 return egl_functions[i].function;
713 }
714 }
715
716 _eglPreloadDrivers();
717
718 /* now loop over drivers to query their procs */
719 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
720 _EGLDriver *drv = _eglGlobal.Drivers[i];
721 _EGLProc p = drv->API.GetProcAddress(drv, procname);
722 if (p)
723 return p;
724 }
725
726 return NULL;
727 }
728
729
730 #ifdef EGL_MESA_screen_surface
731
732
733 /*
734 * EGL_MESA_screen extension
735 */
736
737 EGLBoolean EGLAPIENTRY
738 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
739 const EGLint *attrib_list, EGLModeMESA *modes,
740 EGLint modes_size, EGLint *num_modes)
741 {
742 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
743 return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
744 modes, modes_size, num_modes);
745 }
746
747
748 EGLBoolean EGLAPIENTRY
749 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
750 EGLint mode_size, EGLint *num_mode)
751 {
752 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
753 return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
754 }
755
756
757 EGLBoolean EGLAPIENTRY
758 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
759 EGLint attribute, EGLint *value)
760 {
761 _EGL_DECLARE_DD_AND_MODE(dpy, mode);
762 return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
763 }
764
765
766 EGLBoolean EGLAPIENTRY
767 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
768 EGLint mask)
769 {
770 _EGLDisplay *disp = _eglLookupDisplay(dpy);
771 _EGLContext *source_context = _eglLookupContext(source, disp);
772 _EGLContext *dest_context = _eglLookupContext(dest, disp);
773 _EGLDriver *drv;
774
775 drv = _eglCheckContext(disp, source_context, __FUNCTION__);
776 if (!drv || !dest_context) {
777 if (drv)
778 _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
779 return EGL_FALSE;
780 }
781
782 return drv->API.CopyContextMESA(drv, disp, source_context, dest_context,
783 mask);
784 }
785
786
787 EGLBoolean
788 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
789 EGLint max_screens, EGLint *num_screens)
790 {
791 _EGL_DECLARE_DD(dpy);
792 return drv->API.GetScreensMESA(drv, disp, screens,
793 max_screens, num_screens);
794 }
795
796
797 EGLSurface
798 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
799 const EGLint *attrib_list)
800 {
801 _EGLDisplay *disp = _eglLookupDisplay(dpy);
802 _EGLConfig *conf = _eglLookupConfig(config, disp);
803 _EGLDriver *drv;
804 _EGLSurface *surf;
805
806 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
807 if (!drv)
808 return EGL_NO_SURFACE;
809
810 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
811 if (surf)
812 return _eglLinkSurface(surf, disp);
813 else
814 return EGL_NO_SURFACE;
815 }
816
817
818 EGLBoolean
819 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
820 EGLSurface surface, EGLModeMESA mode)
821 {
822 _EGLDisplay *disp = _eglLookupDisplay(dpy);
823 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
824 _EGLSurface *surf = _eglLookupSurface(surface, disp);
825 _EGLMode *m = _eglLookupMode(mode, disp);
826 _EGLDriver *drv;
827
828 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
829 if (!drv)
830 return EGL_FALSE;
831 if (!surf && surface != EGL_NO_SURFACE)
832 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
833 if (!m && mode != EGL_NO_MODE_MESA)
834 return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__);
835
836 return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
837 }
838
839
840 EGLBoolean
841 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
842 {
843 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
844 return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
845 }
846
847
848 EGLBoolean
849 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
850 EGLint attribute, EGLint *value)
851 {
852 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
853 return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
854 }
855
856
857 EGLBoolean
858 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
859 EGLSurface *surface)
860 {
861 _EGLDisplay *disp = _eglLookupDisplay(dpy);
862 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
863 _EGLDriver *drv;
864 _EGLSurface *surf;
865
866 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
867 if (!drv)
868 return EGL_FALSE;
869
870 if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE)
871 surf = NULL;
872 if (surface)
873 *surface = _eglGetSurfaceHandle(surf);
874 return (surf != NULL);
875 }
876
877
878 EGLBoolean
879 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
880 {
881 _EGLDisplay *disp = _eglLookupDisplay(dpy);
882 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
883 _EGLDriver *drv;
884 _EGLMode *m;
885
886 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
887 if (!drv)
888 return EGL_FALSE;
889
890 if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE)
891 m = NULL;
892 if (mode)
893 *mode = m->Handle;
894
895 return (m != NULL);
896 }
897
898
899 const char *
900 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
901 {
902 _EGL_DECLARE_DD_AND_MODE(dpy, mode);
903 return drv->API.QueryModeStringMESA(drv, disp, m);
904 }
905
906
907 #endif /* EGL_MESA_screen_surface */
908
909
910 /**
911 ** EGL 1.2
912 **/
913
914 #ifdef EGL_VERSION_1_2
915
916
917 /**
918 * Specify the client API to use for subsequent calls including:
919 * eglCreateContext()
920 * eglGetCurrentContext()
921 * eglGetCurrentDisplay()
922 * eglGetCurrentSurface()
923 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
924 * eglWaitClient()
925 * eglWaitNative()
926 * See section 3.7 "Rendering Context" in the EGL specification for details.
927 */
928 EGLBoolean
929 eglBindAPI(EGLenum api)
930 {
931 _EGLThreadInfo *t = _eglGetCurrentThread();
932
933 if (_eglIsCurrentThreadDummy())
934 return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
935
936 if (!_eglIsApiValid(api))
937 return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
938
939 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
940 return EGL_TRUE;
941 }
942
943
944 /**
945 * Return the last value set with eglBindAPI().
946 */
947 EGLenum
948 eglQueryAPI(void)
949 {
950 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
951 _EGLThreadInfo *t = _eglGetCurrentThread();
952 return _eglConvertApiFromIndex(t->CurrentAPIIndex);
953 }
954
955
956 EGLSurface
957 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
958 EGLClientBuffer buffer, EGLConfig config,
959 const EGLint *attrib_list)
960 {
961 _EGLDisplay *disp = _eglLookupDisplay(dpy);
962 _EGLConfig *conf = _eglLookupConfig(config, disp);
963 _EGLDriver *drv;
964 _EGLSurface *surf;
965
966 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
967 if (!drv)
968 return EGL_NO_SURFACE;
969
970 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
971 conf, attrib_list);
972 if (surf)
973 return _eglLinkSurface(surf, disp);
974 else
975 return EGL_NO_SURFACE;
976 }
977
978
979 EGLBoolean
980 eglReleaseThread(void)
981 {
982 /* unbind current context */
983 if (!_eglIsCurrentThreadDummy()) {
984 _EGLDisplay *disp = _eglGetCurrentDisplay();
985 _EGLDriver *drv;
986 if (disp) {
987 drv = disp->Driver;
988 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
989 }
990 }
991
992 _eglDestroyCurrentThread();
993 return EGL_TRUE;
994 }
995
996
997 #endif /* EGL_VERSION_1_2 */