guilford@sunbird.steinmetz (james d guilford) (11/05/87)
I am planning to write some animation-type software, and so I looked up double buffering in the RKM. It suggested that I create two screens and two sets of copper lists, and then to flip screens, I just replace the copper list pointers. My question is whether I still have to sync with the vertical retrace. It seems to me that even after updating the copper-list pointers, they will not be used until the next scan begins. Thus it would not be safe to start rendering into the other screen until after at least one vertical blanking period. Is this right? I am thinking of creating an interrupt handler on the vertical blanking list which would have a private message port. When I change the copper list points, I would send it a message. When the vertical retrace occurs, it would reply to the message. When I see the reply, I know it is safe to start rendering the next screen. Is this the best way to go? --JimG (guilford@csv.rpi.edu)
jimm@mitsumi.UUCP (Jim Mackraz) (11/06/87)
In article <7768@steinmetz.steinmetz.UUCP> guilford@csv.rpi.edu (james d guilford) writes:
)
)I am planning to write some animation-type software, and so I looked
)up double buffering in the RKM. It suggested that I create two screens
)and two sets of copper lists, and then to flip screens, I just replace
)the copper list pointers.
Note that the copper list pointers you replace are in graphics base, unless
you also want to replace the vblank interrupt routine which re-installs
them (and handles interlace). One way to do this is use LoadView().
)
)My question is whether I still have to sync with the vertical retrace.
)It seems to me that even after updating the copper-list pointers, they
)will not be used until the next scan begins. Thus it would not be safe
)to start rendering into the other screen until after at least one
)vertical blanking period. Is this right?
I don't exactly know what protection you need to replace the actual pointers.
If you use LoadView() you probably are safe. But your concern about
rendering in the newly offscreen buffer is exactly correct.
)I am thinking of creating an interrupt handler on the vertical
)blanking list which would have a private message port. When I change
)the copper list points, I would send it a message. When the vertical
)retrace occurs, it would reply to the message. When I see the reply, I
)know it is safe to start rendering the next screen. Is this the best
)way to go?
Not best, but workable. You can tell your interrupt handler that you
made the change by setting a global, perhaps within Disable/Enable.
Your handler need only send a Signal to your main task (which signal/task
values it can read from globals shared with your program's main task).
The big problem is that you will find yourself waiting until TOP
of frame to start rendering, which needlessly prevents you from
rendering during that valuable vertical retrace time. I think (might
not be correct) that the blitter can run much faster when no
display DMA is occuring (during vertical blank).
So the optimal solution uses as bottom of frame interrupt generated
by the Copper. This requires a custom copper list, and this opens
a can of a few worms.
)--JimG (guilford@csv.rpi.edu)
jimm
--
Jim Mackraz
Mitsumi Technology, Inc. 408/980-5422
{amiga,pyramid}!mitsumi!jimm
bilbo@pnet02.cts.com (Bill Daggett) (11/07/87)
I almost hate to do this but would someone please make a simple statement concerning what the Amiga term "copper" means? What did the name derive from and what is it? And now, back to Double Buffering... *Bilbo* Recombinant Hobbit * Sometimes The Dragon Wins! *
dillon@CORY.BERKELEY.EDU (Matt Dillon) (11/08/87)
>I almost hate to do this but would someone please make a simple statement >concerning what the Amiga term "copper" means? What did the name derive from >and what is it? And now, back to Double Buffering... Copper. Co-Processor. The amiga has a simple three-instruction co-processor which handles changing between screens in the middle of a display refresh. Each screen has a copper list which is executed at the place the screen physically starts on the screen, loading the plane pointers and colormap for that screen into the video chip. The graphics.library handles the copper. You really have to get into the guts of the Amiga to use it (beyond the Screen structure and into the View structure). -Matt
peter@sugar.UUCP (Peter da Silva) (11/09/87)
In article <7768@steinmetz.steinmetz.UUCP>, guilford@sunbird.steinmetz (james d guilford) writes: > I am planning to write some animation-type software, and so I looked > up double buffering in the RKM. It suggested that I create two screens > and two sets of copper lists, and then to flip screens, I just replace > the copper list pointers. Why don't you just set up two screens and use ScreenToFront and ScreenToBack to flip them? These routines are (as far as I have been able to tell) as near instantanious as you can get. Let intuition worry about the copper lists. That's what it's for, after all. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.
ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (11/10/87)
In article <7768@steinmetz.steinmetz.UUCP> guilford@csv.rpi.edu (james d guilford) writes:
:My question is whether I still have to sync with the vertical retrace.
:It seems to me that even after updating the copper-list pointers, they
:will not be used until the next scan begins. Thus it would not be safe
:to start rendering into the other screen until after at least one
:vertical blanking period. Is this right?
:
Yup. After finishing rendering into the off-screen bitmap, you'd
LoadView() it (or ScrrenToFront() it), then call WaitTOF(). When WaitTOF()
comes back, the system will be displaying your other view.
:I am thinking of creating an interrupt handler on the vertical
:blanking list which would have a private message port. When I change
:the copper list points, I would send it a message. When the vertical
:retrace occurs, it would reply to the message. When I see the reply, I
:know it is safe to start rendering the next screen. Is this the best
:way to go?
:
Seems needlessly complicated to me. WaitTOF()ing is much easier.
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape ihnp4!ptsfa -\
\_ -_ Recumbent Bikes: dual ---> !{well,unicom}!ewhac
O----^o The Only Way To Fly. hplabs / (pronounced "AE-wack")
"Work FOR? I don't work FOR anybody! I'm just having fun." -- The Doctor
dillon@CORY.BERKELEY.EDU (Matt Dillon) (11/10/87)
>Why don't you just set up two screens and use ScreenToFront and ScreenToBack >to flip them? These routines are (as far as I have been able to tell) as near >instantanious as you can get. Let intuition worry about the copper lists. >That's what it's for, after all. Nah... too clugy... very inefficient considering that Intuition must redo the copper list everytime you do the flip. -Matt
keithd@cadovax.UUCP (Keith Doyle) (11/11/87)
In article <4414@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes: > Yup. After finishing rendering into the off-screen bitmap, you'd >LoadView() it (or ScrrenToFront() it), then call WaitTOF(). When WaitTOF() >comes back, the system will be displaying your other view. Um, wouldn't this be a case where WaitBOVP() would be a teensy bit better? You get to render through the vertical interval, instead of starting at the top of the next screen after the vertical interval. Or has everyone just given up on WaitBOVP()? Keith Doyle # {ucbvax,decvax}!trwrb!cadovax!keithd Contel Business Systems 213-323-8170
keithd@cadovax.UUCP (Keith Doyle) (11/11/87)
In article <1038@sugar.UUCP> peter@sugar.UUCP (Peter da Silva) writes: >Why don't you just set up two screens and use ScreenToFront and ScreenToBack >to flip them? These routines are (as far as I have been able to tell) as near >instantanious as you can get. Let intuition worry about the copper lists. >That's what it's for, after all. I suppose that would work, but if you're waiting for IDCMP messages, it could be a problem. Keith Doyle # {ucbvax,decvax}!trwrb!cadovax!keithd Contel Business Systems 213-323-8170
bart@amiga.UUCP (Barry A. Whitebook) (11/12/87)
[ eat this line -- please! ] this is amiga!bart: regarding double buffering of animation... here is what "robo" does ----------------- begin fragment ------------------------- while( ... ) { Animate(&animKey, rp); SortGList(rp); DrawGList(rp,vp); vp->RasInfo->BitMap = &bitmap[dispIndex]; WaitTOF(); MakeScreen(screen); RethinkDisplay(); dispIndex ^= 1; rp->BitMap = &bitmap[dispIndex]; } ----------------- end fragment ------------------------- note that for a non-dualpf screen the RasInfo->Bitmap is used to remake the copper list for this screen which has a non-layered vp. also note that the rp->BitMap change allows for the current DrawGlist() call to take place in the "not-currently-displayed" bitmap. also remember to tell gels that DBUFFER is in effect so that save/restore works properly between bitmaps. another way to double buffer is found in the amiga3d demo which DOES NOT USE gels code to render into its rp->bitmaps, so it incurs less overhead on the double buffering itself by making these calls: ----------------- begin fragment ------------------------- while( ... ) { Forbid(); WaitTOF(); WaitBlit(); Disable(); (&screen->ViewPort)->RasInfo = rip[frametoggle]; ScrollVPort(&screen->ViewPort); Enable(); Permit(); frametoggle ^= 1; } ----------------- end fragment ------------------------- this stuffs alternate rasinfo pointers into the viewport and lets ScrollVPort handle the pokes directly into the copper list. NOTE CAREFULLY: the elaborate Forbid; WaitTOF; Disable; Enable; Permit; nesting are to protect the "currently displayed" copper list from being modified while the copper is fetching instructions from that list. happy hacking. -- //----------------------------------------------------- ----------\\ //| Bart Whitebook | {|V|))) |\\ | | ()^()-)))| | 16795 Lark Avenue, Suite #106, Los Gatos, CA 95030 | /_ ?))| | UUCP: pyramid!oliveb!amiga!bart | { _ } )\ | | BIX: amiga_bart | \ // | \\|_____________________________________________________|__\//____ |// \\ //
bryce@hoser.berkeley.edu (Bryce Nesbitt) (11/12/87)
In article <1038@> peter@sugar.UUCP (Peter da Silva) writes: >In article <7768@>, guilford@sunbird.steinmetz (james d guilford) writes: > >> I looked up double buffering in the RKM. It suggested... > >Why don't you just set up two screens and use ScreenToFront and ScreenToBack >to flip them? Peter da Silva, multitasking terrorist. This is quick, easy and probably will be compatible in the future. But it is also a dirty, ugly kludge that gives users headaches. Try C= N or C= M on such a program. Try dragging the screen. YUCK! *At least* put some protection in if you go this route. Someone else probably has a better suggestion, but how about: key=LockIBase(0L); check IntuitionBase->FirstScreen; if the same as yours, contine. Else quit animating. UnLockIBase(key); In the second case, post a "start animating" requester in *your* screen. Or maybe one in each, come to think of it. Still a kludge. It could be that many of the "better" Dbuffering techniques may break Hedley's Highres Monitor. (That 1000*800 monochrome monitor shown at Comdex) This is pure speculation, however. This is another one that works: Set the ViewPort->RasInfo->BitMap plane pointers to the "other" data then MakeScreen(Screen), RethinkDisplay(). The problem with this is that it rebuilds the copperlists and that takes a while. (Reference: WaveBench-1 in interlace :-) I've seen ScrollVPort() used. This is fast but seems to have some display trashing problems and has crashed. Perhaphs a Forbid()? A unique solution was used by Matt Dillon. He had a two bitplane display for Wiredemo. He draws into one plane at a time, setting the color registers to make that plane invisible at the time. Flopping the color registers is fast. The problem here is that two bitplanes of data are fetched by the custom chips, I think (but am ot positive) that droping one bitplane will leave more cycles for the blitter. (issue: can the blitter take advantage of free "odd" cycles) Other than that, it works great in practice! |\ /| . Ack! (NAK, SOH, EOT) {o O} . bryce@hoser.berkeley.EDU -or- ucbvax!hoser!bryce (") U "We want to fashon puppets that pull their own strings." -Ann Marion
carolyn@cbmvax.UUCP (11/12/87)
> >Um, wouldn't this be a case where WaitBOVP() would be a teensy bit better? >You get to render through the vertical interval, instead of starting at >the top of the next screen after the vertical interval. Or has everyone >just given up on WaitBOVP()? WaitBOVP(vp) busywaits, WaitTOF() does not. This has to be taken in consideration. For non-multitasking type applications, WaitBOVP(vp) should be ok. -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carolyn Scheppner -- CATS >>Commodore Amiga Technical Support<< UUCP ...{allegra,ihnp4,rutgers}!cbmvax!carolyn PHONE 215-431-9180 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
eric@cbmvax.UUCP (Eric Cotton) (11/12/87)
In article <2740@cbmvax.UUCP> carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) writes: >> >>Um, wouldn't this be a case where WaitBOVP() would be a teensy bit better? >>You get to render through the vertical interval, instead of starting at >>the top of the next screen after the vertical interval. Or has everyone >>just given up on WaitBOVP()? > > WaitBOVP(vp) busywaits, WaitTOF() does not. This has to be taken in >consideration. For non-multitasking type applications, WaitBOVP(vp) should >be ok. Which isn't to say that non-multitasking type applications are encouraged! -- Eric Cotton Commodore-Amiga *======================================================================* *===== UUCP: {rutgers|ihnp4|allegra}!cbmvax!eric =====* *===== FONE: (215) 431-9100 =====* *===== MAIL: 1200 Wilson Drive / West Chester, PA 19380 =====* *===== PAUL: "I don't find this stuff amusing anymore." =====* *======================================================================*
peter@sugar.UUCP (Peter da Silva) (11/14/87)
In article <8711102005.AA06675@cory.Berkeley.EDU>, dillon@CORY.BERKELEY.EDU (Matt Dillon) writes: > >Why don't you just set up two screens and use ScreenToFront and ScreenToBack > >to flip them? These routines are (as far as I have been able to tell) as near > >instantanious as you can get. Let intuition worry about the copper lists. > >That's what it's for, after all. > Nah... too clugy... very inefficient considering that Intuition must > redo the copper list everytime you do the flip. Yes, but the question is: "is it fast enough". I do NOT like playing games that close to the hardware. Too likely to do something that won't survive 1.3 or 1.4 or maybe 2.0. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.
peter@sugar.UUCP (Peter da Silva) (11/15/87)
In article <1863@cadovax.UUCP>, keithd@cadovax.UUCP (Keith Doyle) writes: > In article <1038@sugar.UUCP> peter@sugar.UUCP (Peter da Silva) writes: > >Why don't you just set up two screens and use ScreenToFront and ScreenToBack > >to flip them? > I suppose that would work, but if you're waiting for IDCMP messages, it > could be a problem. Well, I'm using this technique. Could you please explain just what sort of problems you can expect from IDCMP messages? I'm Wait()ing on the OR of all my mp_SigBits, though if I wanted to go for the gold I could share one IDCMP for all the windows on both screens. Or is there some bug in the system you've discovered...? -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.
hobie@sq.UUCP (11/15/87)
Keith Doyle (keithd@cadovax.UUCP) writes: <In article <1038@sugar.UUCP> peter@sugar.UUCP (Peter da Silva) writes: <>Why don't you just set up two screens and use ScreenToFront and ScreenToBack <>to flip them? These routines are (as far as I have been able to tell) as near <>instantanious as you can get. Let intuition worry about the copper lists. <>That's what it's for, after all. < <I suppose that would work, but if you're waiting for IDCMP messages, it <could be a problem. < <Keith Doyle Not if you have a backdrop window in each screen and you call ActivateWindow() after the ScreenToFront(). I've done this and it works well. Of course, you have to do the "clone the IDCMP port" using ModifyIDCMP() so messages always go to the sames place. Hobie Orris | guest of SoftQuad Inc., Toronto, Ont. |"There'll be no more giant leeches {ihnp4 | decvax | ? }!utzoo!sq!hobie | When you find the good Lord Jesus"
peter@sugar.UUCP (Peter da Silva) (11/22/87)
In article <21733@ucbvax.BERKELEY.EDU>, bryce@hoser.berkeley.edu (Bryce Nesbitt) writes: > In article <1038@> peter@sugar.UUCP (Peter da Silva) writes: > >Why don't you just set up two screens and use ScreenToFront and ScreenToBack > >to flip them? > Peter da Silva, multitasking terrorist. Yow! borrowing Stallman's terminology? Have a look at my Gauge program to see some TRUE terror-tactics! > This is quick, easy and probably > will be compatible in the future. My main point. > But it is also a dirty, ugly > kludge that gives users headaches. Try C= N or C= M on such a program. Good point. > Try dragging the screen. YUCK! Flip() { MoveScreen(scr[!mine], 0, scr[mine]->TopEdge - scr[!mine]->TopEdge); ScreenToFront(scr[!mine]); mine = !mine; } > In the second case, post a "start animating" requester in *your* > screen. Or maybe one in each, come to think of it. Still a > kludge. Better than whatever Scult/Animate-3d does, though. And did you try dragging Halfbright Hill, ever? Whetever you do should be attached to screens or you'll see some REAL terror tactics! (Still have no idea why Halfbright Hill did the stuff it did. An overscan screen would have done the job fine.) > Set the ViewPort->RasInfo->BitMap plane pointers to the > "other" data then MakeScreen(Screen), RethinkDisplay(). > The problem with this is that it rebuilds the copperlists > and that takes a while. (Reference: WaveBench-1 in interlace :-) Looks like it's not too bad an idea. > A unique solution was used by Matt Dillon. He had a two bitplane > display for Wiredemo. He draws into one plane at a time, setting > the color registers to make that plane invisible at the time. > Flopping the color registers is fast. This is an all-time classic technique. By the way, how do you get OUT of wiredemo? -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.
kkaempf@rmi.UUCP (Klaus Kaempf) (12/02/87)
This message is being forwarded by me for a friend who has no access to the UseNet (yet!). Feel free to send replies to me. Klaus Kaempf kkaempf@rmi.UUCP - - - - - - - - - In article <782@mitsumi.UUCP> jimm@mitsumi.UUCP (Jim Mackraz) writes: > In article <7768@steinmetz.steinmetz.UUCP> > guilford@csv.rpi.edu (james d guilford) writes: >> I am planning to write some animation-type software, and >> so I looked up double buffering in the RKM. It suggested >> that I create two screens and two sets of copper lists, >> and then to flip screens, I just replace the copper list >> pointers. If you do so, you will certainly run into the same troubles, almost all other programs that use double-buffering have. No-one knows, if there isn't anyone else doing the same thing to the copperlists, you are doing right now. This will result in the same crash the JUGGLER etc. will end up with, if you just try to drag the screen or use Amiga-M/Amiga-N. Intuition will remove and deallocate the copperlist YOU installed and next time YOU need it ... Of course you cannot use MakeVPort()/RethinkDisplay() each and every frame (you might as well display the "zz" cloud then), but I used two approaches to solve this problem in my programs: Scan the copperlists (AND the intermediate copperlists!!!) for the MOVE instructions, that will install your bitplanes, and replace the arguments to these directly (Disable(), of course). You will also have to set up the "struct BitMap" in your ViewPort to reflect these new circumstances, because someone else might call "RemakeDisplay()". DO NOT assume a fixed layout of the copperlists! This one should be written in assembler. The second approach will only "MrgCop()", if the pointers to the copperlists within the View have been changed by someone else since the last time, your program exchanged them. I wrote an example to demonstrate this some time ago and if anyone is interested, I will post the source for it ( <10 KB highly readable C source for both Lattice and Aztec). This method might sometimes miss a change (resulting in flickering) and is certainly VERY SLOW, IF TWO programs behave this way, but at least it won't crash! How about a public semaphore in 1.3? Or something like a "ChangeCount" to check out, if the copperlists have been changed recently. Hey Leo! Don't _you_ have a better idea 'bout this? > Note that the copper list pointers you replace are in > graphics base, unless you also want to replace the vblank > interrupt routine which re-installs them (and handles > interlace). One way to do this is use LoadView(). This was true for 1.1. If you were running at a higher interrupt priority level than the vblank interrupt or simply disabled it, only every second line of an interlace screen was being displayed (this looked rather funny, try it yourself). Under Kickstart 1.2 the copperlists will exchange each other themselves after they did their job for the single frame - so no need for vblank and processor any longer (except for synchronization). !ralph Ralph Babel | sys64824 Falkenweg 3 | (!#X3F0001)() D-6204 Taunusstein | (**((void (**)(void))0xfc0004))();
ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (12/16/87)
In article <812@rmi.UUCP> kkaempf@rmi.UUCP (Klaus Kaempf) writes: :In article <782@mitsumi.UUCP> jimm@mitsumi.UUCP (Jim :Mackraz) writes: :: In article <7768@steinmetz.steinmetz.UUCP> :: guilford@csv.rpi.edu (james d guilford) writes: ::: I am planning to write some animation-type software, and ::: so I looked up double buffering in the RKM. It suggested ::: that I create two screens and two sets of copper lists, ::: and then to flip screens, I just replace the copper list ::: pointers. : :Scan the copperlists (AND the intermediate copperlists!!!) :for the MOVE instructions, that will install your bitplanes, :and replace the arguments to these directly (Disable(), of :course). You will also have to set up the "struct BitMap" in :your ViewPort to reflect these new circumstances, because :someone else might call "RemakeDisplay()". DO NOT assume a :fixed layout of the copperlists! This one should be written :in assembler. : :Hey Leo! Don't _you_ have a better idea 'bout this? : Well, the procedure you just described (scanning Copper lists) is precisely what ScrollVPort() does. For example code, look at my old display hack, "Ing". It double- buffers using ScrollVPort(). You can drag the screen, depth arrange it and everything. It does glitch a tiny bit, but that is largely dependent on the Phase of The Moon. _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ Leo L. Schwab -- The Guy in The Cape ihnp4!ptsfa -\ \_ -_ Recumbent Bikes: dual ---> !{well,unicom}!ewhac O----^o The Only Way To Fly. hplabs / (pronounced "AE-wack") "Work FOR? I don't work FOR anybody! I'm just having fun." -- The Doctor