1. Make two Viewports, Views, and RastPorts. Use LoadView()
to display 1 view. Write into the other one, then use
LoadView() to display the new one and write into the
other. This gets you double-buffering.
2. Open two custom screens with no windows. Write into the
bitmap of one while displaying the other. Use
ScreenToFront() to bring the screens alternately to the
front. This also gets you double buffering, and is
much easier to set up and do than 1.
3. Make a single Viewport, View, and Rastport. Use LoadView().
Display the view, then use the OFF_DISPLAY macro to stop
screen updates while you update the view. Use ON_DISPLAY
again to display it.
Number 2 is easier to set up than 1. What is the advantage of
1 over 2? Would 3 work? What is the advantage of 1 over 3?
It would seem that 3 would get you flicker free screen updates
while only using one bitmap, no?
Here's some more misc questions:
* Say you call PolyDraw a number of times to draw some lines.
Will this happen faster if the RastPort you PolyDraw into
is not being displayed? Otherwise PolyDraw seems somewhat
slow compared to, say, AreaMove()...AreaDraw()...AreaEnd()
where no screen updates take place until the final AreaEnd().
* What is the fastest method to clear a bitmap between
2 frames? SetRast(), or RectFill(), or something else
entirely?
- steve
In a similar vein, how do you find the copper pointers (LOFCprLIST
and SHFCprList) when you use the Intuition OpenScreen function?
These pointers are in the View structure, but the Screen structure
has a ViewPort in it. Basically, I was trying to follow double
buffering method 1 in the 1.3 Libs&Devs RKM (pp 355), but use intuition
based functions I had set up which hide many of the details of
opening screens and windows. BTW, I am programming in C (SAS).
I ended up copying my 'secondary' bitmap onto the active one (yuck!).
Any help would be appreciated.
Thanks,
Mike Brindley brin...@ece.orst.edu
"WYSBOAVRTWYG" - Jim Blinn
Beyond these techniques (Anybody who hasn't noticed; this is an Amiga
question), My PERSONAL favorite is to simply override the display with my
OWN copper list, and swapping frames is a matter of (at most) moving 12 words
of data into the copper list. Must less intense than MakeView and all that!
To do that, you allocate raw chip mem buffers and either draw directly with
the blitter, or setup a rastport for it. The latter gives you direct access
to the OS drawing functions of course.
> * What is the fastest method to clear a bitmap between
> 2 frames? SetRast(), or RectFill(), or something else
> entirely?
Try BltClear(). I dont know how setrast works, but BltClear() will
function with only the blitter's destination channel running (no source).
'Couse, its altogether possible that's what the other two do as well!
Kevin
There are at least 2 faster methods:
1: Use both the CPU and blitter running simultaneously. That is, start the
blitter doing some of the clear, and while it's doing its job, set the CPU
clearing the rest.
2: Blitter NASTY mode (which I know very little about).
Which of these 2 methods is faster probably depends on the Amiga's
configuration. If the CPU has other work to do, then neither may be
appropriate.
--
Peter McGavin. (srw...@wnv.dsir.govt.nz or pet...@am.dsir.govt.nz)
I know of two ways that you can double-buffer; one will work with
Intuition (I've coded this one); the other *should* work, but I haven't
been able to make it work.
1> Before opening a screen, allocate two BitMap structures and initialize
them accordingly. Set ScreenFlags to CustomBitMap and point the
CustomBitMap field of the NewScreen struct to the BitMap you want
displayed first. Open the screen. If successful, do the following:
[example in Modula-2}
sp^.RastPort.BitMap := ADR(undisplayedBitMap);
sp^.ViewPort.RasInfo^.BitMap := ADR(displayedBitMap);
(* This is already set to the appropriate BitMap, but do it again
to keep track. *)
To flip, just swap the above pointers, and MakeScreen()/RethinkDisplay().
When you GraphicsDrawFunction(sp^.RastPort, whatever), you will be rendering
into the undisplayed bitmap.
2> Set up one View, one ViewPort, two RastPorts, and two BitMaps.
LoadView() with ViewPort.RasInfo^.BitMap pointing to the first
BitMap. Save the LOFCprList and the SHFCprList (if screen is
interlaced) someplace. Call LoadView again with
ViewPort.RasInfo^.BitMap pointing to the second BitMap.
You will now be displaying the second bit map. Draw into the
first one via it's RastPort. When you are ready to display it,
swap LOFCprList and SHFCprList with the two you saved earlier
(make sure you do this during the vertical blank). Draw into the
second bitmap via it's RastPort and LOF and SHF with the saved
pointers. Repeat this until you are done.
Someone wanted to know where they could find the View (LOFCprList and
SHFCprList) Intuition uses. This could be found in IntuitionBase.ViewLord.
I can post the Modula source to method one if anyone's interested.
// -Dave
// "AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
\\X/ Computing forever! Sleep for never!
With a 68000, Blitter NASTY will be the best way. With an 030, the CPU
is faster. However, the real question is the fastest way to clear a bitmap
between two frames...
Try just erasing the parts of the screen that were changed since the last time
you "cleared" the whole screen. If you only change 25% of the screen, it is faster
to just erase that 25% than to do the whole thing.
If you want a non-zero background (i.e. graphics), you can copy a rectangle from
a "pristene" (static background image) screen to your double buffered screens to
do the erase. Using the blitter, the copy costs no more cycles than the clear
operation.
--
******************************************************
* Q: Name something that IBM and CBM have in common: *
* A: Their middle name is BUSINESS *
* (and their last name is MACHINES) *
* *
* And if you put them together, you get ICBM. *
******************************************************
Welllllll..... Actually, you can do a clear op with only the "D" (dest)
channel running on the blitter, while it takes at least one source (say "A") to
provide a copy from a pristine buffer to the work area... so I'd say that a
copy would actually be HALF as fast as a clear.
Just a nit-pick. Sorry, Mike.
Kevin
The blitter uses the same bus cycles to access the chip ram as the CPU.
When running in normal mode the blitter has priority over the CPU except if
the CPU has waited three cycles to use the bus, then it gets the next cycle.
In blitter nasty mode the blitter has absolute priority over the CPU, no matter
how long the CPU has waited for a bus cycle. However, the blitter is only
capable of using the bus for 4 continuous cycles if all 4 DMA channels are
enabled, and in some configurations of three channels (I think). So in this case
it will not make any difference.
>
>Try just erasing the parts of the screen that were changed since the last time
>you "cleared" the whole screen. If you only change 25% of the screen, it is faster
>to just erase that 25% than to do the whole thing.
>
>If you want a non-zero background (i.e. graphics), you can copy a rectangle from
>a "pristene" (static background image) screen to your double buffered screens to
>do the erase. Using the blitter, the copy costs no more cycles than the clear
>operation.
>
>--
>******************************************************
>* Q: Name something that IBM and CBM have in common: *
>* A: Their middle name is BUSINESS *
>* (and their last name is MACHINES) *
>* *
>* And if you put them together, you get ICBM. *
>******************************************************
Stuart Twyford
Internet: int...@monu4.cc.monash.edu.au
> 1. Make two Viewports, Views, and RastPorts. Use LoadView()
> [...]. This gets you double-buffering.
> 2. Open two custom screens with no windows. [...] Use
> ScreenToFront() to bring the screens alternately [...]
> 3. Make a single Viewport, View, and Rastport. [...]
> use the OFF_DISPLAY [...] while you update the view. [...]
>
> Number 2 is easier to set up than 1. What is the advantage of
> 1 over 2?
With 1 you do 2 yourself but faster. When you call ScreenToFront()
Intuition has to examine the position of its entire display and
prepares to rebuilt the copperlist(s).
With 1 you just swap your copperlists and because LoadView() just
pokes the copper register with the copperlist you are very fast.
> Would 3 work? What is the advantage of 1 over 3?
If you try 3 (I never tried it) I think you will have to shut your
eyelids synchronously to prevent you from a headache :-)
> It would seem that 3 would get you flicker free screen updates
> while only using one bitmap, no?
With OFF_DISPLAY there is no display at all: a dark grey screen
as if you switch off your Amiga. So you will (see/notsee/see/notsee/
see/notsee/see/notsee/...) your bitmap.
> * Say you call PolyDraw a number of times to draw some lines.
> Will this happen faster if the RastPort you PolyDraw into
> is not being displayed?
The processor can run slower in some case like a lot of colours,
overscan, high resolution, because of the DMA activity. But I'm
not a specialist about that. Generaly don't make a game in a
productivity-overscan-interlace mode :-)
> Otherwise PolyDraw seems somewhat
> slow compared to, say, AreaMove()...AreaDraw()...AreaEnd()
> where no screen updates take place until the final AreaEnd().
PolyDraw() is fast. If you have no layer attached to your RastPort
it is faster (but your lines will not be clipped).
You cannot use AreaEnd() instead of PolyDraw(), you just will not
have the same result (and AreaEnd() is slower).
These two functions start the blitter to write into chip memory
so no one is advantaged.
Note that if you ask for outlines with AreaEnd() it will do the
same as PolyDraw() after having filled the polygon.
> * What is the fastest method to clear a bitmap between
> 2 frames? SetRast(), or RectFill(), or something else
> entirely?
It is BltClear(). Make your bitplanes contiguous and clear them
all in once.
--
\___/
Jean-Michel Forgeas \-/
cbmvax!cbmehq!cbmfra!swinjm!forgeas | The Software Winery
-^-
And, where is the universe ?
> \___/
>Jean-Michel Forgeas \-/
>cbmvax!cbmehq!cbmfra!swinjm!forgeas | The Software Winery
> -^-
> And, where is the universe ?
Stuart Twyford
Internet: int...@monu4.cc.monash.edu.au
Nope, the blitter has twice as many cycles to access chip memort as the CPU
>When running in normal mode the blitter has priority over the CPU except if
>the CPU has waited three cycles to use the bus, then it gets the next cycle.
>In blitter nasty mode the blitter has absolute priority over the CPU, no matter
>how long the CPU has waited for a bus cycle.
If the blitter does not need a cycle, it goes to the cpu, if it is waiting for
it.
However, the blitter is only
>capable of using the bus for 4 continuous cycles if all 4 DMA channels are
>enabled, and in some configurations of three channels (I think). So in this case
>it will not make any difference.
Nope, the blitter can use all available cycles with as few as 2 dma channels.
Like a simple copy from one place to another. Shifts, may add an additional pipeline
delay.
The quickest way to set a section of graphics memory to a particular value on all
Amigas is to use a combination of the blitter and the processor and turn the
display DMA off. The blitter in its quickest mode will use everyother cycle. Also
the cpu in its quickest mode will use every other cycle. Using both together
will maximize usage of the graphics memory bus. An A3000 will be faster than an
A2000 because its accesses are 32 bits wide.
If you must leave the display on, and depending on how many dma cycles are given up
to the display (like every other one) then it will be faster to use the 030 on the
A3000 since it will make use of all the rest of the cycles, and they will be 32
bit cycles and not 16 bit blitter cycles.
--
Dale Luck GfxBase/Boing, Inc.
{uunet!cbmvax|pyramid}!amiga!boing!dale