@ -9,16 +9,51 @@ using Avalonia.Platform;
namespace Avalonia.X11.XShmExtensions ;
namespace Avalonia.X11.XShmExtensions ;
class X11ShmFramebufferContext
{
public X11ShmFramebufferContext ( X11Window x11Window , IntPtr display , IntPtr windowHandle , IntPtr renderHandle )
{
X11Window = x11Window ;
Display = display ;
WindowHandle = windowHandle ;
RenderHandle = renderHandle ;
}
public X11Window X11Window { get ; }
public IntPtr Display { get ; }
public IntPtr WindowHandle { get ; }
public IntPtr RenderHandle { get ; }
}
internal class X11ShmFramebufferSurface : IFramebufferPlatformSurface
internal class X11ShmFramebufferSurface : IFramebufferPlatformSurface
{
{
public X11ShmFramebufferSurface ( X11Window x11Window , IntPtr display , IntPtr windowHandle , IntPtr renderHandle )
{
_ context = new X11ShmFramebufferContext ( x11Window , display , windowHandle , renderHandle ) ;
}
private readonly X11ShmFramebufferContext _ context ;
public IFramebufferRenderTarget CreateFramebufferRenderTarget ( )
public IFramebufferRenderTarget CreateFramebufferRenderTarget ( )
{
{
return new X11ShmImageSwapchain ( ) ;
return new X11ShmImageSwapchain ( _ context ) ;
}
public void OnXShmCompletionEvent ( ref XEvent ev )
{
}
}
}
}
internal class X11ShmImage
internal class X11ShmImage
{
{
/// <summary>
/// Returns false if we haven't got a completion event since the last Present, can call ProcessPendingEvents here
/// </summary>
public bool IsReady { get ; }
}
}
internal class X11ShmImageManager
internal class X11ShmImageManager
@ -26,20 +61,47 @@ internal class X11ShmImageManager
}
}
class DeferredDisplayEvents
//class DeferredDisplayEvents
{
//{
}
//}
internal class X11ShmImageSwapchain : IFramebufferRenderTarget
internal class X11ShmImageSwapchain : IFramebufferRenderTarget
{
{
public X11ShmImageSwapchain ( X11ShmFramebufferContext context )
{
_ context = context ;
}
private readonly X11ShmFramebufferContext _ context ;
private Queue < X11ShmImage > _ availableQueue = new ( ) ;
private Queue < X11ShmImage > _ presentationQueue = new ( ) ;
private PixelSize ? _l astSize ;
public void Dispose ( )
public void Dispose ( )
{
{
}
}
private void DrainPresentationQueue ( )
{
while ( _ presentationQueue . Count > 0 & & _ presentationQueue . Peek ( ) . IsReady )
{
_ availableQueue . Enqueue ( _ presentationQueue . Dequeue ( ) ) ;
}
}
public ILockedFramebuffer Lock ( )
public ILockedFramebuffer Lock ( )
{
{
/ *
1 ) gets the current window geometry , if it doesn ' t match the lastSize disposes images and clears queues
2 ) calls DrainPresentationQueue ( ) ;
3 ) if there is an image in _ availableQueue - use this image
4 ) else if there are no images in _ availableQueue and presentationQueue . Count < swapchainSize - create new image
5 ) else synchronously wait for the first image from _ presentationQueue and use it
6 ) return a framebuffer associated with chosen image
* /
throw new NotImplementedException ( ) ;
throw new NotImplementedException ( ) ;
}
}
}
}