[waffle] [PATCH 10/18] wgl: check for various WGL extensions and fetch their funcptrs

Emil Velikov emil.l.velikov at gmail.com
Tue Jul 22 20:31:36 PDT 2014


Our assumption is that the original (root) context has the same
WGL core functions and any context created after that. Additionally
the wglCreateContextAttribsARB and wglChoosePixelFormatARB functions
and their pointers will remain constant across the creation of the
actual (working) context. Similar logic is used by SDL, xserver and
others.

Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
---
 src/waffle/wgl/wgl_display.c | 101 ++++++++++++++++++++++++++++++++++++++-----
 src/waffle/wgl/wgl_display.h |  21 +++++++++
 2 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/src/waffle/wgl/wgl_display.c b/src/waffle/wgl/wgl_display.c
index e5317aa..13125e9 100644
--- a/src/waffle/wgl/wgl_display.c
+++ b/src/waffle/wgl/wgl_display.c
@@ -124,20 +124,12 @@ wgl_display_hardware_render(struct wgl_display *dpy)
 
     PFNGLGETSTRINGPROC glGetString_func;
     const GLubyte *gl_renderer;
-    bool ok;
 
     glGetString_func = wgl_dl_sym(dpy->wcore.platform, WAFFLE_DL_OPENGL, "glGetString");
     if (!glGetString_func)
         return false;
 
-    ok = wglMakeCurrent(dpy->hDC, dpy->hglrc);
-    if (!ok)
-        return false;
-
     gl_renderer = glGetString_func(GL_RENDERER);
-    ok = wglMakeCurrent(NULL, NULL);
-    if (!ok)
-        return false;
 
     // Bail out if we cannot retrieve the renderer string or if we're using GDI
     if (!gl_renderer || strcasecmp((const char *)gl_renderer, "GDI Generic") == 0)
@@ -146,6 +138,75 @@ wgl_display_hardware_render(struct wgl_display *dpy)
     return true;
 }
 
+static bool
+wgl_display_set_extensions(struct wgl_display *dpy)
+{
+    typedef const char * (__stdcall *PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
+    PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_func;
+    const char *extensions;
+
+    wglGetExtensionsStringARB_func = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
+    if (!wglGetExtensionsStringARB_func) {
+        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+                     "wglGetProcAddress(\"wglGetExtensionsStringARB\") failed");
+        return false;
+    }
+
+    extensions = wglGetExtensionsStringARB_func(dpy->hDC);
+
+    if (!extensions) {
+        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+                     "wglGetExtensionsStringARB failed");
+        return false;
+    }
+
+    dpy->ARB_create_context                     = waffle_is_extension_in_string(extensions, "WGL_ARB_create_context");
+    dpy->ARB_create_context_profile             = waffle_is_extension_in_string(extensions, "WGL_ARB_create_context_profile");
+    dpy->EXT_create_context_es_profile          = waffle_is_extension_in_string(extensions, "WGL_EXT_create_context_es_profile");
+
+    // The WGL_EXT_create_context_es2_profile spec, version 5 2012/04/06,
+    // states that WGL_EXT_create_context_es_profile is an alias of
+    // WGL_EXT_create_context_es2_profile and requires that both names must be
+    // exported together for backwards compatibility with clients that expect
+    // the es2_profile name.
+    if (dpy->EXT_create_context_es_profile) {
+        dpy->EXT_create_context_es2_profile = true;
+    }
+    else {
+        // Assume that WGL does not implement version 3 of the extension, in
+        // which case the ES contexts WGL is capable of creating is ES2.
+        dpy->EXT_create_context_es2_profile = waffle_is_extension_in_string(extensions, "WGL_EXT_create_context_es2_profile");
+    }
+
+    dpy->ARB_pixel_format = waffle_is_extension_in_string(extensions, "WGL_ARB_pixel_format");
+
+    return true;
+}
+
+static bool
+wgl_display_set_func_ptrs(struct wgl_display *dpy)
+{
+    if (dpy->ARB_create_context) {
+        dpy->wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
+        if (!dpy->wglCreateContextAttribsARB) {
+            wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+                         "wglGetProcAddress(\"wglCreateContextAttribsARB\") failed");
+            return false;
+        }
+    }
+
+    if (dpy->ARB_pixel_format) {
+        dpy->wglChoosePixelFormatARB = (void *)wglGetProcAddress("wglChoosePixelFormatARB");
+        if (!dpy->wglChoosePixelFormatARB) {
+            wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+                         "wglGetProcAddress(\"wglChoosePixelFormatARB\") failed");
+            return false;
+        }
+    }
+
+    return true;
+}
+
 struct wcore_display*
 wgl_display_connect(struct wcore_platform *wc_plat,
                     const char *name)
@@ -173,10 +234,26 @@ wgl_display_connect(struct wcore_platform *wc_plat,
     if (!self->hglrc)
         goto error;
 
+    ok = wglMakeCurrent(self->hDC, self->hglrc);
+    if (!ok)
+        goto error;
+
     ok = wgl_display_hardware_render(self);
     if (!ok)
         goto error;
 
+    ok = wgl_display_set_extensions(self);
+    if (!ok)
+        goto error;
+
+    ok = wgl_display_set_func_ptrs(self);
+    if (!ok)
+        goto error;
+
+    ok = wglMakeCurrent(NULL, NULL);
+    if (!ok)
+        goto error;
+
     return &self->wcore;
 
 error:
@@ -188,15 +265,17 @@ bool
 wgl_display_supports_context_api(struct wcore_display *wc_self,
                                  int32_t context_api)
 {
+    struct wgl_display *self = wgl_display(wc_self);
+
     switch (context_api) {
         case WAFFLE_CONTEXT_OPENGL:
             return true;
         case WAFFLE_CONTEXT_OPENGL_ES1:
-            return false;
+            return self->EXT_create_context_es_profile;
         case WAFFLE_CONTEXT_OPENGL_ES2:
-            return false;
+            return self->EXT_create_context_es2_profile;
         case WAFFLE_CONTEXT_OPENGL_ES3:
-            return false;
+            return self->EXT_create_context_es_profile;
         default:
             wcore_error_internal("waffle_context_api has bad value %#x",
                                  context_api);
diff --git a/src/waffle/wgl/wgl_display.h b/src/waffle/wgl/wgl_display.h
index 6a2b6c7..d916f78 100644
--- a/src/waffle/wgl/wgl_display.h
+++ b/src/waffle/wgl/wgl_display.h
@@ -33,6 +33,18 @@
 
 struct wcore_platform;
 
+// XXX: Move the typedefs ?
+typedef HGLRC (__stdcall *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hDC,
+                                                             HGLRC hShareContext,
+                                                             const int *attribList);
+
+typedef BOOL (__stdcall *PFNWGLCHOOSEPIXELFORMATARBPROC )(HDC hdc,
+                                                          const int * piAttribIList,
+                                                          const float * pfAttribFList,
+                                                          unsigned int nMaxFormats,
+                                                          int * piFormats,
+                                                          unsigned int * nNumFormats);
+
 struct wgl_display {
     struct wcore_display wcore;
 
@@ -40,6 +52,15 @@ struct wgl_display {
     HDC hDC;
     int pixel_format;
     HGLRC hglrc;
+
+    bool ARB_create_context;
+    bool ARB_create_context_profile;
+    bool EXT_create_context_es_profile;
+    bool EXT_create_context_es2_profile;
+    bool ARB_pixel_format;
+
+    PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
+    PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
 };
 
 DEFINE_CONTAINER_CAST_FUNC(wgl_display,
-- 
2.0.2



More information about the waffle mailing list