Browse Source

Reduce the number of WrapDirect3D11Texture calls (#20517)

* Reduce the number of WrapDirect3D11Texture calls

Reduce the number of WrapDirect3D11Texture calls by tying the EglSurface lifetime to _renderTexture.
When testing on a 4K display, I observed that eglCreatePbufferFromClientBuffer, which is invoked by WrapDirect3D11Texture, can take around 5 ms per frame.
By reducing the number of eglCreatePbufferFromClientBuffer calls, I was able to improve rendering performance by about 30%.
However, I’m not sure why the previous implementation needed to call WrapDirect3D11Texture on every frame.

* Remove the commented code
#Conflicts:
#	src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs
release/latest
lindexi 2 months ago
committed by Julien Lebosquain
parent
commit
4413f5fa29
No known key found for this signature in database GPG Key ID: 1833CAD10ACC46FD
  1. 2
      src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs
  2. 24
      src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs

2
src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs

@ -131,7 +131,7 @@ namespace Avalonia.Win32.DirectX
using var output = MicroComRuntime.CreateProxyFor<IDXGIOutput>(outputPointer, true);
DXGI_OUTPUT_DESC outputDesc = output.Desc;
var hMonitor = new HMONITOR(outputDesc.Monitor.Value);
var hMonitor = new HMONITOR((IntPtr)outputDesc.Monitor.Value);
var frequency =
monitorFrequencies.TryGetValue(hMonitor, out uint frequencyValue) ?

24
src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs

@ -23,6 +23,7 @@ namespace Avalonia.Win32.DirectX
private IUnknown? _renderTexture;
private RECT _clientRect;
private EglSurface? _surface;
public DxgiRenderTarget(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo window, EglContext context, DxgiConnection connection) : base(context)
{
@ -81,7 +82,6 @@ namespace Avalonia.Win32.DirectX
}
var contextLock = Context.EnsureCurrent();
EglSurface? surface = null;
IDisposable? transaction = null;
var success = false;
try
@ -94,6 +94,9 @@ namespace Avalonia.Win32.DirectX
if (_renderTexture is not null)
{
_surface?.Dispose();
_surface = null;
_renderTexture.Dispose();
_renderTexture = null;
}
@ -112,19 +115,24 @@ namespace Avalonia.Win32.DirectX
var texture = _renderTexture;
if (texture is null)
{
_surface?.Dispose();
_surface = null;
Guid textureGuid = ID3D11Texture2DGuid;
texture = MicroComRuntime.CreateProxyFor<IUnknown>(_swapChain.GetBuffer(0, &textureGuid), true);
}
_renderTexture = texture;
// I also have to get the pointer to this texture directly
surface = ((AngleWin32EglDisplay)Context.Display).WrapDirect3D11Texture(MicroComRuntime.GetNativeIntPtr(_renderTexture),
0, 0, size.Width, size.Height);
if (_surface is null)
{
// I also have to get the pointer to this texture directly
_surface = ((AngleWin32EglDisplay)Context.Display).WrapDirect3D11Texture(MicroComRuntime.GetNativeIntPtr(_renderTexture),
0, 0, size.Width, size.Height);
}
var res = base.BeginDraw(surface, _window.Size, _window.Scaling, () =>
var res = base.BeginDraw(_surface, _window.Size, _window.Scaling, () =>
{
_swapChain.Present((ushort)0U, (ushort)0U);
surface.Dispose();
transaction?.Dispose();
contextLock?.Dispose();
}, true);
@ -135,7 +143,8 @@ namespace Avalonia.Win32.DirectX
{
if (!success)
{
surface?.Dispose();
_surface?.Dispose();
_surface = null;
if (_renderTexture is not null)
{
_renderTexture.Dispose();
@ -153,6 +162,7 @@ namespace Avalonia.Win32.DirectX
_dxgiDevice?.Dispose();
_dxgiFactory?.Dispose();
_swapChain?.Dispose();
_surface?.Dispose();
_renderTexture?.Dispose();
}

Loading…
Cancel
Save