xref: /netbsd-src/sys/dev/rasops/rasops_bitops.h (revision b09e761aad3e91448cec0e5cc3a2724dd216de3c)
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
NAME(erasecols)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
NAME(do_cursor)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
NAME(copycols)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