1 /* Copyright © 2013, Intel Corporation
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include "fips-dispatch-gl.h"
31 typedef struct counter
38 typedef struct program_metrics
44 typedef struct context
48 counter_t *counter_head;
49 counter_t *counter_tail;
51 unsigned num_program_metrics;
52 program_metrics_t *program_metrics;
55 /* FIXME: Need a map from integers to context objects and track the
56 * current context with glXMakeContextCurrent, eglMakeCurrent, etc. */
58 context_t current_context;
61 metrics_add_counter (void)
65 counter = malloc (sizeof(counter_t));
66 if (counter == NULL) {
67 fprintf (stderr, "Out of memory\n");
71 glGenQueries (1, &counter->id);
73 counter->program = current_context.program;
76 if (current_context.counter_tail) {
77 current_context.counter_tail->next = counter;
78 current_context.counter_tail = counter;
80 current_context.counter_tail = counter;
81 current_context.counter_head = counter;
88 metrics_set_current_program (unsigned program)
90 current_context.program = program;
94 accumulate_program_ticks (unsigned program_id, unsigned ticks)
96 context_t *ctx = ¤t_context;
99 if (program_id >= ctx->num_program_metrics) {
100 ctx->program_metrics = realloc (ctx->program_metrics,
101 (program_id + 1) * sizeof (program_metrics_t));
102 for (i = ctx->num_program_metrics; i < program_id + 1; i++) {
103 ctx->program_metrics[i].id = i;
104 ctx->program_metrics[i].ticks = 0.0;
107 ctx->num_program_metrics = program_id + 1;
110 ctx->program_metrics[program_id].ticks += ticks;
113 /* FIXME: Should sort the metrics, print out percentages, etc. */
115 print_program_metrics (void)
117 context_t *ctx = ¤t_context;
120 for (i = 0; i < ctx->num_program_metrics; i++) {
121 if (ctx->program_metrics[i].ticks == 0.0)
123 printf ("Program %d:\t%7.2f mega-ticks\n",
124 i, ctx->program_metrics[i].ticks / 1e6);
129 metrics_end_frame (void)
131 static int initialized = 0;
133 static struct timeval tv_start, tv_now;
137 gettimeofday (&tv_start, NULL);
143 gettimeofday (&tv_now, NULL);
145 /* Consume all counters that are ready. */
146 counter_t *counter = current_context.counter_head;
149 GLuint available, elapsed;
151 glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT_AVAILABLE,
156 glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT, &elapsed);
158 accumulate_program_ticks (counter->program, elapsed);
160 current_context.counter_head = counter->next;
161 if (current_context.counter_head == NULL)
162 current_context.counter_tail = NULL;
164 glDeleteQueries (1, &counter->id);
167 counter = current_context.counter_head;
170 if (frames % 60 == 0) {
173 fps = (double) frames / (tv_now.tv_sec - tv_start.tv_sec +
174 (tv_now.tv_usec - tv_start.tv_usec) / 1.0e6);
176 printf("FPS: %.3f\n", fps);
178 print_program_metrics ();