A game framework written with osu! in mind.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'master' into remove-texture-upload-finalizer-overhead

authored by

Dan Balasescu and committed by
GitHub
d5645b39 3f4961e5

+37 -10
+8 -3
osu.Framework/Graphics/Performance/FrameStatisticsDisplay.cs
··· 18 18 using osu.Framework.Input.Events; 19 19 using osuTK; 20 20 using SixLabors.ImageSharp; 21 + using SixLabors.ImageSharp.Memory; 21 22 using SixLabors.ImageSharp.PixelFormats; 22 23 23 24 namespace osu.Framework.Graphics.Performance 24 25 { 25 26 internal class FrameStatisticsDisplay : Container, IStateful<FrameStatisticsMode> 26 27 { 28 + internal const int HEIGHT = 100; 29 + 27 30 protected const int WIDTH = 800; 28 - protected const int HEIGHT = 100; 29 31 30 32 private const int amount_count_steps = 5; 31 33 ··· 51 53 52 54 private readonly Container mainContainer; 53 55 private readonly Container timeBarsContainer; 56 + 57 + private readonly MemoryAllocator uploadAllocator; 54 58 55 59 private readonly Drawable[] legendMapping = new Drawable[FrameStatistics.NUM_PERFORMANCE_COLLECTION_TYPES]; 56 60 private readonly Dictionary<StatisticsCounterType, CounterBar> counterBars = new Dictionary<StatisticsCounterType, CounterBar>(); ··· 99 103 } 100 104 } 101 105 102 - public FrameStatisticsDisplay(GameThread thread) 106 + public FrameStatisticsDisplay(GameThread thread, MemoryAllocator uploadAllocator) 103 107 { 104 108 Name = thread.Name; 105 109 monitor = thread.Monitor; 110 + this.uploadAllocator = uploadAllocator; 106 111 107 112 Origin = Anchor.TopRight; 108 113 AutoSizeAxes = Axes.Both; ··· 346 351 private void applyFrameTime(FrameStatistics frame) 347 352 { 348 353 TimeBar timeBar = timeBars[timeBarIndex]; 349 - var upload = new ArrayPoolTextureUpload(1, HEIGHT) 354 + var upload = new ArrayPoolTextureUpload(1, HEIGHT, uploadAllocator) 350 355 { 351 356 Bounds = new RectangleI(timeBarX, 0, 1, HEIGHT) 352 357 };
+23 -3
osu.Framework/Graphics/Performance/PerformanceOverlay.cs
··· 5 5 using osu.Framework.Graphics.Containers; 6 6 using osu.Framework.Threading; 7 7 using System.Collections.Generic; 8 + using System.Linq; 9 + using System.Runtime.CompilerServices; 10 + using SixLabors.ImageSharp.Memory; 11 + using SixLabors.ImageSharp.PixelFormats; 8 12 9 13 namespace osu.Framework.Graphics.Performance 10 14 { 11 15 internal class PerformanceOverlay : FillFlowContainer<FrameStatisticsDisplay>, IStateful<FrameStatisticsMode> 12 16 { 13 - private readonly IEnumerable<GameThread> threads; 17 + private readonly GameThread[] threads; 14 18 private FrameStatisticsMode state; 15 19 16 20 public event Action<FrameStatisticsMode> StateChanged; ··· 50 54 if (!initialised) 51 55 { 52 56 initialised = true; 57 + 58 + var uploadPool = createUploadPool(); 59 + 53 60 foreach (GameThread t in threads) 54 - Add(new FrameStatisticsDisplay(t) { State = state }); 61 + Add(new FrameStatisticsDisplay(t, uploadPool) { State = state }); 55 62 } 56 63 57 64 this.FadeIn(100); ··· 64 71 StateChanged?.Invoke(State); 65 72 } 66 73 74 + private ArrayPoolMemoryAllocator createUploadPool() 75 + { 76 + int uploadSize = FrameStatisticsDisplay.HEIGHT * Unsafe.SizeOf<Rgba32>(); 77 + 78 + // bucket size should be enough to allow some overhead when running multi-threaded with draw at 60hz. 79 + const int max_expected_thread_update_rate = 2000; 80 + 81 + int bucketSize = threads.Length * (max_expected_thread_update_rate / 60); 82 + 83 + // we already know the fixed size of uploads so there's no need to use i#'s two-tiered pooling system. 84 + return new ArrayPoolMemoryAllocator(uploadSize, uploadSize, 1, bucketSize); 85 + } 86 + 67 87 public PerformanceOverlay(IEnumerable<GameThread> threads) 68 88 { 69 - this.threads = threads; 89 + this.threads = threads.ToArray(); 70 90 Direction = FillDirection.Vertical; 71 91 } 72 92 }
+4 -2
osu.Framework/Graphics/Textures/ArrayPoolTextureUpload.cs
··· 5 5 using System.Buffers; 6 6 using osu.Framework.Graphics.Primitives; 7 7 using osuTK.Graphics.ES30; 8 + using SixLabors.ImageSharp.Memory; 8 9 using SixLabors.ImageSharp.PixelFormats; 9 10 10 11 namespace osu.Framework.Graphics.Textures ··· 37 38 /// </summary> 38 39 /// <param name="width">The width of the texture.</param> 39 40 /// <param name="height">The height of the texture.</param> 40 - public ArrayPoolTextureUpload(int width, int height) 41 + /// <param name="memoryAllocator">The source to retrieve memory from. Shared default is used if null.</param> 42 + public ArrayPoolTextureUpload(int width, int height, MemoryAllocator memoryAllocator = null) 41 43 { 42 - memoryOwner = SixLabors.ImageSharp.Configuration.Default.MemoryAllocator.Allocate<Rgba32>(width * height); 44 + memoryOwner = (memoryAllocator ?? SixLabors.ImageSharp.Configuration.Default.MemoryAllocator).Allocate<Rgba32>(width * height); 43 45 } 44 46 45 47 // ReSharper disable once ConvertToAutoPropertyWithPrivateSetter
+2 -2
osu.Framework/Graphics/Video/VideoTextureUpload.cs
··· 10 10 11 11 namespace osu.Framework.Graphics.Video 12 12 { 13 - public unsafe class VideoTextureUpload : ITextureUpload 13 + public sealed unsafe class VideoTextureUpload : ITextureUpload 14 14 { 15 15 public readonly AVFrame* Frame; 16 16 ··· 29 29 /// </summary> 30 30 /// <param name="frame">The frame to upload.</param> 31 31 /// <param name="freeFrameDelegate">A function to free the frame on disposal.</param> 32 - public VideoTextureUpload(AVFrame* frame, FFmpegFuncs.AvFrameFreeDelegate freeFrameDelegate) 32 + internal VideoTextureUpload(AVFrame* frame, FFmpegFuncs.AvFrameFreeDelegate freeFrameDelegate) 33 33 { 34 34 Frame = frame; 35 35 this.freeFrameDelegate = freeFrameDelegate;