diff options
| author | Andre Weissflog <floooh@gmail.com> | 2024-02-25 17:04:07 +0100 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2024-02-25 17:04:07 +0100 |
| commit | 443c0cbea1bc0c79116cd9d6a883ec22a4d7b351 (patch) | |
| tree | a884d7ba30898ca835f9a80137f4dc359a2b4e4f | |
| parent | 6a13a96d58a1d2ad88161d9dddb7843e541803a9 (diff) | |
sokol_imgui.h: ignore special ImDrawCallback_ResetRenderState user callback constant (fixes #1000)
| -rw-r--r-- | CHANGELOG.md | 16 | ||||
| -rw-r--r-- | util/sokol_imgui.h | 25 |
2 files changed, 34 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index df52df4a..f3eba225 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ ## Updates +#### 26-Feb-2024: + +- Minor fix in sokol_imgui.h: The drawing code now detects and skips the special + `ImDrawCallback_ResetRenderState` constant, not doing so would try to call a function + at address (-8) which then results in a crash. + + See for what this is: https://github.com/ocornut/imgui/blob/277ae93c41314ba5f4c7444f37c4319cdf07e8cf/imgui.h#L2583-L2587 + + sokol_imgui.h doesn't have any handling for this special callback, it will just ignore it. + + As a minor additional behaviour change, any user callback will now also cause `sg_reset_state_cache()` + to be called. This is just a precaution in case the user callback code calls any native 3D backend API + functions. + + Related issue: https://github.com/floooh/sokol/issues/1000 + #### 21-Feb-2024: - PR https://github.com/floooh/sokol/pull/993 has been merged, this allows to inject diff --git a/util/sokol_imgui.h b/util/sokol_imgui.h index 93b697fa..190ec675 100644 --- a/util/sokol_imgui.h +++ b/util/sokol_imgui.h @@ -609,6 +609,12 @@ inline void simgui_new_frame(const simgui_frame_desc_t& desc) { return simgui_ne // helper macros and constants #define _simgui_def(val, def) (((val) == 0) ? (def) : (val)) +// workaround for missing ImDrawCallback_ResetRenderState in cimgui.h +// see: https://github.com/cimgui/cimgui/issues/261 +#ifndef ImDrawCallback_ResetRenderState +#define ImDrawCallback_ResetRenderState (ImDrawCallback)(-8) +#endif + typedef struct { ImVec2 disp_size; uint8_t _pad_8[8]; @@ -2644,13 +2650,18 @@ SOKOL_API_IMPL void simgui_render(void) { uint32_t vtx_offset = 0; for (int cmd_index = 0; cmd_index < num_cmds; cmd_index++) { ImDrawCmd* pcmd = &cl->CmdBuffer.Data[cmd_index]; - if (pcmd->UserCallback) { - pcmd->UserCallback(cl, pcmd); - // need to re-apply all state after calling a user callback - sg_apply_viewport(0, 0, fb_width, fb_height, true); - sg_apply_pipeline(_simgui.def_pip); - sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(vs_params)); - sg_apply_bindings(&bind); + if (pcmd->UserCallback != 0) { + // 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) { + pcmd->UserCallback(cl, pcmd); + // need to re-apply all state after calling a user callback + sg_reset_state_cache(); + sg_apply_viewport(0, 0, fb_width, fb_height, true); + sg_apply_pipeline(_simgui.def_pip); + sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(vs_params)); + sg_apply_bindings(&bind); + } } else { if ((tex_id != pcmd->TextureId) || (vtx_offset != pcmd->VtxOffset)) { tex_id = pcmd->TextureId; |