Alpha unaligned accesses [PATCH]

Darrell Kindred dkindred "at" cmu.edu
Mon, 07 Jun 1999 06:24:47 +0000


Hi,

When running Xvnc on an alpha (Digital Unix 4.0), dragging a
window outline in twm causes a huge number of unaligned
accesses, and is thus extremely slow.  The patch below fixes
this.

For the curious: the code in question starts with addrp
pointing at some pixel location, and the goal is to move
addrp back to a PixelGroup (unsigned long) boundary, then
set y1_or_e1 to the distance addrp was moved (in pixels).
The existing code uses the wrong mask (PIM rather than
PGSZB-1), so except in the 8bpp case, it masks off too few
bits from addrp, leaving addrp possibly unaligned.

This bug is inherited from XFree86 (and originally, X R6.3)
code.  It looks like the XFree86 folks have noticed the
problem too, as XFree86 3.3.3 contains a (different) fix.
Their fix is hairier than this one and only half-right,
though, so I am submitting my fix to them as well.

Thanks for vnc!

- Darrell

--- ./programs/Xserver/cfb/cfb8line.c.orig	Sat Jul 19 00:59:19 1997
+++ ./programs/Xserver/cfb/cfb8line.c	Sun Jun  6 19:32:40 1999
@@ -688,17 +688,11 @@
 # if PSZ == 24
 	    y1_or_e1 = xOffset & 3;
 # else
-	    y1_or_e1 = ((long) addrp) & PIM;
-	    addrp = (PixelType *) (((unsigned char *) addrp) - y1_or_e1);
-#if PGSZ == 32
-#  if PWSH != 2
-	    y1_or_e1 >>= (2 - PWSH);
-#  endif
-#else /* PGSZ == 64 */
-#  if PWSH != 3
-	    y1_or_e1 >>= (3 - PWSH);
-#  endif
-#endif /* PGSZ */
+	    /* Round addrp down to the next PixelGroup boundary, and
+	     * set y1_or_e1 to the excess (in pixels)
+	     * (assumes PGSZB is a power of 2). */
+	    y1_or_e1 = (((unsigned long) addrp) & (PGSZB - 1)) / (PSZ / 8);
+	    addrp -= y1_or_e1;
 # endif /* PSZ == 24 */
 #if PSZ == 24
 	    {

---------------------------------------------------------------------
The VNC mailing list - see http://www.uk.research.att.com/vnc/intouch.html
---------------------------------------------------------------------