mirror of
https://github.com/SK-la/osu-framework.git
synced 2026-03-15 03:20:30 +00:00
Remove EventList as a concept
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using osu.Framework.Graphics.Rendering.Deferred;
|
||||
using osu.Framework.Graphics.Rendering.Deferred.Allocation;
|
||||
using osu.Framework.Graphics.Rendering.Deferred.Events;
|
||||
|
||||
@@ -12,71 +12,65 @@ namespace osu.Framework.Benchmarks
|
||||
{
|
||||
// Used for benchmark-local testing.
|
||||
private ResourceAllocator localAllocator = null!;
|
||||
private EventList localEventList = null!;
|
||||
private List<RenderEvent> localEventList = null!;
|
||||
|
||||
// Used for benchmark-static testing.
|
||||
// 0: Basic events
|
||||
// 1: Events with data
|
||||
// 2: Mixed events
|
||||
private readonly (ResourceAllocator allocator, EventList list)[] staticItems = new (ResourceAllocator allocator, EventList list)[3];
|
||||
private readonly (ResourceAllocator allocator, List<RenderEvent> list)[] staticItems = new (ResourceAllocator allocator, List<RenderEvent> list)[3];
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
localAllocator = new ResourceAllocator();
|
||||
localEventList = new EventList();
|
||||
localEventList = new List<RenderEvent>();
|
||||
|
||||
for (int i = 0; i < staticItems.Length; i++)
|
||||
{
|
||||
ResourceAllocator allocator = new ResourceAllocator();
|
||||
staticItems[i] = (allocator, new EventList());
|
||||
staticItems[i] = (allocator, new List<RenderEvent>());
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10000; i++)
|
||||
{
|
||||
staticItems[0].list.Enqueue(RenderEvent.Init(new FlushEvent(new ResourceReference(1), 10)));
|
||||
staticItems[1].list.Enqueue(RenderEvent.Init(new AddPrimitiveToBatchEvent(new ResourceReference(0), staticItems[1].allocator.AllocateRegion(1024))));
|
||||
|
||||
if (i % 2 == 0)
|
||||
staticItems[2].list.Enqueue(RenderEvent.Init(new FlushEvent(new ResourceReference(1), 10)));
|
||||
else
|
||||
staticItems[2].list.Enqueue(RenderEvent.Init(new AddPrimitiveToBatchEvent(new ResourceReference(0), staticItems[2].allocator.AllocateRegion(1024))));
|
||||
staticItems[0].list.Add(RenderEvent.Init(new FlushEvent(new ResourceReference(1), 10)));
|
||||
staticItems[1].list.Add(RenderEvent.Init(new AddPrimitiveToBatchEvent(new ResourceReference(0), staticItems[1].allocator.AllocateRegion(1024))));
|
||||
staticItems[2].list.Add(i % 2 == 0
|
||||
? RenderEvent.Init(new FlushEvent(new ResourceReference(1), 10))
|
||||
: RenderEvent.Init(new AddPrimitiveToBatchEvent(new ResourceReference(0), staticItems[2].allocator.AllocateRegion(1024))));
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Write()
|
||||
{
|
||||
localEventList.NewFrame();
|
||||
localAllocator.NewFrame();
|
||||
|
||||
for (int i = 0; i < 10000; i++)
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
localEventList.Add(RenderEvent.Init(new FlushEvent()));
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void WriteWithData()
|
||||
{
|
||||
localEventList.NewFrame();
|
||||
localAllocator.NewFrame();
|
||||
|
||||
for (int i = 0; i < 10000; i++)
|
||||
localEventList.Enqueue(RenderEvent.Init(new AddPrimitiveToBatchEvent(new ResourceReference(0), localAllocator.AllocateRegion(1024))));
|
||||
localEventList.Add(RenderEvent.Init(new AddPrimitiveToBatchEvent(new ResourceReference(0), localAllocator.AllocateRegion(1024))));
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int Read()
|
||||
{
|
||||
var enumerator = staticItems[0].list.CreateEnumerator();
|
||||
|
||||
int totalVertices = 0;
|
||||
|
||||
while (enumerator.Next())
|
||||
foreach (var renderEvent in staticItems[0].list)
|
||||
{
|
||||
switch (enumerator.Current().Type)
|
||||
switch (renderEvent.Type)
|
||||
{
|
||||
case RenderEventType.Flush:
|
||||
enumerator.Current().Decompose(out FlushEvent e);
|
||||
renderEvent.Decompose(out FlushEvent e);
|
||||
totalVertices += e.VertexCount;
|
||||
break;
|
||||
}
|
||||
@@ -88,16 +82,14 @@ namespace osu.Framework.Benchmarks
|
||||
[Benchmark]
|
||||
public int ReadWithData()
|
||||
{
|
||||
var enumerator = staticItems[1].list.CreateEnumerator();
|
||||
|
||||
int data = 0;
|
||||
|
||||
while (enumerator.Next())
|
||||
foreach (var renderEvent in staticItems[1].list)
|
||||
{
|
||||
switch (enumerator.Current().Type)
|
||||
switch (renderEvent.Type)
|
||||
{
|
||||
case RenderEventType.AddPrimitiveToBatch:
|
||||
enumerator.Current().Decompose(out AddPrimitiveToBatchEvent e);
|
||||
renderEvent.Decompose(out AddPrimitiveToBatchEvent e);
|
||||
foreach (byte b in staticItems[1].allocator.GetRegion(e.Memory))
|
||||
data += b;
|
||||
break;
|
||||
@@ -110,24 +102,22 @@ namespace osu.Framework.Benchmarks
|
||||
[Benchmark]
|
||||
public int ReadMixed()
|
||||
{
|
||||
var enumerator = staticItems[2].list.CreateEnumerator();
|
||||
|
||||
int data = 0;
|
||||
|
||||
while (enumerator.Next())
|
||||
foreach (var renderEvent in staticItems[2].list)
|
||||
{
|
||||
switch (enumerator.Current().Type)
|
||||
switch (renderEvent.Type)
|
||||
{
|
||||
case RenderEventType.Flush:
|
||||
{
|
||||
enumerator.Current().Decompose(out FlushEvent e);
|
||||
renderEvent.Decompose(out FlushEvent e);
|
||||
data += e.VertexCount;
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.AddPrimitiveToBatch:
|
||||
{
|
||||
enumerator.Current().Decompose(out AddPrimitiveToBatchEvent e);
|
||||
renderEvent.Decompose(out AddPrimitiveToBatchEvent e);
|
||||
foreach (byte b in staticItems[2].allocator.GetRegion(e.Memory))
|
||||
data += b;
|
||||
break;
|
||||
@@ -137,92 +127,5 @@ namespace osu.Framework.Benchmarks
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int ReplaceSame()
|
||||
{
|
||||
localEventList.NewFrame();
|
||||
localAllocator.NewFrame();
|
||||
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
|
||||
var enumerator = localEventList.CreateEnumerator();
|
||||
enumerator.Next();
|
||||
enumerator.Next();
|
||||
enumerator.Replace(RenderEvent.Init(new FlushEvent()));
|
||||
|
||||
int i = 0;
|
||||
enumerator = localEventList.CreateEnumerator();
|
||||
|
||||
while (enumerator.Next())
|
||||
{
|
||||
enumerator.Current();
|
||||
i++;
|
||||
}
|
||||
|
||||
localAllocator.NewFrame();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int ReplaceSmaller()
|
||||
{
|
||||
localEventList.NewFrame();
|
||||
localAllocator.NewFrame();
|
||||
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
|
||||
var enumerator = localEventList.CreateEnumerator();
|
||||
enumerator.Next();
|
||||
enumerator.Next();
|
||||
enumerator.Replace(RenderEvent.Init(new SetScissorStateEvent()));
|
||||
|
||||
int i = 0;
|
||||
enumerator = localEventList.CreateEnumerator();
|
||||
|
||||
while (enumerator.Next())
|
||||
{
|
||||
enumerator.Current();
|
||||
i++;
|
||||
}
|
||||
|
||||
localAllocator.NewFrame();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int ReplaceBigger()
|
||||
{
|
||||
localEventList.NewFrame();
|
||||
localAllocator.NewFrame();
|
||||
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
localEventList.Enqueue(RenderEvent.Init(new FlushEvent()));
|
||||
|
||||
var enumerator = localEventList.CreateEnumerator();
|
||||
enumerator.Next();
|
||||
enumerator.Next();
|
||||
enumerator.Replace(RenderEvent.Init(new SetUniformBufferDataEvent()));
|
||||
|
||||
int i = 0;
|
||||
enumerator = localEventList.CreateEnumerator();
|
||||
|
||||
while (enumerator.Next())
|
||||
{
|
||||
enumerator.Current();
|
||||
i++;
|
||||
}
|
||||
|
||||
localAllocator.NewFrame();
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics.Rendering.Deferred.Allocation;
|
||||
using osu.Framework.Graphics.Rendering.Deferred.Events;
|
||||
using osu.Framework.Graphics.Veldrid.Pipelines;
|
||||
@@ -17,9 +18,10 @@ namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
public GraphicsPipeline Graphics
|
||||
=> Renderer.Graphics;
|
||||
|
||||
public readonly List<RenderEvent> RenderEvents = new List<RenderEvent>();
|
||||
|
||||
public readonly DeferredRenderer Renderer;
|
||||
public readonly ResourceAllocator Allocator;
|
||||
public readonly EventList RenderEvents;
|
||||
public readonly UniformBufferManager UniformBufferManager;
|
||||
public readonly VertexManager VertexManager;
|
||||
|
||||
@@ -27,15 +29,14 @@ namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
{
|
||||
Renderer = renderer;
|
||||
Allocator = new ResourceAllocator();
|
||||
RenderEvents = new EventList();
|
||||
UniformBufferManager = new UniformBufferManager(this);
|
||||
VertexManager = new VertexManager(this);
|
||||
}
|
||||
|
||||
public void NewFrame()
|
||||
{
|
||||
RenderEvents.Clear();
|
||||
Allocator.NewFrame();
|
||||
RenderEvents.NewFrame();
|
||||
UniformBufferManager.NewFrame();
|
||||
VertexManager.Reset();
|
||||
}
|
||||
@@ -101,6 +102,6 @@ namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
/// </summary>
|
||||
/// <param name="renderEvent">The render event.</param>
|
||||
public void EnqueueEvent(in RenderEvent renderEvent)
|
||||
=> RenderEvents.Enqueue(renderEvent);
|
||||
=> RenderEvents.Add(renderEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics.Rendering.Deferred.Events;
|
||||
|
||||
namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
{
|
||||
internal class EventList
|
||||
{
|
||||
private readonly List<RenderEvent> events = new List<RenderEvent>();
|
||||
|
||||
/// <summary>
|
||||
/// Prepares this <see cref="EventList"/> for a new frame.
|
||||
/// </summary>
|
||||
public void NewFrame()
|
||||
=> events.Clear();
|
||||
|
||||
/// <summary>
|
||||
/// Enqueues a render event to the list.
|
||||
/// </summary>
|
||||
/// <param name="renderEvent">The render event.</param>
|
||||
public void Enqueue(RenderEvent renderEvent)
|
||||
=> events.Add(renderEvent);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a reader of this <see cref="EventList"/>.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Enumerator"/>.</returns>
|
||||
public Enumerator CreateEnumerator()
|
||||
=> new Enumerator(this);
|
||||
|
||||
/// <summary>
|
||||
/// Reads an <see cref="EventList"/>. Semantically, this is very similar to <see cref="IEnumerator{T}"/>.
|
||||
/// </summary>
|
||||
internal ref struct Enumerator
|
||||
{
|
||||
private readonly EventList list;
|
||||
|
||||
private int eventIndex;
|
||||
private RenderEvent currentEvent;
|
||||
|
||||
public Enumerator(EventList list)
|
||||
{
|
||||
this.list = list;
|
||||
eventIndex = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Advances to the next (or first) event in the list.
|
||||
/// </summary>
|
||||
/// <returns>Whether an event can be read.</returns>
|
||||
public bool Next()
|
||||
{
|
||||
if (eventIndex < list.events.Count)
|
||||
{
|
||||
currentEvent = list.events[eventIndex];
|
||||
eventIndex++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public RenderEvent Current() => currentEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the current event with a new one.
|
||||
/// </summary>
|
||||
/// <param name="newEvent">The new render event.</param>
|
||||
public void Replace(RenderEvent newEvent)
|
||||
{
|
||||
list.events[eventIndex - 1] = newEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,21 +38,19 @@ namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
if (string.IsNullOrEmpty(FrameworkEnvironment.DeferredRendererEventsOutputPath))
|
||||
return;
|
||||
|
||||
EventList.Enumerator enumerator = context.RenderEvents.CreateEnumerator();
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int indent = 0;
|
||||
|
||||
while (enumerator.Next())
|
||||
foreach (var renderEvent in context.RenderEvents)
|
||||
{
|
||||
string info;
|
||||
int indentChange = 0;
|
||||
|
||||
switch (enumerator.Current().Type)
|
||||
switch (renderEvent.Type)
|
||||
{
|
||||
case RenderEventType.DrawNodeAction:
|
||||
{
|
||||
enumerator.Current().Decompose(out DrawNodeActionEvent e);
|
||||
renderEvent.Decompose(out DrawNodeActionEvent e);
|
||||
|
||||
info = $"DrawNode.{e.Action} ({context.Dereference<DrawNode>(e.DrawNode)})";
|
||||
|
||||
@@ -72,7 +70,7 @@ namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
|
||||
default:
|
||||
{
|
||||
info = $"{enumerator.Current().Type.ToString()}";
|
||||
info = $"{renderEvent.Type.ToString()}";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -87,15 +85,15 @@ namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
|
||||
private void processUploads()
|
||||
{
|
||||
EventList.Enumerator enumerator = context.RenderEvents.CreateEnumerator();
|
||||
|
||||
while (enumerator.Next())
|
||||
for (int i = 0; i < context.RenderEvents.Count; i++)
|
||||
{
|
||||
switch (enumerator.Current().Type)
|
||||
var renderEvent = context.RenderEvents[i];
|
||||
|
||||
switch (renderEvent.Type)
|
||||
{
|
||||
case RenderEventType.AddPrimitiveToBatch:
|
||||
{
|
||||
enumerator.Current().Decompose(out AddPrimitiveToBatchEvent e);
|
||||
renderEvent.Decompose(out AddPrimitiveToBatchEvent e);
|
||||
IDeferredVertexBatch batch = context.Dereference<IDeferredVertexBatch>(e.VertexBatch);
|
||||
batch.Write(e.Memory);
|
||||
break;
|
||||
@@ -103,16 +101,16 @@ namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
|
||||
case RenderEventType.SetUniformBufferData:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetUniformBufferDataEvent e);
|
||||
renderEvent.Decompose(out SetUniformBufferDataEvent e);
|
||||
IDeferredUniformBuffer buffer = context.Dereference<IDeferredUniformBuffer>(e.Buffer);
|
||||
UniformBufferReference range = buffer.Write(e.Data.Memory);
|
||||
enumerator.Replace(RenderEvent.Init(e with { Data = new UniformBufferData(range) }));
|
||||
context.RenderEvents[i] = RenderEvent.Init(e with { Data = new UniformBufferData(range) });
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetShaderStorageBufferObjectData:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetShaderStorageBufferObjectDataEvent e);
|
||||
renderEvent.Decompose(out SetShaderStorageBufferObjectDataEvent e);
|
||||
IDeferredShaderStorageBufferObject buffer = context.Dereference<IDeferredShaderStorageBufferObject>(e.Buffer);
|
||||
buffer.Write(e.Index, e.Memory);
|
||||
break;
|
||||
@@ -126,113 +124,111 @@ namespace osu.Framework.Graphics.Rendering.Deferred
|
||||
|
||||
private void processEvents()
|
||||
{
|
||||
EventList.Enumerator enumerator = context.RenderEvents.CreateEnumerator();
|
||||
|
||||
while (enumerator.Next())
|
||||
foreach (var renderEvent in context.RenderEvents)
|
||||
{
|
||||
switch (enumerator.Current().Type)
|
||||
switch (renderEvent.Type)
|
||||
{
|
||||
case RenderEventType.SetFrameBuffer:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetFrameBufferEvent e);
|
||||
renderEvent.Decompose(out SetFrameBufferEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.ResizeFrameBuffer:
|
||||
{
|
||||
enumerator.Current().Decompose(out ResizeFrameBufferEvent e);
|
||||
renderEvent.Decompose(out ResizeFrameBufferEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetShader:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetShaderEvent e);
|
||||
renderEvent.Decompose(out SetShaderEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetTexture:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetTextureEvent e);
|
||||
renderEvent.Decompose(out SetTextureEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetUniformBuffer:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetUniformBufferEvent e);
|
||||
renderEvent.Decompose(out SetUniformBufferEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.Clear:
|
||||
{
|
||||
enumerator.Current().Decompose(out ClearEvent e);
|
||||
renderEvent.Decompose(out ClearEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetDepthInfo:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetDepthInfoEvent e);
|
||||
renderEvent.Decompose(out SetDepthInfoEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetScissor:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetScissorEvent e);
|
||||
renderEvent.Decompose(out SetScissorEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetScissorState:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetScissorStateEvent e);
|
||||
renderEvent.Decompose(out SetScissorStateEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetStencilInfo:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetStencilInfoEvent e);
|
||||
renderEvent.Decompose(out SetStencilInfoEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetViewport:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetViewportEvent e);
|
||||
renderEvent.Decompose(out SetViewportEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetBlend:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetBlendEvent e);
|
||||
renderEvent.Decompose(out SetBlendEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetBlendMask:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetBlendMaskEvent e);
|
||||
renderEvent.Decompose(out SetBlendMaskEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.Flush:
|
||||
{
|
||||
enumerator.Current().Decompose(out FlushEvent e);
|
||||
renderEvent.Decompose(out FlushEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderEventType.SetUniformBufferData:
|
||||
{
|
||||
enumerator.Current().Decompose(out SetUniformBufferDataEvent e);
|
||||
renderEvent.Decompose(out SetUniformBufferDataEvent e);
|
||||
processEvent(e);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user