while I was trying to optimize SDL2 rendering phase as much as possible, I reached a wall. I tried to search on the internet but I could not find any solution. So, I need help.
Let me explain the problem. I will use pseudo-code for code examples since this problem is not language-dependent.
Let's imagine we have a main program that follows a tree structure like the following:
Main Handler Component A0 Component A1 ... Component B0 Component B1 ... ...
Tree structures like these are really good for code modularity since, when changes are needed, I can just swap components instead of changing the entire code.
Therefore, to render components, I have the following interface:
INTERFACE Renderer Render( /* SDL renderer */ ) -> error
And so, the main body can just do the following:
PROGRAM main() -> void MyApp <- new MyApp() renderer <- /* setup */ WHILE TRUE DO: /* Handle Events */ err <- MyApp.Render(renderer) IF err THEN: PRINT err BREAK WAIT /* delay (ms) */
The problem is that, when rendering, the main body has to traverse this huge tree for each frame; thus, slowing the entire rendering phase.
To solve this, I updated the Renderer interface to include a function that reports whether the component has changed since the last rendering step. If it did, render it, otherwise skip it.
INTERFACE Renderer IsChanged() -> bool Render( /* SDL renderer */ ) -> error
At first, this sped the rendering phase since now it can skip components that do not change or are unnecessary to draw every frame.
Still, this approach caused another issue since, at every frame, not only the main execution has to traverse this tree one time to check if any component has changed, but when changes occur, the execution has to walk up the tree until the root and then render everything.
However, this created a new problem: At every frame, not only the engine must traverse this tree one time to check if it is changed, but if it did, it has to walk back to the root and render everything.
Especially on components like this one:
STRUCT ButtonTable IMPLEMENTS Renderer List<Renderer> buttons IsChanged() -> bool /* check if this has changed */ /* check if any subcomponent has changed */ FOR EACH button IN this.buttons DO: IF button.IsChanged() THEN: RETURN TRUE RETURN FALSE Render( /* SDL renderer */ r) -> error /* render ButtonTable */ FOR EACH button IN this.buttons DO: err <- button.Render(r) IF err THEN: RETURN err RETURN NONE
I even tried to add multi-threading to speed up processes but occasionally things get rendered in a wrong order (one component before another one).
Any ideas on how to fix this?