Skip to content

Commit

Permalink
Merge pull request #6451 from smoogipoo/reduce-backgrounded-impact
Browse files Browse the repository at this point in the history
Fix increased CPU/energy impact while backgrounded
  • Loading branch information
peppy authored Dec 10, 2024
2 parents 86fc2c7 + 18ccc8f commit ebb2b33
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
28 changes: 21 additions & 7 deletions osu.Framework/Allocation/TripleBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ namespace osu.Framework.Allocation
internal class TripleBuffer<T>
where T : class
{
/// <summary>
/// The default amount of time (in milliseconds) to wait for a write to occur during <see cref="GetForRead"/>.
/// </summary>
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;
Expand All @@ -32,25 +35,36 @@ public TripleBuffer()
buffers[i] = new Buffer(i, finishUsage);
}

/// <summary>
/// Retrieves a buffer to be written to.
/// </summary>
/// <returns>The buffer.</returns>
public Buffer GetForWrite()
{
Buffer usage = buffers[writeIndex];
usage.LastUsage = UsageType.Write;
return usage;
}

public Buffer? GetForRead()
/// <summary>
/// Attempts to retrieve a buffer to read.
/// </summary>
/// <param name="timeout">Amount of time (in milliseconds) to wait for a buffer to be written.</param>
/// <returns>An available buffer to be read, or <c>null</c> if no buffer has been written.</returns>
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];

Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Platform/GameHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ protected virtual void DrawFrame()
Renderer.WaitUntilNextFrameReady();

didRenderFrame = false;
buffer = drawRoots.GetForRead();
buffer = drawRoots.GetForRead(IsActive.Value ? TripleBuffer<DrawNode>.DEFAULT_READ_TIMEOUT : 0);
}

if (buffer == null)
Expand Down

0 comments on commit ebb2b33

Please sign in to comment.