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.4 by gbeauche, 2003-10-26T07:54:02Z

# 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 181 | Line 199 | static bool open_window(int width, int h
199  
200          // Try to create and attach SHM image
201          have_shm = false;
202 <        if (depth != 1 && XShmQueryExtension(x_display)) {
202 >        if (local_X11 && depth != 1 && XShmQueryExtension(x_display)) {
203  
204                  // Create SHM image ("height + 2" for safety)
205                  img = XShmCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
206                  shminfo.shmid = shmget(IPC_PRIVATE, (height + 2) * img->bytes_per_line, IPC_CREAT | 0777);
207 <                screen_base = (uint32)shmat(shminfo.shmid, 0, 0);
208 <                the_buffer = (uint8 *)screen_base;
191 <                shminfo.shmaddr = img->data = (char *)screen_base;
207 >                the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0);
208 >                shminfo.shmaddr = img->data = (char *)the_buffer_copy;
209                  shminfo.readOnly = False;
210  
211                  // Try to attach SHM image, catching errors
# Line 209 | Line 226 | static bool open_window(int width, int h
226  
227          // Create normal X image if SHM doesn't work ("height + 2" for safety)
228          if (!have_shm) {
229 <                int bytes_per_row = width;
229 >                int bytes_per_row = aligned_width;
230                  switch (depth) {
231                          case 1:
232                                  bytes_per_row /= 8;
# Line 223 | Line 240 | static bool open_window(int width, int h
240                                  bytes_per_row *= 4;
241                                  break;
242                  }
243 <                screen_base = (uint32)malloc((height + 2) * bytes_per_row);
244 <                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);
243 >                the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row);
244 >                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);
245          }
246  
247          // 1-Bit mode is big-endian
# Line 234 | Line 250 | static bool open_window(int width, int h
250          img->bitmap_bit_order = MSBFirst;
251      }
252  
253 <        // Allocate memory for frame buffer copy
254 <        the_buffer_copy = (uint8 *)malloc((height + 2) * img->bytes_per_line);
253 > #ifdef ENABLE_VOSF
254 >        use_vosf = true;
255 >        // Allocate memory for frame buffer (SIZE is extended to page-boundary)
256 >        the_host_buffer = the_buffer_copy;
257 >        the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line);
258 >        the_buffer = (uint8 *)vm_acquire(the_buffer_size);
259 >        the_buffer_copy = (uint8 *)malloc(the_buffer_size);
260 >        D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
261 > #else
262 >        // Allocate memory for frame buffer
263 >        the_buffer = (uint8 *)malloc((aligned_height + 2) * img->bytes_per_line);
264 >        D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy));
265 > #endif
266 >        screen_base = (uint32)the_buffer;
267  
268          // Create GC
269          the_gc = XCreateGC(x_display, the_win, 0, 0);
# Line 255 | Line 283 | static bool open_window(int width, int h
283          mac_cursor = XCreatePixmapCursor(x_display, cursor_map, cursor_mask_map, &black, &white, 0, 0);
284          cursor_changed = false;
285  
286 +        // Init blitting routines
287 +        bool native_byte_order;
288 + #ifdef WORDS_BIGENDIAN
289 +        native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
290 + #else
291 +        native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
292 + #endif
293 + #ifdef ENABLE_VOSF
294 +        Screen_blitter_init(&visualInfo, native_byte_order, depth);
295 + #endif
296 +
297          // Set bytes per row
298          VModes[cur_mode].viRowBytes = img->bytes_per_line;
299          XSync(x_display, false);
# Line 289 | Line 328 | static bool open_dga(int width, int heig
328          XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
329          XF86DGASetViewPort(x_display, screen, 0, 0);
330          XF86DGASetVidPage(x_display, screen, 0);
292        screen_base = (uint32)dga_screen_base;
331  
332          // Set colormap
333          if (depth == 8)
# Line 307 | Line 345 | static bool open_dga(int width, int heig
345                          bytes_per_row *= 4;
346                          break;
347          }
348 +
349 + #if ENABLE_VOSF
350 +        bool native_byte_order;
351 + #ifdef WORDS_BIGENDIAN
352 +        native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
353 + #else
354 +        native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
355 + #endif
356 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
357 +        // Screen_blitter_init() returns TRUE if VOSF is mandatory
358 +        // i.e. the framebuffer update function is not Blit_Copy_Raw
359 +        use_vosf = Screen_blitter_init(&visualInfo, native_byte_order, depth);
360 +        
361 +        if (use_vosf) {
362 +          // Allocate memory for frame buffer (SIZE is extended to page-boundary)
363 +          the_host_buffer = the_buffer;
364 +          the_buffer_size = page_extend((height + 2) * bytes_per_row);
365 +          the_buffer_copy = (uint8 *)malloc(the_buffer_size);
366 +          the_buffer = (uint8 *)vm_acquire(the_buffer_size);
367 +        }
368 + #else
369 +        use_vosf = false;
370 +        the_buffer = dga_screen_base;
371 + #endif
372 + #endif
373 +        screen_base = (uint32)the_buffer;
374 +
375          VModes[cur_mode].viRowBytes = bytes_per_row;
376          XSync(x_display, false);
377          return true;
# Line 333 | Line 398 | static bool open_display(void)
398                          depth = 8;
399                          break;
400                  case APPLE_16_BIT:
401 <                        depth = 16;
401 >                        depth = xdepth == 15 ? 15 : 16;
402                          break;
403                  case APPLE_32_BIT:
404                          depth = 32;
405                          break;
406          }
407 +
408 +        bool display_open = false;
409          if (display_type == DIS_SCREEN)
410 <                return open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
410 >                display_open = open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
411          else if (display_type == DIS_WINDOW)
412 <                return open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
413 <        else
414 <                return false;
412 >                display_open = open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
413 >
414 > #ifdef ENABLE_VOSF
415 >        if (use_vosf) {
416 >                // Initialize the VOSF system
417 >                if (!video_vosf_init()) {
418 >                        ErrorAlert(GetString(STR_VOSF_INIT_ERR));
419 >                        return false;
420 >                }
421 >        }
422 > #endif
423 >        
424 >        return display_open;
425   }
426  
427  
# Line 355 | Line 432 | static bool open_display(void)
432   // Close window
433   static void close_window(void)
434   {
435 +        if (have_shm) {
436 +                XShmDetach(x_display, &shminfo);
437 + #ifdef ENABLE_VOSF
438 +                the_host_buffer = NULL; // don't free() in driver_base dtor
439 + #else
440 +                the_buffer_copy = NULL; // don't free() in driver_base dtor
441 + #endif
442 +        }
443 +        if (img) {
444 +                if (!have_shm)
445 +                        img->data = NULL;
446 +                XDestroyImage(img);
447 +        }
448 +        if (have_shm) {
449 +                shmdt(shminfo.shmaddr);
450 +                shmctl(shminfo.shmid, IPC_RMID, 0);
451 +        }
452 +        if (the_gc)
453 +                XFreeGC(x_display, the_gc);
454 +
455          // Close window
456          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        }
457   }
458  
459   // Close DGA mode
# Line 378 | Line 469 | static void close_dga(void)
469          if (has_vidmode)
470                  XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]);
471   #endif
472 +
473 +        if (!use_vosf) {
474 +                // don't free() the screen buffer in driver_base dtor
475 +                the_buffer = NULL;
476 +        }
477 + #ifdef ENABLE_VOSF
478 +        else {
479 +                // don't free() the screen buffer in driver_base dtor
480 +                the_host_buffer = NULL;
481 +        }
482 + #endif
483   }
484  
485   static void close_display(void)
# Line 386 | Line 488 | static void close_display(void)
488                  close_dga();
489          else if (display_type == DIS_WINDOW)
490                  close_window();
491 +
492 + #ifdef ENABLE_VOSF
493 +        if (use_vosf) {
494 +                // Deinitialize VOSF
495 +                video_vosf_exit();
496 +        }
497 + #endif
498 +
499 +        // Free frame buffer(s)
500 +        if (!use_vosf) {
501 +                if (the_buffer_copy) {
502 +                        free(the_buffer_copy);
503 +                        the_buffer_copy = NULL;
504 +                }
505 +        }
506 + #ifdef ENABLE_VOSF
507 +        else {
508 +                // the_buffer shall always be mapped through vm_acquire() so that we can vm_protect() it at will
509 +                if (the_buffer != VM_MAP_FAILED) {
510 +                        D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size));
511 +                        vm_release(the_buffer, the_buffer_size);
512 +                        the_buffer = NULL;
513 +                }
514 +                if (the_host_buffer) {
515 +                        D(bug(" freeing the_host_buffer at %p\n", the_host_buffer));
516 +                        free(the_host_buffer);
517 +                        the_host_buffer = NULL;
518 +                }
519 +                if (the_buffer_copy) {
520 +                        D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy));
521 +                        free(the_buffer_copy);
522 +                        the_buffer_copy = NULL;
523 +                }
524 +        }
525 + #endif
526   }
527  
528  
# Line 456 | Line 593 | static bool has_mode(int x, int y)
593  
594   bool VideoInit(void)
595   {
596 + #ifdef ENABLE_VOSF
597 +        // Zero the mainBuffer structure
598 +        mainBuffer.dirtyPages = NULL;
599 +        mainBuffer.pageInfo = NULL;
600 + #endif
601 +        
602 +        // Check if X server runs on local machine
603 +        local_X11 = (strncmp(XDisplayName(x_display_name), ":", 1) == 0)
604 +                 || (strncmp(XDisplayName(x_display_name), "unix:", 5) == 0);
605 +    
606          // Init variables
607          private_data = NULL;
608          cur_mode = 0;   // Window 640x480
# Line 471 | Line 618 | bool VideoInit(void)
618   #ifdef ENABLE_XF86_DGA
619          // DGA available?
620      int event_base, error_base;
621 <    if (XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
621 >    if (local_X11 && XF86DGAQueryExtension(x_display, &event_base, &error_base)) {
622                  int dga_flags = 0;
623                  XF86DGAQueryDirectVideo(x_display, screen, &dga_flags);
624                  has_dga = dga_flags & XF86DGADirectPresent;
# Line 652 | Line 799 | void VideoExit(void)
799                  redraw_thread_active = false;
800          }
801  
802 + #ifdef ENABLE_VOSF
803 +        if (use_vosf) {
804 +                // Deinitialize VOSF
805 +                video_vosf_exit();
806 +        }
807 + #endif
808 +
809          // Close window and server connection
810          if (x_display != NULL) {
811                  XSync(x_display, false);
# Line 729 | Line 883 | static void resume_emul(void)
883          XF86DGASetViewPort(x_display, screen, 0, 0);
884          XSync(x_display, false);
885  
886 +        // the_buffer already contains the data to restore. i.e. since a temporary
887 +        // frame buffer is used when VOSF is actually used, fb_save is therefore
888 +        // not necessary.
889 + #ifdef ENABLE_VOSF
890 +        if (use_vosf) {
891 +                LOCK_VOSF;
892 +                PFLAG_SET_ALL;
893 +                UNLOCK_VOSF;
894 +                memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
895 +        }
896 + #endif
897 +        
898          // Restore frame buffer
899          if (fb_save) {
900 + #ifdef ENABLE_VOSF
901 +                // Don't copy fb_save to the temporary frame buffer in VOSF mode
902 +                if (!use_vosf)
903 + #endif
904                  memcpy((void *)screen_base, fb_save, VModes[cur_mode].viYsize * VModes[cur_mode].viRowBytes);
905                  free(fb_save);
906                  fb_save = NULL;
# Line 979 | Line 1149 | static void handle_events(void)
1149  
1150                          // Hidden parts exposed, force complete refresh
1151                          case Expose:
1152 + #ifdef ENABLE_VOSF
1153 +                                if (use_vosf) {                 // VOSF refresh
1154 +                                        LOCK_VOSF;
1155 +                                        PFLAG_SET_ALL;
1156 +                                        UNLOCK_VOSF;
1157 +                                }
1158 + #endif
1159                                  memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1160                                  break;
1161                  }
# Line 1376 | Line 1553 | static void *redraw_func(void *arg)
1553                                  tick_counter = 0;
1554  
1555                                  // Update display
1556 <                                update_display();
1556 > #ifdef ENABLE_VOSF
1557 >                                if (use_vosf) {
1558 >                                        if (mainBuffer.dirty) {
1559 >                                                LOCK_VOSF;
1560 >                                                update_display_window_vosf();
1561 >                                                UNLOCK_VOSF;
1562 >                                                XSync(x_display, false); // Let the server catch up
1563 >                                        }
1564 >                                }
1565 >                                else
1566 > #endif
1567 >                                        update_display();
1568  
1569                                  // Set new cursor image if it was changed
1570                                  if (cursor_changed) {
# Line 1391 | Line 1579 | static void *redraw_func(void *arg)
1579                                  }
1580                          }
1581                  }
1582 + #ifdef ENABLE_VOSF
1583 +                else if (use_vosf) {
1584 +                        // Update display (VOSF variant)
1585 +                        static int tick_counter = 0;
1586 +                        if (++tick_counter >= frame_skip) {
1587 +                                tick_counter = 0;
1588 +                                if (mainBuffer.dirty) {
1589 +                                        LOCK_VOSF;
1590 +                                        update_display_dga_vosf();
1591 +                                        UNLOCK_VOSF;
1592 +                                }
1593 +                        }
1594 +                }
1595 + #endif
1596  
1597                  // Set new palette if it was changed
1598                  if (palette_changed && !emul_suspended) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines