public X11GLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shared, bool direct,
int major, int minor, GraphicsContextFlags flags)
{
if (mode == null)
{
throw new ArgumentNullException("mode");
}
if (window == null)
{
throw new ArgumentNullException("window");
}
// Do not move this lower, as almost everything requires the Display
// property to be correctly set.
Display = ((X11WindowInfo)window).Display;
// Check that GLX is supported. We cannot proceed to create
// an OpenGL context without the GLX extension.
int error_base;
int event_base;
int glx_major;
int glx_minor;
using (new XLock(Display))
{
bool supported = Glx.QueryExtension(Display, out error_base, out event_base);
supported &= Glx.QueryVersion(Display, out glx_major, out glx_minor);
if (supported)
{
Debug.Print("[X11] GLX supported. Version is {0}.{1}", glx_major, glx_minor);
}
else
{
throw new NotSupportedException("[X11] GLX extension is not supported.");
}
}
IntPtr visual = IntPtr.Zero;
IntPtr fbconfig = IntPtr.Zero;
// Once a window has a visual, we cannot use a different
// visual on the OpenGL context, or glXMakeCurrent might fail.
// Note: we should only check X11WindowInfo.Visual, as that
// is the only property that can be set by Utilities.CreateX11WindowInfo.
currentWindow = (X11WindowInfo)window;
if (currentWindow.Visual != IntPtr.Zero)
{
visual = currentWindow.Visual;
fbconfig = currentWindow.FBConfig;
Mode = currentWindow.GraphicsMode;
}
if (Mode == null || !Mode.Index.HasValue)
{
Mode = ModeSelector.SelectGraphicsMode(mode, out visual, out fbconfig);
}
ContextHandle shareHandle = shared != null ?
(shared as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
Debug.Write("Creating X11GLContext context: ");
Debug.Write(direct ? "direct, " : "indirect, ");
Debug.WriteLine(shareHandle.Handle == IntPtr.Zero ? "not shared... " :
String.Format("shared with ({0})... ", shareHandle));
// Try using the new context creation method. If it fails, fall back to the old one.
// For each of these methods, we try two times to create a context:
// one with the "direct" flag intact, the other with the flag inversed.
// HACK: It seems that Catalyst 9.1 - 9.4 on Linux have problems with contexts created through
// GLX_ARB_create_context, including hideous input lag, no vsync and other madness.
// Use legacy context creation if the user doesn't request a 3.0+ context.
if (fbconfig != IntPtr.Zero && (major * 10 + minor >= 30) && SupportsCreateContextAttribs(Display, currentWindow))
{
Handle = CreateContextAttribs(Display, currentWindow.Screen,
fbconfig, direct, major, minor, flags, shareHandle);
}
if (Handle == ContextHandle.Zero)
{
Handle = CreateContextLegacy(Display, visual, direct, shareHandle);
}
if (Handle != ContextHandle.Zero)
{
Debug.Print("Context created (id: {0}).", Handle);
}
else
{
throw new GraphicsContextException("Failed to create OpenGL context. Glx.CreateContext call returned 0.");
}
using (new XLock(Display))
{
if (!Glx.IsDirect(Display, Handle.Handle))
{
Debug.Print("Warning: Context is not direct.");
}
}
}