1 /* $NetBSD: wsdisplay_glyphcache.c,v 1.1 2012/02/16 17:29:21 macallan Exp $ */ 2 3 /* 4 * Copyright (c) 2012 Michael Lorenz 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * a simple glyph cache in offscreen memory 30 * For now it only caches glyphs with the default attribute ( assuming they're 31 * the most commonly used glyphs ) but the API should at least not prevent 32 * more sophisticated caching algorithms 33 */ 34 35 #include <sys/atomic.h> 36 #include <sys/errno.h> 37 #include <dev/wscons/wsdisplay_glyphcachevar.h> 38 39 /* first line, lines, width, attr */ 40 int 41 glyphcache_init(glyphcache *gc, int first, int lines, int width, 42 int cellwidth, int cellheight, long attr) 43 { 44 int cache_lines; 45 46 gc->gc_cellwidth = cellwidth; 47 gc->gc_cellheight = cellheight; 48 gc->gc_firstline = first; 49 gc->gc_cellsperline = width / cellwidth; 50 cache_lines = lines / cellheight; 51 gc->gc_numcells = cache_lines * gc->gc_cellsperline; 52 if (gc->gc_numcells > 256) 53 gc->gc_numcells = 256; 54 gc->gc_attr = attr; 55 glyphcache_wipe(gc); 56 return 0; 57 } 58 59 void 60 glyphcache_wipe(glyphcache *gc) 61 { 62 int i; 63 64 gc->gc_usedcells = 0; 65 for (i = 0; i < 256; i++) 66 gc->gc_map[i] = -1; 67 } 68 69 /* 70 * add a glyph drawn at (x,y) to the cache as (c) 71 * call this only if glyphcache_try() returned GC_ADD 72 * caller or gc_bitblt must make sure the glyph is actually completely drawn 73 */ 74 int 75 glyphcache_add(glyphcache *gc, int c, int x, int y) 76 { 77 int cell; 78 int cx, cy; 79 80 if (gc->gc_map[c] != -1) 81 return EINVAL; 82 if (gc->gc_usedcells >= gc->gc_numcells) 83 return ENOMEM; 84 cell = atomic_add_int_nv(&gc->gc_usedcells, 1) - 1; 85 gc->gc_map[c] = cell; 86 cy = gc->gc_firstline + 87 (cell / gc->gc_cellsperline) * gc->gc_cellheight; 88 cx = (cell % gc->gc_cellsperline) * gc->gc_cellwidth; 89 gc->gc_bitblt(gc->gc_blitcookie, x, y, cx, cy, 90 gc->gc_cellwidth, gc->gc_cellheight, gc->gc_rop); 91 return 0; 92 } 93 94 /* 95 * check if (c) is in the cache, if so draw it at (x,y) 96 * return: 97 * - GC_OK when the glyph was found 98 * - GC_ADD when the glyph wasn't found but can be added 99 * - GC_NOPE when the glyph can't be cached 100 */ 101 int 102 glyphcache_try(glyphcache *gc, int c, int x, int y, long attr) 103 { 104 int cell, cx, cy; 105 if ((c < 0) || (c > 255) || (attr != gc->gc_attr)) 106 return GC_NOPE; 107 if (gc->gc_usedcells >= gc->gc_numcells) 108 return GC_NOPE; 109 cell = gc->gc_map[c]; 110 if (cell == -1) 111 return GC_ADD; 112 cy = gc->gc_firstline + 113 (cell / gc->gc_cellsperline) * gc->gc_cellheight; 114 cx = (cell % gc->gc_cellsperline) * gc->gc_cellwidth; 115 gc->gc_bitblt(gc->gc_blitcookie, cx, cy, x, y, 116 gc->gc_cellwidth, gc->gc_cellheight, gc->gc_rop); 117 return GC_OK; 118 } 119