Show More
Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
References:
File last commit:
Show/Diff file:
Action:
FNA/src/FNAPlatform/ThreadedGLDevice.cs
1203 lines | 21.5 KiB | text/x-csharp | CSharpLexer
1203 lines | 21.5 KiB | text/x-csharp | CSharpLexer
r0 | #region License | |||
/* FNA - XNA4 Reimplementation for Desktop Platforms | ||||
* Copyright 2009-2020 Ethan Lee and the MonoGame Team | ||||
* | ||||
* Released under the Microsoft Public License. | ||||
* See LICENSE for details. | ||||
*/ | ||||
#endregion | ||||
#region Using Statements | ||||
using System; | ||||
using System.Threading; | ||||
using System.Collections.Generic; | ||||
using System.Collections.Concurrent; | ||||
#endregion | ||||
namespace Microsoft.Xna.Framework.Graphics | ||||
{ | ||||
internal class ThreadedGLDevice : IGLDevice | ||||
{ | ||||
#region Public Properties | ||||
public Color BlendFactor | ||||
{ | ||||
get | ||||
{ | ||||
Color result = Color.Black; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.BlendFactor; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
set | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.BlendFactor = value; | ||||
}); // End ForceToMainThread | ||||
} | ||||
} | ||||
public int MultiSampleMask | ||||
{ | ||||
get | ||||
{ | ||||
int result = 0; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.MultiSampleMask; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
set | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.MultiSampleMask = value; | ||||
}); // End ForceToMainThread | ||||
} | ||||
} | ||||
public int ReferenceStencil | ||||
{ | ||||
get | ||||
{ | ||||
int result = 0; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.ReferenceStencil; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
set | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.ReferenceStencil = value; | ||||
}); // End ForceToMainThread | ||||
} | ||||
} | ||||
public bool SupportsDxt1 | ||||
{ | ||||
get | ||||
{ | ||||
bool result = false; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.SupportsDxt1; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
} | ||||
public bool SupportsS3tc | ||||
{ | ||||
get | ||||
{ | ||||
bool result = false; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.SupportsS3tc; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
} | ||||
public bool SupportsHardwareInstancing | ||||
{ | ||||
get | ||||
{ | ||||
bool result = false; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.SupportsHardwareInstancing; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
} | ||||
public bool SupportsNoOverwrite | ||||
{ | ||||
get | ||||
{ | ||||
bool result = false; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.SupportsNoOverwrite; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
} | ||||
public int MaxTextureSlots | ||||
{ | ||||
get | ||||
{ | ||||
int result = 0; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.MaxTextureSlots; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
} | ||||
public int MaxMultiSampleCount | ||||
{ | ||||
get | ||||
{ | ||||
int result = 0; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.MaxMultiSampleCount; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
} | ||||
public IGLBackbuffer Backbuffer | ||||
{ | ||||
get | ||||
{ | ||||
IGLBackbuffer result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.Backbuffer; | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
} | ||||
#endregion | ||||
#region Private Variables | ||||
private IGLDevice GLDevice; | ||||
private Thread csThread; | ||||
private bool csDone = false; | ||||
private AutoResetEvent csEvent = new AutoResetEvent(false); | ||||
private List<Action> actions = new List<Action>(); | ||||
#endregion | ||||
#region Private Graphics Object Disposal Queues | ||||
private ConcurrentQueue<IGLTexture> GCTextures = new ConcurrentQueue<IGLTexture>(); | ||||
private ConcurrentQueue<IGLRenderbuffer> GCRenderbuffers = new ConcurrentQueue<IGLRenderbuffer>(); | ||||
private ConcurrentQueue<IGLBuffer> GCVertexBuffers = new ConcurrentQueue<IGLBuffer>(); | ||||
private ConcurrentQueue<IGLBuffer> GCIndexBuffers = new ConcurrentQueue<IGLBuffer>(); | ||||
private ConcurrentQueue<IGLEffect> GCEffects = new ConcurrentQueue<IGLEffect>(); | ||||
private ConcurrentQueue<IGLQuery> GCQueries = new ConcurrentQueue<IGLQuery>(); | ||||
#endregion | ||||
#region Thread Functions | ||||
private void csThreadProc() | ||||
{ | ||||
while (!csDone) | ||||
{ | ||||
csEvent.WaitOne(); | ||||
lock (actions) | ||||
{ | ||||
foreach (Action action in actions) | ||||
{ | ||||
action(); | ||||
} | ||||
actions.Clear(); | ||||
} | ||||
} | ||||
GLDevice.Dispose(); | ||||
} | ||||
private void ForceToMainThread(Action action) | ||||
{ | ||||
ManualResetEventSlim resetEvent = new ManualResetEventSlim(false); | ||||
lock (actions) | ||||
{ | ||||
actions.Add(() => | ||||
{ | ||||
action(); | ||||
resetEvent.Set(); | ||||
}); | ||||
} | ||||
csEvent.Set(); | ||||
resetEvent.Wait(); | ||||
} | ||||
#endregion | ||||
#region Constructor/Disposal | ||||
public ThreadedGLDevice(PresentationParameters presentationParameters) | ||||
{ | ||||
csThread = new Thread(new ThreadStart(csThreadProc)); | ||||
csThread.Start(); | ||||
FNALoggerEXT.LogInfo("Running with ThreadedGLDevice!"); | ||||
ForceToMainThread(() => | ||||
{ | ||||
if (Environment.GetEnvironmentVariable( | ||||
"FNA_THREADEDGLDEVICE_GLDEVICE" | ||||
) == "OpenGLDevice") { | ||||
GLDevice = new OpenGLDevice( | ||||
presentationParameters | ||||
); | ||||
} | ||||
else | ||||
{ | ||||
GLDevice = new ModernGLDevice( | ||||
presentationParameters | ||||
); | ||||
} | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void Dispose() | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
csDone = true; | ||||
}); // End ForceToMainThread | ||||
csThread.Join(); | ||||
} | ||||
#endregion | ||||
#region BeginFrame Operations | ||||
public void BeginFrame() | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.BeginFrame(); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Backbuffer Operations | ||||
public void ResetBackbuffer(PresentationParameters presentationParameters) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.ResetBackbuffer( | ||||
presentationParameters | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SwapBuffers( | ||||
Rectangle? sourceRectangle, | ||||
Rectangle? destinationRectangle, | ||||
IntPtr overrideWindowHandle | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SwapBuffers( | ||||
sourceRectangle, | ||||
destinationRectangle, | ||||
overrideWindowHandle | ||||
); | ||||
IGLTexture gcTexture; | ||||
while (GCTextures.TryDequeue(out gcTexture)) | ||||
{ | ||||
GLDevice.AddDisposeTexture(gcTexture); | ||||
} | ||||
IGLRenderbuffer gcRenderbuffer; | ||||
while (GCRenderbuffers.TryDequeue(out gcRenderbuffer)) | ||||
{ | ||||
GLDevice.AddDisposeRenderbuffer(gcRenderbuffer); | ||||
} | ||||
IGLBuffer gcBuffer; | ||||
while (GCVertexBuffers.TryDequeue(out gcBuffer)) | ||||
{ | ||||
GLDevice.AddDisposeVertexBuffer(gcBuffer); | ||||
} | ||||
while (GCIndexBuffers.TryDequeue(out gcBuffer)) | ||||
{ | ||||
GLDevice.AddDisposeIndexBuffer(gcBuffer); | ||||
} | ||||
IGLEffect gcEffect; | ||||
while (GCEffects.TryDequeue(out gcEffect)) | ||||
{ | ||||
GLDevice.AddDisposeEffect(gcEffect); | ||||
} | ||||
IGLQuery gcQuery; | ||||
while (GCQueries.TryDequeue(out gcQuery)) | ||||
{ | ||||
GLDevice.AddDisposeQuery(gcQuery); | ||||
} | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region SetStringMarkerEXT | ||||
public void SetStringMarker(string text) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetStringMarker(text); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Draw Calls | ||||
public void DrawIndexedPrimitives( | ||||
PrimitiveType primitiveType, | ||||
int baseVertex, | ||||
int minVertexIndex, | ||||
int numVertices, | ||||
int startIndex, | ||||
int primitiveCount, | ||||
IGLBuffer indices, | ||||
IndexElementSize indexElementSize | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.DrawIndexedPrimitives( | ||||
primitiveType, | ||||
baseVertex, | ||||
minVertexIndex, | ||||
numVertices, | ||||
startIndex, | ||||
primitiveCount, | ||||
indices, | ||||
indexElementSize | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void DrawInstancedPrimitives( | ||||
PrimitiveType primitiveType, | ||||
int baseVertex, | ||||
int minVertexIndex, | ||||
int numVertices, | ||||
int startIndex, | ||||
int primitiveCount, | ||||
int instanceCount, | ||||
IGLBuffer indices, | ||||
IndexElementSize indexElementSize | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.DrawInstancedPrimitives( | ||||
primitiveType, | ||||
baseVertex, | ||||
minVertexIndex, | ||||
numVertices, | ||||
startIndex, | ||||
primitiveCount, | ||||
instanceCount, | ||||
indices, | ||||
indexElementSize | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void DrawPrimitives( | ||||
PrimitiveType primitiveType, | ||||
int vertexStart, | ||||
int primitiveCount | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.DrawPrimitives( | ||||
primitiveType, | ||||
vertexStart, | ||||
primitiveCount | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void DrawUserIndexedPrimitives( | ||||
PrimitiveType primitiveType, | ||||
IntPtr vertexData, | ||||
int vertexOffset, | ||||
int numVertices, | ||||
IntPtr indexData, | ||||
int indexOffset, | ||||
IndexElementSize indexElementSize, | ||||
int primitiveCount | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.DrawUserIndexedPrimitives( | ||||
primitiveType, | ||||
vertexData, | ||||
vertexOffset, | ||||
numVertices, | ||||
indexData, | ||||
indexOffset, | ||||
indexElementSize, | ||||
primitiveCount | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void DrawUserPrimitives( | ||||
PrimitiveType primitiveType, | ||||
IntPtr vertexData, | ||||
int vertexOffset, | ||||
int primitiveCount | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.DrawUserPrimitives( | ||||
primitiveType, | ||||
vertexData, | ||||
vertexOffset, | ||||
primitiveCount | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Render States | ||||
public void SetPresentationInterval(PresentInterval presentInterval) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetPresentationInterval(presentInterval); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SetViewport(Viewport vp) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetViewport(vp); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SetScissorRect(Rectangle scissorRect) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetScissorRect(scissorRect); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SetBlendState(BlendState blendState) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetBlendState(blendState); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SetDepthStencilState(DepthStencilState depthStencilState) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetDepthStencilState( | ||||
depthStencilState | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void ApplyRasterizerState(RasterizerState rasterizerState) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.ApplyRasterizerState(rasterizerState); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void VerifySampler( | ||||
int index, | ||||
Texture texture, | ||||
SamplerState sampler | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.VerifySampler(index, texture, sampler); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Target Reads/Writes | ||||
public void Clear( | ||||
ClearOptions options, | ||||
Vector4 color, | ||||
float depth, | ||||
int stencil | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.Clear(options, color, depth, stencil); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SetRenderTargets( | ||||
RenderTargetBinding[] renderTargets, | ||||
IGLRenderbuffer renderbuffer, | ||||
DepthFormat depthFormat | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetRenderTargets( | ||||
renderTargets, | ||||
renderbuffer, | ||||
depthFormat | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void ResolveTarget(RenderTargetBinding target) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.ResolveTarget(target); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void ReadBackbuffer( | ||||
IntPtr data, | ||||
int dataLen, | ||||
int startIndex, | ||||
int elementCount, | ||||
int elementSizeInBytes, | ||||
int subX, | ||||
int subY, | ||||
int subW, | ||||
int subH | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.ReadBackbuffer( | ||||
data, | ||||
dataLen, | ||||
startIndex, | ||||
elementCount, | ||||
elementSizeInBytes, | ||||
subX, | ||||
subY, | ||||
subW, | ||||
subH | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Textures | ||||
public IGLTexture CreateTexture2D( | ||||
SurfaceFormat format, | ||||
int width, | ||||
int height, | ||||
int levelCount, | ||||
bool isRenderTarget | ||||
) { | ||||
IGLTexture result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.CreateTexture2D( | ||||
format, | ||||
width, | ||||
height, | ||||
levelCount, | ||||
isRenderTarget | ||||
); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public IGLTexture CreateTexture3D( | ||||
SurfaceFormat format, | ||||
int width, | ||||
int height, | ||||
int depth, | ||||
int levelCount | ||||
) { | ||||
IGLTexture result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.CreateTexture3D( | ||||
format, | ||||
width, | ||||
height, | ||||
depth, | ||||
levelCount | ||||
); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public IGLTexture CreateTextureCube( | ||||
SurfaceFormat format, | ||||
int size, | ||||
int levelCount, | ||||
bool isRenderTarget | ||||
) { | ||||
IGLTexture result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.CreateTextureCube( | ||||
format, | ||||
size, | ||||
levelCount, | ||||
isRenderTarget | ||||
); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public void AddDisposeTexture(IGLTexture texture) | ||||
{ | ||||
GCTextures.Enqueue(texture); | ||||
} | ||||
public void SetTextureData2D( | ||||
IGLTexture texture, | ||||
SurfaceFormat format, | ||||
int x, | ||||
int y, | ||||
int w, | ||||
int h, | ||||
int level, | ||||
IntPtr data, | ||||
int dataLength | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetTextureData2D( | ||||
texture, | ||||
format, | ||||
x, | ||||
y, | ||||
w, | ||||
h, | ||||
level, | ||||
data, | ||||
dataLength | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SetTextureData3D( | ||||
IGLTexture texture, | ||||
SurfaceFormat format, | ||||
int level, | ||||
int left, | ||||
int top, | ||||
int right, | ||||
int bottom, | ||||
int front, | ||||
int back, | ||||
IntPtr data, | ||||
int dataLength | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetTextureData3D( | ||||
texture, | ||||
format, | ||||
level, | ||||
left, | ||||
top, | ||||
right, | ||||
bottom, | ||||
front, | ||||
back, | ||||
data, | ||||
dataLength | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SetTextureDataCube( | ||||
IGLTexture texture, | ||||
SurfaceFormat format, | ||||
int xOffset, | ||||
int yOffset, | ||||
int width, | ||||
int height, | ||||
CubeMapFace cubeMapFace, | ||||
int level, | ||||
IntPtr data, | ||||
int dataLength | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetTextureDataCube( | ||||
texture, | ||||
format, | ||||
xOffset, | ||||
yOffset, | ||||
width, | ||||
height, | ||||
cubeMapFace, | ||||
level, | ||||
data, | ||||
dataLength | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void SetTextureDataYUV(Texture2D[] textures, IntPtr ptr) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetTextureDataYUV(textures, ptr); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void GetTextureData2D( | ||||
IGLTexture texture, | ||||
SurfaceFormat format, | ||||
int width, | ||||
int height, | ||||
int level, | ||||
int subX, | ||||
int subY, | ||||
int subW, | ||||
int subH, | ||||
IntPtr data, | ||||
int startIndex, | ||||
int elementCount, | ||||
int elementSizeInBytes | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.GetTextureData2D( | ||||
texture, | ||||
format, | ||||
width, | ||||
height, | ||||
level, | ||||
subX, | ||||
subY, | ||||
subW, | ||||
subH, | ||||
data, | ||||
startIndex, | ||||
elementCount, | ||||
elementSizeInBytes | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void GetTextureData3D( | ||||
IGLTexture texture, | ||||
SurfaceFormat format, | ||||
int left, | ||||
int top, | ||||
int front, | ||||
int right, | ||||
int bottom, | ||||
int back, | ||||
int level, | ||||
IntPtr data, | ||||
int startIndex, | ||||
int elementCount, | ||||
int elementSizeInBytes | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.GetTextureData3D( | ||||
texture, | ||||
format, | ||||
left, | ||||
top, | ||||
front, | ||||
right, | ||||
bottom, | ||||
back, | ||||
level, | ||||
data, | ||||
startIndex, | ||||
elementCount, | ||||
elementSizeInBytes | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void GetTextureDataCube( | ||||
IGLTexture texture, | ||||
SurfaceFormat format, | ||||
int size, | ||||
CubeMapFace cubeMapFace, | ||||
int level, | ||||
int subX, | ||||
int subY, | ||||
int subW, | ||||
int subH, | ||||
IntPtr data, | ||||
int startIndex, | ||||
int elementCount, | ||||
int elementSizeInBytes | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.GetTextureDataCube( | ||||
texture, | ||||
format, | ||||
size, | ||||
cubeMapFace, | ||||
level, | ||||
subX, | ||||
subY, | ||||
subW, | ||||
subH, | ||||
data, | ||||
startIndex, | ||||
elementCount, | ||||
elementSizeInBytes | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Renderbuffers | ||||
public IGLRenderbuffer GenRenderbuffer( | ||||
int width, | ||||
int height, | ||||
SurfaceFormat format, | ||||
int multiSampleCount, | ||||
IGLTexture texture | ||||
) { | ||||
IGLRenderbuffer result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.GenRenderbuffer( | ||||
width, | ||||
height, | ||||
format, | ||||
multiSampleCount, | ||||
texture | ||||
); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public IGLRenderbuffer GenRenderbuffer( | ||||
int width, | ||||
int height, | ||||
DepthFormat format, | ||||
int multiSampleCount | ||||
) { | ||||
IGLRenderbuffer result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.GenRenderbuffer( | ||||
width, | ||||
height, | ||||
format, | ||||
multiSampleCount | ||||
); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public void AddDisposeRenderbuffer(IGLRenderbuffer renderbuffer) | ||||
{ | ||||
GCRenderbuffers.Enqueue(renderbuffer); | ||||
} | ||||
#endregion | ||||
#region Vertex/Index Buffers | ||||
public IGLBuffer GenVertexBuffer( | ||||
bool dynamic, | ||||
BufferUsage usage, | ||||
int vertexCount, | ||||
int vertexStride | ||||
) { | ||||
IGLBuffer result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.GenVertexBuffer( | ||||
dynamic, | ||||
usage, | ||||
vertexCount, | ||||
vertexStride | ||||
); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public void AddDisposeVertexBuffer(IGLBuffer buffer) | ||||
{ | ||||
GCVertexBuffers.Enqueue(buffer); | ||||
} | ||||
public void SetVertexBufferData( | ||||
IGLBuffer buffer, | ||||
int offsetInBytes, | ||||
IntPtr data, | ||||
int dataLength, | ||||
SetDataOptions options | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetVertexBufferData( | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
dataLength, | ||||
options | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void GetVertexBufferData( | ||||
IGLBuffer buffer, | ||||
int offsetInBytes, | ||||
IntPtr data, | ||||
int startIndex, | ||||
int elementCount, | ||||
int elementSizeInBytes, | ||||
int vertexStride | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.GetVertexBufferData( | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
startIndex, | ||||
elementCount, | ||||
elementSizeInBytes, | ||||
vertexStride | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public IGLBuffer GenIndexBuffer( | ||||
bool dynamic, | ||||
BufferUsage usage, | ||||
int indexCount, | ||||
IndexElementSize indexElementSize | ||||
) { | ||||
IGLBuffer result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.GenIndexBuffer( | ||||
dynamic, | ||||
usage, | ||||
indexCount, | ||||
indexElementSize | ||||
); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public void AddDisposeIndexBuffer(IGLBuffer buffer) | ||||
{ | ||||
GCIndexBuffers.Enqueue(buffer); | ||||
} | ||||
public void SetIndexBufferData( | ||||
IGLBuffer buffer, | ||||
int offsetInBytes, | ||||
IntPtr data, | ||||
int dataLength, | ||||
SetDataOptions options | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.SetIndexBufferData( | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
dataLength, | ||||
options | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void GetIndexBufferData( | ||||
IGLBuffer buffer, | ||||
int offsetInBytes, | ||||
IntPtr data, | ||||
int startIndex, | ||||
int elementCount, | ||||
int elementSizeInBytes | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.GetIndexBufferData( | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
startIndex, | ||||
elementCount, | ||||
elementSizeInBytes | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Effects | ||||
public IGLEffect CreateEffect(byte[] effectCode) | ||||
{ | ||||
IGLEffect result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.CreateEffect(effectCode); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public IGLEffect CloneEffect(IGLEffect effect) | ||||
{ | ||||
IGLEffect result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.CloneEffect(effect); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public void AddDisposeEffect(IGLEffect effect) | ||||
{ | ||||
GCEffects.Enqueue(effect); | ||||
} | ||||
public void ApplyEffect( | ||||
IGLEffect effect, | ||||
IntPtr technique, | ||||
uint pass, | ||||
IntPtr stateChanges | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.ApplyEffect( | ||||
effect, | ||||
technique, | ||||
pass, | ||||
stateChanges | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void BeginPassRestore(IGLEffect effect, IntPtr stateChanges) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.BeginPassRestore(effect, stateChanges); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void EndPassRestore(IGLEffect effect) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.EndPassRestore(effect); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Vertex Attributes | ||||
public void ApplyVertexAttributes( | ||||
VertexBufferBinding[] bindings, | ||||
int numBindings, | ||||
bool bindingsUpdated, | ||||
int baseVertex | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.ApplyVertexAttributes( | ||||
bindings, | ||||
numBindings, | ||||
bindingsUpdated, | ||||
baseVertex | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void ApplyVertexAttributes( | ||||
VertexDeclaration vertexDeclaration, | ||||
IntPtr ptr, | ||||
int vertexOffset | ||||
) { | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.ApplyVertexAttributes( | ||||
vertexDeclaration, | ||||
ptr, | ||||
vertexOffset | ||||
); | ||||
}); // End ForceToMainThread | ||||
} | ||||
#endregion | ||||
#region Queries | ||||
public IGLQuery CreateQuery() | ||||
{ | ||||
IGLQuery result = null; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.CreateQuery(); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public void AddDisposeQuery(IGLQuery query) | ||||
{ | ||||
GCQueries.Enqueue(query); | ||||
} | ||||
public void QueryBegin(IGLQuery query) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.QueryBegin(query); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public void QueryEnd(IGLQuery query) | ||||
{ | ||||
ForceToMainThread(() => | ||||
{ | ||||
GLDevice.QueryEnd(query); | ||||
}); // End ForceToMainThread | ||||
} | ||||
public bool QueryComplete(IGLQuery query) | ||||
{ | ||||
bool result = false; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.QueryComplete(query); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
public int QueryPixelCount(IGLQuery query) | ||||
{ | ||||
int result = 0; | ||||
ForceToMainThread(() => | ||||
{ | ||||
result = GLDevice.QueryPixelCount(query); | ||||
}); // End ForceToMainThread | ||||
return result; | ||||
} | ||||
#endregion | ||||
} | ||||
} | ||||