From cf640452c390863fbbeb9f298c1809fdcefb94f4 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 25 Jun 2020 14:25:06 -0300 Subject: [PATCH] something on the screen. --- samples/ControlCatalog.NetCore/Program.cs | 5 +++ src/Avalonia.OpenGL/EglConsts.cs | 10 +++++ src/Avalonia.OpenGL/EglDisplay.cs | 11 ++++- src/Avalonia.OpenGL/EglInterface.cs | 10 +++++ .../Avalonia.Win32/DirectCompositionStuff.cs | 44 +++++++++++-------- 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index 5df8c1be64..6c9d9acd6b 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using Avalonia; using Avalonia.Dialogs; +using Avalonia.OpenGL; using Avalonia.ReactiveUI; namespace ControlCatalog.NetCore @@ -65,6 +66,10 @@ namespace ControlCatalog.NetCore EnableMultitouch = true, AllowEglInitialization = true }) + .With(new AngleOptions + { + AllowedPlatformApis = new System.Collections.Generic.List { AngleOptions.PlatformApi.DirectX11 } + }) .UseSkia() .UseReactiveUI() .UseManagedSystemDialogs() diff --git a/src/Avalonia.OpenGL/EglConsts.cs b/src/Avalonia.OpenGL/EglConsts.cs index 62fb3faef6..69de1a2d7b 100644 --- a/src/Avalonia.OpenGL/EglConsts.cs +++ b/src/Avalonia.OpenGL/EglConsts.cs @@ -192,5 +192,15 @@ namespace Avalonia.OpenGL public const int EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE = 0x320F; public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE = 0x320B; public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE = 0x320C; + + //EXT_device_query + public const int EGL_DEVICE_EXT = 0x322C; + + //ANGLE_device_d3d + public const int EGL_D3D9_DEVICE_ANGLE = 0x33A0; + public const int EGL_D3D11_DEVICE_ANGLE = 0x33A1; + + public const int EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200; + public const int EGL_D3D_TEXTURE_ANGLE = 0x33A3; } } diff --git a/src/Avalonia.OpenGL/EglDisplay.cs b/src/Avalonia.OpenGL/EglDisplay.cs index 2bdde9f165..5831a9b437 100644 --- a/src/Avalonia.OpenGL/EglDisplay.cs +++ b/src/Avalonia.OpenGL/EglDisplay.cs @@ -165,9 +165,16 @@ namespace Avalonia.OpenGL return rv; } - public void CreatePBufferFromClientBuffer () + public EglSurface CreatePBufferFromClientBuffer (IntPtr d2dTextureSharedHandle) { - //_egl.CreatePBufferSurface(_) + var s = _egl.CreatePbufferFromClientBuffer( + _display, + EglConsts.EGL_D3D_TEXTURE_ANGLE, + d2dTextureSharedHandle, _config, new[] { EGL_NONE, EGL_NONE }); + + if (s == IntPtr.Zero) + throw OpenGlException.GetFormattedException("eglCreateWindowSurface", _egl); + return new EglSurface(this, _egl, s); } public EglSurface CreateWindowSurface(IntPtr window) diff --git a/src/Avalonia.OpenGL/EglInterface.cs b/src/Avalonia.OpenGL/EglInterface.cs index d8d44695a1..71e37bc1a1 100644 --- a/src/Avalonia.OpenGL/EglInterface.cs +++ b/src/Avalonia.OpenGL/EglInterface.cs @@ -153,6 +153,16 @@ namespace Avalonia.OpenGL return Marshal.PtrToStringAnsi(rv); } + public delegate bool EglQueryDisplayAttribEXT(IntPtr display, int attr, out IntPtr res); + + [GlEntryPoint("eglQueryDisplayAttribEXT")] + public EglQueryDisplayAttribEXT QueryDisplayAttribExt { get; } + + public delegate bool EglQueryDeviceAttribEXT(IntPtr display, int attr, out IntPtr res); + + [GlEntryPoint("eglQueryDeviceAttribEXT")] + public EglQueryDisplayAttribEXT QueryDeviceAttribExt { get; } + // ReSharper restore UnassignedGetOnlyAutoProperty } } diff --git a/src/Windows/Avalonia.Win32/DirectCompositionStuff.cs b/src/Windows/Avalonia.Win32/DirectCompositionStuff.cs index 9472046004..a966131090 100644 --- a/src/Windows/Avalonia.Win32/DirectCompositionStuff.cs +++ b/src/Windows/Avalonia.Win32/DirectCompositionStuff.cs @@ -4,6 +4,7 @@ using System.Text; using Avalonia.Controls; using Avalonia.OpenGL; using SharpDX.DirectComposition; +using WinRT; using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia.Win32 @@ -23,6 +24,7 @@ namespace Avalonia.Win32 private readonly EglDisplay _display; private readonly EglContext _context; private readonly IEglWindowGlPlatformSurfaceInfo _info; + private IntPtr _d3dDeviceHandle; public void AttachToWindow(IntPtr hWnd) { @@ -46,18 +48,14 @@ namespace Avalonia.Win32 SharpDX.Direct3D.FeatureLevel.Level_9_1, }; - var Direct3D11Device = new SharpDX.Direct3D11.Device( - SharpDX.Direct3D.DriverType.Hardware, - SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport, - featureLevels); + var Direct3D11Device = new SharpDX.Direct3D11.Device(_d3dDeviceHandle); + - var DxgiDevice = Direct3D11Device.QueryInterface(); - var Direct2D1Device = new SharpDX.Direct2D1.Device(Direct2D1Factory, DxgiDevice); + var DxgiDevice = Direct3D11Device.QueryInterface(); - - var DCompDevice = new SharpDX.DirectComposition.DesktopDevice(Direct2D1Device); + var DCompDevice = new SharpDX.DirectComposition.DesktopDevice(Direct3D11Device); _device = DCompDevice.QueryInterface(); @@ -72,14 +70,10 @@ namespace Avalonia.Win32 visual.Content = _virtualSurface; } - public SharpDX.Direct2D1.DeviceContext BeginDraw() + public SharpDX.Direct3D11.Texture2D BeginDraw() { - var result = _virtualSurface.BeginDraw(null, out var offset); - - var brush = new SharpDX.Direct2D1.SolidColorBrush(result, new SharpDX.Mathematics.Interop.RawColor4(1, 0, 0, 1)); - - result.DrawLine(new SharpDX.Mathematics.Interop.RawVector2(0, 0), new SharpDX.Mathematics.Interop.RawVector2(100, 100), brush); - + var result = _virtualSurface.BeginDraw(null, out var offset); + return result; } @@ -94,8 +88,19 @@ namespace Avalonia.Win32 _display = context.Display; _context = context; _info = info; + + if (!_display.EglInterface.QueryDisplayAttribExt(_display.Handle, EglConsts.EGL_DEVICE_EXT, out var eglDevice)) + throw new OpenGlException("Unable to get EGL_DEVICE_EXT"); + if (!_display.EglInterface.QueryDeviceAttribExt(eglDevice, EglConsts.EGL_D3D11_DEVICE_ANGLE, out var d3dDeviceHandle)) + throw new OpenGlException("Unable to get EGL_D3D9_DEVICE_ANGLE"); + + _d3dDeviceHandle = d3dDeviceHandle; + + } + private EglSurface CreateSurfaceFromSufaceHandle(IntPtr intPtr) => _display.CreatePBufferFromClientBuffer(intPtr); + protected virtual EglSurface CreateEglSurface() => _display.CreateWindowSurface(_info.Handle); public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() @@ -132,13 +137,15 @@ namespace Avalonia.Win32 { if (IsCorrupted) throw new RenderTargetCorruptedException(); - var d2dcontext = _surface.BeginDraw(); - //var restoreContext = _context.MakeCurrent(_sr); + var d2dtexture = _surface.BeginDraw(); + + var eglSurface = _surface.CreateSurfaceFromSufaceHandle(d2dtexture.NativePointer); + var restoreContext = _context.MakeCurrent(eglSurface); _display.EglInterface.WaitClient(); _display.EglInterface.WaitGL(); _display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); - return new Session(_surface, _display, _context, null, _info, l, null); + return new Session(_surface, _display, _context, eglSurface, _info, l, restoreContext); } catch { @@ -181,6 +188,7 @@ namespace Avalonia.Win32 _display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); _dcompSurface.EndDraw(); _restoreContext?.Dispose(); + _glSurface.Dispose(); _lock.Dispose(); }