Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use of glfwWaitEvents instead of glfwPollEvents in example leads to misdrawings #3220

Closed
JLMorange opened this issue May 10, 2020 · 5 comments

Comments

@JLMorange
Copy link

JLMorange commented May 10, 2020

(you may also go to Demo>About Window, and click "Config/Build Information" to obtain a bunch of detailed information that you can paste here)

Version/Branch of Dear ImGui:
Branch: master
glFW3/opengl2/gcc 7-5-0/linux

My Issue/Question:
in imgui/examples/example_glfw_opengl2/main.cpp if I perform the following changes :

diff --git a/examples/example_glfw_opengl2/main.cpp b/examples/example_glfw_opengl2/main.cpp
index a50b4637..f8b19ced 100644
--- a/examples/example_glfw_opengl2/main.cpp
+++ b/examples/example_glfw_opengl2/main.cpp
@@ -82,7 +82,8 @@ int main(int, char**)
         // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
         // - 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.
-        glfwPollEvents();
+        //glfwPollEvents();
+        glfwWaitEvents();
 
         // Start the Dear ImGui frame
         ImGui_ImplOpenGL2_NewFrame();

some widgets doesn't update correctly :

  • "Popups & Modal windows" -> "Popups" -> "Select..." => the popup only displays if the mouse if moved (seems to be the same for all popups windows)
  • drag and drop doesn't seems to work
@ocornut
Copy link
Owner

ocornut commented May 11, 2020

Hello,

Well, you are not refreshing your app and saying "my app isn't refreshing", that's expected? ;)

Preamble: I cannot repro, naively switching to glfwWaitEvents() under my Windows seems to have those two cases you mentioned working, but it quite depends on how GLFW is triggering events and it's not super sane to rely on that.

Assuming your intent is to implement a "power saving" mode,

  1. First of all make sure you understand that relying on vsync glfwSwapInterval(1) + glfwSwapBuffers() is generally an easy way to cap frame-rate to the natural monitor refresh rate.
    On my setup at 60 Hz it gives me <1% CPU use and 6% GPU use in most of the demo app. You may already know this but since you haven't specified much in your post I don't know.

  2. If you are already waiting on vsync and this is not enough for you in term of power mode, yes, you can instead wait on events and that's recommended, but take note that several interactions will naturally take more than a frame to settle.
    If you don't care about supporting animated elements (such as blinking cursor, or any form of visual change created by your application or which is the reflection of changing data) then you can indeed use glfwWaitEvents pattern, but after any keyboard/mouse inputs you will need to ensure that 2 or 3 frames are fully executed before reverting to full waiting.

Both #2749 and #3124 are full fledged attempt that adding standardized handling for this that would also support animation requests (such as blinking cursors). In particular #2749 is probably quite close to the ideal solution but haven't had time to review it.

@JLMorange
Copy link
Author

yes, that's my aim, I don't want to have anything recomputed if not needed, so my goal was

  1. have only drawings updated if there is input event (or if the program ask for a redraw by setting timer...)
  2. don't want to refresh relying on "natural monitor refresh rate" since it will consume power without need (I target embedded device as well, so power is critical if no refresh is really required)
  • you mention that some elements require several frames to be animated, one solution could be to have ImGui have a "state" getter so the event loop can know if it has to glfwPollEvents or glfwWaitEvents
  • this state could also include some time information, so why not an "imGui::Event" and a imGui::GetNextEvent() ? a widget that require animation could queue a event to the queue, and the main loop will have to check if there is events pending in the queue...
    one other option could be to use the c++11 threads... and have one thread to perform the animations... but not sure this will be well accepted and might cause contention issues, so better let the developer do the jobs... the imGui::Event can have a "mDueDate" field that could give user when in futur the event have to be performed, and a "mKind" field that at least can be "eRefresh"

@ocornut
Copy link
Owner

ocornut commented May 13, 2020

Hello, the linked thread are offering solutions similar to what you describe. As such, feel free to use them or experience with them, some of it being doable without modifying core dear imgui.

Right now none of them is unfortunately merged but down the line we'll have something like that in the library (no ETA).

@JLMorange
Copy link
Author

#2749 does fix this issue

@ocornut
Copy link
Owner

ocornut commented May 13, 2020

Good to hear!
I'll close this as duplicate of #2749 and hope we can look at it soon-ish.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants