* #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
*
*/
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);
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);
}
}
else {
- _glapi_set_dispatch(newCtx->CurrentDispatch);
+ _glapi_set_dispatch(newCtx->CurrentClientDispatch);
if (drawBuffer && readBuffer) {
assert(_mesa_is_winsys_fbo(drawBuffer));
/**
* 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;
}
/*@}*/
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;
+ }
}
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;
+ }
}
/* 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;
+ }
}
}
/* 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;
+ }
}
}
static void
glthread_unmarshal_batch(struct gl_context *ctx, struct glthread_batch *batch)
{
+ _glapi_set_dispatch(ctx->CurrentServerDispatch);
+
free(batch->buffer);
free(batch);
}
free(glthread);
ctx->GLThread = NULL;
+
+ /* Remove ourselves from the dispatch table. */
+ ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+ _glapi_set_dispatch(ctx->CurrentClientDispatch);
}
void
*/
if (false) {
glthread_unmarshal_batch(ctx, batch);
+ _glapi_set_dispatch(ctx->CurrentClientDispatch);
return;
}
/** \name API function pointer tables */
/*@{*/
gl_api API;
+
/**
* The current dispatch table for non-displaylist-saving execution, either
* BeginEnd or OutsideBeginEnd
*/
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;
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);
}
/**
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]));
}
}
}
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] ));
}
}
}
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] ));
}
}
}
/* 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);
}
}
}
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) {