EGL allows multiple current contexts, as long as they are bound to different client APIs.
Signed-off-by: Chia-I Wu <olva...@gmail.com> --- src/egl/main/eglapi.c | 11 +++++++---- src/egl/main/eglcontext.c | 38 ++++++++++++++++++++++++++++++++------ src/egl/main/eglcurrent.c | 12 +++++++----- src/egl/main/eglcurrent.h | 14 ++++++++++++-- 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index ea4d6e1..ca7208b 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -550,11 +550,14 @@ eglBindAPI(EGLenum api) if (_eglDummyCurrentThread()) return _eglError(EGL_BAD_ALLOC, "eglBindAPI"); + if (!_EGL_API_VALID(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->CurrentAPI = api; + t->CurrentAPIIndex = _EGL_API_TO_INDEX(api); return EGL_TRUE; } _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); @@ -562,14 +565,14 @@ eglBindAPI(EGLenum api) #endif case EGL_OPENGL_ES_API: if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) { - t->CurrentAPI = api; + t->CurrentAPIIndex = _EGL_API_TO_INDEX(api); return EGL_TRUE; } _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); return EGL_FALSE; case EGL_OPENVG_API: if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) { - t->CurrentAPI = api; + t->CurrentAPIIndex = _EGL_API_TO_INDEX(api); return EGL_TRUE; } _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); @@ -589,7 +592,7 @@ eglQueryAPI(void) { /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ _EGLThreadInfo *t = _eglGetCurrentThread(); - return t->CurrentAPI; + return _EGL_API_FROM_INDEX(t->CurrentAPIIndex); } diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 1ffad4a..79f65a8 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -203,10 +203,10 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, _EGLContext *ctx = _eglLookupContext(context); _EGLSurface *draw = _eglLookupSurface(d); _EGLSurface *read = _eglLookupSurface(r); - - _EGLContext *oldContext = _eglGetCurrentContext(); - _EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW); - _EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ); + _EGLContext *oldContext = NULL; + _EGLSurface *oldDrawSurface = NULL; + _EGLSurface *oldReadSurface = NULL; + EGLint apiIndex; if (_eglDummyCurrentThread()) return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); @@ -225,6 +225,31 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); return EGL_FALSE; } + +#ifdef EGL_VERSION_1_4 + /* OpenGL and OpenGL ES are conflicting */ + switch (ctx->ClientAPI) { + case EGL_OPENGL_ES_API: + if (t->CurrentContexts[_EGL_API_TO_INDEX(EGL_OPENGL_API)]) + return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); + break; + case EGL_OPENGL_API: + if (t->CurrentContexts[_EGL_API_TO_INDEX(EGL_OPENGL_ES_API)]) + return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); + break; + default: + break; + } +#endif + apiIndex = _EGL_API_TO_INDEX(ctx->ClientAPI); + } else { + apiIndex = t->CurrentAPIIndex; + } + + oldContext = t->CurrentContexts[apiIndex]; + if (oldContext) { + oldDrawSurface = oldContext->DrawSurface; + oldReadSurface = oldContext->ReadSurface; } /* @@ -275,10 +300,11 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, ctx->IsBound = EGL_TRUE; draw->IsBound = EGL_TRUE; read->IsBound = EGL_TRUE; + t->CurrentContexts[apiIndex] = ctx; + } else { + t->CurrentContexts[apiIndex] = NULL; } - t->CurrentContext = ctx; - return EGL_TRUE; } diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index 7b999ab..83ee87a 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -1,4 +1,5 @@ #include <stdlib.h> +#include <string.h> #include "eglcurrent.h" #include "eglcontext.h" #include "egllog.h" @@ -62,9 +63,10 @@ static inline _EGLThreadInfo *_eglGetTSD(void) static void _eglInitThreadInfo(_EGLThreadInfo *t) { - t->CurrentContext = NULL; + memset(t, 0, sizeof(*t)); t->LastError = EGL_SUCCESS; - t->CurrentAPI = EGL_OPENGL_ES_API; /* default, per EGL spec */ + /* default, per EGL spec */ + t->CurrentAPIIndex = _EGL_API_TO_INDEX(EGL_OPENGL_ES_API); } @@ -161,7 +163,7 @@ _EGLContext * _eglGetCurrentContext(void) { _EGLThreadInfo *t = _eglGetCurrentThread(); - return t->CurrentContext; + return t->CurrentContexts[t->CurrentAPIIndex]; } @@ -169,7 +171,7 @@ _EGLDisplay * _eglGetCurrentDisplay(void) { _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *ctx = t->CurrentContext; + _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; if (ctx) return ctx->Display; else @@ -181,7 +183,7 @@ _EGLSurface * _eglGetCurrentSurface(EGLint readdraw) { _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *ctx = t->CurrentContext; + _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; if (ctx) { switch (readdraw) { case EGL_DRAW: diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h index 14d2923..5aa6a78 100644 --- a/src/egl/main/eglcurrent.h +++ b/src/egl/main/eglcurrent.h @@ -5,14 +5,24 @@ #include "eglhash.h" +#define _EGL_API_VALID(api) \ + (((api) >= EGL_OPENGL_ES_API && (api) <= EGL_OPENGL_API) || (api) == EGL_NONE) +#define _EGL_API_NUM_INDICES \ + (EGL_OPENGL_API - EGL_OPENGL_ES_API + 2) /* idx 0 is for EGL_NONE */ + +#define _EGL_API_TO_INDEX(api) \ + ((api) != EGL_NONE ? (api) - EGL_OPENGL_ES_API + 1 : 0) +#define _EGL_API_FROM_INDEX(idx) \ + ((idx) != 0 ? EGL_OPENGL_ES_API + (idx) - 1 : EGL_NONE) + /** * Per-thread info */ struct _egl_thread_info { EGLint LastError; - _EGLContext *CurrentContext; - EGLenum CurrentAPI; + _EGLContext *CurrentContexts[_EGL_API_NUM_INDICES]; + EGLint CurrentAPIIndex; }; -- 1.6.2.4 ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mesa3d-dev