31 |
|
#endif |
32 |
|
|
33 |
|
// Glue for SDL and X11 support |
34 |
+ |
#ifdef TEST_VOSF_PERFORMANCE |
35 |
+ |
#define MONITOR_INIT /* nothing */ |
36 |
+ |
#else |
37 |
|
#ifdef USE_SDL_VIDEO |
38 |
|
#define MONITOR_INIT SDL_monitor_desc &monitor |
39 |
|
#define VIDEO_DRV_WIN_INIT driver_window *drv |
40 |
|
#define VIDEO_DRV_DGA_INIT driver_fullscreen *drv |
41 |
< |
#define VIDEO_DRV_LOCK_PIXELS if (SDL_MUSTLOCK(drv->s)) SDL_LockSurface(drv->s) |
42 |
< |
#define VIDEO_DRV_UNLOCK_PIXELS if (SDL_MUSTLOCK(drv->s)) SDL_UnlockSurface(drv->s) |
41 |
> |
#define VIDEO_DRV_LOCK_PIXELS SDL_VIDEO_LOCK_SURFACE(drv->s) |
42 |
> |
#define VIDEO_DRV_UNLOCK_PIXELS SDL_VIDEO_UNLOCK_SURFACE(drv->s) |
43 |
|
#define VIDEO_DRV_DEPTH drv->s->format->BitsPerPixel |
44 |
|
#define VIDEO_DRV_WIDTH drv->s->w |
45 |
|
#define VIDEO_DRV_HEIGHT drv->s->h |
69 |
|
#define VIDEO_DRV_HEIGHT VIDEO_DRV_IMAGE->height |
70 |
|
#define VIDEO_DRV_ROW_BYTES VIDEO_DRV_IMAGE->bytes_per_line |
71 |
|
#endif |
72 |
+ |
#endif |
73 |
+ |
|
74 |
+ |
// Prototypes |
75 |
+ |
static void vosf_do_set_dirty_area(uintptr first, uintptr last); |
76 |
+ |
static void vosf_set_dirty_area(int x, int y, int w, int h, int screen_width, int bytes_per_row); |
77 |
|
|
78 |
|
// Variables for Video on SEGV support |
79 |
|
static uint8 *the_host_buffer; // Host frame buffer in VOSF mode |
176 |
|
#endif |
177 |
|
} |
178 |
|
|
179 |
< |
#ifdef HAVE_SPINLOCKS |
180 |
< |
static spinlock_t vosf_lock = SPIN_LOCK_UNLOCKED; // Mutex to protect frame buffer (dirtyPages in fact) |
181 |
< |
#define LOCK_VOSF spin_lock(&vosf_lock) |
182 |
< |
#define UNLOCK_VOSF spin_unlock(&vosf_lock) |
179 |
> |
#if defined(HAVE_PTHREADS) |
180 |
> |
static pthread_mutex_t vosf_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect frame buffer (dirtyPages in fact) |
181 |
> |
#define LOCK_VOSF pthread_mutex_lock(&vosf_lock); |
182 |
> |
#define UNLOCK_VOSF pthread_mutex_unlock(&vosf_lock); |
183 |
|
#elif defined(_WIN32) |
184 |
|
static mutex_t vosf_lock; // Mutex to protect frame buffer (dirtyPages in fact) |
185 |
|
#define LOCK_VOSF vosf_lock.lock(); |
186 |
|
#define UNLOCK_VOSF vosf_lock.unlock(); |
187 |
< |
#elif defined(HAVE_PTHREADS) |
188 |
< |
static pthread_mutex_t vosf_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect frame buffer (dirtyPages in fact) |
189 |
< |
#define LOCK_VOSF pthread_mutex_lock(&vosf_lock); |
190 |
< |
#define UNLOCK_VOSF pthread_mutex_unlock(&vosf_lock); |
187 |
> |
#elif defined(HAVE_SPINLOCKS) |
188 |
> |
static spinlock_t vosf_lock = SPIN_LOCK_UNLOCKED; // Mutex to protect frame buffer (dirtyPages in fact) |
189 |
> |
#define LOCK_VOSF spin_lock(&vosf_lock) |
190 |
> |
#define UNLOCK_VOSF spin_unlock(&vosf_lock) |
191 |
|
#else |
192 |
|
#define LOCK_VOSF |
193 |
|
#define UNLOCK_VOSF |
225 |
|
int64 durations[VOSF_PROFITABLE_TRIES]; |
226 |
|
int mean_duration = 0; |
227 |
|
|
228 |
+ |
#ifdef SHEEPSHAVER |
229 |
+ |
const bool accel = PrefsFindBool("gfxaccel"); |
230 |
+ |
#else |
231 |
+ |
const bool accel = false; |
232 |
+ |
#endif |
233 |
+ |
|
234 |
|
for (int i = 0; i < VOSF_PROFITABLE_TRIES; i++) { |
235 |
|
uint64 start = GetTicks_usec(); |
236 |
|
for (int p = 0; p < mainBuffer.pageCount; p++) { |
237 |
|
uint8 *addr = (uint8 *)(mainBuffer.memStart + (p * mainBuffer.pageSize)); |
238 |
< |
addr[0] = 0; // Trigger Screen_fault_handler() |
238 |
> |
if (accel) |
239 |
> |
vosf_do_set_dirty_area((uintptr)addr, (uintptr)addr + mainBuffer.pageSize - 1); |
240 |
> |
else |
241 |
> |
addr[0] = 0; // Trigger Screen_fault_handler() |
242 |
|
} |
243 |
|
int64 duration = GetTicks_usec() - start; |
244 |
|
mean_duration += duration; |
339 |
|
|
340 |
|
|
341 |
|
/* |
342 |
+ |
* Update VOSF state with specified dirty area |
343 |
+ |
*/ |
344 |
+ |
|
345 |
+ |
static void vosf_do_set_dirty_area(uintptr first, uintptr last) |
346 |
+ |
{ |
347 |
+ |
const int first_page = (first - mainBuffer.memStart) >> mainBuffer.pageBits; |
348 |
+ |
const int last_page = (last - mainBuffer.memStart) >> mainBuffer.pageBits; |
349 |
+ |
uint8 *addr = (uint8 *)first; |
350 |
+ |
for (int i = first_page; i <= last_page; i++) { |
351 |
+ |
if (PFLAG_ISCLEAR(i)) { |
352 |
+ |
PFLAG_SET(i); |
353 |
+ |
vm_protect(addr, mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); |
354 |
+ |
} |
355 |
+ |
addr += mainBuffer.pageSize; |
356 |
+ |
} |
357 |
+ |
} |
358 |
+ |
|
359 |
+ |
static void vosf_set_dirty_area(int x, int y, int w, int h, int screen_width, int bytes_per_row) |
360 |
+ |
{ |
361 |
+ |
if (x < 0) { |
362 |
+ |
w -= -x; |
363 |
+ |
x = 0; |
364 |
+ |
} |
365 |
+ |
if (y < 0) { |
366 |
+ |
h -= -y; |
367 |
+ |
y = 0; |
368 |
+ |
} |
369 |
+ |
if (w <= 0 || h <= 0) |
370 |
+ |
return; |
371 |
+ |
LOCK_VOSF; |
372 |
+ |
if (bytes_per_row >= screen_width) { |
373 |
+ |
const int bytes_per_pixel = bytes_per_row / screen_width; |
374 |
+ |
if (bytes_per_row <= mainBuffer.pageSize) { |
375 |
+ |
const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x * bytes_per_pixel; |
376 |
+ |
const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) * bytes_per_pixel; |
377 |
+ |
vosf_do_set_dirty_area(a0, a1); |
378 |
+ |
} else { |
379 |
+ |
for (int j = y; j < y + h; j++) { |
380 |
+ |
const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x * bytes_per_pixel; |
381 |
+ |
const uintptr a1 = a0 + (w - 1) * bytes_per_pixel; |
382 |
+ |
vosf_do_set_dirty_area(a0, a1); |
383 |
+ |
} |
384 |
+ |
} |
385 |
+ |
} else { |
386 |
+ |
const int pixels_per_byte = screen_width / bytes_per_row; |
387 |
+ |
if (bytes_per_row <= mainBuffer.pageSize) { |
388 |
+ |
const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x / pixels_per_byte; |
389 |
+ |
const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) / pixels_per_byte; |
390 |
+ |
vosf_do_set_dirty_area(a0, a1); |
391 |
+ |
} else { |
392 |
+ |
for (int j = y; j < y + h; j++) { |
393 |
+ |
const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x / pixels_per_byte; |
394 |
+ |
const uintptr a1 = mainBuffer.memStart + j * bytes_per_row + (x + w - 1) / pixels_per_byte; |
395 |
+ |
vosf_do_set_dirty_area(a0, a1); |
396 |
+ |
} |
397 |
+ |
} |
398 |
+ |
} |
399 |
+ |
mainBuffer.dirty = true; |
400 |
+ |
UNLOCK_VOSF; |
401 |
+ |
} |
402 |
+ |
|
403 |
+ |
|
404 |
+ |
/* |
405 |
|
* Screen fault handler |
406 |
|
*/ |
407 |
|
|
416 |
|
if (((uintptr)addr - mainBuffer.memStart) < mainBuffer.memLength) { |
417 |
|
const int page = ((uintptr)addr - mainBuffer.memStart) >> mainBuffer.pageBits; |
418 |
|
LOCK_VOSF; |
419 |
< |
PFLAG_SET(page); |
420 |
< |
vm_protect((char *)(addr & -mainBuffer.pageSize), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); |
419 |
> |
if (PFLAG_ISCLEAR(page)) { |
420 |
> |
PFLAG_SET(page); |
421 |
> |
vm_protect((char *)(addr & -mainBuffer.pageSize), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); |
422 |
> |
} |
423 |
|
mainBuffer.dirty = true; |
424 |
|
UNLOCK_VOSF; |
425 |
|
return true; |
467 |
|
than pageCount. |
468 |
|
*/ |
469 |
|
|
470 |
+ |
#ifndef TEST_VOSF_PERFORMANCE |
471 |
|
static void update_display_window_vosf(VIDEO_DRV_WIN_INIT) |
472 |
|
{ |
473 |
|
VIDEO_MODE_INIT; |
514 |
|
} |
515 |
|
mainBuffer.dirty = false; |
516 |
|
} |
517 |
+ |
#endif |
518 |
|
|
519 |
|
|
520 |
|
/* |
522 |
|
* (only in Real or Direct Addressing mode) |
523 |
|
*/ |
524 |
|
|
525 |
+ |
#ifndef TEST_VOSF_PERFORMANCE |
526 |
|
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
527 |
|
static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT) |
528 |
|
{ |
658 |
|
mainBuffer.dirty = false; |
659 |
|
} |
660 |
|
#endif |
661 |
+ |
#endif |
662 |
|
|
663 |
|
#endif /* ENABLE_VOSF */ |
664 |
|
|