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 <[email protected]>
> ---
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev