--- /dev/null
+CC ?= gcc
+CFLAGS ?= -g -Wall -Wextra -Wmissing-declarations
+
+libglfps.so: glfps.c
+ $(CC) $(CFLAGS) -fPIC -shared -Wl,-Bsymbolic -o $@ $<
+
+clean:
+ rm -f libglfps.so
--- /dev/null
+#define _GNU_SOURCE /* For RTLD_NEXT */
+#include <dlfcn.h>
+
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+#include <sys/time.h>
+
+/* How many frames between reports. */
+#define REPORT_FREQ 60
+
+static void
+on_each_frame (void)
+{
+ static int count = 0;
+ static struct timeval tv_last;
+ struct timeval tv_now;
+
+ if ((count % REPORT_FREQ) == 0) {
+ gettimeofday (&tv_now, NULL);
+ if (count == 0) {
+ printf ("glfps: Initializing FPS timer\n");
+ } else {
+ double elapsed = ((tv_now.tv_sec - tv_last.tv_sec) +
+ (tv_now.tv_usec - tv_last.tv_usec) / 1e6);
+ printf ("FPS: %.3f\n", ((double) REPORT_FREQ) / elapsed);
+ }
+ tv_last = tv_now;
+ }
+
+ count++;
+}
+
+void
+glXSwapBuffers (Display *dpy, GLXDrawable drawable)
+{
+ static typeof(&glXSwapBuffers) real_glXSwapBuffers = NULL;
+
+ if (real_glXSwapBuffers == NULL)
+ real_glXSwapBuffers = dlsym (RTLD_NEXT, "glXSwapBuffers");
+
+ on_each_frame ();
+
+ real_glXSwapBuffers (dpy, drawable);
+}