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

Comparing BasiliskII/src/Unix/video_x.cpp (file contents):
Revision 1.31 by cebix, 2000-11-30T16:09:03Z vs.
Revision 1.36 by gbeauche, 2001-01-28T14:05:19Z

# Line 1 | Line 1
1   /*
2   *  video_x.cpp - Video/graphics emulation, X11 specific stuff
3   *
4 < *  Basilisk II (C) 1997-2000 Christian Bauer
4 > *  Basilisk II (C) 1997-2001 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 197 | Line 197 | struct ScreenInfo {
197      int pageBits;                               // Shift count to get the page number
198      uint32 pageCount;                   // Number of pages allocated to the screen
199      
200 <    uint8 * dirtyPages;                 // Table of flags set if page was altered
200 >        bool dirty;                                     // Flag: set if the frame buffer was touched
201 >    char * dirtyPages;                  // Table of flags set if page was altered
202      ScreenPageInfo * pageInfo;  // Table of mappings page -> Mac scanlines
203   };
204  
205   static ScreenInfo mainBuffer;
206  
207 < #define PFLAG_SET(page)                 mainBuffer.dirtyPages[page] = 1
208 < #define PFLAG_CLEAR(page)               mainBuffer.dirtyPages[page] = 0
209 < #define PFLAG_ISSET(page)               mainBuffer.dirtyPages[page]
210 < #define PFLAG_ISCLEAR(page)             (mainBuffer.dirtyPages[page] == 0)
207 > #define PFLAG_SET_VALUE                 0x00
208 > #define PFLAG_CLEAR_VALUE               0x01
209 > #define PFLAG_SET_VALUE_4               0x00000000
210 > #define PFLAG_CLEAR_VALUE_4             0x01010101
211 > #define PFLAG_SET(page)                 mainBuffer.dirtyPages[page] = PFLAG_SET_VALUE
212 > #define PFLAG_CLEAR(page)               mainBuffer.dirtyPages[page] = PFLAG_CLEAR_VALUE
213 > #define PFLAG_ISSET(page)               (mainBuffer.dirtyPages[page] == PFLAG_SET_VALUE)
214 > #define PFLAG_ISCLEAR(page)             (mainBuffer.dirtyPages[page] != PFLAG_SET_VALUE)
215 >
216   #ifdef UNALIGNED_PROFITABLE
217 < # define PFLAG_ISCLEAR_4(page)  (*((uint32 *)(mainBuffer.dirtyPages + page)) == 0)
217 > # define PFLAG_ISSET_4(page)    (*((uint32 *)(mainBuffer.dirtyPages + (page))) == PFLAG_SET_VALUE_4)
218 > # define PFLAG_ISCLEAR_4(page)  (*((uint32 *)(mainBuffer.dirtyPages + (page))) == PFLAG_CLEAR_VALUE_4)
219 > #else
220 > # define PFLAG_ISSET_4(page) \
221 >                PFLAG_ISSET(page  ) && PFLAG_ISSET(page+1) \
222 >        &&      PFLAG_ISSET(page+2) && PFLAG_ISSET(page+3)
223 > # define PFLAG_ISCLEAR_4(page) \
224 >                PFLAG_ISCLEAR(page  ) && PFLAG_ISCLEAR(page+1) \
225 >        &&      PFLAG_ISCLEAR(page+2) && PFLAG_ISCLEAR(page+3)
226 > #endif
227 >
228 > // Set the selected page range [ first_page, last_page [ into the SET state
229 > #define PFLAG_SET_RANGE(first_page, last_page) \
230 >        memset(mainBuffer.dirtyPages + (first_page), PFLAG_SET_VALUE, \
231 >                (last_page) - (first_page))
232 >
233 > // Set the selected page range [ first_page, last_page [ into the CLEAR state
234 > #define PFLAG_CLEAR_RANGE(first_page, last_page) \
235 >        memset(mainBuffer.dirtyPages + (first_page), PFLAG_CLEAR_VALUE, \
236 >                (last_page) - (first_page))
237 >
238 > #define PFLAG_SET_ALL do { \
239 >        PFLAG_SET_RANGE(0, mainBuffer.pageCount); \
240 >        mainBuffer.dirty = true; \
241 > } while (0)
242 >
243 > #define PFLAG_CLEAR_ALL do { \
244 >        PFLAG_CLEAR_RANGE(0, mainBuffer.pageCount); \
245 >        mainBuffer.dirty = false; \
246 > } while (0)
247 >
248 > // Set the following macro definition to 1 if your system
249 > // provides a really fast strchr() implementation
250 > //#define HAVE_FAST_STRCHR 0
251 >
252 > static inline int find_next_page_set(int page)
253 > {
254 > #if HAVE_FAST_STRCHR
255 >        char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_SET_VALUE);
256 >        return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount;
257   #else
258 < # define PFLAG_ISCLEAR_4(page)  \
259 <                (mainBuffer.dirtyPages[page  ] == 0) \
260 <        &&      (mainBuffer.dirtyPages[page+1] == 0) \
261 <        &&      (mainBuffer.dirtyPages[page+2] == 0) \
262 <        &&      (mainBuffer.dirtyPages[page+3] == 0)
258 >        while (PFLAG_ISCLEAR_4(page))
259 >                page += 4;
260 >        while (PFLAG_ISCLEAR(page))
261 >                page++;
262 >        return page;
263   #endif
264 < #define PFLAG_CLEAR_ALL                 memset(mainBuffer.dirtyPages, 0, mainBuffer.pageCount)
265 < #define PFLAG_SET_ALL                   memset(mainBuffer.dirtyPages, 1, mainBuffer.pageCount)
264 > }
265 >
266 > static inline int find_next_page_clear(int page)
267 > {
268 > #if HAVE_FAST_STRCHR
269 >        char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_CLEAR_VALUE);
270 >        return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount;
271 > #else
272 >        while (PFLAG_ISSET_4(page))
273 >                page += 4;
274 >        while (PFLAG_ISSET(page))
275 >                page++;
276 >        return page;
277 > #endif
278 > }
279  
280   static int zero_fd = -1;
281   static bool Screen_fault_handler_init();
# Line 242 | Line 300 | static int log_base_2(uint32 x)
300          }
301          return l;
302   }
303 <
246 < #endif
303 > #endif /* ENABLE_VOSF */
304  
305   // VideoRefresh function
306   void VideoRefreshInit(void);
# Line 334 | Line 391 | static void set_window_name(Window w, in
391                  hints->res_name = "BasiliskII";
392                  hints->res_class = "BasiliskII";
393                  XSetClassHint(x_display, w, hints);
394 <                XFree((char *)hints);
394 >                XFree(hints);
395          }
396   }
397  
# Line 347 | Line 404 | static void set_window_focus(Window w)
404                  hints->initial_state = NormalState;
405                  hints->flags = InputHint | StateHint;
406                  XSetWMHints(x_display, w, hints);
407 <                XFree((char *)hints);
407 >                XFree(hints);
408          }
409   }
410  
# Line 428 | Line 485 | static bool init_window(int width, int h
485                          hints->max_height = height;
486                          hints->flags = PMinSize | PMaxSize;
487                          XSetWMNormalHints(x_display, the_win, hints);
488 <                        XFree((char *)hints);
488 >                        XFree(hints);
489                  }
490          }
491          
# Line 523 | Line 580 | static bool init_window(int width, int h
580          native_byte_order = (XImageByteOrder(x_display) == LSBFirst);
581   #endif
582   #ifdef ENABLE_VOSF
583 <        do_update_framebuffer = GET_FBCOPY_FUNC(depth, native_byte_order, DISPLAY_WINDOW);
583 >        Screen_blitter_init(&visualInfo, native_byte_order);
584   #endif
585          set_video_monitor(width, height, img->bytes_per_line, native_byte_order);
586          
# Line 662 | Line 719 | static bool init_fbdev_dga(char *in_fb_n
719          
720   #if ENABLE_VOSF
721   #if REAL_ADDRESSING || DIRECT_ADDRESSING
722 <        // If the blit function is null, i.e. just a copy of the buffer,
723 <        // we first try to avoid the allocation of a temporary frame buffer
724 <        use_vosf = true;
668 <        do_update_framebuffer = GET_FBCOPY_FUNC(depth, true, DISPLAY_DGA);
669 <        if (do_update_framebuffer == FBCOPY_FUNC(fbcopy_raw))
670 <                use_vosf = false;
722 >        // Screen_blitter_init() returns TRUE if VOSF is mandatory
723 >        // i.e. the framebuffer update function is not Blit_Copy_Raw
724 >        use_vosf = Screen_blitter_init(&visualInfo, true);
725          
726          if (use_vosf) {
727                  the_host_buffer = the_buffer;
# Line 772 | Line 826 | static bool init_xf86_dga(int width, int
826          }
827          
828   #if REAL_ADDRESSING || DIRECT_ADDRESSING
829 <        // If the blit function is null, i.e. just a copy of the buffer,
830 <        // we first try to avoid the allocation of a temporary frame buffer
831 <        use_vosf = true;
778 <        do_update_framebuffer = GET_FBCOPY_FUNC(depth, true, DISPLAY_DGA);
779 <        if (do_update_framebuffer == FBCOPY_FUNC(fbcopy_raw))
780 <                use_vosf = false;
829 >        // Screen_blitter_init() returns TRUE if VOSF is mandatory
830 >        // i.e. the framebuffer update function is not Blit_Copy_Raw
831 >        use_vosf = Screen_blitter_init(&visualInfo, true);
832          
833          if (use_vosf) {
834                  the_host_buffer = the_buffer;
# Line 891 | Line 942 | bool VideoInitBuffer()
942                  if (mainBuffer.dirtyPages != 0)
943                          free(mainBuffer.dirtyPages);
944  
945 <                mainBuffer.dirtyPages = (uint8 *) malloc(mainBuffer.pageCount);
945 >                mainBuffer.dirtyPages = (char *) malloc(mainBuffer.pageCount + 2);
946  
947                  if (mainBuffer.pageInfo != 0)
948                          free(mainBuffer.pageInfo);
# Line 900 | Line 951 | bool VideoInitBuffer()
951  
952                  if ((mainBuffer.dirtyPages == 0) || (mainBuffer.pageInfo == 0))
953                          return false;
954 +                
955 +                mainBuffer.dirty = false;
956  
957                  PFLAG_CLEAR_ALL;
958 +                // Safety net to insure the loops in the update routines will terminate
959 +                // See a discussion in <video_vosf.h> for further details
960 +                PFLAG_CLEAR(mainBuffer.pageCount);
961 +                PFLAG_SET(mainBuffer.pageCount+1);
962  
963                  uint32 a = 0;
964                  for (int i = 0; i < mainBuffer.pageCount; i++) {
# Line 954 | Line 1011 | bool VideoInit(bool classic)
1011          keycode_init();
1012  
1013          // Read prefs
1014 <        mouse_wheel_mode = PrefsFindInt16("mousewheelmode");
1015 <        mouse_wheel_lines = PrefsFindInt16("mousewheellines");
1014 >        mouse_wheel_mode = PrefsFindInt32("mousewheelmode");
1015 >        mouse_wheel_lines = PrefsFindInt32("mousewheellines");
1016  
1017          // Find screen and root window
1018          screen = XDefaultScreen(x_display);
# Line 1893 | Line 1950 | static void update_display_static(void)
1950   *      Screen refresh functions
1951   */
1952  
1953 < // The specialisations hereunder are meant to enable VOSF with DGA in direct
1954 < // addressing mode in case the address spaces (RAM, ROM, FrameBuffer) could
1955 < // not get mapped correctly with respect to the predetermined host frame
1956 < // buffer base address.
1957 < //
1901 < // Hmm, in other words, when in direct addressing mode and DGA is requested,
1902 < // we first try to "triple allocate" the address spaces according to the real
1903 < // host frame buffer address. Then, if it fails, we will use a temporary
1904 < // frame buffer thus making the real host frame buffer updated when pages
1905 < // of the temp frame buffer are altered.
1906 < //
1907 < // As a side effect, a little speed gain in screen updates could be noticed
1908 < // for other modes than DGA.
1909 < //
1910 < // The following two functions below are inline so that a clever compiler
1911 < // could specialise the code according to the current screen depth and
1912 < // display type. A more clever compiler would the job by itself though...
1913 < // (update_display_vosf is inlined as well)
1953 > // We suggest the compiler to inline the next two functions so that it
1954 > // may specialise the code according to the current screen depth and
1955 > // display type. A clever compiler would do that job by itself though...
1956 >
1957 > // NOTE: update_display_vosf is inlined too
1958  
1959   static inline void possibly_quit_dga_mode()
1960   {
# Line 1981 | Line 2025 | static void video_refresh_dga_vosf(void)
2025          static int tick_counter = 0;
2026          if (++tick_counter >= frame_skip) {
2027                  tick_counter = 0;
2028 <                LOCK_VOSF;
2029 <                update_display_dga_vosf();
2030 <                UNLOCK_VOSF;
2028 >                if (mainBuffer.dirty) {
2029 >                        LOCK_VOSF;
2030 >                        update_display_dga_vosf();
2031 >                        UNLOCK_VOSF;
2032 >                }
2033          }
2034   }
2035   #endif
# Line 2003 | Line 2049 | static void video_refresh_window_vosf(vo
2049          static int tick_counter = 0;
2050          if (++tick_counter >= frame_skip) {
2051                  tick_counter = 0;
2052 <                LOCK_VOSF;
2053 <                update_display_window_vosf();
2054 <                UNLOCK_VOSF;
2052 >                if (mainBuffer.dirty) {
2053 >                        LOCK_VOSF;
2054 >                        update_display_window_vosf();
2055 >                        UNLOCK_VOSF;
2056 >                }
2057          }
2058   }
2059   #endif // def ENABLE_VOSF
# Line 2092 | Line 2140 | static void *redraw_func(void *arg)
2140                  ticks++;
2141          }
2142          uint64 end = GetTicks_usec();
2143 <        printf("%Ld ticks in %Ld usec = %Ld ticks/sec\n", ticks, end - start, (end - start) / ticks);
2143 >        printf("%Ld ticks in %Ld usec = %Ld ticks/sec\n", ticks, end - start, ticks * 1000000 / (end - start));
2144          return NULL;
2145   }
2146   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines