mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-02-02 07:21:14 +00:00
Use more aggressive xlib locking following the advice of the multithreaded X manpages (needs work).
This commit is contained in:
parent
2a1924c62c
commit
974641086c
|
@ -1,4 +1,4 @@
|
||||||
#region --- License ---
|
#region --- License ---
|
||||||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
||||||
* Contributions from Erik Ylvisaker
|
* Contributions from Erik Ylvisaker
|
||||||
* See license.txt for license info
|
* See license.txt for license info
|
||||||
|
@ -1589,6 +1589,23 @@ XF86VidModeGetGammaRampSize(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct XLock : IDisposable
|
||||||
|
{
|
||||||
|
readonly IntPtr Display;
|
||||||
|
|
||||||
|
public XLock(IntPtr display)
|
||||||
|
: this()
|
||||||
|
{
|
||||||
|
Functions.XLockDisplay(display);
|
||||||
|
Display = display;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Functions.XUnlockDisplay(Display);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning restore 3019
|
#pragma warning restore 3019
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region --- License ---
|
#region --- License ---
|
||||||
/* Licensed under the MIT/X11 license.
|
/* Licensed under the MIT/X11 license.
|
||||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||||
* This notice may not be removed from any source distribution.
|
* This notice may not be removed from any source distribution.
|
||||||
|
@ -77,10 +77,18 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
internal static partial class Functions
|
internal static partial class Functions
|
||||||
{
|
{
|
||||||
public static readonly object Lock = new object();
|
public static readonly object Lock = API.Lock;
|
||||||
|
|
||||||
[DllImport("libX11", EntryPoint = "XOpenDisplay")]
|
[DllImport("libX11", EntryPoint = "XOpenDisplay")]
|
||||||
public extern static IntPtr XOpenDisplay(IntPtr display);
|
extern static IntPtr sys_XOpenDisplay(IntPtr display);
|
||||||
|
public static IntPtr XOpenDisplay(IntPtr display)
|
||||||
|
{
|
||||||
|
lock (Lock)
|
||||||
|
{
|
||||||
|
return sys_XOpenDisplay(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("libX11", EntryPoint = "XCloseDisplay")]
|
[DllImport("libX11", EntryPoint = "XCloseDisplay")]
|
||||||
public extern static int XCloseDisplay(IntPtr display);
|
public extern static int XCloseDisplay(IntPtr display);
|
||||||
[DllImport("libX11", EntryPoint = "XSynchronize")]
|
[DllImport("libX11", EntryPoint = "XSynchronize")]
|
||||||
|
|
|
@ -130,10 +130,13 @@ namespace OpenTK.Platform.X11
|
||||||
else
|
else
|
||||||
Debug.WriteLine("success!");
|
Debug.WriteLine("success!");
|
||||||
|
|
||||||
|
using (new XLock(Display))
|
||||||
|
{
|
||||||
Functions.XFree((IntPtr)fbconfigs);
|
Functions.XFree((IntPtr)fbconfigs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Handle == ContextHandle.Zero)
|
if (Handle == ContextHandle.Zero)
|
||||||
{
|
{
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
Debug.Indent();
|
Debug.Indent();
|
||||||
|
|
||||||
lock (API.Lock)
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
if (!mode.Index.HasValue)
|
if (!mode.Index.HasValue)
|
||||||
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
|
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
|
||||||
|
@ -164,7 +164,7 @@ namespace OpenTK.Platform.X11
|
||||||
hints.base_width = width;
|
hints.base_width = width;
|
||||||
hints.base_height = height;
|
hints.base_height = height;
|
||||||
hints.flags = (IntPtr)(XSizeHintsFlags.PSize | XSizeHintsFlags.PPosition);
|
hints.flags = (IntPtr)(XSizeHintsFlags.PSize | XSizeHintsFlags.PPosition);
|
||||||
lock (API.Lock)
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints);
|
Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints);
|
||||||
|
|
||||||
|
@ -194,20 +194,17 @@ namespace OpenTK.Platform.X11
|
||||||
Debug.Indent();
|
Debug.Indent();
|
||||||
|
|
||||||
// Open a display connection to the X server, and obtain the screen and root window.
|
// Open a display connection to the X server, and obtain the screen and root window.
|
||||||
window.Display = API.DefaultDisplay;
|
window.Display = Functions.XOpenDisplay(IntPtr.Zero);
|
||||||
|
//window.Display = API.DefaultDisplay;
|
||||||
if (window.Display == IntPtr.Zero)
|
if (window.Display == IntPtr.Zero)
|
||||||
throw new Exception("Could not open connection to X");
|
throw new Exception("Could not open connection to X");
|
||||||
|
|
||||||
try
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
Functions.XLockDisplay(window.Display);
|
Functions.XLockDisplay(window.Display);
|
||||||
window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
|
window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
|
||||||
window.RootWindow = Functions.XRootWindow(window.Display, window.Screen); // API.RootWindow;
|
window.RootWindow = Functions.XRootWindow(window.Display, window.Screen); // API.RootWindow;
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
Functions.XUnlockDisplay(window.Display);
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.Print("Display: {0}, Screen {1}, Root window: {2}", window.Display, window.Screen,
|
Debug.Print("Display: {0}, Screen {1}, Root window: {2}", window.Display, window.Screen,
|
||||||
window.RootWindow);
|
window.RootWindow);
|
||||||
|
@ -231,6 +228,8 @@ namespace OpenTK.Platform.X11
|
||||||
/// Registers the necessary atoms for GameWindow.
|
/// Registers the necessary atoms for GameWindow.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void RegisterAtoms(X11WindowInfo window)
|
private void RegisterAtoms(X11WindowInfo window)
|
||||||
|
{
|
||||||
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
Debug.WriteLine("Registering atoms.");
|
Debug.WriteLine("Registering atoms.");
|
||||||
_atom_wm_destroy = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true);
|
_atom_wm_destroy = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true);
|
||||||
|
@ -267,6 +266,7 @@ namespace OpenTK.Platform.X11
|
||||||
// //WMTitle = atoms[offset++];
|
// //WMTitle = atoms[offset++];
|
||||||
// //UTF8String = atoms[offset++];
|
// //UTF8String = atoms[offset++];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region --- License ---
|
#region --- License ---
|
||||||
/* Licensed under the MIT/X11 license.
|
/* Licensed under the MIT/X11 license.
|
||||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||||
* This notice may not be removed from any source distribution.
|
* This notice may not be removed from any source distribution.
|
||||||
|
@ -35,7 +35,8 @@ namespace OpenTK.Platform.X11
|
||||||
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
|
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
|
||||||
int buffers, bool stereo)
|
int buffers, bool stereo)
|
||||||
{
|
{
|
||||||
GraphicsMode gfx; // The actual GraphicsMode that will be selected.
|
GraphicsMode gfx;
|
||||||
|
// The actual GraphicsMode that will be selected.
|
||||||
IntPtr visual = IntPtr.Zero;
|
IntPtr visual = IntPtr.Zero;
|
||||||
IntPtr display = API.DefaultDisplay;
|
IntPtr display = API.DefaultDisplay;
|
||||||
|
|
||||||
|
@ -66,7 +67,8 @@ namespace OpenTK.Platform.X11
|
||||||
Glx.GetConfig(display, ref info, GLXAttribute.STENCIL_SIZE, out stencil);
|
Glx.GetConfig(display, ref info, GLXAttribute.STENCIL_SIZE, out stencil);
|
||||||
Glx.GetConfig(display, ref info, GLXAttribute.SAMPLES, out samples);
|
Glx.GetConfig(display, ref info, GLXAttribute.SAMPLES, out samples);
|
||||||
Glx.GetConfig(display, ref info, GLXAttribute.DOUBLEBUFFER, out buffers);
|
Glx.GetConfig(display, ref info, GLXAttribute.DOUBLEBUFFER, out buffers);
|
||||||
++buffers; // the above lines returns 0 - false and 1 - true.
|
++buffers;
|
||||||
|
// the above lines returns 0 - false and 1 - true.
|
||||||
int st;
|
int st;
|
||||||
Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
|
Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
|
||||||
stereo = st != 0;
|
stereo = st != 0;
|
||||||
|
@ -74,7 +76,10 @@ namespace OpenTK.Platform.X11
|
||||||
gfx = new GraphicsMode(info.VisualID, new ColorFormat(r, g, b, a), depth, stencil, samples,
|
gfx = new GraphicsMode(info.VisualID, new ColorFormat(r, g, b, a), depth, stencil, samples,
|
||||||
new ColorFormat(ar, ag, ab, aa), buffers, stereo);
|
new ColorFormat(ar, ag, ab, aa), buffers, stereo);
|
||||||
|
|
||||||
|
using (new XLock(display))
|
||||||
|
{
|
||||||
Functions.XFree(visual);
|
Functions.XFree(visual);
|
||||||
|
}
|
||||||
|
|
||||||
return gfx;
|
return gfx;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region --- License ---
|
#region --- License ---
|
||||||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
||||||
* See license.txt for license info
|
* See license.txt for license info
|
||||||
*/
|
*/
|
||||||
|
@ -61,6 +61,8 @@ namespace OpenTK.Platform.X11
|
||||||
mouse.NumberOfWheels = 1;
|
mouse.NumberOfWheels = 1;
|
||||||
dummy_mice_list.Add(mouse);
|
dummy_mice_list.Add(mouse);
|
||||||
|
|
||||||
|
using (new XLock(window.Display))
|
||||||
|
{
|
||||||
// Init keyboard
|
// Init keyboard
|
||||||
API.DisplayKeycodes(window.Display, ref firstKeyCode, ref lastKeyCode);
|
API.DisplayKeycodes(window.Display, ref firstKeyCode, ref lastKeyCode);
|
||||||
Debug.Print("First keycode: {0}, last {1}", firstKeyCode, lastKeyCode);
|
Debug.Print("First keycode: {0}, last {1}", firstKeyCode, lastKeyCode);
|
||||||
|
@ -85,6 +87,7 @@ namespace OpenTK.Platform.X11
|
||||||
// be reset before the program exits.
|
// be reset before the program exits.
|
||||||
bool supported;
|
bool supported;
|
||||||
Functions.XkbSetDetectableAutoRepeat(window.Display, true, out supported);
|
Functions.XkbSetDetectableAutoRepeat(window.Display, true, out supported);
|
||||||
|
}
|
||||||
|
|
||||||
Debug.Unindent();
|
Debug.Unindent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region --- License ---
|
#region --- License ---
|
||||||
/* Licensed under the MIT/X11 license.
|
/* Licensed under the MIT/X11 license.
|
||||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||||
* This notice may not be removed from any source distribution.
|
* This notice may not be removed from any source distribution.
|
||||||
|
@ -42,7 +42,10 @@ namespace OpenTK.Platform.X11
|
||||||
for (int screen = 0; screen < API.ScreenCount; screen++)
|
for (int screen = 0; screen < API.ScreenCount; screen++)
|
||||||
{
|
{
|
||||||
IntPtr timestamp_of_last_update;
|
IntPtr timestamp_of_last_update;
|
||||||
|
using (new XLock(API.DefaultDisplay))
|
||||||
|
{
|
||||||
Functions.XRRTimes(API.DefaultDisplay, screen, out timestamp_of_last_update);
|
Functions.XRRTimes(API.DefaultDisplay, screen, out timestamp_of_last_update);
|
||||||
|
}
|
||||||
lastConfigUpdate.Add(timestamp_of_last_update);
|
lastConfigUpdate.Add(timestamp_of_last_update);
|
||||||
|
|
||||||
List<DisplayResolution> available_res = new List<DisplayResolution>();
|
List<DisplayResolution> available_res = new List<DisplayResolution>();
|
||||||
|
@ -60,7 +63,11 @@ namespace OpenTK.Platform.X11
|
||||||
Debug.Print("[Warning] XRandR returned an invalid resolution ({0}) for display device {1}", size, screen);
|
Debug.Print("[Warning] XRandR returned an invalid resolution ({0}) for display device {1}", size, screen);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
short[] rates = Functions.XRRRates(API.DefaultDisplay, screen, resolution_count);
|
short[] rates = null;
|
||||||
|
using (new XLock(API.DefaultDisplay))
|
||||||
|
{
|
||||||
|
rates = Functions.XRRRates(API.DefaultDisplay, screen, resolution_count);
|
||||||
|
}
|
||||||
|
|
||||||
// It seems that XRRRates returns 0 for modes that are larger than the screen
|
// It seems that XRRRates returns 0 for modes that are larger than the screen
|
||||||
// can support, as well as for all supported modes. On Ubuntu 7.10 the tool
|
// can support, as well as for all supported modes. On Ubuntu 7.10 the tool
|
||||||
|
@ -113,9 +120,12 @@ namespace OpenTK.Platform.X11
|
||||||
#region static int[] FindAvailableDepths(int screen)
|
#region static int[] FindAvailableDepths(int screen)
|
||||||
|
|
||||||
static int[] FindAvailableDepths(int screen)
|
static int[] FindAvailableDepths(int screen)
|
||||||
|
{
|
||||||
|
using (new XLock(API.DefaultDisplay))
|
||||||
{
|
{
|
||||||
return Functions.XListDepths(API.DefaultDisplay, screen);
|
return Functions.XListDepths(API.DefaultDisplay, screen);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -123,7 +133,11 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
static XRRScreenSize[] FindAvailableResolutions(int screen)
|
static XRRScreenSize[] FindAvailableResolutions(int screen)
|
||||||
{
|
{
|
||||||
XRRScreenSize[] resolutions = Functions.XRRSizes(API.DefaultDisplay, screen);
|
XRRScreenSize[] resolutions = null;
|
||||||
|
using (new XLock(API.DefaultDisplay))
|
||||||
|
{
|
||||||
|
resolutions = Functions.XRRSizes(API.DefaultDisplay, screen);
|
||||||
|
}
|
||||||
if (resolutions == null)
|
if (resolutions == null)
|
||||||
throw new NotSupportedException("XRandR extensions not available.");
|
throw new NotSupportedException("XRandR extensions not available.");
|
||||||
return resolutions;
|
return resolutions;
|
||||||
|
@ -134,13 +148,16 @@ namespace OpenTK.Platform.X11
|
||||||
#region static float FindCurrentRefreshRate(int screen)
|
#region static float FindCurrentRefreshRate(int screen)
|
||||||
|
|
||||||
static float FindCurrentRefreshRate(int screen)
|
static float FindCurrentRefreshRate(int screen)
|
||||||
|
{
|
||||||
|
short rate = 0;
|
||||||
|
using (new XLock(API.DefaultDisplay))
|
||||||
{
|
{
|
||||||
IntPtr screen_config = Functions.XRRGetScreenInfo(API.DefaultDisplay, Functions.XRootWindow(API.DefaultDisplay, screen));
|
IntPtr screen_config = Functions.XRRGetScreenInfo(API.DefaultDisplay, Functions.XRootWindow(API.DefaultDisplay, screen));
|
||||||
ushort rotation = 0;
|
ushort rotation = 0;
|
||||||
int size = Functions.XRRConfigCurrentConfiguration(screen_config, out rotation);
|
int size = Functions.XRRConfigCurrentConfiguration(screen_config, out rotation);
|
||||||
short rate = Functions.XRRConfigCurrentRate(screen_config);
|
rate = Functions.XRRConfigCurrentRate(screen_config);
|
||||||
Functions.XRRFreeScreenConfigInfo(screen_config);
|
Functions.XRRFreeScreenConfigInfo(screen_config);
|
||||||
|
}
|
||||||
return (float)rate;
|
return (float)rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,9 +166,12 @@ namespace OpenTK.Platform.X11
|
||||||
#region private static int FindCurrentDepth(int screen)
|
#region private static int FindCurrentDepth(int screen)
|
||||||
|
|
||||||
private static int FindCurrentDepth(int screen)
|
private static int FindCurrentDepth(int screen)
|
||||||
|
{
|
||||||
|
using (new XLock(API.DefaultDisplay))
|
||||||
{
|
{
|
||||||
return (int)Functions.XDefaultDepth(API.DefaultDisplay, screen);
|
return (int)Functions.XDefaultDepth(API.DefaultDisplay, screen);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -163,6 +183,8 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
// If resolution == null, restore to default resolution (new_resolution_index = 0).
|
// If resolution == null, restore to default resolution (new_resolution_index = 0).
|
||||||
|
|
||||||
|
using (new XLock(API.DefaultDisplay))
|
||||||
|
{
|
||||||
int screen = deviceToScreen[device];
|
int screen = deviceToScreen[device];
|
||||||
IntPtr root = Functions.XRootWindow(API.DefaultDisplay, screen);
|
IntPtr root = Functions.XRootWindow(API.DefaultDisplay, screen);
|
||||||
IntPtr screen_config = Functions.XRRGetScreenInfo(API.DefaultDisplay, root);
|
IntPtr screen_config = Functions.XRRGetScreenInfo(API.DefaultDisplay, root);
|
||||||
|
@ -182,6 +204,7 @@ namespace OpenTK.Platform.X11
|
||||||
return 0 == Functions.XRRSetScreenConfigAndRate(API.DefaultDisplay, screen_config, root, new_resolution_index,
|
return 0 == Functions.XRRSetScreenConfigAndRate(API.DefaultDisplay, screen_config, root, new_resolution_index,
|
||||||
current_rotation, (short)(resolution != null ? resolution.RefreshRate : 0), lastConfigUpdate[screen]);
|
current_rotation, (short)(resolution != null ? resolution.RefreshRate : 0), lastConfigUpdate[screen]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryRestoreResolution(DisplayDevice device)
|
public bool TryRestoreResolution(DisplayDevice device)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue