Browse Source

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 5 years ago
parent
commit
e22e3f300a
3 changed files with 26 additions and 11 deletions
  1. 3 0
      docs/CHANGELOG.txt
  2. 1 1
      imgui.cpp
  3. 22 10
      imgui_draw.cpp

+ 3 - 0
docs/CHANGELOG.txt

@@ -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).

+ 1 - 1
imgui.cpp

@@ -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);

+ 22 - 10
imgui_draw.cpp

@@ -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()
@@ -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)
+    {
+        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