Initial changes to allow Mesa and its fake GLX to be built into XFree86 libGL.
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 24 May 2001 19:06:21 +0000 (19:06 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 24 May 2001 19:06:21 +0000 (19:06 +0000)
src/mesa/drivers/x11/fakeglx.c
src/mesa/drivers/x11/glxapi.c
src/mesa/drivers/x11/glxapi.h

index abbd528fb0b05b42bfa0494991743d413968c620..5d6098f14a799c03316e203ddad42f0a3363fa9d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fakeglx.c,v 1.49 2001/04/27 21:18:25 brianp Exp $ */
+/* $Id: fakeglx.c,v 1.50 2001/05/24 19:06:21 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -48,6 +48,7 @@
 #include "context.h"
 #include "config.h"
 #include "macros.h"
+#include "mem.h"
 #include "mmath.h"
 #include "mtypes.h"
 #include "xfonts.h"
@@ -83,17 +84,35 @@ void Fake_glXDummyFunc( void )
 }
 
 
+/*
+ * Our fake GLX context will contain a "real" GLX context and an XMesa context.
+ *
+ * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context,
+ * and vice versa.
+ *
+ * We really just need this structure in order to make the libGL functions
+ * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay()
+ * work correctly.
+ */
+struct fake_glx_context {
+   __GLXcontext glxContext;   /* this MUST be first! */
+   XMesaContext xmesaContext;
+};
 
-#define DONT_CARE -1
 
 
+/**********************************************************************/
+/***                       GLX Visual Code                          ***/
+/**********************************************************************/
+
+#define DONT_CARE -1
+
 
 #define MAX_VISUALS 100
 static XMesaVisual VisualTable[MAX_VISUALS];
 static int NumVisuals = 0;
 
 
-
 /*
  * This struct and some code fragments borrowed
  * from Mark Kilgard's GLUT library.
@@ -869,6 +888,10 @@ static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr,
 }
 
 
+/**********************************************************************/
+/***                  Begin Fake GLX API Functions                  ***/
+/**********************************************************************/
+
 
 static XVisualInfo *
 Fake_glXChooseVisual( Display *dpy, int screen, int *list )
@@ -1108,7 +1131,11 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
                        GLXContext share_list, Bool direct )
 {
    XMesaVisual glxvis;
-   XMesaContext xmctx;
+   struct fake_glx_context *glxCtx;
+
+   glxCtx = CALLOC_STRUCT(fake_glx_context);
+   if (!glxCtx)
+      return 0;
 
    /* deallocate unused windows/buffers */
    XMesaGarbageCollect();
@@ -1119,33 +1146,47 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
       glxvis = create_glx_visual( dpy, visinfo );
       if (!glxvis) {
          /* unusable visual */
+         FREE(glxCtx);
          return NULL;
       }
    }
 
-   xmctx = XMesaCreateContext( glxvis, (XMesaContext) share_list );
-   if (xmctx) {
-      /* set the direct/indirect flag */
-      xmctx->direct = direct;
+   glxCtx->xmesaContext = XMesaCreateContext(glxvis,
+                                             (XMesaContext) share_list);
+   if (!glxCtx->xmesaContext) {
+      FREE(glxCtx);
+      return NULL;
    }
-   return (GLXContext) xmctx;
+
+   glxCtx->xmesaContext->direct = GL_FALSE;
+   glxCtx->glxContext.isDirect = GL_FALSE;
+   glxCtx->glxContext.currentDpy = dpy;
+   glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */
+
+   assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+
+   return (GLXContext) glxCtx;
 }
 
 
+/* XXX these may have to be removed due to thread-safety issues. */
 static GLXContext MakeCurrent_PrevContext = 0;
 static GLXDrawable MakeCurrent_PrevDrawable = 0;
 static GLXDrawable MakeCurrent_PrevReadable = 0;
 static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
 static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
 
+
 /* GLX 1.3 and later */
 static Bool
 Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
                             GLXDrawable read, GLXContext ctx )
 {
+   struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+
    if (ctx && draw && read) {
       XMesaBuffer drawBuffer, readBuffer;
-      XMesaContext xmctx = (XMesaContext) ctx;
+      XMesaContext xmctx = glxCtx->xmesaContext;
 
       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
       if (ctx == MakeCurrent_PrevContext
@@ -1157,7 +1198,7 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
       }
       if (!drawBuffer) {
          /* drawable must be a new window! */
-         drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, (XMesaContext) ctx );
+         drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, xmctx);
          if (!drawBuffer) {
             /* Out of memory, or context/drawable depth mismatch */
             return False;
@@ -1174,7 +1215,8 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
       }
       if (!readBuffer) {
          /* drawable must be a new window! */
-         readBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, read, (XMesaContext) ctx );
+         readBuffer = XMesaCreateWindowBuffer2(glxCtx->xmesaContext->xm_visual,
+                                               read, xmctx);
          if (!readBuffer) {
             /* Out of memory, or context/drawable depth mismatch */
             return False;
@@ -1188,7 +1230,18 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
       MakeCurrent_PrevReadBuffer = readBuffer;
 
       /* Now make current! */
-      return (Bool) XMesaMakeCurrent2((XMesaContext) ctx, drawBuffer, readBuffer);
+      if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
+         ctx->currentDpy = dpy;
+         ctx->currentDrawable = draw;
+         ctx->currentReadable = read;
+#ifdef GLX_BUILD_IN_XLIB_MESA
+         __glXSetCurrentContext(ctx);
+#endif
+         return True;
+      }
+      else {
+         return False;
+      }
    }
    else if (!ctx && !draw && !read) {
       /* release current context w/out assigning new one. */
@@ -1315,13 +1368,14 @@ void _kw_ungrab_all( Display *dpy )
 static void
 Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
 {
+   struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
    (void) dpy;
    MakeCurrent_PrevContext = 0;
    MakeCurrent_PrevDrawable = 0;
    MakeCurrent_PrevReadable = 0;
    MakeCurrent_PrevDrawBuffer = 0;
    MakeCurrent_PrevReadBuffer = 0;
-   XMesaDestroyContext( (XMesaContext) ctx );
+   XMesaDestroyContext( glxCtx->xmesaContext );
    XMesaGarbageCollect();
 }
 
@@ -1330,8 +1384,9 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
 static Bool
 Fake_glXIsDirect( Display *dpy, GLXContext ctx )
 {
+   struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
    (void) dpy;
-   return ((XMesaContext) ctx)->direct;
+   return glxCtx->xmesaContext->direct;
 }
 
 
@@ -1841,12 +1896,13 @@ Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLX
    return False;
 }
 
+/* not used
 static GLXDrawable
-Fake_glXGetCurrentReadDrawableSGI(void)
+make_glXGetCurrentReadDrawableSGI(void)
 {
    return 0;
 }
-
+*/
 #endif
 
 
@@ -1890,12 +1946,6 @@ Fake_glXGetContextIDEXT(const GLXContext context)
    return 0;
 }
 
-static Display *
-Fake_glXGetCurrentDisplayEXT(void)
-{
-   return glXGetCurrentDisplay();
-}
-
 static GLXContext
 Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID)
 {
@@ -2274,7 +2324,7 @@ struct _glxapi_table *_mesa_GetGLXDispatchTable(void)
 
 #ifdef GLX_SGI_make_current_read
    glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI;
-   glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;
+   /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/
 #endif
 
 #if defined(_VL_H) && defined(GLX_SGIX_video_source)
@@ -2285,7 +2335,7 @@ struct _glxapi_table *_mesa_GetGLXDispatchTable(void)
 #ifdef GLX_EXT_import_context
    glx.FreeContextEXT = Fake_glXFreeContextEXT;
    glx.GetContextIDEXT = Fake_glXGetContextIDEXT;
-   glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;
+   /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/
    glx.ImportContextEXT = Fake_glXImportContextEXT;
    glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT;
 #endif
index 67649f403d29121d1879f6c524292490f3809e87..cd94ac8361cff9e2ded26eac270a599799c3500d 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: glxapi.c,v 1.21 2001/05/24 00:00:57 brianp Exp $ */
+/* $Id: glxapi.c,v 1.22 2001/05/24 19:06:21 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * Version:  3.5
  * 
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -161,11 +161,10 @@ get_dispatch(Display *dpy)
 
 
 /* Set by glXMakeCurrent() and glXMakeContextCurrent() only */
-static Display *CurrentDisplay = NULL;
+#ifndef GLX_BUILD_IN_XLIB_MESA
 static GLXContext CurrentContext = 0;
-static GLXDrawable CurrentDrawable = 0;
-static GLXDrawable CurrentReadDrawable = 0;
-
+#define __glXGetCurrentContext() CurrentContext;
+#endif
 
 
 /*
@@ -243,15 +242,21 @@ int glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value)
 }
 
 
+#ifdef GLX_BUILD_IN_XLIB_MESA
+/* Use real libGL's glXGetCurrentContext() function */
+#else
+/* stand-alone Mesa */
 GLXContext glXGetCurrentContext(void)
 {
    return CurrentContext;
 }
+#endif
 
 
 GLXDrawable glXGetCurrentDrawable(void)
 {
-   return CurrentDrawable;
+   GLXContext gc = glXGetCurrentContext();
+   return gc ? gc->currentDrawable : 0;
 }
 
 
@@ -273,12 +278,11 @@ Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
    if (!t)
       return False;
    b = (*t->MakeCurrent)(dpy, drawable, ctx);
+#ifndef  GLX_BUILD_IN_XLIB_MESA
    if (b) {
-      CurrentDisplay = dpy;
       CurrentContext = ctx;
-      CurrentDrawable = drawable;
-      CurrentReadDrawable = drawable;
    }
+#endif
    return b;
 }
 
@@ -316,7 +320,8 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
 void glXUseXFont(Font font, int first, int count, int listBase)
 {
    struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
+   Display *dpy = glXGetCurrentDisplay();
+   GET_DISPATCH(dpy, t);
    if (!t)
       return;
    (t->UseXFont)(font, first, count, listBase);
@@ -326,7 +331,8 @@ void glXUseXFont(Font font, int first, int count, int listBase)
 void glXWaitGL(void)
 {
    struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
+   Display *dpy = glXGetCurrentDisplay();
+   GET_DISPATCH(dpy, t);
    if (!t)
       return;
    (t->WaitGL)();
@@ -336,7 +342,8 @@ void glXWaitGL(void)
 void glXWaitX(void)
 {
    struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
+   Display *dpy = glXGetCurrentDisplay();
+   GET_DISPATCH(dpy, t);
    if (!t)
       return;
    (t->WaitX)();
@@ -382,7 +389,10 @@ const char *glXQueryServerString(Display *dpy, int screen, int name)
 #ifdef GLX_VERSION_1_2
 Display *glXGetCurrentDisplay(void)
 {
-   return CurrentDisplay;
+   /* Same code as in libGL's glxext.c */
+   GLXContext gc = __glXGetCurrentContext();
+   if (NULL == gc) return NULL;
+   return gc->currentDpy;
 }
 #endif
 
@@ -472,7 +482,8 @@ void glXDestroyWindow(Display *dpy, GLXWindow window)
 
 GLXDrawable glXGetCurrentReadDrawable(void)
 {
-   return CurrentReadDrawable;
+   GLXContext gc = glXGetCurrentContext();
+   return gc ? gc->currentReadable : 0;
 }
 
 
@@ -523,12 +534,11 @@ Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLX
    if (!t)
       return False;
    b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
+#ifndef  GLX_BUILD_IN_XLIB_MESA
    if (b) {
-      CurrentDisplay = dpy;
       CurrentContext = ctx;
-      CurrentDrawable = draw;
-      CurrentReadDrawable = read;
    }
+#endif
    return b;
 }
 
@@ -571,7 +581,8 @@ void glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
 int glXSwapIntervalSGI(int interval)
 {
    struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
+   Display *dpy = glXGetCurrentDisplay();
+   GET_DISPATCH(dpy, t);
    if (!t)
       return 0;
    return (t->SwapIntervalSGI)(interval);
@@ -585,7 +596,8 @@ int glXSwapIntervalSGI(int interval)
 int glXGetVideoSyncSGI(unsigned int *count)
 {
    struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
+   Display *dpy = glXGetCurrentDisplay();
+   GET_DISPATCH(dpy, t);
    if (!t)
       return 0;
    return (t->GetVideoSyncSGI)(count);
@@ -594,7 +606,8 @@ int glXGetVideoSyncSGI(unsigned int *count)
 int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 {
    struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
+   Display *dpy = glXGetCurrentDisplay();
+   GET_DISPATCH(dpy, t);
    if (!t)
       return 0;
    return (t->WaitVideoSyncSGI)(divisor, remainder, count);
@@ -616,13 +629,8 @@ Bool glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLX
 
 GLXDrawable glXGetCurrentReadDrawableSGI(void)
 {
-   struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
-   if (!t)
-      return 0;
-   return (t->GetCurrentReadDrawableSGI)();
+   return glXGetCurrentReadDrawable();
 }
-
 #endif
 
 
@@ -660,19 +668,19 @@ void glXFreeContextEXT(Display *dpy, GLXContext context)
    (t->FreeContextEXT)(dpy, context);
 }
 
+#ifdef GLX_BUILD_IN_XLIB_MESA
+/* Use real libGL's glXGetContextIDEXT() function */
+#else
+/* stand-alone Mesa */
 GLXContextID glXGetContextIDEXT(const GLXContext context)
 {
-   /* XXX is this function right? */
-   struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
-   if (!t)
-      return 0;
-   return (t->GetContextIDEXT)(context);
+   return context->xid;
 }
+#endif
 
 Display *glXGetCurrentDisplayEXT(void)
 {
-   return CurrentDisplay;
+   return glXGetCurrentDisplay();
 }
 
 GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID)
@@ -981,7 +989,8 @@ GLXPixmap glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixm
 Bool glXSet3DfxModeMESA(int mode)
 {
    struct _glxapi_table *t;
-   GET_DISPATCH(CurrentDisplay, t);
+   Display *dpy = glXGetCurrentDisplay();
+   GET_DISPATCH(dpy, t);
    if (!t)
       return False;
    return (t->Set3DfxModeMESA)(mode);
index d24b74bcbd5fbd21a4d24ef22f926096dbade365..ea287473a6bf2b208516a968e339e7d58c7011d2 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: glxapi.h,v 1.8 2000/12/15 04:02:50 brianp Exp $ */
+/* $Id: glxapi.h,v 1.9 2001/05/24 19:06:21 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * Version:  3.5
  * 
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "GL/glx.h"
 
 
+#ifdef GLX_BUILD_IN_XLIB_MESA
+/* The GLX API dispatcher is being built into XFree86's libGL */
+#include "glxclient.h"
+#else
+/* The GLX API dispatcher is being built into stand-alone Mesa */
+typedef struct __GLXcontextRec {
+   Display *currentDpy;
+   GLboolean isDirect;
+   GLXDrawable currentDrawable;
+   GLXDrawable currentReadable;
+   XID xid;
+} __GLXcontext;
+#endif
+
+
 /*
  * Almost all the GLX API functions get routed through this dispatch table.
  * The exceptions are the glXGetCurrentXXX() functions.
@@ -106,7 +121,7 @@ struct _glxapi_table {
 
 #ifdef GLX_SGI_make_current_read
    Bool (*MakeCurrentReadSGI)(Display *, GLXDrawable, GLXDrawable, GLXContext);
-   GLXDrawable (*GetCurrentReadDrawableSGI)(void);
+   /*GLXDrawable (*GetCurrentReadDrawableSGI)(void);*/
 #endif
 
 #if defined(_VL_H) && defined(GLX_SGIX_video_source)
@@ -117,7 +132,7 @@ struct _glxapi_table {
 #ifdef GLX_EXT_import_context
    void (*FreeContextEXT)(Display *dpy, GLXContext context);
    GLXContextID (*GetContextIDEXT)(const GLXContext context);
-   Display *(*GetCurrentDisplayEXT)(void);
+   /*Display *(*GetCurrentDisplayEXT)(void);*/
    GLXContext (*ImportContextEXT)(Display *dpy, GLXContextID contextID);
    int (*QueryContextInfoEXT)(Display *dpy, GLXContext context, int attribute,int *value);
 #endif