eglapi.c revision b2006a40eb22899d38cd31691640555228e36975
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 implemented with 32-bit unsigned integers.
13 * It's up to the driver function or fallback function to look up the
14 * handle and get an object.
15 * By using opaque handles, we leave open the possibility of having
16 * indirect rendering in the future, like GLX.
17 *
18 *
19 * Notes on naming conventions:
20 *
21 * eglFooBar    - public EGL function
22 * EGL_FOO_BAR  - public EGL token
23 * EGLDatatype  - public EGL datatype
24 *
25 * _eglFooBar   - private EGL function
26 * _EGLDatatype - private EGL datatype, typedef'd struct
27 * _egl_struct  - private EGL struct, non-typedef'd
28 *
29 */
30
31
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include "eglcontext.h"
37#include "egldisplay.h"
38#include "egltypedefs.h"
39#include "eglglobals.h"
40#include "egldriver.h"
41#include "eglsurface.h"
42
43
44
45/**
46 * NOTE: displayName is treated as a string in _eglChooseDriver()!!!
47 * This will probably change!
48 * See _eglChooseDriver() for details!
49 */
50EGLDisplay APIENTRY
51eglGetDisplay(NativeDisplayType displayName)
52{
53   _EGLDisplay *dpy;
54   _eglInitGlobals();
55   dpy = _eglNewDisplay(displayName);
56   if (dpy)
57      return dpy->Handle;
58   else
59      return EGL_NO_DISPLAY;
60}
61
62
63EGLBoolean APIENTRY
64eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
65{
66   if (dpy) {
67      _EGLDriver *drv = _eglChooseDriver(dpy);
68      if (drv)
69         return drv->API.Initialize(drv, dpy, major, minor);
70   }
71   return EGL_FALSE;
72}
73
74
75EGLBoolean APIENTRY
76eglTerminate(EGLDisplay dpy)
77{
78   _EGLDriver *drv = _eglLookupDriver(dpy);
79   if (drv)
80      return _eglCloseDriver(drv, dpy);
81   else
82      return EGL_FALSE;
83}
84
85
86const char * APIENTRY
87eglQueryString(EGLDisplay dpy, EGLint name)
88{
89   _EGLDriver *drv = _eglLookupDriver(dpy);
90   if (drv)
91      return drv->API.QueryString(drv, dpy, name);
92   else
93      return NULL;
94}
95
96
97EGLBoolean APIENTRY
98eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
99{
100   _EGLDriver *drv = _eglLookupDriver(dpy);
101   /* XXX check drv for null in remaining functions */
102   return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config);
103}
104
105
106EGLBoolean APIENTRY
107eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
108{
109   _EGLDriver *drv = _eglLookupDriver(dpy);
110   return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
111}
112
113
114EGLBoolean APIENTRY
115eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
116{
117   _EGLDriver *drv = _eglLookupDriver(dpy);
118   return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value);
119}
120
121
122EGLContext APIENTRY
123eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
124{
125   _EGLDriver *drv = _eglLookupDriver(dpy);
126   return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list);
127}
128
129
130EGLBoolean APIENTRY
131eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
132{
133   _EGLDriver *drv = _eglLookupDriver(dpy);
134   return drv->API.DestroyContext(drv, dpy, ctx);
135}
136
137
138EGLBoolean APIENTRY
139eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
140{
141   _EGLDriver *drv = _eglLookupDriver(dpy);
142   return drv->API.MakeCurrent(drv, dpy, draw, read, ctx);
143}
144
145
146EGLBoolean APIENTRY
147eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
148{
149   _EGLDriver *drv = _eglLookupDriver(dpy);
150   return drv->API.QueryContext(drv, dpy, ctx, attribute, value);
151}
152
153
154EGLSurface APIENTRY
155eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
156{
157   _EGLDriver *drv = _eglLookupDriver(dpy);
158   return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list);
159}
160
161
162EGLSurface APIENTRY
163eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
164{
165   _EGLDriver *drv = _eglLookupDriver(dpy);
166   return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
167}
168
169
170EGLSurface APIENTRY
171eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
172{
173   _EGLDriver *drv = _eglLookupDriver(dpy);
174   return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list);
175}
176
177
178EGLBoolean APIENTRY
179eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
180{
181   _EGLDriver *drv = _eglLookupDriver(dpy);
182   return drv->API.DestroySurface(drv, dpy, surface);
183}
184
185
186EGLBoolean APIENTRY
187eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
188{
189   _EGLDriver *drv = _eglLookupDriver(dpy);
190   return drv->API.QuerySurface(drv, dpy, surface, attribute, value);
191}
192
193
194EGLBoolean APIENTRY
195eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
196{
197   _EGLDriver *drv = _eglLookupDriver(dpy);
198   return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value);
199}
200
201
202EGLBoolean APIENTRY
203eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
204{
205   _EGLDriver *drv = _eglLookupDriver(dpy);
206   return drv->API.BindTexImage(drv, dpy, surface, buffer);
207}
208
209
210EGLBoolean APIENTRY
211eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
212{
213   _EGLDriver *drv = _eglLookupDriver(dpy);
214   return drv->API.ReleaseTexImage(drv, dpy, surface, buffer);
215}
216
217
218EGLBoolean APIENTRY
219eglSwapInterval(EGLDisplay dpy, EGLint interval)
220{
221   _EGLDriver *drv = _eglLookupDriver(dpy);
222   return drv->API.SwapInterval(drv, dpy, interval);
223}
224
225
226EGLBoolean APIENTRY
227eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
228{
229   _EGLDriver *drv = _eglLookupDriver(dpy);
230   return drv->API.SwapBuffers(drv, dpy, draw);
231}
232
233
234EGLBoolean APIENTRY
235eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
236{
237   _EGLDriver *drv = _eglLookupDriver(dpy);
238   return drv->API.CopyBuffers(drv, dpy, surface, target);
239}
240
241
242EGLBoolean APIENTRY
243eglWaitGL(void)
244{
245   EGLDisplay dpy = eglGetCurrentDisplay();
246   if (dpy != EGL_NO_DISPLAY) {
247      _EGLDriver *drv = _eglLookupDriver(dpy);
248      return drv->API.WaitGL(drv, dpy);
249   }
250   else
251      return EGL_FALSE;
252}
253
254
255EGLBoolean APIENTRY
256eglWaitNative(EGLint engine)
257{
258   EGLDisplay dpy = eglGetCurrentDisplay();
259   if (dpy != EGL_NO_DISPLAY) {
260      _EGLDriver *drv = _eglLookupDriver(dpy);
261      return drv->API.WaitNative(drv, dpy, engine);
262   }
263   else
264      return EGL_FALSE;
265}
266
267
268EGLDisplay APIENTRY
269eglGetCurrentDisplay(void)
270{
271   _EGLDisplay *dpy = _eglGetCurrentDisplay();
272   if (dpy)
273      return dpy->Handle;
274   else
275      return EGL_NO_DISPLAY;
276}
277
278
279EGLContext APIENTRY
280eglGetCurrentContext(void)
281{
282   _EGLContext *ctx = _eglGetCurrentContext();
283   if (ctx)
284      return ctx->Handle;
285   else
286      return EGL_NO_CONTEXT;
287}
288
289
290EGLSurface APIENTRY
291eglGetCurrentSurface(EGLint readdraw)
292{
293   _EGLSurface *s = _eglGetCurrentSurface(readdraw);
294   if (s)
295      return s->Handle;
296   else
297      return EGL_NO_SURFACE;
298}
299
300
301EGLint APIENTRY
302eglGetError(void)
303{
304   _EGLThreadInfo *t = _eglGetCurrentThread();
305   EGLint e = t->LastError;
306   t->LastError = EGL_SUCCESS;
307   return e;
308}
309
310
311void (* APIENTRY eglGetProcAddress(const char *procname))()
312{
313   typedef void (*genericFunc)();
314   struct name_function {
315      const char *name;
316      _EGLProc function;
317   };
318   static struct name_function egl_functions[] = {
319      /* alphabetical order */
320      { "eglBindTexImage", (_EGLProc) eglBindTexImage },
321      { "eglChooseConfig", (_EGLProc) eglChooseConfig },
322      { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
323      { "eglCreateContext", (_EGLProc) eglCreateContext },
324      { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
325      { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
326      { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
327      { "eglDestroyContext", (_EGLProc) eglDestroyContext },
328      { "eglDestroySurface", (_EGLProc) eglDestroySurface },
329      { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
330      { "eglGetConfigs", (_EGLProc) eglGetConfigs },
331      { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
332      { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
333      { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
334      { "eglGetDisplay", (_EGLProc) eglGetDisplay },
335      { "eglGetError", (_EGLProc) eglGetError },
336      { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
337      { "eglInitialize", (_EGLProc) eglInitialize },
338      { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
339      { "eglQueryContext", (_EGLProc) eglQueryContext },
340      { "eglQueryString", (_EGLProc) eglQueryString },
341      { "eglQuerySurface", (_EGLProc) eglQuerySurface },
342      { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
343      { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
344      { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
345      { "eglSwapInterval", (_EGLProc) eglSwapInterval },
346      { "eglTerminate", (_EGLProc) eglTerminate },
347      { "eglWaitGL", (_EGLProc) eglWaitGL },
348      { "eglWaitNative", (_EGLProc) eglWaitNative },
349      /* Extensions */
350#ifdef EGL_MESA_screen_surface
351      { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
352      { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
353      { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
354      { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
355      { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
356      { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
357      { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
358      { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
359      { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
360      { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
361      { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
362      { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
363#endif /* EGL_MESA_screen_surface */
364#ifdef EGL_VERSION_1_2
365      { "eglBindAPI", (_EGLProc) eglBindAPI },
366      { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
367      { "eglQueryAPI", (_EGLProc) eglQueryAPI },
368      { "eglReleaseThread", (_EGLProc) eglReleaseThread },
369      { "eglWaitClient", (_EGLProc) eglWaitClient },
370#endif /* EGL_VERSION_1_2 */
371      { NULL, NULL }
372   };
373   EGLint i;
374   for (i = 0; egl_functions[i].name; i++) {
375      if (strcmp(egl_functions[i].name, procname) == 0) {
376         return (genericFunc) egl_functions[i].function;
377      }
378   }
379#if 0
380   /* XXX enable this code someday */
381   return (genericFunc) _glapi_get_proc_address(procname);
382#else
383   return NULL;
384#endif
385}
386
387
388/*
389 * EGL_MESA_screen extension
390 */
391
392EGLBoolean APIENTRY
393eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
394                  const EGLint *attrib_list, EGLModeMESA *modes,
395                  EGLint modes_size, EGLint *num_modes)
396{
397   _EGLDriver *drv = _eglLookupDriver(dpy);
398   if (drv)
399      return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes);
400   else
401      return EGL_FALSE;
402}
403
404
405EGLBoolean APIENTRY
406eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
407{
408   _EGLDriver *drv = _eglLookupDriver(dpy);
409   if (drv)
410      return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode);
411   else
412      return EGL_FALSE;
413}
414
415
416EGLBoolean APIENTRY
417eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
418{
419   _EGLDriver *drv = _eglLookupDriver(dpy);
420   if (drv)
421      return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value);
422   else
423      return EGL_FALSE;
424}
425
426
427EGLBoolean APIENTRY
428eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
429{
430   _EGLDriver *drv = _eglLookupDriver(dpy);
431   if (drv)
432      return drv->API.CopyContextMESA(drv, dpy, source, dest, mask);
433   else
434      return EGL_FALSE;
435}
436
437
438EGLBoolean
439eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens)
440{
441   _EGLDriver *drv = _eglLookupDriver(dpy);
442   if (drv)
443      return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens);
444   else
445      return EGL_FALSE;
446}
447
448
449EGLSurface
450eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
451{
452   _EGLDriver *drv = _eglLookupDriver(dpy);
453   return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list);
454}
455
456
457EGLBoolean
458eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode)
459{
460   _EGLDriver *drv = _eglLookupDriver(dpy);
461   return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode);
462}
463
464
465EGLBoolean
466eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
467{
468   _EGLDriver *drv = _eglLookupDriver(dpy);
469   return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y);
470}
471
472
473EGLBoolean
474eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value)
475{
476   _EGLDriver *drv = _eglLookupDriver(dpy);
477   return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value);
478}
479
480
481EGLBoolean
482eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface)
483{
484   _EGLDriver *drv = _eglLookupDriver(dpy);
485   return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface);
486}
487
488
489EGLBoolean
490eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
491{
492   _EGLDriver *drv = _eglLookupDriver(dpy);
493   return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode);
494}
495
496
497const char *
498eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
499{
500   _EGLDriver *drv = _eglLookupDriver(dpy);
501   return drv->API.QueryModeStringMESA(drv, dpy, mode);
502}
503
504
505/**
506 ** EGL 1.2
507 **/
508
509#ifdef EGL_VERSION_1_2
510
511EGLBoolean
512eglBindAPI(EGLenum api)
513{
514   _EGLThreadInfo *t = _eglGetCurrentThread();
515
516   switch (api) {
517   case EGL_OPENGL_ES_API:
518      if (_eglGlobal.OpenGLESAPISupported) {
519         t->CurrentAPI = api;
520         return EGL_TRUE;
521      }
522      _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
523      return EGL_FALSE;
524   case EGL_OPENVG_API:
525      if (_eglGlobal.OpenVGAPISupported) {
526         t->CurrentAPI = api;
527         return EGL_TRUE;
528      }
529      _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
530      return EGL_FALSE;
531   default:
532      return EGL_FALSE;
533   }
534   return EGL_TRUE;
535}
536
537
538EGLSurface
539eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
540                                 EGLClientBuffer buffer, EGLConfig config,
541                                 const EGLint *attrib_list)
542{
543   _EGLDriver *drv = _eglLookupDriver(dpy);
544   return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer,
545                                                 config, attrib_list);
546}
547
548
549EGLenum
550eglQueryAPI(void)
551{
552   /* returns one of EGL_OPENGL_ES_API or EGL_OPENVG_API */
553   _EGLThreadInfo *t = _eglGetCurrentThread();
554   return t->CurrentAPI;
555}
556
557
558EGLBoolean
559eglReleaseThread(void)
560{
561   _EGLThreadInfo *t = _eglGetCurrentThread();
562   EGLDisplay dpy = eglGetCurrentDisplay();
563   if (dpy) {
564      _EGLDriver *drv = _eglLookupDriver(dpy);
565      /* unbind context */
566      (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
567                                  EGL_NO_SURFACE, EGL_NO_CONTEXT);
568   }
569   _eglDeleteThreadData(t);
570   return EGL_TRUE;
571}
572
573
574EGLBoolean
575eglWaitClient(void)
576{
577   EGLDisplay dpy = eglGetCurrentDisplay();
578   if (dpy != EGL_NO_DISPLAY) {
579      _EGLDriver *drv = _eglLookupDriver(dpy);
580      return drv->API.WaitClient(drv, dpy);
581   }
582   else
583      return EGL_FALSE;
584}
585
586#endif /* EGL_VERSION_1_2 */
587