X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glwrap.c;h=3c751cc4e19832aa49d55516b8b38b00aea9033b;hb=7c716eca3492764413e63bbd5386b7ec18d2efa7;hp=323c321107c5d37dc7cd0775e0475afe431869c5;hpb=c10f5f0deb7723aa8462ce52e58f40c9490a8340;p=fips diff --git a/glwrap.c b/glwrap.c index 323c321..3c751cc 100644 --- a/glwrap.c +++ b/glwrap.c @@ -19,11 +19,7 @@ * 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: * @@ -45,38 +41,83 @@ #define GL_GLEXT_PROTOTYPES #include -#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. + * + * 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; } } - return dlwrap_real_dlsym (libgl_handle, name); + ret = dlwrap_real_dlsym (gl_handle, name); + + if (ret == NULL) { + fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n", + name); + exit (1); + } + + return ret; } -/* Execute a glBeginQuery/glEndQuery pair around an OpenGL call. */ +/* 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_add_counter (); \ - glBeginQuery (GL_TIME_ELAPSED, counter); \ + counter = metrics_counter_new (); \ + metrics_counter_start (counter); \ } \ GLWRAP_DEFER(function, __VA_ARGS__); \ if (! inside_new_list) { \ - glEndQuery (GL_TIME_ELAPSED); \ + metrics_counter_stop (); \ } \ } while (0); @@ -337,17 +378,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); @@ -359,7 +401,7 @@ glEnd (void) GLWRAP_DEFER (glEnd); if (! inside_new_list) { - glEndQuery (GL_TIME_ELAPSED); + metrics_counter_stop (); } }