On 04/08/14 08:17, Chad Versace wrote: > Thunderbird believes this patch is Chinese... :( > In that case I will attach the patch (and push branch for-upstream-WGL-1.2 shortly).
> I need more time to look at this patch because of the API break. > > Even though eglGetProcAddress and glXGetProcAddress allow queries before the > process > makes any other EGL/GLX calls, in practice I see no harm in requiring Waffle > users > to postpone procAddress queries until after acquiring a display. Except for a > few > special cases, GetProc'd function pointers aren't useful anyway without a > current > context, which requires a display. > > So, I don't believe this should cause any real problems. But I want a little > time to > consider all the implications here. > On possible issue that I can see is if one uses waffle_get_proc_address() using a pointer to the first waffle_display, while a second one is active. On the other hand I assume that waffle itself may explode a bit before that :) Or in other words I am _not_ a big fan of the two API/ABI changes yet I see no clear way of solving this without enforcing additional and "interesting" rules on the user. > Also, when breaking the ABI, we will need to increment Waffle's major > version. It's > just a number, so no big deal. Waffle 2.0 won't be an earth-shattering change > from > Waffle 1.x (except for WGL support!). It will simply be another incremental > improvement > over its previous release, like Git 1.9 to Git 2.0. > And the current versioning scheme makes things even easier wrt having multiple waffles side by side. I like mine with chocolate :) -Emil
>From 905cdede895aef7c234b54c405b93b17927b1746 Mon Sep 17 00:00:00 2001 From: Emil Velikov <[email protected]> Date: Tue, 22 Jul 2014 21:04:21 +0100 Subject: [PATCH 08/19] api: make waffle_get_proc_address() display aware For WGL we need a current context in order to get wglGetProcAddress to work. We resolve this by creating per display context (inside wgl_display_connect) that is later used if we call the above when there is no current context. Wire up wgl_get_proc_address, update all the examples and documentation. Chad, tests/functional/gl_basic_test.c seems to be doing something very nasty with a comprehensive explanation why. Is there another way around this ? Note this commit breaks the API in a non-backwards compatible way. TODO: - Bump the major version. - Add a note in the release notes. Cc: Chad Versace <[email protected]> Signed-off-by: Emil Velikov <[email protected]> Reviewed-by: Jose Fonseca <[email protected]> --- include/waffle/waffle.h | 3 ++- man/waffle_get_proc_address.3.xml | 18 ++++++++++++++++-- src/utils/wflinfo.c | 2 +- src/waffle/api/waffle_gl_misc.c | 12 +++++++++--- src/waffle/cgl/cgl_platform.m | 4 +++- src/waffle/core/wcore_platform.h | 1 + src/waffle/egl/wegl_util.c | 4 +++- src/waffle/egl/wegl_util.h | 4 +++- src/waffle/glx/glx_platform.c | 1 + src/waffle/wgl/wgl_platform.c | 21 +++++++++++++++++++-- tests/functional/gl_basic_test.c | 3 +++ 11 files changed, 61 insertions(+), 12 deletions(-) diff --git a/include/waffle/waffle.h b/include/waffle/waffle.h index e04b23f..170b56c 100644 --- a/include/waffle/waffle.h +++ b/include/waffle/waffle.h @@ -166,7 +166,8 @@ waffle_make_current(struct waffle_display *dpy, struct waffle_context *ctx); void* -waffle_get_proc_address(const char *name); +waffle_get_proc_address(struct waffle_display *dpy, + const char *name); bool waffle_is_extension_in_string(const char *extension_string, diff --git a/man/waffle_get_proc_address.3.xml b/man/waffle_get_proc_address.3.xml index 36b9ea2..8d9bfbf 100644 --- a/man/waffle_get_proc_address.3.xml +++ b/man/waffle_get_proc_address.3.xml @@ -22,7 +22,7 @@ <refnamediv> <refname>waffle_get_proc_address</refname> - <refpurpose>Query address of OpenGL functions</refpurpose> + <refpurpose>Query address of OpenGL functions for the specified display</refpurpose> </refnamediv> <refentryinfo> @@ -43,6 +43,7 @@ <funcprototype> <funcdef>void* <function>waffle_get_proc_address</function></funcdef> + <paramdef>struct waffle_display *<parameter>dpy</parameter></paramdef> <paramdef>const char *<parameter>name</parameter></paramdef> </funcprototype> @@ -66,6 +67,9 @@ On CGL, this function returns <constant>NULL</constant> because there exists no <function>CGLGetProcAdress()</function>. + + On WGL, this redirects to + <citerefentry><refentrytitle><function>wglGetProcAddress</function></refentrytitle><manvolnum>3</manvolnum></citerefentry>. </para> <para> @@ -89,6 +93,14 @@ then <function>waffle_get_proc_address()</function> may return a <constant>NULL</constant>. </para> </listitem> + + <listitem> + <para> + Under Windows (WGL) a current context must be available before executing the function. + + Otherwise <function>waffle_get_proc_address()</function> may return a <constant>NULL</constant>. + </para> + </listitem> </itemizedlist> </para> @@ -99,7 +111,9 @@ the <ulink url="http://www.opengl.org/registry/doc/glx1.4.pdf">GLX 1.4 Specification</ulink> - or the <ulink url="http://www.khronos.org/registry/egl/specs/eglspec.1.4.20110406.pdf">EGL 1.4 Specification</ulink>. + the <ulink url="http://www.khronos.org/registry/egl/specs/eglspec.1.4.20110406.pdf">EGL 1.4 Specification</ulink> + + or the <ulink url="http://msdn.microsoft.com/en-gb/library/windows/desktop/dd374386(v=vs.85).aspx">MSDN article</ulink>. </para> </listitem> </varlistentry> diff --git a/src/utils/wflinfo.c b/src/utils/wflinfo.c index 20ff6b9..e38b1e6 100644 --- a/src/utils/wflinfo.c +++ b/src/utils/wflinfo.c @@ -1038,7 +1038,7 @@ main(int argc, char **argv) if (!glGetString) error_get_gl_symbol("glGetString"); - glGetStringi = waffle_get_proc_address("glGetStringi"); + glGetStringi = waffle_get_proc_address(dpy, "glGetStringi"); const struct wflinfo_config_attrs config_attrs = { .api = opts.context_api, diff --git a/src/waffle/api/waffle_gl_misc.c b/src/waffle/api/waffle_gl_misc.c index 138974d..d92a4b8 100644 --- a/src/waffle/api/waffle_gl_misc.c +++ b/src/waffle/api/waffle_gl_misc.c @@ -101,10 +101,16 @@ waffle_make_current( } WAFFLE_API void* -waffle_get_proc_address(const char *name) +waffle_get_proc_address(struct waffle_display *dpy, const char *name) { - if (!api_check_entry(NULL, 0)) + struct wcore_display *wc_dpy = wcore_display(dpy); + + const struct api_object *obj_list[] = { + wc_dpy ? &wc_dpy->api : NULL, + }; + + if (!api_check_entry(obj_list, 1)) return NULL; - return api_platform->vtbl->get_proc_address(api_platform, name); + return api_platform->vtbl->get_proc_address(api_platform, wc_dpy, name); } diff --git a/src/waffle/cgl/cgl_platform.m b/src/waffle/cgl/cgl_platform.m index 2da0b40..fd7c349 100644 --- a/src/waffle/cgl/cgl_platform.m +++ b/src/waffle/cgl/cgl_platform.m @@ -146,7 +146,9 @@ cgl_make_current(struct wcore_platform *wc_self, } static void* -cgl_get_proc_address(struct wcore_platform *wc_self, const char *name) +cgl_get_proc_address(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, + const char *name) { // There is no CGLGetProcAddress. However, Waffle follows the principle of // least surprise here. The only supported API on CGL is OpenGL, so assume diff --git a/src/waffle/core/wcore_platform.h b/src/waffle/core/wcore_platform.h index 77943e4..67c327c 100644 --- a/src/waffle/core/wcore_platform.h +++ b/src/waffle/core/wcore_platform.h @@ -51,6 +51,7 @@ struct wcore_platform_vtbl { void* (*get_proc_address)( struct wcore_platform *self, + struct wcore_display *dpy, const char *proc); bool diff --git a/src/waffle/egl/wegl_util.c b/src/waffle/egl/wegl_util.c index eb2415b..2ebb58d 100644 --- a/src/waffle/egl/wegl_util.c +++ b/src/waffle/egl/wegl_util.c @@ -90,7 +90,9 @@ wegl_make_current(struct wcore_platform *wc_plat, } void* -wegl_get_proc_address(struct wcore_platform *wc_self, const char *name) +wegl_get_proc_address(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, + const char *name) { return eglGetProcAddress(name); } diff --git a/src/waffle/egl/wegl_util.h b/src/waffle/egl/wegl_util.h index 772f71d..a3aafe6 100644 --- a/src/waffle/egl/wegl_util.h +++ b/src/waffle/egl/wegl_util.h @@ -47,4 +47,6 @@ wegl_make_current(struct wcore_platform *wc_plat, struct wcore_context *wc_ctx); void* -wegl_get_proc_address(struct wcore_platform *wc_self, const char *name); +wegl_get_proc_address(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, + const char *name); diff --git a/src/waffle/glx/glx_platform.c b/src/waffle/glx/glx_platform.c index 804c275..e8fb584 100644 --- a/src/waffle/glx/glx_platform.c +++ b/src/waffle/glx/glx_platform.c @@ -104,6 +104,7 @@ glx_platform_make_current(struct wcore_platform *wc_self, static void* glx_platform_get_proc_address(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, const char *name) { return glXGetProcAddress((const GLubyte*) name); diff --git a/src/waffle/wgl/wgl_platform.c b/src/waffle/wgl/wgl_platform.c index 2f88aff..3c9c1e6 100644 --- a/src/waffle/wgl/wgl_platform.c +++ b/src/waffle/wgl/wgl_platform.c @@ -24,6 +24,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdlib.h> +#include <windows.h> #include "wcore_error.h" @@ -126,9 +127,25 @@ wgl_make_current(struct wcore_platform *wc_self, } static void* -wgl_get_proc_address(struct wcore_platform *wc_self, const char *name) +wgl_get_proc_address(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, + const char *name) { - return NULL; + if (wglGetCurrentContext() != NULL) + return wglGetProcAddress(name); + + // There is no current context. Bind the 'root'/display context. + struct wgl_display *dpy = wgl_display(wc_dpy); + void *proc_address; + + // Don't bother checking if wglMakeCurrent fails. + // Worst case scanario we'll end up returning NULL anywhay. + + wglMakeCurrent(dpy->hDC, dpy->hglrc); + proc_address = wglGetProcAddress(name); + wglMakeCurrent(NULL, NULL); + + return proc_address; } static const struct wcore_platform_vtbl wgl_platform_vtbl = { diff --git a/tests/functional/gl_basic_test.c b/tests/functional/gl_basic_test.c index 035b221..1f1ef8f 100644 --- a/tests/functional/gl_basic_test.c +++ b/tests/functional/gl_basic_test.c @@ -242,7 +242,10 @@ gl_basic_draw__(struct gl_basic_draw_args__ args) // call. Otherwise, libEGL may initialize itself with the incorrect // platform. In my experiments, first calling eglGetProcAddress will // produce a segfault in eglInitialize. + // Emil: Chad can we find a better/less hacky solution for this ? +#if 0 waffle_get_proc_address("glClear"); +#endif // Create objects. ASSERT_TRUE(dpy = waffle_display_connect(NULL)); -- 2.0.2
_______________________________________________ waffle mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/waffle

