18.9 C
New York
Friday, September 12, 2025

Downside with SDL2 optimization (tree construction)


whereas I used to be attempting to optimize SDL2 rendering part as a lot as potential, I reached a wall. I attempted to look on the web however I couldn’t discover any answer. So, I need assistance.

Let me clarify the issue. I’ll use pseudo-code for code examples since this downside shouldn’t be language-dependent.

Lets say we’ve got a fundamental program that follows a tree construction like the next:

Fundamental Handler
   Element A0
      Element A1
         ...
   Element B0
      Element B1
         ...
   ...

Tree constructions like these are actually good for code modularity since, when adjustments are wanted, I can simply swap parts as an alternative of fixing all the code.

Due to this fact, to render parts, I’ve the next interface:

INTERFACE Renderer
   Render( /* SDL renderer */ ) -> error

And so, the primary physique can simply do the next:

PROGRAM fundamental() -> void
   MyApp <- new MyApp()
   
   renderer <- /* setup */

   WHILE TRUE DO:
      /* Deal with Occasions */

      err <- MyApp.Render(renderer)
      IF err THEN:
         PRINT err
         BREAK
      
      WAIT /* delay (ms) */

The issue is that, when rendering, the primary physique has to traverse this big tree for every body; thus, slowing all the rendering part.

To resolve this, I up to date the Renderer interface to incorporate a perform that stories whether or not the part has modified for the reason that final rendering step. If it did, render it, in any other case skip it.

INTERFACE Renderer
   IsChanged() -> bool
   Render( /* SDL renderer */ ) -> error

At first, this sped the rendering part since now it may possibly skip parts that don’t change or are pointless to attract each body.

Nonetheless, this strategy brought about one other subject since, at each body, not solely the primary execution has to traverse this tree one time to verify if any part has modified, however when adjustments happen, the execution has to stroll up the tree till the foundation after which render every thing.

Nevertheless, this created a brand new downside: At each body, not solely the engine should traverse this tree one time to verify whether it is modified, but when it did, it has to stroll again to the foundation and render every thing.

Particularly on parts like this one:

STRUCT ButtonTable IMPLEMENTS Renderer
   Checklist buttons

   IsChanged() -> bool
      /* verify if this has modified */

      /* verify if any subcomponent has modified */
      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 so as to add multi-threading to hurry up processes however often issues get rendered in a unsuitable order (one part earlier than one other one).

Any concepts on tips on how to repair this?

EDIT: Whereas ready for somebody to reply me, I acquired an answer.

We are able to linearize all parts in an array after which, name the Render methodology on them, this removes the tree construction.

pool cmps = {A, B, C, ...}

FOR EACH cmp IN cmps DO:
   IF cmp.IsChanged() THEN: cmp.Render()

In fact, it’s potential so as to add an observer sample to the parts to sign change

STRUCT ButtonTable
   /* fields */

   Checklist observers

   Connect()
   Sign()
   ...

Nevertheless, there are nonetheless few points that I’ve to deal with.

For the reason that render part happens each infrequently, if the rendering part causes different “youngsters” parts to alter, thay might be rendered two occasions; thus, wasting your cycles.

Additionally, how is it potential to create an API that provides an phantasm of a tree-like construction when in actuality is that this pool-observer sample?

Like, earlier than we might do

new MyComponent( /* sub parts */)

however with the brand new construction we’ve got to do the next:

mc <- new MyComponent()

mc.Connect( /* sub parts */ )
main_program.Add( /* sub parts */)
```

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles