Columns: Lower overhead on column switches and switching to background channel. (second attempt for 9b3ce49)

Internals: Bits, comments, added ImRect::ToVec4()
This commit is contained in:
omar
2020-06-13 15:48:05 +02:00
parent d3b37180a3
commit 90c0c0c163
4 changed files with 46 additions and 17 deletions

View File

@ -7398,6 +7398,7 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
//-------------------------------------------------------------------------
// - SetWindowClipRectBeforeSetChannel() [Internal]
// - GetColumnIndex()
// - GetColumnCount()
// - GetColumnOffset()
@ -7415,6 +7416,18 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
// - Columns()
//-------------------------------------------------------------------------
// [Internal] Small optimization to avoid calls to PopClipRect/SetCurrentChannel/PushClipRect in sequences,
// they would meddle many times with the underlying ImDrawCmd.
// Instead, we do a preemptive overwrite of clipping rectangle _without_ altering the command-buffer and let
// the subsequent single call to SetCurrentChannel() does it things once.
void ImGui::SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect)
{
ImVec4 clip_rect_vec4 = clip_rect.ToVec4();
window->ClipRect = clip_rect;
window->DrawList->_CmdHeader.ClipRect = clip_rect_vec4;
window->DrawList->_ClipRectStack.Data[window->DrawList->_ClipRectStack.Size - 1] = clip_rect_vec4;
}
int ImGui::GetColumnIndex()
{
ImGuiWindow* window = GetCurrentWindowRead();
@ -7549,11 +7562,11 @@ void ImGui::PushColumnsBackground()
ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1)
return;
// Optimization: avoid SetCurrentChannel() + PushClipRect()
columns->HostBackupClipRect = window->ClipRect;
SetWindowClipRectBeforeSetChannel(window, columns->HostInitialClipRect);
columns->Splitter.SetCurrentChannel(window->DrawList, 0);
int cmd_size = window->DrawList->CmdBuffer.Size;
PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false);
IM_UNUSED(cmd_size);
IM_ASSERT(cmd_size >= window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd
}
void ImGui::PopColumnsBackground()
@ -7562,8 +7575,10 @@ void ImGui::PopColumnsBackground()
ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1)
return;
// Optimization: avoid PopClipRect() + SetCurrentChannel()
SetWindowClipRectBeforeSetChannel(window, columns->HostBackupClipRect);
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
PopClipRect();
}
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
@ -7611,7 +7626,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
columns->HostCursorPosY = window->DC.CursorPos.y;
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
columns->HostClipRect = window->ClipRect;
columns->HostInitialClipRect = window->ClipRect;
columns->HostWorkRect = window->WorkRect;
// Set state for first column
@ -7683,25 +7698,31 @@ void ImGui::NextColumn()
IM_ASSERT(columns->Current == 0);
return;
}
// Next column
if (++columns->Current == columns->Count)
columns->Current = 0;
PopItemWidth();
PopClipRect();
// Optimization: avoid PopClipRect() + SetCurrentChannel() + PushClipRect()
// (which would needlessly attempt to update commands in the wrong channel, then pop or overwrite them),
ImGuiColumnData* column = &columns->Columns[columns->Current];
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
const float column_padding = g.Style.ItemSpacing.x;
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
if (++columns->Current < columns->Count)
if (columns->Current > 0)
{
// Columns 1+ ignore IndentX (by canceling it out)
// FIXME-COLUMNS: Unnecessary, could be locked?
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding;
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
}
else
{
// New row/line
// Column 0 honor IndentX
// New row/line: column 0 honor IndentX.
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
columns->Splitter.SetCurrentChannel(window->DrawList, 1);
columns->Current = 0;
columns->LineMinY = columns->LineMaxY;
}
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
@ -7709,8 +7730,6 @@ void ImGui::NextColumn()
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrLineTextBaseOffset = 0.0f;
PushColumnClipRect(columns->Current); // FIXME-COLUMNS: Could it be an overwrite?
// FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup.
float offset_0 = GetColumnOffset(columns->Current);
float offset_1 = GetColumnOffset(columns->Current + 1);