Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Maemo: Developers
SDL, tearing, X overhead and direct framebuffer gfx
 

Index | Next | Previous | View Flat


tobias.oberstein at gmail

Feb 17, 2008, 11:56 AM


Views: 5840
Permalink
SDL, tearing, X overhead and direct framebuffer gfx

Hello tableteers,

I've done some initial experiments hacking my N800/OS2008 and ran into a
couple of issues:

When using the supplied SDL library for doing timer-based frame
rendering, there seems to be

- heavy tearing
- significant overhead due to X server
(rendering pipe is : SDL -> X -> Framebuffer)

[.Note: yes, I'm aware that doing full screen blits is evil on the N800
due to limited framebuffer -> video RAM bus bandwidth.]

Q: Is this expected behaviour? What could I do about the tearing? What
about the Xomap overhead?

==

I've read a lot of bits on the web 'bout mplayer, vsync, omapfb etc.
and tried to assemble a minimal example of using direct framebuffer
access for gfx output.

Q: I can't get the tearing away (only fixed at certain line positions).
What am I doing wrong?

Q: Also, frame rate is sluggish, though CPU load is much lower than
SDL/X. Ok, my FB example is not threaded like the SDL timer example ..
is that the reason for framerate even < 15/s?

Q: btw - how can I shutdown Maemo Launcher/Hildon/Matchbox/Xomap?
Whenever I do one of

/etc/init.d/maemo-launcher stop
/etc/init.d/x-server stop

the device will automatically reboot.

==

I wondered if there would be any plans to make SDL run directly on
framebuffer .. if not, I'd maybe give it a try.

Q: Where can I find the sources to the OS2008 SDL?

Thx and cheers,

tgo

=========================================
SDL Test

===> Makefile:

##
## produce ARM11 target optimized code
## use hardware FP, but use soft FP ABI for math lib
##
OPT_FLAGS = -O3 -fomit-frame-pointer -mcpu=arm1136j-s -mfpu=vfp
-mfloat-abi=softfp

##
## SDL compile/link flags
##
SDL_FLAGS = `sdl-config --cflags` `sdl-config --libs`

##
## compiler command
##
CC = gcc -Wall $(OPT_FLAGS) $(SDL_FLAGS)


all: sdl_timer

sdl_timer: sdl_timer.c
$(CC) sdl_timer.c -o sdl_timer

===> Source:

//
// minimal timer based SDL fullscreen test for N800
//
// the test seems to indicate 2 problems:
//
// 1) heavy tearing
// 2) significant overhead due to X server (rendering pipe is : SDL ->
X -> Framebuffer)
//

/*

Mem: 90376K used, 36452K free, 0K shrd, 716K buff, 42956K cached
Load average: 1.01 0.64 0.44
PID USER STATUS VSZ PPID %CPU %MEM COMMAND
756 root SW< 11368 338 21.8 8.9 Xomap
1831 root SW 12532 1365 7.3 9.8 sdl_timer
1815 root RW 1960 1799 3.0 1.5 top
78 root SW< 0 6 2.7 0.0 OMAP McSPI/0
1032 user SW< 32052 957 2.1 25.2 maemo-launcher
376 root SW< 0 6 1.6 0.0 cx3110x
...

*/


#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "SDL.h"

#define HRES 800
#define VRES 480
#define BPP 16


//
// frame render callback
//
Uint32 renderFrame (Uint32 interval, void *param)
{
static int col = 0;

// get screen surface from parameter
SDL_Surface *screen = (SDL_Surface*) param;

// lock surface if needed
if (SDL_MUSTLOCK(screen))
{
if (SDL_LockSurface(screen) < 0)
{
fprintf (stderr, "unable to lock surface\n");
exit(1);
}
}

// "render" whole frame in single color
memset(screen->pixels, ++col, HRES * BPP / 8 * VRES);

// unlock surface if needed
if (SDL_MUSTLOCK(screen))
{
SDL_UnlockSurface(screen);
}

// update whole screen
SDL_UpdateRect(screen, 0, 0, HRES, VRES);

// continue firing
return interval;
}


int main (int argc, char** argv)
{
// initialize SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
{
fprintf (stderr, "unable to initialize SDL : %s\n", SDL_GetError());
exit(1);
}

// register SDL cleanup
atexit (SDL_Quit);

// set mouse pointer invisible
SDL_ShowCursor (SDL_DISABLE);

// set video mode to fullscreen
SDL_Surface *screen = SDL_SetVideoMode(HRES, VRES, BPP, SDL_SWSURFACE
| SDL_FULLSCREEN);

if (screen == NULL)
{
fprintf (stderr, "unable to initialize video : %s\n", SDL_GetError());
exit(1);
}

// setup frame renderer at rate 17 frames/s (every 60ms)
SDL_TimerID tid = SDL_AddTimer (60,
(SDL_NewTimerCallback) renderFrame,
screen);

// run for 60 secs
sleep (60);


// shutdown frame renderer
SDL_bool ret = SDL_RemoveTimer (tid);

if (!ret)
{
fprintf (stderr, "could not shutdown timer : %s\n", SDL_GetError());
exit(1);
}

// finished
return 0;
}
===



=========================================
Framebuffer Test

===> Makefile:

##
## produce ARM11 target optimized code
## use hardware FP, but use soft FP ABI for math lib
##
OPT_FLAGS = -O3 -fomit-frame-pointer -mcpu=arm1136j-s -mfpu=vfp
-mfloat-abi=softfp

##
## compiler command
##
CC = gcc -Wall $(OPT_FLAGS) -lX11


all: fb_minimal

fb_minimal: fb_minimal.c
$(CC) fb_minimal.c -o fb_minimal

===> Source:

//////////////////////////////////////////////////////////////////////////
//
// Test for direct framebuffer graphics bypassing X. (tested on N800)
//
//////////////////////////////////////////////////////////////////////////


/*


Mem: 89132K used, 37696K free, 0K shrd, 716K buff, 42116K cached
Load average: 0.80 0.25 0.18
PID USER STATUS VSZ PPID %CPU %MEM COMMAND
1686 root RW 3124 1685 6.1 2.4 fb_minimal
1032 user SW< 32052 957 2.2 25.2 maemo-launcher
1687 root RW 1960 1365 2.1 1.5 top
756 root SW< 10492 338 1.1 8.2 Xomap
78 root SW< 0 6 0.9 0.0 OMAP McSPI/0
376 root SW< 0 6 0.3 0.0 cx3110x
346 root SW 776 338 0.1 0.6 bme_RX-34
987 user SW< 27532 957 0.0 21.6 maemo-launcher
...


Nokia-N800-50-2:/home/oberstet# time ./fb_minimal
real 1m 48.01s
user 0m 6.31s
sys 0m 0.33s
Nokia-N800-50-2:/home/oberstet#


*/



#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm-arm/arch-omap/omapfb.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

//
/scratchbox/compilers/cs2005q3.2-glibc2.5-arm/usr/include/asm-arm/arch-omap/omapfb.h
//
/scratchbox/compilers/cs2005q3.2-glibc2.5-arm/arm-none-linux-gnueabi/sys-include/asm-arm/arch-omap/omapfb.h


#define HRES 800
#define VRES 480
#define BPP 16
#define LOOPN 1000

#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400


int main (int argc, char** argv)
{


//////////////////////////////////////////////////////////////////////////
//
// setup X stuff (we pull up a "pseudo X window" in fullscreen, so our
// framebuffer graphics will not be overwritten by X server - otherwise
// we had to shutdown X server).
//

//////////////////////////////////////////////////////////////////////////

// setup display, screen and window
Display *display = XOpenDisplay (getenv ("DISPLAY"));
if (display == NULL)
{
fprintf (stderr, "cannot open X display\n");
exit (1);
}

int screen_num = DefaultScreen (display);

Window win = XCreateSimpleWindow(display,
RootWindow (display, screen_num),
0,
0,
720,
420,
0,
WhitePixel (display, screen_num),
BlackPixel (display, screen_num));

XMapWindow (display, win);
XSelectInput (display, win, ExposureMask);
XFlush (display);

XEvent xev;
XWindowEvent (display, win, ExposureMask, &xev);

// bring window to fullscreen
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.message_type = XInternAtom (display, "_NET_WM_STATE", False);
xev.xclient.window = win;
xev.xclient.format = 32;
xev.xclient.data.l[0] = 1;
xev.xclient.data.l[1] = XInternAtom (display,
"_NET_WM_STATE_FULLSCREEN", False);
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;

if (!XSendEvent (display,
DefaultRootWindow (display),
False,
SubstructureRedirectMask | SubstructureNotifyMask,
&xev))
{
fprintf (stderr, "cannot bring X window to fullscreen\n");
exit (1);
}
XSync(display, False);



//////////////////////////////////////////////////////////////////////////
//
// setup framebuffer stuff
//

//////////////////////////////////////////////////////////////////////////

// open framebuffer device
int fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd)
{
fprintf (stderr, "cannot open framebuffer device\n");
exit (1);
}


// screen size
size_t ssize = HRES * BPP / 8 * VRES;


// map framebuffer
char* fbp = (char*) mmap (0, ssize, PROT_READ | PROT_WRITE,
MAP_SHARED, fbfd, 0);
if ((int) fbp == -1)
{
fprintf (stderr, "failed to memory map framebuffer\n");
exit (1);
}

// setup fullscreen update info struct
struct omapfb_update_window update;

// copy full screen from fb to lcd video ram
update.x = 0;
update.y = 0;
update.width = HRES;
update.height = VRES;

// request native pixel format, tearsync and vsync
update.format = OMAPFB_COLOR_RGB565 | OMAPFB_FORMAT_FLAG_TEARSYNC |
OMAPFB_FORMAT_FLAG_FORCE_VSYNC;



//////////////////////////////////////////////////////////////////////////
//
// render loop
//

//////////////////////////////////////////////////////////////////////////

int n;

for (n = 0; n < LOOPN; ++n)
{
// wait for fb->lcd video ram transfer complete
ioctl (fbfd, OMAPFB_SYNC_GFX);

// "render" whole frame in single color
memset (fbp, n, ssize);

// wait for vsync
ioctl (fbfd, OMAPFB_VSYNC);

// request transfer of fb-> lcd video ram for whole screen
ioctl (fbfd, OMAPFB_UPDATE_WINDOW, &update);
}



//////////////////////////////////////////////////////////////////////////
//
// cleanup
//

//////////////////////////////////////////////////////////////////////////

// cleanup framebuffer stuff
munmap (fbp, ssize);
close (fbfd);

// cleanup X stuff
if (display)
{
XCloseDisplay (display);
display = NULL;
}

// finished
return 0;
}

===


_______________________________________________
maemo-developers mailing list
maemo-developers[at]maemo.org
https://lists.maemo.org/mailman/listinfo/maemo-developers

Subject User Time
SDL, tearing, X overhead and direct framebuffer gfx tobias.oberstein at gmail Feb 17, 2008, 11:56 AM
    Re: SDL, tearing, X overhead and direct framebuffer gfx mflaig at pro-linux Feb 17, 2008, 1:50 PM
        Re: SDL, tearing, X overhead and direct framebuffer gfx dufkaf at seznam Feb 17, 2008, 2:12 PM
            Re: SDL, tearing, X overhead and direct framebuffer gfx tobias.oberstein at gmail Feb 17, 2008, 4:06 PM
        Re: SDL, tearing, X overhead and direct framebuffer gfx tobias.oberstein at gmail Feb 17, 2008, 4:07 PM
    Re: SDL, tearing, X overhead and direct framebuffer gfx tapani.palli at nokia Feb 17, 2008, 11:39 PM
        Re: SDL, tearing, X overhead and direct framebuffer gfx dufkaf at seznam Feb 18, 2008, 1:31 AM
        Re: SDL, tearing, X overhead and direct framebuffer gfx siarhei.siamashka at gmail Feb 18, 2008, 3:23 AM
    Re: SDL, tearing, X overhead and direct framebuffer gfx siarhei.siamashka at gmail Feb 18, 2008, 1:40 AM
    Re: SDL, tearing, X overhead and direct framebuffer gfx dufkaf at seznam Feb 18, 2008, 1:51 AM
    Re: SDL, tearing, X overhead and direct framebuffer gfx eero.tamminen at nokia Feb 18, 2008, 2:11 AM
        RE: SDL, tearing, X overhead and direct framebuffer gfx josh.soref at nokia Feb 18, 2008, 2:15 AM
    Re: SDL, tearing, X overhead and direct framebuffer gfx tapani.palli at nokia Feb 18, 2008, 3:28 AM
        Re: SDL, tearing, X overhead and direct framebuffer gfx siarhei.siamashka at gmail Feb 18, 2008, 3:50 AM
    Re: SDL, tearing, X overhead and direct framebuffer gfx dufkaf at seznam Feb 18, 2008, 4:18 AM
    Re: SDL, tearing, X overhead and direct framebuffer gfx tapani.palli at nokia Feb 18, 2008, 4:30 AM

  Index | Next | Previous | View Flat
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.