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
pull/20519/head
lindexi 2 weeks ago
committed by GitHub
parent
commit
62fac86360
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 26
      src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs

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

@ -23,7 +23,8 @@ namespace Avalonia.Win32.DirectX
private IUnknown? _renderTexture;
private RECT _clientRect;
private EglSurface? _surface;
public DxgiRenderTarget(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo window, EglContext context, DxgiConnection connection) : base(context)
{
_window = window;
@ -83,7 +84,6 @@ namespace Avalonia.Win32.DirectX
}
var contextLock = Context.EnsureCurrent();
EglSurface? surface = null;
IDisposable? transaction = null;
var success = false;
try
@ -96,6 +96,9 @@ namespace Avalonia.Win32.DirectX
if (_renderTexture is not null)
{
_surface?.Dispose();
_surface = null;
_renderTexture.Dispose();
_renderTexture = null;
}
@ -114,19 +117,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);
@ -137,7 +145,8 @@ namespace Avalonia.Win32.DirectX
{
if (!success)
{
surface?.Dispose();
_surface?.Dispose();
_surface = null;
if (_renderTexture is not null)
{
_renderTexture.Dispose();
@ -155,6 +164,7 @@ namespace Avalonia.Win32.DirectX
_dxgiDevice?.Dispose();
_dxgiFactory?.Dispose();
_swapChain?.Dispose();
_surface?.Dispose();
_renderTexture?.Dispose();
}

Loading…
Cancel
Save