top | item 46830432

(no title)

wasmperson | 1 month ago

Immediate mode UI doesn't require a powerful CPU and was invented in 2002, so about 24 years ago. I think the belief that it necessarily sacrifices performance is somewhat of a misconception.

Compare a hypothetical "Immediate Mode" counter:

  void render_and_handle_button_click(struct ctx *ctx){
      draw_text(ctx, "Count: %d", ctx->count);
      if(draw_button(ctx, "Increment")){
          ctx->count++;
      }
  }
To the equivalent "Retained" counter:

  void render(struct ctx *ctx){
     set_textbox_text(ctx->textbox, "Count: %d", ctx->count);
  }

  void handle_button_click(void *ctx_in){
     struct ctx *ctx = ctx_in;
     ctx->count++;
     render(ctx);
  }

  void init(struct ctx *ctx){
      ctx->textbox = create_textbox(ctx);
      ctx->button = create_button(ctx);
      set_button_text(ctx->button, "Increment");
      set_button_click_handler(ctx->button, ctx, handle_button_click);
      render(ctx);
  }
The only difference I see here is whether the stateful "cache" of UI components (ctx->textbox and ctx->button) is library-side or application-side.

discuss

order

theamk|1 month ago

You are looking at it from the user side, while all the interesting parts are on the implementation side:

- If you have partial redraw request, can you quickly locate _only_ the controls which are covered and only redraw those?

- If you are clicking on something, can you quickly locate which component will receive the click?

- If you are moving mouse, or dragging a selection, can you quickly determine if any components should change the state? Can you avoid running the full event loop on every mouse move event?

- If your application state has updated, do you need to force redraw or not? (Many immediate mode UIs fail badly here, never going to idle even if nothing is happening)

This is all trivial in the old-style UI - efficient redraw / mouse mapping is table stakes in the older GUIs. While all that immediate mode can do is to keep running redraw loop _every_ _single_ _time_ something as trivial as mouse move is happening, just in case this can change highlighted item or something.

(Unless the "immediate mode UI" is just a thin veneer, and library is using good-old OOP based GUI components under the hood... but in this case, it's still faster to cut out the middleman and control components yourself)

And yes, back when I was doing "game development" class in college, around that time, I've used the immediate mode UI for menus. This only makes sense - games run on foreground _anyway_, and they basically consume 100% of CPU anyway. But for regular apps? Please don't.

Example: I just opened https://www.egui.rs/#demo in background tab... The browser's task manager shows this tab never goes idle, consuming between 0.1% and 3%. Considering I often have 40+ tabs open, this can take a significant part of CPU.

Immediate mode GUIs, unless in app which already uses 100% CPU, like game or video player, will always be less efficient than classical event-driven ones.

wasmperson|1 month ago

You appear to be making assumptions about immediate mode UI limitations based on some implementations you've worked with and not based on what's actually dictated by the interface itself. You touch on this somewhat by claiming that it's possible to be fast as long as the UI is merely a "thin veneer" over something more stateful, but that isn't a distinction I care about.

I'm not a good advocate for IMGUI; there are resources available online which explain it better than I can. I'm just trying to point out that the claim that immediate mode GUIs are some sort of CPU hog isn't really true. That's what I meant by "doesn't necessarily sacrifice performance," not that there is literally zero overhead (although I wouldn't be surprised if that were the case!).

> ...The browser's task manager shows this tab never goes idle...

As far as I can tell, the demo you linked appears to be bugged. You can see from poking around in a profiler (and from the frame timer under the "backend" popout) that the UI code does in fact go idle, but the requestAnimationFrame loop is never disabled for some reason. Regardless, even if this particular GUI library has problems going idle, that's not an inherent problem with the paradigm. I get the impression you understand this already, so I'm not sure why you've brought it up.

kvemkon|1 month ago

> Many immediate mode UIs fail badly here, never going to idle even if nothing is happening

ImGui's author deliberately doesn't fix this because this is one of the main issues preventing ImGui to be widely adopted on desktop potentially attracting too many users at once but lacking support for all of them.

https://github.com/ocornut/imgui/issues/7892#issuecomment-22...