Procházet zdrojové kódy

[X11] Blacklist llvmpipe

Nikita Tsukanov před 6 roky
rodič
revize
2136f5e2c8

+ 14 - 4
src/Avalonia.OpenGL/GlInterface.cs

@@ -9,12 +9,14 @@ namespace Avalonia.OpenGL
     public class GlInterface : GlInterfaceBase
     {
         public string Version { get; }
+        public string Vendor { get; }
+        public string Renderer { get; }
 
         public GlInterface(Func<string, bool, IntPtr> getProcAddress) : base(getProcAddress)
         {
-            var versionPtr = GetString(GlConsts.GL_VERSION);
-            if (versionPtr != IntPtr.Zero)
-                Version = Marshal.PtrToStringAnsi(versionPtr);
+            Version = GetString(GlConsts.GL_VERSION);
+            Renderer = GetString(GlConsts.GL_RENDERER);
+            Vendor = GetString(GlConsts.GL_VENDOR);
         }
 
         public GlInterface(Func<Utf8Buffer, IntPtr> n) : this(ConvertNative(n))
@@ -54,7 +56,15 @@ namespace Avalonia.OpenGL
 
         public delegate IntPtr GlGetString(int v);
         [GlEntryPoint("glGetString")]
-        public GlGetString GetString { get; }
+        public GlGetString GetStringNative { get; }
+
+        public string GetString(int v)
+        {
+            var ptr = GetStringNative(v);
+            if (ptr != IntPtr.Zero)
+                return Marshal.PtrToStringAnsi(ptr);
+            return null;
+        }
 
         public delegate void GlGetIntegerv(int name, out int rv);
         [GlEntryPoint("glGetIntegerv")]

+ 13 - 0
src/Avalonia.X11/Glx/GlxDisplay.cs

@@ -90,6 +90,19 @@ namespace Avalonia.X11.Glx
             GlInterface = new GlInterface(GlxInterface.GlxGetProcAddress);
             if (GlInterface.Version == null)
                 throw new OpenGlException("GL version string is null, aborting");
+            if (GlInterface.Renderer == null)
+                throw new OpenGlException("GL renderer string is null, aborting");
+
+            if (Environment.GetEnvironmentVariable("AVALONIA_GLX_IGNORE_RENDERER_BLACKLIST") != "1")
+            {
+                var blacklist = AvaloniaLocator.Current.GetService<X11PlatformOptions>()
+                    ?.GlxRendererBlacklist;
+                if (blacklist != null)
+                    foreach(var item in blacklist)
+                        if (GlInterface.Renderer.Contains(item))
+                            throw new OpenGlException($"Renderer '{GlInterface.Renderer}' is blacklisted by '{item}'");
+            }
+            
         }
 
         public void ClearContext() => Glx.MakeContextCurrent(_x11.Display,

+ 8 - 0
src/Avalonia.X11/X11Platform.cs

@@ -96,6 +96,14 @@ namespace Avalonia
     {
         public bool UseEGL { get; set; }
         public bool UseGpu { get; set; } = true;
+
+        public List<string> GlxRendererBlacklist { get; set; } = new List<string>
+        {
+            // llvmpipe is a software GL rasterizer. If it's returned by glGetString,
+            // that usually means that something in the system is horribly misconfigured
+            // and sometimes attempts to use GLX might cause a segfault
+            "llvmpipe"
+        };
         public string WmClass { get; set; } = Assembly.GetEntryAssembly()?.GetName()?.Name ?? "AvaloniaApplication";
         public bool? EnableMultiTouch { get; set; }
     }