ref: 96a94c38917bf52c17cc1a280cbb672f4d1d13d3
parent: a321204a2091d20f1ae360064460fd1553938d6f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Apr 12 17:59:52 EDT 2014
libmemdraw: improve readbyte() and writebyte() routines remove unused memsetb() routine. replace foo ? 1 : 0 with foo != 0 avoid double calculation of rgb components in readbyte() handle byte aligned color components in writebyte() which lets us avoid the read-modify-write and the shifting. surprisingly, the branches in the loop are way less important than avoiding the memory access. this change makes ganes/snes playable at -3 scaling.
--- a/sys/src/libmemdraw/draw.c
+++ b/sys/src/libmemdraw/draw.c
@@ -1496,7 +1496,7 @@
end = p->bytey0e + y*p->bwidth;
cmap = p->img->cmap->cmap2rgb;
convgrey = p->convgrey;
- copyalpha = (p->img->flags&Falpha) ? 1 : 0;
+ copyalpha = (p->img->flags&Falpha) != 0;
w = buf;
dx = p->dx;
@@ -1603,7 +1603,7 @@
convgrey = p->convgrey; /* convert rgb to grey */
isgrey = img->flags&Fgrey;
alphaonly = p->alphaonly;
- copyalpha = (img->flags&Falpha) ? 1 : 0;
+ copyalpha = (img->flags&Falpha) != 0;
DBG print("copyalpha %d alphaonly %d convgrey %d isgrey %d\n", copyalpha, alphaonly, convgrey, isgrey);
/* if we can, avoid processing everything */
@@ -1655,9 +1655,10 @@
*w++ = RGB2K(ured, ugrn, ublu);
DBG print("%x\n", w[-1]);
}else{
- *w++ = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]];
- *w++ = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]];
- *w++ = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]];
+ w[0] = ublu;
+ w[1] = ugrn;
+ w[2] = ured;
+ w += 3;
}
}
r += nb;
@@ -1664,7 +1665,7 @@
if(r == end)
r = begin;
}
-
+
b.alpha = copyalpha ? buf : &ones;
b.rgba = (ulong*)buf;
if(alphaonly){
@@ -1708,7 +1709,6 @@
dx = p->dx;
nb = img->depth/8;
- mask = (nb==4) ? 0 : ~((1<<img->depth)-1);
isalpha = img->flags&Falpha;
isgrey = img->flags&Fgrey;
@@ -1720,6 +1720,37 @@
adelta = 0;
}
+ if((img->flags&Fbytes) != 0){
+ int ogry, ored, ogrn, oblu, oalp;
+
+ ogry = img->shift[CGrey]/8;
+ ored = img->shift[CRed]/8;
+ ogrn = img->shift[CGreen]/8;
+ oblu = img->shift[CBlue]/8;
+ oalp = img->shift[CAlpha]/8;
+
+ for(i=0; i<dx; i++){
+ if(isgrey){
+ w[ogry] = *grey;
+ grey += delta;
+ } else {
+ w[ored] = *red;
+ w[ogrn] = *grn;
+ w[oblu] = *blu;
+ red += delta;
+ grn += delta;
+ blu += delta;
+ }
+ if(isalpha){
+ w[oalp] = *alpha;
+ alpha += adelta;
+ }
+ w += nb;
+ }
+ return;
+ }
+
+ mask = (nb==4) ? 0 : ~((1<<img->depth)-1);
for(i=0; i<dx; i++){
u = w[0] | (w[1]<<8) | (w[2]<<16) | (w[3]<<24);
DBG print("u %.8lux...", u);
@@ -2016,17 +2047,6 @@
/*
* Optimized draw for filling and scrolling; uses memset and memmove.
*/
-static void
-memsetb(void *vp, uchar val, int n)
-{
- uchar *p, *ep;
-
- p = vp;
- ep = p+n;
- while(p<ep)
- *p++ = val;
-}
-
static void
memsets(void *vp, ushort val, int n)
{