diff --git a/src/Linux/Avalonia.LinuxFramebuffer/DrmOutputOptions.cs b/src/Linux/Avalonia.LinuxFramebuffer/DrmOutputOptions.cs
new file mode 100644
index 0000000000..e92ad02c7a
--- /dev/null
+++ b/src/Linux/Avalonia.LinuxFramebuffer/DrmOutputOptions.cs
@@ -0,0 +1,27 @@
+using Avalonia.LinuxFramebuffer.Output;
+using Avalonia.Media;
+using JetBrains.Annotations;
+
+namespace Avalonia.LinuxFramebuffer
+{
+ public class DrmOutputOptions
+ {
+ ///
+ /// Scaling factor.
+ /// Default: 1.0
+ ///
+ public double Scaling { get; set; } = 1.0;
+
+ ///
+ /// If true an two cycle buffer swapping is processed at init.
+ /// Default: True
+ ///
+ public bool EnableInitialBufferSwapping { get; set; } = true;
+
+ ///
+ /// Color for
+ /// Default: R0 G0 B0 A0
+ ///
+ public Color InitialBufferSwappingColor { get; set; } = new Color(0, 0, 0, 0);
+ }
+}
diff --git a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs
index 4add4c423b..a642766809 100644
--- a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs
+++ b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs
@@ -140,6 +140,8 @@ public static class LinuxFramebufferPlatformExtensions
public static int StartLinuxDrm(this T builder, string[] args, string card = null, double scaling = 1)
where T : AppBuilderBase, new() => StartLinuxDirect(builder, args, new DrmOutput(card) {Scaling = scaling});
+ public static int StartLinuxDrm(this T builder, string[] args, string card = null, bool connectorsForceProbe = false, [CanBeNull] DrmOutputOptions options = null)
+ where T : AppBuilderBase, new() => StartLinuxDirect(builder, args, new DrmOutput(card, connectorsForceProbe, options));
public static int StartLinuxDirect(this T builder, string[] args, IOutputBackend backend)
where T : AppBuilderBase, new()
diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs
index 9c476b1b63..04bc2c1f67 100644
--- a/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs
+++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs
@@ -162,6 +162,8 @@ namespace Avalonia.LinuxFramebuffer.Output
[DllImport(libdrm, SetLastError = true)]
public static extern drmModeConnector* drmModeGetConnector(int fd, uint connector);
[DllImport(libdrm, SetLastError = true)]
+ public static extern drmModeConnector* drmModeGetConnectorCurrent(int fd, uint connector);
+ [DllImport(libdrm, SetLastError = true)]
public static extern void drmModeFreeConnector(drmModeConnector* res);
[DllImport(libdrm, SetLastError = true)]
diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs
index de281245f1..070e1a95bc 100644
--- a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs
+++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs
@@ -84,7 +84,7 @@ namespace Avalonia.LinuxFramebuffer.Output
{
public List Connectors { get; }= new List();
internal Dictionary Encoders { get; } = new Dictionary();
- public DrmResources(int fd)
+ public DrmResources(int fd, bool connectorsForceProbe = false)
{
var res = drmModeGetResources(fd);
if (res == null)
@@ -107,7 +107,7 @@ namespace Avalonia.LinuxFramebuffer.Output
for (var c = 0; c < res->count_connectors; c++)
{
- var conn = drmModeGetConnector(fd, res->connectors[c]);
+ var conn = connectorsForceProbe ? drmModeGetConnector(fd, res->connectors[c]) : drmModeGetConnectorCurrent(fd, res->connectors[c]);
Connectors.Add(new DrmConnector(conn));
drmModeFreeConnector(conn);
}
@@ -168,7 +168,7 @@ namespace Avalonia.LinuxFramebuffer.Output
}
}
- public DrmResources GetResources() => new DrmResources(Fd);
+ public DrmResources GetResources(bool connectorsForceProbe = false) => new DrmResources(Fd, connectorsForceProbe);
public void Dispose()
{
close(Fd);
diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
index 99c4b62716..ce210019c0 100644
--- a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
+++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
@@ -7,6 +7,7 @@ using Avalonia.OpenGL;
using Avalonia.OpenGL.Egl;
using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform.Interop;
+using JetBrains.Annotations;
using static Avalonia.LinuxFramebuffer.NativeUnsafeMethods;
using static Avalonia.LinuxFramebuffer.Output.LibDrm;
using static Avalonia.LinuxFramebuffer.Output.LibDrm.GbmColorFormats;
@@ -15,20 +16,35 @@ namespace Avalonia.LinuxFramebuffer.Output
{
public unsafe class DrmOutput : IGlOutputBackend, IGlPlatformSurface
{
+ private DrmOutputOptions _outputOptions = new();
private DrmCard _card;
public PixelSize PixelSize => _mode.Resolution;
- public double Scaling { get; set; }
+
+ public double Scaling
+ {
+ get => _outputOptions.Scaling;
+ set => _outputOptions.Scaling = value;
+ }
public IGlContext PrimaryContext => _deferredContext;
private EglPlatformOpenGlInterface _platformGl;
public IPlatformOpenGlInterface PlatformOpenGlInterface => _platformGl;
- public DrmOutput(string path = null)
+ public DrmOutput(DrmCard card, DrmResources resources, DrmConnector connector, DrmModeInfo modeInfo,
+ DrmOutputOptions? options = null)
{
+ if(options != null)
+ _outputOptions = options;
+ Init(card, resources, connector, modeInfo);
+ }
+ public DrmOutput(string path = null, bool connectorsForceProbe = false, [CanBeNull] DrmOutputOptions options = null)
+ {
+ if(options != null)
+ _outputOptions = options;
+
var card = new DrmCard(path);
- var resources = card.GetResources();
-
+ var resources = card.GetResources(connectorsForceProbe);
var connector =
resources.Connectors.FirstOrDefault(x => x.Connection == DrmModeConnection.DRM_MODE_CONNECTED);
@@ -142,9 +158,14 @@ namespace Avalonia.LinuxFramebuffer.Output
_deferredContext = _platformGl.PrimaryEglContext;
+ var initialBufferSwappingColorR = _outputOptions.InitialBufferSwappingColor.R / 255.0f;
+ var initialBufferSwappingColorG = _outputOptions.InitialBufferSwappingColor.G / 255.0f;
+ var initialBufferSwappingColorB = _outputOptions.InitialBufferSwappingColor.B / 255.0f;
+ var initialBufferSwappingColorA = _outputOptions.InitialBufferSwappingColor.A / 255.0f;
using (_deferredContext.MakeCurrent(_eglSurface))
{
- _deferredContext.GlInterface.ClearColor(0, 0, 0, 0);
+ _deferredContext.GlInterface.ClearColor(initialBufferSwappingColorR, initialBufferSwappingColorG,
+ initialBufferSwappingColorB, initialBufferSwappingColorA);
_deferredContext.GlInterface.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_STENCIL_BUFFER_BIT);
_eglSurface.SwapBuffers();
}
@@ -162,13 +183,17 @@ namespace Avalonia.LinuxFramebuffer.Output
_mode = mode;
_currentBo = bo;
- // Go trough two cycles of buffer swapping (there are render artifacts otherwise)
- for(var c=0;c<2;c++)
- using (CreateGlRenderTarget().BeginDraw())
- {
- _deferredContext.GlInterface.ClearColor(0, 0, 0, 0);
- _deferredContext.GlInterface.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_STENCIL_BUFFER_BIT);
- }
+ if (_outputOptions.EnableInitialBufferSwapping)
+ {
+ //Go trough two cycles of buffer swapping (there are render artifacts otherwise)
+ for(var c=0;c<2;c++)
+ using (CreateGlRenderTarget().BeginDraw())
+ {
+ _deferredContext.GlInterface.ClearColor(initialBufferSwappingColorR, initialBufferSwappingColorG,
+ initialBufferSwappingColorB, initialBufferSwappingColorA);
+ _deferredContext.GlInterface.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_STENCIL_BUFFER_BIT);
+ }
+ }
}