ImDrawListSplitter: create first draw cmd on demand + Internals: fix incorrect ImBitArraySetBitRange() (only used by tables)

Make it cheaper to allocate unused draw cmd, can't measure perf difference other our stress tests.
This commit is contained in:
ocornut 2020-11-12 17:34:30 +01:00
parent 13258f5957
commit 78f1d2d319
2 changed files with 10 additions and 13 deletions

View File

@ -1417,6 +1417,7 @@ void ImDrawListSplitter::ClearFreeMemory()
void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count)
{
IM_UNUSED(draw_list);
IM_ASSERT(_Current == 0 && _Count <= 1 && "Nested channel splitting is not supported. Please use separate instances of ImDrawListSplitter.");
int old_channels_count = _Channels.Size;
if (old_channels_count < channels_count)
@ -1441,12 +1442,6 @@ void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count)
_Channels[i]._CmdBuffer.resize(0);
_Channels[i]._IdxBuffer.resize(0);
}
if (_Channels[i]._CmdBuffer.Size == 0)
{
ImDrawCmd draw_cmd;
ImDrawCmd_HeaderCopy(&draw_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset
_Channels[i]._CmdBuffer.push_back(draw_cmd);
}
}
}
@ -1536,8 +1531,10 @@ void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
draw_list->_IdxWritePtr = draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size;
// If current command is used with different settings we need to add a new command
ImDrawCmd* curr_cmd = &draw_list->CmdBuffer.Data[draw_list->CmdBuffer.Size - 1];
if (curr_cmd->ElemCount == 0)
ImDrawCmd* curr_cmd = (draw_list->CmdBuffer.Size == 0) ? NULL : &draw_list->CmdBuffer.Data[draw_list->CmdBuffer.Size - 1];
if (curr_cmd == NULL)
draw_list->AddDrawCmd();
else if (curr_cmd->ElemCount == 0)
ImDrawCmd_HeaderCopy(curr_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset
else if (ImDrawCmd_HeaderCompare(curr_cmd, &draw_list->_CmdHeader) != 0)
draw_list->AddDrawCmd();

View File

@ -453,15 +453,15 @@ struct IMGUI_API ImRect
};
// Helper: ImBitArray
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; }
inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2)
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; }
inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2)
{
while (n <= n2)
{
int a_mod = (n & 31);
int b_mod = ((n2 >= n + 31) ? 31 : (n2 & 31)) + 1;
int b_mod = (n2 > (n | 31) ? 31 : (n2 & 31)) + 1;
ImU32 mask = (ImU32)(((ImU64)1 << b_mod) - 1) & ~(ImU32)(((ImU64)1 << a_mod) - 1);
arr[n >> 5] |= mask;
n = (n + 32) & ~31;