summaryrefslogtreecommitdiffstats
path: root/src/egl/main/eglapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/main/eglapi.c')
-rw-r--r--src/egl/main/eglapi.c237
1 files changed, 131 insertions, 106 deletions
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 29617b7afff..14cc5fa6137 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -9,12 +9,36 @@
* heterogeneous hardware devices in the future.
*
* The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
- * opaque handles implemented with 32-bit unsigned integers.
- * It's up to the driver function or fallback function to look up the
- * handle and get an object.
- * By using opaque handles, we leave open the possibility of having
- * indirect rendering in the future, like GLX.
+ * opaque handles. Internal objects are linked to a display to
+ * create the handles.
*
+ * For each public API entry point, the opaque handles are looked up
+ * before being dispatched to the drivers. When it fails to look up
+ * a handle, one of
+ *
+ * EGL_BAD_DISPLAY
+ * EGL_BAD_CONFIG
+ * EGL_BAD_CONTEXT
+ * EGL_BAD_SURFACE
+ * EGL_BAD_SCREEN_MESA
+ * EGL_BAD_MODE_MESA
+ *
+ * is generated and the driver function is not called. An
+ * uninitialized EGLDisplay has no driver associated with it. When
+ * such display is detected,
+ *
+ * EGL_NOT_INITIALIZED
+ *
+ * is generated.
+ *
+ * Some of the entry points use current display, context, or surface
+ * implicitly. For such entry points, the implicit objects are also
+ * checked before calling the driver function. Other than the
+ * errors listed above,
+ *
+ * EGL_BAD_CURRENT_SURFACE
+ *
+ * may also be generated.
*
* Notes on naming conventions:
*
@@ -92,8 +116,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
snprintf(disp->Version, sizeof(disp->Version),
"%d.%d (%s)", major_int, minor_int, drv->Name);
- /* update the global notion of supported APIs */
- _eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask;
+ /* limit to APIs supported by core */
+ disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
disp->Driver = drv;
} else {
@@ -496,15 +520,31 @@ eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
EGLBoolean EGLAPIENTRY
eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ _EGLSurface *surf;
_EGL_DECLARE_DD(dpy);
- return drv->API.SwapInterval(drv, disp, interval);
+
+ if (!ctx || !_eglIsContextLinked(ctx) || ctx->Display != disp)
+ return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+
+ surf = ctx->DrawSurface;
+ if (!_eglIsSurfaceLinked(surf))
+ return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+
+ return drv->API.SwapInterval(drv, disp, surf, interval);
}
EGLBoolean EGLAPIENTRY
eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
{
+ _EGLContext *ctx = _eglGetCurrentContext();
_EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+
+ /* surface must be bound to current context in EGL 1.4 */
+ if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
+ return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+
return drv->API.SwapBuffers(drv, disp, surf);
}
@@ -518,32 +558,66 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
EGLBoolean EGLAPIENTRY
-eglWaitGL(void)
+eglWaitClient(void)
{
- _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLContext *ctx = _eglGetCurrentContext();
+ _EGLDisplay *disp;
_EGLDriver *drv;
- if (!disp)
+ if (!ctx)
return EGL_TRUE;
+ /* let bad current context imply bad current surface */
+ if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
+ return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__);
- /* a current display is always initialized */
+ /* a valid current context implies an initialized current display */
+ disp = ctx->Display;
drv = disp->Driver;
+ assert(drv);
- return drv->API.WaitGL(drv, disp);
+ return drv->API.WaitClient(drv, disp, ctx);
+}
+
+
+EGLBoolean EGLAPIENTRY
+eglWaitGL(void)
+{
+#ifdef EGL_VERSION_1_2
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+ EGLint api_index = t->CurrentAPIIndex;
+ EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
+ EGLBoolean ret;
+
+ if (api_index != es_index && _eglIsCurrentThreadDummy())
+ return _eglError(EGL_BAD_ALLOC, "eglWaitGL");
+
+ t->CurrentAPIIndex = es_index;
+ ret = eglWaitClient();
+ t->CurrentAPIIndex = api_index;
+ return ret;
+#else
+ return eglWaitClient();
+#endif
}
EGLBoolean EGLAPIENTRY
eglWaitNative(EGLint engine)
{
- _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLContext *ctx = _eglGetCurrentContext();
+ _EGLDisplay *disp;
_EGLDriver *drv;
- if (!disp)
+ if (!ctx)
return EGL_TRUE;
+ /* let bad current context imply bad current surface */
+ if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
+ return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__);
- /* a current display is always initialized */
+ /* a valid current context implies an initialized current display */
+ disp = ctx->Display;
drv = disp->Driver;
+ assert(drv);
return drv->API.WaitNative(drv, disp, engine);
}
@@ -568,8 +642,26 @@ eglGetCurrentContext(void)
EGLSurface EGLAPIENTRY
eglGetCurrentSurface(EGLint readdraw)
{
- _EGLSurface *s = _eglGetCurrentSurface(readdraw);
- return _eglGetSurfaceHandle(s);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ _EGLSurface *surf;
+
+ if (!ctx)
+ return EGL_NO_SURFACE;
+
+ switch (readdraw) {
+ case EGL_DRAW:
+ surf = ctx->DrawSurface;
+ break;
+ case EGL_READ:
+ surf = ctx->ReadSurface;
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER, __FUNCTION__);
+ surf = NULL;
+ break;
+ }
+
+ return _eglGetSurfaceHandle(surf);
}
@@ -586,43 +678,11 @@ eglGetError(void)
void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
{
- typedef void (*genericFunc)();
- struct name_function {
+ static const struct {
const char *name;
_EGLProc function;
- };
- static struct name_function egl_functions[] = {
- /* alphabetical order */
- { "eglBindTexImage", (_EGLProc) eglBindTexImage },
- { "eglChooseConfig", (_EGLProc) eglChooseConfig },
- { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
- { "eglCreateContext", (_EGLProc) eglCreateContext },
- { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
- { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
- { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
- { "eglDestroyContext", (_EGLProc) eglDestroyContext },
- { "eglDestroySurface", (_EGLProc) eglDestroySurface },
- { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
- { "eglGetConfigs", (_EGLProc) eglGetConfigs },
- { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
- { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
- { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
- { "eglGetDisplay", (_EGLProc) eglGetDisplay },
- { "eglGetError", (_EGLProc) eglGetError },
- { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
- { "eglInitialize", (_EGLProc) eglInitialize },
- { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
- { "eglQueryContext", (_EGLProc) eglQueryContext },
- { "eglQueryString", (_EGLProc) eglQueryString },
- { "eglQuerySurface", (_EGLProc) eglQuerySurface },
- { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
- { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
- { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
- { "eglSwapInterval", (_EGLProc) eglSwapInterval },
- { "eglTerminate", (_EGLProc) eglTerminate },
- { "eglWaitGL", (_EGLProc) eglWaitGL },
- { "eglWaitNative", (_EGLProc) eglWaitNative },
- /* Extensions */
+ } egl_functions[] = {
+ /* extensions only */
#ifdef EGL_MESA_screen_surface
{ "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
{ "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
@@ -637,22 +697,23 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
{ "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
{ "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
#endif /* EGL_MESA_screen_surface */
-#ifdef EGL_VERSION_1_2
- { "eglBindAPI", (_EGLProc) eglBindAPI },
- { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
- { "eglQueryAPI", (_EGLProc) eglQueryAPI },
- { "eglReleaseThread", (_EGLProc) eglReleaseThread },
- { "eglWaitClient", (_EGLProc) eglWaitClient },
-#endif /* EGL_VERSION_1_2 */
{ NULL, NULL }
};
EGLint i;
- for (i = 0; egl_functions[i].name; i++) {
- if (strcmp(egl_functions[i].name, procname) == 0) {
- return (genericFunc) egl_functions[i].function;
+
+ if (!procname)
+ return NULL;
+ if (strncmp(procname, "egl", 3) == 0) {
+ for (i = 0; egl_functions[i].name; i++) {
+ if (strcmp(egl_functions[i].name, procname) == 0)
+ return egl_functions[i].function;
}
}
+ /* preload a driver if there isn't one */
+ if (!_eglGlobal.NumDrivers)
+ _eglPreloadDriver(NULL);
+
/* now loop over drivers to query their procs */
for (i = 0; i < _eglGlobal.NumDrivers; i++) {
_EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname);
@@ -664,6 +725,9 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
}
+#ifdef EGL_MESA_screen_surface
+
+
/*
* EGL_MESA_screen extension
*/
@@ -838,6 +902,9 @@ eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
}
+#endif /* EGL_MESA_screen_surface */
+
+
/**
** EGL 1.2
**/
@@ -867,33 +934,7 @@ eglBindAPI(EGLenum api)
if (!_eglIsApiValid(api))
return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
- switch (api) {
-#ifdef EGL_VERSION_1_4
- case EGL_OPENGL_API:
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) {
- t->CurrentAPIIndex = _eglConvertApiToIndex(api);
- return EGL_TRUE;
- }
- _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
- return EGL_FALSE;
-#endif
- case EGL_OPENGL_ES_API:
- if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) {
- t->CurrentAPIIndex = _eglConvertApiToIndex(api);
- return EGL_TRUE;
- }
- _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
- return EGL_FALSE;
- case EGL_OPENVG_API:
- if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) {
- t->CurrentAPIIndex = _eglConvertApiToIndex(api);
- return EGL_TRUE;
- }
- _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
- return EGL_FALSE;
- default:
- return EGL_FALSE;
- }
+ t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
@@ -951,20 +992,4 @@ eglReleaseThread(void)
}
-EGLBoolean
-eglWaitClient(void)
-{
- _EGLDisplay *disp = _eglGetCurrentDisplay();
- _EGLDriver *drv;
-
- if (!disp)
- return EGL_TRUE;
-
- /* a current display is always initialized */
- drv = disp->Driver;
-
- return drv->API.WaitClient(drv, disp);
-}
-
-
#endif /* EGL_VERSION_1_2 */