[comp.sys.amiga.programmer] SuperBitMap Layers, etc.

menelli@sunc7.cs.uiuc.edu (Ron Menelli) (03/05/91)

I've got a bit of a dilemma that I hope someone can assist me with. Here is
some background...

I need to have four completely borderless, full screen windows on a custom
screen. They are intended to act as "pseudo screens". Also, I need to write
pixel by pixel onto this screen. I tried WritePixel(), which worked but
was abysmally slow. I've spent much time attempting to replace it with
something of my own that is faster...

What I did was write a bit of code that writes directly to a BitMap structure
in hopes that this was what I was looking for. It turned out to be a good
four or five times faster than WritePixel(), but unfortunately, due to my
lack of knowledge of the workings of low-level Amiga graphics, I was quite
surprised to find out that writing to any of the four stacked windows resulted
in the image being displayed on the frontmost window. This, of course, does
me no good.

My next attempt was trying to write to a SUPER_BITMAP (instead of 
SMART_REFRESH) window, so I could write to the superbitmap instead of the
common screen bitmap like I was doing before. This resulted in nothing being
displayed at all. After paging through the AutoDocs, I found the
CopySBitMap() function that updates layer information after a write to the
superbitmap structure. This made everything work, but it was MUCH slower than
WritePixel.

So, my question to everyone is, how can I solve this problem? Apparently
CopySBitMap must attempt to 'refresh' (for lack of a better word) the
ENTIRE screen, whereas I'm only dealing with a few pixels (usually 7 at a
time). Can I tell it to update everything it needs to based on the small
changes I make instead of the whole (mostly static) screen? Any suggestions
are most appreciated.

Thanks,
Ron Menelli
menelli@cs.uiuc.edu
menelli@sumter.cso.uiuc.edu

ccplumb@rose.uwaterloo.ca (Colin Plumb) (03/07/91)

menelli@sunc7.cs.uiuc.edu (Ron Menelli) wrote:
>I've got a bit of a dilemma that I hope someone can assist me with. Here is
>some background...
>
>I need to have four completely borderless, full screen windows on a custom
>screen. They are intended to act as "pseudo screens". Also, I need to write
>pixel by pixel onto this screen. I tried WritePixel(), which worked but
>was abysmally slow. I've spent much time attempting to replace it with
>something of my own that is faster...

Since you say later this is a SMART_REFRESH window, why not just go to 4
separate screens?  The 4 windows take up as much memory and are, as you've
observed, less efficient to work with.

>What I did was write a bit of code that writes directly to a BitMap structure
>in hopes that this was what I was looking for. It turned out to be a good
>four or five times faster than WritePixel(), but unfortunately, due to my
>lack of knowledge of the workings of low-level Amiga graphics, I was quite
>surprised to find out that writing to any of the four stacked windows resulted
>in the image being displayed on the frontmost window. This, of course, does
>me no good.

Of course; the primary BitMap structure points to the screen; the information
about what's obscured is hidden in the bowels of the layers.library and
you should go through the graphics.library to get at it.

>So, my question to everyone is, how can I solve this problem? Apparently
>CopySBitMap must attempt to 'refresh' (for lack of a better word) the
>ENTIRE screen, whereas I'm only dealing with a few pixels (usually 7 at a
>time). Can I tell it to update everything it needs to based on the small
>changes I make instead of the whole (mostly static) screen? Any suggestions
>are most appreciated.

Well, if the pixels are widely scattered, you're stuck with WritePixel().
If they're clumped, you can write them into a temporary buffer and use
one blit to write them, which might be faster than WritePixel(), although
just 7 pixels isn't much.

I don't see how to do what you're trying to do.  If you described your
application, maybe I could suggest something else you might try which
would be faster.
-- 
	-Colin

mcmahan@netcom.COM (Dave Mc Mahan) (03/08/91)

 In a previous article, menelli@sunc7.cs.uiuc.edu (Ron Menelli) writes:
>I've got a bit of a dilemma that I hope someone can assist me with. Here is
>some background...
>
>I need to have four completely borderless, full screen windows on a custom
>screen. They are intended to act as "pseudo screens". Also, I need to write
>pixel by pixel onto this screen. I tried WritePixel(), which worked but
>was abysmally slow. I've spent much time attempting to replace it with
>something of my own that is faster...

Yeah, I found this out too.  I did some timing analysis on WritePixel() and
there is some room for improvement.  The downside is that you have to start
going at the window BitMap and SuperBitmaps directly.  It's a bit dangereous
and not really a good idea if you have things like menu bars, requesters, or
other things that can asynchronously 'pop' onto your screen at any time.
It's also NOT gauranteed to work in future revs or models of the amiga.  It
is, however, fast.


>What I did was write a bit of code that writes directly to a BitMap structure
>in hopes that this was what I was looking for. It turned out to be a good
>four or five times faster than WritePixel(), but unfortunately, due to my
>lack of knowledge of the workings of low-level Amiga graphics, I was quite
>surprised to find out that writing to any of the four stacked windows resulted
>in the image being displayed on the frontmost window.
>
>My next attempt was trying to write to a SUPER_BITMAP (instead of 
>SMART_REFRESH) window, so I could write to the superbitmap instead of the
>common screen bitmap like I was doing before. This resulted in nothing being
>displayed at all. After paging through the AutoDocs, I found the
>CopySBitMap() function that updates layer information after a write to the
>superbitmap structure. This made everything work, but it was MUCH slower than
>WritePixel.

What I did was open a SuperBitMap screen with one window.  I knew where on the
SuperBItMap I wanted to place the pixel, so I did a bit of math to determine if
that area falls within the window being displayed or outside the window and is
therefor in the SuperBitMap.  I then picked the desired spot and banged the
BitPlanes directly from my program.  Pulling down a menu bar resulted in my
program writing right across the menu items, so I put in a 'hook' that would
turn off this type of writing when the menu is activated BEFORE I let
neverintuition make the menu bar.  It ain't pretty, but then writing 2000+
pixels/sec never is.  When using this technique, you have to be careful about
refreshing the window being displayed from the SuperBitMap.  AmigaDos thinks
that ALL the info resides within the SuperBitMap and will wipe out all your
hard work if you try and scroll things around.  To avoid this, you have to
ScrollLayer(0,0...) first to force AmigaDos to copy the stuff in the window
to the SuperBitMap.  Like I said, it ain't pretty.  It's been a while since
I did this, but if you have interest, I'll look up the details in the code I
wrote.

Please, no religious commentary on why I shouldn't do this.  I know I
shouldn't, but there just isn't any way to do it fast enough otherwise.



>Ron Menelli
>menelli@cs.uiuc.edu
>menelli@sumter.cso.uiuc.edu

   -dave

-- 
Dave McMahan                            mcmahan@netcom.com
					{apple,amdahl,claris}!netcom!mcmahan

andrew@teslab.lab.OZ (Andrew Phillips) (03/13/91)

In article <1991Mar6.193942.1842@watdragon.waterloo.edu> ccplumb@rose.uwaterloo.ca (Colin Plumb) writes:
>Since you say later this is a SMART_REFRESH window, why not just go to 4
>separate screens?  The 4 windows take up as much memory and are, as you've
>observed, less efficient to work with.

This would not be very friendly to the user as if you are flipping
screens he would not be able to manually get back other screens such
as the WorkBench one.

There are versions of ShowAnim that I believe must also do this.  It
is very annoying as you can't leave it running and do something else.

Andrew.
-- 
Andrew Phillips (andrew@teslab.lab.oz.au) Phone +61 (Aust) 2 (Sydney) 289 8712

menelli@sunc7.cs.uiuc.edu (Ron Menelli) (03/15/91)

In article <1214@teslab.lab.OZ> andrew@teslab.lab.oz.au (Andrew Phillips) writes:
>In article <1991Mar6.193942.1842@watdragon.waterloo.edu> ccplumb@rose.uwaterloo.ca (Colin Plumb) writes:
>>Since you say later this is a SMART_REFRESH window, why not just go to 4
>>separate screens?  The 4 windows take up as much memory and are, as you've
>>observed, less efficient to work with.
>
>This would not be very friendly to the user as if you are flipping
>screens he would not be able to manually get back other screens such
>as the WorkBench one.
>
...
There are other reasons as well - sometimes I need the windows to change size
so I can see part of a window underneath (in a way that screens can't do).

Thanks to all those who sent me suggestions! My eventual choice was using
the AmigaDOS 2.0 WritePixelLine8() function, which removes an amazing amount
of overhead from having to call WritePixel every time. Not quite as fast, and
it requires 2.0, but it WORKS! (and doesn't break any rules that might cause
trouble later).

-Ron
menelli@cs.uiuc.edu

>
>Andrew.
>-- 
>Andrew Phillips (andrew@teslab.lab.oz.au) Phone +61 (Aust) 2 (Sydney) 289 8712