mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Store common stacked settings contiguously in memory to reduce cache misses & unnecessary heap allocations
This commit is contained in:
parent
3d36c81241
commit
0a7024c198
70
imgui.cpp
70
imgui.cpp
@ -1091,7 +1091,7 @@ struct ImGuiDrawContext
|
|||||||
ImVec2 CursorPos;
|
ImVec2 CursorPos;
|
||||||
ImVec2 CursorPosPrevLine;
|
ImVec2 CursorPosPrevLine;
|
||||||
ImVec2 CursorStartPos;
|
ImVec2 CursorStartPos;
|
||||||
ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame
|
ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame
|
||||||
float CurrentLineHeight;
|
float CurrentLineHeight;
|
||||||
float CurrentLineTextBaseOffset;
|
float CurrentLineTextBaseOffset;
|
||||||
float PrevLineHeight;
|
float PrevLineHeight;
|
||||||
@ -1108,17 +1108,21 @@ struct ImGuiDrawContext
|
|||||||
ImGuiStorage* StateStorage;
|
ImGuiStorage* StateStorage;
|
||||||
ImGuiLayoutType LayoutType;
|
ImGuiLayoutType LayoutType;
|
||||||
|
|
||||||
bool ButtonRepeat; // == ButtonRepeatStack.back() [false]
|
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
|
||||||
|
bool ButtonRepeat; // == ButtonRepeatStack.back() [empty == false]
|
||||||
|
bool AllowKeyboardFocus; // == AllowKeyboardFocusStack.back() [empty == true]
|
||||||
|
float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
|
||||||
|
float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
|
||||||
ImVector<bool> ButtonRepeatStack;
|
ImVector<bool> ButtonRepeatStack;
|
||||||
ImVector<bool> AllowKeyboardFocus;
|
ImVector<bool> AllowKeyboardFocusStack;
|
||||||
ImVector<float> ItemWidth; // 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
|
ImVector<float> ItemWidthStack;
|
||||||
ImVector<float> TextWrapPos;
|
ImVector<float> TextWrapPosStack;
|
||||||
ImVector<ImGuiGroupData> GroupStack;
|
ImVector<ImGuiGroupData>GroupStack;
|
||||||
ImGuiColorEditMode ColorEditMode;
|
ImGuiColorEditMode ColorEditMode;
|
||||||
int StackSizesBackup[6]; // Store size of various stacks for asserting
|
int StackSizesBackup[6]; // Store size of various stacks for asserting
|
||||||
|
|
||||||
float ColumnsStartX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
|
float ColumnsStartX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
|
||||||
float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
|
float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
|
||||||
int ColumnsCurrent;
|
int ColumnsCurrent;
|
||||||
int ColumnsCount;
|
int ColumnsCount;
|
||||||
ImVec2 ColumnsStartPos;
|
ImVec2 ColumnsStartPos;
|
||||||
@ -1126,7 +1130,7 @@ struct ImGuiDrawContext
|
|||||||
float ColumnsCellMaxY;
|
float ColumnsCellMaxY;
|
||||||
bool ColumnsShowBorders;
|
bool ColumnsShowBorders;
|
||||||
ImGuiID ColumnsSetID;
|
ImGuiID ColumnsSetID;
|
||||||
ImVector<float> ColumnsOffsetsT; // Columns offset normalized 0.0 (far left) -> 1.0 (far right)
|
ImVector<float> ColumnsOffsetsT; // Columns offset normalized 0.0 (far left) -> 1.0 (far right)
|
||||||
|
|
||||||
ImGuiDrawContext()
|
ImGuiDrawContext()
|
||||||
{
|
{
|
||||||
@ -1801,7 +1805,7 @@ bool ImGuiWindow::FocusItemRegister(bool is_active, bool tab_stop)
|
|||||||
ImGuiState& g = *GImGui;
|
ImGuiState& g = *GImGui;
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
|
||||||
const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus.back();
|
const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus;
|
||||||
FocusIdxAllCounter++;
|
FocusIdxAllCounter++;
|
||||||
if (allow_keyboard_focus)
|
if (allow_keyboard_focus)
|
||||||
FocusIdxTabCounter++;
|
FocusIdxTabCounter++;
|
||||||
@ -3256,7 +3260,7 @@ void ImGui::EndChildFrame()
|
|||||||
// Save and compare stack sizes on Begin()/End() to detect usage errors
|
// Save and compare stack sizes on Begin()/End() to detect usage errors
|
||||||
static void CheckStacksSize(ImGuiWindow* window, bool write)
|
static void CheckStacksSize(ImGuiWindow* window, bool write)
|
||||||
{
|
{
|
||||||
// NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
|
// NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
|
||||||
ImGuiState& g = *GImGui;
|
ImGuiState& g = *GImGui;
|
||||||
int* p_backup = &window->DC.StackSizesBackup[0];
|
int* p_backup = &window->DC.StackSizesBackup[0];
|
||||||
{ int current = (int)window->IDStack.size(); if (write) *p_backup = current; else IM_ASSERT(*p_backup == current); p_backup++; } // User forgot PopID()
|
{ int current = (int)window->IDStack.size(); if (write) *p_backup = current; else IM_ASSERT(*p_backup == current); p_backup++; } // User forgot PopID()
|
||||||
@ -3786,15 +3790,16 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
|
|||||||
window->DC.MenuBarOffsetX = ImMax(window->DC.ColumnsStartX, style.ItemSpacing.x);
|
window->DC.MenuBarOffsetX = ImMax(window->DC.ColumnsStartX, style.ItemSpacing.x);
|
||||||
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f;
|
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f;
|
||||||
window->DC.ChildWindows.resize(0);
|
window->DC.ChildWindows.resize(0);
|
||||||
window->DC.ItemWidth.resize(0);
|
|
||||||
window->DC.ItemWidth.push_back(window->ItemWidthDefault);
|
|
||||||
window->DC.LayoutType = ImGuiLayoutType_Vertical;
|
window->DC.LayoutType = ImGuiLayoutType_Vertical;
|
||||||
|
window->DC.ItemWidthStack.resize(0);
|
||||||
|
window->DC.ItemWidthStack.push_back(window->ItemWidthDefault);
|
||||||
|
window->DC.ItemWidth = window->ItemWidthDefault;
|
||||||
window->DC.ButtonRepeat = false;
|
window->DC.ButtonRepeat = false;
|
||||||
window->DC.ButtonRepeatStack.resize(0);
|
window->DC.ButtonRepeatStack.resize(0);
|
||||||
window->DC.AllowKeyboardFocus.resize(0);
|
window->DC.AllowKeyboardFocus = true;
|
||||||
window->DC.AllowKeyboardFocus.push_back(true);
|
window->DC.AllowKeyboardFocusStack.resize(0);
|
||||||
window->DC.TextWrapPos.resize(0);
|
window->DC.TextWrapPos = -1.0f; // disabled
|
||||||
window->DC.TextWrapPos.push_back(-1.0f); // disabled
|
window->DC.TextWrapPosStack.resize(0);
|
||||||
window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect;
|
window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect;
|
||||||
window->DC.ColumnsCurrent = 0;
|
window->DC.ColumnsCurrent = 0;
|
||||||
window->DC.ColumnsCount = 1;
|
window->DC.ColumnsCount = 1;
|
||||||
@ -4004,7 +4009,8 @@ static void FocusWindow(ImGuiWindow* window)
|
|||||||
void ImGui::PushItemWidth(float item_width)
|
void ImGui::PushItemWidth(float item_width)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
window->DC.ItemWidth.push_back(item_width == 0.0f ? window->ItemWidthDefault : item_width);
|
window->DC.ItemWidth = (item_width == 0.0f ? window->ItemWidthDefault : item_width);
|
||||||
|
window->DC.ItemWidthStack.push_back(window->DC.ItemWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PushMultiItemsWidths(int components, float w_full = 0.0f)
|
static void PushMultiItemsWidths(int components, float w_full = 0.0f)
|
||||||
@ -4015,21 +4021,23 @@ static void PushMultiItemsWidths(int components, float w_full = 0.0f)
|
|||||||
w_full = ImGui::CalcItemWidth();
|
w_full = ImGui::CalcItemWidth();
|
||||||
const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components));
|
const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components));
|
||||||
const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)));
|
const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)));
|
||||||
window->DC.ItemWidth.push_back(w_item_last);
|
window->DC.ItemWidthStack.push_back(w_item_last);
|
||||||
for (int i = 0; i < components-1; i++)
|
for (int i = 0; i < components-1; i++)
|
||||||
window->DC.ItemWidth.push_back(w_item_one);
|
window->DC.ItemWidthStack.push_back(w_item_one);
|
||||||
|
window->DC.ItemWidth = window->DC.ItemWidthStack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::PopItemWidth()
|
void ImGui::PopItemWidth()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
window->DC.ItemWidth.pop_back();
|
window->DC.ItemWidthStack.pop_back();
|
||||||
|
window->DC.ItemWidth = window->DC.ItemWidthStack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
float ImGui::CalcItemWidth()
|
float ImGui::CalcItemWidth()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
float w = window->DC.ItemWidth.back();
|
float w = window->DC.ItemWidth;
|
||||||
if (w < 0.0f)
|
if (w < 0.0f)
|
||||||
{
|
{
|
||||||
// Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well.
|
// Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well.
|
||||||
@ -4073,13 +4081,15 @@ void ImGui::PopFont()
|
|||||||
void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus)
|
void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
window->DC.AllowKeyboardFocus.push_back(allow_keyboard_focus);
|
window->DC.AllowKeyboardFocus = allow_keyboard_focus;
|
||||||
|
window->DC.AllowKeyboardFocusStack.push_back(allow_keyboard_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::PopAllowKeyboardFocus()
|
void ImGui::PopAllowKeyboardFocus()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
window->DC.AllowKeyboardFocus.pop_back();
|
window->DC.AllowKeyboardFocusStack.pop_back();
|
||||||
|
window->DC.AllowKeyboardFocus = window->DC.AllowKeyboardFocusStack.empty() ? true : window->DC.AllowKeyboardFocusStack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::PushButtonRepeat(bool repeat)
|
void ImGui::PushButtonRepeat(bool repeat)
|
||||||
@ -4096,16 +4106,18 @@ void ImGui::PopButtonRepeat()
|
|||||||
window->DC.ButtonRepeat = window->DC.ButtonRepeatStack.empty() ? false : window->DC.ButtonRepeatStack.back();
|
window->DC.ButtonRepeat = window->DC.ButtonRepeatStack.empty() ? false : window->DC.ButtonRepeatStack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::PushTextWrapPos(float wrap_x)
|
void ImGui::PushTextWrapPos(float wrap_pos_x)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
window->DC.TextWrapPos.push_back(wrap_x);
|
window->DC.TextWrapPos = wrap_pos_x;
|
||||||
|
window->DC.TextWrapPosStack.push_back(wrap_pos_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::PopTextWrapPos()
|
void ImGui::PopTextWrapPos()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
window->DC.TextWrapPos.pop_back();
|
window->DC.TextWrapPosStack.pop_back();
|
||||||
|
window->DC.TextWrapPos = window->DC.TextWrapPosStack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
|
void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
|
||||||
@ -4661,7 +4673,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
|
|||||||
if (text_end == NULL)
|
if (text_end == NULL)
|
||||||
text_end = text + strlen(text); // FIXME-OPT
|
text_end = text + strlen(text); // FIXME-OPT
|
||||||
|
|
||||||
const float wrap_pos_x = window->DC.TextWrapPos.back();
|
const float wrap_pos_x = window->DC.TextWrapPos;
|
||||||
const bool wrap_enabled = wrap_pos_x >= 0.0f;
|
const bool wrap_enabled = wrap_pos_x >= 0.0f;
|
||||||
if (text_end - text > 2000 && !wrap_enabled)
|
if (text_end - text > 2000 && !wrap_enabled)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user