NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/51492: rasops byte order issue

The following reply was made to PR kern/51492; it has been noted by GNATS.

From: Valery Ushakov <>
Subject: Re: kern/51492: rasops byte order issue
Date: Wed, 28 Sep 2016 17:56:41 +0300

 On Tue, Sep 20, 2016 at 16:05:00 +0000, wrote:
 > +	/*
 > +	 * XXX - someone should sanity check but think this was doing
 > +	 *   stamp[i] = 8|16, stamp[i+1] = 2|4 (little endian)
 > +	 *   stamp[i] = 4|2, stamp[i+1] = 16|8 (big endian)
 > +	 * where should be
 > +	 *   stamp[i] = 2|4, stamp[i+1] = 8|16 (little endian)
 > +	 *   stamp[i] = 16|8, stamp[i+1] = 4|2 (big endian)
 > +	 */
 Actually looking at what's going on, I think that patch just inverts
 the problem and makes it work for you on big endian, while probably
 (from RTFS) breaking little endian.
 Stamp code is a bit obfuscated but here's what I think is going on
 here.  We pre-build int32_t stamp[32] array, though it's really a
 [16][2] array where the first index is a nibble (4 bits) of font
 raster and it selects an int32_t[2] array (64 bits) of 4 16-bit RGB
 values (64-bits) to write to the framebuffer.  See STAMP_SHIFT and
 STAMP_MASK macros.
 We encode font raster data with leftmost on-screen bit as the most
 significant bit, e.g
   8-bit wide font:
       0xfe,       /* [][][][][][][].. */
   12-bit wide font (padded with zero bits):
       0x07, 0xf0, /* .....******* */
 We take a nibble of font raster data and get its int32_t[2] array of
 rgb stamp data, so upper (leftmost on-screen) two bits of the nibble
 are always in the stamp[i] and the lower (rightmost on-screen) two
 bits are always in the stamp[i+1], to use rasops15_makestamp() terms.
 The corresponding putchar code is:
      so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
      rp[0] = STAMP_READ(so);
      rp[1] = STAMP_READ(so + 4);
 which is an obfuscated way to index into stamp as if it were a
 two-dimensional array.
 Thus makestamp must always build:
     stamp[i  ] = rgb for { 16, 8 };
     stamp[i+1] = rgb for {  4, 2 };
 but it must take RI_BSWAP into account as well to build either 16|8 or
 8|16 32-bit stamp fragment.  Note, that applying bswap32() to stamp[j]
 will also swap bytes of the 16-bit rgb pixel values, but ri_devcmap
 provides them already bsawp16()'ed for RI_BSAWP (see rasops.c), so it
 will cancel out.

Home | Main Index | Thread Index | Old Index