X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glwrap.c;h=ec03ce79c05bed6ed2e2126a4f317a25276dc353;hb=8dc8bcb282b0948605e4b526b9787f51c56301d6;hp=3a789fc131e0c693c398386b8f6f152038cfda35;hpb=b8b9a79e315bf3a030c3b0840ad1490746b5a8e0;p=fips diff --git a/glwrap.c b/glwrap.c index 3a789fc..ec03ce7 100644 --- a/glwrap.c +++ b/glwrap.c @@ -19,503 +19,115 @@ * THE SOFTWARE. */ -#include "fips.h" +#include "dlwrap.h" -#include "glwrap.h" +/* The prototypes for some OpenGL functions changed at one point from: + * + * const void* *indices + * to: + * const void* const coist *indices + * + * This makes it difficult for us to provide an implementation of + * these functions that is consistent with the locally-available gl.h + * since we don't know if the extra const will be present or not. + * + * To workaround this problem, we simply #define away const altogether + * before including gl.h. + * + * Kudos to Keith Packard for suggesting this kludge. + */ +#define const #define GL_GLEXT_PROTOTYPES #include -#include - -#include "dlwrap.h" - -typedef struct counter -{ - unsigned id; - unsigned program; - struct counter *next; -} counter_t; - -typedef struct program_metrics -{ - unsigned id; - double ticks; -} program_metrics_t; - -typedef struct context -{ - unsigned int program; - - counter_t *counter_head; - counter_t *counter_tail; - - unsigned num_program_metrics; - program_metrics_t *program_metrics; -} context_t; - -/* FIXME: Need a map from integers to context objects and track the - * current context with glXMakeContextCurrent, eglMakeCurrent, etc. */ - -context_t current_context; - -static unsigned -add_counter (void) -{ - counter_t *counter; - - counter = malloc (sizeof(counter_t)); - if (counter == NULL) { - fprintf (stderr, "Out of memory\n"); - exit (1); - } - - glGenQueries (1, &counter->id); - - counter->program = current_context.program; - counter->next = NULL; - - if (current_context.counter_tail) { - current_context.counter_tail->next = counter; - current_context.counter_tail = counter; - } else { - current_context.counter_tail = counter; - current_context.counter_head = counter; - } - - return counter->id; -} +#include "fips.h" -static void * -lookup (const char *name) -{ - const char *libgl_filename = "libGL.so.1"; - static void *libgl_handle = NULL; +#include "glwrap.h" - 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); +#include "metrics.h" + +static void *gl_handle; + +void +glwrap_set_gl_handle (void *handle) +{ + if (gl_handle == NULL) + gl_handle = handle; +} + +void * +glwrap_lookup (char *name) +{ + 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); -} - -/* Defer to the underlying, ''real'' function to do the real work. */ -#define DEFER(function,...) do { \ - static typeof(&function) real_ ## function; \ - if (! real_ ## function) \ - real_ ## function = lookup (#function); \ - real_ ## function(__VA_ARGS__); \ -} while (0); - -/* Execute a glBegineQuery/glEndQuery pair around an OpenGL call. */ -#define TIMED_DEFER(function,...) do { \ - unsigned counter; \ - counter = add_counter (); \ - glBeginQuery (GL_TIME_ELAPSED, counter); \ - DEFER(function, __VA_ARGS__); \ - 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); -} + ret = dlwrap_real_dlsym (gl_handle, name); -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); -} - -/* FIXME? -void -glMultiDrawArraysIndirect (...) -{ - TIMED_DEFER (glMultiDrawArraysIndirect, ...); -} -*/ - -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); -} - -void -glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, - GLenum type, const void *indices, GLsizei primcount, - GLint basevertex, GLuint baseinstance) -{ - TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode, - count, type, indices, primcount, basevertex, baseinstance); -} - -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); -} - -/* FIXME? -void -glMultiDrawElementsIndirect (...) -{ - TIMED_DEFER (glMultiDrawElementsIndirect, ...); -} -*/ - -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); -} - -void -glEnd (void) -{ - TIMED_DEFER (glEnd,); -} - -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); -} + if (ret == NULL) { + fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n", + name); + exit (1); + } -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) { - current_context.program = program; + metrics_counter_stop (); - DEFER(glUseProgram, program); -} + metrics_set_current_program (program); -void -glUseProgramObjectARB (GLhandleARB programObj) -{ - current_context.program = programObj; + metrics_counter_start (); - DEFER(glUseProgramObjectARB, programObj); -} - -static void -accumulate_program_ticks (unsigned program_id, unsigned ticks) -{ - context_t *ctx = ¤t_context; - unsigned i; - - if (program_id >= ctx->num_program_metrics) { - ctx->program_metrics = realloc (ctx->program_metrics, - (program_id + 1) * sizeof (program_metrics_t)); - for (i = ctx->num_program_metrics; i < program_id + 1; i++) { - ctx->program_metrics[i].id = i; - ctx->program_metrics[i].ticks = 0.0; - } - - ctx->num_program_metrics = program_id + 1; - } - - ctx->program_metrics[program_id].ticks += ticks; -} - -/* FIXME: Should sort the metrics, print out percentages, etc. */ -static void -print_program_metrics (void) -{ - context_t *ctx = ¤t_context; - unsigned i; - - for (i = 0; i < ctx->num_program_metrics; i++) { - if (ctx->program_metrics[i].ticks == 0.0) - continue; - printf ("Program %d:\t%7.2f mega-ticks\n", - i, ctx->program_metrics[i].ticks / 1e6); - } + GLWRAP_DEFER(glUseProgram, program); } void -glwrap_end_frame (void) +glUseProgramObjectARB (GLhandleARB programObj) { - static int initialized = 0; - static int frames; - static struct timeval tv_start, tv_now; - - if (! initialized) { - frames = 0; - gettimeofday (&tv_start, NULL); - initialized = 1; - } + metrics_counter_stop (); + metrics_set_current_program (programObj); - frames++; + metrics_counter_start (); - if (frames % 60 == 0) { - double fps; - gettimeofday (&tv_now, NULL); - - fps = (double) frames / (tv_now.tv_sec - tv_start.tv_sec + - (tv_now.tv_usec - tv_start.tv_usec) / 1.0e6); - - printf("FPS: %.3f\n", fps); - - print_program_metrics (); - } - - /* Consume all counters that are ready. */ - counter_t *counter = current_context.counter_head; - - while (counter) { - GLint available; - GLuint elapsed; - - glGetQueryObjectiv (counter->id, GL_QUERY_RESULT_AVAILABLE, - &available); - if (! available) - break; - - glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT, &elapsed); - - accumulate_program_ticks (counter->program, elapsed); - - current_context.counter_head = counter->next; - if (current_context.counter_head == NULL) - current_context.counter_tail = NULL; - - glDeleteQueries (1, &counter->id); - - free (counter); - counter = current_context.counter_head; - } + GLWRAP_DEFER(glUseProgramObjectARB, programObj); }