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

Power save mode. Allow user call RequestRedraw to redraw a new frame. #5140

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions backends/imgui_impl_glfw.cpp
Original file line number Diff line number Diff line change
@@ -638,6 +638,46 @@ void ImGui_ImplGlfw_NewFrame()
ImGui_ImplGlfw_UpdateGamepads();
}

void ImGui::RequestRedraw(ImGuiRedrawFlags flags)
{
#ifdef _WIN32
// Only implement ImGuiRedrawFlags_Everything logic
IM_ASSERT(flags == ImGuiRedrawFlags_Everything && "Other redraw mode has not been implemented yet.");
if (flags == ImGuiRedrawFlags_Everything)
{
// Post WM_PAINT messag for windows32 platform system to awake the
// glfwWaitEventsTimeout function
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
HWND win32_window = glfwGetWin32Window(bd->Window);
::RedrawWindow(win32_window, NULL, NULL, RDW_INTERNALPAINT);
}
#endif
//DODO implementation for Linux and Mac OS
}

bool ImGui::WaitAndPollEvents(int timeout/* = 0*/)
{
if (timeout > 0)
{
// This function puts the calling thread to sleep until at least one event is available in the event queue,
// or until the specified timeout is reached.If one or more events are available, it behaves exactly like
// glfwPollEvents, i.e.the events in the queue are processedand the function then returns immediately.
// Processing events will cause the windowand input callbacks associated with those events to be called.
glfwWaitEventsTimeout(timeout);
}
else if(timeout == 0)
{
glfwPollEvents();
}
else if (timeout == -1)
{
glfwWaitEvents();
glfwPollEvents();
}

return true;
}

#if defined(__clang__)
#pragma clang diagnostic pop
#endif
57 changes: 57 additions & 0 deletions backends/imgui_impl_win32.cpp
Original file line number Diff line number Diff line change
@@ -787,4 +787,61 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
}
}

void ImGui::RequestRedraw(ImGuiRedrawFlags flags /*reserved*/)
{
// flags logic in future
if (flags) {}
// Post WM_PAINT messag for windows32 platform system to awake WaitAndPollEvents()
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
HWND win32_window = bd->hWnd;
::RedrawWindow(win32_window, NULL, NULL, RDW_INTERNALPAINT);
}

bool ImGui::WaitAndPollEvents(int timeout/* = 0*/)
{
DWORD dw_timeout = 0;
if (timeout == -1)
{
dw_timeout = 4294967295; // MAX value of DWORD
}
else if (timeout > 0)
{
dw_timeout = (DWORD)(timeout * 1e3);
}

//// About mouse click on Windows system
//// Hex Decimal Symbolic
//// ------------------------------------------------------
//// left mouse click will trigger events of
//// 0201 513 WM_LBUTTONDOWN
//// 0202 514 WM_LBUTTONUP
//// 0200 512 WM_MOUSEFIRST / WM_MOUSEMOVE
//// right mouse click witll trigger events of
//// 0204 516 WM_RBUTTONDOWN
//// 0205 517 WM_RBUTTONUP
//// 0200 512 WM_MOUSEFIRST / WM_MOUSEMOVE
//// middle mouse click witll trigger events of
//// 0207 519 WM_MBUTTONDOWN
//// 0208 520 WM_MBUTTONUP
//// 0200 512 WM_MOUSEFIRST / WM_MOUSEMOVE
//// So any mouse click will result tree frames to be drawed, one on mouse down, two on mouse up


bool done = false;

MsgWaitForMultipleObjects(0, NULL, FALSE, dw_timeout, QS_ALLEVENTS);
// Poll and handle messages (inputs, window resize, etc.)
// See the WndProc() function below for our to dispatch events to the Win32 backend.
MSG msg;
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
if (msg.message == WM_QUIT)
done = true;
}

return !done;
}

//---------------------------------------------------------------------------------------------------------
9 changes: 8 additions & 1 deletion examples/example_glfw_opengl2/main.cpp
Original file line number Diff line number Diff line change
@@ -78,12 +78,19 @@ int main(int, char**)
// Main loop
while (!glfwWindowShouldClose(window))
{
// wait and poll event
// timeout:
// 0 process event immediatly, not blocking
// -1 wait for ever untill an event comes
// positive number wait untill timedout or event comes
// call ImGui::RequestRedraw to awake waiting of this function. Return 0 to signel a quict event.
int timeout = 0;
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
ImGui::WaitAndPollEvents(timeout);

// Start the Dear ImGui frame
ImGui_ImplOpenGL2_NewFrame();
10 changes: 9 additions & 1 deletion examples/example_glfw_opengl3/main.cpp
Original file line number Diff line number Diff line change
@@ -99,12 +99,20 @@ int main(int, char**)
// Main loop
while (!glfwWindowShouldClose(window))
{

// wait and poll event
// timeout:
// 0 process event immediatly, not blocking
// -1 wait for ever untill an event comes
// positive number wait untill timedout or event comes
// call ImGui::RequestRedraw to awake waiting of this function. Return 0 to signel a quict event.
int timeout = 0;
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
ImGui::WaitAndPollEvents(timeout);

// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
9 changes: 8 additions & 1 deletion examples/example_glfw_vulkan/main.cpp
Original file line number Diff line number Diff line change
@@ -465,12 +465,19 @@ int main(int, char**)
// Main loop
while (!glfwWindowShouldClose(window))
{
// wait and poll event
// timeout:
// 0 process event immediatly, not blocking
// -1 wait for ever untill an event comes
// positive number wait untill timedout or event comes
// call ImGui::RequestRedraw to awake waiting of this function. Return 0 to signel a quict event.
int timeout = 0;
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
ImGui::WaitAndPollEvents(timeout);

// Resize swap chain?
if (g_SwapChainRebuild)
19 changes: 9 additions & 10 deletions examples/example_win32_directx10/main.cpp
Original file line number Diff line number Diff line change
@@ -81,18 +81,17 @@ int main(int, char**)
bool done = false;
while (!done)
{
// Poll and handle messages (inputs, window resize, etc.)
// See the WndProc() function below for our to dispatch events to the Win32 backend.
MSG msg;
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
// wait and poll event
// timeout:
// 0 process event immediatly, not blocking
// -1 wait for ever untill an event comes
// positive number wait untill timedout or event comes
// call ImGui::RequestRedraw to awake waiting of this function. Return 0 to signel a quict event.
int timeout = 0;
if (!ImGui::WaitAndPollEvents(timeout))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
if (msg.message == WM_QUIT)
done = true;
done = true; break;
}
if (done)
break;

// Start the Dear ImGui frame
ImGui_ImplDX10_NewFrame();
19 changes: 9 additions & 10 deletions examples/example_win32_directx11/main.cpp
Original file line number Diff line number Diff line change
@@ -81,18 +81,17 @@ int main(int, char**)
bool done = false;
while (!done)
{
// Poll and handle messages (inputs, window resize, etc.)
// See the WndProc() function below for our to dispatch events to the Win32 backend.
MSG msg;
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
// wait and poll event
// timeout:
// 0 process event immediatly, not blocking
// -1 wait for ever untill an event comes
// positive number wait untill timedout or event comes
// call ImGui::RequestRedraw to awake waiting of this function. Return 0 to signel a quict event.
int timeout = 0;
if (!ImGui::WaitAndPollEvents(timeout))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
if (msg.message == WM_QUIT)
done = true;
done = true; break;
}
if (done)
break;

// Start the Dear ImGui frame
ImGui_ImplDX11_NewFrame();
19 changes: 9 additions & 10 deletions examples/example_win32_directx12/main.cpp
Original file line number Diff line number Diff line change
@@ -119,18 +119,17 @@ int main(int, char**)
bool done = false;
while (!done)
{
// Poll and handle messages (inputs, window resize, etc.)
// See the WndProc() function below for our to dispatch events to the Win32 backend.
MSG msg;
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
// wait and poll event
// timeout:
// 0 process event immediatly, not blocking
// -1 wait for ever untill an event comes
// positive number wait untill timedout or event comes
// call ImGui::RequestRedraw to awake waiting of this function. Return 0 to signel a quict event.
int timeout = 0;
if (!ImGui::WaitAndPollEvents(timeout))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
if (msg.message == WM_QUIT)
done = true;
done = true; break;
}
if (done)
break;

// Start the Dear ImGui frame
ImGui_ImplDX12_NewFrame();
19 changes: 9 additions & 10 deletions examples/example_win32_directx9/main.cpp
Original file line number Diff line number Diff line change
@@ -79,18 +79,17 @@ int main(int, char**)
bool done = false;
while (!done)
{
// Poll and handle messages (inputs, window resize, etc.)
// See the WndProc() function below for our to dispatch events to the Win32 backend.
MSG msg;
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
// wait and poll event
// timeout:
// 0 process event immediatly, not blocking
// -1 wait for ever untill an event comes
// positive number wait untill timedout or event comes
// call ImGui::RequestRedraw to awake waiting of this function. Return 0 to signel a quict event.
int timeout = 0;
if (!ImGui::WaitAndPollEvents(timeout))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
if (msg.message == WM_QUIT)
done = true;
done = true; break;
}
if (done)
break;

// Start the Dear ImGui frame
ImGui_ImplDX9_NewFrame();
1 change: 1 addition & 0 deletions imgui.cpp
Original file line number Diff line number Diff line change
@@ -12172,6 +12172,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
Text("%d vertices, %d indices (%d triangles)", io.MetricsRenderVertices, io.MetricsRenderIndices, io.MetricsRenderIndices / 3);
Text("%d visible windows, %d active allocations", io.MetricsRenderWindows, io.MetricsActiveAllocations);
Text("Frame count %d, frame count ended %d, frame coung rendered %d", g.FrameCount, g.FrameCountEnded, g.FrameCountRendered);
//SameLine(); if (SmallButton("GC")) { g.GcCompactAll = true; }

Separator();
12 changes: 12 additions & 0 deletions imgui.h
Original file line number Diff line number Diff line change
@@ -201,6 +201,7 @@ typedef int ImGuiTableRowFlags; // -> enum ImGuiTableRowFlags_ // Flags: F
typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode(), TreeNodeEx(), CollapsingHeader()
typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport
typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild()
typedef int ImGuiRedrawFlags; // -> enum ImGuiRedrawFlags_ // Flags: for RequestRedraw()

// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type]
// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file.
@@ -348,6 +349,8 @@ namespace ImGui
IMGUI_API ImVec2 GetWindowSize(); // get current window size
IMGUI_API float GetWindowWidth(); // get current window width (shortcut for GetWindowSize().x)
IMGUI_API float GetWindowHeight(); // get current window height (shortcut for GetWindowSize().y)
IMGUI_API bool WaitAndPollEvents(int timeout); // block the frame drawing loop untill a event is detected. timeout: 0 process event immediatly, not blocking; -1 wait for ever untill untill an event comes; positive number wait untill timedout or event comes. Call RequestRedraw to awake waiting of this function. Return 0 to signel a quict event.
IMGUI_API void RequestRedraw(ImGuiRedrawFlags flags); // request to redraw (currently redraw everything, may redraw specific region/window/widget only in the future)

// Window manipulation
// - Prefer using SetNextXXX functions (before Begin) rather that SetXXX functions (after Begin).
@@ -1732,6 +1735,14 @@ enum ImGuiCond_
ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time)
};

// Enumeration for ImGui::RequestRedraw()
enum ImGuiRedrawFlags_
{
ImGuiRedrawFlags_Everything = 0, // Redraw everything visible
ImGuiRedrawFlags_SpcifiedWindow = 1 << 2, // Specific window
ImGuiRedrawFlags_RegionOfWindow = 1 << 3, // Region of a specific window
};

//-----------------------------------------------------------------------------
// [SECTION] Helpers: Memory allocations macros, ImVector<>
//-----------------------------------------------------------------------------
@@ -2940,6 +2951,7 @@ struct ImGuiPlatformImeData
ImGuiPlatformImeData() { memset(this, 0, sizeof(*this)); }
};


//-----------------------------------------------------------------------------
// [SECTION] Obsolete functions and types
// (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details)
2 changes: 2 additions & 0 deletions imgui_demo.cpp
Original file line number Diff line number Diff line change
@@ -1701,6 +1701,8 @@ static void ShowDemoWindowWidgets()
progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime;
if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; }
if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; }
// in power save mode when animate is enabled and, request redraw a new frame to show animation
ImGui::RequestRedraw(ImGuiRedrawFlags_Everything);
}

// Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width,