ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/video_vosf.h
(Generate patch)

Comparing BasiliskII/src/Unix/video_vosf.h (file contents):
Revision 1.56 by gbeauche, 2006-01-21T16:00:17Z vs.
Revision 1.57 by gbeauche, 2006-05-13T16:48:47Z

# Line 71 | Line 71
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
80  
# Line 221 | Line 225 | static bool video_vosf_profitable(void)
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;
# Line 326 | Line 339 | static void video_vosf_exit(void)
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  
# Line 340 | Line 416 | bool Screen_fault_handler(sigsegv_addres
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;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines