SDL: Document that video and input functions should be called on the main thread.

From bc4185c685e0db472ff0884d4adf2239dc046c32 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 5 Dec 2024 09:45:32 -0800
Subject: [PATCH] Document that video and input functions should be called on
 the main thread.

This is a hard requirement on Apple platforms and while most other platforms don't have a concept of main thread, all video and input functions should be called on the same thread.
---
 include/SDL3/SDL_clipboard.h |  22 ++--
 include/SDL3/SDL_events.h    |  16 +--
 include/SDL3/SDL_init.h      |   4 +-
 include/SDL3/SDL_keyboard.h  |  48 ++++++++
 include/SDL3/SDL_mouse.h     |  44 +++++++
 include/SDL3/SDL_render.h    | 156 ++++++++++++-------------
 include/SDL3/SDL_video.h     | 220 +++++++++++++++++++++++++++++++++++
 7 files changed, 407 insertions(+), 103 deletions(-)

diff --git a/include/SDL3/SDL_clipboard.h b/include/SDL3/SDL_clipboard.h
index b23bdb7866f7e..21206f288f38e 100644
--- a/include/SDL3/SDL_clipboard.h
+++ b/include/SDL3/SDL_clipboard.h
@@ -49,7 +49,7 @@ extern "C" {
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -68,7 +68,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardText(const char *text);
  *          SDL_GetError() for more information. This should be freed with
  *          SDL_free() when it is no longer needed.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -82,7 +82,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_GetClipboardText(void);
  *
  * \returns true if the clipboard has text, or false if it does not.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -98,7 +98,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardText(void);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -117,7 +117,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetPrimarySelectionText(const char *text);
  *          failure; call SDL_GetError() for more information. This should be
  *          freed with SDL_free() when it is no longer needed.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -132,7 +132,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_GetPrimarySelectionText(void);
  *
  * \returns true if the primary selection has text, or false if it does not.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -199,7 +199,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -215,7 +215,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -235,7 +235,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void);
  *          for more information. This should be freed with SDL_free() when it
  *          is no longer needed.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -251,7 +251,7 @@ extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, s
  * \returns true if there exists data in clipboard for the provided mime type,
  *          false if it does not.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -269,7 +269,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardData(const char *mime_type);
  *          failure; call SDL_GetError() for more information. This should be
  *          freed with SDL_free() when it is no longer needed.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h
index aa1691b951791..d21567a47a0ec 100644
--- a/include/SDL3/SDL_events.h
+++ b/include/SDL3/SDL_events.h
@@ -1034,9 +1034,7 @@ SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NUL
  * polling or waiting for events (e.g. you are filtering them), then you must
  * call SDL_PumpEvents() to force an event queue update.
  *
- * \threadsafety This should only be run in the thread that initialized the
- *               video subsystem, and for extra safety, you should consider
- *               only doing those things on the main thread in any case.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -1234,9 +1232,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType)
  *              the queue, or NULL.
  * \returns true if this got an event or false if there are none available.
  *
- * \threadsafety This should only be run in the thread that initialized the
- *               video subsystem, and for extra safety, you should consider
- *               only doing those things on the main thread in any case.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -1260,9 +1256,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_PollEvent(SDL_Event *event);
  * \returns true on success or false if there was an error while waiting for
  *          events; call SDL_GetError() for more information.
  *
- * \threadsafety This should only be run in the thread that initialized the
- *               video subsystem, and for extra safety, you should consider
- *               only doing those things on the main thread in any case.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -1292,9 +1286,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WaitEvent(SDL_Event *event);
  * \returns true if this got an event or false if the timeout elapsed without
  *          any events available.
  *
- * \threadsafety This should only be run in the thread that initialized the
- *               video subsystem, and for extra safety, you should consider
- *               only doing those things on the main thread in any case.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
diff --git a/include/SDL3/SDL_init.h b/include/SDL3/SDL_init.h
index 3d518e668984f..97d08f2723977 100644
--- a/include/SDL3/SDL_init.h
+++ b/include/SDL3/SDL_init.h
@@ -78,7 +78,7 @@ extern "C" {
 typedef Uint32 SDL_InitFlags;
 
 #define SDL_INIT_AUDIO      0x00000010u /**< `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS` */
-#define SDL_INIT_VIDEO      0x00000020u /**< `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS` */
+#define SDL_INIT_VIDEO      0x00000020u /**< `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread */
 #define SDL_INIT_JOYSTICK   0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`, should be initialized on the same thread as SDL_INIT_VIDEO on Windows if you don't set SDL_HINT_JOYSTICK_THREAD */
 #define SDL_INIT_HAPTIC     0x00001000u
 #define SDL_INIT_GAMEPAD    0x00002000u /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */
@@ -139,7 +139,7 @@ typedef void (SDLCALL *SDL_AppQuit_func)(void *appstate, SDL_AppResult result);
  * - `SDL_INIT_AUDIO`: audio subsystem; automatically initializes the events
  *   subsystem
  * - `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events
- *   subsystem
+ *   subsystem, should be initialized on the main thread.
  * - `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the
  *   events subsystem
  * - `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem
diff --git a/include/SDL3/SDL_keyboard.h b/include/SDL3/SDL_keyboard.h
index 5bae001e07fc2..f843a8070b8f7 100644
--- a/include/SDL3/SDL_keyboard.h
+++ b/include/SDL3/SDL_keyboard.h
@@ -61,6 +61,8 @@ typedef Uint32 SDL_KeyboardID;
  *
  * \returns true if a keyboard is connected, false otherwise.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyboards
@@ -81,6 +83,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasKeyboard(void);
  *          call SDL_GetError() for more information. This should be freed
  *          with SDL_free() when it is no longer needed.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyboardNameForID
@@ -97,6 +101,8 @@ extern SDL_DECLSPEC SDL_KeyboardID * SDLCALL SDL_GetKeyboards(int *count);
  * \returns the name of the selected keyboard or NULL on failure; call
  *          SDL_GetError() for more information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyboards
@@ -108,6 +114,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetKeyboardNameForID(SDL_KeyboardID
  *
  * \returns the window with keyboard focus.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  */
 extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetKeyboardFocus(void);
@@ -136,6 +144,8 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetKeyboardFocus(void);
  * \param numkeys if non-NULL, receives the length of the returned array.
  * \returns a pointer to an array of key states.
  *
+ * \threadsafety It is safe to call this function from any thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_PumpEvents
@@ -148,6 +158,8 @@ extern SDL_DECLSPEC const bool * SDLCALL SDL_GetKeyboardState(int *numkeys);
  *
  * This function will generate key up events for all pressed keys.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyboardState
@@ -160,6 +172,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_ResetKeyboard(void);
  * \returns an OR'd combination of the modifier keys for the keyboard. See
  *          SDL_Keymod for details.
  *
+ * \threadsafety It is safe to call this function from any thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyboardState
@@ -180,6 +194,8 @@ extern SDL_DECLSPEC SDL_Keymod SDLCALL SDL_GetModState(void);
  *
  * \param modstate the desired SDL_Keymod for the keyboard.
  *
+ * \threadsafety It is safe to call this function from any thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetModState
@@ -201,6 +217,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate);
  * \param key_event true if the keycode will be used in key events.
  * \returns the SDL_Keycode that corresponds to the given SDL_Scancode.
  *
+ * \threadsafety This function is not thread safe.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyName
@@ -220,6 +238,8 @@ extern SDL_DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scan
  *                 scancode generates this key, may be NULL.
  * \returns the SDL_Scancode that corresponds to the given SDL_Keycode.
  *
+ * \threadsafety This function is not thread safe.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyFromScancode
@@ -237,6 +257,8 @@ extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key,
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function is not thread safe.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetScancodeName
@@ -259,6 +281,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetScancodeName(SDL_Scancode scancode, cons
  * \returns a pointer to the name for the scancode. If the scancode doesn't
  *          have a name this function returns an empty string ("").
  *
+ * \threadsafety This function is not thread safe.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetScancodeFromKey
@@ -274,6 +298,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetScancodeName(SDL_Scancode scanco
  * \returns the SDL_Scancode, or `SDL_SCANCODE_UNKNOWN` if the name wasn't
  *          recognized; call SDL_GetError() for more information.
  *
+ * \threadsafety This function is not thread safe.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyFromName
@@ -290,6 +316,8 @@ extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *nam
  * \param key the desired SDL_Keycode to query.
  * \returns a UTF-8 encoded string of the key name.
  *
+ * \threadsafety This function is not thread safe.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyFromName
@@ -305,6 +333,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetKeyName(SDL_Keycode key);
  * \returns key code, or `SDLK_UNKNOWN` if the name wasn't recognized; call
  *          SDL_GetError() for more information.
  *
+ * \threadsafety This function is not thread safe.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetKeyFromScancode
@@ -330,6 +360,8 @@ extern SDL_DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_SetTextInputArea
@@ -423,6 +455,8 @@ typedef enum SDL_Capitalization
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_SetTextInputArea
@@ -444,6 +478,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_StartTextInputWithProperties(SDL_Window *wi
  * \param window the window to check.
  * \returns true if text input events are enabled else false.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_StartTextInput
@@ -460,6 +496,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_TextInputActive(SDL_Window *window);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_StartTextInput
@@ -473,6 +511,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_StopTextInput(SDL_Window *window);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_StartTextInput
@@ -494,6 +534,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ClearComposition(SDL_Window *window);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetTextInputArea
@@ -514,6 +556,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetTextInputArea(SDL_Window *window, const
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_SetTextInputArea
@@ -526,6 +570,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetTextInputArea(SDL_Window *window, SDL_Re
  * \returns true if the platform has some screen keyboard support or false if
  *          not.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_StartTextInput
@@ -539,6 +585,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasScreenKeyboardSupport(void);
  * \param window the window for which screen keyboard should be queried.
  * \returns true if screen keyboard is shown or false if not.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_HasScreenKeyboardSupport
diff --git a/include/SDL3/SDL_mouse.h b/include/SDL3/SDL_mouse.h
index 9068b3fab3b34..e6c1ab60bc0dc 100644
--- a/include/SDL3/SDL_mouse.h
+++ b/include/SDL3/SDL_mouse.h
@@ -139,6 +139,8 @@ typedef Uint32 SDL_MouseButtonFlags;
  *
  * \returns true if a mouse is connected, false otherwise.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetMice
@@ -159,6 +161,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasMouse(void);
  *          call SDL_GetError() for more information. This should be freed
  *          with SDL_free() when it is no longer needed.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetMouseNameForID
@@ -175,6 +179,8 @@ extern SDL_DECLSPEC SDL_MouseID * SDLCALL SDL_GetMice(int *count);
  * \returns the name of the selected mouse, or NULL on failure; call
  *          SDL_GetError() for more information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetMice
@@ -186,6 +192,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetMouseNameForID(SDL_MouseID insta
  *
  * \returns the window with mouse focus.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  */
 extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void);
@@ -214,6 +222,8 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void);
  * \returns a 32-bit bitmask of the button state that can be bitwise-compared
  *          against the SDL_BUTTON_MASK(X) macro.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetGlobalMouseState
@@ -248,6 +258,8 @@ extern SDL_DECLSPEC SDL_MouseButtonFlags SDLCALL SDL_GetMouseState(float *x, flo
  * \returns a 32-bit bitmask of the button state that can be bitwise-compared
  *          against the SDL_BUTTON_MASK(X) macro.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_CaptureMouse
@@ -282,6 +294,8 @@ extern SDL_DECLSPEC SDL_MouseButtonFlags SDLCALL SDL_GetGlobalMouseState(float *
  * \returns a 32-bit bitmask of the button state that can be bitwise-compared
  *          against the SDL_BUTTON_MASK(X) macro.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetMouseState
@@ -304,6 +318,8 @@ extern SDL_DECLSPEC SDL_MouseButtonFlags SDLCALL SDL_GetRelativeMouseState(float
  * \param x the x coordinate within the window.
  * \param y the y coordinate within the window.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_WarpMouseGlobal
@@ -327,6 +343,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window,
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_WarpMouseInWindow
@@ -348,6 +366,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WarpMouseGlobal(float x, float y);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetWindowRelativeMouseMode
@@ -360,6 +380,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetWindowRelativeMouseMode(SDL_Window *wind
  * \param window the window to query.
  * \returns true if relative mode is enabled for a window or false otherwise.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_SetWindowRelativeMouseMode
@@ -406,6 +428,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetWindowRelativeMouseMode(SDL_Window *wind
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetGlobalMouseState
@@ -447,6 +471,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CaptureMouse(bool enabled);
  * \returns a new cursor with the specified parameters on success or NULL on
  *          failure; call SDL_GetError() for more information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_CreateColorCursor
@@ -478,6 +504,8 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_CreateCursor(const Uint8 * data,
  * \returns the new cursor on success or NULL on failure; call SDL_GetError()
  *          for more information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_CreateCursor
@@ -496,6 +524,8 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_CreateColorCursor(SDL_Surface *surf
  * \returns a cursor on success or NULL on failure; call SDL_GetError() for
  *          more information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_DestroyCursor
@@ -514,6 +544,8 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_GetCursor
@@ -528,6 +560,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetCursor(SDL_Cursor *cursor);
  *
  * \returns the active cursor or NULL if there is no mouse.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_SetCursor
@@ -543,6 +577,8 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_GetCursor(void);
  * \returns the default cursor on success or NULL on failuree; call
  *          SDL_GetError() for more information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  */
 extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_GetDefaultCursor(void);
@@ -555,6 +591,8 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_GetDefaultCursor(void);
  *
  * \param cursor the cursor to free.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_CreateColorCursor
@@ -569,6 +607,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_DestroyCursor(SDL_Cursor *cursor);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_CursorVisible
@@ -582,6 +622,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ShowCursor(void);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_CursorVisible
@@ -595,6 +637,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HideCursor(void);
  * \returns `true` if the cursor is being shown, or `false` if the cursor is
  *          hidden.
  *
+ * \threadsafety This function should only be called on the main thread.
+ *
  * \since This function is available since SDL 3.1.3.
  *
  * \sa SDL_HideCursor
diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h
index f2dd536eb7253..d76f32cc68e68 100644
--- a/include/SDL3/SDL_render.h
+++ b/include/SDL3/SDL_render.h
@@ -201,7 +201,7 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetRenderDriver(int index);
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -229,7 +229,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CreateWindowAndRenderer(const char *title,
  * \returns a valid rendering context or NULL if there was an error; call
  *          SDL_GetError() for more information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -283,7 +283,7 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window *window
  * \returns a valid rendering context or NULL if there was an error; call
  *          SDL_GetError() for more information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -320,7 +320,7 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRendererWithProperties(SDL_
  * \returns a valid rendering context or NULL if there was an error; call
  *          SDL_GetError() for more information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -487,7 +487,7 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetRendererProperties(SDL_Rende
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -509,7 +509,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderOutputSize(SDL_Renderer *renderer,
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -531,7 +531,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetCurrentRenderOutputSize(SDL_Renderer *re
  *          was active, the format was unsupported, or the width or height
  *          were out of range; call SDL_GetError() for more information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -561,7 +561,7 @@ extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer *render
  * \returns the created texture or NULL on failure; call SDL_GetError() for
  *          more information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -671,7 +671,7 @@ extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Rende
  *          was active, the format was unsupported, or the width or height
  *          were out of range; call SDL_GetError() for more information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -847,7 +847,7 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_GetRendererFromTexture(SDL_Textur
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  */
@@ -872,7 +872,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetTextureSize(SDL_Texture *texture, float
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You may only call this function from the main thread.
+ * \threadsafety This function should only be called on the main thread.
  *
  * \since This function is available since SDL 3.1.3.
  *
@@ -902,7 +902,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetTextureColorMod(SDL_Texture *texture, Ui
  * \returns true on success or false on failure; call SDL_GetError() for more
  *          information.
  *
- * \threadsafety You

(Patch may be truncated, please check the link at the top of this post.)