]> git.cworth.org Git - fips/commitdiff
Move metrics-tracking code from glwrap.c to new metrics.c
authorCarl Worth <cworth@cworth.org>
Mon, 6 May 2013 18:18:33 +0000 (11:18 -0700)
committerCarl Worth <cworth@cworth.org>
Mon, 6 May 2013 18:36:56 +0000 (11:36 -0700)
We're moving toward having separate *wrap.c files for each flavor of GL,
(glwrap.c, glxwrap.c, and eglwrap.c). But this metrics-tracking code is
generic to all of those so belongs in a separate module.

Makefile.local
glwrap.c
glwrap.h
metrics.c [new file with mode: 0644]
metrics.h [new file with mode: 0644]

index c82590c14b478ad582c57927b3e9be765b003d04..2f9b5f0a19e2e8d10aafafeeb63b055c19fa903f 100644 (file)
@@ -82,7 +82,8 @@ extra_cflags += -I$(srcdir) -fPIC
 libfips_srcs = \
        dlwrap.c \
        glwrap.c \
-       glxwrap.c
+       glxwrap.c \
+       metrics.c
 
 libfips_32_modules = $(libfips_srcs:.c=-32.o)
 
index 9537271243c4cfef41969ca01161c43a05c9910e..beb1c97fd38cb05830e6ce1f37b9680c872804bc 100644 (file)
--- a/glwrap.c
+++ b/glwrap.c
@@ -23,6 +23,8 @@
 
 #include "glwrap.h"
 
+#include "metrics.h"
+
 /* The prototypes for some OpenGL functions changed at one point from:
  *
  *     const void* *indices
 #define GL_GLEXT_PROTOTYPES
 #include <GL/gl.h>
 
-#include <sys/time.h>
-
 #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;
-}
-
 void *
 glwrap_lookup (char *name)
 {
@@ -124,7 +68,7 @@ glwrap_lookup (char *name)
 /* Execute a glBegineQuery/glEndQuery pair around an OpenGL call. */
 #define TIMED_DEFER(function,...) do {                 \
        unsigned counter;                               \
-       counter = add_counter ();                       \
+       counter = metrics_add_counter ();               \
        glBeginQuery (GL_TIME_ELAPSED, counter);        \
        GLWRAP_DEFER(function, __VA_ARGS__);            \
        glEndQuery (GL_TIME_ELAPSED);                   \
@@ -426,7 +370,7 @@ glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
 void
 glUseProgram (GLuint program)
 {
-       current_context.program = program;
+       metrics_set_current_program (program);
 
        GLWRAP_DEFER(glUseProgram, program);
 }
@@ -434,97 +378,7 @@ glUseProgram (GLuint program)
 void
 glUseProgramObjectARB (GLhandleARB programObj)
 {
-       current_context.program = programObj;
+       metrics_set_current_program (programObj);
 
        GLWRAP_DEFER(glUseProgramObjectARB, programObj);
 }
-
-static void
-accumulate_program_ticks (unsigned program_id, unsigned ticks)
-{
-       context_t *ctx = &current_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 = &current_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);
-       }
-}
-
-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;
-       }
-}
index 2dc18383c0c864e40e5b033ce67f2f209fe895dd..9195007c4b51b15cd8eb38eea9439ee0c15d4579 100644 (file)
--- a/glwrap.h
+++ b/glwrap.h
@@ -37,10 +37,4 @@ glwrap_lookup (char *name);
        real_ ## function(__VA_ARGS__);                         \
 } while (0);
 
-/* Should be called at the end of ever function wrapper for an OpenGL
- * function that ends a frame, (glXSwapBuffers and similar).
- */
-void
-glwrap_end_frame (void);
-
 #endif
diff --git a/metrics.c b/metrics.c
new file mode 100644 (file)
index 0000000..f4c0a21
--- /dev/null
+++ b/metrics.c
@@ -0,0 +1,182 @@
+/* Copyright © 2013, Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/time.h>
+
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+
+#include "metrics.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;
+
+unsigned
+metrics_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;
+}
+
+void
+metrics_set_current_program (unsigned program)
+{
+       current_context.program = program;
+}
+
+static void
+accumulate_program_ticks (unsigned program_id, unsigned ticks)
+{
+       context_t *ctx = &current_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 = &current_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);
+       }
+}
+
+void
+metrics_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;
+       }
+}
diff --git a/metrics.h b/metrics.h
new file mode 100644 (file)
index 0000000..261a5a5
--- /dev/null
+++ b/metrics.h
@@ -0,0 +1,53 @@
+/* Copyright © 2013, Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef METRICS_H
+#define METRICS_H
+
+/* Add a new counter to the metrics tracking state.
+ *
+ * The value accumulated in this counter be accounted against the
+ * current program (as set with metrics_set_current_program).
+ *
+ * Returns: A counter ID suitable for use with glBeginQuery/glEndQuery
+ */
+unsigned
+metrics_add_counter (void);
+
+/* Set the ID of the currently executing shader program.
+ *
+ * The metrics-tracking code will account for per-shader-program
+ * timings by accumulating counter values measured while each porogram
+ * is active (see metrics_add_counter).
+ */
+void
+metrics_set_current_program (unsigned program);
+
+/* Should be called at the end of every function wrapper for a
+ * function that ends a frame, (glXSwapBuffers and similar).
+ *
+ * This function performs whatever bookkeeping is necessary to
+ * generate a timing report, then emits that report.
+ */
+void
+metrics_end_frame (void);
+
+#endif