static void _eglInitThreadInfo(_EGLThreadInfo *t) { memset(t, 0, sizeof(*t)); t->LastError = EGL_SUCCESS; /* default, per EGL spec */ t->CurrentAPIIndex = _eglConvertApiToIndex(EGL_OPENGL_ES_API); }
/** * Specify the client API to use for subsequent calls including: * eglCreateContext() * eglGetCurrentContext() * eglGetCurrentDisplay() * eglGetCurrentSurface() * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT) * eglWaitClient() * eglWaitNative() * See section 3.7 "Rendering Context" in the EGL specification for details. */ EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api) { _EGLThreadInfo *t = _eglGetCurrentThread(); if (_eglIsCurrentThreadDummy()) RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); if (!_eglIsApiValid(api)) RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); t->CurrentAPIIndex = _eglConvertApiToIndex(api); RETURN_EGL_SUCCESS(NULL, EGL_TRUE); }
EGLBoolean EGLAPIENTRY eglWaitGL(void) { _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_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); t->CurrentAPIIndex = es_index; ret = eglWaitClient(); t->CurrentAPIIndex = api_index; return ret; }
/** * Bind the context to the thread and return the previous context. * * Note that the context may be NULL. */ static _EGLContext * _eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t) { EGLint apiIndex; _EGLContext *oldCtx; apiIndex = (ctx) ? _eglConvertApiToIndex(ctx->ClientAPI) : t->CurrentAPIIndex; oldCtx = t->CurrentContexts[apiIndex]; if (ctx != oldCtx) { if (oldCtx) oldCtx->Binding = NULL; if (ctx) ctx->Binding = t; t->CurrentContexts[apiIndex] = ctx; } return oldCtx; }
/** * Return the currently bound context of the given API, or NULL. */ PUBLIC _EGLContext * _eglGetAPIContext(EGLenum api) { _EGLThreadInfo *t = _eglGetCurrentThread(); return t->CurrentContexts[_eglConvertApiToIndex(api)]; }
/** * Drivers will typically call this to do the error checking and * update the various flags. * Then, the driver will do its device-dependent Make-Current stuff. */ EGLBoolean _eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx) { _EGLThreadInfo *t = _eglGetCurrentThread(); _EGLContext *oldContext = NULL; _EGLSurface *oldDrawSurface = NULL; _EGLSurface *oldReadSurface = NULL; EGLint apiIndex; if (_eglIsCurrentThreadDummy()) return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); if (ctx) { /* error checking */ if (ctx->Binding && ctx->Binding != t) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); if (draw == NULL || read == NULL) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); if (draw->Config != ctx->Config || read->Config != ctx->Config) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); if ((draw->Binding && draw->Binding->Binding != t) || (read->Binding && read->Binding->Binding != t)) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); #ifdef EGL_VERSION_1_4 /* OpenGL and OpenGL ES are conflicting */ switch (ctx->ClientAPI) { case EGL_OPENGL_ES_API: if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); break; case EGL_OPENGL_API: if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_ES_API)]) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); break; default: break; } #endif apiIndex = _eglConvertApiToIndex(ctx->ClientAPI); } else { if (draw != NULL || read != NULL) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); apiIndex = t->CurrentAPIIndex; } oldContext = t->CurrentContexts[apiIndex]; if (oldContext) { oldDrawSurface = oldContext->DrawSurface; oldReadSurface = oldContext->ReadSurface; assert(oldDrawSurface); assert(oldReadSurface); /* break old bindings */ t->CurrentContexts[apiIndex] = NULL; oldContext->Binding = NULL; oldContext->DrawSurface = NULL; oldContext->ReadSurface = NULL; oldDrawSurface->Binding = NULL; oldReadSurface->Binding = NULL; /* * check if the old context or surfaces need to be deleted */ if (!_eglIsSurfaceLinked(oldDrawSurface)) { assert(draw != oldDrawSurface && read != oldDrawSurface); drv->API.DestroySurface(drv, dpy, oldDrawSurface); } if (oldReadSurface != oldDrawSurface && !_eglIsSurfaceLinked(oldReadSurface)) { assert(draw != oldReadSurface && read != oldReadSurface); drv->API.DestroySurface(drv, dpy, oldReadSurface); } if (!_eglIsContextLinked(oldContext)) { assert(ctx != oldContext); drv->API.DestroyContext(drv, dpy, oldContext); } } /* build new bindings */ if (ctx) { t->CurrentContexts[apiIndex] = ctx; ctx->Binding = t; ctx->DrawSurface = draw; ctx->ReadSurface = read; draw->Binding = ctx; read->Binding = ctx; } return EGL_TRUE; }