[waffle] [PATCH 08/18] api: make waffle_get_proc_address() display aware
Emil Velikov
emil.l.velikov at gmail.com
Tue Jul 22 20:31:34 PDT 2014
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 <chad.versace at linux.intel.com>
Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
---
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
More information about the waffle
mailing list