From 579dbaa25cf74ee4ebc8830ad5de1675cd8d3e66 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 24 Jun 2022 04:41:51 +0300 Subject: [PATCH] Report renderer transport pool memory usage in fps line --- src/Avalonia.Base/Avalonia.Base.csproj | 1 + .../Rendering/Composition/Server/FpsCounter.cs | 4 ++-- .../Composition/Server/ServerCompositionTarget.cs | 15 ++++++++++++--- .../Composition/Server/ServerCompositor.cs | 10 +++++----- .../Composition/Transport/BatchStreamArrayPool.cs | 11 +++++++---- .../Utilities}/ByteSizeHelper.cs | 9 +++++---- src/Avalonia.Dialogs/FileSizeStringConverter.cs | 2 +- src/Avalonia.Dialogs/ManagedFileChooserSources.cs | 3 ++- 8 files changed, 35 insertions(+), 20 deletions(-) rename src/{Avalonia.Dialogs => Avalonia.Base/Utilities}/ByteSizeHelper.cs (70%) diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj index 4c988c8ae1..15feed388b 100644 --- a/src/Avalonia.Base/Avalonia.Base.csproj +++ b/src/Avalonia.Base/Avalonia.Base.csproj @@ -35,6 +35,7 @@ + diff --git a/src/Avalonia.Base/Rendering/Composition/Server/FpsCounter.cs b/src/Avalonia.Base/Rendering/Composition/Server/FpsCounter.cs index a09de2c0ff..7585710540 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/FpsCounter.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/FpsCounter.cs @@ -35,7 +35,7 @@ internal class FpsCounter public void FpsTick() => _framesThisSecond++; - public void RenderFps(IDrawingContextImpl context) + public void RenderFps(IDrawingContextImpl context, string aux) { var now = _stopwatch.Elapsed; var elapsed = now - _lastFpsUpdate; @@ -50,7 +50,7 @@ internal class FpsCounter _lastFpsUpdate = now; } - var fpsLine = $"Frame #{_totalFrames:00000000} FPS: {_fps:000}"; + var fpsLine = $"Frame #{_totalFrames:00000000} FPS: {_fps:000} " + aux; double width = 0; double height = 0; foreach (var ch in fpsLine) diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs index 749665156d..5ec5df8416 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs @@ -134,10 +134,19 @@ namespace Avalonia.Rendering.Composition.Server , null, _dirtyRect); } - if(DrawFps) - _fpsCounter.RenderFps(targetContext); + if (DrawFps) + { + var nativeMem = ByteSizeHelper.ToString((ulong)( + (Compositor.BatchMemoryPool.CurrentUsage + Compositor.BatchMemoryPool.CurrentPool) * + Compositor.BatchMemoryPool.BufferSize), false); + var managedMem = ByteSizeHelper.ToString((ulong)( + (Compositor.BatchObjectPool.CurrentUsage + Compositor.BatchObjectPool.CurrentPool) * + Compositor.BatchObjectPool.ArraySize * + IntPtr.Size), false); + _fpsCounter.RenderFps(targetContext, $"M:{managedMem} / N:{nativeMem}"); + } + _dirtyRect = Rect.Empty; - } } diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs index 73792fdf98..564f792ebe 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs @@ -24,8 +24,8 @@ namespace Avalonia.Rendering.Composition.Server private List _activeTargets = new(); private HashSet _activeAnimations = new(); private List _animationsToUpdate = new(); - private BatchStreamObjectPool _batchObjectPool; - private BatchStreamMemoryPool _batchMemoryPool; + internal BatchStreamObjectPool BatchObjectPool; + internal BatchStreamMemoryPool BatchMemoryPool; private object _lock = new object(); public IPlatformGpuContext? GpuContext { get; } @@ -34,8 +34,8 @@ namespace Avalonia.Rendering.Composition.Server { GpuContext = platformGpu?.PrimaryContext; _renderLoop = renderLoop; - _batchObjectPool = batchObjectPool; - _batchMemoryPool = batchMemoryPool; + BatchObjectPool = batchObjectPool; + BatchMemoryPool = batchMemoryPool; _renderLoop.Add(this); } @@ -60,7 +60,7 @@ namespace Avalonia.Rendering.Composition.Server batch = _batches.Dequeue(); } - using (var stream = new BatchStreamReader(batch.Changes, _batchMemoryPool, _batchObjectPool)) + using (var stream = new BatchStreamReader(batch.Changes, BatchMemoryPool, BatchObjectPool)) { while (!stream.IsObjectEof) { diff --git a/src/Avalonia.Base/Rendering/Composition/Transport/BatchStreamArrayPool.cs b/src/Avalonia.Base/Rendering/Composition/Transport/BatchStreamArrayPool.cs index 97d05704af..32b4ed3026 100644 --- a/src/Avalonia.Base/Rendering/Composition/Transport/BatchStreamArrayPool.cs +++ b/src/Avalonia.Base/Rendering/Composition/Transport/BatchStreamArrayPool.cs @@ -18,6 +18,9 @@ internal abstract class BatchStreamPoolBase : IDisposable readonly int[] _usageStatistics = new int[10]; int _usageStatisticsSlot; + public int CurrentUsage => _usage; + public int CurrentPool => _pool.Count; + public BatchStreamPoolBase(bool needsFinalize, Action>? startTimer = null) { if(!needsFinalize) @@ -116,16 +119,16 @@ internal abstract class BatchStreamPoolBase : IDisposable internal sealed class BatchStreamObjectPool : BatchStreamPoolBase where T : class? { - private readonly int _arraySize; + public int ArraySize { get; } - public BatchStreamObjectPool(int arraySize = 1024, Action>? startTimer = null) : base(false, startTimer) + public BatchStreamObjectPool(int arraySize = 128, Action>? startTimer = null) : base(false, startTimer) { - _arraySize = arraySize; + ArraySize = arraySize; } protected override T[] CreateItem() { - return new T[_arraySize]; + return new T[ArraySize]; } protected override void DestroyItem(T[] item) diff --git a/src/Avalonia.Dialogs/ByteSizeHelper.cs b/src/Avalonia.Base/Utilities/ByteSizeHelper.cs similarity index 70% rename from src/Avalonia.Dialogs/ByteSizeHelper.cs rename to src/Avalonia.Base/Utilities/ByteSizeHelper.cs index d849e33399..edaf94231b 100644 --- a/src/Avalonia.Dialogs/ByteSizeHelper.cs +++ b/src/Avalonia.Base/Utilities/ByteSizeHelper.cs @@ -1,10 +1,11 @@ using System; -namespace Avalonia.Dialogs +namespace Avalonia.Utilities { internal static class ByteSizeHelper { - private const string formatTemplate = "{0}{1:0.#} {2}"; + private const string formatTemplateSeparated = "{0}{1:0.#} {2}"; + private const string formatTemplate = "{0}{1:0.#}{2}"; private static readonly string[] Prefixes = { @@ -19,11 +20,11 @@ namespace Avalonia.Dialogs "YB" }; - public static string ToString(ulong bytes) + public static string ToString(ulong bytes, bool separate) { if (bytes == 0) { - return string.Format(formatTemplate, null, 0, Prefixes[0]); + return string.Format(separate ? formatTemplateSeparated : formatTemplate, null, 0, Prefixes[0]); } var absSize = Math.Abs((double)bytes); diff --git a/src/Avalonia.Dialogs/FileSizeStringConverter.cs b/src/Avalonia.Dialogs/FileSizeStringConverter.cs index c2cdf1e502..144f50fd9c 100644 --- a/src/Avalonia.Dialogs/FileSizeStringConverter.cs +++ b/src/Avalonia.Dialogs/FileSizeStringConverter.cs @@ -12,7 +12,7 @@ namespace Avalonia.Dialogs { if (value is long size && size > 0) { - return ByteSizeHelper.ToString((ulong)size); + return Avalonia.Utilities.ByteSizeHelper.ToString((ulong)size, true); } return ""; diff --git a/src/Avalonia.Dialogs/ManagedFileChooserSources.cs b/src/Avalonia.Dialogs/ManagedFileChooserSources.cs index a217a67bc6..a76a84ba5a 100644 --- a/src/Avalonia.Dialogs/ManagedFileChooserSources.cs +++ b/src/Avalonia.Dialogs/ManagedFileChooserSources.cs @@ -6,6 +6,7 @@ using System.Reactive.Linq; using System.Runtime.InteropServices; using Avalonia.Controls.Platform; using Avalonia.Threading; +using Avalonia.Utilities; namespace Avalonia.Dialogs { @@ -60,7 +61,7 @@ namespace Avalonia.Dialogs if (displayName == null & x.VolumeSizeBytes > 0) { - displayName = $"{ByteSizeHelper.ToString(x.VolumeSizeBytes)} Volume"; + displayName = $"{ByteSizeHelper.ToString(x.VolumeSizeBytes, true)} Volume"; }; try