From: Eric Anholt <e...@anholt.net> v2: Rebase on the Begin/End changes, and just disable this feature on non-GL-core. --- src/mapi/glapi/gen/gl_marshal.py | 10 ++++++++++ src/mesa/Makefile.sources | 2 ++ src/mesa/main/glthread.c | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+)
diff --git a/src/mapi/glapi/gen/gl_marshal.py b/src/mapi/glapi/gen/gl_marshal.py index f8dfa00..e4137f4 100644 --- a/src/mapi/glapi/gen/gl_marshal.py +++ b/src/mapi/glapi/gen/gl_marshal.py @@ -59,20 +59,30 @@ def indent(delta = 3): class PrintCode(gl_XML.gl_print_base): def __init__(self): super(PrintCode, self).__init__() self.name = 'gl_marshal.py' self.license = license.bsd_license_template % ( 'Copyright (C) 2012 Intel Corporation', 'INTEL CORPORATION') def printRealHeader(self): print header + print '#include <X11/Xlib-xcb.h>' + print + print 'static _X_INLINE int safe_mul(int a, int b)' + print '{' + print ' if (a < 0 || b < 0) return -1;' + print ' if (a == 0 || b == 0) return 0;' + print ' if (a > INT_MAX / b) return -1;' + print ' return a * b;' + print '}' + print def printRealFooter(self): pass def print_sync_call(self, func): call = 'CALL_{0}(ctx->CurrentServerDispatch, ({1}))'.format( func.name, func.get_called_parameter_string()) if func.return_type == 'void': out('{0};'.format(call)) else: diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources index 87d675d..65e1fc9 100644 --- a/src/mesa/Makefile.sources +++ b/src/mesa/Makefile.sources @@ -125,20 +125,22 @@ MAIN_FILES = \ main/histogram.h \ main/image.c \ main/image.h \ main/imports.c \ main/imports.h \ main/light.c \ main/light.h \ main/lines.c \ main/lines.h \ main/macros.h \ + main/marshal_generated.c \ + main/marshal_generated.h \ main/matrix.c \ main/matrix.h \ main/mipmap.c \ main/mipmap.h \ main/mm.c \ main/mm.h \ main/mtypes.h \ main/multisample.c \ main/multisample.h \ main/objectlabel.c \ diff --git a/src/mesa/main/glthread.c b/src/mesa/main/glthread.c index 8877a69..01ca78c 100644 --- a/src/mesa/main/glthread.c +++ b/src/mesa/main/glthread.c @@ -47,22 +47,30 @@ glthread_allocate_batch(struct gl_context *ctx) /* TODO: handle memory allocation failure. */ glthread->batch = calloc(1, sizeof(*glthread->batch)); if (!glthread->batch) return; glthread->batch->buffer = malloc(MARSHAL_MAX_CMD_SIZE); } static void glthread_unmarshal_batch(struct gl_context *ctx, struct glthread_batch *batch) { + size_t pos = 0; + _glapi_set_dispatch(ctx->CurrentServerDispatch); + while (pos < batch->used) { + pos += _mesa_unmarshal_dispatch_cmd(ctx, &batch->buffer[pos]); + } + + assert(pos == batch->used); + free(batch->buffer); free(batch); } static void * glthread_worker(void *data) { struct gl_context *ctx = data; struct glthread_state *glthread = ctx->GLThread; @@ -105,20 +113,37 @@ glthread_worker(void *data) } void _mesa_glthread_init(struct gl_context *ctx) { struct glthread_state *glthread = calloc(1, sizeof(*glthread)); if (!glthread) return; + /* The marshalling dispatch table isn't integrated with the Begin/End + * dispatch table for desktop OpenGL, and the drawing functions are + * synchronous to support user vertex arrays on everything but GL core + * (even GLES 2/3) anyway, which means you'll end up with too much overhead + * from threading. + */ + if (ctx->API != API_OPENGL_CORE) + return; + + ctx->MarshalExec = _mesa_create_marshal_table(ctx); + if (!ctx->MarshalExec) { + free(glthread); + return; + } + + ctx->CurrentClientDispatch = ctx->MarshalExec; + pthread_mutex_init(&glthread->mutex, NULL); pthread_cond_init(&glthread->new_work, NULL); pthread_cond_init(&glthread->work_done, NULL); glthread->batch_queue_tail = &glthread->batch_queue; ctx->GLThread = glthread; glthread_allocate_batch(ctx); pthread_create(&glthread->thread, NULL, glthread_worker, ctx); -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev