mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-20 00:31:28 +00:00
Use NQD dirty boxes, VOSF backend
+ make video_vosf_profitable() NQD accel aware + call vm_protect() only if PFLAG_CLEAR(page)
This commit is contained in:
parent
3b07ba27e4
commit
e4015e069f
@ -71,6 +71,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Prototypes
|
||||
static void vosf_do_set_dirty_area(uintptr first, uintptr last);
|
||||
static void vosf_set_dirty_area(int x, int y, int w, int h, int screen_width, int bytes_per_row);
|
||||
|
||||
// Variables for Video on SEGV support
|
||||
static uint8 *the_host_buffer; // Host frame buffer in VOSF mode
|
||||
|
||||
@ -221,10 +225,19 @@ static bool video_vosf_profitable(void)
|
||||
int64 durations[VOSF_PROFITABLE_TRIES];
|
||||
int mean_duration = 0;
|
||||
|
||||
#ifdef SHEEPSHAVER
|
||||
const bool accel = PrefsFindBool("gfxaccel");
|
||||
#else
|
||||
const bool accel = false;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < VOSF_PROFITABLE_TRIES; i++) {
|
||||
uint64 start = GetTicks_usec();
|
||||
for (int p = 0; p < mainBuffer.pageCount; p++) {
|
||||
uint8 *addr = (uint8 *)(mainBuffer.memStart + (p * mainBuffer.pageSize));
|
||||
if (accel)
|
||||
vosf_do_set_dirty_area((uintptr)addr, (uintptr)addr + mainBuffer.pageSize - 1);
|
||||
else
|
||||
addr[0] = 0; // Trigger Screen_fault_handler()
|
||||
}
|
||||
int64 duration = GetTicks_usec() - start;
|
||||
@ -325,6 +338,69 @@ static void video_vosf_exit(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update VOSF state with specified dirty area
|
||||
*/
|
||||
|
||||
static void vosf_do_set_dirty_area(uintptr first, uintptr last)
|
||||
{
|
||||
const int first_page = (first - mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
const int last_page = (last - mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
uint8 *addr = (uint8 *)first;
|
||||
for (int i = first_page; i <= last_page; i++) {
|
||||
if (PFLAG_ISCLEAR(i)) {
|
||||
PFLAG_SET(i);
|
||||
vm_protect(addr, mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE);
|
||||
}
|
||||
addr += mainBuffer.pageSize;
|
||||
}
|
||||
}
|
||||
|
||||
static void vosf_set_dirty_area(int x, int y, int w, int h, int screen_width, int bytes_per_row)
|
||||
{
|
||||
if (x < 0) {
|
||||
w -= -x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
h -= -y;
|
||||
y = 0;
|
||||
}
|
||||
if (w <= 0 || h <= 0)
|
||||
return;
|
||||
LOCK_VOSF;
|
||||
if (bytes_per_row >= screen_width) {
|
||||
const int bytes_per_pixel = bytes_per_row / screen_width;
|
||||
if (bytes_per_row <= mainBuffer.pageSize) {
|
||||
const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x * bytes_per_pixel;
|
||||
const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) * bytes_per_pixel;
|
||||
vosf_do_set_dirty_area(a0, a1);
|
||||
} else {
|
||||
for (int j = y; j < y + h; j++) {
|
||||
const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x * bytes_per_pixel;
|
||||
const uintptr a1 = a0 + (w - 1) * bytes_per_pixel;
|
||||
vosf_do_set_dirty_area(a0, a1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const int pixels_per_byte = screen_width / bytes_per_row;
|
||||
if (bytes_per_row <= mainBuffer.pageSize) {
|
||||
const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x / pixels_per_byte;
|
||||
const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) / pixels_per_byte;
|
||||
vosf_do_set_dirty_area(a0, a1);
|
||||
} else {
|
||||
for (int j = y; j < y + h; j++) {
|
||||
const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x / pixels_per_byte;
|
||||
const uintptr a1 = mainBuffer.memStart + j * bytes_per_row + (x + w - 1) / pixels_per_byte;
|
||||
vosf_do_set_dirty_area(a0, a1);
|
||||
}
|
||||
}
|
||||
}
|
||||
mainBuffer.dirty = true;
|
||||
UNLOCK_VOSF;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Screen fault handler
|
||||
*/
|
||||
@ -340,8 +416,10 @@ bool Screen_fault_handler(sigsegv_address_t fault_address, sigsegv_address_t fau
|
||||
if (((uintptr)addr - mainBuffer.memStart) < mainBuffer.memLength) {
|
||||
const int page = ((uintptr)addr - mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||
LOCK_VOSF;
|
||||
if (PFLAG_ISCLEAR(page)) {
|
||||
PFLAG_SET(page);
|
||||
vm_protect((char *)(addr & -mainBuffer.pageSize), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE);
|
||||
}
|
||||
mainBuffer.dirty = true;
|
||||
UNLOCK_VOSF;
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user