Added few more stubs so that control reaches to DestroyDevice().
[mesa.git] / src / glx / indirect_glx.c
index 61ceed3d438081510dd94811e6a4ee889732a632..f370daf8bb6074111e8ad5ce03cc8bd16c2da0bc 100644 (file)
  *   Kristian Høgsberg (krh@bitplanet.net)
  */
 
+#include <stdbool.h>
+
 #include "glapi.h"
 #include "glxclient.h"
+#include "indirect.h"
+#include "util/debug.h"
+
+#ifndef GLX_USE_APPLEGL
 
 extern struct _glapi_table *__glXNewIndirectAPI(void);
 
@@ -43,32 +49,26 @@ 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);
+   free((char *) gc->vendor);
+   free((char *) gc->renderer);
+   free((char *) gc->version);
+   free((char *) gc->extensions);
    __glFreeAttributeState(gc);
-   XFree((char *) gc->buf);
-   Xfree((char *) gc->client_state_private);
-   XFree((char *) gc);
+   free((char *) gc->buf);
+   free((char *) gc->client_state_private);
+   free((char *) gc);
 }
 
 static Bool
-SendMakeCurrentRequest(Display * dpy, CARD8 opcode,
-                       GLXContextID gc_id, GLXContextTag gc_tag,
-                       GLXDrawable draw, GLXDrawable read,
-                       xGLXMakeCurrentReply * reply)
+SendMakeCurrentRequest(Display * dpy, GLXContextID gc_id,
+                       GLXContextTag gc_tag, GLXDrawable draw,
+                       GLXDrawable read, GLXContextTag *out_tag)
 {
+   xGLXMakeCurrentReply reply;
    Bool ret;
+   int opcode = __glXSetupForCommand(dpy);
 
    LockDisplay(dpy);
 
@@ -119,7 +119,10 @@ SendMakeCurrentRequest(Display * dpy, CARD8 opcode,
       }
    }
 
-   ret = _XReply(dpy, (xReply *) reply, 0, False);
+   ret = _XReply(dpy, (xReply *) &reply, 0, False);
+
+   if (out_tag)
+      *out_tag = reply.contextTag;
 
    UnlockDisplay(dpy);
    SyncHandle();
@@ -131,11 +134,9 @@ 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);
+   Bool sent;
 
    if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) {
       tag = old->currentContextTag;
@@ -144,37 +145,49 @@ indirect_bind_context(struct glx_context *gc, struct glx_context *old,
       tag = 0;
    }
 
-   SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, &reply);
+   sent = SendMakeCurrentRequest(dpy, gc->xid, tag, draw, read,
+                                &gc->currentContextTag);
 
-   if (!IndirectAPI)
-      IndirectAPI = __glXNewIndirectAPI();
-   _glapi_set_dispatch(IndirectAPI);
+   if (sent) {
+      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);
+      /* The indirect vertex array state must to be initialised after we
+       * have setup the context, as it needs to query server attributes.
+       *
+       * At the point this is called gc->currentDpy is not initialized
+       * nor is the thread's current context actually set. Hence the
+       * cleverness before the GetString calls.
+       */
+      __GLXattribute *state = gc->client_state_private;
+      if (state && state->array_state == NULL) {
+         gc->currentDpy = gc->psc->dpy;
+         __glXSetCurrentContext(gc);
+         __indirect_glGetString(GL_EXTENSIONS);
+         __indirect_glGetString(GL_VERSION);
+         __glXInitVertexArrayState(gc);
+      }
    }
 
-   return Success;
+   return !sent;
 }
 
 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
+   if (gc == new)
+      return;
+   
+   /* We are either switching to no context, away from an 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);
+      SendMakeCurrentRequest(dpy, None, gc->currentContextTag, None, None,
+                             NULL);
       gc->currentContextTag = 0;
    }
 }
@@ -324,20 +337,25 @@ indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
 }
 
 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,
+   .destroy             = indirect_destroy_context,
+   .bind                = indirect_bind_context,
+   .unbind              = indirect_unbind_context,
+   .wait_gl             = indirect_wait_gl,
+   .wait_x              = indirect_wait_x,
+   .use_x_font          = indirect_use_x_font,
+   .bind_tex_image      = indirect_bind_tex_image,
+   .release_tex_image   = indirect_release_tex_image,
+   .get_proc_address    = NULL,
 };
 
 /**
  * \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).
+ *
+ * \note
+ * This function is \b not the place to validate the context creation
+ * parameters.  It is just the allocator for the \c glx_context.
  */
 _X_HIDDEN struct glx_context *
 indirect_create_context(struct glx_screen *psc,
@@ -355,25 +373,25 @@ indirect_create_context(struct glx_screen *psc,
    }
 
    /* Allocate our context record */
-   gc = Xmalloc(sizeof *gc);
+   gc = calloc(1, 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));
+   state = calloc(1, sizeof(struct __GLXattributeRec));
+   gc->renderType = renderType;
+
    if (state == NULL) {
       /* Out of memory */
-      Xfree(gc);
+      free(gc);
       return NULL;
    }
    gc->client_state_private = state;
-   memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec));
-   state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
+   state->NoDrawArraysProtocol = env_var_as_boolean("LIBGL_NO_DRAWARRAYS", false);
 
    /*
     ** Create a temporary buffer to hold GLX rendering commands.  The size
@@ -383,10 +401,10 @@ indirect_create_context(struct glx_screen *psc,
     */
 
    bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
-   gc->buf = (GLubyte *) Xmalloc(bufSize);
+   gc->buf = malloc(bufSize);
    if (!gc->buf) {
-      Xfree(gc->client_state_private);
-      Xfree(gc);
+      free(gc->client_state_private);
+      free(gc);
       return NULL;
    }
    gc->bufSize = bufSize;
@@ -399,13 +417,6 @@ indirect_create_context(struct glx_screen *psc,
 
    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;
@@ -438,8 +449,39 @@ indirect_create_context(struct glx_screen *psc,
    return gc;
 }
 
-struct glx_screen_vtable indirect_screen_vtable = {
-   indirect_create_context
+_X_HIDDEN struct glx_context *
+indirect_create_context_attribs(struct glx_screen *base,
+                               struct glx_config *config_base,
+                               struct glx_context *shareList,
+                               unsigned num_attribs,
+                               const uint32_t *attribs,
+                               unsigned *error)
+{
+   int renderType = GLX_RGBA_TYPE;
+   unsigned i;
+
+   /* The error parameter is only used on the server so that correct GLX
+    * protocol errors can be generated.  On the client, it can be ignored.
+    */
+   (void) error;
+
+   /* All of the attribute validation for indirect contexts is handled on the
+    * server, so there's not much to do here. Still, we need to parse the
+    * attributes to correctly set renderType.
+    */
+   for (i = 0; i < num_attribs; i++) {
+      if (attribs[i * 2] == GLX_RENDER_TYPE)
+         renderType = attribs[i * 2 + 1];
+   }
+
+   return indirect_create_context(base, config_base, shareList, renderType);
+}
+
+static const struct glx_screen_vtable indirect_screen_vtable = {
+   .create_context         = indirect_create_context,
+   .create_context_attribs = indirect_create_context_attribs,
+   .query_renderer_integer = NULL,
+   .query_renderer_string  = NULL,
 };
 
 _X_HIDDEN struct glx_screen *
@@ -447,13 +489,14 @@ indirect_create_screen(int screen, struct glx_display * priv)
 {
    struct glx_screen *psc;
 
-   psc = Xmalloc(sizeof *psc);
+   psc = calloc(1, 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;
 }
+
+#endif