Skip to content

Commit 73b034a

Browse files
authored
Merge pull request #6686 from Susko3/log-sdl-errors
Log SDL3 errors if function calls fail and the error is not checked
2 parents dc6f00d + bfd5994 commit 73b034a

File tree

12 files changed

+212
-114
lines changed

12 files changed

+212
-114
lines changed

osu.Framework.iOS/IOSWindow.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public IOSWindow(GraphicsSurfaceType surfaceType, string appName)
3838

3939
public override void Create()
4040
{
41-
SDL_SetHint(SDL_HINT_IOS_HIDE_HOME_INDICATOR, "2"u8);
41+
SDL_SetHint(SDL_HINT_IOS_HIDE_HOME_INDICATOR, "2"u8).LogErrorIfFailed();
4242

4343
base.Create();
4444

@@ -59,7 +59,7 @@ protected override unsafe void RunMainLoop()
5959
// iOS may be a good forward direction if this ever comes up, as a user may see a potentially higher
6060
// frame rate with multi-threaded mode turned on, but it is going to give them worse input latency
6161
// and higher power usage.
62-
SDL_SetiOSAnimationCallback(SDLWindowHandle, 1, &runFrame, ObjectHandle.Handle);
62+
SDL_SetiOSAnimationCallback(SDLWindowHandle, 1, &runFrame, ObjectHandle.Handle).ThrowIfFailed();
6363
}
6464

6565
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]

osu.Framework/Platform/Linux/SDL3LinuxWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal class SDL3LinuxWindow : SDL3DesktopWindow
1111
public SDL3LinuxWindow(GraphicsSurfaceType surfaceType, string appName, bool bypassCompositor)
1212
: base(surfaceType, appName)
1313
{
14-
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, bypassCompositor ? "1"u8 : "0"u8);
14+
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, bypassCompositor ? "1"u8 : "0"u8).LogErrorIfFailed();
1515
}
1616
}
1717
}

osu.Framework/Platform/SDL3/SDL3Clipboard.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public SDL3Clipboard(IImageFormat imageFormat)
4242
// assume that empty text means no text.
4343
public override string? GetText() => SDL_HasClipboardText() ? SDL_GetClipboardText() : null;
4444

45-
public override void SetText(string text) => SDL_SetClipboardText(text);
45+
public override void SetText(string text) => SDL_SetClipboardText(text).LogErrorIfFailed();
4646

4747
public override Image<TPixel>? GetImage<TPixel>()
4848
{

osu.Framework/Platform/SDL3/SDL3DesktopWindow.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ protected override unsafe void UpdateWindowStateAndSize(WindowState state, Displ
1717
// this reset is required even on changing from one fullscreen resolution to another.
1818
// if it is not included, the GL context will not get the correct size.
1919
// this is mentioned by multiple sources as an SDL issue, which seems to resolve by similar means (see https://discourse.libsdl.org/t/sdl-setwindowsize-does-not-work-in-fullscreen/20711/4).
20-
SDL_SetWindowBordered(SDLWindowHandle, true);
21-
SDL_SetWindowFullscreen(SDLWindowHandle, false);
22-
SDL_RestoreWindow(SDLWindowHandle);
20+
SDL_SetWindowBordered(SDLWindowHandle, true).LogErrorIfFailed();
21+
SDL_SetWindowFullscreen(SDLWindowHandle, false).LogErrorIfFailed();
22+
SDL_RestoreWindow(SDLWindowHandle).LogErrorIfFailed();
2323

2424
base.UpdateWindowStateAndSize(state, display, displayMode);
2525
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
2+
// See the LICENCE file in the repository root for full licence text.
3+
4+
using System;
5+
using static SDL.SDL3;
6+
7+
namespace osu.Framework.Platform.SDL3
8+
{
9+
internal class SDL3Exception(string? expression) : Exception($"{SDL_GetError()} (at {expression})");
10+
}

osu.Framework/Platform/SDL3/SDL3Extensions.cs

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
22
// See the LICENCE file in the repository root for full licence text.
33

4+
using System;
45
using System.Drawing;
6+
using System.Runtime.CompilerServices;
57
using osu.Framework.Extensions.EnumExtensions;
68
using osu.Framework.Graphics.Primitives;
79
using osu.Framework.Input;
810
using osu.Framework.Input.Bindings;
911
using osu.Framework.Input.StateChanges;
12+
using osu.Framework.Logging;
1013
using osuTK.Input;
1114
using SDL;
1215
using static SDL.SDL3;
@@ -1045,7 +1048,7 @@ public static unsafe DisplayMode ToDisplayMode(this SDL_DisplayMode mode, int di
10451048
{
10461049
int bpp;
10471050
uint unused;
1048-
SDL_GetMasksForPixelFormat(mode.format, &bpp, &unused, &unused, &unused, &unused);
1051+
SDL_GetMasksForPixelFormat(mode.format, &bpp, &unused, &unused, &unused, &unused).ThrowIfFailed();
10491052
return new DisplayMode(SDL_GetPixelFormatName(mode.format), new Size(mode.w, mode.h), bpp, mode.refresh_rate, displayIndex);
10501053
}
10511054

@@ -1144,5 +1147,100 @@ public static string ReadableName(this SDL_LogPriority priority)
11441147
SDL_ClearError();
11451148
return error;
11461149
}
1150+
1151+
private static void logError(string? expression)
1152+
{
1153+
Logger.Log($"SDL error: {SDL_GetError()}");
1154+
if (!string.IsNullOrEmpty(expression))
1155+
Logger.Log($"at {expression}");
1156+
}
1157+
1158+
public static SDLBool LogErrorIfFailed(this SDLBool returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1159+
{
1160+
if (!returnValue)
1161+
logError(expression);
1162+
1163+
return returnValue;
1164+
}
1165+
1166+
public static void ThrowIfFailed(this SDLBool returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1167+
{
1168+
if (!returnValue)
1169+
throw new SDL3Exception(expression);
1170+
}
1171+
1172+
public static SDL_PropertiesID ThrowIfFailed(this SDL_PropertiesID returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1173+
{
1174+
if (returnValue == 0)
1175+
throw new SDL3Exception(expression);
1176+
1177+
return returnValue;
1178+
}
1179+
1180+
public static int LogErrorIfFailed(this int returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1181+
{
1182+
if (returnValue == -1)
1183+
logError(expression);
1184+
1185+
return returnValue;
1186+
}
1187+
1188+
public static IntPtr ThrowIfFailed(this IntPtr returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1189+
{
1190+
if (returnValue == IntPtr.Zero)
1191+
throw new SDL3Exception(expression);
1192+
1193+
return returnValue;
1194+
}
1195+
1196+
public static SDLArray<T>? LogErrorIfFailed<T>(this SDLArray<T>? returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1197+
where T : unmanaged
1198+
{
1199+
if (returnValue == null)
1200+
logError(expression);
1201+
1202+
return returnValue;
1203+
}
1204+
1205+
public static SDL_PenDeviceType ThrowIfFailed(this SDL_PenDeviceType returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1206+
{
1207+
if (returnValue == SDL_PenDeviceType.SDL_PEN_DEVICE_TYPE_INVALID)
1208+
throw new SDL3Exception(expression);
1209+
1210+
return returnValue;
1211+
}
1212+
1213+
public static string? LogErrorIfFailed(this string? returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1214+
{
1215+
if (returnValue == null)
1216+
logError(expression);
1217+
1218+
return returnValue;
1219+
}
1220+
1221+
public static SDL_DisplayID LogErrorIfFailed(this SDL_DisplayID returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1222+
{
1223+
if (returnValue == 0)
1224+
logError(expression);
1225+
1226+
return returnValue;
1227+
}
1228+
1229+
public static SDL_DisplayID ThrowIfFailed(this SDL_DisplayID returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1230+
{
1231+
if (returnValue == 0)
1232+
throw new SDL3Exception(expression);
1233+
1234+
return returnValue;
1235+
}
1236+
1237+
public static unsafe T* LogErrorIfFailed<T>(T* returnValue, [CallerArgumentExpression("returnValue")] string? expression = null)
1238+
where T : unmanaged
1239+
{
1240+
if (returnValue == null)
1241+
logError(expression);
1242+
1243+
return returnValue;
1244+
}
11471245
}
11481246
}

osu.Framework/Platform/SDL3/SDL3GraphicsSurface.cs

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ public SDL3GraphicsSurface(SDL3Window window, GraphicsSurfaceType surfaceType)
3333
switch (surfaceType)
3434
{
3535
case GraphicsSurfaceType.OpenGL:
36-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_RED_SIZE, 8);
37-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_GREEN_SIZE, 8);
38-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_BLUE_SIZE, 8);
39-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_ACCUM_ALPHA_SIZE, 0);
40-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_DEPTH_SIZE, 16);
41-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_STENCIL_SIZE, 8);
36+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_RED_SIZE, 8).ThrowIfFailed();
37+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_GREEN_SIZE, 8).ThrowIfFailed();
38+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_BLUE_SIZE, 8).ThrowIfFailed();
39+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_ACCUM_ALPHA_SIZE, 0).ThrowIfFailed();
40+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_DEPTH_SIZE, 16).ThrowIfFailed();
41+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_STENCIL_SIZE, 8).ThrowIfFailed();
4242
break;
4343

4444
case GraphicsSurfaceType.Vulkan:
@@ -60,7 +60,7 @@ public void Initialise()
6060
public Size GetDrawableSize()
6161
{
6262
int width, height;
63-
SDL_GetWindowSizeInPixels(window.SDLWindowHandle, &width, &height);
63+
SDL_GetWindowSizeInPixels(window.SDLWindowHandle, &width, &height).ThrowIfFailed();
6464
return new Size(width, height);
6565
}
6666

@@ -70,27 +70,27 @@ private void initialiseOpenGL()
7070
{
7171
if (RuntimeInfo.IsMobile)
7272
{
73-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL_GLProfile.SDL_GL_CONTEXT_PROFILE_ES);
73+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL_GLProfile.SDL_GL_CONTEXT_PROFILE_ES).ThrowIfFailed();
7474

7575
// Minimum OpenGL version for ES profile:
76-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_MAJOR_VERSION, 3);
77-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_MINOR_VERSION, 0);
76+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_MAJOR_VERSION, 3).ThrowIfFailed();
77+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_MINOR_VERSION, 0).ThrowIfFailed();
7878
}
7979
else
8080
{
81-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL_GLProfile.SDL_GL_CONTEXT_PROFILE_CORE);
81+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL_GLProfile.SDL_GL_CONTEXT_PROFILE_CORE).ThrowIfFailed();
8282

8383
// Minimum OpenGL version for core profile:
84-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_MAJOR_VERSION, 3);
85-
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_MINOR_VERSION, 2);
84+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_MAJOR_VERSION, 3).ThrowIfFailed();
85+
SDL_GL_SetAttribute(SDL_GLAttr.SDL_GL_CONTEXT_MINOR_VERSION, 2).ThrowIfFailed();
8686
}
8787

8888
context = SDL_GL_CreateContext(window.SDLWindowHandle);
8989

9090
if (context == null)
9191
throw new InvalidOperationException($"Failed to create an SDL3 GL context ({SDL_GetError()})");
9292

93-
SDL_GL_MakeCurrent(window.SDLWindowHandle, context);
93+
SDL_GL_MakeCurrent(window.SDLWindowHandle, context).ThrowIfFailed();
9494

9595
loadBindings();
9696
}
@@ -126,29 +126,13 @@ private void loadEntryPoints(GraphicsBindingsBase bindings)
126126
string? str = Marshal.PtrToStringAnsi(new IntPtr(ptr));
127127

128128
Debug.Assert(str != null);
129-
entryPointsInstance[i] = getProcAddress(str);
129+
entryPointsInstance[i] = SDL_GL_GetProcAddress(str);
130130
}
131131
}
132132

133133
pointsInfo.SetValue(bindings, entryPointsInstance);
134134
}
135135

136-
private IntPtr getProcAddress(string symbol)
137-
{
138-
const SDL_LogCategory error_category = SDL_LogCategory.SDL_LOG_CATEGORY_ERROR;
139-
SDL_LogPriority oldPriority = SDL_GetLogPriority(error_category);
140-
141-
// Prevent logging calls to SDL_GL_GetProcAddress() that fail on systems which don't have the requested symbol (typically macOS).
142-
SDL_SetLogPriority(error_category, SDL_LogPriority.SDL_LOG_PRIORITY_INFO);
143-
144-
IntPtr ret = SDL_GL_GetProcAddress(symbol);
145-
146-
// Reset the logging behaviour.
147-
SDL_SetLogPriority(error_category, oldPriority);
148-
149-
return ret;
150-
}
151-
152136
int? IOpenGLGraphicsSurface.BackbufferFramebuffer
153137
{
154138
get
@@ -195,7 +179,7 @@ bool IOpenGLGraphicsSurface.VerticalSync
195179
void IOpenGLGraphicsSurface.DeleteContext(IntPtr context) => SDL_GL_DestroyContext((SDL_GLContextState*)context);
196180
void IOpenGLGraphicsSurface.MakeCurrent(IntPtr context) => SDL_GL_MakeCurrent(window.SDLWindowHandle, (SDL_GLContextState*)context);
197181
void IOpenGLGraphicsSurface.ClearCurrent() => SDL_GL_MakeCurrent(window.SDLWindowHandle, null);
198-
IntPtr IOpenGLGraphicsSurface.GetProcAddress(string symbol) => getProcAddress(symbol);
182+
IntPtr IOpenGLGraphicsSurface.GetProcAddress(string symbol) => SDL_GL_GetProcAddress(symbol);
199183

200184
#endregion
201185

@@ -217,7 +201,7 @@ bool IOpenGLGraphicsSurface.VerticalSync
217201
#region Android-specific implementation
218202

219203
[SupportedOSPlatform("android")]
220-
IntPtr IAndroidGraphicsSurface.JniEnvHandle => SDL_GetAndroidJNIEnv();
204+
IntPtr IAndroidGraphicsSurface.JniEnvHandle => SDL_GetAndroidJNIEnv().ThrowIfFailed();
221205

222206
[SupportedOSPlatform("android")]
223207
IntPtr IAndroidGraphicsSurface.SurfaceHandle => window.SurfaceHandle;

osu.Framework/Platform/SDL3/SDL3MobileWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public SDL3MobileWindow(GraphicsSurfaceType surfaceType, string appName)
1515
protected override unsafe void UpdateWindowStateAndSize(WindowState state, Display display, DisplayMode displayMode)
1616
{
1717
// This sets the status bar to hidden.
18-
SDL_SetWindowFullscreen(SDLWindowHandle, true);
18+
SDL_SetWindowFullscreen(SDLWindowHandle, true).LogErrorIfFailed();
1919

2020
// Don't run base logic at all. Let's keep things simple.
2121
}

0 commit comments

Comments
 (0)