Skip to content

Commit

Permalink
Viewports: Avoid rendering/swapping secondary viewports that are mini…
Browse files Browse the repository at this point in the history
…mized. (#1542, #2496)
  • Loading branch information
ocornut committed Apr 22, 2019
1 parent 20f0cb0 commit d0fb547
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 15 deletions.
35 changes: 24 additions & 11 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5622,7 +5622,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Pos = FindBestWindowPosForPopup(window);

// Late create viewport if we don't fit within our current host viewport.
if (window->ViewportAllowPlatformMonitorExtend >= 0 && !window->ViewportOwned && !window->Viewport->PlatformWindowMinimized)
if (window->ViewportAllowPlatformMonitorExtend >= 0 && !window->ViewportOwned && !(window->Viewport->Flags & ImGuiViewportFlags_Minimized))
if (!window->Viewport->GetRect().Contains(window->Rect()))
{
// This is based on the assumption that the DPI will be known ahead (same as the DPI of the selection done in UpdateSelectWindowViewport)
Expand Down Expand Up @@ -10171,7 +10171,7 @@ static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window)
static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport)
{
ImGuiContext& g = *GImGui;
if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport || viewport->PlatformWindowMinimized)
if (!(viewport->Flags & (ImGuiViewportFlags_CanHostOtherWindows | ImGuiViewportFlags_Minimized)) || window->Viewport == viewport)
return false;
if (!viewport->GetRect().Contains(window->Rect()))
return false;
Expand Down Expand Up @@ -10226,7 +10226,7 @@ static ImGuiViewportP* FindViewportHoveredFromPlatformWindowStack(const ImVec2 m
for (int n = 0; n < g.Viewports.Size; n++)
{
ImGuiViewportP* viewport = g.Viewports[n];
if (!(viewport->Flags & ImGuiViewportFlags_NoInputs) && !viewport->PlatformWindowMinimized && viewport->GetRect().Contains(mouse_platform_pos))
if (!(viewport->Flags & (ImGuiViewportFlags_NoInputs | ImGuiViewportFlags_Minimized)) && viewport->GetRect().Contains(mouse_platform_pos))
if (best_candidate == NULL || best_candidate->LastFrontMostStampCount < viewport->LastFrontMostStampCount)
best_candidate = viewport;
}
Expand All @@ -10245,7 +10245,13 @@ static void ImGui::UpdateViewportsNewFrame()
const bool platform_funcs_available = viewport->PlatformWindowCreated;
if ((g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable))
if (g.PlatformIO.Platform_GetWindowMinimized && platform_funcs_available)
viewport->PlatformWindowMinimized = g.PlatformIO.Platform_GetWindowMinimized(viewport);
{
bool minimized = g.PlatformIO.Platform_GetWindowMinimized(viewport);
if (minimized)
viewport->Flags |= ImGuiViewportFlags_Minimized;
else
viewport->Flags &= ~ImGuiViewportFlags_Minimized;
}
}

// Create/update main viewport with current platform position and size
Expand All @@ -10255,7 +10261,7 @@ static void ImGui::UpdateViewportsNewFrame()
ImVec2 main_viewport_platform_pos = ImVec2(0.0f, 0.0f);
ImVec2 main_viewport_platform_size = g.IO.DisplaySize;
if (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)
main_viewport_platform_pos = main_viewport->PlatformWindowMinimized ? main_viewport->Pos : g.PlatformIO.Platform_GetWindowPos(main_viewport);
main_viewport_platform_pos = (main_viewport->Flags & ImGuiViewportFlags_Minimized) ? main_viewport->Pos : g.PlatformIO.Platform_GetWindowPos(main_viewport);
AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_platform_pos, main_viewport_platform_size, ImGuiViewportFlags_CanHostOtherWindows);

g.CurrentViewport = NULL;
Expand Down Expand Up @@ -10293,7 +10299,7 @@ static void ImGui::UpdateViewportsNewFrame()
{
// Update Position and Size (from Platform Window to ImGui) if requested.
// We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities.
if (!viewport->PlatformWindowMinimized && platform_funcs_available)
if (!(viewport->Flags & ImGuiViewportFlags_Minimized) && platform_funcs_available)
{
if (viewport->PlatformRequestMove)
viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport);
Expand Down Expand Up @@ -10437,6 +10443,7 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
viewport->Pos = pos;
if (!viewport->PlatformRequestResize)
viewport->Size = size;
viewport->Flags = flags | (viewport->Flags & ImGuiViewportFlags_Minimized); // Preserve existing flags
}
else
{
Expand All @@ -10446,6 +10453,7 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
viewport->Idx = g.Viewports.Size;
viewport->Pos = viewport->LastPos = pos;
viewport->Size = size;
viewport->Flags = flags;
UpdateViewportPlatformMonitor(viewport);
g.Viewports.push_back(viewport);
//IMGUI_DEBUG_LOG("Add Viewport %08X (%s)\n", id, window->Name);
Expand All @@ -10464,7 +10472,6 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
}

viewport->Window = window;
viewport->Flags = flags;
viewport->LastFrameActive = g.FrameCount;
IM_ASSERT(window == NULL || viewport->ID == window->ID);

Expand Down Expand Up @@ -10721,9 +10728,11 @@ void ImGui::UpdatePlatformWindows()
//
// ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
// for (int i = 1; i < platform_io.Viewports.Size; i++)
// MyRenderFunction(platform_io.Viewports[i], my_args);
// if ((platform_io.Viewports[i]->Flags & ImGuiViewportFlags_Minimized) == 0)
// MyRenderFunction(platform_io.Viewports[i], my_args);
// for (int i = 1; i < platform_io.Viewports.Size; i++)
// MySwapBufferFunction(platform_io.Viewports[i], my_args);
// if ((platform_io.Viewports[i]->Flags & ImGuiViewportFlags_Minimized) == 0)
// MySwapBufferFunction(platform_io.Viewports[i], my_args);
//
void ImGui::RenderPlatformWindowsDefault(void* platform_render_arg, void* renderer_render_arg)
{
Expand All @@ -10732,12 +10741,16 @@ void ImGui::RenderPlatformWindowsDefault(void* platform_render_arg, void* render
for (int i = 1; i < platform_io.Viewports.Size; i++)
{
ImGuiViewport* viewport = platform_io.Viewports[i];
if (viewport->Flags & ImGuiViewportFlags_Minimized)
continue;
if (platform_io.Platform_RenderWindow) platform_io.Platform_RenderWindow(viewport, platform_render_arg);
if (platform_io.Renderer_RenderWindow) platform_io.Renderer_RenderWindow(viewport, renderer_render_arg);
}
for (int i = 1; i < platform_io.Viewports.Size; i++)
{
ImGuiViewport* viewport = platform_io.Viewports[i];
if (viewport->Flags & ImGuiViewportFlags_Minimized)
continue;
if (platform_io.Platform_SwapBuffers) platform_io.Platform_SwapBuffers(viewport, platform_render_arg);
if (platform_io.Renderer_SwapBuffers) platform_io.Renderer_SwapBuffers(viewport, renderer_render_arg);
}
Expand Down Expand Up @@ -14072,7 +14085,7 @@ static void RenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewp

ImVec2 scale = bb.GetSize() / viewport->Size;
ImVec2 off = bb.Min - viewport->Pos * scale;
float alpha_mul = viewport->PlatformWindowMinimized ? 0.30f : 1.00f;
float alpha_mul = (viewport->Flags & ImGuiViewportFlags_Minimized) ? 0.30f : 1.00f;
window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul * 0.40f));
for (int i = 0; i != g.Windows.Size; i++)
{
Expand Down Expand Up @@ -14287,7 +14300,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui::BulletText("Flags: 0x%04X =%s%s%s%s%s%s", viewport->Flags,
(flags & ImGuiViewportFlags_CanHostOtherWindows) ? " CanHostOtherWindows" : "", (flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "",
(flags & ImGuiViewportFlags_NoFocusOnAppearing) ? " NoFocusOnAppearing" : "", (flags & ImGuiViewportFlags_NoInputs) ? " NoInputs" : "",
(flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : "", viewport->PlatformWindowMinimized ? ", PlatformWindowMinimized" : "");
(flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : "", (flags & ImGuiViewportFlags_Minimized) ? " Minimized" : "");
for (int layer_i = 0; layer_i < IM_ARRAYSIZE(viewport->DrawDataBuilder.Layers); layer_i++)
for (int draw_list_i = 0; draw_list_i < viewport->DrawDataBuilder.Layers[layer_i].Size; draw_list_i++)
Funcs::NodeDrawList(NULL, viewport, viewport->DrawDataBuilder.Layers[layer_i][draw_list_i], "DrawList");
Expand Down
5 changes: 3 additions & 2 deletions imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ namespace ImGui
IMGUI_API ImGuiPlatformIO& GetPlatformIO(); // platform/renderer functions, for back-end to setup + viewports list.
IMGUI_API ImGuiViewport* GetMainViewport(); // main viewport. same as GetPlatformIO().MainViewport == GetPlatformIO().Viewports[0].
IMGUI_API void UpdatePlatformWindows(); // call in main loop. will call CreateWindow/ResizeWindow/etc. platform functions for each secondary viewport, and DestroyWindow for each inactive viewport.
IMGUI_API void RenderPlatformWindowsDefault(void* platform_arg = NULL, void* renderer_arg = NULL); // call in main loop. will call RenderWindow/SwapBuffers platform functions for each secondary viewport. may be reimplemented by user for custom rendering needs.
IMGUI_API void RenderPlatformWindowsDefault(void* platform_arg = NULL, void* renderer_arg = NULL); // call in main loop. will call RenderWindow/SwapBuffers platform functions for each secondary viewport which doesn't have the ImGuiViewportFlags_Minimized flag set. May be reimplemented by user for custom rendering needs.
IMGUI_API void DestroyPlatformWindows(); // call DestroyWindow platform functions for all viewports. call from back-end Shutdown() if you need to close platform windows before imgui shutdown. otherwise will be called by DestroyContext().
IMGUI_API ImGuiViewport* FindViewportByID(ImGuiID id); // this is a helper for back-ends.
IMGUI_API ImGuiViewport* FindViewportByPlatformHandle(void* platform_handle); // this is a helper for back-ends. the type platform_handle is decided by the back-end (e.g. HWND, MyWindow*, GLFWwindow* etc.)
Expand Down Expand Up @@ -2347,7 +2347,8 @@ enum ImGuiViewportFlags_
ImGuiViewportFlags_NoFocusOnClick = 1 << 3, // Platform Window: Don't take focus when clicked on.
ImGuiViewportFlags_NoInputs = 1 << 4, // Platform Window: Make mouse pass through so we can drag this window while peaking behind it.
ImGuiViewportFlags_NoRendererClear = 1 << 5, // Platform Window: Renderer doesn't need to clear the framebuffer ahead (because we will fill it entirely).
ImGuiViewportFlags_TopMost = 1 << 6 // Platform Window: Display on top (for tooltips only)
ImGuiViewportFlags_TopMost = 1 << 6, // Platform Window: Display on top (for tooltips only)
ImGuiViewportFlags_Minimized = 1 << 7 // Platform Window: Window is minimized, can skip render. When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport.
};

// The viewports created and managed by imgui. The role of the platform back-end is to create the platform/OS windows corresponding to each viewport.
Expand Down
3 changes: 1 addition & 2 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,6 @@ struct ImGuiViewportP : public ImGuiViewport
float LastAlpha;
short PlatformMonitor;
bool PlatformWindowCreated;
bool PlatformWindowMinimized; // When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport
ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set)
ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
ImDrawData DrawDataP;
Expand All @@ -765,7 +764,7 @@ struct ImGuiViewportP : public ImGuiViewport
ImVec2 LastPlatformSize;
ImVec2 LastRendererSize;

ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameDrawLists[0] = LastFrameDrawLists[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = PlatformWindowMinimized = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameDrawLists[0] = LastFrameDrawLists[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); }
ImRect GetRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
Expand Down

0 comments on commit d0fb547

Please sign in to comment.