]> git.cworth.org Git - fips/blobdiff - glwrap.c
glxwrap: Initialize fips_dispatch when glxMakeContextCurrent is called
[fips] / glwrap.c
index a90ef8c4707b9f67f13de51495534aa6d6d5258a..0ae295a87082212b59d764f8b89250c2ab5c68b8 100644 (file)
--- a/glwrap.c
+++ b/glwrap.c
  * THE SOFTWARE.
  */
 
-#include "fips.h"
-
-#include "glwrap.h"
-
-#include "metrics.h"
+#include "dlwrap.h"
 
 /* The prototypes for some OpenGL functions changed at one point from:
  *
 #define GL_GLEXT_PROTOTYPES
 #include <GL/gl.h>
 
-#include "dlwrap.h"
+#include "fips.h"
+
+#include "glwrap.h"
+
+#include "metrics.h"
+
+static int inside_new_list = 0;
+
+static void *gl_handle;
+
+void
+glwrap_set_gl_handle (void *handle)
+{
+       if (gl_handle == NULL)
+               gl_handle = handle;
+}
 
 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);
-               }
+       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.
+        */
+       if (gl_handle == NULL)
+               gl_handle = RTLD_NEXT;
+
+       ret = dlwrap_real_dlsym (gl_handle, name);
+
+       if (ret == NULL) {
+               fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n",
+                        name);
+               exit (1);
        }
 
-       return dlwrap_real_dlsym (libgl_handle, name);
+       return ret;
 }
 
-/* Execute a glBegineQuery/glEndQuery pair around an OpenGL call. */
-#define TIMED_DEFER(function,...) do {                 \
-       unsigned counter;                               \
-       counter = metrics_add_counter ();               \
-       glBeginQuery (GL_TIME_ELAPSED, counter);        \
-       GLWRAP_DEFER(function, __VA_ARGS__);            \
-       glEndQuery (GL_TIME_ELAPSED);                   \
+/* Execute an OpenGL call and time it with a GPU metrics counter. */
+#define TIMED_DEFER(function,...) do {                                 \
+       if (! inside_new_list) {                                        \
+               unsigned counter;                                       \
+               counter = metrics_counter_new ();                       \
+               metrics_counter_start (counter);                        \
+       }                                                               \
+       GLWRAP_DEFER(function, __VA_ARGS__);                            \
+       if (! inside_new_list) {                                        \
+               metrics_counter_stop ();                                \
+       }                                                               \
 } while (0);
 
 /* Thanks to apitrace source code for the list of OpenGL draw calls. */
@@ -151,13 +181,12 @@ glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first,
                     first, count, primcount, modestride);
 }
 
-/* FIXME?
 void
-glMultiDrawArraysIndirect (...)
+glMultiDrawArraysIndirect (GLenum mode, const void *indirect,
+                          GLsizei drawcount, GLsizei stride)
 {
-       TIMED_DEFER (glMultiDrawArraysIndirect, ...);
+       TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride);
 }
-*/
 
 void
 glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect,
@@ -297,13 +326,13 @@ glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count,
                     type, indices, primcount, modestride);
 }
 
-/* FIXME?
 void
-glMultiDrawElementsIndirect (...)
+glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect,
+                            GLsizei drawcount, GLsizei stride)
 {
-       TIMED_DEFER (glMultiDrawElementsIndirect, ...);
+       TIMED_DEFER (glMultiDrawElementsIndirect, mode, type,
+                    indirect, drawcount, stride);
 }
-*/
 
 void
 glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type,
@@ -332,17 +361,18 @@ 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. */
+/* We can't just use TIMED_DEFER for glBegin/glEnd since the metrics
+ * counter must be started before glBegin and stopped after glEnd,
+ * (that is, everything from glBegin to glEnd is counted as a single
+ * operation). */
 void
 glBegin (GLenum mode)
 {
        if (! inside_new_list)
        {
                unsigned counter;
-               counter = metrics_add_counter ();
-               glBeginQuery (GL_TIME_ELAPSED, counter);
+               counter = metrics_counter_new ();
+               metrics_counter_start (counter);
        }
 
        GLWRAP_DEFER (glBegin, mode);
@@ -354,10 +384,26 @@ glEnd (void)
        GLWRAP_DEFER (glEnd);
 
        if (! inside_new_list) {
-               glEndQuery (GL_TIME_ELAPSED);
+               metrics_counter_stop ();
        }
 }
 
+/* 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)