From 83e1f03e229e0e29da82239950143940a9488770 Mon Sep 17 00:00:00 2001 From: Shaun Inman Date: Thu, 5 Jan 2023 23:56:55 -0500 Subject: [PATCH] I made it worse somehow the threaded version is as janky as the pre-waitforvsync version --- src/common/api.c | 106 +++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 64 deletions(-) diff --git a/src/common/api.c b/src/common/api.c index 3ff0c83..676cb24 100644 --- a/src/common/api.c +++ b/src/common/api.c @@ -135,31 +135,23 @@ static struct GFX_Context { static pthread_t flip_pt; static pthread_mutex_t flip_mx; static pthread_cond_t flip_req; -static pthread_cond_t flip_start; static volatile uint32_t now_flipping; +static int flip_y = 0; static void* flip_thread(void* param) { - int arg = 0; - int y_offset = 0; + int last_y = 0; pthread_mutex_lock(&flip_mx); while (1) { - while (!now_flipping) { - puts("waiting for flip request..."); - pthread_cond_wait(&flip_req, &flip_mx); - } - do { - y_offset = gfx.vinfo.yoffset + SCREEN_HEIGHT; - if (y_offset==GFX_BUFFER_COUNT*SCREEN_HEIGHT) y_offset = 0; - gfx.vinfo.yoffset = y_offset; - - printf("perform flip: %i (%i)\n", y_offset / SCREEN_HEIGHT, now_flipping); - - pthread_cond_signal(&flip_start); + pthread_cond_wait(&flip_req, &flip_mx); + if (flip_y!=last_y) { pthread_mutex_unlock(&flip_mx); - ioctl(gfx.fb, FBIO_WAITFORVSYNC, &arg); // TODO: disable this when fast forwarding? + gfx.vinfo.yoffset = flip_y; + last_y = flip_y; + int arg = 0; + ioctl(gfx.fb, FBIO_WAITFORVSYNC, &arg); // TODO: disable this when fast forwarding ioctl(gfx.fb, FBIOPAN_DISPLAY, &gfx.vinfo); pthread_mutex_lock(&flip_mx); - } while (--now_flipping); + } } return NULL; } @@ -332,9 +324,8 @@ SDL_Surface* GFX_init(void) { flip_mx = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; flip_req = (pthread_cond_t)PTHREAD_COND_INITIALIZER; - flip_start = (pthread_cond_t)PTHREAD_COND_INITIALIZER; now_flipping = 0; - // pthread_create(&flip_pt, NULL, flip_thread, NULL); + pthread_create(&flip_pt, NULL, flip_thread, NULL); // return screen gfx.screen = SDL_CreateRGBSurfaceFrom(gfx.map + gfx.buffer_size, SCREEN_WIDTH,SCREEN_HEIGHT, SCREEN_DEPTH,SCREEN_PITCH, 0,0,0,0); @@ -348,56 +339,43 @@ void GFX_clearAll(void) { } void GFX_flip(SDL_Surface* screen) { - // pthread_mutex_lock(&flip_mx); - // while (now_flipping==2) { - // puts("waiting for flip to complete..."); - // pthread_cond_wait(&flip_start, &flip_mx); - // } - // - // gfx.buffer += 1; - // if (gfx.buffer>=GFX_BUFFER_COUNT) gfx.buffer -= GFX_BUFFER_COUNT; - // screen->pixels = gfx.map + (gfx.buffer * gfx.buffer_size); - // - // printf("request flip: %i (%i)\n", gfx.buffer, now_flipping); - // - // if (!now_flipping) { - // now_flipping = 1; - // pthread_cond_signal(&flip_req); - // pthread_cond_wait(&flip_start, &flip_mx); - // } else { - // now_flipping = 2; - // } - // - // pthread_mutex_unlock(&flip_mx); + pthread_mutex_lock(&flip_mx); + flip_y = gfx.buffer * SCREEN_HEIGHT; + pthread_cond_signal(&flip_req); + pthread_mutex_unlock(&flip_mx); - // struct fb_vblank vblank; - // ioctl(gfx.fb, FBIOGET_VBLANK, &vblank); - // printf("flags: %i\n", vblank.flags); - // printf("count: %i\n", vblank.count); - // printf("vcount: %i\n", vblank.vcount); - // printf("hcount: %i\n", vblank.hcount); -#ifdef GFX_ENABLE_VSYNC - int arg = 1; - ioctl(gfx.fb, OWLFB_WAITFORVSYNC, &arg); // TODO: this doesn't wait but it also doesn't error out like FBIO_WAITFORVSYNC... -#endif - -#ifdef GFX_ENABLE_BUFFER - // TODO: this would be moved to a thread - // I'm not clear on why that would be necessary - // if it's non-blocking and the pan will wait - // until the next vblank... - // what if the scaling was also moved to a thread? - gfx.vinfo.yoffset = gfx.buffer * SCREEN_HEIGHT; - ioctl(gfx.fb, FBIOPAN_DISPLAY, &gfx.vinfo); - gfx.buffer += 1; if (gfx.buffer>=GFX_BUFFER_COUNT) gfx.buffer -= GFX_BUFFER_COUNT; - screen->pixels = gfx.map + (gfx.buffer * gfx.buffer_size); -#endif + screen->pixels = gfx.map + (gfx.buffer * gfx.buffer_size); + +// // struct fb_vblank vblank; +// // ioctl(gfx.fb, FBIOGET_VBLANK, &vblank); +// // printf("flags: %i\n", vblank.flags); +// // printf("count: %i\n", vblank.count); +// // printf("vcount: %i\n", vblank.vcount); +// // printf("hcount: %i\n", vblank.hcount); +// #ifdef GFX_ENABLE_VSYNC +// int arg = 1; +// ioctl(gfx.fb, OWLFB_WAITFORVSYNC, &arg); // TODO: this doesn't wait but it also doesn't error out like FBIO_WAITFORVSYNC... +// #endif +// +// #ifdef GFX_ENABLE_BUFFER +// // TODO: this would be moved to a thread +// // I'm not clear on why that would be necessary +// // if it's non-blocking and the pan will wait +// // until the next vblank... +// // what if the scaling was also moved to a thread? +// gfx.vinfo.yoffset = gfx.buffer * SCREEN_HEIGHT; +// ioctl(gfx.fb, FBIOPAN_DISPLAY, &gfx.vinfo); +// +// gfx.buffer += 1; +// if (gfx.buffer>=GFX_BUFFER_COUNT) gfx.buffer -= GFX_BUFFER_COUNT; +// screen->pixels = gfx.map + (gfx.buffer * gfx.buffer_size); +// #endif } void GFX_quit(void) { - // pthread_cancel(flip_pt); - // pthread_join(flip_pt, NULL); + pthread_cancel(flip_pt); + pthread_join(flip_pt, NULL); GFX_clearAll(); munmap(gfx.map, gfx.map_size);