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:
parent
74a48e92d6
commit
c35b18751d
|
@ -464,16 +464,22 @@ double ConsoleViewGL_t::getAspectRatio(void)
|
||||||
|
|
||||||
void ConsoleViewGL_t::transfer2LocalBuffer(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;
|
int numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
|
||||||
unsigned int cpSize = numPixels * 4;
|
unsigned int cpSize = numPixels * 4;
|
||||||
uint8_t *src, *dest;
|
uint8_t *src, *dest;
|
||||||
|
|
||||||
|
bufIdx = nes_shm->pixBufIdx-1;
|
||||||
|
|
||||||
|
if ( bufIdx < 0 )
|
||||||
|
{
|
||||||
|
bufIdx = NES_VIDEO_BUFLEN-1;
|
||||||
|
}
|
||||||
if ( cpSize > localBufSize )
|
if ( cpSize > localBufSize )
|
||||||
{
|
{
|
||||||
cpSize = localBufSize;
|
cpSize = localBufSize;
|
||||||
}
|
}
|
||||||
src = (uint8_t*)nes_shm->pixbuf;
|
src = (uint8_t*)nes_shm->pixbuf[bufIdx];
|
||||||
dest = (uint8_t*)localBuf;
|
dest = (uint8_t*)localBuf;
|
||||||
|
|
||||||
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
|
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
|
||||||
|
@ -492,7 +498,7 @@ void ConsoleViewGL_t::transfer2LocalBuffer(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy( localBuf, nes_shm->pixbuf, cpSize );
|
memcpy( localBuf, src, cpSize );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,16 +206,22 @@ double ConsoleViewSDL_t::getAspectRatio(void)
|
||||||
|
|
||||||
void ConsoleViewSDL_t::transfer2LocalBuffer(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;
|
int numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
|
||||||
unsigned int cpSize = numPixels * 4;
|
unsigned int cpSize = numPixels * 4;
|
||||||
uint8_t *src, *dest;
|
uint8_t *src, *dest;
|
||||||
|
|
||||||
|
bufIdx = nes_shm->pixBufIdx-1;
|
||||||
|
|
||||||
|
if ( bufIdx < 0 )
|
||||||
|
{
|
||||||
|
bufIdx = NES_VIDEO_BUFLEN-1;
|
||||||
|
}
|
||||||
if ( cpSize > localBufSize )
|
if ( cpSize > localBufSize )
|
||||||
{
|
{
|
||||||
cpSize = localBufSize;
|
cpSize = localBufSize;
|
||||||
}
|
}
|
||||||
src = (uint8_t*)nes_shm->pixbuf;
|
src = (uint8_t*)nes_shm->pixbuf[bufIdx];
|
||||||
dest = (uint8_t*)localBuf;
|
dest = (uint8_t*)localBuf;
|
||||||
|
|
||||||
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
|
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
|
||||||
|
@ -234,7 +240,7 @@ void ConsoleViewSDL_t::transfer2LocalBuffer(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy( localBuf, nes_shm->pixbuf, cpSize );
|
memcpy( localBuf, src, cpSize );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4253,16 +4253,16 @@ void consoleWin_t::transferVideoBuffer(void)
|
||||||
{
|
{
|
||||||
if ( nes_shm->blitUpdated )
|
if ( nes_shm->blitUpdated )
|
||||||
{
|
{
|
||||||
|
nes_shm->blitUpdated = 0;
|
||||||
|
|
||||||
if ( viewport_SDL )
|
if ( viewport_SDL )
|
||||||
{
|
{
|
||||||
viewport_SDL->transfer2LocalBuffer();
|
viewport_SDL->transfer2LocalBuffer();
|
||||||
nes_shm->blitUpdated = 0;
|
|
||||||
viewport_SDL->render();
|
viewport_SDL->render();
|
||||||
}
|
}
|
||||||
else if ( viewport_GL )
|
else if ( viewport_GL )
|
||||||
{
|
{
|
||||||
viewport_GL->transfer2LocalBuffer();
|
viewport_GL->transfer2LocalBuffer();
|
||||||
nes_shm->blitUpdated = 0;
|
|
||||||
viewport_GL->update();
|
viewport_GL->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#define GL_NES_WIDTH 256
|
#define GL_NES_WIDTH 256
|
||||||
#define GL_NES_HEIGHT 240
|
#define GL_NES_HEIGHT 240
|
||||||
|
#define NES_VIDEO_BUFLEN 3
|
||||||
#define NES_AUDIO_BUFLEN 480000
|
#define NES_AUDIO_BUFLEN 480000
|
||||||
|
|
||||||
struct nes_shm_t
|
struct nes_shm_t
|
||||||
|
@ -35,7 +36,8 @@ struct nes_shm_t
|
||||||
char runEmulator;
|
char runEmulator;
|
||||||
char blitUpdated;
|
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
|
uint32_t avibuf[1048576]; // 1024 x 1024
|
||||||
|
|
||||||
void clear_pixbuf(void)
|
void clear_pixbuf(void)
|
||||||
|
|
|
@ -398,6 +398,9 @@ static void vsync_test(void)
|
||||||
int i, j, k, l;
|
int i, j, k, l;
|
||||||
int cycleLen, halfCycleLen;
|
int cycleLen, halfCycleLen;
|
||||||
static int ofs = 0;
|
static int ofs = 0;
|
||||||
|
uint32_t *pixbuf;
|
||||||
|
|
||||||
|
pixbuf = nes_shm->pixbuf[nes_shm->pixBufIdx];
|
||||||
|
|
||||||
cycleLen = nes_shm->video.ncol / 4;
|
cycleLen = nes_shm->video.ncol / 4;
|
||||||
|
|
||||||
|
@ -412,11 +415,11 @@ static void vsync_test(void)
|
||||||
|
|
||||||
if ( l < halfCycleLen )
|
if ( l < halfCycleLen )
|
||||||
{
|
{
|
||||||
nes_shm->pixbuf[k] = 0xffffffff; k++;
|
pixbuf[k] = 0xFFFFFFFF; k++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nes_shm->pixbuf[k] = 0x00000000; k++;
|
pixbuf[k] = 0x00000000; k++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,8 +495,11 @@ doBlitScreen(uint8_t *XBuf, uint8_t *dest)
|
||||||
void
|
void
|
||||||
BlitScreen(uint8 *XBuf)
|
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->blit_count++;
|
||||||
nes_shm->blitUpdated = 1;
|
nes_shm->blitUpdated = 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue