ThreadedCounterEvent.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent;
  2. using Ryujinx.Graphics.GAL.Multithreading.Model;
  3. using System.Threading;
  4. namespace Ryujinx.Graphics.GAL.Multithreading.Resources
  5. {
  6. class ThreadedCounterEvent : ICounterEvent
  7. {
  8. private ThreadedRenderer _renderer;
  9. public ICounterEvent Base;
  10. public bool Invalid { get; set; }
  11. public CounterType Type { get; }
  12. public bool ClearCounter { get; }
  13. private bool _reserved;
  14. private int _createLock;
  15. public ThreadedCounterEvent(ThreadedRenderer renderer, CounterType type, bool clearCounter)
  16. {
  17. _renderer = renderer;
  18. Type = type;
  19. ClearCounter = clearCounter;
  20. }
  21. private TableRef<T> Ref<T>(T reference)
  22. {
  23. return new TableRef<T>(_renderer, reference);
  24. }
  25. public void Dispose()
  26. {
  27. _renderer.New<CounterEventDisposeCommand>().Set(Ref(this));
  28. _renderer.QueueCommand();
  29. }
  30. public void Flush()
  31. {
  32. ThreadedHelpers.SpinUntilNonNull(ref Base);
  33. Base.Flush();
  34. }
  35. public bool ReserveForHostAccess()
  36. {
  37. if (Base != null)
  38. {
  39. return Base.ReserveForHostAccess();
  40. }
  41. else
  42. {
  43. bool result = true;
  44. // A very light lock, as this case is uncommon.
  45. ThreadedHelpers.SpinUntilExchange(ref _createLock, 1, 0);
  46. if (Base != null)
  47. {
  48. result = Base.ReserveForHostAccess();
  49. }
  50. else
  51. {
  52. _reserved = true;
  53. }
  54. Volatile.Write(ref _createLock, 0);
  55. return result;
  56. }
  57. }
  58. public void Create(IRenderer renderer, CounterType type, System.EventHandler<ulong> eventHandler, bool hostReserved)
  59. {
  60. ThreadedHelpers.SpinUntilExchange(ref _createLock, 1, 0);
  61. Base = renderer.ReportCounter(type, eventHandler, hostReserved || _reserved);
  62. Volatile.Write(ref _createLock, 0);
  63. }
  64. }
  65. }