diff --git a/osu.Framework/Allocation/TripleBuffer.cs b/osu.Framework/Allocation/TripleBuffer.cs index 16a849a2de..6c7cf49bf4 100644 --- a/osu.Framework/Allocation/TripleBuffer.cs +++ b/osu.Framework/Allocation/TripleBuffer.cs @@ -15,11 +15,14 @@ namespace osu.Framework.Allocation internal class TripleBuffer where T : class { + /// + /// The default amount of time (in milliseconds) to wait for a write to occur during . + /// + public const int DEFAULT_READ_TIMEOUT = 100; + private const int buffer_count = 3; - private const long read_timeout_milliseconds = 100; private readonly Buffer[] buffers = new Buffer[buffer_count]; - private readonly Stopwatch stopwatch = new Stopwatch(); private int writeIndex; @@ -32,6 +35,10 @@ public TripleBuffer() buffers[i] = new Buffer(i, finishUsage); } + /// + /// Retrieves a buffer to be written to. + /// + /// The buffer. public Buffer GetForWrite() { Buffer usage = buffers[writeIndex]; @@ -39,18 +46,25 @@ public Buffer GetForWrite() return usage; } - public Buffer? GetForRead() + /// + /// Attempts to retrieve a buffer to read. + /// + /// Amount of time (in milliseconds) to wait for a buffer to be written. + /// An available buffer to be read, or null if no buffer has been written. + public Buffer? GetForRead(int timeout = DEFAULT_READ_TIMEOUT) { stopwatch.Restart(); - do + while (true) { flip(ref readIndex); - // This should really never happen, but prevents a potential infinite loop if the usage can never be retrieved. - if (stopwatch.ElapsedMilliseconds > read_timeout_milliseconds) + if (buffers[readIndex].LastUsage != UsageType.Read) + break; + + if (timeout == 0 || stopwatch.ElapsedMilliseconds > timeout) return null; - } while (buffers[readIndex].LastUsage == UsageType.Read); + } Buffer usage = buffers[readIndex]; diff --git a/osu.Framework/Platform/GameHost.cs b/osu.Framework/Platform/GameHost.cs index 400283a5ed..1d2d5425a7 100644 --- a/osu.Framework/Platform/GameHost.cs +++ b/osu.Framework/Platform/GameHost.cs @@ -515,7 +515,7 @@ protected virtual void DrawFrame() Renderer.WaitUntilNextFrameReady(); didRenderFrame = false; - buffer = drawRoots.GetForRead(); + buffer = drawRoots.GetForRead(IsActive.Value ? TripleBuffer.DEFAULT_READ_TIMEOUT : 0); } if (buffer == null)