29
35
extern void clear_gl_error (void);
30
36
extern void check_gl_error (const char *type);
32
static int fps_text_x = 10;
33
static int fps_text_y = 10;
34
static int fps_ascent, fps_descent;
35
static GLuint font_dlist;
36
static Bool fps_clear_p = False;
37
static char fps_string[1024];
38
extern GLfloat fps_1 (ModeInfo *mi);
39
extern void fps_2 (ModeInfo *mi);
40
extern void do_fps (ModeInfo *mi);
41
extern void fps_free (ModeInfo *mi);
53
struct timeval prev, now;
40
58
fps_init (ModeInfo *mi)
42
const char *font = get_string_resource ("fpsFont", "Font");
47
fps_clear_p = get_boolean_resource ("fpsSolid", "FPSSolid");
49
if (!font) font = "-*-courier-bold-r-normal-*-180-*";
50
f = XLoadQueryFont(mi->dpy, font);
51
if (!f) f = XLoadQueryFont(mi->dpy, "fixed");
54
first = f->min_char_or_byte2;
55
last = f->max_char_or_byte2;
60
struct fps_state *st = mi->fps_state;
63
st = (struct fps_state *) calloc (1, sizeof(*st));
66
st->clear_p = get_boolean_resource (mi->dpy, "fpsSolid", "FPSSolid");
68
# ifndef HAVE_COCOA /* Xlib version */
75
font = get_string_resource (mi->dpy, "fpsFont", "Font");
77
if (!font) font = "-*-courier-bold-r-normal-*-180-*";
78
f = XLoadQueryFont (mi->dpy, font);
79
if (!f) f = XLoadQueryFont (mi->dpy, "fixed");
82
first = f->min_char_or_byte2;
83
last = f->max_char_or_byte2;
58
font_dlist = glGenLists ((GLuint) last+1);
59
check_gl_error ("glGenLists");
61
fps_ascent = f->ascent;
62
fps_descent = f->descent;
64
if (get_boolean_resource ("fpsTop", "FPSTop"))
65
fps_text_y = - (f->ascent + 10);
67
glXUseXFont(id, first, last-first+1, font_dlist + first);
68
check_gl_error ("glXUseXFont");
86
st->font_dlist = glGenLists ((GLuint) last+1);
87
check_gl_error ("glGenLists");
89
st->ascent = f->ascent;
90
st->descent = f->descent;
92
glXUseXFont (id, first, last-first+1, st->font_dlist + first);
93
check_gl_error ("glXUseXFont");
96
# else /* HAVE_COCOA */
99
AGLContext ctx = aglGetCurrentContext();
100
GLint id = 0; /* 0 = system font; 1 = application font */
101
Style face = 1; /* 0 = plain; 1=B; 2=I; 3=BI; 4=U; 5=UB; etc. */
106
st->ascent = size * 0.9;
107
st->descent = size - st->ascent;
110
st->font_dlist = glGenLists ((GLuint) last+1);
111
check_gl_error ("glGenLists");
113
if (! aglUseFont (ctx, id, face, size,
114
first, last-first+1, st->font_dlist + first)) {
115
check_gl_error ("aglUseFont");
120
# endif /* HAVE_COCOA */
124
if (get_boolean_resource (mi->dpy, "fpsTop", "FPSTop"))
125
st->y = - (st->ascent + 10);
129
fps_free (ModeInfo *mi)
132
free (mi->fps_state);
73
137
fps_print_string (ModeInfo *mi, GLfloat x, GLfloat y, const char *string)
139
struct fps_state *st = mi->fps_state;
75
140
const char *L2 = strchr (string, '\n');
79
144
y = mi->xgwa.height + y;
81
y -= (fps_ascent + fps_descent);
146
y -= (st->ascent + st->descent);
138
203
/* clear the background */
141
206
int lines = L2 ? 2 : 1;
142
207
glColor3f (0, 0, 0);
143
glRecti (x / 2, y - fps_descent,
208
glRecti (x / 2, y - st->descent,
144
209
mi->xgwa.width - x,
145
y + lines * (fps_ascent + fps_descent));
210
y + lines * (st->ascent + st->descent));
148
213
/* draw the text */
149
214
glColor3f (1, 1, 1);
150
215
glRasterPos2f (x, y);
151
glListBase (font_dlist);
216
glListBase (st->font_dlist);
156
221
glCallLists (strlen(L2), GL_UNSIGNED_BYTE, L2);
157
glRasterPos2f (x, y + (fps_ascent + fps_descent));
222
glRasterPos2f (x, y + (st->ascent + st->descent));
158
223
glCallLists (L2 - string - 1, GL_UNSIGNED_BYTE, string);
184
249
fps_1 (ModeInfo *mi)
186
static Bool initted_p = False;
187
static int last_ifps = -1;
188
static GLfloat last_fps = -1;
189
static int frame_count = 0;
190
static struct timeval prev = { 0, 0 };
191
static struct timeval now = { 0, 0 };
251
struct fps_state *st = mi->fps_state;
197
strcpy (fps_string, "FPS: (accumulating...)");
256
strcpy (st->string, "FPS: (accumulating...)");
200
259
/* Every N frames (where N is approximately one second's worth of frames)
201
260
check the wall clock. We do this because checking the wall clock is
202
261
a slow operation.
204
if (frame_count++ >= last_ifps)
263
if (st->frame_count++ >= st->last_ifps)
206
265
# ifdef GETTIMEOFDAY_TWO_ARGS
207
266
struct timezone tzp;
208
gettimeofday(&now, &tzp);
267
gettimeofday(&st->now, &tzp);
269
gettimeofday(&st->now);
213
if (prev.tv_sec == 0)
272
if (st->prev.tv_sec == 0)
217
276
/* If we've probed the wall-clock time, regenerate the string.
219
if (now.tv_sec != prev.tv_sec)
278
if (st->now.tv_sec != st->prev.tv_sec)
221
double uprev = prev.tv_sec + ((double) prev.tv_usec * 0.000001);
222
double unow = now.tv_sec + ((double) now.tv_usec * 0.000001);
223
double fps = frame_count / (unow - uprev);
230
sprintf (fps_string, "FPS: %.02f", fps);
280
double uprev = st->prev.tv_sec + ((double) st->prev.tv_usec * 0.000001);
281
double unow = st->now.tv_sec + ((double) st->now.tv_usec * 0.000001);
282
double fps = st->frame_count / (unow - uprev);
289
sprintf (st->string, "FPS: %.02f", fps);
292
/* since there's no "-delay 0" in the Cocoa version,
293
don't bother mentioning the inter-frame delay. */
232
294
if (mi->pause != 0)
251
314
else if (p >= 2048) p >>= 10, s = "K";
254
strcat (fps_string, "\nPolys: ");
317
strcat (st->string, "\nPolys: ");
255
318
if (p >= 1000000)
256
sprintf (fps_string + strlen(fps_string), "%lu,%03lu,%03lu%s",
319
sprintf (st->string + strlen(st->string), "%lu,%03lu,%03lu%s",
257
320
(p / 1000000), ((p / 1000) % 1000), (p % 1000), s);
258
321
else if (p >= 1000)
259
sprintf (fps_string + strlen(fps_string), "%lu,%03lu%s",
322
sprintf (st->string + strlen(st->string), "%lu,%03lu%s",
260
323
(p / 1000), (p % 1000), s);
262
sprintf (fps_string + strlen(fps_string), "%lu%s", p, s);
325
sprintf (st->string + strlen(st->string), "%lu%s", p, s);
270
333
fps_2 (ModeInfo *mi)
272
fps_print_string (mi, fps_text_x, fps_text_y, fps_string);
335
struct fps_state *st = mi->fps_state;
336
fps_print_string (mi, st->x, st->y, st->string);