X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glwrap.c;h=bcb8111a03e990baa9298c3c939f2f77494a11ad;hb=6475596e655063624dbf54359bd2a45de6a17dd1;hp=c37bae3a16ab1b63ad1883ed5f6c46fdf4def4c8;hpb=fa324e0ec0fbd4becdb000d4b9d8c17d5b79f92a;p=fips diff --git a/glwrap.c b/glwrap.c index c37bae3..bcb8111 100644 --- a/glwrap.c +++ b/glwrap.c @@ -19,10 +19,6 @@ * THE SOFTWARE. */ -#include "fips.h" - -#include "glwrap.h" - /* The prototypes for some OpenGL functions changed at one point from: * * const void* *indices @@ -43,68 +39,18 @@ #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); - } +#include "fips.h" - glGenQueries (1, &counter->id); +#include "glwrap.h" - counter->program = current_context.program; - counter->next = NULL; +#include "metrics.h" - 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; - } +#include "dlwrap.h" - return counter->id; -} +static int inside_new_list = 0; -static void * -lookup (const char *name) +void * +glwrap_lookup (char *name) { const char *libgl_filename = "libGL.so.1"; static void *libgl_handle = NULL; @@ -121,21 +67,17 @@ lookup (const char *name) 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); \ +/* 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. */ @@ -215,13 +157,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, @@ -361,13 +302,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, @@ -396,10 +337,46 @@ 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) +{ + if (! inside_new_list) + { + unsigned counter; + counter = metrics_add_counter (); + glBeginQuery (GL_TIME_ELAPSED, counter); + } + + GLWRAP_DEFER (glBegin, mode); +} + void glEnd (void) { - TIMED_DEFER (glEnd,); + GLWRAP_DEFER (glEnd); + + if (! inside_new_list) { + glEndQuery (GL_TIME_ELAPSED); + } +} + +/* 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 @@ -434,105 +411,15 @@ glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, void glUseProgram (GLuint program) { - current_context.program = program; + metrics_set_current_program (program); - DEFER(glUseProgram, program); + GLWRAP_DEFER(glUseProgram, program); } void glUseProgramObjectARB (GLhandleARB programObj) { - current_context.program = programObj; - - 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; + metrics_set_current_program (programObj); - 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); - } -} - -void -glwrap_end_frame (void) -{ - static int initialized = 0; - static int frames; - static struct timeval tv_start, tv_now; - - if (! initialized) { - frames = 0; - gettimeofday (&tv_start, NULL); - initialized = 1; - } - - - frames++; - - 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); }