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 */ 52static void 53NAME(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 */ 146static void 147NAME(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 */ 218static void 219NAME(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