Skip to content
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

Addcallback, assert Size > 0 ? #4528

Closed
voidware opened this issue Sep 10, 2021 · 9 comments
Closed

Addcallback, assert Size > 0 ? #4528

voidware opened this issue Sep 10, 2021 · 9 comments

Comments

@voidware
Copy link

I'm having a problem with AddCallback. Not sure if i'm doing something wrong;

Works;

  if (ImGui::Begin("Dear ImGui", 0, 0))
  {
        ImGui::GetWindowDrawList()->AddCallback(draw_scene_1, 0);
  }
  ImGui::End();

Fails:

 if (ImGui::Begin("Dear ImGui", 0, 0)) {

        if (ImGui::BeginChild("sokol-gfx", ImVec2(360, 360), true))
        {
            ImGui::GetWindowDrawList()->AddCallback(draw_scene_1, 0);
        }
        ImGui::EndChild();
 ...
 }

Works;

   if (ImGui::Begin("Dear ImGui", 0, 0)) {

        if (ImGui::BeginChild("sokol-gfx", ImVec2(360, 360), true))
        {
            ImGui::Text("hello!");
            ImGui::GetWindowDrawList()->AddCallback(draw_scene_1, 0);
        }
        ImGui::EndChild();
   ...

When it fails, i get assert Size > 0 from imgui.h ImVector::front.

Adding the bogus "hello!" text fixes it.

Is this something to do with the child draw list being otherwise empty, should it be doing this, or should i be doing something different?

Thanks for your help.

@PathogenDavid
Copy link
Contributor

I'm not getting a crash with your provided repro. Can you provide a call stack of the crash?

Also what version of Dear ImGui are you using?

@voidware
Copy link
Author

I'm using the github master branch. It's not a crash, imgui asserts Size > 0 in ImVector. I think it's because i otherwise have nothing to render. I'll see if i can get a stack. It might also be worth noting the callback (draw_scene_1 in this case) does not get called.

@voidware
Copy link
Author

Hang on, i just realised it might not be imgui. I'm using sokol to render the backend and it could be that.

@voidware
Copy link
Author

#1 0x00000000004d08a1 in ImVector::front (this=0x27bf768) at v:/sw/imgui/imgui.h:1727
#2 0x00000000004ac9e7 in simgui_render () at ../../sokol/util/sokol_imgui.h:1930
#3 0x00000000004ae19a in frame () at imgui-tex.cpp:211
#4 0x000000000040165a in _sapp_call_frame () at ../../sokol/sokol_app.h:2333
#5 0x0000000000401e7d in _sapp_frame () at ../../sokol/sokol_app.h:2512
#6 0x0000000000405e38 in _sapp_win32_run (desc=0x81fca0) at ../../sokol/sokol_app.h:6592
#7 0x00000000004060d2 in WinMain (hInstance=0x400000, hPrevInstance=0x0, lpCmdLine=0xa13ebf "", nCmdShow=10) at ../../sokol/sokol_app.h:6674
#8 0x00000000004013c7 in __tmainCRTStartup ()
#9 0x00000000004014fb in mainCRTStartup ()

@voidware
Copy link
Author

Yep, sorry my bad. this is a sokol problem.
Here's the fix for anyone interested;

sokol_imgui.h::simgui_render

change front to begin

       const size_t vtx_size = cl->VtxBuffer.size() * sizeof(ImDrawVert);
            const size_t idx_size = cl->IdxBuffer.size() * sizeof(ImDrawIdx);
            
            //const ImDrawVert* vtx_ptr = &cl->VtxBuffer.front();
            //const ImDrawIdx* idx_ptr = &cl->IdxBuffer.front();

            const ImDrawVert* vtx_ptr = cl->VtxBuffer.begin();
            const ImDrawIdx* idx_ptr = cl->IdxBuffer.begin();

@PathogenDavid
Copy link
Contributor

PathogenDavid commented Sep 11, 2021

Edit: Looks like you beat me to it.

Yeah, this is a bug with the Sokol backend:

https://github.com/floooh/sokol/blob/667df71044ecd19c218c93c5cbdb188c9ed6eeb8/util/sokol_imgui.h#L1930

This is unconditionally calling front() regardless of whether there's actually any vertices to render. Contrast this with the official backends, which just access the Data pointer directly:

glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);

@voidware
Copy link
Author

Yes indeed. Thanks for helping on this. I've posted by changes to the sokol repo in case they want them. It shouldnt call front regardless. If you look at the "C" version, it does the right thing.

@PathogenDavid
Copy link
Contributor

No problem!

I've posted by changes to the sokol repo in case they want them.

In the future you should really provide context on why the changes are necessary. It's not fair to floooh to expect them to read your mind on why begin() is more appropriate than front().

(Also you can probably safely mark this issue as closed.)

@floooh
Copy link
Contributor

floooh commented Sep 12, 2021

My bad, this is now fixed in sokol_imgui.h. Many thanks for investigating the problem!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants