Files
Xune/UIX.RenderApi.Skia/Microsoft/Iris/Render/Internal/RenderEngine.cs
T

227 lines
8.8 KiB
C#
Raw Normal View History

using Microsoft.Iris.Library;
2021-07-11 22:59:29 -05:00
using Microsoft.Iris.Render.Common;
using Microsoft.Iris.Render.Protocol;
using Microsoft.Iris.Render.Sound;
using System;
using System.Collections;
namespace Microsoft.Iris.Render.Internal
{
2021-07-11 23:04:40 -05:00
internal class RenderEngine : RenderObject, IRenderEngine, IRenderObject, IDisposable
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
private static BitArray s_contexts;
private static uint s_contextIdSeed = 1;
private static uint s_maxContextId = 254;
private RenderToken m_primaryToken;
private MessagingSession m_messagingSession;
private RenderSession m_renderSession;
private RenderCaps m_renderCaps;
private GraphicsDeviceType m_typeGraphics;
private SoundDeviceType m_typeSound;
private RenderWindowBase m_renderWindow;
2021-07-11 23:04:40 -05:00
private InputSystem m_inputSystem;
private SoundDevice m_soundDevice;
private ContextID m_localContextId;
private ContextID m_engineContextId;
2021-07-11 22:59:29 -05:00
2021-07-11 23:07:04 -05:00
static RenderEngine() => s_contexts = new BitArray((int)s_maxContextId + 1);
2021-07-11 23:04:40 -05:00
internal RenderEngine(IrisEngineInfo engineInfo, IRenderHost renderHost)
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
Debug2.Validate(engineInfo != null, typeof(ArgumentNullException), nameof(engineInfo));
Debug2.Validate(renderHost != null, typeof(ArgumentNullException), nameof(renderHost));
m_engineInfo = engineInfo;
m_engineContextId = AllocateContextId();
m_localContextId = AllocateContextId();
m_primaryToken = new RenderToken(engineInfo, m_localContextId, m_engineContextId, RENDERGROUP.NULL);
m_messagingSession = new MessagingSession(renderHost, this.m_primaryToken);
2021-07-11 23:04:40 -05:00
this.m_renderSession = new RenderSession(this);
this.m_renderCaps = new RenderCaps(engineInfo.Surface);
2021-07-11 23:04:40 -05:00
this.m_renderCaps.RequestCaps();
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
protected override void Dispose(bool fInDispose)
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
try
{
if (fInDispose)
{
//this.m_renderSession.ReleaseSharedResources();
//if (this.m_renderWindow != null)
// this.m_renderWindow.WindowCreatedEvent -= new EventHandler(OnRenderWindowCreated);
if (m_soundDevice != null)
m_soundDevice.Dispose();
//if (this.m_renderWindow != null)
// this.m_renderWindow.Dispose();
if (m_inputSystem != null)
m_inputSystem.Dispose();
//if (this.m_displayManager != null)
// this.m_displayManager.Dispose();
//if (this.m_renderSession != null)
// this.m_renderSession.Dispose();
2021-07-11 23:04:40 -05:00
if (this.m_messagingSession != null)
{
if (this.m_messagingSession.IsConnected)
this.m_messagingSession.Disconnect();
this.m_messagingSession.Dispose();
}
FreeContextId(m_localContextId);
FreeContextId(m_engineContextId);
2021-07-11 23:04:40 -05:00
}
m_soundDevice = null;
//this.m_displayManager = null;
//this.m_renderWindow = null;
//this.m_renderSession = null;
2021-07-11 23:07:04 -05:00
this.m_messagingSession = null;
2021-07-11 23:04:40 -05:00
}
finally
{
base.Dispose(fInDispose);
}
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
void IRenderEngine.Initialize(
2021-07-16 16:03:13 -05:00
GraphicsDeviceType typeGraphics,
GraphicsRenderingQuality renderingQuality,
SoundDeviceType typeSound)
2021-07-11 23:04:40 -05:00
{
Debug2.Validate(IsGraphicsDeviceAvailable(typeGraphics, false), typeof(InvalidOperationException), "Graphics device type not available");
Debug2.Validate(IsSoundDeviceAvailable(typeSound), typeof(InvalidOperationException), "Sound device type not available");
m_typeGraphics = typeGraphics;
m_typeSound = typeSound;
m_renderSession.Initialize();
// TODO: Set up input system
//m_inputSystem = new InputSystem(this.m_renderSession, this.m_renderWindow);
2021-07-11 23:04:40 -05:00
}
2021-07-11 22:59:29 -05:00
IRenderSession IRenderEngine.Session => m_renderSession;//throw new NotSupportedException("Skia does not use render sessions"); m_renderSession;
2021-07-11 23:04:40 -05:00
internal RenderSession Session => m_renderSession;
2021-07-11 23:04:40 -05:00
IRenderWindow IRenderEngine.Window => m_renderWindow;
internal RenderWindowBase Window => m_renderWindow;
2021-07-11 23:04:40 -05:00
IDisplayManager IRenderEngine.DisplayManager => null;
2021-07-11 23:04:40 -05:00
public InputSystem InputSystem => throw new NotImplementedException("Skia does not support input yet");// m_inputSystem;
2021-07-11 23:04:40 -05:00
internal SoundDevice SoundDevice => m_soundDevice;
2021-07-11 23:04:40 -05:00
2021-07-16 16:03:13 -05:00
internal Vector<GraphicsCaps> GraphicsCaps => this.m_renderCaps.Graphics;
2021-07-11 23:04:40 -05:00
2021-07-16 16:03:13 -05:00
internal Vector<SoundCaps> SoundCaps => this.m_renderCaps.Sound;
2021-07-11 23:04:40 -05:00
private void DoEvents(uint nTimeoutInMsecs)
{
MessagingSession.DoEvents(nTimeoutInMsecs);
}
void IRenderEngine.WaitForWork(uint nTimeoutInMsecs)
{
EngineApi.SpWaitMessage(nTimeoutInMsecs, IntPtr.Zero);
}
void IRenderEngine.FlushBatch()
{
2021-07-11 23:04:40 -05:00
}
bool IRenderEngine.IsGraphicsDeviceAvailable(
GraphicsDeviceType type,
bool fFilterRecommended)
{
return IsGraphicsDeviceAvailable(type, fFilterRecommended);
2021-07-11 23:04:40 -05:00
}
private bool IsGraphicsDeviceAvailable(GraphicsDeviceType type, bool fFilterRecommended)
{
2021-07-16 16:03:13 -05:00
foreach (GraphicsCaps graphic in this.m_renderCaps.Graphics)
2021-07-11 23:04:40 -05:00
{
2021-07-16 16:03:13 -05:00
if (graphic.DeviceType.FulfillsRequirement(type))
2021-07-11 23:04:40 -05:00
return !fFilterRecommended || graphic.DriverWarning == 0;
}
return false;
}
bool IRenderEngine.IsSoundDeviceAvailable(SoundDeviceType type) => IsSoundDeviceAvailable(type);
2021-07-11 23:04:40 -05:00
private bool IsSoundDeviceAvailable(SoundDeviceType type)
{
if (type == SoundDeviceType.None)
return true;
foreach (SoundCaps soundCaps in this.m_renderCaps.Sound)
2021-07-11 23:04:40 -05:00
{
if ((SoundDeviceType)soundCaps.DeviceType == type)
return true;
}
return false;
}
private void OnRenderWindowCreated(object sender, EventArgs args)
{
2021-07-11 23:07:04 -05:00
SoundDevice soundDevice = null;
switch (m_typeSound)
2021-07-11 23:04:40 -05:00
{
case SoundDeviceType.None:
m_soundDevice = soundDevice;
2021-07-11 23:04:40 -05:00
break;
case SoundDeviceType.DirectSound8:
//soundDevice = new Ds8SoundDevice(this.m_renderSession, m_renderWindow);
//goto case SoundDeviceType.None;
2021-07-11 23:04:40 -05:00
case SoundDeviceType.WaveAudio:
case SoundDeviceType.XAudio:
case SoundDeviceType.XAudio2:
2021-07-11 23:04:40 -05:00
Debug2.Validate(false, typeof(NotImplementedException), "{0} is not yet supported");
break;
2021-07-11 23:04:40 -05:00
default:
Debug2.Validate(false, typeof(ArgumentException), "typeSound");
break;
2021-07-11 23:04:40 -05:00
}
}
internal static ContextID AllocateContextId()
{
uint num1 = 0;
2021-07-11 23:07:04 -05:00
lock (s_contexts)
2021-07-11 23:04:40 -05:00
{
2021-07-11 23:07:04 -05:00
for (int index = 0; index < s_maxContextId; ++index)
2021-07-11 23:04:40 -05:00
{
2021-07-11 23:07:04 -05:00
uint num2 = s_contextIdSeed++;
if (s_contextIdSeed > s_maxContextId)
s_contextIdSeed = 1U;
if (!s_contexts[(int)num2])
2021-07-11 23:04:40 -05:00
{
num1 = num2;
2021-07-11 23:07:04 -05:00
s_contexts[(int)num1] = true;
2021-07-11 23:04:40 -05:00
break;
}
}
}
Debug2.Validate(num1 != 0U, typeof(InvalidOperationException), "Failed to allocate a context ID");
return ContextID.FromUInt32(num1);
}
private static void FreeContextId(ContextID contextId)
{
uint uint32 = ContextID.ToUInt32(contextId);
2021-07-11 23:07:04 -05:00
Debug2.Validate(s_contexts[(int)uint32], typeof(InvalidOperationException), "ContextID is not in use");
lock (s_contexts)
s_contexts[(int)uint32] = false;
2021-07-11 23:04:40 -05:00
}
protected override void Invariant()
{
Debug2.Validate(m_localContextId != ContextID.NULL, typeof(InvalidOperationException), "local ContextId should not be NULL while running");
Debug2.Validate(m_engineContextId != ContextID.NULL, typeof(InvalidOperationException), "engine ContextId should not be NULL while running");
}
bool IRenderEngine.ProcessNativeEvents() => true;
void IRenderEngine.InterThreadWake()
{
2021-07-11 23:04:40 -05:00
}
2021-07-11 22:59:29 -05:00
}
}