Mesa (master): glx: Split indirect and applegl implementations into different files

Kristian Høgsberg krh at kemper.freedesktop.org
Wed Jul 28 20:50:38 UTC 2010


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

Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Wed Jul 28 16:40:43 2010 -0400

glx: Split indirect and applegl implementations into different files

---

 src/glx/Makefile       |    5 +-
 src/glx/applegl_glx.c  |  155 ++++++++++++++++
 src/glx/glxclient.h    |    9 +-
 src/glx/glxcmds.c      |  393 -----------------------------------------
 src/glx/glxcurrent.c   |  147 ----------------
 src/glx/glxext.c       |    6 +-
 src/glx/indirect_glx.c |  456 ++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 624 insertions(+), 547 deletions(-)

diff --git a/src/glx/Makefile b/src/glx/Makefile
index 70def7a..9a22d0c 100644
--- a/src/glx/Makefile
+++ b/src/glx/Makefile
@@ -13,6 +13,7 @@ SOURCES = \
 	  glxcurrent.c \
 	  glxext.c \
 	  glxextensions.c \
+	  indirect_glx.c \
 	  indirect.c \
 	  indirect_init.c \
 	  indirect_size.c \
@@ -37,7 +38,9 @@ SOURCES = \
 	  XF86dri.c \
 	  glxhash.c \
 	  dri2_glx.c \
-	  dri2.c
+	  dri2.c \
+	  applegl_glx.c
+
 
 GLAPI_LIB = $(TOP)/src/mapi/glapi/libglapi.a
 
diff --git a/src/glx/applegl_glx.c b/src/glx/applegl_glx.c
new file mode 100644
index 0000000..3da1f19
--- /dev/null
+++ b/src/glx/applegl_glx.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Soft-
+ * ware"), to deal in the Software without restriction, including without
+ * limitation the rights to use, copy, modify, merge, publish, distribute,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, provided that the above copyright
+ * notice(s) and this permission notice appear in all copies of the Soft-
+ * ware and that both the above copyright notice(s) and this permission
+ * notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+ * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
+ * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
+ * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
+ * MANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization of
+ * the copyright holder.
+ *
+ * Authors:
+ *   Kristian Høgsberg (krh at bitplanet.net)
+ */
+
+#if defined(GLX_USE_APPLEGL)
+
+static void
+applegl_destroy_context(struct glx_context *gc)
+{
+   apple_glx_destroy_context(&gc->driContext, gc->currentDpy);
+}
+
+static int
+applegl_bind_context(struct glx_context *gc, struct glx_context *old,
+		     GLXDrawable draw, GLXDrawable read)
+{
+   bool error = apple_glx_make_current_context(dpy,
+					       (oldGC && oldGC != &dummyContext) ? oldGC->driContext : NUL~
+					       gc ? gc->driContext : NULL, draw);
+
+   apple_glx_diagnostic("%s: error %s\n", __func__, error ? "YES" : "NO");
+   if (error)
+      return GLXBadContext;
+
+   return Success;
+}
+
+static void
+applegl_unbind_context(struct glx_context *gc, struct glx_context *new)
+{
+}
+
+static void
+applegl_wait_gl(struct glx_context *gc)
+{
+   glFinish();
+}
+
+static void
+applegl_wait_x(struct glx_context *gc)
+{
+   apple_glx_waitx(gc->dpy, gc->driContext);
+}
+
+static const struct glx_context_vtable applegl_context_vtable = {
+   applegl_destroy_context,
+   applegl_bind_context,
+   applegl_unbind_context,
+   applegl_wait_gl,
+   applegl_wait_x,
+   DRI_glXUseXFont,
+   NULL, /* bind_tex_image, */
+   NULL, /* release_tex_image, */
+};
+
+static struct glx_context *
+applegl_create_context(struct glx_screen *psc,
+		       struct glx_config *mode,
+		       struct glx_context *shareList, int renderType)
+{
+   struct glx_context *gc;
+   int errorcode;
+   bool x11error;
+
+   /* TODO: Integrate this with apple_glx_create_context and make
+    * struct apple_glx_context inherit from struct glx_context. */
+
+   gc = Xmalloc(sizeof *gc);
+   if (pcp == NULL)
+      return NULL;
+
+   memset(gc, 0, sizeof *gc);
+   if (!glx_context_init(&gc->base, &psc->base, mode)) {
+      Xfree(gc);
+      return NULL;
+   }
+
+   gc->vtable = &applegl_context_vtable;
+   gc->driContext = NULL;
+   gc->do_destroy = False;
+
+   /* TODO: darwin: Integrate with above to do indirect */
+   if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, 
+			       shareList ? shareList->driContext : NULL,
+			       &errorcode, &x11error)) {
+      __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error);
+      gc->vtable->destroy(gc);
+      return NULL;
+   }
+
+   gc->currentContextTag = -1;
+   gc->mode = fbconfig;
+   gc->isDirect = allowDirect;
+   gc->xid = 1; /* Just something not None, so we know when to destroy
+		 * it in MakeContextCurrent. */
+
+   return gc;
+}
+
+struct glx_screen_vtable appegl_screen_vtable = {
+   applegl_create_context
+};
+
+_X_HIDDEN struct glx_screen *
+applegl_create_screen(int screen, struct glx_display * priv)
+{
+   struct glx_screen *psc;
+
+   psc = Xmalloc(sizeof *psc);
+   if (psc == NULL)
+      return NULL;
+
+   memset(psc, 0, sizeof *psc);
+   glx_screen_init(psc, screen, priv);
+   psc->vtable = &applegl_screen_vtable;
+
+   return psc;
+}
+
+_X_HIDDEN int
+applegl_create_display(struct glx_display *display)
+{
+   /* create applegl display and stuff in display->appleglDisplay */
+   apple_init_glx(display);
+}
+
+#endif
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index b13cc81..84e1742 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -776,10 +776,9 @@ GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable);
 
 extern struct glx_screen *
 indirect_create_screen(int screen, struct glx_display * priv);
-extern int 
-indirect_bind_context(struct glx_context *gc, struct glx_context *old,
-		      GLXDrawable draw, GLXDrawable read);
-extern void
-indirect_unbind_context(struct glx_context *gc, struct glx_context *new);
+extern struct glx_context *
+indirect_create_context(struct glx_screen *psc,
+			struct glx_config *mode,
+			struct glx_context *shareList, int renderType);
 
 #endif /* !__GLX_client_h__ */
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index 717108e..7513ebd 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -58,7 +58,6 @@
 
 static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
 static const char __glXGLXClientVersion[] = "1.4";
-static const struct glx_context_vtable indirect_context_vtable;
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
 
@@ -229,186 +228,6 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig)
    return NULL;
 }
 
-#ifdef GLX_USE_APPLEGL
-
-static const struct glx_context_vtable applegl_context_vtable;
-
-static struct glx_context *
-applegl_create_context(struct glx_screen *psc,
-		       struct glx_config *mode,
-		       struct glx_context *shareList, int renderType)
-{
-   struct glx_context *gc;
-   int errorcode;
-   bool x11error;
-
-   /* TODO: Integrate this with apple_glx_create_context and make
-    * struct apple_glx_context inherit from struct glx_context. */
-
-   gc = Xmalloc(sizeof *gc);
-   if (pcp == NULL)
-      return NULL;
-
-   memset(gc, 0, sizeof *gc);
-   if (!glx_context_init(&gc->base, &psc->base, mode)) {
-      Xfree(gc);
-      return NULL;
-   }
-
-   gc->vtable = &applegl_context_vtable;
-   gc->driContext = NULL;
-   gc->do_destroy = False;
-
-   /* TODO: darwin: Integrate with above to do indirect */
-   if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, 
-			       shareList ? shareList->driContext : NULL,
-			       &errorcode, &x11error)) {
-      __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error);
-      gc->vtable->destroy(gc);
-      return NULL;
-   }
-
-   gc->currentContextTag = -1;
-   gc->mode = fbconfig;
-   gc->isDirect = allowDirect;
-   gc->xid = 1; /* Just something not None, so we know when to destroy
-		 * it in MakeContextCurrent. */
-
-   return gc;
-}
-#endif
-
-
-/**
- * \todo It should be possible to move the allocate of \c client_state_private
- * later in the function for direct-rendering contexts.  Direct-rendering
- * contexts don't need to track client state, so they don't need that memory
- * at all.
- *
- * \todo Eliminate \c __glXInitVertexArrayState.  Replace it with a new
- * function called \c __glXAllocateClientState that allocates the memory and
- * does all the initialization (including the pixel pack / unpack).
- */
-static struct glx_context *
-indirect_create_context(struct glx_screen *psc,
-			struct glx_config *mode,
-			struct glx_context *shareList, int renderType)
-{
-   struct glx_context *gc;
-   int bufSize;
-   CARD8 opcode;
-   __GLXattribute *state;
-
-   opcode = __glXSetupForCommand(psc->dpy);
-   if (!opcode) {
-      return NULL;
-   }
-
-   /* Allocate our context record */
-   gc = Xmalloc(sizeof *gc);
-   if (!gc) {
-      /* Out of memory */
-      return NULL;
-   }
-   memset(gc, 0, sizeof *gc);
-
-   glx_context_init(gc, psc, mode);
-   gc->isDirect = GL_FALSE;
-   gc->vtable = &indirect_context_vtable;
-   state = Xmalloc(sizeof(struct __GLXattributeRec));
-   if (state == NULL) {
-      /* Out of memory */
-      Xfree(gc);
-      return NULL;
-   }
-   gc->client_state_private = state;
-   memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec));
-   state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
-
-   /*
-    ** Create a temporary buffer to hold GLX rendering commands.  The size
-    ** of the buffer is selected so that the maximum number of GLX rendering
-    ** commands can fit in a single X packet and still have room in the X
-    ** packet for the GLXRenderReq header.
-    */
-
-   bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
-   gc->buf = (GLubyte *) Xmalloc(bufSize);
-   if (!gc->buf) {
-      Xfree(gc->client_state_private);
-      Xfree(gc);
-      return NULL;
-   }
-   gc->bufSize = bufSize;
-
-   /* Fill in the new context */
-   gc->renderMode = GL_RENDER;
-
-   state->storePack.alignment = 4;
-   state->storeUnpack.alignment = 4;
-
-   gc->attributes.stackPointer = &gc->attributes.stack[0];
-
-   /*
-    ** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
-    ** Other code uses the fastImageUnpack bit, but it is never set
-    ** to GL_TRUE.
-    */
-   gc->fastImageUnpack = GL_FALSE;
-   gc->fillImage = __glFillImage;
-   gc->pc = gc->buf;
-   gc->bufEnd = gc->buf + bufSize;
-   gc->isDirect = GL_FALSE;
-   if (__glXDebug) {
-      /*
-       ** Set limit register so that there will be one command per packet
-       */
-      gc->limit = gc->buf;
-   }
-   else {
-      gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
-   }
-   gc->majorOpcode = opcode;
-
-   /*
-    ** Constrain the maximum drawing command size allowed to be
-    ** transfered using the X_GLXRender protocol request.  First
-    ** constrain by a software limit, then constrain by the protocl
-    ** limit.
-    */
-   if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
-      bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
-   }
-   if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
-      bufSize = __GLX_MAX_RENDER_CMD_SIZE;
-   }
-   gc->maxSmallRenderCommandSize = bufSize;
-   
-
-   return gc;
-}
-
-struct glx_screen_vtable indirect_screen_vtable = {
-   indirect_create_context
-};
-
-_X_HIDDEN struct glx_screen *
-indirect_create_screen(int screen, struct glx_display * priv)
-{
-   struct glx_screen *psc;
-
-   psc = Xmalloc(sizeof *psc);
-   if (psc == NULL)
-      return NULL;
-
-   memset(psc, 0, sizeof *psc);
-   glx_screen_init(psc, screen, priv);
-   psc->vtable = &indirect_screen_vtable;
-
-   return psc;
-}
-
-
 _X_HIDDEN Bool
 glx_context_init(struct glx_context *gc,
 		 struct glx_screen *psc, struct glx_config *config)
@@ -576,28 +395,6 @@ glx_send_destroy_context(Display *dpy, XID xid)
    SyncHandle();
 }
 
-static void
-indirect_destroy_context(struct glx_context *gc)
-{
-   if (!gc->imported && gc->xid)
-      glx_send_destroy_context(gc->psc->dpy, gc->xid);
-
-   __glXFreeVertexArrayState(gc);
-
-   if (gc->vendor)
-      XFree((char *) gc->vendor);
-   if (gc->renderer)
-      XFree((char *) gc->renderer);
-   if (gc->version)
-      XFree((char *) gc->version);
-   if (gc->extensions)
-      XFree((char *) gc->extensions);
-   __glFreeAttributeState(gc);
-   XFree((char *) gc->buf);
-   Xfree((char *) gc->client_state_private);
-   XFree((char *) gc);
-}
-
 /*
 ** Destroy the named context
 */
@@ -673,25 +470,6 @@ glXQueryExtension(Display * dpy, int *errorBase, int *eventBase)
    return rv;
 }
 
-static void
-indirect_wait_gl(struct glx_context *gc)
-{
-   xGLXWaitGLReq *req;
-   Display *dpy = gc->currentDpy;
-
-   /* Flush any pending commands out */
-   __glXFlushRenderBuffer(gc, gc->pc);
-
-   /* Send the glXWaitGL request */
-   LockDisplay(dpy);
-   GetReq(GLXWaitGL, req);
-   req->reqType = gc->majorOpcode;
-   req->glxCode = X_GLXWaitGL;
-   req->contextTag = gc->currentContextTag;
-   UnlockDisplay(dpy);
-   SyncHandle();
-}
-
 /*
 ** Put a barrier in the token stream that forces the GL to finish its
 ** work before X can proceed.
@@ -705,24 +483,6 @@ glXWaitGL(void)
       gc->vtable->wait_gl(gc);
 }
 
-static void
-indirect_wait_x(struct glx_context *gc)
-{
-   xGLXWaitXReq *req;
-   Display *dpy = gc->currentDpy;
-
-   /* Flush any pending commands out */
-   __glXFlushRenderBuffer(gc, gc->pc);
-
-   LockDisplay(dpy);
-   GetReq(GLXWaitX, req);
-   req->reqType = gc->majorOpcode;
-   req->glxCode = X_GLXWaitX;
-   req->contextTag = gc->currentContextTag;
-   UnlockDisplay(dpy);
-   SyncHandle();
-}
-
 /*
 ** Put a barrier in the token stream that forces X to finish its
 ** work before GL can proceed.
@@ -736,61 +496,6 @@ glXWaitX(void)
       gc->vtable->wait_x(gc);
 }
 
-static void
-indirect_use_x_font(struct glx_context *gc,
-		    Font font, int first, int count, int listBase)
-{
-   xGLXUseXFontReq *req;
-   Display *dpy = gc->currentDpy;
-
-   /* Flush any pending commands out */
-   __glXFlushRenderBuffer(gc, gc->pc);
-
-   /* Send the glXUseFont request */
-   LockDisplay(dpy);
-   GetReq(GLXUseXFont, req);
-   req->reqType = gc->majorOpcode;
-   req->glxCode = X_GLXUseXFont;
-   req->contextTag = gc->currentContextTag;
-   req->font = font;
-   req->first = first;
-   req->count = count;
-   req->listBase = listBase;
-   UnlockDisplay(dpy);
-   SyncHandle();
-}
-
-#ifdef GLX_USE_APPLEGL
-
-static void
-applegl_destroy_context(struct glx_context *gc)
-{
-   apple_glx_destroy_context(&gc->driContext, gc->currentDpy);
-}
-
-static void
-applegl_wait_gl(struct glx_context *gc)
-{
-   glFinish();
-}
-
-static void
-applegl_wait_x(struct glx_context *gc)
-{
-   apple_glx_waitx(gc->dpy, gc->driContext);
-}
-
-static const struct glx_context_vtable applegl_context_vtable = {
-   applegl_destroy_context,
-   applegl_wait_gl,
-   applegl_wait_x,
-   DRI_glXUseXFont,
-   NULL, /* bind_tex_image, */
-   NULL, /* release_tex_image, */
-};
-
-#endif
-
 _X_EXPORT void
 glXUseXFont(Font font, int first, int count, int listBase)
 {
@@ -2630,104 +2335,6 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
    SyncHandle();
 }
 
-
-/**
- * GLX_EXT_texture_from_pixmap
- */
-static void
-indirect_bind_tex_image(Display * dpy,
-			GLXDrawable drawable,
-			int buffer, const int *attrib_list)
-{
-   xGLXVendorPrivateReq *req;
-   struct glx_context *gc = __glXGetCurrentContext();
-   CARD32 *drawable_ptr;
-   INT32 *buffer_ptr;
-   CARD32 *num_attrib_ptr;
-   CARD32 *attrib_ptr;
-   CARD8 opcode;
-   unsigned int i;
-
-   i = 0;
-   if (attrib_list) {
-      while (attrib_list[i * 2] != None)
-         i++;
-   }
-
-   opcode = __glXSetupForCommand(dpy);
-   if (!opcode)
-      return;
-
-   LockDisplay(dpy);
-   GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req);
-   req->reqType = opcode;
-   req->glxCode = X_GLXVendorPrivate;
-   req->vendorCode = X_GLXvop_BindTexImageEXT;
-   req->contextTag = gc->currentContextTag;
-
-   drawable_ptr = (CARD32 *) (req + 1);
-   buffer_ptr = (INT32 *) (drawable_ptr + 1);
-   num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
-   attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);
-
-   *drawable_ptr = drawable;
-   *buffer_ptr = buffer;
-   *num_attrib_ptr = (CARD32) i;
-
-   i = 0;
-   if (attrib_list) {
-      while (attrib_list[i * 2] != None) {
-         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
-         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
-         i++;
-      }
-   }
-
-   UnlockDisplay(dpy);
-   SyncHandle();
-}
-
-static void
-indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
-{
-   xGLXVendorPrivateReq *req;
-   struct glx_context *gc = __glXGetCurrentContext();
-   CARD32 *drawable_ptr;
-   INT32 *buffer_ptr;
-   CARD8 opcode;
-
-   opcode = __glXSetupForCommand(dpy);
-   if (!opcode)
-      return;
-
-   LockDisplay(dpy);
-   GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req);
-   req->reqType = opcode;
-   req->glxCode = X_GLXVendorPrivate;
-   req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
-   req->contextTag = gc->currentContextTag;
-
-   drawable_ptr = (CARD32 *) (req + 1);
-   buffer_ptr = (INT32 *) (drawable_ptr + 1);
-
-   *drawable_ptr = drawable;
-   *buffer_ptr = buffer;
-
-   UnlockDisplay(dpy);
-   SyncHandle();
-}
-
-static const struct glx_context_vtable indirect_context_vtable = {
-   indirect_destroy_context,
-   indirect_bind_context,
-   indirect_unbind_context,
-   indirect_wait_gl,
-   indirect_wait_x,
-   indirect_use_x_font,
-   indirect_bind_tex_image,
-   indirect_release_tex_image,
-};
-
 /*@{*/
 static void
 __glXBindTexImageEXT(Display * dpy,
diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c
index 5955860..0eccc9f 100644
--- a/src/glx/glxcurrent.c
+++ b/src/glx/glxcurrent.c
@@ -45,7 +45,6 @@
 #include "apple_glx_context.h"
 #else
 #include "glapi.h"
-#include "indirect_init.h"
 #endif
 
 /*
@@ -69,14 +68,6 @@ static struct glx_context dummyContext = {
    sizeof(dummyBuffer),
 };
 
-
-#ifndef GLX_USE_APPLEGL
-/*
-** All indirect rendering contexts will share the same indirect dispatch table.
-*/
-static struct _glapi_table *IndirectAPI = NULL;
-#endif
-
 /*
  * Current context management and locking
  */
@@ -176,9 +167,6 @@ __glXSetCurrentContextNull(void)
 #endif
 }
 
-
-/************************************************************************/
-
 _X_EXPORT GLXContext
 glXGetCurrentContext(void)
 {
@@ -199,90 +187,6 @@ glXGetCurrentDrawable(void)
    return gc->currentDrawable;
 }
 
-
-#ifndef GLX_USE_APPLEGL
-/************************************************************************/
-
-/**
- * Sends a GLX protocol message to the specified display to make the context
- * and the drawables current.
- *
- * \param dpy     Display to send the message to.
- * \param opcode  Major opcode value for the display.
- * \param gc_id   Context tag for the context to be made current.
- * \param draw    Drawable ID for the "draw" drawable.
- * \param read    Drawable ID for the "read" drawable.
- * \param reply   Space to store the X-server's reply.
- *
- * \warning
- * This function assumes that \c dpy is locked with \c LockDisplay on entry.
- */
-static Bool
-SendMakeCurrentRequest(Display * dpy, CARD8 opcode,
-                       GLXContextID gc_id, GLXContextTag gc_tag,
-                       GLXDrawable draw, GLXDrawable read,
-                       xGLXMakeCurrentReply * reply)
-{
-   Bool ret;
-
-
-   LockDisplay(dpy);
-
-   if (draw == read) {
-      xGLXMakeCurrentReq *req;
-
-      GetReq(GLXMakeCurrent, req);
-      req->reqType = opcode;
-      req->glxCode = X_GLXMakeCurrent;
-      req->drawable = draw;
-      req->context = gc_id;
-      req->oldContextTag = gc_tag;
-   }
-   else {
-      struct glx_display *priv = __glXInitialize(dpy);
-
-      /* If the server can support the GLX 1.3 version, we should
-       * perfer that.  Not only that, some servers support GLX 1.3 but
-       * not the SGI extension.
-       */
-
-      if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
-         xGLXMakeContextCurrentReq *req;
-
-         GetReq(GLXMakeContextCurrent, req);
-         req->reqType = opcode;
-         req->glxCode = X_GLXMakeContextCurrent;
-         req->drawable = draw;
-         req->readdrawable = read;
-         req->context = gc_id;
-         req->oldContextTag = gc_tag;
-      }
-      else {
-         xGLXVendorPrivateWithReplyReq *vpreq;
-         xGLXMakeCurrentReadSGIReq *req;
-
-         GetReqExtra(GLXVendorPrivateWithReply,
-                     sz_xGLXMakeCurrentReadSGIReq -
-                     sz_xGLXVendorPrivateWithReplyReq, vpreq);
-         req = (xGLXMakeCurrentReadSGIReq *) vpreq;
-         req->reqType = opcode;
-         req->glxCode = X_GLXVendorPrivateWithReply;
-         req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
-         req->drawable = draw;
-         req->readable = read;
-         req->context = gc_id;
-         req->oldContextTag = gc_tag;
-      }
-   }
-
-   ret = _XReply(dpy, (xReply *) reply, 0, False);
-
-   UnlockDisplay(dpy);
-   SyncHandle();
-
-   return ret;
-}
-
 static void
 __glXGenerateError(Display * dpy, struct glx_context *gc, XID resource,
                    BYTE errorCode, CARD16 minorCode)
@@ -298,57 +202,6 @@ __glXGenerateError(Display * dpy, struct glx_context *gc, XID resource,
    _XError(dpy, &error);
 }
 
-#endif /* GLX_USE_APPLEGL */
-
-_X_HIDDEN int
-indirect_bind_context(struct glx_context *gc, struct glx_context *old,
-		      GLXDrawable draw, GLXDrawable read)
-{
-   xGLXMakeCurrentReply reply;
-   GLXContextTag tag;
-   __GLXattribute *state;
-   Display *dpy = gc->psc->dpy;
-   int opcode = __glXSetupForCommand(dpy);
-
-   if (old && !old->isDirect && old->psc->dpy == dpy)
-      tag = old->currentContextTag;
-   else
-      tag = None;
-
-   SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, &reply);
-
-   if (!IndirectAPI)
-      IndirectAPI = __glXNewIndirectAPI();
-   _glapi_set_dispatch(IndirectAPI);
-
-   gc->currentContextTag = reply.contextTag;
-   state = gc->client_state_private;
-   if (state->array_state == NULL) {
-      glGetString(GL_EXTENSIONS);
-      glGetString(GL_VERSION);
-      __glXInitVertexArrayState(gc);
-   }
-
-   return Success;
-}
-
-_X_HIDDEN void
-indirect_unbind_context(struct glx_context *gc, struct glx_context *new)
-{
-   Display *dpy = gc->psc->dpy;
-   int opcode = __glXSetupForCommand(dpy);
-   xGLXMakeCurrentReply reply;
-
-   /* We are either switching to no context, away from a indirect
-    * context to a direct context or from one dpy to another and have
-    * to send a request to the dpy to unbind the previous context.
-    */
-   if (!new || new->isDirect || new->psc->dpy != dpy)
-      SendMakeCurrentRequest(dpy, opcode, None,
-			     gc->currentContextTag, None, None, &reply);
-   gc->currentContextTag = 0;
-}
-
 /**
  * Make a particular context current.
  *
diff --git a/src/glx/glxext.c b/src/glx/glxext.c
index e48c4c2..c227215 100644
--- a/src/glx/glxext.c
+++ b/src/glx/glxext.c
@@ -772,6 +772,10 @@ AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv)
       if (psc == NULL && priv->driswDisplay)
 	 psc = (*priv->driswDisplay->createScreen) (i, priv);
 #endif
+#if defined(GLX_USE_APPLEGL)
+      if (psc == NULL && priv->appleglDisplay)
+	 psc = (*priv->appleglDisplay->createScreen) (i, priv);
+#endif
       if (psc == NULL)
 	 psc = indirect_create_screen(i, priv);
       priv->screens[i] = psc;
@@ -853,7 +857,7 @@ __glXInitialize(Display * dpy)
 #endif
 
 #ifdef GLX_USE_APPLEGL
-   if (apple_init_glx(dpy)) {
+   if (!applegl_create_display(dpyPriv)) {
       Xfree(dpyPriv);
       return NULL;
    }
diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
new file mode 100644
index 0000000..cbc3129
--- /dev/null
+++ b/src/glx/indirect_glx.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Soft-
+ * ware"), to deal in the Software without restriction, including without
+ * limitation the rights to use, copy, modify, merge, publish, distribute,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, provided that the above copyright
+ * notice(s) and this permission notice appear in all copies of the Soft-
+ * ware and that both the above copyright notice(s) and this permission
+ * notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+ * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
+ * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
+ * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
+ * MANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization of
+ * the copyright holder.
+ *
+ * Authors:
+ *   Kristian Høgsberg (krh at bitplanet.net)
+ */
+
+#include "glapi.h"
+#include "glxclient.h"
+
+extern struct _glapi_table *__glXNewIndirectAPI(void);
+
+/*
+** All indirect rendering contexts will share the same indirect dispatch table.
+*/
+static struct _glapi_table *IndirectAPI = NULL;
+
+static void
+indirect_destroy_context(struct glx_context *gc)
+{
+   if (!gc->imported && gc->xid)
+      glx_send_destroy_context(gc->psc->dpy, gc->xid);
+
+   __glXFreeVertexArrayState(gc);
+
+   if (gc->vendor)
+      XFree((char *) gc->vendor);
+   if (gc->renderer)
+      XFree((char *) gc->renderer);
+   if (gc->version)
+      XFree((char *) gc->version);
+   if (gc->extensions)
+      XFree((char *) gc->extensions);
+   __glFreeAttributeState(gc);
+   XFree((char *) gc->buf);
+   Xfree((char *) gc->client_state_private);
+   XFree((char *) gc);
+}
+
+static Bool
+SendMakeCurrentRequest(Display * dpy, CARD8 opcode,
+                       GLXContextID gc_id, GLXContextTag gc_tag,
+                       GLXDrawable draw, GLXDrawable read,
+                       xGLXMakeCurrentReply * reply)
+{
+   Bool ret;
+
+   LockDisplay(dpy);
+
+   if (draw == read) {
+      xGLXMakeCurrentReq *req;
+
+      GetReq(GLXMakeCurrent, req);
+      req->reqType = opcode;
+      req->glxCode = X_GLXMakeCurrent;
+      req->drawable = draw;
+      req->context = gc_id;
+      req->oldContextTag = gc_tag;
+   }
+   else {
+      struct glx_display *priv = __glXInitialize(dpy);
+
+      /* If the server can support the GLX 1.3 version, we should
+       * perfer that.  Not only that, some servers support GLX 1.3 but
+       * not the SGI extension.
+       */
+
+      if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
+         xGLXMakeContextCurrentReq *req;
+
+         GetReq(GLXMakeContextCurrent, req);
+         req->reqType = opcode;
+         req->glxCode = X_GLXMakeContextCurrent;
+         req->drawable = draw;
+         req->readdrawable = read;
+         req->context = gc_id;
+         req->oldContextTag = gc_tag;
+      }
+      else {
+         xGLXVendorPrivateWithReplyReq *vpreq;
+         xGLXMakeCurrentReadSGIReq *req;
+
+         GetReqExtra(GLXVendorPrivateWithReply,
+                     sz_xGLXMakeCurrentReadSGIReq -
+                     sz_xGLXVendorPrivateWithReplyReq, vpreq);
+         req = (xGLXMakeCurrentReadSGIReq *) vpreq;
+         req->reqType = opcode;
+         req->glxCode = X_GLXVendorPrivateWithReply;
+         req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
+         req->drawable = draw;
+         req->readable = read;
+         req->context = gc_id;
+         req->oldContextTag = gc_tag;
+      }
+   }
+
+   ret = _XReply(dpy, (xReply *) reply, 0, False);
+
+   UnlockDisplay(dpy);
+   SyncHandle();
+
+   return ret;
+}
+
+static int
+indirect_bind_context(struct glx_context *gc, struct glx_context *old,
+		      GLXDrawable draw, GLXDrawable read)
+{
+   xGLXMakeCurrentReply reply;
+   GLXContextTag tag;
+   __GLXattribute *state;
+   Display *dpy = gc->psc->dpy;
+   int opcode = __glXSetupForCommand(dpy);
+
+   if (old && !old->isDirect && old->psc->dpy == dpy)
+      tag = old->currentContextTag;
+   else
+      tag = None;
+
+   SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, &reply);
+
+   if (!IndirectAPI)
+      IndirectAPI = __glXNewIndirectAPI();
+   _glapi_set_dispatch(IndirectAPI);
+
+   gc->currentContextTag = reply.contextTag;
+   state = gc->client_state_private;
+   if (state->array_state == NULL) {
+      glGetString(GL_EXTENSIONS);
+      glGetString(GL_VERSION);
+      __glXInitVertexArrayState(gc);
+   }
+
+   return Success;
+}
+
+static void
+indirect_unbind_context(struct glx_context *gc, struct glx_context *new)
+{
+   Display *dpy = gc->psc->dpy;
+   int opcode = __glXSetupForCommand(dpy);
+   xGLXMakeCurrentReply reply;
+
+   /* We are either switching to no context, away from a indirect
+    * context to a direct context or from one dpy to another and have
+    * to send a request to the dpy to unbind the previous context.
+    */
+   if (!new || new->isDirect || new->psc->dpy != dpy)
+      SendMakeCurrentRequest(dpy, opcode, None,
+			     gc->currentContextTag, None, None, &reply);
+   gc->currentContextTag = 0;
+}
+
+static void
+indirect_wait_gl(struct glx_context *gc)
+{
+   xGLXWaitGLReq *req;
+   Display *dpy = gc->currentDpy;
+
+   /* Flush any pending commands out */
+   __glXFlushRenderBuffer(gc, gc->pc);
+
+   /* Send the glXWaitGL request */
+   LockDisplay(dpy);
+   GetReq(GLXWaitGL, req);
+   req->reqType = gc->majorOpcode;
+   req->glxCode = X_GLXWaitGL;
+   req->contextTag = gc->currentContextTag;
+   UnlockDisplay(dpy);
+   SyncHandle();
+}
+
+static void
+indirect_wait_x(struct glx_context *gc)
+{
+   xGLXWaitXReq *req;
+   Display *dpy = gc->currentDpy;
+
+   /* Flush any pending commands out */
+   __glXFlushRenderBuffer(gc, gc->pc);
+
+   LockDisplay(dpy);
+   GetReq(GLXWaitX, req);
+   req->reqType = gc->majorOpcode;
+   req->glxCode = X_GLXWaitX;
+   req->contextTag = gc->currentContextTag;
+   UnlockDisplay(dpy);
+   SyncHandle();
+}
+
+static void
+indirect_use_x_font(struct glx_context *gc,
+		    Font font, int first, int count, int listBase)
+{
+   xGLXUseXFontReq *req;
+   Display *dpy = gc->currentDpy;
+
+   /* Flush any pending commands out */
+   __glXFlushRenderBuffer(gc, gc->pc);
+
+   /* Send the glXUseFont request */
+   LockDisplay(dpy);
+   GetReq(GLXUseXFont, req);
+   req->reqType = gc->majorOpcode;
+   req->glxCode = X_GLXUseXFont;
+   req->contextTag = gc->currentContextTag;
+   req->font = font;
+   req->first = first;
+   req->count = count;
+   req->listBase = listBase;
+   UnlockDisplay(dpy);
+   SyncHandle();
+}
+
+static void
+indirect_bind_tex_image(Display * dpy,
+			GLXDrawable drawable,
+			int buffer, const int *attrib_list)
+{
+   xGLXVendorPrivateReq *req;
+   struct glx_context *gc = __glXGetCurrentContext();
+   CARD32 *drawable_ptr;
+   INT32 *buffer_ptr;
+   CARD32 *num_attrib_ptr;
+   CARD32 *attrib_ptr;
+   CARD8 opcode;
+   unsigned int i;
+
+   i = 0;
+   if (attrib_list) {
+      while (attrib_list[i * 2] != None)
+         i++;
+   }
+
+   opcode = __glXSetupForCommand(dpy);
+   if (!opcode)
+      return;
+
+   LockDisplay(dpy);
+   GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req);
+   req->reqType = opcode;
+   req->glxCode = X_GLXVendorPrivate;
+   req->vendorCode = X_GLXvop_BindTexImageEXT;
+   req->contextTag = gc->currentContextTag;
+
+   drawable_ptr = (CARD32 *) (req + 1);
+   buffer_ptr = (INT32 *) (drawable_ptr + 1);
+   num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
+   attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);
+
+   *drawable_ptr = drawable;
+   *buffer_ptr = buffer;
+   *num_attrib_ptr = (CARD32) i;
+
+   i = 0;
+   if (attrib_list) {
+      while (attrib_list[i * 2] != None) {
+         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
+         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
+         i++;
+      }
+   }
+
+   UnlockDisplay(dpy);
+   SyncHandle();
+}
+
+static void
+indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
+{
+   xGLXVendorPrivateReq *req;
+   struct glx_context *gc = __glXGetCurrentContext();
+   CARD32 *drawable_ptr;
+   INT32 *buffer_ptr;
+   CARD8 opcode;
+
+   opcode = __glXSetupForCommand(dpy);
+   if (!opcode)
+      return;
+
+   LockDisplay(dpy);
+   GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req);
+   req->reqType = opcode;
+   req->glxCode = X_GLXVendorPrivate;
+   req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
+   req->contextTag = gc->currentContextTag;
+
+   drawable_ptr = (CARD32 *) (req + 1);
+   buffer_ptr = (INT32 *) (drawable_ptr + 1);
+
+   *drawable_ptr = drawable;
+   *buffer_ptr = buffer;
+
+   UnlockDisplay(dpy);
+   SyncHandle();
+}
+
+static const struct glx_context_vtable indirect_context_vtable = {
+   indirect_destroy_context,
+   indirect_bind_context,
+   indirect_unbind_context,
+   indirect_wait_gl,
+   indirect_wait_x,
+   indirect_use_x_font,
+   indirect_bind_tex_image,
+   indirect_release_tex_image,
+};
+
+/**
+ * \todo Eliminate \c __glXInitVertexArrayState.  Replace it with a new
+ * function called \c __glXAllocateClientState that allocates the memory and
+ * does all the initialization (including the pixel pack / unpack).
+ */
+_X_HIDDEN struct glx_context *
+indirect_create_context(struct glx_screen *psc,
+			struct glx_config *mode,
+			struct glx_context *shareList, int renderType)
+{
+   struct glx_context *gc;
+   int bufSize;
+   CARD8 opcode;
+   __GLXattribute *state;
+
+   opcode = __glXSetupForCommand(psc->dpy);
+   if (!opcode) {
+      return NULL;
+   }
+
+   /* Allocate our context record */
+   gc = Xmalloc(sizeof *gc);
+   if (!gc) {
+      /* Out of memory */
+      return NULL;
+   }
+   memset(gc, 0, sizeof *gc);
+
+   glx_context_init(gc, psc, mode);
+   gc->isDirect = GL_FALSE;
+   gc->vtable = &indirect_context_vtable;
+   state = Xmalloc(sizeof(struct __GLXattributeRec));
+   if (state == NULL) {
+      /* Out of memory */
+      Xfree(gc);
+      return NULL;
+   }
+   gc->client_state_private = state;
+   memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec));
+   state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
+
+   /*
+    ** Create a temporary buffer to hold GLX rendering commands.  The size
+    ** of the buffer is selected so that the maximum number of GLX rendering
+    ** commands can fit in a single X packet and still have room in the X
+    ** packet for the GLXRenderReq header.
+    */
+
+   bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
+   gc->buf = (GLubyte *) Xmalloc(bufSize);
+   if (!gc->buf) {
+      Xfree(gc->client_state_private);
+      Xfree(gc);
+      return NULL;
+   }
+   gc->bufSize = bufSize;
+
+   /* Fill in the new context */
+   gc->renderMode = GL_RENDER;
+
+   state->storePack.alignment = 4;
+   state->storeUnpack.alignment = 4;
+
+   gc->attributes.stackPointer = &gc->attributes.stack[0];
+
+   /*
+    ** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
+    ** Other code uses the fastImageUnpack bit, but it is never set
+    ** to GL_TRUE.
+    */
+   gc->fastImageUnpack = GL_FALSE;
+   gc->fillImage = __glFillImage;
+   gc->pc = gc->buf;
+   gc->bufEnd = gc->buf + bufSize;
+   gc->isDirect = GL_FALSE;
+   if (__glXDebug) {
+      /*
+       ** Set limit register so that there will be one command per packet
+       */
+      gc->limit = gc->buf;
+   }
+   else {
+      gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
+   }
+   gc->majorOpcode = opcode;
+
+   /*
+    ** Constrain the maximum drawing command size allowed to be
+    ** transfered using the X_GLXRender protocol request.  First
+    ** constrain by a software limit, then constrain by the protocl
+    ** limit.
+    */
+   if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
+      bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
+   }
+   if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
+      bufSize = __GLX_MAX_RENDER_CMD_SIZE;
+   }
+   gc->maxSmallRenderCommandSize = bufSize;
+   
+
+   return gc;
+}
+
+struct glx_screen_vtable indirect_screen_vtable = {
+   indirect_create_context
+};
+
+_X_HIDDEN struct glx_screen *
+indirect_create_screen(int screen, struct glx_display * priv)
+{
+   struct glx_screen *psc;
+
+   psc = Xmalloc(sizeof *psc);
+   if (psc == NULL)
+      return NULL;
+
+   memset(psc, 0, sizeof *psc);
+   glx_screen_init(psc, screen, priv);
+   psc->vtable = &indirect_screen_vtable;
+
+   return psc;
+}




More information about the mesa-commit mailing list