[comp.sys.amiga] BltMaskBitMapRastPort

jesup@steinmetz.steinmetz.UUCP (Randell Jesup) (08/12/87)

I've been doing some 4-bitplane, 640x200 graphics work and wondered why, every
time I updated a portion of the screen with the new 1.2 BltMaskBitMapRastPort,
there was a white flash in the area before the update.  In that resolution,
things are slow enough that it was VERY annoying.
	I thought to myself, "Why would it flash?  I KNOW the blitter can
handle a source, destination, and 1 other channel as inputs, it should be a
one pass operation."  So I worked out the minterm for a blit through a mask,
and Lo!, it was the the cookie cut minterm, $ca.  (D = AC + BNC in reduced
form).
	And I consulted the 1.2 Gamma 2 Infominder AutoDocs (holy book) and
saw, as I remembered, that only 2 minterms were allowed (1 for straight copy,
one for inverted).  I looked up the values for the minterms, and Lo!, they
were $e0 and $20.  
	And the inspiration struck!  The BltMaskBitMapRastPort was implemented
as Rob Pecks ClipBlitTransparent was, by blasting a hole in the destination,
then blitting in the new version (2 blits on every plane)!
	And I am left with the dilemma:  to use the blitter directly, via
OwnBlitter or QBlit, ignoring the layers library, maybe trashing requestors,
or blit the area masked out onto the source, then back to the destination
(SLOW).
	I implore ye, oh Amiga Gurus, is there any way out of this dilemma?
(Like a way to set up the blits the way BltMaskBitMapRastPort does, but
using the cookie cut minterm?)  And will ye fix it at the soonest possible
moment?  Otherwise, for doing screen updates it is useless.

	Your humble servant,
		Randell Jesup
		jesup@steinmetz.uucp (uunet!steinmetz!jesup)
		jesup@ge-crd.arpa

rap@dana.UUCP (Rob Peck) (08/13/87)

In article <6978@steinmetz.steinmetz.UUCP>, jesup@steinmetz.steinmetz.UUCP (Randell Jesup) writes:
> I've been doing some 4-bitplane, 640x200 graphics work and wondered why, every
> time I updated a portion of the screen with the new 1.2 BltMaskBitMapRastPort,
> there was a white flash in the area before the update.  In that resolution,
> things are slow enough that it was VERY annoying.
> ....
> 	And the inspiration struck!  The BltMaskBitMapRastPort was implemented
> as Rob Pecks ClipBlitTransparent was, by blasting a hole in the destination,
> then blitting in the new version (2 blits on every plane)!

To avoid the flash, I'd suggest doing the merge using BltMask... in an
offscreen rastport/bitmap combination, then use ClipBlit() itself to
simply replace the onscreen with the offscreen stuff in a single rectangular
blit, of a size equal to that which would cover the outermost boundaries
of the old-version vs the new version of the object that has morphed.
(In other words, actually update the screen with only as much of the
screen as is now different.)  I created ClipBlitTransparent before the
BltMask... routine existed - I guess you're right about how BltMask
does things, I never looked at its insides.  There will be a couple more
blits needed overall, but only one would happen onscreen and you'd
be less likely to see the flash in that case.

(I suggested using BltMask... instead of trying to use ClipBlitTransparent
because I was told that BltMask was designed to be much more efficient
than what I created, supposedly fewer setups and fewer blits.  Probably.)

Second suggestion would be to use the GEL system to do your update work.
The Bob's use the blitter also, and in a more direct manner than all of
the overhead I had to use in ClipBlitTransparent (Bobs use QBlit or QBSBlit
as I recall).   If an object is to move against a background I believe
that the Bobs system may be the most efficient available in the system
at the moment.  If an object is to change while moving, there are a
couple of things you can try - for a limited number of views of an
object, create a Bob structure for each, then

   RemBob( ... old bob ...)  (restore background; erase during next DrawGList)	
   AddBob( ... next view ...)
   DrawGList(.... )            (no book here, forgot parameters)

to get the new view of the object drawn while also restoring the background
behind where the old object was located.

As suggested, by using the blitter directly, one would not go through
the layers library in the process.  So it would probably be best to
come up with something that the system already has.  It took Dale a
while to make sure that everything worked right with layers ... reinventing
the wheel is a bummer.

There is something else interesting that Randell pointed out:  the
BltMaskBitMapRastPort is limited to two possible minterms.  Notice
that the system ClipBlit routine is limited to FOUR rather than two.
(It lets you specify the B and C terms, basically, minterm values
as $x0 where x can be in the range of 0-F).  That's what let me
blast the hole in the destination area using the mask for ClipBlitTransparent,
then reverse the process saying blit in only where the mask was
a 1 bit.   The A term is left out of the ClipBlit equation since
the routine uses it internally (I forget exactly how ... maybe
Dale .. or Kodiak if he is listening ... can expand on this.)

Maybe someday a system routine can be created (for 1.3?) that would
be maybe ClipBlitAll(...) that would be the same as the current 
ClipBlit but allow all of the possible combinations of minterms,
perhaps taking a mask parameter as well (as ClipBlitTransparent does).
Would be nice. 

As a final remark, at 640 by 200, the display DMA is taking up all of the
time during the display part of the screen.  The blitter can only do its
work during non-display time (because both are accessing CHIP RAM), so
this is really asking an awful lot of the system.  One more suggestion,
then... if there is FAST memory available, make sure that everything
that can be in FAST memory is located there so the 68000 can do the
setup work for the blitter while the display DMA is on the independent
CHIP mem bus, then the "only" contention you'll have is between the blitter
and the display DMA, not asking the processor to try to get its job 
done on that same bus as well.


Please let me know via EMAIL what you finally come up with to solve
your problem - I may have a few other things to suggest as well.

Good luck in the meantime.

Rob Peck			...ihnp4!hplabs!dana!rap

keithd@cadovax.UUCP (Keith Doyle) (08/13/87)

BTW, while we're talking about blitter routines, has anyone written
or seen the source to a complete general purpose arbitrary rectangle
blit routine?  I mean, like the system BlitBitMap (or whatever it
is called, I forget) but that will allow important modifications, like
the use of a mask plane, the changing of MINTERMS, etc. (modifications
allowed because we have the source, not because everything is
parameterized).

While there is enough information at my disposal to create such a beast,
I'd just as soon not re-invent the wheel and save a little time if
possible.  Figuring out all those shifts and offsets etc. is something
I'm sure has been done dozens of times by now.

Keith Doyle
#  {ucbvax,decvax}!trwrb!cadovax!keithd
#  cadovax!keithd@ucla-locus.arpa  Contel Business Systems 213-323-8170

-- 
Keith Doyle
#  {ucbvax,decvax}!trwrb!cadovax!keithd
#  cadovax!keithd@ucla-locus.arpa  Contel Business Systems 213-323-8170
"You'll PAY to know what you REALLY think!"

rokicki@rocky.UUCP (08/15/87)

$ BTW, while we're talking about blitter routines, has anyone written
$ or seen the source to a complete general purpose arbitrary rectangle
$ blit routine?

Well, BlitLab on fish disk 84 has a description of how one would work,
down to all the nitty gritty details of shifts and everything.  Coding
one up from the description shouldn't be too difficult.

Please note that an arbitrary rectangle *copy* requires all three
sources and the destination---A to mask out the edges of the
rectangle, B to fetch the source, C to fetch the destination, and
D to write the destination.  You could change minterms or a few
other things, but not too much more.

If I get a few demands, I'll write that general purpose copying
routine and post it . . .

-tom

keithd@cadovax.UUCP (Keith Doyle) (08/19/87)

In article <493@rocky.STANFORD.EDU> rokicki@rocky.UUCP (Tomas Rokicki) writes:
>Please note that an arbitrary rectangle *copy* requires all three
>sources and the destination---A to mask out the edges of the
>rectangle, B to fetch the source, C to fetch the destination, and
>D to write the destination.  You could change minterms or a few
>other things, but not too much more.

Are you saying that it is not possible to do an arbitrary rectangle
*copy* with a *mask plane* in a single operation because of this?  
If so, that's a 2 and 2 I hadn't put together yet.  Couldn't A be
a mask plane and serve to both mask out the edges of the rectangle, 
as well as acting as a 'shape' mask for the object being copyied?

Inquiring minds want to know.

Keith Doyle
#  {ucbvax,decvax}!trwrb!cadovax!keithd
#  cadovax!keithd@ucla-locus.arpa  Contel Business Systems 213-323-8170

dale@amiga.UUCP (Dale Luck) (08/21/87)

In some article Keith writes:
>In article <493@rocky.STANFORD.EDU> rokicki@rocky.UUCP (Tomas Rokicki) writes:
>>Please note that an arbitrary rectangle *copy* requires all three
>>sources and the destination---A to mask out the edges of the
>>rectangle, B to fetch the source, C to fetch the destination, and
>>D to write the destination.  You could change minterms or a few
>>other things, but not too much more.
>
>Are you saying that it is not possible to do an arbitrary rectangle
>*copy* with a *mask plane* in a single operation because of this?  
>If so, that's a 2 and 2 I hadn't put together yet.  Couldn't A be
>a mask plane and serve to both mask out the edges of the rectangle, 
>as well as acting as a 'shape' mask for the object being copyied?
>
>Inquiring minds want to know.
>
>Keith Doyle
>
Yes, it is true that you can use one of the srcs as the mask plane and
the rectangle. And this works ok as long as you have simple bitmaps.
When you are blitting from a window to another window that has been
diced up because of overlappingness <sic?> , you need to dice that
mask up also into pieces. It is handy to have yet another simple mask
src that only places a rectangular mask to mask the mask. Also if
you are doing stuff more complicated then simple copy this to there
except for the bits I've zeroed in this mask, then you cannot use
the mask to cut out the rectangular areas. For example, if I want
complement those areas where there exists a 1, but I want to zero out
the bits where there is a 0 in the mask.
So to sum up, I really want another blitter term, just a rectangular
mask. Especially helps in the 'scrolling' cases where you have
overlapping source and destination.
Dale Luck

bart@amiga.UUCP (Barry A. Whitebook) (08/24/87)

[eat this line, please!]

this is amiga!bart in response to jesup@steinmetz.steinmetz.UUCP (Randell Jesup)

>And the inspiration struck!  The BltMaskBitMapRastPort was implemented
>as Rob Pecks ClipBlitTransparent was, by blasting a hole in the destination,
>then blitting in the new version (2 blits on every plane)!

not exactly. my objections to rob's clipblittransparent were 1) it was allocating temporary planes to do the work (bad for system code!) and 2) rob did not do
a thourough debugging on all cases of his code. so i wrote BltMaskBitMapRastPort

BltMaskBitMapRastPort does not blast a hole in the destination, rather, it
performs three clipblits (for a tricky xor type of transfer)

thus:

clipbltrastport(srcbm,srcx,srcy,dst,dstx,dsty,xsize,ysize,(ABC|ANBNC),TempA);
clipbltrastport(tbm,srcx,srcy,dst,dstx,dsty,xsize,ysize,minterm,TempA);
clipbltrastport(srcbm,srcx,srcy,dst,dstx,dsty,xsize,ysize,(ABC|ANBNC),TempA);

this is at least as reliable as clipbltrastport for system use and only
requires a TempA one scan line high by maxbytesperror wide.

the REASON for all these shenanigans is that DUE TO A BLITTER LIMITATION,
some overlapping blits, not on word boundaries, and using a srcA mask NEED
THE MASK TO PERFORM THE RIGHTEDGE/LEFTEDGE BLOCKMASKING.  if you are always
going to bltmask on word boundaries then the proper thing is to qblit
yourself.  if you ever run into this cusp case, you will have to either
1) monkey with your mask by creating a copy and jerking with the leftedge/
rightedge bits or 2) doing what is essentially a reprise of the above.

of course, if you come up with a more general solution i'll be glad to
fold your code into the sytem code for bltbitmaskrastport next release ;-)

bart