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); } /*