[comp.sys.mac.programmer] Aligining bitmaps?

jnh@ecemwl.ncsu.edu (Joseph N. Hall) (08/29/89)

What is the most straightforward procedure for ensuring that a window's
portBits begin on a word boundary?  What I would like to do is check after
the user creates or resizes a graphics window and shift the window horizontally
(if necessary) so that it will be aligned for later updates from an offscreen
bitmap.

Also, how much speed difference is there between an aligned and unaligned
one-to-one CopyBits?  I assume that performance is no better for an
odd-byte-aligned bitmap than it is for a totally unaligned bitmap, right?

I'm only messing with b/w bitmaps now, but I'd appreciate hearing the answer
for both classic and color QuickDraw ...

v   v sssss|| joseph hall                      || 4116 Brewster Drive
 v v s   s || jnh@ecemwl.ncsu.edu (Internet)   || Raleigh, NC  27606
  v   sss  || SP Software/CAD Tool Developer, Mac Hacker and Keyboardist
-----------|| Disclaimer: NCSU may not share my views, but is welcome to.

earleh@eleazar.dartmouth.edu (Earle R. Horton) (08/29/89)

In article <3791@ncsuvx.ncsu.edu> jnh@ecemwl.UUCP (Joseph N. Hall) writes:
>What is the most straightforward procedure for ensuring that a window's
>portBits begin on a word boundary?  What I would like to do is check after
>the user creates or resizes a graphics window and shift the window horizontally
>(if necessary) so that it will be aligned for later updates from an offscreen
>bitmap.

I don't know what you mean by straightforward, but ANDing the
horizontal coordinate with NOT-0x0F before calling MoveWindow() should
work fine.  Resize and create should not be a problem, but moving the
window is conceptually difficult for the average user since you will
15 times out of 16 place it on a different location than that to which
it has been dragged if you use the regular DragWindow() routine.  They
might not notice, but if they do they might perceive it as a bug.
Consider dragging the window by some other method that shows the
discrete end positions you will allow.

short x;
	x = whatever;
	x &= ~15;	/* Align x on word boundary not greater than x. */

>Also, how much speed difference is there between an aligned and unaligned
>one-to-one CopyBits?  I assume that performance is no better for an
>odd-byte-aligned bitmap than it is for a totally unaligned bitmap, right?

In four-bit mode, aligned BitMaps makes for noticeably faster
CopyBits().  Most of my experience is in using four-bit mode for
animation, but I think it is definitely worth the trouble to align
source and destination BitMaps when attempting any kind of animation
and the screen depth is greater than one.  Byte alignment seems to be
all that's necessary.  Where did you get your information that word
alignment is needed?

>I'm only messing with b/w bitmaps now, but I'd appreciate hearing the answer
>for both classic and color QuickDraw ...

     I don't notice any difference between aligned or non-aligned
BitMaps with a black and white screen.  On the other hand, these are
subjective results since I haven't done formal timing.

Earle R. Horton

mnkonar@gorby.SRC.Honeywell.COM (Murat N. Konar) (08/29/89)

In article <15288@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu (Earle R. Horton) writes:
-I don't know what you mean by straightforward, but ANDing the
-horizontal coordinate with NOT-0x0F before calling MoveWindow() should
-work fine.  Resize and create should not be a problem, but moving the
-window is conceptually difficult for the average user since you will
-15 times out of 16 place it on a different location than that to which
-it has been dragged if you use the regular DragWindow() routine.  They
-might not notice, but if they do they might perceive it as a bug.
-Consider dragging the window by some other method that shows the
-discrete end positions you will allow.


Ever notice how Hypercard does a *quantized* drag of the main window (on
Mac IIs anyway)?  I've always wondered why but I think maybe you've hit
the nail on the head.



____________________________________________________________________
Have a day. :^|
Murat N. Konar        Honeywell Systems & Research Center, Camden, MN
mnkonar@SRC.honeywell.com (internet) {umn-cs,ems,bthpyd}!srcsip!mnkonar(UUCP)

lsr@Apple.COM (Larry Rosenstein) (08/29/89)

In article <15288@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> In article <3791@ncsuvx.ncsu.edu> jnh@ecemwl.UUCP (Joseph N. Hall) 
writes:
> >What is the most straightforward procedure for ensuring that a window's
> >portBits begin on a word boundary?  What I would like to do is check 
after
> >the user creates or resizes a graphics window and shift the window 
horizontally
> >(if necessary) so that it will be aligned for later updates from an 
offscreen
> >bitmap.
> 
> I don't know what you mean by straightforward, but ANDing the
> horizontal coordinate with NOT-0x0F before calling MoveWindow() should
> work fine.  Resize and create should not be a problem, but moving the

As someone noticed, Hypercard grids the window position and shows this by 
gridding the gray outline.  

Another approach is to perform the alignment offscreen by allocating an 
offscreen bitmap that is 16 bits wider than necessary.  Then you use a 
similar calculation to Earl's and align the offscreen buffer before 
copying it on the screen.  I used this technique in the old MacApp Paint 
program and it worked very well. (And it looked much better than doing 
unaligned CopyBits.)  In this case, you don't have to worry about 
non-standard window behavior.

I'm positive that alignment is important for 1-bit deep bitmaps on a 
68000-based machine.  (It might be that on a 68020 machine it's not 
necessary.)  As I recall, it required 1/2 second on a MacPlus to align a 
MacPaint image offscreen.  I did this by calling CopyBits with the same 
bitmaps as source and destination.  

Also, notice that what counts is the global coordinates of the 
destination.  If you use my trick of aligning the offscreen bitmap, then 
you will need to compute the global coordinates of your window.  To do 
this first call SetPort(yourWindow), assign (0, 0) to a Point, and use 
LocalToGlobal.

Finally, I'm not sure that a word boundary is optimal alignment for Color 
Quickdraw.  I think you might want to use longword alignment.  I haven't 
done any stuff with offscreen pixmaps, so I don't know for sure.

> and the screen depth is greater than one.  Byte alignment seems to be
> all that's necessary.  Where did you get your information that word
> alignment is needed?

I don't know about color, but for 1-bit deep images, word alignment alows 
QuickDraw to fetch and store longwords at a time (except for the edges).  
If you are only byte aligned then it may have to fetch things a byte at a 
time.  (On a 68000 you can't fetch and store a word on an odd boundary; on 
a 68020 you can fetch and store on odd byte boundaries, but you pay a 
speed penalty.)

>      I don't notice any difference between aligned or non-aligned
> BitMaps with a black and white screen.  On the other hand, these are
> subjective results since I haven't done formal timing.

On a MacPlus it is noticeable, although I haven't done any formal 
measurements, either.

Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

earleh@eleazar.dartmouth.edu (Earle R. Horton) (08/29/89)

In article <3967@internal.Apple.COM> lsr@Apple.COM (Larry Rosenstein) writes:
>In article <15288@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
>(Earle R. Horton) writes:
...
>Finally, I'm not sure that a word boundary is optimal alignment for Color 
>Quickdraw.  I think you might want to use longword alignment.  I haven't 
>done any stuff with offscreen pixmaps, so I don't know for sure.
...
>>      I don't notice any difference between aligned or non-aligned
>> BitMaps with a black and white screen.  On the other hand, these are
>> subjective results since I haven't done formal timing.
>
>On a MacPlus it is noticeable, although I haven't done any formal 
>measurements, either.

     OK, I broke out the old Timex, and actually timed some big screen
animation on the Mac II using 1, 2, and 4 bits screen depth with big
offscreen PixMaps.  My conclusion after about a half hour of testing
was that the only alignment that makes any difference to Color
QuickDraw CopyBits() is longword alignment.  The performance increase
when both PixMaps are longword-aligned is what I would call
spectacular, too.  It's about 2 to 1!  There does appear to be little,
if any, performance increase for byte or word alignment over random
alignment, so I wasn't totally wrong before.

     Sorry for any confusion my earlier posting might have caused.

Earle R. Horton

jmunkki@kampi.hut.fi (Juri Munkki) (08/29/89)

In article <3791@ncsuvx.ncsu.edu> jnh@ecemwl.UUCP (Joseph N. Hall) writes:
>What is the most straightforward procedure for ensuring that a window's
>portBits begin on a word boundary?  What I would like to do is check after
>the user creates or resizes a graphics window and shift the window horizontally
>(if necessary) so that it will be aligned for later updates from an offscreen
>bitmap.
>
>Also, how much speed difference is there between an aligned and unaligned
>one-to-one CopyBits?  I assume that performance is no better for an
>odd-byte-aligned bitmap than it is for a totally unaligned bitmap, right?

The speed difference is visible. I assume that you have an offscreen bitmap
that you regularly copy into a window. The best solution for alignment is
to shift the bitmap instead of forcing the window. You will only waste a
few bytes for the extra margin necessary.

Here are a few code fragments:

/*
>>	AdjustVidPort adjusts the offscreen bitmap so that
>>	CopyBits can always work in 32 bit alignment.
>>
>>	Call AdjustVidPort whenever your window has moved.
>>
>>	The method was originally suggested by Larry Rosenstein
>>	from Apple's Advanced Technology Group.
*/
void	AdjustVidPort()
{
	BitMap	temporary;
	GrafPtr	saved;
	
	GetPort(&saved);
	SetPort(&VidPort);

/*	Save old port location:
*/
	temporary=VidPort.portBits;
	
/*	Align port with magic formula:
*/
	MovePortTo((HMARGIN-VTWind->portBits.bounds.left) & 31,0);

/*	Align image:
*/
	CopyBits(	&temporary,		&VidPort.portBits,
			&VidPort.portRect,	&VidPort.portRect,
			0,srcCopy);

	SetPort(saved);
}

/*	Open an offscreen grafport for VT100 screen
**	Make it 32 pixels wider than absolutely necessary.
*/
	RowBytes=	((ts.hsize*ts.charwidth+47)/16)*2;
...
	VidPort.portBits.bounds.left=0;
	VidPort.portBits.bounds.right=ts.hsize*ts.charwidth+32;
	VidPort.portBits.bounds.top=0;
	VidPort.portBits.bounds.bottom=ts.vsize*ts.lineheight;

	VidPort.portRect=VidPort.portBits.bounds;
	VidPort.portRect.right-=32;
	RectRgn(VidPort.visRgn,&VidPort.portRect);
	RectRgn(VidPort.clipRgn,&VidPort.portRect);

The above code makes sure that all your drawing is long word aligned. My
terminal program doubled speed in cases where the window was badly positioned.
All this has no effect on color screens, because I'm using a B&W bitmap
even when the screen is in color. You would have to make small changes to
apply the same technique to color pixmaps.

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^

pwp@shamash.cdc.com ( HOUFAC) (08/29/89)

For a good example of the benefits of aligning the window download the program
"Color Globe". (I'm pretty sure it's on Sumex -- if not Email me and I'll
send it in.)  This program draws a rotating globe in color, displays the
frame/second rate, and has a menu command to align the window. (To what
boundary I don't know.)

On my un-accelerated Mac II it achieves 45 frames/second with a randomly
placed window, and 50 with it aligned.

--Pete Poorman
  Control Data Corporation -- Houston Texas
  pwp@shamash.cdc.com