英文:
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...
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 use case? 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 the background and not a call to RenderFillRect(). Also: the more black space a rule has, the higher the fps are.
英文:
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.
答案1
得分: -1
UPDATE:
我的当前解决方案可以归结为以下内容:
(在选择新的规则集之后)
// 清除旧的表面和纹理
SDL_FillRect(pSurfaceMap, NULL, 0x000000);
SDL_DestroyTexture(pTextureMap);
// 将此规则的确定矩形绘制到表面上
SDL_FillRects(pSurfaceMap, sCellRects, iCountRectsRendered, SDL_MapRGBA(pSurfaceMap->format, cDarkYellow.r, cDarkYellow.g, cDarkYellow.b, cDarkYellow.a));
// 从表面创建纹理
pTextureMap = SDL_CreateTextureFromSurface(pRenderer, pSurfaceMap);
(在FrameDrawingFunction中)
SDL_RenderCopy(pRenderer, pTextureMap, NULL, NULL);
这种方法将导致稳定的59帧每秒的垂直同步(vsync),以及700多帧每秒的非同步。这已经更符合我对简单渲染任务工作负荷的期望了。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论