Home | History | Annotate | Line # | Download | only in rasops
      1 /* 	$NetBSD: rasops_bitops.h,v 1.25 2019/08/10 01:24:17 rin Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Andrew Doran.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifndef _RASOPS_BITOPS_H_
     33 #define _RASOPS_BITOPS_H_ 1
     34 
     35 #if   RASOPS_DEPTH == 1
     36 #define	PIXEL_SHIFT	0
     37 #elif RASOPS_DEPTH == 2
     38 #define	PIXEL_SHIFT	1
     39 #elif RASOPS_DEPTH == 4
     40 #define	PIXEL_SHIFT	2
     41 #else
     42 #error "Depth not supported"
     43 #endif
     44 
     45 #define	NAME(name)		NAME1(RASOPS_DEPTH, name)
     46 #define	NAME1(depth, name)	NAME2(depth, name)
     47 #define	NAME2(depth, name)	rasops ## depth ## _ ## name
     48 
     49 /*
     50  * Erase columns.
     51  */
     52 static void
     53 NAME(erasecols)(void *cookie, int row, int col, int num, long attr)
     54 {
     55 	struct rasops_info *ri = (struct rasops_info *)cookie;
     56 	int height, cnt;
     57 	uint32_t bg, lbg, rbg, lmask, rmask, tmp;
     58 	uint32_t *dp, *rp, *hp;
     59 
     60 	hp = NULL;	/* XXX GCC */
     61 
     62 #ifdef RASOPS_CLIPPING
     63 	if ((unsigned)row >= (unsigned)ri->ri_rows)
     64 		return;
     65 
     66 	if (col < 0) {
     67 		num += col;
     68 		col = 0;
     69 	}
     70 
     71 	if (col + num > ri->ri_cols)
     72 		num = ri->ri_cols - col;
     73 
     74 	if (num <= 0)
     75 		return;
     76 #endif
     77 
     78 	height = ri->ri_font->fontheight;
     79 	col *= ri->ri_font->fontwidth << PIXEL_SHIFT;
     80 	num *= ri->ri_font->fontwidth << PIXEL_SHIFT;
     81 
     82 	rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3));
     83 	if (ri->ri_hwbits)
     84 		hp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
     85 		    ((col >> 3) & ~3));
     86 
     87 	col &= 31;
     88 
     89 	bg = ATTR_BG(ri, attr);
     90 
     91 	if (col + num <= 32) {
     92 		lmask = ~rasops_pmask[col][num & 31];
     93 		bg &= ~lmask;
     94 
     95 		while (height--) {
     96 			tmp = (*rp & lmask) | bg;
     97 			*rp = tmp;
     98 
     99 			if (ri->ri_hwbits) {
    100 				*hp = tmp;
    101 				DELTA(hp, ri->ri_stride, uint32_t *);
    102 			}
    103 
    104 			DELTA(rp, ri->ri_stride, uint32_t *);
    105 		}
    106 	} else {
    107 		lmask = rasops_rmask[col];
    108 		rmask = rasops_lmask[(col + num) & 31];
    109 
    110 		if (lmask)
    111 			num = (num - (32 - col)) >> 5;
    112 		else
    113 			num = num >> 5;
    114 
    115 		lbg = bg & ~lmask;
    116 		rbg = bg & ~rmask;
    117 
    118 		while (height--) {
    119 			dp = rp;
    120 
    121 			if (lmask) {
    122 				*dp = (*dp & lmask) | lbg;
    123 				dp++;
    124 			}
    125 
    126 			for (cnt = num; cnt > 0; cnt--)
    127 				*dp++ = bg;
    128 
    129 			if (rmask)
    130 				*dp = (*dp & rmask) | rbg;
    131 
    132 			if (ri->ri_hwbits) {
    133 				memcpy(hp, rp, ((lmask != 0) + num +
    134 				    (rmask != 0)) << 2);
    135 				DELTA(hp, ri->ri_stride, uint32_t *);
    136 			}
    137 
    138 			DELTA(rp, ri->ri_stride, uint32_t *);
    139 		}
    140 	}
    141 }
    142 
    143 /*
    144  * Actually paint the cursor.
    145  */
    146 static void
    147 NAME(do_cursor)(struct rasops_info *ri)
    148 {
    149 	int row, col, height, width, cnt;
    150 	uint32_t lmask, rmask, tmp;
    151 	uint32_t *dp, *rp, *hp;
    152 
    153 	hp = NULL;	/* XXX GCC */
    154 
    155 	row = ri->ri_crow;
    156 	col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT;
    157 
    158 	height = ri->ri_font->fontheight;
    159 	width = ri->ri_font->fontwidth << PIXEL_SHIFT;
    160 
    161 	rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale +
    162 	    ((col >> 3) & ~3));
    163 	if (ri->ri_hwbits)
    164 		hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale +
    165 		    ((col >> 3) & ~3));
    166 
    167 	col &= 31;
    168 
    169 	if (col + width <= 32) {
    170 		lmask = rasops_pmask[col][width & 31];
    171 
    172 		while (height--) {
    173 			tmp = *rp ^ lmask;
    174 			*rp = tmp;
    175 			if (ri->ri_hwbits) {
    176 				*hp = tmp;
    177 				DELTA(hp, ri->ri_stride, uint32_t *);
    178 			}
    179 			DELTA(rp, ri->ri_stride, uint32_t *);
    180 		}
    181 	} else {
    182 		lmask = ~rasops_rmask[col];
    183 		rmask = ~rasops_lmask[(col + width) & 31];
    184 
    185 		if (lmask != -1)
    186 			width = (width - (32 - col)) >> 5;
    187 		else
    188 			width = width >> 5;
    189 
    190 		while (height--) {
    191 			dp = rp;
    192 
    193 			if (lmask != -1)
    194 				*dp++ ^= lmask;
    195 
    196 			for (cnt = width; cnt; cnt--) {
    197 				*dp = ~*dp;
    198 				dp++;
    199 			}
    200 
    201 			if (rmask != -1)
    202 				*dp ^= rmask;
    203 
    204 			if (ri->ri_hwbits) {
    205 				memcpy(hp, rp, ((lmask != -1) + width +
    206 				    (rmask != -1)) << 2);
    207 				DELTA(hp, ri->ri_stride, uint32_t *);
    208 			}
    209 
    210 			DELTA(rp, ri->ri_stride, uint32_t *);
    211 		}
    212 	}
    213 }
    214 
    215 /*
    216  * Copy columns. Ick!
    217  */
    218 static void
    219 NAME(copycols)(void *cookie, int row, int src, int dst, int num)
    220 {
    221 	struct rasops_info *ri = (struct rasops_info *)cookie;
    222 	int height, width, lnum, rnum, sb, db, full, cnt, sboff;
    223 	uint32_t lmask, rmask, tmp;
    224 	uint32_t *sp, *dp, *srp, *drp, *hp;
    225 	bool sbover;
    226 
    227 	hp = NULL;	/* XXX GCC */
    228 
    229 	if (__predict_false(dst == src))
    230 		return;
    231 
    232 #ifdef RASOPS_CLIPPING
    233 	/* Catches < 0 case too */
    234 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    235 		return;
    236 
    237 	if (src < 0) {
    238 		num += src;
    239 		src = 0;
    240 	}
    241 
    242 	if (src + num > ri->ri_cols)
    243 		num = ri->ri_cols - src;
    244 
    245 	if (dst < 0) {
    246 		num += dst;
    247 		dst = 0;
    248 	}
    249 
    250 	if (dst + num > ri->ri_cols)
    251 		num = ri->ri_cols - dst;
    252 
    253 	if (num <= 0)
    254 		return;
    255 #endif
    256 
    257 	height = ri->ri_font->fontheight;
    258 	width = ri->ri_font->fontwidth << PIXEL_SHIFT;
    259 
    260 	row *= ri->ri_yscale;
    261 
    262 	src *= width;
    263 	dst *= width;
    264 	num *= width;
    265 
    266 	sb = src & 31;
    267 	db = dst & 31;
    268 
    269 	if (db + num <= 32) {
    270 		/* Destination is contained within a single word */
    271 		srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
    272 		drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
    273 		if (ri->ri_hwbits)
    274 			hp = (uint32_t *)(ri->ri_hwbits + row +
    275 			    ((dst >> 3) & ~3));
    276 
    277 		while (height--) {
    278 			GETBITS(srp, sb, num, tmp);
    279 			PUTBITS(tmp, db, num, drp);
    280 			if (ri->ri_hwbits) {
    281 				*hp = *drp;
    282 				DELTA(hp, ri->ri_stride, uint32_t *);
    283 			}
    284 			DELTA(srp, ri->ri_stride, uint32_t *);
    285 			DELTA(drp, ri->ri_stride, uint32_t *);
    286 		}
    287 
    288 		return;
    289 	}
    290 
    291 	lmask = rasops_rmask[db];
    292 	rmask = rasops_lmask[(dst + num) & 31];
    293 	lnum = (32 - db) & 31;
    294 	rnum = (dst + num) & 31;
    295 
    296 	if (lmask != 0)
    297 		full = (num - lnum) >> 5;
    298 	else
    299 		full = num >> 5;
    300 
    301 	if (src < dst && src + num > dst) {
    302 		/* Copy right-to-left */
    303 		srp = (uint32_t *)(ri->ri_bits + row +
    304 		    (((src + num) >> 3) & ~3));
    305 		drp = (uint32_t *)(ri->ri_bits + row +
    306 		    (((dst + num) >> 3) & ~3));
    307 		if (ri->ri_hwbits) {
    308 			hp = (uint32_t *)(ri->ri_hwbits + row +
    309 			    (((dst + num) >> 3) & ~3));
    310 			hp -= (lmask != 0) + full;
    311 		}
    312 
    313 		sboff = (src + num) & 31;
    314 		sbover = sb + lnum >= 32;
    315 		if ((sboff -= rnum) < 0) {
    316 			srp--;
    317 			sboff += 32;
    318 		}
    319 
    320 		while (height--) {
    321 			sp = srp;
    322 			dp = drp;
    323 
    324 			if (rmask != 0) {
    325 				GETBITS(sp, sboff, rnum, tmp);
    326 				PUTBITS(tmp, 0, rnum, dp);
    327 			}
    328 
    329 			/* Now aligned to 32-bits wrt dp */
    330 			for (cnt = full; cnt; cnt--) {
    331 				--dp;
    332 				--sp;
    333 				GETBITS(sp, sboff, 32, tmp);
    334 				*dp = tmp;
    335 			}
    336 
    337 			if (lmask != 0) {
    338 				if (sbover)
    339 					--sp;
    340 				--dp;
    341 				GETBITS(sp, sb, lnum, tmp);
    342 				PUTBITS(tmp, db, lnum, dp);
    343  			}
    344 
    345 			if (ri->ri_hwbits) {
    346 				memcpy(hp, dp, ((lmask != 0) + full +
    347 				    (rmask != 0)) << 2);
    348 				DELTA(hp, ri->ri_stride, uint32_t *);
    349 			}
    350 
    351 			DELTA(srp, ri->ri_stride, uint32_t *);
    352 			DELTA(drp, ri->ri_stride, uint32_t *);
    353  		}
    354 	} else {
    355 		/* Copy left-to-right */
    356 		srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
    357 		drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
    358 		if (ri->ri_hwbits)
    359 			hp = (uint32_t *)(ri->ri_hwbits + row +
    360 			    ((dst >> 3) & ~3));
    361 
    362 		while (height--) {
    363 			sp = srp;
    364 			dp = drp;
    365 
    366 			sboff = sb;
    367 
    368 			if (lmask != 0) {
    369 				GETBITS(sp, sboff, lnum, tmp);
    370 				PUTBITS(tmp, db, lnum, dp);
    371 				dp++;
    372 
    373 				if ((sboff += lnum) > 31) {
    374 					sp++;
    375 					sboff -= 32;
    376 				}
    377 			}
    378 
    379 			/* Now aligned to 32-bits wrt dp */
    380 			for (cnt = full; cnt; cnt--, sp++) {
    381 				GETBITS(sp, sboff, 32, tmp);
    382 				*dp++ = tmp;
    383 			}
    384 
    385 			if (rmask != 0) {
    386 				GETBITS(sp, sboff, rnum, tmp);
    387 				PUTBITS(tmp, 0, rnum, dp);
    388  			}
    389 
    390 			if (ri->ri_hwbits) {
    391 				memcpy(hp, drp, ((lmask != 0) + full +
    392 				    (rmask != 0)) << 2);
    393 				DELTA(hp, ri->ri_stride, uint32_t *);
    394 			}
    395 
    396 			DELTA(srp, ri->ri_stride, uint32_t *);
    397 			DELTA(drp, ri->ri_stride, uint32_t *);
    398  		}
    399  	}
    400 }
    401 
    402 #undef	PIXEL_SHIFT
    403 
    404 #undef	NAME
    405 #undef	NAME1
    406 #undef	NAME2
    407 
    408 #endif /* _RASOPS_BITOPS_H_ */
    409