summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2013-12-17 14:32:18 -0800
committerEric Anholt <eric@anholt.net>2013-12-17 15:08:02 -0800
commit9bc909f5a7024ca3c2b5aa2fc26b19e8de9c7cf0 (patch)
tree0728cce0be62976c66f9894c51929866f1d35a10
parent3ae4726cdbb0fccdb02bcdba07662fe6f6a15589 (diff)
win32: Convert the API to being based on function pointers, like Linux.
For performance, I want to be able to make single-context (well, single-pixel-format-and-device) apps be able to directly call GL functions through function pointers. Bake that into the ABI now so I can get a release out the door and fix this up later. This also fixes the lack of __stdcall annotation on the PFNWHATEVERPROC typedefs.
-rw-r--r--README.md10
-rw-r--r--include/epoxy/gl.h2
-rw-r--r--src/dispatch_common.c2
-rw-r--r--src/dispatch_common.h12
-rw-r--r--src/dispatch_wgl.c4
-rwxr-xr-xsrc/gen_dispatch.py36
6 files changed, 38 insertions, 28 deletions
diff --git a/README.md b/README.md
index b52faed..a0fab31 100644
--- a/README.md
+++ b/README.md
@@ -119,3 +119,13 @@ pixel format. If ```wglMakeCurrent()``` is called from outside of
epoxy (in a way that might change the device or pixel format), then
epoxy needs to be notified of the change using
```epoxy_handle_external_wglMakeCurrent()```.
+
+The win32 dispatch layer is currently slower than it should be in the
+single-context (or multi-context, but same device and pixel format)
+case. We need to switch to using the linux-like function pointer
+stubs, and detect when transitioning to multi-device/format and hook
+in the per-thread dispatch table at that point.
+
+The win32 wglMakeCurrent () variants are slower than they should be,
+because they should be caching the resolved dispatch tables instead of
+resetting an entire thread-local dispatch table every time.
diff --git a/include/epoxy/gl.h b/include/epoxy/gl.h
index c70a8d6..023810c 100644
--- a/include/epoxy/gl.h
+++ b/include/epoxy/gl.h
@@ -59,7 +59,7 @@ extern "C" {
#endif
#ifndef EPOXYAPIENTRY
-#define EPOXYAPIENTRY __declspec(dllimport)
+#define EPOXYAPIENTRY __declspec(dllimport) __stdcall
#endif
#ifndef GLAPI
diff --git a/src/dispatch_common.c b/src/dispatch_common.c
index 0ac5d23..8c04526 100644
--- a/src/dispatch_common.c
+++ b/src/dispatch_common.c
@@ -503,7 +503,5 @@ WRAPPER(epoxy_glEnd)(void)
#endif
}
-#ifndef _WIN32
PUBLIC PFNGLBEGINPROC epoxy_glBegin = epoxy_glBegin_wrapped;
PUBLIC PFNGLENDPROC epoxy_glEnd = epoxy_glEnd_wrapped;
-#endif
diff --git a/src/dispatch_common.h b/src/dispatch_common.h
index 02599bd..1274b49 100644
--- a/src/dispatch_common.h
+++ b/src/dispatch_common.h
@@ -27,7 +27,7 @@
#define PLATFORM_HAS_EGL 0
#define PLATFORM_HAS_GLX 0
#define PLATFORM_HAS_WGL 1
-#define EPOXYAPIENTRY __declspec(dllexport)
+#define EPOXYAPIENTRY __declspec(dllexport) __stdcall
#elif defined(__APPLE__)
#define PLATFORM_HAS_EGL 0
#define PLATFORM_HAS_GLX 1
@@ -65,16 +65,14 @@
*/
#if defined(_WIN32)
#define USING_DISPATCH_TABLE 1
-#define UNWRAPPED_PROTO(x) x
-#define WRAPPER_VISIBILITY PUBLIC
-#define WRAPPER(x) x
#else
#define USING_DISPATCH_TABLE 0
-#define UNWRAPPED_PROTO(x) (*x)
-#define WRAPPER_VISIBILITY static
-#define WRAPPER(x) x ## _wrapped
#endif
+#define UNWRAPPED_PROTO(x) (GLAPIENTRY *x)
+#define WRAPPER_VISIBILITY static GLAPIENTRY
+#define WRAPPER(x) x ## _wrapped
+
void *epoxy_egl_dlsym(const char *name);
void *epoxy_glx_dlsym(const char *name);
void *epoxy_gl_dlsym(const char *name);
diff --git a/src/dispatch_wgl.c b/src/dispatch_wgl.c
index a0b7277..1156419 100644
--- a/src/dispatch_wgl.c
+++ b/src/dispatch_wgl.c
@@ -176,3 +176,7 @@ WRAPPER(epoxy_wglMakeAssociatedContextCurrentAMD)(HGLRC hglrc)
return ret;
}
+PUBLIC PFNWGLMAKECURRENTPROC epoxy_wglMakeCurrent = epoxy_wglMakeCurrent_wrapped;
+PUBLIC PFNWGLMAKECONTEXTCURRENTEXTPROC epoxy_wglMakeContextCurrentEXT = epoxy_wglMakeContextCurrentEXT_wrapped;
+PUBLIC PFNWGLMAKECONTEXTCURRENTARBPROC epoxy_wglMakeContextCurrentARB = epoxy_wglMakeContextCurrentARB_wrapped;
+PUBLIC PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC epoxy_wglMakeAssociatedContextCurrentEXT = epoxy_wglMakeAssociatedContextCurrentAMD_wrapped;
diff --git a/src/gen_dispatch.py b/src/gen_dispatch.py
index 7a2d2df..9b53fc2 100755
--- a/src/gen_dispatch.py
+++ b/src/gen_dispatch.py
@@ -451,8 +451,9 @@ class Generator(object):
def write_function_ptr_typedefs(self):
for func in self.sorted_functions:
- self.outln('typedef {0} (*{1})({2});'.format(func.ret_type, func.ptr_type,
- func.args_decl))
+ self.outln('typedef {0} (GLAPIENTRY *{1})({2});'.format(func.ret_type,
+ func.ptr_type,
+ func.args_decl))
def write_header_header(self, file):
self.out_file = open(file, 'w')
@@ -503,18 +504,8 @@ class Generator(object):
self.outln('')
self.write_function_ptr_typedefs()
- self.outln('/* The library ABI is a set of functions on win32 (where')
- self.outln(' * we have to use per-thread dispatch tables) and a set')
- self.outln(' * of function pointers, otherwise.')
- self.outln(' */')
- self.outln('#ifdef _WIN32')
- self.outln('#define EPOXY_FPTR(x) x')
- self.outln('#else')
- self.outln('#define EPOXY_FPTR(x) (*x)')
- self.outln('#endif')
-
for func in self.sorted_functions:
- self.outln('extern EPOXYAPIENTRY {0} EPOXY_FPTR(epoxy_{1})({2});'.format(func.ret_type,
+ self.outln('extern EPOXYAPIENTRY {0} (*epoxy_{1})({2});'.format(func.ret_type,
func.name,
func.args_decl))
self.outln('')
@@ -582,8 +573,8 @@ class Generator(object):
dispatch_table_entry = 'dispatch_table->p{0}'.format(func.alias_name)
- self.outln('{0}{1}'.format(func.public, func.ret_type))
- self.outln('epoxy_{0}({1})'.format(func.wrapped_name, func.args_decl))
+ self.outln('static __stdcall {0}'.format(func.ret_type))
+ self.outln('epoxy_{0}_dispatch_table_thunk({1})'.format(func.wrapped_name, func.args_decl))
self.outln('{')
self.outln(' struct dispatch_table *dispatch_table = get_dispatch_table();')
self.outln('')
@@ -601,7 +592,7 @@ class Generator(object):
dispatch_table_entry = 'dispatch_table->p{0}'.format(func.name)
- self.outln('static {0}'.format(func.ret_type))
+ self.outln('static GLAPIENTRY {0}'.format(func.ret_type))
self.outln('epoxy_{0}_rewrite_stub({1})'.format(func.name, func.args_decl))
self.outln('{')
self.outln(' struct dispatch_table *dispatch_table = get_dispatch_table();')
@@ -616,7 +607,7 @@ class Generator(object):
self.outln('}')
self.outln('')
- def write_function_pointer(self, func):
+ def write_linux_function_pointer(self, func):
# Writes out the function for resolving and updating the
# global function pointer, plus the actual global function
# pointer initializer.
@@ -642,6 +633,12 @@ class Generator(object):
func.wrapped_name))
self.outln('')
+ def write_win32_function_pointer(self, func):
+ self.outln('{0}{1} epoxy_{2} = epoxy_{2}_dispatch_table_thunk;'.format(func.public,
+ func.ptr_type,
+ func.wrapped_name))
+ self.outln('')
+
def write_provider_enums(self):
# Writes the enum declaration for the list of providers
# supported by gl_provider_resolver()
@@ -816,10 +813,13 @@ class Generator(object):
self.outln('}')
self.outln('')
+ for func in self.sorted_functions:
+ self.write_win32_function_pointer(func)
+
self.outln('#else /* !USING_DISPATCH_TABLE */')
for func in self.sorted_functions:
- self.write_function_pointer(func)
+ self.write_linux_function_pointer(func)
self.outln('#endif /* !USING_DISPATCH_TABLE */')