Optimisation, removed the duplicate ClipRectStack in ImGuiWindow, storing single value

This commit is contained in:
ocornut 2015-07-06 21:46:12 -06:00
parent d6987d1586
commit b92396b46a

View File

@ -1442,8 +1442,8 @@ struct ImGuiWindow
ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame
ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack
ImVector<ImVec4> ClipRectStack; // Scissoring / clipping rectangle. x1, y1, x2, y2. ImVec4 ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2.
ImRect ClippedRect; // = ClipRectStack.front() after setup in Begin() ImRect ClippedWindowRect; // = ClipRect just after setup in Begin()
int LastFrameDrawn; int LastFrameDrawn;
float ItemWidthDefault; float ItemWidthDefault;
ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items
@ -2358,25 +2358,25 @@ static void PushClipRect(const ImVec4& clip_rect, bool clipped = true)
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
ImVec4 cr = clip_rect; ImVec4 cr = clip_rect;
if (clipped && !window->ClipRectStack.empty()) if (clipped)
{ {
// Clip with existing clip rect // Clip with existing clip rect
const ImVec4 cur_cr = window->ClipRectStack.back(); const ImVec4 cur_cr = window->ClipRect;
cr = ImVec4(ImMax(cr.x, cur_cr.x), ImMax(cr.y, cur_cr.y), ImMin(cr.z, cur_cr.z), ImMin(cr.w, cur_cr.w)); cr = ImVec4(ImMax(cr.x, cur_cr.x), ImMax(cr.y, cur_cr.y), ImMin(cr.z, cur_cr.z), ImMin(cr.w, cur_cr.w));
} }
cr.z = ImMax(cr.x, cr.z); cr.z = ImMax(cr.x, cr.z);
cr.w = ImMax(cr.y, cr.w); cr.w = ImMax(cr.y, cr.w);
IM_ASSERT(cr.x <= cr.z && cr.y <= cr.w); IM_ASSERT(cr.x <= cr.z && cr.y <= cr.w);
window->ClipRectStack.push_back(cr); window->ClipRect = cr;
window->DrawList->PushClipRect(cr); window->DrawList->PushClipRect(cr);
} }
static void PopClipRect() static void PopClipRect()
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
window->ClipRectStack.pop_back();
window->DrawList->PopClipRect(); window->DrawList->PopClipRect();
window->ClipRect = window->DrawList->clip_rect_stack.back();
} }
void ImGui::Render() void ImGui::Render()
@ -2812,9 +2812,8 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
} }
const ImVec2 pos = window->DC.CursorPos; const ImVec2 pos = window->DC.CursorPos;
const ImVec4 clip_rect = window->ClipRectStack.back(); const float clip_y1 = window->ClipRect.y;
const float clip_y1 = clip_rect.y; const float clip_y2 = window->ClipRect.w;
const float clip_y2 = clip_rect.w;
int start = (int)((clip_y1 - pos.y) / items_height); int start = (int)((clip_y1 - pos.y) / items_height);
int end = (int)((clip_y2 - pos.y) / items_height); int end = (int)((clip_y2 - pos.y) / items_height);
@ -2837,7 +2836,7 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs)
continue; continue;
// Using the clipped AABB so a child window will typically be clipped by its parent. // Using the clipped AABB so a child window will typically be clipped by its parent.
ImRect bb(window->ClippedRect.Min - g.Style.TouchExtraPadding, window->ClippedRect.Max + g.Style.TouchExtraPadding); ImRect bb(window->ClippedWindowRect.Min - g.Style.TouchExtraPadding, window->ClippedWindowRect.Max + g.Style.TouchExtraPadding);
if (bb.Contains(pos)) if (bb.Contains(pos))
return window; return window;
} }
@ -2854,11 +2853,7 @@ static bool IsMouseHoveringRect(const ImRect& rect)
// Clip // Clip
ImRect rect_clipped = rect; ImRect rect_clipped = rect;
if (!window->ClipRectStack.empty()) rect_clipped.Clip(window->ClipRect);
{
const ImVec4 clip_rect = window->ClipRectStack.back();
rect_clipped.Clip(ImRect(ImVec2(clip_rect.x, clip_rect.y), ImVec2(clip_rect.z, clip_rect.w)));
}
// Expand for touch input // Expand for touch input
const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding);
@ -3066,7 +3061,7 @@ bool ImGui::IsAnyItemActive()
bool ImGui::IsItemVisible() bool ImGui::IsItemVisible()
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
ImRect r(window->ClipRectStack.back()); ImRect r(window->ClipRect);
return r.Overlaps(window->DC.LastItemRect); return r.Overlaps(window->DC.LastItemRect);
} }
@ -3659,14 +3654,14 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
window->Active = true; window->Active = true;
window->BeginCount = 0; window->BeginCount = 0;
window->DrawList->Clear(); window->DrawList->Clear();
window->ClipRectStack.resize(0); window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
window->LastFrameDrawn = current_frame; window->LastFrameDrawn = current_frame;
window->IDStack.resize(1); window->IDStack.resize(1);
// Setup texture, outer clipping rectangle // Setup texture, outer clipping rectangle
window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ComboBox|ImGuiWindowFlags_Popup))) if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ComboBox|ImGuiWindowFlags_Popup)))
PushClipRect(parent_window->ClipRectStack.back()); PushClipRect(parent_window->ClipRect);
else else
PushClipRect(GetVisibleRect()); PushClipRect(GetVisibleRect());
@ -4053,8 +4048,8 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
} }
// Save clipped aabb so we can access it in constant-time in FindHoveredWindow() // Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
window->ClippedRect = window->Rect(); window->ClippedWindowRect = window->Rect();
window->ClippedRect.Clip(window->ClipRectStack.front()); window->ClippedWindowRect.Clip(window->ClipRect);
// Pressing CTRL+C while holding on a window copy its content to the clipboard // Pressing CTRL+C while holding on a window copy its content to the clipboard
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
@ -4089,7 +4084,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
{ {
const ImVec4 clip_rect_t = window->ClipRectStack.back(); const ImVec4 clip_rect_t = window->ClipRect;
window->Collapsed |= (clip_rect_t.x >= clip_rect_t.z || clip_rect_t.y >= clip_rect_t.w); window->Collapsed |= (clip_rect_t.x >= clip_rect_t.z || clip_rect_t.y >= clip_rect_t.w);
} }
@ -4968,7 +4963,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
const char* line = text; const char* line = text;
const float line_height = ImGui::GetTextLineHeight(); const float line_height = ImGui::GetTextLineHeight();
const ImVec2 text_pos = window->DC.CursorPos + ImVec2(0.0f, window->DC.CurrentLineTextBaseOffset); const ImVec2 text_pos = window->DC.CursorPos + ImVec2(0.0f, window->DC.CurrentLineTextBaseOffset);
const ImVec4 clip_rect = window->ClipRectStack.back(); const ImVec4 clip_rect = window->ClipRect;
ImVec2 text_size(0,0); ImVec2 text_size(0,0);
if (text_pos.y <= clip_rect.w) if (text_pos.y <= clip_rect.w)
@ -8499,7 +8494,7 @@ static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
if (!bb.Overlaps(ImRect(window->ClipRectStack.back()))) if (!bb.Overlaps(ImRect(window->ClipRect)))
{ {
if (!id || *id != GImGui->ActiveId) if (!id || *id != GImGui->ActiveId)
if (clip_even_when_logged || !g.LogEnabled) if (clip_even_when_logged || !g.LogEnabled)
@ -8511,7 +8506,7 @@ static bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when
bool ImGui::IsRectVisible(const ImVec2& size) bool ImGui::IsRectVisible(const ImVec2& size)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
ImRect r(window->ClipRectStack.back()); ImRect r(window->ClipRect);
return r.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); return r.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size));
} }