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.36 by gbeauche, 2004-01-04T06:11:49Z vs.
Revision 1.46 by gbeauche, 2004-12-11T10:20:32Z

# Line 1 | Line 1
1   /*
2   *  video_vosf.h - Video/graphics emulation, video on SEGV signals support
3   *
4 < *  Basilisk II (C) 1997-2002 Christian Bauer
4 > *  Basilisk II (C) 1997-2004 Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 24 | Line 24
24   // Note: this file must be #include'd only in video_x.cpp
25   #ifdef ENABLE_VOSF
26  
27 #include <fcntl.h>
28 #include <sys/mman.h>
27   #include "sigsegv.h"
28   #include "vm_alloc.h"
29 + #ifdef _WIN32
30 + #include "util_windows.h"
31 + #endif
32  
33 < // Glue for SheepShaver and BasiliskII
34 < #if POWERPC_ROM
35 < #define X11_MONITOR_INIT                /* nothing */
33 > // Glue for SDL and X11 support
34 > #ifdef USE_SDL_VIDEO
35 > #define MONITOR_INIT                    SDL_monitor_desc &monitor
36 > #define VIDEO_DRV_INIT                  driver_window *drv
37 > #define VIDEO_DRV_ROW_BYTES             drv->s->pitch
38 > #define VIDEO_DRV_LOCK_PIXELS   if (SDL_MUSTLOCK(drv->s)) SDL_LockSurface(drv->s)
39 > #define VIDEO_DRV_UNLOCK_PIXELS if (SDL_MUSTLOCK(drv->s)) SDL_UnlockSurface(drv->s)
40 > #else
41 > #ifdef SHEEPSHAVER
42 > #define MONITOR_INIT                    /* nothing */
43   #define VIDEO_DRV_INIT                  /* nothing */
44   #define VIDEO_DRV_WINDOW                the_win
45   #define VIDEO_DRV_GC                    the_gc
46   #define VIDEO_DRV_IMAGE                 img
47   #define VIDEO_DRV_HAVE_SHM              have_shm
40 #define VIDEO_MODE_INIT                 VideoInfo const & mode = VModes[cur_mode]
41 #define VIDEO_MODE_ROW_BYTES    mode.viRowBytes
42 #define VIDEO_MODE_X                    mode.viXsize
43 #define VIDEO_MODE_Y                    mode.viYsize
44 #define VIDEO_MODE_DEPTH                mode.viAppleMode
45 enum {
46  VIDEO_DEPTH_1BIT = APPLE_1_BIT,
47  VIDEO_DEPTH_2BIT = APPLE_2_BIT,
48  VIDEO_DEPTH_4BIT = APPLE_4_BIT,
49  VIDEO_DEPTH_8BIT = APPLE_8_BIT,
50  VIDEO_DEPTH_16BIT = APPLE_16_BIT,
51  VIDEO_DEPTH_32BIT = APPLE_32_BIT
52 };
48   #else
49 < #define X11_MONITOR_INIT                X11_monitor_desc &monitor
49 > #define MONITOR_INIT                    X11_monitor_desc &monitor
50   #define VIDEO_DRV_INIT                  driver_window *drv
51   #define VIDEO_DRV_WINDOW                drv->w
52   #define VIDEO_DRV_GC                    drv->gc
53   #define VIDEO_DRV_IMAGE                 drv->img
54   #define VIDEO_DRV_HAVE_SHM              drv->have_shm
55 < #define VIDEO_MODE_INIT                 video_mode const & mode = drv->monitor.get_current_mode();
56 < #define VIDEO_MODE_ROW_BYTES    mode.bytes_per_row
57 < #define VIDEO_MODE_X                    mode.x
58 < #define VIDEO_MODE_Y                    mode.y
64 < #define VIDEO_MODE_DEPTH                (int)mode.depth
65 < enum {
66 <  VIDEO_DEPTH_1BIT = VDEPTH_1BIT,
67 <  VIDEO_DEPTH_2BIT = VDEPTH_2BIT,
68 <  VIDEO_DEPTH_4BIT = VDEPTH_4BIT,
69 <  VIDEO_DEPTH_8BIT = VDEPTH_8BIT,
70 <  VIDEO_DEPTH_16BIT = VDEPTH_16BIT,
71 <  VIDEO_DEPTH_32BIT = VDEPTH_32BIT
72 < };
55 > #endif
56 > #define VIDEO_DRV_LOCK_PIXELS   /* nothing */
57 > #define VIDEO_DRV_UNLOCK_PIXELS /* nothing */
58 > #define VIDEO_DRV_ROW_BYTES             VIDEO_DRV_IMAGE->bytes_per_line
59   #endif
60  
61   // Variables for Video on SEGV support
# Line 171 | Line 157 | static inline int find_next_page_clear(i
157   static spinlock_t vosf_lock = SPIN_LOCK_UNLOCKED;                               // Mutex to protect frame buffer (dirtyPages in fact)
158   #define LOCK_VOSF spin_lock(&vosf_lock)
159   #define UNLOCK_VOSF spin_unlock(&vosf_lock)
160 + #elif defined(_WIN32)
161 + static mutex_t vosf_lock;                                                                               // Mutex to protect frame buffer (dirtyPages in fact)
162 + #define LOCK_VOSF vosf_lock.lock();
163 + #define UNLOCK_VOSF vosf_lock.unlock();
164   #elif defined(HAVE_PTHREADS)
165   static pthread_mutex_t vosf_lock = PTHREAD_MUTEX_INITIALIZER;   // Mutex to protect frame buffer (dirtyPages in fact)
166   #define LOCK_VOSF pthread_mutex_lock(&vosf_lock);
# Line 194 | Line 184 | static int log_base_2(uint32 x)
184   // Extend size to page boundary
185   static uint32 page_extend(uint32 size)
186   {
187 <        const uint32 page_size = getpagesize();
187 >        const uint32 page_size = vm_page_size();
188          const uint32 page_mask = page_size - 1;
189          return (size + page_mask) & ~page_mask;
190   }
191  
192  
193   /*
194 + *  Check if VOSF acceleration is profitable on this platform
195 + */
196 +
197 + const int VOSF_PROFITABLE_TRIES = 3;                    // Make 3 attempts for full screen update
198 + const int VOSF_PROFITABLE_THRESHOLD = 16667;    // 60 Hz
199 +
200 + static bool video_vosf_profitable(void)
201 + {
202 +        int64 durations[VOSF_PROFITABLE_TRIES];
203 +        int mean_duration = 0;
204 +
205 +        for (int i = 0; i < VOSF_PROFITABLE_TRIES; i++) {
206 +                uint64 start = GetTicks_usec();
207 +                for (int p = 0; p < mainBuffer.pageCount; p++) {
208 +                        uint8 *addr = (uint8 *)(mainBuffer.memStart + (p * mainBuffer.pageSize));
209 +                        addr[0] = 0; // Trigger Screen_fault_handler()
210 +                }
211 +                int64 duration = GetTicks_usec() - start;
212 +                mean_duration += duration;
213 +                durations[i] = duration;
214 +
215 +                PFLAG_CLEAR_ALL;
216 +                mainBuffer.dirty = false;
217 +                if (vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ) != 0)
218 +                        return false;
219 +        }
220 +
221 +        mean_duration /= VOSF_PROFITABLE_TRIES;
222 +        D(bug("Triggered %d screen faults in %ld usec on average\n", mainBuffer.pageCount, mean_duration));
223 +        return (mean_duration < (VOSF_PROFITABLE_THRESHOLD * (frame_skip ? frame_skip : 1)));
224 + }
225 +
226 +
227 + /*
228   *  Initialize the VOSF system (mainBuffer structure, SIGSEGV handler)
229   */
230  
231 < static bool video_vosf_init(X11_MONITOR_INIT)
231 > static bool video_vosf_init(MONITOR_INIT)
232   {
233 <        VIDEO_MODE_INIT;
233 >        VIDEO_MODE_INIT_MONITOR;
234  
235 <        const uintptr page_size = getpagesize();
235 >        const uintptr page_size = vm_page_size();
236          const uintptr page_mask = page_size - 1;
237          
238          // Round up frame buffer base to page boundary
# Line 313 | Line 337 | bool Screen_fault_handler(sigsegv_addres
337   *      Update display for Windowed mode and VOSF
338   */
339  
316 // From video_blit.cpp
317 extern void (*Screen_blit)(uint8 * dest, const uint8 * source, uint32 length);
318 extern bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order, int mac_depth);
319 extern uint32 ExpandMap[256];
320
340   /*      How can we deal with array overrun conditions ?
341          
342          The state of the framebuffer pages that have been touched are maintained
# Line 373 | Line 392 | static inline void update_display_window
392                  const int y1 = mainBuffer.pageInfo[first_page].top;
393                  const int y2 = mainBuffer.pageInfo[page - 1].bottom;
394                  const int height = y2 - y1 + 1;
395 <                
396 <                if (VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) {
395 >
396 >                VIDEO_DRV_LOCK_PIXELS;
397 >
398 >                if ((int)VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) {
399  
400                          // Update the_host_buffer and copy of the_buffer
401                          const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES;
402 <                        const int dst_bytes_per_row = VIDEO_DRV_IMAGE->bytes_per_line;
402 >                        const int dst_bytes_per_row = VIDEO_DRV_ROW_BYTES;
403                          const int pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row;
404                          int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j;
405                          for (j = y1; j <= y2; j++) {
# Line 391 | Line 412 | static inline void update_display_window
412  
413                          // Update the_host_buffer and copy of the_buffer
414                          const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES;
415 <                        const int dst_bytes_per_row = VIDEO_DRV_IMAGE->bytes_per_line;
415 >                        const int dst_bytes_per_row = VIDEO_DRV_ROW_BYTES;
416                          const int bytes_per_pixel = src_bytes_per_row / VIDEO_MODE_X;
417                          int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j;
418                          for (j = y1; j <= y2; j++) {
# Line 401 | Line 422 | static inline void update_display_window
422                          }
423                  }
424  
425 +                VIDEO_DRV_UNLOCK_PIXELS;
426 +
427 + #ifdef USE_SDL_VIDEO
428 +                SDL_UpdateRect(drv->s, 0, y1, VIDEO_MODE_X, height);
429 + #else
430                  if (VIDEO_DRV_HAVE_SHM)
431                          XShmPutImage(x_display, VIDEO_DRV_WINDOW, VIDEO_DRV_GC, VIDEO_DRV_IMAGE, 0, y1, 0, y1, VIDEO_MODE_X, height, 0);
432                  else
433                          XPutImage(x_display, VIDEO_DRV_WINDOW, VIDEO_DRV_GC, VIDEO_DRV_IMAGE, 0, y1, 0, y1, VIDEO_MODE_X, height);
434 + #endif
435          }
436          mainBuffer.dirty = false;
437   }
# Line 472 | Line 499 | static inline void update_display_dga_vo
499                  
500                  // Update the_host_buffer and copy of the_buffer
501                  // There should be at least one pixel to copy
502 +                VIDEO_DRV_LOCK_PIXELS;
503                  const int width = x2 - x1 + 1;
504                  i = y1 * bytes_per_row + x1 * bytes_per_pixel;
505                  for (j = y1; j <= y2; j++) {
# Line 479 | Line 507 | static inline void update_display_dga_vo
507                          memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * width);
508                          i += bytes_per_row;
509                  }
510 +                VIDEO_DRV_UNLOCK_PIXELS;
511          }
512          mainBuffer.dirty = false;
513   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines