diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | include/epoxy/wgl.h | 60 | ||||
-rw-r--r-- | src/Makefile.am | 29 | ||||
-rw-r--r-- | src/dispatch_common.c | 12 | ||||
-rw-r--r-- | src/dispatch_common.h | 6 | ||||
-rw-r--r-- | src/dispatch_wgl.c | 60 | ||||
-rwxr-xr-x | src/gen_dispatch.py | 34 |
8 files changed, 212 insertions, 1 deletions
@@ -93,3 +93,7 @@ glx_generated_vtable_defines.h egl_generated_dispatch.c egl_generated.h egl_generated_vtable_defines.h + +wgl_generated_dispatch.c +wgl_generated.h +wgl_generated_vtable_defines.h diff --git a/configure.ac b/configure.ac index a9fc38b..2031414 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,7 @@ case $host_os in mingw*) build_egl=no build_glx=no + build_wgl=yes # On windows, the DLL has to have all of its functions # resolved at link time, so we have to link directly aginst # opengl32.dll. But that's the only GL provider, anyway. @@ -66,6 +67,7 @@ case $host_os in *) build_egl=yes build_glx=yes + build_wgl=no # On platforms with dlopen, we load everything dynamically and # don't link against a specific window system or GL implementation. EPOXY_LINK_LIBS="" @@ -84,6 +86,11 @@ if test x$build_glx = xyes; then AC_DEFINE([BUILD_GLX], [1], [build GLX tests]) fi +AM_CONDITIONAL(BUILD_WGL, test x$build_wgl = xyes) +if test x$build_wgl = xyes; then + AC_DEFINE([BUILD_WGL], [1], [build WGL tests]) +fi + case $host_os in mingw*) @@ -123,4 +130,5 @@ AC_OUTPUT echo " EGL: $build_egl" echo " GLX: $build_glx" +echo " WGL: $build_wgl" echo " PYTHON: $PYTHON" diff --git a/include/epoxy/wgl.h b/include/epoxy/wgl.h new file mode 100644 index 0000000..ded7b59 --- /dev/null +++ b/include/epoxy/wgl.h @@ -0,0 +1,60 @@ +/* + * 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. + */ + +/** @file wgl.h + * + * Provides an implementation of a WGL dispatch layer using a hidden + * vtable. + */ + +#ifndef __EPOXY_WGL_H +#define __EPOXY_WGL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdbool.h> +#include <windows.h> + +#undef wglUseFontBitmaps +#undef wglUseFontOutlines + +#if defined(__wglxext_h_) +#error epoxy/wgl.h must be included before (or in place of) wgl.h +#else +#define __wglxext_h_ +#endif + +#pragma once + +#include "epoxy/wgl_generated.h" +#include "epoxy/wgl_generated_vtable_defines.h" + +bool epoxy_has_wgl_extension(HDC hdc, const char *extension); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __EPOXY_WGL_H */ diff --git a/src/Makefile.am b/src/Makefile.am index cfe4cea..a39300c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,10 @@ if BUILD_GLX INSTALL_GLX_INCLUDES = $(GENERATED_GLX_INCLUDES) endif +if BUILD_WGL +INSTALL_WGL_INCLUDES = $(GENERATED_WGL_INCLUDES) +endif + GENERATED_GL_INCLUDES = \ $(builddir)/../include/epoxy/gl_generated.h \ $(builddir)/../include/epoxy/gl_generated_vtable_defines.h \ @@ -57,6 +61,11 @@ GENERATED_EGL_INCLUDES = \ $(builddir)/../include/epoxy/egl_generated_vtable_defines.h \ $() +GENERATED_WGL_INCLUDES = \ + $(tuilddir)/../include/epoxy/wgl_generated.h \ + $(builddir)/../include/epoxy/wgl_generated_vtable_defines.h \ + $() + GENERATED_GL_SOURCE = gl_generated_dispatch.c GENERATED_GL = \ @@ -78,10 +87,18 @@ GENERATED_EGL = \ $(GENERATED_EGL_INCLUDES) \ $() +GENERATED_WGL_SOURCE = wgl_generated_dispatch.c + +GENERATED_WGL = \ + $(GENERATED_WGL_SOURCE) \ + $(GENERATED_WGL_INCLUDES) \ + $() + BUILT_SOURCES = \ $(GENERATED_GL) \ $(GENERATED_GLX) \ $(GENERATED_EGL) \ + $(GENERATED_WGL) \ $() CLEANFILES = $(BUILT_SOURCES) @@ -91,6 +108,7 @@ libepoxy_la_SOURCES = \ $(GENERATED_GL) \ $(BUILD_EGL_CODE) \ $(BUILD_GLX_CODE) \ + $(BUILD_WGL_CODE) \ $() libepoxy_la_LDFLAGS = \ @@ -112,10 +130,18 @@ BUILD_GLX_CODE = \ $() endif +if BUILD_WGL +BUILD_WGL_CODE = \ + $(GENERATED_WGL) \ + dispatch_wgl.c \ + $() +endif + # These are generated alongside the .c file. $(GENERATED_GL_INCLUDES): $(GENERATED_GL_SOURCE) $(GENERATED_GLX_INCLUDES): $(GENERATED_GLX_SOURCE) $(GENERATED_EGL_INCLUDES): $(GENERATED_EGL_SOURCE) +$(GENERATED_WGL_INCLUDES): $(GENERATED_WGL_SOURCE) $(GENERATED_GL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/gl.xml $(MKDIR_P) $(top_builddir)/include/epoxy @@ -126,3 +152,6 @@ $(GENERATED_GLX_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/glx.xm $(GENERATED_EGL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/egl.xml $(AM_V_GEN)$(PYTHON) $(srcdir)/gen_dispatch.py --dir $(top_builddir) $(top_srcdir)/registry/egl.xml + +$(GENERATED_WGL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/wgl.xml + $(AM_V_GEN)$(PYTHON) $(srcdir)/gen_dispatch.py --dir $(top_builddir) $(top_srcdir)/registry/wgl.xml diff --git a/src/dispatch_common.c b/src/dispatch_common.c index 002180b..d5051cd 100644 --- a/src/dispatch_common.c +++ b/src/dispatch_common.c @@ -322,8 +322,12 @@ epoxy_glx_dlsym(const char *name) void * epoxy_gl_dlsym(const char *name) { +#ifdef _WIN32 + return GetProcAddress(LoadLibraryA("OPENGL32"), name); +#else /* There's no library for desktop GL support independent of GLX. */ return epoxy_glx_dlsym(name); +#endif } void * @@ -341,7 +345,13 @@ epoxy_gles2_dlsym(const char *name) void * epoxy_get_core_proc_address(const char *name, int core_version) { - if (core_version <= 12) { +#ifdef _WIN32 + int core_symbol_support = 10; +#else + int core_symbol_support = 12; +#endif + + if (core_version <= core_symbol_support) { return epoxy_gl_dlsym(name); } else { return epoxy_get_proc_address(name); diff --git a/src/dispatch_common.h b/src/dispatch_common.h index 78fc042..f18fd7b 100644 --- a/src/dispatch_common.h +++ b/src/dispatch_common.h @@ -26,9 +26,11 @@ #ifdef _WIN32 #define PLATFORM_HAS_EGL 0 #define PLATFORM_HAS_GLX 0 +#define PLATFORM_HAS_WGL 1 #else #define PLATFORM_HAS_EGL 1 #define PLATFORM_HAS_GLX 1 +#define PLATFORM_HAS_WGL 0 #endif #include "epoxy/gl.h" @@ -38,6 +40,9 @@ #if PLATFORM_HAS_EGL #include "epoxy/egl.h" #endif +#if PLATFORM_HAS_WGL +#include "epoxy/wgl.h" +#endif #ifndef PUBLIC # ifdef _WIN32 @@ -63,6 +68,7 @@ int epoxy_conservative_glx_version(void); bool epoxy_conservative_has_glx_extension(const char *name); int epoxy_conservative_egl_version(void); bool epoxy_conservative_has_egl_extension(const char *name); +bool epoxy_conservative_has_wgl_extension(const char *name); void epoxy_print_failure_reasons(const char *name, const char **provider_names, const int *providers); diff --git a/src/dispatch_wgl.c b/src/dispatch_wgl.c new file mode 100644 index 0000000..fe871d9 --- /dev/null +++ b/src/dispatch_wgl.c @@ -0,0 +1,60 @@ +/* + * 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" + +/** + * 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); +} + +PUBLIC bool +epoxy_has_wgl_extension(HDC hdc, const char *ext) + { + PFNWGLGETEXTENSIONSSTRINGARBPROC getext; + + getext = (void *)wglGetProcAddress("wglGetExtensionsStringARB"); + if (!getext) { + fprintf(stderr, + "Implementation unexpectedly missing " + "WGL_ARB_extensions_string. Probably a libepoxy bug.\n"); + return false; + } + + return epoxy_extension_in_string(getext(hdc), ext); +} diff --git a/src/gen_dispatch.py b/src/gen_dispatch.py index 373b9ff..c7d9473 100755 --- a/src/gen_dispatch.py +++ b/src/gen_dispatch.py @@ -85,6 +85,13 @@ class GLFunction(object): self.alias_exts = [] def add_arg(self, type, name): + # Reword glDepthRange() arguments to avoid clashing with the + # "near" and "far" keywords on win32. + if name == "near": + name = "hither" + elif name == "far": + name = "yon" + self.args.append((type, name)) if self.args_decl == 'void': self.args_list = name @@ -192,6 +199,14 @@ class Generator(object): def parse_enums(self, reg): for enum in reg.findall('enums/enum'): name = enum.get('name') + + # wgl.xml's 0xwhatever definitions end up colliding with + # wingdi.h's decimal definitions of these. + if ('WGL_SWAP_OVERLAY' in name or + 'WGL_SWAP_UNDERLAY' in name or + 'WGL_SWAP_MAIN_PLANE' in name): + continue + self.max_enum_name_len = max(self.max_enum_name_len, len(name)) self.enums[name] = enum.get('value') @@ -270,6 +285,11 @@ class Generator(object): func = self.functions[name] func.add_provider(condition, loader, human_name) + def delete_require_statements(self, feature): + for command in feature.findall('require/command'): + name = command.get('name') + del self.functions[name] + def parse_function_providers(self, reg): for feature in reg.findall('feature'): api = feature.get('api') # string gl, gles1, gles2, glx @@ -316,6 +336,15 @@ class Generator(object): else: condition = 'true' loader = 'epoxy_egl_dlsym({0})' + elif api == 'wgl': + # There's no reason for us to interpose the + # non-extension WGL symbols, which we know are always + # available. The registry lists WGL 1.0 symbols both + # from opengl32.dll and gdi32.dll, so our dlsym() + # would have to know which came from where, if we were + # to interpose. + self.delete_require_statements(feature) + continue else: sys.exit('unknown API: "{0}"'.format(api)) @@ -339,6 +368,11 @@ class Generator(object): condition = 'epoxy_conservative_has_egl_extension("{0}")'.format(extname) loader = 'eglGetProcAddress({0})' self.process_require_statements(extension, condition, loader, human_name) + if 'wgl' in apis: + human_name = 'WGL extension \\"{0}\\"'.format(extname) + condition = 'epoxy_conservative_has_wgl_extension("{0}")'.format(extname) + loader = 'wglGetProcAddress({0})' + self.process_require_statements(extension, condition, loader, human_name) if {'gl', 'gles1', 'gles2'}.intersection(apis): human_name = 'GL extension \\"{0}\\"'.format(extname) condition = 'epoxy_conservative_has_gl_extension("{0}")'.format(extname) |