Force Voodoo blit

Certain applications using the Voodoo adapter stop blitting
when there's no activity (e.g mouse movement, animation).
This results in a black screen when events like window/full screen
transitions take place. Usually this can be fixed by
moving the mouse or with keyboard inout. This change forces
a blit to refresh the screen.

In addition, added critical sections since they are lighter
than mutexes.
This commit is contained in:
luisjoseromero
2021-01-14 00:19:47 +00:00
parent efe7fc4043
commit eca2625093
5 changed files with 115 additions and 2 deletions

View File

@@ -142,6 +142,7 @@ extern void ioctl_close(uint8_t id);
typedef void thread_t;
typedef void event_t;
typedef void mutex_t;
typedef void lightmutex_t;
extern thread_t *thread_create(void (*thread_func)(void *param), void *param);
extern void thread_kill(thread_t *arg);
@@ -157,6 +158,13 @@ extern void thread_close_mutex(mutex_t *arg);
extern int thread_wait_mutex(mutex_t *arg);
extern int thread_release_mutex(mutex_t *mutex);
#define LIGHT_MUTEX_DEFAULT_SPIN_COUNT 1024
lightmutex_t *thread_create_light_mutex();
lightmutex_t *thread_create_light_mutex_and_spin_count(unsigned int spin_count);
int thread_wait_light_mutex(lightmutex_t *lightmutex);
int thread_release_light_mutex(lightmutex_t *lightmutex);
void thread_close_light_mutex(lightmutex_t *lightmutex);
/* Other stuff. */
extern void startblit(void);

View File

@@ -489,6 +489,10 @@ typedef struct voodoo_t
uint64_t time;
int render_time[4];
int force_blit_count;
int can_blit;
lightmutex_t* force_blit_mutex;
int use_recompiler;
void *codegen_data;

View File

@@ -514,6 +514,12 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
if (voodoo->initEnable & 0x01)
{
voodoo->fbiInit0 = val;
thread_wait_light_mutex(voodoo->force_blit_mutex);
voodoo->can_blit = (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) ? 1 : 0;
if (!voodoo->can_blit)
voodoo->force_blit_count = 0;
thread_release_light_mutex(voodoo->force_blit_mutex);
if (voodoo->set->nr_cards == 2)
svga_set_override(voodoo->svga, (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1);
else
@@ -877,6 +883,24 @@ static void voodoo_speed_changed(void *p)
// voodoo_log("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4);
}
static void voodoo_force_blit(void *p)
{
voodoo_set_t *voodoo_set = (voodoo_set_t *)p;
thread_wait_light_mutex(voodoo_set->voodoos[0]->force_blit_mutex);
if(voodoo_set->voodoos[0]->can_blit) {
voodoo_set->voodoos[0]->force_blit_count++;
}
thread_release_light_mutex(voodoo_set->voodoos[0]->force_blit_mutex);
if(voodoo_set->nr_cards == 2) {
thread_wait_light_mutex(voodoo_set->voodoos[1]->force_blit_mutex);
if(voodoo_set->voodoos[1]->can_blit) {
voodoo_set->voodoos[1]->force_blit_count++;
}
thread_release_light_mutex(voodoo_set->voodoos[1]->force_blit_mutex);
}
}
void *voodoo_card_init()
{
int c;
@@ -1014,6 +1038,10 @@ void *voodoo_card_init()
voodoo->disp_buffer = 0;
voodoo->draw_buffer = 1;
voodoo->force_blit_count = 0;
voodoo->can_blit = 0;
voodoo->force_blit_mutex = thread_create_light_mutex();
return voodoo;
}
@@ -1128,6 +1156,10 @@ void *voodoo_2d3d_card_init(int type)
voodoo->disp_buffer = 0;
voodoo->draw_buffer = 1;
voodoo->force_blit_count = 0;
voodoo->can_blit = 0;
voodoo->force_blit_mutex = thread_create_light_mutex();
return voodoo;
}
@@ -1241,6 +1273,9 @@ void voodoo_card_close(voodoo_t *voodoo)
free(voodoo->tex_mem[1]);
free(voodoo->tex_mem[0]);
}
thread_close_light_mutex(voodoo->force_blit_mutex);
free(voodoo);
}
@@ -1386,6 +1421,6 @@ const device_t voodoo_device =
NULL,
{ NULL },
voodoo_speed_changed,
NULL,
voodoo_force_blit,
voodoo_config
};

View File

@@ -645,7 +645,16 @@ skip_draw:
{
if (voodoo->line == voodoo->v_disp)
{
if (voodoo->dirty_line_high > voodoo->dirty_line_low)
int force_blit = 0;
thread_wait_light_mutex(voodoo->force_blit_mutex);
if(voodoo->force_blit_count) {
force_blit = 1;
if(--voodoo->force_blit_count < 0)
voodoo->force_blit_count = 0;
}
thread_release_light_mutex(voodoo->force_blit_mutex);
if (voodoo->dirty_line_high > voodoo->dirty_line_low || force_blit)
svga_doblit(0, voodoo->v_disp, voodoo->h_disp, voodoo->v_disp-1, voodoo->svga);
if (voodoo->clutData_dirty)
{

View File

@@ -167,3 +167,60 @@ thread_release_mutex(mutex_t *mutex)
return(!!ReleaseMutex((HANDLE)mutex));
}
lightmutex_t *
thread_create_light_mutex()
{
return thread_create_light_mutex_and_spin_count(LIGHT_MUTEX_DEFAULT_SPIN_COUNT);
}
lightmutex_t *
thread_create_light_mutex_and_spin_count(unsigned int spin_count)
{
lightmutex_t *lightmutex = malloc(sizeof(CRITICAL_SECTION));
InitializeCriticalSectionAndSpinCount(lightmutex, spin_count);
return lightmutex;
}
int
thread_wait_light_mutex(lightmutex_t *lightmutex)
{
if (lightmutex == NULL) return(0);
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)lightmutex;
EnterCriticalSection(critsec);
return 1;
}
int
thread_release_light_mutex(lightmutex_t *lightmutex)
{
if (lightmutex == NULL) return(0);
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)lightmutex;
LeaveCriticalSection(critsec);
return 1;
}
void
thread_close_light_mutex(lightmutex_t *lightmutex)
{
if (lightmutex == NULL) return;
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)lightmutex;
DeleteCriticalSection(critsec);
free(critsec);
}