diff options
author | Eric Anholt <eric@anholt.net> | 2013-12-17 09:31:39 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2013-12-17 12:11:05 -0800 |
commit | 9a7be0784faba0d97a32051a873d7feb47981a37 (patch) | |
tree | ab1e3ff4bb950aee5dd0c1844c0389b06236bd71 /src | |
parent | 8022cda75d65f537c48d4b43b44879abe558c1b7 (diff) |
win32: Use thread local storage to get us a dispatch table per thread.
Diffstat (limited to 'src')
-rw-r--r-- | src/dispatch_common.h | 7 | ||||
-rw-r--r-- | src/dispatch_wgl.c | 59 | ||||
-rwxr-xr-x | 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('') |