Remove Vertex from PlatformInterfaces
This commit is contained in:
committed by
Matthias Mailänder
parent
d77fd5c13e
commit
0a90c2a95e
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA
|
||||
@@ -83,9 +82,9 @@ namespace OpenRA
|
||||
|
||||
public interface IGraphicsContext : IDisposable
|
||||
{
|
||||
IVertexBuffer<Vertex> CreateVertexBuffer(int size);
|
||||
IVertexBuffer<T> CreateVertexBuffer<T>(int size) where T : struct;
|
||||
T[] CreateVertices<T>(int size) where T : struct;
|
||||
IIndexBuffer CreateIndexBuffer(uint[] indices);
|
||||
Vertex[] CreateVertices(int size);
|
||||
ITexture CreateTexture();
|
||||
IFrameBuffer CreateFrameBuffer(Size s);
|
||||
IFrameBuffer CreateFrameBuffer(Size s, Color clearColor);
|
||||
@@ -104,7 +103,7 @@ namespace OpenRA
|
||||
string GLVersion { get; }
|
||||
}
|
||||
|
||||
public interface IVertexBuffer<T> : IDisposable
|
||||
public interface IVertexBuffer<T> : IDisposable where T : struct
|
||||
{
|
||||
void Bind();
|
||||
void SetData(T[] vertices, int length);
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
this.renderer = renderer;
|
||||
this.shader = shader;
|
||||
vertices = renderer.Context.CreateVertices(renderer.TempVertexBufferSize);
|
||||
vertices = renderer.Context.CreateVertices<Vertex>(renderer.TempVertexBufferSize);
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
vertexRowStride = 4 * map.MapSize.X;
|
||||
vertices = new Vertex[vertexRowStride * map.MapSize.Y];
|
||||
vertexBuffer = Game.Renderer.Context.CreateVertexBuffer(vertices.Length);
|
||||
vertexBuffer = Game.Renderer.Context.CreateVertexBuffer<Vertex>(vertices.Length);
|
||||
|
||||
indexRowStride = 6 * map.MapSize.X;
|
||||
lock (IndexBuffers)
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace OpenRA
|
||||
RgbaSpriteRenderer = new RgbaSpriteRenderer(SpriteRenderer);
|
||||
RgbaColorRenderer = new RgbaColorRenderer(SpriteRenderer);
|
||||
|
||||
tempVertexBuffer = Context.CreateVertexBuffer(TempVertexBufferSize);
|
||||
tempVertexBuffer = Context.CreateVertexBuffer<Vertex>(TempVertexBufferSize);
|
||||
quadIndexBuffer = Context.CreateIndexBuffer(Util.CreateQuadIndices(TempIndexBufferSize / 6));
|
||||
}
|
||||
|
||||
@@ -382,9 +382,9 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public IVertexBuffer<Vertex> CreateVertexBuffer(int length)
|
||||
public IVertexBuffer<T> CreateVertexBuffer<T>(int length) where T : struct
|
||||
{
|
||||
return Context.CreateVertexBuffer(length);
|
||||
return Context.CreateVertexBuffer<T>(length);
|
||||
}
|
||||
|
||||
public void EnableScissor(Rectangle rect)
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
public void RefreshBuffer()
|
||||
{
|
||||
vertexBuffer?.Dispose();
|
||||
vertexBuffer = Game.Renderer.CreateVertexBuffer(totalVertexCount);
|
||||
vertexBuffer = Game.Renderer.CreateVertexBuffer<Vertex>(totalVertexCount);
|
||||
vertexBuffer.SetData(vertices.SelectMany(v => v).ToArray(), totalVertexCount);
|
||||
cachedVertexCount = totalVertexCount;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
using SDL2;
|
||||
|
||||
@@ -62,10 +61,10 @@ namespace OpenRA.Platforms.Default
|
||||
OpenGL.CheckGLError();
|
||||
}
|
||||
|
||||
public IVertexBuffer<Vertex> CreateVertexBuffer(int size)
|
||||
public IVertexBuffer<T> CreateVertexBuffer<T>(int size) where T : struct
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
return new VertexBuffer<Vertex>(size);
|
||||
return new VertexBuffer<T>(size);
|
||||
}
|
||||
|
||||
public IIndexBuffer CreateIndexBuffer(uint[] indices)
|
||||
@@ -74,10 +73,10 @@ namespace OpenRA.Platforms.Default
|
||||
return new StaticIndexBuffer(indices);
|
||||
}
|
||||
|
||||
public Vertex[] CreateVertices(int size)
|
||||
public T[] CreateVertices<T>(int size) where T : struct
|
||||
{
|
||||
VerifyThreadAffinity();
|
||||
return new Vertex[size];
|
||||
return new T[size];
|
||||
}
|
||||
|
||||
public ITexture CreateTexture()
|
||||
|
||||
@@ -13,7 +13,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
@@ -25,7 +24,7 @@ namespace OpenRA.Platforms.Default
|
||||
sealed class ThreadedGraphicsContext : IGraphicsContext
|
||||
{
|
||||
// PERF: Maintain several object pools to reduce allocations.
|
||||
readonly Stack<Vertex[]> verticesPool = new();
|
||||
readonly Dictionary<Type, object> vertexBufferPools = new();
|
||||
readonly Stack<Message> messagePool = new();
|
||||
readonly Queue<Message> messages = new();
|
||||
|
||||
@@ -46,7 +45,7 @@ namespace OpenRA.Platforms.Default
|
||||
Func<ITexture> getCreateTexture;
|
||||
Func<object, IFrameBuffer> getCreateFrameBuffer;
|
||||
Func<object, IShader> getCreateShader;
|
||||
Func<object, IVertexBuffer<Vertex>> getCreateVertexBuffer;
|
||||
Func<object, object> getCreateVertexBuffer;
|
||||
Func<object, IIndexBuffer> getCreateIndexBuffer;
|
||||
Action<object> doDrawPrimitives;
|
||||
Action<object> doDrawElements;
|
||||
@@ -97,7 +96,13 @@ namespace OpenRA.Platforms.Default
|
||||
context.CreateFrameBuffer(t.Item1, (ITextureInternal)CreateTexture(), t.Item2));
|
||||
};
|
||||
getCreateShader = name => new ThreadedShader(this, context.CreateShader((string)name));
|
||||
getCreateVertexBuffer = length => new ThreadedVertexBuffer(this, context.CreateVertexBuffer((int)length));
|
||||
getCreateVertexBuffer =
|
||||
tuple =>
|
||||
{
|
||||
(object t, var type) = ((int, Type))tuple;
|
||||
var vertexBuffer = context.GetType().GetMethod(nameof(CreateVertexBuffer)).MakeGenericMethod(type).Invoke(context, new[] { t });
|
||||
return typeof(ThreadedVertexBuffer<>).MakeGenericType(type).GetConstructors()[0].Invoke(new[] { this, vertexBuffer });
|
||||
};
|
||||
getCreateIndexBuffer = indices => new ThreadedIndexBuffer(this, context.CreateIndexBuffer((uint[])indices));
|
||||
doDrawPrimitives =
|
||||
tuple =>
|
||||
@@ -150,20 +155,31 @@ namespace OpenRA.Platforms.Default
|
||||
}
|
||||
}
|
||||
|
||||
internal Vertex[] GetVertices(int size)
|
||||
internal T[] GetVertices<T>(int size)
|
||||
{
|
||||
lock (verticesPool)
|
||||
if (size <= VertexBatchSize && verticesPool.Count > 0)
|
||||
return verticesPool.Pop();
|
||||
lock (vertexBufferPools)
|
||||
{
|
||||
Stack<T[]> pool;
|
||||
if (!vertexBufferPools.TryGetValue(typeof(T), out var poolObject))
|
||||
{
|
||||
pool = new Stack<T[]>();
|
||||
vertexBufferPools.Add(typeof(T), pool);
|
||||
}
|
||||
else
|
||||
pool = (Stack<T[]>)poolObject;
|
||||
|
||||
return new Vertex[size < VertexBatchSize ? VertexBatchSize : size];
|
||||
if (size <= VertexBatchSize && pool.Count > 0)
|
||||
return pool.Pop();
|
||||
}
|
||||
|
||||
internal void ReturnVertices(Vertex[] vertices)
|
||||
return new T[size < VertexBatchSize ? VertexBatchSize : size];
|
||||
}
|
||||
|
||||
internal void ReturnVertices<T>(T[] vertices)
|
||||
{
|
||||
if (vertices.Length == VertexBatchSize)
|
||||
lock (verticesPool)
|
||||
verticesPool.Push(vertices);
|
||||
lock (vertexBufferPools)
|
||||
((Stack<T[]>)vertexBufferPools[typeof(T)]).Push(vertices);
|
||||
}
|
||||
|
||||
sealed class Message
|
||||
@@ -410,9 +426,9 @@ namespace OpenRA.Platforms.Default
|
||||
return Send(getCreateTexture);
|
||||
}
|
||||
|
||||
public IVertexBuffer<Vertex> CreateVertexBuffer(int length)
|
||||
public IVertexBuffer<T> CreateVertexBuffer<T>(int size) where T : struct
|
||||
{
|
||||
return Send(getCreateVertexBuffer, length);
|
||||
return (IVertexBuffer<T>)Send(getCreateVertexBuffer, (size, typeof(T)));
|
||||
}
|
||||
|
||||
public IIndexBuffer CreateIndexBuffer(uint[] indices)
|
||||
@@ -420,9 +436,9 @@ namespace OpenRA.Platforms.Default
|
||||
return Send(getCreateIndexBuffer, indices);
|
||||
}
|
||||
|
||||
public Vertex[] CreateVertices(int size)
|
||||
public T[] CreateVertices<T>(int size) where T : struct
|
||||
{
|
||||
return GetVertices(size);
|
||||
return GetVertices<T>(size);
|
||||
}
|
||||
|
||||
public void DisableDepthBuffer()
|
||||
@@ -521,7 +537,7 @@ namespace OpenRA.Platforms.Default
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ThreadedVertexBuffer : IVertexBuffer<Vertex>
|
||||
sealed class ThreadedVertexBuffer<T> : IVertexBuffer<T> where T : struct
|
||||
{
|
||||
readonly ThreadedGraphicsContext device;
|
||||
readonly Action bind;
|
||||
@@ -530,12 +546,24 @@ namespace OpenRA.Platforms.Default
|
||||
readonly Func<object, object> setData3;
|
||||
readonly Action dispose;
|
||||
|
||||
public ThreadedVertexBuffer(ThreadedGraphicsContext device, IVertexBuffer<Vertex> vertexBuffer)
|
||||
public ThreadedVertexBuffer(ThreadedGraphicsContext device, IVertexBuffer<T> vertexBuffer)
|
||||
{
|
||||
this.device = device;
|
||||
bind = vertexBuffer.Bind;
|
||||
setData1 = tuple => { var t = ((Vertex[], int))tuple; vertexBuffer.SetData(t.Item1, t.Item2); device.ReturnVertices(t.Item1); };
|
||||
setData2 = tuple => { var t = ((Vertex[], int, int, int))tuple; vertexBuffer.SetData(t.Item1, t.Item2, t.Item3, t.Item4); device.ReturnVertices(t.Item1); };
|
||||
setData1 = tuple =>
|
||||
{
|
||||
var t = ((T[], int))tuple;
|
||||
vertexBuffer.SetData(t.Item1, t.Item2);
|
||||
device.ReturnVertices(t.Item1);
|
||||
};
|
||||
|
||||
setData2 = tuple =>
|
||||
{
|
||||
var t = ((T[], int, int, int))tuple;
|
||||
vertexBuffer.SetData(t.Item1, t.Item2, t.Item3, t.Item4);
|
||||
device.ReturnVertices(t.Item1);
|
||||
};
|
||||
|
||||
setData3 = tuple => { setData2(tuple); return null; };
|
||||
dispose = vertexBuffer.Dispose;
|
||||
}
|
||||
@@ -545,9 +573,9 @@ namespace OpenRA.Platforms.Default
|
||||
device.Post(bind);
|
||||
}
|
||||
|
||||
public void SetData(Vertex[] vertices, int length)
|
||||
public void SetData(T[] vertices, int length)
|
||||
{
|
||||
var buffer = device.GetVertices(length);
|
||||
var buffer = device.GetVertices<T>(length);
|
||||
Array.Copy(vertices, buffer, length);
|
||||
device.Post(setData1, (buffer, length));
|
||||
}
|
||||
@@ -556,18 +584,18 @@ namespace OpenRA.Platforms.Default
|
||||
/// PERF: The vertices array is passed without copying to the render thread. Upon return `vertices` may reference another
|
||||
/// array object of at least the same size - containing random values.
|
||||
/// </summary>
|
||||
public void SetData(ref Vertex[] vertices, int length)
|
||||
public void SetData(ref T[] vertices, int length)
|
||||
{
|
||||
device.Post(setData1, (vertices, length));
|
||||
vertices = device.GetVertices(vertices.Length);
|
||||
vertices = device.GetVertices<T>(vertices.Length);
|
||||
}
|
||||
|
||||
public void SetData(Vertex[] vertices, int offset, int start, int length)
|
||||
public void SetData(T[] vertices, int offset, int start, int length)
|
||||
{
|
||||
if (length <= device.VertexBatchSize)
|
||||
{
|
||||
// If we are able to use a buffer without allocation, post a message to avoid blocking.
|
||||
var buffer = device.GetVertices(length);
|
||||
var buffer = device.GetVertices<T>(length);
|
||||
Array.Copy(vertices, offset, buffer, 0, length);
|
||||
device.Post(setData2, (buffer, 0, start, length));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user