shithub: riscv

Download patch

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)
 {