From 1d2f521e0bc600737e319eb26c5d7d25eee79bc7 Mon Sep 17 00:00:00 2001 From: Aaron Culliney Date: Sat, 24 Nov 2018 15:16:38 -0800 Subject: [PATCH] Fix graphics tearing and stuttering for disk images that sync to video scanner - Use a second framebuffer to avoid tearing - Occasionally stall graphics thread for ~4ms until CPU thread (video scanner) completes drawing a frame - These fixes seem to essentially fix graphics issues with Dagen Brock's Flappie Bird (flapple140.po.gz disk image) --- src/display.c | 4 +++- src/video/glvideo.c | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/display.c b/src/display.c index d2611784..c28fbda6 100644 --- a/src/display.c +++ b/src/display.c @@ -73,6 +73,7 @@ static PIXEL_TYPE *general_colors[NUM_COLOROPTS] = { 0 }; #define FB_SIZ (SCANWIDTH*SCANHEIGHT) static PIXEL_TYPE fbFull[FB_SIZ + (SCANWIDTH<<1)] = { 0 }; // HACK NOTE: extra scanlines used for sampling +static PIXEL_TYPE fbDone[FB_SIZ] = { 0 }; // ---------------------------------------------------------------------------- // Initialization routines @@ -956,7 +957,7 @@ void display_flashText(void) { } PIXEL_TYPE *display_getCurrentFramebuffer(void) { - return fbFull; + return fbDone; } void display_flushScanline(scan_data_t *scandata) { @@ -996,6 +997,7 @@ void display_frameComplete(void) { SCOPE_TRACE_CPU("frameComplete"); + memcpy(/*dst:*/fbDone, /*src:*/fbFull, sizeof(fbDone)); video_setDirty(FB_DIRTY_FLAG); #if TESTING diff --git a/src/video/glvideo.c b/src/video/glvideo.c index 4541d690..7fbf0fba 100644 --- a/src/video/glvideo.c +++ b/src/video/glvideo.c @@ -13,6 +13,7 @@ #include +// HACK NOTE : display.c "fbDone" buffer is the crtModel->texPixels to avoid a memcpy #define FB_PIXELS_PASS_THRU 1 static int viewportX = 0; @@ -331,11 +332,25 @@ static void glvideo_render(void) { glUniformMatrix4fv(uniformMVPIdx, 1, GL_FALSE, mvpIdentity); #endif - unsigned long wasDirty = (video_clearDirty(FB_DIRTY_FLAG) & FB_DIRTY_FLAG); - glActiveTexture(TEXTURE_ACTIVE_FRAMEBUFFER); glBindTexture(GL_TEXTURE_2D, crtModel->textureName); glUniform1i(texSamplerLoc, TEXTURE_ID_FRAMEBUFFER); + + unsigned long wasDirty = (video_clearDirty(FB_DIRTY_FLAG) & FB_DIRTY_FLAG); + if (!wasDirty) { + // Framebuffer is not dirty, so stall here to wait for cpu thread to (potentially) complete the video frame ... + // This seems to improve "stuttering" of Dagen Brock's Flappy Bird + SCOPE_TRACE_VIDEO("sleep"); + + struct timespec deltat = { + .tv_sec = 0, + .tv_nsec = NANOSECONDS_PER_SECOND / 240, + }; + nanosleep(&deltat, NULL); // approx 4.714ms + + wasDirty = (video_clearDirty(FB_DIRTY_FLAG) & FB_DIRTY_FLAG); + } + if (wasDirty) { SCOPE_TRACE_VIDEO("glvideo texImage2D"); _HACKAROUND_GLTEXIMAGE2D_PRE(TEXTURE_ACTIVE_FRAMEBUFFER, crtModel->textureName);