Partner sites:
Aminet
- Amiga downloads
IntuitionBase
- Amiga guides
AmigaNN
- Amiga news
AmiFund
- Sponsor projects
UtilityBase
Your guide to Amiga development
Not logged in
Home
Projects
Forum
Articles
Resources
Links
Chat
About
Search
All articles
Forum posts
News articles
Links
Chat
Documentations
Reviews
Tutorials
Sources
FAQs
Login
Username:
Password:
•
Register now!
•
Forgot your password?
Aminet - Development
•
Blitz_AVI.lha (dev/basic)
•
bullet.lha (dev/lib)
•
MCC_TheBar-26.6.lha (dev/mui)
•
MCC_TextEditor-15.35.lha (dev/mui)
•
MCC_BetterString-11.19.lha (dev/mui)
•
fw_c2p_p2c.lha (dev/lib)
•
plib_examples.lha (dev/src)
•
plib.lha (dev/lib)
•
MCC_NList-0.107.lha (dev/mui)
•
MCC_NList-0.106.lha (dev/mui)
More...
Newest users
•
prowler
•
apache64
(Chris)
•
cpeel2300
(Chris)
•
Branquito
•
chris
(Chris Young)
Pending:
•
ZebraZeem
,
Mad_Dog
,
hhjoker
,
voxel
,
JosDuchIt
,
MarcB
,
MarBo
,
Sollaris
,
sara
,
species
More...
Who's Online
Online members:
10 guests are online.
You are an Anonymous user. You can register for free by clicking
here
.
News sites
•
Amiga-News.de
•
Amiga.org
•
AmigaNN
•
Amigans.net
•
Amigaweb.net
•
AmigaWorld.net
•
AROS-Exec
•
MorphOS-News.de
•
MorphZone
•
polarBoing
Tutorials
•
Change Graphics cards in AmigaOS 4.
•
Installing the latest OS4 SDK in Cubic IDE
•
Writing Installer scripts for AmiUpdate
•
Cross Compiling for OS4 or OS3 using MS Visual Studio 2005
•
Installing an AmigaOS 4 cross compiler
More...
Sources
•
How to open and use the exec debug interface
•
How to install a hardware interrupt
•
Install SObjs with Installer
•
How to make clean picture datatypes
•
Most of the old ClassACT examples converted to OS4
More...
Documentations
•
How to write portable code for Amiga (english)
•
Comment écrire du code portable pour Amiga (français)
•
Development How to with OS3.9 SDK
•
The PartyPack Hack
•
The Amiga PDA Programming Guidelines
More...
UtilityBase needs your help!
Forum
/
Algorithms and techniques
/
Talks about perfect double-buffering for graphics.
Page 2 of 4:
««
1
2
3
4
»»
Wanderer
Forums Member
#31
· Posted: 2009-06-01 10:56
As I said, ScreenBufferChange in combination with Wait() does no reliable timing for you either.
I have tested all combinations what was discussed here and more.
kas1e
Forums Member
#32
· Posted: 2009-06-01 11:00 · Edited by: kas1e
Wanderer, then, what i can use with Wait() to make it works ?
Can you make an example which will works on all platforms more or less good ? I mean example with just fucntion called SwithDisplay(), and inside only buffer flipping + waiting.
If WaitTOF() on aos4, works fine , then, some code was added to it on os4 => then it mean it possible to make smooth animation by aos apis ?
At moment, i think, we just can use WaitTOF() for aos3,aos4,aros, and somethink different (with Wait() ), for morphos
ps. and again, how we can explain morphos sdl ports which works at 60fps without any artefacts ? If we looks at itix's code from this sdl
here
, then i see that he don't use ChangeScreenBuffer fucntion at all, but just do some copy of bitmaps + wait for signal (what is must do ChangeScreenBuffer as i think, but is not looks like).
Wanderer
Forums Member
#33
· Posted: 2009-06-01 11:12
All the source is part of the Amibltiz3 Distribution and can be found in the file "includes/dbl_display.include.bb2"
I dont have time right now, but later I can point out specific code lines here.
Short:
Wait() is a Function that waits for a Task Signal, which is typically send on GUI input, AREXX message, CTRL+C etc.
ChangeScreenBuffer() is generating such a signal too.
To use ChangeScreenBuffer correctly, you MUST wait for the signal, otherwise this is not the correct usage of this function.
However, the autodocs make you think it does timing, but depending on the GFX driver, it does or does not.
I get Artefacts on the latest WinUAE using this method.
I have no solution that works on all platforms. that's why i am reading this thread with great interesst.
kas1e
Forums Member
#34
· Posted: 2009-06-01 11:20
Wait() for the signal, it's not timing which is need it for us ? And about ChangeScreenBuffer() - for what port this fucntions will send a signal ? Fucntion have as argument only screen and buffer, nothink about ports. So, if i just will do:
ChangeScreenBuffer(screen,buffer[drawBuffer]);
Wait(which_port_from_where_signal)
I will always have stop of programm, becouse wait will never end (no one send correct signal to it). As i read in autodocs, they use ChangeVPBitMap fucntion from graphics.library , which have as argument A pointer to a DBufInfo (which have connections with ports). With ChangeScreenBuffer i just do not understand how generate (and by which fucntion) correct signal to make Wait works.
At moment all my attempts it's just white/black screen and nothink more (i.e. wait never recieve signal).
ChaosLord
Forums Member
#35
· Posted: 2009-06-01 11:26
Possible super simple solution 1:
Keep using WaitTOF(); but do it like this:
[csource]
WaitBlit();
WaitTOF();
ShowTheFrame();
[/csource]
Test out the above way. If it does not give you perfect results then you should do as wanderer says and wait for the signal that he is talking about first so it would look like this:
[csource]
Wait(TopSecretScreenBufferSignalBit);
WaitTOF();
ShowTheFrame();
[/csource]
ChaosLord
Forums Member
#36
· Posted: 2009-06-01 11:43
Animation on a CRT monitor can
NEVER
be perfectly smooth unless it synchronized to the raster beam. Period. The End.
[quote]I do not know what you mean about NEVER on CRT. Maybe you jump too deep into details, and "perfect" for you mean somethink technical, but i mean "perfect from user side". [/quote]
You said you want perfect double-buffering. To me "Perfect" means:
No jerking
No flickering
No flashing
No tearing
No gfx corruption
Silky smooth scrolling
If the above is what you want, then WaitTOF() is your 2nd best friend in the whole wide world. I am your 1st of course :D
kas1e
Forums Member
#37
· Posted: 2009-06-01 11:56 · Edited by: kas1e
@chaoslord
First way i try on morphos like this:
[csource]
void SwitchDisplayText(W3D_Context *context,struct Screen *screen)
{
//1st way
WaitBlit();
WaitTOF();
//flip/show the frame
W3D_SetDrawRegion(context, buffer[drawBuffer]->sb_BitMap,0, &s);
ChangeScreenBuffer(screen,buffer[drawBuffer]);
drawBuffer ^=1;
}
[/csource]
Morphos Jerkys are here still on more than 70hz modes :)
With second way i am a bit stuck. Trying over winuae for first, but just have no signal looks like. Routine looks like this:
[csource]
struct ScreenBuffer* buffer[2];
struct MsgPort *ports[2];
int drawBuffer;
void SwitchDisplay(W3D_Context *context,struct Screen *screen)
{
//assign ports by my screen info
ports[0]=buffer[drawBuffer]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort ;
ports[1]=buffer[drawBuffer]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort ;
//set SafeMessage as OK
buffer[drawBuffer]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=0;
//wait for signal before fliping.
while(GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
//show the frame
ChangeVPBitMap(&(screen)->ViewPort,buffer[drawBuffer]->sb_BitMap,buffe r[drawBuffer]->sb_DBufInfo);//myDBI);
}
[/csource]
itix
Forums Member
#38
· Posted: 2009-06-01 12:03
@kas1e
[quote]
struct MsgPort *ports[2];
struct DBufInfo *myDBI;
BOOL wait = FALSE;
void SwithDisplay(void)
{
myDBI->dbi_SafeMessage.mn_ReplyPort=ports[0];
myDBI->dbi_DispMessage.mn_ReplyPort=ports[1];
if (wait)
{
while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
}
ChangeScreenBuffer(screen,buffer[drawBuffer]);
drawBuffer ^=1;
wait = TRUE;
}
[/quote]
There. You should also wait for SafeMessage before drawing new content. See my SDL source or check autodocs for graphics.library/ChangeVPBitMap().
[quote]
ps. and again, how we can explain morphos sdl ports which works at 60fps without any artefacts ?
[/quote]
Well, it is not guaranteed there are no artefacts but Intuition double buffering is the best what MorphOS can give to you.
[quote]
If we looks at itix's code from this sdl here, then i see that he don't use ChangeScreenBuffer fucntion at all, but just do some copy of bitmaps + wait for signal (what is must do ChangeScreenBuffer as i think, but is not looks like).
[/quote]
Humm, there is ChangeScreenBuffer() in my SDL code. It does swap bitmap pointers for offscreen rendering. Then there is another wait which could be optimized away to some other place but havent bothered with that yet...
ChaosLord
Forums Member
#39
· Posted: 2009-06-01 12:10 · Edited by: ChaosLord
Your MorphOS may simply have some task running that is causing the random jerks. Try it like this to see what happens:
[csource]
void SwitchDisplayText(W3D_Context *context,struct Screen *screen)
{
//1st way
SetTaskPri(FindTask(0L),100);
WaitBlit();
WaitTOF();
//flip/show the frame
W3D_SetDrawRegion(context, buffer[drawBuffer]->sb_BitMap,0, &s);
ChangeScreenBuffer(screen,buffer[drawBuffer]);
SetTaskPri(FindTask(0L),0);
drawBuffer ^=1;
}
[/csource]
kas1e
Forums Member
#40
· Posted: 2009-06-01 12:12
Itix, i mean you do not use ChangeScreenBuffer() from intuition. You make your own. Only fucntion which you use for double-buffering from intuition, it's Alloc and Free screenbuffers (correct?)
I also tryed example which you post, and again, just have white screen which never ended. If i just remove this
[csource]
while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
[/csource]
Programm works, but with jerkyns of course. Just looks like it never got the answer about Wait for GetMsg. You sure that i need to create these new myDBI, and not using from my opening screen ones ?
itix
Forums Member
#41
· Posted: 2009-06-01 12:28
@kas1e
[quote]
if (ChangeScreenBuffer(SDL_Display, hidden->SB[hidden->CurrentBuf ^ 1]))
{
surface->hwdata->bmap = SDL_RastPort->BitMap = hidden->SB[hidden->CurrentBuf]->sb_BitMap;
hidden->SafeChange = FALSE;
hidden->CurrentBuf ^= 1;
// Wait for frame change
#if 1
if (hidden->SafePort)
{
while (!GetMsg(hidden->SafePort))
Wait(1L << hidden->SafePort->mp_SigBit);
}
#endif
}
[/quote]
Please also note I am waiting for SafeMessage right after ChangeScreenBuffer() call.
If you get white screen you are flipping buffers in wrong order. Also double verify you are allocating screen buffers correctly.
[quote]
You sure that i need to create these new myDBI, and not using from my opening screen ones ?
[/quote]
What autodocs say about it?
kas1e
Forums Member
#42
· Posted: 2009-06-01 12:31 · Edited by: kas1e
@ChaosLord
The same with TaskPri. I think it's not related to task priority, it's WaitTOF() boredoom for sure :)
@itix
Autdocs as usually said not many:
[csource]
NAME
ChangeScreenBuffer -- Swap the screen's BitMap. (V39)
SYNOPSIS
success = ChangeScreenBuffer( Screen, ScreenBuffer )
ULONG ChangeScreenBuffer( struct Screen *, struct ScreenBuffer * );
FUNCTION
Performs double (or multiple) buffering on an Intuition screen
in an Intuition-cooperative manner. The BitMap associated
with the supplied ScreenBuffer will be installed in the
specified screen, if possible. The previously-installed BitMap
is available for re-use upon receiving a signal from
graphics.library. See the graphics.library autodocs for
graphics.library/AllocDBufInfo() and graphics.library/ChangeVPBitMap()
for details.
INPUTS
Screen: pointer to the screen whose bitmap is to be swapped.
ScreenBuffer: pointer to a ScreenBuffer structure obtained from
AllocScreenBuffer().
RESULT
Returns non-zero if the operation succeeded. Returns zero
if the operation cannot be performed. This function will
fail if Intuition's state cannot permit it, for example the
user is playing with menus or gadgets.
NOTES
It is not required to restore the original ScreenBuffer
before closing the screen. Simply FreeScreenBuffer() each
buffer (including the original and the currently-installed one)
then close the screen. Of course, you cannot call
ChangeScreenBuffer() after freeing the currently-installed one.
[/csource]
Allocation of buffer i think i do correctly, becouse if just remove "wait" ChangeSreenBuffers works as must, just without good 'sync'.
I do alllocation like this in the begining:
[csource]
struct ScreenBuffer* buffer[2];
buffer[0] = AllocScreenBuffer(screen,NULL, SB_SCREEN_BITMAP);
buffer[1] = AllocScreenBuffer(screen,NULL, 0);
[/csource]
itix
Forums Member
#43
· Posted: 2009-06-01 12:33
[quote]
See the graphics.library autodocs for
graphics.library/AllocDBufInfo() and graphics.library/ChangeVPBitMap()
for details.
[/quote]
kas1e
Forums Member
#44
· Posted: 2009-06-01 12:37 · Edited by: kas1e
Itix, yeah, already.
And i am already try to change ScreenChange buffer, on just
[csource]
ChangeVPBitMap(&(screen)->ViewPort,buffer[drawBuffer]->sb_BitMap,buffe r[drawBuffer]->sb_DBufInfo);
[/csource]
the same end loop. I.e. it's not just flip buffers in wrong way, programm itself start not works. No any keys works, exit not works, application meditation after. If remove Wait - all is ok.
What i can detect also (with your latest example) it's what for beginig it flip buffers i think 5-7 times faste-faster, like flip-flip-flip-flip, and then meditation.
itix
Forums Member
#45
· Posted: 2009-06-01 12:44
Do not use ChangeVPBitMap() directly. ChangeScreenBuffer() is high level Intuition call which does call ChangeVPBitMap() internally.
1) Use ChangeScreenBuffer()
2) See what docs say about ChangeVPBitMap() but do not call that function in your code
It is just that with Intuition if you dont have all details correctly placed you experience difficult crash. I can not fix your code so you must iterate through your code and verify everything is done correctly, try it again, and then iterate again, try again and so on. Coding is, especially on Amiga, tough work :)
kas1e
Forums Member
#46
· Posted: 2009-06-01 13:17 · Edited by: kas1e
@itix
yes, i not use ChangeVPBitMap() directly, it was only as test, to make sure that it's the same as ChangeScreenBuffer.
I also checked ChangeVPBitMap() docs, and only what i foun about its:
[quote]
NOTES
This will set the vp->RasInfo->BitMap field to the bm pointer which is
passed.
When using the synchronization features, you MUST carefully insure that
all messages have been replied to before calling FreeDBufInfo or
calling ChangeVPBitMap with the same DBufInfo.
[/quote]
I.e. nothinkt about signals, only about "you must reply on all messages before do the same think next time". But how i can do it (and why, it's not done by ChangeScreenBuffer (or it's do?) ) - i do not know.
About AllocDBufInfo , wrote nothink interesting. Only that:
[quote]
Returns 0 if there is no memory available or if the display mode
of the viewport does not support double-buffering.
The only fields of the DBufInfo structure which can be used by application
programs are the dbi_SafeMessage, dbi_DispMessage, dbi_UserData1 and
dbi_UserData2 fields.
dbi_SafeMessage and dbi_DispMessage are standard exec message structures
which may be used for synchronizing your animation with the screen update.
dbi_SafeMessage is a message which is replied to when it is safe to write to
the old BitMap (the one which was installed when you called ChangeVPBitMap).
dbi_DispMessage is replied to when it is safe to call ChangeVPBitMap again
and be certain that the new frame has been seen at least once.
The dbi_UserData1 and dbi_UserData2 fields, which are stored after each
message, are for your application to stuff any data into that it may need
to examine when looking at the reply coming into the ReplyPort for either
of the embedded Message structures.
DBufInfo structures MUST be allocated with this function. The size of
the structure will grow in future releases.
[/quote]
And next going an example how they called "proper double buffering synchronization" which just do not works correctly for me. The idea of this example routine looks like this:
1. Check, it's save to write by messages
2. Render fucntions (that is suck, for whay need to put render fucntions to the sync fucntions, boring)
3. Check save to change, or not and after flip buffers by WaitBlit() and ChangeVPBitMap
4. cleanup the messages.
itix
Forums Member
#47
· Posted: 2009-06-01 13:28
Hmm, good point. It mus be a documentation error. The example code in AllocDBufInfo() does not reply to messages but gets messages via GetMsg().
kas1e
Forums Member
#48
· Posted: 2009-06-01 13:32
Yeah,you mean these ones ?
[csource]
if (! SafeToChange) /* cleanup pending messages */
while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
if (! SafeToWrite) /* cleanup */
while(! GetMsg(ports[0])) Wait(1l<<(ports[0]->mp_SigBit));
[/csource]
How reply must be done then ? SendMsg fucntion ?
itix
Forums Member
#49
· Posted: 2009-06-01 13:32 · Edited by: itix
@kas1e
[quote]
2. Render fucntions (that is suck, for whay need to put render fucntions to the sync fucntions, boring)
[/quote]
You dont have to (i.e. see SDL code). You just must GetMsg() dbi_SafeMessage before you start rendering.
[quote]
How reply must be done then ? SendMsg fucntion ?
[/quote]
Yes I mean those ones. Do not reply at all.
kas1e
Forums Member
#50
· Posted: 2009-06-01 13:37 · Edited by: kas1e
@itix
so, then, normal routine with Wait, must be looks like this:
1. GetMsg on SafeMessage from port which i assingn by my screen.
2. Flip the buffer
3. SendMsg to SafeMessage and to DispMessage of my assigned ports ?
(it can explain why i have whitescreen and nothink happened next, becouse no message sended, and SageMessage always in one state ?).
itix
Forums Member
#51
· Posted: 2009-06-01 13:51
1. Flip the buffer
2. GetMsg() on SafeMessage.
3. Render to the buffer
4. GetMsg() on DispMessage.
5. Goto 1
kas1e
Forums Member
#52
· Posted: 2009-06-01 13:59
Itix, uhmm.. i need just routine which will be called SwithDisplay();
becouse all my code (huge) already based on idea that i draw by some fucntinions to buffer, and when i need flip, i call fucntion for flipping/sync.
So, by your idea i need for every draw function add somethink. I think that it canbe reorganize like this:
1. get msg on DispMessage
1. flip the buffer
2. getmsg on SafeMessage
I.e. i will draw when i need (3), then do in SwithDisplay function (4,1,2).
ps. you sure about GetMsg in 4 ? It's not must be SendMsg (for sending replyes?)
itix
Forums Member
#53
· Posted: 2009-06-01 14:02
I am sure abuot GetMsg() in 4.
kas1e
Forums Member
#54
· Posted: 2009-06-01 14:05
Then strange.. I just try it like this:
[csource]
void SwitchDisplayText(W3D_Context *context,struct Screen *screen)
{
ports[0]=buffer[drawBuffer]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort ;
ports[1]=buffer[drawBuffer]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort ;
while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
while(!ChangeScreenBuffer(screen,buffer[drawBuffer]));
while(! GetMsg(ports[0])) Wait(1l<<(ports[0]->mp_SigBit));
drawBuffer ^=1;
W3D_SetDrawRegion(context, buffer[drawBuffer]->sb_BitMap,0, &SwiDisp);
}
[/csource]
Just halt. Never have answer for Wait.
ChaosLord
Forums Member
#55
· Posted: 2009-06-01 14:13
For the record, I tried using the OS ChangeScreenBuffer(), etc. routines way back in the mid 90s.
I have the following vague memories:
1. It seemed way to complicated for such a simple little thing as double-buffering.
2. I never could get it to work. Or maybe I finally got it to "work" but it sucked and was useless...
3. I gave up on it and did things the simple, normal way.
Repeating Deja Vu? ;)
Hypex
Forums Member
#56
· Posted: 2009-06-01 14:17
@ kas1e
You could manage the signal handling yourself. You can add an interrupt routine with graphics.library amiga.lib function AddTOF(), exec AddIntServer() with INTB_VERTB, or lowlevel.library AddIntServer.
Simply alloc a signal bit and in the routine signal your task. It should work on al systems and gfx cards and signal on every refresh. I tested it on OS4 and it could let me exactly record the 60Hz frame rate of my LCD. :-)
AddTOF() is made for C programming, but I have no idea how to set it up, it looks hard to me! The others are easier for assembly, what I programmed with.
http://utilitybase.com/ref/?keyword=AddTOF&funcgroup=AmigaOS&action=Se arch
http://utilitybase.com/ref/?keyword=AddIntServer&funcgroup=AmigaOS&act ion=Search
http://utilitybase.com/ref/?keyword=AddVBlankInt&funcgroup=AmigaOS&act ion=Search
Hypex
Forums Member
#57
· Posted: 2009-06-01 14:22
@GetMsg() :-)
BTW, if you need too GetMsg(), you can use WaitPort() to wait and avoid needing to specify signal bits. You just need the port.
itix
Forums Member
#58
· Posted: 2009-06-01 14:28
@kas1e
You forget that when your SwitchDisplayText() is called for the first time you do not Wait(). Only when it is called again second and third time and so on.
itix
Forums Member
#59
· Posted: 2009-06-01 14:31
@Hypex
It wouldnt help with MorphOS. There vertical blanking interrupt is static 50 Hz timer not linked to gfx card vertical sync. And again it would have problem with multiple gfx cards on the system.
kas1e
Forums Member
#60
· Posted: 2009-06-01 14:36
@ChaosLord
ChangeScreenBuffer itself works fine (ie. it's do what is must to do - changes buffer). Problem not becouse of it, but becouse of how make this changes Smooth. Right now trying over these Wait(), but looks like i suck very much, or developers of all this shit suck very much :)
I mean when a solution ? I have on morphos 'jerkynes', but i wan't. Of course , better saud - hey, mos defs, make please WaitTOF like it on AOS4. But i know what he said, and how these talks with looks like :)
So, it's not solution.
@Hypex
omg, one more soltuion which is pretty hard for me to implement i think :) Have any work-live example without refering to autdocs ?:)
At moment i give up, need wait some hourse .. But i really want to say "for what the hell this MUST BE think not implement in all oses like it's done right now in OS4". But ok, let's be patient and try to make it works :)
Hypex, i also think, than on AOS4 it can be good for you just becouse you put somethere WaitTOF(), you sure that you not ?
Page 2 of 4:
««
1
2
3
4
»»
Forum
/
Algorithms and techniques
/ Talks about perfect double-buffering for graphics.
↑
Top
Your Reply
Amiga OS 4.x - C/C++ development
AmigaOS 4.x - General
AmigaOS Classic - C/C++ development
AmigaOS Classic - Assembler
AmigaOS Classic - General
AmigaAnywhere/DE - C/C++ development
AmigaAnywhere/DE - VP Assembler
AmigaAnywhere/DE - General
AROS - C/C++ development
AROS - General
MorphOS - C/C++ development
MorphOS - General
PowerPC - Assembler/Altivec
ARexx scripting
GUI - Magic User Interface (MUI)
GUI - Reaction/ClassAct
3D Programming
Requests
Platform independent C/C++ Development
API - Feelin
Site Feedback
General Chat
News
Tutorials
Documentations
Sources
Reviews
Links
Developer connection
Algorithms and techniques
Introduce yourself
Java programming
UtilityBase is a site focused on development for Amiga systems,
spanning over all different Amiga clones, that be AmigaOS 3.x, 4.x, MorphOS, AROS or AmigaDE/Anywhere.
News syndication:
Contact address:
mail@utilitybase com