[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