-
-
Notifications
You must be signed in to change notification settings - Fork 11.4k
Description
This is not a real issue but something I would like to discuss and double-check with the imgui developers and users.
Proposition to discuss
Here the modification I made to the SDL/opengl3 example. The purpose is to let the demo application wait on event and stop using the CPU.
diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp
index 804190ea..51e74b9c 100644
--- a/examples/example_sdl_opengl3/main.cpp
+++ b/examples/example_sdl_opengl3/main.cpp
@@ -40,6 +40,14 @@ using namespace gl;
#include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#endif
+static void process_event(SDL_Event *event, bool& done, Uint32 window_id) {
+ ImGui_ImplSDL2_ProcessEvent(event);
+ if (event->type == SDL_QUIT)
+ done = true;
+ if (event->type == SDL_WINDOWEVENT && event->window.event == SDL_WINDOWEVENT_CLOSE && event->window.windowID == window_id)
+ done = true;
+}
+
// Main code
int main(int, char**)
{
@@ -145,6 +153,8 @@ int main(int, char**)
// Main loop
bool done = false;
+ int idle_frames = 0;
+ const int config_fps = -1000; // could be 60 to run at 60 FPS. If negative wait indefinitely.
while (!done)
{
// Poll and handle events (inputs, window resize, etc.)
@@ -153,14 +163,24 @@ int main(int, char**)
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
SDL_Event event;
- while (SDL_PollEvent(&event))
- {
- ImGui_ImplSDL2_ProcessEvent(&event);
- if (event.type == SDL_QUIT)
- done = true;
- if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
- done = true;
+ Uint32 window_id = SDL_GetWindowID(window);
+ if (idle_frames >= 5) {
+ if (SDL_WaitEventTimeout(&event, 1000 / config_fps)) {
+ process_event(&event, done, window_id);
+ while (SDL_PollEvent(&event))
+ {
+ process_event(&event, done, window_id);
+ }
+ idle_frames = 0;
+ }
+ } else {
+ while (SDL_PollEvent(&event))
+ {
+ idle_frames = 0;
+ process_event(&event, done, window_id);
+ }
}
+ idle_frames++;
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();Context / SDL2 issue
I am the author of a patch of the SDL2 library with the purpose to reduce CPU usage to zero when waiting for an incoming event. Here the PR (not accepted neither refused up to now):
The patch is meant for desktop applications that use SDL2. The SDL2 library internally continuously polls for events even when WaitEvent or WaitEventTimeout is used. This cause continuous CPU usage even when a desktop applications is idle waiting for incoming events. My patch fix this so that the functions WaitEvent/WaitEventTimeout actually wait for events instead of polling.
I am successfully using the modified SDL library for my applications lite-xl
Discussion
You may notice that I use a variable idle_frames to check for how many frames the applications was running idle without events. The idea is that when an event arrives we want to let the application process at least a few frames before blocking the application waiting for events.
I found empirically the imgui needs a few frames to make some transitions in the UI but I would appreciate to have a confirmation if I am correct or not.
If the variable config_fps is set to -1000 it waits indefinitely for events. To run at a fixed FPS the value should be set to the desired FPS value but no attempt is made to account for the elapsed time and correct the waiting time.
I am asking to @ocornut and other imgui users or contributors is they can validated the correctness of the modified loop I am using.
I don't mean the modification should be included into the imgui library.