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.2 by gbeauche, 2002-04-21T11:47:18Z vs.
Revision 1.3 by gbeauche, 2003-05-22T22:12:05Z

# Line 58 | Line 58 | static volatile bool thread_stop_ack = f
58   static bool has_dga = false;                            // Flag: Video DGA capable
59   static bool has_vidmode = false;                        // Flag: VidMode extension available
60  
61 + #ifdef ENABLE_VOSF
62 + static bool use_vosf = true;                            // Flag: VOSF enabled
63 + #else
64 + static const bool use_vosf = false;                     // VOSF not possible
65 + #endif
66 +
67   static bool palette_changed = false;            // Flag: Palette changed, redraw thread must update palette
68   static bool ctrl_down = false;                          // Flag: Ctrl key pressed
69   static bool quit_full_screen = false;           // Flag: DGA close requested from redraw thread
# Line 92 | Line 98 | static Cursor mac_cursor;
98   static GC cursor_gc, cursor_mask_gc;
99   static bool cursor_changed = false;                     // Flag: Cursor changed, window_func must update cursor
100   static bool have_shm = false;                           // Flag: SHM present and usable
101 < static uint8 *the_buffer;                                       // Pointer to Mac frame buffer
101 > static uint8 *the_buffer = NULL;                        // Pointer to Mac frame buffer
102   static uint8 *the_buffer_copy = NULL;           // Copy of Mac frame buffer
103 + static uint32 the_buffer_size;                          // Size of allocated the_buffer
104  
105   // Variables for DGA mode
106   static char *dga_screen_base;
# Line 118 | Line 125 | extern Display *x_display;
125   extern void SysMountFirstFloppy(void);
126  
127  
128 + // Video acceleration through SIGSEGV
129 + #ifdef ENABLE_VOSF
130 + # include "video_vosf.h"
131 + #endif
132 +
133 +
134   /*
135   *  Open display (window or fullscreen)
136   */
# Line 138 | Line 151 | static int error_handler(Display *d, XEr
151   // Open window
152   static bool open_window(int width, int height)
153   {
154 +        int aligned_width = (width + 15) & ~15;
155 +        int aligned_height = (height + 15) & ~15;
156 +
157          // Set absolute mouse mode
158          ADBSetRelMouseMode(false);
159  
# Line 186 | Line 202 | static bool open_window(int width, int h
202                  // Create SHM image ("height + 2" for safety)
203                  img = XShmCreateImage(x_display, vis, depth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height);
204                  shminfo.shmid = shmget(IPC_PRIVATE, (height + 2) * img->bytes_per_line, IPC_CREAT | 0777);
205 <                screen_base = (uint32)shmat(shminfo.shmid, 0, 0);
206 <                the_buffer = (uint8 *)screen_base;
191 <                shminfo.shmaddr = img->data = (char *)screen_base;
205 >                the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0);
206 >                shminfo.shmaddr = img->data = (char *)the_buffer_copy;
207                  shminfo.readOnly = False;
208  
209                  // Try to attach SHM image, catching errors
# Line 209 | Line 224 | static bool open_window(int width, int h
224  
225          // Create normal X image if SHM doesn't work ("height + 2" for safety)
226          if (!have_shm) {
227 <                int bytes_per_row = width;
227 >                int bytes_per_row = aligned_width;
228                  switch (depth) {
229                          case 1:
230                                  bytes_per_row /= 8;
# Line 223 | Line 238 | static bool open_window(int width, int h
238                                  bytes_per_row *= 4;
239                                  break;
240                  }
241 <                screen_base = (uint32)malloc((height + 2) * bytes_per_row);
242 <                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);
241 >                the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row);
242 >                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);
243          }
244  
245          // 1-Bit mode is big-endian
# Line 234 | Line 248 | static bool open_window(int width, int h
248          img->bitmap_bit_order = MSBFirst;
249      }
250  
251 <        // Allocate memory for frame buffer copy
252 <        the_buffer_copy = (uint8 *)malloc((height + 2) * img->bytes_per_line);
251 > #ifdef ENABLE_VOSF
252 >        use_vosf = true;
253 >        // Allocate memory for frame buffer (SIZE is extended to page-boundary)
254 >        the_host_buffer = the_buffer_copy;
255 >        the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line);
256 >        the_buffer = (uint8 *)vm_acquire(the_buffer_size);
257 >        the_buffer_copy = (uint8 *)malloc(the_buffer_size);
258 >        D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
259 > #else
260 >        // Allocate memory for frame buffer
261 >        the_buffer = (uint8 *)malloc((aligned_height + 2) * img->bytes_per_line);
262 >        D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy));
263 > #endif
264 >        screen_base = (uint32)the_buffer;
265  
266          // Create GC
267          the_gc = XCreateGC(x_display, the_win, 0, 0);
# Line 255 | Line 281 | static bool open_window(int width, int h
281          mac_cursor = XCreatePixmapCursor(x_display, cursor_map, cursor_mask_map, &black, &white, 0, 0);
282          cursor_changed = false;
283  
284 +        // Init blitting routines
285 +        bool native_byte_order;
286 + #ifdef WORDS_BIGENDIAN
287 +        native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
288 + #else
289 +        native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
290 + #endif
291 + #ifdef ENABLE_VOSF
292 +        Screen_blitter_init(&visualInfo, native_byte_order, depth);
293 + #endif
294 +
295          // Set bytes per row
296          VModes[cur_mode].viRowBytes = img->bytes_per_line;
297          XSync(x_display, false);
# Line 289 | Line 326 | static bool open_dga(int width, int heig
326          XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse);
327          XF86DGASetViewPort(x_display, screen, 0, 0);
328          XF86DGASetVidPage(x_display, screen, 0);
292        screen_base = (uint32)dga_screen_base;
329  
330          // Set colormap
331          if (depth == 8)
# Line 307 | Line 343 | static bool open_dga(int width, int heig
343                          bytes_per_row *= 4;
344                          break;
345          }
346 +
347 + #if ENABLE_VOSF
348 +        bool native_byte_order;
349 + #ifdef WORDS_BIGENDIAN
350 +        native_byte_order = (XImageByteOrder(x_display) == MSBFirst);
351 + #else
352 +        native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
353 + #endif
354 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
355 +        // Screen_blitter_init() returns TRUE if VOSF is mandatory
356 +        // i.e. the framebuffer update function is not Blit_Copy_Raw
357 +        use_vosf = Screen_blitter_init(&visualInfo, native_byte_order, depth);
358 +        
359 +        if (use_vosf) {
360 +          // Allocate memory for frame buffer (SIZE is extended to page-boundary)
361 +          the_host_buffer = the_buffer;
362 +          the_buffer_size = page_extend((height + 2) * bytes_per_row);
363 +          the_buffer_copy = (uint8 *)malloc(the_buffer_size);
364 +          the_buffer = (uint8 *)vm_acquire(the_buffer_size);
365 +        }
366 + #else
367 +        use_vosf = false;
368 +        the_buffer = dga_screen_base;
369 + #endif
370 + #endif
371 +        screen_base = (uint32)the_buffer;
372 +
373          VModes[cur_mode].viRowBytes = bytes_per_row;
374          XSync(x_display, false);
375          return true;
# Line 339 | Line 402 | static bool open_display(void)
402                          depth = 32;
403                          break;
404          }
405 +
406 +        bool display_open = false;
407          if (display_type == DIS_SCREEN)
408 <                return open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
408 >                display_open = open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
409          else if (display_type == DIS_WINDOW)
410 <                return open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
411 <        else
412 <                return false;
410 >                display_open = open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize);
411 >
412 > #ifdef ENABLE_VOSF
413 >        if (use_vosf) {
414 >                // Initialize the VOSF system
415 >                if (!video_vosf_init()) {
416 >                        ErrorAlert(GetString(STR_VOSF_INIT_ERR));
417 >                        return false;
418 >                }
419 >        }
420 > #endif
421 >        
422 >        return display_open;
423   }
424  
425  
# Line 355 | Line 430 | static bool open_display(void)
430   // Close window
431   static void close_window(void)
432   {
433 +        if (have_shm) {
434 +                XShmDetach(x_display, &shminfo);
435 + #ifdef ENABLE_VOSF
436 +                the_host_buffer = NULL; // don't free() in driver_base dtor
437 + #else
438 +                the_buffer_copy = NULL; // don't free() in driver_base dtor
439 + #endif
440 +        }
441 +        if (img) {
442 +                if (!have_shm)
443 +                        img->data = NULL;
444 +                XDestroyImage(img);
445 +        }
446 +        if (have_shm) {
447 +                shmdt(shminfo.shmaddr);
448 +                shmctl(shminfo.shmid, IPC_RMID, 0);
449 +        }
450 +        if (the_gc)
451 +                XFreeGC(x_display, the_gc);
452 +
453          // Close window
454          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        }
455   }
456  
457   // Close DGA mode
# Line 378 | Line 467 | static void close_dga(void)
467          if (has_vidmode)
468                  XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]);
469   #endif
470 +
471 +        if (!use_vosf) {
472 +                // don't free() the screen buffer in driver_base dtor
473 +                the_buffer = NULL;
474 +        }
475 + #ifdef ENABLE_VOSF
476 +        else {
477 +                // don't free() the screen buffer in driver_base dtor
478 +                the_host_buffer = NULL;
479 +        }
480 + #endif
481   }
482  
483   static void close_display(void)
# Line 386 | Line 486 | static void close_display(void)
486                  close_dga();
487          else if (display_type == DIS_WINDOW)
488                  close_window();
489 +
490 + #ifdef ENABLE_VOSF
491 +        if (use_vosf) {
492 +                // Deinitialize VOSF
493 +                video_vosf_exit();
494 +        }
495 + #endif
496 +
497 +        // Free frame buffer(s)
498 +        if (!use_vosf) {
499 +                if (the_buffer_copy) {
500 +                        free(the_buffer_copy);
501 +                        the_buffer_copy = NULL;
502 +                }
503 +        }
504 + #ifdef ENABLE_VOSF
505 +        else {
506 +                // the_buffer shall always be mapped through vm_acquire() so that we can vm_protect() it at will
507 +                if (the_buffer != VM_MAP_FAILED) {
508 +                        D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size));
509 +                        vm_release(the_buffer, the_buffer_size);
510 +                        the_buffer = NULL;
511 +                }
512 +                if (the_host_buffer) {
513 +                        D(bug(" freeing the_host_buffer at %p\n", the_host_buffer));
514 +                        free(the_host_buffer);
515 +                        the_host_buffer = NULL;
516 +                }
517 +                if (the_buffer_copy) {
518 +                        D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy));
519 +                        free(the_buffer_copy);
520 +                        the_buffer_copy = NULL;
521 +                }
522 +        }
523 + #endif
524   }
525  
526  
# Line 456 | Line 591 | static bool has_mode(int x, int y)
591  
592   bool VideoInit(void)
593   {
594 + #ifdef ENABLE_VOSF
595 +        // Zero the mainBuffer structure
596 +        mainBuffer.dirtyPages = NULL;
597 +        mainBuffer.pageInfo = NULL;
598 + #endif
599 +        
600          // Init variables
601          private_data = NULL;
602          cur_mode = 0;   // Window 640x480
# Line 652 | Line 793 | void VideoExit(void)
793                  redraw_thread_active = false;
794          }
795  
796 + #ifdef ENABLE_VOSF
797 +        if (use_vosf) {
798 +                // Deinitialize VOSF
799 +                video_vosf_exit();
800 +        }
801 + #endif
802 +
803          // Close window and server connection
804          if (x_display != NULL) {
805                  XSync(x_display, false);
# Line 729 | Line 877 | static void resume_emul(void)
877          XF86DGASetViewPort(x_display, screen, 0, 0);
878          XSync(x_display, false);
879  
880 +        // the_buffer already contains the data to restore. i.e. since a temporary
881 +        // frame buffer is used when VOSF is actually used, fb_save is therefore
882 +        // not necessary.
883 + #ifdef ENABLE_VOSF
884 +        if (use_vosf) {
885 +                LOCK_VOSF;
886 +                PFLAG_SET_ALL;
887 +                UNLOCK_VOSF;
888 +                memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
889 +        }
890 + #endif
891 +        
892          // Restore frame buffer
893          if (fb_save) {
894 + #ifdef ENABLE_VOSF
895 +                // Don't copy fb_save to the temporary frame buffer in VOSF mode
896 +                if (!use_vosf)
897 + #endif
898                  memcpy((void *)screen_base, fb_save, VModes[cur_mode].viYsize * VModes[cur_mode].viRowBytes);
899                  free(fb_save);
900                  fb_save = NULL;
# Line 979 | Line 1143 | static void handle_events(void)
1143  
1144                          // Hidden parts exposed, force complete refresh
1145                          case Expose:
1146 + #ifdef ENABLE_VOSF
1147 +                                if (use_vosf) {                 // VOSF refresh
1148 +                                        LOCK_VOSF;
1149 +                                        PFLAG_SET_ALL;
1150 +                                        UNLOCK_VOSF;
1151 +                                }
1152 + #endif
1153                                  memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
1154                                  break;
1155                  }
# Line 1376 | Line 1547 | static void *redraw_func(void *arg)
1547                                  tick_counter = 0;
1548  
1549                                  // Update display
1550 <                                update_display();
1550 > #ifdef ENABLE_VOSF
1551 >                                if (use_vosf) {
1552 >                                        if (mainBuffer.dirty) {
1553 >                                                LOCK_VOSF;
1554 >                                                update_display_window_vosf();
1555 >                                                UNLOCK_VOSF;
1556 >                                                XSync(x_display, false); // Let the server catch up
1557 >                                        }
1558 >                                }
1559 >                                else
1560 > #endif
1561 >                                        update_display();
1562  
1563                                  // Set new cursor image if it was changed
1564                                  if (cursor_changed) {
# Line 1391 | Line 1573 | static void *redraw_func(void *arg)
1573                                  }
1574                          }
1575                  }
1576 + #ifdef ENABLE_VOSF
1577 +                else if (use_vosf) {
1578 +                        // Update display (VOSF variant)
1579 +                        static int tick_counter = 0;
1580 +                        if (++tick_counter >= frame_skip) {
1581 +                                tick_counter = 0;
1582 +                                if (mainBuffer.dirty) {
1583 +                                        LOCK_VOSF;
1584 +                                        update_display_dga_vosf();
1585 +                                        UNLOCK_VOSF;
1586 +                                }
1587 +                        }
1588 +                }
1589 + #endif
1590  
1591                  // Set new palette if it was changed
1592                  if (palette_changed && !emul_suspended) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines