DrawList: Optimize AddRectFilled()

- detect and draw non-rounded non-AA rect with less branches and calculations
- improves new AddRectFilled() overhead from 30% to 5-10%
This commit is contained in:
Mikko Mononen 2026-06-15 21:07:08 +03:00 committed by ocornut
parent c5c76dcda5
commit 145b838818

View File

@ -2917,17 +2917,27 @@ void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 c
return; return;
} }
if ((flags & ImDrawFlags_RoundCornersMask_) == 0) const bool has_rounding = (flags & ImDrawFlags_RoundCornersMask_) != ImDrawFlags_RoundCornersNone && IM_HAS_ROUNDING(rounding);
flags |= ImDrawFlags_RoundCornersAll;
const bool is_truncated = IM_IS_TRUNCATED4(p_min.x, p_min.y, p_max.x, p_max.y) && IM_IS_TRUNCATED(rounding); const bool is_truncated = IM_IS_TRUNCATED4(p_min.x, p_min.y, p_max.x, p_max.y) && IM_IS_TRUNCATED(rounding);
if (_FringeScaleIsInteger && is_truncated) if (_FringeScaleIsInteger && is_truncated)
{ {
// Fast path for the non-AA non-rounded rect.
if (!has_rounding)
{
PrimReserve(6, 4);
PrimRect(p_min, p_max, col);
return;
}
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
flags |= ImDrawFlags_RoundCornersAll;
rounding = ImMin(rounding, ImFabs(width) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f); rounding = ImMin(rounding, ImFabs(width) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f);
rounding = ImMin(rounding, ImFabs(height) * (((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f) - 1.0f); rounding = ImMin(rounding, ImFabs(height) * (((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f) - 1.0f);
const int s_rounding = (int)(rounding * _InvFringeScale); const int s_rounding = (int)(rounding * _InvFringeScale);
if (s_rounding <= 0 || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) if (s_rounding <= 0)
{ {
PrimReserve(6, 4); PrimReserve(6, 4);
PrimRect(p_min, p_max, col); PrimRect(p_min, p_max, col);
@ -2947,8 +2957,7 @@ void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 c
} }
} }
const bool has_rounding = (rounding >= _FringeScale * 0.5f); if (!has_rounding)
if (!has_rounding || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
{ {
const ImVec2 points[4] = { p_min, ImVec2(p_max.x, p_min.y), p_max, ImVec2(p_min.x, p_max.y) }; const ImVec2 points[4] = { p_min, ImVec2(p_max.x, p_min.y), p_max, ImVec2(p_min.x, p_max.y) };
AddConvexPolyFilled(points, 4, col, ImDrawFlags_MiterOnly); AddConvexPolyFilled(points, 4, col, ImDrawFlags_MiterOnly);