A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

94 lines
3.8 KiB

using System.Diagnostics;
using System.Diagnostics.Metrics;
using Avalonia.Interactivity;
using Avalonia.Threading;
using Avalonia.Utilities;
namespace Avalonia.Diagnostics;
internal static partial class Diagnostic
{
private static Histogram<double>? s_compositorRender;
private static Histogram<double>? s_compositorUpdate;
private static Histogram<double>? s_layoutMeasure;
private static Histogram<double>? s_layoutArrange;
private static Histogram<double>? s_layoutRender;
private static Histogram<double>? s_layoutInput;
public static void InitMetrics()
{
// Metrics
var meter = new Meter("Avalonia.Diagnostic.Meter");
s_compositorRender = meter.CreateHistogram<double>(
Meters.CompositorRenderPassName,
Meters.MillisecondsUnit,
Meters.CompositorRenderPassDescription);
s_compositorUpdate = meter.CreateHistogram<double>(
Meters.CompositorUpdatePassName,
Meters.MillisecondsUnit,
Meters.CompositorUpdatePassDescription);
s_layoutMeasure = meter.CreateHistogram<double>(
Meters.LayoutMeasurePassName,
Meters.MillisecondsUnit,
Meters.LayoutMeasurePassDescription);
s_layoutArrange = meter.CreateHistogram<double>(
Meters.LayoutArrangePassName,
Meters.MillisecondsUnit,
Meters.LayoutArrangePassDescription);
s_layoutRender = meter.CreateHistogram<double>(
Meters.LayoutRenderPassName,
Meters.MillisecondsUnit,
Meters.LayoutRenderPassDescription);
s_layoutInput = meter.CreateHistogram<double>(
Meters.LayoutInputPassName,
Meters.MillisecondsUnit,
Meters.LayoutInputPassDescription);
meter.CreateObservableUpDownCounter(
Meters.TotalEventHandleCountName,
() => Interactive.TotalHandlersCount,
Meters.TotalEventHandleCountUnit,
Meters.TotalEventHandleCountDescription);
meter.CreateObservableUpDownCounter(
Meters.TotalVisualCountName,
() => Visual.RootedVisualChildrenCount,
Meters.TotalVisualCountUnit,
Meters.TotalVisualCountDescription);
meter.CreateObservableUpDownCounter(
Meters.TotalDispatcherTimerCountName,
() => DispatcherTimer.ActiveTimersCount,
Meters.TotalDispatcherTimerCountUnit,
Meters.TotalDispatcherTimerCountDescription);
}
public static HistogramReportDisposable BeginCompositorRenderPass() => Begin(s_compositorRender);
public static HistogramReportDisposable BeginCompositorUpdatePass() => Begin(s_compositorUpdate);
public static HistogramReportDisposable BeginLayoutMeasurePass() => Begin(s_layoutMeasure);
public static HistogramReportDisposable BeginLayoutArrangePass() => Begin(s_layoutArrange);
public static HistogramReportDisposable BeginLayoutInputPass() => Begin(s_layoutInput);
public static HistogramReportDisposable BeginLayoutRenderPass() => Begin(s_layoutRender);
private static HistogramReportDisposable Begin(Histogram<double>? histogram) => histogram is not null ? new(histogram) : default;
internal readonly ref struct HistogramReportDisposable
{
private readonly Histogram<double> _histogram;
private readonly long _timestamp;
public HistogramReportDisposable(Histogram<double> histogram)
{
_histogram = histogram;
if (histogram.Enabled)
{
_timestamp = Stopwatch.GetTimestamp();
}
}
public void Dispose()
{
if (_timestamp > 0)
{
_histogram.Record(StopwatchHelper.GetElapsedTimeMs(_timestamp));
}
}
}
}