Reputation: 67
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...
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
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