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