Compare commits

...
Author SHA1 Message Date
Sam Lantinga a8589a8422 Updated to version 3.2.24 for release 2025-10-02 10:52:32 -07:00
Simon McVittie 0bdaaf6c76 build: Prefix SDL- to revision from REVISION.txt
This makes it possible to get the version number of an unknown SDL binary
from `strings libSDL3.so.0 | grep SDL-`, like we could for SDL 2.

Resolves: https://github.com/libsdl-org/SDL/issues/14114
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 618b7b6c73)
2025-10-02 09:09:03 -07:00
Simon McVittie 390197d3aa build: Prefix version from git with SDL- rather than SDL3-
We can tell it's SDL 3 from the version number and git revision,
so there's no need to duplicate that in the prefix.

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit d5b79418f4)
2025-10-02 09:09:03 -07:00
Mathieu Eyraud 9fafba49dc Zero-initialize SDL_GPUDevice
(cherry picked from commit 86da08b0be)
2025-10-01 07:23:41 -07:00
Victor Ilyushchenko 5d47efe7fb Fix Metal 3D texture upload stride calculation
Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
(cherry picked from commit a34d31322c)
2025-09-28 07:32:48 -07:00
Sam Lantinga 824234accc Fixed HIDAPI controller disconnect reading on multiple threads
If multiple threads are calling SDL_UpdateJoysticks(), then an overlapped read can be initiated on one thread (read_pending set to true) and GetOverlappedResult() called on another thread. This results in ERROR_OPERATION_ABORTED. This is harmless so we shouldn't return an error in this case, we'll just retry the read on the next call.

Fixes https://github.com/libsdl-org/SDL/issues/14033

(cherry picked from commit b2188b325d)
2025-09-25 10:41:52 -07:00
Frank Praznik 6519158ae5 wayland: Ignore bogus libdecor content sizes if an unmapped window is suspended
If a client takes a long time to present the first frame after creating the window, a configure event to set the suspended state may arrive with libdecor increasing the content size by the decoration dimensions, which should be ignored.

(cherry picked from commit 9d5d7010de)
2025-09-24 10:36:04 -04:00
Frank Praznik 00718d60d2 x11: Use the pending size for the min/max limits if a resize is in flight
Otherwise, an outdated size may be used, reverting the requested resize operation.

(cherry picked from commit 45480f5fe5)
2025-09-24 10:36:04 -04:00
Sam Lantinga 18c2e179ee Use the real window position on macOS
On newer MacBooks, the fullscreen window might be placed below the camera notch, so use the actual window position

Fixes https://github.com/libsdl-org/SDL/issues/10441

(cherry picked from commit 0a50058f7a)
2025-09-23 23:04:41 -07:00
Sam Lantinga 21ae008fc2 Use an empty bitmap for the blank cursor on macOS
Some macOS installations seem to have trouble decoding the GIF we were using

Fixes https://github.com/libsdl-org/SDL/issues/14012

(cherry picked from commit 221d1f12ea)
2025-09-22 19:16:01 -07:00
Sam Lantinga 97a8bb44e6 The default swap interval on EGL is 1, according to the spec
Fixes https://github.com/libsdl-org/SDL/issues/14014

(cherry picked from commit 137b0b2bee)
2025-09-22 11:28:46 -07:00
Ryan C. Gordon 5d33fce898 wav: Patched to compile on Visual Studio.
(cherry picked from commit 09ee8876b3)
2025-09-22 08:14:33 -07:00
Ryan C. Gordon bb5df96f69 wav: Clamp DATA chunk to size of file if possible.
Prevents a malicious file from malloc'ing multiple gigabytes.

Fixes #10052.

(cherry picked from commit 44e4deab7c)
2025-09-22 08:14:33 -07:00
Brenton Bostick 12b97944f3 fix: Extra parameter(s) for call to 'getCacheDir()'.
(cherry picked from commit 6590a5bc0b)
2025-09-22 07:25:19 -07:00
Brenton Bostick 0f17fbe1ca fix 'SDL_MessageBoxFlags' is not a valid JVM type.
(cherry picked from commit ed7d39b28c)
2025-09-22 07:05:05 -07:00
Sam Lantinga c3480ca99c Use clearPrimaryClip() on Android 9 and newer
Fixes https://github.com/libsdl-org/SDL/issues/8355

(cherry picked from commit 34b09be6a5)
2025-09-21 23:30:57 -07:00
Sam Lantinga 936d94c2ee Fixed SDL_RunOnMainThread() on Android
If the application is waiting in SDL_WaitEvent(), we still need to run event loop maintenance in between calls to Android_PumpEvents().

Fixes the testautomation events_mainThreadCallbacks() test on Android.

(cherry picked from commit bae34c3e34)
2025-09-21 13:58:51 -07:00
Sam Lantinga 6cb55ebd46 Fixed a memory leak in fill_device_info_usage() (thanks @digant73)
Fixes https://github.com/libsdl-org/SDL/issues/13998

(cherry picked from commit 5503fe1c1b)
2025-09-20 09:05:52 -07:00
Andrei Sabalenka 482c5130eb wayland: fix typo in xdg_positioner_set_anchor_rect
(cherry picked from commit bb2b39b8ea)
2025-09-20 08:54:18 -07:00
Anonymous Maarten 066bcc5204 ci: disable ccache on macOS 13 job
(cherry picked from commit 566e7c2379)
2025-09-17 22:06:16 +02:00
ManifoldFR 21baa27bea gpu/vulkan : fix clear value indexing
(cherry picked from commit 8bc4e029bd)
2025-09-16 08:45:56 -07:00
Sora 93fd4a1c80 fix: use productCategory instead of vendorName for joy name for apple driver
(cherry picked from commit 964bedfdd9)
2025-09-15 11:52:21 -07:00
Ozkan Sezer 7135779599 SDL_endian.h: don't add _m_prefetch hack for clang-cl if available as a builtin
Fixes: https://github.com/libsdl-org/SDL/issues/13952 .

(cherry picked from commit 81f2f44843)
2025-09-15 20:10:28 +03:00
Eddy Jansson 62c151d044 wayland: Silence unused variable warning
'vd' and 'd' are only used if SDL_USE_LIBDBUS is set.

(cherry picked from commit 21c9f5304d)
2025-09-15 10:27:51 -04:00
Sam Lantinga 11d38fc23b Only use a transparent cursor on Windows when connected via RDP
VMware relies on the cursor being set to NULL to optimize relative mouse motion for games.

We should also revisit whether current RDP works better with a NULL cursor or a transparent cursor.

Fixes https://github.com/libsdl-org/SDL/issues/13700

(cherry picked from commit dac6af4ba6)
2025-09-14 17:31:09 -07:00
Sam Lantinga d027f0ae6e Remove Windows 32-bit ARM build from CI
This architecture is deprecated and is now failing with:
Windows SDK 10.0.22621.0 : 'C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\um' not found or was incomplete

Fixes https://github.com/libsdl-org/SDL/issues/13949

(cherry picked from commit cc3274b6f1)
2025-09-14 15:45:34 -07:00
Nintorch 44290c204e Fix HP Deluxe Webcam KQ246AA detected as joystick
(cherry picked from commit 556ee00fe3)
2025-09-14 15:40:40 -07:00
Sam Lantinga 0b69860af6 Fixed testprocess on 32-bit Windows
Previously the test would kill the child process while it was in the process of initializing (loading DLLs, etc) and this would cause the test to fail.

(cherry picked from commit 937b7e6aea)
2025-09-14 15:40:06 -07:00
Sam Lantinga e7a1ae0ea5 Clarify why we ignore EINVAL when flushing a file descriptor
(cherry picked from commit a1d3fc1f50)
2025-09-14 15:39:53 -07:00
Sam Lantinga 7af36d6c40 Ignore errors flushing output on POSIX pipes
Fixes https://github.com/libsdl-org/SDL/issues/13116
Fixes https://github.com/libsdl-org/SDL/issues/13412

(cherry picked from commit e40d337a47)
2025-09-14 12:10:18 -07:00
Sam Lantinga d1ae1163dd Wait briefly after enabling effects on DualSense controller
The rumble motors apparently take a short time to power up after enabling enhanced mode.

Fixes https://github.com/libsdl-org/SDL/issues/13909

(cherry picked from commit 1aba421bd3)
2025-09-14 10:00:40 -07:00
Sam Lantinga b2cf5729b4 Disable Windows.Gaming.Input by default
The functionality is already covered by XInput and DirectInput, and Microsoft is recommending GameInput going forward.

Fixes https://github.com/libsdl-org/SDL/issues/13000

(cherry picked from commit 78a29d1670)
2025-09-14 08:52:43 -07:00
Sam Lantinga 11b8dd76db Fixed memory leak when using detached threads
Fixes https://github.com/libsdl-org/SDL/issues/13886

(cherry picked from commit ede86a1267)
2025-09-14 08:43:12 -07:00
Frank Praznik 56507a6122 x11: Use the SDL_WindowFlags type instead of Uint32
Uint32 can potentially truncate the flag value, as it is 64 bits in SDL3.

(cherry picked from commit 4561be89a5)
2025-09-13 15:45:43 -04:00
Evan Hemsley 8d4324cba2 GPU: Bump MAX_COLOR_TARGET_BINDINGS to 8 (#13937)
(cherry picked from commit fe314a1b8a)
2025-09-12 13:38:58 -07:00
Jaan Soulier 35408a2126 Fix reallocation of GPU renderer vertex buffer
(cherry picked from commit ed6a72a7fd)
2025-09-09 20:28:32 -07:00
Sam Lantinga e5b9dfd181 Fixed setting SDL_PROP_TEXTURE_VULKAN_TEXTURE_NUMBER
(cherry picked from commit b7dba970e1)
2025-09-09 17:35:03 -07:00
eafton e8a5d07e5e X11: Check for invalid opcodes in SHM error handler
(cherry picked from commit b59d6d49c3)
2025-09-09 10:59:58 -07:00
Luis Caceres 8c1daf0caf gpu/vulkan: Move dereference after null check
(cherry picked from commit 03d0c2ad74)
2025-09-08 09:50:09 -07:00
Sam Lantinga ad2b211f75 Fixed pitch and chroma issues with the Vulkan planar YUV texture update functions
Fixes https://github.com/libsdl-org/SDL/issues/13734

(cherry picked from commit 466f93aee1)
2025-09-07 10:19:59 -07:00
Sam Lantinga 414ae344af Fixed rumble strength on DualSense Edge and Bluetooth connected controllers
Fixes https://github.com/libsdl-org/SDL/issues/13771

(cherry picked from commit 25d9096d41)
2025-09-06 11:53:55 -07:00
Adrian 71af2c020c Set preferredFrameRateRange in main callbacks CADisplayLink
(cherry picked from commit 01e6aceffc)
2025-09-06 10:13:44 -07:00
Aleksey Melekh e755f50072 xbox: fix build
(cherry picked from commit 129c97f610)
2025-09-05 09:20:34 -07:00
Sam Lantinga a0b8275e9c Fixed the perspective matrix calculation (thanks @KonkolyTamas!)
Fixes https://github.com/libsdl-org/SDL/issues/13867

(cherry picked from commit ea1a769322)
2025-09-04 06:07:28 -07:00
Cameron Cawley ea362839b1 Remove unused PSP source files
(cherry picked from commit 42f571ea4b)
2025-09-03 15:20:00 -07:00
Sam Lantinga e7dd5d841b Don't set SDL_SURFACE_LOCK_NEEDED until a surface is RLE encoded
Reference https://github.com/libsdl-org/sdl2-compat/issues/476

(cherry picked from commit 437d78499c)
2025-09-02 21:32:17 -07:00
Sam Lantinga 5594d03da0 Leave letterbox borders set to the frame clear color
Fixes https://github.com/libsdl-org/sdl2-compat/issues/483

(cherry picked from commit fbbc29159a)
2025-09-02 20:14:56 -07:00
Sam Lantinga f2ae66b64f Set the texture scale and address mode when creating a texture
Fixes https://github.com/libsdl-org/sdl2-compat/issues/506

(cherry picked from commit ef19c72015)
2025-09-02 19:46:28 -07:00
Anonymous Maarten 393d99338f cmake: make SDL_CPU_xxx variable visible when using CMAKE_OSX_ARCHITECTURES
(cherry picked from commit ebb52973e1)
2025-09-02 23:00:10 +03:00
Ozkan Sezer 4d88280931 cmake: simd detection clean-up for Apple multi-arch configs.
(cherry picked from commit 83bb0f9105)
2025-09-02 22:35:32 +03:00
Anonymous Maarten e8cc359b5e cmake: use 'TargetConditionals.h' on Apple for SIMD tests
(cherry picked from commit e15e2808f2)
2025-09-02 22:35:20 +03:00
Anonymous Maarten 3b4a198655 cmake: use APPLE in dep_option
expands to <nothing> on e.g. Windows, which will be interpreted as true by cmake_dependent_option.

(cherry picked from commit 1e7d3b51de)
2025-09-02 22:35:02 +03:00
Ethan Lee 03dd1520a3 gpu: VK_KHR_get_physical_device_properties2 can be optional
(cherry picked from commit 689049f8ec)
2025-09-02 09:53:59 -07:00
Sam Lantinga a6fd74fa3b Fix crash when enumerating Steam Controllers
Closes https://github.com/libsdl-org/SDL/pull/13746
2025-09-02 08:42:16 -07:00
Sam Lantinga 03b36bac94 Updated to version 3.2.23 for development 2025-09-01 15:12:43 -07:00
Sam Lantinga a96677bdf6 Updated to version 3.2.22 for release 2025-09-01 14:40:32 -07:00
Ryan C. Gordon 67f89d0a2b openslES: Patched to compile.
(whoops.)

(cherry picked from commit 7323104f97)
2025-09-01 11:10:33 -04:00
Ryan C. Gordon f6de8877ec openslES: OpenSL ES on Android only supports two formats, limit to that.
(Three with the floating point extension, which we use.)

This is according to:

https://developer.android.com/ndk/guides/audio/opensl/opensl-for-android

Previously, this would accept a request for Sint8 or Sint32 and disaster
would ensue.

Fixes #13779.

(cherry picked from commit 0b2a003a35)
2025-09-01 10:31:05 -04:00
Ozkan Sezer 7c189b1f17 cmake: revert commit 5d1bbd9 and change sse4.2 test
clang doesn't support -mcrc32 until version 14.0, therefore drop -mcrc32
use in sse 4.2 test, and change it to check _mm_cmpgt_epi64() instead of
_mm_crc32_u32(). without this, sse4.2 check was failing with clang <= 13

Fixes https://github.com/libsdl-org/SDL/pull/12223

(cherry picked from commit 875653658a)
2025-08-31 03:20:40 +03:00
Sam Lantinga a7947080c0 Fixed warnings building with Visual Studio
(cherry picked from commit 7c8df4ea52)
2025-08-30 10:16:11 -07:00
Sam Lantinga 08c82a3781 Fixed build
(cherry picked from commit 3cf2350f21)
2025-08-30 10:15:48 -07:00
Jordan Saunders 589aea50c2 Fix two uninitialized variables
Found when running in valgrind looking at another issue.

- RenderPass' depth_stencil_target
    Tripped in SDL_BindGPUFragmentSamplers when not binding a DS target

- VulkanCommandBuffer's swapchainRequested
    Tripped in VULKAN_Submit for the end transition barrier when
    creating an image. The field is only reset when reused, not on first
    use

(cherry picked from commit 265236d952)
2025-08-30 06:05:43 -07:00
Ozkan Sezer 72acd7c9df CI: add OpenBSD workflow
(cherry picked from commit c0e5fd55d2)
2025-08-30 14:22:24 +03:00
Frank Praznik 1a70d1158e fs: Fix OpenBSD path retrieval
Set the path start pointer to point to a valid string.

(cherry picked from commit fdfde42db1)
2025-08-30 14:21:24 +03:00
Frank Praznik ae915c6516 wayland: Add a sigtimedwait() implementation for OpenBSD
sigtimedwait() is an optional part of POSIX.1-2001, and OpenBSD doesn't implement it. Add a replacement implementation based on https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation

(cherry picked from commit 1049426a76)
2025-08-30 14:21:00 +03:00
Xander 54d573332e Add SDL_SENSOR_COUNT to SDL_SensorType
(cherry picked from commit dc7a3a1219)
2025-08-29 07:31:25 -07:00
Matthew Zavislak 0204a69f6b Add elf alignment check for Android artifacts (#13818)
(cherry picked from commit 4f11feb708)
2025-08-28 16:31:25 -07:00
Susko3 b2689ff76a Avoid checking for HAVE_POSIX_SPAWN on Android
This makes the CMake build closer to SDL_build_config_android.h
as both will now use SDL_PROCESS_DUMMY.

(cherry picked from commit cd21bbe796)
2025-08-28 04:10:16 -07:00
Ozkan Sezer 611940fb80 cmake: fall back to -Wconversion if -Wfloat-conversion isn't available
... during checks for valid isinf/isinff/isnan/isnanf macros.

(cherry picked from commit 98bed62259)
2025-08-27 22:20:37 +03:00
Nintorch 16c0329a2a Add Emscripten joystick rumble support
Adds support for Emscripten (Web) joystick rumble support via EM_ASM_INT macros and HTML5's Gamepad API.

(cherry picked from commit 1fbed16cb0)
2025-08-25 12:59:15 -07:00
Nintorch 2743716132 Allow Android to ignore unnecessary joysticks
Previously, SDL_ShouldIgnoreJoystick wasn't being called for Android, and fingerprint sensors were recognized as joysticks.

(cherry picked from commit 1af7dfb0a7)
2025-08-25 11:23:34 -07:00
Colin Kinloch a744eee993 testffmpeg: avutil queue family version check
The `AVVulkanDeviceQueueFamily` struct was introduced by libavutil
59.34.100

(cherry picked from commit 81920b5db7)
2025-08-25 11:10:31 -07:00
Evan Hemsley 0e24267eb5 gpu: D3D12 only requires feature level 11_0 with Resource Binding Tier 2. (#13782)
We previously thought this wasn't possible because constant buffer offsets and
partial updates were unavailable, but we were reading the wrong table - this is
only the case for D3D11...

https://learn.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro

... while 12 doesn't list this feature at all:

https://learn.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels

We double checked and Jesse Natalie confirmed that this feature is required for
D3D12 even for 11_0 drivers. (Thanks Jesse!)

Additionally, D3D12 requires that UAVs are accessible from all shader stages,
meaning Tier 2 is enough to support the number of UAVs we need. Tier 1 could be
a property to lower the requirements, but that can be done later.
2025-08-22 14:07:58 -07:00
Wilson Jallet f4d6043aa4 GPU: Fix Vulkan indexing error for resolve attachment refs (#13768)
(cherry picked from commit 03b14f5211)
2025-08-19 12:13:23 -07:00
Petar Popovic 9fb9bd31a3 emscripten tests: fix warning: uninitialized variable
(cherry picked from commit 45feacf608)
2025-08-13 17:01:31 -07:00
ChaseKnowlden c3828bb0a3 Keep MSVC Flags Consistent across CMake runs
(cherry picked from commit 10478c59db)
2025-08-12 19:39:44 -07:00
Sam Lantinga 40371f0907 Support the "ambient" value for SDL_HINT_AUDIO_CATEGORY
Fixes https://github.com/libsdl-org/SDL/issues/13732

(cherry picked from commit 4725213eef)
2025-08-12 09:54:43 -07:00
Sylvain 94f9434564 Fixed bug #13493: Assertion failure at SDL_AddTouch with Android API 28
Java touch id should be -1 because it's reserved for internal SDL
synthetic events.
It should also not be 0, because this is SDL invalid value.

(cherry picked from commit 970c0bfe96)
2025-08-12 09:44:04 -07:00
Chase Knowlden bfaf247d30 Update NDK version to 28 (#13729)
* Update NDK version to 28 and add 16kb page size linker flags to x86_64

* Remove Android Linker Options

16kb page size is now the default since NDK r28c

* Update Android CI to use NDK 28

(cherry picked from commit 6e422e5ff2)
2025-08-12 07:46:27 -07:00
Beyley Cardellio 2287c43b59 GPU: Hold submit lock before waiting for device idle
(cherry picked from commit e699f3dca1)
2025-08-10 07:22:19 -07:00
Petar Popovic 15cc0f5f91 linux/SDL_syshaptic.c:SDL_SYS_HapticStopAll(): Fix return on error
(cherry picked from commit 43f3991398)
2025-08-09 09:28:02 -07:00
Anonymous Maarten 68e0108b1c release: build aarch64 libraries with 16kiB page size
[ci skip]

(cherry picked from commit 7017fbaa8e)
2025-08-09 05:23:43 +02:00
Mohamed Shazan 7b3796bc39 SDL_TriggerBreakpoint() will default to __debugbreak() on MinGW toolchain on windows
(cherry picked from commit f4c124e4bf)
2025-08-08 16:21:15 -07:00
Petar Popovic b5bc6d2cc4 SDL_SendJoystickVirtualSensorDataInner(): Fix max_sensor_events increment
(cherry picked from commit d9c20cfd0a)
2025-08-08 12:52:03 -07:00
Petar Popovic 0d1d4ea1f9 SDL_SetRenderDrawBlendMode(): Remove redundant param check
(cherry picked from commit b63c32e790)
2025-08-08 14:06:27 -04:00
Pino Toscano 1a48f897f2 ime: fcitx: use SDL_GetExeName() in GetAppName()
Use the existing SDL_GetExeName(), available for all the UNIX
platforms, in the internal GetAppName(); this has few advantanges:
- SDL_GetExeName() (and SDL_GetAppID() that builds on top of it) are
  used in various places already; since it caches the executable name,
  this may remove one extra read of the application name
- SDL_GetExeName() has a non-dummy implementation in more OSes than
  GetAppName(), thus providing a small improvement for this IME

As drive-by change: since SDL_GetExeName() provides a constant string,
there is no more need to allocate a new string in GetAppName(), which
is used as constant string anyway. Hence, return a constant string in
GetAppName() too.

(cherry picked from commit 248bcf6b29)
2025-08-07 13:58:27 -07:00
Simon McVittie 2b42789de6 Fix some typos detected by Debian's lintian QA tool
I assume the demoninator is a typo, rather than an indication that
someone has been playing too much Doom :-)

Signed-off-by: Simon McVittie <smcv@collabora.com>

(cherry picked from commit d83503f80e)
2025-08-07 13:55:44 -07:00
Simon McVittie b9c1da10ba hints: Rephrase documentation to improve grammar
"This thing allows to do something" is not really grammatically correct.
The closest rephrasing would be "allows one to do something" or "allows
the user to do something", but I think the passive voice reads more
naturally here.

Detected by Debian's lintian QA tool.

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 40b941c826)
2025-08-07 13:55:44 -07:00
cosmonaut 56f5a76696 GPU: Fix uninitialized value in Vulkan command buffer structure
(cherry picked from commit fe6b2161bf)
2025-08-07 13:42:16 -07:00
Sam Lantinga c7e8977e60 Revert "Support Google Play 16 KB Page Size Requirement (#13470)"
This reverts commit edef6e66e9

If you need to support the Google Play 16 kiB page size requirement, the recommendation is to use NDK r28c or newer, which automatically aligns binaries correctly.
2025-08-07 11:41:43 -07:00
Pino Toscano e6ba3612db SDL_endian.h: extend Linux way for GNU libc
The currently used way to determine the endianness (i.e. include
<endian.h> and use the __BYTE_ORDER macro) is provided in general by
GNU libc. Thus, extend that to any platform/OS based on GNU libc.

(cherry picked from commit 561c99ee11)
2025-08-06 16:13:44 -07:00
Frank Praznik 5e77fb314c win32: Use the current flags to determine if NCCALCSIZE is required
SDL_GetWindowFlags() also ORs in pending flags, whereas the current state is needed here, particularly when creating/showing a window.

(cherry picked from commit cd0c660dea)
2025-08-05 18:49:41 -04:00
Frank Praznik 1a2841deb1 win32: Use STYLE_BORDERLESS when showing a pending fullscreen window
In addition to hiding the border on bordered windows that will immediately become fullscreen, The combination of flags used in STYLE_BORDERLESS_WINDOWED will still show the borders on borderless windows if the initial window size exactly matches the desktop, so STYLE_BORDERLESS must be used instead.

(cherry picked from commit 90a023007f)
2025-08-05 15:59:06 -04:00
Mathieu Eyraud 688637eca8 Fix condition for setting HDR properties
(cherry picked from commit a05aca51ec)
2025-08-05 09:26:12 -07:00
Frank Praznik 85d1d70ca1 cocoa: Wait for fullscreen spaces transitions to complete if switching to an exclusive mode
If attempting to switch to an exclusive mode while a fullscreen spaces transition is active, wait until the transition is complete before trying to apply the changes, or the window can wind up in a weird, broken state if a mode switch occurs while in a fullscreen space.

(cherry picked from commit f44a98729c)
2025-08-05 12:17:01 -04:00
Frank Praznik 09356c709a Revert "cocoa: Don't re-enter a fullscreen space if leaving to enter an exclusive mode"
This reverts commit 07b9e86d02.

It turns out that the problem is elsewhere, related to needing to block mode changes until spaces transitions are complete.
2025-08-04 23:51:47 -04:00
Frank Praznik 07b9e86d02 cocoa: Don't re-enter a fullscreen space if leaving to enter an exclusive mode
Doing so can leave the window in a weird, offset state.

(cherry picked from commit ee8f2861e7)
2025-08-04 22:16:22 -04:00
Sam Lantinga 8e46e5d8b4 Updated to version 3.2.21 for development 2025-08-04 11:54:34 -07:00
Sam Lantinga 96292a5b46 Updated to version 3.2.20 for release 2025-08-04 09:58:55 -07:00
Petar Popovic ffa618c00b SDL_LoadWAV_IO(): On error, set *audio_buf to NULL and *audio_len to 0
(cherry picked from commit 23e08f7807)
2025-08-03 13:44:37 -04:00
Petar Popovic 291b9b3c82 SDL_enabled_assert(): Use NULL istead of 0 to explicity initialize the pointer members of SDL_AssertData
(cherry picked from commit faf3bd9991)
2025-08-03 13:36:14 -04:00
Frank Praznik ec45117f0f x11: Filter mouse wheel events from "Master" devices
Discard wheel events from "Master" devices to avoid duplicates, as wheel events are stateless and can't be deduplicated.

(cherry picked from commit 51ce3f8c8d)
2025-08-02 18:57:44 -04:00
Frank Praznik 0d7aff9c56 GPU: Vulkan backend flags command buffer for cleanup when swapchain is requested
When skipping presentation due to the window being hidden, presentDataCount is not incremented on the command buffer, and subsequently the submitted command buffers will not be cleaned up as long as the window is hidden. This results in a lag spike when showing the window due to all previously submitted command buffers suddenly being cleaned up at once, and lag at shutdown due to an equivalent number of fences needing to be destroyed.

Instead of relying on presentDataCount to determine whether a command buffer should be cleaned up, use a flag, which is set under the appropriate circumstances.

(cherry picked from commit 42463569d5)
2025-08-02 09:24:21 -07:00
Petar Popovic d31b239288 Fix double-free warning in src/hidapi/linux/hid.c
(cherry picked from commit ae5ce258cf)
2025-08-02 07:09:12 -07:00
capehill b1cadf0e99 Fix SDL_BlitSurfaceScaled crash
SDL_BlitSurfaceScaled could crash when passed large coordinates, due
to final_dst.w or final_dst.h getting negative values.

(cherry picked from commit 1c5c3b1479)
2025-08-01 09:22:38 -07:00
Frank Praznik c1f67585e6 wayland: Cleanup an outdated conditional and comment
There may have been a reason for not attaching a null buffer when destroying a popup at some point in the past, but that is unnecessary now, as is the comment about ShowWindow crashing, as ShowWindow assures that a null buffer is attached before (re)creating the window.

(cherry picked from commit 550d95e04f)
2025-08-01 10:40:32 -04:00
A1029384756 93988e28c0 wayland: reorder surface destruction to avoid premature blanking
(cherry picked from commit 9034375d2f)
2025-08-01 10:40:32 -04:00
Matthew Zavislak edef6e66e9 Support Google Play 16 KB Page Size Requirement (#13470)
- See: https://developer.android.com/guide/practices/page-sizes#update-packaging
- Also, make min API uniform at 21 (from 16 and 23 in a few places)

(cherry picked from commit dc2c83c383)
2025-07-31 16:21:02 -07:00
Petar Popovic e3f47809c4 Fix potential memory leak in SDL_render_gles2.c
(cherry picked from commit 09221820f6)
2025-07-31 16:19:10 -07:00
cosmonaut f759e7ac59 GPU: Bail out of aquiring Vulkan swapchain if window is hidden
(cherry picked from commit c5edf4bd5b)
2025-07-31 16:03:19 -07:00
Frank Praznik 544eb2c5a9 wayland: Adjust popup adjoining check
The previous calculation could result in a window whose original position was positioned exactly corner-to-corner with the parent not being adjusted to be adjoining, and thus subject to spurious closure.

(cherry picked from commit b0cdb7143f)
2025-07-31 12:13:54 -04:00
Cheney Wang 30e3eba20a GPU: Fix wrong Vulkan swapchain size when retrying acquire
(cherry picked from commit d8ac51859e)
2025-07-30 15:35:23 -07:00
Wouter Wijsman f0e85a2a9c psp: fix audio not playing
(cherry picked from commit 3d1a28ccf2)
2025-07-30 13:11:23 -07:00
Thaddeus Crews 106af5b46a Define relevant macros when LACKS_ERRNO_H is true
(cherry picked from commit 3195980b49)
2025-07-30 09:11:22 -07:00
Stefan Schlosser 522716ed90 SDL_getenv.c: fix dynamic loading of environ symbol on FreeBSD
The current implementation uses the returned address of the `dlsym` function
directly to load the `environ` symbol. But this function doesn't return the
address to the symbol itself, instead it returns the address to the location
where the actual address is stored, i.e. it's an additional indirection.
Consequently, the implementation fails to load and process the environment
variables successfully.

One example where this error shows up is in the `Dialog API`: in an `X11`
environment, the `zenity` driver requires access to the user's `DISPLAY` and
`XAUTHORITY` environment variables. Because these variables aren't transfered
to the `zenity` process, no dialogs are shown. This can be exercised in the
`test/testdialog.c` testprogram.

The fix changes the indirection level of the `dlsym` call from `char **` to
`char ***`, does a `NULL`-check in case the call failed, and returns the
dereferenced actual adress to the `environ` symbol.

(cherry picked from commit 10458f2cac)
2025-07-30 07:06:54 -07:00
Evan Hemsley a65fbb0211 GPU: Fix incorrect block size when D3D12 uniform buffer is rotated (#13469)
(cherry picked from commit 07af4b237b)
2025-07-29 15:51:58 -07:00
Petar Popovic 46ec859bd1 Fix two use-after-free warnings
(cherry picked from commit f27dbb22f0)
2025-07-29 12:29:34 -07:00
Xen 2a7aa4eae4 Update SDL_clipboard.h
Typo fixes and a small addition to SDL_SetClipboardData about mime_type list usage clarity.

(cherry picked from commit b3ba1c159e)
2025-07-28 11:59:34 -07:00
Dan Andrus c31ddf021e Check NSWindow::isVisible before sending SDL_WINDOWEVENT_RESTORED during Cocoa_WindowListener::windowDidResize
(cherry picked from commit 30f0aeb26a)
2025-07-28 14:47:45 -04:00
Shootfast eaa2a8239f Fixed typo in SDL_scancode.h
The backslash/vertical line key is between the left shift and "Z" key on ISO keyboards

(cherry picked from commit 507ee033cc)
2025-07-27 19:58:45 -07:00
Brenton Bostick d313ecb737 Fix warning on Android arm-v7
Building SDL for armeabi-v7a gives this warning:
```
SDL/src/audio/SDL_audiotypecvt.c:541:14: warning: '#pragma FENV_ACCESS' is not supported on this target - ignored [-Wignored-pragmas]
  541 | #pragma STDC FENV_ACCESS ON
```

(cherry picked from commit ed4de7aeed)
2025-07-27 08:16:21 -07:00
Petar Popovic 64b2af0340 SDL_gpu.c: Fixed deref-before-check warning
(cherry picked from commit 6a5af95364)
2025-07-26 12:08:57 -07:00
Anonymous Maarten 58d0702948 ci+n3ds: avoid apt-get package manager
- use Unix Makefiles (with parallelization) CMake generator
- use binutils strings binary from devkitpro

(cherry picked from commit e6d200e51c)
2025-07-26 16:06:36 +02:00
Sam Lantinga 707717e94b Reverted: Added Steam Virtual Gamepad support to the GameInput driver
This version of SDL doesn't support newer GameInput versions required for this feature.
2025-07-24 14:00:20 -07:00
Sam Lantinga a140bba55a Fixed building with GameInput v1.0
(cherry picked from commit e5d57d8ad6)
2025-07-24 10:52:28 -07:00
Sam Lantinga f4ddacacd0 Fixed building with GameInput v1.0
(cherry picked from commit 0ee0fe1572)
2025-07-24 10:43:05 -07:00
Sam Lantinga ebba656bdb Added Steam Virtual Gamepad support to the GameInput driver
(cherry picked from commit 66dad9c21f)
2025-07-24 10:38:02 -07:00
Sam Lantinga b78c61d67a Fixed double SDL_EVENT_GAMEPAD_ADDED for controllers with automatic gamepad mappings
(cherry picked from commit 6babade758)
2025-07-24 10:38:02 -07:00
L zard 4210aa61e1 build_config_windows: define HAVE_STDARG/STDDEF_H outside of
condition.
They are defined in both `#if HAVE_LIBC` and its `#else` anyway.
[sdl-ci-filter msvc-*]

(cherry picked from commit ea995b1694)
2025-07-21 14:45:19 -07:00
L zard d8a345d924 build_config_windows: fix HAVE_VSSCANF defined regardless of MSVC version.
[sdl-ci-filter msvc-*]

(cherry picked from commit a977a11fa6)
2025-07-21 14:45:19 -07:00
Acclution b8dc9767da GPU: Fix Vulkan compute uniform descriptor not being marked as set (#13389)
(cherry picked from commit 8bd29f7ca3)
2025-07-18 15:30:05 -07:00
BurntRanch 1ab01b9367 Clarify SDL_GPUVertexBufferDescription.pitch comment (#13381)
(cherry picked from commit ee6d8f78f4)
2025-07-17 08:55:04 -07:00
Sam Lantinga ee371ff740 Fixed crash if a clipboard event was sent with video uninitialized
This can happen if you're using SDL on Android without using the video subsystem.

(cherry picked from commit 855d28e97a)
2025-07-17 08:48:00 -07:00
Evan Hemsley ef58dd77ca GPU: Clean up properties in SDL_ReleaseGPUTexture (#13378) 2025-07-17 00:23:52 -07:00
Ryan C. Gordon e6a7121904 audio: Binding an SDL_AudioStream will set missing formats.
It _must_ have the format set for the opposite side from the device (so
playback needs the src format set, and recording needs the dst format set),
since the stream gets mangled by the device thread if not. So if it has never
been set (stream created with NULL audiospec), just set it to match the device.
If the stream is just meant to buffer and not convert, this is desired
behavior, even if it didn't also fix a bug.

Binding the audio stream will always set the device side's format, as usual;
this does not need to be set by the caller at all.

Fixes #13363.

(cherry picked from commit f2ae6503c0)
2025-07-15 06:44:12 -04:00
Sam Lantinga a6ed8ab59d Updated to version 3.2.19 for development 2025-07-14 11:44:22 -07:00
Sam Lantinga bd40d0ded1 Removed the Mayflash GameCube adapter from the PS3 controller list
(cherry picked from commit 277f91c317)
2025-07-14 11:30:46 -07:00
103 changed files with 1096 additions and 611 deletions

No files matched your search

+26 -10
View File
@@ -20,7 +20,6 @@ class AppleArch(Enum):
class MsvcArch(Enum): class MsvcArch(Enum):
X86 = "x86" X86 = "x86"
X64 = "x64" X64 = "x64"
Arm32 = "arm"
Arm64 = "arm64" Arm64 = "arm64"
@@ -54,6 +53,7 @@ class SdlPlatform(Enum):
Riscos = "riscos" Riscos = "riscos"
FreeBSD = "freebsd" FreeBSD = "freebsd"
NetBSD = "netbsd" NetBSD = "netbsd"
OpenBSD = "openbsd"
class Msys2Platform(Enum): class Msys2Platform(Enum):
@@ -108,7 +108,6 @@ JOB_SPECS = {
"msvc-x86": JobSpec(name="Windows (MSVC, x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x86", msvc_arch=MsvcArch.X86, msvc_project="VisualC/SDL.sln", ), "msvc-x86": JobSpec(name="Windows (MSVC, x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x86", msvc_arch=MsvcArch.X86, msvc_project="VisualC/SDL.sln", ),
"msvc-clang-x64": JobSpec(name="Windows (MSVC, clang-cl x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x64", msvc_arch=MsvcArch.X64, clang_cl=True, ), "msvc-clang-x64": JobSpec(name="Windows (MSVC, clang-cl x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x64", msvc_arch=MsvcArch.X64, clang_cl=True, ),
"msvc-clang-x86": JobSpec(name="Windows (MSVC, clang-cl x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x86", msvc_arch=MsvcArch.X86, clang_cl=True, ), "msvc-clang-x86": JobSpec(name="Windows (MSVC, clang-cl x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x86", msvc_arch=MsvcArch.X86, clang_cl=True, ),
"msvc-arm32": JobSpec(name="Windows (MSVC, ARM)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm32", msvc_arch=MsvcArch.Arm32, ),
"msvc-arm64": JobSpec(name="Windows (MSVC, ARM64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm64", msvc_arch=MsvcArch.Arm64, ), "msvc-arm64": JobSpec(name="Windows (MSVC, ARM64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm64", msvc_arch=MsvcArch.Arm64, ),
"msvc-gdk-x64": JobSpec(name="GDK (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-GDK", msvc_arch=MsvcArch.X64, msvc_project="VisualC-GDK/SDL.sln", gdk=True, no_cmake=True, ), "msvc-gdk-x64": JobSpec(name="GDK (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-GDK", msvc_arch=MsvcArch.X64, msvc_project="VisualC-GDK/SDL.sln", gdk=True, no_cmake=True, ),
"ubuntu-22.04": JobSpec(name="Ubuntu 22.04", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04", ), "ubuntu-22.04": JobSpec(name="Ubuntu 22.04", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04", ),
@@ -137,6 +136,7 @@ JOB_SPECS = {
"vita-pvr": JobSpec(name="Sony PlayStation Vita (GLES w/ PVR_PSP2)", os=JobOs.UbuntuLatest, platform=SdlPlatform.Vita, artifact="SDL-vita-pvr", container="vitasdk/vitasdk:latest", vita_gles=VitaGLES.Pvr, ), "vita-pvr": JobSpec(name="Sony PlayStation Vita (GLES w/ PVR_PSP2)", os=JobOs.UbuntuLatest, platform=SdlPlatform.Vita, artifact="SDL-vita-pvr", container="vitasdk/vitasdk:latest", vita_gles=VitaGLES.Pvr, ),
"riscos": JobSpec(name="RISC OS", os=JobOs.UbuntuLatest, platform=SdlPlatform.Riscos, artifact="SDL-riscos", container="riscosdotinfo/riscos-gccsdk-4.7:latest", ), "riscos": JobSpec(name="RISC OS", os=JobOs.UbuntuLatest, platform=SdlPlatform.Riscos, artifact="SDL-riscos", container="riscosdotinfo/riscos-gccsdk-4.7:latest", ),
"netbsd": JobSpec(name="NetBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.NetBSD, artifact="SDL-netbsd-x64", ), "netbsd": JobSpec(name="NetBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.NetBSD, artifact="SDL-netbsd-x64", ),
"openbsd": JobSpec(name="OpenBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.OpenBSD, artifact="SDL-openbsd-x64", ),
"freebsd": JobSpec(name="FreeBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.FreeBSD, artifact="SDL-freebsd-x64", ), "freebsd": JobSpec(name="FreeBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.FreeBSD, artifact="SDL-freebsd-x64", ),
} }
@@ -174,6 +174,7 @@ class JobDetails:
brew_packages: list[str] = dataclasses.field(default_factory=list) brew_packages: list[str] = dataclasses.field(default_factory=list)
cmake_toolchain_file: str = "" cmake_toolchain_file: str = ""
cmake_arguments: list[str] = dataclasses.field(default_factory=list) cmake_arguments: list[str] = dataclasses.field(default_factory=list)
cmake_generator: str = "Ninja"
cmake_build_arguments: list[str] = dataclasses.field(default_factory=list) cmake_build_arguments: list[str] = dataclasses.field(default_factory=list)
clang_tidy: bool = True clang_tidy: bool = True
cppflags: list[str] = dataclasses.field(default_factory=list) cppflags: list[str] = dataclasses.field(default_factory=list)
@@ -222,6 +223,7 @@ class JobDetails:
check_sources: bool = False check_sources: bool = False
setup_python: bool = False setup_python: bool = False
pypi_packages: list[str] = dataclasses.field(default_factory=list) pypi_packages: list[str] = dataclasses.field(default_factory=list)
binutils_strings: str = "strings"
def to_workflow(self, enable_artifacts: bool) -> dict[str, str|bool]: def to_workflow(self, enable_artifacts: bool) -> dict[str, str|bool]:
data = { data = {
@@ -255,6 +257,7 @@ class JobDetails:
"cflags": my_shlex_join(self.cppflags + self.cflags), "cflags": my_shlex_join(self.cppflags + self.cflags),
"cxxflags": my_shlex_join(self.cppflags + self.cxxflags), "cxxflags": my_shlex_join(self.cppflags + self.cxxflags),
"ldflags": my_shlex_join(self.ldflags), "ldflags": my_shlex_join(self.ldflags),
"cmake-generator": self.cmake_generator,
"cmake-toolchain-file": self.cmake_toolchain_file, "cmake-toolchain-file": self.cmake_toolchain_file,
"clang-tidy": self.clang_tidy, "clang-tidy": self.clang_tidy,
"cmake-arguments": my_shlex_join(self.cmake_arguments), "cmake-arguments": my_shlex_join(self.cmake_arguments),
@@ -289,6 +292,7 @@ class JobDetails:
"check-sources": self.check_sources, "check-sources": self.check_sources,
"setup-python": self.setup_python, "setup-python": self.setup_python,
"pypi-packages": my_shlex_join(self.pypi_packages), "pypi-packages": my_shlex_join(self.pypi_packages),
"binutils-strings": self.binutils_strings,
} }
return {k: v for k, v in data.items() if v != ""} return {k: v for k, v in data.items() if v != ""}
@@ -403,10 +407,6 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.msvc_vcvars_arch = "x64_x86" job.msvc_vcvars_arch = "x64_x86"
case MsvcArch.X64: case MsvcArch.X64:
job.msvc_vcvars_arch = "x64" job.msvc_vcvars_arch = "x64"
case MsvcArch.Arm32:
job.msvc_vcvars_arch = "x64_arm"
job.msvc_vcvars_sdk = "10.0.22621.0" # 10.0.26100.0 dropped ARM32 um and ucrt libraries
job.run_tests = False
case MsvcArch.Arm64: case MsvcArch.Arm64:
job.msvc_vcvars_arch = "x64_arm64" job.msvc_vcvars_arch = "x64_arm64"
job.run_tests = False job.run_tests = False
@@ -512,11 +512,14 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.shared_lib = SharedLibType.DYLIB job.shared_lib = SharedLibType.DYLIB
job.static_lib = StaticLibType.A job.static_lib = StaticLibType.A
job.ccache = True job.ccache = True
if spec.os == JobOs.Macos13:
job.ccache = False
job.apt_packages = [] job.apt_packages = []
job.brew_packages.extend(( job.brew_packages.extend((
"ccache",
"ninja", "ninja",
)) ))
if job.ccache:
job.brew_packages.append("ccache")
if job.clang_tidy: if job.clang_tidy:
job.brew_packages.append("llvm") job.brew_packages.append("llvm")
if spec.xcode: if spec.xcode:
@@ -550,6 +553,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
"testmultiaudio-apk", "testmultiaudio-apk",
"testsprite-apk", "testsprite-apk",
] ]
# -fPIC is required after updating NDK from 21 to 28
job.cflags.append("-fPIC")
job.cxxflags.append("-fPIC")
case SdlPlatform.Emscripten: case SdlPlatform.Emscripten:
job.clang_tidy = False # clang-tidy does not understand -gsource-map job.clang_tidy = False # clang-tidy does not understand -gsource-map
job.shared = False job.shared = False
@@ -675,13 +682,16 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.shared_lib = SharedLibType.SO_0 job.shared_lib = SharedLibType.SO_0
job.static_lib = StaticLibType.A job.static_lib = StaticLibType.A
case SdlPlatform.N3ds: case SdlPlatform.N3ds:
job.ccache = True job.cmake_generator = "Unix Makefiles"
job.cmake_build_arguments.append("-j$(nproc)")
job.ccache = False
job.shared = False job.shared = False
job.apt_packages = ["ccache", "ninja-build", "binutils"] job.apt_packages = []
job.clang_tidy = False job.clang_tidy = False
job.run_tests = False job.run_tests = False
job.cc_from_cmake = True job.cc_from_cmake = True
job.cmake_toolchain_file = "${DEVKITPRO}/cmake/3DS.cmake" job.cmake_toolchain_file = "${DEVKITPRO}/cmake/3DS.cmake"
job.binutils_strings = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-strings"
job.static_lib = StaticLibType.A job.static_lib = StaticLibType.A
case SdlPlatform.Msys2: case SdlPlatform.Msys2:
job.ccache = True job.ccache = True
@@ -713,7 +723,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
)) ))
job.cmake_toolchain_file = "/home/riscos/env/toolchain-riscos.cmake" job.cmake_toolchain_file = "/home/riscos/env/toolchain-riscos.cmake"
job.static_lib = StaticLibType.A job.static_lib = StaticLibType.A
case SdlPlatform.FreeBSD | SdlPlatform.NetBSD: case SdlPlatform.FreeBSD | SdlPlatform.NetBSD | SdlPlatform.OpenBSD:
job.cpactions = True job.cpactions = True
job.no_cmake = True job.no_cmake = True
job.run_tests = False job.run_tests = False
@@ -737,6 +747,12 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.cpactions_arch = "x86-64" job.cpactions_arch = "x86-64"
job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update" job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update"
job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1" job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
case SdlPlatform.OpenBSD:
job.cpactions_os = "openbsd"
job.cpactions_version = "7.4"
job.cpactions_arch = "x86-64"
job.cpactions_setup_cmd = "sudo pkg_add -u"
job.cpactions_install_cmd = "sudo pkg_add cmake ninja pkgconf wayland wayland-protocols xwayland libxkbcommon libinotify pulseaudio dbus ibus"
case _: case _:
raise ValueError(f"Unsupported platform={spec.platform}") raise ValueError(f"Unsupported platform={spec.platform}")
+13 -5
View File
@@ -76,7 +76,7 @@ jobs:
id: setup-ndk id: setup-ndk
with: with:
local-cache: true local-cache: true
ndk-version: r21e ndk-version: r28c
- name: 'Configure Android NDK variables' - name: 'Configure Android NDK variables'
if: ${{ matrix.platform.android-ndk }} if: ${{ matrix.platform.android-ndk }}
shell: sh shell: sh
@@ -201,7 +201,7 @@ jobs:
#shell: ${{ matrix.platform.shell }} #shell: ${{ matrix.platform.shell }}
run: | run: |
${{ matrix.platform.source-cmd }} ${{ matrix.platform.source-cmd }}
${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -GNinja \ ${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -G "${{ matrix.platform.cmake-generator }}" \
-Wdeprecated -Wdev -Werror \ -Wdeprecated -Wdev -Werror \
${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \ ${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \
-DSDL_WERROR=${{ matrix.platform.werror }} \ -DSDL_WERROR=${{ matrix.platform.werror }} \
@@ -232,9 +232,9 @@ jobs:
run: | run: |
echo "This should show us the SDL_REVISION" echo "This should show us the SDL_REVISION"
echo "Shared library:" echo "Shared library:"
${{ (matrix.platform.shared-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }} ${{ (matrix.platform.shared-lib && format('{0} build/{1} | grep "Github Workflow"', matrix.platform.binutils-strings, matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }}
echo "Static library:" echo "Static library:"
${{ (matrix.platform.static-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }} ${{ (matrix.platform.static-lib && format('{0} build/{1} | grep "Github Workflow"', matrix.platform.binutils-strings, matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }}
- name: 'Run build-time tests (CMake)' - name: 'Run build-time tests (CMake)'
id: tests id: tests
if: ${{ !matrix.platform.no-cmake && matrix.platform.run-tests }} if: ${{ !matrix.platform.no-cmake && matrix.platform.run-tests }}
@@ -406,6 +406,14 @@ jobs:
build-scripts/test-versioning.sh build-scripts/test-versioning.sh
python build-scripts/check_android_jni.py python build-scripts/check_android_jni.py
python build-scripts/check_stdlib_usage.py python build-scripts/check_stdlib_usage.py
- name: 'Verify alignment of Android test apks'
if: ${{ matrix.platform.android-ndk && !matrix.platform.no-cmake }}
run: |
find ./ -iname '*.apk' | xargs -L1 ./build-scripts/check_elf_alignment.sh
- name: 'Verify alignment of Android .so files'
if: ${{ matrix.platform.android-ndk && !matrix.platform.no-cmake }}
run: |
find ./ -iname '*.so' | xargs -L1 ./build-scripts/check_elf_alignment.sh
- name: 'Upload binary package' - name: 'Upload binary package'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: ${{ always() && matrix.platform.artifact != '' && (steps.package.outcome == 'success' || steps.cpactions.outcome == 'success') && (matrix.platform.enable-artifacts || steps.tests.outcome == 'failure') }} if: ${{ always() && matrix.platform.artifact != '' && (steps.package.outcome == 'success' || steps.cpactions.outcome == 'success') && (matrix.platform.enable-artifacts || steps.tests.outcome == 'failure') }}
@@ -428,4 +436,4 @@ jobs:
with: with:
if-no-files-found: error if-no-files-found: error
name: '${{ matrix.platform.artifact }}-apks' name: '${{ matrix.platform.artifact }}-apks'
path: build/test/*.apk path: build/test/*.apk
+1 -1
View File
@@ -535,7 +535,7 @@ jobs:
uses: nttld/setup-ndk@v1 uses: nttld/setup-ndk@v1
with: with:
local-cache: true local-cache: true
ndk-version: r21e ndk-version: r28c
- name: 'Setup Java JDK' - name: 'Setup Java JDK'
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
+71 -67
View File
@@ -5,7 +5,7 @@ if(NOT DEFINED CMAKE_BUILD_TYPE)
endif() endif()
# See docs/release_checklist.md # See docs/release_checklist.md
project(SDL3 LANGUAGES C VERSION "3.2.18") project(SDL3 LANGUAGES C VERSION "3.2.24")
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(SDL3_MAINPROJECT ON) set(SDL3_MAINPROJECT ON)
@@ -79,6 +79,12 @@ include("${SDL3_SOURCE_DIR}/cmake/PreseedEmscriptenCache.cmake")
SDL_DetectCompiler() SDL_DetectCompiler()
SDL_DetectTargetCPUArchitectures(SDL_CPUS) SDL_DetectTargetCPUArchitectures(SDL_CPUS)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
list(LENGTH CMAKE_OSX_ARCHITECTURES _num_arches)
if(_num_arches GREATER 1)
set(APPLE_MULTIARCH TRUE)
endif()
endif()
# Increment this if there is an incompatible change - but if that happens, # Increment this if there is an incompatible change - but if that happens,
# we should rename the library from SDL3 to SDL4, at which point this would # we should rename the library from SDL3 to SDL4, at which point this would
@@ -183,29 +189,6 @@ if(MSVC)
set(SDL_RELOCATABLE_DEFAULT ON) set(SDL_RELOCATABLE_DEFAULT ON)
endif() endif()
if(MSVC)
if(NOT SDL_LIBC)
# Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
set(CMAKE_MSVC_RUNTIME_CHECKS "")
endif()
if(MSVC_CLANG)
# clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
endif()
endif()
set(SDL_SHARED_DEFAULT ON) set(SDL_SHARED_DEFAULT ON)
set(SDL_STATIC_DEFAULT ON) set(SDL_STATIC_DEFAULT ON)
@@ -373,7 +356,7 @@ dep_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ON "WIN
dep_option(SDL_RENDER_D3D "Enable the Direct3D 9 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF) dep_option(SDL_RENDER_D3D "Enable the Direct3D 9 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
dep_option(SDL_RENDER_D3D11 "Enable the Direct3D 11 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF) dep_option(SDL_RENDER_D3D11 "Enable the Direct3D 11 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF) dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;${APPLE}" OFF) dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;APPLE" OFF)
dep_option(SDL_RENDER_GPU "Enable the SDL_GPU render driver" ON "SDL_RENDER;SDL_GPU" OFF) dep_option(SDL_RENDER_GPU "Enable the SDL_GPU render driver" ON "SDL_RENDER;SDL_GPU" OFF)
dep_option(SDL_VIVANTE "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF) dep_option(SDL_VIVANTE "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF)
dep_option(SDL_VULKAN "Enable Vulkan support" ON "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR WINDOWS" OFF) dep_option(SDL_VULKAN "Enable Vulkan support" ON "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR WINDOWS" OFF)
@@ -424,6 +407,29 @@ if(SDL_PRESEED)
SDL_Preseed_CMakeCache() SDL_Preseed_CMakeCache()
endif() endif()
if(MSVC)
if(NOT SDL_LIBC)
# Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
set(CMAKE_MSVC_RUNTIME_CHECKS "")
endif()
if(MSVC_CLANG)
# clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
endif()
endif()
if(SDL_SHARED) if(SDL_SHARED)
add_library(SDL3-shared SHARED) add_library(SDL3-shared SHARED)
add_library(SDL3::SDL3-shared ALIAS SDL3-shared) add_library(SDL3::SDL3-shared ALIAS SDL3-shared)
@@ -658,7 +664,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -mmmx") string(APPEND CMAKE_REQUIRED_FLAGS " -mmmx")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <mmintrin.h> #include <mmintrin.h>
void ints_add(int *dest, int *a, int *b, unsigned size) { void ints_add(int *dest, int *a, int *b, unsigned size) {
for (; size >= 2; size -= 2, dest += 2, a += 2, b += 2) { for (; size >= 2; size -= 2, dest += 2, a += 2, b += 2) {
@@ -668,7 +674,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
ints_add((int*)0, (int*)0, (int*)0, 0); ints_add((int*)0, (int*)0, (int*)0, 0);
return 0; return 0;
}" COMPILER_SUPPORTS_MMX) }]==] COMPILER_SUPPORTS_MMX)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_MMX) if(COMPILER_SUPPORTS_MMX)
set(HAVE_MMX TRUE) set(HAVE_MMX TRUE)
@@ -679,7 +685,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse") string(APPEND CMAKE_REQUIRED_FLAGS " -msse")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <xmmintrin.h> #include <xmmintrin.h>
void floats_add(float *dest, float *a, float *b, unsigned size) { void floats_add(float *dest, float *a, float *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) { for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -689,7 +695,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) { int main(int argc, char **argv) {
floats_add((float*)0, (float*)0, (float*)0, 0); floats_add((float*)0, (float*)0, (float*)0, 0);
return 0; return 0;
}" COMPILER_SUPPORTS_SSE) }]==] COMPILER_SUPPORTS_SSE)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE) if(COMPILER_SUPPORTS_SSE)
set(HAVE_SSE TRUE) set(HAVE_SSE TRUE)
@@ -700,7 +706,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse2") string(APPEND CMAKE_REQUIRED_FLAGS " -msse2")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <emmintrin.h> #include <emmintrin.h>
void doubles_add(double *dest, double *a, double *b, unsigned size) { void doubles_add(double *dest, double *a, double *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) { for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -710,7 +716,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) { int main(int argc, char **argv) {
doubles_add((double*)0, (double*)0, (double*)0, 0); doubles_add((double*)0, (double*)0, (double*)0, 0);
return 0; return 0;
}" COMPILER_SUPPORTS_SSE2) }]==] COMPILER_SUPPORTS_SSE2)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE2) if(COMPILER_SUPPORTS_SSE2)
set(HAVE_SSE2 TRUE) set(HAVE_SSE2 TRUE)
@@ -721,7 +727,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse3") string(APPEND CMAKE_REQUIRED_FLAGS " -msse3")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <pmmintrin.h> #include <pmmintrin.h>
void ints_add(int *dest, int *a, int *b, unsigned size) { void ints_add(int *dest, int *a, int *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) { for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -731,7 +737,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) { int main(int argc, char **argv) {
ints_add((int*)0, (int*)0, (int*)0, 0); ints_add((int*)0, (int*)0, (int*)0, 0);
return 0; return 0;
}" COMPILER_SUPPORTS_SSE3) }]==] COMPILER_SUPPORTS_SSE3)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE3) if(COMPILER_SUPPORTS_SSE3)
set(HAVE_SSE3 TRUE) set(HAVE_SSE3 TRUE)
@@ -742,7 +748,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.1") string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.1")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <smmintrin.h> #include <smmintrin.h>
void ints_mul(int *dest, int *a, int *b, unsigned size) { void ints_mul(int *dest, int *a, int *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) { for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
@@ -752,7 +758,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) { int main(int argc, char **argv) {
ints_mul((int*)0, (int*)0, (int*)0, 0); ints_mul((int*)0, (int*)0, (int*)0, 0);
return 0; return 0;
}" COMPILER_SUPPORTS_SSE4_1) }]==] COMPILER_SUPPORTS_SSE4_1)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE4_1) if(COMPILER_SUPPORTS_SSE4_1)
set(HAVE_SSE4_1 TRUE) set(HAVE_SSE4_1 TRUE)
@@ -761,21 +767,16 @@ if(SDL_ASSEMBLY)
if(SDL_SSE4_2) if(SDL_SSE4_2)
cmake_push_check_state() cmake_push_check_state()
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.2 -mcrc32") string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.2")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <nmmintrin.h> #include <nmmintrin.h>
unsigned calc_crc32c(const char *text, unsigned len) { __m128i bitmask;
unsigned crc32c = ~0; char data[16];
for (; len >= 4; len -= 4, text += 4) {
crc32c = (unsigned)_mm_crc32_u32(crc32c, *(unsigned*)text);
}
return crc32c;
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
calc_crc32c(\"SDL_SSE4\",8); bitmask = _mm_cmpgt_epi64(_mm_set1_epi64x(0), _mm_loadu_si128((void*)data));
return 0; return 0;
}" COMPILER_SUPPORTS_SSE4_2) }]==] COMPILER_SUPPORTS_SSE4_2)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_SSE4_2) if(COMPILER_SUPPORTS_SSE4_2)
set(HAVE_SSE4_2 TRUE) set(HAVE_SSE4_2 TRUE)
@@ -786,7 +787,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx") string(APPEND CMAKE_REQUIRED_FLAGS " -mavx")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <immintrin.h> #include <immintrin.h>
void floats_add(float *dest, float *a, float *b, unsigned size) { void floats_add(float *dest, float *a, float *b, unsigned size) {
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) { for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
@@ -796,7 +797,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) { int main(int argc, char **argv) {
floats_add((float*)0, (float*)0, (float*)0, 0); floats_add((float*)0, (float*)0, (float*)0, 0);
return 0; return 0;
}" COMPILER_SUPPORTS_AVX) }]==] COMPILER_SUPPORTS_AVX)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_AVX) if(COMPILER_SUPPORTS_AVX)
set(HAVE_AVX TRUE) set(HAVE_AVX TRUE)
@@ -807,7 +808,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx2") string(APPEND CMAKE_REQUIRED_FLAGS " -mavx2")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <immintrin.h> #include <immintrin.h>
void ints_add(int *dest, int *a, int *b, unsigned size) { void ints_add(int *dest, int *a, int *b, unsigned size) {
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) { for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
@@ -817,7 +818,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) { int main(int argc, char **argv) {
ints_add((int*)0, (int*)0, (int*)0, 0); ints_add((int*)0, (int*)0, (int*)0, 0);
return 0; return 0;
}" COMPILER_SUPPORTS_AVX2) }]==] COMPILER_SUPPORTS_AVX2)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_AVX2) if(COMPILER_SUPPORTS_AVX2)
set(HAVE_AVX2 TRUE) set(HAVE_AVX2 TRUE)
@@ -828,7 +829,7 @@ if(SDL_ASSEMBLY)
if(USE_GCC OR USE_CLANG OR USE_INTELCC) if(USE_GCC OR USE_CLANG OR USE_INTELCC)
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx512f") string(APPEND CMAKE_REQUIRED_FLAGS " -mavx512f")
endif() endif()
check_c_source_compiles(" check_x86_source_compiles([==[
#include <immintrin.h> #include <immintrin.h>
void floats_add(float *dest, float *a, float *b, unsigned size) { void floats_add(float *dest, float *a, float *b, unsigned size) {
for (; size >= 16; size -= 16, dest += 16, a += 16, b += 16) { for (; size >= 16; size -= 16, dest += 16, a += 16, b += 16) {
@@ -838,7 +839,7 @@ if(SDL_ASSEMBLY)
int main(int argc, char **argv) { int main(int argc, char **argv) {
floats_add((float*)0, (float*)0, (float*)0, 0); floats_add((float*)0, (float*)0, (float*)0, 0);
return 0; return 0;
}" COMPILER_SUPPORTS_AVX512F) }]==] COMPILER_SUPPORTS_AVX512F)
cmake_pop_check_state() cmake_pop_check_state()
if(COMPILER_SUPPORTS_AVX512F) if(COMPILER_SUPPORTS_AVX512F)
set(HAVE_AVX512F TRUE) set(HAVE_AVX512F TRUE)
@@ -846,18 +847,17 @@ if(SDL_ASSEMBLY)
endif() endif()
if(SDL_ARMNEON) if(SDL_ARMNEON)
check_c_source_compiles(" check_arm_source_compiles([==[
#include <arm_neon.h> #include <arm_neon.h>
void floats_add(float *dest, float *a, float *b, unsigned size) { void floats_add(float *dest, float *a, float *b, unsigned size) {
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) { for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b))); vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b)));
}
} }
int main(int argc, char *argv[]) { }
floats_add((float*)0, (float*)0, (float*)0, 0); int main(int argc, char *argv[]) {
return 0; floats_add((float*)0, (float*)0, (float*)0, 0);
}" COMPILER_SUPPORTS_ARMNEON) return 0;
}]==] COMPILER_SUPPORTS_ARMNEON)
if(COMPILER_SUPPORTS_ARMNEON) if(COMPILER_SUPPORTS_ARMNEON)
set(HAVE_ARMNEON TRUE) set(HAVE_ARMNEON TRUE)
endif() endif()
@@ -1060,8 +1060,10 @@ if(SDL_LIBC)
cmake_push_check_state() cmake_push_check_state()
if(MSVC) if(MSVC)
string(APPEND CMAKE_REQUIRED_FLAGS " -we4244 -WX") # 'conversion' conversion from 'type1' to 'type2', possible loss of data string(APPEND CMAKE_REQUIRED_FLAGS " -we4244 -WX") # 'conversion' conversion from 'type1' to 'type2', possible loss of data
else() elseif(HAVE_GCC_WFLOAT_CONVERSION)
string(APPEND CMAKE_REQUIRED_FLAGS " -Wfloat-conversion -Werror") string(APPEND CMAKE_REQUIRED_FLAGS " -Wfloat-conversion -Werror")
else()
string(APPEND CMAKE_REQUIRED_FLAGS " -Wconversion -Werror")
endif() endif()
foreach(math_fn isinf isnan) foreach(math_fn isinf isnan)
string(TOUPPER "${math_fn}" MATH_FN) string(TOUPPER "${math_fn}" MATH_FN)
@@ -1099,6 +1101,7 @@ if(SDL_LIBC)
check_symbol_exists(gethostname "unistd.h" HAVE_GETHOSTNAME) check_symbol_exists(gethostname "unistd.h" HAVE_GETHOSTNAME)
check_symbol_exists(getpagesize "unistd.h" HAVE_GETPAGESIZE) check_symbol_exists(getpagesize "unistd.h" HAVE_GETPAGESIZE)
check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION) check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
check_symbol_exists(sigtimedwait "signal.h" HAVE_SIGTIMEDWAIT)
check_symbol_exists(setjmp "setjmp.h" HAVE_SETJMP) check_symbol_exists(setjmp "setjmp.h" HAVE_SETJMP)
check_symbol_exists(nanosleep "time.h" HAVE_NANOSLEEP) check_symbol_exists(nanosleep "time.h" HAVE_NANOSLEEP)
check_symbol_exists(gmtime_r "time.h" HAVE_GMTIME_R) check_symbol_exists(gmtime_r "time.h" HAVE_GMTIME_R)
@@ -2960,7 +2963,7 @@ if(WINDOWS)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/process/windows/*.c") sdl_glob_sources("${SDL3_SOURCE_DIR}/src/process/windows/*.c")
set(SDL_PROCESS_WINDOWS 1) set(SDL_PROCESS_WINDOWS 1)
set(HAVE_SDL_PROCESS TRUE) set(HAVE_SDL_PROCESS TRUE)
else() elseif(NOT ANDROID)
check_c_source_compiles(" check_c_source_compiles("
#include <spawn.h> #include <spawn.h>
#include <unistd.h> #include <unistd.h>
@@ -3150,14 +3153,15 @@ endforeach()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt")
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt" revisions) file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt" revisions)
list(GET revisions 0 revisions_0) list(GET revisions 0 revisions_0)
string(STRIP "${revisions_0}" SDL_REVISION) string(STRIP "${revisions_0}" revisions_0_stripped)
set(SDL_REVISION "SDL-${revisions_0_stripped}")
else() else()
set(SDL_REVISION "" CACHE STRING "Custom SDL revision (only used when REVISION.txt does not exist)") set(SDL_REVISION "" CACHE STRING "Custom SDL revision (only used when REVISION.txt does not exist)")
endif() endif()
if(NOT SDL_REVISION) if(NOT SDL_REVISION)
# If SDL_REVISION is not overrided, use git to describe # If SDL_REVISION is not overrided, use git to describe
git_describe(SDL_REVISION_GIT) git_describe(SDL_REVISION_GIT)
set(SDL_REVISION "SDL3-${SDL3_VERSION}-${SDL_REVISION_GIT}") set(SDL_REVISION "SDL-${SDL3_VERSION}-${SDL_REVISION_GIT}")
endif() endif()
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${SDL3_BINARY_DIR}/include-revision/SDL3") execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${SDL3_BINARY_DIR}/include-revision/SDL3")
+2 -2
View File
@@ -19,10 +19,10 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>3.2.18</string> <string>3.2.24</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>SDLX</string> <string>SDLX</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>3.2.18</string> <string>3.2.24</string>
</dict> </dict>
</plist> </plist>
+4 -4
View File
@@ -3086,7 +3086,7 @@
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
DEPLOYMENT_POSTPROCESSING = YES; DEPLOYMENT_POSTPROCESSING = YES;
DYLIB_COMPATIBILITY_VERSION = 201.0.0; DYLIB_COMPATIBILITY_VERSION = 201.0.0;
DYLIB_CURRENT_VERSION = 201.18.0; DYLIB_CURRENT_VERSION = 201.24.0;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ALTIVEC_EXTENSIONS = YES; GCC_ALTIVEC_EXTENSIONS = YES;
@@ -3121,7 +3121,7 @@
"@loader_path/Frameworks", "@loader_path/Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 10.13; MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 3.2.18; MARKETING_VERSION = 3.2.24;
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
PRODUCT_NAME = SDL3; PRODUCT_NAME = SDL3;
@@ -3150,7 +3150,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
DYLIB_COMPATIBILITY_VERSION = 201.0.0; DYLIB_COMPATIBILITY_VERSION = 201.0.0;
DYLIB_CURRENT_VERSION = 201.18.0; DYLIB_CURRENT_VERSION = 201.24.0;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
@@ -3182,7 +3182,7 @@
"@loader_path/Frameworks", "@loader_path/Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 10.13; MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 3.2.18; MARKETING_VERSION = 3.2.24;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
+1 -1
View File
@@ -1,4 +1,4 @@
Title SDL 3.2.18 Title SDL 3.2.24
Version 1 Version 1
Description SDL Library for macOS (http://www.libsdl.org) Description SDL Library for macOS (http://www.libsdl.org)
DefaultLocation /Library/Frameworks DefaultLocation /Library/Frameworks
+1 -1
View File
@@ -7,4 +7,4 @@
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
# Min runtime API level # Min runtime API level
APP_PLATFORM=android-16 APP_PLATFORM=android-21
@@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL"; private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 3; private static final int SDL_MAJOR_VERSION = 3;
private static final int SDL_MINOR_VERSION = 2; private static final int SDL_MINOR_VERSION = 2;
private static final int SDL_MICRO_VERSION = 18; private static final int SDL_MICRO_VERSION = 24;
/* /*
// Display InputType.SOURCE/CLASS of events and devices // Display InputType.SOURCE/CLASS of events and devices
// //
@@ -2196,7 +2196,11 @@ class SDLClipboardHandler implements
} }
public boolean clipboardHasText() { public boolean clipboardHasText() {
return mClipMgr.hasPrimaryClip(); if (Build.VERSION.SDK_INT >= 28 /* Android 9 (P) */) {
return mClipMgr.hasPrimaryClip();
} else {
return mClipMgr.hasText();
}
} }
public String clipboardGetText() { public String clipboardGetText() {
@@ -2214,10 +2218,19 @@ class SDLClipboardHandler implements
} }
public void clipboardSetText(String string) { public void clipboardSetText(String string) {
mClipMgr.removePrimaryClipChangedListener(this); mClipMgr.removePrimaryClipChangedListener(this);
ClipData clip = ClipData.newPlainText(null, string); if (string.isEmpty()) {
mClipMgr.setPrimaryClip(clip); if (Build.VERSION.SDK_INT >= 28 /* Android 9 (P) */) {
mClipMgr.addPrimaryClipChangedListener(this); mClipMgr.clearPrimaryClip();
} else {
ClipData clip = ClipData.newPlainText(null, "");
mClipMgr.setPrimaryClip(clip);
}
} else {
ClipData clip = ClipData.newPlainText(null, string);
mClipMgr.setPrimaryClip(clip);
}
mClipMgr.addPrimaryClipChangedListener(this);
} }
@Override @Override
+8 -3
View File
@@ -542,6 +542,7 @@ class AndroidApiVersion:
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>" return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>"
ANDROID_ABI_EXTRA_LINK_OPTIONS = {}
class Releaser: class Releaser:
def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool): def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool):
@@ -1013,6 +1014,7 @@ class Releaser:
android_devel_file_tree = ArchiveFileTree() android_devel_file_tree = ArchiveFileTree()
for android_abi in android_abis: for android_abi in android_abis:
extra_link_options = ANDROID_ABI_EXTRA_LINK_OPTIONS.get(android_abi, "")
with self.section_printer.group(f"Building for Android {android_api} {android_abi}"): with self.section_printer.group(f"Building for Android {android_api} {android_abi}"):
build_dir = self.root / "build-android" / f"{android_abi}-build" build_dir = self.root / "build-android" / f"{android_abi}-build"
install_dir = self.root / "install-android" / f"{android_abi}-install" install_dir = self.root / "install-android" / f"{android_abi}-install"
@@ -1023,8 +1025,11 @@ class Releaser:
"cmake", "cmake",
"-S", str(self.root), "-S", str(self.root),
"-B", str(build_dir), "-B", str(build_dir),
f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', # NDK 21e does not support -ffile-prefix-map
f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', # f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
# f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
f"-DCMAKE_EXE_LINKER_FLAGS={extra_link_options}",
f"-DCMAKE_SHARED_LINKER_FLAGS={extra_link_options}",
f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}", f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}", f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH", f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
@@ -1530,7 +1535,7 @@ def main(argv=None) -> int:
parser.error("Invalid --android-api, and/or could not be detected") parser.error("Invalid --android-api, and/or could not be detected")
android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}" android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}"
if not android_api_path.is_dir(): if not android_api_path.is_dir():
parser.error(f"Android API directory does not exist ({android_api_path})") logger.warning(f"Android API directory does not exist ({android_api_path})")
with section_printer.group("Android arguments"): with section_printer.group("Android arguments"):
print(f"android_home = {args.android_home}") print(f"android_home = {args.android_home}")
print(f"android_ndk_home = {args.android_ndk_home}") print(f"android_ndk_home = {args.android_ndk_home}")
+127
View File
@@ -0,0 +1,127 @@
#!/bin/bash
progname="${0##*/}"
progname="${progname%.sh}"
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
cleanup_trap() {
if [ -n "${tmp}" -a -d "${tmp}" ]; then
rm -rf ${tmp}
fi
exit $1
}
usage() {
echo "Host side script to check the ELF alignment of shared libraries."
echo "Shared libraries are reported ALIGNED when their ELF regions are"
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
echo
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
}
if [ ${#} -ne 1 ]; then
usage
exit
fi
case ${1} in
--help | -h | -\?)
usage
exit
;;
*)
dir="${1}"
;;
esac
if ! [ -f "${dir}" -o -d "${dir}" ]; then
echo "Invalid file: ${dir}" >&2
exit 1
fi
if [[ "${dir}" == *.apk ]]; then
trap 'cleanup_trap' EXIT
echo
echo "Recursively analyzing $dir"
echo
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
echo "=== APK zip-alignment ==="
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
echo "========================="
else
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
echo " You can install the latest build-tools by running the below command"
echo " and updating your \$PATH:"
echo
echo " sdkmanager \"build-tools;35.0.0-rc3\""
fi
dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
dir="${tmp}"
fi
if [[ "${dir}" == *.apex ]]; then
trap 'cleanup_trap' EXIT
echo
echo "Recursively analyzing $dir"
echo
dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
dir="${tmp}"
fi
RED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"
unaligned_libs=()
unaligned_critical_libs=()
echo
echo "=== ELF alignment ==="
matches="$(find "${dir}" -type f)"
IFS=$'\n'
for match in $matches; do
# We could recursively call this script or rewrite it to though.
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
[[ $(file "${match}") == *"ELF"* ]] || continue
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
else
unaligned_libs+=("${match}")
# Check if this is a critical architecture (arm64-v8a or x86_64)
if [[ "${match}" == *"arm64-v8a"* ]] || [[ "${match}" == *"x86_64"* ]]; then
unaligned_critical_libs+=("${match}")
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
else
echo -e "${match}: UNALIGNED ($res)"
fi
fi
done
if [ ${#unaligned_libs[@]} -gt 0 ]; then
echo -e "Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
fi
echo "====================="
# Exit with appropriate code: 1 if critical unaligned libs found, 0 otherwise
if [ ${#unaligned_critical_libs[@]} -gt 0 ]; then
echo -e "${RED}Found ${#unaligned_critical_libs[@]} critical unaligned libs.${ENDCOLOR}"
exit 1
else
echo -e "${GREEN}ELF Verification Successful${ENDCOLOR}"
exit 0
fi
+1 -1
View File
@@ -183,7 +183,7 @@
], ],
"api-minimum": 21, "api-minimum": 21,
"api-target": 35, "api-target": 35,
"ndk-minimum": 21, "ndk-minimum": 28,
"aar-files": { "aar-files": {
"": [ "": [
"android-project/app/proguard-rules.pro:proguard.txt", "android-project/app/proguard-rules.pro:proguard.txt",
-21
View File
@@ -1,21 +0,0 @@
#!/bin/sh
#
# libtool assumes that the compiler can handle the -fPIC flag
# This isn't always true (for example, nasm can't handle it)
command=""
while [ $# -gt 0 ]; do
case "$1" in
-?PIC)
# Ignore -fPIC and -DPIC options
;;
-fno-common)
# Ignore -fPIC and -DPIC options
;;
*)
command="$command $1"
;;
esac
shift
done
echo $command
exec $command
+60
View File
@@ -160,3 +160,63 @@ function(SDL_AddCommonCompilerFlags TARGET)
endif() endif()
endif() endif()
endfunction() endfunction()
function(check_x86_source_compiles BODY VAR)
if(ARGN)
message(FATAL_ERROR "Unknown arguments: ${ARGN}")
endif()
if(APPLE_MULTIARCH AND (SDL_CPU_X86 OR SDL_CPU_X64))
set(test_conditional 1)
else()
set(test_conditional 0)
endif()
check_c_source_compiles("
#if ${test_conditional}
# if defined(__i386__) || defined(__x86_64__)
# define test_enabled 1
# else
# define test_enabled 0 /* feign success in Apple multi-arch configs */
# endif
#else /* test normally */
# define test_enabled 1
#endif
#if test_enabled
${BODY}
#else
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
return 0;
}
#endif" ${VAR})
endfunction()
function(check_arm_source_compiles BODY VAR)
if(ARGN)
message(FATAL_ERROR "Unknown arguments: ${ARGN}")
endif()
if(APPLE_MULTIARCH AND (SDL_CPU_ARM32 OR SDL_CPU_ARM64))
set(test_conditional 1)
else()
set(test_conditional 0)
endif()
check_c_source_compiles("
#if ${test_conditional}
# if defined(__arm__) || defined(__aarch64__)
# define test_enabled 1
# else
# define test_enabled 0 /* feign success in Apple multi-arch configs */
# endif
#else /* test normally */
# define test_enabled 1
#endif
#if test_enabled
${BODY}
#else
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
return 0;
}
#endif" ${VAR})
endfunction()
+3 -3
View File
@@ -4,15 +4,15 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS)
if(APPLE AND CMAKE_OSX_ARCHITECTURES) if(APPLE AND CMAKE_OSX_ARCHITECTURES)
foreach(known_arch IN LISTS known_archs) foreach(known_arch IN LISTS known_archs)
set(SDL_CPU_${known_arch} "0") set(SDL_CPU_${known_arch} "0" PARENT_SCOPE)
endforeach() endforeach()
set(detected_archs) set(detected_archs)
foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES) foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES)
if(osx_arch STREQUAL "x86_64") if(osx_arch STREQUAL "x86_64")
set(SDL_CPU_X64 "1") set(SDL_CPU_X64 "1" PARENT_SCOPE)
list(APPEND detected_archs "X64") list(APPEND detected_archs "X64")
elseif(osx_arch STREQUAL "arm64") elseif(osx_arch STREQUAL "arm64")
set(SDL_CPU_ARM64 "1") set(SDL_CPU_ARM64 "1" PARENT_SCOPE)
list(APPEND detected_archs "ARM64") list(APPEND detected_archs "ARM64")
endif() endif()
endforeach() endforeach()
+1 -1
View File
@@ -20,7 +20,7 @@
*/ */
/** /**
* Main include header for the SDL library, version 3.2.18 * Main include header for the SDL library, version 3.2.24
* *
* It is almost always best to include just this one header instead of * It is almost always best to include just this one header instead of
* picking out individual headers included here. There are exceptions to * picking out individual headers included here. There are exceptions to
+2 -2
View File
@@ -126,7 +126,7 @@ extern "C" {
*/ */
#define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner #define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner
#elif defined(_MSC_VER) && _MSC_VER >= 1310 #elif defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1310)
/* Don't include intrin.h here because it contains C++ code */ /* Don't include intrin.h here because it contains C++ code */
extern void __cdecl __debugbreak(void); extern void __cdecl __debugbreak(void);
#define SDL_TriggerBreakpoint() __debugbreak() #define SDL_TriggerBreakpoint() __debugbreak()
@@ -362,7 +362,7 @@ extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *
#define SDL_enabled_assert(condition) \ #define SDL_enabled_assert(condition) \
do { \ do { \
while ( !(condition) ) { \ while ( !(condition) ) { \
static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \ static struct SDL_AssertData sdl_assert_data = { false, 0, #condition, NULL, 0, NULL, NULL }; \
const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
continue; /* go again. */ \ continue; /* go again. */ \
+4 -1
View File
@@ -942,7 +942,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID devid);
* Binding a stream to a device will set its output format for playback * Binding a stream to a device will set its output format for playback
* devices, and its input format for recording devices, so they match the * devices, and its input format for recording devices, so they match the
* device's settings. The caller is welcome to change the other end of the * device's settings. The caller is welcome to change the other end of the
* stream's format at any time with SDL_SetAudioStreamFormat(). * stream's format at any time with SDL_SetAudioStreamFormat(). If the other
* end of the stream's format has never been set (the audio stream was created
* with a NULL audio spec), this function will set it to match the device
* end's format.
* *
* \param devid an audio device to bind a stream to. * \param devid an audio device to bind a stream to.
* \param streams an array of audio streams to bind. * \param streams an array of audio streams to bind.
+1 -1
View File
@@ -119,7 +119,7 @@ typedef struct SDL_CameraSpec
int width; /**< Frame width */ int width; /**< Frame width */
int height; /**< Frame height */ int height; /**< Frame height */
int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */ int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */
int framerate_denominator; /**< Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds) */ int framerate_denominator; /**< Frame rate denominator ((num / denom) == FPS, (denom / num) == duration in seconds) */
} SDL_CameraSpec; } SDL_CameraSpec;
/** /**
+14 -14
View File
@@ -106,7 +106,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardText(const char *text);
/** /**
* Get UTF-8 text from the clipboard. * Get UTF-8 text from the clipboard.
* *
* This functions returns an empty string if there was not enough memory left * This function returns an empty string if there is not enough memory left
* for a copy of the clipboard's content. * for a copy of the clipboard's content.
* *
* \returns the clipboard text on success or an empty string on failure; call * \returns the clipboard text on success or an empty string on failure; call
@@ -155,7 +155,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetPrimarySelectionText(const char *text);
/** /**
* Get UTF-8 text from the primary selection. * Get UTF-8 text from the primary selection.
* *
* This functions returns an empty string if there was not enough memory left * This function returns an empty string if there is not enough memory left
* for a copy of the primary selection's content. * for a copy of the primary selection's content.
* *
* \returns the primary selection text on success or an empty string on * \returns the primary selection text on success or an empty string on
@@ -194,15 +194,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
* clipboard is cleared or new data is set. The clipboard is automatically * clipboard is cleared or new data is set. The clipboard is automatically
* cleared in SDL_Quit(). * cleared in SDL_Quit().
* *
* \param userdata a pointer to provided user data. * \param userdata a pointer to the provided user data.
* \param mime_type the requested mime-type. * \param mime_type the requested mime-type.
* \param size a pointer filled in with the length of the returned data. * \param size a pointer filled in with the length of the returned data.
* \returns a pointer to the data for the provided mime-type. Returning NULL * \returns a pointer to the data for the provided mime-type. Returning NULL
* or setting length to 0 will cause no data to be sent to the * or setting the length to 0 will cause no data to be sent to the
* "receiver". It is up to the receiver to handle this. Essentially * "receiver". It is up to the receiver to handle this. Essentially
* returning no data is more or less undefined behavior and may cause * returning no data is more or less undefined behavior and may cause
* breakage in receiving applications. The returned data will not be * breakage in receiving applications. The returned data will not be
* freed so it needs to be retained and dealt with internally. * freed, so it needs to be retained and dealt with internally.
* *
* \since This function is available since SDL 3.2.0. * \since This function is available since SDL 3.2.0.
* *
@@ -211,10 +211,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
typedef const void *(SDLCALL *SDL_ClipboardDataCallback)(void *userdata, const char *mime_type, size_t *size); typedef const void *(SDLCALL *SDL_ClipboardDataCallback)(void *userdata, const char *mime_type, size_t *size);
/** /**
* Callback function that will be called when the clipboard is cleared, or new * Callback function that will be called when the clipboard is cleared, or when new
* data is set. * data is set.
* *
* \param userdata a pointer to provided user data. * \param userdata a pointer to the provided user data.
* *
* \since This function is available since SDL 3.2.0. * \since This function is available since SDL 3.2.0.
* *
@@ -231,7 +231,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
* respond with the data for the requested mime-type. * respond with the data for the requested mime-type.
* *
* The size of text data does not include any terminator, and the text does * The size of text data does not include any terminator, and the text does
* not need to be null terminated (e.g. you can directly copy a portion of a * not need to be null-terminated (e.g., you can directly copy a portion of a
* document). * document).
* *
* \param callback a function pointer to the function that provides the * \param callback a function pointer to the function that provides the
@@ -239,7 +239,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
* \param cleanup a function pointer to the function that cleans up the * \param cleanup a function pointer to the function that cleans up the
* clipboard data. * clipboard data.
* \param userdata an opaque pointer that will be forwarded to the callbacks. * \param userdata an opaque pointer that will be forwarded to the callbacks.
* \param mime_types a list of mime-types that are being offered. * \param mime_types a list of mime-types that are being offered. SDL copies the given list.
* \param num_mime_types the number of mime-types in the mime_types list. * \param num_mime_types the number of mime-types in the mime_types list.
* \returns true on success or false on failure; call SDL_GetError() for more * \returns true on success or false on failure; call SDL_GetError() for more
* information. * information.
@@ -269,10 +269,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback
extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void); extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void);
/** /**
* Get the data from clipboard for a given mime type. * Get the data from the clipboard for a given mime type.
* *
* The size of text data does not include the terminator, but the text is * The size of text data does not include the terminator, but the text is
* guaranteed to be null terminated. * guaranteed to be null-terminated.
* *
* \param mime_type the mime type to read from the clipboard. * \param mime_type the mime type to read from the clipboard.
* \param size a pointer filled in with the length of the returned data. * \param size a pointer filled in with the length of the returned data.
@@ -292,8 +292,8 @@ extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, s
/** /**
* Query whether there is data in the clipboard for the provided mime type. * Query whether there is data in the clipboard for the provided mime type.
* *
* \param mime_type the mime type to check for data for. * \param mime_type the mime type to check for data.
* \returns true if there exists data in clipboard for the provided mime type, * \returns true if data exists in the clipboard for the provided mime type,
* false if it does not. * false if it does not.
* *
* \threadsafety This function should only be called on the main thread. * \threadsafety This function should only be called on the main thread.
@@ -310,7 +310,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardData(const char *mime_type);
* *
* \param num_mime_types a pointer filled with the number of mime types, may * \param num_mime_types a pointer filled with the number of mime types, may
* be NULL. * be NULL.
* \returns a null terminated array of strings with mime types, or NULL on * \returns a null-terminated array of strings with mime types, or NULL on
* failure; call SDL_GetError() for more information. This should be * failure; call SDL_GetError() for more information. This should be
* freed with SDL_free() when it is no longer needed. * freed with SDL_free() when it is no longer needed.
* *
+2 -2
View File
@@ -46,7 +46,7 @@
#if defined(_MSC_VER) && (_MSC_VER >= 1400) #if defined(_MSC_VER) && (_MSC_VER >= 1400)
/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, /* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
#ifdef __clang__ #if defined(__clang__) && !SDL_HAS_BUILTIN(_m_prefetch)
#ifndef __PRFCHWINTRIN_H #ifndef __PRFCHWINTRIN_H
#define __PRFCHWINTRIN_H #define __PRFCHWINTRIN_H
static __inline__ void __attribute__((__always_inline__, __nodebug__)) static __inline__ void __attribute__((__always_inline__, __nodebug__))
@@ -128,7 +128,7 @@ _m_prefetch(void *__P)
* \sa SDL_BIG_ENDIAN * \sa SDL_BIG_ENDIAN
*/ */
#define SDL_BYTEORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN #define SDL_BYTEORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
#elif defined(SDL_PLATFORM_LINUX) #elif defined(SDL_PLATFORM_LINUX) || defined(__GLIBC__)
#include <endian.h> #include <endian.h>
#define SDL_BYTEORDER __BYTE_ORDER #define SDL_BYTEORDER __BYTE_ORDER
#elif defined(SDL_PLATFORM_SOLARIS) #elif defined(SDL_PLATFORM_SOLARIS)
+5 -5
View File
@@ -224,8 +224,8 @@
* - `drawIndirectFirstInstance` * - `drawIndirectFirstInstance`
* *
* **D3D12:** Supported on Windows 10 or newer, Xbox One (GDK), and Xbox * **D3D12:** Supported on Windows 10 or newer, Xbox One (GDK), and Xbox
* Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level * Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level 11_0 and
* 11_1. * Resource Binding Tier 2 or above.
* *
* **Metal:** Supported on macOS 10.14+ and iOS/tvOS 13.0+. Hardware * **Metal:** Supported on macOS 10.14+ and iOS/tvOS 13.0+. Hardware
* requirements vary by operating system: * requirements vary by operating system:
@@ -1091,7 +1091,7 @@ typedef enum SDL_GPUCompareOp
SDL_GPU_COMPAREOP_LESS_OR_EQUAL, /**< The comparison evaluates reference <= test. */ SDL_GPU_COMPAREOP_LESS_OR_EQUAL, /**< The comparison evaluates reference <= test. */
SDL_GPU_COMPAREOP_GREATER, /**< The comparison evaluates reference > test. */ SDL_GPU_COMPAREOP_GREATER, /**< The comparison evaluates reference > test. */
SDL_GPU_COMPAREOP_NOT_EQUAL, /**< The comparison evaluates reference != test. */ SDL_GPU_COMPAREOP_NOT_EQUAL, /**< The comparison evaluates reference != test. */
SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evalutes reference >= test. */ SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evaluates reference >= test. */
SDL_GPU_COMPAREOP_ALWAYS /**< The comparison always evaluates true. */ SDL_GPU_COMPAREOP_ALWAYS /**< The comparison always evaluates true. */
} SDL_GPUCompareOp; } SDL_GPUCompareOp;
@@ -1549,7 +1549,7 @@ typedef struct SDL_GPUSamplerCreateInfo
typedef struct SDL_GPUVertexBufferDescription typedef struct SDL_GPUVertexBufferDescription
{ {
Uint32 slot; /**< The binding slot of the vertex buffer. */ Uint32 slot; /**< The binding slot of the vertex buffer. */
Uint32 pitch; /**< The byte pitch between consecutive elements of the vertex buffer. */ Uint32 pitch; /**< The size of a single element + the offset between elements. */
SDL_GPUVertexInputRate input_rate; /**< Whether attribute addressing is a function of the vertex index or instance index. */ SDL_GPUVertexInputRate input_rate; /**< Whether attribute addressing is a function of the vertex index or instance index. */
Uint32 instance_step_rate; /**< Reserved for future use. Must be set to 0. */ Uint32 instance_step_rate; /**< Reserved for future use. Must be set to 0. */
} SDL_GPUVertexBufferDescription; } SDL_GPUVertexBufferDescription;
@@ -2648,7 +2648,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_InsertGPUDebugLabel(
const char *text); const char *text);
/** /**
* Begins a debug group with an arbitary name. * Begins a debug group with an arbitrary name.
* *
* Used for denoting groups of calls when viewing the command buffer * Used for denoting groups of calls when viewing the command buffer
* callstream in a graphics debugging tool. * callstream in a graphics debugging tool.
+3 -3
View File
@@ -595,7 +595,7 @@ extern "C" {
* A variable that limits what CPU features are available. * A variable that limits what CPU features are available.
* *
* By default, SDL marks all features the current CPU supports as available. * By default, SDL marks all features the current CPU supports as available.
* This hint allows to limit these to a subset. * This hint allows the enabled features to be limited to a subset.
* *
* When the hint is unset, or empty, SDL will enable all detected CPU * When the hint is unset, or empty, SDL will enable all detected CPU
* features. * features.
@@ -2126,8 +2126,8 @@ extern "C" {
* *
* The variable can be set to the following values: * The variable can be set to the following values:
* *
* - "0": WGI is not used. * - "0": WGI is not used. (default)
* - "1": WGI is used. (default) * - "1": WGI is used.
* *
* This hint should be set before SDL is initialized. * This hint should be set before SDL is initialized.
* *
+1 -1
View File
@@ -2612,7 +2612,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, flo
* Draw debug text to an SDL_Renderer. * Draw debug text to an SDL_Renderer.
* *
* This function will render a printf()-style format string to a renderer. * This function will render a printf()-style format string to a renderer.
* Note that this is a convinence function for debugging, with severe * Note that this is a convenience function for debugging, with severe
* limitations, and is not intended to be used for production apps and games. * limitations, and is not intended to be used for production apps and games.
* *
* For the full list of limitations and other useful information, see * For the full list of limitations and other useful information, see
+1 -1
View File
@@ -208,7 +208,7 @@ typedef enum SDL_Scancode
SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO
* keyboards have over ANSI ones, * keyboards have over ANSI ones,
* located between left shift and Y. * located between left shift and Z.
* Produces GRAVE ACCENT and TILDE in a * Produces GRAVE ACCENT and TILDE in a
* US or UK Mac layout, REVERSE SOLIDUS * US or UK Mac layout, REVERSE SOLIDUS
* (backslash) and VERTICAL LINE in a * (backslash) and VERTICAL LINE in a
+2 -1
View File
@@ -138,7 +138,8 @@ typedef enum SDL_SensorType
SDL_SENSOR_ACCEL_L, /**< Accelerometer for left Joy-Con controller and Wii nunchuk */ SDL_SENSOR_ACCEL_L, /**< Accelerometer for left Joy-Con controller and Wii nunchuk */
SDL_SENSOR_GYRO_L, /**< Gyroscope for left Joy-Con controller */ SDL_SENSOR_GYRO_L, /**< Gyroscope for left Joy-Con controller */
SDL_SENSOR_ACCEL_R, /**< Accelerometer for right Joy-Con controller */ SDL_SENSOR_ACCEL_R, /**< Accelerometer for right Joy-Con controller */
SDL_SENSOR_GYRO_R /**< Gyroscope for right Joy-Con controller */ SDL_SENSOR_GYRO_R, /**< Gyroscope for right Joy-Con controller */
SDL_SENSOR_COUNT
} SDL_SensorType; } SDL_SensorType;
+9 -9
View File
@@ -3426,7 +3426,7 @@ extern SDL_DECLSPEC size_t SDLCALL SDL_utf8strnlen(const char *str, size_t bytes
* Convert an integer into a string. * Convert an integer into a string.
* *
* This requires a radix to specified for string format. Specifying 10 * This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2 * produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36. * to 36.
* *
* Note that this function will overflow a buffer if `str` is not large enough * Note that this function will overflow a buffer if `str` is not large enough
@@ -3454,7 +3454,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_itoa(int value, char *str, int radix);
* Convert an unsigned integer into a string. * Convert an unsigned integer into a string.
* *
* This requires a radix to specified for string format. Specifying 10 * This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2 * produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36. * to 36.
* *
* Note that this function will overflow a buffer if `str` is not large enough * Note that this function will overflow a buffer if `str` is not large enough
@@ -3482,7 +3482,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_uitoa(unsigned int value, char *str, int
* Convert a long integer into a string. * Convert a long integer into a string.
* *
* This requires a radix to specified for string format. Specifying 10 * This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2 * produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36. * to 36.
* *
* Note that this function will overflow a buffer if `str` is not large enough * Note that this function will overflow a buffer if `str` is not large enough
@@ -3510,7 +3510,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_ltoa(long value, char *str, int radix);
* Convert an unsigned long integer into a string. * Convert an unsigned long integer into a string.
* *
* This requires a radix to specified for string format. Specifying 10 * This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2 * produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36. * to 36.
* *
* Note that this function will overflow a buffer if `str` is not large enough * Note that this function will overflow a buffer if `str` is not large enough
@@ -3540,7 +3540,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_ultoa(unsigned long value, char *str, int
* Convert a long long integer into a string. * Convert a long long integer into a string.
* *
* This requires a radix to specified for string format. Specifying 10 * This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2 * produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36. * to 36.
* *
* Note that this function will overflow a buffer if `str` is not large enough * Note that this function will overflow a buffer if `str` is not large enough
@@ -3568,7 +3568,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_lltoa(long long value, char *str, int rad
* Convert an unsigned long long integer into a string. * Convert an unsigned long long integer into a string.
* *
* This requires a radix to specified for string format. Specifying 10 * This requires a radix to specified for string format. Specifying 10
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2 * produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
* to 36. * to 36.
* *
* Note that this function will overflow a buffer if `str` is not large enough * Note that this function will overflow a buffer if `str` is not large enough
@@ -3923,7 +3923,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str
extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen); extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen);
/** /**
* Searches a string for the first occurence of any character contained in a * Searches a string for the first occurrence of any character contained in a
* breakset, and returns a pointer from the string to that character. * breakset, and returns a pointer from the string to that character.
* *
* \param str The null-terminated string to be searched. Must not be NULL, and * \param str The null-terminated string to be searched. Must not be NULL, and
@@ -3931,7 +3931,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *st
* \param breakset A null-terminated string containing the list of characters * \param breakset A null-terminated string containing the list of characters
* to look for. Must not be NULL, and must not overlap with * to look for. Must not be NULL, and must not overlap with
* `str`. * `str`.
* \returns A pointer to the location, in str, of the first occurence of a * \returns A pointer to the location, in str, of the first occurrence of a
* character present in the breakset, or NULL if none is found. * character present in the breakset, or NULL if none is found.
* *
* \threadsafety It is safe to call this function from any thread. * \threadsafety It is safe to call this function from any thread.
@@ -5821,7 +5821,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd);
* This function converts text between encodings, reading from and writing to * This function converts text between encodings, reading from and writing to
* a buffer. * a buffer.
* *
* It returns the number of succesful conversions on success. On error, * It returns the number of successful conversions on success. On error,
* SDL_ICONV_E2BIG is returned when the output buffer is too small, or * SDL_ICONV_E2BIG is returned when the output buffer is too small, or
* SDL_ICONV_EILSEQ is returned when an invalid input sequence is encountered, * SDL_ICONV_EILSEQ is returned when an invalid input sequence is encountered,
* or SDL_ICONV_EINVAL is returned when an incomplete input sequence is * or SDL_ICONV_EINVAL is returned when an incomplete input sequence is
+1 -1
View File
@@ -62,7 +62,7 @@ extern "C" {
* *
* \since This macro is available since SDL 3.2.0. * \since This macro is available since SDL 3.2.0.
*/ */
#define SDL_MICRO_VERSION 18 #define SDL_MICRO_VERSION 24
/** /**
* This macro turns the version numbers into a numeric value. * This macro turns the version numbers into a numeric value.
+1 -1
View File
@@ -1473,7 +1473,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowParent(SDL_Window *window)
* - `SDL_PROP_WINDOW_COCOA_WINDOW_POINTER`: the `(__unsafe_unretained)` * - `SDL_PROP_WINDOW_COCOA_WINDOW_POINTER`: the `(__unsafe_unretained)`
* NSWindow associated with the window * NSWindow associated with the window
* - `SDL_PROP_WINDOW_COCOA_METAL_VIEW_TAG_NUMBER`: the NSInteger tag * - `SDL_PROP_WINDOW_COCOA_METAL_VIEW_TAG_NUMBER`: the NSInteger tag
* assocated with metal views on the window * associated with metal views on the window
* *
* On OpenVR: * On OpenVR:
* *
@@ -174,6 +174,7 @@
#cmakedefine HAVE_MEMFD_CREATE 1 #cmakedefine HAVE_MEMFD_CREATE 1
#cmakedefine HAVE_POSIX_FALLOCATE 1 #cmakedefine HAVE_POSIX_FALLOCATE 1
#cmakedefine HAVE_SIGACTION 1 #cmakedefine HAVE_SIGACTION 1
#cmakedefine HAVE_SIGTIMEDWAIT 1
#cmakedefine HAVE_SA_SIGACTION 1 #cmakedefine HAVE_SA_SIGACTION 1
#cmakedefine HAVE_ST_MTIM 1 #cmakedefine HAVE_ST_MTIM 1
#cmakedefine HAVE_SETJMP 1 #cmakedefine HAVE_SETJMP 1
@@ -111,6 +111,9 @@ typedef unsigned int uintptr_t;
# define SDL_DISABLE_AVX 1 # define SDL_DISABLE_AVX 1
#endif #endif
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
/* This can be disabled to avoid C runtime dependencies and manifest requirements */ /* This can be disabled to avoid C runtime dependencies and manifest requirements */
#ifndef HAVE_LIBC #ifndef HAVE_LIBC
#define HAVE_LIBC 1 #define HAVE_LIBC 1
@@ -122,8 +125,6 @@ typedef unsigned int uintptr_t;
#define HAVE_LIMITS_H 1 #define HAVE_LIMITS_H 1
#define HAVE_MATH_H 1 #define HAVE_MATH_H 1
#define HAVE_SIGNAL_H 1 #define HAVE_SIGNAL_H 1
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
#define HAVE_STDIO_H 1 #define HAVE_STDIO_H 1
#define HAVE_STDLIB_H 1 #define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1 #define HAVE_STRING_H 1
@@ -153,7 +154,6 @@ typedef unsigned int uintptr_t;
#define HAVE_STRCMP 1 #define HAVE_STRCMP 1
#define HAVE_STRNCMP 1 #define HAVE_STRNCMP 1
#define HAVE_STRPBRK 1 #define HAVE_STRPBRK 1
#define HAVE_VSSCANF 1
#define HAVE_VSNPRINTF 1 #define HAVE_VSNPRINTF 1
#define HAVE_ACOS 1 #define HAVE_ACOS 1
#define HAVE_ASIN 1 #define HAVE_ASIN 1
@@ -211,10 +211,7 @@ typedef unsigned int uintptr_t;
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
#define HAVE__FSEEKI64 1 #define HAVE__FSEEKI64 1
#endif #endif
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#else
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
#endif #endif
/* Enable various audio drivers */ /* Enable various audio drivers */
+14 -4
View File
@@ -1153,7 +1153,10 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
// We should have updated this elsewhere if the format changed! // We should have updated this elsewhere if the format changed!
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &device->spec, NULL, NULL)); SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &device->spec, NULL, NULL));
SDL_assert(stream->src_spec.format != SDL_AUDIO_UNKNOWN);
const int br = SDL_GetAtomicInt(&logdev->paused) ? 0 : SDL_GetAudioStreamDataAdjustGain(stream, device_buffer, buffer_size, logdev->gain); const int br = SDL_GetAtomicInt(&logdev->paused) ? 0 : SDL_GetAudioStreamDataAdjustGain(stream, device_buffer, buffer_size, logdev->gain);
if (br < 0) { // Probably OOM. Kill the audio device; the whole thing is likely dying soon anyhow. if (br < 0) { // Probably OOM. Kill the audio device; the whole thing is likely dying soon anyhow.
failed = true; failed = true;
SDL_memset(device_buffer, device->silence_value, buffer_size); // just supply silence to the device before we die. SDL_memset(device_buffer, device->silence_value, buffer_size); // just supply silence to the device before we die.
@@ -1195,6 +1198,8 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
// We should have updated this elsewhere if the format changed! // We should have updated this elsewhere if the format changed!
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &outspec, NULL, NULL)); SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &outspec, NULL, NULL));
SDL_assert(stream->src_spec.format != SDL_AUDIO_UNKNOWN);
/* this will hold a lock on `stream` while getting. We don't explicitly lock the streams /* this will hold a lock on `stream` while getting. We don't explicitly lock the streams
for iterating here because the binding linked list can only change while the device lock is held. for iterating here because the binding linked list can only change while the device lock is held.
(we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind (we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind
@@ -1330,6 +1335,7 @@ bool SDL_RecordingAudioThreadIterate(SDL_AudioDevice *device)
SDL_assert(stream->src_spec.format == ((logdev->postmix || (logdev->gain != 1.0f)) ? SDL_AUDIO_F32 : device->spec.format)); SDL_assert(stream->src_spec.format == ((logdev->postmix || (logdev->gain != 1.0f)) ? SDL_AUDIO_F32 : device->spec.format));
SDL_assert(stream->src_spec.channels == device->spec.channels); SDL_assert(stream->src_spec.channels == device->spec.channels);
SDL_assert(stream->src_spec.freq == device->spec.freq); SDL_assert(stream->src_spec.freq == device->spec.freq);
SDL_assert(stream->dst_spec.format != SDL_AUDIO_UNKNOWN);
void *final_buf = output_buffer; void *final_buf = output_buffer;
@@ -1975,10 +1981,6 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
} else if (logdev->simplified) { } else if (logdev->simplified) {
result = SDL_SetError("Cannot change stream bindings on device opened with SDL_OpenAudioDeviceStream"); result = SDL_SetError("Cannot change stream bindings on device opened with SDL_OpenAudioDeviceStream");
} else { } else {
// !!! FIXME: We'll set the device's side's format below, but maybe we should refuse to bind a stream if the app's side doesn't have a format set yet.
// !!! FIXME: Actually, why do we allow there to be an invalid format, again?
// make sure start of list is sane. // make sure start of list is sane.
SDL_assert(!logdev->bound_streams || (logdev->bound_streams->prev_binding == NULL)); SDL_assert(!logdev->bound_streams || (logdev->bound_streams->prev_binding == NULL));
@@ -2013,9 +2015,17 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
if (result) { if (result) {
// Now that everything is verified, chain everything together. // Now that everything is verified, chain everything together.
const bool recording = device->recording;
for (int i = 0; i < num_streams; i++) { for (int i = 0; i < num_streams; i++) {
SDL_AudioStream *stream = streams[i]; SDL_AudioStream *stream = streams[i];
if (stream) { // shouldn't be NULL, but just in case... if (stream) { // shouldn't be NULL, but just in case...
// if the stream never had its non-device-end format set, just set it to the device end's format.
if (recording && (stream->dst_spec.format == SDL_AUDIO_UNKNOWN)) {
SDL_copyp(&stream->dst_spec, &device->spec);
} else if (!recording && (stream->src_spec.format == SDL_AUDIO_UNKNOWN)) {
SDL_copyp(&stream->src_spec, &device->spec);
}
stream->bound_device = logdev; stream->bound_device = logdev;
stream->prev_binding = NULL; stream->prev_binding = NULL;
stream->next_binding = logdev->bound_streams; stream->next_binding = logdev->bound_streams;
+4
View File
@@ -537,8 +537,10 @@ static void SDL_TARGETING("ssse3") SDL_Convert_Swap32_SSSE3(Uint32* dst, const U
// behavior. However, the compiler support for this pragma is bad. // behavior. However, the compiler support for this pragma is bad.
#if defined(__clang__) #if defined(__clang__)
#if __clang_major__ >= 12 #if __clang_major__ >= 12
#if defined(__aarch64__)
#pragma STDC FENV_ACCESS ON #pragma STDC FENV_ACCESS ON
#endif #endif
#endif
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#pragma fenv_access (on) #pragma fenv_access (on)
#elif defined(__GNUC__) #elif defined(__GNUC__)
@@ -814,8 +816,10 @@ static void SDL_Convert_Swap32_NEON(Uint32* dst, const Uint32* src, int num_samp
#if defined(__clang__) #if defined(__clang__)
#if __clang_major__ >= 12 #if __clang_major__ >= 12
#if defined(__aarch64__)
#pragma STDC FENV_ACCESS DEFAULT #pragma STDC FENV_ACCESS DEFAULT
#endif #endif
#endif
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#pragma fenv_access (off) #pragma fenv_access (off)
#elif defined(__GNUC__) #elif defined(__GNUC__)
+11 -2
View File
@@ -1775,6 +1775,7 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
int result; int result;
Uint32 chunkcount = 0; Uint32 chunkcount = 0;
Uint32 chunkcountlimit = 10000; Uint32 chunkcountlimit = 10000;
const Sint64 flen = SDL_GetIOSize(src); // this might be -1 if the IOStream can't determine the total size.
const char *hint; const char *hint;
Sint64 RIFFstart, RIFFend, lastchunkpos; Sint64 RIFFstart, RIFFend, lastchunkpos;
bool RIFFlengthknown = false; bool RIFFlengthknown = false;
@@ -1883,6 +1884,14 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
fmtchunk = *chunk; fmtchunk = *chunk;
} }
} else if (chunk->fourcc == DATA) { } else if (chunk->fourcc == DATA) {
/* If the data chunk is bigger than the file, it might be corrupt
or the file is truncated. Try to recover by clamping the file
size. This also means a malicious file can't allocate 4 gigabytes
for the chunks without actually supplying a 4 gigabyte file. */
if ((flen > 0) && ((chunk->position + chunk->length) > flen)) {
chunk->length = (Uint32) (flen - chunk->position);
}
/* Only use the first data chunk. Handling the wavl list madness /* Only use the first data chunk. Handling the wavl list madness
* may require a different approach. * may require a different approach.
*/ */
@@ -2114,8 +2123,8 @@ bool SDL_LoadWAV_IO(SDL_IOStream *src, bool closeio, SDL_AudioSpec *spec, Uint8
result = WaveLoad(src, &file, spec, audio_buf, audio_len); result = WaveLoad(src, &file, spec, audio_buf, audio_len);
if (!result) { if (!result) {
SDL_free(*audio_buf); SDL_free(*audio_buf);
audio_buf = NULL; *audio_buf = NULL;
audio_len = 0; *audio_len = 0;
} }
// Cleanup // Cleanup
+2 -1
View File
@@ -420,7 +420,8 @@ static bool UpdateAudioSession(SDL_AudioDevice *device, bool open, bool allow_pl
hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY); hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY);
if (hint) { if (hint) {
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) { if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0 ||
SDL_strcasecmp(hint, "ambient") == 0) {
category = AVAudioSessionCategoryAmbient; category = AVAudioSessionCategoryAmbient;
} else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) { } else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) {
category = AVAudioSessionCategorySoloAmbient; category = AVAudioSessionCategorySoloAmbient;
+13 -8
View File
@@ -426,28 +426,33 @@ static void OPENSLES_DestroyPCMPlayer(SDL_AudioDevice *device)
static bool OPENSLES_CreatePCMPlayer(SDL_AudioDevice *device) static bool OPENSLES_CreatePCMPlayer(SDL_AudioDevice *device)
{ {
/* If we want to add floating point audio support (requires API level 21) /* according to https://developer.android.com/ndk/guides/audio/opensl/opensl-for-android,
it can be done as described here: Android's OpenSL ES only supports Uint8 and _littleendian_ Sint16.
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point (and float32, with an extension we use, below.) */
*/
if (SDL_GetAndroidSDKVersion() >= 21) { if (SDL_GetAndroidSDKVersion() >= 21) {
const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format);
SDL_AudioFormat test_format; SDL_AudioFormat test_format;
while ((test_format = *(closefmts++)) != 0) { while ((test_format = *(closefmts++)) != 0) {
if (SDL_AUDIO_ISSIGNED(test_format)) { switch (test_format) {
case SDL_AUDIO_U8:
case SDL_AUDIO_S16LE:
case SDL_AUDIO_F32:
break; break;
default:
continue;
} }
break;
} }
if (!test_format) { if (!test_format) {
// Didn't find a compatible format : // Didn't find a compatible format :
LOGI("No compatible audio format, using signed 16-bit audio"); LOGI("No compatible audio format, using signed 16-bit LE audio");
test_format = SDL_AUDIO_S16; test_format = SDL_AUDIO_S16LE;
} }
device->spec.format = test_format; device->spec.format = test_format;
} else { } else {
// Just go with signed 16-bit audio as it's the most compatible // Just go with signed 16-bit audio as it's the most compatible
device->spec.format = SDL_AUDIO_S16; device->spec.format = SDL_AUDIO_S16LE;
} }
// Update the fragment size as size in bytes // Update the fragment size as size in bytes
+1 -1
View File
@@ -114,7 +114,7 @@ static bool PSPAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, in
} else { } else {
rc = sceAudioOutputPannedBlocking(device->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, (void *) buffer); rc = sceAudioOutputPannedBlocking(device->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, (void *) buffer);
} }
return (rc == 0); return (rc >= 0);
} }
static bool PSPAUDIO_WaitDevice(SDL_AudioDevice *device) static bool PSPAUDIO_WaitDevice(SDL_AudioDevice *device)
+1 -1
View File
@@ -814,7 +814,7 @@ static void ANDROIDCAMERA_Deinitialize(void)
static bool ANDROIDCAMERA_Init(SDL_CameraDriverImpl *impl) static bool ANDROIDCAMERA_Init(SDL_CameraDriverImpl *impl)
{ {
// !!! FIXME: slide this off into a subroutine // !!! FIXME: slide this off into a subroutine
// system libraries are in android-24 and later; we currently target android-16 and later, so check if they exist at runtime. // system libraries are in android-24 and later; we currently target android-21 and later, so check if they exist at runtime.
void *libcamera2 = dlopen("libcamera2ndk.so", RTLD_NOW | RTLD_LOCAL); void *libcamera2 = dlopen("libcamera2ndk.so", RTLD_NOW | RTLD_LOCAL);
if (!libcamera2) { if (!libcamera2) {
SDL_Log("CAMERA: libcamera2ndk.so can't be loaded: %s", dlerror()); SDL_Log("CAMERA: libcamera2ndk.so can't be loaded: %s", dlerror());
+4 -3
View File
@@ -1080,7 +1080,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
{ {
const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
SDL_AddTouch((SDL_TouchID)touchId, SDL_TOUCH_DEVICE_DIRECT, utfname); SDL_AddTouch(Android_ConvertJavaTouchID(touchId),
SDL_TOUCH_DEVICE_DIRECT, utfname);
(*env)->ReleaseStringUTFChars(env, name, utfname); (*env)->ReleaseStringUTFChars(env, name, utfname);
} }
@@ -2163,7 +2164,7 @@ bool Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *b
mid = (*env)->GetMethodID(env, clazz, mid = (*env)->GetMethodID(env, clazz,
"messageboxShowMessageBox", "(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I"); "messageboxShowMessageBox", "(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I");
*buttonID = (*env)->CallIntMethod(env, context, mid, *buttonID = (*env)->CallIntMethod(env, context, mid,
messageboxdata->flags, (jint)messageboxdata->flags,
title, title,
message, message,
button_flags, button_flags,
@@ -2417,7 +2418,7 @@ const char *SDL_GetAndroidCachePath(void)
// fileObj = context.getExternalFilesDir(); // fileObj = context.getExternalFilesDir();
mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
"getCacheDir", "()Ljava/io/File;"); "getCacheDir", "()Ljava/io/File;");
fileObject = (*env)->CallObjectMethod(env, context, mid, NULL); fileObject = (*env)->CallObjectMethod(env, context, mid);
if (!fileObject) { if (!fileObject) {
SDL_SetError("Couldn't get cache directory"); SDL_SetError("Couldn't get cache directory");
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
+7 -26
View File
@@ -25,6 +25,7 @@
#include "SDL_fcitx.h" #include "SDL_fcitx.h"
#include "../../video/SDL_sysvideo.h" #include "../../video/SDL_sysvideo.h"
#include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_keyboard_c.h"
#include "../../core/unix/SDL_appid.h"
#include "SDL_dbus.h" #include "SDL_dbus.h"
#ifdef SDL_VIDEO_DRIVER_X11 #ifdef SDL_VIDEO_DRIVER_X11
@@ -53,32 +54,14 @@ typedef struct FcitxClient
static FcitxClient fcitx_client; static FcitxClient fcitx_client;
static char *GetAppName(void) static const char *GetAppName(void)
{ {
#if defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_FREEBSD) const char *exe_name = SDL_GetExeName();
char *spot; if (exe_name) {
char procfile[1024]; return exe_name;
char linkfile[1024];
int linksize;
#ifdef SDL_PLATFORM_LINUX
(void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/exe", getpid());
#elif defined(SDL_PLATFORM_FREEBSD)
(void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/file", getpid());
#endif
linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
if (linksize > 0) {
linkfile[linksize] = '\0';
spot = SDL_strrchr(linkfile, '/');
if (spot) {
return SDL_strdup(spot + 1);
} else {
return SDL_strdup(linkfile);
}
} }
#endif // SDL_PLATFORM_LINUX || SDL_PLATFORM_FREEBSD
return SDL_strdup("SDL_App"); return "SDL_App";
} }
static size_t Fcitx_GetPreeditString(SDL_DBusContext *dbus, static size_t Fcitx_GetPreeditString(SDL_DBusContext *dbus,
@@ -281,7 +264,7 @@ static bool FcitxCreateInputContext(SDL_DBusContext *dbus, const char *appname,
static bool FcitxClientCreateIC(FcitxClient *client) static bool FcitxClientCreateIC(FcitxClient *client)
{ {
char *appname = GetAppName(); const char *appname = GetAppName();
char *ic_path = NULL; char *ic_path = NULL;
SDL_DBusContext *dbus = client->dbus; SDL_DBusContext *dbus = client->dbus;
@@ -290,8 +273,6 @@ static bool FcitxClientCreateIC(FcitxClient *client)
ic_path = NULL; // just in case. ic_path = NULL; // just in case.
} }
SDL_free(appname);
if (ic_path) { if (ic_path) {
SDL_free(client->ic_path); SDL_free(client->ic_path);
client->ic_path = SDL_strdup(ic_path); client->ic_path = SDL_strdup(ic_path);
+4 -4
View File
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,2,18,0 FILEVERSION 3,2,24,0
PRODUCTVERSION 3,2,18,0 PRODUCTVERSION 3,2,24,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L FILEFLAGS 0x0L
FILEOS 0x40004L FILEOS 0x40004L
@@ -23,12 +23,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "\0" VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL\0" VALUE "FileDescription", "SDL\0"
VALUE "FileVersion", "3, 2, 18, 0\0" VALUE "FileVersion", "3, 2, 24, 0\0"
VALUE "InternalName", "SDL\0" VALUE "InternalName", "SDL\0"
VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0"
VALUE "OriginalFilename", "SDL3.dll\0" VALUE "OriginalFilename", "SDL3.dll\0"
VALUE "ProductName", "Simple DirectMedia Layer\0" VALUE "ProductName", "Simple DirectMedia Layer\0"
VALUE "ProductVersion", "3, 2, 18, 0\0" VALUE "ProductVersion", "3, 2, 24, 0\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
+2
View File
@@ -1646,6 +1646,8 @@ bool SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
#ifdef SDL_PLATFORM_ANDROID #ifdef SDL_PLATFORM_ANDROID
for (;;) { for (;;) {
SDL_PumpEventsInternal(true);
if (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST) > 0) { if (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST) > 0) {
return true; return true;
} }
+2 -2
View File
@@ -78,7 +78,7 @@ static char *search_path_for_binary(const char *bin)
char *envr; char *envr;
size_t alloc_size; size_t alloc_size;
char *exe = NULL; char *exe = NULL;
char *start = envr; char *start;
char *ptr; char *ptr;
if (!envr_real) { if (!envr_real) {
@@ -86,7 +86,7 @@ static char *search_path_for_binary(const char *bin)
return NULL; return NULL;
} }
envr = SDL_strdup(envr_real); start = envr = SDL_strdup(envr_real);
if (!envr) { if (!envr) {
return NULL; return NULL;
} }
+5 -3
View File
@@ -1785,6 +1785,8 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
commandBufferHeader->render_pass.num_color_targets = num_color_targets; commandBufferHeader->render_pass.num_color_targets = num_color_targets;
if (depth_stencil_target_info != NULL) { if (depth_stencil_target_info != NULL) {
commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture; commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture;
} else {
commandBufferHeader->render_pass.depth_stencil_target = NULL;
} }
} }
@@ -2248,14 +2250,14 @@ void SDL_DrawGPUIndexedPrimitivesIndirect(
void SDL_EndGPURenderPass( void SDL_EndGPURenderPass(
SDL_GPURenderPass *render_pass) SDL_GPURenderPass *render_pass)
{ {
CommandBufferCommonHeader *commandBufferCommonHeader;
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
if (render_pass == NULL) { if (render_pass == NULL) {
SDL_InvalidParamError("render_pass"); SDL_InvalidParamError("render_pass");
return; return;
} }
CommandBufferCommonHeader *commandBufferCommonHeader;
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
if (RENDERPASS_DEVICE->debug_mode) { if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS CHECK_RENDERPASS
} }
+1 -1
View File
@@ -35,7 +35,7 @@
#define UNIFORM_BUFFER_SIZE 32768 #define UNIFORM_BUFFER_SIZE 32768
#define MAX_VERTEX_BUFFERS 16 #define MAX_VERTEX_BUFFERS 16
#define MAX_VERTEX_ATTRIBUTES 16 #define MAX_VERTEX_ATTRIBUTES 16
#define MAX_COLOR_TARGET_BINDINGS 4 #define MAX_COLOR_TARGET_BINDINGS 8
#define MAX_PRESENT_COUNT 16 #define MAX_PRESENT_COUNT 16
#define MAX_FRAMES_IN_FLIGHT 3 #define MAX_FRAMES_IN_FLIGHT 3
+42 -8
View File
@@ -109,8 +109,8 @@
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface" #define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
#define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface" #define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface"
#define WINDOW_PROPERTY_DATA "SDL_GPUD3D12WindowPropertyData" #define WINDOW_PROPERTY_DATA "SDL_GPUD3D12WindowPropertyData"
#define D3D_FEATURE_LEVEL_CHOICE D3D_FEATURE_LEVEL_11_1 #define D3D_FEATURE_LEVEL_CHOICE D3D_FEATURE_LEVEL_11_0
#define D3D_FEATURE_LEVEL_CHOICE_STR "11_1" #define D3D_FEATURE_LEVEL_CHOICE_STR "11_0"
#define MAX_ROOT_SIGNATURE_PARAMETERS 64 #define MAX_ROOT_SIGNATURE_PARAMETERS 64
#define D3D12_FENCE_UNSIGNALED_VALUE 0 #define D3D12_FENCE_UNSIGNALED_VALUE 0
#define D3D12_FENCE_SIGNAL_VALUE 1 #define D3D12_FENCE_SIGNAL_VALUE 1
@@ -1194,7 +1194,6 @@ struct D3D12UniformBuffer
D3D12Buffer *buffer; D3D12Buffer *buffer;
Uint32 writeOffset; Uint32 writeOffset;
Uint32 drawOffset; Uint32 drawOffset;
Uint32 currentBlockSize;
}; };
// Forward function declarations // Forward function declarations
@@ -1441,6 +1440,8 @@ static void D3D12_INTERNAL_ReleaseTextureContainer(
container->textures[i]); container->textures[i]);
} }
SDL_DestroyProperties(container->header.info.props);
// Containers are just client handles, so we can destroy immediately // Containers are just client handles, so we can destroy immediately
if (container->debugName) { if (container->debugName) {
SDL_free(container->debugName); SDL_free(container->debugName);
@@ -4496,7 +4497,6 @@ static D3D12UniformBuffer *D3D12_INTERNAL_AcquireUniformBufferFromPool(
SDL_UnlockMutex(renderer->acquireUniformBufferLock); SDL_UnlockMutex(renderer->acquireUniformBufferLock);
uniformBuffer->currentBlockSize = 0;
uniformBuffer->drawOffset = 0; uniformBuffer->drawOffset = 0;
uniformBuffer->writeOffset = 0; uniformBuffer->writeOffset = 0;
@@ -4535,6 +4535,7 @@ static void D3D12_INTERNAL_PushUniformData(
Uint32 length) Uint32 length)
{ {
D3D12UniformBuffer *uniformBuffer; D3D12UniformBuffer *uniformBuffer;
Uint32 blockSize;
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) { if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
if (commandBuffer->vertexUniformBuffers[slotIndex] == NULL) { if (commandBuffer->vertexUniformBuffers[slotIndex] == NULL) {
@@ -4559,13 +4560,13 @@ static void D3D12_INTERNAL_PushUniformData(
return; return;
} }
uniformBuffer->currentBlockSize = blockSize =
D3D12_INTERNAL_Align( D3D12_INTERNAL_Align(
length, length,
256); 256);
// If there is no more room, acquire a new uniform buffer // If there is no more room, acquire a new uniform buffer
if (uniformBuffer->writeOffset + uniformBuffer->currentBlockSize >= UNIFORM_BUFFER_SIZE) { if (uniformBuffer->writeOffset + blockSize >= UNIFORM_BUFFER_SIZE) {
ID3D12Resource_Unmap( ID3D12Resource_Unmap(
uniformBuffer->buffer->handle, uniformBuffer->buffer->handle,
0, 0,
@@ -4595,7 +4596,7 @@ static void D3D12_INTERNAL_PushUniformData(
data, data,
length); length);
uniformBuffer->writeOffset += uniformBuffer->currentBlockSize; uniformBuffer->writeOffset += blockSize;
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) { if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
commandBuffer->needVertexUniformBufferBind[slotIndex] = true; commandBuffer->needVertexUniformBufferBind[slotIndex] = true;
@@ -8352,6 +8353,7 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
IDXGIFactory4 *factory4; IDXGIFactory4 *factory4;
IDXGIFactory6 *factory6; IDXGIFactory6 *factory6;
IDXGIAdapter1 *adapter; IDXGIAdapter1 *adapter;
bool supports_64UAVs = false;
// Can we load D3D12? // Can we load D3D12?
@@ -8440,12 +8442,39 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
return false; return false;
} }
SDL_COMPILE_TIME_ASSERT(featurelevel, D3D_FEATURE_LEVEL_CHOICE < D3D_FEATURE_LEVEL_11_1);
// Check feature level 11_1 first, guarantees 64+ UAVs unlike 11_0 Tier1
res = D3D12CreateDeviceFunc( res = D3D12CreateDeviceFunc(
(IUnknown *)adapter, (IUnknown *)adapter,
D3D_FEATURE_LEVEL_CHOICE, D3D_FEATURE_LEVEL_11_1,
D3D_GUID(D3D_IID_ID3D12Device), D3D_GUID(D3D_IID_ID3D12Device),
(void **)&device); (void **)&device);
if (SUCCEEDED(res)) {
supports_64UAVs = true;
} else {
res = D3D12CreateDeviceFunc(
(IUnknown *)adapter,
D3D_FEATURE_LEVEL_CHOICE,
D3D_GUID(D3D_IID_ID3D12Device),
(void **)&device);
if (SUCCEEDED(res)) {
D3D12_FEATURE_DATA_D3D12_OPTIONS featureOptions;
SDL_zero(featureOptions);
res = ID3D12Device_CheckFeatureSupport(
device,
D3D12_FEATURE_D3D12_OPTIONS,
&featureOptions,
sizeof(featureOptions));
if (SUCCEEDED(res) && featureOptions.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_2) {
supports_64UAVs = true;
}
}
}
if (SUCCEEDED(res)) { if (SUCCEEDED(res)) {
ID3D12Device_Release(device); ID3D12Device_Release(device);
} }
@@ -8455,6 +8484,11 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
SDL_UnloadObject(d3d12Dll); SDL_UnloadObject(d3d12Dll);
SDL_UnloadObject(dxgiDll); SDL_UnloadObject(dxgiDll);
if (!supports_64UAVs) {
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Tier 2 Resource binding is not supported");
return false;
}
if (FAILED(res)) { if (FAILED(res)) {
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not create D3D12Device with feature level " D3D_FEATURE_LEVEL_CHOICE_STR); SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not create D3D12Device with feature level " D3D_FEATURE_LEVEL_CHOICE_STR);
return false; return false;
+3 -1
View File
@@ -888,6 +888,7 @@ static void METAL_INTERNAL_DestroyTextureContainer(
container->textures[i]->handle = nil; container->textures[i]->handle = nil;
SDL_free(container->textures[i]); SDL_free(container->textures[i]);
} }
SDL_DestroyProperties(container->header.info.props);
if (container->debugName != NULL) { if (container->debugName != NULL) {
SDL_free(container->debugName); SDL_free(container->debugName);
} }
@@ -1777,7 +1778,8 @@ static void METAL_UploadToTexture(
copyFromBuffer:bufferContainer->activeBuffer->handle copyFromBuffer:bufferContainer->activeBuffer->handle
sourceOffset:source->offset sourceOffset:source->offset
sourceBytesPerRow:BytesPerRow(destination->w, textureContainer->header.info.format) sourceBytesPerRow:BytesPerRow(destination->w, textureContainer->header.info.format)
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, destination->d) // sourceBytesPerImage expects the stride between 2D images (slices) of a 3D texture, not the size of the entire region
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, 1)
sourceSize:MTLSizeMake(destination->w, destination->h, destination->d) sourceSize:MTLSizeMake(destination->w, destination->h, destination->d)
toTexture:metalTexture->handle toTexture:metalTexture->handle
destinationSlice:destination->layer destinationSlice:destination->layer
+84 -33
View File
@@ -1108,6 +1108,7 @@ typedef struct VulkanCommandBuffer
VulkanFenceHandle *inFlightFence; VulkanFenceHandle *inFlightFence;
bool autoReleaseFence; bool autoReleaseFence;
bool swapchainRequested;
bool isDefrag; // Whether this CB was created for defragging bool isDefrag; // Whether this CB was created for defragging
} VulkanCommandBuffer; } VulkanCommandBuffer;
@@ -1142,6 +1143,7 @@ struct VulkanRenderer
VulkanExtensions supports; VulkanExtensions supports;
bool supportsDebugUtils; bool supportsDebugUtils;
bool supportsColorspace; bool supportsColorspace;
bool supportsPhysicalDeviceProperties2;
bool supportsFillModeNonSolid; bool supportsFillModeNonSolid;
bool supportsMultiDrawIndirect; bool supportsMultiDrawIndirect;
@@ -1277,13 +1279,20 @@ static inline const char *VkErrorMessages(VkResult code)
#undef ERR_TO_STR #undef ERR_TO_STR
} }
#define SET_ERROR_AND_RETURN(fmt, msg, ret) \ #define SET_ERROR(fmt, msg) \
do { \ do { \
if (renderer->debugMode) { \ if (renderer->debugMode) { \
SDL_LogError(SDL_LOG_CATEGORY_GPU, fmt, msg); \ SDL_LogError(SDL_LOG_CATEGORY_GPU, fmt, msg); \
} \ } \
SDL_SetError((fmt), (msg)); \ SDL_SetError((fmt), (msg)); \
return ret; \ } while (0)
#define SET_STRING_ERROR(msg) SET_ERROR("%s", msg)
#define SET_ERROR_AND_RETURN(fmt, msg, ret) \
do { \
SET_ERROR(fmt, msg); \
return ret; \
} while (0) } while (0)
#define SET_STRING_ERROR_AND_RETURN(msg, ret) SET_ERROR_AND_RETURN("%s", msg, ret) #define SET_STRING_ERROR_AND_RETURN(msg, ret) SET_ERROR_AND_RETURN("%s", msg, ret)
@@ -6081,7 +6090,6 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
colorAttachmentReferences[colorAttachmentReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; colorAttachmentReferences[colorAttachmentReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptionCount += 1; attachmentDescriptionCount += 1;
colorAttachmentReferenceCount += 1;
if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) { if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
VulkanTextureContainer *resolveContainer = (VulkanTextureContainer *)colorTargetInfos[i].resolve_texture; VulkanTextureContainer *resolveContainer = (VulkanTextureContainer *)colorTargetInfos[i].resolve_texture;
@@ -6096,12 +6104,16 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
resolveReferences[resolveReferenceCount].attachment = attachmentDescriptionCount; resolveReferences[colorAttachmentReferenceCount].attachment = attachmentDescriptionCount;
resolveReferences[resolveReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; resolveReferences[colorAttachmentReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescriptionCount += 1; attachmentDescriptionCount += 1;
resolveReferenceCount += 1; resolveReferenceCount += 1;
} else {
resolveReferences[colorAttachmentReferenceCount].attachment = VK_ATTACHMENT_UNUSED;
} }
colorAttachmentReferenceCount += 1;
} }
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
@@ -6951,6 +6963,8 @@ static void VULKAN_ReleaseTexture(
VULKAN_INTERNAL_ReleaseTexture(renderer, vulkanTextureContainer->textures[i]); VULKAN_INTERNAL_ReleaseTexture(renderer, vulkanTextureContainer->textures[i]);
} }
SDL_DestroyProperties(vulkanTextureContainer->header.info.props);
// Containers are just client handles, so we can destroy immediately // Containers are just client handles, so we can destroy immediately
if (vulkanTextureContainer->debugName != NULL) { if (vulkanTextureContainer->debugName != NULL) {
SDL_free(vulkanTextureContainer->debugName); SDL_free(vulkanTextureContainer->debugName);
@@ -7896,15 +7910,17 @@ static void VULKAN_BeginRenderPass(
clearValues = SDL_stack_alloc(VkClearValue, clearCount); clearValues = SDL_stack_alloc(VkClearValue, clearCount);
for (i = 0; i < totalColorAttachmentCount; i += 1) { int clearIndex = 0;
clearValues[i].color.float32[0] = colorTargetInfos[i].clear_color.r; for (i = 0; i < numColorTargets; i += 1) {
clearValues[i].color.float32[1] = colorTargetInfos[i].clear_color.g; clearValues[clearIndex].color.float32[0] = colorTargetInfos[i].clear_color.r;
clearValues[i].color.float32[2] = colorTargetInfos[i].clear_color.b; clearValues[clearIndex].color.float32[1] = colorTargetInfos[i].clear_color.g;
clearValues[i].color.float32[3] = colorTargetInfos[i].clear_color.a; clearValues[clearIndex].color.float32[2] = colorTargetInfos[i].clear_color.b;
clearValues[clearIndex].color.float32[3] = colorTargetInfos[i].clear_color.a;
clearIndex += 1;
if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) { if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
// Skip over the resolve texture, we're not clearing it // Skip over the resolve texture, we're not clearing it
i += 1; clearIndex += 1;
} }
} }
@@ -8592,7 +8608,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
dynamicOffsetCount, dynamicOffsetCount,
dynamicOffsets); dynamicOffsets);
commandBuffer->needNewVertexUniformOffsets = false; commandBuffer->needNewComputeUniformOffsets = false;
} }
static void VULKAN_DispatchCompute( static void VULKAN_DispatchCompute(
@@ -9395,6 +9411,8 @@ static bool VULKAN_INTERNAL_AllocateCommandBuffer(
commandBuffer->usedUniformBuffers = SDL_malloc( commandBuffer->usedUniformBuffers = SDL_malloc(
commandBuffer->usedUniformBufferCapacity * sizeof(VulkanUniformBuffer *)); commandBuffer->usedUniformBufferCapacity * sizeof(VulkanUniformBuffer *));
commandBuffer->swapchainRequested = false;
// Pool it! // Pool it!
vulkanCommandPool->inactiveCommandBuffers[vulkanCommandPool->inactiveCommandBufferCount] = commandBuffer; vulkanCommandPool->inactiveCommandBuffers[vulkanCommandPool->inactiveCommandBufferCount] = commandBuffer;
@@ -9505,7 +9523,8 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
VulkanCommandBuffer *commandBuffer = VulkanCommandBuffer *commandBuffer =
VULKAN_INTERNAL_GetInactiveCommandBufferFromPool(renderer, threadID); VULKAN_INTERNAL_GetInactiveCommandBufferFromPool(renderer, threadID);
commandBuffer->descriptorSetCache = VULKAN_INTERNAL_AcquireDescriptorSetCache(renderer); DescriptorSetCache *descriptorSetCache =
VULKAN_INTERNAL_AcquireDescriptorSetCache(renderer);
SDL_UnlockMutex(renderer->acquireCommandBufferLock); SDL_UnlockMutex(renderer->acquireCommandBufferLock);
@@ -9513,6 +9532,8 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
return NULL; return NULL;
} }
commandBuffer->descriptorSetCache = descriptorSetCache;
// Reset state // Reset state
commandBuffer->currentComputePipeline = NULL; commandBuffer->currentComputePipeline = NULL;
@@ -9577,6 +9598,7 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
commandBuffer->autoReleaseFence = true; commandBuffer->autoReleaseFence = true;
commandBuffer->swapchainRequested = false;
commandBuffer->isDefrag = 0; commandBuffer->isDefrag = 0;
/* Reset the command buffer here to avoid resets being called /* Reset the command buffer here to avoid resets being called
@@ -9925,6 +9947,14 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
SET_STRING_ERROR_AND_RETURN("Cannot acquire a swapchain texture from an unclaimed window!", false); SET_STRING_ERROR_AND_RETURN("Cannot acquire a swapchain texture from an unclaimed window!", false);
} }
// The command buffer is flagged for cleanup when the swapchain is requested as a cleanup timing mechanism
vulkanCommandBuffer->swapchainRequested = true;
if (window->flags & SDL_WINDOW_HIDDEN) {
// Edge case, texture is filled in with NULL but not an error
return true;
}
// If window data marked as needing swapchain recreate, try to recreate // If window data marked as needing swapchain recreate, try to recreate
if (windowData->needsSwapchainRecreate) { if (windowData->needsSwapchainRecreate) {
Uint32 recreateSwapchainResult = VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData); Uint32 recreateSwapchainResult = VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData);
@@ -9942,13 +9972,6 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
} }
} }
if (swapchainTextureWidth) {
*swapchainTextureWidth = windowData->width;
}
if (swapchainTextureHeight) {
*swapchainTextureHeight = windowData->height;
}
if (windowData->inFlightFences[windowData->frameCounter] != NULL) { if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
if (block) { if (block) {
// If we are blocking, just wait for the fence! // If we are blocking, just wait for the fence!
@@ -10000,6 +10023,14 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
} }
} }
if (swapchainTextureWidth) {
*swapchainTextureWidth = windowData->width;
}
if (swapchainTextureHeight) {
*swapchainTextureHeight = windowData->height;
}
swapchainTextureContainer = &windowData->textureContainers[swapchainImageIndex]; swapchainTextureContainer = &windowData->textureContainers[swapchainImageIndex];
// We need a special execution dependency with pWaitDstStageMask or image transition can start before acquire finishes // We need a special execution dependency with pWaitDstStageMask or image transition can start before acquire finishes
@@ -10377,6 +10408,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
commandBuffer->presentDataCount = 0; commandBuffer->presentDataCount = 0;
commandBuffer->waitSemaphoreCount = 0; commandBuffer->waitSemaphoreCount = 0;
commandBuffer->signalSemaphoreCount = 0; commandBuffer->signalSemaphoreCount = 0;
commandBuffer->swapchainRequested = false;
// Reset defrag state // Reset defrag state
@@ -10474,11 +10506,18 @@ static bool VULKAN_Wait(
VkResult result; VkResult result;
Sint32 i; Sint32 i;
SDL_LockMutex(renderer->submitLock);
result = renderer->vkDeviceWaitIdle(renderer->logicalDevice); result = renderer->vkDeviceWaitIdle(renderer->logicalDevice);
CHECK_VULKAN_ERROR_AND_RETURN(result, vkDeviceWaitIdle, false); if (result != VK_SUCCESS) {
if (renderer->debugMode) {
SDL_LockMutex(renderer->submitLock); SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s %s", "vkDeviceWaitIdle", VkErrorMessages(result));
}
SDL_SetError("%s %s", "vkDeviceWaitIdle", VkErrorMessages(result));
SDL_UnlockMutex(renderer->submitLock);
return false;
}
for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) { for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
commandBuffer = renderer->submittedCommandBuffers[i]; commandBuffer = renderer->submittedCommandBuffers[i];
@@ -10533,7 +10572,7 @@ static bool VULKAN_Submit(
VulkanTextureSubresource *swapchainTextureSubresource; VulkanTextureSubresource *swapchainTextureSubresource;
VulkanMemorySubAllocator *allocator; VulkanMemorySubAllocator *allocator;
bool performCleanups = bool performCleanups =
(renderer->claimedWindowCount > 0 && vulkanCommandBuffer->presentDataCount > 0) || (renderer->claimedWindowCount > 0 && vulkanCommandBuffer->swapchainRequested) ||
renderer->claimedWindowCount == 0; renderer->claimedWindowCount == 0;
SDL_LockMutex(renderer->submitLock); SDL_LockMutex(renderer->submitLock);
@@ -11003,7 +11042,8 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
const char **requiredExtensions, const char **requiredExtensions,
Uint32 requiredExtensionsLength, Uint32 requiredExtensionsLength,
bool *supportsDebugUtils, bool *supportsDebugUtils,
bool *supportsColorspace) bool *supportsColorspace,
bool *supportsPhysicalDeviceProperties2)
{ {
Uint32 extensionCount, i; Uint32 extensionCount, i;
VkExtensionProperties *availableExtensions; VkExtensionProperties *availableExtensions;
@@ -11042,6 +11082,12 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
availableExtensions, availableExtensions,
extensionCount); extensionCount);
// Only needed for KHR_driver_properties!
*supportsPhysicalDeviceProperties2 = SupportsInstanceExtension(
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
availableExtensions,
extensionCount);
SDL_free(availableExtensions); SDL_free(availableExtensions);
return allExtensionsSupported; return allExtensionsSupported;
} }
@@ -11152,10 +11198,6 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
instanceExtensionCount + 4); instanceExtensionCount + 4);
SDL_memcpy((void *)instanceExtensionNames, originalInstanceExtensionNames, instanceExtensionCount * sizeof(const char *)); SDL_memcpy((void *)instanceExtensionNames, originalInstanceExtensionNames, instanceExtensionCount * sizeof(const char *));
// Core since 1.1
instanceExtensionNames[instanceExtensionCount++] =
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
#ifdef SDL_PLATFORM_APPLE #ifdef SDL_PLATFORM_APPLE
instanceExtensionNames[instanceExtensionCount++] = instanceExtensionNames[instanceExtensionCount++] =
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME; VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
@@ -11166,7 +11208,8 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
instanceExtensionNames, instanceExtensionNames,
instanceExtensionCount, instanceExtensionCount,
&renderer->supportsDebugUtils, &renderer->supportsDebugUtils,
&renderer->supportsColorspace)) { &renderer->supportsColorspace,
&renderer->supportsPhysicalDeviceProperties2)) {
SDL_stack_free((char *)instanceExtensionNames); SDL_stack_free((char *)instanceExtensionNames);
SET_STRING_ERROR_AND_RETURN("Required Vulkan instance extensions not supported", false); SET_STRING_ERROR_AND_RETURN("Required Vulkan instance extensions not supported", false);
} }
@@ -11188,6 +11231,12 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME; VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME;
} }
if (renderer->supportsPhysicalDeviceProperties2) {
// Append KHR_physical_device_properties2 extension
instanceExtensionNames[instanceExtensionCount++] =
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
}
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pNext = NULL; createInfo.pNext = NULL;
createInfo.flags = createFlags; createInfo.flags = createFlags;
@@ -11694,9 +11743,10 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
renderer->allowedFramesInFlight = 2; renderer->allowedFramesInFlight = 2;
if (!VULKAN_INTERNAL_PrepareVulkan(renderer)) { if (!VULKAN_INTERNAL_PrepareVulkan(renderer)) {
SET_STRING_ERROR("Failed to initialize Vulkan!");
SDL_free(renderer); SDL_free(renderer);
SDL_Vulkan_UnloadLibrary(); SDL_Vulkan_UnloadLibrary();
SET_STRING_ERROR_AND_RETURN("Failed to initialize Vulkan!", NULL); return NULL;
} }
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Vulkan"); SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Vulkan");
@@ -11722,13 +11772,14 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
if (!VULKAN_INTERNAL_CreateLogicalDevice( if (!VULKAN_INTERNAL_CreateLogicalDevice(
renderer)) { renderer)) {
SET_STRING_ERROR("Failed to create logical device!");
SDL_free(renderer); SDL_free(renderer);
SDL_Vulkan_UnloadLibrary(); SDL_Vulkan_UnloadLibrary();
SET_STRING_ERROR_AND_RETURN("Failed to create logical device!", NULL); return NULL;
} }
// FIXME: just move this into this function // FIXME: just move this into this function
result = (SDL_GPUDevice *)SDL_malloc(sizeof(SDL_GPUDevice)); result = (SDL_GPUDevice *)SDL_calloc(1, sizeof(SDL_GPUDevice));
ASSIGN_DRIVER(VULKAN) ASSIGN_DRIVER(VULKAN)
result->driverData = (SDL_GPURenderer *)renderer; result->driverData = (SDL_GPURenderer *)renderer;
+2 -3
View File
@@ -1117,13 +1117,12 @@ bool SDL_SYS_HapticResume(SDL_Haptic *haptic)
*/ */
bool SDL_SYS_HapticStopAll(SDL_Haptic *haptic) bool SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
{ {
int i, ret; int i;
// Linux does not support this natively so we have to loop. // Linux does not support this natively so we have to loop.
for (i = 0; i < haptic->neffects; i++) { for (i = 0; i < haptic->neffects; i++) {
if (haptic->effects[i].hweffect != NULL) { if (haptic->effects[i].hweffect != NULL) {
ret = SDL_SYS_HapticStopEffect(haptic, &haptic->effects[i]); if (!SDL_SYS_HapticStopEffect(haptic, &haptic->effects[i])) {
if (ret < 0) {
return SDL_SetError("Haptic: Error while trying to stop all playing effects."); return SDL_SetError("Haptic: Error while trying to stop all playing effects.");
} }
} }
+20 -18
View File
@@ -260,19 +260,19 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
} }
if (key_cmd == 0x4) { if (key_cmd == 0x4) {
*usage_page = get_bytes(report_descriptor, size, data_len, i); *usage_page = (unsigned short)get_bytes(report_descriptor, size, data_len, i);
usage_page_found = 1; usage_page_found = 1;
//printf("Usage Page: %x\n", (uint32_t)*usage_page); //printf("Usage Page: %x\n", (uint32_t)*usage_page);
} }
if (key_cmd == 0x8) { if (key_cmd == 0x8) {
if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */ if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */
*usage_page = get_bytes(report_descriptor, size, 2, i + 2); *usage_page = (unsigned short)get_bytes(report_descriptor, size, 2, i + 2);
usage_page_found = 1; usage_page_found = 1;
*usage = get_bytes(report_descriptor, size, 2, i); *usage = (unsigned short)get_bytes(report_descriptor, size, 2, i);
usage_found = 1; usage_found = 1;
} }
else { else {
*usage = get_bytes(report_descriptor, size, data_len, i); *usage = (unsigned short)get_bytes(report_descriptor, size, data_len, i);
usage_found = 1; usage_found = 1;
} }
//printf("Usage: %x\n", (uint32_t)*usage); //printf("Usage: %x\n", (uint32_t)*usage);
@@ -640,7 +640,7 @@ static int hid_get_report_descriptor_libusb(libusb_device_handle *handle, int in
/* Get the HID Report Descriptor. /* Get the HID Report Descriptor.
See USB HID Specification, section 7.1.1 See USB HID Specification, section 7.1.1
*/ */
int res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8), interface_num, tmp, expected_report_descriptor_size, 5000); int res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8), (uint16_t)interface_num, tmp, expected_report_descriptor_size, 5000);
if (res >= 0) { if (res >= 0) {
if (res > (int)buf_size) if (res > (int)buf_size)
res = (int)buf_size; res = (int)buf_size;
@@ -671,6 +671,8 @@ static void fill_device_info_usage(struct hid_device_info *cur_dev, libusb_devic
cur_dev->usage_page = page; cur_dev->usage_page = page;
cur_dev->usage = usage; cur_dev->usage = usage;
free(hid_report_descriptor);
} }
#ifdef INVASIVE_GET_USAGE #ifdef INVASIVE_GET_USAGE
@@ -1191,7 +1193,7 @@ static void *read_thread(void *param)
dev->transfer = libusb_alloc_transfer(0); dev->transfer = libusb_alloc_transfer(0);
libusb_fill_interrupt_transfer(dev->transfer, libusb_fill_interrupt_transfer(dev->transfer,
dev->device_handle, dev->device_handle,
dev->input_endpoint, (unsigned char)dev->input_endpoint,
buf, buf,
(int) length, (int) length,
read_callback, read_callback,
@@ -1610,8 +1612,8 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
res = libusb_control_transfer(dev->device_handle, res = libusb_control_transfer(dev->device_handle,
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
0x09/*HID Set_Report*/, 0x09/*HID Set_Report*/,
(2/*HID output*/ << 8) | report_number, (uint16_t)((2/*HID output*/ << 8) | report_number),
dev->interface, (uint16_t)dev->interface,
(unsigned char *)data, (uint16_t)length, (unsigned char *)data, (uint16_t)length,
1000/*timeout millis*/); 1000/*timeout millis*/);
@@ -1627,7 +1629,7 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
/* Use the interrupt out endpoint */ /* Use the interrupt out endpoint */
int actual_length; int actual_length;
res = libusb_interrupt_transfer(dev->device_handle, res = libusb_interrupt_transfer(dev->device_handle,
dev->output_endpoint, (unsigned char)dev->output_endpoint,
(unsigned char*)data, (unsigned char*)data,
(int) length, (int) length,
&actual_length, 1000); &actual_length, 1000);
@@ -1776,8 +1778,8 @@ int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char
res = libusb_control_transfer(dev->device_handle, res = libusb_control_transfer(dev->device_handle,
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
0x09/*HID set_report*/, 0x09/*HID set_report*/,
(3/*HID feature*/ << 8) | report_number, (uint16_t)((3/*HID feature*/ << 8) | report_number),
dev->interface, (uint16_t)dev->interface,
(unsigned char *)data, (uint16_t)length, (unsigned char *)data, (uint16_t)length,
1000/*timeout millis*/); 1000/*timeout millis*/);
@@ -1807,8 +1809,8 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
res = libusb_control_transfer(dev->device_handle, res = libusb_control_transfer(dev->device_handle,
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
0x01/*HID get_report*/, 0x01/*HID get_report*/,
(3/*HID feature*/ << 8) | report_number, (uint16_t)((3/*HID feature*/ << 8) | report_number),
dev->interface, (uint16_t)dev->interface,
(unsigned char *)data, (uint16_t)length, (unsigned char *)data, (uint16_t)length,
1000/*timeout millis*/); 1000/*timeout millis*/);
@@ -1837,8 +1839,8 @@ int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned c
res = libusb_control_transfer(dev->device_handle, res = libusb_control_transfer(dev->device_handle,
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
0x01/*HID get_report*/, 0x01/*HID get_report*/,
(1/*HID Input*/ << 8) | report_number, (uint16_t)((1/*HID Input*/ << 8) | report_number),
dev->interface, (uint16_t)dev->interface,
(unsigned char *)data, (uint16_t)length, (unsigned char *)data, (uint16_t)length,
1000/*timeout millis*/); 1000/*timeout millis*/);
@@ -1930,7 +1932,7 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index
{ {
wchar_t *str; wchar_t *str;
str = get_usb_string(dev->device_handle, string_index); str = get_usb_string(dev->device_handle, (uint8_t)string_index);
if (str) { if (str) {
wcsncpy(string, str, maxlen); wcsncpy(string, str, maxlen);
string[maxlen-1] = L'\0'; string[maxlen-1] = L'\0';
@@ -2118,7 +2120,7 @@ uint16_t get_usb_code_for_current_locale(void)
/* Chop off the encoding part, and make it lower case. */ /* Chop off the encoding part, and make it lower case. */
ptr = search_string; ptr = search_string;
while (*ptr) { while (*ptr) {
*ptr = tolower(*ptr); *ptr = (char)tolower(*ptr);
if (*ptr == '.') { if (*ptr == '.') {
*ptr = '\0'; *ptr = '\0';
break; break;
@@ -2139,7 +2141,7 @@ uint16_t get_usb_code_for_current_locale(void)
/* Chop off the variant. Chop it off at the '_'. */ /* Chop off the variant. Chop it off at the '_'. */
ptr = search_string; ptr = search_string;
while (*ptr) { while (*ptr) {
*ptr = tolower(*ptr); *ptr = (char)tolower(*ptr);
if (*ptr == '_') { if (*ptr == '_') {
*ptr = '\0'; *ptr = '\0';
break; break;
+1 -1
View File
@@ -134,7 +134,6 @@ static wchar_t *utf8_to_wchar_t(const char *utf8)
* Use register_error_str(NULL) to free the error message completely. */ * Use register_error_str(NULL) to free the error message completely. */
static void register_error_str(wchar_t **error_str, const char *msg) static void register_error_str(wchar_t **error_str, const char *msg)
{ {
free(*error_str);
#ifdef HIDAPI_USING_SDL_RUNTIME #ifdef HIDAPI_USING_SDL_RUNTIME
/* Thread-safe error handling */ /* Thread-safe error handling */
if (msg) { if (msg) {
@@ -143,6 +142,7 @@ static void register_error_str(wchar_t **error_str, const char *msg)
SDL_ClearError(); SDL_ClearError();
} }
#else #else
free(*error_str);
*error_str = utf8_to_wchar_t(msg); *error_str = utf8_to_wchar_t(msg);
#endif #endif
} }
+5
View File
@@ -1399,6 +1399,11 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char
} }
} }
if (!res) { if (!res) {
if (GetLastError() == ERROR_OPERATION_ABORTED) {
/* The read request was issued on another thread.
This is harmless, so just ignore it. */
return 0;
}
register_winapi_error(dev, L"hid_read_timeout/GetOverlappedResult"); register_winapi_error(dev, L"hid_read_timeout/GetOverlappedResult");
} }
+2 -1
View File
@@ -455,7 +455,8 @@ static bool SDLCALL fd_flush(void *userdata, SDL_IOStatus *status)
result = SDL_fdatasync(iodata->fd); result = SDL_fdatasync(iodata->fd);
} while (result < 0 && errno == EINTR); } while (result < 0 && errno == EINTR);
if (result < 0) { // We get EINVAL when flushing a pipe, just make that a no-op
if (result < 0 && errno != EINVAL) {
return SDL_SetError("Error flushing datastream: %s", strerror(errno)); return SDL_SetError("Error flushing datastream: %s", strerror(errno));
} }
return true; return true;
+3 -3
View File
@@ -311,7 +311,7 @@ void SDL_PrivateGamepadAdded(SDL_JoystickID instance_id)
{ {
SDL_Event event; SDL_Event event;
if (!SDL_gamepads_initialized) { if (!SDL_gamepads_initialized || SDL_IsJoystickBeingAdded()) {
return; return;
} }
@@ -2683,8 +2683,8 @@ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version
} }
#endif #endif
if (name && SDL_strcmp(name, "uinput-fpc") == 0) { if (name && SDL_startswith(name, "uinput-")) {
// The Google Pixel fingerprint sensor reports itself as a joystick // The Google Pixel fingerprint sensor, as well as other fingerprint sensors, reports itself as a joystick
return true; return true;
} }
+6 -1
View File
@@ -278,6 +278,7 @@ static Uint32 initial_blacklist_devices[] = {
MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller
MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only) MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only)
MAKE_VIDPID(0x3434, 0x0211), // Keychron K1 Pro System Control MAKE_VIDPID(0x3434, 0x0211), // Keychron K1 Pro System Control
MAKE_VIDPID(0x04f2, 0xa13c), // HP Deluxe Webcam KQ246AA
}; };
static SDL_vidpid_list blacklist_devices = { static SDL_vidpid_list blacklist_devices = {
SDL_HINT_JOYSTICK_BLACKLIST_DEVICES, 0, 0, NULL, SDL_HINT_JOYSTICK_BLACKLIST_DEVICES, 0, 0, NULL,
@@ -2143,6 +2144,7 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id)
SDL_JoystickDriver *driver; SDL_JoystickDriver *driver;
int device_index; int device_index;
int player_index = -1; int player_index = -1;
bool is_gamepad;
SDL_AssertJoysticksLocked(); SDL_AssertJoysticksLocked();
@@ -2177,9 +2179,12 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id)
} }
} }
// This might create an automatic gamepad mapping, so wait to send the event
is_gamepad = SDL_IsGamepad(instance_id);
SDL_joystick_being_added = false; SDL_joystick_being_added = false;
if (SDL_IsGamepad(instance_id)) { if (is_gamepad) {
SDL_PrivateGamepadAdded(instance_id); SDL_PrivateGamepadAdded(instance_id);
} }
} }
+4
View File
@@ -328,6 +328,10 @@ void Android_AddJoystick(int device_id, const char *name, const char *desc, int
goto done; goto done;
} }
if (SDL_ShouldIgnoreJoystick(vendor_id, product_id, 0, name)) {
goto done;
}
#ifdef DEBUG_JOYSTICK #ifdef DEBUG_JOYSTICK
SDL_Log("Joystick: %s, descriptor %s, vendor = 0x%.4x, product = 0x%.4x, %d axes, %d hats", name, desc, vendor_id, product_id, naxes, nhats); SDL_Log("Joystick: %s, descriptor %s, vendor = 0x%.4x, product = 0x%.4x, %d axes, %d hats", name, desc, vendor_id, product_id, naxes, nhats);
#endif #endif
+8 -2
View File
@@ -300,8 +300,14 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
* struct, and ARC doesn't work with structs. */ * struct, and ARC doesn't work with structs. */
device->controller = (__bridge GCController *)CFBridgingRetain(controller); device->controller = (__bridge GCController *)CFBridgingRetain(controller);
if (controller.vendorName) { if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
name = controller.vendorName.UTF8String; if (controller.productCategory) {
name = controller.productCategory.UTF8String;
}
} else {
if (controller.vendorName) {
name = controller.vendorName.UTF8String;
}
} }
if (!name) { if (!name) {
-1
View File
@@ -21,7 +21,6 @@
static const ControllerDescription_t arrControllers[] = { static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x0079, 0x181a ), k_eControllerType_PS3Controller, NULL }, // Venom Arcade Stick { MAKE_CONTROLLER_ID( 0x0079, 0x181a ), k_eControllerType_PS3Controller, NULL }, // Venom Arcade Stick
{ MAKE_CONTROLLER_ID( 0x0079, 0x1844 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller, NULL }, // Firestorm Dual Analog 3 { MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller, NULL }, // Firestorm Dual Analog 3
{ MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller, NULL }, // Thrustmaster wireless 3-1 { MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller, NULL }, // Thrustmaster wireless 3-1
{ MAKE_CONTROLLER_ID( 0x046d, 0xcad1 ), k_eControllerType_PS3Controller, NULL }, // Logitech Chillstream { MAKE_CONTROLLER_ID( 0x046d, 0xcad1 ), k_eControllerType_PS3Controller, NULL }, // Logitech Chillstream
+40 -1
View File
@@ -305,6 +305,7 @@ static SDL_JoystickID EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index)
static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index) static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index)
{ {
SDL_joylist_item *item = JoystickByDeviceIndex(device_index); SDL_joylist_item *item = JoystickByDeviceIndex(device_index);
bool rumble_available = false;
if (!item) { if (!item) {
return SDL_SetError("No such device"); return SDL_SetError("No such device");
@@ -323,6 +324,22 @@ static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index)
joystick->nbuttons = item->nbuttons; joystick->nbuttons = item->nbuttons;
joystick->naxes = item->naxes; joystick->naxes = item->naxes;
rumble_available = EM_ASM_INT({
let gamepads = navigator['getGamepads']();
if (!gamepads) {
return 0;
}
let gamepad = gamepads[$0];
if (!gamepad || !gamepad['vibrationActuator']) {
return 0;
}
return 1;
}, item->index);
if (rumble_available) {
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, true);
}
return true; return true;
} }
@@ -390,7 +407,29 @@ static SDL_GUID EMSCRIPTEN_JoystickGetDeviceGUID(int device_index)
static bool EMSCRIPTEN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) static bool EMSCRIPTEN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata;
// clang-format off
bool result = EM_ASM_INT({
let gamepads = navigator['getGamepads']();
if (!gamepads) {
return 0;
}
let gamepad = gamepads[$0];
if (!gamepad || !gamepad['vibrationActuator']) {
return 0;
}
gamepad['vibrationActuator']['playEffect']('dual-rumble', {
'startDelay': 0,
'duration': 3000,
'weakMagnitude': $1 / 0xFFFF,
'strongMagnitude': $2 / 0xFFFF,
});
return 1;
}, item->index, low_frequency_rumble, high_frequency_rumble);
return result;
} }
static bool EMSCRIPTEN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) static bool EMSCRIPTEN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
+18 -6
View File
@@ -251,6 +251,7 @@ typedef struct
Uint64 last_packet; Uint64 last_packet;
int player_index; int player_index;
bool player_lights; bool player_lights;
bool enhanced_rumble;
Uint8 rumble_left; Uint8 rumble_left;
Uint8 rumble_right; Uint8 rumble_right;
bool color_set; bool color_set;
@@ -432,6 +433,14 @@ static bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device)
} }
} }
if (device->vendor_id == USB_VENDOR_SONY) {
if (device->product_id == USB_PRODUCT_SONY_DS5_EDGE ||
ctx->firmware_version == 0 || // Assume that it's updated firmware over Bluetooth
ctx->firmware_version >= 0x0224) {
ctx->enhanced_rumble = true;
}
}
// Get the device capabilities // Get the device capabilities
if (device->vendor_id == USB_VENDOR_SONY) { if (device->vendor_id == USB_VENDOR_SONY) {
ctx->sensors_supported = true; ctx->sensors_supported = true;
@@ -684,17 +693,17 @@ static bool HIDAPI_DriverPS5_UpdateEffects(SDL_DriverPS5_Context *ctx, int effec
if (ctx->vibration_supported) { if (ctx->vibration_supported) {
if (ctx->rumble_left || ctx->rumble_right) { if (ctx->rumble_left || ctx->rumble_right) {
if (ctx->firmware_version < 0x0224) { if (ctx->enhanced_rumble) {
effects.ucEnableBits3 |= 0x04; // Enable improved rumble emulation on 2.24 firmware and newer
effects.ucRumbleLeft = ctx->rumble_left;
effects.ucRumbleRight = ctx->rumble_right;
} else {
effects.ucEnableBits1 |= 0x01; // Enable rumble emulation effects.ucEnableBits1 |= 0x01; // Enable rumble emulation
// Shift to reduce effective rumble strength to match Xbox controllers // Shift to reduce effective rumble strength to match Xbox controllers
effects.ucRumbleLeft = ctx->rumble_left >> 1; effects.ucRumbleLeft = ctx->rumble_left >> 1;
effects.ucRumbleRight = ctx->rumble_right >> 1; effects.ucRumbleRight = ctx->rumble_right >> 1;
} else {
effects.ucEnableBits3 |= 0x04; // Enable improved rumble emulation on 2.24 firmware and newer
effects.ucRumbleLeft = ctx->rumble_left;
effects.ucRumbleRight = ctx->rumble_right;
} }
effects.ucEnableBits1 |= 0x02; // Disable audio haptics effects.ucEnableBits1 |= 0x02; // Disable audio haptics
} else { } else {
@@ -1038,6 +1047,9 @@ static bool HIDAPI_DriverPS5_InternalSendJoystickEffect(SDL_DriverPS5_Context *c
if (!ctx->enhanced_mode) { if (!ctx->enhanced_mode) {
if (application_usage) { if (application_usage) {
HIDAPI_DriverPS5_UpdateEnhancedModeOnApplicationUsage(ctx); HIDAPI_DriverPS5_UpdateEnhancedModeOnApplicationUsage(ctx);
// Wait briefly before sending additional effects
SDL_Delay(10);
} }
if (!ctx->enhanced_mode) { if (!ctx->enhanced_mode) {
+5
View File
@@ -1038,6 +1038,11 @@ static bool HIDAPI_DriverSteam_IsSupportedDevice(SDL_HIDAPI_Device *device, cons
return false; return false;
} }
if (!device) {
// Might be supported by this driver, enumerate and find out
return true;
}
if (device->is_bluetooth) { if (device->is_bluetooth) {
return true; return true;
} }
+1 -1
View File
@@ -471,7 +471,7 @@ bool SDL_SendJoystickVirtualSensorDataInner(SDL_Joystick *joystick, SDL_SensorTy
return false; return false;
} }
hwdata->sensor_events = sensor_events; hwdata->sensor_events = sensor_events;
hwdata->max_sensor_events = hwdata->max_sensor_events; hwdata->max_sensor_events = new_max_sensor_events;
} }
VirtualSensorEvent *event = &hwdata->sensor_events[hwdata->num_sensor_events++]; VirtualSensorEvent *event = &hwdata->sensor_events[hwdata->num_sensor_events++];
@@ -585,7 +585,7 @@ static bool WGI_JoystickInit(void)
{ {
HRESULT hr; HRESULT hr;
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, true)) { if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, false)) {
return true; return true;
} }
+11
View File
@@ -43,6 +43,17 @@ static SDLIosMainCallbacksDisplayLink *globalDisplayLink;
{ {
if ((self = [super init])) { if ((self = [super init])) {
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(appIteration:)]; self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(appIteration:)];
// Enable high refresh rates on iOS
// To enable this on phones, you should add the following line to Info.plist:
// <key>CADisableMinimumFrameDurationOnPhone</key> <true/>
// If main callbacks are used then this CADisplayLink will affect framerate, not one in SDL_uikitviewcontroller.
if (@available(iOS 15.0, tvOS 15.0, *)) {
const SDL_DisplayMode *mode = SDL_GetDesktopDisplayMode(SDL_GetPrimaryDisplay());
if (mode && mode->refresh_rate > 60.0f) {
int frame_rate = (int)mode->refresh_rate;
self.displayLink.preferredFrameRateRange = CAFrameRateRangeMake((frame_rate * 2) / 3, frame_rate, frame_rate);
}
}
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
} }
return self; return self;
-94
View File
@@ -2737,94 +2737,6 @@ bool SDL_GetRenderLogicalPresentationRect(SDL_Renderer *renderer, SDL_FRect *rec
return true; return true;
} }
static void SDL_RenderLogicalBorders(SDL_Renderer *renderer, const SDL_FRect *dst)
{
const SDL_RenderViewState *view = renderer->view;
if (dst->x > 0.0f || dst->y > 0.0f) {
SDL_BlendMode saved_blend_mode = renderer->blendMode;
SDL_FColor saved_color = renderer->color;
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColorFloat(renderer, 0.0f, 0.0f, 0.0f, 1.0f);
if (dst->x > 0.0f) {
SDL_FRect rect;
rect.x = 0.0f;
rect.y = 0.0f;
rect.w = dst->x;
rect.h = (float)view->pixel_h;
SDL_RenderFillRect(renderer, &rect);
rect.x = dst->x + dst->w;
rect.w = (float)view->pixel_w - rect.x;
SDL_RenderFillRect(renderer, &rect);
}
if (dst->y > 0.0f) {
SDL_FRect rect;
rect.x = 0.0f;
rect.y = 0.0f;
rect.w = (float)view->pixel_w;
rect.h = dst->y;
SDL_RenderFillRect(renderer, &rect);
rect.y = dst->y + dst->h;
rect.h = (float)view->pixel_h - rect.y;
SDL_RenderFillRect(renderer, &rect);
}
SDL_SetRenderDrawBlendMode(renderer, saved_blend_mode);
SDL_SetRenderDrawColorFloat(renderer, saved_color.r, saved_color.g, saved_color.b, saved_color.a);
}
}
static void SDL_RenderLogicalPresentation(SDL_Renderer *renderer)
{
SDL_assert(renderer->view == &renderer->main_view);
SDL_RenderViewState *view = &renderer->main_view;
const SDL_RendererLogicalPresentation mode = view->logical_presentation_mode;
if (mode == SDL_LOGICAL_PRESENTATION_LETTERBOX) {
// save off some state we're going to trample.
const int logical_w = view->logical_w;
const int logical_h = view->logical_h;
const float scale_x = view->scale.x;
const float scale_y = view->scale.y;
const bool clipping_enabled = view->clipping_enabled;
SDL_Rect orig_viewport, orig_cliprect;
const SDL_FRect logical_dst_rect = view->logical_dst_rect;
SDL_copyp(&orig_viewport, &view->viewport);
if (clipping_enabled) {
SDL_copyp(&orig_cliprect, &view->clip_rect);
}
// trample some state.
SDL_SetRenderLogicalPresentation(renderer, logical_w, logical_h, SDL_LOGICAL_PRESENTATION_DISABLED);
SDL_SetRenderViewport(renderer, NULL);
if (clipping_enabled) {
SDL_SetRenderClipRect(renderer, NULL);
}
SDL_SetRenderScale(renderer, 1.0f, 1.0f);
// draw the borders.
SDL_RenderLogicalBorders(renderer, &logical_dst_rect);
// now set everything back.
view->logical_presentation_mode = mode;
SDL_SetRenderViewport(renderer, &orig_viewport);
if (clipping_enabled) {
SDL_SetRenderClipRect(renderer, &orig_cliprect);
}
SDL_SetRenderScale(renderer, scale_x, scale_y);
SDL_SetRenderLogicalPresentation(renderer, logical_w, logical_h, mode);
}
}
static bool SDL_RenderVectorFromWindow(SDL_Renderer *renderer, float window_dx, float window_dy, float *dx, float *dy) static bool SDL_RenderVectorFromWindow(SDL_Renderer *renderer, float window_dx, float window_dy, float *dx, float *dy)
{ {
// Convert from window coordinates to pixels within the window // Convert from window coordinates to pixels within the window
@@ -3306,10 +3218,6 @@ bool SDL_SetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
return SDL_InvalidParamError("blendMode"); return SDL_InvalidParamError("blendMode");
} }
if (blendMode == SDL_BLENDMODE_INVALID) {
return SDL_InvalidParamError("blendMode");
}
if (!IsSupportedBlendMode(renderer, blendMode)) { if (!IsSupportedBlendMode(renderer, blendMode)) {
return SDL_Unsupported(); return SDL_Unsupported();
} }
@@ -5140,8 +5048,6 @@ bool SDL_RenderPresent(SDL_Renderer *renderer)
SDL_SetRenderTarget(renderer, NULL); SDL_SetRenderTarget(renderer, NULL);
} }
SDL_RenderLogicalPresentation(renderer);
if (renderer->transparent_window) { if (renderer->transparent_window) {
SDL_RenderApplyWindowShape(renderer); SDL_RenderApplyWindowShape(renderer);
} }
+2
View File
@@ -620,6 +620,8 @@ static bool InitVertexBuffer(GPU_RenderData *data, Uint32 size)
return false; return false;
} }
data->vertices.buffer_size = size;
return true; return true;
} }
+48 -37
View File
@@ -439,6 +439,40 @@ static bool convert_format(Uint32 pixel_format, GLint *internalFormat, GLenum *f
return true; return true;
} }
static bool SetTextureScaleMode(GL_RenderData *data, GLenum textype, SDL_ScaleMode scaleMode)
{
switch (scaleMode) {
case SDL_SCALEMODE_NEAREST:
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
break;
case SDL_SCALEMODE_LINEAR:
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
break;
default:
return SDL_SetError("Unknown texture scale mode: %d", scaleMode);
}
return true;
}
static bool SetTextureAddressMode(GL_RenderData *data, GLenum textype, SDL_TextureAddressMode addressMode)
{
switch (addressMode) {
case SDL_TEXTURE_ADDRESS_CLAMP:
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;
case SDL_TEXTURE_ADDRESS_WRAP:
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_REPEAT);
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_REPEAT);
break;
default:
return SDL_SetError("Unknown texture address mode: %d", addressMode);
}
return true;
}
static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props) static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props)
{ {
GL_RenderData *renderdata = (GL_RenderData *)renderer->internal; GL_RenderData *renderdata = (GL_RenderData *)renderer->internal;
@@ -535,10 +569,12 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
data->format = format; data->format = format;
data->formattype = type; data->formattype = type;
data->texture_scale_mode = SDL_SCALEMODE_INVALID; data->texture_scale_mode = texture->scaleMode;
data->texture_address_mode = SDL_TEXTURE_ADDRESS_INVALID; data->texture_address_mode = SDL_TEXTURE_ADDRESS_CLAMP;
renderdata->glEnable(textype); renderdata->glEnable(textype);
renderdata->glBindTexture(textype, data->texture); renderdata->glBindTexture(textype, data->texture);
SetTextureScaleMode(renderdata, textype, data->texture_scale_mode);
SetTextureAddressMode(renderdata, textype, data->texture_address_mode);
#ifdef SDL_PLATFORM_MACOS #ifdef SDL_PLATFORM_MACOS
#ifndef GL_TEXTURE_STORAGE_HINT_APPLE #ifndef GL_TEXTURE_STORAGE_HINT_APPLE
#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
@@ -570,10 +606,11 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
renderdata->glTexImage2D(textype, 0, internalFormat, texture_w, renderdata->glTexImage2D(textype, 0, internalFormat, texture_w,
texture_h, 0, format, type, NULL); texture_h, 0, format, type, NULL);
} }
renderdata->glDisable(textype);
if (!GL_CheckError("glTexImage2D()", renderer)) { if (!GL_CheckError("glTexImage2D()", renderer)) {
return false; return false;
} }
SetTextureScaleMode(renderdata, textype, data->texture_scale_mode);
SetTextureAddressMode(renderdata, textype, data->texture_address_mode);
#ifdef SDL_HAVE_YUV #ifdef SDL_HAVE_YUV
if (texture->format == SDL_PIXELFORMAT_YV12 || if (texture->format == SDL_PIXELFORMAT_YV12 ||
@@ -596,11 +633,15 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
renderdata->glBindTexture(textype, data->utexture); renderdata->glBindTexture(textype, data->utexture);
renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2, renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2,
(texture_h + 1) / 2, 0, format, type, NULL); (texture_h + 1) / 2, 0, format, type, NULL);
SetTextureScaleMode(renderdata, textype, data->texture_scale_mode);
SetTextureAddressMode(renderdata, textype, data->texture_address_mode);
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_U_NUMBER, data->utexture); SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_U_NUMBER, data->utexture);
renderdata->glBindTexture(textype, data->vtexture); renderdata->glBindTexture(textype, data->vtexture);
renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2, renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2,
(texture_h + 1) / 2, 0, format, type, NULL); (texture_h + 1) / 2, 0, format, type, NULL);
SetTextureScaleMode(renderdata, textype, data->texture_scale_mode);
SetTextureAddressMode(renderdata, textype, data->texture_address_mode);
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_V_NUMBER, data->vtexture); SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_V_NUMBER, data->vtexture);
} }
@@ -617,6 +658,8 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
renderdata->glBindTexture(textype, data->utexture); renderdata->glBindTexture(textype, data->utexture);
renderdata->glTexImage2D(textype, 0, GL_LUMINANCE_ALPHA, (texture_w + 1) / 2, renderdata->glTexImage2D(textype, 0, GL_LUMINANCE_ALPHA, (texture_w + 1) / 2,
(texture_h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); (texture_h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
SetTextureScaleMode(renderdata, textype, data->texture_scale_mode);
SetTextureAddressMode(renderdata, textype, data->texture_address_mode);
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_UV_NUMBER, data->utexture); SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_UV_NUMBER, data->utexture);
} }
#endif #endif
@@ -651,6 +694,8 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
} }
#endif // SDL_HAVE_YUV #endif // SDL_HAVE_YUV
renderdata->glDisable(textype);
return GL_CheckError("", renderer); return GL_CheckError("", renderer);
} }
@@ -1074,40 +1119,6 @@ static bool SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, cons
return true; return true;
} }
static bool SetTextureScaleMode(GL_RenderData *data, GLenum textype, SDL_ScaleMode scaleMode)
{
switch (scaleMode) {
case SDL_SCALEMODE_NEAREST:
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
break;
case SDL_SCALEMODE_LINEAR:
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
break;
default:
return SDL_SetError("Unknown texture scale mode: %d", scaleMode);
}
return true;
}
static bool SetTextureAddressMode(GL_RenderData *data, GLenum textype, SDL_TextureAddressMode addressMode)
{
switch (addressMode) {
case SDL_TEXTURE_ADDRESS_CLAMP:
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;
case SDL_TEXTURE_ADDRESS_WRAP:
data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_REPEAT);
data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_REPEAT);
break;
default:
return SDL_SetError("Unknown texture address mode: %d", addressMode);
}
return true;
}
static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd) static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
{ {
SDL_Texture *texture = cmd->data.draw.texture; SDL_Texture *texture = cmd->data.draw.texture;
+31 -2
View File
@@ -1616,8 +1616,8 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
data->texture_u = 0; data->texture_u = 0;
data->texture_v = 0; data->texture_v = 0;
#endif #endif
data->texture_scale_mode = SDL_SCALEMODE_INVALID; data->texture_scale_mode = texture->scaleMode;
data->texture_address_mode = SDL_TEXTURE_ADDRESS_INVALID; data->texture_address_mode = SDL_TEXTURE_ADDRESS_CLAMP;
// Allocate a blob for image renderdata // Allocate a blob for image renderdata
if (texture->access == SDL_TEXTUREACCESS_STREAMING) { if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
@@ -1651,12 +1651,21 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
} else { } else {
renderdata->glGenTextures(1, &data->texture_v); renderdata->glGenTextures(1, &data->texture_v);
if (!GL_CheckError("glGenTexures()", renderer)) { if (!GL_CheckError("glGenTexures()", renderer)) {
SDL_free(data->pixel_data);
SDL_free(data);
return false; return false;
} }
} }
renderdata->glActiveTexture(GL_TEXTURE2); renderdata->glActiveTexture(GL_TEXTURE2);
renderdata->glBindTexture(data->texture_type, data->texture_v); renderdata->glBindTexture(data->texture_type, data->texture_v);
renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL);
if (!GL_CheckError("glTexImage2D()", renderer)) {
SDL_free(data->pixel_data);
SDL_free(data);
return false;
}
SetTextureScaleMode(renderdata, data->texture_type, data->texture_scale_mode);
SetTextureAddressMode(renderdata, data->texture_type, data->texture_address_mode);
SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_V_NUMBER, data->texture_v); SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_V_NUMBER, data->texture_v);
data->texture_u = (GLuint)SDL_GetNumberProperty(create_props, SDL_PROP_TEXTURE_CREATE_OPENGLES2_TEXTURE_U_NUMBER, 0); data->texture_u = (GLuint)SDL_GetNumberProperty(create_props, SDL_PROP_TEXTURE_CREATE_OPENGLES2_TEXTURE_U_NUMBER, 0);
@@ -1665,6 +1674,8 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
} else { } else {
renderdata->glGenTextures(1, &data->texture_u); renderdata->glGenTextures(1, &data->texture_u);
if (!GL_CheckError("glGenTexures()", renderer)) { if (!GL_CheckError("glGenTexures()", renderer)) {
SDL_free(data->pixel_data);
SDL_free(data);
return false; return false;
} }
} }
@@ -1672,11 +1683,17 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
renderdata->glBindTexture(data->texture_type, data->texture_u); renderdata->glBindTexture(data->texture_type, data->texture_u);
renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL);
if (!GL_CheckError("glTexImage2D()", renderer)) { if (!GL_CheckError("glTexImage2D()", renderer)) {
SDL_free(data->pixel_data);
SDL_free(data);
return false; return false;
} }
SetTextureScaleMode(renderdata, data->texture_type, data->texture_scale_mode);
SetTextureAddressMode(renderdata, data->texture_type, data->texture_address_mode);
SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_U_NUMBER, data->texture_u); SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_U_NUMBER, data->texture_u);
if (!SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8)) { if (!SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8)) {
SDL_free(data->pixel_data);
SDL_free(data);
return SDL_SetError("Unsupported YUV colorspace"); return SDL_SetError("Unsupported YUV colorspace");
} }
} else if (data->nv12) { } else if (data->nv12) {
@@ -1686,6 +1703,8 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
} else { } else {
renderdata->glGenTextures(1, &data->texture_u); renderdata->glGenTextures(1, &data->texture_u);
if (!GL_CheckError("glGenTexures()", renderer)) { if (!GL_CheckError("glGenTexures()", renderer)) {
SDL_free(data->pixel_data);
SDL_free(data);
return false; return false;
} }
} }
@@ -1693,11 +1712,17 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
renderdata->glBindTexture(data->texture_type, data->texture_u); renderdata->glBindTexture(data->texture_type, data->texture_u);
renderdata->glTexImage2D(data->texture_type, 0, GL_LUMINANCE_ALPHA, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); renderdata->glTexImage2D(data->texture_type, 0, GL_LUMINANCE_ALPHA, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
if (!GL_CheckError("glTexImage2D()", renderer)) { if (!GL_CheckError("glTexImage2D()", renderer)) {
SDL_free(data->pixel_data);
SDL_free(data);
return false; return false;
} }
SetTextureScaleMode(renderdata, data->texture_type, data->texture_scale_mode);
SetTextureAddressMode(renderdata, data->texture_type, data->texture_address_mode);
SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_UV_NUMBER, data->texture_u); SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_UV_NUMBER, data->texture_u);
if (!SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8)) { if (!SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8)) {
SDL_free(data->pixel_data);
SDL_free(data);
return SDL_SetError("Unsupported YUV colorspace"); return SDL_SetError("Unsupported YUV colorspace");
} }
} }
@@ -1709,6 +1734,8 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
} else { } else {
renderdata->glGenTextures(1, &data->texture); renderdata->glGenTextures(1, &data->texture);
if (!GL_CheckError("glGenTexures()", renderer)) { if (!GL_CheckError("glGenTexures()", renderer)) {
SDL_free(data->pixel_data);
SDL_free(data);
return false; return false;
} }
} }
@@ -1721,6 +1748,8 @@ static bool GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
return false; return false;
} }
} }
SetTextureScaleMode(renderdata, data->texture_type, data->texture_scale_mode);
SetTextureAddressMode(renderdata, data->texture_type, data->texture_address_mode);
SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_NUMBER, data->texture); SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_NUMBER, data->texture);
SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER, data->texture_type); SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER, data->texture_type);
+23 -10
View File
@@ -421,7 +421,7 @@ static int VULKAN_VkFormatGetNumPlanes(VkFormat vkFormat)
} }
} }
static VkDeviceSize VULKAN_GetBytesPerPixel(VkFormat vkFormat) static VkDeviceSize VULKAN_GetBytesPerPixel(VkFormat vkFormat, int plane)
{ {
switch (vkFormat) { switch (vkFormat) {
case VK_FORMAT_R8_UNORM: case VK_FORMAT_R8_UNORM:
@@ -436,6 +436,10 @@ static VkDeviceSize VULKAN_GetBytesPerPixel(VkFormat vkFormat)
return 4; return 4;
case VK_FORMAT_R16G16B16A16_SFLOAT: case VK_FORMAT_R16G16B16A16_SFLOAT:
return 8; return 8;
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
return 1;
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
return (plane == 0) ? 1 : 2;
default: default:
return 4; return 4;
} }
@@ -2738,7 +2742,7 @@ static bool VULKAN_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, S
} }
SDL_PropertiesID props = SDL_GetTextureProperties(texture); SDL_PropertiesID props = SDL_GetTextureProperties(texture);
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_VULKAN_TEXTURE_NUMBER, (Sint64)textureData->mainImage.image); SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_VULKAN_TEXTURE_NUMBER, (Sint64)textureData->mainImage.image);
if (texture->access == SDL_TEXTUREACCESS_TARGET) { if (texture->access == SDL_TEXTUREACCESS_TARGET) {
result = VULKAN_CreateFramebuffersAndRenderPasses(renderer, result = VULKAN_CreateFramebuffersAndRenderPasses(renderer,
@@ -2811,7 +2815,7 @@ static void VULKAN_DestroyTexture(SDL_Renderer *renderer,
static bool VULKAN_UpdateTextureInternal(VULKAN_RenderData *rendererData, VkImage image, VkFormat format, int plane, int x, int y, int w, int h, const void *pixels, int pitch, VkImageLayout *imageLayout) static bool VULKAN_UpdateTextureInternal(VULKAN_RenderData *rendererData, VkImage image, VkFormat format, int plane, int x, int y, int w, int h, const void *pixels, int pitch, VkImageLayout *imageLayout)
{ {
VkDeviceSize pixelSize = VULKAN_GetBytesPerPixel(format); VkDeviceSize pixelSize = VULKAN_GetBytesPerPixel(format, plane);
VkDeviceSize length = w * pixelSize; VkDeviceSize length = w * pixelSize;
VkDeviceSize uploadBufferSize = length * h; VkDeviceSize uploadBufferSize = length * h;
const Uint8 *src; const Uint8 *src;
@@ -2964,11 +2968,20 @@ static bool VULKAN_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture
if (!VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 0, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch, &textureData->mainImage.imageLayout)) { if (!VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 0, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch, &textureData->mainImage.imageLayout)) {
return false; return false;
} }
if (!VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 1, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Uplane, Upitch, &textureData->mainImage.imageLayout)) { if (texture->format == SDL_PIXELFORMAT_YV12) {
return false; if (!VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 1, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, Vplane, Vpitch, &textureData->mainImage.imageLayout)) {
} return false;
if (!VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 2, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Vplane, Vpitch, &textureData->mainImage.imageLayout)) { }
return false; if (!VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 2, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, Uplane, Upitch, &textureData->mainImage.imageLayout)) {
return false;
}
} else {
if (!VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 1, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, Uplane, Upitch, &textureData->mainImage.imageLayout)) {
return false;
}
if (!VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 2, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, Vplane, Vpitch, &textureData->mainImage.imageLayout)) {
return false;
}
} }
return true; return true;
} }
@@ -3010,7 +3023,7 @@ static bool VULKAN_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
return SDL_SetError("texture is already locked"); return SDL_SetError("texture is already locked");
} }
VkDeviceSize pixelSize = VULKAN_GetBytesPerPixel(textureData->mainImage.format); VkDeviceSize pixelSize = VULKAN_GetBytesPerPixel(textureData->mainImage.format, 0);
VkDeviceSize length = rect->w * pixelSize; VkDeviceSize length = rect->w * pixelSize;
VkDeviceSize stagingBufferSize = length * rect->h; VkDeviceSize stagingBufferSize = length * rect->h;
rc = VULKAN_AllocateBuffer(rendererData, rc = VULKAN_AllocateBuffer(rendererData,
@@ -3999,7 +4012,7 @@ static SDL_Surface* VULKAN_RenderReadPixels(SDL_Renderer *renderer, const SDL_Re
vkFormat = rendererData->surfaceFormat.format; vkFormat = rendererData->surfaceFormat.format;
} }
pixelSize = VULKAN_GetBytesPerPixel(vkFormat); pixelSize = VULKAN_GetBytesPerPixel(vkFormat, 0);
length = rect->w * pixelSize; length = rect->w * pixelSize;
readbackBufferSize = length * rect->h; readbackBufferSize = length * rect->h;
if (VULKAN_AllocateBuffer(rendererData, readbackBufferSize, if (VULKAN_AllocateBuffer(rendererData, readbackBufferSize,
+6 -1
View File
@@ -41,7 +41,12 @@
#define environ (*_NSGetEnviron()) #define environ (*_NSGetEnviron())
#elif defined(SDL_PLATFORM_FREEBSD) #elif defined(SDL_PLATFORM_FREEBSD)
#include <dlfcn.h> #include <dlfcn.h>
#define environ ((char **)dlsym(RTLD_DEFAULT, "environ")) static char **get_environ_rtld(void)
{
char ***environ_rtld = (char ***)dlsym(RTLD_DEFAULT, "environ");
return environ_rtld ? *environ_rtld : NULL;
}
#define environ (get_environ_rtld())
#else #else
extern char **environ; extern char **environ;
#endif #endif
+7
View File
@@ -1478,6 +1478,13 @@ DLMALLOC_EXPORT int mspace_mallopt(int, int);
#endif /* NO_MALLOC_STATS */ #endif /* NO_MALLOC_STATS */
#ifndef LACKS_ERRNO_H #ifndef LACKS_ERRNO_H
#include <errno.h> /* for MALLOC_FAILURE_ACTION */ #include <errno.h> /* for MALLOC_FAILURE_ACTION */
#else /* LACKS_ERRNO_H */
#ifndef EINVAL
#define EINVAL 22
#endif
#ifndef ENOMEM
#define ENOMEM 12
#endif
#endif /* LACKS_ERRNO_H */ #endif /* LACKS_ERRNO_H */
#ifdef DEBUG #ifdef DEBUG
#if ABORT_ON_ASSERT_FAILURE #if ABORT_ON_ASSERT_FAILURE
+3 -4
View File
@@ -333,7 +333,7 @@ void SDL_RunThread(SDL_Thread *thread)
// Mark us as ready to be joined (or detached) // Mark us as ready to be joined (or detached)
if (!SDL_CompareAndSwapAtomicInt(&thread->state, SDL_THREAD_ALIVE, SDL_THREAD_COMPLETE)) { if (!SDL_CompareAndSwapAtomicInt(&thread->state, SDL_THREAD_ALIVE, SDL_THREAD_COMPLETE)) {
// Clean up if something already detached us. // Clean up if something already detached us.
if (SDL_GetThreadState(thread) == SDL_THREAD_DETACHED) { if (SDL_GetAtomicInt(&thread->state) == SDL_THREAD_DETACHED) {
SDL_free(thread->name); // Can't free later, we've already cleaned up TLS SDL_free(thread->name); // Can't free later, we've already cleaned up TLS
SDL_free(thread); SDL_free(thread);
} }
@@ -487,11 +487,10 @@ void SDL_DetachThread(SDL_Thread *thread)
return; return;
} }
// The thread may vanish at any time, it's no longer valid
SDL_SetObjectValid(thread, SDL_OBJECT_TYPE_THREAD, false);
// Grab dibs if the state is alive+joinable. // Grab dibs if the state is alive+joinable.
if (SDL_CompareAndSwapAtomicInt(&thread->state, SDL_THREAD_ALIVE, SDL_THREAD_DETACHED)) { if (SDL_CompareAndSwapAtomicInt(&thread->state, SDL_THREAD_ALIVE, SDL_THREAD_DETACHED)) {
// The thread may vanish at any time, it's no longer valid
SDL_SetObjectValid(thread, SDL_OBJECT_TYPE_THREAD, false);
SDL_SYS_DetachThread(thread); SDL_SYS_DetachThread(thread);
} else { } else {
// all other states are pretty final, see where we landed. // all other states are pretty final, see where we landed.
+4 -2
View File
@@ -1434,6 +1434,7 @@ bool SDL_RLESurface(SDL_Surface *surface)
// The surface is now accelerated // The surface is now accelerated
surface->internal_flags |= SDL_INTERNAL_SURFACE_RLEACCEL; surface->internal_flags |= SDL_INTERNAL_SURFACE_RLEACCEL;
SDL_UpdateSurfaceLockFlag(surface);
return true; return true;
} }
@@ -1565,11 +1566,12 @@ void SDL_UnRLESurface(SDL_Surface *surface, bool recode)
} }
} }
} }
surface->map.info.flags &= surface->map.info.flags &= ~(SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY);
~(SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY);
SDL_free(surface->map.data); SDL_free(surface->map.data);
surface->map.data = NULL; surface->map.data = NULL;
SDL_UpdateSurfaceLockFlag(surface);
} }
} }
+1 -1
View File
@@ -191,7 +191,7 @@ bool SDL_CalculateBlit(SDL_Surface *surface, SDL_Surface *dst)
#ifdef SDL_HAVE_RLE #ifdef SDL_HAVE_RLE
// Clean everything out to start // Clean everything out to start
if (surface->flags & SDL_INTERNAL_SURFACE_RLEACCEL) { if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) {
SDL_UnRLESurface(surface, true); SDL_UnRLESurface(surface, true);
} }
#endif #endif
+10 -4
View File
@@ -42,6 +42,10 @@ void SDL_CancelClipboardData(Uint32 sequence)
{ {
SDL_VideoDevice *_this = SDL_GetVideoDevice(); SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (!_this) {
return;
}
if (sequence && sequence != _this->clipboard_sequence) { if (sequence && sequence != _this->clipboard_sequence) {
// This clipboard data was already canceled // This clipboard data was already canceled
return; return;
@@ -62,6 +66,10 @@ bool SDL_SaveClipboardMimeTypes(const char **mime_types, size_t num_mime_types)
{ {
SDL_VideoDevice *_this = SDL_GetVideoDevice(); SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (!_this) {
return SDL_UninitializedVideo();
}
SDL_FreeClipboardMimeTypes(_this); SDL_FreeClipboardMimeTypes(_this);
if (mime_types && num_mime_types > 0) { if (mime_types && num_mime_types > 0) {
@@ -234,13 +242,11 @@ bool SDL_HasClipboardData(const char *mime_type)
SDL_VideoDevice *_this = SDL_GetVideoDevice(); SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (!_this) { if (!_this) {
SDL_UninitializedVideo(); return SDL_UninitializedVideo();
return false;
} }
if (!mime_type) { if (!mime_type) {
SDL_InvalidParamError("mime_type"); return SDL_InvalidParamError("mime_type");
return false;
} }
if (_this->HasClipboardData) { if (_this->HasClipboardData) {
+2 -1
View File
@@ -1078,7 +1078,8 @@ SDL_GLContext SDL_EGL_CreateContext(SDL_VideoDevice *_this, EGLSurface egl_surfa
return NULL; return NULL;
} }
_this->egl_data->egl_swapinterval = 0; // The default swap interval is 1, according to the spec
_this->egl_data->egl_swapinterval = 1;
if (!SDL_EGL_MakeCurrent(_this, egl_surface, (SDL_GLContext)egl_context)) { if (!SDL_EGL_MakeCurrent(_this, egl_surface, (SDL_GLContext)egl_context)) {
// Delete the context // Delete the context
+3 -3
View File
@@ -49,7 +49,7 @@ bool SDL_SurfaceValid(SDL_Surface *surface)
void SDL_UpdateSurfaceLockFlag(SDL_Surface *surface) void SDL_UpdateSurfaceLockFlag(SDL_Surface *surface)
{ {
if (SDL_SurfaceHasRLE(surface)) { if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) {
surface->flags |= SDL_SURFACE_LOCK_NEEDED; surface->flags |= SDL_SURFACE_LOCK_NEEDED;
} else { } else {
surface->flags &= ~SDL_SURFACE_LOCK_NEEDED; surface->flags &= ~SDL_SURFACE_LOCK_NEEDED;
@@ -611,7 +611,6 @@ bool SDL_SetSurfaceRLE(SDL_Surface *surface, bool enabled)
if (surface->map.info.flags != flags) { if (surface->map.info.flags != flags) {
SDL_InvalidateMap(&surface->map); SDL_InvalidateMap(&surface->map);
} }
SDL_UpdateSurfaceLockFlag(surface);
return true; return true;
} }
@@ -1247,7 +1246,7 @@ bool SDL_BlitSurfaceScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surfac
// Clip again // Clip again
SDL_GetRectIntersection(clip_rect, &final_dst, &final_dst); SDL_GetRectIntersection(clip_rect, &final_dst, &final_dst);
if (final_dst.w == 0 || final_dst.h == 0 || if (final_dst.w <= 0 || final_dst.h <= 0 ||
final_src.w < 0 || final_src.h < 0) { final_src.w < 0 || final_src.h < 0) {
// No-op. // No-op.
return true; return true;
@@ -1751,6 +1750,7 @@ bool SDL_LockSurface(SDL_Surface *surface)
if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) { if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) {
SDL_UnRLESurface(surface, true); SDL_UnRLESurface(surface, true);
surface->internal_flags |= SDL_INTERNAL_SURFACE_RLEACCEL; // save accel'd state surface->internal_flags |= SDL_INTERNAL_SURFACE_RLEACCEL; // save accel'd state
SDL_UpdateSurfaceLockFlag(surface);
} }
#endif #endif
} }
+19 -2
View File
@@ -173,6 +173,7 @@ static VideoBootStrap *bootstrap[] = {
#if defined(SDL_PLATFORM_MACOS) && defined(SDL_VIDEO_DRIVER_COCOA) #if defined(SDL_PLATFORM_MACOS) && defined(SDL_VIDEO_DRIVER_COCOA)
// Support for macOS fullscreen spaces, etc. // Support for macOS fullscreen spaces, etc.
extern bool Cocoa_IsWindowInFullscreenSpace(SDL_Window *window); extern bool Cocoa_IsWindowInFullscreenSpace(SDL_Window *window);
extern bool Cocoa_IsWindowInFullscreenSpaceTransition(SDL_Window *window);
extern bool Cocoa_SetWindowFullscreenSpace(SDL_Window *window, bool state, bool blocking); extern bool Cocoa_SetWindowFullscreenSpace(SDL_Window *window, bool state, bool blocking);
extern bool Cocoa_IsShowingModalDialog(SDL_Window *window); extern bool Cocoa_IsShowingModalDialog(SDL_Window *window);
#endif #endif
@@ -1162,7 +1163,7 @@ float SDL_GetDisplayContentScale(SDL_DisplayID displayID)
void SDL_SetWindowHDRProperties(SDL_Window *window, const SDL_HDROutputProperties *HDR, bool send_event) void SDL_SetWindowHDRProperties(SDL_Window *window, const SDL_HDROutputProperties *HDR, bool send_event)
{ {
if (window->HDR.HDR_headroom != HDR->HDR_headroom || window->HDR.SDR_white_level != window->HDR.SDR_white_level) { if (window->HDR.HDR_headroom != HDR->HDR_headroom || window->HDR.SDR_white_level != HDR->SDR_white_level) {
SDL_PropertiesID window_props = SDL_GetWindowProperties(window); SDL_PropertiesID window_props = SDL_GetWindowProperties(window);
SDL_SetFloatProperty(window_props, SDL_PROP_WINDOW_HDR_HEADROOM_FLOAT, SDL_max(HDR->HDR_headroom, 1.0f)); SDL_SetFloatProperty(window_props, SDL_PROP_WINDOW_HDR_HEADROOM_FLOAT, SDL_max(HDR->HDR_headroom, 1.0f));
@@ -2111,6 +2112,16 @@ bool SDL_SetWindowFullscreenMode(SDL_Window *window, const SDL_DisplayMode *mode
* is in progress. It will be overwritten if a new request is made. * is in progress. It will be overwritten if a new request is made.
*/ */
SDL_copyp(&window->current_fullscreen_mode, &window->requested_fullscreen_mode); SDL_copyp(&window->current_fullscreen_mode, &window->requested_fullscreen_mode);
#if defined(SDL_PLATFORM_MACOS) && defined(SDL_VIDEO_DRIVER_COCOA)
/* If this is called while in the middle of a Cocoa fullscreen spaces transition,
* wait until the transition has completed, or the window can wind up in a weird,
* broken state if a mode switch occurs while in a fullscreen space.
*/
if (SDL_strcmp(_this->name, "cocoa") == 0 && Cocoa_IsWindowInFullscreenSpaceTransition(window)) {
SDL_SyncWindow(window);
}
#endif
if (SDL_WINDOW_FULLSCREEN_VISIBLE(window)) { if (SDL_WINDOW_FULLSCREEN_VISIBLE(window)) {
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_UPDATE, true); SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_UPDATE, true);
SDL_SyncIfRequired(window); SDL_SyncIfRequired(window);
@@ -2913,8 +2924,14 @@ bool SDL_GetWindowPosition(SDL_Window *window, int *x, int *y)
{ {
CHECK_WINDOW_MAGIC(window, false); CHECK_WINDOW_MAGIC(window, false);
#ifdef SDL_PLATFORM_MACOS
// On newer MacBooks, the fullscreen window might be placed below the camera notch, so use the actual window position
bool use_display_origin = false;
#else
// Fullscreen windows are always at their display's origin // Fullscreen windows are always at their display's origin
if (window->flags & SDL_WINDOW_FULLSCREEN) { bool use_display_origin = ((window->flags & SDL_WINDOW_FULLSCREEN) != 0);
#endif
if (use_display_origin) {
SDL_DisplayID displayID; SDL_DisplayID displayID;
if (x) { if (x) {
+20 -5
View File
@@ -47,6 +47,25 @@ void Android_QuitTouch(void)
{ {
} }
SDL_TouchID Android_ConvertJavaTouchID(int touchID)
{
SDL_TouchID retval = touchID;
if (touchID < 0) {
// Touch ID -1 appears when using Android emulator, eg:
// adb shell input mouse tap 100 100
// adb shell input touchscreen tap 100 100
//
// Prevent to be -1, since it's used in SDL internal for synthetic events:
retval -= 1;
} else {
// Touch ID 0 is invalid
retval += 1;
}
return retval;
}
void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p) void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p)
{ {
SDL_TouchID touchDeviceId = 0; SDL_TouchID touchDeviceId = 0;
@@ -56,11 +75,7 @@ void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_fin
return; return;
} }
/* Touch device -1 appears when using Android emulator, eg: touchDeviceId = Android_ConvertJavaTouchID(touch_device_id_in);
* adb shell input mouse tap 100 100
* adb shell input touchscreen tap 100 100
*/
touchDeviceId = (SDL_TouchID)(touch_device_id_in + 2);
// Finger ID should be greater than 0 // Finger ID should be greater than 0
fingerId = (SDL_FingerID)(pointer_finger_id_in + 1); fingerId = (SDL_FingerID)(pointer_finger_id_in + 1);
+1
View File
@@ -25,3 +25,4 @@
extern void Android_InitTouch(void); extern void Android_InitTouch(void);
extern void Android_QuitTouch(void); extern void Android_QuitTouch(void);
extern void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p); extern void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p);
extern SDL_TouchID Android_ConvertJavaTouchID(int touchID);
+13 -12
View File
@@ -44,19 +44,20 @@
{ {
static NSCursor *invisibleCursor = NULL; static NSCursor *invisibleCursor = NULL;
if (!invisibleCursor) { if (!invisibleCursor) {
// RAW 16x16 transparent GIF const int size = 32;
static unsigned char cursorBytes[] = { NSImage *cursorImage = [[NSImage alloc] initWithSize:NSMakeSize(size, size)];
0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04, pixelsWide:size
0x01, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10, pixelsHigh:size
0x00, 0x10, 0x00, 0x00, 0x02, 0x0E, 0x8C, 0x8F, 0xA9, 0xCB, 0xED, bitsPerSample:8
0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B samplesPerPixel:4
}; hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:(size * 4)
bitsPerPixel:32];
[cursorImage addRepresentation:imgrep];
NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0]
length:sizeof(cursorBytes)
freeWhenDone:NO];
NSImage *cursorImage = [[NSImage alloc] initWithData:cursorData];
invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage
hotSpot:NSZeroPoint]; hotSpot:NSZeroPoint];
} }
+33 -14
View File
@@ -411,6 +411,19 @@ bool Cocoa_IsWindowInFullscreenSpace(SDL_Window *window)
} }
} }
bool Cocoa_IsWindowInFullscreenSpaceTransition(SDL_Window *window)
{
@autoreleasepool {
SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal;
if ([data.listener isInFullscreenSpaceTransition]) {
return true;
} else {
return false;
}
}
}
bool Cocoa_IsWindowZoomed(SDL_Window *window) bool Cocoa_IsWindowZoomed(SDL_Window *window)
{ {
SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal; SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal;
@@ -1199,21 +1212,27 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
ScheduleContextUpdates(_data); ScheduleContextUpdates(_data);
/* isZoomed always returns true if the window is not resizable /* The OS can resize the window automatically if the display density
* and fullscreen windows are considered zoomed. * changes while the window is miniaturized or hidden.
*/ */
if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed] && if ([nswindow isVisible])
!(window->flags & SDL_WINDOW_FULLSCREEN) && ![self isInFullscreenSpace]) { {
zoomed = YES; /* isZoomed always returns true if the window is not resizable
} else { * and fullscreen windows are considered zoomed.
zoomed = NO; */
} if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed] &&
if (!zoomed) { !(window->flags & SDL_WINDOW_FULLSCREEN) && ![self isInFullscreenSpace]) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0); zoomed = YES;
} else { } else {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0); zoomed = NO;
if ([self windowOperationIsPending:PENDING_OPERATION_MINIMIZE]) { }
[nswindow miniaturize:nil]; if (!zoomed) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
} else {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
if ([self windowOperationIsPending:PENDING_OPERATION_MINIMIZE]) {
[nswindow miniaturize:nil];
}
} }
} }
+1 -1
View File
@@ -1540,7 +1540,7 @@ static SDL_VideoDevice *OPENVR_CreateDevice(void)
SDL_SetError("Could not get interfaces for the OpenVR System (%s), Overlay (%s) and Input (%s) versions", IVRSystem_Version, IVROverlay_Version, IVRInput_Version); SDL_SetError("Could not get interfaces for the OpenVR System (%s), Overlay (%s) and Input (%s) versions", IVRSystem_Version, IVROverlay_Version, IVRInput_Version);
} }
const char *hint = SDL_GetHint("SDL_OPENVR_INPUT_PROFILE"); hint = SDL_GetHint("SDL_OPENVR_INPUT_PROFILE");
char *loadpath = 0; char *loadpath = 0;
EVRInputError err; EVRInputError err;
-37
View File
@@ -1,37 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_PSP
#include <stdio.h>
#include "../../events/SDL_events_c.h"
#include "SDL_pspmouse_c.h"
// The implementation dependent data for the window manager cursor
struct WMcursor
{
int unused;
};
#endif // SDL_VIDEO_DRIVER_PSP
-24
View File
@@ -1,24 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_pspvideo.h"
// Functions to be exported
+43 -1
View File
@@ -41,6 +41,48 @@
*/ */
#define PIPE_TIMEOUT_NS SDL_MS_TO_NS(14) #define PIPE_TIMEOUT_NS SDL_MS_TO_NS(14)
/* sigtimedwait() is an optional part of POSIX.1-2001, and OpenBSD doesn't implement it.
* Based on https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation
*/
#ifndef HAVE_SIGTIMEDWAIT
#include <errno.h>
#include <time.h>
static int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
{
struct timespec elapsed = { 0 }, rem = { 0 };
sigset_t pending;
do {
// Check the pending signals, and call sigwait if there is at least one of interest in the set.
sigpending(&pending);
for (int signo = 1; signo < NSIG; ++signo) {
if (sigismember(set, signo) && sigismember(&pending, signo)) {
if (!sigwait(set, &signo)) {
if (info) {
SDL_memset(info, 0, sizeof *info);
info->si_signo = signo;
}
return signo;
} else {
return -1;
}
}
}
if (timeout->tv_sec || timeout->tv_nsec) {
long ns = 20000000L; // 2/100ths of a second
nanosleep(&(struct timespec){ 0, ns }, &rem);
ns -= rem.tv_nsec;
elapsed.tv_sec += (elapsed.tv_nsec + ns) / 1000000000L;
elapsed.tv_nsec = (elapsed.tv_nsec + ns) % 1000000000L;
}
} while (elapsed.tv_sec < timeout->tv_sec || (elapsed.tv_sec == timeout->tv_sec && elapsed.tv_nsec < timeout->tv_nsec));
errno = EAGAIN;
return -1;
}
#endif
static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_t *pos) static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_t *pos)
{ {
int ready = 0; int ready = 0;
@@ -76,7 +118,7 @@ static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_
} }
} }
sigtimedwait(&sig_set, 0, &zerotime); sigtimedwait(&sig_set, NULL, &zerotime);
#ifdef SDL_THREADS_DISABLED #ifdef SDL_THREADS_DISABLED
sigprocmask(SIG_SETMASK, &old_sig_set, NULL); sigprocmask(SIG_SETMASK, &old_sig_set, NULL);
+4 -3
View File
@@ -971,8 +971,6 @@ void Wayland_RecreateCursors(void)
void Wayland_InitMouse(void) void Wayland_InitMouse(void)
{ {
SDL_Mouse *mouse = SDL_GetMouse(); SDL_Mouse *mouse = SDL_GetMouse();
SDL_VideoDevice *vd = SDL_GetVideoDevice();
SDL_VideoData *d = vd->internal;
mouse->CreateCursor = Wayland_CreateCursor; mouse->CreateCursor = Wayland_CreateCursor;
mouse->CreateSystemCursor = Wayland_CreateSystemCursor; mouse->CreateSystemCursor = Wayland_CreateSystemCursor;
@@ -1021,7 +1019,10 @@ void Wayland_InitMouse(void)
} }
#ifdef SDL_USE_LIBDBUS #ifdef SDL_USE_LIBDBUS
/* The DBus cursor properties are only needed when manually loading themes and cursors. SDL_VideoDevice *vd = SDL_GetVideoDevice();
SDL_VideoData *d = vd->internal;
/* The D-Bus cursor properties are only needed when manually loading themes and system cursors.
* If the cursor shape protocol is present, the compositor will handle it internally. * If the cursor shape protocol is present, the compositor will handle it internally.
*/ */
if (!d->cursor_shape_manager) { if (!d->cursor_shape_manager) {
+18 -15
View File
@@ -215,32 +215,32 @@ static void EnsurePopupPositionIsValid(SDL_Window *window, int *x, int *y)
int adj_count = 0; int adj_count = 0;
/* Per the xdg-positioner spec, child popup windows must intersect or at /* Per the xdg-positioner spec, child popup windows must intersect or at
* least be partially adjacent to the parent window. * least be partially adjoining the parent window.
* *
* Failure to ensure this on a compositor that enforces this restriction * Failure to ensure this on a compositor that enforces this restriction
* can result in behavior ranging from the window being spuriously closed * can result in behavior ranging from the window being spuriously closed
* to a protocol violation. * to a protocol violation.
*/ */
if (*x + window->w < 0) { if (*x + window->w <= 0) {
*x = -window->w; *x = -window->w;
++adj_count; ++adj_count;
} }
if (*y + window->h < 0) { if (*y + window->h <= 0) {
*y = -window->h; *y = -window->h;
++adj_count; ++adj_count;
} }
if (*x > window->parent->w) { if (*x >= window->parent->w) {
*x = window->parent->w; *x = window->parent->w;
++adj_count; ++adj_count;
} }
if (*y > window->parent->h) { if (*y >= window->parent->h) {
*y = window->parent->h; *y = window->parent->h;
++adj_count; ++adj_count;
} }
/* If adjustment was required on the x and y axes, the popup is aligned with /* If adjustment was required on the x and y axes, the popup is aligned with
* the parent corner-to-corner and is neither overlapping nor adjacent, so it * the parent corner-to-corner and is neither overlapping nor adjoining, so it
* must be nudged by 1 to be considered adjacent. * must be nudged by 1 to be considered adjoining.
*/ */
if (adj_count > 1) { if (adj_count > 1) {
*x += *x < 0 ? 1 : -1; *x += *x < 0 ? 1 : -1;
@@ -1295,8 +1295,13 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
} else { } else {
/* Don't apply the supplied dimensions if they haven't changed from the last configuration /* Don't apply the supplied dimensions if they haven't changed from the last configuration
* event, or a newer size set programmatically can be overwritten by old data. * event, or a newer size set programmatically can be overwritten by old data.
*
* If a client takes a long time to present the first frame after creating the window, a
* configure event to set the suspended state may arrive with the content size increased
* by the decoration dimensions, which should also be ignored.
*/ */
if (width != wind->last_configure.width || height != wind->last_configure.height) { if ((width != wind->last_configure.width || height != wind->last_configure.height) &&
!(wind->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME && wind->suspended != suspended)) {
wind->requested.logical_width = width; wind->requested.logical_width = width;
wind->requested.logical_height = height; wind->requested.logical_height = height;
@@ -1895,7 +1900,7 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
// Set up the positioner for the popup and configure the constraints // Set up the positioner for the popup and configure the constraints
data->shell_surface.xdg.popup.xdg_positioner = xdg_wm_base_create_positioner(c->shell.xdg); data->shell_surface.xdg.popup.xdg_positioner = xdg_wm_base_create_positioner(c->shell.xdg);
xdg_positioner_set_anchor(data->shell_surface.xdg.popup.xdg_positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT); xdg_positioner_set_anchor(data->shell_surface.xdg.popup.xdg_positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT);
xdg_positioner_set_anchor_rect(data->shell_surface.xdg.popup.xdg_positioner, 0, 0, parent->internal->current.logical_width, parent->internal->current.logical_width); xdg_positioner_set_anchor_rect(data->shell_surface.xdg.popup.xdg_positioner, 0, 0, parent->internal->current.logical_width, parent->internal->current.logical_height);
const Uint32 constraint = window->constrain_popup ? (XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y) : XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE; const Uint32 constraint = window->constrain_popup ? (XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y) : XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE;
xdg_positioner_set_constraint_adjustment(data->shell_surface.xdg.popup.xdg_positioner, constraint); xdg_positioner_set_constraint_adjustment(data->shell_surface.xdg.popup.xdg_positioner, constraint);
@@ -2116,12 +2121,6 @@ void Wayland_HideWindow(SDL_VideoDevice *_this, SDL_Window *window)
wind->server_decoration = NULL; wind->server_decoration = NULL;
} }
// Be sure to detach after this is done, otherwise ShowWindow crashes!
if (wind->shell_surface_type != WAYLAND_SHELL_SURFACE_TYPE_XDG_POPUP) {
wl_surface_attach(wind->surface, NULL, 0, 0);
wl_surface_commit(wind->surface);
}
// Clean up the export handle. // Clean up the export handle.
if (wind->exported) { if (wind->exported) {
zxdg_exported_v2_destroy(wind->exported); zxdg_exported_v2_destroy(wind->exported);
@@ -2159,6 +2158,10 @@ void Wayland_HideWindow(SDL_VideoDevice *_this, SDL_Window *window)
} }
} }
// Attach a null buffer to unmap the surface.
wl_surface_attach(wind->surface, NULL, 0, 0);
wl_surface_commit(wind->surface);
SDL_zero(wind->shell_surface); SDL_zero(wind->shell_surface);
wind->show_hide_sync_required = true; wind->show_hide_sync_required = true;
struct wl_callback *cb = wl_display_sync(_this->internal->display); struct wl_callback *cb = wl_display_sync(_this->internal->display);
+1 -1
View File
@@ -2201,7 +2201,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
case WM_NCCALCSIZE: case WM_NCCALCSIZE:
{ {
SDL_WindowFlags window_flags = SDL_GetWindowFlags(data->window); SDL_WindowFlags window_flags = data->window->flags;
if (wParam == TRUE && (window_flags & SDL_WINDOW_BORDERLESS) && !(window_flags & SDL_WINDOW_FULLSCREEN)) { if (wParam == TRUE && (window_flags & SDL_WINDOW_BORDERLESS) && !(window_flags & SDL_WINDOW_FULLSCREEN)) {
// When borderless, need to tell windows that the size of the non-client area is 0 // When borderless, need to tell windows that the size of the non-client area is 0
NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam; NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam;
+4 -1
View File
@@ -443,7 +443,10 @@ error:
static bool WIN_ShowCursor(SDL_Cursor *cursor) static bool WIN_ShowCursor(SDL_Cursor *cursor)
{ {
if (!cursor) { if (!cursor) {
cursor = SDL_blank_cursor; if (GetSystemMetrics(SM_REMOTESESSION)) {
// Use a blank cursor so we continue to get relative motion over RDP
cursor = SDL_blank_cursor;
}
} }
if (cursor) { if (cursor) {
if (cursor->internal->surface) { if (cursor->internal->surface) {
+2
View File
@@ -747,8 +747,10 @@ bool WIN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properties
return false; return false;
} }
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
// Ensure that the IME isn't active on the new window until explicitly requested. // Ensure that the IME isn't active on the new window until explicitly requested.
WIN_StopTextInput(_this, window); WIN_StopTextInput(_this, window);
#endif
// Inform Windows of the frame change so we can respond to WM_NCCALCSIZE // Inform Windows of the frame change so we can respond to WM_NCCALCSIZE
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE); SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
+4 -8
View File
@@ -194,7 +194,7 @@ static bool X11_KeyRepeat(Display *display, XEvent *event)
return d.found; return d.found;
} }
static bool X11_IsWheelEvent(Display *display, int button, int *xticks, int *yticks) bool X11_IsWheelEvent(int button, int *xticks, int *yticks)
{ {
/* according to the xlib docs, no specific mouse wheel events exist. /* according to the xlib docs, no specific mouse wheel events exist.
However, the defacto standard is that the vertical wheel is X buttons However, the defacto standard is that the vertical wheel is X buttons
@@ -1016,8 +1016,6 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time) void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time)
{ {
SDL_Window *window = windowdata->window; SDL_Window *window = windowdata->window;
const SDL_VideoData *videodata = _this->internal;
Display *display = videodata->display;
int xticks = 0, yticks = 0; int xticks = 0, yticks = 0;
Uint64 timestamp = X11_GetEventTimestamp(time); Uint64 timestamp = X11_GetEventTimestamp(time);
@@ -1031,7 +1029,7 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
SDL_SendMouseMotion(timestamp, window, mouseID, false, x, y); SDL_SendMouseMotion(timestamp, window, mouseID, false, x, y);
} }
if (X11_IsWheelEvent(display, button, &xticks, &yticks)) { if (X11_IsWheelEvent(button, &xticks, &yticks)) {
SDL_SendMouseWheel(timestamp, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL); SDL_SendMouseWheel(timestamp, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL);
} else { } else {
bool ignore_click = false; bool ignore_click = false;
@@ -1063,8 +1061,6 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time) void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time)
{ {
SDL_Window *window = windowdata->window; SDL_Window *window = windowdata->window;
const SDL_VideoData *videodata = _this->internal;
Display *display = videodata->display;
// The X server sends a Release event for each Press for wheels. Ignore them. // The X server sends a Release event for each Press for wheels. Ignore them.
int xticks = 0, yticks = 0; int xticks = 0, yticks = 0;
Uint64 timestamp = X11_GetEventTimestamp(time); Uint64 timestamp = X11_GetEventTimestamp(time);
@@ -1072,7 +1068,7 @@ void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata,
#ifdef DEBUG_XEVENTS #ifdef DEBUG_XEVENTS
SDL_Log("window 0x%lx: ButtonRelease (X11 button = %d)", windowdata->xwindow, button); SDL_Log("window 0x%lx: ButtonRelease (X11 button = %d)", windowdata->xwindow, button);
#endif #endif
if (!X11_IsWheelEvent(display, button, &xticks, &yticks)) { if (!X11_IsWheelEvent(button, &xticks, &yticks)) {
if (button > 7) { if (button > 7) {
// see explanation at case ButtonPress // see explanation at case ButtonPress
button -= (8 - SDL_BUTTON_X1); button -= (8 - SDL_BUTTON_X1);
@@ -1518,7 +1514,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
* expected by SDL and its clients. Defer emitting the size/move events until the corresponding * expected by SDL and its clients. Defer emitting the size/move events until the corresponding
* PropertyNotify arrives for consistency. * PropertyNotify arrives for consistency.
*/ */
const Uint32 changed = X11_GetNetWMState(_this, data->window, xevent->xproperty.window) ^ data->window->flags; const SDL_WindowFlags changed = X11_GetNetWMState(_this, data->window, xevent->xproperty.window) ^ data->window->flags;
if (changed & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED)) { if (changed & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED)) {
SDL_copyp(&data->pending_xconfigure, &xevent->xconfigure); SDL_copyp(&data->pending_xconfigure, &xevent->xconfigure);
data->emit_size_move_after_property_notify = true; data->emit_size_move_after_property_notify = true;
+1
View File
@@ -36,5 +36,6 @@ extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *wind
extern SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window); extern SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window);
extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result); extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result);
extern bool X11_TriggerHitTestAction(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y); extern bool X11_TriggerHitTestAction(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y);
extern bool X11_IsWheelEvent(int button, int *xticks, int *yticks);
#endif // SDL_x11events_h_ #endif // SDL_x11events_h_
+1 -1
View File
@@ -33,7 +33,7 @@ static int shm_error;
static int (*X_handler)(Display *, XErrorEvent *) = NULL; static int (*X_handler)(Display *, XErrorEvent *) = NULL;
static int shm_errhandler(Display *d, XErrorEvent *e) static int shm_errhandler(Display *d, XErrorEvent *e)
{ {
if (e->error_code == BadAccess) { if (e->error_code == BadAccess || e->error_code == BadRequest) {
shm_error = True; shm_error = True;
return 0; return 0;
} }
+8 -3
View File
@@ -283,7 +283,7 @@ static void X11_SetKeyboardFocus(SDL_Window *window, bool set_active_focus)
} }
} }
Uint32 X11_GetNetWMState(SDL_VideoDevice *_this, SDL_Window *window, Window xwindow) SDL_WindowFlags X11_GetNetWMState(SDL_VideoDevice *_this, SDL_Window *window, Window xwindow)
{ {
SDL_VideoData *videodata = _this->internal; SDL_VideoData *videodata = _this->internal;
Display *display = videodata->display; Display *display = videodata->display;
@@ -1226,8 +1226,13 @@ void X11_SetWindowMinMax(SDL_Window *window, bool use_current)
} else { } else {
// Set the min/max to the same values to make the window non-resizable // Set the min/max to the same values to make the window non-resizable
sizehints->flags |= PMinSize | PMaxSize; sizehints->flags |= PMinSize | PMaxSize;
sizehints->min_width = sizehints->max_width = use_current ? data->window->floating.w : window->windowed.w; if (use_current) {
sizehints->min_height = sizehints->max_height = use_current ? data->window->floating.h : window->windowed.h; sizehints->min_width = sizehints->max_width = window->last_size_pending ? window->pending.w : data->window->floating.w;
sizehints->min_height = sizehints->max_height = window->last_size_pending ? window->pending.h : data->window->floating.h;
} else {
sizehints->min_width = sizehints->max_width = window->last_size_pending ? window->pending.w : data->window->windowed.w;
sizehints->min_height = sizehints->max_height = window->last_size_pending ? window->pending.h : data->window->windowed.h;
}
} }
X11_XSetWMNormalHints(display, data->xwindow, sizehints); X11_XSetWMNormalHints(display, data->xwindow, sizehints);
+1 -1
View File
@@ -128,7 +128,7 @@ struct SDL_WindowData
}; };
extern void X11_SetNetWMState(SDL_VideoDevice *_this, Window xwindow, SDL_WindowFlags flags); extern void X11_SetNetWMState(SDL_VideoDevice *_this, Window xwindow, SDL_WindowFlags flags);
extern Uint32 X11_GetNetWMState(SDL_VideoDevice *_this, SDL_Window *window, Window xwindow); extern SDL_WindowFlags X11_GetNetWMState(SDL_VideoDevice *_this, SDL_Window *window, Window xwindow);
extern bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props); extern bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
extern char *X11_GetWindowTitle(SDL_VideoDevice *_this, Window xwindow); extern char *X11_GetWindowTitle(SDL_VideoDevice *_this, Window xwindow);
+8
View File
@@ -425,6 +425,14 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
} else { } else {
// Otherwise assume a regular mouse // Otherwise assume a regular mouse
SDL_WindowData *windowdata = xinput2_get_sdlwindowdata(videodata, xev->event); SDL_WindowData *windowdata = xinput2_get_sdlwindowdata(videodata, xev->event);
int x_ticks = 0, y_ticks = 0;
/* Discard wheel events from "Master" devices to avoid duplicates,
* as coarse wheel events are stateless and can't be deduplicated.
*/
if (xev->deviceid != xev->sourceid && X11_IsWheelEvent(button, &x_ticks, &y_ticks)) {
break;
}
if (down) { if (down) {
X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button, X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button,
+3 -3
View File
@@ -889,7 +889,7 @@ static int SDLCALL rect_testIntersectRectEmpty(void *arg)
*/ */
static int SDLCALL rect_testIntersectRectParam(void *arg) static int SDLCALL rect_testIntersectRectParam(void *arg)
{ {
SDL_Rect rectA; SDL_Rect rectA = { 0 };
SDL_Rect rectB = { 0 }; SDL_Rect rectB = { 0 };
SDL_Rect result; SDL_Rect result;
bool intersection; bool intersection;
@@ -1138,7 +1138,7 @@ static int SDLCALL rect_testHasIntersectionEmpty(void *arg)
*/ */
static int SDLCALL rect_testHasIntersectionParam(void *arg) static int SDLCALL rect_testHasIntersectionParam(void *arg)
{ {
SDL_Rect rectA; SDL_Rect rectA = { 0 };
SDL_Rect rectB = { 0 }; SDL_Rect rectB = { 0 };
bool intersection; bool intersection;
@@ -1699,7 +1699,7 @@ static int SDLCALL rect_testUnionRectInside(void *arg)
*/ */
static int SDLCALL rect_testUnionRectParam(void *arg) static int SDLCALL rect_testUnionRectParam(void *arg)
{ {
SDL_Rect rectA, rectB = { 0 }; SDL_Rect rectA = { 0 }, rectB = { 0 };
SDL_Rect result; SDL_Rect result;
/* invalid parameter combinations */ /* invalid parameter combinations */
+44
View File
@@ -989,6 +989,45 @@ static int SDLCALL surface_testBlitInvalid(void *arg)
return TEST_COMPLETED; return TEST_COMPLETED;
} }
static int SDLCALL surface_testBlitsWithBadCoordinates(void *arg)
{
const SDL_Rect rect[8] = {
{ SDL_MAX_SINT32, 0, 2, 2 },
{ 0, SDL_MAX_SINT32, 2, 2 },
{ 0, 0, SDL_MAX_SINT32, 2 },
{ 0, 0, 2, SDL_MAX_SINT32 },
{ SDL_MIN_SINT32, 0, 2, 2 },
{ 0, SDL_MIN_SINT32, 2, 2 },
{ 0, 0, SDL_MIN_SINT32, 2 },
{ 0, 0, 2, SDL_MIN_SINT32 }
};
SDL_Surface *s;
bool result;
int i;
s = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_RGBA8888);
SDLTest_AssertCheck(s != NULL, "Check surface creation");
for (i = 0; i < 8; i++) {
result = SDL_BlitSurface(s, NULL, s, &rect[i]);
SDLTest_AssertCheck(result == true, "SDL_BlitSurface(valid, NULL, valid, &rect), result = %s", result ? "true" : "false");
result = SDL_BlitSurface(s, &rect[i], s, NULL);
SDLTest_AssertCheck(result == true, "SDL_BlitSurface(valid, &rect, valid, NULL), result = %s", result ? "true" : "false");
result = SDL_BlitSurfaceScaled(s, NULL, s, &rect[i], SDL_SCALEMODE_NEAREST);
SDLTest_AssertCheck(result == true, "SDL_BlitSurfaceScaled(valid, NULL, valid, &rect, SDL_SCALEMODE_NEAREST), result = %s", result ? "true" : "false");
result = SDL_BlitSurfaceScaled(s, &rect[i], s, NULL, SDL_SCALEMODE_NEAREST);
SDLTest_AssertCheck(result == true, "SDL_BlitSurfaceScaled(valid, &rect, valid, NULL, SDL_SCALEMODE_NEAREST), result = %s", result ? "true" : "false");
}
SDL_DestroySurface(s);
return TEST_COMPLETED;
}
static int SDLCALL surface_testOverflow(void *arg) static int SDLCALL surface_testOverflow(void *arg)
{ {
char buf[1024]; char buf[1024];
@@ -1664,6 +1703,10 @@ static const SDLTest_TestCaseReference surfaceTestBlitInvalid = {
surface_testBlitInvalid, "surface_testBlitInvalid", "Tests blitting routines with invalid surfaces.", TEST_ENABLED surface_testBlitInvalid, "surface_testBlitInvalid", "Tests blitting routines with invalid surfaces.", TEST_ENABLED
}; };
static const SDLTest_TestCaseReference surfaceTestBlitsWithBadCoordinates = {
surface_testBlitsWithBadCoordinates, "surface_testBlitsWithBadCoordinates", "Test blitting routines with bad coordinates.", TEST_ENABLED
};
static const SDLTest_TestCaseReference surfaceTestOverflow = { static const SDLTest_TestCaseReference surfaceTestOverflow = {
surface_testOverflow, "surface_testOverflow", "Test overflow detection.", TEST_ENABLED surface_testOverflow, "surface_testOverflow", "Test overflow detection.", TEST_ENABLED
}; };
@@ -1713,6 +1756,7 @@ static const SDLTest_TestCaseReference *surfaceTests[] = {
&surfaceTestBlitBlendMod, &surfaceTestBlitBlendMod,
&surfaceTestBlitBlendMul, &surfaceTestBlitBlendMul,
&surfaceTestBlitInvalid, &surfaceTestBlitInvalid,
&surfaceTestBlitsWithBadCoordinates,
&surfaceTestOverflow, &surfaceTestOverflow,
&surfaceTestFlip, &surfaceTestFlip,
&surfaceTestPalette, &surfaceTestPalette,
+4 -4
View File
@@ -679,7 +679,7 @@ void SetupVulkanRenderProperties(VulkanVideoContext *context, SDL_PropertiesID p
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_VULKAN_GRAPHICS_QUEUE_FAMILY_INDEX_NUMBER, context->graphicsQueueFamilyIndex); SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_VULKAN_GRAPHICS_QUEUE_FAMILY_INDEX_NUMBER, context->graphicsQueueFamilyIndex);
} }
#if LIBAVUTIL_VERSION_MAJOR >= 59 #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(59, 34, 100)
static void AddQueueFamily(AVVulkanDeviceContext *ctx, int idx, int num, VkQueueFlagBits flags) static void AddQueueFamily(AVVulkanDeviceContext *ctx, int idx, int num, VkQueueFlagBits flags)
{ {
AVVulkanDeviceQueueFamily *entry = &ctx->qf[ctx->nb_qf++]; AVVulkanDeviceQueueFamily *entry = &ctx->qf[ctx->nb_qf++];
@@ -687,7 +687,7 @@ static void AddQueueFamily(AVVulkanDeviceContext *ctx, int idx, int num, VkQueue
entry->num = num; entry->num = num;
entry->flags = flags; entry->flags = flags;
} }
#endif /* LIBAVUTIL_VERSION_MAJOR */ #endif /* LIBAVUTIL_VERSION_INT */
void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceContext *ctx) void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceContext *ctx)
{ {
@@ -700,7 +700,7 @@ void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceCon
ctx->nb_enabled_inst_extensions = context->instanceExtensionsCount; ctx->nb_enabled_inst_extensions = context->instanceExtensionsCount;
ctx->enabled_dev_extensions = context->deviceExtensions; ctx->enabled_dev_extensions = context->deviceExtensions;
ctx->nb_enabled_dev_extensions = context->deviceExtensionsCount; ctx->nb_enabled_dev_extensions = context->deviceExtensionsCount;
#if LIBAVUTIL_VERSION_MAJOR >= 59 #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(59, 34, 100)
AddQueueFamily(ctx, context->graphicsQueueFamilyIndex, context->graphicsQueueCount, VK_QUEUE_GRAPHICS_BIT); AddQueueFamily(ctx, context->graphicsQueueFamilyIndex, context->graphicsQueueCount, VK_QUEUE_GRAPHICS_BIT);
AddQueueFamily(ctx, context->transferQueueFamilyIndex, context->transferQueueCount, VK_QUEUE_TRANSFER_BIT); AddQueueFamily(ctx, context->transferQueueFamilyIndex, context->transferQueueCount, VK_QUEUE_TRANSFER_BIT);
AddQueueFamily(ctx, context->computeQueueFamilyIndex, context->computeQueueCount, VK_QUEUE_COMPUTE_BIT); AddQueueFamily(ctx, context->computeQueueFamilyIndex, context->computeQueueCount, VK_QUEUE_COMPUTE_BIT);
@@ -716,7 +716,7 @@ void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceCon
ctx->nb_encode_queues = 0; ctx->nb_encode_queues = 0;
ctx->queue_family_decode_index = context->decodeQueueFamilyIndex; ctx->queue_family_decode_index = context->decodeQueueFamilyIndex;
ctx->nb_decode_queues = context->decodeQueueCount; ctx->nb_decode_queues = context->decodeQueueCount;
#endif /* LIBAVUTIL_VERSION_MAJOR */ #endif /* LIBAVUTIL_VERSION_INT */
} }
static int CreateCommandBuffers(VulkanVideoContext *context, SDL_Renderer *renderer) static int CreateCommandBuffers(VulkanVideoContext *context, SDL_Renderer *renderer)
Loaded 100 of 103 files, more files were not shown because too many files have changed in this diff. Show more