Sdl Vs Opengl Es Vs. /dev/fb0?


Cthulhu32

Still Fresh
Joined
Nov 9, 2010
Messages
21
Location
Denver, CO
I'm looking at porting my own version of FCEUX (updated FCEU) over to the Caanoo, and I've been reading though a lot of other emulator developers sources. It seems to me like the preferred graphics library is SDL, which in the PC world is notorious for having slow software writes. I'm experienced with using OpenGL and monkeying with straight frame-buffer writes, but I'm just wondering why certain authors choose SDL over OpenGL ES or just mapping /dev/fb0? Is it the flexibility SDL has over doing raw calls yourself, or has GPH optimized the video rendering in SDL to make it pretty speedy and take advantage of their 3D hardware?

Also, is there any memory map layout for the Caanoo that shows which bits of the Caanoo /dev/mem point to what? I've seen some pretty good defines in the GPH SDK, but some emulators like Cano-Hugo use certain known memory locations to do things like over-clock or set the CPU.
 
SDL is not neccessarily slow, and has huge advantages over OpenGL ES and especially direct memory access. First of all, it's platform independent. I ususally develop my games on a Mac (OSX), sometimes on Linux, and occasionally build windows versions. You can't do that with direct memory access, and using a wrapper to be able to use OGL ES is not always a good solution.
My current game produces 30-50 FPS on caanoo using SDL (the whole screen is redrawn in each frame), without too much optimization.
Of course SDL CAN be used to produce very slow results, but that's usually a coder error...
 
i think the main reason why to use SDL is that it is widely available - on tons of different platforms.

On the caanoo i think you'll hit the problem when using OpenGL/ES that updating a fullscreen texture each frame will reduce performance much more than simply using SDL. But you could prove me wrong :)

on the wiz for example, i've once tried to use a texture as a framebuffer alternative, writing *directly* to the texture memory. the problem is though, that textures don't lie linearily in memory but swizzled. you can check out the original thread here.

there's also a link to the source code of the test application i've made, if you are interested in porting/trying it out on the caanoo.
 
Last edited by a moderator:
SDL is not neccessarily slow, and has huge advantages over OpenGL ES and especially direct memory access. First of all, it's platform independent. I ususally develop my games on a Mac (OSX), sometimes on Linux, and occasionally build windows versions. You can't do that with direct memory access, and using a wrapper to be able to use OGL ES is not always a good solution.
My current game produces 30-50 FPS on caanoo using SDL (the whole screen is redrawn in each frame), without too much optimization.
Of course SDL CAN be used to produce very slow results, but that's usually a coder error...

Yeah for an emu you gotta keep your FPS as high as possible, so every frame I'm going to be updating the frame buffer with a full write. In SDL you can just set the ->pixels() of your screen which should render itself to the frame-buffer called by flip(), but there should be a faster way to do this. I have no qualms with SDL, I've used it for my own games before but for speed I usually switch over to OpenGL because of the hardware acceleration benefits. I can get an SDL application from ~5% cpu to 0% cpu after I offload all of the draw routines to the graphics card. I can post some of my PC projects showing this, but for now I'll keep it on-topic with the Caanoo :)

crow_riot said:
i think the main reason why to use SDL is that it is widely available - on tons of different platforms.

On the caanoo i think you'll hit the problem when using OpenGL/ES that updating a fullscreen texture each frame will reduce performance much more than simply using SDL. But you could prove me wrong :)

on the wiz for example, i've once tried to use a texture as a framebuffer alternative, writing *directly* to the texture memory. the problem is though, that textures don't lie linearily in memory but swizzled. you can check out the original thread here.

there's also a link to the source code of the test application i've made, if you are interested in porting/trying it out on the caanoo.

Yeah swizzling is not that uncommon in gaming platforms. On the Wii, the textures are swizzled all the hell, its a pretty nasty format honestly. (source) I think your swizzle code is perfect to try though, my Caanoo comes in next week so I'm going to start trying some of my tests on the actual hardware. The only way I could think SDL is out-performing a GPU approach is if there is a significant read/write time increase when writing directly to memory shared by the GPU. My guess would be the SDL port probably binds directly to /dev/fb* when you set the video mode, so you don't have to worry about the software copying screen buffer->actual video out. I will definitely run some tests though when I get my system, I'll just write a quick plasma demo and see what kind of FPS I get for each method. That is generally a good way to test direct pixel manipulation.
 
Last edited by a moderator:
Unless you need scaling, writing directly to the framebuffer is almost always going to be faster than writing to a texture and getting the GPU to blit it. That's using crow_riot's approach, which is a pretty ugly hack of circumventing OpenGL ES, but it's necessary because texture uploads there are a lot slower. You probably won't be able to render data naturally swizzled. No matter what you do, make sure you're writing to write buffered memory.. if you open it in /dev/mem you'll have to use wARM to make it write buffered.

Both the framebuffer and textures visible in main memory, so you're not hit with a slower path. I don't know the quality of /dev/fb0, ie what features are available, for instance if it makes it easy to perform double buffering... A lot of us hit the 2D hardware directly (through /dev/mem). libcastor is another alternative that does that. I wouldn't trust SDL to be a direct framebuffer implementation either without testing it first.
 
Exophase said:
Unless you need scaling, writing directly to the framebuffer is almost always going to be faster than writing to a texture and getting the GPU to blit it. That's using crow_riot's approach, which is a pretty ugly hack of circumventing OpenGL ES, but it's necessary because texture uploads there are a lot slower. You probably won't be able to render data naturally swizzled. No matter what you do, make sure you're writing to write buffered memory.. if you open it in /dev/mem you'll have to use wARM to make it write buffered.

Both the framebuffer and textures visible in main memory, so you're not hit with a slower path. I don't know the quality of /dev/fb0, ie what features are available, for instance if it makes it easy to perform double buffering... A lot of us hit the 2D hardware directly (through /dev/mem). libcastor is another alternative that does that. I wouldn't trust SDL to be a direct framebuffer implementation either without testing it first.

Yeah you would think rendering a texture and pushing the GL would be close to as fast as writing to the direct frame buffer. I think having proper stretching would definitely be a perk, and its super easy to do that via texture scaling. But if I needed to, I could write directly to the frame buffer during emulation routines, then save the frame buffer to a texture and draw the GUI via GL when the user wants to go back to the menu.

I'm looking at the framebuffer defines in /GPH_SDK/tools/target/opengles/port.c vs. libcastor 0.1, and it looks like the memory offsets are in different positions for the Wiz vs. Caanoo. It probably would not be that difficult to update libcastor to the Caanoo, but its just a matter of tracking down the memory offsets in the GPH SDK. Take a look at this:

Code:
// From port.c Opengl ES binding for Caanoo
	// Clear Framebuffer
	mapped_mem = mmap(NULL, 320*240*3, PROT_READ|PROT_WRITE, MAP_SHARED, fd_mem, 0x5600000);
	memset(mapped_mem, 0x00, (320*240*3));
        munmap( mapped_mem, (320*240*3));

Code:
// From castor.c for Wiz
	/* assign framebuffers */
	fb0_0 = (volatile uint16_t*)mmap(0, 0x4B000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0x3700000);
	fb0_1 = (volatile uint16_t*)mmap(0, 0x4B000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0x374B000);
	fb1_0 = (volatile uint16_t*)mmap(0, 0x4B000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0x3796000);
	fb1_1 = (volatile uint16_t*)mmap(0, 0x4B000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0x37E1000);
	fb0 = fb0_1; /* assign initial framebuffers */
	fb1 = fb1_1;
	memset((void*)fb0_0, 0x00, 0x4B000); /* clear framebuffers */
	memset((void*)fb0_1, 0x00, 0x4B000);
	memset((void*)fb1_0, 0x00, 0x4B000);
	memset((void*)fb1_1, 0x00, 0x4B000);

I bet you they did the next frame buffers the same, so you could write three more (320*240*3) chunks (R8B8G8). It makes sense the offsets would be further up in order to make room for more memory at the base of the memory map. I guess now its just a matter of putting together some test DGE's to see how much of a performance hit using OpenGL ES texture swizzling is vs. frame buffer rendering, and waiting for my Caanoo to arrive :)
 
Last edited by a moderator:
I haven't finished the GL or pure Frame Buffer versions yet, but here's a quick SDL port of a plasma demo I have laying around. I also haven't had a chance to put it on real hardware yet because my Caanoo is sitting at the USPS office and I won't get it till Monday. Let me know what kind of FPS you see, I have the Caanoo version uncapped at 240 fps max, but the Windows version should run at a constant 60 fps. Also you'll need SDL.dll for the Win32 version, I didn't want to package that in this zip.

Download SDL fps counter
 
Alright, so I just played around with writing directly to the frame-buffer vs. using SDL to do all of my writes. And I have to say.. BIG fps difference.

For my plasma demo, the SDL difference saw around 8.00 fps, while the straight Frame-buffer write was 8.50 fps pretty consistently. So then I tried writing nothing but black, and frame-buffer writing saw a consistent 98.0 fps while the SDL write was averaging somewhere around 67 fps. I did not try implementing a full OpenGLES implementation yet, but I really doubt it will be faster than a direct FB write. Also, I might port caster's simple lib over to Caanoo while I work on this emulator just to make my life a little easier. It seems like the screen and screen buffers are completely different from the Wiz, but I'll make sure to document my work :)
 
SDL is nice and portable, but I'm having trouble using SDL with OpenGL(ES) on Caanoo. I keep getting "OpenGL not available" errors when trying to set the SDL vidmode. Does this mean the SDL libraries shipped with Caanoo firmware do not have OpenGL support?
 
i think caanoo support OpenGL library, have a look at AAAA, for example ;)
but,anyway, wait the experts ;)
 
Patches said:
SDL is nice and portable, but I'm having trouble using SDL with OpenGL(ES) on Caanoo. I keep getting "OpenGL not available" errors when trying to set the SDL vidmode. Does this mean the SDL libraries shipped with Caanoo firmware do not have OpenGL support?

I think you have to use the unofficial SDL libraries to enable opengl the way you described -> http://dl.openhandhelds.org/cgi-bin/caanoo.cgi?0,0,0,0,19,521
then you can make a call like:
SDL_SetVideoMode(800, 480, 16, SDL_OPENGLES)

Alternatively you can use EGL with the normal SDL libs, heres some information on how to do it for pandora (I guess it translates well to caanoo): http://pandorawiki.org/Combining_OpenGL_ES_1.1_and_SDL_to_create_a_window_on_the_Pandora
 
Last edited by a moderator:
badmonkeyfinger said:
Patches said:
SDL is nice and portable, but I'm having trouble using SDL with OpenGL(ES) on Caanoo. I keep getting "OpenGL not available" errors when trying to set the SDL vidmode. Does this mean the SDL libraries shipped with Caanoo firmware do not have OpenGL support?

I think you have to use the unofficial SDL libraries to enable opengl the way you described -> http://dl.openhandhelds.org/cgi-bin/caanoo.cgi?0,0,0,0,19,521
then you can make a call like:
SDL_SetVideoMode(800, 480, 16, SDL_OPENGLES)

It's starting to look like a custom SDL lib is my only solution. I've confirmed that the stock Caanoo SDL libs don't have OpenGL support at all.

badmonkeyfinger said:
Alternatively you can use EGL with the normal SDL libs, heres some information on how to do it for pandora (I guess it translates well to caanoo): http://pandorawiki.org/Combining_OpenGL_ES_1.1_and_SDL_to_create_a_window_on_the_Pandora

I had already been looking into EGL as a solution to get a usable OpenGL|ES context, but without luck. eglGetDisplay(EGL_DEFAULT_DISPLAY) returns EGL_NO_DISPLAY. This Pandora stuff looks a lot like what I've got, but uses Xlib, which doesn't seem to be on Caanoo at all!

EDIT: I've managed to get EGL rendering correctly now. I'm not sure what the problem was, but I suspect it was something to do with glib ...
 
Last edited by a moderator:
I've documented the steps needed to get SDL + OpenGL|ES + EGL behaving together on Caanoo (it's probably the same on all GPH devices). The order of the steps is important. The earlier issue I had was because I did the SDL and EGL stuff in the wrong order.

http://code.google.com/p/cantuna/wiki/OpenglOnCaanoo

With this method, SDL's input subsystem still works :)
 
Another alternative is the Ikari SDL lib which has EGL support built in, so you can take a more natural SDL approach without all the EGL/SDL hacking.
 
Pickle said:
Another alternative is the Ikari SDL lib which has EGL support built in, so you can take a more natural SDL approach without all the EGL/SDL hacking.
I'd need some documentation or a code example on what exactly to do there. Although, right now, I have a system that works, and doesn't require a hacked/non-standard version of SDL :)
 
Last edited by a moderator:
Patches said:
Pickle said:
Another alternative is the Ikari SDL lib which has EGL support built in, so you can take a more natural SDL approach without all the EGL/SDL hacking.
I'd need some documentation or a code example on what exactly to do there. Although, right now, I have a system that works, and doesn't require a hacked/non-standard version of SDL :)

Theres a readme included will all the needed info, but its basically the standard SDL opengl API.
 
Last edited by a moderator:
Patches said:
I've documented the steps needed to get SDL + OpenGL|ES + EGL behaving together on Caanoo (it's probably the same on all GPH devices). The order of the steps is important. The earlier issue I had was because I did the SDL and EGL stuff in the wrong order.

http://code.google.com/p/cantuna/wiki/OpenglOnCaanoo

With this method, SDL's input subsystem still works :)
Thanks for sharing this, I had temporarily given up on EGL
 
Last edited by a moderator:
badmonkeyfinger said:
Patches said:
I've documented the steps needed to get SDL + OpenGL|ES + EGL behaving together on Caanoo (it's probably the same on all GPH devices). The order of the steps is important. The earlier issue I had was because I did the SDL and EGL stuff in the wrong order.

http://code.google.com/p/cantuna/wiki/OpenglOnCaanoo

With this method, SDL's input subsystem still works :)
Thanks for sharing this, I had temporarily given up on EGL

Glad you found it useful :) Now I just need someone to check whether any changes are needed for Wiz or F200/F100.
 
Last edited by a moderator:
Patches said:
Glad you found it useful :) Now I just need someone to check whether any changes are needed for Wiz or F200/F100.

any code used should be fine on the either the caanoo or wiz (unless you rotate the screen which doesnt make sense for the caanoo)
F100 and F200 are software render only, so not really sure why you mentioned those.
 
Last edited by a moderator:
Pickle said:
Patches said:
Glad you found it useful :) Now I just need someone to check whether any changes are needed for Wiz or F200/F100.

any code used should be fine on the either the caanoo or wiz (unless you rotate the screen which doesnt make sense for the caanoo)
F100 and F200 are software render only, so not really sure why you mentioned those.

Because I've been spending all my time and energy trying to make gstreamer libs from GPH SDK work instead of learning about hardware I don't have :)
 
Last edited by a moderator:
Back
Top