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