Skip to content

Suspend & Resume may lead to corrupted ImDrawCmd in some cases #282

@pthom

Description

@pthom

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:

        static ed::NodeId node_id = 1;

        BeginMainWindow();        // See explanations below

        ed::Begin("Graph");

        ed::BeginNode(node_id);

        if (ImGui::Button("O"))
        {
            ed::Suspend();
            ImGui::OpenPopup("expandable_str_popup");
            ed::Resume();
        }

        ed::Suspend();
        if (ImGui::BeginPopup("expandable_str_popup"))
        {
            ImGui::Text("AAAA");
            ImGui::EndPopup();
        }
        ed::Resume();

        ed::EndNode();

        ed::End();

        EndMainWindow();

And I encounter a bug inside ImGui_ImplOpenGL3_RenderDrawData

An issue is triggered at startup inside void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)

void    ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
{

   ...

    for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
    {
        const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
        if (pcmd->UserCallback != nullptr)
        {
            // User callback, registered via ImDrawList::AddCallback()
            // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
            if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
                ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
            else
                pcmd->UserCallback(cmd_list, pcmd);     // <== the bug is triggered here
        }

When the bug occurs, here is the content of pcmd

pcmd = {const ImDrawCmd *} 0x15a63c860 
 ClipRect = {ImVec4} 
 TextureId = {ImTextureID} 0x1 
 VtxOffset = {unsigned int} 0
 IdxOffset = {unsigned int} 930
 ElemCount = {unsigned int} 0
 UserCallback = {ImDrawCallback} 0xfffffffffffffffe        // This is a bad pointer 
 UserCallbackData = {void *} NULL

In order to trigger the bug, I had to create the main background window with several flags:

    void BeginMainWindow()
    {
        // the following code will create a background window that will cover the entire viewport
        // The bug is quite subtle and needs all the flags below to be set

        ImGuiViewport* viewport = ImGui::GetMainViewport();

        ImGui::SetNextWindowPos(viewport->Pos);
        ImVec2 viewportSize = viewport->Size;
        ImGui::SetNextWindowSize(viewportSize);
        ImGui::SetNextWindowViewport(viewport->ID);
        ImGui::SetNextWindowBgAlpha(0.0f);

        ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
        ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
        ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
        static bool p_open = true;

        ImGuiWindowFlags window_flags = 0;
        window_flags = window_flags
            | ImGuiWindowFlags_NoDocking
            | ImGuiWindowFlags_NoTitleBar
            | ImGuiWindowFlags_NoCollapse
            | ImGuiWindowFlags_NoResize
            | ImGuiWindowFlags_NoMove
            | ImGuiWindowFlags_NoScrollbar
            | ImGuiWindowFlags_NoSavedSettings
            | ImGuiWindowFlags_NoBringToFrontOnFocus
            | ImGuiWindowFlags_NoNavFocus
            ;

        ImGui::Begin("Main window", & p_open, window_flags);
        ImGui::PopStyleVar(3);

    }

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions