AutoDeleteCache.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. /// Using this method is only recommended if you know that the texture is not yet on the cache,
  24. /// otherwise it would store the same texture more than once.
  25. /// </summary>
  26. /// <param name="texture">The texture to be added to the cache</param>
  27. public void Add(Texture texture)
  28. {
  29. texture.IncrementReferenceCount();
  30. texture.CacheNode = _textures.AddLast(texture);
  31. if (_textures.Count > MaxCapacity)
  32. {
  33. Texture oldestTexture = _textures.First.Value;
  34. _textures.RemoveFirst();
  35. oldestTexture.DecrementReferenceCount();
  36. oldestTexture.CacheNode = null;
  37. }
  38. }
  39. /// <summary>
  40. /// Adds a new texture to the cache, or just moves it to the top of the list if the
  41. /// texture is already on the cache. Moving the texture to the top of the list prevents
  42. /// it from being deleted, as the textures on the bottom of the list are deleted when new ones are added.
  43. /// </summary>
  44. /// <param name="texture">The texture to be added, or moved to the top</param>
  45. public void Lift(Texture texture)
  46. {
  47. if (texture.CacheNode != null)
  48. {
  49. if (texture.CacheNode != _textures.Last)
  50. {
  51. _textures.Remove(texture.CacheNode);
  52. texture.CacheNode = _textures.AddLast(texture);
  53. }
  54. }
  55. else
  56. {
  57. Add(texture);
  58. }
  59. }
  60. public IEnumerator<Texture> GetEnumerator()
  61. {
  62. return _textures.GetEnumerator();
  63. }
  64. IEnumerator IEnumerable.GetEnumerator()
  65. {
  66. return _textures.GetEnumerator();
  67. }
  68. }
  69. }