planteater
planteater

Reputation: 67

Low fps when rendering 146.735 squares (2x2) in sdl2?

I build a printer for one dimensional cellular automata, for which I use SDL_RenderFillRect()/ SDL_RenderFillRects() to print the cells. The view allows certain zoom levels for a rule, the lowest zoom level (width of a square) will render 146.735 squares for Rule 30 (see screenshot), with each square having a dimension of 2x2 px (total px: 586.940 ).

However, the fps are not what I expected...

(Rule 30 at pixeldim 2x2) Rule 30 at pixeldim 2x2

I first used SDL_RenderFillRect() in a loop which resulted in the following fps

Rendering Rule 30 using SDL_RenderFillRect():

Zoom fps
10 59
9 59
8 59
7 59
6 59
5 55
4 36
3 19
2 9

I then handed the data to SDL_RenderFillRects() which resulted in the following fps

Rendering Rule 30 using SDL_RenderFillRects():

Zoom fps
10 59
9 59
8 59
7 59
6 59
5 59
4 59
3 59
2 45

That is way better but I still don't understand how a simple task like that drops to anything below 60 on a modern office computer ??

My question is: Is SDL_RenderFillRect()/ SDL_RenderFillRects() not the right thing for this usecase ? What would be a more efficient approach ?

Renderer (uses vsync and hardware acceleration)

...
pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
...

Using the Renderer for Table 1

    // Render only the zoomed contents
    for (int i = 0; i < iZoomedCells; i++) {
        if (sCellMap[i].bActive) {
            SDL_RenderFillRect(pRenderer, &sCellMap[i].rCell);
        }
    }

Using the Renderer for Table 2

SDL_RenderFillRects(pRenderer, sCellRects, iZoomedCells);

Anything black is background and not a call to RenderFillRect(). Also: the more black space a rule has the higher the fps are.

Upvotes: 3

Views: 318

Answers (1)

planteater
planteater

Reputation: 67

UPDATE:

My current solution boils down to this:

(After a new ruleset is choosen)

// Flush the old surface and texture

SDL_FillRect(pSurfaceMap, NULL, 0x000000);
SDL_DestroyTexture(pTextureMap);

// Draw determined rects of this rule to a surface

SDL_FillRects(pSurfaceMap, sCellRects, iCountRectsRendered, SDL_MapRGBA(pSurfaceMap->format, cDarkYellow.r, cDarkYellow.g, cDarkYellow.b, cDarkYellow.a));

// Create a texture from the surface

pTextureMap = SDL_CreateTextureFromSurface(pRenderer, pSurfaceMap);

(In the FrameDrawingFunction)

SDL_RenderCopy(pRenderer, pTextureMap, NULL, NULL);

That approach will lead to stable 59 fps vsynced and 700+ fps unsynced. That is already more like what I expected a simple rendering task's workload should cause.

Upvotes: -1

Related Questions