Chia-I Wu wrote: > 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 {
Please put the } and else { on separate lines to be consistant with the rest of the code: } 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) These macros should all be inline functions instead. For example: static INLINE EGLBoolean _eglIsApiValid(EGLint api) { return (((api) >= EGL_OPENGL_ES_API && (api) <= EGL_OPENGL_API) || (api) == EGL_NONE); } Also, please add a comment for each function. > /** > * Per-thread info > */ > struct _egl_thread_info > { > EGLint LastError; > - _EGLContext *CurrentContext; > - EGLenum CurrentAPI; > + _EGLContext *CurrentContexts[_EGL_API_NUM_INDICES]; > + EGLint CurrentAPIIndex; > }; > > ------------------------------------------------------------------------------ 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