ResourcePool.cs
1 using Ryujinx.Graphics.GAL; 2 using Ryujinx.Graphics.OpenGL.Image; 3 using System; 4 using System.Collections.Generic; 5 6 namespace Ryujinx.Graphics.OpenGL 7 { 8 class DisposedTexture 9 { 10 public TextureCreateInfo Info; 11 public TextureView View; 12 public int RemainingFrames; 13 } 14 15 /// <summary> 16 /// A structure for pooling resources that can be reused without recreation, such as textures. 17 /// </summary> 18 class ResourcePool : IDisposable 19 { 20 private const int DisposedLiveFrames = 2; 21 22 private readonly object _lock = new(); 23 private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new(); 24 25 /// <summary> 26 /// Add a texture that is not being used anymore to the resource pool to be used later. 27 /// Both the texture's view and storage should be completely unused. 28 /// </summary> 29 /// <param name="view">The texture's view</param> 30 public void AddTexture(TextureView view) 31 { 32 lock (_lock) 33 { 34 if (!_textures.TryGetValue(view.Info, out List<DisposedTexture> list)) 35 { 36 list = new List<DisposedTexture>(); 37 _textures.Add(view.Info, list); 38 } 39 40 list.Add(new DisposedTexture() 41 { 42 Info = view.Info, 43 View = view, 44 RemainingFrames = DisposedLiveFrames, 45 }); 46 } 47 } 48 49 /// <summary> 50 /// Attempt to obtain a texture from the resource cache with the desired parameters. 51 /// </summary> 52 /// <param name="info">The creation info for the desired texture</param> 53 /// <returns>A TextureView with the description specified, or null if one was not found.</returns> 54 public TextureView GetTextureOrNull(TextureCreateInfo info) 55 { 56 lock (_lock) 57 { 58 if (!_textures.TryGetValue(info, out List<DisposedTexture> list)) 59 { 60 return null; 61 } 62 63 foreach (DisposedTexture texture in list) 64 { 65 list.Remove(texture); 66 return texture.View; 67 } 68 69 return null; 70 } 71 } 72 73 /// <summary> 74 /// Update the pool, removing any resources that have expired. 75 /// </summary> 76 public void Tick() 77 { 78 lock (_lock) 79 { 80 foreach (List<DisposedTexture> list in _textures.Values) 81 { 82 for (int i = 0; i < list.Count; i++) 83 { 84 DisposedTexture tex = list[i]; 85 86 if (--tex.RemainingFrames < 0) 87 { 88 tex.View.Dispose(); 89 list.RemoveAt(i--); 90 } 91 } 92 } 93 } 94 } 95 96 /// <summary> 97 /// Disposes the resource pool. 98 /// </summary> 99 public void Dispose() 100 { 101 lock (_lock) 102 { 103 foreach (List<DisposedTexture> list in _textures.Values) 104 { 105 foreach (DisposedTexture texture in list) 106 { 107 texture.View.Dispose(); 108 } 109 } 110 _textures.Clear(); 111 } 112 } 113 } 114 }