SDL Fullscreen speed problems Win32

Started by
9 comments, last by rip-off 17 years ago
Hi, in a game I am developing, I use SDL_SetVideoMode(1024, 768, 32, SDL_DOUBLEBUF | SDL_FULLSCREEN)); to set the video mode. (And I also tried various combinations of SDL_HWSURFACE/SW_SURFACE, SDL_HWACCEL, SDL_ANYFORMAT, etc.) The problem is that the game runs smoothly in windowed mode (at around 50 FPS) which drop down to _7_ FPS in full screen. The game itself is "simply" blitting 2d tiles on a surface, using SDL_BlitSurface. Scrolling is involved and it works like a breeze in windowed mode, as I said... I googled and found that this seems to be a problem in Windows only, namely the renderer appears to be DirectX 5 which might not be supported by MS which causes it to be so slow. So, I am supposed to set the renderer to the Windows GDI which supposedly is going to make it faster (sounds bad enough to me, but if it works...). First problem: How do I set the video mode? The function SDL_setenv does not appear to be in the SDL or SDLmain.dll. (I am using SDL 1.2.9 btw -- could upgrading to 1.2.11 help?). However, I found the information stated above here in a _pascal_ forum. I am using Visual C++ (.Net 2003). I tried setting a regular environment variable under Windows using setenv("SDL_VIDEODRIVER=windib"); which had no effect at all (and I called it, before I called SDL_Init. The call to SDL_Init is SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_TIMER | SDL_INIT_AUDIO). Anything wrong here?). Any ideas what could be wrong? Thanks for your help! Beren
Advertisement
I don't remember how to change the rendering engine, but no, you don't want GDI anyway. DirectX 5 is old, but it's not "unsupported" in the technical sense. It works just fine for this sort of application. The problem is probably that you're not converting the loaded images to the display format. I believe the function in question is SDL_DisplayFormat. Windows handles things differently in fullscreen and you're probably finding that it's converting each surface from software to hardware or vice versa with each individual blit.
Thanks for the reply. But I do use DisplayFormat for every surface I use. If I hadn't, I'd have a frame rate around 11-16 in windowed mode.

Removing the SDL_DOUBLEBUF in the video init call solved the problem: Now I do have 50 frames in fullscreen as well. I don't really understand it, but since I do not see any side-effects (i.e. flicker), I'll stick to the "solution" for now. Does anyone have a clue as to why I can't use double buffering when in full screen? Is DirectX already double buffering everything I send to the pipeline?

Thanks!
No, there's definitely something else broken there. Are you doing some alpha blending? If you are, then that runs very slowly with hardware surfaces. Windowed mode tends to force SDL/DirectDraw back down to software surfaces which is why you may see faster results in the windowed case.
Yes, I am doing some alpha blending. I changed all surfaces from HW to SW but I cannot see any change. Whenever I enable double buffering, the frame rate in fullscreen mode goes way down.

I'd send in code examples, but I'm not sure what I could show you: Apart from the initialization and blitting, I don't do anything fancy:

if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_TIMER | SDL_INIT_AUDIO) < 0) {    fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());    exit(1);  }  atexit(SDL_Quit);  atexit(deInit);      SDL_SetVideoMode(getWidth(), getHeight(), getBits(), SDL_SWSURFACE /*| SDL_FULLSCREEN*/));...  SDL_Surface *temp = IMG_Load("tilesAlpha.png");  SDL_PixelFormat dd;	dd.Aloss = 0;	dd.alpha = 255;	dd.Amask = 0x000000FF;	dd.Ashift = 0;	dd.BitsPerPixel = 32;	dd.Bloss  = 0;	dd.Bmask  = 0xFF00;	dd.Bshift = 8;	dd.BytesPerPixel = 4;	dd.colorkey = 0;	dd.Gloss = 0;	dd.Gmask = 0xFF0000;	dd.Gshift = 16;	dd.Rloss  = 0;	dd.Rmask  = 0xFF000000;	dd.Rshift = 24;	dd.palette = getScreen() -> format -> palette;	  transparentTileSurface = SDL_ConvertSurface(temp, &dd, SDL_SWSURFACE);	    SDL_FreeSurface(temp);...  SDL_Rect sourceRect;  SDL_Rect destRect;  sourceRect.w = destRect.w = TILESIZE;  sourceRect.h = destRect.h = TILESIZE;  sourceRect.x = 0;  sourceRect.y = TILESIZE * tile;  destRect.x   = x;  destRect.y   = y;  SDL_BlitSurface(transparentTileSurface()                    &sourceRect,                    getScreen(),                    &destRect);


Anything looks odd?

Thanks.
We had that exact same problem when I was making Q'Bicles. I managed to figure out using a profiler that the game was spending an absurd amount of time (~100ms/frame) in WaitForSingleObject in, of all places, the DirectInput code. As I barely know DX at all, I fixed the symptom by upgrading the DirectInput code in SDL from whatever version it was using (3, iirc) to version 8. The FPS went "way" up to about 20 fps (which was still something like half the windowed mode frame rate but it was closer).

I would actually be really interested if this really was was the same problem we had.
The DirectInput problem sounds interesting. I will look into that. Thanks! When you say you "upgraded the DirectInput code in SDL", do you mean that you recompiled the SDL sources with DirectInput in its latest version? Or is there a way to externally hook the DI code without recompiling SDL?
SDL will try obtain a hardware surface for SDL_DOUBLEBUF. As such alpha blending and SDL's double buffering will be extremely slow. Note that using SDL_SWSURFACE will not affect this as SDL_SWSURFACE is actually 0 and will be overridden by any other format value you OR with it.

For a really interesting read about SDL and hardware surfaces ( and 2 other interesting SDL related articles ), take a look at Bob Pendelton's articles here.

Also, your surface conversion code seems a bit verbose when you could simply use SDL_DisplayFormatAlpha(). [smile]
I just upgraded to SDL 1.2.11 and SDL_Image 1.2.5.
What happens is that I now get _the exact same framerate_ for windowed and fullscreen mode, even if I enable SDL_DOUBLEBUF.

BUT: I have upgraded SDL on my home computer and I honestly don't know if the problem existed here in the first place. So, now I will also upgrade to the latest SDL version on my development machine and I will keep you posted if that solved the problem.

@rip-off: Thanks for the link to the articles -- and the hint to my verbose conversion function oooops -- they are proving to be helpful already.
Updating to SDL 1.2.11 solved the problem for me. Why? I don't have a clue...

This topic is closed to new replies.

Advertisement