]> git.cworth.org Git - fips/commitdiff
Add dynamic dispatch for any calls to OpenGL functions.
authorCarl Worth <cworth@cworth.org>
Sat, 22 Jun 2013 00:10:03 +0000 (17:10 -0700)
committerCarl Worth <cworth@cworth.org>
Mon, 24 Jun 2013 20:31:49 +0000 (13:31 -0700)
Previously, fips code was making direct calls to OpenGL functions,
(such as glGenQueries, glBeinQuery, etc. within metrics.c). Some
OpenGL implementations do not export these symbols directly,
(expecting the application to instead look the symbols up via a call
to glXGetProcAddressARB or eglGetProcAddress).

The new fips-dispatch code added here does precisely that, (and adds
wrapper for both glXMakeCurrent and eglMakeCurrent in order to know
which GetProcAddress function should be called).

The dispatch code follows the model of piglit-dispatch, (available
under the same license as fips). Thanks to Eric Anholt for suggesting
following the same approach as piglit.

Makefile.local
eglwrap.c
fips-dispatch.c [new file with mode: 0644]
fips-dispatch.h [new file with mode: 0644]
fips.h
glwrap.c
glxwrap.c
metrics.c

index 79147188ac145e50f95dc24bb3bcc4039618fc70..9b54011107d05e7a60d6e5dfc251da8e8821b378 100644 (file)
@@ -94,6 +94,7 @@ extra_cflags += -I$(srcdir) -fPIC
 
 libfips_srcs = \
        dlwrap.c \
+       fips-dispatch.c \
        glwrap.c \
        glxwrap.c \
        metrics.c
index 6f009c35c53f3017d49cf8e22caa5a8725ca0966..913fd488d74a23dc0d7a9277dfe37525e3db776f 100644 (file)
--- a/eglwrap.c
+++ b/eglwrap.c
@@ -21,6 +21,8 @@
 
 #include "fips.h"
 
+#include "fips-dispatch.h"
+
 #include <EGL/egl.h>
 
 #include "dlwrap.h"
@@ -74,3 +76,16 @@ eglSwapBuffers (EGLDisplay dpy, EGLSurface surface)
 
        return ret;
 }
+
+EGLBoolean
+eglMakeCurrent (EGLDisplay display, EGLSurface draw, EGLSurface read,
+               EGLContext context)
+{
+       EGLBoolean ret;
+
+       fips_dispatch_init (FIPS_API_EGL);
+
+       EGLWRAP_DEFER_WITH_RETURN (ret, eglMakeCurrent, display, draw, read, context);
+
+       return ret;
+}
diff --git a/fips-dispatch.c b/fips-dispatch.c
new file mode 100644 (file)
index 0000000..c5f767c
--- /dev/null
@@ -0,0 +1,177 @@
+/* Copyright © 2012, Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "fips.h"
+
+#include "fips-dispatch.h"
+
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+#include <EGL/egl.h>
+
+static bool fips_initialized;
+static fips_api_t fips_api;
+
+void
+fips_dispatch_init (fips_api_t api)
+{
+       fips_api = api;
+
+       fips_initialized = true;
+}
+
+static void
+check_initialized (void)
+{
+       if (fips_initialized)
+               return;
+
+       fprintf (stderr,
+                "Internal error: fips_dispatch_init must be called before\n"
+                "any OpenGL function supported via fips_dispatch.\n");
+       exit (1);
+}
+
+static void
+unsupported (const char *name)
+{
+       fprintf (stderr, "Error: fips failed to find support for %s\n", name);
+
+       exit (1);
+}
+
+static void *
+lookup (const char *name)
+{
+       if (fips_api == FIPS_API_GLX)
+               return glXGetProcAddressARB ((const GLubyte *)name);
+       else
+               return eglGetProcAddress (name);
+}
+
+static void
+resolve_glGenQueries (void)
+{
+       fips_dispatch_glGenQueries = lookup ("glGenQueries");
+
+       if (! fips_dispatch_glGenQueries)
+               fips_dispatch_glGenQueries = lookup ("glGenQueriesARB");
+
+       if (! fips_dispatch_glGenQueries)
+               unsupported ("GenQueries");
+}
+
+static void
+stub_glGenQueries (GLsizei n, GLuint *ids)
+{
+       check_initialized ();
+       resolve_glGenQueries ();
+       fips_dispatch_glGenQueries (n, ids);
+}
+
+PFNGLGENQUERIESPROC fips_dispatch_glGenQueries = stub_glGenQueries;
+
+static void
+resolve_glDeleteQueries (void)
+{
+       fips_dispatch_glDeleteQueries = lookup ("glDeleteQueries");
+
+       if (! fips_dispatch_glDeleteQueries)
+               fips_dispatch_glDeleteQueries = lookup ("glDeleteQueriesARB");
+
+       if (! fips_dispatch_glDeleteQueries)
+               unsupported ("DeleteQueries");
+}
+
+static void
+stub_glDeleteQueries (GLsizei n, const GLuint * ids)
+{
+       check_initialized ();
+       resolve_glDeleteQueries ();
+       fips_dispatch_glDeleteQueries (n, ids);
+}
+
+PFNGLDELETEQUERIESPROC fips_dispatch_glDeleteQueries = stub_glDeleteQueries;
+
+static void
+resolve_glBeginQuery (void)
+{
+       fips_dispatch_glBeginQuery = lookup ("glBeginQuery");
+
+       if (! fips_dispatch_glBeginQuery)
+               fips_dispatch_glBeginQuery = lookup ("glBeginQueryARB");
+
+       if (! fips_dispatch_glBeginQuery)
+               unsupported ("BeginQuery");
+}
+
+static void
+stub_glBeginQuery (GLenum target, GLuint id)
+{
+       check_initialized ();
+       resolve_glBeginQuery ();
+       fips_dispatch_glBeginQuery (target, id);
+}
+
+PFNGLBEGINQUERYPROC fips_dispatch_glBeginQuery = stub_glBeginQuery;
+
+static void
+resolve_glEndQuery (void)
+{
+       fips_dispatch_glEndQuery = lookup ("glEndQuery");
+
+       if (! fips_dispatch_glEndQuery)
+               fips_dispatch_glEndQuery = lookup ("glEndQueryARB");
+
+       if (! fips_dispatch_glEndQuery)
+               unsupported ("EndQuery");
+}
+
+static void
+stub_glEndQuery (GLenum target)
+{
+       check_initialized ();
+       resolve_glEndQuery ();
+       fips_dispatch_glEndQuery (target);
+}
+
+PFNGLENDQUERYPROC fips_dispatch_glEndQuery = stub_glEndQuery;
+
+static void
+resolve_glGetQueryObjectuiv (void)
+{
+       fips_dispatch_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVARBPROC) lookup("glGetQueryObjectuivARB");
+
+       if (! fips_dispatch_glGetQueryObjectuiv)
+               unsupported ("GetQueryObjectuiv");
+}
+
+static void
+stub_glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint * params)
+{
+       check_initialized ();
+       resolve_glGetQueryObjectuiv ();
+       fips_dispatch_glGetQueryObjectuiv (id, pname, params);
+}
+
+PFNGLGETQUERYOBJECTUIVPROC fips_dispatch_glGetQueryObjectuiv = stub_glGetQueryObjectuiv;
diff --git a/fips-dispatch.h b/fips-dispatch.h
new file mode 100644 (file)
index 0000000..a371703
--- /dev/null
@@ -0,0 +1,51 @@
+/* Copyright © 2012, Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef FIPS_DISPATCH_H
+#define FIPS_DISPATCH_H
+
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+
+extern PFNGLGENQUERIESPROC fips_dispatch_glGenQueries;
+#define glGenQueries fips_dispatch_glGenQueries
+
+extern PFNGLDELETEQUERIESPROC fips_dispatch_glDeleteQueries;
+#define glDeleteQueries fips_dispatch_glDeleteQueries
+
+extern PFNGLBEGINQUERYPROC fips_dispatch_glBeginQuery;
+#define glBeginQuery fips_dispatch_glBeginQuery
+
+extern PFNGLENDQUERYPROC fips_dispatch_glEndQuery;
+#define glEndQuery fips_dispatch_glEndQuery
+
+extern PFNGLGETQUERYOBJECTUIVPROC fips_dispatch_glGetQueryObjectuiv;
+#define glGetQueryObjectuiv fips_dispatch_glGetQueryObjectuiv
+
+typedef enum {
+       FIPS_API_GLX,
+       FIPS_API_EGL
+} fips_api_t;
+
+void
+fips_dispatch_init (fips_api_t api);
+
+#endif /* FIPS_DISPATCH_H */
diff --git a/fips.h b/fips.h
index 4c6c5bd13e6607d4783dd5074ff010ff1c7d04c6..306ea1bf1405efa51efa745bf78361d6cfdcdfcd 100644 (file)
--- a/fips.h
+++ b/fips.h
@@ -26,6 +26,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 
 #include <string.h>
 
index 323c321107c5d37dc7cd0775e0475afe431869c5..e92889a7688da5efb636f1fc4503c251e3f91b79 100644 (file)
--- a/glwrap.c
+++ b/glwrap.c
  * THE SOFTWARE.
  */
 
-#include "fips.h"
-
-#include "glwrap.h"
-
-#include "metrics.h"
-
 /* The prototypes for some OpenGL functions changed at one point from:
  *
  *     const void* *indices
  */
 #define const
 
-#define GL_GLEXT_PROTOTYPES
-#include <GL/gl.h>
+#include "fips.h"
+#include "fips-dispatch.h"
+
+#include "glwrap.h"
+
+#include "metrics.h"
 
 #include "dlwrap.h"
 
index 84bf48522565e489de274cd87e752d5a470ebd01..799a0190f794de1a63346c372f17b2148835879d 100644 (file)
--- a/glxwrap.c
+++ b/glxwrap.c
@@ -21,6 +21,8 @@
 
 #include "fips.h"
 
+#include "fips-dispatch.h"
+
 #include <X11/Xlib.h>
 #include <GL/gl.h>
 #include <GL/glx.h>
@@ -57,3 +59,15 @@ void (*glXGetProcAddressARB (const GLubyte *func))(void)
 
        return ret;
 }
+
+Bool
+glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx)
+{
+       Bool ret;
+
+       fips_dispatch_init (FIPS_API_GLX);
+
+       GLWRAP_DEFER_WITH_RETURN (ret, glXMakeCurrent, dpy, drawable, ctx);
+
+       return ret;
+}
index b6dbbd098b38672bdebb887ac58abf159baa1db6..cbfe52e9d1ce6d8c19bed45c9d038b11d14bfa0e 100644 (file)
--- a/metrics.c
+++ b/metrics.c
@@ -24,9 +24,7 @@
 
 #include <sys/time.h>
 
-#define GL_GLEXT_PROTOTYPES
-#include <GL/gl.h>
-
+#include "fips-dispatch.h"
 #include "metrics.h"
 
 typedef struct counter