A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5using System.Buffers;
6using osu.Framework.Graphics.Containers;
7using osu.Framework.Threading;
8using System.Collections.Generic;
9using System.Linq;
10using SixLabors.ImageSharp.PixelFormats;
11
12namespace osu.Framework.Graphics.Performance
13{
14 internal class PerformanceOverlay : FillFlowContainer<FrameStatisticsDisplay>, IStateful<FrameStatisticsMode>
15 {
16 private readonly GameThread[] threads;
17 private FrameStatisticsMode state;
18
19 public event Action<FrameStatisticsMode> StateChanged;
20
21 private bool initialised;
22
23 public FrameStatisticsMode State
24 {
25 get => state;
26 set
27 {
28 if (state == value) return;
29
30 state = value;
31
32 if (IsLoaded)
33 updateState();
34 }
35 }
36
37 protected override void LoadComplete()
38 {
39 base.LoadComplete();
40 updateState();
41 }
42
43 private void updateState()
44 {
45 switch (state)
46 {
47 case FrameStatisticsMode.None:
48 this.FadeOut(100);
49 break;
50
51 case FrameStatisticsMode.Minimal:
52 case FrameStatisticsMode.Full:
53 if (!initialised)
54 {
55 initialised = true;
56
57 var uploadPool = createUploadPool();
58
59 foreach (GameThread t in threads)
60 Add(new FrameStatisticsDisplay(t, uploadPool) { State = state });
61 }
62
63 this.FadeIn(100);
64 break;
65 }
66
67 foreach (FrameStatisticsDisplay d in Children)
68 d.State = state;
69
70 StateChanged?.Invoke(State);
71 }
72
73 private ArrayPool<Rgba32> createUploadPool()
74 {
75 // bucket size should be enough to allow some overhead when running multi-threaded with draw at 60hz.
76 const int max_expected_thread_update_rate = 2000;
77
78 int bucketSize = threads.Length * (max_expected_thread_update_rate / 60);
79
80 return ArrayPool<Rgba32>.Create(FrameStatisticsDisplay.HEIGHT, bucketSize);
81 }
82
83 public PerformanceOverlay(IEnumerable<GameThread> threads)
84 {
85 this.threads = threads.ToArray();
86 Direction = FillDirection.Vertical;
87 }
88 }
89
90 public enum FrameStatisticsMode
91 {
92 None,
93 Minimal,
94 Full
95 }
96}