aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.OpenGL/ResourcePool.cs')
-rw-r--r--src/Ryujinx.Graphics.OpenGL/ResourcePool.cs122
1 files changed, 122 insertions, 0 deletions
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;
+ }
+
+ /// <summary>
+ /// A structure for pooling resources that can be reused without recreation, such as textures.
+ /// </summary>
+ class ResourcePool : IDisposable
+ {
+ private const int DisposedLiveFrames = 2;
+
+ private readonly object _lock = new object();
+ private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new Dictionary<TextureCreateInfo, List<DisposedTexture>>();
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="view">The texture's view</param>
+ public void AddTexture(TextureView view)
+ {
+ lock (_lock)
+ {
+ List<DisposedTexture> list;
+ if (!_textures.TryGetValue(view.Info, out list))
+ {
+ list = new List<DisposedTexture>();
+ _textures.Add(view.Info, list);
+ }
+
+ list.Add(new DisposedTexture()
+ {
+ Info = view.Info,
+ View = view,
+ ScaleFactor = view.ScaleFactor,
+ RemainingFrames = DisposedLiveFrames
+ });
+ }
+ }
+
+ /// <summary>
+ /// Attempt to obtain a texture from the resource cache with the desired parameters.
+ /// </summary>
+ /// <param name="info">The creation info for the desired texture</param>
+ /// <param name="scaleFactor">The scale factor for the desired texture</param>
+ /// <returns>A TextureView with the description specified, or null if one was not found.</returns>
+ public TextureView GetTextureOrNull(TextureCreateInfo info, float scaleFactor)
+ {
+ lock (_lock)
+ {
+ List<DisposedTexture> 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;
+ }
+ }
+
+ /// <summary>
+ /// Update the pool, removing any resources that have expired.
+ /// </summary>
+ public void Tick()
+ {
+ lock (_lock)
+ {
+ foreach (List<DisposedTexture> 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--);
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Disposes the resource pool.
+ /// </summary>
+ public void Dispose()
+ {
+ lock (_lock)
+ {
+ foreach (List<DisposedTexture> list in _textures.Values)
+ {
+ foreach (DisposedTexture texture in list)
+ {
+ texture.View.Dispose();
+ }
+ }
+ _textures.Clear();
+ }
+ }
+ }
+}