From 5d5875499f8f471d8748b6e04c1438edc9963bb9 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Thu, 11 May 2017 16:48:57 -0400 Subject: add fps timer, openmp --- Makefile | 4 ++-- main.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 46cebbd..f0f7b3a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -CFLAGS=-std=c11 -W -Wall -pedantic -O2 +CFLAGS=-std=c11 -fopenmp -W -Wall -pedantic -O2 APP=compute-test -LIBS=-lSDL2 -lGLEW -lGL +LIBS=-fopenmp -lSDL2 -lGLEW -lGL OBJS=main.o .PHONY=all clean test diff --git a/main.c b/main.c index 79a9d58..76811ec 100644 --- a/main.c +++ b/main.c @@ -7,6 +7,12 @@ #define UNUSED(a) ((void) (a)) +// number of time records to keep (must be power of two - 1) +#define MAX_TIMES 0xFF + +// custom SDL_USEREVENT code for timer +#define EVENT_CODE_TIMER 0 + static const float verts[] = { -0.5, 0.5, 0, @@ -112,7 +118,7 @@ link_compute_program( static SDL_Window * init(void) { - if (SDL_Init(SDL_INIT_VIDEO) < 0) { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { SDL_Log("SDL_Init() failed: %s", SDL_GetError()); exit(EXIT_FAILURE); } @@ -182,12 +188,42 @@ init(void) { return win; } +static Uint32 timer_cb( + Uint32 interval, + void *arg +) { + SDL_Event ev; + UNUSED(arg); + + ev.type = SDL_USEREVENT; + ev.user.type = SDL_USEREVENT; + ev.user.code = EVENT_CODE_TIMER; + ev.user.data1 = NULL; + ev.user.data2 = NULL; + + SDL_PushEvent(&ev); + + // return interval + return interval; +} + int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); + // init SDL SDL_Window *win = init(); + // init times ring buffer + struct { + uint32_t draw_start, + draw_end; + } times[MAX_TIMES] = { { 0, 0 } }; + uint32_t times_ofs = 0; + + // init timer (5 seconds) + SDL_TimerID timer_id = SDL_AddTimer(5000, timer_cb, NULL); + // generate vertex array GLuint vao; glGenVertexArrays(1, &vao); @@ -209,16 +245,24 @@ int main(int argc, char *argv[]) { GLuint prog = link_render_program(vs_src, fs_src); GLint u_time = glGetUniformLocation(prog, "time"); - // main loop + // init flags bool done = false, fullscreen = false; + + // main loop while (!done) { + // get start time + uint32_t now = SDL_GetTicks(); + + // save start time + times[times_ofs].draw_start = now; + // clear screen glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); // use program, set uniform glUseProgram(prog); - glUniform1f(u_time, SDL_GetTicks() / 1000.0); + glUniform1f(u_time, now / 1000.0); // draw glBindVertexArray(vao); @@ -228,6 +272,10 @@ int main(int argc, char *argv[]) { // swap buffer SDL_GL_SwapWindow(win); + // save end time + times[times_ofs].draw_end = SDL_GetTicks(); + times_ofs = (times_ofs + 1) & MAX_TIMES; + // handle events { SDL_Event ev; @@ -267,12 +315,37 @@ int main(int argc, char *argv[]) { break; } + break; + case SDL_USEREVENT: + if (ev.user.code == EVENT_CODE_TIMER) { + uint32_t sum = 0; + + #pragma omp parallel for reduction(+:sum) + for (int i = 0; i < MAX_TIMES; i++) { + sum += times[i].draw_end - times[i].draw_start; + } + + // print fps + SDL_Log("fps: %f", sum * 1.0 / MAX_TIMES); + } + break; } } } } + // remove timer + if (SDL_RemoveTimer(timer_id) == SDL_FALSE) { + SDL_Log("SDL_RemoveTimer() failed"); + } + + // delete GL context + SDL_GLContext context = SDL_GL_GetCurrentContext(); + if (context) { + SDL_GL_DeleteContext(context); + } + // destroy window SDL_DestroyWindow(win); -- cgit v1.2.3