I made it worse somehow
the threaded version is as janky as the pre-waitforvsync version
This commit is contained in:
parent
473af67f51
commit
83e1f03e22
1 changed files with 42 additions and 64 deletions
106
src/common/api.c
106
src/common/api.c
|
|
@ -135,31 +135,23 @@ static struct GFX_Context {
|
||||||
static pthread_t flip_pt;
|
static pthread_t flip_pt;
|
||||||
static pthread_mutex_t flip_mx;
|
static pthread_mutex_t flip_mx;
|
||||||
static pthread_cond_t flip_req;
|
static pthread_cond_t flip_req;
|
||||||
static pthread_cond_t flip_start;
|
|
||||||
static volatile uint32_t now_flipping;
|
static volatile uint32_t now_flipping;
|
||||||
|
static int flip_y = 0;
|
||||||
|
|
||||||
static void* flip_thread(void* param) {
|
static void* flip_thread(void* param) {
|
||||||
int arg = 0;
|
int last_y = 0;
|
||||||
int y_offset = 0;
|
|
||||||
pthread_mutex_lock(&flip_mx);
|
pthread_mutex_lock(&flip_mx);
|
||||||
while (1) {
|
while (1) {
|
||||||
while (!now_flipping) {
|
pthread_cond_wait(&flip_req, &flip_mx);
|
||||||
puts("waiting for flip request...");
|
if (flip_y!=last_y) {
|
||||||
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_mutex_unlock(&flip_mx);
|
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);
|
ioctl(gfx.fb, FBIOPAN_DISPLAY, &gfx.vinfo);
|
||||||
pthread_mutex_lock(&flip_mx);
|
pthread_mutex_lock(&flip_mx);
|
||||||
} while (--now_flipping);
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -332,9 +324,8 @@ SDL_Surface* GFX_init(void) {
|
||||||
|
|
||||||
flip_mx = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
|
flip_mx = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
|
||||||
flip_req = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
|
flip_req = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
|
||||||
flip_start = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
|
|
||||||
now_flipping = 0;
|
now_flipping = 0;
|
||||||
// pthread_create(&flip_pt, NULL, flip_thread, NULL);
|
pthread_create(&flip_pt, NULL, flip_thread, NULL);
|
||||||
|
|
||||||
// return screen
|
// return screen
|
||||||
gfx.screen = SDL_CreateRGBSurfaceFrom(gfx.map + gfx.buffer_size, SCREEN_WIDTH,SCREEN_HEIGHT, SCREEN_DEPTH,SCREEN_PITCH, 0,0,0,0);
|
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) {
|
void GFX_flip(SDL_Surface* screen) {
|
||||||
// pthread_mutex_lock(&flip_mx);
|
pthread_mutex_lock(&flip_mx);
|
||||||
// while (now_flipping==2) {
|
flip_y = gfx.buffer * SCREEN_HEIGHT;
|
||||||
// puts("waiting for flip to complete...");
|
pthread_cond_signal(&flip_req);
|
||||||
// pthread_cond_wait(&flip_start, &flip_mx);
|
pthread_mutex_unlock(&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);
|
|
||||||
|
|
||||||
// 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;
|
gfx.buffer += 1;
|
||||||
if (gfx.buffer>=GFX_BUFFER_COUNT) gfx.buffer -= GFX_BUFFER_COUNT;
|
if (gfx.buffer>=GFX_BUFFER_COUNT) gfx.buffer -= GFX_BUFFER_COUNT;
|
||||||
screen->pixels = gfx.map + (gfx.buffer * gfx.buffer_size);
|
screen->pixels = gfx.map + (gfx.buffer * gfx.buffer_size);
|
||||||
#endif
|
|
||||||
|
// // 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) {
|
void GFX_quit(void) {
|
||||||
// pthread_cancel(flip_pt);
|
pthread_cancel(flip_pt);
|
||||||
// pthread_join(flip_pt, NULL);
|
pthread_join(flip_pt, NULL);
|
||||||
|
|
||||||
GFX_clearAll();
|
GFX_clearAll();
|
||||||
munmap(gfx.map, gfx.map_size);
|
munmap(gfx.map, gfx.map_size);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue