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