Skip to content

Commit

Permalink
Optimise many add vertex events
Browse files Browse the repository at this point in the history
  • Loading branch information
smoogipoo committed Jan 10, 2024
1 parent 981ea3d commit 3466317
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ int IVertexBatch.Draw()
void IVertexBatch<TVertex>.Add(TVertex vertex)
{
pendingVertices.Add(vertex);
renderer.EnqueueEvent(new AddVertexToBatchEvent(renderer.Reference(this), pendingVertices.Count - 1));
renderer.EnqueueEvent(new AddVertexToBatchEvent(renderer.Reference(this), pendingVertices.Count - 1, 1));
}

public void Dispose()
Expand Down
23 changes: 23 additions & 0 deletions osu.Framework/Graphics/Rendering/Deferred/EventList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using osu.Framework.Graphics.Rendering.Deferred.Events;

Expand All @@ -11,15 +12,37 @@ namespace osu.Framework.Graphics.Rendering.Deferred
public class EventList
{
private readonly List<byte> renderEvents = new List<byte>();
private AddVertexToBatchEvent lastAddVertexEvent;

public void Reset()
{
renderEvents.Clear();
lastAddVertexEvent = default;
}

public void Enqueue<T>(T renderEvent)
where T : unmanaged, IRenderEvent
{
// Early optimisation for AddVertexToBatchEvents which are extremely frequent.
if (typeof(T) == typeof(AddVertexToBatchEvent))
{
AddVertexToBatchEvent thisAddVertexEvent = (AddVertexToBatchEvent)(object)renderEvent;

// Safeguard that the vertex is part of the same batch and is directly after the last vertex.
if (thisAddVertexEvent.VertexBatch == lastAddVertexEvent.VertexBatch
&& thisAddVertexEvent.Index == lastAddVertexEvent.Index + lastAddVertexEvent.Count)
{
int size = Unsafe.SizeOf<AddVertexToBatchEvent>();

renderEvents.RemoveRange(renderEvents.Count - size - 1, size + 1);
renderEvent = (T)(object)new AddVertexToBatchEvent(lastAddVertexEvent.VertexBatch, lastAddVertexEvent.Index, lastAddVertexEvent.Count + thisAddVertexEvent.Count);
}

lastAddVertexEvent = (AddVertexToBatchEvent)(object)renderEvent;
}
else
lastAddVertexEvent = default;

ReadOnlySpan<byte> eventBytes = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref renderEvent, 1));

renderEvents.Add((byte)renderEvent.Type);
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Graphics/Rendering/Deferred/EventPainter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public void ProcessEvent(AddVertexToBatchEvent e)
FlushCurrentBatch(FlushBatchSource.BindBuffer);

drawStartIndex ??= e.Index;
drawEndIndex = e.Index;
drawEndIndex = e.Index + e.Count;
currentDrawBatch = batch;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace osu.Framework.Graphics.Rendering.Deferred.Events
{
public readonly record struct AddVertexToBatchEvent(RendererResource VertexBatch, int Index) : IRenderEvent
public readonly record struct AddVertexToBatchEvent(RendererResource VertexBatch, int Index, int Count) : IRenderEvent
{
public RenderEventType Type => RenderEventType.AddVertexToBatch;
}
Expand Down

0 comments on commit 3466317

Please sign in to comment.