Added a triple buffer for video frame data to ensure clean transfer of that data between emulation and Qt GUI threads.

This commit is contained in:
mjbudd77 2021-12-13 21:16:53 -05:00
parent 74a48e92d6
commit c35b18751d
5 changed files with 32 additions and 12 deletions

View File

@ -464,16 +464,22 @@ double ConsoleViewGL_t::getAspectRatio(void)
void ConsoleViewGL_t::transfer2LocalBuffer(void)
{
int i=0, hq = 0;
int i=0, hq = 0, bufIdx;
int numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
unsigned int cpSize = numPixels * 4;
uint8_t *src, *dest;
bufIdx = nes_shm->pixBufIdx-1;
if ( bufIdx < 0 )
{
bufIdx = NES_VIDEO_BUFLEN-1;
}
if ( cpSize > localBufSize )
{
cpSize = localBufSize;
}
src = (uint8_t*)nes_shm->pixbuf;
src = (uint8_t*)nes_shm->pixbuf[bufIdx];
dest = (uint8_t*)localBuf;
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
@ -492,7 +498,7 @@ void ConsoleViewGL_t::transfer2LocalBuffer(void)
}
else
{
memcpy( localBuf, nes_shm->pixbuf, cpSize );
memcpy( localBuf, src, cpSize );
}
}

View File

@ -206,16 +206,22 @@ double ConsoleViewSDL_t::getAspectRatio(void)
void ConsoleViewSDL_t::transfer2LocalBuffer(void)
{
int i=0, hq = 0;
int i=0, hq = 0, bufIdx;
int numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
unsigned int cpSize = numPixels * 4;
uint8_t *src, *dest;
bufIdx = nes_shm->pixBufIdx-1;
if ( bufIdx < 0 )
{
bufIdx = NES_VIDEO_BUFLEN-1;
}
if ( cpSize > localBufSize )
{
cpSize = localBufSize;
}
src = (uint8_t*)nes_shm->pixbuf;
src = (uint8_t*)nes_shm->pixbuf[bufIdx];
dest = (uint8_t*)localBuf;
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
@ -234,7 +240,7 @@ void ConsoleViewSDL_t::transfer2LocalBuffer(void)
}
else
{
memcpy( localBuf, nes_shm->pixbuf, cpSize );
memcpy( localBuf, src, cpSize );
}
}

View File

@ -4253,16 +4253,16 @@ void consoleWin_t::transferVideoBuffer(void)
{
if ( nes_shm->blitUpdated )
{
nes_shm->blitUpdated = 0;
if ( viewport_SDL )
{
viewport_SDL->transfer2LocalBuffer();
nes_shm->blitUpdated = 0;
viewport_SDL->render();
}
else if ( viewport_GL )
{
viewport_GL->transfer2LocalBuffer();
nes_shm->blitUpdated = 0;
viewport_GL->update();
}
}

View File

@ -11,6 +11,7 @@
#define GL_NES_WIDTH 256
#define GL_NES_HEIGHT 240
#define NES_VIDEO_BUFLEN 3
#define NES_AUDIO_BUFLEN 480000
struct nes_shm_t
@ -35,7 +36,8 @@ struct nes_shm_t
char runEmulator;
char blitUpdated;
uint32_t pixbuf[1048576]; // 1024 x 1024
int pixBufIdx;
uint32_t pixbuf[NES_VIDEO_BUFLEN][1048576]; // 1024 x 1024
uint32_t avibuf[1048576]; // 1024 x 1024
void clear_pixbuf(void)

View File

@ -398,6 +398,9 @@ static void vsync_test(void)
int i, j, k, l;
int cycleLen, halfCycleLen;
static int ofs = 0;
uint32_t *pixbuf;
pixbuf = nes_shm->pixbuf[nes_shm->pixBufIdx];
cycleLen = nes_shm->video.ncol / 4;
@ -412,11 +415,11 @@ static void vsync_test(void)
if ( l < halfCycleLen )
{
nes_shm->pixbuf[k] = 0xffffffff; k++;
pixbuf[k] = 0xFFFFFFFF; k++;
}
else
{
nes_shm->pixbuf[k] = 0x00000000; k++;
pixbuf[k] = 0x00000000; k++;
}
}
}
@ -492,8 +495,11 @@ doBlitScreen(uint8_t *XBuf, uint8_t *dest)
void
BlitScreen(uint8 *XBuf)
{
doBlitScreen(XBuf, (uint8_t*)nes_shm->pixbuf);
int i = nes_shm->pixBufIdx;
doBlitScreen(XBuf, (uint8_t*)nes_shm->pixbuf[i]);
nes_shm->pixBufIdx = (i+1) % NES_VIDEO_BUFLEN;
nes_shm->blit_count++;
nes_shm->blitUpdated = 1;
}