From b20af287eabab7f9c98f93adeebe8fedbb537f18 Mon Sep 17 00:00:00 2001 From: Yoshi Askharoun Date: Sat, 25 Jul 2026 19:32:47 -0500 Subject: [PATCH] Clean up initial OpenGL passes --- UIX.RenderApi.OpenGL/Animation/GLAnimation.cs | 4 +- .../Animation/GLAnimationSystem.cs | 13 +- UIX.RenderApi.OpenGL/Engine/GLDisplay.cs | 12 +- .../Engine/GLDisplayManager.cs | 5 +- .../Engine/GLInputTranslator.cs | 83 +++---- UIX.RenderApi.OpenGL/OpenGLRenderApi.cs | 15 +- .../Rendering/SceneRenderer.cs | 68 +++--- UIX.RenderApi.OpenGL/Scene/GLEffect.cs | 2 +- UIX.RenderApi.OpenGL/Scene/GLVisual.cs | 11 +- .../Scene/GLVisualContainer.cs | 18 +- .../Iris/Render/Protocol/EngineApi.cs | 214 ------------------ 11 files changed, 109 insertions(+), 336 deletions(-) diff --git a/UIX.RenderApi.OpenGL/Animation/GLAnimation.cs b/UIX.RenderApi.OpenGL/Animation/GLAnimation.cs index 8fa90e7..10e3923 100644 --- a/UIX.RenderApi.OpenGL/Animation/GLAnimation.cs +++ b/UIX.RenderApi.OpenGL/Animation/GLAnimation.cs @@ -52,7 +52,7 @@ namespace Microsoft.Iris.Render.OpenGL public override void Play() { base.Play(); - foreach (GLAnimation a in m_members) + foreach (var a in m_members) a.Play(); } @@ -60,7 +60,7 @@ namespace Microsoft.Iris.Render.OpenGL internal override void Advance(int advanceMs) { - foreach (GLAnimation a in m_members) + foreach (var a in m_members) a.Advance(advanceMs); } } diff --git a/UIX.RenderApi.OpenGL/Animation/GLAnimationSystem.cs b/UIX.RenderApi.OpenGL/Animation/GLAnimationSystem.cs index b48806d..f058cc6 100644 --- a/UIX.RenderApi.OpenGL/Animation/GLAnimationSystem.cs +++ b/UIX.RenderApi.OpenGL/Animation/GLAnimationSystem.cs @@ -36,23 +36,18 @@ namespace Microsoft.Iris.Render.OpenGL { if (m_paused) return; - int scaled = (int)(nAdvanceMs * SpeedAdjustment); - foreach (GLAnimation a in m_animations) - { - if (a.IsPlaying) - a.Advance(scaled); - } + + var scaled = (int)(nAdvanceMs * SpeedAdjustment); + StepAnimations(scaled); } public void PauseAnimations() => m_paused = true; public void StepAnimations(int nAdvanceMs) { - foreach (GLAnimation a in m_animations) - { + foreach (var a in m_animations) if (a.IsPlaying) a.Advance(nAdvanceMs); - } } public void ResumeAnimations() => m_paused = false; diff --git a/UIX.RenderApi.OpenGL/Engine/GLDisplay.cs b/UIX.RenderApi.OpenGL/Engine/GLDisplay.cs index 9620ab4..6c44374 100644 --- a/UIX.RenderApi.OpenGL/Engine/GLDisplay.cs +++ b/UIX.RenderApi.OpenGL/Engine/GLDisplay.cs @@ -9,8 +9,6 @@ namespace Microsoft.Iris.Render.OpenGL /// public sealed class GLDisplay : IDisplay { - private readonly DisplayMode m_mode; - public GLDisplay(IMonitor monitor, bool isPrimary) { 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); LogicalFullScreenResolution = size; - m_mode = new DisplayMode + CurrentMode = new DisplayMode { sizePhysicalPxl = size, sizeLogicalPxl = size, @@ -39,11 +37,11 @@ namespace Microsoft.Iris.Render.OpenGL public bool TvMode => false; public Size LogicalFullScreenResolution { get; } - public DisplayMode[] SupportedModes => new[] { m_mode }; + public DisplayMode[] SupportedModes => new[] { CurrentMode }; public DisplayMode[] ExtraModes => DisplayMode.EmptyModes; public DisplayMode[] AllModes => SupportedModes; - public DisplayMode CurrentMode => m_mode; - public DisplayMode DesktopMode => m_mode; + public DisplayMode CurrentMode { get; } + public DisplayMode DesktopMode => CurrentMode; public string MonitorPnP => DeviceName; public bool ValidateDisplayMode( @@ -54,7 +52,7 @@ namespace Microsoft.Iris.Render.OpenGL out DisplayModeFlags nCompleteCheck) { // We only expose the desktop mode, so echo it back as the completed mode. - modeComplete = m_mode; + modeComplete = CurrentMode; nCompleteCheck = nCheck; return true; } diff --git a/UIX.RenderApi.OpenGL/Engine/GLDisplayManager.cs b/UIX.RenderApi.OpenGL/Engine/GLDisplayManager.cs index a426518..ce9442a 100644 --- a/UIX.RenderApi.OpenGL/Engine/GLDisplayManager.cs +++ b/UIX.RenderApi.OpenGL/Engine/GLDisplayManager.cs @@ -33,11 +33,10 @@ namespace Microsoft.Iris.Render.OpenGL public IDisplay DisplayFromDeviceName(string stDeviceName) { - foreach (GLDisplay d in m_displays) - { + foreach (var d in m_displays) if (d.DeviceName == stDeviceName) return d; - } + return PrimaryDisplay; } } diff --git a/UIX.RenderApi.OpenGL/Engine/GLInputTranslator.cs b/UIX.RenderApi.OpenGL/Engine/GLInputTranslator.cs index 7026330..b010d15 100644 --- a/UIX.RenderApi.OpenGL/Engine/GLInputTranslator.cs +++ b/UIX.RenderApi.OpenGL/Engine/GLInputTranslator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.Iris.Input; using Silk.NET.Input; using SilkKey = Silk.NET.Input.Key; @@ -37,9 +38,9 @@ namespace Microsoft.Iris.Render.OpenGL m_input = input; m_window = window; - foreach (IKeyboard keyboard in context.Keyboards) + foreach (var keyboard in context.Keyboards) Hook(keyboard); - foreach (IMouse mouse in context.Mice) + foreach (var mouse in context.Mice) Hook(mouse); context.ConnectionChanged += OnConnectionChanged; @@ -120,7 +121,14 @@ namespace Microsoft.Iris.Render.OpenGL 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.Right => (WM_RBUTTONDOWN, MouseButtons.Right), @@ -129,36 +137,19 @@ namespace Microsoft.Iris.Render.OpenGL SilkMouseButton.Button5 => (WM_XBUTTONDOWN, MouseButtons.XButton2), _ => (0u, MouseButtons.None), }; - if (message != 0) - DispatchMouse(mouse, message, iris, 0); + return message; } private void OnMouseUp(IMouse mouse, SilkMouseButton button) { - (uint message, MouseButtons iris) = button switch - { - 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), - }; + var message = MapSilkMouseButton(button, out var iris); if (message != 0) DispatchMouse(mouse, message, iris, 0); } private void OnDoubleClick(IMouse mouse, SilkMouseButton button, System.Numerics.Vector2 position) { - (uint message, MouseButtons iris) = button switch - { - 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), - }; + var message = MapSilkMouseButton(button, out var iris); if (message != 0) DispatchMouse(mouse, message, iris, 0, doubleClick: true); } @@ -216,41 +207,53 @@ namespace Microsoft.Iris.Render.OpenGL InputModifiers m = InputModifiers.None; foreach (IKeyboard k in m_context.Keyboards) { - if (k.IsKeyPressed(SilkKey.ControlLeft) || k.IsKeyPressed(SilkKey.ControlRight)) m |= InputModifiers.ControlKey; - 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; + if (k.IsKeyPressed(SilkKey.ControlLeft) || k.IsKeyPressed(SilkKey.ControlRight)) + m |= InputModifiers.ControlKey; + + 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(); if (mouse != null) { - if (mouse.IsButtonPressed(SilkMouseButton.Left)) m |= InputModifiers.LeftMouse; - if (mouse.IsButtonPressed(SilkMouseButton.Right)) 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; + if (mouse.IsButtonPressed(SilkMouseButton.Left)) + m |= InputModifiers.LeftMouse; + + if (mouse.IsButtonPressed(SilkMouseButton.Right)) + 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; } - private IMouse? FirstMouse() - { - foreach (IMouse mouse in m_context.Mice) - return mouse; - return null; - } + private IMouse? FirstMouse() => m_context.Mice.Count > 0 ? m_context.Mice[0] : null; public void Dispose() { m_context.ConnectionChanged -= OnConnectionChanged; - foreach (IKeyboard keyboard in m_context.Keyboards) + foreach (var keyboard in m_context.Keyboards) { keyboard.KeyDown -= OnKeyDown; keyboard.KeyUp -= OnKeyUp; keyboard.KeyChar -= OnKeyChar; } - foreach (IMouse mouse in m_context.Mice) + foreach (var mouse in m_context.Mice) { mouse.MouseMove -= OnMouseMove; mouse.MouseDown -= OnMouseDown; diff --git a/UIX.RenderApi.OpenGL/OpenGLRenderApi.cs b/UIX.RenderApi.OpenGL/OpenGLRenderApi.cs index 8c48a52..506d3dc 100644 --- a/UIX.RenderApi.OpenGL/OpenGLRenderApi.cs +++ b/UIX.RenderApi.OpenGL/OpenGLRenderApi.cs @@ -12,20 +12,9 @@ namespace Microsoft.Iris.Render.OpenGL /// Create an OpenGL render engine for the given Iris engine info. public static IRenderEngine CreateEngine(IrisEngineInfo engineInfo, IRenderHost renderHost) { - if (engineInfo == null) throw new ArgumentNullException(nameof(engineInfo)); - if (renderHost == null) throw new ArgumentNullException(nameof(renderHost)); + ArgumentNullException.ThrowIfNull(engineInfo); + ArgumentNullException.ThrowIfNull(renderHost); return new GLRenderEngine(engineInfo, renderHost); } - - /// - /// Convenience overload matching RenderApi.CreateEngine's signature. - /// Only is supported (the sole EngineType). - /// - 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); - } } } diff --git a/UIX.RenderApi.OpenGL/Rendering/SceneRenderer.cs b/UIX.RenderApi.OpenGL/Rendering/SceneRenderer.cs index f898d23..adae0f2 100644 --- a/UIX.RenderApi.OpenGL/Rendering/SceneRenderer.cs +++ b/UIX.RenderApi.OpenGL/Rendering/SceneRenderer.cs @@ -10,38 +10,44 @@ namespace Microsoft.Iris.Render.OpenGL /// internal sealed unsafe class SceneRenderer : IDisposable { - private const string VertexSource = @"#version 330 core -layout(location = 0) in vec2 aPos; -layout(location = 1) in vec2 aTex; -uniform mat4 uModel; -uniform mat4 uProj; -uniform vec2 uSize; -out vec2 vTex; -void main() -{ - vTex = aTex; - gl_Position = uProj * uModel * vec4(aPos * uSize, 0.0, 1.0); -}"; + private const string VertexSource = + """ + #version 330 core + layout(location = 0) in vec2 aPos; + layout(location = 1) in vec2 aTex; + uniform mat4 uModel; + uniform mat4 uProj; + uniform vec2 uSize; + out vec2 vTex; + void main() + { + vTex = aTex; + gl_Position = uProj * uModel * vec4(aPos * uSize, 0.0, 1.0); + } +"""; - private const string FragmentSource = @"#version 330 core -in vec2 vTex; -out vec4 fragColor; -uniform sampler2D uTex; -uniform int uUseTexture; -uniform vec4 uColor; -uniform float uAlpha; -void main() -{ - if (uUseTexture == 1) - { - vec4 t = texture(uTex, vTex); - fragColor = vec4(t.rgb, t.a * uAlpha); - } - else - { - fragColor = vec4(uColor.rgb, uColor.a * uAlpha); - } -}"; + private const string FragmentSource = + """ + #version 330 core + in vec2 vTex; + out vec4 fragColor; + uniform sampler2D uTex; + uniform int uUseTexture; + uniform vec4 uColor; + uniform float uAlpha; + void main() + { + if (uUseTexture == 1) + { + vec4 t = texture(uTex, vTex); + fragColor = vec4(t.rgb, t.a * uAlpha); + } + else + { + fragColor = vec4(uColor.rgb, uColor.a * uAlpha); + } + } + """; private readonly GL m_gl; private readonly uint m_program; diff --git a/UIX.RenderApi.OpenGL/Scene/GLEffect.cs b/UIX.RenderApi.OpenGL/Scene/GLEffect.cs index e635743..b2caec2 100644 --- a/UIX.RenderApi.OpenGL/Scene/GLEffect.cs +++ b/UIX.RenderApi.OpenGL/Scene/GLEffect.cs @@ -55,7 +55,7 @@ namespace Microsoft.Iris.Render.OpenGL { get { - foreach (object v in m_values.Values) + foreach (var v in m_values.Values) { if (v is GLImage img) return img; diff --git a/UIX.RenderApi.OpenGL/Scene/GLVisual.cs b/UIX.RenderApi.OpenGL/Scene/GLVisual.cs index 0812d5b..4613c4c 100644 --- a/UIX.RenderApi.OpenGL/Scene/GLVisual.cs +++ b/UIX.RenderApi.OpenGL/Scene/GLVisual.cs @@ -77,16 +77,15 @@ namespace Microsoft.Iris.Render.OpenGL public void AddGradient(IGradient gradient) { - if (gradient is GLGradient g) - { - g.RegisterUsage(this); - m_gradients.Add(g); - } + if (gradient is not GLGradient g) + return; + g.RegisterUsage(this); + m_gradients.Add(g); } public void RemoveAllGradients() { - foreach (GLGradient g in m_gradients) + foreach (var g in m_gradients) g.UnregisterUsage(this); m_gradients.Clear(); } diff --git a/UIX.RenderApi.OpenGL/Scene/GLVisualContainer.cs b/UIX.RenderApi.OpenGL/Scene/GLVisualContainer.cs index 2151808..a6f27a2 100644 --- a/UIX.RenderApi.OpenGL/Scene/GLVisualContainer.cs +++ b/UIX.RenderApi.OpenGL/Scene/GLVisualContainer.cs @@ -10,15 +10,14 @@ namespace Microsoft.Iris.Render.OpenGL public sealed class GLVisualContainer : GLVisual, IVisualContainer { private readonly List m_children = new List(); - private readonly bool m_isRoot; public GLVisualContainer(GLRenderSession session, object ownerData, bool isRoot) : base(session, ownerData) { - m_isRoot = isRoot; + IsRoot = isRoot; } - public bool IsRoot => m_isRoot; + public bool IsRoot { get; } public int ChildCount => m_children.Count; public ICamera? Camera { get; set; } @@ -52,11 +51,10 @@ namespace Microsoft.Iris.Render.OpenGL public void RemoveChild(IVisual vChild) { - if (vChild is GLVisual child && m_children.Remove(child)) - { - child.ParentContainer = null; - child.UnregisterUsage(this); - } + if (vChild is not GLVisual child || !m_children.Remove(child)) + return; + child.ParentContainer = null; + child.UnregisterUsage(this); } public void RemoveAllChildren() @@ -77,7 +75,7 @@ namespace Microsoft.Iris.Render.OpenGL // Draw children back-to-front by layer. OrderBy is stable, preserving // insertion order within a 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); } @@ -93,7 +91,7 @@ namespace Microsoft.Iris.Render.OpenGL m_children.Sort((a, b) => a.Layer.CompareTo(b.Layer)); 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) return hit; } diff --git a/UIX.RenderApi/Microsoft/Iris/Render/Protocol/EngineApi.cs b/UIX.RenderApi/Microsoft/Iris/Render/Protocol/EngineApi.cs index 4e49554..32ccea5 100644 --- a/UIX.RenderApi/Microsoft/Iris/Render/Protocol/EngineApi.cs +++ b/UIX.RenderApi/Microsoft/Iris/Render/Protocol/EngineApi.cs @@ -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(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)] public static extern HRESULT SpInit(ref InitArgs args); @@ -170,41 +127,7 @@ namespace Microsoft.Iris.Render.Protocol public static extern unsafe HRESULT SpWrapBufferProc( MessageBufferEventHandler pfnProcessBufferProc, 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)] public static extern HRESULT SpPeekMessage( out Win32Api.MSG msg, @@ -223,65 +146,7 @@ namespace Microsoft.Iris.Render.Protocol IntPtr pfnInvoke, IntPtr pvArgs, 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)] public static extern HRESULT SpRenderThreadInit( ref InitArgs argsRender, @@ -289,86 +154,8 @@ namespace Microsoft.Iris.Render.Protocol [DllImport(s_stEhRenderDll)] 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)] public static extern HRESULT SpRemoteCreateServerStreams( string stSession, @@ -407,7 +194,6 @@ namespace Microsoft.Iris.Render.Protocol [DllImport(s_stEhRenderDll)] public static extern void SpObjectRelease(IntPtr pUnknown); -#endif [Flags] public enum BufferFlags