Fixed GetBackgroundDrawList()/GetForegroundDrawList() not being properly reset every frame when cumulated session time is very large. (#9521)

Using a FrameCount for compare. Kept time as float to be consistent with other GC-related timestamps: if there is an actual need to use double we'll switch everywhere.
This commit is contained in:
ocornut
2026-08-23 13:05:33 +02:00
parent 1d7b37dc9b
commit 0af8f475d1
3 changed files with 10 additions and 5 deletions

View File

@@ -56,6 +56,9 @@ Other Changes:
- Reworked `AddFontDefault()` to use `io.DisplayFrameBufferScale` as part of the heuristic
to select `AddFontDefaultVector()` by default, effectively using ProggyForever instead of
ProggyClean on most Apple/Retina setups by default.
- Misc:
- Fixed `GetBackgroundDrawList()`/`GetForegroundDrawList()` not being properly reset
every frame when cumulated session time is very large (e.g. a few days). [@lailoken]
- ImDrawList:
- Per-viewport FramebufferScale for Apple/Retina screen is applied to draw lists:
- AA Fringe is scaled accordingly.

View File

@@ -5305,12 +5305,13 @@ static ImDrawList* GetViewportBgFgDrawList(ImGuiViewportP* viewport, size_t draw
}
// Our ImDrawList system requires that there is always a command
if (viewport->BgFgDrawListsLastTimeActive[drawlist_no] != (float)g.Time)
if (viewport->BgFgDrawListsLastFrameActive[drawlist_no] != g.FrameCount)
{
draw_list->_ResetForNewFrame();
draw_list->_SetPixelDensity(viewport->FramebufferScale.x);
draw_list->PushTexture(g.IO.Fonts->TexRef);
draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false);
viewport->BgFgDrawListsLastFrameActive[drawlist_no] = g.FrameCount;
viewport->BgFgDrawListsLastTimeActive[drawlist_no] = (float)g.Time;
}
return draw_list;
@@ -6212,7 +6213,7 @@ void ImGui::Render()
for (ImGuiViewportP* viewport : g.Viewports)
{
InitViewportDrawData(viewport);
if (viewport->BgFgDrawLists[0] != NULL && viewport->BgFgDrawListsLastTimeActive[0] == (float)g.Time)
if (viewport->BgFgDrawLists[0] != NULL && viewport->BgFgDrawListsLastFrameActive[0] == g.FrameCount)
AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[0], GetBackgroundDrawList(viewport));
}
@@ -6244,7 +6245,7 @@ void ImGui::Render()
FlattenDrawDataIntoSingleLayer(&viewport->DrawDataBuilder);
// Add foreground ImDrawList (for each active viewport)
if (viewport->BgFgDrawLists[1] != NULL && viewport->BgFgDrawListsLastTimeActive[1] == (float)g.Time)
if (viewport->BgFgDrawLists[1] != NULL && viewport->BgFgDrawListsLastFrameActive[1] == g.FrameCount)
AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[0], GetForegroundDrawList(viewport));
// We call _PopUnusedDrawCmd() last thing, as RenderDimmedBackgrounds() rely on a valid command being there (especially in docking branch).

View File

@@ -1999,8 +1999,9 @@ struct IMGUI_API ImGuiMultiSelectState
// Every instance of ImGuiViewport is in fact a ImGuiViewportP.
struct ImGuiViewportP : public ImGuiViewport
{
float BgFgDrawListsLastTimeActive[2]; // Last frame number the background (0) and foreground (1) draw lists were used
ImDrawList* BgFgDrawLists[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.
int BgFgDrawListsLastFrameActive[2]; // Last frame the background (0) and foreground (1) draw lists were used.
float BgFgDrawListsLastTimeActive[2]; // Timestamps for Gc.
ImDrawData DrawDataP;
ImDrawDataBuilder DrawDataBuilder; // Temporary data while building final ImDrawData
@@ -2013,7 +2014,7 @@ struct ImGuiViewportP : public ImGuiViewport
ImVec2 BuildWorkInsetMin; // Work Area inset accumulator for current frame, to become next frame's WorkInset
ImVec2 BuildWorkInsetMax; // "
ImGuiViewportP() { BgFgDrawListsLastTimeActive[0] = BgFgDrawListsLastTimeActive[1] = -1.0f; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; }
ImGuiViewportP() { BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; BgFgDrawListsLastFrameActive[0] = BgFgDrawListsLastFrameActive[1] = -1; BgFgDrawListsLastTimeActive[0] = BgFgDrawListsLastTimeActive[1] = -1.0; }
~ImGuiViewportP() { if (BgFgDrawLists[0]) IM_DELETE(BgFgDrawLists[0]); if (BgFgDrawLists[1]) IM_DELETE(BgFgDrawLists[1]); }
// Calculate work rect pos/size given a set of offset (we have 1 pair of offset for rect locked from last frame data, and 1 pair for currently building rect)