Skip to content

Commit

Permalink
ImDrawList: Fixed an issue when draw command merging or cancelling wh…
Browse files Browse the repository at this point in the history
…ile crossing the VtxOffset boundary would lead to draw command being emitted with wrong VtxOffset value. (#3129, #3163, #3232)
  • Loading branch information
thedmd authored and ocornut committed Jun 6, 2020
1 parent 78d5ccf commit e22e3f3
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 11 deletions.
3 changes: 3 additions & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ Other Changes:
BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups]
- Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when
drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups]
- ImDrawList: Fixed an issue when draw command merging or cancelling while crossing the VtxOffset
boundary would lead to draw command being emitted with wrong VtxOffset value. (#3129, #3163, #3232)
[@thedmd, @Shironekoben, @sergeyn, @ocornut]
- Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
- CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups,
static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns).
Expand Down
2 changes: 1 addition & 1 deletion imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10267,7 +10267,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)

ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
char buf[300];
ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd: %4d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd:%5d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
pcmd->ElemCount/3, (void*)(intptr_t)pcmd->TextureId,
pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf);
Expand Down
32 changes: 22 additions & 10 deletions imgui_draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,11 +460,17 @@ void ImDrawList::UpdateClipRect()
}

// Try to merge with previous command if it matches, else use current command
ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL;
if (curr_cmd->ElemCount == 0 && prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL)
CmdBuffer.pop_back();
else
curr_cmd->ClipRect = curr_clip_rect;
if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1)
{
ImDrawCmd* prev_cmd = curr_cmd - 1;
if (memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->VtxOffset == _VtxCurrentOffset && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL)
{
CmdBuffer.pop_back();
return;
}
}

curr_cmd->ClipRect = curr_clip_rect;
}

void ImDrawList::UpdateTextureID()
Expand All @@ -479,11 +485,17 @@ void ImDrawList::UpdateTextureID()
}

// Try to merge with previous command if it matches, else use current command
ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL;
if (curr_cmd->ElemCount == 0 && prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL)
CmdBuffer.pop_back();
else
curr_cmd->TextureId = curr_texture_id;
if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1)

This comment has been minimized.

Copy link
@elect86

elect86 Sep 13, 2020

Contributor

maybe extract equal code into a third function?

This comment has been minimized.

Copy link
@ocornut

ocornut Sep 16, 2020

Owner

Each of them is omitting one thing from the test, anyway this code has been reworked again soon after that commit.

{
ImDrawCmd* prev_cmd = curr_cmd - 1;
if (prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->VtxOffset == _VtxCurrentOffset && prev_cmd->UserCallback == NULL)
{
CmdBuffer.pop_back();
return;
}
}

curr_cmd->TextureId = curr_texture_id;
}

#undef GetCurrentClipRect
Expand Down

0 comments on commit e22e3f3

Please sign in to comment.