Mesa (master): egl: Fix eglMakeCurrent with different surfaces.

Chia-I Wu olv at kemper.freedesktop.org
Mon Apr 5 20:39:36 PDT 2010


Module: Mesa
Branch: master
Commit: bbe459b14d593bd2d7b6c0f010e165fe815e8396
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bbe459b14d593bd2d7b6c0f010e165fe815e8396

Author: Chia-I Wu <olv at lunarg.com>
Date:   Mon Apr  5 21:26:34 2010 +0800

egl: Fix eglMakeCurrent with different surfaces.

0a82fadcdd0b6ebbc345c7c302da0e0efce40a98 seems to trigger a bug in
_eglBindContext.  Rework the logics yet again.  It is simpler, and
hopefully correct this time.

---

 src/egl/main/eglcontext.c |   75 +++++++++++++++++++++++++++------------------
 1 files changed, 45 insertions(+), 30 deletions(-)

diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 5e831aa..80e316a 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -208,39 +208,56 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
  * bound to;  when the context is NULL, the same surfaces are returned.
  */
 static void
-_eglBindContextToSurfaces(_EGLContext *ctx,
+_eglBindContextToSurfaces(_EGLContext *newCtx,
                           _EGLSurface **draw, _EGLSurface **read)
 {
    _EGLSurface *newDraw = *draw, *newRead = *read;
    _EGLContext *oldCtx;
 
+   /*
+    * The goal is to bind a newCtx to newDraw.  Since newDraw may already have
+    * a binding context (oldCtx), and newCtx may already be bound to another
+    * surface (oldDraw), the old bindings are broken first and the new one is
+    * created.
+    */
    oldCtx = newDraw->CurrentContext;
-   if (ctx != oldCtx) {
+   if (newCtx != oldCtx) {
       if (oldCtx) {
-         assert(*draw == oldCtx->DrawSurface);
+         assert(oldCtx->DrawSurface == newDraw);
          oldCtx->DrawSurface = NULL;
       }
-      if (ctx) {
-         *draw = ctx->DrawSurface;
-         ctx->DrawSurface = newDraw;
+
+      if (newCtx) {
+         _EGLSurface *oldDraw = newCtx->DrawSurface;
+         if (oldDraw)
+            oldDraw->CurrentContext = NULL;
+
+         newCtx->DrawSurface = newDraw;
+         *draw = oldDraw;
       }
 
-      newDraw->CurrentContext = ctx;
+      newDraw->CurrentContext = newCtx;
    }
 
+   /* likewise */
    if (newRead != newDraw)
       oldCtx = newRead->CurrentContext;
-   if (ctx != oldCtx) {
+   if (newCtx != oldCtx) {
       if (oldCtx) {
-         assert(*read == oldCtx->ReadSurface);
+         assert(oldCtx->ReadSurface == newRead);
          oldCtx->ReadSurface = NULL;
       }
-      if (ctx) {
-         *read = ctx->ReadSurface;
-         ctx->ReadSurface = newRead;
+
+      if (newCtx) {
+         _EGLSurface *oldRead = newCtx->ReadSurface;
+         if (oldRead)
+            oldRead->CurrentContext = NULL;
+
+         newCtx->ReadSurface = newRead;
+         *read = oldRead;
       }
 
-      newRead->CurrentContext = ctx;
+      newRead->CurrentContext = newCtx;
    }
 }
 
@@ -360,27 +377,25 @@ _eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read)
 
    /* bind the new context */
    oldCtx = _eglBindContextToThread(newCtx, t);
-   *ctx = oldCtx;
-   if (newCtx)
+
+   if (newCtx) {
       _eglBindContextToSurfaces(newCtx, draw, read);
+   }
+   else {
+      assert(!*draw && !*read);
+      if (oldCtx) {
+         *draw = oldCtx->DrawSurface;
+         *read = oldCtx->ReadSurface;
+         assert(*draw && *read);
 
-   /* unbind the old context from its binding surfaces */
-   if (oldCtx && oldCtx != newCtx) {
-      /*
-       * If the new context replaces some old context, the new one should not
-       * be current before the replacement and it should not be bound to any
-       * surface.
-       */
-      if (newCtx)
-         assert(!*draw && !*read);
-
-      *draw = oldCtx->DrawSurface;
-      *read = oldCtx->ReadSurface;
-      assert(*draw && *read);
-
-      _eglBindContextToSurfaces(NULL, draw, read);
+         /* unbind the old context from its surfaces */
+         _eglBindContextToSurfaces(NULL, draw, read);
+      }
    }
 
+   *ctx = oldCtx;
+   /* draw and read have been updated in _eglBindContextToSurfaces */
+
    return EGL_TRUE;
 }
 



More information about the mesa-commit mailing list