[Scummvm-cvs-logs] SF.net SVN: scummvm: [32206] scummvm/branches/gsoc2008-gui/graphics

Tanoku at users.sourceforge.net Tanoku at users.sourceforge.net
Wed May 21 13:21:19 CEST 2008


Revision: 32206
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32206&view=rev
Author:   Tanoku
Date:     2008-05-21 04:21:19 -0700 (Wed, 21 May 2008)

Log Message:
-----------
- Loop unrolling for color fills.

Modified Paths:
--------------
    scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp
    scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h

Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp	2008-05-21 10:07:33 UTC (rev 32205)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp	2008-05-21 11:21:19 UTC (rev 32206)
@@ -211,7 +211,7 @@
 	if (dy == 0) { // horizontal lines
 		// these can be filled really fast with a single memset.
 		// TODO: Platform specific ASM in set_to, would make this thing fly 
-		Common::set_to(ptr, ptr + dx + 1, (PixelType)_fgColor);
+		colorFill(ptr, ptr + dx + 1, (PixelType)_fgColor);
 
 	} else if (dx == 0) { // vertical lines
 		// these ones use a static pitch increase.
@@ -366,21 +366,21 @@
 			if (fill_m == kGradientFill)
 				color = calcGradient(max_h - h, max_h);
 
-			Common::set_to(ptr, ptr + w, color);
+			colorFill(ptr, ptr + w, color);
 			ptr += pitch;
 		}
 	} else {
 		int sw = Base::_strokeWidth, sp = 0, hp = pitch * (h - 1);
 
 		while (sw--) {
-			Common::set_to(ptr + sp, ptr + w + sp, color);
-			Common::set_to(ptr + hp - sp, ptr + w + hp - sp, color);
+			colorFill(ptr + sp, ptr + w + sp, color);
+			colorFill(ptr + hp - sp, ptr + w + hp - sp, color);
 			sp += pitch;
 		}
 
 		while (h--) {
-			Common::set_to(ptr, ptr + Base::_strokeWidth, color);
-			Common::set_to(ptr + w - Base::_strokeWidth, ptr + w, color);
+			colorFill(ptr, ptr + Base::_strokeWidth, color);
+			colorFill(ptr + w - Base::_strokeWidth, ptr + w, color);
 			ptr += pitch;
 		}
 	}
@@ -455,8 +455,8 @@
 
 	if (fill_m == kNoFill) {
 		while (sw++ < Base::_strokeWidth) {
-			Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
-			Common::set_to(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
+			colorFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
+			colorFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
 			sp += pitch;
 
 			__BE_RESET();
@@ -475,8 +475,8 @@
 
 		ptr_fill += pitch * real_radius;
 		while (short_h--) {
-			Common::set_to(ptr_fill, ptr_fill + Base::_strokeWidth, color);
-			Common::set_to(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
+			colorFill(ptr_fill, ptr_fill + Base::_strokeWidth, color);
+			colorFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
 			ptr_fill += pitch;
 		}
 	} else {
@@ -485,21 +485,21 @@
 		if (fill_m == kGradientFill) {
 			while (x++ < y) {
 				__BE_ALGORITHM();
-				Common::set_to(ptr_tl - x - py, ptr_tr + x - py, calcGradient(real_radius - y, long_h));
-				Common::set_to(ptr_tl - y - px, ptr_tr + y - px, calcGradient(real_radius - x, long_h));
+				colorFill(ptr_tl - x - py, ptr_tr + x - py, calcGradient(real_radius - y, long_h));
+				colorFill(ptr_tl - y - px, ptr_tr + y - px, calcGradient(real_radius - x, long_h));
 
-				Common::set_to(ptr_bl - x + py, ptr_br + x + py, calcGradient(long_h - r + y, long_h));
-				Common::set_to(ptr_bl - y + px, ptr_br + y + px, calcGradient(long_h - r + x, long_h));
+				colorFill(ptr_bl - x + py, ptr_br + x + py, calcGradient(long_h - r + y, long_h));
+				colorFill(ptr_bl - y + px, ptr_br + y + px, calcGradient(long_h - r + x, long_h));
 			}
 		} else {
 			while (x++ < y) {
 				__BE_ALGORITHM();			
 
-				Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color);
-				Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color);
+				colorFill(ptr_tl - x - py, ptr_tr + x - py, color);
+				colorFill(ptr_tl - y - px, ptr_tr + y - px, color);
 
-				Common::set_to(ptr_bl - x + py, ptr_br + x + py, color);
-				Common::set_to(ptr_bl - y + px, ptr_br + y + px, color);
+				colorFill(ptr_bl - x + py, ptr_br + x + py, color);
+				colorFill(ptr_bl - y + px, ptr_br + y + px, color);
 
 				// FIXME: maybe not needed at all?
 				__BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
@@ -510,7 +510,7 @@
 		while (short_h--) {
 			if (fill_m == kGradientFill)
 				color = calcGradient(real_radius++, long_h);
-			Common::set_to(ptr_fill, ptr_fill + w + 1, color);
+			colorFill(ptr_fill, ptr_fill + w + 1, color);
 			ptr_fill += pitch;
 		}
 	}
@@ -546,15 +546,15 @@
 			}
 		}
 	} else {
-		Common::set_to(ptr - r, ptr + r, color);
+		colorFill(ptr - r, ptr + r, color);
 		__BE_RESET();
 
 		while (x++ < y) {
 			__BE_ALGORITHM();
-			Common::set_to(ptr - x + py, ptr + x + py, color);
-			Common::set_to(ptr - x - py, ptr + x - py, color);
-			Common::set_to(ptr - y + px, ptr + y + px, color);
-			Common::set_to(ptr - y - px, ptr + y - px, color);
+			colorFill(ptr - x + py, ptr + x + py, color);
+			colorFill(ptr - x - py, ptr + x - py, color);
+			colorFill(ptr - y + px, ptr + y + px, color);
+			colorFill(ptr - y - px, ptr + y - px, color);
 		}
 	}
 }
@@ -732,8 +732,8 @@
 
 	if (fill_m == VectorRenderer::kNoFill) {
 		while (sw++ < Base::_strokeWidth) {
-			Common::set_to(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
-			Common::set_to(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
+			colorFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
+			colorFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color);
 			sp += p;
 
 			x = r - (sw - 1); y = 0; T = 0;
@@ -752,8 +752,8 @@
 
 		ptr_fill += p * r;
 		while (short_h-- >= 0) {
-			Common::set_to(ptr_fill, ptr_fill + Base::_strokeWidth, color);
-			Common::set_to(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
+			colorFill(ptr_fill, ptr_fill + Base::_strokeWidth, color);
+			colorFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color);
 			ptr_fill += p;
 		}
 	} else {
@@ -763,18 +763,18 @@
 		while (x > y++) {
 			__WU_ALGORITHM();
 
-			Common::set_to(ptr_tl - x - py, ptr_tr + x - py, color);
-			Common::set_to(ptr_tl - y - px, ptr_tr + y - px, color);
+			colorFill(ptr_tl - x - py, ptr_tr + x - py, color);
+			colorFill(ptr_tl - y - px, ptr_tr + y - px, color);
 
-			Common::set_to(ptr_bl - x + py, ptr_br + x + py, color);
-			Common::set_to(ptr_bl - y + px, ptr_br + y + px, color);
+			colorFill(ptr_bl - x + py, ptr_br + x + py, color);
+			colorFill(ptr_bl - y + px, ptr_br + y + px, color);
 
 			__WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
 		}
 
 		ptr_fill += p * r;
 		while (short_h-- >= 0) {
-			Common::set_to(ptr_fill, ptr_fill + w + 1, color);
+			colorFill(ptr_fill, ptr_fill + w + 1, color);
 			ptr_fill += p;
 		}
 	}
@@ -814,17 +814,17 @@
 			}
 		}
 	} else {
-		Common::set_to(ptr - r, ptr + r + 1, color);
+		colorFill(ptr - r, ptr + r + 1, color);
 		x = r; y = 0; T = 0;
 		px = p * x; py = 0;
 
 		while (x > y++) {
 			__WU_ALGORITHM();
 
-			Common::set_to(ptr - x + py, ptr + x + py, color);
-			Common::set_to(ptr - x - py, ptr + x - py, color);
-			Common::set_to(ptr - y + px, ptr + y + px, color);
-			Common::set_to(ptr - y - px, ptr + y - px, color);
+			colorFill(ptr - x + py, ptr + x + py, color);
+			colorFill(ptr - x - py, ptr + x - py, color);
+			colorFill(ptr - y + px, ptr + y + px, color);
+			colorFill(ptr - y - px, ptr + y - px, color);
 				
 			__WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1);
 		}				

Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h	2008-05-21 10:07:33 UTC (rev 32205)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h	2008-05-21 11:21:19 UTC (rev 32206)
@@ -339,13 +339,13 @@
 		int pitch = surfacePitch();
 
 		if (mode == kBackgroundFill)
-			Common::set_to(ptr, ptr + w * h, _bgColor);
+			colorFill(ptr, ptr + w * h, _bgColor);
 		else if (mode == kForegroundFill)
-			Common::set_to(ptr, ptr + w * h, _fgColor);
+			colorFill(ptr, ptr + w * h, _fgColor);
 		else if (mode == kGradientFill) {
 			int i = h;
 			while (i--) {
-				Common::set_to(ptr, ptr + w, calcGradient(h - i, h));
+				colorFill(ptr, ptr + w, calcGradient(h - i, h));
 				ptr += pitch;
 			}
 		}
@@ -453,7 +453,7 @@
 	 * @param max Maximum amount of the progress.
 	 * @return Composite color of the gradient at the given "progress" amount.
 	 */
-	inline PixelType calcGradient(uint32 pos, uint32 max) {
+	virtual inline PixelType calcGradient(uint32 pos, uint32 max) {
 		PixelType output = 0;
 		pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max;
 		
@@ -475,11 +475,46 @@
 	 * @param color Color of the pixel
 	 * @param alpha Alpha intensity of the pixel (0-255)
 	 */
-	inline void blendFill(PixelType *first, PixelType *last, PixelType color, uint8 alpha) {
+	virtual inline void blendFill(PixelType *first, PixelType *last, PixelType color, uint8 alpha) {
 		while (first != last)
 			blendPixelPtr(first++, color, alpha);
-	}	
+	}
 
+	/**
+	 * Fills several pixels in a row with a given color.
+	 *
+	 * This is a replacement function for Common::set_to, using an unrolled
+	 * loop to maximize performance on most architectures.
+	 * This function may (and should) be overloaded in any child renderers
+	 * for portable platforms with platform-specific assembly code.
+	 *
+	 * This fill operation is extensively used throughout the renderer, so this
+	 * counts as one of the main bottlenecks. Please replace it with assembly 
+	 * when possible!
+	 *
+	 * @param first Pointer to the first pixel to fill.
+	 * @param last Pointer to the last pixel to fill.
+	 * @param color Color of the pixel
+	 */
+	virtual inline void colorFill(PixelType *first, PixelType *last, PixelType color) {
+		register PixelType *ptr = first;
+		register int count = (last - first);
+		{
+			register int n = (count + 7) / 8;
+			switch (count % 8) {
+			case 0: do { *ptr++ = color;
+			case 7:      *ptr++ = color;
+			case 6:      *ptr++ = color;
+			case 5:      *ptr++ = color;
+			case 4:      *ptr++ = color;
+			case 3:      *ptr++ = color;
+			case 2:      *ptr++ = color;
+			case 1:      *ptr++ = color;
+					} while (--n > 0);
+			}
+		}
+	}
+
 	PixelType _fgColor; /** Foreground color currently being used to draw on the renderer */
 	PixelType _bgColor; /** Background color currently being used to draw on the renderer */
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list