Question about choice of graphics library/code optimisation for low-end systems.

I have a question about choice of library to be used on low-end systems.

I've so far been using SDL to create a user interface for a media system, and it's been working fantastically on my development machine, a dual core 2GHz machine with 2Gb RAM and an Intel graphics card. I get a frame rate of up to 100fps, and there is no slowdown at all. However when I run the exact same program on an embedded motherboard, the VIA EPIA EN15000G, which has a 1.5GHz processor, and a VIA P4M800 graphics chip (possibly the worst graphics chip ever invented as far as Linux support goes), I get a frame rate of less than 5fps. This makes the entire program totally unusable, and I've been left in a bit of a pickle. I've looked into alternatives like SFML, but that looks like it won't help at all on an unaccelerated system. I've also tried using OpenChrome drivers on it, and that made a negligible or nonexistent difference.

Can anybody suggest anything I could look into re: optimising my code or changing libraries goes? I already use SDL_DisplayFormatAlpha to convert my surfaces to the correct format. I haven't looked into Dirty Rectangles yet massively, as there's not much movement at all on the GUI, just the changing of button states.

Would use of OpenGL help at all if using the OpenChrome driver, which apparently has 2D acceleration? I'm more than willing to totally overhaul the code if needs be.

Any help at all would be appreciated massively, as I'm a bit stumped, and floundering a little!

X-T
There is usually no single "use this instead of this to make everything 10 times faster" switch - if you want to optimize, start out with the obvious stuff - do you have unnecessary iterations in your loops that you could optimize out, do you have unnecessary variables, do you allocate unnecessarily large chunks of memory etc...
Last edited on
Haha, yeah I'd have guessed that it wasn't likely that it'd be one thing that I was doing which caused it. To be honest, I'm fairly new to C++ and generally low level programming.

I do quite a lot of iteration through arrays of SDL_Surfaces to work out what needs to be updated on the screen and then updating it. I'll look into possibly changing my thinking on how I deal with that.

I'll take those points and make good use of them to start with :-) Thanks, mate!

X-T
Right, I've investigated the problem further, and have removed literally EVERYTHING from my project.

My main event loop now reads as follows:

(fps = custom timer class to measure SDL_GetTicks between the start and end of each frame)

bool done = false;
while (!done)
{
// Start Frame Counter
fps.start();
SDL_Flip(screen);

// Frame rate Counter
cout << "" << 1000 / FRAMES_PER_SECOND << " : " << 1000 / fps.getTicks() << endl;
if(fps.getTicks() < 1000 / FRAMES_PER_SECOND)
{
SDL_Delay((1000/FRAMES_PER_SECOND) - fps.getTicks());
}
fps.stop();
} // End main loop

Surely, this should be running at an insanely fast speed, given that it's not doing ANYTHING. It also looks like I screwed up my frame speed in my first post. the 100 was ms/frame, not FPS. The FPS is anything between 6 and 40.

Anybody have any ideas why this is producing such an incredibly low frame rate? I've heard of people getting frame rates in the hundreds, if not thousands with far lower spec machines than mine. It's a little worrying.

Anyway, thanks in advance for any help people!!

X-T
Last edited on
Uh... doesn't SDL_delay interrupt the execution of your program? It's no wonder your program runs slow if you stop it all the time :O
That code is there to limit the FPS to a variable FRAMES_PER_SECOND. Sorry, should have posted that too. I've set it to 150, to find the maximum I could manage. SDL_Delay does halt the execution, but only if the frame processes faster than 1000ms/FRAMES_PER_SECOND, which in this case would be 6. The loop takes more than that to process, so the conditional will never be triggered.

I've tested this theory with the Code::Blocks default SDL project, and done nothing but print the frames per second at the end of the loop. I got very similar FPS as I did in my own project (maybe 5-10fps difference). This is leading me to believe that SDL is actually horribly slow, and my code is fine. I'll post the code for this at the end to show how non-processor-intensive this should be.

Any ideas, anybody? I'm starting to lose faith in how awesome SDL seemed :-(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif
#ifdef __APPLE__
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif
#include "timer.h"
#include <iostream>
using namespace std;
int ticks = 0;

int main ( int argc, char** argv )
{
    // initialize SDL video
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        return 1;
    }

    // make sure SDL cleans up before exit
    atexit(SDL_Quit);

    // create a new window
    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16,
                                           SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !screen )
    {
        printf("Unable to set 640x480 video: %s\n", SDL_GetError());
        return 1;
    }

    // load an image
    SDL_Surface* bmp = SDL_LoadBMP("cb.bmp");
    if (!bmp)
    {
        printf("Unable to load bitmap: %s\n", SDL_GetError());
        return 1;
    }

    // centre the bitmap on screen
    SDL_Rect dstrect;
    dstrect.x = (screen->w - bmp->w) / 2;
    dstrect.y = (screen->h - bmp->h) / 2;

    // program main loop
    bool done = false;
    while (!done)
    {
        ticks = SDL_GetTicks();
        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                done = true;
                break;

                // check for keypresses
            case SDL_KEYDOWN:
                {
                    // exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                }
            } // end switch
        } // end of message processing

        // DRAWING STARTS HERE

        // clear screen
        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));

        // draw bitmap
        SDL_BlitSurface(bmp, 0, screen, &dstrect);

        // DRAWING ENDS HERE

        // finally, update the screen :)
        SDL_Flip(screen);

        cout << 1000 / (SDL_GetTicks() - ticks) << endl;

        SDL_Delay(5);

    } // end main loop

    // free loaded bitmap
    SDL_FreeSurface(bmp);

    // all is well ;)
    printf("Exited cleanly\n");
    return 0;
}

Last edited on
Topic archived. No new replies allowed.