r1949

dslinux_amadeus at dslinux.in-berlin.de dslinux_amadeus at dslinux.in-berlin.de
Sun Sep 30 20:56:58 CEST 2007


Author: amadeus
Date: 2007-09-30 20:56:52 +0200 (Sun, 30 Sep 2007)
New Revision: 1949

Log:
Speed up primitive drawing operations

Modified: trunk/user/microwin/src/drivers/fblin16.c
===================================================================
--- trunk/user/microwin/src/drivers/fblin16.c	2007-09-29 08:14:54 UTC (rev 1948)
+++ trunk/user/microwin/src/drivers/fblin16.c	2007-09-30 18:56:52 UTC (rev 1949)
@@ -101,9 +101,29 @@
 	DRAWON;
 	addr += x1 + y * psd->linelen;
 	if(gr_mode == MWMODE_COPY) {
+#if NDSDRIVER
+		int count = x2 - x1 + 1;
+		asm ( "   tst    %0, #2\n"		// odd 16bit address?
+		      "   strneh %2, [%0], #2\n"	// yes: store one pixel
+		      "   subne  %1, %1, #1\n"          // count--
+	              "   orr    %2, %2, %2, lsl #16\n"	// extend pixelvalue to 32 bit
+		      "   subs	 %1, %1, #2\n"		// count -= 2	  
+		      "1: strhs  %2, [%0], #4\n"	// draw 2 pixels
+		      "	  subhss %1, %1, #2\n"		// count -= 2	  
+		      "   strhs  %2, [%0], #4\n"	// draw 2 pixels
+		      "	  subhss %1, %1, #2\n"		// count -= 2	  
+		      "   bhs    1b\n"			// and again
+		      "   adds   %1, %1, #1\n"		// count++
+		      "   streqh %2, [%0]\n"		// draw last byte
+		    : /* no output registers */
+		    : "r" (addr), "r" (count), "r" (c) 
+                    : "cc" /* no memory, because we know GCC does not read it here */
+                    );
+#else
 		/* FIXME: memsetw(dst, c, x2-x1+1)*/
 		while(x1++ <= x2)
 			*addr++ = c;
+#endif
 	} else {
 		while (x1++ <= x2) {
 			*addr = applyOpR(gr_mode, c, *addr) | ALPHA_1B;
@@ -130,10 +150,25 @@
 	DRAWON;
 	addr += x + y1 * linelen;
 	if(gr_mode == MWMODE_COPY) {
+#if NDSDRIVER
+		int count = y2 - y1 + 1;
+		asm ( "   mov	 %3, %3, lsl #1\n"      // linelen * 2
+		      "   subs   %1, %1, #1\n"          // count--
+		      "1: strhsh %2, [%0], %3\n"	// draw 1 pixel
+		      "	  subhss %1, %1, #1\n"		// count--
+		      "   strhsh %2, [%0], %3\n"	// draw 1 pixel
+		      "	  subhss %1, %1, #1\n"		// count--
+		      "   bhs    1b\n"			// and again
+		    : /* no output registers */
+		    : "r" (addr), "r" (count), "r" (c), "r" (linelen) 
+                    : "cc" /* no memory, because we know GCC does not read it here */
+                    );
+#else
 		while(y1++ <= y2) {
 			*addr = c;
 			addr += linelen;
 		}
+#endif
 	} else {
 		while (y1++ <= y2) {
 			*addr = applyOpR(gr_mode, c, *addr) | ALPHA_1B;




More information about the dslinux-commit mailing list