Add dispatch generation for wgl.

This is very poorly tested at this point, but survives a simple testcase.
macos/v1.5.9
Eric Anholt 11 years ago
parent f4992e1518
commit 1d746bfeb2
  1. 4
      .gitignore
  2. 8
      configure.ac
  3. 60
      include/epoxy/wgl.h
  4. 29
      src/Makefile.am
  5. 12
      src/dispatch_common.c
  6. 6
      src/dispatch_common.h
  7. 60
      src/dispatch_wgl.c
  8. 34
      src/gen_dispatch.py

4
.gitignore vendored

@ -93,3 +93,7 @@ glx_generated_vtable_defines.h
egl_generated_dispatch.c egl_generated_dispatch.c
egl_generated.h egl_generated.h
egl_generated_vtable_defines.h egl_generated_vtable_defines.h
wgl_generated_dispatch.c
wgl_generated.h
wgl_generated_vtable_defines.h

@ -52,6 +52,7 @@ case $host_os in
mingw*) mingw*)
build_egl=no build_egl=no
build_glx=no build_glx=no
build_wgl=yes
# On windows, the DLL has to have all of its functions # On windows, the DLL has to have all of its functions
# resolved at link time, so we have to link directly aginst # resolved at link time, so we have to link directly aginst
# opengl32.dll. But that's the only GL provider, anyway. # opengl32.dll. But that's the only GL provider, anyway.
@ -66,6 +67,7 @@ case $host_os in
*) *)
build_egl=yes build_egl=yes
build_glx=yes build_glx=yes
build_wgl=no
# On platforms with dlopen, we load everything dynamically and # On platforms with dlopen, we load everything dynamically and
# don't link against a specific window system or GL implementation. # don't link against a specific window system or GL implementation.
EPOXY_LINK_LIBS="" EPOXY_LINK_LIBS=""
@ -84,6 +86,11 @@ if test x$build_glx = xyes; then
AC_DEFINE([BUILD_GLX], [1], [build GLX tests]) AC_DEFINE([BUILD_GLX], [1], [build GLX tests])
fi 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 case $host_os in
mingw*) mingw*)
@ -123,4 +130,5 @@ AC_OUTPUT
echo " EGL: $build_egl" echo " EGL: $build_egl"
echo " GLX: $build_glx" echo " GLX: $build_glx"
echo " WGL: $build_wgl"
echo " PYTHON: $PYTHON" echo " PYTHON: $PYTHON"

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

@ -42,6 +42,10 @@ if BUILD_GLX
INSTALL_GLX_INCLUDES = $(GENERATED_GLX_INCLUDES) INSTALL_GLX_INCLUDES = $(GENERATED_GLX_INCLUDES)
endif endif
if BUILD_WGL
INSTALL_WGL_INCLUDES = $(GENERATED_WGL_INCLUDES)
endif
GENERATED_GL_INCLUDES = \ GENERATED_GL_INCLUDES = \
$(builddir)/../include/epoxy/gl_generated.h \ $(builddir)/../include/epoxy/gl_generated.h \
$(builddir)/../include/epoxy/gl_generated_vtable_defines.h \ $(builddir)/../include/epoxy/gl_generated_vtable_defines.h \
@ -57,6 +61,11 @@ GENERATED_EGL_INCLUDES = \
$(builddir)/../include/epoxy/egl_generated_vtable_defines.h \ $(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_SOURCE = gl_generated_dispatch.c
GENERATED_GL = \ GENERATED_GL = \
@ -78,10 +87,18 @@ GENERATED_EGL = \
$(GENERATED_EGL_INCLUDES) \ $(GENERATED_EGL_INCLUDES) \
$() $()
GENERATED_WGL_SOURCE = wgl_generated_dispatch.c
GENERATED_WGL = \
$(GENERATED_WGL_SOURCE) \
$(GENERATED_WGL_INCLUDES) \
$()
BUILT_SOURCES = \ BUILT_SOURCES = \
$(GENERATED_GL) \ $(GENERATED_GL) \
$(GENERATED_GLX) \ $(GENERATED_GLX) \
$(GENERATED_EGL) \ $(GENERATED_EGL) \
$(GENERATED_WGL) \
$() $()
CLEANFILES = $(BUILT_SOURCES) CLEANFILES = $(BUILT_SOURCES)
@ -91,6 +108,7 @@ libepoxy_la_SOURCES = \
$(GENERATED_GL) \ $(GENERATED_GL) \
$(BUILD_EGL_CODE) \ $(BUILD_EGL_CODE) \
$(BUILD_GLX_CODE) \ $(BUILD_GLX_CODE) \
$(BUILD_WGL_CODE) \
$() $()
libepoxy_la_LDFLAGS = \ libepoxy_la_LDFLAGS = \
@ -112,10 +130,18 @@ BUILD_GLX_CODE = \
$() $()
endif endif
if BUILD_WGL
BUILD_WGL_CODE = \
$(GENERATED_WGL) \
dispatch_wgl.c \
$()
endif
# These are generated alongside the .c file. # These are generated alongside the .c file.
$(GENERATED_GL_INCLUDES): $(GENERATED_GL_SOURCE) $(GENERATED_GL_INCLUDES): $(GENERATED_GL_SOURCE)
$(GENERATED_GLX_INCLUDES): $(GENERATED_GLX_SOURCE) $(GENERATED_GLX_INCLUDES): $(GENERATED_GLX_SOURCE)
$(GENERATED_EGL_INCLUDES): $(GENERATED_EGL_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 $(GENERATED_GL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/gl.xml
$(MKDIR_P) $(top_builddir)/include/epoxy $(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 $(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 $(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

@ -322,8 +322,12 @@ epoxy_glx_dlsym(const char *name)
void * void *
epoxy_gl_dlsym(const char *name) 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. */ /* There's no library for desktop GL support independent of GLX. */
return epoxy_glx_dlsym(name); return epoxy_glx_dlsym(name);
#endif
} }
void * void *
@ -341,7 +345,13 @@ epoxy_gles2_dlsym(const char *name)
void * void *
epoxy_get_core_proc_address(const char *name, int core_version) 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); return epoxy_gl_dlsym(name);
} else { } else {
return epoxy_get_proc_address(name); return epoxy_get_proc_address(name);

@ -26,9 +26,11 @@
#ifdef _WIN32 #ifdef _WIN32
#define PLATFORM_HAS_EGL 0 #define PLATFORM_HAS_EGL 0
#define PLATFORM_HAS_GLX 0 #define PLATFORM_HAS_GLX 0
#define PLATFORM_HAS_WGL 1
#else #else
#define PLATFORM_HAS_EGL 1 #define PLATFORM_HAS_EGL 1
#define PLATFORM_HAS_GLX 1 #define PLATFORM_HAS_GLX 1
#define PLATFORM_HAS_WGL 0
#endif #endif
#include "epoxy/gl.h" #include "epoxy/gl.h"
@ -38,6 +40,9 @@
#if PLATFORM_HAS_EGL #if PLATFORM_HAS_EGL
#include "epoxy/egl.h" #include "epoxy/egl.h"
#endif #endif
#if PLATFORM_HAS_WGL
#include "epoxy/wgl.h"
#endif
#ifndef PUBLIC #ifndef PUBLIC
# ifdef _WIN32 # ifdef _WIN32
@ -63,6 +68,7 @@ int epoxy_conservative_glx_version(void);
bool epoxy_conservative_has_glx_extension(const char *name); bool epoxy_conservative_has_glx_extension(const char *name);
int epoxy_conservative_egl_version(void); int epoxy_conservative_egl_version(void);
bool epoxy_conservative_has_egl_extension(const char *name); 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, void epoxy_print_failure_reasons(const char *name,
const char **provider_names, const char **provider_names,
const int *providers); const int *providers);

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

@ -85,6 +85,13 @@ class GLFunction(object):
self.alias_exts = [] self.alias_exts = []
def add_arg(self, type, name): 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)) self.args.append((type, name))
if self.args_decl == 'void': if self.args_decl == 'void':
self.args_list = name self.args_list = name
@ -192,6 +199,14 @@ class Generator(object):
def parse_enums(self, reg): def parse_enums(self, reg):
for enum in reg.findall('enums/enum'): for enum in reg.findall('enums/enum'):
name = enum.get('name') 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.max_enum_name_len = max(self.max_enum_name_len, len(name))
self.enums[name] = enum.get('value') self.enums[name] = enum.get('value')
@ -270,6 +285,11 @@ class Generator(object):
func = self.functions[name] func = self.functions[name]
func.add_provider(condition, loader, human_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): def parse_function_providers(self, reg):
for feature in reg.findall('feature'): for feature in reg.findall('feature'):
api = feature.get('api') # string gl, gles1, gles2, glx api = feature.get('api') # string gl, gles1, gles2, glx
@ -316,6 +336,15 @@ class Generator(object):
else: else:
condition = 'true' condition = 'true'
loader = 'epoxy_egl_dlsym({0})' 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: else:
sys.exit('unknown API: "{0}"'.format(api)) sys.exit('unknown API: "{0}"'.format(api))
@ -339,6 +368,11 @@ class Generator(object):
condition = 'epoxy_conservative_has_egl_extension("{0}")'.format(extname) condition = 'epoxy_conservative_has_egl_extension("{0}")'.format(extname)
loader = 'eglGetProcAddress({0})' loader = 'eglGetProcAddress({0})'
self.process_require_statements(extension, condition, loader, human_name) 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): if {'gl', 'gles1', 'gles2'}.intersection(apis):
human_name = 'GL extension \\"{0}\\"'.format(extname) human_name = 'GL extension \\"{0}\\"'.format(extname)
condition = 'epoxy_conservative_has_gl_extension("{0}")'.format(extname) condition = 'epoxy_conservative_has_gl_extension("{0}")'.format(extname)

Loading…
Cancel
Save