mesa: Create pointers for multithread marshalling dispatch table.
authorPaul Berry <stereotype441@gmail.com>
Wed, 3 Oct 2012 22:39:52 +0000 (15:39 -0700)
committerTimothy Arceri <tarceri@itsqueeze.com>
Thu, 16 Mar 2017 03:14:18 +0000 (14:14 +1100)
This patch splits the context's CurrentDispatch pointer into two
pointers, CurrentClientDispatch, and CurrentServerDispatch, so that
when doing multithread marshalling, we can distinguish between the
dispatch table that's being used by the client (to serialize GL calls
into the marshal buffer) and the dispatch table that's being used by
the server (to execute the GL calls).

Acked-by: Timothy Arceri <tarceri@itsqueeze.com>
Acked-by: Marek Olšák <maraeo@gmail.com>
Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
Tested-by: Mike Lothian <mike@fireburn.co.uk>
src/mapi/glapi/gen/gl_apitemp.py
src/mesa/main/context.c
src/mesa/main/dlist.c
src/mesa/main/glthread.c
src/mesa/main/mtypes.h
src/mesa/main/robustness.c
src/mesa/main/varray.c
src/mesa/vbo/vbo_exec_api.c

index e1b94f5025627e392a1e6999118fe7ce1a5dba5f..a8e5d814555bbdab536d0b49a1185fdebdcc53d1 100644 (file)
@@ -133,11 +133,11 @@ class PrintGlOffsets(gl_XML.gl_print_base):
  *   #define KEYWORD1
  *   #define KEYWORD2
  *   #define NAME(func)  gl##func
- *   #define DISPATCH(func, args, msg)                           \\
- *          struct _glapi_table *dispatch = CurrentDispatch;     \\
+ *   #define DISPATCH(func, args, msg)                             \\
+ *          struct _glapi_table *dispatch = CurrentClientDispatch; \\
  *          (*dispatch->func) args
- *   #define RETURN DISPATCH(func, args, msg)                    \\
- *          struct _glapi_table *dispatch = CurrentDispatch;     \\
+ *   #define RETURN DISPATCH(func, args, msg)                      \\
+ *          struct _glapi_table *dispatch = CurrentClientDispatch; \\
  *          return (*dispatch->func) args
  *
  */
index 95a337b14bc69f41fd9afa7993b31fc2e9255527..4b654de4582f61f196c3c294e7bf951f40006f74 100644 (file)
@@ -1213,7 +1213,7 @@ _mesa_initialize_context(struct gl_context *ctx,
    if (!ctx->OutsideBeginEnd)
       goto fail;
    ctx->Exec = ctx->OutsideBeginEnd;
-   ctx->CurrentDispatch = ctx->OutsideBeginEnd;
+   ctx->CurrentClientDispatch = ctx->CurrentServerDispatch = ctx->OutsideBeginEnd;
 
    ctx->FragmentProgram._MaintainTexEnvProgram
       = (getenv("MESA_TEX_PROG") != NULL);
@@ -1342,6 +1342,7 @@ _mesa_free_context_data( struct gl_context *ctx )
    free(ctx->OutsideBeginEnd);
    free(ctx->Save);
    free(ctx->ContextLost);
+   free(ctx->MarshalExec);
 
    /* Shared context state (display lists, textures, etc) */
    _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
@@ -1666,7 +1667,7 @@ _mesa_make_current( struct gl_context *newCtx,
       }
    }
    else {
-      _glapi_set_dispatch(newCtx->CurrentDispatch);
+      _glapi_set_dispatch(newCtx->CurrentClientDispatch);
 
       if (drawBuffer && readBuffer) {
          assert(_mesa_is_winsys_fbo(drawBuffer));
@@ -1768,19 +1769,19 @@ _mesa_get_current_context( void )
 /**
  * Get context's current API dispatch table.
  *
- * It'll either be the immediate-mode execute dispatcher or the display list
- * compile dispatcher.
+ * It'll either be the immediate-mode execute dispatcher, the display list
+ * compile dispatcher, or the thread marshalling dispatcher.
  *
  * \param ctx GL context.
  *
  * \return pointer to dispatch_table.
  *
- * Simply returns __struct gl_contextRec::CurrentDispatch.
+ * Simply returns __struct gl_contextRec::CurrentClientDispatch.
  */
 struct _glapi_table *
 _mesa_get_dispatch(struct gl_context *ctx)
 {
-   return ctx->CurrentDispatch;
+   return ctx->CurrentClientDispatch;
 }
 
 /*@}*/
index 2976f62a5912db4f1bcb874a56c4b2ddef800595..7e440549e5bf081d66c7c2c338b009322cd50fc7 100644 (file)
@@ -9340,8 +9340,11 @@ _mesa_NewList(GLuint name, GLenum mode)
 
    vbo_save_NewList(ctx, name, mode);
 
-   ctx->CurrentDispatch = ctx->Save;
-   _glapi_set_dispatch(ctx->CurrentDispatch);
+   ctx->CurrentServerDispatch = ctx->Save;
+   _glapi_set_dispatch(ctx->CurrentServerDispatch);
+   if (ctx->MarshalExec == NULL) {
+      ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+   }
 }
 
 
@@ -9396,8 +9399,11 @@ _mesa_EndList(void)
    ctx->ExecuteFlag = GL_TRUE;
    ctx->CompileFlag = GL_FALSE;
 
-   ctx->CurrentDispatch = ctx->Exec;
-   _glapi_set_dispatch(ctx->CurrentDispatch);
+   ctx->CurrentServerDispatch = ctx->Exec;
+   _glapi_set_dispatch(ctx->CurrentServerDispatch);
+   if (ctx->MarshalExec == NULL) {
+      ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+   }
 }
 
 
@@ -9432,8 +9438,11 @@ _mesa_CallList(GLuint list)
 
    /* also restore API function pointers to point to "save" versions */
    if (save_compile_flag) {
-      ctx->CurrentDispatch = ctx->Save;
-      _glapi_set_dispatch(ctx->CurrentDispatch);
+      ctx->CurrentServerDispatch = ctx->Save;
+       _glapi_set_dispatch(ctx->CurrentServerDispatch);
+      if (ctx->MarshalExec == NULL) {
+         ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+      }
    }
 }
 
@@ -9555,8 +9564,11 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
 
    /* also restore API function pointers to point to "save" versions */
    if (save_compile_flag) {
-      ctx->CurrentDispatch = ctx->Save;
-      _glapi_set_dispatch(ctx->CurrentDispatch);
+      ctx->CurrentServerDispatch = ctx->Save;
+      _glapi_set_dispatch(ctx->CurrentServerDispatch);
+      if (ctx->MarshalExec == NULL) {
+         ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+      }
    }
 }
 
index 76eb0cf7dac818193858b856e429a156acb46fb0..8877a695f0c4c0d94b377fd1d061034adef1035a 100644 (file)
@@ -54,6 +54,8 @@ glthread_allocate_batch(struct gl_context *ctx)
 static void
 glthread_unmarshal_batch(struct gl_context *ctx, struct glthread_batch *batch)
 {
+   _glapi_set_dispatch(ctx->CurrentServerDispatch);
+
    free(batch->buffer);
    free(batch);
 }
@@ -156,6 +158,10 @@ _mesa_glthread_destroy(struct gl_context *ctx)
 
    free(glthread);
    ctx->GLThread = NULL;
+
+   /* Remove ourselves from the dispatch table. */
+   ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+   _glapi_set_dispatch(ctx->CurrentClientDispatch);
 }
 
 void
@@ -183,6 +189,7 @@ _mesa_glthread_flush_batch(struct gl_context *ctx)
     */
    if (false) {
       glthread_unmarshal_batch(ctx, batch);
+      _glapi_set_dispatch(ctx->CurrentClientDispatch);
       return;
    }
 
index 187f2d1bd68cc3959ec7a30df50d2855f4562690..7e970843d5cb3b386ed33c2341ce61576726dc5f 100644 (file)
@@ -4405,6 +4405,7 @@ struct gl_context
    /** \name API function pointer tables */
    /*@{*/
    gl_api API;
+
    /**
     * The current dispatch table for non-displaylist-saving execution, either
     * BeginEnd or OutsideBeginEnd
@@ -4427,10 +4428,24 @@ struct gl_context
     */
    struct _glapi_table *ContextLost;
    /**
-    * Tracks the current dispatch table out of the 4 above, so that it can be
-    * re-set on glXMakeCurrent().
+    * Dispatch table used to marshal API calls from the client program to a
+    * separate server thread.  NULL if API calls are not being marshalled to
+    * another thread.
+    */
+   struct _glapi_table *MarshalExec;
+   /**
+    * Dispatch table currently in use for fielding API calls from the client
+    * program.  If API calls are being marshalled to another thread, this ==
+    * MarshalExec.  Otherwise it == CurrentServerDispatch.
     */
-   struct _glapi_table *CurrentDispatch;
+   struct _glapi_table *CurrentClientDispatch;
+
+   /**
+    * Dispatch table currently in use for performing API calls.  == Save or
+    * Exec.
+    */
+   struct _glapi_table *CurrentServerDispatch;
+
    /*@}*/
 
    struct glthread_state *GLThread;
index f54d9f3eb1e9f5069598770c7c22b7a11b26b31a..47402a293041206c5277ecb8b795abfb006ce680 100644 (file)
@@ -101,8 +101,8 @@ _mesa_set_context_lost_dispatch(struct gl_context *ctx)
       SET_GetQueryObjectuiv(ctx->ContextLost, _context_lost_GetQueryObjectuiv);
    }
 
-   ctx->CurrentDispatch = ctx->ContextLost;
-   _glapi_set_dispatch(ctx->CurrentDispatch);
+   ctx->CurrentServerDispatch = ctx->ContextLost;
+   _glapi_set_dispatch(ctx->CurrentServerDispatch);
 }
 
 /**
index c4283551882ea7286b45ccb86c3fe6ece3e57011..92e3f4d1f8a9d426f2a57d06cf8930bdbc7ed198 100644 (file)
@@ -1558,7 +1558,7 @@ _mesa_MultiDrawArrays( GLenum mode, const GLint *first,
 
    for (i = 0; i < primcount; i++) {
       if (count[i] > 0) {
-         CALL_DrawArrays(ctx->CurrentDispatch, (mode, first[i], count[i]));
+         CALL_DrawArrays(ctx->CurrentClientDispatch, (mode, first[i], count[i]));
       }
    }
 }
@@ -1578,7 +1578,7 @@ _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
    for ( i = 0 ; i < primcount ; i++ ) {
       if ( count[i] > 0 ) {
          GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
-        CALL_DrawArrays(ctx->CurrentDispatch, ( m, first[i], count[i] ));
+        CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] ));
       }
    }
 }
@@ -1600,8 +1600,8 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
    for ( i = 0 ; i < primcount ; i++ ) {
       if ( count[i] > 0 ) {
          GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
-        CALL_DrawElements(ctx->CurrentDispatch, ( m, count[i], type,
-                                                   indices[i] ));
+        CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type,
+                                                        indices[i] ));
       }
    }
 }
index fffff0b3bf0983bef1c6d00be1e3db720dfc115e..f08fd4c32c6ed561cfdbf681b47681c0bd269c7c 100644 (file)
@@ -797,11 +797,11 @@ vbo_exec_Begin(GLenum mode)
    /* We may have been called from a display list, in which case we should
     * leave dlist.c's dispatch table in place.
     */
-   if (ctx->CurrentDispatch == ctx->OutsideBeginEnd) {
-      ctx->CurrentDispatch = ctx->BeginEnd;
-      _glapi_set_dispatch(ctx->CurrentDispatch);
+   if (ctx->CurrentClientDispatch == ctx->OutsideBeginEnd) {
+      ctx->CurrentClientDispatch = ctx->BeginEnd;
+      _glapi_set_dispatch(ctx->CurrentClientDispatch);
    } else {
-      assert(ctx->CurrentDispatch == ctx->Save);
+      assert(ctx->CurrentClientDispatch == ctx->Save);
    }
 }
 
@@ -849,9 +849,9 @@ vbo_exec_End(void)
    }
 
    ctx->Exec = ctx->OutsideBeginEnd;
-   if (ctx->CurrentDispatch == ctx->BeginEnd) {
-      ctx->CurrentDispatch = ctx->OutsideBeginEnd;
-      _glapi_set_dispatch(ctx->CurrentDispatch);
+   if (ctx->CurrentClientDispatch == ctx->BeginEnd) {
+      ctx->CurrentClientDispatch = ctx->OutsideBeginEnd;
+      _glapi_set_dispatch(ctx->CurrentClientDispatch);
    }
 
    if (exec->vtx.prim_count > 0) {