add 2bpp support, for sake of NeXT monochrome displays, from

matt debergalis <deberg@mit.edu> KB1CTH per PR kern/6741 and kern/6786,
minimally corrected
This commit is contained in:
drochner 1999-01-11 11:08:14 +00:00
parent 9f77dc2e81
commit 2379551296
2 changed files with 226 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: raster.h,v 1.3 1995/11/24 23:50:51 cgd Exp $ */
/* $NetBSD: raster.h,v 1.4 1999/01/11 11:08:14 drochner Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -66,7 +66,7 @@
/* CONFIGURE: The text routines can optionally keep a cache of 8-bit
** characters. This uses about 30K, but makes text on a color screen
** go 3.2 times faster.
** go 3.2 times faster. XXX: it will also break 2bpp displays.
*/
#undef COLORFONT_CACHE
@ -85,7 +85,7 @@
/* Raster struct. */
struct raster {
int width, height; /* size in pixels */
int depth; /* bits per pixel - 1 or 8 */
int depth; /* bits per pixel - 1, 2, or 8 */
int linelongs; /* longs from one line to the next - for padding */
u_int32_t *pixels; /* pointer to the actual bits */
caddr_t data; /* special pointer for frame buffers and subregions */

View File

@ -1,4 +1,4 @@
/* $NetBSD: raster_op.c,v 1.5 1998/12/18 21:59:34 thorpej Exp $ */
/* $NetBSD: raster_op.c,v 1.6 1999/01/11 11:08:14 drochner Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -49,10 +49,14 @@
*
* src required
* 1-bit to 1-bit
* 1-bit to 2-bits
* 1-bit to 8-bits
* 2-bits to 2-bits
* 2-bits to 8-bits
* 8-bits to 8-bits
* no src required
* 1-bit no-src
* 2-bits no-src
* 8-bits no-src
*/
@ -492,8 +496,22 @@ static u_int32_t rightmask[32] = {
#ifdef MSBYTE_FIRST
static u_int32_t bytemask[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
#ifdef RCONS_2BPP
static u_int32_t twobitmask[16] = {
0xc0000000, 0x30000000, 0x0c000000, 0x03000000,
0x00c00000, 0x00300000, 0x000c0000, 0x00030000,
0x0000c000, 0x00003000, 0x00000c00, 0x00000300,
0x000000c0, 0x00000030, 0x0000000c, 0x00000003 };
#endif /* RCONS_2BPP */
#else /*MSBYTE_FIRST*/
static u_int32_t bytemask[4] = { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
#ifdef RCONS_2BPP
static u_int32_t twobitmask[16] = {
0x00000003, 0x0000000c, 0x00000030, 0x000000c0,
0x00000300, 0x00000c00, 0x00003000, 0x0000c000,
0x00030000, 0x000c0000, 0x00300000, 0x00c00000,
0x03000000, 0x0c000000, 0x30000000, 0xc0000000 };
#endif /* RCONS_2BPP */
#endif /*MSBYTE_FIRST*/
@ -640,6 +658,79 @@ raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy )
dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
}
#ifdef RCONS_2BPP
else if ( dst->depth == 2 )
{
/* One to two, using the color in the rop. */
u_int32_t* srclin1;
u_int32_t* dstlin1;
u_int32_t* srclin2;
u_int32_t* srclin;
u_int32_t* dstlin;
register u_int32_t* srclong;
register u_int32_t* dstlong;
register u_int32_t color, dl;
register int srcbit, dstbyte, i;
color = RAS_GETCOLOR( rop );
if ( color == 0 )
color = 3;
/* Make 32 bits of color so we can do the ROP without shifting. */
color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 )
| ( color << 24 ) | ( color << 22 ) | ( color << 20 )
| ( color << 18 ) | ( color << 16 ) | ( color << 14 )
| ( color << 12 ) | ( color << 10 ) | ( color << 8 )
| ( color << 6 ) | ( color << 4 ) | ( color << 2 ));
/* Don't have to worry about overlapping blits here. */
srclin1 = RAS_ADDR( src, sx, sy );
srclin2 = srclin1 + h * src->linelongs;
dstlin1 = RAS_ADDR( dst, dx, dy );
srclin = srclin1;
dstlin = dstlin1;
while ( srclin != srclin2 )
{
srclong = srclin;
srcbit = sx & 31;
dstlong = dstlin;
dstbyte = dx & 15;
i = w;
/* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
ROP_SRCDSTCOLOR(
/*op*/ op,
/*pre*/ while ( i > 0 )
{
dl = *dstlong;,
/*s*/ *srclong & raster_bitmask[srcbit],
/*d*/ dl,
/*c*/ color,
/*pst*/ *dstlong = ( *dstlong & ~twobitmask[dstbyte] ) |
( dl & twobitmask[dstbyte] );
if ( srcbit == 31 )
{
srcbit = 0;
++srclong;
}
else
++srcbit;
if ( dstbyte == 15 )
{
dstbyte = 0;
++dstlong;
}
else
++dstbyte;
--i;
} )
srclin += src->linelongs;
dstlin += dst->linelongs;
}
}
#endif /* RCONS_2BPP */
else
{
/* One to eight, using the color in the rop. This could
@ -711,6 +802,30 @@ raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy )
}
}
}
#ifdef RCONS_2BPP
else if ( src->depth == 2 )
{
/* Two to two blit. */
u_int32_t* srclin1;
u_int32_t* dstlin1;
int srcleftignore, srcrightignore, srclongs;
int dstleftignore, dstrightignore, dstlongs;
srclin1 = RAS_ADDR( src, sx, sy );
dstlin1 = RAS_ADDR( dst, dx, dy );
srcleftignore = ( sx & 15 ) * 2;
srclongs = ( srcleftignore + w * 2 + 31 ) >> 5;
srcrightignore = ( srclongs * 32 - w * 2 - srcleftignore ) & 31;
dstleftignore = ( dx & 15 ) * 2;
dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5;
dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31;
return raster_blit(
src, srclin1, srcleftignore, srcrightignore, srclongs,
dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
}
#endif /* RCONS_2BPP */
else
{
@ -858,6 +973,113 @@ raster_op_nosrc_noclip( dst, dx, dy, w, h, rop )
}
}
#ifdef RCONS_2BPP
else if ( dst->depth == 2 )
{
/* Two-bit no-src blit. */
register u_int32_t color;
u_int32_t* dstlin1;
u_int32_t* dstlin2;
u_int32_t* dstlin;
int dstleftignore, dstrightignore, dstlongs;
u_int32_t dl, lm, nlm, rm, nrm;
register u_int32_t* dstlong2;
register u_int32_t* dstlong;
dstlin1 = RAS_ADDR( dst, dx, dy );
#ifdef BCOPY_FASTER
/* Special-case full-width clears. */
if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 5 )
{
bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_int32_t) );
return 0;
}
#endif /*BCOPY_FASTER*/
color = RAS_GETCOLOR( rop );
if ( color == 0 )
color = 3;
/* Make 32 bits of color so we can do the ROP without shifting. */
color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 )
| ( color << 24 ) | ( color << 22 ) | ( color << 20 )
| ( color << 18 ) | ( color << 16 ) | ( color << 14 )
| ( color << 12 ) | ( color << 10 ) | ( color << 8 )
| ( color << 6 ) | ( color << 4 ) | ( color << 2 ));
dstleftignore = ( dx & 15 ) * 2;
dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5;
dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31;
dstlin2 = dstlin1 + h * dst->linelongs;
dstlin = dstlin1;
if ( dstlongs == 1 )
{
/* It fits into a single longword. */
lm = leftmask[dstleftignore] | rightmask[dstrightignore];
nlm = ~lm;
while ( dstlin != dstlin2 )
{
ROP_DST(
/*op*/ op,
/*pre*/ dl = *dstlin;,
/*d*/ dl,
/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
dstlin += dst->linelongs;
}
}
else
{
lm = leftmask[dstleftignore];
rm = rightmask[dstrightignore];
nrm = ~rm;
nlm = ~lm;
while ( dstlin != dstlin2 )
{
dstlong = dstlin;
dstlong2 = dstlong + dstlongs;
if ( dstrightignore != 0 )
--dstlong2;
/* Leading edge. */
if ( dstleftignore != 0 )
{
ROP_DST(
/*op*/ op,
/*pre*/ dl = *dstlong;,
/*d*/ dl,
/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
++dstlong;
}
/* Main rop. */
ROP_DST(
/*op*/ op,
/*pre*/ while ( dstlong != dstlong2 )
{,
/*d*/ *dstlong,
/*pst*/ ++dstlong;
} )
/* Trailing edge. */
if ( dstrightignore != 0 )
{
ROP_DST(
/*op*/ op,
/*pre*/ dl = *dstlong;,
/*d*/ dl,
/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
}
dstlin += dst->linelongs;
}
}
}
#endif /* RCONS_2BPP */
else
{
/* Eight-bit no-src blit. */