Files
sbox-public/engine/Sandbox.Engine/Systems/UI/Render/DebugOverlay.UI.cs
Matt Stevens 0ca4a90e28 UI panels that use backdrops can be batched (#4735)
* Panels with backdrop filters are batched now and reuse the same frame grab, break batch on Z groups

Before: https://files.facepunch.com/matt/1b0311b1/sbox_HB6vN6Reo6.png
After: https://files.facepunch.com/matt/1b0311b1/sbox_gFO4enjxiv.png

* Save backdropGrabActive, panel children can't share a backdrop (if they use one) since they won't contain the fresh quad, but siblings can use the same backdrop still

Fixes overlapping blurred panels using the original frame grab e.g Sandbox:

Before: https://files.facepunch.com/matt/1b0311b1/sbox_M8xXVyxcsF.png
After: https://files.facepunch.com/matt/1b0311b1/sbox_RePJDF3HWW.png

(Even though Sandbox shouldn't be layering 3 blurred panels on top of each other)
2026-05-04 09:05:14 +01:00

60 lines
2.4 KiB
C#

namespace Sandbox;
internal static partial class DebugOverlay
{
[ConVar( "overlay_ui", Help = "Draws an overlay showing UI batching stats" )]
internal static int overlay_ui { get; set; } = 0;
public partial class UI
{
static readonly TextRendering.Outline _outline = new() { Color = Color.Black, Size = 2, Enabled = true };
internal static void Draw( ref Vector2 pos )
{
var s = Sandbox.UI.PanelRenderer.Stats;
var drawPos = new Vector2( pos.x + 24, pos.y );
var startY = drawPos.y;
DrawHeader( ref drawPos, "UI Batching" );
Row( ref drawPos, "Panels", s.Panels, $"({s.BatchedPanels} batched, {s.InlinePanels} inline, {s.LayerPanels} layer)" );
Row( ref drawPos, "Draw Calls", s.DrawCalls );
Row( ref drawPos, "Frame Grabs", s.FrameGrabs );
Row( ref drawPos, "Flushes", s.FlushCount, s.FlushCount > 0 ? $"avg {s.InstanceCount / s.FlushCount} instances" : null );
Row( ref drawPos, "Instances", s.InstanceCount );
Row( ref drawPos, "Scissors", s.ScissorCount );
drawPos.y += 6;
DrawHeader( ref drawPos, "UI Memory" );
Row( ref drawPos, "RenderLayers", Sandbox.UI.RenderLayer.ActiveCount, $"({Sandbox.UI.RenderLayer.PoolCount} pooled)" );
Row( ref drawPos, "GpuBuffers", s.GpuBufferCount );
pos.y += MathF.Max( 0, drawPos.y - startY );
}
static void DrawHeader( ref Vector2 pos, string label )
{
var rect = new Rect( pos, new Vector2( 512, 18 ) );
var scope = new TextRendering.Scope( label, Color.White.WithAlpha( 0.9f ), 11, "Roboto Mono", 700 ) { Outline = _outline };
Hud.DrawText( scope, rect, TextFlag.LeftCenter );
pos.y += 18;
}
static void Row( ref Vector2 pos, string label, int value, string detail = null )
{
var rect = new Rect( pos, new Vector2( 560, 14 ) );
var scope = new TextRendering.Scope( label, Color.White.WithAlpha( 0.8f ), 11, "Roboto Mono", 600 ) { Outline = _outline };
Hud.DrawText( scope, rect with { Width = 120 }, TextFlag.RightCenter );
scope.TextColor = value > 0 ? Color.White : Color.White.WithAlpha( 0.5f );
scope.Text = value.ToString( "N0" );
Hud.DrawText( scope, rect with { Left = rect.Left + 128, Width = detail is null ? 420 : 90 }, TextFlag.LeftCenter );
if ( detail is not null )
{
scope.TextColor = Color.White.WithAlpha( 0.75f );
scope.Text = detail;
Hud.DrawText( scope, rect with { Left = rect.Left + 228, Width = 320 }, TextFlag.LeftCenter );
}
pos.y += rect.Height;
}
}
}