So even when you set the RI_WRONLY or RI_VCONS flag, the rasops code
still does framebuffer reads when it draws the cursor.  This causes
problems on a particular (somewhat broken) machine I have.  But since
we know that framebuffer reads are quite expensive on other machines,
I think it makes sense to fix this.

The existing code would xor the cursor position with 0xffffffff.  This
implementation instead redraws the character at the cursor position
with foreground and background color reversed.  That isn't the same
thing, but I think it is a sensible approach and for most cases you
wouldn't be able to tell the difference.

ok?


Index: dev/rasops/rasops.c
===================================================================
RCS file: /cvs/src/sys/dev/rasops/rasops.c,v
retrieving revision 1.54
diff -u -p -r1.54 rasops.c
--- dev/rasops/rasops.c 3 May 2018 10:05:47 -0000       1.54
+++ dev/rasops/rasops.c 20 Aug 2018 10:25:15 -0000
@@ -130,6 +130,22 @@ const u_char rasops_isgray[16] = {
        0, 0, 0, 1
 };
 
+struct rasops_screen {
+       LIST_ENTRY(rasops_screen) rs_next;
+       struct rasops_info *rs_ri;
+
+       struct wsdisplay_charcell *rs_bs;
+       int rs_visible;
+       int rs_crow;
+       int rs_ccol;
+       long rs_defattr;
+
+       int rs_sbscreens;
+#define RS_SCROLLBACK_SCREENS 5
+       int rs_dispoffset;      /* rs_bs index, start of our actual screen */
+       int rs_visibleoffset;   /* rs_bs index, current scrollback screen */
+};
+
 /* Generic functions */
 int    rasops_copycols(void *, int, int, int, int);
 int    rasops_copyrows(void *, int, int, int);
@@ -179,6 +195,7 @@ int rasops_wronly_copycols(void *, int, 
 int    rasops_wronly_erasecols(void *, int, int, int, long);
 int    rasops_wronly_copyrows(void *, int, int, int);
 int    rasops_wronly_eraserows(void *, int, int, long);
+int    rasops_wronly_do_cursor(struct rasops_info *);
 
 int    rasops_add_font(struct rasops_info *, struct wsdisplay_font *);
 int    rasops_use_font(struct rasops_info *, struct wsdisplay_font *);
@@ -268,6 +285,7 @@ rasops_init(struct rasops_info *ri, int 
                        return (-1);
 
                ri->ri_active = cookie;
+               ri->ri_bs = ri->ri_active->rs_bs;
 
                ri->ri_ops.cursor = rasops_vcons_cursor;
                ri->ri_ops.mapchar = rasops_vcons_mapchar;
@@ -278,6 +296,7 @@ rasops_init(struct rasops_info *ri, int 
                ri->ri_ops.eraserows = rasops_vcons_eraserows;
                ri->ri_ops.alloc_attr = rasops_vcons_alloc_attr;
                ri->ri_ops.unpack_attr = rasops_vcons_unpack_attr;
+               ri->ri_do_cursor = rasops_wronly_do_cursor;
        } else if ((ri->ri_flg & RI_WRONLY) && ri->ri_bs != NULL) {
                long attr;
                int i;
@@ -287,6 +306,7 @@ rasops_init(struct rasops_info *ri, int 
                ri->ri_ops.erasecols = rasops_wronly_erasecols;
                ri->ri_ops.copyrows = rasops_wronly_copyrows;
                ri->ri_ops.eraserows = rasops_wronly_eraserows;
+               ri->ri_do_cursor = rasops_wronly_do_cursor;
 
                ri->ri_alloc_attr(ri, 0, 0, 0, &attr);
                for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) {
@@ -1365,22 +1385,6 @@ slow_bcopy(void *s, void *d, size_t len)
 }
 #endif /* NRASOPS_BSWAP */
 
-struct rasops_screen {
-       LIST_ENTRY(rasops_screen) rs_next;
-       struct rasops_info *rs_ri;
-
-       struct wsdisplay_charcell *rs_bs;
-       int rs_visible;
-       int rs_crow;
-       int rs_ccol;
-       long rs_defattr;
-
-       int rs_sbscreens;
-#define RS_SCROLLBACK_SCREENS 5
-       int rs_dispoffset;      /* rs_bs index, start of our actual screen */
-       int rs_visibleoffset;   /* rs_bs index, current scrollback screen */
-};
-
 int
 rasops_alloc_screen(void *v, void **cookiep,
     int *curxp, int *curyp, long *attrp)
@@ -1482,6 +1486,7 @@ rasops_doswitch(void *v)
        ri->ri_active->rs_visible = 0;
        ri->ri_eraserows(ri, 0, ri->ri_rows, scr->rs_defattr);
        ri->ri_active = scr;
+       ri->ri_bs = ri->ri_active->rs_bs;
        ri->ri_active->rs_visible = 1;
        ri->ri_active->rs_visibleoffset = ri->ri_active->rs_dispoffset;
        for (row = 0; row < ri->ri_rows; row++) {
@@ -1767,6 +1772,27 @@ rasops_wronly_eraserows(void *cookie, in
        }
 
        return ri->ri_eraserows(ri, row, num, attr);
+}
+
+int
+rasops_wronly_do_cursor(struct rasops_info *ri)
+{
+       int off = ri->ri_crow * ri->ri_cols + ri->ri_ccol;
+       u_int uc;
+       long attr;
+       int fg, bg;
+
+       uc = ri->ri_bs[off].uc;
+       attr = ri->ri_bs[off].attr;
+
+       if ((ri->ri_flg & RI_CURSOR) == 0) {
+               fg = ((u_int)attr >> 24) & 0xf;
+               bg = ((u_int)attr >> 16) & 0xf;
+               attr &= ~0x0ffff0000;
+               attr |= (fg << 16) | (bg << 24);
+       }
+
+       return ri->ri_putchar(ri, ri->ri_crow, ri->ri_ccol, uc, attr);
 }
 
 /*

Reply via email to