From cee712105850ac3385cd0091a923438167433f9f Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 8 Apr 2023 01:22:00 +0200 Subject: Move solution and projects to src --- src/Ryujinx.Graphics.OpenGL/ResourcePool.cs | 122 ++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/Ryujinx.Graphics.OpenGL/ResourcePool.cs (limited to 'src/Ryujinx.Graphics.OpenGL/ResourcePool.cs') diff --git a/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs b/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs new file mode 100644 index 00000000..57231cd6 --- /dev/null +++ b/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs @@ -0,0 +1,122 @@ +using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.OpenGL.Image; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Graphics.OpenGL +{ + class DisposedTexture + { + public TextureCreateInfo Info; + public TextureView View; + public float ScaleFactor; + public int RemainingFrames; + } + + /// + /// A structure for pooling resources that can be reused without recreation, such as textures. + /// + class ResourcePool : IDisposable + { + private const int DisposedLiveFrames = 2; + + private readonly object _lock = new object(); + private readonly Dictionary> _textures = new Dictionary>(); + + /// + /// Add a texture that is not being used anymore to the resource pool to be used later. + /// Both the texture's view and storage should be completely unused. + /// + /// The texture's view + public void AddTexture(TextureView view) + { + lock (_lock) + { + List list; + if (!_textures.TryGetValue(view.Info, out list)) + { + list = new List(); + _textures.Add(view.Info, list); + } + + list.Add(new DisposedTexture() + { + Info = view.Info, + View = view, + ScaleFactor = view.ScaleFactor, + RemainingFrames = DisposedLiveFrames + }); + } + } + + /// + /// Attempt to obtain a texture from the resource cache with the desired parameters. + /// + /// The creation info for the desired texture + /// The scale factor for the desired texture + /// A TextureView with the description specified, or null if one was not found. + public TextureView GetTextureOrNull(TextureCreateInfo info, float scaleFactor) + { + lock (_lock) + { + List list; + if (!_textures.TryGetValue(info, out list)) + { + return null; + } + + foreach (DisposedTexture texture in list) + { + if (scaleFactor == texture.ScaleFactor) + { + list.Remove(texture); + return texture.View; + } + } + + return null; + } + } + + /// + /// Update the pool, removing any resources that have expired. + /// + public void Tick() + { + lock (_lock) + { + foreach (List list in _textures.Values) + { + for (int i = 0; i < list.Count; i++) + { + DisposedTexture tex = list[i]; + + if (--tex.RemainingFrames < 0) + { + tex.View.Dispose(); + list.RemoveAt(i--); + } + } + } + } + } + + /// + /// Disposes the resource pool. + /// + public void Dispose() + { + lock (_lock) + { + foreach (List list in _textures.Values) + { + foreach (DisposedTexture texture in list) + { + texture.View.Dispose(); + } + } + _textures.Clear(); + } + } + } +} -- cgit v1.2.3