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