X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glwrap.c;h=0ae295a87082212b59d764f8b89250c2ab5c68b8;hb=d6ac766abe401b681282cdcf273e7fb67fff99bd;hp=beb1c97fd38cb05830e6ce1f37b9680c872804bc;hpb=c0c549440d852153d1777eca3fa962c1b70483b3;p=fips diff --git a/glwrap.c b/glwrap.c index beb1c97..0ae295a 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,33 +41,67 @@ #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. + */ + 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,10 +361,47 @@ glClear (GLbitfield mask) TIMED_DEFER (glClear, mask); } +/* 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_counter_new (); + metrics_counter_start (counter); + } + + GLWRAP_DEFER (glBegin, mode); +} + void glEnd (void) { - TIMED_DEFER (glEnd,); + GLWRAP_DEFER (glEnd); + + if (! inside_new_list) { + 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