]> git.cworth.org Git - fips/blobdiff - glwrap.c
Rework timer queries to run continuously.
[fips] / glwrap.c
index e92889a7688da5efb636f1fc4503c251e3f91b79..ec03ce79c05bed6ed2e2126a4f317a25276dc353 100644 (file)
--- a/glwrap.c
+++ b/glwrap.c
@@ -19,6 +19,8 @@
  * THE SOFTWARE.
  */
 
+#include "dlwrap.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"
-
-static int inside_new_list = 0;
-
-void *
-glwrap_lookup (char *name)
-{
-       const char *libgl_filename = "libGL.so.1";
-       static void *libgl_handle = NULL;
-
-       if (! libgl_handle) {
-               libgl_handle = dlwrap_real_dlopen (libgl_filename, RTLD_NOW | RTLD_DEEPBIND);
-               if (! libgl_handle) {
-                       fprintf (stderr, "Error: Failed to dlopen %s\n",
-                                libgl_filename);
-                       exit (1);
-               }
-       }
-
-       return dlwrap_real_dlsym (libgl_handle, name);
-}
-
-/* Execute a glBeginQuery/glEndQuery pair around an OpenGL call. */
-#define TIMED_DEFER(function,...) do {                                 \
-       if (! inside_new_list) {                                        \
-               unsigned counter;                                       \
-               counter = metrics_add_counter ();                       \
-               glBeginQuery (GL_TIME_ELAPSED, counter);                \
-       }                                                               \
-       GLWRAP_DEFER(function, __VA_ARGS__);                            \
-       if (! inside_new_list) {                                        \
-               glEndQuery (GL_TIME_ELAPSED);                           \
-       }                                                               \
-} while (0);
-
-/* Thanks to apitrace source code for the list of OpenGL draw calls. */
-void
-glDrawArrays (GLenum mode, GLint first, GLsizei count)
-{
-       TIMED_DEFER (glDrawArrays, mode, first, count);
-}
-
-void
-glDrawArraysEXT (GLenum mode, GLint first, GLsizei count)
-{
-       TIMED_DEFER (glDrawArraysEXT, mode, first, count);
-}
-
-void
-glDrawArraysIndirect (GLenum mode, const GLvoid *indirect)
-{
-       TIMED_DEFER (glDrawArraysIndirect, mode, indirect);
-}
-
-void
-glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count,
-                      GLsizei primcount)
-{
-       TIMED_DEFER (glDrawArraysInstanced, mode, first, count, primcount);
-}
-
-void
-glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count,
-                         GLsizei primcount)
-{
-       TIMED_DEFER (glDrawArraysInstancedARB, mode, first, count, primcount);
-}
-
-void
-glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count,
-                         GLsizei primcount)
-{
-       TIMED_DEFER (glDrawArraysInstancedEXT, mode, start, count, primcount);
-}
-
-void
-glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count,
-                                  GLsizei primcount, GLuint baseinstance)
-{
-       TIMED_DEFER (glDrawArraysInstancedBaseInstance, mode,
-                    first, count, primcount, baseinstance);
-}
-
-void
-glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width)
-{
-       TIMED_DEFER (glDrawMeshArraysSUN, mode, first, count, width);
-}
-
-void
-glMultiDrawArrays (GLenum mode, const GLint *first,
-                  const GLsizei *count, GLsizei primcount)
-{
-       TIMED_DEFER (glMultiDrawArrays, mode, first, count, primcount);
-}
-
-void
-glMultiDrawArraysEXT (GLenum mode, const GLint *first,
-                     const GLsizei *count, GLsizei primcount)
-{
-       TIMED_DEFER (glMultiDrawArraysEXT, mode, first, count, primcount);
-}
-
-void
-glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first,
-                         const GLsizei *count, GLsizei primcount,
-                         GLint modestride)
-{
-       TIMED_DEFER (glMultiModeDrawArraysIBM, mode,
-                    first, count, primcount, modestride);
-}
-
-void
-glMultiDrawArraysIndirect (GLenum mode, const void *indirect,
-                          GLsizei drawcount, GLsizei stride)
-{
-       TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride);
-}
-
-void
-glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect,
-                             GLsizei primcount, GLsizei stride)
-{
-       TIMED_DEFER (glMultiDrawArraysIndirectAMD, mode,
-                    indirect, primcount, stride);
-}
-
-void
-glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
-{
-       TIMED_DEFER (glDrawElements, mode, count, type, indices);
-}
-
-void
-glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type,
-                         const GLvoid *indices, GLint basevertex)
-{
-       TIMED_DEFER (glDrawElementsBaseVertex, mode, count,
-                    type, indices, basevertex);
-}
-
-void
-glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect)
-{
-       TIMED_DEFER (glDrawElementsIndirect, mode, type, indirect);
-}
-
-void
-glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type,
-                        const GLvoid *indices, GLsizei primcount)
-{
-       TIMED_DEFER (glDrawElementsInstanced, mode, count,
-                    type, indices, primcount);
-}
-
-void
-glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type,
-                           const GLvoid *indices, GLsizei primcount)
-{
-       TIMED_DEFER (glDrawElementsInstancedARB, mode, count,
-                    type, indices, primcount);
-}
-
-void
-glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type,
-                           const GLvoid *indices, GLsizei primcount)
-{
-       TIMED_DEFER (glDrawElementsInstancedEXT, mode, count,
-                    type, indices, primcount);
-}
-
-void
-glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type,
-                                  const GLvoid *indices, GLsizei primcount,
-                                  GLint basevertex)
-{
-       TIMED_DEFER (glDrawElementsInstancedBaseVertex, mode, count,
-                    type, indices, primcount, basevertex);
-}
-
-void
-glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type,
-                                    const void *indices, GLsizei primcount,
-                                    GLuint baseinstance)
-{
-       TIMED_DEFER (glDrawElementsInstancedBaseInstance, mode, count, type,
-                    indices, primcount, baseinstance);
-}
+static void *gl_handle;
 
 void
-glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count,
-                     GLenum type, const void *indices, GLsizei primcount,
-                     GLint basevertex, GLuint baseinstance)
+glwrap_set_gl_handle (void *handle)
 {
-       TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode,
-                    count, type, indices, primcount, basevertex, baseinstance);
+       if (gl_handle == NULL)
+               gl_handle = handle;
 }
 
-void
-glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count,
-                    GLenum type, const GLvoid *indices)
-{
-       TIMED_DEFER (glDrawRangeElements, mode, start, end,
-                    count, type, indices);
-}
-
-void
-glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count,
-                       GLenum type, const GLvoid *indices)
-{
-       TIMED_DEFER (glDrawRangeElementsEXT, mode, start, end,
-                    count, type, indices);
-}
-
-void
-glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end,
-                              GLsizei count, GLenum type,
-                              const GLvoid *indices, GLint basevertex)
-{
-       TIMED_DEFER (glDrawRangeElementsBaseVertex, mode, start, end,
-                    count, type, indices, basevertex);
-}
-
-void
-glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type,
-                    const GLvoid* *indices, GLsizei primcount)
-{
-       TIMED_DEFER (glMultiDrawElements, mode, count, type,
-                    indices, primcount);
-}
-
-void
-glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count,
-                              GLenum type, const GLvoid* *indices,
-                              GLsizei primcount, const GLint *basevertex)
-{
-       TIMED_DEFER (glMultiDrawElementsBaseVertex, mode, count,
-                    type, indices, primcount, basevertex);
-}
-
-void
-glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type,
-                       const GLvoid* *indices, GLsizei primcount)
-{
-       TIMED_DEFER (glMultiDrawElementsEXT, mode, count,
-                    type, indices, primcount);
-}
-
-void
-glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count,
-                           GLenum type, const GLvoid* const *indices,
-                           GLsizei primcount, GLint modestride)
-{
-       TIMED_DEFER (glMultiModeDrawElementsIBM, mode, count,
-                    type, indices, primcount, modestride);
-}
-
-void
-glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect,
-                            GLsizei drawcount, GLsizei stride)
-{
-       TIMED_DEFER (glMultiDrawElementsIndirect, mode, type,
-                    indirect, drawcount, stride);
-}
-
-void
-glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type,
-                               const GLvoid *indirect,
-                               GLsizei primcount, GLsizei stride)
-{
-       TIMED_DEFER (glMultiDrawElementsIndirectAMD, mode, type,
-                    indirect, primcount, stride);
-}
-
-void
-glCallList (GLuint list)
-{
-       TIMED_DEFER (glCallList, list);
-}
-
-void
-glCallLists (GLsizei n, GLenum type, const GLvoid *lists)
-{
-       TIMED_DEFER (glCallLists, n, type, lists);
-}
-
-void
-glClear (GLbitfield mask)
-{
-       TIMED_DEFER (glClear, mask);
-}
-
-/* We can't just use TIMED_DEFER for glBegin/glEnd since the
- * glBeginQuery/glEndQuery calls must both be outside
- * glBegin/glEnd. */
-void
-glBegin (GLenum mode)
+void *
+glwrap_lookup (char *name)
 {
-       if (! inside_new_list)
-       {
-               unsigned counter;
-               counter = metrics_add_counter ();
-               glBeginQuery (GL_TIME_ELAPSED, counter);
+       void *ret;
+
+       /* We don't call dlopen here to find the library in which to
+        * perform a dlsym lookup. That's because the application may
+        * be loading libGL.so or libGLESv2.so for its OpenGL symbols.
+        *
+        * So we instead watch for one of those filenames to go by in
+        * our dlopen wrapper, which will then call
+        * glwrap_set_gl_handle to give us the handle to use here.
+        *
+        * If the application hasn't called dlopen on a "libGL"
+        * library, then presumably the application is linked directly
+        * to an OpenGL implementation. In this case, we can use
+        * RTLD_NEXT to find the symbol.
+        *
+        * But just in case, we also let the user override that by
+        * specifying the FIPS_LIBGL environment variable to the path
+        * of the real libGL.so library that fips should dlopen here.
+        */
+       if (gl_handle == NULL) {
+               const char *path;
+
+               path = getenv ("FIPS_LIBGL");
+               if (path) {
+                       gl_handle = dlopen (path, RTLD_LAZY);
+
+                       if (gl_handle == NULL) {
+                               fprintf (stderr, "Failed to dlopen FIPS_LIBGL: "
+                                        "%s\n", path);
+                               exit (1);
+                       }
+               } else {
+                       gl_handle = RTLD_NEXT;
+               }
        }
 
-       GLWRAP_DEFER (glBegin, mode);
-}
+       ret = dlwrap_real_dlsym (gl_handle, name);
 
-void
-glEnd (void)
-{
-       GLWRAP_DEFER (glEnd);
-
-       if (! inside_new_list) {
-               glEndQuery (GL_TIME_ELAPSED);
+       if (ret == NULL) {
+               fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n",
+                        name);
+               exit (1);
        }
-}
 
-/* And we need to track display lists to avoid inserting queries
- * inside the list while it's being constructed. */
-void
-glNewList (GLuint list, GLenum mode)
-{
-       inside_new_list = 1;
-       GLWRAP_DEFER (glNewList, list, mode);
-}
-
-void
-glEndList (void)
-{
-       GLWRAP_DEFER (glEndList);
-       inside_new_list = 0;
-}
-
-void
-glDrawPixels (GLsizei width, GLsizei height, GLenum format,
-             GLenum type, const GLvoid *pixels)
-{
-       TIMED_DEFER (glDrawPixels, width, height, format, type, pixels);
-}
-
-void
-glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                  GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                  GLbitfield mask, GLenum filter)
-{
-       TIMED_DEFER (glBlitFramebuffer,
-                    srcX0, srcY0, srcX1, srcY1,
-                    dstX0, dstY0, dstX1, dstY1,
-                    mask, filter);
-}
-
-void
-glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                     GLbitfield mask, GLenum filter)
-{
-       TIMED_DEFER (glBlitFramebufferEXT,
-                    srcX0, srcY0, srcX1, srcY1,
-                    dstX0, dstY0, dstX1, dstY1,
-                    mask, filter);
+       return ret;
 }
 
+/* With a program change, we stop the counter, update the
+ * active program, then start the counter up again. */
 void
 glUseProgram (GLuint program)
 {
+       metrics_counter_stop ();
+
        metrics_set_current_program (program);
 
+       metrics_counter_start ();
+
        GLWRAP_DEFER(glUseProgram, program);
 }
 
 void
 glUseProgramObjectARB (GLhandleARB programObj)
 {
+       metrics_counter_stop ();
+
        metrics_set_current_program (programObj);
 
+       metrics_counter_start ();
+
        GLWRAP_DEFER(glUseProgramObjectARB, programObj);
 }