ImDrawList: Additional comments and extracted bits into ImDrawList::PopUnusedDrawCmd()
This commit is contained in:
parent
a6bb047bab
commit
117d57df5b
@ -61,6 +61,8 @@ Other Changes:
|
|||||||
[@thedmd, @Shironekoben, @sergeyn, @ocornut]
|
[@thedmd, @Shironekoben, @sergeyn, @ocornut]
|
||||||
- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split when current
|
- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split when current
|
||||||
VtxOffset was not zero would lead to draw commands with wrong VtxOffset. (#2591)
|
VtxOffset was not zero would lead to draw commands with wrong VtxOffset. (#2591)
|
||||||
|
- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after
|
||||||
|
a callback draw command would incorrectly override the callback draw command.
|
||||||
- Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
|
- 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,
|
- 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).
|
static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns).
|
||||||
|
12
imgui.cpp
12
imgui.cpp
@ -4077,18 +4077,12 @@ static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, Im
|
|||||||
|
|
||||||
static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
|
static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
|
||||||
{
|
{
|
||||||
|
// Remove trailing command if unused.
|
||||||
|
// Technically we could return directly instead of popping, but this make things looks neat in Metrics window as well.
|
||||||
|
draw_list->PopUnusedDrawCmd();
|
||||||
if (draw_list->CmdBuffer.Size == 0)
|
if (draw_list->CmdBuffer.Size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove trailing command if unused
|
|
||||||
ImDrawCmd* curr_cmd = &draw_list->CmdBuffer.back();
|
|
||||||
if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL)
|
|
||||||
{
|
|
||||||
draw_list->CmdBuffer.pop_back();
|
|
||||||
if (draw_list->CmdBuffer.Size == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
|
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
|
||||||
// May trigger for you if you are using PrimXXX functions incorrectly.
|
// May trigger for you if you are using PrimXXX functions incorrectly.
|
||||||
IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
|
IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
|
||||||
|
1
imgui.h
1
imgui.h
@ -2061,6 +2061,7 @@ struct ImDrawList
|
|||||||
// NB: all primitives needs to be reserved via PrimReserve() beforehand!
|
// NB: all primitives needs to be reserved via PrimReserve() beforehand!
|
||||||
IMGUI_API void ResetForNewFrame();
|
IMGUI_API void ResetForNewFrame();
|
||||||
IMGUI_API void ClearFreeMemory();
|
IMGUI_API void ClearFreeMemory();
|
||||||
|
IMGUI_API void PopUnusedDrawCmd();
|
||||||
IMGUI_API void PrimReserve(int idx_count, int vtx_count);
|
IMGUI_API void PrimReserve(int idx_count, int vtx_count);
|
||||||
IMGUI_API void PrimUnreserve(int idx_count, int vtx_count);
|
IMGUI_API void PrimUnreserve(int idx_count, int vtx_count);
|
||||||
IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles)
|
IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles)
|
||||||
|
@ -437,6 +437,17 @@ void ImDrawList::AddDrawCmd()
|
|||||||
CmdBuffer.push_back(draw_cmd);
|
CmdBuffer.push_back(draw_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pop trailing draw command (used before merging or presenting to user)
|
||||||
|
// Note that this leaves the ImDrawList in a state unfit for further commands, as most code assume that CmdBuffer.Size > 0 && CmdBuffer.back().UserCallback == NULL
|
||||||
|
void ImDrawList::PopUnusedDrawCmd()
|
||||||
|
{
|
||||||
|
if (CmdBuffer.Size == 0)
|
||||||
|
return;
|
||||||
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
|
if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL)
|
||||||
|
CmdBuffer.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
||||||
{
|
{
|
||||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
@ -1362,13 +1373,12 @@ void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count)
|
|||||||
|
|
||||||
void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
||||||
{
|
{
|
||||||
// Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use.
|
// Note that we never use or rely on _Channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use.
|
||||||
if (_Count <= 1)
|
if (_Count <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetCurrentChannel(draw_list, 0);
|
SetCurrentChannel(draw_list, 0);
|
||||||
if (draw_list->CmdBuffer.Size != 0 && draw_list->CmdBuffer.back().ElemCount == 0)
|
draw_list->PopUnusedDrawCmd();
|
||||||
draw_list->CmdBuffer.pop_back();
|
|
||||||
|
|
||||||
// Calculate our final buffer sizes. Also fix the incorrect IdxOffset values in each command.
|
// Calculate our final buffer sizes. Also fix the incorrect IdxOffset values in each command.
|
||||||
int new_cmd_buffer_count = 0;
|
int new_cmd_buffer_count = 0;
|
||||||
@ -1378,8 +1388,11 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
|||||||
for (int i = 1; i < _Count; i++)
|
for (int i = 1; i < _Count; i++)
|
||||||
{
|
{
|
||||||
ImDrawChannel& ch = _Channels[i];
|
ImDrawChannel& ch = _Channels[i];
|
||||||
|
|
||||||
|
// Equivalent of PopUnusedDrawCmd() for this channel's cmdbuffer and except we don't need to test for UserCallback.
|
||||||
if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0)
|
if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0)
|
||||||
ch._CmdBuffer.pop_back();
|
ch._CmdBuffer.pop_back();
|
||||||
|
|
||||||
if (ch._CmdBuffer.Size > 0 && last_cmd != NULL)
|
if (ch._CmdBuffer.Size > 0 && last_cmd != NULL)
|
||||||
{
|
{
|
||||||
ImDrawCmd* next_cmd = &ch._CmdBuffer[0];
|
ImDrawCmd* next_cmd = &ch._CmdBuffer[0];
|
||||||
|
Loading…
Reference in New Issue
Block a user