diff options
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs b/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs index 0e1025af..8b0ae30e 100644 --- a/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs +++ b/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs @@ -1,4 +1,5 @@ using OpenTK.Graphics.OpenGL; +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using System; using System.Threading; @@ -21,7 +22,11 @@ namespace Ryujinx.Graphics.OpenGL.Queries private CounterQueue _queue; private BufferedQuery _counter; + private bool _hostAccessReserved = false; + private int _refCount = 1; // Starts with a reference from the counter queue. + private object _lock = new object(); + private ulong _result = ulong.MaxValue; public CounterQueueEvent(CounterQueue queue, QueryTarget type, ulong drawIndex) { @@ -76,6 +81,8 @@ namespace Ryujinx.Graphics.OpenGL.Queries result += (ulong)queryResult; + _result = result; + OnResult?.Invoke(this, result); Dispose(); // Return the our resources to the pool. @@ -95,10 +102,60 @@ namespace Ryujinx.Graphics.OpenGL.Queries _queue.FlushTo(this); } + public void DecrementRefCount() + { + if (Interlocked.Decrement(ref _refCount) == 0) + { + DisposeInternal(); + } + } + + public bool ReserveForHostAccess() + { + if (_hostAccessReserved) + { + return true; + } + + if (IsValueAvailable()) + { + return false; + } + + if (Interlocked.Increment(ref _refCount) == 1) + { + Interlocked.Decrement(ref _refCount); + + return false; + } + + _hostAccessReserved = true; + + return true; + } + + public void ReleaseHostAccess() + { + _hostAccessReserved = false; + + DecrementRefCount(); + } + + private void DisposeInternal() + { + _queue.ReturnQueryObject(_counter); + } + + private bool IsValueAvailable() + { + return _result != ulong.MaxValue || _counter.TryGetResult(out _); + } + public void Dispose() { Disposed = true; - _queue.ReturnQueryObject(_counter); + + DecrementRefCount(); } } } |