mirror of
https://github.com/ZuneDev/MicrosoftIris.git
synced 2026-07-27 13:13:29 -07:00
Clean up initial OpenGL passes
This commit is contained in:
@@ -52,7 +52,7 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
public override void Play()
|
public override void Play()
|
||||||
{
|
{
|
||||||
base.Play();
|
base.Play();
|
||||||
foreach (GLAnimation a in m_members)
|
foreach (var a in m_members)
|
||||||
a.Play();
|
a.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
|
|
||||||
internal override void Advance(int advanceMs)
|
internal override void Advance(int advanceMs)
|
||||||
{
|
{
|
||||||
foreach (GLAnimation a in m_members)
|
foreach (var a in m_members)
|
||||||
a.Advance(advanceMs);
|
a.Advance(advanceMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,24 +36,19 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
{
|
{
|
||||||
if (m_paused)
|
if (m_paused)
|
||||||
return;
|
return;
|
||||||
int scaled = (int)(nAdvanceMs * SpeedAdjustment);
|
|
||||||
foreach (GLAnimation a in m_animations)
|
var scaled = (int)(nAdvanceMs * SpeedAdjustment);
|
||||||
{
|
StepAnimations(scaled);
|
||||||
if (a.IsPlaying)
|
|
||||||
a.Advance(scaled);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PauseAnimations() => m_paused = true;
|
public void PauseAnimations() => m_paused = true;
|
||||||
|
|
||||||
public void StepAnimations(int nAdvanceMs)
|
public void StepAnimations(int nAdvanceMs)
|
||||||
{
|
{
|
||||||
foreach (GLAnimation a in m_animations)
|
foreach (var a in m_animations)
|
||||||
{
|
|
||||||
if (a.IsPlaying)
|
if (a.IsPlaying)
|
||||||
a.Advance(nAdvanceMs);
|
a.Advance(nAdvanceMs);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void ResumeAnimations() => m_paused = false;
|
public void ResumeAnimations() => m_paused = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class GLDisplay : IDisplay
|
public sealed class GLDisplay : IDisplay
|
||||||
{
|
{
|
||||||
private readonly DisplayMode m_mode;
|
|
||||||
|
|
||||||
public GLDisplay(IMonitor monitor, bool isPrimary)
|
public GLDisplay(IMonitor monitor, bool isPrimary)
|
||||||
{
|
{
|
||||||
DeviceName = monitor.Name ?? $"Monitor{monitor.Index}";
|
DeviceName = monitor.Name ?? $"Monitor{monitor.Index}";
|
||||||
@@ -21,7 +19,7 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
|
|
||||||
var size = new Size(b.Size.X, b.Size.Y);
|
var size = new Size(b.Size.X, b.Size.Y);
|
||||||
LogicalFullScreenResolution = size;
|
LogicalFullScreenResolution = size;
|
||||||
m_mode = new DisplayMode
|
CurrentMode = new DisplayMode
|
||||||
{
|
{
|
||||||
sizePhysicalPxl = size,
|
sizePhysicalPxl = size,
|
||||||
sizeLogicalPxl = size,
|
sizeLogicalPxl = size,
|
||||||
@@ -39,11 +37,11 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
public bool TvMode => false;
|
public bool TvMode => false;
|
||||||
public Size LogicalFullScreenResolution { get; }
|
public Size LogicalFullScreenResolution { get; }
|
||||||
|
|
||||||
public DisplayMode[] SupportedModes => new[] { m_mode };
|
public DisplayMode[] SupportedModes => new[] { CurrentMode };
|
||||||
public DisplayMode[] ExtraModes => DisplayMode.EmptyModes;
|
public DisplayMode[] ExtraModes => DisplayMode.EmptyModes;
|
||||||
public DisplayMode[] AllModes => SupportedModes;
|
public DisplayMode[] AllModes => SupportedModes;
|
||||||
public DisplayMode CurrentMode => m_mode;
|
public DisplayMode CurrentMode { get; }
|
||||||
public DisplayMode DesktopMode => m_mode;
|
public DisplayMode DesktopMode => CurrentMode;
|
||||||
public string MonitorPnP => DeviceName;
|
public string MonitorPnP => DeviceName;
|
||||||
|
|
||||||
public bool ValidateDisplayMode(
|
public bool ValidateDisplayMode(
|
||||||
@@ -54,7 +52,7 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
out DisplayModeFlags nCompleteCheck)
|
out DisplayModeFlags nCompleteCheck)
|
||||||
{
|
{
|
||||||
// We only expose the desktop mode, so echo it back as the completed mode.
|
// We only expose the desktop mode, so echo it back as the completed mode.
|
||||||
modeComplete = m_mode;
|
modeComplete = CurrentMode;
|
||||||
nCompleteCheck = nCheck;
|
nCompleteCheck = nCheck;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,10 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
|
|
||||||
public IDisplay DisplayFromDeviceName(string stDeviceName)
|
public IDisplay DisplayFromDeviceName(string stDeviceName)
|
||||||
{
|
{
|
||||||
foreach (GLDisplay d in m_displays)
|
foreach (var d in m_displays)
|
||||||
{
|
|
||||||
if (d.DeviceName == stDeviceName)
|
if (d.DeviceName == stDeviceName)
|
||||||
return d;
|
return d;
|
||||||
}
|
|
||||||
return PrimaryDisplay;
|
return PrimaryDisplay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Microsoft.Iris.Input;
|
using Microsoft.Iris.Input;
|
||||||
using Silk.NET.Input;
|
using Silk.NET.Input;
|
||||||
using SilkKey = Silk.NET.Input.Key;
|
using SilkKey = Silk.NET.Input.Key;
|
||||||
@@ -37,9 +38,9 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
m_input = input;
|
m_input = input;
|
||||||
m_window = window;
|
m_window = window;
|
||||||
|
|
||||||
foreach (IKeyboard keyboard in context.Keyboards)
|
foreach (var keyboard in context.Keyboards)
|
||||||
Hook(keyboard);
|
Hook(keyboard);
|
||||||
foreach (IMouse mouse in context.Mice)
|
foreach (var mouse in context.Mice)
|
||||||
Hook(mouse);
|
Hook(mouse);
|
||||||
|
|
||||||
context.ConnectionChanged += OnConnectionChanged;
|
context.ConnectionChanged += OnConnectionChanged;
|
||||||
@@ -120,7 +121,14 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
|
|
||||||
private void OnMouseDown(IMouse mouse, SilkMouseButton button)
|
private void OnMouseDown(IMouse mouse, SilkMouseButton button)
|
||||||
{
|
{
|
||||||
(uint message, MouseButtons iris) = button switch
|
var message = MapSilkMouseButton(button, out var iris);
|
||||||
|
if (message != 0)
|
||||||
|
DispatchMouse(mouse, message, iris, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint MapSilkMouseButton(SilkMouseButton button, out MouseButtons iris)
|
||||||
|
{
|
||||||
|
(var message, iris) = button switch
|
||||||
{
|
{
|
||||||
SilkMouseButton.Left => (WM_LBUTTONDOWN, MouseButtons.Left),
|
SilkMouseButton.Left => (WM_LBUTTONDOWN, MouseButtons.Left),
|
||||||
SilkMouseButton.Right => (WM_RBUTTONDOWN, MouseButtons.Right),
|
SilkMouseButton.Right => (WM_RBUTTONDOWN, MouseButtons.Right),
|
||||||
@@ -129,36 +137,19 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
SilkMouseButton.Button5 => (WM_XBUTTONDOWN, MouseButtons.XButton2),
|
SilkMouseButton.Button5 => (WM_XBUTTONDOWN, MouseButtons.XButton2),
|
||||||
_ => (0u, MouseButtons.None),
|
_ => (0u, MouseButtons.None),
|
||||||
};
|
};
|
||||||
if (message != 0)
|
return message;
|
||||||
DispatchMouse(mouse, message, iris, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMouseUp(IMouse mouse, SilkMouseButton button)
|
private void OnMouseUp(IMouse mouse, SilkMouseButton button)
|
||||||
{
|
{
|
||||||
(uint message, MouseButtons iris) = button switch
|
var message = MapSilkMouseButton(button, out var iris);
|
||||||
{
|
|
||||||
SilkMouseButton.Left => (WM_LBUTTONUP, MouseButtons.Left),
|
|
||||||
SilkMouseButton.Right => (WM_RBUTTONUP, MouseButtons.Right),
|
|
||||||
SilkMouseButton.Middle => (WM_MBUTTONUP, MouseButtons.Middle),
|
|
||||||
SilkMouseButton.Button4 => (WM_XBUTTONUP, MouseButtons.XButton1),
|
|
||||||
SilkMouseButton.Button5 => (WM_XBUTTONUP, MouseButtons.XButton2),
|
|
||||||
_ => (0u, MouseButtons.None),
|
|
||||||
};
|
|
||||||
if (message != 0)
|
if (message != 0)
|
||||||
DispatchMouse(mouse, message, iris, 0);
|
DispatchMouse(mouse, message, iris, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDoubleClick(IMouse mouse, SilkMouseButton button, System.Numerics.Vector2 position)
|
private void OnDoubleClick(IMouse mouse, SilkMouseButton button, System.Numerics.Vector2 position)
|
||||||
{
|
{
|
||||||
(uint message, MouseButtons iris) = button switch
|
var message = MapSilkMouseButton(button, out var iris);
|
||||||
{
|
|
||||||
SilkMouseButton.Left => (WM_LBUTTONDBLCLK, MouseButtons.Left),
|
|
||||||
SilkMouseButton.Right => (WM_RBUTTONDBLCLK, MouseButtons.Right),
|
|
||||||
SilkMouseButton.Middle => (WM_MBUTTONDBLCLK, MouseButtons.Middle),
|
|
||||||
SilkMouseButton.Button4 => (WM_XBUTTONDBLCLK, MouseButtons.XButton1),
|
|
||||||
SilkMouseButton.Button5 => (WM_XBUTTONDBLCLK, MouseButtons.XButton2),
|
|
||||||
_ => (0u, MouseButtons.None),
|
|
||||||
};
|
|
||||||
if (message != 0)
|
if (message != 0)
|
||||||
DispatchMouse(mouse, message, iris, 0, doubleClick: true);
|
DispatchMouse(mouse, message, iris, 0, doubleClick: true);
|
||||||
}
|
}
|
||||||
@@ -216,41 +207,53 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
InputModifiers m = InputModifiers.None;
|
InputModifiers m = InputModifiers.None;
|
||||||
foreach (IKeyboard k in m_context.Keyboards)
|
foreach (IKeyboard k in m_context.Keyboards)
|
||||||
{
|
{
|
||||||
if (k.IsKeyPressed(SilkKey.ControlLeft) || k.IsKeyPressed(SilkKey.ControlRight)) m |= InputModifiers.ControlKey;
|
if (k.IsKeyPressed(SilkKey.ControlLeft) || k.IsKeyPressed(SilkKey.ControlRight))
|
||||||
if (k.IsKeyPressed(SilkKey.ShiftLeft) || k.IsKeyPressed(SilkKey.ShiftRight)) m |= InputModifiers.ShiftKey;
|
m |= InputModifiers.ControlKey;
|
||||||
if (k.IsKeyPressed(SilkKey.AltLeft) || k.IsKeyPressed(SilkKey.AltRight)) m |= InputModifiers.AltKey;
|
|
||||||
if (k.IsKeyPressed(SilkKey.SuperLeft) || k.IsKeyPressed(SilkKey.SuperRight)) m |= InputModifiers.WindowsKey;
|
if (k.IsKeyPressed(SilkKey.ShiftLeft) || k.IsKeyPressed(SilkKey.ShiftRight))
|
||||||
|
m |= InputModifiers.ShiftKey;
|
||||||
|
|
||||||
|
if (k.IsKeyPressed(SilkKey.AltLeft) || k.IsKeyPressed(SilkKey.AltRight))
|
||||||
|
m |= InputModifiers.AltKey;
|
||||||
|
|
||||||
|
if (k.IsKeyPressed(SilkKey.SuperLeft) || k.IsKeyPressed(SilkKey.SuperRight))
|
||||||
|
m |= InputModifiers.WindowsKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
mouse ??= FirstMouse();
|
mouse ??= FirstMouse();
|
||||||
if (mouse != null)
|
if (mouse != null)
|
||||||
{
|
{
|
||||||
if (mouse.IsButtonPressed(SilkMouseButton.Left)) m |= InputModifiers.LeftMouse;
|
if (mouse.IsButtonPressed(SilkMouseButton.Left))
|
||||||
if (mouse.IsButtonPressed(SilkMouseButton.Right)) m |= InputModifiers.RightMouse;
|
m |= InputModifiers.LeftMouse;
|
||||||
if (mouse.IsButtonPressed(SilkMouseButton.Middle)) m |= InputModifiers.MiddleMouse;
|
|
||||||
if (mouse.IsButtonPressed(SilkMouseButton.Button4)) m |= InputModifiers.XMouse1;
|
if (mouse.IsButtonPressed(SilkMouseButton.Right))
|
||||||
if (mouse.IsButtonPressed(SilkMouseButton.Button5)) m |= InputModifiers.XMouse2;
|
m |= InputModifiers.RightMouse;
|
||||||
|
|
||||||
|
if (mouse.IsButtonPressed(SilkMouseButton.Middle))
|
||||||
|
m |= InputModifiers.MiddleMouse;
|
||||||
|
|
||||||
|
if (mouse.IsButtonPressed(SilkMouseButton.Button4))
|
||||||
|
m |= InputModifiers.XMouse1;
|
||||||
|
|
||||||
|
if (mouse.IsButtonPressed(SilkMouseButton.Button5))
|
||||||
|
m |= InputModifiers.XMouse2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IMouse? FirstMouse()
|
private IMouse? FirstMouse() => m_context.Mice.Count > 0 ? m_context.Mice[0] : null;
|
||||||
{
|
|
||||||
foreach (IMouse mouse in m_context.Mice)
|
|
||||||
return mouse;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
m_context.ConnectionChanged -= OnConnectionChanged;
|
m_context.ConnectionChanged -= OnConnectionChanged;
|
||||||
foreach (IKeyboard keyboard in m_context.Keyboards)
|
foreach (var keyboard in m_context.Keyboards)
|
||||||
{
|
{
|
||||||
keyboard.KeyDown -= OnKeyDown;
|
keyboard.KeyDown -= OnKeyDown;
|
||||||
keyboard.KeyUp -= OnKeyUp;
|
keyboard.KeyUp -= OnKeyUp;
|
||||||
keyboard.KeyChar -= OnKeyChar;
|
keyboard.KeyChar -= OnKeyChar;
|
||||||
}
|
}
|
||||||
foreach (IMouse mouse in m_context.Mice)
|
foreach (var mouse in m_context.Mice)
|
||||||
{
|
{
|
||||||
mouse.MouseMove -= OnMouseMove;
|
mouse.MouseMove -= OnMouseMove;
|
||||||
mouse.MouseDown -= OnMouseDown;
|
mouse.MouseDown -= OnMouseDown;
|
||||||
|
|||||||
@@ -12,20 +12,9 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
/// <summary>Create an OpenGL render engine for the given Iris engine info.</summary>
|
/// <summary>Create an OpenGL render engine for the given Iris engine info.</summary>
|
||||||
public static IRenderEngine CreateEngine(IrisEngineInfo engineInfo, IRenderHost renderHost)
|
public static IRenderEngine CreateEngine(IrisEngineInfo engineInfo, IRenderHost renderHost)
|
||||||
{
|
{
|
||||||
if (engineInfo == null) throw new ArgumentNullException(nameof(engineInfo));
|
ArgumentNullException.ThrowIfNull(engineInfo);
|
||||||
if (renderHost == null) throw new ArgumentNullException(nameof(renderHost));
|
ArgumentNullException.ThrowIfNull(renderHost);
|
||||||
return new GLRenderEngine(engineInfo, renderHost);
|
return new GLRenderEngine(engineInfo, renderHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Convenience overload matching <c>RenderApi.CreateEngine</c>'s signature.
|
|
||||||
/// Only <see cref="IrisEngineInfo"/> is supported (the sole EngineType).
|
|
||||||
/// </summary>
|
|
||||||
public static IRenderEngine CreateEngine(EngineInfo engineInfo, IRenderHost renderHost)
|
|
||||||
{
|
|
||||||
if (engineInfo is not IrisEngineInfo iris)
|
|
||||||
throw new ArgumentException("Only IrisEngineInfo is supported.", nameof(engineInfo));
|
|
||||||
return CreateEngine(iris, renderHost);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,28 +10,33 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal sealed unsafe class SceneRenderer : IDisposable
|
internal sealed unsafe class SceneRenderer : IDisposable
|
||||||
{
|
{
|
||||||
private const string VertexSource = @"#version 330 core
|
private const string VertexSource =
|
||||||
layout(location = 0) in vec2 aPos;
|
"""
|
||||||
layout(location = 1) in vec2 aTex;
|
#version 330 core
|
||||||
uniform mat4 uModel;
|
layout(location = 0) in vec2 aPos;
|
||||||
uniform mat4 uProj;
|
layout(location = 1) in vec2 aTex;
|
||||||
uniform vec2 uSize;
|
uniform mat4 uModel;
|
||||||
out vec2 vTex;
|
uniform mat4 uProj;
|
||||||
void main()
|
uniform vec2 uSize;
|
||||||
{
|
out vec2 vTex;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
vTex = aTex;
|
vTex = aTex;
|
||||||
gl_Position = uProj * uModel * vec4(aPos * uSize, 0.0, 1.0);
|
gl_Position = uProj * uModel * vec4(aPos * uSize, 0.0, 1.0);
|
||||||
}";
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
private const string FragmentSource = @"#version 330 core
|
private const string FragmentSource =
|
||||||
in vec2 vTex;
|
"""
|
||||||
out vec4 fragColor;
|
#version 330 core
|
||||||
uniform sampler2D uTex;
|
in vec2 vTex;
|
||||||
uniform int uUseTexture;
|
out vec4 fragColor;
|
||||||
uniform vec4 uColor;
|
uniform sampler2D uTex;
|
||||||
uniform float uAlpha;
|
uniform int uUseTexture;
|
||||||
void main()
|
uniform vec4 uColor;
|
||||||
{
|
uniform float uAlpha;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
if (uUseTexture == 1)
|
if (uUseTexture == 1)
|
||||||
{
|
{
|
||||||
vec4 t = texture(uTex, vTex);
|
vec4 t = texture(uTex, vTex);
|
||||||
@@ -41,7 +46,8 @@ void main()
|
|||||||
{
|
{
|
||||||
fragColor = vec4(uColor.rgb, uColor.a * uAlpha);
|
fragColor = vec4(uColor.rgb, uColor.a * uAlpha);
|
||||||
}
|
}
|
||||||
}";
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
private readonly GL m_gl;
|
private readonly GL m_gl;
|
||||||
private readonly uint m_program;
|
private readonly uint m_program;
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
foreach (object v in m_values.Values)
|
foreach (var v in m_values.Values)
|
||||||
{
|
{
|
||||||
if (v is GLImage img)
|
if (v is GLImage img)
|
||||||
return img;
|
return img;
|
||||||
|
|||||||
@@ -77,16 +77,15 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
|
|
||||||
public void AddGradient(IGradient gradient)
|
public void AddGradient(IGradient gradient)
|
||||||
{
|
{
|
||||||
if (gradient is GLGradient g)
|
if (gradient is not GLGradient g)
|
||||||
{
|
return;
|
||||||
g.RegisterUsage(this);
|
g.RegisterUsage(this);
|
||||||
m_gradients.Add(g);
|
m_gradients.Add(g);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAllGradients()
|
public void RemoveAllGradients()
|
||||||
{
|
{
|
||||||
foreach (GLGradient g in m_gradients)
|
foreach (var g in m_gradients)
|
||||||
g.UnregisterUsage(this);
|
g.UnregisterUsage(this);
|
||||||
m_gradients.Clear();
|
m_gradients.Clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,14 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
public sealed class GLVisualContainer : GLVisual, IVisualContainer
|
public sealed class GLVisualContainer : GLVisual, IVisualContainer
|
||||||
{
|
{
|
||||||
private readonly List<GLVisual> m_children = new List<GLVisual>();
|
private readonly List<GLVisual> m_children = new List<GLVisual>();
|
||||||
private readonly bool m_isRoot;
|
|
||||||
|
|
||||||
public GLVisualContainer(GLRenderSession session, object ownerData, bool isRoot)
|
public GLVisualContainer(GLRenderSession session, object ownerData, bool isRoot)
|
||||||
: base(session, ownerData)
|
: base(session, ownerData)
|
||||||
{
|
{
|
||||||
m_isRoot = isRoot;
|
IsRoot = isRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsRoot => m_isRoot;
|
public bool IsRoot { get; }
|
||||||
public int ChildCount => m_children.Count;
|
public int ChildCount => m_children.Count;
|
||||||
public ICamera? Camera { get; set; }
|
public ICamera? Camera { get; set; }
|
||||||
|
|
||||||
@@ -52,12 +51,11 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
|
|
||||||
public void RemoveChild(IVisual vChild)
|
public void RemoveChild(IVisual vChild)
|
||||||
{
|
{
|
||||||
if (vChild is GLVisual child && m_children.Remove(child))
|
if (vChild is not GLVisual child || !m_children.Remove(child))
|
||||||
{
|
return;
|
||||||
child.ParentContainer = null;
|
child.ParentContainer = null;
|
||||||
child.UnregisterUsage(this);
|
child.UnregisterUsage(this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAllChildren()
|
public void RemoveAllChildren()
|
||||||
{
|
{
|
||||||
@@ -77,7 +75,7 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
// Draw children back-to-front by layer. OrderBy is stable, preserving
|
// Draw children back-to-front by layer. OrderBy is stable, preserving
|
||||||
// insertion order within a layer.
|
// insertion order within a layer.
|
||||||
m_children.Sort((a, b) => a.Layer.CompareTo(b.Layer));
|
m_children.Sort((a, b) => a.Layer.CompareTo(b.Layer));
|
||||||
foreach (GLVisual child in m_children)
|
foreach (var child in m_children)
|
||||||
child.Render(renderer, matrix, alpha);
|
child.Render(renderer, matrix, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +91,7 @@ namespace Microsoft.Iris.Render.OpenGL
|
|||||||
m_children.Sort((a, b) => a.Layer.CompareTo(b.Layer));
|
m_children.Sort((a, b) => a.Layer.CompareTo(b.Layer));
|
||||||
for (int i = m_children.Count - 1; i >= 0; i--)
|
for (int i = m_children.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
GLVisual? hit = m_children[i].HitTest(screenPoint, world);
|
var hit = m_children[i].HitTest(screenPoint, world);
|
||||||
if (hit != null)
|
if (hit != null)
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,49 +112,6 @@ namespace Microsoft.Iris.Render.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !NETFRAMEWORK
|
|
||||||
public static HRESULT SpInit(ref InitArgs args) => new HRESULT(0);
|
|
||||||
|
|
||||||
public static HRESULT SpUninit() => new HRESULT(0);
|
|
||||||
|
|
||||||
public static unsafe HRESULT SpBufferOpen(
|
|
||||||
BufferInfo* phdrData,
|
|
||||||
void* pvData)
|
|
||||||
{
|
|
||||||
var src = new Iface.ContextID(ContextID.ToUInt32(phdrData->idContextSrc));
|
|
||||||
var dest = new Iface.ContextID(ContextID.ToUInt32(phdrData->idContextDest));
|
|
||||||
var bufferHandle = new Iface.RENDERHANDLE(RENDERHANDLE.ToUInt32(phdrData->idBuffer));
|
|
||||||
var flags = (Iface.BufferFlags)phdrData->nFlags;
|
|
||||||
var span = new ReadOnlySpan<byte>(pvData, (int)phdrData->cbSizeBuffer);
|
|
||||||
|
|
||||||
Iface.HRESULT result = EngineService.SendBuffer(src, dest, bufferHandle, flags, span);
|
|
||||||
return new HRESULT(result.hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe HRESULT SpWrapBufferProc(
|
|
||||||
MessageBufferEventHandler pfnProcessBufferProc,
|
|
||||||
IntPtr* ppNativeProc)
|
|
||||||
{
|
|
||||||
if (ppNativeProc == null)
|
|
||||||
return new HRESULT(unchecked((int)0x80070057));
|
|
||||||
|
|
||||||
if (pfnProcessBufferProc == null)
|
|
||||||
{
|
|
||||||
*ppNativeProc = IntPtr.Zero;
|
|
||||||
return new HRESULT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Managed-direct: store the delegate itself instead of marshaling to a
|
|
||||||
// native function pointer -- SpRenderThreadInit resolves this straight back
|
|
||||||
// to the delegate object and invokes it directly, no calli anywhere on this
|
|
||||||
// path. See logs/UIXrender/EngineCore.md.
|
|
||||||
GCHandle handle = GCHandle.Alloc(pfnProcessBufferProc, GCHandleType.Normal);
|
|
||||||
*ppNativeProc = GCHandle.ToIntPtr(handle);
|
|
||||||
return new HRESULT(0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// net461 (EnableNetFXTarget): UIXrender's managed API isn't referenceable from
|
|
||||||
// .NET Framework, so this TFM keeps calling the real native UIXRender.dll.
|
|
||||||
[DllImport(s_stEhRenderDll)]
|
[DllImport(s_stEhRenderDll)]
|
||||||
public static extern HRESULT SpInit(ref InitArgs args);
|
public static extern HRESULT SpInit(ref InitArgs args);
|
||||||
|
|
||||||
@@ -170,41 +127,7 @@ namespace Microsoft.Iris.Render.Protocol
|
|||||||
public static extern unsafe HRESULT SpWrapBufferProc(
|
public static extern unsafe HRESULT SpWrapBufferProc(
|
||||||
MessageBufferEventHandler pfnProcessBufferProc,
|
MessageBufferEventHandler pfnProcessBufferProc,
|
||||||
IntPtr* ppNativeProc);
|
IntPtr* ppNativeProc);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !NETFRAMEWORK
|
|
||||||
// No Win32 message queue exists behind this reimplementation (see EngineService),
|
|
||||||
// and LocalChannel -- the path Zune uses -- never peeks. Reports "no message".
|
|
||||||
public static HRESULT SpPeekMessage(
|
|
||||||
out Win32Api.MSG msg,
|
|
||||||
HWND hwnd,
|
|
||||||
uint nMsgFilterMin,
|
|
||||||
uint nMsgFilterMax,
|
|
||||||
uint wRemoveMsg,
|
|
||||||
out WorkResult nResult)
|
|
||||||
{
|
|
||||||
msg = default;
|
|
||||||
nResult = (WorkResult)EngineService.PeekMessage(nMsgFilterMin, nMsgFilterMax, wRemoveMsg);
|
|
||||||
return new HRESULT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HRESULT SpWaitMessage(uint nTimeOutMs, IntPtr _unused)
|
|
||||||
{
|
|
||||||
EngineService.WaitMessage(nTimeOutMs);
|
|
||||||
return new HRESULT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HRESULT SpInvoke(
|
|
||||||
ContextID idContext,
|
|
||||||
IntPtr pfnInvoke,
|
|
||||||
IntPtr pvArgs,
|
|
||||||
bool synchronous)
|
|
||||||
{
|
|
||||||
Iface.HRESULT result = EngineService.Invoke(
|
|
||||||
new Iface.ContextID(ContextID.ToUInt32(idContext)), pfnInvoke, pvArgs, synchronous);
|
|
||||||
return new HRESULT(result.hr);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
[DllImport(s_stEhRenderDll, CharSet = CharSet.Auto)]
|
[DllImport(s_stEhRenderDll, CharSet = CharSet.Auto)]
|
||||||
public static extern HRESULT SpPeekMessage(
|
public static extern HRESULT SpPeekMessage(
|
||||||
out Win32Api.MSG msg,
|
out Win32Api.MSG msg,
|
||||||
@@ -223,65 +146,7 @@ namespace Microsoft.Iris.Render.Protocol
|
|||||||
IntPtr pfnInvoke,
|
IntPtr pfnInvoke,
|
||||||
IntPtr pvArgs,
|
IntPtr pvArgs,
|
||||||
bool synchronous);
|
bool synchronous);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !NETFRAMEWORK
|
|
||||||
public static HRESULT SpRenderThreadInit(
|
|
||||||
ref InitArgs argsRender,
|
|
||||||
out IntPtr pThread)
|
|
||||||
{
|
|
||||||
var contextId = new Iface.ContextID(ContextID.ToUInt32(argsRender.idContext));
|
|
||||||
|
|
||||||
MessageBufferEventHandler managedCallback = argsRender.pfnProcessBuffer != IntPtr.Zero
|
|
||||||
? GCHandle.FromIntPtr(argsRender.pfnProcessBuffer).Target as MessageBufferEventHandler
|
|
||||||
: null;
|
|
||||||
|
|
||||||
BufferReceivedHandler handler = managedCallback != null
|
|
||||||
? AdaptCallback(managedCallback, argsRender.idContext)
|
|
||||||
: delegate { };
|
|
||||||
|
|
||||||
IRenderThreadHandle threadHandle = EngineService.StartRenderThread(contextId, handler);
|
|
||||||
pThread = GCHandle.ToIntPtr(GCHandle.Alloc(threadHandle, GCHandleType.Normal));
|
|
||||||
return new HRESULT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adapts a stored MessageBufferEventHandler (already-decompiled, still
|
|
||||||
// pointer-shaped -- see logs/UIXrender/EngineCore.md) into the idiomatic
|
|
||||||
// BufferReceivedHandler shape EngineService deals in. Factored out of
|
|
||||||
// SpRenderThreadInit so that method reads as resolve -> adapt -> start -> wrap,
|
|
||||||
// and named to make clear it's the same kind of adaptation
|
|
||||||
// UIXrender/Interop/EngineApi.cs's own SpRenderThreadInit does for native
|
|
||||||
// callers (there: raw function pointer -> BufferReceivedHandler; here: managed
|
|
||||||
// delegate -> BufferReceivedHandler -- same shape, different invocation
|
|
||||||
// mechanism at the end).
|
|
||||||
private static unsafe BufferReceivedHandler AdaptCallback(MessageBufferEventHandler callback, ContextID destContext) =>
|
|
||||||
(source, bufferHandle, flags, data) =>
|
|
||||||
{
|
|
||||||
fixed (byte* pData = data)
|
|
||||||
{
|
|
||||||
var info = new BufferInfo
|
|
||||||
{
|
|
||||||
idContextSrc = ContextID.FromUInt32(source.value),
|
|
||||||
idContextDest = destContext,
|
|
||||||
idBuffer = RENDERHANDLE.FromUInt32(bufferHandle.value),
|
|
||||||
nFlags = (BufferFlags)flags,
|
|
||||||
cbSizeBuffer = (uint)data.Length,
|
|
||||||
};
|
|
||||||
callback(IntPtr.Zero, source.value, &info, pData);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static HRESULT SpRenderThreadUninit(IntPtr pThread)
|
|
||||||
{
|
|
||||||
if (pThread == IntPtr.Zero)
|
|
||||||
return new HRESULT(unchecked((int)0x80070057));
|
|
||||||
|
|
||||||
GCHandle handle = GCHandle.FromIntPtr(pThread);
|
|
||||||
(handle.Target as IDisposable)?.Dispose();
|
|
||||||
handle.Free();
|
|
||||||
return new HRESULT(0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
[DllImport(s_stEhRenderDll)]
|
[DllImport(s_stEhRenderDll)]
|
||||||
public static extern HRESULT SpRenderThreadInit(
|
public static extern HRESULT SpRenderThreadInit(
|
||||||
ref InitArgs argsRender,
|
ref InitArgs argsRender,
|
||||||
@@ -289,86 +154,8 @@ namespace Microsoft.Iris.Render.Protocol
|
|||||||
|
|
||||||
[DllImport(s_stEhRenderDll)]
|
[DllImport(s_stEhRenderDll)]
|
||||||
public static extern HRESULT SpRenderThreadUninit(IntPtr pThread);
|
public static extern HRESULT SpRenderThreadUninit(IntPtr pThread);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !NETFRAMEWORK
|
|
||||||
public static HRESULT SpRemoteCreateServerStreams(
|
|
||||||
string stSession,
|
|
||||||
TransportProtocol nProtocol,
|
|
||||||
out IntPtr pSendStream,
|
|
||||||
out IntPtr pReceiveStream)
|
|
||||||
{
|
|
||||||
Iface.HRESULT result = EngineService.RemoteCreateServerStreams(
|
|
||||||
stSession, (Iface.Protocol.TransportProtocol)(int)nProtocol, out pSendStream, out pReceiveStream);
|
|
||||||
return new HRESULT(result.hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HRESULT SpRemoteWaitServerStreamsConnected(
|
|
||||||
TransportProtocol nProtocol,
|
|
||||||
IntPtr pSendStream,
|
|
||||||
IntPtr pReceiveStream)
|
|
||||||
{
|
|
||||||
Iface.HRESULT result = EngineService.RemoteWaitServerStreamsConnected(
|
|
||||||
(Iface.Protocol.TransportProtocol)(int)nProtocol, pSendStream);
|
|
||||||
return new HRESULT(result.hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HRESULT SpRemoteServerInit(
|
|
||||||
IntPtr pSendStream,
|
|
||||||
IntPtr pReceiveStream,
|
|
||||||
InitArgs argsSend,
|
|
||||||
out IntPtr pSession)
|
|
||||||
{
|
|
||||||
var context = new Iface.ContextID(ContextID.ToUInt32(argsSend.idContext));
|
|
||||||
|
|
||||||
// Same delegate-behind-a-GCHandle representation SpRenderThreadInit resolves;
|
|
||||||
// RemoteChannel connects without a receive callback (pfnProcessBuffer == 0),
|
|
||||||
// so this is normally null.
|
|
||||||
MessageBufferEventHandler managedCallback = argsSend.pfnProcessBuffer != IntPtr.Zero
|
|
||||||
? GCHandle.FromIntPtr(argsSend.pfnProcessBuffer).Target as MessageBufferEventHandler
|
|
||||||
: null;
|
|
||||||
BufferReceivedHandler handler = managedCallback != null
|
|
||||||
? AdaptCallback(managedCallback, argsSend.idContext)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
Iface.HRESULT result = EngineService.RemoteServerInit(pSendStream, context, handler, out pSession);
|
|
||||||
return new HRESULT(result.hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HRESULT SpRemoteServerUninit(
|
|
||||||
IntPtr pSession,
|
|
||||||
bool fForceShutdown,
|
|
||||||
out ShutdownReason nShutdownReason)
|
|
||||||
{
|
|
||||||
Iface.HRESULT result = EngineService.RemoteServerUninit(
|
|
||||||
pSession, fForceShutdown, out Iface.Protocol.ShutdownReason reason);
|
|
||||||
nShutdownReason = (ShutdownReason)(int)reason;
|
|
||||||
return new HRESULT(result.hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HRESULT SpDx9CompileEffect(
|
|
||||||
string stEffect,
|
|
||||||
string stDefines,
|
|
||||||
out IntPtr pErrorString,
|
|
||||||
out IntPtr pErrorBuffer,
|
|
||||||
out IntPtr pEffectBlob,
|
|
||||||
out uint EffectBlobSize,
|
|
||||||
out IntPtr pEffectBlobBuffer)
|
|
||||||
{
|
|
||||||
pErrorString = IntPtr.Zero;
|
|
||||||
pErrorBuffer = IntPtr.Zero;
|
|
||||||
pEffectBlob = IntPtr.Zero;
|
|
||||||
EffectBlobSize = 0U;
|
|
||||||
pEffectBlobBuffer = IntPtr.Zero;
|
|
||||||
return new HRESULT(EngineService.Dx9CompileEffect().hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SpObjectRelease's only callers (RemoteChannel) release the stream handles from
|
|
||||||
// SpRemoteCreateServerStreams, which in the managed-direct path are UIXrender
|
|
||||||
// handles, not COM pointers -- so this drops the handle's reference rather than
|
|
||||||
// calling through a vtable.
|
|
||||||
public static void SpObjectRelease(IntPtr pUnknown) => EngineService.ReleaseRemoteStream(pUnknown);
|
|
||||||
#else
|
|
||||||
[DllImport(s_stEhRenderDll, CharSet = CharSet.Unicode)]
|
[DllImport(s_stEhRenderDll, CharSet = CharSet.Unicode)]
|
||||||
public static extern HRESULT SpRemoteCreateServerStreams(
|
public static extern HRESULT SpRemoteCreateServerStreams(
|
||||||
string stSession,
|
string stSession,
|
||||||
@@ -407,7 +194,6 @@ namespace Microsoft.Iris.Render.Protocol
|
|||||||
|
|
||||||
[DllImport(s_stEhRenderDll)]
|
[DllImport(s_stEhRenderDll)]
|
||||||
public static extern void SpObjectRelease(IntPtr pUnknown);
|
public static extern void SpObjectRelease(IntPtr pUnknown);
|
||||||
#endif
|
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum BufferFlags
|
public enum BufferFlags
|
||||||
|
|||||||
Reference in New Issue
Block a user