Pop the geometry queue?/Optimize render with textures

I’m writing an IDE/text editor. Sometimes lines are long and need to wrap around but most of the time it doesn’t. Sometimes a person uses small font on a 4K screen causing my editor to render 50K letters and icons, but I still want to hit my target goal of 144 fps. I don’t want to be sloppy with my code and I didn’t see an optimization guide for “best practices” so I took a look at source

I see that when I call SDL_RenderTexture it’ll make its way into a geometry queue. I don’t suppose I can delete items I put on it? For example if “QueueGeometry” needs to wrap around I may want to delete previous letters until I reach a space. I’m guessing there’s no option to say delete the last X entries in the queue? Alternatively I could draw over the letters with the background color but I think that’s sloppy

Is my best option to put the letters into my own queue before I call SDL? I think so but how far do I want to take this? Line or whole text file/whole screen? I don’t think I saw a command that let me render many texture rects with one call? All the characters I draw are in one large texture and I render very few icons in a different texture but thats typically at the start of frame before I draw letters. There’s few texture switches. I do change color a lot for syntax highlighting. Instead of queuing just the line should I queue everything and send them down according to color? I don’t know if there’s a penalty for a color change. I target only desktop so I’m not concerned abut mobile gpus

Do you have any suggestions on what I should do to keep my framerate as high as possible?

The latest SDL_ttf code might be of interest. You can create TTF_Text objects, specifying a wrapping location and then query their layout. It’s not in yet, but I’m planning on adding an x/y offset within the wrapped text block so you can chain TTF_Text objects with different fonts and colors.

There’s currently a way to render them to surfaces, using the SDL 2D renderer, and coming soon, using the SDL GPU API.

FYI I was the one offering to do the ttf atlas code. I might implement kerning from the kern table but it looks harder to deal with gpos and harfbuzz even harder

Is there no performance penalty on switching color? I haven’t written a stress test to check I did a quick test, for my hardware it appears there’s no cost changing color.

Figuring out your text layout as you’re calling SDL_RenderTexture() is the wrong way to go. Layout your text at a higher level, then send it off to be drawn all at once.

SDL_Renderer does render batching, so doing many SDL_RenderTexture() calls with the same texture in a row will batch them into one big draw call that gets sent off to the GPU.

The nice thing about using actual UI toolkits that use the underlying OS UI stuff is that most of this kind of thing is handled for you, and some OSes have really nice text layout and rendering features. Take a look at wxWidgets or Qt, which are cross-platform UI APIs that wrap the actual OS UI stuff.

If you still want to use SDL instead, there’s always Dear ImGUI

SDL_ttf 3.0 also has improved text rendering (inspired by your atlas work), where you can create text objects and render them to a surface, or using the 2D rendering API, or the GPU API. It automatically handles texture atlas creation and batching for you.

2 Likes

Can you mix SDL 2.0 with SDL_ttf 3.0? For various reasons I cannot use SDL3 (including the lack of support for OpenGLES 1.1, which I need for glLogicOp) but SDL3_ttf sounds potentially very useful.

Great. I’m glad that code did something. I was a little disappointed knowing I didn’t finished it because I didn’t know if just using the kern table would be good enough (and I didn’t implement that because I didn’t receive a good answer from anyone).

I deleted my github but I still have my atlas code around if you want it. I may have to send it as a zip. It’s written for SDL3 but should be very easy to use SDL2 calls on it. My main project is written SDL2 (and is written in C++ instead of C)

Would you like to tell me which function draws them all at once :stuck_out_tongue:

I do all the rendering for the source files at once. There’s no texture switching so it appears to be batched and it is fast. I’m able to hit 144fps on a 4K screen with 12pt-ish font (I’m not sure if I made it smaller or bigger than it should be). I rather weaker hardware be able to hit 144fps as well. I don’t render every frame but I do when I want to measure/profile my code

It is the automatic line-wrapping mentioned by Sam that is of particular interest to me. Harfbuzz support is also essential. If SDL3_ttf does both of those, along with automatic atlas generation, it would be very handy in my application.

I meant just drawing them all in one go. But you can use SDL_RenderGeometry() or SDL_RenderGeometryRaw() to actually send off all your quads that use the same texture at once.

For the record, even the weak little Intel 630 GPU in my daily driver Mac Mini can handle rendering lots of little 2D quads.

FYI it appeared to be a little slower in the test I wrote SDL_RenderGeometry slower than SDL_RenderCopy?