Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/wscons add a cache so when we update the screen we o...
details: https://anonhg.NetBSD.org/src/rev/3ee202c2e2ef
branches: trunk
changeset: 765397:3ee202c2e2ef
user: macallan <macallan%NetBSD.org@localhost>
date: Wed May 25 06:01:38 2011 +0000
description:
add a cache so when we update the screen we only redraw the character cells
that actually changed since last time. This gives a noticeable speedup on
slower hardware with dumb framebuffers.
For now this works with VCONS_DRAW_INTR and VCONS_DONT_READ only.
diffstat:
sys/dev/wscons/wsdisplay_vcons.c | 224 ++++++++++++++++++++++++++++++---
sys/dev/wscons/wsdisplay_vcons_util.c | 6 +-
sys/dev/wscons/wsdisplay_vconsvar.h | 15 ++-
3 files changed, 221 insertions(+), 24 deletions(-)
diffs (truncated from 466 to 300 lines):
diff -r 5d563af1a46e -r 3ee202c2e2ef sys/dev/wscons/wsdisplay_vcons.c
--- a/sys/dev/wscons/wsdisplay_vcons.c Wed May 25 05:42:37 2011 +0000
+++ b/sys/dev/wscons/wsdisplay_vcons.c Wed May 25 06:01:38 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wsdisplay_vcons.c,v 1.24 2011/02/18 13:56:11 jmcneill Exp $ */
+/* $NetBSD: wsdisplay_vcons.c,v 1.25 2011/05/25 06:01:38 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.24 2011/02/18 13:56:11 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.25 2011/05/25 06:01:38 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -102,6 +102,9 @@
static void vcons_copyrows(void *, int, int, int);
static void vcons_eraserows(void *, int, int, long);
static void vcons_putchar(void *, int, int, u_int, long);
+#ifdef VCONS_DRAW_INTR
+static void vcons_putchar_cached(void *, int, int, u_int, long);
+#endif
static void vcons_cursor(void *, int, int, int);
/*
@@ -159,6 +162,12 @@
vd->currenttype = def;
callout_init(&vd->switch_callout, 0);
callout_setfunc(&vd->switch_callout, vcons_do_switch, vd);
+#ifdef VCONS_DRAW_INTR
+ vd->cells = 0;
+ vd->attrs = NULL;
+ vd->chars = NULL;
+ vd->cursor_offset = -1;
+#endif
/*
* a lock to serialize access to the framebuffer.
@@ -234,6 +243,9 @@
{
struct rasops_info *ri = &scr->scr_ri;
int cnt, i;
+#ifdef VCONS_DRAW_INTR
+ int size;
+#endif
scr->scr_cookie = vd->cookie;
scr->scr_vd = scr->scr_origvd = vd;
@@ -313,6 +325,18 @@
scr->scr_chars[i] = 0x20;
}
+#ifdef VCONS_DRAW_INTR
+ size = ri->ri_cols * ri->ri_rows;
+ if (size > vd->cells) {
+ if (vd->chars != NULL) free(vd->chars, M_DEVBUF);
+ if (vd->attrs != NULL) free(vd->attrs, M_DEVBUF);
+ vd->cells = size;
+ vd->chars = malloc(size * sizeof(uint16_t), M_DEVBUF, M_WAITOK);
+ vd->attrs = malloc(size * sizeof(long), M_DEVBUF, M_WAITOK);
+ vcons_invalidate_cache(vd);
+ }
+#endif
+
if(vd->active == NULL) {
vd->active = scr;
SCREEN_VISIBLE(scr);
@@ -402,7 +426,8 @@
uint16_t *charptr = scr->scr_chars;
long *attrptr = scr->scr_attrs;
struct rasops_info *ri = &scr->scr_ri;
- int i, j, offset;
+ struct vcons_data *vd = scr->scr_vd;
+ int i, j, offset, boffset = 0;
vcons_lock(scr);
if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
@@ -412,7 +437,7 @@
* going to overwrite every single character cell anyway
*/
if (ri->ri_flg & RI_FULLCLEAR) {
- scr->scr_vd->eraserows(ri, 0, ri->ri_rows,
+ vd->eraserows(ri, 0, ri->ri_rows,
scr->scr_defattr);
}
@@ -430,17 +455,80 @@
* and we already made sure the screen we're
* working on is visible
*/
- scr->scr_vd->putchar(ri, i, j,
+ vd->putchar(ri, i, j,
charptr[offset], attrptr[offset]);
+#ifdef VCONS_DRAW_INTR
+ vd->chars[boffset] = charptr[offset];
+ vd->attrs[boffset] = attrptr[offset];
+#endif
offset++;
+ boffset++;
}
}
ri->ri_flg &= ~RI_CURSOR;
scr->scr_vd->cursor(ri, 1, ri->ri_crow, ri->ri_ccol);
+#ifdef VCONS_DRAW_INTR
+ vd->cursor_offset = ri->ri_crow * ri->ri_cols + ri->ri_ccol;
+#endif
}
vcons_unlock(scr);
}
+#ifdef VCONS_DRAW_INTR
+void
+vcons_update_screen(struct vcons_screen *scr)
+{
+ uint16_t *charptr = scr->scr_chars;
+ long *attrptr = scr->scr_attrs;
+ struct rasops_info *ri = &scr->scr_ri;
+ struct vcons_data *vd = scr->scr_vd;
+ int i, j, offset, boffset = 0;
+
+ vcons_lock(scr);
+ if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
+
+ /* redraw the screen */
+#ifdef WSDISPLAY_SCROLLSUPPORT
+ offset = scr->scr_current_offset;
+#else
+ offset = 0;
+#endif
+ /*
+ * we mark the character cell occupied by the cursor as dirty
+ * so we don't have to deal with it
+ * notice that this isn't necessarily the position where rasops
+ * thinks it is, just where we drew it the last time
+ */
+ if (vd->cursor_offset >= 0)
+ vd->attrs[vd->cursor_offset] = 0xffffffff;
+
+ for (i = 0; i < ri->ri_rows; i++) {
+ for (j = 0; j < ri->ri_cols; j++) {
+ /*
+ * no need to use the wrapper function - we
+ * don't change any characters or attributes
+ * and we already made sure the screen we're
+ * working on is visible
+ */
+ if ((vd->chars[boffset] != charptr[offset]) ||
+ (vd->attrs[boffset] != attrptr[offset])) {
+ vd->putchar(ri, i, j,
+ charptr[offset], attrptr[offset]);
+ vd->chars[boffset] = charptr[offset];
+ vd->attrs[boffset] = attrptr[offset];
+ }
+ offset++;
+ boffset++;
+ }
+ }
+ ri->ri_flg &= ~RI_CURSOR;
+ scr->scr_vd->cursor(ri, 1, ri->ri_crow, ri->ri_ccol);
+ vd->cursor_offset = ri->ri_crow * ri->ri_cols + ri->ri_ccol;
+ }
+ vcons_unlock(scr);
+}
+#endif
+
static int
vcons_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
struct lwp *l)
@@ -618,20 +706,33 @@
{
struct rasops_info *ri = cookie;
struct vcons_screen *scr = ri->ri_hw;
+ struct vcons_data *vd = scr->scr_vd;
if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
- int pos, c, offset;
+ int pos, c, offset, ppos;
#ifdef WSDISPLAY_SCROLLSUPPORT
offset = scr->scr_current_offset;
#else
offset = 0;
#endif
- pos = ri->ri_cols * row + dstcol + offset;
+ ppos = ri->ri_cols * row + dstcol;
+ pos = ppos + offset;
for (c = dstcol; c < (dstcol + ncols); c++) {
- scr->scr_vd->putchar(cookie, row, c,
- scr->scr_chars[pos], scr->scr_attrs[pos]);
+#ifdef VCONS_DRAW_INTR
+ if ((scr->scr_chars[pos] != vd->chars[ppos]) ||
+ (scr->scr_attrs[pos] != vd->attrs[ppos])) {
+ vd->putchar(cookie, row, c,
+ scr->scr_chars[pos], scr->scr_attrs[pos]);
+ vd->chars[ppos] = scr->scr_chars[pos];
+ vd->attrs[ppos] = scr->scr_attrs[pos];
+ }
+#else
+ vd->putchar(cookie, row, c, scr->scr_chars[pos],
+ scr->scr_attrs[pos]);
+#endif
pos++;
+ ppos++;
}
}
}
@@ -664,6 +765,23 @@
#endif
}
+#ifdef VCONS_DRAW_INTR
+static void
+vcons_erasecols_cached(void *cookie, int row, int startcol, int ncols, long fillattr)
+{
+ struct rasops_info *ri = cookie;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct vcons_data *vd = scr->scr_vd;
+ int i, pos = row * ri->ri_cols + startcol;
+
+ for (i = pos; i < ncols; i++) {
+ vd->chars[i] = 0x20;
+ vd->attrs[i] = fillattr;
+ }
+ vd->erasecols(cookie, row, startcol, ncols, fillattr);
+}
+#endif
+
static void
vcons_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
{
@@ -686,8 +804,12 @@
fillattr);
} else
#endif
- scr->scr_vd->erasecols(cookie, row, startcol, ncols,
+#ifdef VCONS_DRAW_INTR
+ vcons_erasecols_cached(cookie, row, startcol, ncols,
fillattr);
+#else
+ scr->scr_vd->erasecols(cookie, row, startcol, ncols, fillattr);
+#endif
}
vcons_unlock(scr);
}
@@ -763,21 +885,36 @@
{
struct rasops_info *ri = cookie;
struct vcons_screen *scr = ri->ri_hw;
+ struct vcons_data *vd = scr->scr_vd;
+ int dist;
if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
- int pos, l, c, offset;
+ int pos, l, c, offset, ppos;
#ifdef WSDISPLAY_SCROLLSUPPORT
offset = scr->scr_current_offset;
#else
offset = 0;
#endif
- pos = ri->ri_cols * dstrow + offset;
+ dist = (dstrow - srcrow) * ri->ri_cols;
+ ppos = ri->ri_cols * dstrow;
+ pos = ppos + 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]);
+#ifdef VCONS_DRAW_INTR
+ if ((scr->scr_chars[pos] != vd->chars[ppos]) ||
+ (scr->scr_attrs[pos] != vd->attrs[ppos])) {
+ vd->putchar(cookie, l, c,
+ scr->scr_chars[pos], scr->scr_attrs[pos]);
+ vd->chars[ppos] = scr->scr_chars[pos];
+ vd->attrs[ppos] = scr->scr_attrs[pos];
+ }
+#else
+ vd->putchar(cookie, l, c, scr->scr_chars[pos],
+ scr->scr_attrs[pos]);
+#endif
pos++;
+ ppos++;
}
}
}
@@ -832,7 +969,7 @@
vcons_eraserows_async(cookie, row, nrows, fillattr);
} else
#endif
- scr->scr_vd->eraserows(cookie, row, nrows, fillattr);
+ scr->scr_vd->eraserows(cookie, row, nrows, fillattr);
}
vcons_unlock(scr);
}
@@ -868,6 +1005,27 @@
#endif
}
Home |
Main Index |
Thread Index |
Old Index