-
Notifications
You must be signed in to change notification settings - Fork 547
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
Suspend & Resume may lead to corrupted ImDrawCmd in some cases #282
Comments
pthom
added a commit
to pthom/fiatlight
that referenced
this issue
Mar 8, 2024
pthom
added a commit
to pthom/imgui
that referenced
this issue
Mar 19, 2024
… sentinel callback // Patch for imgui-node-editor, which sometimes leaves // its sentinel callback ImDrawCallback_ImCanvas on the command list // (ImDrawCallback_ImCanvas is actually -2 cast to ImDrawCallback // and thus, not a valid pointer, since it equals to 0xfffffffffffffffe // See issues: // thedmd/imgui-node-editor#282 // and thedmd/imgui-node-editor#205 // + partial solution: thedmd/imgui-node-editor@af7fa51 bool isUserCallbackAddressValid = ( reinterpret_cast<uintptr_t>(pcmd->UserCallback) < 0xffffffffffffff00 );
pthom
added a commit
to pthom/imgui-node-editor
that referenced
this issue
Mar 20, 2024
…tFirstCommandIndex (proposed fix for thedmd#282) Analysis of the bug thedmd#282 when using this repro: https://github.com/pthom/node_window_clipping_issue/tree/suspend_resume_issue2 At the 4th call of LeaveLocalSpace(), we have: this = {ImGuiEx::Canvas *} m_DrawList = {ImDrawList *} mDrawList is of size 4 CmdBuffer = {ImVector<ImDrawCmd>} its elements at index 2 Size = {int} 4 has UserCallback == {ImDrawCallback_ImCanvas} Capacity = {int} 8 Data = {ImDrawCmd *} m_ExpectedChannel = {int} 0 m_DrawListFirstCommandIndex = {int} 2 m_DrawListCommadBufferSize = {int} 1 m_DrawListStartVertexIndex = {int} 8 We have m_DrawListFirstCommandIndex = 2, however, the tests in the original code will test only at index 0 and 1! if (m_DrawList->CmdBuffer.size() > m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize].UserCallback == ImDrawCallback_ImCanvas) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize); else if (m_DrawList->CmdBuffer.size() >= m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize - 1].UserCallback == ImDrawCallback_ImCanvas) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize - 1); // Proposed solution: test all commands from index >= m_DrawListFirstCommandIndex // and remove the one with UserCallback == ImDrawCallback_ImCanvas // (based on the original code, it seems there can be only one) int idxCommand_ImDrawCallback_ImCanvas = -1; for (int i = m_DrawListFirstCommandIndex; i < m_DrawList->CmdBuffer.size(); ++i) { auto & command = m_DrawList->CmdBuffer[i]; if (command.UserCallback == ImDrawCallback_ImCanvas) { idxCommand_ImDrawCallback_ImCanvas = i; break; } } if (idxCommand_ImDrawCallback_ImCanvas >= 0) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + idxCommand_ImDrawCallback_ImCanvas);
pthom
added a commit
to pthom/imgui-node-editor
that referenced
this issue
Mar 20, 2024
…tFirstCommandIndex (proposed fix for thedmd#282) Analysis of the bug thedmd#282 when using this repro: https://github.com/pthom/node_window_clipping_issue/tree/suspend_resume_issue2 At the 4th call of LeaveLocalSpace(), we have: this = {ImGuiEx::Canvas *} m_DrawList = {ImDrawList *} mDrawList is of size 4 CmdBuffer = {ImVector<ImDrawCmd>} its elements at index 2 Size = {int} 4 has UserCallback == {ImDrawCallback_ImCanvas} Capacity = {int} 8 Data = {ImDrawCmd *} m_ExpectedChannel = {int} 0 m_DrawListFirstCommandIndex = {int} 2 m_DrawListCommadBufferSize = {int} 1 m_DrawListStartVertexIndex = {int} 8 We have m_DrawListFirstCommandIndex = 2, however, the tests in the original code will test only at index 0 and 1! if (m_DrawList->CmdBuffer.size() > m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize].UserCallback == ImDrawCallback_ImCanvas) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize); else if (m_DrawList->CmdBuffer.size() >= m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize - 1].UserCallback == ImDrawCallback_ImCanvas) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize - 1); // Proposed solution: test all commands from index >= m_DrawListFirstCommandIndex // and remove the one with UserCallback == ImDrawCallback_ImCanvas // (based on the original code, it seems there can be only one) int idxCommand_ImDrawCallback_ImCanvas = -1; for (int i = m_DrawListFirstCommandIndex; i < m_DrawList->CmdBuffer.size(); ++i) { auto & command = m_DrawList->CmdBuffer[i]; if (command.UserCallback == ImDrawCallback_ImCanvas) { idxCommand_ImDrawCallback_ImCanvas = i; break; } } if (idxCommand_ImDrawCallback_ImCanvas >= 0) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + idxCommand_ImDrawCallback_ImCanvas);
pthom
added a commit
to pthom/imgui_bundle
that referenced
this issue
Mar 20, 2024
pthom
added a commit
to pthom/imgui-node-editor
that referenced
this issue
May 12, 2024
…tFirstCommandIndex (proposed fix for thedmd#282) Analysis of the bug thedmd#282 when using this repro: https://github.com/pthom/node_window_clipping_issue/tree/suspend_resume_issue2 At the 4th call of LeaveLocalSpace(), we have: this = {ImGuiEx::Canvas *} m_DrawList = {ImDrawList *} mDrawList is of size 4 CmdBuffer = {ImVector<ImDrawCmd>} its elements at index 2 Size = {int} 4 has UserCallback == {ImDrawCallback_ImCanvas} Capacity = {int} 8 Data = {ImDrawCmd *} m_ExpectedChannel = {int} 0 m_DrawListFirstCommandIndex = {int} 2 m_DrawListCommadBufferSize = {int} 1 m_DrawListStartVertexIndex = {int} 8 We have m_DrawListFirstCommandIndex = 2, however, the tests in the original code will test only at index 0 and 1! if (m_DrawList->CmdBuffer.size() > m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize].UserCallback == ImDrawCallback_ImCanvas) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize); else if (m_DrawList->CmdBuffer.size() >= m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize - 1].UserCallback == ImDrawCallback_ImCanvas) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize - 1); // Proposed solution: test all commands from index >= m_DrawListFirstCommandIndex // and remove the one with UserCallback == ImDrawCallback_ImCanvas // (based on the original code, it seems there can be only one) int idxCommand_ImDrawCallback_ImCanvas = -1; for (int i = m_DrawListFirstCommandIndex; i < m_DrawList->CmdBuffer.size(); ++i) { auto & command = m_DrawList->CmdBuffer[i]; if (command.UserCallback == ImDrawCallback_ImCanvas) { idxCommand_ImDrawCallback_ImCanvas = i; break; } } if (idxCommand_ImDrawCallback_ImCanvas >= 0) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + idxCommand_ImDrawCallback_ImCanvas);
pthom
added a commit
to pthom/fiatlight
that referenced
this issue
Jun 19, 2024
pthom
added a commit
to pthom/imgui-node-editor
that referenced
this issue
Sep 10, 2024
…tFirstCommandIndex (proposed fix for thedmd#282) Analysis of the bug thedmd#282 when using this repro: https://github.com/pthom/node_window_clipping_issue/tree/suspend_resume_issue2 At the 4th call of LeaveLocalSpace(), we have: this = {ImGuiEx::Canvas *} m_DrawList = {ImDrawList *} mDrawList is of size 4 CmdBuffer = {ImVector<ImDrawCmd>} its elements at index 2 Size = {int} 4 has UserCallback == {ImDrawCallback_ImCanvas} Capacity = {int} 8 Data = {ImDrawCmd *} m_ExpectedChannel = {int} 0 m_DrawListFirstCommandIndex = {int} 2 m_DrawListCommadBufferSize = {int} 1 m_DrawListStartVertexIndex = {int} 8 We have m_DrawListFirstCommandIndex = 2, however, the tests in the original code will test only at index 0 and 1! if (m_DrawList->CmdBuffer.size() > m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize].UserCallback == ImDrawCallback_ImCanvas) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize); else if (m_DrawList->CmdBuffer.size() >= m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize - 1].UserCallback == ImDrawCallback_ImCanvas) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize - 1); // Proposed solution: test all commands from index >= m_DrawListFirstCommandIndex // and remove the one with UserCallback == ImDrawCallback_ImCanvas // (based on the original code, it seems there can be only one) int idxCommand_ImDrawCallback_ImCanvas = -1; for (int i = m_DrawListFirstCommandIndex; i < m_DrawList->CmdBuffer.size(); ++i) { auto & command = m_DrawList->CmdBuffer[i]; if (command.UserCallback == ImDrawCallback_ImCanvas) { idxCommand_ImDrawCallback_ImCanvas = i; break; } } if (idxCommand_ImDrawCallback_ImCanvas >= 0) m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + idxCommand_ImDrawCallback_ImCanvas);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello Michał,
I encountered another issue with Suspend and Resume: in some cases, the ImDrawData CmdBuffer might be corrupted.
I put together a small repro, which you can find on the suspend_resume_issue2 branch of the same repro repository I used before (please use the suspend_resume_issue2 branch)
Here is a quick summary of what happens:
I use the node editor in a simple way, and I use suspend and resume to create popups:
And I encounter a bug inside
ImGui_ImplOpenGL3_RenderDrawData
An issue is triggered at startup inside
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
When the bug occurs, here is the content of pcmd
In order to trigger the bug, I had to create the main background window with several flags:
In a sense, this might be related to of 205, since there were some discussions there about ImDrawCmd handling, and I think we are experiencing an issue around this here also.
Cheers!
The text was updated successfully, but these errors were encountered: