linuxOS_AP05/buildroot/package/retroarch/libretro-fbalpha/0001-pgm-Support-threaded-draw-and-bind-it-to-cpu-0.patch

255 lines
7.1 KiB
Diff
Raw Normal View History

2025-06-02 05:59:07 +00:00
From 4bcf194c5017d4f2af2025a6b22f14e8d1c8cacc Mon Sep 17 00:00:00 2001
From: Jeffy Chen <jeffy.chen@rock-chips.com>
Date: Mon, 29 Oct 2018 09:54:50 +0800
Subject: [PATCH] pgm: Support threaded draw, and bind it to cpu 0
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
makefile.libretro_common | 6 ++
src/burn/drv/pgm/pgm.h | 22 +++++++
src/burn/drv/pgm/pgm_draw.cpp | 13 ++++
src/burn/drv/pgm/pgm_run.cpp | 133 +++++++++++++++++++++++++++++++++++++++
src/burner/libretro/libretro.cpp | 4 +-
5 files changed, 177 insertions(+), 1 deletion(-)
diff --git a/makefile.libretro_common b/makefile.libretro_common
index b7b2850..28b0beb 100644
--- a/makefile.libretro_common
+++ b/makefile.libretro_common
@@ -315,3 +315,9 @@ GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
ifneq ($(GIT_VERSION)," unknown")
CXXFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
endif
+
+ENABLE_PGM_THREADED_DRAW = 1
+ifeq ($(ENABLE_PGM_THREADED_DRAW),1)
+ FBA_DEFINES += -DPGM_THREADED_DRAW
+ LDFLAGS += -lpthread
+endif
diff --git a/src/burn/drv/pgm/pgm.h b/src/burn/drv/pgm/pgm.h
index 5927233..7d83d85 100644
--- a/src/burn/drv/pgm/pgm.h
+++ b/src/burn/drv/pgm/pgm.h
@@ -6,6 +6,28 @@
#define HARDWARE_IGS_JAMMAPCB 0x0002
+// threaded pgm draw
+#ifdef PGM_THREADED_DRAW
+
+/* Mirror memory for pgmDraw() */
+struct PGM_DRAW_CONTEXT {
+ /* Sizes come from pgm_run.cpp:pgmMemIndex() */
+ UINT32 PGMBgRAM[0x0001000 / 4];
+ UINT32 PGMTxtRAM[0x0002000 / 4];
+ UINT16 PGMRowRAM[0x0001000 / 2];
+ UINT16 PGMPalRAM[0x0001400 / 2];
+ UINT16 PGMVidReg[0x0010000 / 2];
+ UINT16 PGMSprBuf[0x0000a00 / 2];
+ UINT32 RamCurPal[0x0001204 / 2];
+
+ UINT8 *pBurnDraw;
+ volatile int nDirty;
+};
+
+extern struct PGM_DRAW_CONTEXT PgmDrawCtx;
+
+#endif // PGM_THREADED_DRAW
+
// pgm_run
extern INT32 nPGM68KROMLen;
extern INT32 nPGMSPRColMaskLen;
diff --git a/src/burn/drv/pgm/pgm_draw.cpp b/src/burn/drv/pgm/pgm_draw.cpp
index bbf070c..604f01a 100644
--- a/src/burn/drv/pgm/pgm_draw.cpp
+++ b/src/burn/drv/pgm/pgm_draw.cpp
@@ -1,6 +1,19 @@
#include "pgm.h"
#include "pgm_sprite.h"
+#ifdef PGM_THREADED_DRAW
+
+/* Redirect to mirror draw ctx */
+#define PGMBgRAM PgmDrawCtx.PGMBgRAM
+#define PGMTxtRAM PgmDrawCtx.PGMTxtRAM
+#define PGMRowRAM PgmDrawCtx.PGMRowRAM
+#define PGMPalRAM PgmDrawCtx.PGMPalRAM
+#define PGMVidReg PgmDrawCtx.PGMVidReg
+#define PGMSprBuf PgmDrawCtx.PGMSprBuf
+#define RamCurPal PgmDrawCtx.RamCurPal
+
+#endif
+
//#define DUMP_SPRITE_BITMAPS
//#define DRAW_SPRITE_NUMBER
diff --git a/src/burn/drv/pgm/pgm_run.cpp b/src/burn/drv/pgm/pgm_run.cpp
index cf8ab4d..30db0ea 100644
--- a/src/burn/drv/pgm/pgm_run.cpp
+++ b/src/burn/drv/pgm/pgm_run.cpp
@@ -4,6 +4,139 @@
#include "ics2115.h"
#include "timer.h"
+#ifdef PGM_THREADED_DRAW
+
+#include <pthread.h>
+#include <sched.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#define gettid() syscall(SYS_gettid)
+
+#define PGM_DRAW_SIZE (nScreenWidth * nScreenHeight * sizeof(UINT32))
+
+struct PGM_DRAW_CONTEXT PgmDrawCtx;
+static struct PGM_DRAW_CONTEXT PgmTempDrawCtx;
+
+static pthread_t PgmDrawThread;
+static volatile int PgmDrawThreadExit = 0;
+
+static pthread_mutex_t PgmDrawMutex;
+static pthread_mutex_t PgmBurnDrawMutex;
+
+static inline void pgmInitDrawReal() { pgmInitDraw(); }
+static inline void pgmExitDrawReal() { pgmExitDraw(); }
+static inline void pgmDrawReal() { pgmDraw(); }
+#define pgmInitDraw() pgmInitThreadDraw()
+#define pgmExitDraw() pgmExitThreadDraw()
+#define pgmDraw() pgmThreadedDraw()
+
+extern void *pBurnDrawCustom;
+
+static void pgmThreadedDraw()
+{
+ pthread_mutex_lock(&PgmDrawMutex);
+
+ // Update mirror memory.
+#define PGM_COPY_CTX(ctx, area) memcpy(ctx.area, area, sizeof(ctx.area))
+ PGM_COPY_CTX(PgmTempDrawCtx, PGMBgRAM);
+ PGM_COPY_CTX(PgmTempDrawCtx, PGMTxtRAM);
+ PGM_COPY_CTX(PgmTempDrawCtx, PGMRowRAM);
+ PGM_COPY_CTX(PgmTempDrawCtx, PGMPalRAM);
+ PGM_COPY_CTX(PgmTempDrawCtx, PGMVidReg);
+ PGM_COPY_CTX(PgmTempDrawCtx, PGMSprBuf);
+ PGM_COPY_CTX(PgmTempDrawCtx, RamCurPal);
+
+ PgmTempDrawCtx.nDirty = 1;
+ pthread_mutex_unlock(&PgmDrawMutex);
+
+ // Update pBurnDrawCustom.
+ pthread_mutex_lock(&PgmBurnDrawMutex);
+ memcpy(pBurnDrawCustom, PgmTempDrawCtx.pBurnDraw, PGM_DRAW_SIZE);
+ pthread_mutex_unlock(&PgmBurnDrawMutex);
+}
+
+/* Try to bind draw thread to the cpu 0. */
+static void pgm_draw_thread_bind_cpu()
+{
+ int i;
+ cpu_set_t mask;
+
+ CPU_ZERO(&mask);
+ CPU_SET(0, &mask);
+
+ if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
+ perror("pthread_setaffinity_np");
+
+ if (pthread_getaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
+ perror("pthread_getaffinity_np");
+
+ printf("Thread(%ld) bound to cpu:", gettid());
+ for (i = 0; i < CPU_SETSIZE; i++) {
+ if (CPU_ISSET(i, &mask))
+ printf(" %d", i);
+ }
+ printf("\n");
+}
+
+void *pgmDrawFunc(void *arg)
+{
+ pgm_draw_thread_bind_cpu();
+
+ while (!PgmDrawThreadExit) {
+ if (!PgmTempDrawCtx.nDirty) {
+ pthread_yield();
+ continue;
+ }
+
+ // The PgmTempDrawCtx is dirty.
+ pthread_mutex_lock(&PgmDrawMutex);
+ memcpy(&PgmDrawCtx, &PgmTempDrawCtx, sizeof(PgmDrawCtx));
+ PgmTempDrawCtx.nDirty = 0;
+ pthread_mutex_unlock(&PgmDrawMutex);
+
+ pgmDrawReal();
+
+ // Update PgmTempDrawCtx.pBurnDraw.
+ pthread_mutex_lock(&PgmBurnDrawMutex);
+ memcpy(PgmTempDrawCtx.pBurnDraw, pBurnDraw, PGM_DRAW_SIZE);
+ pthread_mutex_unlock(&PgmBurnDrawMutex);
+ }
+ return NULL;
+}
+
+static void pgmInitThreadDraw()
+{
+ pgmInitDrawReal();
+
+ memset(&PgmDrawCtx, 0, sizeof(PgmDrawCtx));
+ memset(&PgmTempDrawCtx, 0, sizeof(PgmTempDrawCtx));
+
+ PgmTempDrawCtx.pBurnDraw = (UINT8*)BurnMalloc(PGM_DRAW_SIZE);
+ pBurnDrawCustom = BurnMalloc(PGM_DRAW_SIZE);
+
+ pthread_mutex_init(&PgmDrawMutex, NULL);
+ pthread_mutex_init(&PgmBurnDrawMutex, NULL);
+
+ PgmDrawThreadExit = 0;
+ pthread_create(&PgmDrawThread, NULL, pgmDrawFunc, NULL);
+}
+
+static void pgmExitThreadDraw()
+{
+ PgmDrawThreadExit = 1;
+ pthread_join(PgmDrawThread, NULL);
+
+ pthread_mutex_destroy(&PgmDrawMutex);
+ pthread_mutex_destroy(&PgmBurnDrawMutex);
+
+ BurnFree (pBurnDrawCustom);
+ BurnFree (PgmTempDrawCtx.pBurnDraw);
+
+ pgmExitDrawReal();
+}
+#endif
+
UINT8 PgmJoy1[8] = {0,0,0,0,0,0,0,0};
UINT8 PgmJoy2[8] = {0,0,0,0,0,0,0,0};
UINT8 PgmJoy3[8] = {0,0,0,0,0,0,0,0};
diff --git a/src/burner/libretro/libretro.cpp b/src/burner/libretro/libretro.cpp
index 241dfec..3fc2d02 100644
--- a/src/burner/libretro/libretro.cpp
+++ b/src/burner/libretro/libretro.cpp
@@ -149,6 +149,7 @@ static unsigned fba_devices[5] = { RETROPAD_CLASSIC, RETROPAD_CLASSIC, RETROPAD_
INT32 g_audio_samplerate = 48000;
INT32 nAudSegLen = 0;
+void *pBurnDrawCustom = NULL;
static uint32_t *g_fba_frame;
static int16_t *g_audio_buf;
@@ -1499,7 +1500,8 @@ void retro_run()
nBurnPitch = width * pitch_size;
}
- video_cb(g_fba_frame, width, height, nBurnPitch);
+ // Allow overriding frame data.
+ video_cb(pBurnDrawCustom ? pBurnDrawCustom : g_fba_frame, width, height, nBurnPitch);
audio_batch_cb(g_audio_buf, nBurnSoundLen);
bool updated = false;
--
2.11.0