Module Name: src Committed By: macallan Date: Wed Aug 18 16:46:51 UTC 2010
Modified Files: src/sys/dev/wscons: wsdisplay_vcons.c wsdisplay_vconsvar.h Log Message: Add copycols() and copyrows() methods which, instead of calling the underlying driver methods, call the driver's putchar() method to redraw the affected areas. For unaccelerated framebuffers where reads are expensive and we can't spare any memory for a shadow framebuffer. Enabled by setting VCONS_DONT_READ in scr_flags To generate a diff of this commit: cvs rdiff -u -r1.16 -r1.17 src/sys/dev/wscons/wsdisplay_vcons.c cvs rdiff -u -r1.10 -r1.11 src/sys/dev/wscons/wsdisplay_vconsvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/wscons/wsdisplay_vcons.c diff -u src/sys/dev/wscons/wsdisplay_vcons.c:1.16 src/sys/dev/wscons/wsdisplay_vcons.c:1.17 --- src/sys/dev/wscons/wsdisplay_vcons.c:1.16 Mon Apr 28 20:24:01 2008 +++ src/sys/dev/wscons/wsdisplay_vcons.c Wed Aug 18 16:46:51 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_vcons.c,v 1.16 2008/04/28 20:24:01 martin Exp $ */ +/* $NetBSD: wsdisplay_vcons.c,v 1.17 2010/08/18 16:46:51 macallan Exp $ */ /*- * Copyright (c) 2005, 2006 Michael Lorenz @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.16 2008/04/28 20:24:01 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.17 2010/08/18 16:46:51 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -89,6 +89,13 @@ static void vcons_putchar(void *, int, int, u_int, long); static void vcons_cursor(void *, int, int, int); +/* + * methods that avoid framebuffer reads + */ +static void vcons_copycols_noread(void *, int, int, int, int); +static void vcons_copyrows_noread(void *, int, int, int); + + /* support for reading/writing text buffers. For wsmoused */ static int vcons_putwschar(struct vcons_screen *, struct wsdisplay_char *); static int vcons_getwschar(struct vcons_screen *, struct wsdisplay_char *); @@ -223,11 +230,18 @@ vd->cursor = ri->ri_ops.cursor; ri->ri_ops.eraserows = vcons_eraserows; - ri->ri_ops.copyrows = vcons_copyrows; ri->ri_ops.erasecols = vcons_erasecols; - ri->ri_ops.copycols = vcons_copycols; ri->ri_ops.putchar = vcons_putchar; ri->ri_ops.cursor = vcons_cursor; + + if (scr->scr_flags & VCONS_DONT_READ) { + ri->ri_ops.copyrows = vcons_copyrows_noread; + ri->ri_ops.copycols = vcons_copycols_noread; + } else { + ri->ri_ops.copyrows = vcons_copyrows; + ri->ri_ops.copycols = vcons_copycols; + } + ri->ri_hw = scr; /* @@ -558,6 +572,33 @@ } static void +vcons_copycols_noread(void *cookie, int row, int srccol, int dstcol, int ncols) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + + vcons_copycols_buffer(cookie, row, srccol, dstcol, ncols); + + vcons_lock(scr); + if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) { + int pos, c, offset; + +#ifdef WSDISPLAY_SCROLLSUPPORT + offset = scr->scr_current_offset; +#else + offset = 0; +#endif + pos = ri->ri_cols * row + dstcol + offset; + for (c = dstcol; c < (dstcol + ncols); c++) { + scr->scr_vd->putchar(cookie, row, c, + scr->scr_chars[pos], scr->scr_attrs[pos]); + pos++; + } + } + vcons_unlock(scr); +} + +static void vcons_erasecols_buffer(void *cookie, int row, int startcol, int ncols, long fillattr) { struct rasops_info *ri = cookie; @@ -649,6 +690,35 @@ } static void +vcons_copyrows_noread(void *cookie, int srcrow, int dstrow, int nrows) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + + vcons_copyrows_buffer(cookie, srcrow, dstrow, nrows); + + vcons_lock(scr); + if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) { + int pos, l, c, offset; + +#ifdef WSDISPLAY_SCROLLSUPPORT + offset = scr->scr_current_offset; +#else + offset = 0; +#endif + pos = ri->ri_cols * dstrow + offset; + for (l = dstrow; l < (dstrow + nrows); l++) { + for (c = 0; c < ri->ri_cols; c++) { + scr->scr_vd->putchar(cookie, l, c, + scr->scr_chars[pos], scr->scr_attrs[pos]); + pos++; + } + } + } + vcons_unlock(scr); +} + +static void vcons_eraserows_buffer(void *cookie, int row, int nrows, long fillattr) { struct rasops_info *ri = cookie; Index: src/sys/dev/wscons/wsdisplay_vconsvar.h diff -u src/sys/dev/wscons/wsdisplay_vconsvar.h:1.10 src/sys/dev/wscons/wsdisplay_vconsvar.h:1.11 --- src/sys/dev/wscons/wsdisplay_vconsvar.h:1.10 Thu Aug 20 02:01:08 2009 +++ src/sys/dev/wscons/wsdisplay_vconsvar.h Wed Aug 18 16:46:51 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_vconsvar.h,v 1.10 2009/08/20 02:01:08 macallan Exp $ */ +/* $NetBSD: wsdisplay_vconsvar.h,v 1.11 2010/08/18 16:46:51 macallan Exp $ */ /*- * Copyright (c) 2005, 2006 Michael Lorenz @@ -53,6 +53,7 @@ * - for drivers that use software * drawing */ #define VCONS_DONT_DRAW 8 /* don't draw on this screen at all */ +#define VCONS_DONT_READ 0x10 /* avoid framebuffer reads */ /* status flags used by vcons */ uint32_t scr_status; #define VCONS_IS_VISIBLE 1 /* this screen is currently visible */