From 9a7be0784faba0d97a32051a873d7feb47981a37 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 17 Dec 2013 09:31:39 -0800 Subject: [PATCH] win32: Use thread local storage to get us a dispatch table per thread. --- src/dispatch_common.h | 7 +++++ src/dispatch_wgl.c | 59 +++++++++++++++++++++++++++++++++++++++++++ src/gen_dispatch.py | 15 +++++++++-- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/dispatch_common.h b/src/dispatch_common.h index 7f317a4..5170239 100644 --- a/src/dispatch_common.h +++ b/src/dispatch_common.h @@ -94,3 +94,10 @@ bool epoxy_extension_in_string(const char *extension_list, const char *ext); extern void UNWRAPPED_PROTO(epoxy_glBegin_unwrapped)(GLenum primtype); extern void UNWRAPPED_PROTO(epoxy_glEnd_unwrapped)(void); + +#if USING_DISPATCH_TABLE +void gl_init_dispatch_table(void); +void wgl_init_dispatch_table(void); +extern uint32_t gl_tls_index, gl_tls_size; +extern uint32_t wgl_tls_index, wgl_tls_size; +#endif diff --git a/src/dispatch_wgl.c b/src/dispatch_wgl.c index fe871d9..0161ad4 100644 --- a/src/dispatch_wgl.c +++ b/src/dispatch_wgl.c @@ -58,3 +58,62 @@ epoxy_has_wgl_extension(HDC hdc, const char *ext) return epoxy_extension_in_string(getext(hdc), ext); } + +static void +reset_dispatch_table(void) +{ + gl_init_dispatch_table(); + wgl_init_dispatch_table(); +} + +/** + * This global symbol is apparently looked up by Windows when loading + * a DLL, but it doesn't declare the prototype. + */ +BOOL WINAPI +DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved); + +BOOL WINAPI +DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved) +{ + void *data; + + switch (reason) { + case DLL_PROCESS_ATTACH: + gl_tls_index = TlsAlloc(); + if (gl_tls_index == TLS_OUT_OF_INDEXES) + return FALSE; + wgl_tls_index = TlsAlloc(); + if (wgl_tls_index == TLS_OUT_OF_INDEXES) + return FALSE; + + /* FALLTHROUGH */ + + case DLL_THREAD_ATTACH: + data = LocalAlloc(LPTR, gl_tls_size); + TlsSetValue(gl_tls_index, data); + + data = LocalAlloc(LPTR, wgl_tls_size); + TlsSetValue(wgl_tls_index, data); + + reset_dispatch_table(); + break; + + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + data = TlsGetValue(gl_tls_index); + LocalFree(data); + + data = TlsGetValue(wgl_tls_index); + LocalFree(data); + break; + + if (reason == DLL_PROCESS_DETACH) { + TlsFree(gl_tls_index); + TlsFree(wgl_tls_index); + } + break; + } + + return TRUE; +} diff --git a/src/gen_dispatch.py b/src/gen_dispatch.py index 4da840a..35c74de 100755 --- a/src/gen_dispatch.py +++ b/src/gen_dispatch.py @@ -794,11 +794,22 @@ class Generator(object): self.outln('};') self.outln('') + self.outln('uint32_t {0}_tls_index;'.format(self.target)) + self.outln('uint32_t {0}_tls_size = sizeof(struct dispatch_table);'.format(self.target)) + self.outln('') + self.outln('static inline struct dispatch_table *') self.outln('get_dispatch_table(void)') self.outln('{') - self.outln(' /* XXX: Make this thread-local and swapped on makecurrent on win32. */') - self.outln(' return &resolver_table;') + self.outln(' return TlsGetValue({0}_tls_index);'.format(self.target)) + self.outln('}') + self.outln('') + + self.outln('void') + self.outln('{0}_init_dispatch_table(void)'.format(self.target)) + self.outln('{') + self.outln(' struct dispatch_table *dispatch_table = get_dispatch_table();') + self.outln(' memcpy(dispatch_table, &resolver_table, sizeof(resolver_table));') self.outln('}') self.outln('')