From 6475596e655063624dbf54359bd2a45de6a17dd1 Mon Sep 17 00:00:00 2001
From: Carl Worth <cworth@cworth.org>
Date: Mon, 24 Jun 2013 13:22:59 -0700
Subject: [PATCH] fips-dispatch: Completely separate fips-dispatch GL
 prototypes from GL/gl.h

Move the OpenGL prototypes previously in fips-dispatch.h to a new
fips-dispatch-gl.h. The idea here is that any given file should
include only one of GL/gl.h or fips-dispatch-gl.h.

Files that implement libfips wrappers for OpenGL functions include
GL/gl.h to ensure that they implement functions with the correct
prototypes.

Meanwhile, files that call into OpenGL functions at run-time, (such as
metrics.c which calls the various OpenGL query-related functions),
instead include fips-dispatch-gl.h and do not include GL/gl.h. With
this approach, any new calls to OpenGL functions will cause
compilation warnings if the stubs are not also added to
fips-dispatch-gl.h.
---
 Makefile.local     |   1 +
 fips-dispatch-gl.c | 149 +++++++++++++++++++++++++++++++++++++++++++++
 fips-dispatch-gl.h |  90 +++++++++++++++++++++++++++
 fips-dispatch.c    | 143 +++----------------------------------------
 fips-dispatch.h    |  41 +++++++------
 glwrap.c           |   4 +-
 metrics.c          |   3 +-
 7 files changed, 276 insertions(+), 155 deletions(-)
 create mode 100644 fips-dispatch-gl.c
 create mode 100644 fips-dispatch-gl.h

diff --git a/Makefile.local b/Makefile.local
index 9b54011..f468c64 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -95,6 +95,7 @@ extra_cflags += -I$(srcdir) -fPIC
 libfips_srcs = \
 	dlwrap.c \
 	fips-dispatch.c \
+	fips-dispatch-gl.c \
 	glwrap.c \
 	glxwrap.c \
 	metrics.c
diff --git a/fips-dispatch-gl.c b/fips-dispatch-gl.c
new file mode 100644
index 0000000..cd9e35e
--- /dev/null
+++ b/fips-dispatch-gl.c
@@ -0,0 +1,149 @@
+/* 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-dispatch-gl.h"
+
+static void
+check_initialized (void)
+{
+	if (fips_dispatch_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
+resolve_glGenQueries (void)
+{
+	fips_dispatch_glGenQueries = fips_dispatch_lookup ("glGenQueries");
+
+	if (! fips_dispatch_glGenQueries)
+		fips_dispatch_glGenQueries = fips_dispatch_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 = fips_dispatch_lookup ("glDeleteQueries");
+
+	if (! fips_dispatch_glDeleteQueries)
+		fips_dispatch_glDeleteQueries = fips_dispatch_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 = fips_dispatch_lookup ("glBeginQuery");
+
+	if (! fips_dispatch_glBeginQuery)
+		fips_dispatch_glBeginQuery = fips_dispatch_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 = fips_dispatch_lookup ("glEndQuery");
+
+	if (! fips_dispatch_glEndQuery)
+		fips_dispatch_glEndQuery = fips_dispatch_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 = (PFNGLGETQUERYOBJECTUIVPROC) fips_dispatch_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-gl.h b/fips-dispatch-gl.h
new file mode 100644
index 0000000..928d139
--- /dev/null
+++ b/fips-dispatch-gl.h
@@ -0,0 +1,90 @@
+/* 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.
+ */
+
+/* This header file provides an interface to (the fips-dispatch subset
+ * of) OpenGL through dynamic dispatch as an alternative to including
+ * <GL/gl.h>.
+ *
+ * No file in fips should include both <GL/gl.h> and
+ * "fips-dispatch-gl.h" (whether directly or indirectly).
+ */
+
+#ifndef FIPS_DISPATCH_GL_H
+#define FIPS_DISPATCH_GL_H
+
+#include "fips-dispatch.h"
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef unsigned int GLenum;
+typedef unsigned int GLbitfield;
+typedef unsigned int GLuint;
+typedef int GLint;
+typedef int GLsizei;
+typedef unsigned char GLboolean;
+typedef signed char GLbyte;
+typedef short GLshort;
+typedef unsigned char GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned long GLulong;
+typedef float GLfloat;
+typedef float GLclampf;
+typedef double GLdouble;
+typedef double GLclampd;
+typedef void GLvoid;
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+typedef GLint64EXT  GLint64;
+typedef GLuint64EXT GLuint64;
+typedef char GLchar;
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+typedef char GLcharARB;
+typedef unsigned int GLhandleARB;
+
+typedef void (*PFNGLGENQUERIESPROC)(GLsizei, GLuint *);
+typedef void (*PFNGLDELETEQUERIESPROC)(GLsizei, const GLuint *);
+typedef void (*PFNGLBEGINQUERYPROC)(GLenum, GLuint);
+typedef void (*PFNGLENDQUERYPROC)(GLenum);
+typedef void (*PFNGLGETQUERYOBJECTUIVPROC)(GLuint, GLenum, GLuint *);
+
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+
+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
+
+#endif /* FIPS_DISPATCH_GL_H */
diff --git a/fips-dispatch.c b/fips-dispatch.c
index c5f767c..beb0fa7 100644
--- a/fips-dispatch.c
+++ b/fips-dispatch.c
@@ -19,8 +19,6 @@
  * THE SOFTWARE.
  */
 
-#include "fips.h"
-
 #include "fips-dispatch.h"
 
 #define GL_GLEXT_PROTOTYPES
@@ -29,149 +27,22 @@
 
 #include <EGL/egl.h>
 
-static bool fips_initialized;
-static fips_api_t fips_api;
+bool fips_dispatch_initialized;
+fips_api_t fips_dispatch_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);
+	fips_dispatch_api = api;
 
-	exit (1);
+	fips_dispatch_initialized = true;
 }
 
-static void *
-lookup (const char *name)
+void *
+fips_dispatch_lookup (const char *name)
 {
-	if (fips_api == FIPS_API_GLX)
+	if (fips_dispatch_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
index a371703..8938e61 100644
--- a/fips-dispatch.h
+++ b/fips-dispatch.h
@@ -19,33 +19,40 @@
  * THE SOFTWARE.
  */
 
+/* This header file provides prototypes to iniatialize the
+ * fips-dispatch system (fips_dispatch_init) but does not provide the
+ * prototypes for dynamically-dipatched OpenGL functions.
+ * See fips-dispatch-gl.h for those.
+ */
+
 #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
+#include "fips.h"
 
 typedef enum {
 	FIPS_API_GLX,
 	FIPS_API_EGL
 } fips_api_t;
 
+extern bool fips_dispatch_initialized;
+extern fips_api_t fips_dispatch_api;
+
+/* Initialize fips-dispatch with the appropriate API, (whether GLX or
+ * EGL, etc.). */
 void
 fips_dispatch_init (fips_api_t api);
 
+/* Lookup a named symbol, (via either glXGetProcAddressARB or
+ * eglGetProcAddress).
+ *
+ * Note: No user of fips-dispatch need ever call this
+ * function. Instead, users should simply include fips-dispatch-gl.h,
+ * then make direct calls to GL functions and through some
+ * C-preprocessor magic, the lookup will magically happen at
+ * runtime.
+ */
+void *
+fips_dispatch_lookup (const char *name);
+
 #endif /* FIPS_DISPATCH_H */
diff --git a/glwrap.c b/glwrap.c
index e92889a..bcb8111 100644
--- a/glwrap.c
+++ b/glwrap.c
@@ -36,8 +36,10 @@
  */
 #define const
 
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+
 #include "fips.h"
-#include "fips-dispatch.h"
 
 #include "glwrap.h"
 
diff --git a/metrics.c b/metrics.c
index cbfe52e..7298fa8 100644
--- a/metrics.c
+++ b/metrics.c
@@ -24,7 +24,8 @@
 
 #include <sys/time.h>
 
-#include "fips-dispatch.h"
+#include "fips-dispatch-gl.h"
+
 #include "metrics.h"
 
 typedef struct counter
-- 
2.45.2