ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/video_x.cpp
(Generate patch)

Comparing SheepShaver/src/Unix/video_x.cpp (file contents):
Revision 1.1 by cebix, 2002-02-04T16:58:13Z vs.
Revision 1.5 by gbeauche, 2003-11-20T16:24:57Z

# Line 52 | Line 52 | static int32 frame_skip;
52   static bool redraw_thread_active = false;       // Flag: Redraw thread installed
53   static pthread_t redraw_thread;                         // Redraw thread
54  
55 + static bool local_X11;                                          // Flag: X server running on local machine?
56   static volatile bool thread_stop_req = false;
57   static volatile bool thread_stop_ack = false;   // Acknowledge for thread_stop_req
58  
59   static bool has_dga = false;                            // Flag: Video DGA capable
60   static bool has_vidmode = false;                        // Flag: VidMode extension available
61  
62 + #ifdef ENABLE_VOSF
63 + static bool use_vosf = true;                            // Flag: VOSF enabled
64 + #else
65 + static const bool use_vosf = false;                     // VOSF not possible
66 + #endif
67 +
68   static bool palette_changed = false;            // Flag: Palette changed, redraw thread must update palette
69   static bool ctrl_down = false;                          // Flag: Ctrl key pressed
70   static bool quit_full_screen = false;           // Flag: DGA close requested from redraw thread
# Line 92 | Line 99 | static Cursor mac_cursor;
99   static GC cursor_gc, cursor_mask_gc;
100   static bool cursor_changed = false;                     // Flag: Cursor changed, window_func must update cursor
101   static bool have_shm = false;                           // Flag: SHM present and usable
102 < static uint8 *the_buffer;                                       // Pointer to Mac frame buffer
102 > static uint8 *the_buffer = NULL;                        // Pointer to Mac frame buffer
103   static uint8 *the_buffer_copy = NULL;           // Copy of Mac frame buffer
104 + static uint32 the_buffer_size;                          // Size of allocated the_buffer
105  
106   // Variables for DGA mode
107   static char *dga_screen_base;
# Line 111 | Line 119 | static int num_x_video_modes;
119   static void *redraw_func(void *arg);
120  
121  
122 < // From main_linux.cpp
122 > // From main_unix.cpp
123 > extern char *x_display_name;
124   extern Display *x_display;
125  
126   // From sys_unix.cpp
127   extern void SysMountFirstFloppy(void);
128  
129  
130 + // Video acceleration through SIGSEGV
131 + #ifdef ENABLE_VOSF
132 + # include "video_vosf.h"
133 + #endif
134 +
135 +
136   /*
137   *  Open display (window or fullscreen)
138   */
# Line 138 | Line 153 | static int error_handler(Display *d, XEr
153   // Open window
154   static bool open_window(int width, int height)
155   {
156 +        int aligned_width = (width + 15) & ~15;
157 +        int aligned_height = (height + 15) & ~15;
158 +
159          // Set absolute mouse mode
160          ADBSetRelMouseMode(false);
161  
# Line 179 | Line 197 | static bool open_window(int width, int h
197                  XFree((char *)hints);
198          }
199  
200 +        // 1-bit mode is big-endian; if the X server is little-endian, we can't
201 +        // use SHM because that doesn't allow changing the image byte order
202 +        bool need_msb_image = (depth == 1 && XImageByteOrder(x_display) == LSBFirst);
203 +
204          // Try to create and attach SHM image
205          have_shm = false;
206 <        if (depth != 1 && XShmQueryExtension(x_display)) {
206 >        if (local_X11 && !need_msb_image && XShmQueryExtension(x_display)) {
207  
208                  // Create SHM image ("height + 2" for safety)
209 <                img = XShmCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
209 >                img = XShmCreateImage(x_display, vis, depth == 1 ? 1 : xdepth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
210                  shminfo.shmid = shmget(IPC_PRIVATE, (height + 2) * img->bytes_per_line, IPC_CREAT | 0777);
211 <                screen_base = (uint32)shmat(shminfo.shmid, 0, 0);
212 <                the_buffer = (uint8 *)screen_base;
191 <                shminfo.shmaddr = img->data = (char *)screen_base;
211 >                the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0);
212 >                shminfo.shmaddr = img->data = (char *)the_buffer_copy;
213                  shminfo.readOnly = False;
214  
215                  // Try to attach SHM image, catching errors
# Line 209 | Line 230 | static bool open_window(int width, int h
230  
231          // Create normal X image if SHM doesn't work ("height + 2" for safety)
232          if (!have_shm) {
233 <                int bytes_per_row = width;
233 >                int bytes_per_row = aligned_width;
234                  switch (depth) {
235                          case 1:
236                                  bytes_per_row /= 8;
# Line 223 | Line 244 | static bool open_window(int width, int h
244                                  bytes_per_row *= 4;
245                                  break;
246                  }
247 <                screen_base = (uint32)malloc((height + 2) * bytes_per_row);
248 <                the_buffer = (uint8 *)screen_base;
228 <                img = XCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, (char *)screen_base, width, height, 32, bytes_per_row);
247 >                the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row);
248 >                img = XCreateImage(x_display, vis, depth == 1 ? 1 : xdepth, depth == 1 ? XYBitmap : ZPixmap, 0, (char *)the_buffer_copy, aligned_width, aligned_height, 32, bytes_per_row);
249          }
250  
251          // 1-Bit mode is big-endian
# Line 234 | Line 254 | static bool open_window(int width, int h
254          img->bitmap_bit_order = MSBFirst;
255      }
256  
257 <        // Allocate memory for frame buffer copy
258 <        the_buffer_copy = (uint8 *)malloc((height + 2) * img->bytes_per_line);
257 > #ifdef ENABLE_VOSF
258 >        use_vosf = true;
259 >        // Allocate memory for frame buffer (SIZE is extended to page-boundary)
260 >        the_host_buffer = the_buffer_copy;
261 >        the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line);
262 >        the_buffer = (uint8 *)vm_acquire(the_buffer_size);
263 >        the_buffer_copy = (uint8 *)malloc(the_buffer_size);
264 >        D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
265 > #else
266 >        // Allocate memory for frame buffer
267 >        the_buffer = (uint8 *)malloc((aligned_height + 2) * img->bytes_per_line);
268 >        D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy));
269 > #endif
270 >        screen_base = (uint32)the_buffer;
271  
272          // Create GC
273          the_gc = XCreateGC(x_display, the_win, 0, 0);
# Line 255 | Line 287 | static bool open_window(int width, int h
287          mac_cursor = XCreatePixmapCursor(x_display, cursor_map, cursor_mask_map, &black, &white, 0, 0);
288          cursor_changed = false;
289  
290 +        // Init blitting routines
291 +        bool native_byte_order;
292 + #ifdef WORDS_BIGENDIAN
293 +        native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
294 + #else
295 +        native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
296 + #endif
297 + #ifdef ENABLE_VOSF
298 +        Screen_blitter_init(&visualInfo, native_byte_order, depth);
299 + #endif
300 +
301          // Set bytes per row
302          VModes[cur_mode].viRowBytes = img->bytes_per_line;
303          XSync(x_display, false);
# Line 289 | Line 332 | static bool open_dga(int width, int heig
332          XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
333          XF86DGASetViewPort(x_display, screen, 0, 0);
334          XF86DGASetVidPage(x_display, screen, 0);
292        screen_base = (uint32)dga_screen_base;
335  
336          // Set colormap
337          if (depth == 8)
# Line 307 | Line 349 | static bool open_dga(int width, int heig
349                          bytes_per_row *= 4;
350                          break;
351          }
352 +
353 + #if ENABLE_VOSF
354 +        bool native_byte_order;
355 + #ifdef WORDS_BIGENDIAN
356 +        native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
357 + #else
358 +        native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
359 + #endif
360 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
361 +        // Screen_blitter_init() returns TRUE if VOSF is mandatory
362 +        // i.e. the framebuffer update function is not Blit_Copy_Raw
363 +        use_vosf = Screen_blitter_init(&visualInfo, native_byte_order, depth);
364 +        
365 +        if (use_vosf) {
366 +          // Allocate memory for frame buffer (SIZE is extended to page-boundary)
367 +          the_host_buffer = the_buffer;
368 +          the_buffer_size = page_extend((height + 2) * bytes_per_row);
369 +          the_buffer_copy = (uint8 *)malloc(the_buffer_size);
370 +          the_buffer = (uint8 *)vm_acquire(the_buffer_size);
371 +        }
372 + #else
373 +        use_vosf = false;
374 +        the_buffer = dga_screen_base;
375 + #endif
376 + #endif
377 +        screen_base = (uint32)the_buffer;
378 +
379          VModes[cur_mode].viRowBytes = bytes_per_row;
380          XSync(x_display, false);
381          return true;
# Line 333 | Line 402 | static bool open_display(void)
402                          depth = 8;
403                          break;
404                  case APPLE_16_BIT:
405 <                        depth = 16;
405 >                        depth = xdepth == 15 ? 15 : 16;
406                          break;
407                  case APPLE_32_BIT:
408                          depth = 32;
409                          break;
410          }
411 +
412 +        bool display_open = false;
413          if (display_type == DIS_SCREEN)
414 <                return open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
414 >                display_open = open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
415          else if (display_type == DIS_WINDOW)
416 <                return open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
417 <        else
418 <                return false;
416 >                display_open = open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
417 >
418 > #ifdef ENABLE_VOSF
419 >        if (use_vosf) {
420 >                // Initialize the VOSF system
421 >                if (!video_vosf_init()) {
422 >                        ErrorAlert(GetString(STR_VOSF_INIT_ERR));
423 >                        return false;
424 >                }
425 >        }
426 > #endif
427 >        
428 >        return display_open;
429   }
430  
431  
# Line 355 | Line 436 | static bool open_display(void)
436   // Close window
437   static void close_window(void)
438   {
439 +        if (have_shm) {
440 +                XShmDetach(x_display, &shminfo);
441 + #ifdef ENABLE_VOSF
442 +                the_host_buffer = NULL; // don't free() in driver_base dtor
443 + #else
444 +                the_buffer_copy = NULL; // don't free() in driver_base dtor
445 + #endif
446 +        }
447 +        if (img) {
448 +                if (!have_shm)
449 +                        img->data = NULL;
450 +                XDestroyImage(img);
451 +        }
452 +        if (have_shm) {
453 +                shmdt(shminfo.shmaddr);
454 +                shmctl(shminfo.shmid, IPC_RMID, 0);
455 +        }
456 +        if (the_gc)
457 +                XFreeGC(x_display, the_gc);
458 +
459          // Close window
460          XDestroyWindow(x_display, the_win);
360
361        // Close frame buffer copy
362        if (the_buffer_copy) {
363                free(the_buffer_copy);
364                the_buffer_copy = NULL;
365        }
461   }
462  
463   // Close DGA mode
# Line 378 | Line 473 | static void close_dga(void)
473          if (has_vidmode)
474                  XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]);
475   #endif
476 +
477 +        if (!use_vosf) {
478 +                // don't free() the screen buffer in driver_base dtor
479 +                the_buffer = NULL;
480 +        }
481 + #ifdef ENABLE_VOSF
482 +        else {
483 +                // don't free() the screen buffer in driver_base dtor
484 +                the_host_buffer = NULL;
485 +        }
486 + #endif
487   }
488  
489   static void close_display(void)
# Line 386 | Line 492 | static void close_display(void)
492                  close_dga();
493          else if (display_type == DIS_WINDOW)
494                  close_window();
495 +
496 + #ifdef ENABLE_VOSF
497 +        if (use_vosf) {
498 +                // Deinitialize VOSF
499 +                video_vosf_exit();
500 +        }
501 + #endif
502 +
503 +        // Free frame buffer(s)
504 +        if (!use_vosf) {
505 +                if (the_buffer_copy) {
506 +                        free(the_buffer_copy);
507 +                        the_buffer_copy = NULL;
508 +                }
509 +        }
510 + #ifdef ENABLE_VOSF
511 +        else {
512 +                // the_buffer shall always be mapped through vm_acquire() so that we can vm_protect() it at will
513 +                if (the_buffer != VM_MAP_FAILED) {
514 +                        D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size));
515 +                        vm_release(the_buffer, the_buffer_size);
516 +                        the_buffer = NULL;
517 +                }
518 +                if (the_host_buffer) {
519 +                        D(bug(" freeing the_host_buffer at %p\n", the_host_buffer));
520 +                        free(the_host_buffer);
521 +                        the_host_buffer = NULL;
522 +                }
523 +                if (the_buffer_copy) {
524 +                        D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy));
525 +                        free(the_buffer_copy);
526 +                        the_buffer_copy = NULL;
527 +                }
528 +        }
529 + #endif
530   }
531  
532  
# Line 456 | Line 597 | static bool has_mode(int x, int y)
597  
598   bool VideoInit(void)
599   {
600 + #ifdef ENABLE_VOSF
601 +        // Zero the mainBuffer structure
602 +        mainBuffer.dirtyPages = NULL;
603 +        mainBuffer.pageInfo = NULL;
604 + #endif
605 +        
606 +        // Check if X server runs on local machine
607 +        local_X11 = (strncmp(XDisplayName(x_display_name), ":", 1) == 0)
608 +                 || (strncmp(XDisplayName(x_display_name), "unix:", 5) == 0);
609 +    
610          // Init variables
611          private_data = NULL;
612          cur_mode = 0;   // Window 640x480
# Line 471 | Line 622 | bool VideoInit(void)
622   #ifdef ENABLE_XF86_DGA
623          // DGA available?
624      int event_base, error_base;
625 <    if (XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
625 >    if (local_X11 && XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
626                  int dga_flags = 0;
627                  XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
628                  has_dga = dga_flags & XF86DGADirectPresent;
# Line 652 | Line 803 | void VideoExit(void)
803                  redraw_thread_active = false;
804          }
805  
806 + #ifdef ENABLE_VOSF
807 +        if (use_vosf) {
808 +                // Deinitialize VOSF
809 +                video_vosf_exit();
810 +        }
811 + #endif
812 +
813          // Close window and server connection
814          if (x_display != NULL) {
815                  XSync(x_display, false);
# Line 729 | Line 887 | static void resume_emul(void)
887          XF86DGASetViewPort(x_display, screen, 0, 0);
888          XSync(x_display, false);
889  
890 +        // the_buffer already contains the data to restore. i.e. since a temporary
891 +        // frame buffer is used when VOSF is actually used, fb_save is therefore
892 +        // not necessary.
893 + #ifdef ENABLE_VOSF
894 +        if (use_vosf) {
895 +                LOCK_VOSF;
896 +                PFLAG_SET_ALL;
897 +                UNLOCK_VOSF;
898 +                memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
899 +        }
900 + #endif
901 +        
902          // Restore frame buffer
903          if (fb_save) {
904 + #ifdef ENABLE_VOSF
905 +                // Don't copy fb_save to the temporary frame buffer in VOSF mode
906 +                if (!use_vosf)
907 + #endif
908                  memcpy((void *)screen_base, fb_save, VModes[cur_mode].viYsize * VModes[cur_mode].viRowBytes);
909                  free(fb_save);
910                  fb_save = NULL;
# Line 979 | Line 1153 | static void handle_events(void)
1153  
1154                          // Hidden parts exposed, force complete refresh
1155                          case Expose:
1156 + #ifdef ENABLE_VOSF
1157 +                                if (use_vosf) {                 // VOSF refresh
1158 +                                        LOCK_VOSF;
1159 +                                        PFLAG_SET_ALL;
1160 +                                        UNLOCK_VOSF;
1161 +                                }
1162 + #endif
1163                                  memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1164                                  break;
1165                  }
# Line 1376 | Line 1557 | static void *redraw_func(void *arg)
1557                                  tick_counter = 0;
1558  
1559                                  // Update display
1560 <                                update_display();
1560 > #ifdef ENABLE_VOSF
1561 >                                if (use_vosf) {
1562 >                                        if (mainBuffer.dirty) {
1563 >                                                LOCK_VOSF;
1564 >                                                update_display_window_vosf();
1565 >                                                UNLOCK_VOSF;
1566 >                                                XSync(x_display, false); // Let the server catch up
1567 >                                        }
1568 >                                }
1569 >                                else
1570 > #endif
1571 >                                        update_display();
1572  
1573                                  // Set new cursor image if it was changed
1574                                  if (cursor_changed) {
# Line 1391 | Line 1583 | static void *redraw_func(void *arg)
1583                                  }
1584                          }
1585                  }
1586 + #ifdef ENABLE_VOSF
1587 +                else if (use_vosf) {
1588 +                        // Update display (VOSF variant)
1589 +                        static int tick_counter = 0;
1590 +                        if (++tick_counter >= frame_skip) {
1591 +                                tick_counter = 0;
1592 +                                if (mainBuffer.dirty) {
1593 +                                        LOCK_VOSF;
1594 +                                        update_display_dga_vosf();
1595 +                                        UNLOCK_VOSF;
1596 +                                }
1597 +                        }
1598 +                }
1599 + #endif
1600  
1601                  // Set new palette if it was changed
1602                  if (palette_changed && !emul_suspended) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines