[Max] Use RelaxGraphicsMode to find optimal mode
authorthefiddler <stapostol@gmail.com>
Wed, 22 Jan 2014 10:03:40 +0000 (11:03 +0100)
committerthefiddler <stapostol@gmail.com>
Wed, 22 Jan 2014 10:03:40 +0000 (11:03 +0100)
Source/OpenTK/Platform/MacOS/AglContext.cs
Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs

index d1de666..f8e0fe0 100644 (file)
@@ -52,8 +52,6 @@ namespace OpenTK.Platform.MacOS
         DisplayDevice device;
         bool mIsFullscreen = false;
 
-        readonly MacOSGraphicsMode ModeSelector = new MacOSGraphicsMode();
-
         public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext)
         {
             Debug.Print("Context Type: {0}", shareContext);
@@ -103,6 +101,7 @@ namespace OpenTK.Platform.MacOS
             aglAttributes.Add((int)pixelFormatAttribute);
             aglAttributes.Add(value);
         }
+
         void CreateContext(GraphicsMode mode, CarbonWindowInfo carbonWindow, IntPtr shareContextRef, bool fullscreen)
         {
             Debug.Print("AGL pixel format attributes:");
@@ -110,51 +109,30 @@ namespace OpenTK.Platform.MacOS
             AGLPixelFormat myAGLPixelFormat;
             
             // Choose a pixel format with the attributes we specified.
-            if (fullscreen)
-            {
-                IntPtr gdevice;
-                IntPtr cgdevice = GetQuartzDevice(carbonWindow);
-                
-                if (cgdevice == IntPtr.Zero)
-                    cgdevice = (IntPtr)DisplayDevice.Default.Id;
+            IntPtr gdevice;
+            IntPtr cgdevice = GetQuartzDevice(carbonWindow);
                 
-                OSStatus status = Carbon.API.DMGetGDeviceByDisplayID(cgdevice, out gdevice, false);
+            if (cgdevice == IntPtr.Zero)
+                cgdevice = (IntPtr)DisplayDevice.Default.Id;
                 
-                if (status != OSStatus.NoError)
-                    throw new MacOSException(status, "DMGetGDeviceByDisplayID failed.");
+            OSStatus status = Carbon.API.DMGetGDeviceByDisplayID(cgdevice, out gdevice, false);
                 
-                myAGLPixelFormat = ModeSelector.SelectPixelFormat(
-                    mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples,
-                    mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
-                    true, gdevice);
-                
-                Agl.AglError err = Agl.GetError();
-                if (myAGLPixelFormat == IntPtr.Zero || err == Agl.AglError.BadPixelFormat)
-                {
-                    Debug.Print("Failed to create full screen pixel format.");
-                    Debug.Print("Trying again to create a non-fullscreen pixel format.");
-                    
-                    CreateContext(mode, carbonWindow, shareContextRef, false);
-                    return;
-                }
-            }
-            else
-            {
-                myAGLPixelFormat = ModeSelector.SelectPixelFormat(
-                    mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples,
-                    mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
-                    false, IntPtr.Zero);
-                MyAGLReportError("aglChoosePixelFormat");
-            }
-            
+            if (status != OSStatus.NoError)
+                throw new MacOSException(status, "DMGetGDeviceByDisplayID failed.");
+
+            IGraphicsMode selector = new MacOSGraphicsMode(gdevice);
+            Mode = selector.SelectGraphicsMode(
+                mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples,
+                mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
+            MyAGLReportError("aglChoosePixelFormat");
+
             Debug.Print("Creating AGL context.  Sharing with {0}", shareContextRef);
-            
+            myAGLPixelFormat = Mode.Index.Value;
+
             // create the context and share it with the share reference.
             Handle = new ContextHandle(Agl.aglCreateContext(myAGLPixelFormat, shareContextRef));
             MyAGLReportError("aglCreateContext");
 
-            Mode = ModeSelector.GetGraphicsModeFromPixelFormat(myAGLPixelFormat);
-                        
             // Free the pixel format from memory.
             Agl.aglDestroyPixelFormat(myAGLPixelFormat);
             MyAGLReportError("aglDestroyPixelFormat");
index 604973e..7f09155 100644 (file)
@@ -37,14 +37,47 @@ namespace OpenTK.Platform.MacOS
 
     class MacOSGraphicsMode : IGraphicsMode
     {
+        readonly IntPtr Device;
+
+        public MacOSGraphicsMode(IntPtr device)
+        {
+            Device = device;
+        }
+
         #region IGraphicsMode Members
 
         public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil,
             int samples, ColorFormat accum, int buffers, bool stereo)
         {
-            IntPtr pixelformat = SelectPixelFormat(
-                color, depth, stencil, samples, accum, buffers, stereo,
-                false, IntPtr.Zero);
+            IntPtr pixelformat;
+            do
+            {
+                pixelformat = SelectPixelFormat(
+                    color, depth, stencil, samples, accum, buffers, stereo,
+                    true, Device);
+
+                Agl.AglError err = Agl.GetError();
+                if (pixelformat == IntPtr.Zero || err == Agl.AglError.BadPixelFormat)
+                {
+                    Debug.Print("Failed to create full screen pixel format.");
+                    Debug.Print("Trying again to create a non-fullscreen pixel format.");
+                    pixelformat = SelectPixelFormat(
+                        color, depth, stencil, samples, accum, buffers, stereo,
+                        false, IntPtr.Zero);
+                }
+
+                if (pixelformat == IntPtr.Zero)
+                {
+                    if (!Utilities.RelaxGraphicsMode(
+                        ref color, ref depth, ref stencil, ref samples, ref accum,
+                        ref buffers, ref stereo))
+                    {
+                        throw new GraphicsModeException("Requested GraphicsMode not available.");
+                    }
+                }
+            }
+            while (pixelformat == IntPtr.Zero);
+
             return GetGraphicsModeFromPixelFormat(pixelformat);
         }
 
@@ -52,7 +85,7 @@ namespace OpenTK.Platform.MacOS
 
         #region Internal Members
 
-        internal GraphicsMode GetGraphicsModeFromPixelFormat(IntPtr pixelformat)
+        GraphicsMode GetGraphicsModeFromPixelFormat(IntPtr pixelformat)
         {
             int r, g, b, a;
             Agl.aglDescribePixelFormat(pixelformat, Agl.PixelFormatAttribute.AGL_RED_SIZE, out r);
@@ -75,7 +108,7 @@ namespace OpenTK.Platform.MacOS
                 depth, stencil, samples, new ColorFormat(ar, ag, ab, aa), buffers + 1, stereo != 0);
         }
 
-        internal IntPtr SelectPixelFormat(ColorFormat color, int depth, int stencil, int samples,
+        IntPtr SelectPixelFormat(ColorFormat color, int depth, int stencil, int samples,
             ColorFormat accum, int buffers, bool stereo, bool fullscreen, IntPtr device)
         {
             List<int> attribs = new List<int>();