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 IUnknown? _renderTexture;
private RECT _clientRect; private RECT _clientRect;
private EglSurface? _surface;
public DxgiRenderTarget(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo window, EglContext context, DxgiConnection connection) : base(context) public DxgiRenderTarget(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo window, EglContext context, DxgiConnection connection) : base(context)
{ {
_window = window; _window = window;
@ -83,7 +84,6 @@ namespace Avalonia.Win32.DirectX
} }
var contextLock = Context.EnsureCurrent(); var contextLock = Context.EnsureCurrent();
EglSurface? surface = null;
IDisposable? transaction = null; IDisposable? transaction = null;
var success = false; var success = false;
try try
@ -96,6 +96,9 @@ namespace Avalonia.Win32.DirectX
if (_renderTexture is not null) if (_renderTexture is not null)
{ {
_surface?.Dispose();
_surface = null;
_renderTexture.Dispose(); _renderTexture.Dispose();
_renderTexture = null; _renderTexture = null;
} }
@ -114,19 +117,24 @@ namespace Avalonia.Win32.DirectX
var texture = _renderTexture; var texture = _renderTexture;
if (texture is null) if (texture is null)
{ {
_surface?.Dispose();
_surface = null;
Guid textureGuid = ID3D11Texture2DGuid; Guid textureGuid = ID3D11Texture2DGuid;
texture = MicroComRuntime.CreateProxyFor<IUnknown>(_swapChain.GetBuffer(0, &textureGuid), true); texture = MicroComRuntime.CreateProxyFor<IUnknown>(_swapChain.GetBuffer(0, &textureGuid), true);
} }
_renderTexture = texture; _renderTexture = texture;
// I also have to get the pointer to this texture directly if (_surface is null)
surface = ((AngleWin32EglDisplay)Context.Display).WrapDirect3D11Texture(MicroComRuntime.GetNativeIntPtr(_renderTexture), {
0, 0, size.Width, size.Height); // 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); _swapChain.Present((ushort)0U, (ushort)0U);
surface.Dispose();
transaction?.Dispose(); transaction?.Dispose();
contextLock?.Dispose(); contextLock?.Dispose();
}, true); }, true);
@ -137,7 +145,8 @@ namespace Avalonia.Win32.DirectX
{ {
if (!success) if (!success)
{ {
surface?.Dispose(); _surface?.Dispose();
_surface = null;
if (_renderTexture is not null) if (_renderTexture is not null)
{ {
_renderTexture.Dispose(); _renderTexture.Dispose();
@ -155,6 +164,7 @@ namespace Avalonia.Win32.DirectX
_dxgiDevice?.Dispose(); _dxgiDevice?.Dispose();
_dxgiFactory?.Dispose(); _dxgiFactory?.Dispose();
_swapChain?.Dispose(); _swapChain?.Dispose();
_surface?.Dispose();
_renderTexture?.Dispose(); _renderTexture?.Dispose();
} }

Loading…
Cancel
Save