Module Name: src Committed By: martin Date: Thu Aug 15 12:21:28 UTC 2019
Modified Files: src/share/man/man9 [netbsd-9]: rasops.9 src/sys/arch/luna68k/dev [netbsd-9]: omrasops.c src/sys/dev/rasops [netbsd-9]: README rasops.c rasops.h rasops1.c rasops15.c rasops1_putchar_width.h rasops2.c rasops24.c rasops32.c rasops4.c rasops8.c rasops_bitops.h rasops_masks.c rasops_masks.h rasops_putchar.h rasops_putchar_width.h src/sys/dev/wscons [netbsd-9]: wsdisplay_vcons.c src/sys/dev/wsfb [netbsd-9]: genfb.c Added Files: src/sys/dev/rasops [netbsd-9]: rasops1-4_putchar.h Removed Files: src/sys/dev/rasops [netbsd-9]: rasops_putchar_aa.h Log Message: Pull up following revision(s) (requested by rin in ticket #56): sys/dev/rasops/rasops.c: revision 1.120 sys/dev/rasops/rasops.h: revision 1.40 sys/dev/rasops/rasops.c: revision 1.121 sys/dev/rasops/rasops.h: revision 1.41 sys/dev/rasops/rasops.c: revision 1.122 sys/dev/rasops/rasops.h: revision 1.42 sys/dev/rasops/rasops.h: revision 1.43 sys/dev/rasops/rasops.h: revision 1.44 sys/dev/rasops/rasops.h: revision 1.45 sys/dev/rasops/rasops.h: revision 1.46 sys/dev/rasops/rasops.h: revision 1.47 sys/dev/rasops/rasops.h: revision 1.48 sys/dev/rasops/rasops32.c: revision 1.40 sys/dev/rasops/rasops32.c: revision 1.41 sys/dev/rasops/rasops32.c: revision 1.42 sys/dev/rasops/rasops32.c: revision 1.43 sys/dev/rasops/rasops32.c: revision 1.44 sys/dev/rasops/rasops32.c: revision 1.45 sys/dev/rasops/rasops32.c: revision 1.46 sys/dev/rasops/rasops1-4_putchar.h: revision 1.1 sys/dev/rasops/rasops1-4_putchar.h: revision 1.2 sys/dev/rasops/rasops1-4_putchar.h: revision 1.3 sys/dev/rasops/rasops1_putchar_width.h: revision 1.3 sys/dev/rasops/rasops1_putchar_width.h: revision 1.4 sys/dev/rasops/rasops1_putchar_width.h: revision 1.5 sys/dev/rasops/rasops1_putchar_width.h: revision 1.6 sys/dev/rasops/README: revision 1.7 sys/dev/rasops/rasops_putchar_aa.h: revision 1.5 sys/dev/rasops/rasops_putchar_aa.h: revision 1.6 sys/dev/rasops/rasops8.c: revision 1.45 sys/dev/rasops/rasops8.c: revision 1.46 sys/dev/rasops/rasops8.c: revision 1.47 sys/dev/rasops/rasops24.c: revision 1.40 sys/dev/rasops/rasops8.c: revision 1.48 sys/dev/rasops/rasops24.c: revision 1.41 sys/dev/rasops/rasops8.c: revision 1.49 sys/dev/rasops/rasops24.c: revision 1.42 sys/dev/rasops/rasops24.c: revision 1.43 sys/dev/rasops/rasops24.c: revision 1.44 sys/dev/rasops/rasops_masks.c: revision 1.10 doc/CHANGES: revision 1.2566 sys/dev/rasops/rasops24.c: revision 1.45 doc/CHANGES: revision 1.2567 sys/dev/rasops/rasops24.c: revision 1.46 sys/dev/rasops/rasops24.c: revision 1.47 sys/dev/rasops/rasops24.c: revision 1.48 sys/dev/rasops/rasops24.c: revision 1.49 sys/dev/rasops/rasops_bitops.h: revision 1.19 sys/dev/rasops/rasops_putchar_aa.h: file removal sys/dev/wscons/wsdisplay_vcons.c: revision 1.40 sys/dev/rasops/rasops8.c: revision 1.50 sys/dev/rasops/rasops8.c: revision 1.51 sys/dev/rasops/rasops24.c: revision 1.50 sys/arch/luna68k/dev/omrasops.c: revision 1.21 sys/dev/rasops/rasops_bitops.h: revision 1.20 sys/dev/wsfb/genfb.c: revision 1.68 sys/dev/rasops/rasops_bitops.h: revision 1.21 sys/dev/wsfb/genfb.c: revision 1.69 sys/dev/rasops/rasops_putchar_width.h: revision 1.10 sys/dev/rasops/rasops_bitops.h: revision 1.22 sys/dev/rasops/rasops_putchar_width.h: revision 1.11 sys/dev/rasops/rasops_bitops.h: revision 1.23 sys/dev/rasops/rasops_putchar_width.h: revision 1.12 sys/dev/rasops/rasops_bitops.h: revision 1.24 sys/dev/rasops/rasops_putchar_width.h: revision 1.13 sys/dev/rasops/rasops_bitops.h: revision 1.25 sys/dev/rasops/rasops_putchar_width.h: revision 1.14 sys/dev/rasops/rasops_putchar_width.h: revision 1.15 sys/dev/rasops/rasops1.c: revision 1.32 sys/dev/rasops/rasops1.c: revision 1.33 sys/dev/rasops/rasops1.c: revision 1.34 sys/dev/rasops/rasops1.c: revision 1.35 sys/dev/rasops/rasops1.c: revision 1.36 sys/dev/rasops/rasops1.c: revision 1.37 sys/dev/rasops/rasops4.c: revision 1.21 sys/dev/rasops/rasops4.c: revision 1.22 sys/dev/rasops/rasops4.c: revision 1.23 sys/dev/rasops/rasops4.c: revision 1.24 sys/dev/rasops/rasops4.c: revision 1.25 sys/dev/rasops/rasops4.c: revision 1.26 sys/dev/rasops/rasops4.c: revision 1.27 sys/dev/rasops/rasops4.c: revision 1.28 sys/dev/wsfb/genfb.c: revision 1.70 sys/dev/rasops/rasops2.c: revision 1.27 sys/dev/rasops/rasops2.c: revision 1.28 share/man/man9/rasops.9: revision 1.18 sys/dev/rasops/rasops.c: revision 1.102 sys/dev/rasops/rasops2.c: revision 1.29 share/man/man9/rasops.9: revision 1.19 sys/dev/rasops/rasops.c: revision 1.103 sys/dev/rasops/rasops.c: revision 1.104 sys/dev/rasops/rasops.c: revision 1.105 sys/dev/rasops/rasops.c: revision 1.106 sys/dev/rasops/rasops.c: revision 1.107 sys/dev/rasops/rasops_putchar.h: revision 1.6 sys/dev/rasops/rasops.c: revision 1.108 sys/dev/rasops/rasops_putchar.h: revision 1.7 sys/dev/rasops/rasops.c: revision 1.109 sys/dev/rasops/rasops_putchar.h: revision 1.8 sys/dev/rasops/rasops2.c: revision 1.30 sys/dev/rasops/rasops2.c: revision 1.31 sys/dev/rasops/rasops15.c: revision 1.32 sys/dev/rasops/rasops2.c: revision 1.32 sys/dev/rasops/rasops15.c: revision 1.33 sys/dev/rasops/rasops2.c: revision 1.33 sys/dev/rasops/rasops15.c: revision 1.34 sys/dev/rasops/rasops15.c: revision 1.35 sys/dev/rasops/rasops15.c: revision 1.36 sys/dev/rasops/rasops.c: revision 1.110 sys/dev/rasops/rasops15.c: revision 1.37 sys/dev/rasops/rasops.c: revision 1.111 sys/dev/rasops/rasops15.c: revision 1.38 sys/dev/rasops/rasops.c: revision 1.112 sys/dev/rasops/rasops15.c: revision 1.39 sys/dev/rasops/rasops.c: revision 1.113 sys/dev/rasops/rasops.c: revision 1.114 sys/dev/rasops/rasops.c: revision 1.115 sys/dev/rasops/rasops_masks.h: revision 1.9 sys/dev/rasops/rasops.c: revision 1.116 sys/dev/rasops/rasops.c: revision 1.117 sys/dev/rasops/rasops.c: revision 1.118 sys/dev/rasops/rasops.c: revision 1.119 sys/dev/rasops/rasops.h: revision 1.39 Misc clean-up's: - protect private stuff in rasops.h by _RASOPS_PRIVATE - staticify rasops_copycols() and rasops_isgray[] - G/C unused extern int cold Switch to per-device stamp, and retire stamp_mutex. Provide buffer capable of single-row pixels in order to make things simpler. Factor out copy-paste. No functional changes. When font is switched, not only putchar, but also other ri_ops can be changed by backend driver, e.g., see rasops1.c: https://nxr.netbsd.org/xref/src/sys/dev/rasops/rasops1.c#58 4 is 1 << 2, not 1 << 3... Fix erasecols and do_cursor for font width >= 32 bits. Also, some cosmetic clean-up's. Oops, for rasops_copycols(), we cannot use memmove even if src == dst. On the other hand, memmove is safe for rasops_copyrows(). Fix unaligned writes to buffer, that are introduced in 1.105: http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/rasops/rasops.c#rev1.105 Support font width 32 on monochrome screen. Remove duplicate substitution. Style. No functional changes. Correct copy count. This affects ``left-to-right'' copy for region including word boundary. Fix a bug in shadow fb support for copycols on 1, 2, and 4bpp screen, which was introduced in 1.18: http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/rasops/rasops_bitops.h#rev1.18 Add general putchar functions for 2 and 4bpp. Note that 1bpp continues to use its local version in rasops1.c, which is much faster and simpler. Cosmetic changes. No functional changes. Reflect reality. Notify size of shadow framebuffer if enabled. Fix unaligned word write's to buffer, introduced in rev 1.42: http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/rasops/rasops24.c#rev1.42 Real fix for 24-bpp color: - When centering screen, locate effective base address of framebuffer to both word and 24-bit color boundary. - Consistently convert ri_devcmap to ``big endian'' if not RI_BSWAP. Also, fix possible bug for 15/16-bpp with RI_BSWAP (not tested). Protect rasops_copy{rows,cols}() by _RASOPS_PRIVATE. Use _KERNEL_OPT. Simplify calculation for 12-byte alignment. No functional changes. Fix black color-attribution for depths 2 and 4. Depth 2 is monochrome. IMO, it is impossible to support ANSI colors on 2-bpp display; fore- and background can be same value even if they are different colors logically. Fix a critical bug for rasops_copyrows() introduced in rev. 1.90: http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/rasops/rasops.c#rev1.90 When src < dst, we have to copy backward. Simplify rasops_do_cursor(): - Use static masks similar to that used in rasops_bitops.h, rather than generating them on the fly. - Use pointer for proper type to avoid unnecessary casts. Use "hp" instead of "hrp" consistently with other files. No functional changes. Stop allocating ri_buf and ri_stamp dynamically. As commented in rasops.h, it is not safe to use kmem_alloc(9) in rasops_init(); rasops routines can be used for early putchar, which means that UVM is not fully initialized. Should fix a problem reported by macallan: http://mail-index.netbsd.org/tech-kern/2019/08/02/msg025327.html Instead of using ri_buf, inline function rasops_memcpy32() is introduced to fill 32bit data efficiently. Instead of using ri_stamp (per device stamp), stamp_ri is introduced to distinguish for which device stamp is calculated. Oops, revert an unintentional change for now. If RI_CLEAR is set, do not forget to clear real framebuffer. Modify struct rasops_info again (ride 9.99.4 bump). - remove ri_buf and friends. - remove ri_stamp and frieds. - introduce ri_ul, which will be used for scaling underline with font. Also add hack for ri_ul; adjust its size to obsoleted member, ri_delta, which was only used rasops routines internally. Now, size and offsets of all members of struct rasops_info become same with netbsd-9, -8, and -7, again. So we can safelly pull up fixes to any release branches! Scaling dimensions of underline by font height. Currently, - offset of underline is fixed to 1-row from bottom of characters, and - height of underline is fixed to 1. Both are good for standard 8x16 fonts. However, it is too thin for larger fonts, especially when used on display of high resolution. Also, 1-row offset of underline is ugly for small fonts, e.g., spleen5x8. Therefore, adjust offset and height as, - no changes for standard 16-height fonts. - scaling by font height for larger fonts. - set offset to zero for fonts of height smaller than 16. Merge rasops_putchar_aa.h into rasops_putchar.h. Support scaling underline dimensions by font height. Separate general putchar for 1-4bpp from rasops_bitops: - Support anti-aliasing for 2bpp, which works perfectly! - Support scaling underline dimensions with font height. We support anti-aliasing for depth 2. Use switch appropriately. - Stop showing struct rasops_info; readers can read the header itself. - Correct description for optimized font widths. - Remove strange blank line. Try to improve formatting and naration. Make rasops_erase{rows,cols}() public again; hp300/diofb uses them. Pointed out by martin. When legacy Apple 4-bpp color palette is used, make green dark so that kernel messages are printed nicely on white background. Fix color range overflow; we cannot make bright colors more brighter. Correctly check whether character is in font in rasops_mapchar(). Also, make sure that in putchar functions for completeness. Fix bug introduced in rev. 1.69: http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/wsfb/genfb.c#rev1.69 is_bgr should be initialized to false. Otherwise, color becomes strange for depths 24 and 32 unless backend explicitly set "is_bgr" property. Set 4-bpp devcmap in a similar manner to non-RGB case of 8-bpp. No functional changes since this is not in use (4-bpp is monochrome). Misc style clean up's. - Introduce and use proper macros. - Use not ambiguous variable names. - Unify similar functions as possible as I can. - G/C unused headers. - Use #include <dev/rasops/foo.h> instead of "foo.h" No particular functional changes intended. My work for rasops(9) was finished (hopefully). I will send pull-up request for netbsd-9, if there are no new failures reported within few days. Fix format in order not to confuse changes2html script. Minor improvements of wording for my entry. When using stamp, drop attributions other than back and foreground colors so that stamp is not updated unnecessarily. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.17.8.1 src/share/man/man9/rasops.9 cvs rdiff -u -r1.20 -r1.20.6.1 src/sys/arch/luna68k/dev/omrasops.c cvs rdiff -u -r1.6 -r1.6.36.1 src/sys/dev/rasops/README cvs rdiff -u -r1.101 -r1.101.2.1 src/sys/dev/rasops/rasops.c cvs rdiff -u -r1.38 -r1.38.2.1 src/sys/dev/rasops/rasops.h cvs rdiff -u -r0 -r1.3.2.2 src/sys/dev/rasops/rasops1-4_putchar.h cvs rdiff -u -r1.31 -r1.31.2.1 src/sys/dev/rasops/rasops1.c \ src/sys/dev/rasops/rasops15.c cvs rdiff -u -r1.2 -r1.2.2.1 src/sys/dev/rasops/rasops1_putchar_width.h cvs rdiff -u -r1.26 -r1.26.2.1 src/sys/dev/rasops/rasops2.c cvs rdiff -u -r1.39 -r1.39.2.1 src/sys/dev/rasops/rasops24.c \ src/sys/dev/rasops/rasops32.c cvs rdiff -u -r1.20 -r1.20.2.1 src/sys/dev/rasops/rasops4.c cvs rdiff -u -r1.44 -r1.44.2.1 src/sys/dev/rasops/rasops8.c cvs rdiff -u -r1.18 -r1.18.2.1 src/sys/dev/rasops/rasops_bitops.h cvs rdiff -u -r1.9 -r1.9.36.1 src/sys/dev/rasops/rasops_masks.c cvs rdiff -u -r1.8 -r1.8.36.1 src/sys/dev/rasops/rasops_masks.h cvs rdiff -u -r1.5 -r1.5.2.1 src/sys/dev/rasops/rasops_putchar.h cvs rdiff -u -r1.4 -r0 src/sys/dev/rasops/rasops_putchar_aa.h cvs rdiff -u -r1.9 -r1.9.2.1 src/sys/dev/rasops/rasops_putchar_width.h cvs rdiff -u -r1.39 -r1.39.4.1 src/sys/dev/wscons/wsdisplay_vcons.c cvs rdiff -u -r1.67 -r1.67.2.1 src/sys/dev/wsfb/genfb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man9/rasops.9 diff -u src/share/man/man9/rasops.9:1.17 src/share/man/man9/rasops.9:1.17.8.1 --- src/share/man/man9/rasops.9:1.17 Mon Jul 3 21:28:48 2017 +++ src/share/man/man9/rasops.9 Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -.\" $NetBSD: rasops.9,v 1.17 2017/07/03 21:28:48 wiz Exp $ +.\" $NetBSD: rasops.9,v 1.17.8.1 2019/08/15 12:21:27 martin Exp $ .\" .\" Copyright (c) 2001 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 13, 2012 +.Dd August 7, 2019 .Dt RASOPS 9 .Os .Sh NAME @@ -42,6 +42,9 @@ .Fn rasops_init "struct rasops_info *ri" "int wantrows" "int wantcols" .Ft int .Fn rasops_reconfig "struct rasops_info *ri" "int wantrows" "int wantcols" +.Pp +.Cd options RASOPS_DEFAULT_WIDTH=80 +.Cd options RASOPS_DEFAULT_HEIGHT=25 .Sh DESCRIPTION The .Nm @@ -49,86 +52,15 @@ subsystem is a set of raster operations .Xr wscons 9 . .Pp The primary data type for using the raster operations is the -.Em rasops_info +.Vt rasops_info structure in -.Pa dev/rasops/rasops.h : -.Bd -literal -struct rasops_info { - - /* - * These must be filled in by the caller - */ - int ri_depth; /* depth in bits */ - u_char *ri_bits; /* ptr to bits */ - int ri_width; /* width (pels) */ - int ri_height; /* height (pels) */ - int ri_stride; /* stride in bytes */ - - /* - * If you want shadow framebuffer support, point ri_hwbits - * to the real framebuffer, and ri_bits to the shadow framebuffer - */ - u_char *ri_hwbits; - - /* - * These can optionally be left zeroed out. If you fill ri_font, - * but aren't using wsfont, set ri_wsfcookie to -1. - */ - struct wsdisplay_font *ri_font; - int ri_wsfcookie; /* wsfont cookie */ - void *ri_hw; /* driver private data */ - int ri_crow; /* cursor row */ - int ri_ccol; /* cursor column */ - int ri_flg; /* various operational flags */ - - /* - * These are optional and will default if zero. Meaningless - * on depths other than 15, 16, 24 and 32 bits per pel. On - * 24 bit displays, ri_{r,g,b}num must be 8. - */ - u_char ri_rnum; /* number of bits for red */ - u_char ri_gnum; /* number of bits for green */ - u_char ri_bnum; /* number of bits for blue */ - u_char ri_rpos; /* which bit red starts at */ - u_char ri_gpos; /* which bit green starts at */ - u_char ri_bpos; /* which bit blue starts at */ - - /* - * These are filled in by rasops_init() - */ - int ri_emuwidth; /* width we actually care about */ - int ri_emuheight; /* height we actually care about */ - int ri_emustride; /* bytes per row we actually care about */ - int ri_rows; /* number of rows (characters) */ - int ri_cols; /* number of columns (characters) */ - int ri_delta; /* row delta in bytes */ - int ri_pelbytes; /* bytes per pel (may be zero) */ - int ri_fontscale; /* fontheight * fontstride */ - int ri_xscale; /* fontwidth * pelbytes */ - int ri_yscale; /* fontheight * stride */ - u_char *ri_origbits; /* where screen bits actually start */ - int ri_xorigin; /* where ri_bits begins (x) */ - int ri_yorigin; /* where ri_bits begins (y) */ - int32_t ri_devcmap[16]; /* color -> framebuffer data */ - - /* - * The emulops you need to use, and the screen caps for wscons - */ - struct wsdisplay_emulops ri_ops; - int ri_caps; - - /* - * Callbacks so we can share some code - */ - void (*ri_do_cursor)(struct rasops_info *); -}; -.Ed +.In dev/rasops/rasops.h . .Pp Valid values for the -.Em ri_flg +.Fa ri_flg member are: .Pp -.Bl -tag -offset indent -width RI_ENABLE_ALPHA_XX -compact +.Bl -tag -width ".Dv RI_ENABLE_ALPHA" -offset indent -compact .It Dv RI_FULLCLEAR .Fn eraserows hack to clear full screen @@ -152,50 +84,47 @@ do not generate box drawing characters f Use this when it is not safe to allocate memory, for example when setting up an early console. .It Dv RI_ENABLE_ALPHA -set this if the caller supports anti-aliased fonts in the given colour depth. +the caller supports anti-aliased fonts in the given colour depth. Without this flag .Fn rasops_init will only pick bitmap fonts. .It Dv RI_8BIT_IS_RGB -set this if the caller uses an R3G3B2 colour map in 8 bit. +the caller uses an R3G3B2 colour map in 8 bit. .Fn rasops_init -will generate an appropriate ri_devcmap[] but the caller still needs to set up -the actual colour map. +will generate an appropriate +.Fa ri_devcmap Ns Li [] +but the caller still needs to set up the actual colour map. .El .Sh FUNCTIONS -.Bl -tag -width compact -.It Fn rasops_init "ri" "wantrows" "wantcols" -Initialise a -.Em rasops_info +.Fn rasops_init +initialises a +.Vt rasops_info descriptor. +.Fn rasops_reconfig +is used to reconfigure it if parameters have changed in some way. +.Pp The arguments .Fa wantrows and .Fa wantcols are the number of rows and columns we'd like. -In terms of optimization, fonts that are a multiple of 8 pixels wide -work the best. -.It Fn rasops_reconfig "ri" "wantrows" "wantcols" -Reconfigure a -.Em rasops_info -descriptor because parameters have changed in some way. -The arguments -.Fa wantrows +Passing zero for either one of them uses the default \(em normally +80 by 25 but it can be changed with config options +.Dv RASOPS_DEFAULT_WIDTH and -.Fa wantcols -are the number of rows and columns we'd like. -Passing zero for either one of -them uses the default - normally 80x25 but it can be changed with -.Bd -literal -offset indent -options RASOPS_DEFAULT_WIDTH=80 -options RASOPS_DEFAULT_HEIGHT=25 -.Ed +.Dv RASOPS_DEFAULT_HEIGHT . +.Pp +In terms of optimization, bitmap fonts of width 8 or 16 work the best +for all depths. +For depths other than 1 the fonts of width 12 are also optimized. +.Pp If calling .Fn rasops_reconfig -to change the font and ri_wsfcookie \*[Ge] 0, you must call +to change the font and +.Fa ri_wsfcookie +is non-negative, you must call .Fn wsfont_unlock -on it, and reset it to -1 (or a new, valid cookie). -.El +on it, and reset it to \-1 or a new, valid cookie. .Sh CODE REFERENCES The rasops subsystem is implemented within the directory .Pa sys/dev/rasops . Index: src/sys/arch/luna68k/dev/omrasops.c diff -u src/sys/arch/luna68k/dev/omrasops.c:1.20 src/sys/arch/luna68k/dev/omrasops.c:1.20.6.1 --- src/sys/arch/luna68k/dev/omrasops.c:1.20 Wed Jun 6 01:49:08 2018 +++ src/sys/arch/luna68k/dev/omrasops.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: omrasops.c,v 1.20 2018/06/06 01:49:08 maya Exp $ */ +/* $NetBSD: omrasops.c,v 1.20.6.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: omrasops.c,v 1.20 2018/06/06 01:49:08 maya Exp $"); +__KERNEL_RCSID(0, "$NetBSD: omrasops.c,v 1.20.6.1 2019/08/15 12:21:27 martin Exp $"); /* * Designed speficically for 'm68k bitorder'; @@ -1202,7 +1202,6 @@ omrasops_init(struct rasops_info *ri, in ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth; ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight; ri->ri_emustride = ri->ri_emuwidth * bpp >> 3; - ri->ri_delta = ri->ri_stride - ri->ri_emustride; ri->ri_ccol = 0; ri->ri_crow = 0; ri->ri_pelbytes = bpp >> 3; Index: src/sys/dev/rasops/README diff -u src/sys/dev/rasops/README:1.6 src/sys/dev/rasops/README:1.6.36.1 --- src/sys/dev/rasops/README:1.6 Mon Dec 2 14:05:51 2013 +++ src/sys/dev/rasops/README Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -$NetBSD: README,v 1.6 2013/12/02 14:05:51 tsutsui Exp $ +$NetBSD: README,v 1.6.36.1 2019/08/15 12:21:27 martin Exp $ This directory contains `rasops', a set of raster operations intended to replace the dev/rcons/raster stuff for both wscons and rcons. It yields @@ -6,11 +6,9 @@ significantly improved performance, supp Issues/TODO: -- There is no generic `putchar' function for 2bpp - Color handling for 2bpp is broken - 64-bit types are not used on machines that are 64-bit - We should never be doing reads/writes of less than 32-bits -- Flags in attribute values are hardcoded - Need a manpage - Should handle multiple fonts simulatneously - Generate an `empty' box character when we have no match? Index: src/sys/dev/rasops/rasops.c diff -u src/sys/dev/rasops/rasops.c:1.101 src/sys/dev/rasops/rasops.c:1.101.2.1 --- src/sys/dev/rasops/rasops.c:1.101 Tue Jul 30 15:29:40 2019 +++ src/sys/dev/rasops/rasops.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops.c,v 1.101 2019/07/30 15:29:40 rin Exp $ */ +/* $NetBSD: rasops.c,v 1.101.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,24 +30,27 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.101 2019/07/30 15:29:40 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.101.2.1 2019/08/15 12:21:27 martin Exp $"); +#ifdef _KERNEL_OPT #include "opt_rasops.h" -#include "rasops_glue.h" #include "opt_wsmsgattrs.h" +#include "rasops_glue.h" +#endif #include <sys/param.h> #include <sys/bswap.h> #include <sys/kmem.h> -#include <sys/systm.h> -#include <sys/time.h> #include <machine/endian.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsconsio.h> #include <dev/wsfont/wsfont.h> + +#define _RASOPS_PRIVATE #include <dev/rasops/rasops.h> +#include <dev/rasops/rasops_masks.h> /* XXX for MBE */ #ifndef _KERNEL #include <errno.h> @@ -67,6 +70,16 @@ struct rasops_matchdata { int ident; }; +static const uint32_t rasops_lmask32[4 + 1] = { + MBE(0x00000000), MBE(0x00ffffff), MBE(0x0000ffff), MBE(0x000000ff), + MBE(0x00000000), +}; + +static const uint32_t rasops_rmask32[4 + 1] = { + MBE(0x00000000), MBE(0xff000000), MBE(0xffff0000), MBE(0xffffff00), + MBE(0xffffffff), +}; + /* ANSI colormap (R,G,B). Upper 8 are high-intensity */ const uint8_t rasops_cmap[256 * 3] = { 0x00, 0x00, 0x00, /* black */ @@ -127,11 +140,9 @@ const uint8_t rasops_cmap[256 * 3] = { }; /* True if color is gray */ -const uint8_t rasops_isgray[16] = { - 1, 0, 0, 0, - 0, 0, 0, 1, - 1, 0, 0, 0, - 0, 0, 0, 1, +static const uint8_t rasops_isgray[16] = { + 1, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 1, }; #ifdef RASOPS_APPLE_PALETTE @@ -161,7 +172,7 @@ static const uint8_t apple8_devcmap[16] static const uint8_t apple4_devcmap[16] = { 15, /* black */ 3, /* red */ - 8, /* green */ + 9, /* dark green */ 1, /* yellow */ 6, /* blue */ 4, /* magenta */ @@ -170,7 +181,7 @@ static const uint8_t apple4_devcmap[16] 13, /* medium grey */ 3, /* red */ - 8, /* green */ + 9, /* dark green */ 1, /* yellow */ 6, /* blue */ 4, /* magenta */ @@ -181,12 +192,17 @@ static const uint8_t apple4_devcmap[16] /* Generic functions */ static void rasops_copyrows(void *, int, int, int); +static void rasops_copycols(void *, int, int, int, int); static int rasops_mapchar(void *, int, u_int *); static void rasops_cursor(void *, int, int, int); static int rasops_allocattr_color(void *, int, int, int, long *); static int rasops_allocattr_mono(void *, int, int, int, long *); static void rasops_do_cursor(struct rasops_info *); static void rasops_init_devcmap(struct rasops_info *); +static void rasops_make_box_chars_8(struct rasops_info *); +static void rasops_make_box_chars_16(struct rasops_info *); +static void rasops_make_box_chars_32(struct rasops_info *); +static void rasops_make_box_chars_alpha(struct rasops_info *); #if NRASOPS_ROTATION > 0 static void rasops_rotate_font(int *, int); @@ -218,13 +234,6 @@ struct rotatedfont { }; #endif /* NRASOPS_ROTATION > 0 */ -void rasops_make_box_chars_8(struct rasops_info *); -void rasops_make_box_chars_16(struct rasops_info *); -void rasops_make_box_chars_32(struct rasops_info *); -void rasops_make_box_chars_alpha(struct rasops_info *); - -extern int cold; - /* * Initialize a 'rasops_info' descriptor. */ @@ -319,7 +328,7 @@ rasops_init(struct rasops_info *ri, int int rasops_reconfig(struct rasops_info *ri, int wantrows, int wantcols) { - int bpp, s; + int bpp, height, s; size_t len; s = splhigh(); @@ -413,12 +422,10 @@ rasops_reconfig(struct rasops_info *ri, } else #endif { - ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth; ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight; } ri->ri_emustride = ri->ri_emuwidth * bpp >> 3; - ri->ri_delta = ri->ri_stride - ri->ri_emustride; ri->ri_ccol = 0; ri->ri_crow = 0; ri->ri_pelbytes = bpp >> 3; @@ -427,32 +434,44 @@ rasops_reconfig(struct rasops_info *ri, ri->ri_yscale = ri->ri_font->fontheight * ri->ri_stride; ri->ri_fontscale = ri->ri_font->fontheight * ri->ri_font->stride; - if ((ri->ri_delta & 3) != 0) { - aprint_error( - "%s: ri_delta not aligned on 32-bit boundary", __func__); - splx(s); - return -1; - } ri->ri_origbits = ri->ri_bits; ri->ri_hworigbits = ri->ri_hwbits; /* Clear the entire display */ - if ((ri->ri_flg & RI_CLEAR) != 0) - memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height); + if ((ri->ri_flg & RI_CLEAR) != 0) { + rasops_memset32(ri->ri_bits, 0, ri->ri_stride * ri->ri_height); + if (ri->ri_hwbits) + rasops_memset32(ri->ri_hwbits, 0, + ri->ri_stride * ri->ri_height); + } /* Now centre our window if needs be */ if ((ri->ri_flg & RI_CENTER) != 0) { - ri->ri_bits += (((ri->ri_width * bpp >> 3) - - ri->ri_emustride) >> 1) & ~3; - ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) * + uint32_t xoff, yoff; + + xoff = ((ri->ri_width * bpp >> 3) - ri->ri_emustride) >> 1; + if (ri->ri_depth != 24) { + /* + * Truncate to word boundary. + */ + xoff &= ~3; + } else { + /* + * Truncate to both word and 24-bit color boundary. + */ + xoff -= xoff % 12; + } + + yoff = ((ri->ri_height - ri->ri_emuheight) >> 1) * ri->ri_stride; + + ri->ri_bits += xoff; + ri->ri_bits += yoff; if (ri->ri_hwbits != NULL) { - ri->ri_hwbits += (((ri->ri_width * bpp >> 3) - - ri->ri_emustride) >> 1) & ~3; - ri->ri_hwbits += - ((ri->ri_height - ri->ri_emuheight) >> 1) * - ri->ri_stride; + ri->ri_hwbits += xoff; + ri->ri_hwbits += yoff; } + ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits) / ri->ri_stride; ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits) % @@ -460,6 +479,11 @@ rasops_reconfig(struct rasops_info *ri, } else ri->ri_xorigin = ri->ri_yorigin = 0; + /* Scaling underline by font height */ + height = ri->ri_font->fontheight; + ri->ri_ul.off = rounddown(height, 16) / 16; /* offset from bottom */ + ri->ri_ul.height = roundup(height, 16) / 16; /* height */ + /* * Fill in defaults for operations set. XXX this nukes private * routines used by accelerated fb drivers. @@ -476,10 +500,10 @@ rasops_reconfig(struct rasops_info *ri, WSSCREEN_WSCOLORS | WSSCREEN_REVERSE); if ((ri->ri_flg & RI_FORCEMONO) != 0 || -#ifdef RASOPS_APPLE_PALETTE - ri->ri_depth == 1 -#else +#ifndef RASOPS_APPLE_PALETTE ri->ri_depth < 8 +#else + ri->ri_depth < 4 #endif ) { ri->ri_ops.allocattr = rasops_allocattr_mono; @@ -570,17 +594,10 @@ rasops_mapchar(void *cookie, int c, u_in KASSERT(ri->ri_font != NULL); if ((c = wsfont_map_unichar(ri->ri_font, c)) < 0 || - c < ri->ri_font->firstchar) { - *cp = ' '; - return 0; - } - -#if 0 /* XXXRO */ - if (CHAR_IN_FONT(c, ri->ri_font)) { + !CHAR_IN_FONT(c, ri->ri_font)) { *cp = ' '; return 0; } -#endif *cp = c; return 5; @@ -602,6 +619,7 @@ rasops_allocattr_color(void *cookie, int fg &= 7; bg &= 7; #endif + if ((flg & WSATTR_BLINK) != 0) return EINVAL; @@ -618,7 +636,7 @@ rasops_allocattr_color(void *cookie, int #endif } - if ((flg & WSATTR_HILIT) != 0) + if ((flg & WSATTR_HILIT) != 0 && fg < 8) fg += 8; if ((flg & WSATTR_REVERSE) != 0) { @@ -650,7 +668,7 @@ rasops_allocattr_mono(void *cookie, int if ((flg & (WSATTR_BLINK | WSATTR_HILIT | WSATTR_WSCOLORS)) != 0) return EINVAL; - fg = 1; + fg = 0xff; bg = 0; if ((flg & WSATTR_REVERSE) != 0) { @@ -670,8 +688,8 @@ static void rasops_copyrows(void *cookie, int src, int dst, int num) { struct rasops_info *ri = (struct rasops_info *)cookie; + int stride; uint8_t *sp, *dp, *hp; - int n, stride; hp = NULL; /* XXX GCC */ @@ -699,23 +717,31 @@ rasops_copyrows(void *cookie, int src, i return; #endif + src *= ri->ri_yscale; + dst *= ri->ri_yscale; num *= ri->ri_font->fontheight; - n = ri->ri_emustride; stride = ri->ri_stride; - sp = ri->ri_bits + src * ri->ri_yscale; - dp = ri->ri_bits + dst * ri->ri_yscale; + if (src < dst) { + /* backward copy */ + src += (num - 1) * stride; + dst += (num - 1) * stride; + stride *= -1; + } + + sp = ri->ri_bits + src; + dp = ri->ri_bits + dst; if (ri->ri_hwbits) - hp = ri->ri_hwbits + dst * ri->ri_yscale; + hp = ri->ri_hwbits + dst; while (num--) { - memcpy(dp, sp, n); - dp += stride; + memcpy(dp, sp, ri->ri_emustride); if (ri->ri_hwbits) { - memcpy(hp, sp, n); + memcpy(hp, dp, ri->ri_emustride); hp += stride; } sp += stride; + dp += stride; } } @@ -725,12 +751,12 @@ rasops_copyrows(void *cookie, int src, i * We simply cop-out here and use memmove(), since it handles all of * these cases anyway. */ -void +static void rasops_copycols(void *cookie, int row, int src, int dst, int num) { struct rasops_info *ri = (struct rasops_info *)cookie; - uint8_t *sp, *dp, *hp; int height; + uint8_t *sp, *dp, *hp; hp = NULL; /* XXX GCC */ @@ -762,9 +788,9 @@ rasops_copycols(void *cookie, int row, i return; #endif - num *= ri->ri_xscale; - row *= ri->ri_yscale; height = ri->ri_font->fontheight; + row *= ri->ri_yscale; + num *= ri->ri_xscale; sp = ri->ri_bits + row + src * ri->ri_xscale; dp = ri->ri_bits + row + dst * ri->ri_xscale; @@ -772,13 +798,13 @@ rasops_copycols(void *cookie, int row, i hp = ri->ri_hwbits + row + dst * ri->ri_xscale; while (height--) { - memcpy(dp, sp, num); - dp += ri->ri_stride; + memmove(dp, sp, num); if (ri->ri_hwbits) { - memcpy(hp, sp, num); + memcpy(hp, dp, num); hp += ri->ri_stride; } sp += ri->ri_stride; + dp += ri->ri_stride; } } @@ -798,16 +824,16 @@ rasops_cursor(void *cookie, int on, int ri->ri_do_cursor(ri); /* Select new cursor */ + ri->ri_crow = row; + ri->ri_ccol = col; + #ifdef RASOPS_CLIPPING ri->ri_flg &= ~RI_CURSORCLIP; - if (row < 0 || row >= ri->ri_rows) ri->ri_flg |= RI_CURSORCLIP; else if (col < 0 || col >= ri->ri_cols) ri->ri_flg |= RI_CURSORCLIP; #endif - ri->ri_crow = row; - ri->ri_ccol = col; if (on) { ri->ri_flg |= RI_CURSOR; @@ -845,18 +871,18 @@ rasops_init_devcmap(struct rasops_info * ri->ri_devcmap[15] = -1; return; -#ifdef RASOPS_APPLE_PALETTE case 4: for (i = 0; i < 16; i++) { +#ifdef RASOPS_APPLE_PALETTE c = apple4_devcmap[i]; +#else + c = i; +#endif ri->ri_devcmap[i] = (c << 0) | (c << 4) | (c << 8) | (c << 12) | (c << 16) | (c << 20) | (c << 24) | (c << 28); } return; -#else - /* XXXRO What should we do here? */ -#endif case 8: if ((ri->ri_flg & RI_8BIT_IS_RGB) == 0) { @@ -894,39 +920,48 @@ rasops_init_devcmap(struct rasops_info * c |= (uint32_t)(*p << (ri->ri_bnum - 8)) << ri->ri_bpos; p++; - /* Fill the word for generic routines, which want this */ - if (ri->ri_depth == 8) { + /* + * Swap byte order if necessary. Then, fill the word for + * generic routines, which want this. + */ + switch (ri->ri_depth) { + case 8: c |= c << 8; c |= c << 16; - } else if (ri->ri_depth == 15 || ri->ri_depth == 16) + break; + case 15: + case 16: + if ((ri->ri_flg & RI_BSWAP) != 0) + c = bswap16(c); c |= c << 16; - else if (ri->ri_depth == 24) { + break; + case 24: #if BYTE_ORDER == LITTLE_ENDIAN -# ifndef RASOPS_SMALL - if (ri->ri_font->fontwidth != 12) -# endif - c = (c & 0x0000ff) << 16 | (c & 0x00ff00) | - (c & 0xff0000) >> 16; -# ifndef RASOPS_SMALL - else - c = (c & 0x0000ff) | (c & 0x00ff00) << 8 | - (c & 0xff0000) >> 8; -# endif + if ((ri->ri_flg & RI_BSWAP) == 0) #else - /* XXXRO What should we do here? */ + if ((ri->ri_flg & RI_BSWAP) != 0) #endif + { + /* + * Convert to ``big endian'' if not RI_BSWAP. + */ + c = (c & 0x0000ff) << 16| + (c & 0x00ff00) | + (c & 0xff0000) >> 16; + } + /* + * No worries, we use generic routines only for + * gray colors, where all 3 bytes are same. + */ c |= (c & 0xff) << 24; + break; + case 32: + if ((ri->ri_flg & RI_BSWAP) != 0) + c = bswap32(c); + break; } - /* 24bpp does bswap on the fly. {32,16,15}bpp do it here. */ - if ((ri->ri_flg & RI_BSWAP) == 0) - ri->ri_devcmap[i] = c; - else if (ri->ri_depth == 15 || ri->ri_depth == 16) - ri->ri_devcmap[i] = bswap16(c); - else if (ri->ri_depth == 32) - ri->ri_devcmap[i] = bswap32(c); - else /* 8, 24 */ - ri->ri_devcmap[i] = c; + ri->ri_devcmap[i] = c; } } @@ -950,8 +985,8 @@ void rasops_eraserows(void *cookie, int row, int num, long attr) { struct rasops_info *ri = (struct rasops_info *)cookie; - uint32_t *rp, *dp, *hp, clr; - int n, cnt; + int bytes; + uint32_t bg, *rp, *hp; hp = NULL; /* XXX GCC */ @@ -968,8 +1003,6 @@ rasops_eraserows(void *cookie, int row, return; #endif - clr = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; - /* * XXX The wsdisplay_emulops interface seems a little deficient in * that there is no way to clear the *entire* screen. We provide a @@ -977,25 +1010,25 @@ rasops_eraserows(void *cookie, int row, * the RI_FULLCLEAR flag is set, clear the entire display. */ if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) { - n = ri->ri_stride >> 2; + bytes = ri->ri_stride; num = ri->ri_height; rp = (uint32_t *)ri->ri_origbits; if (ri->ri_hwbits) hp = (uint32_t *)ri->ri_hworigbits; } else { - n = ri->ri_emustride >> 2; + bytes = ri->ri_emustride; num *= ri->ri_font->fontheight; rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale); if (ri->ri_hwbits) hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale); } + bg = ATTR_BG(ri, attr); + while (num--) { - dp = rp; - for (cnt = n; cnt; cnt--) - *dp++ = clr; + rasops_memset32(rp, bg, bytes); if (ri->ri_hwbits) { - memcpy(hp, rp, n << 2); + memcpy(hp, rp, bytes); DELTA(hp, ri->ri_stride, uint32_t *); } DELTA(rp, ri->ri_stride, uint32_t *); @@ -1009,10 +1042,9 @@ rasops_eraserows(void *cookie, int row, static void rasops_do_cursor(struct rasops_info *ri) { - int full, height, cnt, slop1, slop2, row, col; - uint32_t tmp32, msk1, msk2; - uint8_t tmp8; - uint8_t *dp, *rp, *hp; + int row, col, height, slop1, slop2, full, cnt; + uint32_t mask1, mask2, *dp; + uint8_t tmp, *rp, *hp; hp = NULL; /* XXX GCC */ @@ -1037,11 +1069,12 @@ rasops_do_cursor(struct rasops_info *ri) col = ri->ri_ccol; } - rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; - if (ri->ri_hwbits) - hp = ri->ri_hwbits + row * ri->ri_yscale + col * ri->ri_xscale; height = ri->ri_font->fontheight; + rp = ri->ri_bits + FBOFFSET(ri, row, col); + if (ri->ri_hwbits) + hp = ri->ri_hwbits + FBOFFSET(ri, row, col); + /* * For ri_xscale = 1: * @@ -1050,15 +1083,13 @@ rasops_do_cursor(struct rasops_info *ri) */ if (ri->ri_xscale == 1) { while (height--) { - tmp8 = ~*rp; - - *rp = tmp8; - rp += ri->ri_stride; - + tmp = ~*rp; + *rp = tmp; if (ri->ri_hwbits) { - *hp = tmp8; + *hp = tmp; hp += ri->ri_stride; } + rp += ri->ri_stride; } return; } @@ -1076,28 +1107,24 @@ rasops_do_cursor(struct rasops_info *ri) rp = (uint8_t *)((uintptr_t)rp & ~3); hp = (uint8_t *)((uintptr_t)hp & ~3); - msk1 = !slop1 ? 0 : be32toh(0xffffffffU >> (32 - (8 * slop1))); - msk2 = !slop2 ? 0 : be32toh(0xffffffffU << (32 - (8 * slop2))); + mask1 = rasops_lmask32[4 - slop1]; + mask2 = rasops_rmask32[slop2]; while (height--) { - dp = rp; + dp = (uint32_t *)rp; if (slop1) { - tmp32 = *(uint32_t *)dp ^ msk1; - *(uint32_t *)dp = tmp32; - dp += 4; + *dp = *dp ^ mask1; + dp++; } for (cnt = full; cnt; cnt--) { - tmp32 = ~*(uint32_t *)dp; - *(uint32_t *)dp = tmp32; - dp += 4; + *dp = ~*(uint32_t *)dp; + dp++; } - if (slop2) { - tmp32 = *(uint32_t *)dp ^ msk2; - *(uint32_t *)dp = tmp32; - } + if (slop2) + *dp = *dp ^ mask2; if (ri->ri_hwbits) { memcpy(hp, rp, ((slop1 != 0) + full + @@ -1115,8 +1142,8 @@ void rasops_erasecols(void *cookie, int row, int col, int num, long attr) { struct rasops_info *ri = (struct rasops_info *)cookie; - int height, cnt, slop1, slop2, clr; - uint32_t *rp, *dp, *hp; + int height; + uint32_t bg, *rp, *hp; hp = NULL; /* XXX GCC */ @@ -1136,158 +1163,288 @@ rasops_erasecols(void *cookie, int row, return; #endif + height = ri->ri_font->fontheight; num *= ri->ri_xscale; - rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); + + rp = (uint32_t *)(ri->ri_bits + FBOFFSET(ri, row, col)); if (ri->ri_hwbits) - hp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale + - col*ri->ri_xscale); - height = ri->ri_font->fontheight; - clr = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; + hp = (uint32_t *)(ri->ri_hwbits + FBOFFSET(ri, row, col)); - /* Don't bother using the full loop for <= 32 pels */ - if (num <= 32) { - if (((num | ri->ri_xscale) & 3) == 0) { - /* Word aligned blt */ - num >>= 2; - - while (height--) { - dp = rp; - for (cnt = num; cnt; cnt--) - *dp++ = clr; - if (ri->ri_hwbits) { - memcpy(hp, rp, num << 2); - DELTA(hp, ri->ri_stride, uint32_t *); - } - DELTA(rp, ri->ri_stride, uint32_t *); - } - } else if (((num | ri->ri_xscale) & 1) == 0) { - /* - * Halfword aligned blt. This is needed so the - * 15/16 bit ops can use this function. - */ - num >>= 1; + bg = ATTR_BG(ri, attr); - while (height--) { - dp = rp; - for (cnt = num; cnt; cnt--) { - *(uint16_t *)dp = clr; - DELTA(dp, 2, uint32_t *); - } - if (ri->ri_hwbits) { - memcpy(hp, rp, num << 1); - DELTA(hp, ri->ri_stride, uint32_t *); - } - DELTA(rp, ri->ri_stride, uint32_t *); - } - } else { - while (height--) { - dp = rp; - for (cnt = num; cnt; cnt--) { - *(uint8_t *)dp = clr; - DELTA(dp, 1, uint32_t *); - } - if (ri->ri_hwbits) { - memcpy(hp, rp, num); - DELTA(hp, ri->ri_stride, uint32_t *); - } - DELTA(rp, ri->ri_stride, uint32_t *); - } + while (height--) { + rasops_memset32(rp, bg, num); + if (ri->ri_hwbits) { + memcpy(hp, rp, num); + DELTA(hp, ri->ri_stride, uint32_t *); } - - return; + DELTA(rp, ri->ri_stride, uint32_t *); } +} - slop1 = (4 - ((uintptr_t)rp & 3)) & 3; - slop2 = (num - slop1) & 3; - num = (num - slop1 /* - slop2 */) >> 2; +void +rasops_make_box_chars_16(struct rasops_info *ri) +{ + int c, i, mid; + uint16_t vert_mask, hmask_left, hmask_right; + uint16_t *data = (uint16_t *)ri->ri_optfont.data; - while (height--) { - dp = rp; + vert_mask = 0xc000U >> ((ri->ri_font->fontwidth >> 1) - 1); + hmask_left = 0xff00U << (8 - (ri->ri_font->fontwidth >> 1)); + hmask_right = hmask_left >> ((ri->ri_font->fontwidth + 1) >> 1); + mid = (ri->ri_font->fontheight + 1) >> 1; - /* Align span to 4 bytes */ - if (slop1 & 1) { - *(uint8_t *)dp = clr; - DELTA(dp, 1, uint32_t *); + /* 0x00 would be empty anyway so don't bother */ + for (c = 1; c < 16; c++) { + data += ri->ri_font->fontheight; + if (c & 1) { + /* upper segment */ + for (i = 0; i < mid; i++) + data[i] = vert_mask; } - - if (slop1 & 2) { - *(uint16_t *)dp = clr; - DELTA(dp, 2, uint32_t *); + if (c & 4) { + /* lower segment */ + for (i = mid; i < ri->ri_font->fontheight; i++) + data[i] = vert_mask; } - - /* Write 4 bytes per loop */ - for (cnt = num; cnt; cnt--) - *dp++ = clr; - - /* Write unaligned trailing slop */ - if (slop2 & 1) { - *(uint8_t *)dp = clr; - DELTA(dp, 1, uint32_t *); + if (c & 2) { + /* right segment */ + i = ri->ri_font->fontheight >> 1; + data[mid - 1] |= hmask_right; + data[mid] |= hmask_right; } - - if (slop2 & 2) - *(uint16_t *)dp = clr; - - if (ri->ri_hwbits) { - memcpy(hp, rp, slop1 + (num << 2) + slop2); - DELTA(hp, ri->ri_stride, uint32_t *); + if (c & 8) { + /* left segment */ + data[mid - 1] |= hmask_left; + data[mid] |= hmask_left; } - DELTA(rp, ri->ri_stride, uint32_t *); } } -#if NRASOPS_ROTATION > 0 -/* - * Quarter clockwise rotation routines (originally intended for the - * built-in Zaurus C3x00 display in 16bpp). - */ - -static void -rasops_rotate_font(int *cookie, int rotate) +void +rasops_make_box_chars_8(struct rasops_info *ri) { - struct rotatedfont *f; - int ncookie; + int c, i, mid; + uint8_t vert_mask, hmask_left, hmask_right; + uint8_t *data = (uint8_t *)ri->ri_optfont.data; - SLIST_FOREACH(f, &rotatedfonts, rf_next) { - if (f->rf_cookie == *cookie) { - *cookie = f->rf_rotated; - return; + vert_mask = 0xc0U >> ((ri->ri_font->fontwidth >> 1) - 1); + hmask_left = 0xf0U << (4 - (ri->ri_font->fontwidth >> 1)); + hmask_right = hmask_left >> ((ri->ri_font->fontwidth + 1) >> 1); + mid = (ri->ri_font->fontheight + 1) >> 1; + + /* 0x00 would be empty anyway so don't bother */ + for (c = 1; c < 16; c++) { + data += ri->ri_font->fontheight; + if (c & 1) { + /* upper segment */ + for (i = 0; i < mid; i++) + data[i] = vert_mask; + } + if (c & 4) { + /* lower segment */ + for (i = mid; i < ri->ri_font->fontheight; i++) + data[i] = vert_mask; + } + if (c & 2) { + /* right segment */ + i = ri->ri_font->fontheight >> 1; + data[mid - 1] |= hmask_right; + data[mid] |= hmask_right; + } + if (c & 8) { + /* left segment */ + data[mid - 1] |= hmask_left; + data[mid] |= hmask_left; } } +} - /* - * We did not find a rotated version of this font. Ask the wsfont - * code to compute one for us. - */ - - f = kmem_alloc(sizeof(*f), KM_SLEEP); - - if ((ncookie = wsfont_rotate(*cookie, rotate)) == -1) - goto fail; - - f->rf_cookie = *cookie; - f->rf_rotated = ncookie; - SLIST_INSERT_HEAD(&rotatedfonts, f, rf_next); +void +rasops_make_box_chars_32(struct rasops_info *ri) +{ + int c, i, mid; + uint32_t vert_mask, hmask_left, hmask_right; + uint32_t *data = (uint32_t *)ri->ri_optfont.data; - *cookie = ncookie; - return; + vert_mask = 0xc0000000U >> ((ri->ri_font->fontwidth >> 1) - 1); + hmask_left = 0xffff0000U << (16 - (ri->ri_font->fontwidth >> 1)); + hmask_right = hmask_left >> ((ri->ri_font->fontwidth + 1) >> 1); + mid = (ri->ri_font->fontheight + 1) >> 1; -fail: kmem_free(f, sizeof(*f)); - return; + /* 0x00 would be empty anyway so don't bother */ + for (c = 1; c < 16; c++) { + data += ri->ri_font->fontheight; + if (c & 1) { + /* upper segment */ + for (i = 0; i < mid; i++) + data[i] = vert_mask; + } + if (c & 4) { + /* lower segment */ + for (i = mid; i < ri->ri_font->fontheight; i++) + data[i] = vert_mask; + } + if (c & 2) { + /* right segment */ + i = ri->ri_font->fontheight >> 1; + data[mid - 1] |= hmask_right; + data[mid] |= hmask_right; + } + if (c & 8) { + /* left segment */ + data[mid - 1] |= hmask_left; + data[mid] |= hmask_left; + } + } } -static void -rasops_copychar(void *cookie, int srcrow, int dstrow, int srccol, int dstcol) +void +rasops_make_box_chars_alpha(struct rasops_info *ri) { - struct rasops_info *ri = (struct rasops_info *)cookie; - int height; - int r_srcrow, r_dstrow, r_srccol, r_dstcol; - uint8_t *sp, *dp; + int c, i, hmid, vmid, wi, he; + uint8_t *data = (uint8_t *)ri->ri_optfont.data; + uint8_t *ddata; - r_srcrow = srccol; - r_dstrow = dstcol; - r_srccol = ri->ri_rows - srcrow - 1; - r_dstcol = ri->ri_rows - dstrow - 1; + he = ri->ri_font->fontheight; + wi = ri->ri_font->fontwidth; + + vmid = (he + 1) >> 1; + hmid = (wi + 1) >> 1; + + /* 0x00 would be empty anyway so don't bother */ + for (c = 1; c < 16; c++) { + data += ri->ri_fontscale; + if (c & 1) { + /* upper segment */ + ddata = data + hmid; + for (i = 0; i <= vmid; i++) { + *ddata = 0xff; + ddata += wi; + } + } + if (c & 4) { + /* lower segment */ + ddata = data + wi * vmid + hmid; + for (i = vmid; i < he; i++) { + *ddata = 0xff; + ddata += wi; + } + } + if (c & 2) { + /* right segment */ + ddata = data + wi * vmid + hmid; + for (i = hmid; i < wi; i++) { + *ddata = 0xff; + ddata++; + } + } + if (c & 8) { + /* left segment */ + ddata = data + wi * vmid; + for (i = 0; i <= hmid; i++) { + *ddata = 0xff; + ddata++; + } + } + } +} + +/* + * Return a colour map appropriate for the given struct rasops_info in the + * same form used by rasops_cmap[] + * For now this is either a copy of rasops_cmap[] or an R3G3B2 map, it should + * probably be a linear ( or gamma corrected? ) ramp for higher depths. + */ +int +rasops_get_cmap(struct rasops_info *ri, uint8_t *palette, size_t bytes) +{ + + if ((ri->ri_depth == 8) && ((ri->ri_flg & RI_8BIT_IS_RGB) != 0)) { + /* generate an R3G3B2 palette */ + int i, idx = 0; + uint8_t tmp; + + if (bytes < 256 * 3) + return EINVAL; + for (i = 0; i < 256; i++) { + tmp = i & 0xe0; + /* + * replicate bits so 0xe0 maps to a red value of 0xff + * in order to make white look actually white + */ + tmp |= (tmp >> 3) | (tmp >> 6); + palette[idx] = tmp; + idx++; + + tmp = (i & 0x1c) << 3; + tmp |= (tmp >> 3) | (tmp >> 6); + palette[idx] = tmp; + idx++; + + tmp = (i & 0x03) << 6; + tmp |= tmp >> 2; + tmp |= tmp >> 4; + palette[idx] = tmp; + idx++; + } + } else + memcpy(palette, rasops_cmap, uimin(bytes, sizeof(rasops_cmap))); + + return 0; +} + +#if NRASOPS_ROTATION > 0 +/* + * Quarter clockwise rotation routines (originally intended for the + * built-in Zaurus C3x00 display in 16bpp). + */ + +static void +rasops_rotate_font(int *cookie, int rotate) +{ + struct rotatedfont *f; + int ncookie; + + SLIST_FOREACH(f, &rotatedfonts, rf_next) { + if (f->rf_cookie == *cookie) { + *cookie = f->rf_rotated; + return; + } + } + + /* + * We did not find a rotated version of this font. Ask the wsfont + * code to compute one for us. + */ + + f = kmem_alloc(sizeof(*f), KM_SLEEP); + + if ((ncookie = wsfont_rotate(*cookie, rotate)) == -1) + goto fail; + + f->rf_cookie = *cookie; + f->rf_rotated = ncookie; + SLIST_INSERT_HEAD(&rotatedfonts, f, rf_next); + + *cookie = ncookie; + return; + +fail: kmem_free(f, sizeof(*f)); + return; +} + +static void +rasops_copychar(void *cookie, int srcrow, int dstrow, int srccol, int dstcol) +{ + struct rasops_info *ri = (struct rasops_info *)cookie; + int r_srcrow, r_dstrow, r_srccol, r_dstcol, height; + uint8_t *sp, *dp; + + r_srcrow = srccol; + r_dstrow = dstcol; + r_srccol = ri->ri_rows - srcrow - 1; + r_dstcol = ri->ri_rows - dstrow - 1; r_srcrow *= ri->ri_yscale; r_dstrow *= ri->ri_yscale; @@ -1308,7 +1465,7 @@ rasops_putchar_rotated_cw(void *cookie, { struct rasops_info *ri = (struct rasops_info *)cookie; int height; - uint8_t *rp; + uint16_t fg, *rp; if (__predict_false((unsigned int)row > ri->ri_rows || (unsigned int)col > ri->ri_cols)) @@ -1322,19 +1479,21 @@ rasops_putchar_rotated_cw(void *cookie, ri->ri_real_ops.putchar(cookie, col, ri->ri_rows - row - 1, uc, attr & ~WSATTR_UNDERLINE); - /* Do rotated underline */ - rp = ri->ri_bits + col * ri->ri_yscale + (ri->ri_rows - row - 1) * - ri->ri_xscale; - height = ri->ri_font->fontheight; - - /* XXX this assumes 16-bit color depth */ + /* + * Do rotated underline + * XXX this assumes 16-bit color depth + */ if ((attr & WSATTR_UNDERLINE) != 0) { - uint16_t c = - (uint16_t)ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf]; + height = ri->ri_font->fontheight; + + rp = (uint16_t *)(ri->ri_bits + col * ri->ri_yscale + + (ri->ri_rows - row - 1) * ri->ri_xscale); + + fg = (uint16_t)ATTR_FG(ri, attr); while (height--) { - *(uint16_t *)rp = c; - rp += ri->ri_stride; + *rp = fg; + DELTA(rp, ri->ri_stride, uint16_t *); } } } @@ -1403,7 +1562,7 @@ rasops_copychar_ccw(void *cookie, int sr int dstcol) { struct rasops_info *ri = (struct rasops_info *)cookie; - int height, r_srcrow, r_dstrow, r_srccol, r_dstcol; + int r_srcrow, r_dstrow, r_srccol, r_dstcol, height; uint8_t *sp, *dp; r_srcrow = ri->ri_cols - srccol - 1; @@ -1430,7 +1589,7 @@ rasops_putchar_rotated_ccw(void *cookie, { struct rasops_info *ri = (struct rasops_info *)cookie; int height; - uint8_t *rp; + uint16_t fg, *rp; if (__predict_false((unsigned int)row > ri->ri_rows || (unsigned int)col > ri->ri_cols)) @@ -1444,20 +1603,23 @@ rasops_putchar_rotated_ccw(void *cookie, ri->ri_real_ops.putchar(cookie, ri->ri_cols - col - 1, row, uc, attr & ~WSATTR_UNDERLINE); - /* Do rotated underline */ - rp = ri->ri_bits + (ri->ri_cols - col - 1) * ri->ri_yscale + - row * ri->ri_xscale + - (ri->ri_font->fontwidth - 1) * ri->ri_pelbytes; - height = ri->ri_font->fontheight; - - /* XXX this assumes 16-bit color depth */ + /* + * Do rotated underline + * XXX this assumes 16-bit color depth + */ if ((attr & WSATTR_UNDERLINE) != 0) { - uint16_t c = - (uint16_t)ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf]; + height = ri->ri_font->fontheight; + + rp = (uint16_t *)(ri->ri_bits + + (ri->ri_cols - col - 1) * ri->ri_yscale + + row * ri->ri_xscale + + (ri->ri_font->fontwidth - 1) * ri->ri_pelbytes); + + fg = (uint16_t)ATTR_FG(ri, attr); while (height--) { - *(uint16_t *)rp = c; - rp += ri->ri_stride; + *rp = fg; + DELTA(rp, ri->ri_stride, uint16_t *); } } } @@ -1496,215 +1658,3 @@ rasops_copycols_rotated_ccw(void *cookie src + coff, dst + coff); } #endif /* NRASOPS_ROTATION */ - -void -rasops_make_box_chars_16(struct rasops_info *ri) -{ - int c, i, mid; - uint16_t vert_mask, hmask_left, hmask_right; - uint16_t *data = (uint16_t *)ri->ri_optfont.data; - - vert_mask = 0xc000U >> ((ri->ri_font->fontwidth >> 1) - 1); - hmask_left = 0xff00U << (8 - (ri->ri_font->fontwidth >> 1)); - hmask_right = hmask_left >> ((ri->ri_font->fontwidth + 1) >> 1); - mid = (ri->ri_font->fontheight + 1) >> 1; - - /* 0x00 would be empty anyway so don't bother */ - for (c = 1; c < 16; c++) { - data += ri->ri_font->fontheight; - if (c & 1) { - /* upper segment */ - for (i = 0; i < mid; i++) - data[i] = vert_mask; - } - if (c & 4) { - /* lower segment */ - for (i = mid; i < ri->ri_font->fontheight; i++) - data[i] = vert_mask; - } - if (c & 2) { - /* right segment */ - i = ri->ri_font->fontheight >> 1; - data[mid - 1] |= hmask_right; - data[mid] |= hmask_right; - } - if (c & 8) { - /* left segment */ - data[mid - 1] |= hmask_left; - data[mid] |= hmask_left; - } - } -} - -void -rasops_make_box_chars_8(struct rasops_info *ri) -{ - int c, i, mid; - uint8_t vert_mask, hmask_left, hmask_right; - uint8_t *data = (uint8_t *)ri->ri_optfont.data; - - vert_mask = 0xc0U >> ((ri->ri_font->fontwidth >> 1) - 1); - hmask_left = 0xf0U << (4 - (ri->ri_font->fontwidth >> 1)); - hmask_right = hmask_left >> ((ri->ri_font->fontwidth + 1) >> 1); - mid = (ri->ri_font->fontheight + 1) >> 1; - - /* 0x00 would be empty anyway so don't bother */ - for (c = 1; c < 16; c++) { - data += ri->ri_font->fontheight; - if (c & 1) { - /* upper segment */ - for (i = 0; i < mid; i++) - data[i] = vert_mask; - } - if (c & 4) { - /* lower segment */ - for (i = mid; i < ri->ri_font->fontheight; i++) - data[i] = vert_mask; - } - if (c & 2) { - /* right segment */ - i = ri->ri_font->fontheight >> 1; - data[mid - 1] |= hmask_right; - data[mid] |= hmask_right; - } - if (c & 8) { - /* left segment */ - data[mid - 1] |= hmask_left; - data[mid] |= hmask_left; - } - } -} - -void -rasops_make_box_chars_32(struct rasops_info *ri) -{ - int c, i, mid; - uint32_t vert_mask, hmask_left, hmask_right; - uint32_t *data = (uint32_t *)ri->ri_optfont.data; - - vert_mask = 0xc0000000U >> ((ri->ri_font->fontwidth >> 1) - 1); - hmask_left = 0xffff0000U << (16 - (ri->ri_font->fontwidth >> 1)); - hmask_right = hmask_left >> ((ri->ri_font->fontwidth + 1) >> 1); - mid = (ri->ri_font->fontheight + 1) >> 1; - - /* 0x00 would be empty anyway so don't bother */ - for (c = 1; c < 16; c++) { - data += ri->ri_font->fontheight; - if (c & 1) { - /* upper segment */ - for (i = 0; i < mid; i++) - data[i] = vert_mask; - } - if (c & 4) { - /* lower segment */ - for (i = mid; i < ri->ri_font->fontheight; i++) - data[i] = vert_mask; - } - if (c & 2) { - /* right segment */ - i = ri->ri_font->fontheight >> 1; - data[mid - 1] |= hmask_right; - data[mid] |= hmask_right; - } - if (c & 8) { - /* left segment */ - data[mid - 1] |= hmask_left; - data[mid] |= hmask_left; - } - } -} - -void -rasops_make_box_chars_alpha(struct rasops_info *ri) -{ - int c, i, hmid, vmid, wi, he; - uint8_t *data = (uint8_t *)ri->ri_optfont.data; - uint8_t *ddata; - - he = ri->ri_font->fontheight; - wi = ri->ri_font->fontwidth; - - vmid = (he + 1) >> 1; - hmid = (wi + 1) >> 1; - - /* 0x00 would be empty anyway so don't bother */ - for (c = 1; c < 16; c++) { - data += ri->ri_fontscale; - if (c & 1) { - /* upper segment */ - ddata = data + hmid; - for (i = 0; i <= vmid; i++) { - *ddata = 0xff; - ddata += wi; - } - } - if (c & 4) { - /* lower segment */ - ddata = data + wi * vmid + hmid; - for (i = vmid; i < he; i++) { - *ddata = 0xff; - ddata += wi; - } - } - if (c & 2) { - /* right segment */ - ddata = data + wi * vmid + hmid; - for (i = hmid; i < wi; i++) { - *ddata = 0xff; - ddata++; - } - } - if (c & 8) { - /* left segment */ - ddata = data + wi * vmid; - for (i = 0; i <= hmid; i++) { - *ddata = 0xff; - ddata++; - } - } - } -} - -/* - * Return a colour map appropriate for the given struct rasops_info in the - * same form used by rasops_cmap[] - * For now this is either a copy of rasops_cmap[] or an R3G3B2 map, it should - * probably be a linear ( or gamma corrected? ) ramp for higher depths. - */ - -int -rasops_get_cmap(struct rasops_info *ri, uint8_t *palette, size_t bytes) -{ - - if ((ri->ri_depth == 8) && ((ri->ri_flg & RI_8BIT_IS_RGB) != 0)) { - /* generate an R3G3B2 palette */ - int i, idx = 0; - uint8_t tmp; - - if (bytes < 768) - return EINVAL; - for (i = 0; i < 256; i++) { - tmp = i & 0xe0; - /* - * replicate bits so 0xe0 maps to a red value of 0xff - * in order to make white look actually white - */ - tmp |= (tmp >> 3) | (tmp >> 6); - palette[idx] = tmp; - idx++; - - tmp = (i & 0x1c) << 3; - tmp |= (tmp >> 3) | (tmp >> 6); - palette[idx] = tmp; - idx++; - - tmp = (i & 0x03) << 6; - tmp |= tmp >> 2; - tmp |= tmp >> 4; - palette[idx] = tmp; - idx++; - } - } else - memcpy(palette, rasops_cmap, uimin(bytes, sizeof(rasops_cmap))); - return 0; -} Index: src/sys/dev/rasops/rasops.h diff -u src/sys/dev/rasops/rasops.h:1.38 src/sys/dev/rasops/rasops.h:1.38.2.1 --- src/sys/dev/rasops/rasops.h:1.38 Mon Jul 29 08:13:50 2019 +++ src/sys/dev/rasops/rasops.h Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops.h,v 1.38 2019/07/29 08:13:50 rin Exp $ */ +/* $NetBSD: rasops.h,v 1.38.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -32,6 +32,8 @@ #ifndef _RASOPS_H_ #define _RASOPS_H_ 1 +#include <sys/param.h> + #include <dev/wscons/wsconsio.h> #include <dev/wsfont/wsfont.h> @@ -100,8 +102,7 @@ struct rasops_info { * on depths other than 15, 16, 24 and 32 bits per pel. On * 24 bit displays, ri_{r,g,b}num must be 8. */ - uint8_t ri_rnum; - /* number of bits for red */ + uint8_t ri_rnum; /* number of bits for red */ uint8_t ri_gnum; /* number of bits for green */ uint8_t ri_bnum; /* number of bits for blue */ uint8_t ri_rpos; /* which bit red starts at */ @@ -114,7 +115,22 @@ struct rasops_info { int ri_emustride; /* bytes per row we actually care about */ int ri_rows; /* number of rows (characters, not pels) */ int ri_cols; /* number of columns (characters, not pels) */ - int ri_delta; /* row delta in bytes */ +#if __NetBSD_Prereq__(9, 99, 1) + struct { + int off; /* offset of underline from bottom */ + int height; /* height of underline */ + } ri_ul; +#else + /* + * XXX + * hack to keep ABI compatibility for netbsd-9, -8, and -7. + */ + // int ri_delta; /* obsoleted */ + struct { + short off; + short height; + } __packed ri_ul; +#endif int ri_pelbytes; /* bytes per pel (may be zero) */ int ri_fontscale; /* fontheight * fontstride */ int ri_xscale; /* fontwidth * pelbytes */ @@ -139,31 +155,14 @@ struct rasops_info { #endif }; -#define DELTA(p, d, cast) ((p) = (cast)((uint8_t *)(p) + (d))) - -#define CHAR_IN_FONT(c,font) \ - ((c) >= (font)->firstchar && \ - ((c) - (font)->firstchar) < (font)->numchars) - -#define PICK_FONT(ri, c) (((c & WSFONT_FLAGS_MASK) == WSFONT_FLAG_OPT) && \ - (ri->ri_optfont.data != NULL)) ? \ - &ri->ri_optfont : ri->ri_font - -#define FONT_GLYPH(uc, font, ri) \ - ((uint8_t *)(font)->data + ((uc) - ((font)->firstchar)) * \ - (ri)->ri_fontscale) - -static __inline uint32_t -be32uatoh(uint8_t *p) -{ - uint32_t u; - - u = p[0]; u <<= 8; - u |= p[1]; u <<= 8; - u |= p[2]; u <<= 8; - u |= p[3]; - return u; -} +#define CHAR_IN_FONT(c, font) \ + ((c) >= (font)->firstchar && \ + (c) - (font)->firstchar < (font)->numchars) + +#define PICK_FONT(ri, c) \ + ((((c) & WSFONT_FLAGS_MASK) == WSFONT_FLAG_OPT && \ + (ri)->ri_optfont.data != NULL) ? \ + &(ri)->ri_optfont : (ri)->ri_font) /* * rasops_init(). @@ -179,9 +178,19 @@ be32uatoh(uint8_t *p) * to -1 (or a new, valid cookie). */ +/* rasops.c */ +int rasops_init(struct rasops_info *, int, int); +int rasops_reconfig(struct rasops_info *, int, int); +void rasops_unpack_attr(long, int *, int *, int *); +void rasops_eraserows(void *, int, int, long); +void rasops_erasecols(void *, int, int, int, long); +int rasops_get_cmap(struct rasops_info *, uint8_t *, size_t); + +extern const uint8_t rasops_cmap[256 * 3]; + +#ifdef _RASOPS_PRIVATE /* - * Per-depth initialization functions. These should not be called outside - * the rasops code. + * Per-depth initialization functions. */ void rasops1_init(struct rasops_info *); void rasops2_init(struct rasops_info *); @@ -191,17 +200,71 @@ void rasops15_init(struct rasops_info *) void rasops24_init(struct rasops_info *); void rasops32_init(struct rasops_info *); -/* rasops.c */ -int rasops_init(struct rasops_info *, int, int); -int rasops_reconfig(struct rasops_info *, int, int); -void rasops_unpack_attr(long, int *, int *, int *); -void rasops_eraserows(void *, int, int, long); -void rasops_erasecols(void *, int, int, int, long); -void rasops_copycols(void *, int, int, int, int); -int rasops_get_cmap(struct rasops_info *, uint8_t *, size_t); +#define ATTR_BG(ri, attr) ((ri)->ri_devcmap[((uint32_t)(attr) >> 16) & 0xf]) +#define ATTR_FG(ri, attr) ((ri)->ri_devcmap[((uint32_t)(attr) >> 24) & 0xf]) + +#define ATTR_MASK_BG __BITS(16, 19) +#define ATTR_MASK_FG __BITS(24, 27) +#define DELTA(p, d, cast) ((p) = (cast)((uint8_t *)(p) + (d))) + +#define FBOFFSET(ri, row, col) \ + ((row) * (ri)->ri_yscale + (col) * (ri)->ri_xscale) + +#define FONT_GLYPH(uc, font, ri) \ + ((uint8_t *)(font)->data + ((uc) - ((font)->firstchar)) * \ + (ri)->ri_fontscale) + +static __inline void +rasops_memset32(void *p, uint32_t val, size_t bytes) +{ + int slop1, slop2, full; + uint8_t *dp = (uint8_t *)p; -extern const uint8_t rasops_isgray[16]; -extern const uint8_t rasops_cmap[256*3]; + if (bytes == 1) { + *dp = val; + return; + } + + slop1 = (4 - ((uintptr_t)dp & 3)) & 3; + slop2 = (bytes - slop1) & 3; + full = (bytes - slop1 /* - slop2 */) >> 2; + + if (slop1 & 1) + *dp++ = val; + + if (slop1 & 2) { + *(uint16_t *)dp = val; + dp += 2; + } + + for (; full; full--) { + *(uint32_t *)dp = val; + dp += 4; + } + + if (slop2 & 2) { + *(uint16_t *)dp = val; + dp += 2; + } + + if (slop2 & 1) + *dp = val; + + return; +} + +static __inline uint32_t +rasops_be32uatoh(uint8_t *p) +{ + uint32_t u; + + u = p[0]; u <<= 8; + u |= p[1]; u <<= 8; + u |= p[2]; u <<= 8; + u |= p[3]; + return u; +} +#endif /* _RASOPS_PRIVATE */ #endif /* _RASOPS_H_ */ Index: src/sys/dev/rasops/rasops1.c diff -u src/sys/dev/rasops/rasops1.c:1.31 src/sys/dev/rasops/rasops1.c:1.31.2.1 --- src/sys/dev/rasops/rasops1.c:1.31 Tue Jul 30 15:29:40 2019 +++ src/sys/dev/rasops/rasops1.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops1.c,v 1.31 2019/07/30 15:29:40 rin Exp $ */ +/* $NetBSD: rasops1.c,v 1.31.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,17 +30,21 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.31 2019/07/30 15:29:40 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.31.2.1 2019/08/15 12:21:27 martin Exp $"); +#ifdef _KERNEL_OPT #include "opt_rasops.h" +#endif #include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> + #include <machine/endian.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsconsio.h> + +#define _RASOPS_PRIVATE +#define RASOPS_DEPTH 1 #include <dev/rasops/rasops.h> #include <dev/rasops/rasops_masks.h> @@ -89,14 +93,17 @@ rasops1_putchar(void *cookie, int row, i { struct rasops_info *ri = (struct rasops_info *)cookie; struct wsdisplay_font *font = PICK_FONT(ri, uc); - uint32_t fs, rs, fb, bg, fg, lmask, rmask; - uint32_t height, width; - uint32_t *rp, *hp, tmp, tmp0, tmp1; + int height, width; + uint32_t bg, fg, lbg, rbg, fb, lmask, rmask, tmp, tmp0, tmp1; + uint32_t *rp, *hp; uint8_t *fr; bool space; hp = NULL; /* XXX GCC */ + if (__predict_false(!CHAR_IN_FONT(uc, font))) + return; + #ifdef RASOPS_CLIPPING /* Catches 'row < 0' case too */ if ((unsigned)row >= (unsigned)ri->ri_rows) @@ -106,35 +113,33 @@ rasops1_putchar(void *cookie, int row, i return; #endif - col *= ri->ri_font->fontwidth; + height = font->fontheight; + width = font->fontwidth; + col *= width; + rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3)); if (ri->ri_hwbits) hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale + ((col >> 3) & ~3)); - height = font->fontheight; - width = font->fontwidth; + col &= 31; - rs = ri->ri_stride; - bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; - fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; + bg = ATTR_BG(ri, attr); + fg = ATTR_FG(ri, attr); /* If fg and bg match this becomes a space character */ - if (uc == ' ' || fg == bg) { + if (uc == ' ' || __predict_false(fg == bg)) { space = true; fr = NULL; /* XXX GCC */ - fs = 0; /* XXX GCC */ } else { space = false; fr = FONT_GLYPH(uc, font, ri); - fs = font->stride; } if (col + width <= 32) { /* Single word, only one mask */ - - rmask = rasops_pmask[col][width]; + rmask = rasops_pmask[col][width & 31]; lmask = ~rmask; if (space) { @@ -142,106 +147,134 @@ rasops1_putchar(void *cookie, int row, i while (height--) { tmp = (*rp & lmask) | bg; *rp = tmp; - DELTA(rp, rs, uint32_t *); if (ri->ri_hwbits) { *hp = tmp; - DELTA(hp, rs, uint32_t *); + DELTA(hp, ri->ri_stride, uint32_t *); } + DELTA(rp, ri->ri_stride, uint32_t *); } } else { while (height--) { - tmp = *rp & lmask; - fb = be32uatoh(fr); - fr += fs; + fb = rasops_be32uatoh(fr); + fr += font->stride; if (bg) fb = ~fb; + + tmp = *rp & lmask; tmp |= (MBE(fb >> col) & rmask); *rp = tmp; - DELTA(rp, rs, uint32_t *); + if (ri->ri_hwbits) { *hp = tmp; - DELTA(hp, rs, uint32_t *); + DELTA(hp, ri->ri_stride, uint32_t *); } + + DELTA(rp, ri->ri_stride, uint32_t *); } } /* Do underline */ if ((attr & WSATTR_UNDERLINE) != 0) { - DELTA(rp, -(ri->ri_stride << 1), uint32_t *); - tmp = (*rp & lmask) | (fg & rmask); - *rp = tmp; - if (ri->ri_hwbits) { - DELTA(hp, -(ri->ri_stride << 1), uint32_t *); - *hp = tmp; + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, + uint32_t *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, uint32_t *); + tmp = (*rp & lmask) | (fg & rmask); + *rp = tmp; + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, uint32_t *); + *hp = tmp; + } } } } else { /* Word boundary, two masks needed */ - lmask = ~rasops_lmask[col]; rmask = ~rasops_rmask[(col + width) & 31]; if (space) { - width = bg & ~rmask; - bg = bg & ~lmask; + lbg = bg & ~lmask; + rbg = bg & ~rmask; + while (height--) { - tmp0 = (rp[0] & lmask) | bg; - tmp1 = (rp[1] & rmask) | width; + tmp0 = (rp[0] & lmask) | lbg; + tmp1 = (rp[1] & rmask) | rbg; + rp[0] = tmp0; rp[1] = tmp1; - DELTA(rp, rs, uint32_t *); + if (ri->ri_hwbits) { hp[0] = tmp0; hp[1] = tmp1; - DELTA(hp, rs, uint32_t *); + DELTA(hp, ri->ri_stride, uint32_t *); } + + DELTA(rp, ri->ri_stride, uint32_t *); } } else { width = 32 - col; + while (height--) { - tmp0 = rp[0] & lmask; - tmp1 = rp[1] & rmask; - fb = be32uatoh(fr); - fr += fs; + fb = rasops_be32uatoh(fr); + fr += font->stride; if (bg) fb = ~fb; + + tmp0 = rp[0] & lmask; tmp0 |= MBE(fb >> col); + + tmp1 = rp[1] & rmask; tmp1 |= (MBE(fb << width) & ~rmask); + rp[0] = tmp0; rp[1] = tmp1; - DELTA(rp, rs, uint32_t *); + if (ri->ri_hwbits) { hp[0] = tmp0; hp[1] = tmp1; - DELTA(hp, rs, uint32_t *); + DELTA(hp, ri->ri_stride, uint32_t *); } + + DELTA(rp, ri->ri_stride, uint32_t *); } } /* Do underline */ if ((attr & WSATTR_UNDERLINE) != 0) { - DELTA(rp, -(ri->ri_stride << 1), uint32_t *); - tmp0 = (rp[0] & lmask) | (fg & ~lmask); - tmp1 = (rp[1] & rmask) | (fg & ~rmask); - rp[0] = tmp0; - rp[1] = tmp1; - if (ri->ri_hwbits) { - DELTA(hp, -(ri->ri_stride << 1), uint32_t *); - hp[0] = tmp0; - hp[1] = tmp1; + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, + uint32_t *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, uint32_t *); + tmp0 = (rp[0] & lmask) | (fg & ~lmask); + tmp1 = (rp[1] & rmask) | (fg & ~rmask); + rp[0] = tmp0; + rp[1] = tmp1; + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, uint32_t *); + hp[0] = tmp0; + hp[1] = tmp1; + } } } } } #ifndef RASOPS_SMALL - +/* + * Width-optimized putchar functions + */ #define RASOPS_WIDTH 8 -#include "rasops1_putchar_width.h" +#include <dev/rasops/rasops1_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 16 -#include "rasops1_putchar_width.h" +#include <dev/rasops/rasops1_putchar_width.h> #undef RASOPS_WIDTH #endif /* !RASOPS_SMALL */ @@ -249,7 +282,4 @@ rasops1_putchar(void *cookie, int row, i /* * Grab routines common to depths where (bpp < 8) */ -#define NAME(ident) rasops1_##ident -#define PIXEL_SHIFT 0 - #include <dev/rasops/rasops_bitops.h> Index: src/sys/dev/rasops/rasops15.c diff -u src/sys/dev/rasops/rasops15.c:1.31 src/sys/dev/rasops/rasops15.c:1.31.2.1 --- src/sys/dev/rasops/rasops15.c:1.31 Mon Jul 29 10:55:56 2019 +++ src/sys/dev/rasops/rasops15.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops15.c,v 1.31 2019/07/29 10:55:56 rin Exp $ */ +/* $NetBSD: rasops15.c,v 1.31.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,16 +30,19 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops15.c,v 1.31 2019/07/29 10:55:56 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops15.c,v 1.31.2.1 2019/08/15 12:21:27 martin Exp $"); +#ifdef _KERNEL_OPT #include "opt_rasops.h" +#endif #include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsconsio.h> + +#define _RASOPS_PRIVATE +#define RASOPS_DEPTH 15 #include <dev/rasops/rasops.h> static void rasops15_putchar(void *, int, int, u_int, long); @@ -52,12 +55,10 @@ static void rasops15_makestamp(struct ra #endif #ifndef RASOPS_SMALL -/* - * 4x1 stamp for optimized character blitting - */ -static uint32_t stamp[32]; -static long stamp_attr; -static int stamp_mutex; /* XXX see note in readme */ +/* stamp for optimized character blitting */ +static uint32_t stamp[32]; +static long stamp_attr; +static struct rasops_info *stamp_ri; /* * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK @@ -104,13 +105,23 @@ rasops15_init(struct rasops_info *ri) #endif /* !RASOPS_SMALL */ default: ri->ri_ops.putchar = rasops15_putchar; - break; + return; } + +#ifndef RASOPS_SMALL + stamp_attr = -1; + stamp_ri = NULL; +#endif } -#define RASOPS_DEPTH 15 -#include "rasops_putchar.h" -#include "rasops_putchar_aa.h" +/* rasops15_putchar */ +#undef RASOPS_AA +#include <dev/rasops/rasops_putchar.h> + +/* rasops15_putchar_aa */ +#define RASOPS_AA +#include <dev/rasops/rasops_putchar.h> +#undef RASOPS_AA #ifndef RASOPS_SMALL /* @@ -119,12 +130,14 @@ rasops15_init(struct rasops_info *ri) static void rasops15_makestamp(struct rasops_info *ri, long attr) { - uint32_t fg, bg; int i; + uint32_t bg, fg; - fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf] & 0xffff; - bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf] & 0xffff; stamp_attr = attr; + stamp_ri = ri; + + bg = ATTR_BG(ri, attr) & 0xffff; + fg = ATTR_FG(ri, attr) & 0xffff; for (i = 0; i < 32; i += 2) { #if BYTE_ORDER == LITTLE_ENDIAN @@ -141,16 +154,19 @@ rasops15_makestamp(struct rasops_info *r } } +/* + * Width-optimized putchar functions + */ #define RASOPS_WIDTH 8 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 12 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 16 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #endif /* !RASOPS_SMALL */ Index: src/sys/dev/rasops/rasops1_putchar_width.h diff -u src/sys/dev/rasops/rasops1_putchar_width.h:1.2 src/sys/dev/rasops/rasops1_putchar_width.h:1.2.2.1 --- src/sys/dev/rasops/rasops1_putchar_width.h:1.2 Mon Jul 29 17:22:19 2019 +++ src/sys/dev/rasops/rasops1_putchar_width.h Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops1_putchar_width.h,v 1.2 2019/07/29 17:22:19 rin Exp $ */ +/* $NetBSD: rasops1_putchar_width.h,v 1.2.2.1 2019/08/15 12:21:27 martin Exp $ */ /* NetBSD: rasops1.c,v 1.28 2019/07/25 03:02:44 rin Exp */ /*- @@ -34,40 +34,44 @@ #error "Width not supported" #endif -#define PUTCHAR_WIDTH1(width) rasops1_putchar ## width -#define PUTCHAR_WIDTH(width) PUTCHAR_WIDTH1(width) - #if RASOPS_WIDTH == 8 -#define COPY_UNIT uint8_t -#define GET_GLYPH tmp = fr[0] +#define SUBST_UNIT uint8_t +#define GET_GLYPH(fr) (fr)[0] #endif #if RASOPS_WIDTH == 16 /* - * rp and hrp are always half-word aligned, whereas + * rp and hp are always half-word aligned, whereas * fr may not be aligned in half-word boundary. */ -#define COPY_UNIT uint16_t +#define SUBST_UNIT uint16_t # if BYTE_ORDER == BIG_ENDIAN -#define GET_GLYPH tmp = (fr[0] << 8) | fr[1] +#define GET_GLYPH(fr) ((fr)[0] << 8) | (fr)[1] # else -#define GET_GLYPH tmp = fr[0] | (fr[1] << 8) +#define GET_GLYPH(fr) (fr)[0] | ((fr)[1] << 8) # endif #endif /* RASOPS_WIDTH == 16 */ +#define NAME(width) NAME1(width) +#define NAME1(width) rasops1_putchar ## width + /* * Width-optimized putchar function. */ static void -PUTCHAR_WIDTH(RASOPS_WIDTH)(void *cookie, int row, int col, u_int uc, long attr) +NAME(RASOPS_WIDTH)(void *cookie, int row, int col, u_int uc, long attr) { struct rasops_info *ri = (struct rasops_info *)cookie; struct wsdisplay_font *font = PICK_FONT(ri, uc); - int height, fs, rs, bg, fg; + int height; + uint32_t bg, fg; uint8_t *fr; - COPY_UNIT *rp, *hrp, tmp; + SUBST_UNIT tmp, *rp, *hp; - hrp = NULL; /* XXX GCC */ + hp = NULL; /* XXX GCC */ + + if (__predict_false(!CHAR_IN_FONT(uc, font))) + return; #ifdef RASOPS_CLIPPING /* Catches 'row < 0' case too */ @@ -78,58 +82,67 @@ PUTCHAR_WIDTH(RASOPS_WIDTH)(void *cookie return; #endif - rp = (COPY_UNIT *)(ri->ri_bits + row * ri->ri_yscale + - col * sizeof(COPY_UNIT)); - if (ri->ri_hwbits) - hrp = (COPY_UNIT *)(ri->ri_hwbits + row * ri->ri_yscale + - col * sizeof(COPY_UNIT)); height = font->fontheight; - rs = ri->ri_stride; - bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; - fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; + rp = (SUBST_UNIT *)(ri->ri_bits + row * ri->ri_yscale + + col * sizeof(SUBST_UNIT)); + if (ri->ri_hwbits) + hp = (SUBST_UNIT *)(ri->ri_hwbits + row * ri->ri_yscale + + col * sizeof(SUBST_UNIT)); + + bg = ATTR_BG(ri, attr); + fg = ATTR_FG(ri, attr); /* If fg and bg match this becomes a space character */ - if (uc == ' ' || fg == bg) { + if (uc == ' ' || __predict_false(fg == bg)) { while (height--) { *rp = bg; - DELTA(rp, rs, COPY_UNIT *); if (ri->ri_hwbits) { - *hrp = bg; - DELTA(hrp, rs, COPY_UNIT *); + *hp = bg; + DELTA(hp, ri->ri_stride, SUBST_UNIT *); } + DELTA(rp, ri->ri_stride, SUBST_UNIT *); } } else { fr = FONT_GLYPH(uc, font, ri); - fs = font->stride; while (height--) { - GET_GLYPH; + tmp = GET_GLYPH(fr); + fr += font->stride; if (bg) tmp = ~tmp; + *rp = tmp; - DELTA(rp, rs, COPY_UNIT *); + if (ri->ri_hwbits) { - *hrp = tmp; - DELTA(hrp, rs, COPY_UNIT *); + *hp = tmp; + DELTA(hp, ri->ri_stride, SUBST_UNIT *); } - fr += fs; + + DELTA(rp, ri->ri_stride, SUBST_UNIT *); } } /* Do underline */ if ((attr & WSATTR_UNDERLINE) != 0) { - DELTA(rp, -(ri->ri_stride << 1), COPY_UNIT *); - *rp = fg; - if (ri->ri_hwbits) { - DELTA(hrp, -(ri->ri_stride << 1), COPY_UNIT *); - *hrp = fg; + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, SUBST_UNIT *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, + SUBST_UNIT *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, SUBST_UNIT *); + *rp = fg; + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, SUBST_UNIT *); + *hp = fg; + } } } } -#undef PUTCHAR_WIDTH1 -#undef PUTCHAR_WIDTH - -#undef COPY_UNIT +#undef SUBST_UNIT #undef GET_GLYPH + +#undef NAME +#undef NAME1 Index: src/sys/dev/rasops/rasops2.c diff -u src/sys/dev/rasops/rasops2.c:1.26 src/sys/dev/rasops/rasops2.c:1.26.2.1 --- src/sys/dev/rasops/rasops2.c:1.26 Mon Jul 29 03:01:09 2019 +++ src/sys/dev/rasops/rasops2.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops2.c,v 1.26 2019/07/29 03:01:09 rin Exp $ */ +/* $NetBSD: rasops2.c,v 1.26.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,17 +30,21 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops2.c,v 1.26 2019/07/29 03:01:09 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops2.c,v 1.26.2.1 2019/08/15 12:21:27 martin Exp $"); +#ifdef _KERNEL_OPT #include "opt_rasops.h" +#endif #include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> + #include <machine/endian.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsconsio.h> + +#define _RASOPS_PRIVATE +#define RASOPS_DEPTH 2 #include <dev/rasops/rasops.h> #include <dev/rasops/rasops_masks.h> @@ -48,20 +52,20 @@ static void rasops2_copycols(void *, int static void rasops2_erasecols(void *, int, int, int, long); static void rasops2_do_cursor(struct rasops_info *); static void rasops2_putchar(void *, int, int col, u_int, long); +static void rasops2_putchar_aa(void *, int, int col, u_int, long); #ifndef RASOPS_SMALL static void rasops2_putchar8(void *, int, int col, u_int, long); static void rasops2_putchar12(void *, int, int col, u_int, long); static void rasops2_putchar16(void *, int, int col, u_int, long); static void rasops2_makestamp(struct rasops_info *, long); - -/* - * 4x1 stamp for optimized character blitting - */ -static uint8_t stamp[16]; -static long stamp_attr; -static int stamp_mutex; /* XXX see note in README */ #endif +#ifndef RASOPS_SMALL +/* stamp for optimized character blitting */ +static uint8_t stamp[16]; +static long stamp_attr; +static struct rasops_info *stamp_ri; + /* * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK * destination = STAMP_READ(offset) @@ -69,6 +73,7 @@ static int stamp_mutex; /* XXX see note #define STAMP_SHIFT(fb, n) ((n) ? (fb) >> 4 : (fb)) #define STAMP_MASK 0xf #define STAMP_READ(o) stamp[o] +#endif /* * Initialize rasops_info struct for this colordepth. @@ -77,6 +82,17 @@ void rasops2_init(struct rasops_info *ri) { + if ((ri->ri_font->fontwidth & 3) != 0) { + ri->ri_ops.erasecols = rasops2_erasecols; + ri->ri_ops.copycols = rasops2_copycols; + ri->ri_do_cursor = rasops2_do_cursor; + } + + if (FONT_IS_ALPHA(ri->ri_font)) { + ri->ri_ops.putchar = rasops2_putchar_aa; + return; + } + switch (ri->ri_font->fontwidth) { #ifndef RASOPS_SMALL case 8: @@ -88,28 +104,16 @@ rasops2_init(struct rasops_info *ri) case 16: ri->ri_ops.putchar = rasops2_putchar16; break; -#endif /* !RASOPS_SMALL */ +#endif default: - panic("fontwidth not 8/12/16 or RASOPS_SMALL - fixme!"); ri->ri_ops.putchar = rasops2_putchar; - break; + return; } - if ((ri->ri_font->fontwidth & 3) != 0) { - ri->ri_ops.erasecols = rasops2_erasecols; - ri->ri_ops.copycols = rasops2_copycols; - ri->ri_do_cursor = rasops2_do_cursor; - } -} - -/* - * Put a single character. This is the generic version. - */ -static void -rasops2_putchar(void *cookie, int row, int col, u_int uc, long attr) -{ - - /* XXX punt */ +#ifndef RASOPS_SMALL + stamp_attr = -1; + stamp_ri = NULL; +#endif } #ifndef RASOPS_SMALL @@ -119,19 +123,22 @@ rasops2_putchar(void *cookie, int row, i static void rasops2_makestamp(struct rasops_info *ri, long attr) { - int i, fg, bg; + int i; + uint32_t bg, fg; - fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf] & 3; - bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf] & 3; stamp_attr = attr; + stamp_ri = ri; + + bg = ATTR_BG(ri, attr) & 3; + fg = ATTR_FG(ri, attr) & 3; for (i = 0; i < 16; i++) { -#if BYTE_ORDER == BIG_ENDIAN -#define NEED_LITTLE_ENDIAN_STAMP RI_BSWAP +#if BYTE_ORDER == LITTLE_ENDIAN + if ((ri->ri_flg & RI_BSWAP) == 0) #else -#define NEED_LITTLE_ENDIAN_STAMP 0 + if ((ri->ri_flg & RI_BSWAP) != 0) #endif - if ((ri->ri_flg & RI_BSWAP) == NEED_LITTLE_ENDIAN_STAMP) { + { /* littel endian */ stamp[i] = (i & 8 ? fg : bg); stamp[i] |= (i & 4 ? fg : bg) << 2; @@ -147,26 +154,33 @@ rasops2_makestamp(struct rasops_info *ri } } -#define RASOPS_DEPTH 2 - +/* + * Width-optimized putchar functions + */ #define RASOPS_WIDTH 8 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 12 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 16 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #endif /* !RASOPS_SMALL */ +/* rasops2_putchar */ +#undef RASOPS_AA +#include <dev/rasops/rasops1-4_putchar.h> + +/* rasops2_putchar_aa */ +#define RASOPS_AA +#include <dev/rasops/rasops1-4_putchar.h> +#undef RASOPS_AA + /* * Grab routines common to depths where (bpp < 8) */ -#define NAME(ident) rasops2_##ident -#define PIXEL_SHIFT 1 - #include <dev/rasops/rasops_bitops.h> Index: src/sys/dev/rasops/rasops24.c diff -u src/sys/dev/rasops/rasops24.c:1.39 src/sys/dev/rasops/rasops24.c:1.39.2.1 --- src/sys/dev/rasops/rasops24.c:1.39 Tue Jul 30 15:23:23 2019 +++ src/sys/dev/rasops/rasops24.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops24.c,v 1.39 2019/07/30 15:23:23 rin Exp $ */ +/* $NetBSD: rasops24.c,v 1.39.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,39 +30,44 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.39 2019/07/30 15:23:23 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.39.2.1 2019/08/15 12:21:27 martin Exp $"); +#ifdef _KERNEL_OPT #include "opt_rasops.h" +#endif #include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> +#include <sys/bswap.h> #include <machine/endian.h> -#include <sys/bswap.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsconsio.h> + +#define _RASOPS_PRIVATE +#define RASOPS_DEPTH 24 #include <dev/rasops/rasops.h> static void rasops24_erasecols(void *, int, int, int, long); static void rasops24_eraserows(void *, int, int, long); static void rasops24_putchar(void *, int, int, u_int, long); static void rasops24_putchar_aa(void *, int, int, u_int, long); +static __inline void + rasops24_makestamp1(struct rasops_info *, uint32_t *, + uint32_t, uint32_t, uint32_t, uint32_t); #ifndef RASOPS_SMALL static void rasops24_putchar8(void *, int, int, u_int, long); static void rasops24_putchar12(void *, int, int, u_int, long); static void rasops24_putchar16(void *, int, int, u_int, long); static void rasops24_makestamp(struct rasops_info *, long); - -/* - * 4x1 stamp for optimized character blitting - */ -static uint32_t stamp[64]; -static long stamp_attr; -static int stamp_mutex; /* XXX see note in readme */ #endif +#ifndef RASOPS_SMALL +/* stamp for optimized character blitting */ +static uint32_t stamp[64]; +static long stamp_attr; +static struct rasops_info *stamp_ri; + /* * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK * destination uint32_t[0] = STAMP_READ(offset) @@ -72,6 +77,7 @@ static int stamp_mutex; /* XXX see note #define STAMP_SHIFT(fb, n) ((n) ? (fb) : (fb) << 4) #define STAMP_MASK (0xf << 4) #define STAMP_READ(o) (*(uint32_t *)((uint8_t *)stamp + (o))) +#endif /* * Initialize rasops_info struct for this colordepth. @@ -80,14 +86,6 @@ void rasops24_init(struct rasops_info *ri) { -#ifndef RASOPS_SMALL - /* - * Different devcmap's are used depending on font widths, - * therefore we need reset stamp here. - */ - stamp_attr = 0; -#endif - if (ri->ri_rnum == 0) { ri->ri_rnum = ri->ri_gnum = ri->ri_bnum = 8; @@ -118,13 +116,44 @@ rasops24_init(struct rasops_info *ri) #endif default: ri->ri_ops.putchar = rasops24_putchar; - break; + return; } + +#ifndef RASOPS_SMALL + stamp_attr = -1; + stamp_ri = NULL; +#endif } -#define RASOPS_DEPTH 24 -#include "rasops_putchar.h" -#include "rasops_putchar_aa.h" +/* rasops24_putchar */ +#undef RASOPS_AA +#include <dev/rasops/rasops_putchar.h> + +/* rasops24_putchar_aa */ +#define RASOPS_AA +#include <dev/rasops/rasops_putchar.h> +#undef RASOPS_AA + +static __inline void +rasops24_makestamp1(struct rasops_info *ri, uint32_t *xstamp, + uint32_t c1, uint32_t c2, uint32_t c3, uint32_t c4) +{ + + xstamp[0] = (c1 << 8) | (c2 >> 16); + xstamp[1] = (c2 << 16) | (c3 >> 8); + xstamp[2] = (c3 << 24) | c4; + +#if BYTE_ORDER == LITTLE_ENDIAN + if ((ri->ri_flg & RI_BSWAP) == 0) +#else + if ((ri->ri_flg & RI_BSWAP) != 0) +#endif + { + xstamp[0] = bswap32(xstamp[0]); + xstamp[1] = bswap32(xstamp[1]); + xstamp[2] = bswap32(xstamp[2]); + } +} #ifndef RASOPS_SMALL /* @@ -133,12 +162,14 @@ rasops24_init(struct rasops_info *ri) static void rasops24_makestamp(struct rasops_info *ri, long attr) { - uint32_t fg, bg, c1, c2, c3, c4; int i; + uint32_t bg, fg, c1, c2, c3, c4; - fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf] & 0xffffff; - bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf] & 0xffffff; stamp_attr = attr; + stamp_ri = ri; + + bg = ATTR_BG(ri, attr) & 0xffffff; + fg = ATTR_FG(ri, attr) & 0xffffff; for (i = 0; i < 64; i += 4) { #if BYTE_ORDER == LITTLE_ENDIAN @@ -152,32 +183,23 @@ rasops24_makestamp(struct rasops_info *r c3 = i & 16 ? fg : bg; c4 = i & 32 ? fg : bg; #endif - stamp[i + 0] = (c1 << 8) | (c2 >> 16); - stamp[i + 1] = (c2 << 16) | (c3 >> 8); - stamp[i + 2] = (c3 << 24) | c4; - -#if BYTE_ORDER == LITTLE_ENDIAN - if ((ri->ri_flg & RI_BSWAP) == 0) { -#else - if ((ri->ri_flg & RI_BSWAP) != 0) { -#endif - stamp[i + 0] = bswap32(stamp[i + 0]); - stamp[i + 1] = bswap32(stamp[i + 1]); - stamp[i + 2] = bswap32(stamp[i + 2]); - } + rasops24_makestamp1(ri, &stamp[i], c1, c2, c3, c4); } } +/* + * Width-optimized putchar functions + */ #define RASOPS_WIDTH 8 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 12 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 16 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #endif /* !RASOPS_SMALL */ @@ -189,8 +211,9 @@ static void rasops24_eraserows(void *cookie, int row, int num, long attr) { struct rasops_info *ri = (struct rasops_info *)cookie; - int n9, n3, n1, cnt, stride; - uint32_t *rp, *dp, *hp, clr, xstamp[3]; + int bytes, full, slop, cnt; + uint32_t bg, xstamp[3]; + uint32_t *dp, *rp, *hp; hp = NULL; /* XXX GCC */ @@ -216,20 +239,8 @@ rasops24_eraserows(void *cookie, int row return; #endif - clr = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf] & 0xffffff; - xstamp[0] = (clr << 8) | (clr >> 16); - xstamp[1] = (clr << 16) | (clr >> 8); - xstamp[2] = (clr << 24) | clr; - -#if BYTE_ORDER == LITTLE_ENDIAN - if ((ri->ri_flg & RI_BSWAP) == 0) { -#else - if ((ri->ri_flg & RI_BSWAP) != 0) { -#endif - xstamp[0] = bswap32(xstamp[0]); - xstamp[1] = bswap32(xstamp[1]); - xstamp[2] = bswap32(xstamp[2]); - } + bg = ATTR_BG(ri, attr) & 0xffffff; + rasops24_makestamp1(ri, xstamp, bg, bg, bg, bg); /* * XXX the wsdisplay_emulops interface seems a little deficient in @@ -238,46 +249,40 @@ rasops24_eraserows(void *cookie, int row * the RI_FULLCLEAR flag is set, clear the entire display. */ if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) { - stride = ri->ri_stride; + bytes = ri->ri_stride; num = ri->ri_height; rp = (uint32_t *)ri->ri_origbits; if (ri->ri_hwbits) hp = (uint32_t *)ri->ri_hworigbits; } else { - stride = ri->ri_emustride; + bytes = ri->ri_emustride; num *= ri->ri_font->fontheight; rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale); if (ri->ri_hwbits) hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale); } - n9 = stride / (4 * 9); - cnt = n9 * (4 * 9); - n3 = (stride - cnt) / (4 * 3); - cnt += n3 * (4 * 3); - n1 = (stride - cnt) / 4; + full = bytes / (4 * 3); + slop = (bytes - full * (4 * 3)) / 4; while (num--) { dp = rp; - for (cnt = n9; cnt; cnt--) { - dp[0] = xstamp[0]; dp[1] = xstamp[1]; dp[2] = xstamp[2]; - dp[3] = xstamp[0]; dp[4] = xstamp[1]; dp[5] = xstamp[2]; - dp[6] = xstamp[0]; dp[7] = xstamp[1]; dp[8] = xstamp[2]; - dp += 9; - } - for (cnt = n3; cnt; cnt--) { - dp[0] = xstamp[0]; dp[1] = xstamp[1]; dp[2] = xstamp[2]; + for (cnt = full; cnt; cnt--) { + dp[0] = xstamp[0]; + dp[1] = xstamp[1]; + dp[2] = xstamp[2]; dp += 3; } - for (cnt = 0; cnt < n1; cnt++) + for (cnt = 0; cnt < slop; cnt++) *dp++ = xstamp[cnt]; if (ri->ri_hwbits) { - memcpy(hp, rp, stride); + memcpy(hp, rp, bytes); DELTA(hp, ri->ri_stride, uint32_t *); } + DELTA(rp, ri->ri_stride, uint32_t *); } } @@ -289,9 +294,10 @@ static void rasops24_erasecols(void *cookie, int row, int col, int num, long attr) { struct rasops_info *ri = (struct rasops_info *)cookie; - int n12, n4, height, cnt, slop1, slop2, clr, xstamp[3]; + int height, slop1, slop2, full, cnt; + uint32_t bg, xstamp[3]; uint32_t *dp; - uint8_t *rp, *hp, *dbp; + uint8_t *bp, *rp, *hp; hp = NULL; /* XXX GCC */ @@ -321,85 +327,66 @@ rasops24_erasecols(void *cookie, int row return; #endif + height = ri->ri_font->fontheight; + num *= ri->ri_xscale; + rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; if (ri->ri_hwbits) hp = ri->ri_hwbits + row * ri->ri_yscale + col * ri->ri_xscale; - num *= ri->ri_font->fontwidth; - height = ri->ri_font->fontheight; - - clr = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf] & 0xffffff; - xstamp[0] = (clr << 8) | (clr >> 16); - xstamp[1] = (clr << 16) | (clr >> 8); - xstamp[2] = (clr << 24) | clr; - -#if BYTE_ORDER == LITTLE_ENDIAN - if ((ri->ri_flg & RI_BSWAP) == 0) { -#else - if ((ri->ri_flg & RI_BSWAP) != 0) { -#endif - xstamp[0] = bswap32(xstamp[0]); - xstamp[1] = bswap32(xstamp[1]); - xstamp[2] = bswap32(xstamp[2]); - } + bg = ATTR_BG(ri, attr) & 0xffffff; + rasops24_makestamp1(ri, xstamp, bg, bg, bg, bg); /* - * The current byte offset mod 4 tells us the number of 24-bit pels - * we need to write for alignment to 32-bits. Once we're aligned on - * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so - * the stamp does not need to be rotated. The following shows the - * layout of 4 pels in a 3 word region and illustrates this: + * Align to word boundary by 24-bit-wise operations: + * + * rp % 4 == 1 ---> slop1 = 3: + * 0123 + * -RGB * - * aaab bbcc cddd + * rp % 4 == 2 ---> slop1 = 6: + * 0123 0123 + * --RG BRGB + * + * rp % 4 == 3 ---> slop1 = 9: + * 0123 0123 0123 + * ---R GBRG BRGB */ - slop1 = (uintptr_t)rp & 3; - cnt = slop1; - n12 = (num - cnt) / 12; - cnt += n12 * 12; - n4 = (num - cnt) / 4; - cnt += n4 * 4; - slop2 = num - cnt; + slop1 = 3 * ((uintptr_t)rp % 4); + slop2 = (num - slop1) % 12; + full = (num - slop1 /* - slop2 */) / 12; while (height--) { - dbp = rp; - - /* Align to 4 bytes */ - /* XXX handle with masks, bring under control of RI_BSWAP */ - for (cnt = slop1; cnt; cnt--) { - *dbp++ = (clr >> 16); - *dbp++ = (clr >> 8); - *dbp++ = clr; - } - - dp = (uint32_t *)dbp; - - /* 12 pels per loop */ - for (cnt = n12; cnt; cnt--) { - dp[0] = xstamp[0]; dp[1] = xstamp[1]; dp[2] = xstamp[2]; - dp[3] = xstamp[0]; dp[4] = xstamp[1]; dp[5] = xstamp[2]; - dp[6] = xstamp[0]; dp[7] = xstamp[1]; dp[8] = xstamp[2]; - dp += 9; + /* Align to word boundary */ + bp = rp; + for (cnt = slop1; cnt; cnt -= 3) { + *bp++ = (bg >> 16); + *bp++ = (bg >> 8); + *bp++ = bg; } /* 4 pels per loop */ - for (cnt = n4; cnt; cnt--) { - dp[0] = xstamp[0]; dp[1] = xstamp[1]; dp[2] = xstamp[2]; + dp = (uint32_t *)bp; + for (cnt = full; cnt; cnt--) { + dp[0] = xstamp[0]; + dp[1] = xstamp[1]; + dp[2] = xstamp[2]; dp += 3; } /* Trailing slop */ - /* XXX handle with masks, bring under control of RI_BSWAP */ - dbp = (uint8_t *)dp; - for (cnt = slop2; cnt; cnt--) { - *dbp++ = (clr >> 16); - *dbp++ = (clr >> 8); - *dbp++ = clr; + bp = (uint8_t *)dp; + for (cnt = slop2; cnt; cnt -= 3) { + *bp++ = (bg >> 16); + *bp++ = (bg >> 8); + *bp++ = bg; } if (ri->ri_hwbits) { - memcpy(hp, rp, num * 3); + memcpy(hp, rp, num); hp += ri->ri_stride; } + rp += ri->ri_stride; } } Index: src/sys/dev/rasops/rasops32.c diff -u src/sys/dev/rasops/rasops32.c:1.39 src/sys/dev/rasops/rasops32.c:1.39.2.1 --- src/sys/dev/rasops/rasops32.c:1.39 Mon Jul 29 10:55:56 2019 +++ src/sys/dev/rasops/rasops32.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops32.c,v 1.39 2019/07/29 10:55:56 rin Exp $ */ +/* $NetBSD: rasops32.c,v 1.39.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,16 +30,19 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.39 2019/07/29 10:55:56 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.39.2.1 2019/08/15 12:21:27 martin Exp $"); +#ifdef _KERNEL_OPT #include "opt_rasops.h" +#endif #include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsconsio.h> + +#define _RASOPS_PRIVATE +#define RASOPS_DEPTH 32 #include <dev/rasops/rasops.h> static void rasops32_putchar(void *, int, int, u_int, long); @@ -49,15 +52,14 @@ static void rasops32_putchar8(void *, in static void rasops32_putchar12(void *, int, int, u_int, long); static void rasops32_putchar16(void *, int, int, u_int, long); static void rasops32_makestamp(struct rasops_info *, long); - -/* - * 4x1 stamp for optimized character blitting - */ -static uint32_t stamp[64]; -static long stamp_attr; -static int stamp_mutex; /* XXX see note in readme */ #endif +#ifndef RASOPS_SMALL +/* stamp for optimized character blitting */ +static uint32_t stamp[64]; +static long stamp_attr; +static struct rasops_info *stamp_ri; + /* * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK * destination uint32_t[0] = STAMP_READ(offset) @@ -68,6 +70,7 @@ static int stamp_mutex; /* XXX see note #define STAMP_SHIFT(fb, n) ((n) ? (fb) : (fb) << 4) #define STAMP_MASK (0xf << 4) #define STAMP_READ(o) (*(uint32_t *)((uint8_t *)stamp + (o))) +#endif /* * Initialize a 'rasops_info' descriptor for this depth. @@ -103,13 +106,23 @@ rasops32_init(struct rasops_info *ri) #endif default: ri->ri_ops.putchar = rasops32_putchar; - break; + return; } + +#ifndef RASOPS_SMALL + stamp_attr = -1; + stamp_ri = NULL; +#endif } -#define RASOPS_DEPTH 32 -#include "rasops_putchar.h" -#include "rasops_putchar_aa.h" +/* rasops32_putchar */ +#undef RASOPS_AA +#include <dev/rasops/rasops_putchar.h> + +/* rasops32_putchar_aa */ +#define RASOPS_AA +#include <dev/rasops/rasops_putchar.h> +#undef RASOPS_AA #ifndef RASOPS_SMALL /* @@ -121,9 +134,11 @@ rasops32_makestamp(struct rasops_info *r uint32_t fg, bg; int i; - fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf]; - bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; stamp_attr = attr; + stamp_ri = ri; + + bg = ATTR_BG(ri, attr); + fg = ATTR_FG(ri, attr); for (i = 0; i < 64; i += 4) { stamp[i + 0] = i & 32 ? fg : bg; @@ -133,16 +148,19 @@ rasops32_makestamp(struct rasops_info *r } } +/* + * Width-optimized putchar functions + */ #define RASOPS_WIDTH 8 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 12 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 16 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #endif /* !RASOPS_SMALL */ Index: src/sys/dev/rasops/rasops4.c diff -u src/sys/dev/rasops/rasops4.c:1.20 src/sys/dev/rasops/rasops4.c:1.20.2.1 --- src/sys/dev/rasops/rasops4.c:1.20 Mon Jul 29 03:01:09 2019 +++ src/sys/dev/rasops/rasops4.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops4.c,v 1.20 2019/07/29 03:01:09 rin Exp $ */ +/* $NetBSD: rasops4.c,v 1.20.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,17 +30,21 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops4.c,v 1.20 2019/07/29 03:01:09 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops4.c,v 1.20.2.1 2019/08/15 12:21:27 martin Exp $"); +#ifdef _KERNEL_OPT #include "opt_rasops.h" +#endif #include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> + #include <machine/endian.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsconsio.h> + +#define _RASOPS_PRIVATE +#define RASOPS_DEPTH 4 #include <dev/rasops/rasops.h> #include <dev/rasops/rasops_masks.h> @@ -53,15 +57,14 @@ static void rasops4_putchar8(void *, int static void rasops4_putchar12(void *, int, int col, u_int, long); static void rasops4_putchar16(void *, int, int col, u_int, long); static void rasops4_makestamp(struct rasops_info *, long); - -/* - * 4x1 stamp for optimized character blitting - */ -static uint16_t stamp[16]; -static long stamp_attr; -static int stamp_mutex; /* XXX see note in README */ #endif +#ifndef RASOPS_SMALL +/* stamp for optimized character blitting */ +static uint16_t stamp[16]; +static long stamp_attr; +static struct rasops_info *stamp_ri; + /* * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK * destination = STAMP_READ(offset) @@ -69,6 +72,7 @@ static int stamp_mutex; /* XXX see note #define STAMP_SHIFT(fb, n) ((n) ? (fb) >> 4 : (fb)) #define STAMP_MASK 0xf #define STAMP_READ(o) stamp[o] +#endif /* * Initialize rasops_info struct for this colordepth. @@ -96,20 +100,14 @@ rasops4_init(struct rasops_info *ri) break; #endif /* !RASOPS_SMALL */ default: - panic("fontwidth not 8/12/16 or RASOPS_SMALL - fixme!"); ri->ri_ops.putchar = rasops4_putchar; - break; + return; } -} - -/* - * Put a single character. This is the generic version. - */ -static void -rasops4_putchar(void *cookie, int row, int col, u_int uc, long attr) -{ - /* XXX punt */ +#ifndef RASOPS_SMALL + stamp_attr = -1; + stamp_ri = NULL; +#endif } #ifndef RASOPS_SMALL @@ -119,19 +117,22 @@ rasops4_putchar(void *cookie, int row, i static void rasops4_makestamp(struct rasops_info *ri, long attr) { - int i, fg, bg; + int i; + uint32_t bg, fg; - fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf] & 0xf; - bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf] & 0xf; stamp_attr = attr; + stamp_ri = ri; + + bg = ATTR_BG(ri, attr) & 0xf; + fg = ATTR_FG(ri, attr) & 0xf; for (i = 0; i < 16; i++) { -#if BYTE_ORDER == BIG_ENDIAN -#define NEED_LITTLE_ENDIAN_STAMP RI_BSWAP +#if BYTE_ORDER == LITTLE_ENDIAN + if ((ri->ri_flg & RI_BSWAP) == 0) #else -#define NEED_LITTLE_ENDIAN_STAMP 0 + if ((ri->ri_flg & RI_BSWAP) != 0) #endif - if ((ri->ri_flg & RI_BSWAP) == NEED_LITTLE_ENDIAN_STAMP) { + { /* little endian */ stamp[i] = (i & 1 ? fg : bg) << 12; stamp[i] |= (i & 2 ? fg : bg) << 8; @@ -147,26 +148,28 @@ rasops4_makestamp(struct rasops_info *ri } } -#define RASOPS_DEPTH 4 - +/* + * Width-optimized putchar functions + */ #define RASOPS_WIDTH 8 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 12 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 16 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #endif /* !RASOPS_SMALL */ +/* rasops4_putchar */ +#undef RASOPS_AA +#include <dev/rasops/rasops1-4_putchar.h> + /* * Grab routines common to depths where (bpp < 8) */ -#define NAME(ident) rasops4_##ident -#define PIXEL_SHIFT 3 - #include <dev/rasops/rasops_bitops.h> Index: src/sys/dev/rasops/rasops8.c diff -u src/sys/dev/rasops/rasops8.c:1.44 src/sys/dev/rasops/rasops8.c:1.44.2.1 --- src/sys/dev/rasops/rasops8.c:1.44 Mon Jul 29 10:55:56 2019 +++ src/sys/dev/rasops/rasops8.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops8.c,v 1.44 2019/07/29 10:55:56 rin Exp $ */ +/* $NetBSD: rasops8.c,v 1.44.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,16 +30,19 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.44 2019/07/29 10:55:56 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.44.2.1 2019/08/15 12:21:27 martin Exp $"); +#ifdef _KERNEL_OPT #include "opt_rasops.h" +#endif #include <sys/param.h> -#include <sys/systm.h> -#include <sys/time.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/wscons/wsconsio.h> + +#define _RASOPS_PRIVATE +#define RASOPS_DEPTH 8 #include <dev/rasops/rasops.h> static void rasops8_putchar(void *, int, int, u_int, long); @@ -49,15 +52,14 @@ static void rasops8_putchar8(void *, in static void rasops8_putchar12(void *, int, int, u_int, long); static void rasops8_putchar16(void *, int, int, u_int, long); static void rasops8_makestamp(struct rasops_info *ri, long); - -/* - * 4x1 stamp for optimized character blitting - */ -static uint32_t stamp[16]; -static long stamp_attr; -static int stamp_mutex; /* XXX see note in README */ #endif +#ifndef RASOPS_SMALL +/* stamp for optimized character blitting */ +static uint32_t stamp[16]; +static long stamp_attr; +static struct rasops_info *stamp_ri; + /* * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK * destination = STAMP_READ(offset) @@ -65,6 +67,7 @@ static int stamp_mutex; /* XXX see note #define STAMP_SHIFT(fb, n) ((n) ? (fb) >> 2 : (fb) << 2) #define STAMP_MASK (0xf << 2) #define STAMP_READ(o) (*(uint32_t *)((uint8_t *)stamp + (o))) +#endif /* * Initialize a 'rasops_info' descriptor for this depth. @@ -101,35 +104,47 @@ rasops8_init(struct rasops_info *ri) #endif /* !RASOPS_SMALL */ default: ri->ri_ops.putchar = rasops8_putchar; - break; + return; } + +#ifndef RASOPS_SMALL + stamp_attr = -1; + stamp_ri = NULL; +#endif } -#define RASOPS_DEPTH 8 -#include "rasops_putchar.h" -#include "rasops_putchar_aa.h" +/* rasops8_putchar */ +#undef RASOPS_AA +#include <dev/rasops/rasops_putchar.h> + +/* rasops8_putchar_aa */ +#define RASOPS_AA +#include <dev/rasops/rasops_putchar.h> +#undef RASOPS_AA #ifndef RASOPS_SMALL /* - * Recompute the 4x1 blitting stamp. + * Recompute the blitting stamp. */ static void rasops8_makestamp(struct rasops_info *ri, long attr) { - uint32_t fg, bg; int i; + uint32_t bg, fg; - fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf] & 0xff; - bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf] & 0xff; stamp_attr = attr; + stamp_ri = ri; + + bg = ATTR_BG(ri, attr) & 0xff; + fg = ATTR_FG(ri, attr) & 0xff; for (i = 0; i < 16; i++) { -#if BYTE_ORDER == BIG_ENDIAN -#define NEED_LITTLE_ENDIAN_STAMP RI_BSWAP +#if BYTE_ORDER == LITTLE_ENDIAN + if ((ri->ri_flg & RI_BSWAP) == 0) #else -#define NEED_LITTLE_ENDIAN_STAMP 0 + if ((ri->ri_flg & RI_BSWAP) != 0) #endif - if ((ri->ri_flg & RI_BSWAP) == NEED_LITTLE_ENDIAN_STAMP) { + { /* little endian */ stamp[i] = (i & 8 ? fg : bg); stamp[i] |= (i & 4 ? fg : bg) << 8; @@ -145,16 +160,19 @@ rasops8_makestamp(struct rasops_info *ri } } +/* + * Width-optimized putchar functions + */ #define RASOPS_WIDTH 8 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 12 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH #define RASOPS_WIDTH 16 -#include "rasops_putchar_width.h" +#include <dev/rasops/rasops_putchar_width.h> #undef RASOPS_WIDTH -#endif +#endif /* !RASOPS_SMALL */ Index: src/sys/dev/rasops/rasops_bitops.h diff -u src/sys/dev/rasops/rasops_bitops.h:1.18 src/sys/dev/rasops/rasops_bitops.h:1.18.2.1 --- src/sys/dev/rasops/rasops_bitops.h:1.18 Tue Jul 30 15:29:40 2019 +++ src/sys/dev/rasops/rasops_bitops.h Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops_bitops.h,v 1.18 2019/07/30 15:29:40 rin Exp $ */ +/* $NetBSD: rasops_bitops.h,v 1.18.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -32,21 +32,33 @@ #ifndef _RASOPS_BITOPS_H_ #define _RASOPS_BITOPS_H_ 1 +#if RASOPS_DEPTH == 1 +#define PIXEL_SHIFT 0 +#elif RASOPS_DEPTH == 2 +#define PIXEL_SHIFT 1 +#elif RASOPS_DEPTH == 4 +#define PIXEL_SHIFT 2 +#else +#error "Depth not supported" +#endif + +#define NAME(name) NAME1(RASOPS_DEPTH, name) +#define NAME1(depth, name) NAME2(depth, name) +#define NAME2(depth, name) rasops ## depth ## _ ## name + /* * Erase columns. */ static void NAME(erasecols)(void *cookie, int row, int col, int num, long attr) { - int lclr, rclr, clr; - struct rasops_info *ri; - uint32_t *dp, *rp, *hp, tmp, lmask, rmask; + struct rasops_info *ri = (struct rasops_info *)cookie; int height, cnt; + uint32_t bg, lbg, rbg, lmask, rmask, tmp; + uint32_t *dp, *rp, *hp; hp = NULL; /* XXX GCC */ - ri = (struct rasops_info *)cookie; - #ifdef RASOPS_CLIPPING if ((unsigned)row >= (unsigned)ri->ri_rows) return; @@ -56,66 +68,73 @@ NAME(erasecols)(void *cookie, int row, i col = 0; } - if ((col + num) > ri->ri_cols) + if (col + num > ri->ri_cols) num = ri->ri_cols - col; if (num <= 0) return; #endif + + height = ri->ri_font->fontheight; col *= ri->ri_font->fontwidth << PIXEL_SHIFT; num *= ri->ri_font->fontwidth << PIXEL_SHIFT; - height = ri->ri_font->fontheight; - clr = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; + rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3)); if (ri->ri_hwbits) hp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale + ((col >> 3) & ~3)); - if ((col & 31) + num <= 32) { - lmask = ~rasops_pmask[col & 31][num]; - lclr = clr & ~lmask; + + col &= 31; + + bg = ATTR_BG(ri, attr); + + if (col + num <= 32) { + lmask = ~rasops_pmask[col][num & 31]; + bg &= ~lmask; while (height--) { - dp = rp; - DELTA(rp, ri->ri_stride, uint32_t *); + tmp = (*rp & lmask) | bg; + *rp = tmp; - tmp = (*dp & lmask) | lclr; - *dp = tmp; if (ri->ri_hwbits) { *hp = tmp; DELTA(hp, ri->ri_stride, uint32_t *); } + + DELTA(rp, ri->ri_stride, uint32_t *); } } else { - lmask = rasops_rmask[col & 31]; + lmask = rasops_rmask[col]; rmask = rasops_lmask[(col + num) & 31]; if (lmask) - num = (num - (32 - (col & 31))) >> 5; + num = (num - (32 - col)) >> 5; else num = num >> 5; - lclr = clr & ~lmask; - rclr = clr & ~rmask; + lbg = bg & ~lmask; + rbg = bg & ~rmask; while (height--) { dp = rp; if (lmask) { - *dp = (*dp & lmask) | lclr; + *dp = (*dp & lmask) | lbg; dp++; } for (cnt = num; cnt > 0; cnt--) - *dp++ = clr; + *dp++ = bg; if (rmask) - *dp = (*dp & rmask) | rclr; + *dp = (*dp & rmask) | rbg; if (ri->ri_hwbits) { memcpy(hp, rp, ((lmask != 0) + num + (rmask != 0)) << 2); DELTA(hp, ri->ri_stride, uint32_t *); } + DELTA(rp, ri->ri_stride, uint32_t *); } } @@ -127,61 +146,68 @@ NAME(erasecols)(void *cookie, int row, i static void NAME(do_cursor)(struct rasops_info *ri) { - int height, row, col, num; - uint32_t *dp, *rp, *hrp, *hp, tmp, lmask, rmask; + int row, col, height, width, cnt; + uint32_t lmask, rmask, tmp; + uint32_t *dp, *rp, *hp; - hrp = hp = NULL; /* XXX GCC */ + hp = NULL; /* XXX GCC */ row = ri->ri_crow; col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT; + height = ri->ri_font->fontheight; - num = ri->ri_font->fontwidth << PIXEL_SHIFT; + width = ri->ri_font->fontwidth << PIXEL_SHIFT; + rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3)); if (ri->ri_hwbits) - hrp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale + + hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale + ((col >> 3) & ~3)); - if ((col & 31) + num <= 32) { - lmask = rasops_pmask[col & 31][num]; + col &= 31; + + if (col + width <= 32) { + lmask = rasops_pmask[col][width & 31]; while (height--) { tmp = *rp ^ lmask; *rp = tmp; if (ri->ri_hwbits) { - *hrp = tmp; - DELTA(hrp, ri->ri_stride, uint32_t *); + *hp = tmp; + DELTA(hp, ri->ri_stride, uint32_t *); } DELTA(rp, ri->ri_stride, uint32_t *); } } else { - lmask = ~rasops_rmask[col & 31]; - rmask = ~rasops_lmask[(col + num) & 31]; + lmask = ~rasops_rmask[col]; + rmask = ~rasops_lmask[(col + width) & 31]; + + if (lmask != -1) + width = (width - (32 - col)) >> 5; + else + width = width >> 5; while (height--) { dp = rp; - DELTA(rp, ri->ri_stride, uint32_t *); - if (ri->ri_hwbits) { - hp = hrp; - DELTA(hrp, ri->ri_stride, uint32_t *); - } - if (lmask != -1) { - tmp = *dp ^ lmask; - *dp = tmp; + if (lmask != -1) + *dp++ ^= lmask; + + for (cnt = width; cnt; cnt--) { + *dp = ~*dp; dp++; - if (ri->ri_hwbits) { - *hp = tmp; - hp++; - } } - if (rmask != -1) { - tmp = *dp ^ rmask; - *dp = tmp; - if (ri->ri_hwbits) - *hp = tmp; + if (rmask != -1) + *dp ^= rmask; + + if (ri->ri_hwbits) { + memcpy(hp, rp, ((lmask != -1) + width + + (rmask != -1)) << 2); + DELTA(hp, ri->ri_stride, uint32_t *); } + + DELTA(rp, ri->ri_stride, uint32_t *); } } } @@ -193,16 +219,17 @@ static void NAME(copycols)(void *cookie, int row, int src, int dst, int num) { struct rasops_info *ri = (struct rasops_info *)cookie; - int height, lnum, rnum, sb, db, cnt, full; - uint32_t tmp, lmask, rmask; - uint32_t *sp, *dp, *srp, *drp, *dhp, *hp; + int height, width, lnum, rnum, sb, db, full, cnt, sboff; + uint32_t lmask, rmask, tmp; + uint32_t *sp, *dp, *srp, *drp, *hp; + bool sbover; - dhp = hp = NULL; /* XXX GCC */ + hp = NULL; /* XXX GCC */ -#ifdef RASOPS_CLIPPING - if (dst == src) + if (__predict_false(dst == src)) return; +#ifdef RASOPS_CLIPPING /* Catches < 0 case too */ if ((unsigned)row >= (unsigned)ri->ri_rows) return; @@ -227,12 +254,16 @@ NAME(copycols)(void *cookie, int row, in return; #endif - cnt = ri->ri_font->fontwidth << PIXEL_SHIFT; - src *= cnt; - dst *= cnt; - num *= cnt; - row *= ri->ri_yscale; height = ri->ri_font->fontheight; + width = ri->ri_font->fontwidth << PIXEL_SHIFT; + + row *= ri->ri_yscale; + + src *= width; + dst *= width; + num *= width; + + sb = src & 31; db = dst & 31; if (db + num <= 32) { @@ -240,16 +271,15 @@ NAME(copycols)(void *cookie, int row, in srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); if (ri->ri_hwbits) - dhp = (uint32_t *)(ri->ri_hwbits + row + + hp = (uint32_t *)(ri->ri_hwbits + row + ((dst >> 3) & ~3)); - sb = src & 31; while (height--) { GETBITS(srp, sb, num, tmp); PUTBITS(tmp, db, num, drp); if (ri->ri_hwbits) { - PUTBITS(tmp, db, num, dhp); - DELTA(dhp, ri->ri_stride, uint32_t *); + *hp = *drp; + DELTA(hp, ri->ri_stride, uint32_t *); } DELTA(srp, ri->ri_stride, uint32_t *); DELTA(drp, ri->ri_stride, uint32_t *); @@ -263,27 +293,25 @@ NAME(copycols)(void *cookie, int row, in lnum = (32 - db) & 31; rnum = (dst + num) & 31; - if (lmask) - full = (num - (32 - (dst & 31))) >> 5; + if (lmask != 0) + full = (num - lnum) >> 5; else full = num >> 5; if (src < dst && src + num > dst) { /* Copy right-to-left */ - bool sbover; - int sboff; - srp = (uint32_t *)(ri->ri_bits + row + (((src + num) >> 3) & ~3)); drp = (uint32_t *)(ri->ri_bits + row + (((dst + num) >> 3) & ~3)); - if (ri->ri_hwbits) - dhp = (uint32_t *)(ri->ri_hwbits + row + + if (ri->ri_hwbits) { + hp = (uint32_t *)(ri->ri_hwbits + row + (((dst + num) >> 3) & ~3)); + hp -= (lmask != 0) + full; + } - sb = src & 31; - sbover = (sb + lnum) >= 32; sboff = (src + num) & 31; + sbover = sb + lnum >= 32; if ((sboff -= rnum) < 0) { srp--; sboff += 32; @@ -292,10 +320,8 @@ NAME(copycols)(void *cookie, int row, in while (height--) { sp = srp; dp = drp; - DELTA(srp, ri->ri_stride, uint32_t *); - DELTA(drp, ri->ri_stride, uint32_t *); - if (rnum) { + if (rmask != 0) { GETBITS(sp, sboff, rnum, tmp); PUTBITS(tmp, 0, rnum, dp); } @@ -308,7 +334,7 @@ NAME(copycols)(void *cookie, int row, in *dp = tmp; } - if (lmask) { + if (lmask != 0) { if (sbover) --sp; --dp; @@ -317,53 +343,54 @@ NAME(copycols)(void *cookie, int row, in } if (ri->ri_hwbits) { - hp = dhp; - hp -= full + (lmask != 0); - memcpy(hp, dp, ((rmask != 0) + cnt + - (lmask != 0)) << 2); - DELTA(dhp, ri->ri_stride, uint32_t *); + memcpy(hp, dp, ((lmask != 0) + full + + (rmask != 0)) << 2); + DELTA(hp, ri->ri_stride, uint32_t *); } + + DELTA(srp, ri->ri_stride, uint32_t *); + DELTA(drp, ri->ri_stride, uint32_t *); } } else { /* Copy left-to-right */ srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); if (ri->ri_hwbits) - dhp = (uint32_t *)(ri->ri_hwbits + row + + hp = (uint32_t *)(ri->ri_hwbits + row + ((dst >> 3) & ~3)); - db = dst & 31; while (height--) { - sb = src & 31; sp = srp; dp = drp; - if (lmask) { - GETBITS(sp, sb, lnum, tmp); + sboff = sb; + + if (lmask != 0) { + GETBITS(sp, sboff, lnum, tmp); PUTBITS(tmp, db, lnum, dp); dp++; - if (sb += lnum > 31) { + if ((sboff += lnum) > 31) { sp++; - sb -= 32; + sboff -= 32; } } /* Now aligned to 32-bits wrt dp */ for (cnt = full; cnt; cnt--, sp++) { - GETBITS(sp, sb, 32, tmp); + GETBITS(sp, sboff, 32, tmp); *dp++ = tmp; } - if (rmask) { - GETBITS(sp, sb, rnum, tmp); + if (rmask != 0) { + GETBITS(sp, sboff, rnum, tmp); PUTBITS(tmp, 0, rnum, dp); } if (ri->ri_hwbits) { - memcpy(dhp, drp, ((lmask != 0) + full + + memcpy(hp, drp, ((lmask != 0) + full + (rmask != 0)) << 2); - DELTA(dhp, ri->ri_stride, uint32_t *); + DELTA(hp, ri->ri_stride, uint32_t *); } DELTA(srp, ri->ri_stride, uint32_t *); @@ -372,4 +399,10 @@ NAME(copycols)(void *cookie, int row, in } } +#undef PIXEL_SHIFT + +#undef NAME +#undef NAME1 +#undef NAME2 + #endif /* _RASOPS_BITOPS_H_ */ Index: src/sys/dev/rasops/rasops_masks.c diff -u src/sys/dev/rasops/rasops_masks.c:1.9 src/sys/dev/rasops/rasops_masks.c:1.9.36.1 --- src/sys/dev/rasops/rasops_masks.c:1.9 Mon Dec 2 14:05:51 2013 +++ src/sys/dev/rasops/rasops_masks.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops_masks.c,v 1.9 2013/12/02 14:05:51 tsutsui Exp $ */ +/* $NetBSD: rasops_masks.c,v 1.9.36.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,12 +30,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops_masks.c,v 1.9 2013/12/02 14:05:51 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops_masks.c,v 1.9.36.1 2019/08/15 12:21:27 martin Exp $"); -#include "rasops_masks.h" +#include <dev/rasops/rasops_masks.h> /* `ragged edge' bitmasks */ -const uint32_t rasops_lmask[32+1] = { +const uint32_t rasops_lmask[32 + 1] = { MBE(0x00000000), MBE(0x7fffffff), MBE(0x3fffffff), MBE(0x1fffffff), MBE(0x0fffffff), MBE(0x07ffffff), MBE(0x03ffffff), MBE(0x01ffffff), MBE(0x00ffffff), MBE(0x007fffff), MBE(0x003fffff), MBE(0x001fffff), @@ -47,7 +47,7 @@ const uint32_t rasops_lmask[32+1] = { MBE(0x00000000) }; -const uint32_t rasops_rmask[32+1] = { +const uint32_t rasops_rmask[32 + 1] = { MBE(0x00000000), MBE(0x80000000), MBE(0xc0000000), MBE(0xe0000000), MBE(0xf0000000), MBE(0xf8000000), MBE(0xfc000000), MBE(0xfe000000), MBE(0xff000000), MBE(0xff800000), MBE(0xffc00000), MBE(0xffe00000), Index: src/sys/dev/rasops/rasops_masks.h diff -u src/sys/dev/rasops/rasops_masks.h:1.8 src/sys/dev/rasops/rasops_masks.h:1.8.36.1 --- src/sys/dev/rasops/rasops_masks.h:1.8 Mon Dec 2 14:05:51 2013 +++ src/sys/dev/rasops/rasops_masks.h Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops_masks.h,v 1.8 2013/12/02 14:05:51 tsutsui Exp $ */ +/* $NetBSD: rasops_masks.h,v 1.8.36.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -33,6 +33,7 @@ #define _RASOPS_MASKS_H_ 1 #include <sys/types.h> + #include <machine/endian.h> /* @@ -71,25 +72,24 @@ dw = MBL(*(sp), (x)); \ if (((x) + (w)) > 32) \ dw |= (MBR((sp)[1], 32 - (x))); \ -} while(0); +} while (0 /* CONSTCOND */) /* Put a number of bits ( <= 32 ) from sw to *dp */ #define PUTBITS(sw, x, w, dp) do { \ int n = (x) + (w) - 32; \ - \ if (n <= 0) { \ - n = rasops_pmask[x & 31][w & 31]; \ - *(dp) = (*(dp) & ~n) | (MBR(sw, x) & n); \ + uint32_t mask = rasops_pmask[(x) & 31][(w) & 31]; \ + *(dp) = (*(dp) & ~mask) | (MBR(sw, x) & mask); \ } else { \ - *(dp) = (*(dp) & rasops_rmask[x]) | (MBR((sw), x)); \ + *(dp) = (*(dp) & rasops_rmask[x]) | (MBR(sw, x)); \ (dp)[1] = ((dp)[1] & rasops_rmask[n]) | \ (MBL(sw, 32-(x)) & rasops_lmask[n]); \ } \ -} while(0); +} while (0 /* CONSTCOND */) /* rasops_masks.c */ -extern const uint32_t rasops_lmask[32+1]; -extern const uint32_t rasops_rmask[32+1]; +extern const uint32_t rasops_lmask[32 + 1]; +extern const uint32_t rasops_rmask[32 + 1]; extern const uint32_t rasops_pmask[32][32]; #endif /* _RASOPS_MASKS_H_ */ Index: src/sys/dev/rasops/rasops_putchar.h diff -u src/sys/dev/rasops/rasops_putchar.h:1.5 src/sys/dev/rasops/rasops_putchar.h:1.5.2.1 --- src/sys/dev/rasops/rasops_putchar.h:1.5 Tue Jul 30 15:29:40 2019 +++ src/sys/dev/rasops/rasops_putchar.h Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops_putchar.h,v 1.5 2019/07/30 15:29:40 rin Exp $ */ +/* $NetBSD: rasops_putchar.h,v 1.5.2.1 2019/08/15 12:21:27 martin Exp $ */ /* NetBSD: rasops8.c,v 1.41 2019/07/25 03:02:44 rin Exp */ /*- @@ -35,9 +35,6 @@ #error "Depth not supported" #endif -#define PUTCHAR(depth) PUTCHAR1(depth) -#define PUTCHAR1(depth) rasops ## depth ## _putchar - #if RASOPS_DEPTH == 8 #define COLOR_TYPE uint8_t #elif RASOPS_DEPTH == 15 @@ -47,41 +44,69 @@ #endif #if RASOPS_DEPTH != 24 -#define PIXEL_BYTES sizeof(COLOR_TYPE) -#define SET_PIXEL(p, index) \ - do { \ - *(COLOR_TYPE *)(p) = clr[index]; \ - (p) += sizeof(COLOR_TYPE); \ - } while (0 /* CONSTCOND */) +#define PIXEL_TYPE COLOR_TYPE +#define PIXEL_BYTES sizeof(PIXEL_TYPE) +#define SET_COLOR(p, index) *(p)++ = clr[index] +#define SET_RGB(p, r, g, b) \ + *(p)++ = (((r) >> (8 - ri->ri_rnum)) << ri->ri_rpos) | \ + (((g) >> (8 - ri->ri_gnum)) << ri->ri_gpos) | \ + (((b) >> (8 - ri->ri_bnum)) << ri->ri_bpos) #endif #if RASOPS_DEPTH == 24 +#define PIXEL_TYPE uint8_t #define PIXEL_BYTES 3 -#define SET_PIXEL(p, index) \ +#define SET_COLOR(p, index) \ do { \ COLOR_TYPE c = clr[index]; \ *(p)++ = c >> 16; \ *(p)++ = c >> 8; \ *(p)++ = c; \ } while (0 /* CONSTCOND */) +#define SET_RGB(p, r, g, b) \ + do { \ + (p)[R_OFF] = (r); \ + (p)[G_OFF] = (g); \ + (p)[B_OFF] = (b); \ + (p) += 3; \ + } while (0 /* CONSTCOND */) +#endif + +#define AV(p, w) (((w) * (p)[1] + (0xff - (w)) * (p)[0]) >> 8) + +#if BYTE_ORDER == LITTLE_ENDIAN +#define R_OFF (ri->ri_rpos / 8) +#define G_OFF (ri->ri_gpos / 8) +#define B_OFF (ri->ri_bpos / 8) +#else /* BIG_ENDIAN XXX not tested */ +#define R_OFF (2 - ri->ri_rpos / 8) +#define G_OFF (2 - ri->ri_gpos / 8) +#define B_OFF (2 - ri->ri_bpos / 8) +#endif + +#define NAME(depth) NAME1(depth) +#ifndef RASOPS_AA +#define NAME1(depth) rasops ## depth ## _putchar +#else +#define NAME1(depth) rasops ## depth ## _putchar_aa #endif /* * Put a single character. */ static void -PUTCHAR(RASOPS_DEPTH)(void *cookie, int row, int col, u_int uc, long attr) +NAME(RASOPS_DEPTH)(void *cookie, int row, int col, u_int uc, long attr) { struct rasops_info *ri = (struct rasops_info *)cookie; struct wsdisplay_font *font = PICK_FONT(ri, uc); - int width, height, cnt, fs; - uint32_t fb; - uint8_t *dp, *rp, *hp, *fr; + int height, width, cnt; + uint8_t *fr; COLOR_TYPE clr[2]; + PIXEL_TYPE *dp, *rp, *hp; hp = NULL; /* XXX GCC */ - if (!CHAR_IN_FONT(uc, font)) + if (__predict_false(!CHAR_IN_FONT(uc, font))) return; #ifdef RASOPS_CLIPPING @@ -93,66 +118,117 @@ PUTCHAR(RASOPS_DEPTH)(void *cookie, int return; #endif - rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; - if (ri->ri_hwbits) - hp = ri->ri_hwbits + row * ri->ri_yscale + col * ri->ri_xscale; - height = font->fontheight; width = font->fontwidth; - clr[0] = (COLOR_TYPE)ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; - clr[1] = (COLOR_TYPE)ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf]; + rp = (PIXEL_TYPE *)(ri->ri_bits + FBOFFSET(ri, row, col)); + if (ri->ri_hwbits) + hp = (PIXEL_TYPE *)(ri->ri_hwbits + FBOFFSET(ri, row, col)); + + clr[0] = (COLOR_TYPE)ATTR_BG(ri, attr); + clr[1] = (COLOR_TYPE)ATTR_FG(ri, attr); if (uc == ' ') { while (height--) { dp = rp; for (cnt = width; cnt; cnt--) - SET_PIXEL(dp, 0); + SET_COLOR(dp, 0); if (ri->ri_hwbits) { uint16_t bytes = width * PIXEL_BYTES; /* XXX GCC */ memcpy(hp, rp, bytes); - hp += ri->ri_stride; + DELTA(hp, ri->ri_stride, PIXEL_TYPE *); } - rp += ri->ri_stride; + DELTA(rp, ri->ri_stride, PIXEL_TYPE *); } } else { fr = FONT_GLYPH(uc, font, ri); - fs = font->stride; + +#ifdef RASOPS_AA + int off[2]; + uint8_t r[2], g[2], b[2]; + + /* + * This is independent to positions/lengths of RGB in pixel. + */ + off[0] = (((uint32_t)attr >> 16) & 0xf) * 3; + off[1] = (((uint32_t)attr >> 24) & 0xf) * 3; + + r[0] = rasops_cmap[off[0]]; + r[1] = rasops_cmap[off[1]]; + g[0] = rasops_cmap[off[0] + 1]; + g[1] = rasops_cmap[off[1] + 1]; + b[0] = rasops_cmap[off[0] + 2]; + b[1] = rasops_cmap[off[1] + 2]; +#endif while (height--) { dp = rp; - fb = be32uatoh(fr); - fr += fs; + +#ifndef RASOPS_AA + uint32_t fb = rasops_be32uatoh(fr); + fr += ri->ri_font->stride; + for (cnt = width; cnt; cnt--) { - SET_PIXEL(dp, (fb >> 31) & 1); + SET_COLOR(dp, (fb >> 31) & 1); fb <<= 1; } +#else /* RASOPS_AA */ + for (cnt = width; cnt; cnt--) { + int w = *fr++; + if (w == 0xff) + SET_COLOR(dp, 1); + else if (w == 0) + SET_COLOR(dp, 0); + else + SET_RGB(dp, + AV(r, w), AV(g, w), AV(b, w)); + } +#endif if (ri->ri_hwbits) { uint16_t bytes = width * PIXEL_BYTES; /* XXX GCC */ memcpy(hp, rp, bytes); - hp += ri->ri_stride; + DELTA(hp, ri->ri_stride, PIXEL_TYPE *); } - rp += ri->ri_stride; + DELTA(rp, ri->ri_stride, PIXEL_TYPE *); } } /* Do underline */ if ((attr & WSATTR_UNDERLINE) != 0) { - rp -= (ri->ri_stride << 1); - dp = rp; - while (width--) - SET_PIXEL(dp, 1); - if (ri->ri_hwbits) { - hp -= (ri->ri_stride << 1); - uint16_t bytes = width * PIXEL_BYTES; /* XXX GCC */ - memcpy(hp, rp, bytes); + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, PIXEL_TYPE *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, + PIXEL_TYPE *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, PIXEL_TYPE *); + dp = rp; + for (cnt = width; cnt; cnt--) + SET_COLOR(dp, 1); + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, PIXEL_TYPE *); + uint16_t bytes = width * PIXEL_BYTES; + /* XXX GCC */ + memcpy(hp, rp, bytes); + } } } } -#undef PUTCHAR #undef COLOR_TYPE + +#undef PIXEL_TYPE #undef PIXEL_BYTES -#undef SET_PIXEL +#undef SET_COLOR +#undef SET_RGB + +#undef AV + +#undef R_OFF +#undef G_OFF +#undef B_OFF + +#undef NAME +#undef NAME1 Index: src/sys/dev/rasops/rasops_putchar_width.h diff -u src/sys/dev/rasops/rasops_putchar_width.h:1.9 src/sys/dev/rasops/rasops_putchar_width.h:1.9.2.1 --- src/sys/dev/rasops/rasops_putchar_width.h:1.9 Tue Jul 30 15:29:40 2019 +++ src/sys/dev/rasops/rasops_putchar_width.h Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops_putchar_width.h,v 1.9 2019/07/30 15:29:40 rin Exp $ */ +/* $NetBSD: rasops_putchar_width.h,v 1.9.2.1 2019/08/15 12:21:27 martin Exp $ */ /* NetBSD: rasops8.c,v 1.41 2019/07/25 03:02:44 rin Exp */ /*- @@ -39,15 +39,6 @@ #error "Width not supported" #endif -#define PUTCHAR_WIDTH1(depth, width) rasops ## depth ## _putchar ## width -#define PUTCHAR_WIDTH(depth, width) PUTCHAR_WIDTH1(depth, width) - -#define PUTCHAR1(depth) rasops ## depth ## _putchar -#define PUTCHAR(depth) PUTCHAR1(depth) - -#define MAKESTAMP1(depth) rasops ## depth ## _makestamp -#define MAKESTAMP(depth) MAKESTAMP1(depth) - #if RASOPS_DEPTH == 2 #define STAMP_TYPE uint8_t #elif RASOPS_DEPTH == 4 @@ -172,6 +163,8 @@ } while (0 /* CONSTCOND */) #endif +/* ################################################################### */ + #if RASOPS_WIDTH == 8 #define SUBST_GLYPH \ do { \ @@ -195,21 +188,37 @@ } while (0 /* CONSTCOND */) #endif +/* ################################################################### */ + +#define NAME(depth, width) NAME1(depth, width) +#define NAME1(depth, width) rasops ## depth ## _putchar ## width + +#define PUTCHAR(depth) PUTCHAR1(depth) +#define PUTCHAR1(depth) rasops ## depth ## _putchar + +#define MAKESTAMP(depth) MAKESTAMP1(depth) +#define MAKESTAMP1(depth) rasops ## depth ## _makestamp + /* * Width-optimized putchar function. */ static void -PUTCHAR_WIDTH(RASOPS_DEPTH, RASOPS_WIDTH)(void *cookie, int row, int col, - u_int uc, long attr) +NAME(RASOPS_DEPTH, RASOPS_WIDTH)(void *cookie, int row, int col, u_int uc, + long attr) { struct rasops_info *ri = (struct rasops_info *)cookie; struct wsdisplay_font *font = PICK_FONT(ri, uc); - int height, fs; - STAMP_TYPE *rp, *hp; + int height; uint8_t *fr; + bool do_ul; + STAMP_TYPE *rp, *hp; hp = NULL; /* XXX GCC */ + /* check if character fits into font limits */ + if (__predict_false(!CHAR_IN_FONT(uc, font))) + return; + #ifdef RASOPS_CLIPPING /* Catches 'row < 0' case too */ if ((unsigned)row >= (unsigned)ri->ri_rows) @@ -219,29 +228,23 @@ PUTCHAR_WIDTH(RASOPS_DEPTH, RASOPS_WIDTH return; #endif - /* check if character fits into font limits */ - if (!CHAR_IN_FONT(uc, font)) - return; - - /* Can't risk remaking the stamp if it's already in use */ - if (stamp_mutex++) { - stamp_mutex--; - PUTCHAR(RASOPS_DEPTH)(cookie, row, col, uc, attr); - return; - } + /* + * We don't care attributions other than back/foreground + * colors when using stamp. + */ + do_ul = (attr & WSATTR_UNDERLINE) != 0; + attr &= (ATTR_MASK_BG | ATTR_MASK_FG); /* Recompute stamp? */ - if (attr != stamp_attr) + if (attr != stamp_attr || __predict_false(ri != stamp_ri)) MAKESTAMP(RASOPS_DEPTH)(ri, attr); - rp = (STAMP_TYPE *)(ri->ri_bits + row * ri->ri_yscale + - col * ri->ri_xscale); - if (ri->ri_hwbits) - hp = (STAMP_TYPE *)(ri->ri_hwbits + row * ri->ri_yscale + - col * ri->ri_xscale); - height = font->fontheight; + rp = (STAMP_TYPE *)(ri->ri_bits + FBOFFSET(ri, row, col)); + if (ri->ri_hwbits) + hp = (STAMP_TYPE *)(ri->ri_hwbits + FBOFFSET(ri, row, col)); + if (uc == ' ') { while (height--) { SUBST_STAMP(0); @@ -253,11 +256,9 @@ PUTCHAR_WIDTH(RASOPS_DEPTH, RASOPS_WIDTH } } else { fr = FONT_GLYPH(uc, font, ri); - fs = font->stride; - while (height--) { SUBST_GLYPH; - fr += fs; + fr += font->stride; if (ri->ri_hwbits) { memcpy(hp, rp, SUBST_BYTES); DELTA(hp, ri->ri_stride, STAMP_TYPE *); @@ -267,16 +268,21 @@ PUTCHAR_WIDTH(RASOPS_DEPTH, RASOPS_WIDTH } /* Do underline */ - if ((attr & WSATTR_UNDERLINE) != 0) { - DELTA(rp, -(ri->ri_stride << 1), STAMP_TYPE *); - SUBST_STAMP(FILLED_STAMP); - if (ri->ri_hwbits) { - DELTA(hp, -(ri->ri_stride << 1), STAMP_TYPE *); - memcpy(hp, rp, SUBST_BYTES); + if (do_ul) { + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, STAMP_TYPE *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, + STAMP_TYPE *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, STAMP_TYPE *); + SUBST_STAMP(FILLED_STAMP); + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, STAMP_TYPE *); + memcpy(hp, rp, SUBST_BYTES); + } } } - - stamp_mutex--; } #undef STAMP_TYPE @@ -286,17 +292,17 @@ PUTCHAR_WIDTH(RASOPS_DEPTH, RASOPS_WIDTH #undef FILLED_STAMP -#undef PUTCHAR_WIDTH1 -#undef PUTCHAR_WIDTH - -#undef PUTCHAR1 -#undef PUTCHAR - -#undef MAKESTAMP1 -#undef MAKESTAMP - #undef SUBST_STAMP1 #undef SUBST_STAMP #undef SUBST_GLYPH1 #undef SUBST_GLYPH + +#undef NAME +#undef NAME1 + +#undef PUTCHAR +#undef PUTCHAR1 + +#undef MAKESTAMP +#undef MAKESTAMP1 Index: src/sys/dev/wscons/wsdisplay_vcons.c diff -u src/sys/dev/wscons/wsdisplay_vcons.c:1.39 src/sys/dev/wscons/wsdisplay_vcons.c:1.39.4.1 --- src/sys/dev/wscons/wsdisplay_vcons.c:1.39 Sat Dec 1 00:28:45 2018 +++ src/sys/dev/wscons/wsdisplay_vcons.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_vcons.c,v 1.39 2018/12/01 00:28:45 msaitoh Exp $ */ +/* $NetBSD: wsdisplay_vcons.c,v 1.39.4.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 2005, 2006 Michael Lorenz @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.39 2018/12/01 00:28:45 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.39.4.1 2019/08/15 12:21:27 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -430,8 +430,23 @@ vcons_load_font(void *v, void *cookie, s /* allocate new buffers */ vcons_alloc_buffers(vd, scr); - /* save the potentially changed putchar */ + /* save the potentially changed ri_ops */ + vd->eraserows = ri->ri_ops.eraserows; + vd->erasecols = ri->ri_ops.erasecols; scr->putchar = ri->ri_ops.putchar; + vd->cursor = ri->ri_ops.cursor; + + if (scr->scr_flags & VCONS_NO_COPYCOLS) { + vd->copycols = vcons_copycols_noread; + } else { + vd->copycols = ri->ri_ops.copycols; + } + + if (scr->scr_flags & VCONS_NO_COPYROWS) { + vd->copyrows = vcons_copyrows_noread; + } else { + vd->copyrows = ri->ri_ops.copyrows; + } /* and put our wrappers back */ ri->ri_ops.eraserows = vcons_eraserows; Index: src/sys/dev/wsfb/genfb.c diff -u src/sys/dev/wsfb/genfb.c:1.67 src/sys/dev/wsfb/genfb.c:1.67.2.1 --- src/sys/dev/wsfb/genfb.c:1.67 Mon Jul 29 14:07:37 2019 +++ src/sys/dev/wsfb/genfb.c Thu Aug 15 12:21:27 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: genfb.c,v 1.67 2019/07/29 14:07:37 rin Exp $ */ +/* $NetBSD: genfb.c,v 1.67.2.1 2019/08/15 12:21:27 martin Exp $ */ /*- * Copyright (c) 2007 Michael Lorenz @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.67 2019/07/29 14:07:37 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.67.2.1 2019/08/15 12:21:27 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -261,6 +261,9 @@ genfb_attach(struct genfb_softc *sc, str sc->sc_shadowfb = kmem_alloc(sc->sc_fbsize, KM_SLEEP); if (sc->sc_want_clear == false) memcpy(sc->sc_shadowfb, sc->sc_fbaddr, sc->sc_fbsize); + aprint_verbose_dev(sc->sc_dev, + "shadow framebuffer enabled, size %zu KB\n", + sc->sc_fbsize >> 10); } vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, @@ -538,6 +541,7 @@ genfb_init_screen(void *cookie, struct v struct genfb_softc *sc = cookie; struct rasops_info *ri = &scr->scr_ri; int wantcols; + bool is_bgr; ri->ri_depth = sc->sc_depth; ri->ri_width = sc->sc_width; @@ -560,10 +564,12 @@ genfb_init_screen(void *cookie, struct v if (existing && sc->sc_want_clear) ri->ri_flg |= RI_CLEAR; - if (ri->ri_depth == 32 || ri->ri_depth == 24) { + switch (ri->ri_depth) { + case 32: + case 24: ri->ri_flg |= RI_ENABLE_ALPHA; - bool is_bgr = false; + is_bgr = false; prop_dictionary_get_bool(device_properties(sc->sc_dev), "is_bgr", &is_bgr); if (is_bgr) { @@ -583,13 +589,25 @@ genfb_init_screen(void *cookie, struct v ri->ri_gpos = 8; ri->ri_bpos = 0; } - } + break; - if (ri->ri_depth == 16 || ri->ri_depth == 15) + case 16: + case 15: ri->ri_flg |= RI_ENABLE_ALPHA; + break; + + case 8: + if (sc->sc_cmcb != NULL) + ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB; + break; - if (ri->ri_depth == 8 && sc->sc_cmcb != NULL) - ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB; + case 2: + ri->ri_flg |= RI_ENABLE_ALPHA; + break; + + default: + break; + } wantcols = genfb_calc_cols(sc); Added files: Index: src/sys/dev/rasops/rasops1-4_putchar.h diff -u /dev/null src/sys/dev/rasops/rasops1-4_putchar.h:1.3.2.2 --- /dev/null Thu Aug 15 12:21:28 2019 +++ src/sys/dev/rasops/rasops1-4_putchar.h Thu Aug 15 12:21:27 2019 @@ -0,0 +1,311 @@ +/* $NetBSD: rasops1-4_putchar.h,v 1.3.2.2 2019/08/15 12:21:27 martin Exp $ */ + +/* NetBSD: rasops_bitops.h,v 1.23 2019/08/02 04:39:09 rin Exp */ +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define PIXEL_BITS RASOPS_DEPTH + +#if RASOPS_DEPTH == 1 +#define PIXEL_SHIFT 0 +#elif RASOPS_DEPTH == 2 +#define PIXEL_SHIFT 1 +#elif RASOPS_DEPTH == 4 +#define PIXEL_SHIFT 2 +#else +#error "Depth not supported" +#endif + +#ifndef RASOPS_AA +#define COLOR_MASK __BITS(32 - PIXEL_BITS, 31) +#else +# if RASOPS_DEPTH == 2 +#define COLOR_MASK 0x3 +# else +#error "Anti-aliasing not supported" +# endif +#endif + +#ifndef RASOPS_AA +#define PIXEL_OR(tmp) \ + do { \ + (tmp) |= clr[(fb >> 31) & 1] >> bit; \ + fb <<= 1; \ + } while (0 /* CONSTCOND */) +#else +#define PIXEL_OR(tmp) \ + do { \ + uint8_t c, w = *fr++; \ + if (w == 0xff) \ + c = clr[1]; \ + else if (w == 0) \ + c = clr[0]; \ + else \ + c = (w * clr[1] + (0xff - w) * clr[0]) >> 8; \ + (tmp) |= c << (32 - PIXEL_BITS - bit); \ + } while (0 /* CONSTCOND */) +#endif + +#define NAME(depth) NAME1(depth) +#ifndef RASOPS_AA +#define NAME1(depth) rasops ## depth ## _ ## putchar +#else +#define NAME1(depth) rasops ## depth ## _ ## putchar_aa +#endif + +/* + * Paint a single character. This function is also applicable to + * monochrome, but that in rasops1.c is much simpler and faster. + */ +static void +NAME(RASOPS_DEPTH)(void *cookie, int row, int col, u_int uc, long attr) +{ + struct rasops_info *ri = (struct rasops_info *)cookie; + struct wsdisplay_font *font = PICK_FONT(ri, uc); + int height, width, full, cnt, bit; + uint32_t bg, fg, lbg, rbg, clr[2], lmask, rmask, tmp; + uint32_t *rp, *bp, *hp; + uint8_t *fr; + bool space; + + hp = NULL; /* XXX GCC */ + + if (__predict_false(!CHAR_IN_FONT(uc, font))) + return; + +#ifdef RASOPS_CLIPPING + /* Catches 'row < 0' case too */ + if ((unsigned)row >= (unsigned)ri->ri_rows) + return; + + if ((unsigned)col >= (unsigned)ri->ri_cols) + return; +#endif + + height = font->fontheight; + width = font->fontwidth << PIXEL_SHIFT; + col *= width; + + rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale + + ((col >> 3) & ~3)); + if (ri->ri_hwbits) + hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale + + ((col >> 3) & ~3)); + + col &= 31; + + bg = ATTR_BG(ri, attr); + fg = ATTR_FG(ri, attr); + + /* If fg and bg match this becomes a space character */ + if (uc == ' ' || __predict_false(fg == bg)) { + space = true; + fr = NULL; /* XXX GCC */ + } else { + space = false; + fr = FONT_GLYPH(uc, font, ri); + } + + if (col + width <= 32) { + /* Single word, only one mask */ + rmask = rasops_pmask[col][width & 31]; + lmask = ~rmask; + + if (space) { + bg &= rmask; + while (height--) { + tmp = (*rp & lmask) | bg; + *rp = tmp; + if (ri->ri_hwbits) { + *hp = tmp; + DELTA(hp, ri->ri_stride, uint32_t *); + } + DELTA(rp, ri->ri_stride, uint32_t *); + } + } else { + clr[0] = bg & COLOR_MASK; + clr[1] = fg & COLOR_MASK; + + while (height--) { +#ifndef RASOPS_AA + uint32_t fb = rasops_be32uatoh(fr); + fr += ri->ri_font->stride; +#endif + + tmp = 0; + for (bit = col; bit < col + width; + bit += PIXEL_BITS) + PIXEL_OR(tmp); + tmp = (*rp & lmask) | MBE(tmp); + *rp = tmp; + + if (ri->ri_hwbits) { + *hp = tmp; + DELTA(hp, ri->ri_stride, uint32_t *); + } + + DELTA(rp, ri->ri_stride, uint32_t *); + } + } + + /* Do underline */ + if ((attr & WSATTR_UNDERLINE) != 0) { + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, + uint32_t *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, uint32_t *); + tmp = (*rp & lmask) | (fg & rmask); + *rp = tmp; + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, uint32_t *); + *hp = tmp; + } + } + } + + return; + } + + /* Word boundary, two masks needed */ + lmask = ~rasops_lmask[col]; + rmask = ~rasops_rmask[(col + width) & 31]; + + if (lmask != -1) + width -= 32 - col; + + full = width / 32; + width -= full * 32; + + if (space) { + lbg = bg & ~lmask; + rbg = bg & ~rmask; + + while (height--) { + bp = rp; + + if (lmask != -1) { + *bp = (*bp & lmask) | lbg; + bp++; + } + + for (cnt = full; cnt; cnt--) + *bp++ = bg; + + if (rmask != -1) + *bp = (*bp & rmask) | rbg; + + if (ri->ri_hwbits) { + memcpy(hp, rp, ((lmask != -1) + full + + (rmask != -1)) << 2); + DELTA(hp, ri->ri_stride, uint32_t *); + } + + DELTA(rp, ri->ri_stride, uint32_t *); + } + } else { + clr[0] = bg & COLOR_MASK; + clr[1] = fg & COLOR_MASK; + + while (height--) { + bp = rp; + +#ifndef RASOPS_AA + uint32_t fb = rasops_be32uatoh(fr); + fr += ri->ri_font->stride; +#endif + + if (lmask != -1) { + tmp = 0; + for (bit = col; bit < 32; bit += PIXEL_BITS) + PIXEL_OR(tmp); + *bp = (*bp & lmask) | MBE(tmp); + bp++; + } + + for (cnt = full; cnt; cnt--) { + tmp = 0; + for (bit = 0; bit < 32; bit += PIXEL_BITS) + PIXEL_OR(tmp); + *bp++ = MBE(tmp); + } + + if (rmask != -1) { + tmp = 0; + for (bit = 0; bit < width; bit += PIXEL_BITS) + PIXEL_OR(tmp); + *bp = (*bp & rmask) | MBE(tmp); + } + + if (ri->ri_hwbits) { + memcpy(hp, rp, ((lmask != -1) + full + + (rmask != -1)) << 2); + DELTA(hp, ri->ri_stride, uint32_t *); + } + + DELTA(rp, ri->ri_stride, uint32_t *); + } + } + + /* Do underline */ + if ((attr & WSATTR_UNDERLINE) != 0) { + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, uint32_t *); + bp = rp; + if (lmask != -1) { + *bp = (*bp & lmask) | (fg & ~lmask); + bp++; + } + for (cnt = full; cnt; cnt--) + *bp++ = fg; + if (rmask != -1) + *bp = (*bp & rmask) | (fg & ~rmask); + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, uint32_t *); + memcpy(hp, rp, ((lmask != -1) + full + + (rmask != -1)) << 2); + } + } + } +} + +#undef PIXEL_BITS +#undef PIXEL_SHIFT +#undef COLOR_MASK + +#undef PIXEL_OR + +#undef NAME +#undef NAME1