TexturePoolCache.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Ryujinx.Graphics.Gpu.Image
  4. {
  5. /// <summary>
  6. /// Texture pool cache.
  7. /// This can keep multiple texture pools, and return the current one as needed.
  8. /// It is useful for applications that uses multiple texture pools.
  9. /// </summary>
  10. class TexturePoolCache
  11. {
  12. private const int MaxCapacity = 4;
  13. private readonly GpuContext _context;
  14. private readonly LinkedList<TexturePool> _pools;
  15. /// <summary>
  16. /// Constructs a new instance of the texture pool.
  17. /// </summary>
  18. /// <param name="context">GPU context that the texture pool belongs to</param>
  19. public TexturePoolCache(GpuContext context)
  20. {
  21. _context = context;
  22. _pools = new LinkedList<TexturePool>();
  23. }
  24. /// <summary>
  25. /// Finds a cache texture pool, or creates a new one if not found.
  26. /// </summary>
  27. /// <param name="channel">GPU channel that the texture pool cache belongs to</param>
  28. /// <param name="address">Start address of the texture pool</param>
  29. /// <param name="maximumId">Maximum ID of the texture pool</param>
  30. /// <returns>The found or newly created texture pool</returns>
  31. public TexturePool FindOrCreate(GpuChannel channel, ulong address, int maximumId)
  32. {
  33. TexturePool pool;
  34. // First we try to find the pool.
  35. for (LinkedListNode<TexturePool> node = _pools.First; node != null; node = node.Next)
  36. {
  37. pool = node.Value;
  38. if (pool.Address == address)
  39. {
  40. if (pool.CacheNode != _pools.Last)
  41. {
  42. _pools.Remove(pool.CacheNode);
  43. pool.CacheNode = _pools.AddLast(pool);
  44. }
  45. return pool;
  46. }
  47. }
  48. // If not found, create a new one.
  49. pool = new TexturePool(_context, channel, address, maximumId);
  50. pool.CacheNode = _pools.AddLast(pool);
  51. if (_pools.Count > MaxCapacity)
  52. {
  53. TexturePool oldestPool = _pools.First.Value;
  54. _pools.RemoveFirst();
  55. oldestPool.Dispose();
  56. oldestPool.CacheNode = null;
  57. }
  58. return pool;
  59. }
  60. }
  61. }