Module Name: src Committed By: macallan Date: Fri Jun 2 19:30:10 UTC 2017
Modified Files: src/sys/dev/wscons: wsdisplay_glyphcache.c wsdisplay_glyphcachevar.h Log Message: make glyph caches reconfigurable To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/dev/wscons/wsdisplay_glyphcache.c cvs rdiff -u -r1.4 -r1.5 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/wsdisplay_glyphcache.c diff -u src/sys/dev/wscons/wsdisplay_glyphcache.c:1.8 src/sys/dev/wscons/wsdisplay_glyphcache.c:1.9 --- src/sys/dev/wscons/wsdisplay_glyphcache.c:1.8 Thu Jun 1 02:45:12 2017 +++ src/sys/dev/wscons/wsdisplay_glyphcache.c Fri Jun 2 19:30:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_glyphcache.c,v 1.8 2017/06/01 02:45:12 chs Exp $ */ +/* $NetBSD: wsdisplay_glyphcache.c,v 1.9 2017/06/02 19:30:10 macallan Exp $ */ /* * Copyright (c) 2012 Michael Lorenz @@ -27,9 +27,6 @@ /* * 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 */ #ifdef _KERNEL_OPT @@ -40,6 +37,9 @@ #include <sys/atomic.h> #include <sys/errno.h> #include <sys/kmem.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> +#include <dev/wscons/wsdisplay_vconsvar.h> #include <dev/wscons/wsdisplay_glyphcachevar.h> #ifdef GLYPHCACHE_DEBUG @@ -48,6 +48,8 @@ #define DPRINTF while (0) printf #endif +#define NBUCKETS 32 + static inline int attr2idx(long attr) { @@ -62,18 +64,42 @@ int glyphcache_init(glyphcache *gc, int first, int lines, int width, int cellwidth, int cellheight, long attr) { - int cache_lines, buckets, i, usedcells = 0, idx; - gc_bucket *b; /* first the geometry stuff */ - gc->gc_cellwidth = cellwidth; - gc->gc_cellheight = cellheight; + if (lines < 0) lines = 0; + gc->gc_width = width; + gc->gc_cellwidth = -1; + gc->gc_cellheight = -1; gc->gc_firstline = first; - gc->gc_cellsperline = width / cellwidth; + gc->gc_lines = lines; gc->gc_buckets = NULL; gc->gc_numbuckets = 0; - if (lines < 0) lines = 0; - cache_lines = lines / cellheight; + gc->gc_buckets = kmem_alloc(sizeof(gc_bucket) * NBUCKETS, KM_SLEEP); + gc->gc_nbuckets = NBUCKETS; + return glyphcache_reconfig(gc, cellwidth, cellheight, attr); + +} + +int +glyphcache_reconfig(glyphcache *gc, int cellwidth, int cellheight, long attr) +{ + int cache_lines, buckets, i, usedcells = 0, idx; + gc_bucket *b; + + /* see if we actually need to reconfigure anything */ + if ((gc->gc_cellwidth == cellwidth) && + (gc->gc_cellheight == cellheight) && + ((gc->gc_buckets != NULL) && + (gc->gc_buckets[0].gb_index == attr2idx(attr)))) { + return 0; + } + + gc->gc_cellwidth = cellwidth; + gc->gc_cellheight = cellheight; + + gc->gc_cellsperline = gc->gc_width / cellwidth; + + cache_lines = gc->gc_lines / cellheight; gc->gc_numcells = cache_lines * gc->gc_cellsperline; /* now allocate buckets */ @@ -88,7 +114,7 @@ glyphcache_init(glyphcache *gc, int firs if (buckets < 1) return ENOMEM; - gc->gc_buckets = kmem_alloc(sizeof(gc_bucket) * buckets, KM_SLEEP); + buckets = min(buckets, gc->gc_nbuckets); gc->gc_numbuckets = buckets; DPRINTF("%s: using %d buckets\n", __func__, buckets); @@ -120,6 +146,21 @@ glyphcache_init(glyphcache *gc, int firs } void +glyphcache_adapt(struct vcons_screen *scr, void *cookie) +{ + glyphcache *gc = cookie; + struct rasops_info *ri = &scr->scr_ri; + + if (ri->ri_wsfcookie != gc->gc_fontcookie) { + glyphcache_wipe(gc); + gc->gc_fontcookie = ri->ri_wsfcookie; + } + + glyphcache_reconfig(gc, ri->ri_font->fontwidth, + ri->ri_font->fontheight, scr->scr_defattr); +} + +void glyphcache_wipe(glyphcache *gc) { gc_bucket *b; Index: src/sys/dev/wscons/wsdisplay_glyphcachevar.h diff -u src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.4 src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.5 --- src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.4 Thu Oct 4 10:26:32 2012 +++ src/sys/dev/wscons/wsdisplay_glyphcachevar.h Fri Jun 2 19:30:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_glyphcachevar.h,v 1.4 2012/10/04 10:26:32 macallan Exp $ */ +/* $NetBSD: wsdisplay_glyphcachevar.h,v 1.5 2017/06/02 19:30:10 macallan Exp $ */ /* * Copyright (c) 2012 Michael Lorenz @@ -48,8 +48,12 @@ typedef struct _glyphcache { int gc_cellheight; int gc_cellsperline; int gc_firstline; /* first line in vram to use for glyphs */ + int gc_lines; + int gc_width; + int gc_fontcookie; /* buckets */ - int gc_numbuckets; + int gc_numbuckets; /* buckets we can use */ + int gc_nbuckets; /* buckets allocated */ gc_bucket *gc_buckets; /* we allocate as many as we can get into vram */ gc_bucket *gc_next; /* bucket the next glyph goes into */ long gc_underline; /* draw an underline in glyphcache_add() */ @@ -66,10 +70,19 @@ typedef struct _glyphcache { /* first line, lines, width, cellwidth, cellheight, attr */ int glyphcache_init(glyphcache *, int, int, int, int, int, long); + +/* adapt to changed font */ +int glyphcache_reconfig(glyphcache *, int, int, long); + +/* helper for showscreen_cb */ +void glyphcache_adapt(struct vcons_screen *, void *); + /* 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 */