[Win] More robust pixel format selection
authorStefanos A. <stapostol@gmail.com>
Fri, 10 Jan 2014 14:41:57 +0000 (15:41 +0100)
committerStefanos A. <stapostol@gmail.com>
Fri, 10 Jan 2014 14:41:57 +0000 (15:41 +0100)
This patch adds more robust checks for WGL_ARB_pixel_format and
WGL_ARB_multisample before using the relevant extensions, and adds
checks whether Wgl.Arb.ChoosePixelFormat() returns a valid pixel format
before trying to use it (thanks to Repetier for catching this edge
case.)

Additionally, the ChoosePixelFormatPFD code-path now heavily penalizes
single-buffered modes when the user requests a double-buffered mode.

Affects issues #42 and #45

Source/OpenTK/Platform/Windows/WinGraphicsMode.cs

index a5886f9..1fc3954 100644 (file)
@@ -99,7 +99,8 @@ namespace OpenTK.Platform.Windows
         GraphicsMode ChoosePixelFormatARB(IntPtr device, GraphicsMode mode)
         {
             GraphicsMode created_mode = null;
-            if (Wgl.Delegates.wglChoosePixelFormatARB != null)
+            if (Wgl.SupportsExtension("WGL_ARB_pixel_format") &&
+                Wgl.Delegates.wglChoosePixelFormatARB != null)
             {
                 List<int> attributes = new List<int>();
                 attributes.Add((int)WGL_ARB_pixel_format.AccelerationArb);
@@ -168,7 +169,8 @@ namespace OpenTK.Platform.Windows
                     attributes.Add(mode.AccumulatorFormat.Alpha);
                 }
 
-                if (mode.Samples > 0)
+                if (mode.Samples > 0 &&
+                    Wgl.SupportsExtension("WGL_ARB_multisample"))
                 {
                     attributes.Add((int)WGL_ARB_multisample.SampleBuffersArb);
                     attributes.Add(1);
@@ -193,7 +195,8 @@ namespace OpenTK.Platform.Windows
 
                 int[] format = new int[1];
                 int count;
-                if (Wgl.Arb.ChoosePixelFormat(device, attributes.ToArray(), null, format.Length, format, out count))
+                if (Wgl.Arb.ChoosePixelFormat(device, attributes.ToArray(), null, format.Length, format, out count)
+                    && count > 0)
                 {
                     created_mode = DescribePixelFormatARB(device, format[0]);
                 }
@@ -271,13 +274,6 @@ namespace OpenTK.Platform.Windows
             {
                 flags |= PixelFormatDescriptorFlags.STEREO;
             }
-            if (mode.Buffers > 1)
-            {
-                // On Win7 64bit + Nvidia 650M, no pixel format advertises DOUBLEBUFFER.
-                // Adding this check here causes mode selection to fail.
-                // Does not appear to be supported by DescribePixelFormat
-                //flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER;
-            }
 
             if (System.Environment.OSVersion.Version.Major >= 6 &&
                 requested_acceleration_type != AccelerationType.None)
@@ -304,6 +300,9 @@ namespace OpenTK.Platform.Windows
                 valid &= GetAccelerationType(ref pfd) == requested_acceleration_type;
                 valid &= (pfd.Flags & flags) == flags;
                 valid &= pfd.PixelType == PixelType.RGBA; // indexed modes not currently supported
+                // heavily penalize single-buffered modes when the user requests double buffering
+                if ((pfd.Flags & PixelFormatDescriptorFlags.DOUBLEBUFFER) == 0 && mode.Buffers > 1)
+                    dist += 1000;
                 valid &= Compare(pfd.ColorBits, mode.ColorFormat.BitsPerPixel, ref dist);
                 valid &= Compare(pfd.RedBits, mode.ColorFormat.Red, ref dist);
                 valid &= Compare(pfd.GreenBits, mode.ColorFormat.Green, ref dist);