From 0d1df413938aa2821d3cacd921d6be3a99bd97b6 Mon Sep 17 00:00:00 2001 From: thefiddler Date: Fri, 27 Dec 2013 14:01:21 +0200 Subject: [PATCH] [X11] Improve GraphicsMode fallback (fixes issue #23) When the user requests a GraphicsMode that is not directly supported by the GPU/drivers, we should relax the requested parameters until we find a supported mode. An exception should only be thrown when there is no usable mode. This makes the X11 backend match the behavior of Windows. The SDL/X11 backend works a little bit differently, in that it falls back to the a default mode directly if the requested mode is not available. There is nothing we can do about that. --- Source/OpenTK/Platform/X11/X11GraphicsMode.cs | 73 ++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/Source/OpenTK/Platform/X11/X11GraphicsMode.cs b/Source/OpenTK/Platform/X11/X11GraphicsMode.cs index 789281b..1c01903 100644 --- a/Source/OpenTK/Platform/X11/X11GraphicsMode.cs +++ b/Source/OpenTK/Platform/X11/X11GraphicsMode.cs @@ -39,19 +39,68 @@ namespace OpenTK.Platform.X11 // The actual GraphicsMode that will be selected. IntPtr visual = IntPtr.Zero; IntPtr display = API.DefaultDisplay; - - // Try to select a visual using Glx.ChooseFBConfig and Glx.GetVisualFromFBConfig. - // This is only supported on GLX 1.3 - if it fails, fall back to Glx.ChooseVisual. - visual = SelectVisualUsingFBConfig(color, depth, stencil, samples, accum, buffers, stereo); - - if (visual == IntPtr.Zero) - visual = SelectVisualUsingChooseVisual(color, depth, stencil, samples, accum, buffers, stereo); - - if (visual == IntPtr.Zero) - throw new GraphicsModeException("Requested GraphicsMode not available."); - + + do + { + // Try to select a visual using Glx.ChooseFBConfig and Glx.GetVisualFromFBConfig. + // This is only supported on GLX 1.3 - if it fails, fall back to Glx.ChooseVisual. + visual = SelectVisualUsingFBConfig(color, depth, stencil, samples, accum, buffers, stereo); + + if (visual == IntPtr.Zero) + visual = SelectVisualUsingChooseVisual(color, depth, stencil, samples, accum, buffers, stereo); + + if (visual == IntPtr.Zero) + { + // Relax parameters and retry + if (stereo) + { + stereo = false; + continue; + } + + if (accum != 0) + { + accum = 0; + continue; + } + + if (samples > 0) + { + samples = Math.Max(samples - 2, 0); + continue; + } + + if (stencil != 0) + { + stencil = 0; + continue; + } + + if (depth != 0) + { + depth = 0; + continue; + } + + if (color != 24) + { + color = 24; + continue; + } + + if (buffers != 0) + { + buffers = 0; + continue; + } + + throw new GraphicsModeException("Requested GraphicsMode not available."); + } + } + while (visual == IntPtr.Zero); + XVisualInfo info = (XVisualInfo)Marshal.PtrToStructure(visual, typeof(XVisualInfo)); - + // See what we *really* got: int r, g, b, a; Glx.GetConfig(display, ref info, GLXAttribute.ALPHA_SIZE, out a); -- 2.7.4