Open Cascades opened 2 years ago
I think a much easier approach for that idea would be to leave last ImDrawList of a specific window untouched and keep rendering that at the end of the frame. It would only work if the user is strictly respecting not submitting anything directly to the ImDrawList instance if Begin() returns false.
I think you should investigate that idea, perhaps by adding a custom window flags to do that. It MIGHT be as simple as:
window->DrawList->_ResetForNewFrame()
when that flag is setThanks for the reply Omar! I realise you're extremely busy (always), so appreciate your time.
Having ImDrawLists persist over frames like this would be ideal! I think I'm correct in saying that ImDrawList::_ResetForNewFrame()
is the new version of ImDrawList::Clear()
in v1.64
(my company's current version).
I can see some of the equivalent calls you're referring to, e.g. in Begin()
, but are you suggesting I can supress these without modifying the ImGui source? I can of course guard calls in ImGui source with if statements or similar, but can I do so while staying on the consumer side of the ImGui interface?
but can I do so while staying on the consumer side of the ImGui interface?
You cannot currently, but I think this is the way forward and we can aim to support a feature like that. First we need to validat the proof of concept then we can introduce policies (e.g. interlaced refresh rates, with different setting for focused or hovered window than for other windows).
If you make local mods my suggestion to enforce a standard such as making all changes under a specific defines:
#ifdef !IMGUI_MYCOMPANY
if (flags & ImGuiWindowsFlags_NoRefresh)
window->DrawList->_ResetForNewFrame()
#else
window->DrawList->_ResetForNewFrame()
#endif
This way it is easier to rebase.
PS: You should really update ihmo, 1.64 is getting very old and the most often you update the less issues you'll get into.
I pushed an experiment: d449544
You can toy with it as ImGui::SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags_TryToAvoidRefresh);
(require imgui_internal.h)
Note that this behave at the Window level, not on a per-DrawList basis. So it doesn't exactly full-fill the title of this topic. See comments/caveats in the commit description.
I think it'll be a good tool for reduce costs of "normally heavy" UI traversal, but may be an inadequate tool to reduce cost of "abnormally heavy" computation, as for that later you'll want very precise control and guaranteed avoidance that e.g. something is not done two frames in a row.
Version/Branch of Dear ImGui:
Version: 1.64 Branch: master
Back-end/Renderer/Compiler/OS
Back-ends: Custom OpenGL implementation of this (looks identical) Compiler: Ninja 1.10.2 Operating System: Windows (also building for Linux, but I'm on Windows usually)
My Issue/Question:
Hi, I currently have a project which, while using a custom backend and various custom widgets, is otherwise fairly normal in terms of Dear ImGui flow (in my opinion). The only potential abnormality is the number of windows being used. Dear ImGui is starting to bottleneck a bit, and I'm investigating caching methods. I've had a look through #3515, #2391, #1878 and this external issue. I thought I'd give an approach similar to #3515 a go, but am getting nothing rendered.
I have attached a minimal code example of what I'm currently trying. When I run it, I get everything rendered properly for the first 10 frames (I disable the caching attempt for that amount of time), and then once it switches over to caching, I get nothing. Looking at RenderDoc, it looks like most of the render pass just doesn't happen, should I also be updating something else when I cache?
Edit 1: I have updated things a little, and now I get an abort() in ImGui somewhere. I'll update once I know where (in
ImGui::Render()
almost certainly.Edit 2: Hmmm, this is what I'm getting
Edit 3: Looks like
draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size
is failing with:draw_list->VtxBuffer.Size == 1798
((draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size) - draw_list->_VtxWritePtr) / sizeof(ImDrawVert) == 1797
Edit 4: And with end() not back(), I think it's doing what I expect it to now! I'd appreciate any comments on improvements or thoughts on performance (perhaps reducing the number of allocated objects), but otherwise I'll close this Monday afternoon.
Screenshots/Video
Don't think this is applicable. My output before frame 10 are my windows, the output after 10 frames is nothing.
Standalone, minimal, complete and verifiable example: (see https://github.com/ocornut/imgui/issues/2261)
I am sorry, this is neither complete nor verifiable, but is just a very rough pseudocode idea of what I'm trying to achieve.