diff options
Diffstat (limited to 'third_party/libepoxy/libepoxy/src/dispatch_wgl.c')
-rw-r--r-- | third_party/libepoxy/libepoxy/src/dispatch_wgl.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/third_party/libepoxy/libepoxy/src/dispatch_wgl.c b/third_party/libepoxy/libepoxy/src/dispatch_wgl.c new file mode 100644 index 0000000000..7baf130571 --- /dev/null +++ b/third_party/libepoxy/libepoxy/src/dispatch_wgl.c @@ -0,0 +1,196 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> + +#include "dispatch_common.h" + +static bool first_context_current = false; +static bool already_switched_to_dispatch_table = false; + +/** + * If we can determine the WGL extension support from the current + * context, then return that, otherwise give the answer that will just + * send us on to get_proc_address(). + */ +bool +epoxy_conservative_has_wgl_extension(const char *ext) +{ + HDC hdc = wglGetCurrentDC(); + + if (!hdc) + return true; + + return epoxy_has_wgl_extension(hdc, ext); +} + +bool +epoxy_has_wgl_extension(HDC hdc, const char *ext) + { + PFNWGLGETEXTENSIONSSTRINGARBPROC getext; + + getext = (void *)wglGetProcAddress("wglGetExtensionsStringARB"); + if (!getext) { + fputs("Implementation unexpectedly missing " + "WGL_ARB_extensions_string. Probably a libepoxy bug.\n", + stderr); + return false; + } + + return epoxy_extension_in_string(getext(hdc), ext); +} + +/** + * Does the work necessary to update the win32 per-thread dispatch + * tables when wglMakeCurrent() is called. + * + * Right now, we use global function pointers until the second + * MakeCurrent occurs, at which point we switch to dispatch tables. + * This could be improved in the future to track a resolved dispatch + * table per context and reuse it when the context is made current + * again. + */ +void +epoxy_handle_external_wglMakeCurrent(void) +{ + if (!first_context_current) { + first_context_current = true; + } else { + if (!already_switched_to_dispatch_table) { + already_switched_to_dispatch_table = true; + gl_switch_to_dispatch_table(); + wgl_switch_to_dispatch_table(); + } + + 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; + + first_context_current = 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); + + break; + + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + data = TlsGetValue(gl_tls_index); + LocalFree(data); + + data = TlsGetValue(wgl_tls_index); + LocalFree(data); + + if (reason == DLL_PROCESS_DETACH) { + TlsFree(gl_tls_index); + TlsFree(wgl_tls_index); + } + break; + } + + return TRUE; +} + +WRAPPER_VISIBILITY (BOOL) +WRAPPER(epoxy_wglMakeCurrent)(HDC hdc, HGLRC hglrc) +{ + BOOL ret = epoxy_wglMakeCurrent_unwrapped(hdc, hglrc); + + epoxy_handle_external_wglMakeCurrent(); + + return ret; +} + + +WRAPPER_VISIBILITY (BOOL) +WRAPPER(epoxy_wglMakeContextCurrentARB)(HDC hDrawDC, + HDC hReadDC, + HGLRC hglrc) +{ + BOOL ret = epoxy_wglMakeContextCurrentARB_unwrapped(hDrawDC, hReadDC, + hglrc); + + epoxy_handle_external_wglMakeCurrent(); + + return ret; +} + + +WRAPPER_VISIBILITY (BOOL) +WRAPPER(epoxy_wglMakeContextCurrentEXT)(HDC hDrawDC, + HDC hReadDC, + HGLRC hglrc) +{ + BOOL ret = epoxy_wglMakeContextCurrentEXT_unwrapped(hDrawDC, hReadDC, + hglrc); + + epoxy_handle_external_wglMakeCurrent(); + + return ret; +} + + +WRAPPER_VISIBILITY (BOOL) +WRAPPER(epoxy_wglMakeAssociatedContextCurrentAMD)(HGLRC hglrc) +{ + BOOL ret = epoxy_wglMakeAssociatedContextCurrentAMD_unwrapped(hglrc); + + epoxy_handle_external_wglMakeCurrent(); + + return ret; +} + +PFNWGLMAKECURRENTPROC epoxy_wglMakeCurrent = epoxy_wglMakeCurrent_wrapped; +PFNWGLMAKECONTEXTCURRENTEXTPROC epoxy_wglMakeContextCurrentEXT = epoxy_wglMakeContextCurrentEXT_wrapped; +PFNWGLMAKECONTEXTCURRENTARBPROC epoxy_wglMakeContextCurrentARB = epoxy_wglMakeContextCurrentARB_wrapped; +PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC epoxy_wglMakeAssociatedContextCurrentEXT = epoxy_wglMakeAssociatedContextCurrentAMD_wrapped; |