win32: Use thread local storage to get us a dispatch table per thread.

macos/v1.5.9
Eric Anholt 11 years ago
parent 8022cda75d
commit 9a7be0784f
  1. 7
      src/dispatch_common.h
  2. 59
      src/dispatch_wgl.c
  3. 15
      src/gen_dispatch.py

@ -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

@ -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;
}

@ -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('')

Loading…
Cancel
Save