http://listas.apesol.org/pipermail/sdl-libsdl.org/2001-January/014085.html Hi! Tiny little bug in SDL I've found: In SDL_dgavideo.c: 843: static int DGA_FlipHWSurface(_THIS, SDL_Surface *surface) 844: { 845: int yoffset; 846: 847: /* Wait for vertical retrace and then flip display */ 848: yoffset = flip_page*surface->h; 849: while ( XDGAGetViewportStatus(DGA_Display, DGA_Screen) ) 850: /* Keep waiting for the hardware ... */ ; 851: XDGASetViewport(DGA_Display, DGA_Screen, 0, yoffset, XDGAFlipRetrace); 852: flip_page = !flip_page; 853: 854: surface->pixels = flip_address[flip_page]; 855: return(0); 856: } Notice that the code is waiting for all pending XDGASetViewport() requests on line 849. After that it calls XDGASetViewport(). This of course is totally wrong since it defeat the whole purpose of doing it in the first place (which is to wait for the vertical retrace to end before switching the viewport). What happens in above case is that it waits for the previous viewport change to complete and then flips it which causes all kinds of flickering. If you first change the viewport and then polls till it completes you get the desired effect, i.e. it should be: 849: XDGASetViewport(DGA_Display, DGA_Screen, 0, yoffset, XDGAFlipRetrace); 850: while ( XDGAGetViewportStatus(DGA_Display, DGA_Screen) ) 851: /* Keep waiting for the hardware ... */ ; Try it. Make a huge difference (; Btw, I'd really like to make a suggestion here (one of the main reasons I'm not keen on using SDL for my projects): I'd really appreciate it if you guys could change SDL_Flip() from int SDL_Flip(SDL_Surface *screen); to int SDL_Flip(SDL_Surface *screen,int wait_for_vertical_refresh); Sometimes, especially when programming, it is desirable to disable waiting for the vertical refresh so that one can get a clear indication of the framerate achieved. Forcing people to wait for the screen refresh isn't very cool... In fact, I think waiting for the vertical refresh and flipping the screen shouldn't even be in the same function since almost always it's better to first wait for the vertical refresh, then draw everything, flip it to the screen, etc. E.g. SDL_WaitForRefresh (); draw_all_my_stuff_on_buffer (); SDL_Flip (); clear_all_my_stuff_on_buffer (); === Abraham vd Merwe wrote: >What happens in above case is that it waits for the previous viewport change >to complete and then flips it which causes all kinds of flickering. I don't see how this can cause flickering. This is what's supposed to happen: client calls SDL_Flip(): waits for *previous* flip to complete XDGASetViewport() to the other buffer (to complete asynchronously) client draws something on the screen (either by locking the display and bashing bits directly or by doing a BlitSurface or FillRect): DGA_WaitHardware() waits for above XDGASetViewport to take effect (in essence waiting for retrace) client then updates the not currently displayed buffer client calls SDL_Flip(): waits for the flip above to complete, which is a no-op (since the client already did a wait when drawing something to the screen) XDGASetViewport() to the other buffer (to complete asynchronously) If you still find flickering that is a bug in your code or possibly in SDL. Please post a minimal but complete example that exhibits the problem >If you first change the viewport and then polls till it completes you get >the desired effect, i.e. it should be: > >849: XDGASetViewport(DGA_Display, DGA_Screen, 0, yoffset, XDGAFlipRetra= >ce); >850: while ( XDGAGetViewportStatus(DGA_Display, DGA_Screen) ) >851: /* Keep waiting for the hardware ... */ ; If this makes a difference then you are doing something wrong. Perhaps you have forgotten to lock the screen before accessing pixels on it? Your change will only defeat the attempt to avoid blocking for retrace until absolutely necessary >Sometimes, especially when programming, it is desirable to disable waiting >for the vertical refresh so that one can get a clear indication of the >framerate achieved. This makes no sense. Measure the time over several frames, divide by the number of frames, and you get the frame rate === >This makes no sense. Measure the time over several frames, divide by the >number of frames, and you get the frame rate er, the inverted frame rate :-) === It indeeds makes a lot of sense, since if your application is limited at 60fps due to the vertical blank, you cannot have any idea about how fast it could get without it. This is at least true under Win32. Moreover, looking at the DX5 video implementation, I can see that DDFLIP_WAIT flag is always specified. In this way, the flipping call is syncronous, at it waits till the real flip happens (instead of just scheduling the flip, as the SDL documentation says). This is very bad in case of triple buffering, but it seems that SDL does not support triple buffering. Do you think it is feasable for the future? It would be just great. === >It indeeds makes a lot of sense, since if your application is limited at >60fps due to the vertical blank, you cannot have any idea about how fast it >could get without it. This is at least true under Win32. If you just want to profile your code, then don't flip at all >Moreover, looking at the DX5 video implementation, I can see that >DDFLIP_WAIT flag is always specified. In this way, the flipping call is >syncronous, at it waits till the real flip happens (instead of just >scheduling the flip, as the SDL documentation says). That sounds wrong --- someone who knows DirectX should look at that > This is very bad in >case of triple buffering, but it seems that SDL does not support triple >buffering. Do you think it is feasable for the future? It would be just >great. I personally think the usefulness of triple buffering is limited, but it might be worth supporting anyway. It probably requires an api revision though === > -----Messaggio originale----- > Da: owner-sdl at lokigames.com [mailto:owner-sdl at lokigames.com]Per conto di > Mattias Engdegård > Inviato: martedì 9 gennaio 2001 15.35 > A: sdl at lokigames.com > Oggetto: Re: R: [SDL] bug in SDL DGA driver > >It indeeds makes a lot of sense, since if your application is limited at > >60fps due to the vertical blank, you cannot have any idea about > how fast it > >could get without it. This is at least true under Win32. > If you just want to profile your code, then don't flip at all I want to profile my code *including* the flip operation. However, I think this only means introducing a new flag. Since I'm very new at SDL, I don't know if this kind of process (i.e. adding a new flag) is common or it is discouraged by API mantainers. > >Moreover, looking at the DX5 video implementation, I can see that > >DDFLIP_WAIT flag is always specified. In this way, the flipping call is > >syncronous, at it waits till the real flip happens (instead of just > >scheduling the flip, as the SDL documentation says). > That sounds wrong --- someone who knows DirectX should look at that I'm really sorry about this, but you are right, I was just wrong. The meaning of the flag is different, and it does exactly what it is supposed to do. > > This is very bad in > >case of triple buffering, but it seems that SDL does not support triple > >buffering. Do you think it is feasable for the future? It would be just > >great. > I personally think the usefulness of triple buffering is limited, but > it might be worth supporting anyway. It probably requires an api > revision though I use it rarely, but I understand that some kind of applications can take performance gains from that. === Tue, 09 Jan 2001 Mattias Engdegård wrote: [...] > I personally think the usefulness of triple buffering is limited, but > it might be worth supporting anyway. It probably requires an api > revision though Tripple buffering is a performance hack that can improve performance a great deal in at least two cases: 1. Software rasterizing + flipping involving hardware blitting. The CPU can get started with the next frame while the flip is in progress; double buffering would force the operations to be serialized. 2. Software or hardware rasterizing at less than full frame rate. The engine can keep working most of the time, rather than wasting time waiting for the *next* frame it it's a bit late. For example, if it takes 110% of a frame period to render one frame, double buffering would run at half frame rate, while triple buffering would drop approximatey one frame in ten; ie run at almost full frame rate. Right, it's said that game engines are not all about speed. But if that's true, how come almost every serious action gamer and engine coder is obsessed with it...? ;-) === On Tue, Jan 09, 2001 at 11:15:39AM +0100, =?ISO-8859-1?Q?Mattias Engdeg=E5rd?= wrote: > >Sometimes, especially when programming, it is desirable to disable waiting > >for the vertical refresh so that one can get a clear indication of the > >framerate achieved. > > This makes no sense. Measure the time over several frames, divide by the > number of frames, and you get the frame rate I assume hes talking about performance testing here. In the real world, drawing more frames than can actually be displayed is of course as futile as capacitance....uh....resistance. However, if you want to see how well your code/hardware is performing it is handy to be able to unthrottle it.