Browse Source

something on the screen.

feature/render-inside-windows-ui-composition-visual-tree
Dan Walmsley 6 years ago
parent
commit
cf640452c3
  1. 5
      samples/ControlCatalog.NetCore/Program.cs
  2. 10
      src/Avalonia.OpenGL/EglConsts.cs
  3. 11
      src/Avalonia.OpenGL/EglDisplay.cs
  4. 10
      src/Avalonia.OpenGL/EglInterface.cs
  5. 44
      src/Windows/Avalonia.Win32/DirectCompositionStuff.cs

5
samples/ControlCatalog.NetCore/Program.cs

@ -5,6 +5,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using Avalonia; using Avalonia;
using Avalonia.Dialogs; using Avalonia.Dialogs;
using Avalonia.OpenGL;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
namespace ControlCatalog.NetCore namespace ControlCatalog.NetCore
@ -65,6 +66,10 @@ namespace ControlCatalog.NetCore
EnableMultitouch = true, EnableMultitouch = true,
AllowEglInitialization = true AllowEglInitialization = true
}) })
.With(new AngleOptions
{
AllowedPlatformApis = new System.Collections.Generic.List<AngleOptions.PlatformApi> { AngleOptions.PlatformApi.DirectX11 }
})
.UseSkia() .UseSkia()
.UseReactiveUI() .UseReactiveUI()
.UseManagedSystemDialogs() .UseManagedSystemDialogs()

10
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_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_WARP_ANGLE = 0x320B;
public const int EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE = 0x320C; 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;
} }
} }

11
src/Avalonia.OpenGL/EglDisplay.cs

@ -165,9 +165,16 @@ namespace Avalonia.OpenGL
return rv; 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) public EglSurface CreateWindowSurface(IntPtr window)

10
src/Avalonia.OpenGL/EglInterface.cs

@ -153,6 +153,16 @@ namespace Avalonia.OpenGL
return Marshal.PtrToStringAnsi(rv); 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 // ReSharper restore UnassignedGetOnlyAutoProperty
} }
} }

44
src/Windows/Avalonia.Win32/DirectCompositionStuff.cs

@ -4,6 +4,7 @@ using System.Text;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using SharpDX.DirectComposition; using SharpDX.DirectComposition;
using WinRT;
using static Avalonia.Win32.Interop.UnmanagedMethods; using static Avalonia.Win32.Interop.UnmanagedMethods;
namespace Avalonia.Win32 namespace Avalonia.Win32
@ -23,6 +24,7 @@ namespace Avalonia.Win32
private readonly EglDisplay _display; private readonly EglDisplay _display;
private readonly EglContext _context; private readonly EglContext _context;
private readonly IEglWindowGlPlatformSurfaceInfo _info; private readonly IEglWindowGlPlatformSurfaceInfo _info;
private IntPtr _d3dDeviceHandle;
public void AttachToWindow(IntPtr hWnd) public void AttachToWindow(IntPtr hWnd)
{ {
@ -46,18 +48,14 @@ namespace Avalonia.Win32
SharpDX.Direct3D.FeatureLevel.Level_9_1, SharpDX.Direct3D.FeatureLevel.Level_9_1,
}; };
var Direct3D11Device = new SharpDX.Direct3D11.Device( var Direct3D11Device = new SharpDX.Direct3D11.Device(_d3dDeviceHandle);
SharpDX.Direct3D.DriverType.Hardware,
SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport,
featureLevels);
var DxgiDevice = Direct3D11Device.QueryInterface<SharpDX.DXGI.Device1>();
var Direct2D1Device = new SharpDX.Direct2D1.Device(Direct2D1Factory, DxgiDevice); var DxgiDevice = Direct3D11Device.QueryInterface<SharpDX.DXGI.Device1>();
var DCompDevice = new SharpDX.DirectComposition.DesktopDevice(Direct3D11Device);
var DCompDevice = new SharpDX.DirectComposition.DesktopDevice(Direct2D1Device);
_device = DCompDevice.QueryInterface<Device>(); _device = DCompDevice.QueryInterface<Device>();
@ -72,14 +70,10 @@ namespace Avalonia.Win32
visual.Content = _virtualSurface; visual.Content = _virtualSurface;
} }
public SharpDX.Direct2D1.DeviceContext BeginDraw() public SharpDX.Direct3D11.Texture2D BeginDraw()
{ {
var result = _virtualSurface.BeginDraw<SharpDX.Direct2D1.DeviceContext>(null, out var offset); var result = _virtualSurface.BeginDraw<SharpDX.Direct3D11.Texture2D>(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);
return result; return result;
} }
@ -94,8 +88,19 @@ namespace Avalonia.Win32
_display = context.Display; _display = context.Display;
_context = context; _context = context;
_info = info; _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); protected virtual EglSurface CreateEglSurface() => _display.CreateWindowSurface(_info.Handle);
public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget()
@ -132,13 +137,15 @@ namespace Avalonia.Win32
{ {
if (IsCorrupted) if (IsCorrupted)
throw new RenderTargetCorruptedException(); throw new RenderTargetCorruptedException();
var d2dcontext = _surface.BeginDraw(); var d2dtexture = _surface.BeginDraw();
//var restoreContext = _context.MakeCurrent(_sr);
var eglSurface = _surface.CreateSurfaceFromSufaceHandle(d2dtexture.NativePointer);
var restoreContext = _context.MakeCurrent(eglSurface);
_display.EglInterface.WaitClient(); _display.EglInterface.WaitClient();
_display.EglInterface.WaitGL(); _display.EglInterface.WaitGL();
_display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); _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 catch
{ {
@ -181,6 +188,7 @@ namespace Avalonia.Win32
_display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE); _display.EglInterface.WaitNative(EglConsts.EGL_CORE_NATIVE_ENGINE);
_dcompSurface.EndDraw(); _dcompSurface.EndDraw();
_restoreContext?.Dispose(); _restoreContext?.Dispose();
_glSurface.Dispose();
_lock.Dispose(); _lock.Dispose();
} }

Loading…
Cancel
Save