diff options
Diffstat (limited to 'src/screen.c')
-rw-r--r-- | src/screen.c | 70 |
1 files changed, 39 insertions, 31 deletions
diff --git a/src/screen.c b/src/screen.c index 5e84038..86d829d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -5,10 +5,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <time.h> #include <pthread.h> -#include <unistd.h> -#include <signal.h> #define XLIB_ILLEGAL_ACCESS #include <X11/X.h> @@ -33,6 +30,8 @@ typedef struct { XImage** images; pthread_t update_thread; pthread_mutex_t recreate_lock; + pthread_mutex_t lock; + uint16_t update_rate; } WindowState; static void init_x() { @@ -173,7 +172,6 @@ void swapchain_next(Swapchain* swapchain) { next += 1; next %= 3; } - swapchain->image_current = next; pthread_mutex_unlock(&swapchain->lock); } @@ -184,28 +182,54 @@ void swapchain_submit(Swapchain* swapchain) { pthread_mutex_unlock(&swapchain->lock); } +static long get_time() { + struct timespec spec; + clock_gettime(CLOCK_MONOTONIC, &spec); + return round(spec.tv_nsec / 1.0e6) + spec.tv_sec * 1000; +} + +static void update_delta(float* delta, long* last) { + long now = get_time(); + if (*last == 0) { + *delta = 0; + } else { + *delta = (now - *last) / 1000.0; + } + *last = now; +} + static void* swapchain_thread(void* arg) { struct Screen* screen = (struct Screen*) arg; WindowState* state = (WindowState*) screen->internal; + long last = get_time(); + float delta; + while (1) { if (screen->swapchain.images == NULL) { return NULL; } + + long now = last; + update_delta(&delta, &now); + if (delta < 1.0 / state->update_rate) { + continue; + } else { + last = now; + } pthread_mutex_lock(&state->recreate_lock); pthread_mutex_lock(&screen->swapchain.lock); - int index = screen->swapchain.image_recent; - screen->swapchain.image_front = index; + screen->swapchain.image_front = screen->swapchain.image_recent; pthread_mutex_unlock(&screen->swapchain.lock); XPutImage( dpy, state->window, state->graphics_ctx, - state->images[index], + state->images[screen->swapchain.image_front], 0, 0, 0, 0, screen->swapchain.width, screen->swapchain.height @@ -213,8 +237,6 @@ static void* swapchain_thread(void* arg) { XSync(dpy, 0); pthread_mutex_unlock(&state->recreate_lock); - - usleep(1000 * 1000 / 60); } return NULL; @@ -222,7 +244,7 @@ static void* swapchain_thread(void* arg) { #define FRAMES 3 -void init_screen(struct Screen* screen, uint16_t width, uint16_t height, const char* title) { +void init_screen(struct Screen* screen, uint16_t width, uint16_t height, const char* title, uint16_t update_rate) { if (dpy == NULL) { init_x(); @@ -233,6 +255,7 @@ void init_screen(struct Screen* screen, uint16_t width, uint16_t height, const c WindowState* state = malloc(sizeof(WindowState)); state->window = window; + state->update_rate = update_rate; screen->swapchain = create_swapchain(width, height, FRAMES, bit_depth, state); pthread_create(&state->update_thread, NULL, &swapchain_thread, screen); @@ -242,23 +265,6 @@ void init_screen(struct Screen* screen, uint16_t width, uint16_t height, const c count++; } -static long get_time() { - struct timespec spec; - clock_gettime(CLOCK_MONOTONIC, &spec); - return round(spec.tv_nsec / 1.0e6) + spec.tv_sec * 1000; -} - -static long last = 0; - -static void update_delta(struct Screen* screen) { - long now = get_time(); - if (last == 0) { - screen->delta = 0; - } else { - screen->delta = (now - last) / 1000.0; - } - last = now; -} static void handle_event(struct Screen* screen) { XEvent event; @@ -291,11 +297,11 @@ static void handle_event(struct Screen* screen) { } bool poll_screen(struct Screen* screen) { - while (XPending(dpy)) handle_event(screen); - update_delta(screen); + static long last = 0; + update_delta(&screen->delta, &last); return true; } @@ -320,13 +326,15 @@ void free_screen(struct Screen* screen) { } } -bool key_pressed(int keycode) { +bool key_pressed(int code) { + int keycode = code - dpy->min_keycode; if (key_checked[keycode]) return false; if (!key_state[keycode]) return false; key_checked[keycode] = true; return true; } -bool key_down(int keycode) { +bool key_down(int code) { + int keycode = code - dpy->min_keycode; return key_state[keycode]; } |