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

Reply via email to