AutoDeleteCache.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. namespace Ryujinx.Graphics.Gpu.Image
  4. {
  5. /// <summary>
  6. /// A texture cache that automatically removes older textures that are not used for some time.
  7. /// The cache works with a rotated list with a fixed size. When new textures are added, the
  8. /// old ones at the bottom of the list are deleted.
  9. /// </summary>
  10. class AutoDeleteCache : IEnumerable<Texture>
  11. {
  12. private const int MaxCapacity = 2048;
  13. private readonly LinkedList<Texture> _textures;
  14. /// <summary>
  15. /// Creates a new instance of the automatic deletion cache.
  16. /// </summary>
  17. public AutoDeleteCache()
  18. {
  19. _textures = new LinkedList<Texture>();
  20. }
  21. /// <summary>
  22. /// Adds a new texture to the cache, even if the texture added is already on the cache.
  23. /// </summary>
  24. /// <remarks>
  25. /// Using this method is only recommended if you know that the texture is not yet on the cache,
  26. /// otherwise it would store the same texture more than once.
  27. /// </remarks>
  28. /// <param name="texture">The texture to be added to the cache</param>
  29. public void Add(Texture texture)
  30. {
  31. texture.IncrementReferenceCount();
  32. texture.CacheNode = _textures.AddLast(texture);
  33. if (_textures.Count > MaxCapacity)
  34. {
  35. Texture oldestTexture = _textures.First.Value;
  36. _textures.RemoveFirst();
  37. oldestTexture.DecrementReferenceCount();
  38. oldestTexture.CacheNode = null;
  39. }
  40. }
  41. /// <summary>
  42. /// Adds a new texture to the cache, or just moves it to the top of the list if the
  43. /// texture is already on the cache.
  44. /// </summary>
  45. /// <remarks>
  46. /// Moving the texture to the top of the list prevents it from being deleted,
  47. /// as the textures on the bottom of the list are deleted when new ones are added.
  48. /// </remarks>
  49. /// <param name="texture">The texture to be added, or moved to the top</param>
  50. public void Lift(Texture texture)
  51. {
  52. if (texture.CacheNode != null)
  53. {
  54. if (texture.CacheNode != _textures.Last)
  55. {
  56. _textures.Remove(texture.CacheNode);
  57. texture.CacheNode = _textures.AddLast(texture);
  58. }
  59. }
  60. else
  61. {
  62. Add(texture);
  63. }
  64. }
  65. public IEnumerator<Texture> GetEnumerator()
  66. {
  67. return _textures.GetEnumerator();
  68. }
  69. IEnumerator IEnumerable.GetEnumerator()
  70. {
  71. return _textures.GetEnumerator();
  72. }
  73. }
  74. }