Module Name:    src
Committed By:   macallan
Date:           Thu Feb 16 17:29:21 UTC 2012

Modified Files:
        src/sys/dev/wscons: files.wscons
Added Files:
        src/sys/dev/wscons: wsdisplay_glyphcache.c wsdisplay_glyphcachevar.h

Log Message:
generic support for caching glyphs in video memory
for speeding up anti-aliased fonts on slow CPUs


To generate a diff of this commit:
cvs rdiff -u -r1.45 -r1.46 src/sys/dev/wscons/files.wscons
cvs rdiff -u -r0 -r1.1 src/sys/dev/wscons/wsdisplay_glyphcache.c \
    src/sys/dev/wscons/wsdisplay_glyphcachevar.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/files.wscons
diff -u src/sys/dev/wscons/files.wscons:1.45 src/sys/dev/wscons/files.wscons:1.46
--- src/sys/dev/wscons/files.wscons:1.45	Wed Jun 29 03:09:37 2011
+++ src/sys/dev/wscons/files.wscons	Thu Feb 16 17:29:21 2012
@@ -1,4 +1,4 @@
-# $NetBSD: files.wscons,v 1.45 2011/06/29 03:09:37 macallan Exp $
+# $NetBSD: files.wscons,v 1.46 2012/02/16 17:29:21 macallan Exp $
 
 #
 # "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
@@ -77,3 +77,7 @@ defflag opt_tpcalib.h		TPCALIBDEBUG
 file	dev/wscons/wsdisplay_vcons.c		vcons
 file	dev/wscons/wsdisplay_vcons_util.c	vcons
 defflag	opt_vcons.h		VCONS_DRAW_INTR VCONS_INTR_DEBUG
+
+# generic support code for caching rendered glyphs in video memory
+define	glyphcache
+file	dev/wscons/wsdisplay_glyphcache.c	glyphcache

Added files:

Index: src/sys/dev/wscons/wsdisplay_glyphcache.c
diff -u /dev/null src/sys/dev/wscons/wsdisplay_glyphcache.c:1.1
--- /dev/null	Thu Feb 16 17:29:21 2012
+++ src/sys/dev/wscons/wsdisplay_glyphcache.c	Thu Feb 16 17:29:21 2012
@@ -0,0 +1,118 @@
+/*	$NetBSD: wsdisplay_glyphcache.c,v 1.1 2012/02/16 17:29:21 macallan Exp $	*/
+
+/*
+ * Copyright (c) 2012 Michael Lorenz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* 
+ * a simple glyph cache in offscreen memory
+ * For now it only caches glyphs with the default attribute ( assuming they're
+ * the most commonly used glyphs ) but the API should at least not prevent
+ * more sophisticated caching algorithms
+ */
+
+#include <sys/atomic.h>
+#include <sys/errno.h>
+#include <dev/wscons/wsdisplay_glyphcachevar.h>
+
+/* first line, lines, width, attr */
+int
+glyphcache_init(glyphcache *gc, int first, int lines, int width,
+    int cellwidth, int cellheight, long attr)
+{
+	int cache_lines;
+
+	gc->gc_cellwidth = cellwidth;
+	gc->gc_cellheight = cellheight;
+	gc->gc_firstline = first;
+	gc->gc_cellsperline = width / cellwidth;
+	cache_lines = lines / cellheight;
+	gc->gc_numcells = cache_lines * gc->gc_cellsperline;
+	if (gc->gc_numcells > 256)
+		gc->gc_numcells = 256;
+	gc->gc_attr = attr;
+	glyphcache_wipe(gc);
+	return 0;
+}
+
+void
+glyphcache_wipe(glyphcache *gc)
+{
+	int i;
+
+	gc->gc_usedcells = 0;
+	for (i = 0; i < 256; i++)
+		gc->gc_map[i] = -1;
+}
+
+/*
+ * add a glyph drawn at (x,y) to the cache as (c)
+ * call this only if glyphcache_try() returned GC_ADD
+ * caller or gc_bitblt must make sure the glyph is actually completely drawn
+ */
+int
+glyphcache_add(glyphcache *gc, int c, int x, int y)
+{
+	int cell;
+	int cx, cy;
+
+	if (gc->gc_map[c] != -1)
+		return EINVAL;
+	if (gc->gc_usedcells >= gc->gc_numcells)
+		return ENOMEM;
+	cell = atomic_add_int_nv(&gc->gc_usedcells, 1) - 1;
+	gc->gc_map[c] = cell;
+	cy = gc->gc_firstline +
+	    (cell / gc->gc_cellsperline) * gc->gc_cellheight;
+	cx = (cell % gc->gc_cellsperline) * gc->gc_cellwidth;
+	gc->gc_bitblt(gc->gc_blitcookie, x, y, cx, cy,
+	    gc->gc_cellwidth, gc->gc_cellheight, gc->gc_rop);
+	return 0;
+}
+
+/*
+ * check if (c) is in the cache, if so draw it at (x,y)
+ * return:
+ * - GC_OK when the glyph was found
+ * - GC_ADD when the glyph wasn't found but can be added
+ * - GC_NOPE when the glyph can't be cached
+ */
+int
+glyphcache_try(glyphcache *gc, int c, int x, int y, long attr)
+{
+	int cell, cx, cy;
+	if ((c < 0) || (c > 255) || (attr != gc->gc_attr))
+		return GC_NOPE;
+	if (gc->gc_usedcells >= gc->gc_numcells)
+		return GC_NOPE;
+	cell = gc->gc_map[c];
+	if (cell == -1)
+		return GC_ADD;
+	cy = gc->gc_firstline +
+	    (cell / gc->gc_cellsperline) * gc->gc_cellheight;
+	cx = (cell % gc->gc_cellsperline) * gc->gc_cellwidth;
+	gc->gc_bitblt(gc->gc_blitcookie, cx, cy, x, y,
+	    gc->gc_cellwidth, gc->gc_cellheight, gc->gc_rop);
+	return GC_OK;
+}
Index: src/sys/dev/wscons/wsdisplay_glyphcachevar.h
diff -u /dev/null src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.1
--- /dev/null	Thu Feb 16 17:29:21 2012
+++ src/sys/dev/wscons/wsdisplay_glyphcachevar.h	Thu Feb 16 17:29:21 2012
@@ -0,0 +1,65 @@
+/*	$NetBSD: wsdisplay_glyphcachevar.h,v 1.1 2012/02/16 17:29:21 macallan Exp $	*/
+
+/*
+ * Copyright (c) 2012 Michael Lorenz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* a simple glyph cache in offscreen memory */
+
+#ifndef WSDISPLAY_GLYPHCACHEVAR_H
+#define WSDISPLAY_GLYPHCACHEVAR_H
+
+typedef struct _glyphcache {
+	/* mapping char codes to cache cells */
+	volatile unsigned int gc_usedcells;
+	int gc_numcells;
+	int gc_map[256];
+	/* geometry */
+	int gc_cellwidth;
+	int gc_cellheight;
+	int gc_cellsperline;
+	int gc_firstline;	/* first line in vram to use for glyphs */
+	long gc_attr;
+	/*
+	 * method to copy glyphs within vram,
+	 * to be initialized before calling glyphcache_init()
+	 */
+	void (*gc_bitblt)(void *, int, int, int, int, int, int, int);
+	void *gc_blitcookie;
+	int gc_rop;
+} glyphcache;
+
+/* first line, lines, width, cellwidth, cellheight, attr */
+int glyphcache_init(glyphcache *, int, int, int, int, int, long);
+/* clear out the cache, for example when returning from X */
+void glyphcache_wipe(glyphcache *);
+/* add a glyph to the cache */
+int glyphcache_add(glyphcache *, int, int, int); /* char code, x, y */
+/* try to draw a glyph from the cache */
+int glyphcache_try(glyphcache *, int, int, int, long); /* char code, x, y, attr */
+#define	GC_OK	0 /* glyph was in cache and has been drawn */
+#define GC_ADD	1 /* glyph is not in cache but can be added */
+#define GC_NOPE 2 /* glyph is not in cache and can't be added */
+
+#endif /* WSDISPLAY_GLYPHCACHEVAR_H */
\ No newline at end of file

Reply via email to