This commit is contained in:
Sasha Szpakowski
2024-10-17 23:10:10 -03:00
parent 8c52dce565
commit 7ca40027e0
224 changed files with 8872 additions and 6448 deletions
+60 -3
View File
@@ -55,6 +55,9 @@
#include "video/SDL_surface_c.h"
#include "video/SDL_video_c.h"
#include "filesystem/SDL_filesystem_c.h"
#ifdef SDL_PLATFORM_ANDROID
#include "core/android/SDL_android.h"
#endif
#define SDL_INIT_EVERYTHING ~0U
@@ -251,10 +254,26 @@ void SDL_SetMainReady(void)
// Initialize all the subsystems that require initialization before threads start
void SDL_InitMainThread(void)
{
static bool done_info = false;
SDL_InitTLSData();
SDL_InitEnvironment();
SDL_InitTicks();
SDL_InitFilesystem();
if (!done_info) {
const char *value;
value = SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING);
SDL_LogInfo(SDL_LOG_CATEGORY_SYSTEM, "App name: %s", value ? value : "<unspecified>");
value = SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_VERSION_STRING);
SDL_LogInfo(SDL_LOG_CATEGORY_SYSTEM, "App version: %s", value ? value : "<unspecified>");
value = SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_IDENTIFIER_STRING);
SDL_LogInfo(SDL_LOG_CATEGORY_SYSTEM, "App ID: %s", value ? value : "<unspecified>");
SDL_LogInfo(SDL_LOG_CATEGORY_SYSTEM, "SDL revision: %s", SDL_REVISION);
done_info = true;
}
}
static void SDL_QuitMainThread(void)
@@ -643,7 +662,9 @@ const char *SDL_GetRevision(void)
// Get the name of the platform
const char *SDL_GetPlatform(void)
{
#if defined(SDL_PLATFORM_AIX)
#if defined(SDL_PLATFORM_PRIVATE)
return SDL_PLATFORM_PRIVATE_NAME;
#elif defined(SDL_PLATFORM_AIX)
return "AIX";
#elif defined(SDL_PLATFORM_ANDROID)
return "Android";
@@ -711,7 +732,6 @@ const char *SDL_GetPlatform(void)
bool SDL_IsTablet(void)
{
#ifdef SDL_PLATFORM_ANDROID
extern bool SDL_IsAndroidTablet(void);
return SDL_IsAndroidTablet();
#elif defined(SDL_PLATFORM_IOS)
extern bool SDL_IsIPad(void);
@@ -724,7 +744,6 @@ bool SDL_IsTablet(void)
bool SDL_IsTV(void)
{
#ifdef SDL_PLATFORM_ANDROID
extern bool SDL_IsAndroidTV(void);
return SDL_IsAndroidTV();
#elif defined(SDL_PLATFORM_IOS)
extern bool SDL_IsAppleTV(void);
@@ -734,6 +753,44 @@ bool SDL_IsTV(void)
#endif
}
static SDL_Sandbox SDL_DetectSandbox(void)
{
#if defined(SDL_PLATFORM_LINUX)
if (access("/.flatpak-info", F_OK) == 0) {
return SDL_SANDBOX_FLATPAK;
}
/* For Snap, we check multiple variables because they might be set for
* unrelated reasons. This is the same thing WebKitGTK does. */
if (SDL_getenv("SNAP") && SDL_getenv("SNAP_NAME") && SDL_getenv("SNAP_REVISION")) {
return SDL_SANDBOX_SNAP;
}
if (access("/run/host/container-manager", F_OK) == 0) {
return SDL_SANDBOX_UNKNOWN;
}
#elif defined(SDL_PLATFORM_MACOS)
if (SDL_getenv("APP_SANDBOX_CONTAINER_ID")) {
return SDL_SANDBOX_MACOS;
}
#endif
return SDL_SANDBOX_NONE;
}
SDL_Sandbox SDL_GetSandbox(void)
{
static SDL_Sandbox sandbox;
static bool sandbox_initialized;
if (!sandbox_initialized) {
sandbox = SDL_DetectSandbox();
sandbox_initialized = true;
}
return sandbox;
}
#ifdef SDL_PLATFORM_WIN32
#if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
+6 -2
View File
@@ -245,7 +245,9 @@ static SDL_AssertState SDLCALL SDL_PromptAssertion(const SDL_AssertData *data, v
state = (SDL_AssertState)selected;
}
} else {
#ifdef SDL_PLATFORM_EMSCRIPTEN
#ifdef SDL_PLATFORM_PRIVATE_ASSERT
SDL_PRIVATE_PROMPTASSERTION();
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
// This is nasty, but we can't block on a custom UI.
for (;;) {
bool okay = true;
@@ -283,7 +285,7 @@ static SDL_AssertState SDLCALL SDL_PromptAssertion(const SDL_AssertData *data, v
break;
}
}
#elif defined(HAVE_STDIO_H)
#elif defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_3DS)
// this is a little hacky.
for (;;) {
char buf[32];
@@ -310,6 +312,8 @@ static SDL_AssertState SDLCALL SDL_PromptAssertion(const SDL_AssertData *data, v
break;
}
}
#else
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Assertion Failed", message, window);
#endif // HAVE_STDIO_H
}
+18 -7
View File
@@ -25,18 +25,29 @@
#include "SDL_error_c.h"
bool SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
bool result;
va_start(ap, fmt);
result = SDL_SetErrorV(fmt, ap);
va_end(ap);
return result;
}
bool SDL_SetErrorV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap)
{
// Ignore call if invalid format pointer was passed
if (fmt) {
va_list ap;
int result;
SDL_error *error = SDL_GetErrBuf(true);
va_list ap2;
error->error = SDL_ErrorCodeGeneric;
va_start(ap, fmt);
result = SDL_vsnprintf(error->str, error->len, fmt, ap);
va_end(ap);
va_copy(ap2, ap);
result = SDL_vsnprintf(error->str, error->len, fmt, ap2);
va_end(ap2);
if (result >= 0 && (size_t)result >= error->len && error->realloc_func) {
size_t len = (size_t)result + 1;
@@ -44,9 +55,9 @@ bool SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
if (str) {
error->str = str;
error->len = len;
va_start(ap, fmt);
(void)SDL_vsnprintf(error->str, error->len, fmt, ap);
va_end(ap);
va_copy(ap2, ap);
(void)SDL_vsnprintf(error->str, error->len, fmt, ap2);
va_end(ap2);
}
}
+12 -11
View File
@@ -95,7 +95,7 @@ SDL_HashTable *SDL_CreateHashTable(void *data,
return table;
}
static SDL_INLINE Uint32 calc_hash(const SDL_HashTable *restrict table, const void *key)
static SDL_INLINE Uint32 calc_hash(const SDL_HashTable *table, const void *key)
{
const Uint32 BitMixer = 0x9E3779B1u;
return table->hash(key, table->data) * BitMixer;
@@ -112,7 +112,7 @@ static SDL_INLINE Uint32 get_probe_length(Uint32 zero_idx, Uint32 actual_idx, Ui
return actual_idx - zero_idx;
}
static SDL_HashItem *find_item(const SDL_HashTable *restrict ht, const void *key, Uint32 hash, Uint32 *restrict i, Uint32 *restrict probe_len)
static SDL_HashItem *find_item(const SDL_HashTable *ht, const void *key, Uint32 hash, Uint32 *i, Uint32 *probe_len)
{
Uint32 hash_mask = ht->hash_mask;
Uint32 max_probe_len = ht->max_probe_len;
@@ -146,14 +146,14 @@ static SDL_HashItem *find_item(const SDL_HashTable *restrict ht, const void *key
}
}
static SDL_HashItem *find_first_item(const SDL_HashTable *restrict ht, const void *key, Uint32 hash)
static SDL_HashItem *find_first_item(const SDL_HashTable *ht, const void *key, Uint32 hash)
{
Uint32 i = hash & ht->hash_mask;
Uint32 probe_len = 0;
return find_item(ht, key, hash, &i, &probe_len);
}
static SDL_HashItem *insert_item(SDL_HashItem *restrict item_to_insert, SDL_HashItem *restrict table, Uint32 hash_mask, Uint32 *max_probe_len_ptr)
static SDL_HashItem *insert_item(SDL_HashItem *item_to_insert, SDL_HashItem *table, Uint32 hash_mask, Uint32 *max_probe_len_ptr)
{
Uint32 idx = item_to_insert->hash & hash_mask;
SDL_HashItem temp_item, *target = NULL;
@@ -213,7 +213,7 @@ static SDL_HashItem *insert_item(SDL_HashItem *restrict item_to_insert, SDL_Hash
return target;
}
static void delete_item(SDL_HashTable *restrict ht, SDL_HashItem *item)
static void delete_item(SDL_HashTable *ht, SDL_HashItem *item)
{
Uint32 hash_mask = ht->hash_mask;
SDL_HashItem *table = ht->table;
@@ -241,7 +241,7 @@ static void delete_item(SDL_HashTable *restrict ht, SDL_HashItem *item)
}
}
static bool resize(SDL_HashTable *restrict ht, Uint32 new_size)
static bool resize(SDL_HashTable *ht, Uint32 new_size)
{
SDL_HashItem *old_table = ht->table;
Uint32 old_size = ht->hash_mask + 1;
@@ -267,7 +267,7 @@ static bool resize(SDL_HashTable *restrict ht, Uint32 new_size)
return true;
}
static bool maybe_resize(SDL_HashTable *restrict ht)
static bool maybe_resize(SDL_HashTable *ht)
{
Uint32 capacity = ht->hash_mask + 1;
@@ -276,7 +276,7 @@ static bool maybe_resize(SDL_HashTable *restrict ht)
}
Uint32 max_load_factor = 217; // range: 0-255; 217 is roughly 85%
Uint32 resize_threshold = (max_load_factor * (Uint64)capacity) >> 8;
Uint32 resize_threshold = (Uint32)((max_load_factor * (Uint64)capacity) >> 8);
if (ht->num_occupied_slots > resize_threshold) {
return resize(ht, capacity * 2);
@@ -285,7 +285,7 @@ static bool maybe_resize(SDL_HashTable *restrict ht)
return true;
}
bool SDL_InsertIntoHashTable(SDL_HashTable *restrict table, const void *key, const void *value)
bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *value)
{
SDL_HashItem *item;
Uint32 hash;
@@ -307,6 +307,7 @@ bool SDL_InsertIntoHashTable(SDL_HashTable *restrict table, const void *key, con
new_item.value = value;
new_item.hash = hash;
new_item.live = true;
new_item.probe_len = 0;
table->num_occupied_slots++;
@@ -455,7 +456,7 @@ bool SDL_HashTableEmpty(SDL_HashTable *table)
return !(table && table->num_occupied_slots);
}
static void nuke_all(SDL_HashTable *restrict table)
static void nuke_all(SDL_HashTable *table)
{
void *data = table->data;
SDL_HashItem *end = table->table + (table->hash_mask + 1);
@@ -468,7 +469,7 @@ static void nuke_all(SDL_HashTable *restrict table)
}
}
void SDL_EmptyHashTable(SDL_HashTable *restrict table)
void SDL_EmptyHashTable(SDL_HashTable *table)
{
if (table) {
if (table->nuke) {
+21 -6
View File
@@ -83,13 +83,28 @@ static void SDLCALL CleanupHintProperty(void *userdata, void *value)
SDL_free(hint);
}
static const char* GetHintEnvironmentVariable(const char *name)
{
const char *result = SDL_getenv(name);
if (!result && name && *name) {
// fall back to old (SDL2) names of environment variables that
// are important to users (e.g. many use SDL_VIDEODRIVER=wayland)
if (SDL_strcmp(name, SDL_HINT_VIDEO_DRIVER) == 0) {
result = SDL_getenv("SDL_VIDEODRIVER");
} else if (SDL_strcmp(name, SDL_HINT_AUDIO_DRIVER) == 0) {
result = SDL_getenv("SDL_AUDIODRIVER");
}
}
return result;
}
bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriority priority)
{
if (!name || !*name) {
return SDL_InvalidParamError("name");
}
const char *env = SDL_getenv(name);
const char *env = GetHintEnvironmentVariable(name);
if (env && (priority < SDL_HINT_OVERRIDE)) {
return SDL_SetError("An environment variable is taking priority");
}
@@ -143,7 +158,7 @@ bool SDL_ResetHint(const char *name)
return SDL_InvalidParamError("name");
}
const char *env = SDL_getenv(name);
const char *env = GetHintEnvironmentVariable(name);
const SDL_PropertiesID hints = GetHintProperties(false);
if (!hints) {
@@ -182,7 +197,7 @@ static void SDLCALL ResetHintsCallback(void *userdata, SDL_PropertiesID hints, c
return; // uh...okay.
}
const char *env = SDL_getenv(name);
const char *env = GetHintEnvironmentVariable(name);
if ((!env && hint->value) || (env && !hint->value) || (env && SDL_strcmp(env, hint->value) != 0)) {
SDL_HintWatch *entry = hint->callbacks;
while (entry) {
@@ -213,7 +228,7 @@ const char *SDL_GetHint(const char *name)
return NULL;
}
const char *result = SDL_getenv(name);
const char *result = GetHintEnvironmentVariable(name);
const SDL_PropertiesID hints = GetHintProperties(false);
if (hints) {
@@ -237,10 +252,10 @@ int SDL_GetStringInteger(const char *value, int default_value)
if (!value || !*value) {
return default_value;
}
if (*value == '0' || SDL_strcasecmp(value, "false") == 0) {
if (SDL_strcasecmp(value, "false") == 0) {
return 0;
}
if (*value == '1' || SDL_strcasecmp(value, "true") == 0) {
if (SDL_strcasecmp(value, "true") == 0) {
return 1;
}
if (*value == '-' || SDL_isdigit(*value)) {
+8
View File
@@ -696,6 +696,9 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
#endif // !defined(SDL_PLATFORM_GDK)
length = SDL_strlen(GetLogPriorityPrefix(priority)) + SDL_strlen(message) + 1 + 1 + 1;
output = SDL_small_alloc(char, length, &isstack);
if (!output) {
return;
}
(void)SDL_snprintf(output, length, "%s%s\r\n", GetLogPriorityPrefix(priority), message);
tstr = WIN_UTF8ToString(output);
@@ -772,6 +775,11 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
#endif
}
SDL_LogOutputFunction SDL_GetDefaultLogOutputFunction(void)
{
return SDL_LogOutput;
}
void SDL_GetLogOutputFunction(SDL_LogOutputFunction *callback, void **userdata)
{
SDL_LockMutex(SDL_log_function_lock);
+2 -2
View File
@@ -20,7 +20,7 @@
*/
#include "SDL_internal.h"
#if defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE)
#if defined(HAVE_GETHOSTNAME) && !defined(SDL_PLATFORM_WINDOWS)
#include <unistd.h>
#endif
@@ -299,7 +299,7 @@ int SDL_URIToLocal(const char *src, char *dst)
const size_t src_len = hostname_end - (src + 1);
size_t hostname_len;
#if defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE)
#if defined(HAVE_GETHOSTNAME) && !defined(SDL_PLATFORM_WINDOWS)
char hostname[257];
if (gethostname(hostname, 255) == 0) {
hostname[256] = '\0';
+3
View File
@@ -26,6 +26,9 @@
// Available audio drivers
static const AudioBootStrap *const bootstrap[] = {
#ifdef SDL_AUDIO_DRIVER_PRIVATE
&PRIVATEAUDIO_bootstrap,
#endif
#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO
#ifdef SDL_AUDIO_DRIVER_PIPEWIRE
&PIPEWIRE_PREFERRED_bootstrap,
+1
View File
@@ -353,6 +353,7 @@ typedef struct AudioBootStrap
} AudioBootStrap;
// Not all of these are available in a given build. Use #ifdefs, etc.
extern AudioBootStrap PRIVATEAUDIO_bootstrap;
extern AudioBootStrap PIPEWIRE_PREFERRED_bootstrap;
extern AudioBootStrap PIPEWIRE_bootstrap;
extern AudioBootStrap PULSEAUDIO_bootstrap;
+16 -2
View File
@@ -2093,7 +2093,8 @@ bool SDL_LoadWAV_IO(SDL_IOStream *src, bool closeio, SDL_AudioSpec *spec, Uint8
// Make sure we are passed a valid data source
if (!src) {
goto done; // Error may come from SDL_IOStream.
SDL_InvalidParamError("src");
goto done;
} else if (!spec) {
SDL_InvalidParamError("spec");
goto done;
@@ -2132,6 +2133,19 @@ done:
bool SDL_LoadWAV(const char *path, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
{
return SDL_LoadWAV_IO(SDL_IOFromFile(path, "rb"), 1, spec, audio_buf, audio_len);
SDL_IOStream *stream = SDL_IOFromFile(path, "rb");
if (!stream) {
if (spec) {
SDL_zerop(spec);
}
if (audio_buf) {
*audio_buf = NULL;
}
if (audio_len) {
*audio_len = 0;
}
return false;
}
return SDL_LoadWAV_IO(stream, true, spec, audio_buf, audio_len);
}
@@ -40,6 +40,13 @@ static bool EMSCRIPTENAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buf
{
const int framelen = SDL_AUDIO_FRAMESIZE(device->spec);
MAIN_THREAD_EM_ASM({
/* Convert incoming buf pointer to a HEAPF32 offset. */
#ifdef __wasm64__
var buf = $0 / 4;
#else
var buf = $0 >>> 2;
#endif
var SDL3 = Module['SDL3'];
var numChannels = SDL3.audio_playback.currentPlaybackBuffer['numberOfChannels'];
for (var c = 0; c < numChannels; ++c) {
@@ -49,7 +56,7 @@ static bool EMSCRIPTENAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buf
}
for (var j = 0; j < $1; ++j) {
channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; // !!! FIXME: why are these shifts here?
channelData[j] = HEAPF32[buf + (j*numChannels + c)];
}
}
}, buffer, buffer_size / framelen);
+3
View File
@@ -50,6 +50,9 @@ static const CameraBootStrap *const bootstrap[] = {
#ifdef SDL_CAMERA_DRIVER_MEDIAFOUNDATION
&MEDIAFOUNDATION_bootstrap,
#endif
#ifdef SDL_CAMERA_DRIVER_VITA
&VITACAMERA_bootstrap,
#endif
#ifdef SDL_CAMERA_DRIVER_DUMMY
&DUMMYCAMERA_bootstrap,
#endif
+1 -2
View File
@@ -27,8 +27,6 @@
#define DEBUG_CAMERA 0
typedef struct SDL_Camera SDL_Camera;
/* Backends should call this as devices are added to the system (such as
a USB camera being plugged in), and should also be called for
for every device found during DetectDevices(). */
@@ -217,5 +215,6 @@ extern CameraBootStrap COREMEDIA_bootstrap;
extern CameraBootStrap ANDROIDCAMERA_bootstrap;
extern CameraBootStrap EMSCRIPTENCAMERA_bootstrap;
extern CameraBootStrap MEDIAFOUNDATION_bootstrap;
extern CameraBootStrap VITACAMERA_bootstrap;
#endif // SDL_syscamera_h_
+258
View File
@@ -0,0 +1,258 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 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_CAMERA_DRIVER_VITA
#include "../SDL_syscamera.h"
#include <psp2/camera.h>
#include <psp2/kernel/sysmem.h>
static struct {
Sint32 w;
Sint32 h;
Sint32 res;
} resolutions[] = {
{640, 480, SCE_CAMERA_RESOLUTION_640_480},
{320, 240, SCE_CAMERA_RESOLUTION_320_240},
{160, 120, SCE_CAMERA_RESOLUTION_160_120},
{352, 288, SCE_CAMERA_RESOLUTION_352_288},
{176, 144, SCE_CAMERA_RESOLUTION_176_144},
{480, 272, SCE_CAMERA_RESOLUTION_480_272},
{640, 360, SCE_CAMERA_RESOLUTION_640_360},
{0, 0, 0}
};
static Sint32 fps[] = {5, 10, 15, 20, 24, 25, 30, 60, 0};
static void GatherCameraSpecs(Sint32 devid, CameraFormatAddData *add_data, char **fullname, SDL_CameraPosition *position)
{
SDL_zerop(add_data);
if (devid == SCE_CAMERA_DEVICE_FRONT) {
*position = SDL_CAMERA_POSITION_FRONT_FACING;
*fullname = SDL_strdup("Front-facing camera");
} else if (devid == SCE_CAMERA_DEVICE_BACK) {
*position = SDL_CAMERA_POSITION_BACK_FACING;
*fullname = SDL_strdup("Back-facing camera");
}
if (!*fullname) {
*fullname = SDL_strdup("Generic camera");
}
// Note: there are actually more fps and pixelformats. Planar YUV is fastest. Support only YUV and integer fps for now
Sint32 idx = 0;
while (resolutions[idx].res > 0) {
Sint32 fps_idx = 0;
while (fps[fps_idx] > 0) {
SDL_AddCameraFormat(add_data, SDL_PIXELFORMAT_IYUV, SDL_COLORSPACE_BT601_LIMITED, resolutions[idx].w, resolutions[idx].h, fps[fps_idx], 1); /* SCE_CAMERA_FORMAT_ARGB */
fps_idx++;
}
idx++;
}
}
static bool FindVitaCameraByID(SDL_Camera *device, void *userdata)
{
Sint32 devid = (Sint32) userdata;
return (devid == (Sint32)device->handle);
}
static void MaybeAddDevice(Sint32 devid)
{
#if DEBUG_CAMERA
SDL_Log("CAMERA: MaybeAddDevice('%d')", devid);
#endif
if (SDL_FindPhysicalCameraByCallback(FindVitaCameraByID, (void *) devid)) {
return; // already have this one.
}
SDL_CameraPosition position = SDL_CAMERA_POSITION_UNKNOWN;
char *fullname = NULL;
CameraFormatAddData add_data;
GatherCameraSpecs(devid, &add_data, &fullname, &position);
if (add_data.num_specs > 0) {
SDL_AddCamera(fullname, position, add_data.num_specs, add_data.specs, (void*)devid);
}
SDL_free(fullname);
SDL_free(add_data.specs);
}
static SceUID imbUid = -1;
static void freeBuffers(SceCameraInfo* info)
{
if (imbUid != -1) {
sceKernelFreeMemBlock(imbUid);
info->pIBase = NULL;
imbUid = -1;
}
}
static bool VITACAMERA_OpenDevice(SDL_Camera *device, const SDL_CameraSpec *spec)
{
// we can't open more than one camera, so error-out early
if (imbUid != -1) {
return SDL_SetError("Only one camera can be active");
}
SceCameraInfo* info = (SceCameraInfo*)SDL_calloc(1, sizeof(SceCameraInfo));
info->size = sizeof(SceCameraInfo);
info->priority = SCE_CAMERA_PRIORITY_SHARE;
info->buffer = 0; // target buffer set by sceCameraOpen
info->framerate = spec->framerate_numerator / spec->framerate_denominator;
Sint32 idx = 0;
while (resolutions[idx].res > 0) {
if (spec->width == resolutions[idx].w && spec->height == resolutions[idx].h) {
info->resolution = resolutions[idx].res;
break;
}
idx++;
}
info->range = 1;
info->format = SCE_CAMERA_FORMAT_YUV420_PLANE;
info->pitch = 0; // same size surface
info->sizeIBase = spec->width*spec->height;;
info->sizeUBase = ((spec->width+1)/2) * ((spec->height+1) / 2);
info->sizeVBase = ((spec->width+1)/2) * ((spec->height+1) / 2);
// PHYCONT memory size *must* be a multiple of 1MB, we can just always spend 2MB, since we don't use PHYCONT anywhere else
imbUid = sceKernelAllocMemBlock("CameraI", SCE_KERNEL_MEMBLOCK_TYPE_USER_MAIN_PHYCONT_NC_RW, 2*1024*1024 , NULL);
if (imbUid < 0)
{
return SDL_SetError("sceKernelAllocMemBlock error: 0x%08X", imbUid);
}
sceKernelGetMemBlockBase(imbUid, &(info->pIBase));
info->pUBase = info->pIBase + info->sizeIBase;
info->pVBase = info->pIBase + (info->sizeIBase + info->sizeUBase);
device->hidden = (struct SDL_PrivateCameraData *)info;
int ret = sceCameraOpen((int)device->handle, info);
if (ret == 0) {
ret = sceCameraStart((int)device->handle);
if (ret == 0) {
SDL_CameraPermissionOutcome(device, true);
return true;
} else {
SDL_SetError("sceCameraStart error: 0x%08X", imbUid);
}
} else {
SDL_SetError("sceCameraOpen error: 0x%08X", imbUid);
}
freeBuffers(info);
return false;
}
static void VITACAMERA_CloseDevice(SDL_Camera *device)
{
if (device->hidden) {
sceCameraStop((int)device->handle);
sceCameraClose((int)device->handle);
freeBuffers((SceCameraInfo*)device->hidden);
SDL_free(device->hidden);
}
}
static bool VITACAMERA_WaitDevice(SDL_Camera *device)
{
while(!sceCameraIsActive((int)device->handle)) {}
return true;
}
static SDL_CameraFrameResult VITACAMERA_AcquireFrame(SDL_Camera *device, SDL_Surface *frame, Uint64 *timestampNS)
{
SceCameraRead read = {0};
read.size = sizeof(SceCameraRead);
read.mode = 1; // don't wait next frame
int ret = sceCameraRead((int)device->handle, &read);
if (ret < 0) {
SDL_SetError("sceCameraRead error: 0x%08X", ret);
return SDL_CAMERA_FRAME_ERROR;
}
*timestampNS = read.timestamp;
SceCameraInfo* info = (SceCameraInfo*)(device->hidden);
frame->pitch = info->width;
frame->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), info->sizeIBase + info->sizeUBase + info->sizeVBase);
if (frame->pixels) {
SDL_memcpy(frame->pixels, info->pIBase, info->sizeIBase + info->sizeUBase + info->sizeVBase);
return SDL_CAMERA_FRAME_READY;
}
return SDL_CAMERA_FRAME_ERROR;
}
static void VITACAMERA_ReleaseFrame(SDL_Camera *device, SDL_Surface *frame)
{
SDL_aligned_free(frame->pixels);
}
static void VITACAMERA_DetectDevices(void)
{
MaybeAddDevice(SCE_CAMERA_DEVICE_FRONT);
MaybeAddDevice(SCE_CAMERA_DEVICE_BACK);
}
static void VITACAMERA_FreeDeviceHandle(SDL_Camera *device)
{
}
static void VITACAMERA_Deinitialize(void)
{
}
static bool VITACAMERA_Init(SDL_CameraDriverImpl *impl)
{
impl->DetectDevices = VITACAMERA_DetectDevices;
impl->OpenDevice = VITACAMERA_OpenDevice;
impl->CloseDevice = VITACAMERA_CloseDevice;
impl->WaitDevice = VITACAMERA_WaitDevice;
impl->AcquireFrame = VITACAMERA_AcquireFrame;
impl->ReleaseFrame = VITACAMERA_ReleaseFrame;
impl->FreeDeviceHandle = VITACAMERA_FreeDeviceHandle;
impl->Deinitialize = VITACAMERA_Deinitialize;
return true;
}
CameraBootStrap VITACAMERA_bootstrap = {
"vita", "SDL PSVita camera driver", VITACAMERA_Init, false
};
#endif // SDL_CAMERA_DRIVER_VITA
+2 -2
View File
@@ -146,8 +146,8 @@ const char *SDL_GetAndroidInternalStoragePath(void)
return NULL;
}
SDL_DECLSPEC void *SDLCALL SDL_GetAndroidJNIEnv(void);
void *SDL_GetAndroidJNIEnv(void)
SDL_DECLSPEC JNIEnv *SDLCALL SDL_GetAndroidJNIEnv(void);
JNIEnv *SDL_GetAndroidJNIEnv(void)
{
SDL_Unsupported();
return NULL;
+1 -1
View File
@@ -2177,7 +2177,7 @@ bool Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *b
//////////////////////////////////////////////////////////////////////////////
*/
void *SDL_GetAndroidJNIEnv(void)
JNIEnv *SDL_GetAndroidJNIEnv(void)
{
return Android_JNI_GetEnv();
}
+1
View File
@@ -146,6 +146,7 @@ bool Android_JNI_OpenURL(const char *url);
int SDL_GetAndroidSDKVersion(void);
bool SDL_IsAndroidTablet(void);
bool SDL_IsAndroidTV(void);
// File Dialogs
bool Android_JNI_OpenFileDialog(SDL_DialogFileCallback callback, void* userdata,
+1 -2
View File
@@ -20,7 +20,6 @@
*/
#include "SDL_internal.h"
#include "SDL_dbus.h"
#include "SDL_sandbox.h"
#include "../../stdlib/SDL_vacopy.h"
#ifdef SDL_USE_LIBDBUS
@@ -443,7 +442,7 @@ bool SDL_DBus_ScreensaverInhibit(bool inhibit)
return false;
}
if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) {
if (SDL_GetSandbox() != SDL_SANDBOX_NONE) {
const char *bus_name = "org.freedesktop.portal.Desktop";
const char *path = "/org/freedesktop/portal/desktop";
const char *interface = "org.freedesktop.portal.Inhibit";
-47
View File
@@ -1,47 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 2022 Collabora Ltd.
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"
#include "SDL_sandbox.h"
#include <unistd.h>
SDL_Sandbox SDL_DetectSandbox(void)
{
if (access("/.flatpak-info", F_OK) == 0) {
return SDL_SANDBOX_FLATPAK;
}
/* For Snap, we check multiple variables because they might be set for
* unrelated reasons. This is the same thing WebKitGTK does. */
if (SDL_getenv("SNAP") != NULL &&
SDL_getenv("SNAP_NAME") != NULL &&
SDL_getenv("SNAP_REVISION") != NULL) {
return SDL_SANDBOX_SNAP;
}
if (access("/run/host/container-manager", F_OK) == 0) {
return SDL_SANDBOX_UNKNOWN_CONTAINER;
}
return SDL_SANDBOX_NONE;
}
-37
View File
@@ -1,37 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 2022 Collabora Ltd.
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.
*/
#ifndef SDL_SANDBOX_H
#define SDL_SANDBOX_H
typedef enum
{
SDL_SANDBOX_NONE = 0,
SDL_SANDBOX_UNKNOWN_CONTAINER,
SDL_SANDBOX_FLATPAK,
SDL_SANDBOX_SNAP,
} SDL_Sandbox;
// Return the sandbox type currently in use, if any
SDL_Sandbox SDL_DetectSandbox(void);
#endif // SDL_SANDBOX_H
+1 -1
View File
@@ -119,7 +119,7 @@ extern "C" {
// Sets an error message based on a given HRESULT
extern bool WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
// Sets an error message based on GetLastError(). Always return -1.
// Sets an error message based on GetLastError(). Always returns false.
extern bool WIN_SetError(const char *prefix);
// Load a function from combase.dll
+4 -4
View File
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,1,3,0
PRODUCTVERSION 3,1,3,0
FILEVERSION 3,1,5,0
PRODUCTVERSION 3,1,5,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
@@ -23,12 +23,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL\0"
VALUE "FileVersion", "3, 1, 3, 0\0"
VALUE "FileVersion", "3, 1, 5, 0\0"
VALUE "InternalName", "SDL\0"
VALUE "LegalCopyright", "Copyright (C) 2024 Sam Lantinga\0"
VALUE "OriginalFilename", "SDL3.dll\0"
VALUE "ProductName", "Simple DirectMedia Layer\0"
VALUE "ProductVersion", "3, 1, 3, 0\0"
VALUE "ProductVersion", "3, 1, 5, 0\0"
END
END
BLOCK "VarFileInfo"
+4 -5
View File
@@ -21,6 +21,8 @@
#include "SDL_internal.h"
#include "../SDL_dialog_utils.h"
#ifdef SDL_PLATFORM_MACOS
#import <Cocoa/Cocoa.h>
#import <UniformTypeIdentifiers/UTType.h>
@@ -33,10 +35,6 @@ typedef enum
void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, bool allow_many)
{
#if defined(SDL_PLATFORM_TVOS) || defined(SDL_PLATFORM_IOS)
SDL_SetError("tvOS and iOS don't support path-based file dialogs");
callback(userdata, NULL, -1);
#else
if (filters) {
const char *msg = validate_filters(filters, nfilters);
@@ -175,7 +173,6 @@ void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback
callback(userdata, files, -1);
}
}
#endif // defined(SDL_PLATFORM_TVOS) || defined(SDL_PLATFORM_IOS)
}
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, bool allow_many)
@@ -192,3 +189,5 @@ void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, S
{
show_file_dialog(FDT_OPENFOLDER, callback, userdata, window, NULL, 0, default_location, allow_many);
}
#endif // SDL_PLATFORM_MACOS
@@ -20,6 +20,8 @@
*/
#include "SDL_internal.h"
#ifdef SDL_DIALOG_DUMMY
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, bool allow_many)
{
SDL_Unsupported();
@@ -37,3 +39,5 @@ void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, S
SDL_Unsupported();
callback(userdata, NULL, -1);
}
#endif // SDL_DIALOG_DUMMY
-5
View File
@@ -194,11 +194,6 @@ typedef struct
#undef SDL_DYNAPI_PROC
} SDL_DYNAPI_jump_table;
// Predeclare the default functions for initializing the jump table.
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) static rc SDLCALL fn##_DEFAULT params;
#include "SDL_dynapi_procs.h"
#undef SDL_DYNAPI_PROC
// The actual jump table.
static SDL_DYNAPI_jump_table jump_table = {
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) fn##_DEFAULT,
+3 -1
View File
@@ -43,7 +43,9 @@
#include "TargetConditionals.h"
#endif
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE // probably not useful on iOS.
#if defined(SDL_PLATFORM_PRIVATE) // probably not useful on private platforms.
#define SDL_DYNAMIC_API 0
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE // probably not useful on iOS.
#define SDL_DYNAMIC_API 0
#elif defined(SDL_PLATFORM_ANDROID) // probably not useful on Android.
#define SDL_DYNAMIC_API 0
+7
View File
@@ -1176,6 +1176,13 @@ SDL3_0.0.0 {
SDL_wcsnstr;
SDL_wcsstr;
SDL_wcstol;
SDL_StepBackUTF8;
SDL_DelayPrecise;
SDL_CalculateGPUTextureFormatSize;
SDL_SetErrorV;
SDL_GetDefaultLogOutputFunction;
SDL_RenderDebugText;
SDL_GetSandbox;
# extra symbols go here (don't modify this line)
local: *;
};
@@ -1201,3 +1201,10 @@
#define SDL_wcsnstr SDL_wcsnstr_REAL
#define SDL_wcsstr SDL_wcsstr_REAL
#define SDL_wcstol SDL_wcstol_REAL
#define SDL_StepBackUTF8 SDL_StepBackUTF8_REAL
#define SDL_DelayPrecise SDL_DelayPrecise_REAL
#define SDL_CalculateGPUTextureFormatSize SDL_CalculateGPUTextureFormatSize_REAL
#define SDL_SetErrorV SDL_SetErrorV_REAL
#define SDL_GetDefaultLogOutputFunction SDL_GetDefaultLogOutputFunction_REAL
#define SDL_RenderDebugText SDL_RenderDebugText_REAL
#define SDL_GetSandbox SDL_GetSandbox_REAL
+8 -1
View File
@@ -255,7 +255,7 @@ SDL_DYNAPI_PROC(const char*,SDL_GetAndroidCachePath,(void),(),return)
SDL_DYNAPI_PROC(const char*,SDL_GetAndroidExternalStoragePath,(void),(),return)
SDL_DYNAPI_PROC(Uint32,SDL_GetAndroidExternalStorageState,(void),(),return)
SDL_DYNAPI_PROC(const char*,SDL_GetAndroidInternalStoragePath,(void),(),return)
SDL_DYNAPI_PROC(void*,SDL_GetAndroidJNIEnv,(void),(),return)
SDL_DYNAPI_PROC(JNIEnv*,SDL_GetAndroidJNIEnv,(void),(),return)
SDL_DYNAPI_PROC(int,SDL_GetAndroidSDKVersion,(void),(),return)
SDL_DYNAPI_PROC(const char*,SDL_GetAppMetadataProperty,(const char *a),(a),return)
SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetAssertionHandler,(void **a),(a),return)
@@ -1207,3 +1207,10 @@ SDL_DYNAPI_PROC(size_t,SDL_wcsnlen,(const wchar_t *a, size_t b),(a,b),return)
SDL_DYNAPI_PROC(wchar_t*,SDL_wcsnstr,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
SDL_DYNAPI_PROC(wchar_t*,SDL_wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),return)
SDL_DYNAPI_PROC(long,SDL_wcstol,(const wchar_t *a, wchar_t **b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(Uint32,SDL_StepBackUTF8,(const char *a, const char **b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_DelayPrecise,(Uint64 a),(a),)
SDL_DYNAPI_PROC(Uint32,SDL_CalculateGPUTextureFormatSize,(SDL_GPUTextureFormat a, Uint32 b, Uint32 c, Uint32 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(bool,SDL_SetErrorV,(SDL_PRINTF_FORMAT_STRING const char *a,va_list b),(a,b),return)
SDL_DYNAPI_PROC(SDL_LogOutputFunction,SDL_GetDefaultLogOutputFunction,(void),(),return)
SDL_DYNAPI_PROC(bool,SDL_RenderDebugText,(SDL_Renderer *a,float b,float c,const char *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(SDL_Sandbox,SDL_GetSandbox,(void),(),return)
+223 -265
View File
@@ -24,60 +24,68 @@
# output looks sane (git diff, it adds to existing files), and commit it.
# It keeps the dynamic API jump table operating correctly.
#
# OS-specific API:
# Platform-specific API:
# After running the script, you have to manually add #ifdef SDL_PLATFORM_WIN32
# or similar around the function in 'SDL_dynapi_procs.h'
# or similar around the function in 'SDL_dynapi_procs.h'.
#
import argparse
import dataclasses
import json
import logging
import os
import pathlib
from pathlib import Path
import pprint
import re
SDL_ROOT = pathlib.Path(__file__).resolve().parents[2]
SDL_ROOT = Path(__file__).resolve().parents[2]
SDL_INCLUDE_DIR = SDL_ROOT / "include/SDL3"
SDL_DYNAPI_PROCS_H = SDL_ROOT / "src/dynapi/SDL_dynapi_procs.h"
SDL_DYNAPI_OVERRIDES_H = SDL_ROOT / "src/dynapi/SDL_dynapi_overrides.h"
SDL_DYNAPI_SYM = SDL_ROOT / "src/dynapi/SDL_dynapi.sym"
full_API = []
RE_EXTERN_C = re.compile(r'.*extern[ "]*C[ "].*')
RE_COMMENT_REMOVE_CONTENT = re.compile(r'\/\*.*\*/')
RE_PARSING_FUNCTION = re.compile(r'(.*SDLCALL[^\(\)]*) ([a-zA-Z0-9_]+) *\((.*)\) *;.*')
#eg:
# void (SDLCALL *callback)(void*, int)
# \1(\2)\3
RE_PARSING_CALLBACK = re.compile(r'([^\(\)]*)\(([^\(\)]+)\)(.*)')
def main():
logger = logging.getLogger(__name__)
# Parse 'sdl_dynapi_procs_h' file to find existing functions
existing_procs = find_existing_procs()
# Get list of SDL headers
sdl_list_includes = get_header_list()
@dataclasses.dataclass(frozen=True)
class SdlProcedure:
retval: str
name: str
parameter: list[str]
parameter_name: list[str]
header: str
comment: str
reg_externC = re.compile(r'.*extern[ "]*C[ "].*')
reg_comment_remove_content = re.compile(r'\/\*.*\*/')
reg_parsing_function = re.compile(r'(.*SDLCALL[^\(\)]*) ([a-zA-Z0-9_]+) *\((.*)\) *;.*')
@property
def variadic(self) -> bool:
return "..." in self.parameter
#eg:
# void (SDLCALL *callback)(void*, int)
# \1(\2)\3
reg_parsing_callback = re.compile(r'([^\(\)]*)\(([^\(\)]+)\)(.*)')
for filename in sdl_list_includes:
if args.debug:
print("Parse header: %s" % filename)
def parse_header(header_path: Path) -> list[SdlProcedure]:
logger.debug("Parse header: %s", header_path)
input = open(filename)
header_procedures = []
parsing_function = False
current_func = ""
parsing_comment = False
current_comment = ""
parsing_function = False
current_func = ""
parsing_comment = False
current_comment = ""
ignore_wiki_documentation = False
ignore_wiki_documentation = False
for line in input:
with header_path.open() as f:
for line in f:
# Skip lines if we're in a wiki documentation block.
if ignore_wiki_documentation:
@@ -95,13 +103,13 @@ def main():
continue
# Discard "extern C" line
match = reg_externC.match(line)
match = RE_EXTERN_C.match(line)
if match:
continue
# Remove one line comment // ...
# eg: extern SDL_DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path, int bExclusive /* = false */);
line = reg_comment_remove_content.sub('', line)
# eg: extern SDL_DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path, int bExclusive /* = false */)
line = RE_COMMENT_REMOVE_CONTENT.sub('', line)
# Get the comment block /* ... */ across several lines
match_start = "/*" in line
@@ -131,14 +139,14 @@ def main():
continue
# Start grabbing the new function
current_func = line.strip()
parsing_function = True;
parsing_function = True
# If it contains ';', then the function is complete
if ";" not in current_func:
continue
# Got function/comment, reset vars
parsing_function = False;
parsing_function = False
func = current_func
comment = current_comment
current_func = ""
@@ -146,47 +154,48 @@ def main():
# Discard if it doesn't contain 'SDLCALL'
if "SDLCALL" not in func:
if args.debug:
print(" Discard, doesn't have SDLCALL: " + func)
logger.debug(" Discard, doesn't have SDLCALL: %r", func)
continue
# Discard if it contains 'SDLMAIN_DECLSPEC' (these are not SDL symbols).
if "SDLMAIN_DECLSPEC" in func:
if args.debug:
print(" Discard, has SDLMAIN_DECLSPEC: " + func)
logger.debug(" Discard, has SDLMAIN_DECLSPEC: %r", func)
continue
if args.debug:
print(" Raw data: " + func);
logger.debug("Raw data: %r", func)
# Replace unusual stuff...
func = func.replace(" SDL_PRINTF_VARARG_FUNC(1)", "");
func = func.replace(" SDL_PRINTF_VARARG_FUNC(2)", "");
func = func.replace(" SDL_PRINTF_VARARG_FUNC(3)", "");
func = func.replace(" SDL_PRINTF_VARARG_FUNCV(1)", "");
func = func.replace(" SDL_PRINTF_VARARG_FUNCV(2)", "");
func = func.replace(" SDL_PRINTF_VARARG_FUNCV(3)", "");
func = func.replace(" SDL_WPRINTF_VARARG_FUNC(3)", "");
func = func.replace(" SDL_WPRINTF_VARARG_FUNCV(3)", "");
func = func.replace(" SDL_SCANF_VARARG_FUNC(2)", "");
func = func.replace(" SDL_SCANF_VARARG_FUNCV(2)", "");
func = func.replace(" SDL_ANALYZER_NORETURN", "");
func = func.replace(" SDL_MALLOC", "");
func = func.replace(" SDL_ALLOC_SIZE2(1, 2)", "");
func = func.replace(" SDL_ALLOC_SIZE(2)", "");
func = re.sub(r" SDL_ACQUIRE\(.*\)", "", func);
func = re.sub(r" SDL_ACQUIRE_SHARED\(.*\)", "", func);
func = re.sub(r" SDL_TRY_ACQUIRE\(.*\)", "", func);
func = re.sub(r" SDL_TRY_ACQUIRE_SHARED\(.*\)", "", func);
func = re.sub(r" SDL_RELEASE\(.*\)", "", func);
func = re.sub(r" SDL_RELEASE_SHARED\(.*\)", "", func);
func = re.sub(r" SDL_RELEASE_GENERIC\(.*\)", "", func);
func = func.replace(" SDL_PRINTF_VARARG_FUNC(1)", "")
func = func.replace(" SDL_PRINTF_VARARG_FUNC(2)", "")
func = func.replace(" SDL_PRINTF_VARARG_FUNC(3)", "")
func = func.replace(" SDL_PRINTF_VARARG_FUNCV(1)", "")
func = func.replace(" SDL_PRINTF_VARARG_FUNCV(2)", "")
func = func.replace(" SDL_PRINTF_VARARG_FUNCV(3)", "")
func = func.replace(" SDL_WPRINTF_VARARG_FUNC(3)", "")
func = func.replace(" SDL_WPRINTF_VARARG_FUNCV(3)", "")
func = func.replace(" SDL_SCANF_VARARG_FUNC(2)", "")
func = func.replace(" SDL_SCANF_VARARG_FUNCV(2)", "")
func = func.replace(" SDL_ANALYZER_NORETURN", "")
func = func.replace(" SDL_MALLOC", "")
func = func.replace(" SDL_ALLOC_SIZE2(1, 2)", "")
func = func.replace(" SDL_ALLOC_SIZE(2)", "")
func = re.sub(r" SDL_ACQUIRE\(.*\)", "", func)
func = re.sub(r" SDL_ACQUIRE_SHARED\(.*\)", "", func)
func = re.sub(r" SDL_TRY_ACQUIRE\(.*\)", "", func)
func = re.sub(r" SDL_TRY_ACQUIRE_SHARED\(.*\)", "", func)
func = re.sub(r" SDL_RELEASE\(.*\)", "", func)
func = re.sub(r" SDL_RELEASE_SHARED\(.*\)", "", func)
func = re.sub(r" SDL_RELEASE_GENERIC\(.*\)", "", func)
func = re.sub(r"([ (),])(SDL_IN_BYTECAP\([^)]*\))", r"\1", func)
func = re.sub(r"([ (),])(SDL_OUT_BYTECAP\([^)]*\))", r"\1", func)
func = re.sub(r"([ (),])(SDL_INOUT_Z_CAP\([^)]*\))", r"\1", func)
func = re.sub(r"([ (),])(SDL_OUT_Z_CAP\([^)]*\))", r"\1", func)
# Should be a valid function here
match = reg_parsing_function.match(func)
match = RE_PARSING_FUNCTION.match(func)
if not match:
print("Cannot parse: "+ func)
exit(-1)
logger.error("Cannot parse: %s", func)
raise ValueError(func)
func_ret = match.group(1)
func_name = match.group(2)
@@ -198,11 +207,8 @@ def main():
func_ret = func_ret.replace('extern', ' ')
func_ret = func_ret.replace('SDLCALL', ' ')
func_ret = func_ret.replace('SDL_DECLSPEC', ' ')
func_ret, _ = re.subn('([ ]{2,})', ' ', func_ret)
# Remove trailing spaces in front of '*'
tmp = ""
while func_ret != tmp:
tmp = func_ret
func_ret = func_ret.replace(' ', ' ')
func_ret = func_ret.replace(' *', '*')
func_ret = func_ret.strip()
@@ -246,10 +252,10 @@ def main():
# parameter is a callback
if '(' in t:
match = reg_parsing_callback.match(t)
match = RE_PARSING_CALLBACK.match(t)
if not match:
print("cannot parse callback: " + t);
exit(-1)
logger.error("cannot parse callback: %s", t)
raise ValueError(t)
a = match.group(1).strip()
b = match.group(2).strip()
c = match.group(3).strip()
@@ -257,7 +263,7 @@ def main():
try:
(param_type, param_name) = b.rsplit('*', 1)
except:
param_type = t;
param_type = t
param_name = "param_name_not_specified"
# bug rsplit ??
@@ -281,7 +287,7 @@ def main():
try:
(param_type, param_name) = t.rsplit('*', 1)
except:
param_type = t;
param_type = t
param_name = "param_name_not_specified"
# bug rsplit ??
@@ -305,7 +311,7 @@ def main():
try:
(param_type, param_name) = t.rsplit(' ', 1)
except:
param_type = t;
param_type = t
param_name = "param_name_not_specified"
val = param_type.strip() + " REWRITE_NAME"
@@ -317,268 +323,220 @@ def main():
func_param_type.append(val)
func_param_name.append(param_name.strip())
new_proc = {}
# Return value type
new_proc['retval'] = func_ret
# List of parameters (type + anonymized param name 'REWRITE_NAME')
new_proc['parameter'] = func_param_type
# Real parameter name, or 'param_name_not_specified'
new_proc['parameter_name'] = func_param_name
# Function name
new_proc['name'] = func_name
# Header file
new_proc['header'] = os.path.basename(filename)
# Function comment
new_proc['comment'] = comment
new_proc = SdlProcedure(
retval=func_ret, # Return value type
name=func_name, # Function name
comment=comment, # Function comment
header=header_path.name, # Header file
parameter=func_param_type, # List of parameters (type + anonymized param name 'REWRITE_NAME')
parameter_name=func_param_name, # Real parameter name, or 'param_name_not_specified'
)
full_API.append(new_proc)
header_procedures.append(new_proc)
if args.debug:
pprint.pprint(new_proc);
print("\n")
if logger.getEffectiveLevel() <= logging.DEBUG:
logger.debug("%s", pprint.pformat(new_proc))
if func_name not in existing_procs:
print("NEW " + func)
add_dyn_api(new_proc)
return header_procedures
# For-End line in input
input.close()
# For-End parsing all files of sdl_list_includes
# Dump API into a json file
full_API_json()
# Check comment formatting
check_comment();
# Dump API into a json file
def full_API_json():
if args.dump:
filename = 'sdl.json'
with open(filename, 'w', newline='') as f:
json.dump(full_API, f, indent=4, sort_keys=True)
print("dump API to '%s'" % filename);
def full_API_json(path: Path, procedures: list[SdlProcedure]):
with path.open('w', newline='') as f:
json.dump([dataclasses.asdict(proc) for proc in procedures], f, indent=4, sort_keys=True)
logger.info("dump API to '%s'", path)
class CallOnce:
def __init__(self, cb):
self._cb = cb
self._called = False
def __call__(self, *args, **kwargs):
if self._called:
return
self._called = True
self._cb(*args, **kwargs)
# Check public function comments are correct
def check_comment_header():
if not check_comment_header.done:
check_comment_header.done = True
print("")
print("Please fix following warning(s):")
print("-------------------------------")
def print_check_comment_header():
logger.warning("")
logger.warning("Please fix following warning(s):")
logger.warning("--------------------------------")
def check_comment():
def check_documentations(procedures: list[SdlProcedure]) -> None:
check_comment_header.done = False
check_comment_header = CallOnce(print_check_comment_header)
warning_header_printed = False
# Check \param
for i in full_API:
comment = i['comment']
name = i['name']
retval = i['retval']
header = i['header']
expected = len(i['parameter'])
for proc in procedures:
expected = len(proc.parameter)
if expected == 1:
if i['parameter'][0] == 'void':
expected = 0;
count = comment.count("\\param")
if proc.parameter[0] == 'void':
expected = 0
count = proc.comment.count("\\param")
if count != expected:
# skip SDL_stdinc.h
if header != 'SDL_stdinc.h':
if proc.header != 'SDL_stdinc.h':
# Warning mismatch \param and function prototype
check_comment_header()
print(" In file %s: function %s() has %d '\\param' but expected %d" % (header, name, count, expected));
logger.warning(" In file %s: function %s() has %d '\\param' but expected %d", proc.header, proc.name, count, expected)
# Warning check \param uses the correct parameter name
# skip SDL_stdinc.h
if header != 'SDL_stdinc.h':
parameter_name = i['parameter_name']
for n in parameter_name:
if n != "" and "\\param " + n not in comment and "\\param[out] " + n not in comment:
if proc.header != 'SDL_stdinc.h':
for n in proc.parameter_name:
if n != "" and "\\param " + n not in proc.comment and "\\param[out] " + n not in proc.comment:
check_comment_header()
print(" In file %s: function %s() missing '\\param %s'" % (header, name, n));
logger.warning(" In file %s: function %s() missing '\\param %s'", proc.header, proc.name, n)
# Check \returns
for i in full_API:
comment = i['comment']
name = i['name']
retval = i['retval']
header = i['header']
for proc in procedures:
expected = 1
if retval == 'void':
expected = 0;
if proc.retval == 'void':
expected = 0
count = comment.count("\\returns")
count = proc.comment.count("\\returns")
if count != expected:
# skip SDL_stdinc.h
if header != 'SDL_stdinc.h':
if proc.header != 'SDL_stdinc.h':
# Warning mismatch \param and function prototype
check_comment_header()
print(" In file %s: function %s() has %d '\\returns' but expected %d" % (header, name, count, expected));
logger.warning(" In file %s: function %s() has %d '\\returns' but expected %d" % (proc.header, proc.name, count, expected))
# Check \since
for i in full_API:
comment = i['comment']
name = i['name']
retval = i['retval']
header = i['header']
for proc in procedures:
expected = 1
count = comment.count("\\since")
count = proc.comment.count("\\since")
if count != expected:
# skip SDL_stdinc.h
if header != 'SDL_stdinc.h':
if proc.header != 'SDL_stdinc.h':
# Warning mismatch \param and function prototype
check_comment_header()
print(" In file %s: function %s() has %d '\\since' but expected %d" % (header, name, count, expected));
logger.warning(" In file %s: function %s() has %d '\\since' but expected %d" % (proc.header, proc.name, count, expected))
# Parse 'sdl_dynapi_procs_h' file to find existing functions
def find_existing_procs():
def find_existing_proc_names() -> list[str]:
reg = re.compile(r'SDL_DYNAPI_PROC\([^,]*,([^,]*),.*\)')
ret = []
input = open(SDL_DYNAPI_PROCS_H)
for line in input:
match = reg.match(line)
if not match:
continue
existing_func = match.group(1)
ret.append(existing_func);
# print(existing_func)
input.close()
with SDL_DYNAPI_PROCS_H.open() as f:
for line in f:
match = reg.match(line)
if not match:
continue
existing_func = match.group(1)
ret.append(existing_func)
return ret
# Get list of SDL headers
def get_header_list():
reg = re.compile(r'^.*\.h$')
def get_header_list() -> list[Path]:
ret = []
tmp = os.listdir(SDL_INCLUDE_DIR)
for f in tmp:
for f in SDL_INCLUDE_DIR.iterdir():
# Only *.h files
match = reg.match(f)
if not match:
if args.debug:
print("Skip %s" % f)
continue
ret.append(SDL_INCLUDE_DIR / f)
if f.is_file() and f.suffix == ".h":
ret.append(f)
else:
logger.debug("Skip %s", f)
return ret
# Write the new API in files: _procs.h _overrivides.h and .sym
def add_dyn_api(proc):
func_name = proc['name']
func_ret = proc['retval']
func_argtype = proc['parameter']
def add_dyn_api(proc: SdlProcedure) -> None:
decl_args: list[str] = []
call_args = []
for i, argtype in enumerate(proc.parameter):
# Special case, void has no parameter name
if argtype == "void":
assert len(decl_args) == 0
assert len(proc.parameter) == 1
decl_args.append("void")
continue
# Var name: a, b, c, ...
varname = chr(ord('a') + i)
decl_args.append(argtype.replace("REWRITE_NAME", varname))
if argtype != "...":
call_args.append(varname)
macro_args = (
proc.retval,
proc.name,
"({})".format(",".join(decl_args)),
"({})".format(",".join(call_args)),
"" if proc.retval == "void" else "return",
)
# File: SDL_dynapi_procs.h
#
# Add at last
# SDL_DYNAPI_PROC(SDL_EGLConfig,SDL_EGL_GetCurrentConfig,(void),(),return)
f = open(SDL_DYNAPI_PROCS_H, "a", newline="")
dyn_proc = "SDL_DYNAPI_PROC(" + func_ret + "," + func_name + ",("
i = ord('a')
remove_last = False
for argtype in func_argtype:
# Special case, void has no parameter name
if argtype == "void":
dyn_proc += "void"
continue
# Var name: a, b, c, ...
varname = chr(i)
i += 1
tmp = argtype.replace("REWRITE_NAME", varname)
dyn_proc += tmp + ", "
remove_last = True
# remove last 2 char ', '
if remove_last:
dyn_proc = dyn_proc[:-1]
dyn_proc = dyn_proc[:-1]
dyn_proc += "),("
i = ord('a')
remove_last = False
for argtype in func_argtype:
# Special case, void has no parameter name
if argtype == "void":
continue
# Special case, '...' has no parameter name
if argtype == "...":
continue
# Var name: a, b, c, ...
varname = chr(i)
i += 1
dyn_proc += varname + ","
remove_last = True
# remove last char ','
if remove_last:
dyn_proc = dyn_proc[:-1]
dyn_proc += "),"
if func_ret != "void":
dyn_proc += "return"
dyn_proc += ")"
f.write(dyn_proc + "\n")
f.close()
with SDL_DYNAPI_PROCS_H.open("a", newline="") as f:
if proc.variadic:
f.write("#ifndef SDL_DYNAPI_PROC_NO_VARARGS\n")
f.write(f"SDL_DYNAPI_PROC({','.join(macro_args)})\n")
if proc.variadic:
f.write("#endif\n")
# File: SDL_dynapi_overrides.h
#
# Add at last
# "#define SDL_DelayNS SDL_DelayNS_REAL
f = open(SDL_DYNAPI_OVERRIDES_H, "a", newline="")
f.write("#define " + func_name + " " + func_name + "_REAL\n")
f.write(f"#define {proc.name} {proc.name}_REAL\n")
f.close()
# File: SDL_dynapi.sym
#
# Add before "extra symbols go here" line
input = open(SDL_DYNAPI_SYM)
new_input = []
for line in input:
if "extra symbols go here" in line:
new_input.append(" " + func_name + ";\n")
new_input.append(line)
input.close()
f = open(SDL_DYNAPI_SYM, 'w', newline='')
for line in new_input:
f.write(line)
f.close()
with SDL_DYNAPI_SYM.open() as f:
new_input = []
for line in f:
if "extra symbols go here" in line:
new_input.append(f" {proc.name};\n")
new_input.append(line)
with SDL_DYNAPI_SYM.open('w', newline='') as f:
for line in new_input:
f.write(line)
def main():
parser = argparse.ArgumentParser()
parser.set_defaults(loglevel=logging.INFO)
parser.add_argument('--dump', nargs='?', default=None, const="sdl.json", metavar="JSON", help='output all SDL API into a .json file')
parser.add_argument('--debug', action='store_const', const=logging.DEBUG, dest="loglevel", help='add debug traces')
args = parser.parse_args()
logging.basicConfig(level=args.loglevel, format='[%(levelname)s] %(message)s')
# Get list of SDL headers
sdl_list_includes = get_header_list()
procedures = []
for filename in sdl_list_includes:
header_procedures = parse_header(filename)
procedures.extend(header_procedures)
# Parse 'sdl_dynapi_procs_h' file to find existing functions
existing_proc_names = find_existing_proc_names()
for procedure in procedures:
if procedure.name not in existing_proc_names:
logger.info("NEW %s", procedure.name)
add_dyn_api(procedure)
if args.dump:
# Dump API into a json file
full_API_json(path=Path(args.dump), procedures=procedures)
# Check comment formatting
check_documentations(procedures)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--dump', help='output all SDL API into a .json file', action='store_true')
parser.add_argument('--debug', help='add debug traces', action='store_true')
args = parser.parse_args()
try:
main()
except Exception as e:
print(e)
exit(-1)
print("done!")
exit(0)
raise SystemExit(main())
+6 -1
View File
@@ -637,7 +637,12 @@ void SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
SDL_Keymod modstate = SDL_KMOD_NONE;
SDL_Scancode scancode = SDL_GetKeymapScancode(keyboard->keymap, ch, &modstate);
SDL_Scancode scancode;
if (ch == '\n') {
ch = SDLK_RETURN;
}
scancode = SDL_GetKeymapScancode(keyboard->keymap, ch, &modstate);
// Make sure we have this keycode in our keymap
if (scancode == SDL_SCANCODE_UNKNOWN && ch < SDLK_SCANCODE_MASK) {
+16 -5
View File
@@ -133,7 +133,13 @@ static HANDLE SDLCALL windows_file_open(const char *filename, const char *mode)
#endif
if (h == INVALID_HANDLE_VALUE) {
SDL_SetError("Couldn't open %s", filename);
char *error;
if (SDL_asprintf(&error, "Couldn't open %s", filename) > 0) {
WIN_SetError(error);
SDL_free(error);
} else {
SDL_SetError("Couldn't open %s", filename);
}
}
return h;
}
@@ -370,10 +376,8 @@ static int SDL_fdatasync(int fd)
result = fcntl(fd, F_FULLFSYNC);
#elif defined(SDL_PLATFORM_HAIKU)
result = fsync(fd);
#elif defined(_POSIX_SYNCHRONIZED_IO) // POSIX defines this if fdatasync() exists, so we don't need a CMake test.
#ifndef SDL_PLATFORM_RISCOS // !!! FIXME: however, RISCOS doesn't have the symbol...maybe we need to link to an extra library or something?
#elif defined(HAVE_FDATASYNC)
result = fdatasync(fd);
#endif
#endif
return result;
}
@@ -1204,7 +1208,14 @@ done:
void *SDL_LoadFile(const char *file, size_t *datasize)
{
return SDL_LoadFile_IO(SDL_IOFromFile(file, "rb"), datasize, true);
SDL_IOStream *stream = SDL_IOFromFile(file, "rb");
if (!stream) {
if (datasize) {
*datasize = 0;
}
return NULL;
}
return SDL_LoadFile_IO(stream, datasize, true);
}
SDL_PropertiesID SDL_GetIOProperties(SDL_IOStream *context)
+77 -15
View File
@@ -386,22 +386,22 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props)
return NULL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOL, false)) {
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_PRIVATE;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOL, false)) {
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_SPIRV;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOL, false)) {
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_DXBC;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOL, false)) {
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_DXIL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOL, false)) {
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_MSL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOL, false)) {
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_METALLIB;
}
@@ -449,24 +449,24 @@ static void SDL_GPU_FillProperties(
const char *name)
{
if (format_flags & SDL_GPU_SHADERFORMAT_PRIVATE) {
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOL, true);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN, true);
}
if (format_flags & SDL_GPU_SHADERFORMAT_SPIRV) {
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOL, true);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, true);
}
if (format_flags & SDL_GPU_SHADERFORMAT_DXBC) {
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOL, true);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN, true);
}
if (format_flags & SDL_GPU_SHADERFORMAT_DXIL) {
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOL, true);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN, true);
}
if (format_flags & SDL_GPU_SHADERFORMAT_MSL) {
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOL, true);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, true);
}
if (format_flags & SDL_GPU_SHADERFORMAT_METALLIB) {
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOL, true);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN, true);
}
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, debug_mode);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN, debug_mode);
SDL_SetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING, name);
}
#endif // SDL_GPU_DISABLED
@@ -526,8 +526,8 @@ SDL_GPUDevice *SDL_CreateGPUDeviceWithProperties(SDL_PropertiesID props)
selectedBackend = SDL_GPUSelectBackend(props);
if (selectedBackend != NULL) {
debug_mode = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, true);
preferLowPower = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOL, false);
debug_mode = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN, true);
preferLowPower = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, false);
result = selectedBackend->CreateDevice(debug_mode, preferLowPower, props);
if (result != NULL) {
@@ -619,6 +619,7 @@ Uint32 SDL_GPUTextureFormatTexelBlockSize(
case SDL_GPU_TEXTUREFORMAT_R16_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16_SNORM:
case SDL_GPU_TEXTUREFORMAT_R16_UINT:
case SDL_GPU_TEXTUREFORMAT_D16_UNORM:
return 2;
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM:
@@ -633,7 +634,12 @@ Uint32 SDL_GPUTextureFormatTexelBlockSize(
case SDL_GPU_TEXTUREFORMAT_R16G16_UINT:
case SDL_GPU_TEXTUREFORMAT_R16G16_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16G16_SNORM:
case SDL_GPU_TEXTUREFORMAT_D24_UNORM:
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT:
return 4;
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT:
return 5;
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM:
@@ -642,6 +648,49 @@ Uint32 SDL_GPUTextureFormatTexelBlockSize(
return 8;
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT:
return 16;
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT:
return 16;
default:
SDL_assert_release(!"Unrecognized TextureFormat!");
return 0;
@@ -2753,3 +2802,16 @@ void SDL_ReleaseGPUFence(
device->driverData,
fence);
}
Uint32 SDL_CalculateGPUTextureFormatSize(
SDL_GPUTextureFormat format,
Uint32 width,
Uint32 height,
Uint32 depth_or_layer_count)
{
Uint32 blockWidth = SDL_max(Texture_GetBlockWidth(format), 1);
Uint32 blockHeight = SDL_max(Texture_GetBlockHeight(format), 1);
Uint32 blocksPerRow = (width + blockWidth - 1) / blockWidth;
Uint32 blocksPerColumn = (height + blockHeight - 1) / blockHeight;
return depth_or_layer_count * blocksPerRow * blocksPerColumn * SDL_GPUTextureFormatTexelBlockSize(format);
}
+170 -21
View File
@@ -69,7 +69,7 @@ typedef struct BlitPipelineCacheEntry
// Internal Helper Utilities
#define SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE (SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT + 1)
#define SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE (SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT + 1)
#define SDL_GPU_VERTEXELEMENTFORMAT_MAX_ENUM_VALUE (SDL_GPU_VERTEXELEMENTFORMAT_HALF4 + 1)
#define SDL_GPU_COMPAREOP_MAX_ENUM_VALUE (SDL_GPU_COMPAREOP_ALWAYS + 1)
#define SDL_GPU_STENCILOP_MAX_ENUM_VALUE (SDL_GPU_STENCILOP_DECREMENT_AND_WRAP + 1)
@@ -78,10 +78,54 @@ typedef struct BlitPipelineCacheEntry
#define SDL_GPU_SWAPCHAINCOMPOSITION_MAX_ENUM_VALUE (SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2048 + 1)
#define SDL_GPU_PRESENTMODE_MAX_ENUM_VALUE (SDL_GPU_PRESENTMODE_MAILBOX + 1)
static inline Sint32 Texture_GetBlockSize(
static inline Sint32 Texture_GetBlockWidth(
SDL_GPUTextureFormat format)
{
switch (format) {
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT:
return 12;
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT:
return 10;
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT:
return 8;
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT:
return 6;
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT:
return 5;
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM:
@@ -93,6 +137,9 @@ static inline Sint32 Texture_GetBlockSize(
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT:
return 4;
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM:
@@ -133,6 +180,125 @@ static inline Sint32 Texture_GetBlockSize(
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_INT:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_D16_UNORM:
case SDL_GPU_TEXTUREFORMAT_D24_UNORM:
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT:
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT:
return 1;
default:
SDL_assert_release(!"Unrecognized TextureFormat!");
return 0;
}
}
static inline Sint32 Texture_GetBlockHeight(
SDL_GPUTextureFormat format)
{
switch (format) {
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT:
return 12;
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT:
return 10;
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT:
return 8;
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT:
return 6;
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT:
return 5;
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC4_R_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC5_RG_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT:
case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT:
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT:
return 4;
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM:
case SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM:
case SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM:
case SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM:
case SDL_GPU_TEXTUREFORMAT_R8G8_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16G16_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM:
case SDL_GPU_TEXTUREFORMAT_R8_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16_UNORM:
case SDL_GPU_TEXTUREFORMAT_A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_R8_SNORM:
case SDL_GPU_TEXTUREFORMAT_R8G8_SNORM:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM:
case SDL_GPU_TEXTUREFORMAT_R16_SNORM:
case SDL_GPU_TEXTUREFORMAT_R16G16_SNORM:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM:
case SDL_GPU_TEXTUREFORMAT_R16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R11G11B10_UFLOAT:
case SDL_GPU_TEXTUREFORMAT_R8_UINT:
case SDL_GPU_TEXTUREFORMAT_R8G8_UINT:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT:
case SDL_GPU_TEXTUREFORMAT_R16_UINT:
case SDL_GPU_TEXTUREFORMAT_R16G16_UINT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT:
case SDL_GPU_TEXTUREFORMAT_R8_INT:
case SDL_GPU_TEXTUREFORMAT_R8G8_INT:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_INT:
case SDL_GPU_TEXTUREFORMAT_R16_INT:
case SDL_GPU_TEXTUREFORMAT_R16G16_INT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_INT:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_D16_UNORM:
case SDL_GPU_TEXTUREFORMAT_D24_UNORM:
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT:
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT:
return 1;
default:
SDL_assert_release(!"Unrecognized TextureFormat!");
@@ -201,28 +367,11 @@ static inline Uint32 BytesPerRow(
Sint32 width,
SDL_GPUTextureFormat format)
{
Uint32 blocksPerRow = width;
Uint32 pixelRowsPerBlock = Texture_GetBlockSize(format);
blocksPerRow = (width + pixelRowsPerBlock - 1) / pixelRowsPerBlock;
Uint32 blockWidth = Texture_GetBlockWidth(format);
Uint32 blocksPerRow = (width + blockWidth - 1) / blockWidth;
return blocksPerRow * SDL_GPUTextureFormatTexelBlockSize(format);
}
static inline Sint32 BytesPerImage(
Uint32 width,
Uint32 height,
SDL_GPUTextureFormat format)
{
Uint32 blocksPerRow = width;
Uint32 blocksPerColumn = height;
Uint32 pixelRowsPerBlock = Texture_GetBlockSize(format);
Uint32 pixelColumnsPerBlock = pixelRowsPerBlock;
blocksPerRow = (width + pixelRowsPerBlock - 1) / pixelRowsPerBlock;
blocksPerColumn = (height + pixelColumnsPerBlock - 1) / pixelColumnsPerBlock;
return blocksPerRow * blocksPerColumn * SDL_GPUTextureFormatTexelBlockSize(format);
}
// GraphicsDevice Limits
#define MAX_TEXTURE_SAMPLERS_PER_STAGE 16
+63 -21
View File
@@ -237,6 +237,48 @@ static DXGI_FORMAT SDLToD3D11_TextureFormat[] = {
DXGI_FORMAT_D32_FLOAT, // D32_FLOAT
DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM_S8_UINT
DXGI_FORMAT_D32_FLOAT_S8X24_UINT, // D32_FLOAT_S8_UINT
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
};
SDL_COMPILE_TIME_ASSERT(SDLToD3D11_TextureFormat, SDL_arraysize(SDLToD3D11_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
@@ -2656,10 +2698,11 @@ static void D3D11_UploadToTexture(
destination->mip_level,
cycle);
Sint32 blockSize = Texture_GetBlockSize(dstFormat);
if (blockSize > 1) {
w = (w + blockSize - 1) & ~(blockSize - 1);
h = (h + blockSize - 1) & ~(blockSize - 1);
Sint32 blockWidth = Texture_GetBlockWidth(dstFormat);
Sint32 blockHeight = Texture_GetBlockHeight(dstFormat);
if (blockWidth > 1 && blockHeight > 1) {
w = (w + blockWidth - 1) & ~(blockWidth - 1);
h = (h + blockHeight - 1) & ~(blockHeight - 1);
}
if (bufferStride == 0) {
@@ -5227,9 +5270,8 @@ static bool D3D11_INTERNAL_CreateSwapchain(
return false;
}
int w, h;
SDL_SyncWindow(windowData->window);
SDL_GetWindowSizeInPixels(windowData->window, &w, &h);
res = IDXGISwapChain_GetDesc(swapchain, &swapchainDesc);
CHECK_D3D11_ERROR_AND_RETURN("Failed to get swapchain descriptor!", false);
// Initialize dummy container, width/height will be filled out in AcquireSwapchainTexture
SDL_zerop(&windowData->textureContainer);
@@ -5246,14 +5288,14 @@ static bool D3D11_INTERNAL_CreateSwapchain(
windowData->textureContainer.header.info.num_levels = 1;
windowData->textureContainer.header.info.sample_count = SDL_GPU_SAMPLECOUNT_1;
windowData->textureContainer.header.info.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
windowData->textureContainer.header.info.width = w;
windowData->textureContainer.header.info.height = h;
windowData->textureContainer.header.info.width = swapchainDesc.BufferDesc.Width;
windowData->textureContainer.header.info.height = swapchainDesc.BufferDesc.Height;
windowData->texture.container = &windowData->textureContainer;
windowData->texture.containerIndex = 0;
windowData->width = w;
windowData->height = h;
windowData->width = swapchainDesc.BufferDesc.Width;
windowData->height = swapchainDesc.BufferDesc.Height;
return true;
}
@@ -5268,16 +5310,12 @@ static bool D3D11_INTERNAL_ResizeSwapchain(
SDL_free(windowData->texture.subresources[0].colorTargetViews);
SDL_free(windowData->texture.subresources);
int w, h;
SDL_SyncWindow(windowData->window);
SDL_GetWindowSizeInPixels(windowData->window, &w, &h);
// Resize the swapchain
HRESULT res = IDXGISwapChain_ResizeBuffers(
windowData->swapchain,
0, // Keep buffer count the same
w,
h,
0, // Use client window width
0, // Use client window height
DXGI_FORMAT_UNKNOWN, // Keep the old format
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0);
CHECK_D3D11_ERROR_AND_RETURN("Could not resize swapchain buffers", false);
@@ -5290,10 +5328,14 @@ static bool D3D11_INTERNAL_ResizeSwapchain(
(windowData->swapchainComposition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : windowData->swapchainFormat,
&windowData->texture);
windowData->textureContainer.header.info.width = w;
windowData->textureContainer.header.info.height = h;
windowData->width = w;
windowData->height = h;
DXGI_SWAP_CHAIN_DESC swapchainDesc;
res = IDXGISwapChain_GetDesc(windowData->swapchain, &swapchainDesc);
CHECK_D3D11_ERROR_AND_RETURN("Failed to get swapchain descriptor!", false);
windowData->textureContainer.header.info.width = swapchainDesc.BufferDesc.Width;
windowData->textureContainer.header.info.height = swapchainDesc.BufferDesc.Height;
windowData->width = swapchainDesc.BufferDesc.Width;
windowData->height = swapchainDesc.BufferDesc.Height;
windowData->needsSwapchainRecreate = !result;
return result;
}
+59 -18
View File
@@ -312,6 +312,48 @@ static DXGI_FORMAT SDLToD3D12_TextureFormat[] = {
DXGI_FORMAT_D32_FLOAT, // D32_FLOAT
DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM_S8_UINT
DXGI_FORMAT_D32_FLOAT_S8X24_UINT, // D32_FLOAT_S8_UINT
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
};
SDL_COMPILE_TIME_ASSERT(SDLToD3D12_TextureFormat, SDL_arraysize(SDLToD3D12_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
@@ -6105,6 +6147,8 @@ static bool D3D12_INTERNAL_CreateSwapchain(
windowData->swapchainComposition = swapchain_composition;
windowData->swapchainColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
windowData->frameCounter = 0;
windowData->width = width;
windowData->height = height;
// Precache blit pipelines for the swapchain format
for (Uint32 i = 0; i < 5; i += 1) {
@@ -6303,19 +6347,12 @@ static bool D3D12_INTERNAL_ResizeSwapchain(
SDL_free(windowData->textureContainers[i].textures);
}
int w, h;
SDL_SyncWindow(windowData->window);
SDL_GetWindowSizeInPixels(
windowData->window,
&w,
&h);
// Resize the swapchain
HRESULT res = IDXGISwapChain_ResizeBuffers(
windowData->swapchain,
0, // Keep buffer count the same
w,
h,
0, // use client window width
0, // use client window height
DXGI_FORMAT_UNKNOWN, // Keep the old format
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0);
CHECK_D3D12_ERROR_AND_RETURN("Could not resize swapchain buffers", false)
@@ -6332,8 +6369,12 @@ static bool D3D12_INTERNAL_ResizeSwapchain(
}
}
windowData->width = w;
windowData->height = h;
DXGI_SWAP_CHAIN_DESC1 swapchainDesc;
IDXGISwapChain3_GetDesc1(windowData->swapchain, &swapchainDesc);
CHECK_D3D12_ERROR_AND_RETURN("Failed to retrieve swapchain descriptor!", false)
windowData->width = swapchainDesc.Width;
windowData->height = swapchainDesc.Height;
windowData->needsSwapchainRecreate = false;
return true;
}
@@ -6385,12 +6426,9 @@ static bool D3D12_INTERNAL_CreateSwapchain(
swapchainFormat = SwapchainCompositionToTextureFormat[swapchainComposition];
int w, h;
SDL_GetWindowSizeInPixels(windowData->window, &w, &h);
// Initialize the swapchain buffer descriptor
swapchainDesc.Width = 0;
swapchainDesc.Height = 0;
swapchainDesc.Width = 0; // use client window width
swapchainDesc.Height = 0; // use client window height
swapchainDesc.Format = swapchainFormat;
swapchainDesc.SampleDesc.Count = 1;
swapchainDesc.SampleDesc.Quality = 0;
@@ -6477,14 +6515,17 @@ static bool D3D12_INTERNAL_CreateSwapchain(
IDXGIFactory1_Release(pParent);
}
IDXGISwapChain3_GetDesc1(swapchain3, &swapchainDesc);
CHECK_D3D12_ERROR_AND_RETURN("Failed to retrieve swapchain descriptor!", false)
// Initialize the swapchain data
windowData->swapchain = swapchain3;
windowData->present_mode = presentMode;
windowData->swapchainComposition = swapchainComposition;
windowData->swapchainColorSpace = SwapchainCompositionToColorSpace[swapchainComposition];
windowData->frameCounter = 0;
windowData->width = w;
windowData->height = h;
windowData->width = swapchainDesc.Width;
windowData->height = swapchainDesc.Height;
// Precache blit pipelines for the swapchain format
for (Uint32 i = 0; i < 5; i += 1) {
+98 -5
View File
@@ -166,6 +166,48 @@ static MTLPixelFormat SDLToMetal_SurfaceFormat[] = {
MTLPixelFormatInvalid, // D24_UNORM_S8_UINT
#endif
MTLPixelFormatDepth32Float_Stencil8, // D32_FLOAT_S8_UINT
MTLPixelFormatASTC_4x4_LDR, // ASTC_4x4_UNORM
MTLPixelFormatASTC_5x4_LDR, // ASTC_5x4_UNORM
MTLPixelFormatASTC_5x5_LDR, // ASTC_5x5_UNORM
MTLPixelFormatASTC_6x5_LDR, // ASTC_6x5_UNORM
MTLPixelFormatASTC_6x6_LDR, // ASTC_6x6_UNORM
MTLPixelFormatASTC_8x5_LDR, // ASTC_8x5_UNORM
MTLPixelFormatASTC_8x6_LDR, // ASTC_8x6_UNORM
MTLPixelFormatASTC_8x8_LDR, // ASTC_8x8_UNORM
MTLPixelFormatASTC_10x5_LDR, // ASTC_10x5_UNORM
MTLPixelFormatASTC_10x6_LDR, // ASTC_10x6_UNORM
MTLPixelFormatASTC_10x8_LDR, // ASTC_10x8_UNORM
MTLPixelFormatASTC_10x10_LDR, // ASTC_10x10_UNORM
MTLPixelFormatASTC_12x10_LDR, // ASTC_12x10_UNORM
MTLPixelFormatASTC_12x12_LDR, // ASTC_12x12_UNORM
MTLPixelFormatASTC_4x4_sRGB, // ASTC_4x4_UNORM_SRGB
MTLPixelFormatASTC_5x4_sRGB, // ASTC_5x4_UNORM_SRGB
MTLPixelFormatASTC_5x5_sRGB, // ASTC_5x5_UNORM_SRGB
MTLPixelFormatASTC_6x5_sRGB, // ASTC_6x5_UNORM_SRGB
MTLPixelFormatASTC_6x6_sRGB, // ASTC_6x6_UNORM_SRGB
MTLPixelFormatASTC_8x5_sRGB, // ASTC_8x5_UNORM_SRGB
MTLPixelFormatASTC_8x6_sRGB, // ASTC_8x6_UNORM_SRGB
MTLPixelFormatASTC_8x8_sRGB, // ASTC_8x8_UNORM_SRGB
MTLPixelFormatASTC_10x5_sRGB, // ASTC_10x5_UNORM_SRGB
MTLPixelFormatASTC_10x6_sRGB, // ASTC_10x6_UNORM_SRGB
MTLPixelFormatASTC_10x8_sRGB, // ASTC_10x8_UNORM_SRGB
MTLPixelFormatASTC_10x10_sRGB, // ASTC_10x10_UNORM_SRGB
MTLPixelFormatASTC_12x10_sRGB, // ASTC_12x10_UNORM_SRGB
MTLPixelFormatASTC_12x12_sRGB, // ASTC_12x12_UNORM_SRGB
MTLPixelFormatASTC_4x4_HDR, // ASTC_4x4_FLOAT
MTLPixelFormatASTC_5x4_HDR, // ASTC_5x4_FLOAT
MTLPixelFormatASTC_5x5_HDR, // ASTC_5x5_FLOAT
MTLPixelFormatASTC_6x5_HDR, // ASTC_6x5_FLOAT
MTLPixelFormatASTC_6x6_HDR, // ASTC_6x6_FLOAT
MTLPixelFormatASTC_8x5_HDR, // ASTC_8x5_FLOAT
MTLPixelFormatASTC_8x6_HDR, // ASTC_8x6_FLOAT
MTLPixelFormatASTC_8x8_HDR, // ASTC_8x8_FLOAT
MTLPixelFormatASTC_10x5_HDR, // ASTC_10x5_FLOAT
MTLPixelFormatASTC_10x6_HDR, // ASTC_10x6_FLOAT
MTLPixelFormatASTC_10x8_HDR, // ASTC_10x8_FLOAT
MTLPixelFormatASTC_10x10_HDR, // ASTC_10x10_FLOAT
MTLPixelFormatASTC_12x10_HDR, // ASTC_12x10_FLOAT
MTLPixelFormatASTC_12x12_HDR // ASTC_12x12_FLOAT
};
SDL_COMPILE_TIME_ASSERT(SDLToMetal_SurfaceFormat, SDL_arraysize(SDLToMetal_SurfaceFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
@@ -1289,9 +1331,9 @@ static SDL_GPUSampler *METAL_CreateSampler(
id<MTLSamplerState> sampler;
MetalSampler *metalSampler;
samplerDesc.rAddressMode = SDLToMetal_SamplerAddressMode[createinfo->address_mode_u];
samplerDesc.sAddressMode = SDLToMetal_SamplerAddressMode[createinfo->address_mode_v];
samplerDesc.tAddressMode = SDLToMetal_SamplerAddressMode[createinfo->address_mode_w];
samplerDesc.sAddressMode = SDLToMetal_SamplerAddressMode[createinfo->address_mode_u];
samplerDesc.tAddressMode = SDLToMetal_SamplerAddressMode[createinfo->address_mode_v];
samplerDesc.rAddressMode = SDLToMetal_SamplerAddressMode[createinfo->address_mode_w];
samplerDesc.minFilter = SDLToMetal_MinMagFilter[createinfo->min_filter];
samplerDesc.magFilter = SDLToMetal_MinMagFilter[createinfo->mag_filter];
samplerDesc.mipFilter = SDLToMetal_MipFilter[createinfo->mipmap_mode]; // FIXME: Is this right with non-mipmapped samplers?
@@ -1710,7 +1752,7 @@ static void METAL_UploadToTexture(
copyFromBuffer:bufferContainer->activeBuffer->handle
sourceOffset:source->offset
sourceBytesPerRow:BytesPerRow(destination->w, textureContainer->header.info.format)
sourceBytesPerImage:BytesPerImage(destination->w, destination->h, textureContainer->header.info.format)
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, destination->d)
sourceSize:MTLSizeMake(destination->w, destination->h, destination->d)
toTexture:metalTexture->handle
destinationSlice:destination->layer
@@ -3877,7 +3919,58 @@ static bool METAL_SupportsTextureFormat(
#else
return false;
#endif
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM:
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB:
#ifdef SDL_PLATFORM_MACOS
return [renderer->device supportsFamily:MTLGPUFamilyApple7];
#else
return true;
#endif
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT:
case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT:
#ifdef SDL_PLATFORM_MACOS
return [renderer->device supportsFamily:MTLGPUFamilyApple7];
#else
return [renderer->device supportsFamily:MTLGPUFamilyApple6];
#endif
default:
return true;
}
+155 -87
View File
@@ -60,6 +60,8 @@ typedef struct VulkanExtensions
Uint8 EXT_vertex_attribute_divisor;
// Only required for special implementations (i.e. MoltenVK)
Uint8 KHR_portability_subset;
// Only required for decoding HDR ASTC textures
Uint8 EXT_texture_compression_astc_hdr;
} VulkanExtensions;
// Defines
@@ -135,69 +137,111 @@ static VkPresentModeKHR SDLToVK_PresentMode[] = {
};
static VkFormat SDLToVK_TextureFormat[] = {
VK_FORMAT_UNDEFINED, // INVALID
VK_FORMAT_R8_UNORM, // A8_UNORM
VK_FORMAT_R8_UNORM, // R8_UNORM
VK_FORMAT_R8G8_UNORM, // R8G8_UNORM
VK_FORMAT_R8G8B8A8_UNORM, // R8G8B8A8_UNORM
VK_FORMAT_R16_UNORM, // R16_UNORM
VK_FORMAT_R16G16_UNORM, // R16G16_UNORM
VK_FORMAT_R16G16B16A16_UNORM, // R16G16B16A16_UNORM
VK_FORMAT_A2B10G10R10_UNORM_PACK32, // R10G10B10A2_UNORM
VK_FORMAT_R5G6B5_UNORM_PACK16, // B5G6R5_UNORM
VK_FORMAT_A1R5G5B5_UNORM_PACK16, // B5G5R5A1_UNORM
VK_FORMAT_B4G4R4A4_UNORM_PACK16, // B4G4R4A4_UNORM
VK_FORMAT_B8G8R8A8_UNORM, // B8G8R8A8_UNORM
VK_FORMAT_BC1_RGBA_UNORM_BLOCK, // BC1_UNORM
VK_FORMAT_BC2_UNORM_BLOCK, // BC2_UNORM
VK_FORMAT_BC3_UNORM_BLOCK, // BC3_UNORM
VK_FORMAT_BC4_UNORM_BLOCK, // BC4_UNORM
VK_FORMAT_BC5_UNORM_BLOCK, // BC5_UNORM
VK_FORMAT_BC7_UNORM_BLOCK, // BC7_UNORM
VK_FORMAT_BC6H_SFLOAT_BLOCK, // BC6H_FLOAT
VK_FORMAT_BC6H_UFLOAT_BLOCK, // BC6H_UFLOAT
VK_FORMAT_R8_SNORM, // R8_SNORM
VK_FORMAT_R8G8_SNORM, // R8G8_SNORM
VK_FORMAT_R8G8B8A8_SNORM, // R8G8B8A8_SNORM
VK_FORMAT_R16_SNORM, // R16_SNORM
VK_FORMAT_R16G16_SNORM, // R16G16_SNORM
VK_FORMAT_R16G16B16A16_SNORM, // R16G16B16A16_SNORM
VK_FORMAT_R16_SFLOAT, // R16_FLOAT
VK_FORMAT_R16G16_SFLOAT, // R16G16_FLOAT
VK_FORMAT_R16G16B16A16_SFLOAT, // R16G16B16A16_FLOAT
VK_FORMAT_R32_SFLOAT, // R32_FLOAT
VK_FORMAT_R32G32_SFLOAT, // R32G32_FLOAT
VK_FORMAT_R32G32B32A32_SFLOAT, // R32G32B32A32_FLOAT
VK_FORMAT_B10G11R11_UFLOAT_PACK32, // R11G11B10_UFLOAT
VK_FORMAT_R8_UINT, // R8_UINT
VK_FORMAT_R8G8_UINT, // R8G8_UINT
VK_FORMAT_R8G8B8A8_UINT, // R8G8B8A8_UINT
VK_FORMAT_R16_UINT, // R16_UINT
VK_FORMAT_R16G16_UINT, // R16G16_UINT
VK_FORMAT_R16G16B16A16_UINT, // R16G16B16A16_UINT
VK_FORMAT_R32_UINT, // R32_UINT
VK_FORMAT_R32G32_UINT, // R32G32_UINT
VK_FORMAT_R32G32B32A32_UINT, // R32G32B32A32_UINT
VK_FORMAT_R8_SINT, // R8_INT
VK_FORMAT_R8G8_SINT, // R8G8_INT
VK_FORMAT_R8G8B8A8_SINT, // R8G8B8A8_INT
VK_FORMAT_R16_SINT, // R16_INT
VK_FORMAT_R16G16_SINT, // R16G16_INT
VK_FORMAT_R16G16B16A16_SINT, // R16G16B16A16_INT
VK_FORMAT_R32_SINT, // R32_INT
VK_FORMAT_R32G32_SINT, // R32G32_INT
VK_FORMAT_R32G32B32A32_SINT, // R32G32B32A32_INT
VK_FORMAT_R8G8B8A8_SRGB, // R8G8B8A8_UNORM_SRGB
VK_FORMAT_B8G8R8A8_SRGB, // B8G8R8A8_UNORM_SRGB
VK_FORMAT_BC1_RGBA_SRGB_BLOCK, // BC1_UNORM_SRGB
VK_FORMAT_BC2_SRGB_BLOCK, // BC3_UNORM_SRGB
VK_FORMAT_BC3_SRGB_BLOCK, // BC3_UNORM_SRGB
VK_FORMAT_BC7_SRGB_BLOCK, // BC7_UNORM_SRGB
VK_FORMAT_D16_UNORM, // D16_UNORM
VK_FORMAT_X8_D24_UNORM_PACK32, // D24_UNORM
VK_FORMAT_D32_SFLOAT, // D32_FLOAT
VK_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM_S8_UINT
VK_FORMAT_D32_SFLOAT_S8_UINT, // D32_FLOAT_S8_UINT
VK_FORMAT_UNDEFINED, // INVALID
VK_FORMAT_R8_UNORM, // A8_UNORM
VK_FORMAT_R8_UNORM, // R8_UNORM
VK_FORMAT_R8G8_UNORM, // R8G8_UNORM
VK_FORMAT_R8G8B8A8_UNORM, // R8G8B8A8_UNORM
VK_FORMAT_R16_UNORM, // R16_UNORM
VK_FORMAT_R16G16_UNORM, // R16G16_UNORM
VK_FORMAT_R16G16B16A16_UNORM, // R16G16B16A16_UNORM
VK_FORMAT_A2B10G10R10_UNORM_PACK32, // R10G10B10A2_UNORM
VK_FORMAT_R5G6B5_UNORM_PACK16, // B5G6R5_UNORM
VK_FORMAT_A1R5G5B5_UNORM_PACK16, // B5G5R5A1_UNORM
VK_FORMAT_B4G4R4A4_UNORM_PACK16, // B4G4R4A4_UNORM
VK_FORMAT_B8G8R8A8_UNORM, // B8G8R8A8_UNORM
VK_FORMAT_BC1_RGBA_UNORM_BLOCK, // BC1_UNORM
VK_FORMAT_BC2_UNORM_BLOCK, // BC2_UNORM
VK_FORMAT_BC3_UNORM_BLOCK, // BC3_UNORM
VK_FORMAT_BC4_UNORM_BLOCK, // BC4_UNORM
VK_FORMAT_BC5_UNORM_BLOCK, // BC5_UNORM
VK_FORMAT_BC7_UNORM_BLOCK, // BC7_UNORM
VK_FORMAT_BC6H_SFLOAT_BLOCK, // BC6H_FLOAT
VK_FORMAT_BC6H_UFLOAT_BLOCK, // BC6H_UFLOAT
VK_FORMAT_R8_SNORM, // R8_SNORM
VK_FORMAT_R8G8_SNORM, // R8G8_SNORM
VK_FORMAT_R8G8B8A8_SNORM, // R8G8B8A8_SNORM
VK_FORMAT_R16_SNORM, // R16_SNORM
VK_FORMAT_R16G16_SNORM, // R16G16_SNORM
VK_FORMAT_R16G16B16A16_SNORM, // R16G16B16A16_SNORM
VK_FORMAT_R16_SFLOAT, // R16_FLOAT
VK_FORMAT_R16G16_SFLOAT, // R16G16_FLOAT
VK_FORMAT_R16G16B16A16_SFLOAT, // R16G16B16A16_FLOAT
VK_FORMAT_R32_SFLOAT, // R32_FLOAT
VK_FORMAT_R32G32_SFLOAT, // R32G32_FLOAT
VK_FORMAT_R32G32B32A32_SFLOAT, // R32G32B32A32_FLOAT
VK_FORMAT_B10G11R11_UFLOAT_PACK32, // R11G11B10_UFLOAT
VK_FORMAT_R8_UINT, // R8_UINT
VK_FORMAT_R8G8_UINT, // R8G8_UINT
VK_FORMAT_R8G8B8A8_UINT, // R8G8B8A8_UINT
VK_FORMAT_R16_UINT, // R16_UINT
VK_FORMAT_R16G16_UINT, // R16G16_UINT
VK_FORMAT_R16G16B16A16_UINT, // R16G16B16A16_UINT
VK_FORMAT_R32_UINT, // R32_UINT
VK_FORMAT_R32G32_UINT, // R32G32_UINT
VK_FORMAT_R32G32B32A32_UINT, // R32G32B32A32_UINT
VK_FORMAT_R8_SINT, // R8_INT
VK_FORMAT_R8G8_SINT, // R8G8_INT
VK_FORMAT_R8G8B8A8_SINT, // R8G8B8A8_INT
VK_FORMAT_R16_SINT, // R16_INT
VK_FORMAT_R16G16_SINT, // R16G16_INT
VK_FORMAT_R16G16B16A16_SINT, // R16G16B16A16_INT
VK_FORMAT_R32_SINT, // R32_INT
VK_FORMAT_R32G32_SINT, // R32G32_INT
VK_FORMAT_R32G32B32A32_SINT, // R32G32B32A32_INT
VK_FORMAT_R8G8B8A8_SRGB, // R8G8B8A8_UNORM_SRGB
VK_FORMAT_B8G8R8A8_SRGB, // B8G8R8A8_UNORM_SRGB
VK_FORMAT_BC1_RGBA_SRGB_BLOCK, // BC1_UNORM_SRGB
VK_FORMAT_BC2_SRGB_BLOCK, // BC3_UNORM_SRGB
VK_FORMAT_BC3_SRGB_BLOCK, // BC3_UNORM_SRGB
VK_FORMAT_BC7_SRGB_BLOCK, // BC7_UNORM_SRGB
VK_FORMAT_D16_UNORM, // D16_UNORM
VK_FORMAT_X8_D24_UNORM_PACK32, // D24_UNORM
VK_FORMAT_D32_SFLOAT, // D32_FLOAT
VK_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM_S8_UINT
VK_FORMAT_D32_SFLOAT_S8_UINT, // D32_FLOAT_S8_UINT
VK_FORMAT_ASTC_4x4_UNORM_BLOCK, // ASTC_4x4_UNORM
VK_FORMAT_ASTC_5x4_UNORM_BLOCK, // ASTC_5x4_UNORM
VK_FORMAT_ASTC_5x5_UNORM_BLOCK, // ASTC_5x5_UNORM
VK_FORMAT_ASTC_6x5_UNORM_BLOCK, // ASTC_6x5_UNORM
VK_FORMAT_ASTC_6x6_UNORM_BLOCK, // ASTC_6x6_UNORM
VK_FORMAT_ASTC_8x5_UNORM_BLOCK, // ASTC_8x5_UNORM
VK_FORMAT_ASTC_8x6_UNORM_BLOCK, // ASTC_8x6_UNORM
VK_FORMAT_ASTC_8x8_UNORM_BLOCK, // ASTC_8x8_UNORM
VK_FORMAT_ASTC_10x5_UNORM_BLOCK, // ASTC_10x5_UNORM
VK_FORMAT_ASTC_10x6_UNORM_BLOCK, // ASTC_10x6_UNORM
VK_FORMAT_ASTC_10x8_UNORM_BLOCK, // ASTC_10x8_UNORM
VK_FORMAT_ASTC_10x10_UNORM_BLOCK, // ASTC_10x10_UNORM
VK_FORMAT_ASTC_12x10_UNORM_BLOCK, // ASTC_12x10_UNORM
VK_FORMAT_ASTC_12x12_UNORM_BLOCK, // ASTC_12x12_UNORM
VK_FORMAT_ASTC_4x4_SRGB_BLOCK, // ASTC_4x4_UNORM_SRGB
VK_FORMAT_ASTC_5x4_SRGB_BLOCK, // ASTC_5x4_UNORM_SRGB
VK_FORMAT_ASTC_5x5_SRGB_BLOCK, // ASTC_5x5_UNORM_SRGB
VK_FORMAT_ASTC_6x5_SRGB_BLOCK, // ASTC_6x5_UNORM_SRGB
VK_FORMAT_ASTC_6x6_SRGB_BLOCK, // ASTC_6x6_UNORM_SRGB
VK_FORMAT_ASTC_8x5_SRGB_BLOCK, // ASTC_8x5_UNORM_SRGB
VK_FORMAT_ASTC_8x6_SRGB_BLOCK, // ASTC_8x6_UNORM_SRGB
VK_FORMAT_ASTC_8x8_SRGB_BLOCK, // ASTC_8x8_UNORM_SRGB
VK_FORMAT_ASTC_10x5_SRGB_BLOCK, // ASTC_10x5_UNORM_SRGB
VK_FORMAT_ASTC_10x6_SRGB_BLOCK, // ASTC_10x6_UNORM_SRGB
VK_FORMAT_ASTC_10x8_SRGB_BLOCK, // ASTC_10x8_UNORM_SRGB
VK_FORMAT_ASTC_10x10_SRGB_BLOCK, // ASTC_10x10_UNORM_SRGB
VK_FORMAT_ASTC_12x10_SRGB_BLOCK, // ASTC_12x10_UNORM_SRGB
VK_FORMAT_ASTC_12x12_SRGB_BLOCK, // ASTC_12x12_UNORM_SRGB
VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT, // ASTC_4x4_FLOAT
VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT, // ASTC_5x4_FLOAT
VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT, // ASTC_5x5_FLOAT
VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT, // ASTC_6x5_FLOAT
VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT, // ASTC_6x6_FLOAT
VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT, // ASTC_8x5_FLOAT
VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT, // ASTC_8x6_FLOAT
VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT, // ASTC_8x8_FLOAT
VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT, // ASTC_10x5_FLOAT
VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT, // ASTC_10x6_FLOAT
VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT, // ASTC_10x8_FLOAT
VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT, // ASTC_10x10_FLOAT
VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT, // ASTC_12x10_FLOAT
VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK // ASTC_12x12_FLOAT
};
SDL_COMPILE_TIME_ASSERT(SDLToVK_TextureFormat, SDL_arraysize(SDLToVK_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
@@ -670,6 +714,8 @@ typedef struct WindowData
SDL_GPUSwapchainComposition swapchainComposition;
SDL_GPUPresentMode presentMode;
bool needsSwapchainRecreate;
Uint32 swapchainCreateWidth;
Uint32 swapchainCreateHeight;
// Window surface
VkSurfaceKHR surface;
@@ -2941,6 +2987,9 @@ static void VULKAN_INTERNAL_DestroyTexture(
}
if (texture->subresources[subresourceIndex].depthStencilView != VK_NULL_HANDLE) {
VULKAN_INTERNAL_RemoveFramebuffersContainingView(
renderer,
texture->subresources[subresourceIndex].depthStencilView);
renderer->vkDestroyImageView(
renderer->logicalDevice,
texture->subresources[subresourceIndex].depthStencilView,
@@ -4381,14 +4430,13 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
VkSemaphoreCreateInfo semaphoreCreateInfo;
SwapchainSupportDetails swapchainSupportDetails;
bool hasValidSwapchainComposition, hasValidPresentMode;
Sint32 drawableWidth, drawableHeight;
Uint32 i;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_assert(_this && _this->Vulkan_CreateSurface);
windowData->frameCounter = 0;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_assert(_this && _this->Vulkan_CreateSurface);
// Each swapchain must have its own surface.
if (!_this->Vulkan_CreateSurface(
_this,
@@ -4491,16 +4539,20 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
return VULKAN_INTERNAL_TRY_AGAIN;
}
// Sync now to be sure that our swapchain size is correct
SDL_SyncWindow(windowData->window);
SDL_GetWindowSizeInPixels(
windowData->window,
&drawableWidth,
&drawableHeight);
windowData->imageCount = MAX_FRAMES_IN_FLIGHT;
windowData->width = drawableWidth;
windowData->height = drawableHeight;
#ifdef SDL_PLATFORM_APPLE
windowData->width = swapchainSupportDetails.capabilities.currentExtent.width;
windowData->height = swapchainSupportDetails.capabilities.currentExtent.height;
#else
windowData->width = SDL_clamp(
windowData->swapchainCreateWidth,
swapchainSupportDetails.capabilities.minImageExtent.width,
swapchainSupportDetails.capabilities.maxImageExtent.width);
windowData->height = SDL_clamp(windowData->swapchainCreateHeight,
swapchainSupportDetails.capabilities.minImageExtent.height,
swapchainSupportDetails.capabilities.maxImageExtent.height);
#endif
if (swapchainSupportDetails.capabilities.maxImageCount > 0 &&
windowData->imageCount > swapchainSupportDetails.capabilities.maxImageCount) {
@@ -4528,8 +4580,8 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
swapchainCreateInfo.minImageCount = windowData->imageCount;
swapchainCreateInfo.imageFormat = windowData->format;
swapchainCreateInfo.imageColorSpace = windowData->colorSpace;
swapchainCreateInfo.imageExtent.width = drawableWidth;
swapchainCreateInfo.imageExtent.height = drawableHeight;
swapchainCreateInfo.imageExtent.width = windowData->width;
swapchainCreateInfo.imageExtent.height = windowData->height;
swapchainCreateInfo.imageArrayLayers = 1;
swapchainCreateInfo.imageUsage =
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
@@ -4603,8 +4655,8 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
// Initialize dummy container
SDL_zero(windowData->textureContainers[i]);
windowData->textureContainers[i].canBeCycled = false;
windowData->textureContainers[i].header.info.width = drawableWidth;
windowData->textureContainers[i].header.info.height = drawableHeight;
windowData->textureContainers[i].header.info.width = windowData->width;
windowData->textureContainers[i].header.info.height = windowData->height;
windowData->textureContainers[i].header.info.layer_count_or_depth = 1;
windowData->textureContainers[i].header.info.format = SwapchainCompositionToSDLFormat(
windowData->swapchainComposition,
@@ -8900,6 +8952,7 @@ static void VULKAN_Blit(
// Using BeginRenderPass to clear because vkCmdClearColorImage requires barriers anyway
if (info->load_op == SDL_GPU_LOADOP_CLEAR) {
SDL_GPUColorTargetInfo targetInfo;
SDL_zero(targetInfo);
targetInfo.texture = info->destination.texture;
targetInfo.mip_level = info->destination.mip_level;
targetInfo.layer_or_depth_plane = info->destination.layer_or_depth_plane;
@@ -9367,6 +9420,8 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e)
if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) {
data = VULKAN_INTERNAL_FetchWindowData(w);
data->needsSwapchainRecreate = true;
data->swapchainCreateWidth = e->window.data1;
data->swapchainCreateHeight = e->window.data2;
}
return true;
@@ -9465,6 +9520,16 @@ static bool VULKAN_ClaimWindow(
windowData->presentMode = SDL_GPU_PRESENTMODE_VSYNC;
windowData->swapchainComposition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR;
// On non-Apple platforms the swapchain capability currentExtent can be different from the window,
// so we have to query the window size.
#ifndef SDL_PLATFORM_APPLE
int w, h;
SDL_SyncWindow(window);
SDL_GetWindowSizeInPixels(window, &w, &h);
windowData->swapchainCreateWidth = w;
windowData->swapchainCreateHeight = h;
#endif
Uint32 createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowData);
if (createSwapchainResult == 1) {
SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData);
@@ -10232,20 +10297,21 @@ static bool VULKAN_Submit(
renderer->unifiedQueue,
&presentInfo);
presentData->windowData->frameCounter =
(presentData->windowData->frameCounter + 1) % MAX_FRAMES_IN_FLIGHT;
if (presentResult == VK_SUCCESS || presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
if (presentResult == VK_SUCCESS || presentResult == VK_SUBOPTIMAL_KHR || presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
// If presenting, the swapchain is using the in-flight fence
presentData->windowData->inFlightFences[presentData->windowData->frameCounter] = (SDL_GPUFence*)vulkanCommandBuffer->inFlightFence;
(void)SDL_AtomicIncRef(&vulkanCommandBuffer->inFlightFence->referenceCount);
if (presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
if (presentResult == VK_SUBOPTIMAL_KHR || presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
presentData->windowData->needsSwapchainRecreate = true;
}
} else {
CHECK_VULKAN_ERROR_AND_RETURN(presentResult, vkQueuePresentKHR, false)
}
presentData->windowData->frameCounter =
(presentData->windowData->frameCounter + 1) % MAX_FRAMES_IN_FLIGHT;
}
// Check if we can perform any cleanups
@@ -10568,7 +10634,7 @@ static inline Uint8 CheckDeviceExtensions(
supports->ext = 1; \
}
CHECK(KHR_swapchain)
else CHECK(KHR_maintenance1) else CHECK(KHR_driver_properties) else CHECK(EXT_vertex_attribute_divisor) else CHECK(KHR_portability_subset)
else CHECK(KHR_maintenance1) else CHECK(KHR_driver_properties) else CHECK(EXT_vertex_attribute_divisor) else CHECK(KHR_portability_subset) else CHECK(EXT_texture_compression_astc_hdr)
#undef CHECK
}
@@ -10583,7 +10649,8 @@ static inline Uint32 GetDeviceExtensionCount(VulkanExtensions *supports)
supports->KHR_maintenance1 +
supports->KHR_driver_properties +
supports->EXT_vertex_attribute_divisor +
supports->KHR_portability_subset);
supports->KHR_portability_subset +
supports->EXT_texture_compression_astc_hdr);
}
static inline void CreateDeviceExtensionArray(
@@ -10600,6 +10667,7 @@ static inline void CreateDeviceExtensionArray(
CHECK(KHR_driver_properties)
CHECK(EXT_vertex_attribute_divisor)
CHECK(KHR_portability_subset)
CHECK(EXT_texture_compression_astc_hdr)
#undef CHECK
}
+1 -2
View File
@@ -60,7 +60,6 @@
#include "../core/linux/SDL_udev.h"
#ifdef SDL_USE_LIBUDEV
#include <poll.h>
#include "../core/linux/SDL_sandbox.h"
#endif
#ifdef HAVE_INOTIFY
@@ -1144,7 +1143,7 @@ int SDL_hid_init(void)
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"udev disabled by SDL_HINT_HIDAPI_UDEV");
linux_enumeration_method = ENUMERATION_FALLBACK;
} else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) {
} else if (SDL_GetSandbox() != SDL_SANDBOX_NONE) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Container detected, disabling HIDAPI udev integration");
linux_enumeration_method = ENUMERATION_FALLBACK;
+104 -108
View File
@@ -98,9 +98,6 @@ struct hid_device_
int m_nDeviceRefCount;
};
static JavaVM *g_JVM;
static pthread_key_t g_ThreadKey;
template<class T>
class hid_device_ref
{
@@ -495,10 +492,7 @@ public:
bool BOpen()
{
// Make sure thread is attached to JVM/env
JNIEnv *env;
g_JVM->AttachCurrentThread( &env, NULL );
pthread_setspecific( g_ThreadKey, (void*)env );
JNIEnv *env = SDL_GetAndroidJNIEnv();
if ( !g_HIDDeviceManagerCallbackHandler )
{
@@ -506,46 +500,38 @@ public:
return false;
}
m_bIsWaitingForOpen = false;
m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
ExceptionCheck( env, "BOpen" );
if ( m_bIsWaitingForOpen )
{
hid_mutex_guard cvl( &m_cvLock );
const int OPEN_TIMEOUT_SECONDS = 60;
struct timespec ts, endtime;
clock_gettime( CLOCK_REALTIME, &ts );
endtime = ts;
endtime.tv_sec += OPEN_TIMEOUT_SECONDS;
do
{
if ( pthread_cond_timedwait( &m_cv, &m_cvLock, &endtime ) != 0 )
{
break;
}
}
while ( m_bIsWaitingForOpen && get_timespec_ms( ts ) < get_timespec_ms( endtime ) );
SDL_SetError( "Waiting for permission" );
return false;
}
if ( !m_bOpenResult )
{
m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
ExceptionCheck( env, "BOpen" );
if ( m_bIsWaitingForOpen )
{
LOGV( "Device open failed - timed out waiting for device permission" );
LOGV( "Device open waiting for permission" );
SDL_SetError( "Waiting for permission" );
m_bWasOpenPending = true;
return false;
}
else
if ( !m_bOpenResult )
{
LOGV( "Device open failed" );
SDL_SetError( "Device open failed" );
return false;
}
return false;
}
m_pDevice = new hid_device;
m_pDevice->m_nId = m_nId;
m_pDevice->m_nDeviceRefCount = 1;
LOGD("Creating device %d (%p), refCount = 1\n", m_pDevice->m_nId, m_pDevice);
return true;
}
@@ -554,16 +540,44 @@ public:
m_bIsWaitingForOpen = true;
}
bool BOpenPending() const
{
return m_bIsWaitingForOpen;
}
void SetWasOpenPending( bool bState )
{
m_bWasOpenPending = bState;
}
bool BWasOpenPending() const
{
return m_bWasOpenPending;
}
void SetOpenResult( bool bResult )
{
if ( m_bIsWaitingForOpen )
{
m_bOpenResult = bResult;
m_bIsWaitingForOpen = false;
pthread_cond_signal( &m_cv );
if ( m_bOpenResult )
{
LOGV( "Device open succeeded" );
}
else
{
LOGV( "Device open failed" );
}
}
}
bool BOpenResult() const
{
return m_bOpenResult;
}
void ProcessInput( const uint8_t *pBuf, size_t nBufSize )
{
hid_mutex_guard l( &m_dataLock );
@@ -610,23 +624,18 @@ public:
int WriteReport( const unsigned char *pData, size_t nDataLen, bool bFeature )
{
// Make sure thread is attached to JVM/env
JNIEnv *env;
g_JVM->AttachCurrentThread( &env, NULL );
pthread_setspecific( g_ThreadKey, (void*)env );
JNIEnv *env = SDL_GetAndroidJNIEnv();
int nRet = -1;
if ( g_HIDDeviceManagerCallbackHandler )
{
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerWriteReport, m_nId, pBuf, bFeature );
ExceptionCheck( env, "WriteReport" );
env->DeleteLocalRef( pBuf );
}
else
if ( !g_HIDDeviceManagerCallbackHandler )
{
LOGV( "WriteReport without callback handler" );
return -1;
}
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerWriteReport, m_nId, pBuf, bFeature );
ExceptionCheck( env, "WriteReport" );
env->DeleteLocalRef( pBuf );
return nRet;
}
@@ -645,10 +654,7 @@ public:
int ReadReport( unsigned char *pData, size_t nDataLen, bool bFeature )
{
// Make sure thread is attached to JVM/env
JNIEnv *env;
g_JVM->AttachCurrentThread( &env, NULL );
pthread_setspecific( g_ThreadKey, (void*)env );
JNIEnv *env = SDL_GetAndroidJNIEnv();
if ( !g_HIDDeviceManagerCallbackHandler )
{
@@ -721,15 +727,15 @@ public:
void Close( bool bDeleteDevice )
{
// Make sure thread is attached to JVM/env
JNIEnv *env;
g_JVM->AttachCurrentThread( &env, NULL );
pthread_setspecific( g_ThreadKey, (void*)env );
JNIEnv *env = SDL_GetAndroidJNIEnv();
if ( g_HIDDeviceManagerCallbackHandler )
{
env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
ExceptionCheck( env, "Close" );
if ( !m_bIsWaitingForOpen && m_bOpenResult )
{
env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
ExceptionCheck( env, "Close" );
}
}
hid_mutex_guard dataLock( &m_dataLock );
@@ -764,6 +770,7 @@ private:
pthread_mutex_t m_cvLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access any variables below
pthread_cond_t m_cv = PTHREAD_COND_INITIALIZER;
bool m_bIsWaitingForOpen = false;
bool m_bWasOpenPending = false;
bool m_bOpenResult = false;
bool m_bIsWaitingForReportResponse = false;
int m_nReportResponseError = 0;
@@ -793,16 +800,6 @@ static hid_device_ref<CHIDDevice> FindDevice( int nDeviceId )
return pDevice;
}
static void ThreadDestroyed(void* value)
{
/* The thread is being destroyed, detach it from the Java VM and set the g_ThreadKey value to NULL as required */
JNIEnv *env = (JNIEnv*) value;
if (env != NULL) {
g_JVM->DetachCurrentThread();
pthread_setspecific(g_ThreadKey, NULL);
}
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);
@@ -834,16 +831,6 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallba
{
LOGV( "HIDDeviceRegisterCallback()");
env->GetJavaVM( &g_JVM );
/*
* Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
* Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
*/
if (pthread_key_create(&g_ThreadKey, ThreadDestroyed) != 0) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "Error initializing pthread key");
}
if ( g_HIDDeviceManagerCallbackHandler != NULL )
{
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
@@ -1029,51 +1016,43 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReportResponse
extern "C"
{
// !!! FIXME: make this non-blocking!
static void SDLCALL RequestAndroidPermissionBlockingCallback(void *userdata, const char *permission, bool granted)
static void SDLCALL RequestBluetoothPermissionCallback( void *userdata, const char *permission, bool granted )
{
SDL_SetAtomicInt((SDL_AtomicInt *) userdata, granted ? 1 : -1);
SDL_Log( "Bluetooth permission %s\n", granted ? "granted" : "denied" );
if ( granted && g_HIDDeviceManagerCallbackHandler )
{
JNIEnv *env = SDL_GetAndroidJNIEnv();
env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, false, true );
}
}
static bool RequestBluetoothPermissions(const char *permission)
{
// !!! FIXME: make this non-blocking!
SDL_AtomicInt permission_response;
SDL_SetAtomicInt(&permission_response, 0);
if (!SDL_RequestAndroidPermission(permission, RequestAndroidPermissionBlockingCallback, &permission_response)) {
return false;
}
while (SDL_GetAtomicInt(&permission_response) == 0) {
SDL_Delay(10);
}
return SDL_GetAtomicInt(&permission_response) > 0;
}
int hid_init(void)
{
if ( !g_initialized && g_HIDDeviceManagerCallbackHandler )
{
// HIDAPI doesn't work well with Android < 4.3
if (SDL_GetAndroidSDKVersion() >= 18) {
// Make sure thread is attached to JVM/env
JNIEnv *env;
g_JVM->AttachCurrentThread( &env, NULL );
pthread_setspecific( g_ThreadKey, (void*)env );
if ( SDL_GetAndroidSDKVersion() >= 18 )
{
JNIEnv *env = SDL_GetAndroidJNIEnv();
env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, true, false );
// Bluetooth is currently only used for Steam Controllers, so check that hint
// before initializing Bluetooth, which will prompt the user for permission.
bool init_usb = true;
bool init_bluetooth = false;
if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAM, false)) {
if (SDL_GetAndroidSDKVersion() < 31 ||
RequestBluetoothPermissions("android.permission.BLUETOOTH_CONNECT")) {
init_bluetooth = true;
if ( SDL_GetHintBoolean( SDL_HINT_JOYSTICK_HIDAPI_STEAM, false ) )
{
if ( SDL_GetAndroidSDKVersion() < 31 )
{
env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, false, true );
}
else
{
SDL_Log( "Requesting Bluetooth permission" );
SDL_RequestAndroidPermission( "android.permission.BLUETOOTH_CONNECT", RequestBluetoothPermissionCallback, NULL );
}
}
env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, init_usb, init_bluetooth );
ExceptionCheck( env, NULL, "hid_init" );
}
g_initialized = true; // Regardless of result, so it's only called once
@@ -1088,6 +1067,18 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
hid_mutex_guard l( &g_DevicesMutex );
for ( hid_device_ref<CHIDDevice> pDevice = g_Devices; pDevice; pDevice = pDevice->next )
{
// Don't enumerate devices that are currently being opened, we'll re-enumerate them when we're done
// Make sure we skip them at least once, so they get removed and then re-added to the caller's device list
if ( pDevice->BWasOpenPending() )
{
// Don't enumerate devices that failed to open, otherwise the application might try to keep prompting for access
if ( !pDevice->BOpenPending() && pDevice->BOpenResult() )
{
pDevice->SetWasOpenPending( false );
}
continue;
}
const hid_device_info *info = pDevice->GetDeviceInfo();
/* See if there are any devices we should skip in enumeration */
@@ -1148,7 +1139,12 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
}
}
}
if ( pDevice && pDevice->BOpen() )
if ( !pDevice )
{
SDL_SetError( "Couldn't find device with path %s", path );
return NULL;
}
if ( pDevice->BOpen() )
{
return pDevice->GetDevice();
}
@@ -1159,7 +1155,7 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned ch
{
if ( device )
{
LOGV( "hid_write id=%d length=%zu", device->m_nId, length );
// LOGV( "hid_write id=%d length=%zu", device->m_nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
@@ -1223,7 +1219,7 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned ch
// TODO: Implement blocking
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
{
LOGV( "hid_read id=%d length=%zu", device->m_nId, length );
// LOGV( "hid_read id=%d length=%zu", device->m_nId, length );
return hid_read_timeout( device, data, length, 0 );
}
+5 -29
View File
@@ -2595,12 +2595,8 @@ bool SDL_IsGamepad(SDL_JoystickID instance_id)
/*
* Return 1 if the gamepad should be ignored by SDL
*/
bool SDL_ShouldIgnoreGamepad(const char *name, SDL_GUID guid)
bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
{
Uint16 vendor;
Uint16 product;
Uint16 version;
#ifdef SDL_PLATFORM_LINUX
if (SDL_endswith(name, " Motion Sensors")) {
// Don't treat the PS3 and PS4 motion controls as a separate gamepad
@@ -2624,37 +2620,17 @@ bool SDL_ShouldIgnoreGamepad(const char *name, SDL_GUID guid)
return true;
}
if (SDL_allowed_gamepads.num_included_entries == 0 &&
SDL_ignored_gamepads.num_included_entries == 0) {
return false;
}
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version, NULL);
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", false)) {
// We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real gamepads so it can remap input for the virtual gamepad
// https://partner.steamgames.com/doc/features/steam_gamepad/steam_input_gamepad_emulation_bestpractices
bool bSteamVirtualGamepad = false;
#ifdef SDL_PLATFORM_LINUX
bSteamVirtualGamepad = (vendor == USB_VENDOR_VALVE && product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD);
#elif defined(SDL_PLATFORM_MACOS)
bSteamVirtualGamepad = (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 0);
#elif defined(SDL_PLATFORM_WIN32)
// We can't tell on Windows, but Steam will block others in input hooks
bSteamVirtualGamepad = true;
#endif
if (bSteamVirtualGamepad) {
return false;
}
if (SDL_IsJoystickSteamVirtualGamepad(vendor_id, product_id, version)) {
return !SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", false);
}
if (SDL_allowed_gamepads.num_included_entries > 0) {
if (SDL_VIDPIDInList(vendor, product, &SDL_allowed_gamepads)) {
if (SDL_VIDPIDInList(vendor_id, product_id, &SDL_allowed_gamepads)) {
return false;
}
return true;
} else {
if (SDL_VIDPIDInList(vendor, product, &SDL_ignored_gamepads)) {
if (SDL_VIDPIDInList(vendor_id, product_id, &SDL_ignored_gamepads)) {
return true;
}
return false;
+1 -1
View File
@@ -39,7 +39,7 @@ extern void SDL_PrivateGamepadRemoved(SDL_JoystickID instance_id);
extern bool SDL_IsGamepadNameAndGUID(const char *name, SDL_GUID guid);
// Function to return whether a gamepad should be ignored
extern bool SDL_ShouldIgnoreGamepad(const char *name, SDL_GUID guid);
extern bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);
// Handle delayed guide button on a gamepad
extern void SDL_GamepadHandleDelayedGuideButton(SDL_Joystick *joystick);
+4 -1
View File
@@ -29,6 +29,9 @@
Alternatively, you can use the app located in test/controllermap
*/
static const char *s_GamepadMappings[] = {
#ifdef SDL_JOYSTICK_PRIVATE
SDL_PRIVATE_GAMEPAD_DEFINITIONS
#endif
#ifdef SDL_JOYSTICK_XINPUT
"xinput,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
#endif
@@ -732,7 +735,7 @@ static const char *s_GamepadMappings[] = {
"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"03000000de2800000512000000016800,Steam Deck,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"03000000de2800000512000000016800,Steam Deck Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"03000000de2800000512000011010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,misc1:b2,paddle1:b21,paddle2:b20,paddle3:b23,paddle4:b22,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,",
"03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
+35 -35
View File
@@ -52,6 +52,9 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = {
#ifdef SDL_JOYSTICK_HIDAPI // Highest priority driver for supported devices
&SDL_HIDAPI_JoystickDriver,
#endif
#ifdef SDL_JOYSTICK_PRIVATE
&SDL_PRIVATE_JoystickDriver,
#endif
#ifdef SDL_JOYSTICK_GAMEINPUT // Higher priority than other Windows drivers
&SDL_GAMEINPUT_JoystickDriver,
#endif
@@ -888,9 +891,6 @@ static bool IsROGAlly(SDL_Joystick *joystick)
static bool ShouldAttemptSensorFusion(SDL_Joystick *joystick, bool *invert_sensors)
{
const char *hint;
int hint_value;
SDL_AssertJoysticksLocked();
*invert_sensors = false;
@@ -905,30 +905,26 @@ static bool ShouldAttemptSensorFusion(SDL_Joystick *joystick, bool *invert_senso
return false;
}
hint = SDL_GetHint(SDL_HINT_GAMECONTROLLER_SENSOR_FUSION);
hint_value = SDL_GetStringInteger(hint, -1);
if (hint_value > 0) {
return true;
}
if (hint_value == 0) {
return false;
}
const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLER_SENSOR_FUSION);
if (hint && *hint) {
if (*hint == '@' || SDL_strncmp(hint, "0x", 2) == 0) {
SDL_vidpid_list gamepads;
SDL_GUID guid;
Uint16 vendor, product;
bool enabled;
SDL_zero(gamepads);
if (hint) {
SDL_vidpid_list gamepads;
SDL_GUID guid;
Uint16 vendor, product;
bool enabled;
SDL_zero(gamepads);
// See if the gamepad is in our list of devices to enable
guid = SDL_GetJoystickGUID(joystick);
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
SDL_LoadVIDPIDListFromHints(&gamepads, hint, NULL);
enabled = SDL_VIDPIDInList(vendor, product, &gamepads);
SDL_FreeVIDPIDList(&gamepads);
if (enabled) {
return true;
// See if the gamepad is in our list of devices to enable
guid = SDL_GetJoystickGUID(joystick);
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
SDL_LoadVIDPIDListFromHints(&gamepads, hint, NULL);
enabled = SDL_VIDPIDInList(vendor, product, &gamepads);
SDL_FreeVIDPIDList(&gamepads);
if (enabled) {
return true;
}
} else {
return SDL_GetStringBoolean(hint, false);
}
}
@@ -3094,6 +3090,15 @@ bool SDL_IsJoystickNVIDIASHIELDController(Uint16 vendor_id, Uint16 product_id)
product_id == USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V104));
}
bool SDL_IsJoystickSteamVirtualGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version)
{
#ifdef SDL_PLATFORM_MACOS
return (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 0);
#else
return (vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD);
#endif
}
bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id)
{
EControllerType eType = GuessControllerType(vendor_id, product_id);
@@ -3231,24 +3236,19 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_GUID guid)
return SDL_JOYSTICK_TYPE_UNKNOWN;
}
bool SDL_ShouldIgnoreJoystick(const char *name, SDL_GUID guid)
bool SDL_ShouldIgnoreJoystick(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
{
Uint16 vendor;
Uint16 product;
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
// Check the joystick blacklist
if (SDL_VIDPIDInList(vendor, product, &blacklist_devices)) {
if (SDL_VIDPIDInList(vendor_id, product_id, &blacklist_devices)) {
return true;
}
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_ROG_CHAKRAM, false)) {
if (SDL_VIDPIDInList(vendor, product, &rog_gamepad_mice)) {
if (SDL_VIDPIDInList(vendor_id, product_id, &rog_gamepad_mice)) {
return true;
}
}
if (SDL_ShouldIgnoreGamepad(name, guid)) {
if (SDL_ShouldIgnoreGamepad(vendor_id, product_id, version, name)) {
return true;
}
+4 -1
View File
@@ -126,6 +126,9 @@ extern bool SDL_IsJoystickGoogleStadiaController(Uint16 vendor_id, Uint16 produc
// Function to return whether a joystick is an NVIDIA SHIELD controller
extern bool SDL_IsJoystickNVIDIASHIELDController(Uint16 vendor_id, Uint16 product_id);
// Function to return whether a joystick is a Steam Virtual Gamepad
extern bool SDL_IsJoystickSteamVirtualGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version);
// Function to return whether a joystick is a Steam Controller
extern bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id);
@@ -154,7 +157,7 @@ extern bool SDL_IsJoystickRAWINPUT(SDL_GUID guid);
extern bool SDL_IsJoystickVIRTUAL(SDL_GUID guid);
// Function to return whether a joystick should be ignored
extern bool SDL_ShouldIgnoreJoystick(const char *name, SDL_GUID guid);
extern bool SDL_ShouldIgnoreJoystick(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);
// Internal event queueing functions
extern void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers);
@@ -127,6 +127,11 @@ void SDL_InitSteamVirtualGamepadInfo(void)
SDL_AssertJoysticksLocked();
// The file isn't available inside the macOS sandbox
if (SDL_GetSandbox() == SDL_SANDBOX_MACOS) {
return;
}
file = SDL_GetHint(SDL_HINT_STEAM_VIRTUAL_GAMEPAD_INFO_FILE);
if (file && *file) {
SDL_steam_virtual_gamepad_info_file = SDL_strdup(file);
+1
View File
@@ -240,6 +240,7 @@ typedef struct SDL_JoystickDriver
#define SDL_LED_MIN_REPEAT_MS 5000
// The available joystick drivers
extern SDL_JoystickDriver SDL_PRIVATE_JoystickDriver;
extern SDL_JoystickDriver SDL_ANDROID_JoystickDriver;
extern SDL_JoystickDriver SDL_BSD_JoystickDriver;
extern SDL_JoystickDriver SDL_DARWIN_JoystickDriver;
+10 -5
View File
@@ -392,7 +392,8 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
device->is_switch_joyconL = IsControllerSwitchJoyConL(controller);
device->is_switch_joyconR = IsControllerSwitchJoyConR(controller);
#ifdef SDL_JOYSTICK_HIDAPI
if ((device->is_xbox && HIDAPI_IsDeviceTypePresent(SDL_GAMEPAD_TYPE_XBOXONE)) ||
if ((device->is_xbox && (HIDAPI_IsDeviceTypePresent(SDL_GAMEPAD_TYPE_XBOXONE) ||
HIDAPI_IsDeviceTypePresent(SDL_GAMEPAD_TYPE_XBOX360))) ||
(device->is_ps4 && HIDAPI_IsDeviceTypePresent(SDL_GAMEPAD_TYPE_PS4)) ||
(device->is_ps5 && HIDAPI_IsDeviceTypePresent(SDL_GAMEPAD_TYPE_PS5)) ||
(device->is_switch_pro && HIDAPI_IsDeviceTypePresent(SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO)) ||
@@ -404,6 +405,10 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
return false;
}
#endif
if (device->is_xbox && SDL_strncmp(name, "GamePad-", 8) == 0) {
// This is a Steam Virtual Gamepad, which isn't supported by GCController
return false;
}
CheckControllerSiriRemote(controller, &device->is_siri_remote);
if (device->is_siri_remote && !SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, true)) {
@@ -493,6 +498,10 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
return false;
}
if (SDL_ShouldIgnoreJoystick(vendor, product, 0, name)) {
return false;
}
#ifdef ENABLE_PHYSICAL_INPUT_PROFILE
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
NSDictionary<NSString *, GCControllerElement *> *elements = controller.physicalInputProfile.elements;
@@ -661,10 +670,6 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
}
device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor, product, signature, NULL, name, 'm', subtype);
if (SDL_ShouldIgnoreJoystick(name, device->guid)) {
return false;
}
/* This will be set when the first button press of the controller is
* detected. */
controller.playerIndex = -1;
+1 -1
View File
@@ -426,7 +426,7 @@ static bool MaybeAddDevice(const char *path)
name = SDL_CreateJoystickName(di.udi_vendorNo, di.udi_productNo, di.udi_vendor, di.udi_product);
guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, di.udi_vendor, di.udi_product, 0, 0);
if (SDL_ShouldIgnoreJoystick(name, guid) ||
if (SDL_ShouldIgnoreJoystick(di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name) ||
SDL_JoystickHandledByAnotherDriver(&SDL_BSD_JoystickDriver, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name)) {
SDL_free(name);
FreeHwData(hw);
@@ -475,6 +475,11 @@ static bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
CFNumberGetValue(refCF, kCFNumberSInt32Type, &version);
}
if (SDL_IsJoystickXboxOne(vendor, product)) {
// We can't actually use this API for Xbox controllers
return false;
}
// get device name
refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey));
if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) {
@@ -490,6 +495,10 @@ static bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
SDL_free(name);
}
if (SDL_ShouldIgnoreJoystick(vendor, product, version, pDevice->product)) {
return false;
}
if (SDL_JoystickHandledByAnotherDriver(&SDL_DARWIN_JoystickDriver, vendor, product, version, pDevice->product)) {
return false;
}
@@ -548,11 +557,6 @@ static void JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender
return; // not a device we care about, probably.
}
if (SDL_ShouldIgnoreJoystick(device->product, device->guid)) {
FreeDevice(device);
return;
}
// Get notified when this device is disconnected.
IOHIDDeviceRegisterRemovalCallback(ioHIDDeviceObject, JoystickDeviceWasRemovedCallback, device);
IOHIDDeviceScheduleWithRunLoop(ioHIDDeviceObject, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);
@@ -28,6 +28,13 @@
#define COBJMACROS
#include <gameinput.h>
// Default value for SDL_HINT_JOYSTICK_GAMEINPUT
#if defined(SDL_PLATFORM_GDK)
#define SDL_GAMEINPUT_DEFAULT true
#else
#define SDL_GAMEINPUT_DEFAULT false
#endif
enum
{
SDL_GAMEPAD_BUTTON_GAMEINPUT_SHARE = 11
@@ -234,7 +241,7 @@ static bool GAMEINPUT_JoystickInit(void)
{
HRESULT hR;
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, false)) {
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT)) {
return true;
}
@@ -1154,6 +1154,9 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_STEAM_RIGHT_PADDLE,
((ctx->m_state.ulButtons & STEAM_BUTTON_BACK_RIGHT_MASK) != 0));
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK,
((ctx->m_state.ulButtons & STEAM_BUTTON_RIGHTPAD_CLICKED_MASK) != 0));
if (ctx->m_state.ulButtons & STEAM_DPAD_UP_MASK) {
hat |= SDL_HAT_UP;
}
@@ -80,21 +80,15 @@ static bool HIDAPI_DriverXbox360_IsSupportedDevice(SDL_HIDAPI_Device *device, co
// This is the chatpad or other input interface, not the Xbox 360 interface
return false;
}
#ifdef SDL_PLATFORM_MACOS
if (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 0) {
// This is the Steam Virtual Gamepad, which isn't supported by this driver
#if defined(SDL_PLATFORM_MACOS) && defined(SDL_JOYSTICK_MFI)
if (SDL_IsJoystickSteamVirtualGamepad(vendor_id, product_id, version)) {
// GCController support doesn't work with the Steam Virtual Gamepad
return true;
} else {
// On macOS you can't write output reports to wired XBox controllers,
// so we'll just use the GCController support instead.
return false;
}
/* Wired Xbox One controllers are handled by this driver, interfacing with
the 360Controller driver available from:
https://github.com/360Controller/360Controller/releases
Bluetooth Xbox One controllers are handled by the SDL Xbox One driver
*/
if (SDL_IsJoystickBluetoothXboxOne(vendor_id, product_id)) {
return false;
}
return (type == SDL_GAMEPAD_TYPE_XBOX360 || type == SDL_GAMEPAD_TYPE_XBOXONE);
#else
return (type == SDL_GAMEPAD_TYPE_XBOX360);
#endif
@@ -149,6 +143,13 @@ static bool HIDAPI_DriverXbox360_InitDevice(SDL_HIDAPI_Device *device)
device->type = SDL_GAMEPAD_TYPE_XBOX360;
if (SDL_IsJoystickSteamVirtualGamepad(device->vendor_id, device->product_id, device->version) &&
device->product_string && SDL_strncmp(device->product_string, "GamePad-", 8) == 0) {
int slot = 0;
SDL_sscanf(device->product_string, "GamePad-%d", &slot);
device->steam_virtual_gamepad_slot = (slot - 1);
}
return HIDAPI_JoystickConnected(device, NULL);
}
@@ -197,30 +198,6 @@ static bool HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
static bool HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
#ifdef SDL_PLATFORM_MACOS
if (SDL_IsJoystickBluetoothXboxOne(device->vendor_id, device->product_id)) {
Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 };
rumble_packet[4] = (low_frequency_rumble >> 8);
rumble_packet[5] = (high_frequency_rumble >> 8);
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
return SDL_SetError("Couldn't send rumble packet");
}
} else {
/* On macOS the 360Controller driver uses this short report,
and we need to prefix it with a magic token so hidapi passes it through untouched
*/
Uint8 rumble_packet[] = { 'M', 'A', 'G', 'I', 'C', '0', 0x00, 0x04, 0x00, 0x00 };
rumble_packet[6 + 2] = (low_frequency_rumble >> 8);
rumble_packet[6 + 3] = (high_frequency_rumble >> 8);
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
return SDL_SetError("Couldn't send rumble packet");
}
}
#else
Uint8 rumble_packet[] = { 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
rumble_packet[3] = (low_frequency_rumble >> 8);
@@ -229,7 +206,6 @@ static bool HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_J
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
return SDL_SetError("Couldn't send rumble packet");
}
#endif
return true;
}
@@ -350,9 +350,11 @@ static bool HIDAPI_DriverXboxOne_IsEnabled(void)
static bool HIDAPI_DriverXboxOne_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
#ifdef SDL_PLATFORM_MACOS
// Wired Xbox One controllers are handled by the 360Controller driver
#if defined(SDL_PLATFORM_MACOS) && defined(SDL_JOYSTICK_MFI)
if (!SDL_IsJoystickBluetoothXboxOne(vendor_id, product_id)) {
// On macOS we get a shortened version of the real report and
// you can't write output reports for wired controllers, so
// we'll just use the GCController support instead.
return false;
}
#endif
@@ -1552,8 +1554,9 @@ static bool HIDAPI_GIP_ProcessData(SDL_Joystick *joystick, SDL_DriverXboxOne_Con
while (size > GIP_HEADER_MIN_LENGTH) {
hdr_len = HIDAPI_GIP_DecodeHeader(&hdr, data, size);
if ((hdr_len + hdr.packet_length) > (size_t)size) {
return false;
if ((hdr_len + hdr.packet_length) > (Uint32)size) {
// On macOS we get a shortened version of the real report
hdr.packet_length = (Uint32)(size - hdr_len);
}
if (!HIDAPI_GIP_ProcessPacket(joystick, ctx, &hdr, data + hdr_len)) {
@@ -31,9 +31,6 @@
#include "../windows/SDL_rawinputjoystick_c.h"
#endif
#ifdef SDL_USE_LIBUDEV
#include "../../core/linux/SDL_sandbox.h"
#endif
struct joystick_hwdata
{
@@ -331,7 +328,7 @@ static SDL_HIDAPI_DeviceDriver *HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device
return &SDL_HIDAPI_DriverCombined;
}
if (SDL_ShouldIgnoreJoystick(device->name, device->guid)) {
if (SDL_ShouldIgnoreJoystick(device->vendor_id, device->product_id, device->version, device->name)) {
return NULL;
}
@@ -457,57 +454,7 @@ static void HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, bool *removed) S
// Wait a little bit for the device to initialize
SDL_Delay(10);
#ifdef SDL_PLATFORM_ANDROID
/* On Android we need to leave joysticks unlocked because it calls
* out to the main thread for permissions and the main thread can
* be in the process of handling controller input.
*
* See https://github.com/libsdl-org/SDL/issues/6347 for details
*/
{
SDL_HIDAPI_Device *curr;
int lock_count = 0;
char *path = SDL_strdup(device->path);
SDL_AssertJoysticksLocked();
while (SDL_JoysticksLocked()) {
++lock_count;
SDL_UnlockJoysticks();
}
dev = SDL_hid_open_path(path);
while (lock_count > 0) {
--lock_count;
SDL_LockJoysticks();
}
SDL_free(path);
// Make sure the device didn't get removed while opening the HID path
for (curr = SDL_HIDAPI_devices; curr && curr != device; curr = curr->next) {
continue;
}
if (curr == NULL) {
*removed = true;
if (dev) {
SDL_hid_close(dev);
}
return;
}
}
#else
/* On other platforms we want to keep the lock so other threads wait for
* us to finish opening the controller before checking to see whether the
* HIDAPI driver is handling the device.
*
* On Windows, for example, the main thread can be enumerating DirectInput
* devices while the Windows.Gaming.Input thread is calling back with a new
* controller available.
*
* See https://github.com/libsdl-org/SDL/issues/7304 for details.
*/
dev = SDL_hid_open_path(device->path);
#endif
if (dev == NULL) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
@@ -586,7 +533,7 @@ static bool HIDAPI_JoystickInit(void)
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"udev disabled by SDL_HINT_HIDAPI_UDEV");
linux_enumeration_method = ENUMERATION_FALLBACK;
} else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) {
} else if (SDL_GetSandbox() != SDL_SANDBOX_NONE) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Container detected, disabling HIDAPI udev integration");
linux_enumeration_method = ENUMERATION_FALLBACK;
@@ -983,6 +930,7 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf
device->guid = SDL_CreateJoystickGUID(bus, device->vendor_id, device->product_id, device->version, device->manufacturer_string, device->product_string, 'h', 0);
device->joystick_type = SDL_JOYSTICK_TYPE_GAMEPAD;
device->type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
device->steam_virtual_gamepad_slot = -1;
if (num_children > 0) {
int i;
@@ -1440,6 +1388,12 @@ static const char *HIDAPI_JoystickGetDevicePath(int device_index)
static int HIDAPI_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index)
{
SDL_HIDAPI_Device *device;
device = HIDAPI_GetDeviceByIndex(device_index, NULL);
if (device) {
return device->steam_virtual_gamepad_slot;
}
return -1;
}
@@ -85,6 +85,7 @@ typedef struct SDL_HIDAPI_Device
bool is_bluetooth;
SDL_JoystickType joystick_type;
SDL_GamepadType type;
int steam_virtual_gamepad_slot;
struct SDL_HIDAPI_DeviceDriver *driver;
void *context;
@@ -124,7 +124,6 @@
#include "../../core/linux/SDL_evdev_capabilities.h"
#include "../../core/linux/SDL_udev.h"
#include "../../core/linux/SDL_sandbox.h"
#if 0
#define DEBUG_INPUT_EVENTS 1
@@ -330,15 +329,14 @@ static bool IsJoystick(const char *path, int *fd, char **name_return, Uint16 *ve
SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
#endif
*guid = SDL_CreateJoystickGUID(inpid.bustype, inpid.vendor, inpid.product, inpid.version, NULL, product_string, 0, 0);
if (SDL_ShouldIgnoreJoystick(name, *guid)) {
if (SDL_ShouldIgnoreJoystick(inpid.vendor, inpid.product, inpid.version, name)) {
SDL_free(name);
return false;
}
*name_return = name;
*vendor_return = inpid.vendor;
*product_return = inpid.product;
*guid = SDL_CreateJoystickGUID(inpid.bustype, inpid.vendor, inpid.product, inpid.version, NULL, product_string, 0, 0);
return true;
}
@@ -1069,7 +1067,7 @@ static bool LINUX_JoystickInit(void)
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
enumeration_method = ENUMERATION_FALLBACK;
} else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) {
} else if (SDL_GetSandbox() != SDL_SANDBOX_NONE) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Container detected, disabling udev integration");
enumeration_method = ENUMERATION_FALLBACK;
@@ -472,6 +472,8 @@ static BOOL CALLBACK EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInsta
CHECK(QueryDeviceInfo(device, &vendor, &product));
CHECK(!SDL_IsXInputDevice(vendor, product, hidPath));
CHECK(!SDL_ShouldIgnoreJoystick(vendor, product, version, name));
CHECK(!SDL_JoystickHandledByAnotherDriver(&SDL_WINDOWS_JoystickDriver, vendor, product, version, name));
pNewJoystick = *(JoyStick_DeviceData **)pContext;
while (pNewJoystick) {
@@ -514,10 +516,6 @@ static BOOL CALLBACK EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInsta
pNewJoystick->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor, product, version, NULL, name, 0, 0);
}
CHECK(!SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid));
CHECK(!SDL_JoystickHandledByAnotherDriver(&SDL_WINDOWS_JoystickDriver, vendor, product, version, pNewJoystick->joystickname));
WINDOWS_AddJoystickDevice(pNewJoystick);
pNewJoystick = NULL;
@@ -881,7 +881,9 @@ static void RAWINPUT_AddDevice(HANDLE hDevice)
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &size) != (UINT)-1);
// Only take XInput-capable devices
CHECK(SDL_strstr(dev_name, "IG_") != NULL);
CHECK(!SDL_ShouldIgnoreJoystick((Uint16)rdi.hid.dwVendorId, (Uint16)rdi.hid.dwProductId, (Uint16)rdi.hid.dwVersionNumber, ""));
CHECK(!SDL_JoystickHandledByAnotherDriver(&SDL_RAWINPUT_JoystickDriver, (Uint16)rdi.hid.dwVendorId, (Uint16)rdi.hid.dwProductId, (Uint16)rdi.hid.dwVersionNumber, ""));
device = (SDL_RAWINPUT_Device *)SDL_calloc(1, sizeof(SDL_RAWINPUT_Device));
CHECK(device);
device->hDevice = hDevice;
@@ -399,7 +399,6 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID___x_ABI_CWindows_CGaming_CInput_CIRawGameController, (void **)&controller);
if (SUCCEEDED(hr)) {
char *name = NULL;
SDL_GUID guid = { 0 };
Uint16 bus = SDL_HARDWARE_BUS_USB;
Uint16 vendor = 0;
Uint16 product = 0;
@@ -446,6 +445,10 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
name = SDL_strdup("");
}
if (!ignore_joystick && SDL_ShouldIgnoreJoystick(vendor, product, version, name)) {
ignore_joystick = true;
}
if (!ignore_joystick && SDL_JoystickHandledByAnotherDriver(&SDL_WGI_JoystickDriver, vendor, product, version, name)) {
ignore_joystick = true;
}
@@ -455,18 +458,6 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
ignore_joystick = true;
}
if (!ignore_joystick) {
if (game_controller) {
type = GetGameControllerType(game_controller);
}
guid = SDL_CreateJoystickGUID(bus, vendor, product, version, NULL, name, 'w', (Uint8)type);
if (SDL_ShouldIgnoreJoystick(name, guid)) {
ignore_joystick = true;
}
}
if (!ignore_joystick) {
// New device, add it
WindowsGamingInputControllerState *controllers = SDL_realloc(wgi.controllers, sizeof(wgi.controllers[0]) * (wgi.controller_count + 1));
@@ -474,11 +465,15 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
WindowsGamingInputControllerState *state = &controllers[wgi.controller_count];
SDL_JoystickID joystickID = SDL_GetNextObjectID();
if (game_controller) {
type = GetGameControllerType(game_controller);
}
SDL_zerop(state);
state->instance_id = joystickID;
state->controller = controller;
state->name = name;
state->guid = guid;
state->guid = SDL_CreateJoystickGUID(bus, vendor, product, version, NULL, name, 'w', (Uint8)type);
state->type = type;
state->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot(controller, vendor, product);
@@ -185,13 +185,18 @@ static void AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pC
pNewJoystick = pNewJoystick->pNext;
}
name = GetXInputName(userid, SubType);
GetXInputDeviceInfo(userid, &vendor, &product, &version);
if (SDL_ShouldIgnoreJoystick(vendor, product, version, name) ||
SDL_JoystickHandledByAnotherDriver(&SDL_WINDOWS_JoystickDriver, vendor, product, version, name)) {
return;
}
pNewJoystick = (JoyStick_DeviceData *)SDL_calloc(1, sizeof(JoyStick_DeviceData));
if (!pNewJoystick) {
return; // better luck next time?
}
name = GetXInputName(userid, SubType);
GetXInputDeviceInfo(userid, &vendor, &product, &version);
pNewJoystick->bXInputDevice = true;
pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, name);
if (!pNewJoystick->joystickname) {
@@ -203,16 +208,6 @@ static void AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pC
pNewJoystick->SubType = SubType;
pNewJoystick->XInputUserId = userid;
if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
SDL_free(pNewJoystick);
return;
}
if (SDL_JoystickHandledByAnotherDriver(&SDL_WINDOWS_JoystickDriver, vendor, product, version, pNewJoystick->joystickname)) {
SDL_free(pNewJoystick);
return;
}
WINDOWS_AddJoystickDevice(pNewJoystick);
}
+1 -1
View File
@@ -102,7 +102,7 @@ union {
Uint64 u64;
double d;
} inf_union = {
0x7ff0000000000000 /* Binary representation of a 64-bit infinite double (sign=0, exponent=2047, mantissa=0) */
SDL_UINT64_C(0x7ff0000000000000) /* Binary representation of a 64-bit infinite double (sign=0, exponent=2047, mantissa=0) */
};
double __ieee754_exp(double x) /* default IEEE double exp */
+5
View File
@@ -75,6 +75,11 @@ static bool SDLCALL SDL_MainCallbackEventWatcher(void *userdata, SDL_Event *even
// Make sure any currently queued events are processed then dispatch this before continuing
SDL_DispatchMainCallbackEvents();
SDL_DispatchMainCallbackEvent(event);
// Make sure that we quit if we get a terminating event
if (event->type == SDL_EVENT_TERMINATING) {
SDL_CompareAndSwapAtomicInt(&apprc, SDL_APP_CONTINUE, SDL_APP_SUCCESS);
}
} else {
// We'll process this event later from the main event queue
}
@@ -65,7 +65,7 @@ int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit,
} else {
const Uint64 now = SDL_GetTicksNS();
if (next_iteration > now) { // Running faster than the limit, sleep a little.
SDL_DelayNS(next_iteration - now);
SDL_DelayPrecise(next_iteration - now);
} else {
next_iteration = now; // running behind (or just lost the window)...reset the timer.
}
@@ -73,6 +73,14 @@ static bool SetupRedirect(SDL_PropertiesID props, const char *property, HANDLE *
WIN_SetError("DuplicateHandle()");
return false;
}
if (GetFileType(*result) == FILE_TYPE_PIPE) {
DWORD wait_mode = PIPE_WAIT;
if (!SetNamedPipeHandleState(*result, &wait_mode, NULL, NULL)) {
WIN_SetError("SetNamedPipeHandleState()");
return false;
}
}
return true;
}
+126 -5
View File
@@ -23,6 +23,7 @@
// The SDL 2D rendering system
#include "SDL_sysrender.h"
#include "SDL_render_debug_font.h"
#include "software/SDL_render_sw_c.h"
#include "../video/SDL_pixels_c.h"
#include "../video/SDL_video_c.h"
@@ -3578,8 +3579,7 @@ bool SDL_RenderLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count
bool isstack1;
bool isstack2;
float *xy = SDL_small_alloc(float, 4 * 2 * count, &isstack1);
int *indices = SDL_small_alloc(int,
(4) * 3 * (count - 1) + (2) * 3 * (count), &isstack2);
int *indices = SDL_small_alloc(int, (4) * 3 * (count - 1) + (2) * 3 * (count), &isstack2);
if (xy && indices) {
int i;
@@ -4389,7 +4389,7 @@ bool SDL_RenderGeometry(SDL_Renderer *renderer,
}
#ifdef SDL_VIDEO_RENDER_SW
static bool remap_one_indice(
static int remap_one_indice(
int prev,
int k,
SDL_Texture *texture,
@@ -4427,7 +4427,7 @@ static bool remap_one_indice(
return prev;
}
static bool remap_indices(
static int remap_indices(
int prev[3],
int k,
SDL_Texture *texture,
@@ -4948,7 +4948,7 @@ static void SDL_SimulateRenderVSync(SDL_Renderer *renderer)
elapsed = (now - renderer->last_present);
if (elapsed < interval) {
Uint64 duration = (interval - elapsed);
SDL_DelayNS(duration);
SDL_DelayPrecise(duration);
now = SDL_GetTicksNS();
}
@@ -5098,6 +5098,11 @@ void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer)
SDL_DiscardAllCommands(renderer);
if (renderer->debug_char_texture_atlas) {
SDL_DestroyTexture(renderer->debug_char_texture_atlas);
renderer->debug_char_texture_atlas = NULL;
}
// Free existing textures for this renderer
while (renderer->textures) {
SDL_Texture *tex = renderer->textures;
@@ -5347,3 +5352,119 @@ bool SDL_GetRenderVSync(SDL_Renderer *renderer, int *vsync)
}
return true;
}
#define SDL_DEBUG_FONT_GLYPHS_PER_ROW 14
static bool CreateDebugTextAtlas(SDL_Renderer *renderer)
{
SDL_assert(renderer->debug_char_texture_atlas == NULL); // don't double-create it!
const int charWidth = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
const int charHeight = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
// actually make each glyph two pixels taller/wider, to prevent scaling artifacts.
const int rows = (SDL_DEBUG_FONT_NUM_GLYPHS / SDL_DEBUG_FONT_GLYPHS_PER_ROW) + 1;
SDL_Surface *atlas = SDL_CreateSurface((charWidth + 2) * SDL_DEBUG_FONT_GLYPHS_PER_ROW, rows * (charHeight + 2), SDL_PIXELFORMAT_RGBA8888);
if (!atlas) {
return false;
}
const int pitch = atlas->pitch;
SDL_memset(atlas->pixels, '\0', atlas->h * atlas->pitch);
int column = 0;
int row = 0;
for (int glyph = 0; glyph < SDL_DEBUG_FONT_NUM_GLYPHS; glyph++) {
// find top-left of this glyph in destination surface. The +2's account for glyph padding.
Uint8 *linepos = (((Uint8 *)atlas->pixels) + ((row * (charHeight + 2) + 1) * pitch)) + ((column * (charWidth + 2) + 1) * sizeof (Uint32));
const Uint8 *charpos = SDL_RenderDebugTextFontData + (glyph * 8);
// Draw the glyph to the surface...
for (int iy = 0; iy < charHeight; iy++) {
Uint32 *curpos = (Uint32 *)linepos;
for (int ix = 0; ix < charWidth; ix++) {
if ((*charpos) & (1 << ix)) {
*curpos = 0xffffffff;
} else {
*curpos = 0;
}
++curpos;
}
linepos += pitch;
++charpos;
}
// move to next position (and if too far, start the next row).
column++;
if (column >= SDL_DEBUG_FONT_GLYPHS_PER_ROW) {
row++;
column = 0;
}
}
SDL_assert((row < rows) || ((row == rows) && (column == 0))); // make sure we didn't overflow the surface.
// Convert temp surface into texture
renderer->debug_char_texture_atlas = SDL_CreateTextureFromSurface(renderer, atlas);
SDL_DestroySurface(atlas);
return (renderer->debug_char_texture_atlas != NULL);
}
static bool DrawDebugCharacter(SDL_Renderer *renderer, float x, float y, Uint32 c)
{
SDL_assert(renderer->debug_char_texture_atlas != NULL); // should have been created by now!
const int charWidth = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
const int charHeight = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
// Character index in cache
Uint32 ci = c;
if ((ci <= 32) || ((ci >= 127) && (ci <= 160))) {
return true; // these are just completely blank chars, don't bother doing anything.
} else if (ci >= SDL_DEBUG_FONT_NUM_GLYPHS) {
ci = SDL_DEBUG_FONT_NUM_GLYPHS - 1; // use our "not a valid/supported character" glyph.
} else if (ci < 127) {
ci -= 33; // adjust for the 33 blank glyphs at the start
} else {
ci -= 67; // adjust for the 33 blank glyphs at the start AND the 34 gap in the middle.
}
const float src_x = (float) (((ci % SDL_DEBUG_FONT_GLYPHS_PER_ROW) * (charWidth + 2)) + 1);
const float src_y = (float) (((ci / SDL_DEBUG_FONT_GLYPHS_PER_ROW) * (charHeight + 2)) + 1);
// Draw texture onto destination
const SDL_FRect srect = { src_x, src_y, (float) charWidth, (float) charHeight };
const SDL_FRect drect = { x, y, (float) charWidth, (float) charHeight };
return SDL_RenderTexture(renderer, renderer->debug_char_texture_atlas, &srect, &drect);
}
bool SDL_RenderDebugText(SDL_Renderer *renderer, float x, float y, const char *s)
{
CHECK_RENDERER_MAGIC(renderer, false);
// Allocate a texture atlas for this renderer if needed.
if (!renderer->debug_char_texture_atlas) {
if (!CreateDebugTextAtlas(renderer)) {
return false;
}
}
bool result = true;
Uint8 r, g, b, a;
result &= SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a);
result &= SDL_SetTextureColorMod(renderer->debug_char_texture_atlas, r, g, b);
result &= SDL_SetTextureAlphaMod(renderer->debug_char_texture_atlas, a);
float curx = x;
Uint32 ch;
while (result && ((ch = SDL_StepUTF8(&s, NULL)) != 0)) {
result &= DrawDebugCharacter(renderer, curx, y, ch);
curx += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
}
return result;
}
File diff suppressed because it is too large Load Diff
+2
View File
@@ -305,6 +305,8 @@ struct SDL_Renderer
SDL_PropertiesID props;
SDL_Texture *debug_char_texture_atlas;
bool destroyed; // already destroyed by SDL_DestroyWindow; just free this struct in SDL_DestroyRenderer.
void *internal;
+4 -4
View File
@@ -1215,15 +1215,15 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
renderer->window = window;
renderer->name = GPU_RenderDriver.name;
bool debug = SDL_GetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, false);
bool lowpower = SDL_GetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOL, false);
bool debug = SDL_GetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN, false);
bool lowpower = SDL_GetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, false);
// Prefer environment variables/hints if they exist, otherwise defer to properties
debug = SDL_GetHintBoolean(SDL_HINT_RENDER_GPU_DEBUG, debug);
lowpower = SDL_GetHintBoolean(SDL_HINT_RENDER_GPU_LOW_POWER, lowpower);
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, debug);
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOL, lowpower);
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN, debug);
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, lowpower);
GPU_FillSupportedShaderFormats(create_props);
data->device = SDL_CreateGPUDeviceWithProperties(create_props);
+4 -4
View File
@@ -247,10 +247,10 @@ SDL_GPUShader *GPU_GetFragmentShader(GPU_Shaders *shaders, GPU_FragmentShaderID
void GPU_FillSupportedShaderFormats(SDL_PropertiesID props)
{
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOL, HAVE_SPIRV_SHADERS);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOL, HAVE_DXBC50_SHADERS);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOL, HAVE_DXIL60_SHADERS);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOL, HAVE_METAL_SHADERS);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, HAVE_SPIRV_SHADERS);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN, HAVE_DXBC50_SHADERS);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN, HAVE_DXIL60_SHADERS);
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, HAVE_METAL_SHADERS);
}
#endif // SDL_VIDEO_RENDER_GPU
+1 -14
View File
@@ -1497,20 +1497,7 @@ static SDL_Surface *GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *
// Flip the rows to be top-down if necessary
if (!renderer->target) {
bool isstack;
int length = rect->w * SDL_BYTESPERPIXEL(format);
Uint8 *src = (Uint8 *)surface->pixels + (rect->h - 1) * surface->pitch;
Uint8 *dst = (Uint8 *)surface->pixels;
Uint8 *tmp = SDL_small_alloc(Uint8, length, &isstack);
int rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += surface->pitch;
src -= surface->pitch;
}
SDL_small_free(tmp, isstack);
SDL_FlipSurface(surface, SDL_FLIP_VERTICAL);
}
return surface;
}
+5 -9
View File
@@ -348,15 +348,11 @@ static bool CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char
ctx->glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
info = SDL_small_alloc(char, length + 1, &isstack);
ctx->glGetInfoLogARB(shader, length, NULL, info);
SDL_LogError(SDL_LOG_CATEGORY_RENDER,
"Failed to compile shader:\n%s%s\n%s", defines, source, info);
#ifdef DEBUG_SHADERS
fprintf(stderr,
"Failed to compile shader:\n%s%s\n%s", defines, source, info);
#endif
SDL_small_free(info, isstack);
if (info) {
ctx->glGetInfoLogARB(shader, length, NULL, info);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to compile shader:\n%s%s\n%s", defines, source, info);
SDL_small_free(info, isstack);
}
return false;
} else {
return true;
@@ -2014,20 +2014,7 @@ static SDL_Surface *GLES2_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rec
// Flip the rows to be top-down if necessary
if (!renderer->target) {
bool isstack;
int length = rect->w * SDL_BYTESPERPIXEL(format);
Uint8 *src = (Uint8 *)surface->pixels + (rect->h - 1) * surface->pitch;
Uint8 *dst = (Uint8 *)surface->pixels;
Uint8 *tmp = SDL_small_alloc(Uint8, length, &isstack);
int rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += surface->pitch;
src -= surface->pitch;
}
SDL_small_free(tmp, isstack);
SDL_FlipSurface(surface, SDL_FLIP_VERTICAL);
}
return surface;
}
@@ -349,6 +349,7 @@ static bool VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
if (length == pitch && length == dpitch) {
SDL_memcpy(dst, pixels, length * rect->h);
pixels += pitch * rect->h;
} else {
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, pixels, length);
@@ -376,6 +377,7 @@ static bool VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
// U plane
if (length == uv_src_pitch && length == uv_pitch) {
SDL_memcpy(Udst, pixels, length * UVrect.h);
pixels += uv_src_pitch * UVrect.h;
} else {
for (row = 0; row < UVrect.h; ++row) {
SDL_memcpy(Udst, pixels, length);
@@ -1103,22 +1105,8 @@ static SDL_Surface *VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_
read_pixels(rect->x, y, rect->w, rect->h, surface->pixels);
// Flip the rows to be top-down if necessary
if (!renderer->target) {
bool isstack;
int length = rect->w * SDL_BYTESPERPIXEL(format);
Uint8 *src = (Uint8 *)surface->pixels + (rect->h - 1) * surface->pitch;
Uint8 *dst = (Uint8 *)surface->pixels;
Uint8 *tmp = SDL_small_alloc(Uint8, length, &isstack);
int rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += surface->pitch;
src -= surface->pitch;
}
SDL_small_free(tmp, isstack);
SDL_FlipSurface(surface, SDL_FLIP_VERTICAL);
}
return surface;
}
@@ -740,10 +740,10 @@ int gxm_init(SDL_Renderer *renderer)
colorVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
colorVertexAttributes[0].componentCount = 2; // (x, y)
colorVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorPositionAttribute);
// color: 4 unsigned char = 32 bits
// color: 4 floats = 4*32 bits
colorVertexAttributes[1].streamIndex = 0;
colorVertexAttributes[1].offset = 8; // (x, y) * 4 = 8 bytes
colorVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N;
colorVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
colorVertexAttributes[1].componentCount = 4; // (color)
colorVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorColorAttribute);
// 16 bit (short) indices
@@ -785,10 +785,10 @@ int gxm_init(SDL_Renderer *renderer)
textureVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
textureVertexAttributes[1].componentCount = 2; // (u, v)
textureVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureTexcoordAttribute);
// r,g,b,a: 4 unsigned chars 32 bits
// r,g,b,a: 4 floats 4*32 bits
textureVertexAttributes[2].streamIndex = 0;
textureVertexAttributes[2].offset = 16; // (x, y, u, v) * 4 = 16 bytes
textureVertexAttributes[2].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N;
textureVertexAttributes[2].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
textureVertexAttributes[2].componentCount = 4; // (r, g, b, a)
textureVertexAttributes[2].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureColorAttribute);
// 16 bit (short) indices
+83 -72
View File
@@ -2054,6 +2054,89 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
return result;
}
// clean up previous swapchain resources
if (rendererData->swapchainImageViews) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
vkDestroyImageView(rendererData->device, rendererData->swapchainImageViews[i], NULL);
}
SDL_free(rendererData->swapchainImageViews);
rendererData->swapchainImageViews = NULL;
}
if (rendererData->fences) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->fences[i] != VK_NULL_HANDLE) {
vkDestroyFence(rendererData->device, rendererData->fences[i], NULL);
}
}
SDL_free(rendererData->fences);
rendererData->fences = NULL;
}
if (rendererData->framebuffers) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->framebuffers[i] != VK_NULL_HANDLE) {
vkDestroyFramebuffer(rendererData->device, rendererData->framebuffers[i], NULL);
}
}
SDL_free(rendererData->framebuffers);
rendererData->framebuffers = NULL;
}
if (rendererData->descriptorPools) {
SDL_assert(rendererData->numDescriptorPools);
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
for (uint32_t j = 0; j < rendererData->numDescriptorPools[i]; j++) {
if (rendererData->descriptorPools[i][j] != VK_NULL_HANDLE) {
vkDestroyDescriptorPool(rendererData->device, rendererData->descriptorPools[i][j], NULL);
}
}
SDL_free(rendererData->descriptorPools[i]);
}
SDL_free(rendererData->descriptorPools);
rendererData->descriptorPools = NULL;
SDL_free(rendererData->numDescriptorPools);
rendererData->numDescriptorPools = NULL;
}
if (rendererData->imageAvailableSemaphores) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
if (rendererData->imageAvailableSemaphores[i] != VK_NULL_HANDLE) {
vkDestroySemaphore(rendererData->device, rendererData->imageAvailableSemaphores[i], NULL);
}
}
SDL_free(rendererData->imageAvailableSemaphores);
rendererData->imageAvailableSemaphores = NULL;
}
if (rendererData->renderingFinishedSemaphores) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
if (rendererData->renderingFinishedSemaphores[i] != VK_NULL_HANDLE) {
vkDestroySemaphore(rendererData->device, rendererData->renderingFinishedSemaphores[i], NULL);
}
}
SDL_free(rendererData->renderingFinishedSemaphores);
rendererData->renderingFinishedSemaphores = NULL;
}
if (rendererData->uploadBuffers) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
for (uint32_t j = 0; j < SDL_VULKAN_NUM_UPLOAD_BUFFERS; j++) {
VULKAN_DestroyBuffer(rendererData, &rendererData->uploadBuffers[i][j]);
}
SDL_free(rendererData->uploadBuffers[i]);
}
SDL_free(rendererData->uploadBuffers);
rendererData->uploadBuffers = NULL;
}
if (rendererData->constantBuffers) {
SDL_assert(rendererData->numConstantBuffers);
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
for (uint32_t j = 0; j < rendererData->numConstantBuffers[i]; j++) {
VULKAN_DestroyBuffer(rendererData, &rendererData->constantBuffers[i][j]);
}
SDL_free(rendererData->constantBuffers[i]);
}
SDL_free(rendererData->constantBuffers);
rendererData->constantBuffers = NULL;
SDL_free(rendererData->numConstantBuffers);
rendererData->numConstantBuffers = NULL;
}
// pick an image count
rendererData->swapchainDesiredImageCount = rendererData->surfaceCapabilities.minImageCount + SDL_VULKAN_FRAME_QUEUE_DEPTH;
if ((rendererData->swapchainDesiredImageCount > rendererData->surfaceCapabilities.maxImageCount) &&
@@ -2217,12 +2300,6 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
imageViewCreateInfo.subresourceRange.layerCount = 1;
imageViewCreateInfo.subresourceRange.levelCount = 1;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
if (rendererData->swapchainImageViews) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
vkDestroyImageView(rendererData->device, rendererData->swapchainImageViews[i], NULL);
}
SDL_free(rendererData->swapchainImageViews);
}
rendererData->swapchainImageViews = (VkImageView *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkImageView));
SDL_free(rendererData->swapchainImageLayouts);
rendererData->swapchainImageLayouts = (VkImageLayout *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkImageLayout));
@@ -2259,14 +2336,6 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
}
// Create fences
if (rendererData->fences) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->fences[i] != VK_NULL_HANDLE) {
vkDestroyFence(rendererData->device, rendererData->fences[i], NULL);
}
}
SDL_free(rendererData->fences);
}
rendererData->fences = (VkFence *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkFence));
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
VkFenceCreateInfo fenceCreateInfo = { 0 };
@@ -2281,14 +2350,6 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
}
// Create renderpasses and framebuffer
if (rendererData->framebuffers) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->framebuffers[i] != VK_NULL_HANDLE) {
vkDestroyFramebuffer(rendererData->device, rendererData->framebuffers[i], NULL);
}
}
SDL_free(rendererData->framebuffers);
}
for (uint32_t i = 0; i < SDL_arraysize(rendererData->renderPasses); i++) {
if (rendererData->renderPasses[i] != VK_NULL_HANDLE) {
vkDestroyRenderPass(rendererData->device, rendererData->renderPasses[i], NULL);
@@ -2311,19 +2372,6 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
}
// Create descriptor pools - start by allocating one per swapchain image, let it grow if more are needed
if (rendererData->descriptorPools) {
SDL_assert(rendererData->numDescriptorPools);
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
for (uint32_t j = 0; j < rendererData->numDescriptorPools[i]; j++) {
if (rendererData->descriptorPools[i][j] != VK_NULL_HANDLE) {
vkDestroyDescriptorPool(rendererData->device, rendererData->descriptorPools[i][j], NULL);
}
}
SDL_free(rendererData->descriptorPools[i]);
}
SDL_free(rendererData->descriptorPools);
SDL_free(rendererData->numDescriptorPools);
}
rendererData->descriptorPools = (VkDescriptorPool **)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkDescriptorPool*));
rendererData->numDescriptorPools = (uint32_t *)SDL_calloc(rendererData->swapchainImageCount, sizeof(uint32_t));
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
@@ -2338,22 +2386,6 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
}
// Create semaphores
if (rendererData->imageAvailableSemaphores) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
if (rendererData->imageAvailableSemaphores[i] != VK_NULL_HANDLE) {
vkDestroySemaphore(rendererData->device, rendererData->imageAvailableSemaphores[i], NULL);
}
}
SDL_free(rendererData->imageAvailableSemaphores);
}
if (rendererData->renderingFinishedSemaphores) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
if (rendererData->renderingFinishedSemaphores[i] != VK_NULL_HANDLE) {
vkDestroySemaphore(rendererData->device, rendererData->renderingFinishedSemaphores[i], NULL);
}
}
SDL_free(rendererData->renderingFinishedSemaphores);
}
rendererData->imageAvailableSemaphores = (VkSemaphore *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkSemaphore));
rendererData->renderingFinishedSemaphores = (VkSemaphore *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkSemaphore));
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
@@ -2370,15 +2402,6 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
}
// Upload buffers
if (rendererData->uploadBuffers) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
for (uint32_t j = 0; j < SDL_VULKAN_NUM_UPLOAD_BUFFERS; j++) {
VULKAN_DestroyBuffer(rendererData, &rendererData->uploadBuffers[i][j]);
}
SDL_free(rendererData->uploadBuffers[i]);
}
SDL_free(rendererData->uploadBuffers);
}
rendererData->uploadBuffers = (VULKAN_Buffer **)SDL_calloc(rendererData->swapchainImageCount, sizeof(VULKAN_Buffer*));
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
rendererData->uploadBuffers[i] = (VULKAN_Buffer *)SDL_calloc(SDL_VULKAN_NUM_UPLOAD_BUFFERS, sizeof(VULKAN_Buffer));
@@ -2387,18 +2410,6 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
rendererData->currentUploadBuffer = (int *)SDL_calloc(rendererData->swapchainImageCount, sizeof(int));
// Constant buffers
if (rendererData->constantBuffers) {
SDL_assert(rendererData->numConstantBuffers);
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
for (uint32_t j = 0; j < rendererData->numConstantBuffers[i]; j++) {
VULKAN_DestroyBuffer(rendererData, &rendererData->constantBuffers[i][j]);
}
SDL_free(rendererData->constantBuffers[i]);
}
SDL_free(rendererData->constantBuffers);
SDL_free(rendererData->numConstantBuffers);
rendererData->constantBuffers = NULL;
}
rendererData->constantBuffers = (VULKAN_Buffer **)SDL_calloc(rendererData->swapchainImageCount, sizeof(VULKAN_Buffer*));
rendererData->numConstantBuffers = (uint32_t *)SDL_calloc(rendererData->swapchainImageCount, sizeof(uint32_t));
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
+20
View File
@@ -265,6 +265,26 @@ Uint32 SDL_StepUTF8(const char **pstr, size_t *pslen)
return result;
}
Uint32 SDL_StepBackUTF8(const char *start, const char **pstr)
{
if (!pstr || *pstr <= start) {
return 0;
}
// Step back over the previous UTF-8 character
const char *str = *pstr;
do {
if (str == start) {
break;
}
--str;
} while ((*str & 0xC0) == 0x80);
size_t length = (*pstr - str);
*pstr = str;
return StepUTF8(&str, length);
}
#if (SDL_SIZEOF_WCHAR_T == 2)
static Uint32 StepUTF16(const Uint16 **_str, const size_t slen)
{
File diff suppressed because it is too large Load Diff
+42 -52
View File
@@ -41,11 +41,11 @@
typedef struct SDL_cond_generic
{
SDL_Mutex *lock;
int waiting;
int signals;
SDL_Semaphore *wait_sem;
SDL_Semaphore *wait_done;
SDL_Semaphore *sem;
SDL_Semaphore *handshake_sem;
SDL_Semaphore *signal_sem;
int num_waiting;
int num_signals;
} SDL_cond_generic;
// Create a condition variable
@@ -55,11 +55,10 @@ SDL_Condition *SDL_CreateCondition_generic(void)
#ifndef SDL_THREADS_DISABLED
if (cond) {
cond->lock = SDL_CreateMutex();
cond->wait_sem = SDL_CreateSemaphore(0);
cond->wait_done = SDL_CreateSemaphore(0);
cond->waiting = cond->signals = 0;
if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
cond->sem = SDL_CreateSemaphore(0);
cond->handshake_sem = SDL_CreateSemaphore(0);
cond->signal_sem = SDL_CreateSemaphore(1);
if (!cond->sem || !cond->handshake_sem || !cond->signal_sem) {
SDL_DestroyCondition_generic((SDL_Condition *)cond);
cond = NULL;
}
@@ -74,14 +73,14 @@ void SDL_DestroyCondition_generic(SDL_Condition *_cond)
{
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
if (cond) {
if (cond->wait_sem) {
SDL_DestroySemaphore(cond->wait_sem);
if (cond->sem) {
SDL_DestroySemaphore(cond->sem);
}
if (cond->wait_done) {
SDL_DestroySemaphore(cond->wait_done);
if (cond->handshake_sem) {
SDL_DestroySemaphore(cond->handshake_sem);
}
if (cond->lock) {
SDL_DestroyMutex(cond->lock);
if (cond->signal_sem) {
SDL_DestroySemaphore(cond->signal_sem);
}
SDL_free(cond);
}
@@ -99,14 +98,14 @@ void SDL_SignalCondition_generic(SDL_Condition *_cond)
/* If there are waiting threads not already signalled, then
signal the condition and wait for the thread to respond.
*/
SDL_LockMutex(cond->lock);
if (cond->waiting > cond->signals) {
++cond->signals;
SDL_SignalSemaphore(cond->wait_sem);
SDL_UnlockMutex(cond->lock);
SDL_WaitSemaphore(cond->wait_done);
SDL_WaitSemaphore(cond->signal_sem);
if (cond->num_waiting > cond->num_signals) {
cond->num_signals++;
SDL_SignalSemaphore(cond->sem);
SDL_SignalSemaphore(cond->signal_sem);
SDL_WaitSemaphore(cond->handshake_sem);
} else {
SDL_UnlockMutex(cond->lock);
SDL_SignalSemaphore(cond->signal_sem);
}
#endif
}
@@ -123,24 +122,22 @@ void SDL_BroadcastCondition_generic(SDL_Condition *_cond)
/* If there are waiting threads not already signalled, then
signal the condition and wait for the thread to respond.
*/
SDL_LockMutex(cond->lock);
if (cond->waiting > cond->signals) {
int i, num_waiting;
num_waiting = (cond->waiting - cond->signals);
cond->signals = cond->waiting;
for (i = 0; i < num_waiting; ++i) {
SDL_SignalSemaphore(cond->wait_sem);
SDL_WaitSemaphore(cond->signal_sem);
if (cond->num_waiting > cond->num_signals) {
const int num_waiting = (cond->num_waiting - cond->num_signals);
cond->num_signals = cond->num_waiting;
for (int i = 0; i < num_waiting; i++) {
SDL_SignalSemaphore(cond->sem);
}
/* Now all released threads are blocked here, waiting for us.
Collect them all (and win fabulous prizes!) :-)
*/
SDL_UnlockMutex(cond->lock);
for (i = 0; i < num_waiting; ++i) {
SDL_WaitSemaphore(cond->wait_done);
SDL_SignalSemaphore(cond->signal_sem);
for (int i = 0; i < num_waiting; i++) {
SDL_WaitSemaphore(cond->handshake_sem);
}
} else {
SDL_UnlockMutex(cond->lock);
SDL_SignalSemaphore(cond->signal_sem);
}
#endif
}
@@ -180,15 +177,15 @@ bool SDL_WaitConditionTimeoutNS_generic(SDL_Condition *_cond, SDL_Mutex *mutex,
This allows the signal mechanism to only perform a signal if there
are waiting threads.
*/
SDL_LockMutex(cond->lock);
++cond->waiting;
SDL_UnlockMutex(cond->lock);
SDL_WaitSemaphore(cond->signal_sem);
cond->num_waiting++;
SDL_SignalSemaphore(cond->signal_sem);
// Unlock the mutex, as is required by condition variable semantics
SDL_UnlockMutex(mutex);
// Wait for a signal
result = SDL_WaitSemaphoreTimeoutNS(cond->wait_sem, timeoutNS);
result = SDL_WaitSemaphoreTimeoutNS(cond->sem, timeoutNS);
/* Let the signaler know we have completed the wait, otherwise
the signaler can race ahead and get the condition semaphore
@@ -196,20 +193,13 @@ bool SDL_WaitConditionTimeoutNS_generic(SDL_Condition *_cond, SDL_Mutex *mutex,
giving a deadlock. See the following URL for details:
http://web.archive.org/web/20010914175514/http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html#Workshop
*/
SDL_LockMutex(cond->lock);
if (cond->signals > 0) {
// If we timed out, we need to eat a condition signal
if (!result) {
SDL_WaitSemaphore(cond->wait_sem);
}
// We always notify the signal thread that we are done
SDL_SignalSemaphore(cond->wait_done);
// Signal handshake complete
--cond->signals;
SDL_WaitSemaphore(cond->signal_sem);
if (cond->num_signals > 0) {
SDL_SignalSemaphore(cond->handshake_sem);
cond->num_signals--;
}
--cond->waiting;
SDL_UnlockMutex(cond->lock);
cond->num_waiting--;
SDL_SignalSemaphore(cond->signal_sem);
// Lock the mutex, as is required by condition variable semantics
SDL_LockMutex(mutex);
@@ -26,7 +26,9 @@
#include <pthread_np.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include <errno.h>
#ifdef SDL_PLATFORM_LINUX
@@ -55,11 +57,13 @@
#include <kernel/OS.h>
#endif
#ifdef HAVE_SIGNAL_H
// List of signals to mask in the subthreads
static const int sig_list[] = {
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
SIGVTALRM, SIGPROF, 0
};
#endif
static void *RunThread(void *data)
{
@@ -117,8 +121,10 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread,
void SDL_SYS_SetupThread(const char *name)
{
#ifdef HAVE_SIGNAL_H
int i;
sigset_t mask;
#endif
if (name) {
#if (defined(SDL_PLATFORM_MACOS) || defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_LINUX)) && defined(HAVE_DLOPEN)
@@ -154,12 +160,14 @@ void SDL_SYS_SetupThread(const char *name)
#endif
}
#ifdef HAVE_SIGNAL_H
// Mask asynchronous signals for this thread
sigemptyset(&mask);
for (i = 0; sig_list[i]; ++i) {
sigaddset(&mask, sig_list[i]);
}
pthread_sigmask(SIG_BLOCK, &mask, 0);
#endif
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
// Allow ourselves to be asynchronously cancelled
+9 -4
View File
@@ -32,6 +32,8 @@
#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
#endif
#define SDL_DEBUGGER_NAME_EXCEPTION_CODE 0x406D1388
typedef void (__cdecl * SDL_EndThreadExCallback) (unsigned retval);
typedef uintptr_t (__cdecl * SDL_BeginThreadExCallback)
(void *security, unsigned stacksize, unsigned (__stdcall *startaddr)(void *),
@@ -97,10 +99,13 @@ typedef struct tagTHREADNAME_INFO
} THREADNAME_INFO;
#pragma pack(pop)
static LONG NTAPI EmptyVectoredExceptionHandler(EXCEPTION_POINTERS *ExceptionInfo)
static LONG NTAPI EmptyVectoredExceptionHandler(EXCEPTION_POINTERS *info)
{
(void)ExceptionInfo;
return EXCEPTION_CONTINUE_EXECUTION;
if (info != NULL && info->ExceptionRecord != NULL && info->ExceptionRecord->ExceptionCode == SDL_DEBUGGER_NAME_EXCEPTION_CODE) {
return EXCEPTION_CONTINUE_EXECUTION;
} else {
return EXCEPTION_CONTINUE_SEARCH;
}
}
typedef HRESULT(WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR);
@@ -148,7 +153,7 @@ void SDL_SYS_SetupThread(const char *name)
inf.dwFlags = 0;
// The debugger catches this, renames the thread, continues on.
RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR *)&inf);
RaiseException(SDL_DEBUGGER_NAME_EXCEPTION_CODE, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR *)&inf);
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
}
}
+69 -13
View File
@@ -658,21 +658,77 @@ void SDL_Delay(Uint32 ms)
void SDL_DelayNS(Uint64 ns)
{
Uint64 current_value = SDL_GetTicksNS();
Uint64 target_value = current_value + ns;
SDL_SYS_DelayNS(ns);
}
// Sleep for a short number of cycles
// We'll use 1 ms as a scheduling timeslice, it's a good value for modern operating systems
const int SCHEDULING_TIMESLICE_NS = 1 * SDL_NS_PER_MS;
while (current_value < target_value) {
Uint64 remaining_ns = (target_value - current_value);
if (remaining_ns > (SCHEDULING_TIMESLICE_NS + SDL_NS_PER_US)) {
// Sleep for a short time, less than the scheduling timeslice
SDL_SYS_DelayNS(SCHEDULING_TIMESLICE_NS - SDL_NS_PER_US);
} else {
// Spin for any remaining time
SDL_CPUPauseInstruction();
void SDL_DelayPrecise(Uint64 ns)
{
Uint64 current_value = SDL_GetTicksNS();
const Uint64 target_value = current_value + ns;
// Sleep for a short number of cycles when real sleeps are desired.
// We'll use 1 ms, it's the minimum guaranteed to produce real sleeps across
// all platforms.
const Uint64 SHORT_SLEEP_NS = 1 * SDL_NS_PER_MS;
// Try to sleep short of target_value. If for some crazy reason
// a particular platform sleeps for less than 1 ms when 1 ms was requested,
// that's fine, the code below can cope with that, but in practice no
// platforms behave that way.
Uint64 max_sleep_ns = SHORT_SLEEP_NS;
while (current_value + max_sleep_ns < target_value) {
// Sleep for a short time
SDL_SYS_DelayNS(SHORT_SLEEP_NS);
const Uint64 now = SDL_GetTicksNS();
const Uint64 next_sleep_ns = (now - current_value);
if (next_sleep_ns > max_sleep_ns) {
max_sleep_ns = next_sleep_ns;
}
current_value = now;
}
// Do a shorter sleep of the remaining time here, less the max overshoot in
// the first loop. Due to maintaining max_sleep_ns as
// greater-than-or-equal-to-1 ms, we can always subtract off 1 ms to get
// the duration overshot beyond a 1 ms sleep request; if the system never
// overshot, great, it's zero duration. By choosing the max overshoot
// amount, we're likely to not overshoot here. If the sleep here ends up
// functioning like SDL_DelayNS(0) internally, that's fine, we just don't
// get to do a more-precise-than-1 ms-resolution sleep to undershoot by a
// small amount on the current system, but SDL_DelayNS(0) does at least
// introduce a small, yielding delay on many platforms, better than an
// unyielding busyloop.
//
// Note that we'll always do at least one sleep in this function, so the
// minimum resolution will be that of SDL_SYS_DelayNS()
if (current_value < target_value && (target_value - current_value) > (max_sleep_ns - SHORT_SLEEP_NS)) {
const Uint64 delay_ns = (target_value - current_value) - (max_sleep_ns - SHORT_SLEEP_NS);
SDL_SYS_DelayNS(delay_ns);
current_value = SDL_GetTicksNS();
}
// We've likely undershot target_value at this point by a pretty small
// amount, but maybe not. The footgun case if not handled here is where
// we've undershot by a large amount, like several ms, but still smaller
// than the amount max_sleep_ns overshot by; in such a situation, the above
// shorter-sleep block didn't do any delay, the if-block wasn't entered.
// Also, maybe the shorter-sleep undershot by several ms, so we still don't
// want to spin a lot then. In such a case, we accept the possibility of
// overshooting to not spin much, or if overshot here, not at all, keeping
// CPU/power usage down in any case. Due to scheduler sloppiness, it's
// entirely possible to end up undershooting/overshooting here by much less
// than 1 ms even if the current system's sleep function is only 1
// ms-resolution, as SDL_GetTicksNS() generally is better resolution than 1
// ms on the systems SDL supports.
while (current_value + SHORT_SLEEP_NS < target_value) {
SDL_SYS_DelayNS(SHORT_SLEEP_NS);
current_value = SDL_GetTicksNS();
}
// Spin for any remaining time
while (current_value < target_value) {
SDL_CPUPauseInstruction();
current_value = SDL_GetTicksNS();
}
}
+32 -20
View File
@@ -25,13 +25,13 @@
#include "../../core/windows/SDL_windows.h"
#ifdef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
static void SDL_CleanupWaitableTimer(void *timer)
static void SDL_CleanupWaitableHandle(void *handle)
{
CloseHandle(timer);
CloseHandle(handle);
}
HANDLE SDL_GetWaitableTimer(void)
#ifdef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
static HANDLE SDL_GetWaitableTimer(void)
{
static SDL_TLSID TLS_timer_handle;
HANDLE timer;
@@ -40,13 +40,28 @@ HANDLE SDL_GetWaitableTimer(void)
if (!timer) {
timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
if (timer) {
SDL_SetTLS(&TLS_timer_handle, timer, SDL_CleanupWaitableTimer);
SDL_SetTLS(&TLS_timer_handle, timer, SDL_CleanupWaitableHandle);
}
}
return timer;
}
#endif // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
static HANDLE SDL_GetWaitableEvent(void)
{
static SDL_TLSID TLS_event_handle;
HANDLE event;
event = SDL_GetTLS(&TLS_event_handle);
if (!event) {
event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (event) {
SDL_SetTLS(&TLS_event_handle, event, SDL_CleanupWaitableHandle);
}
}
return event;
}
Uint64 SDL_GetPerformanceCounter(void)
{
LARGE_INTEGER counter;
@@ -81,22 +96,19 @@ void SDL_SYS_DelayNS(Uint64 ns)
}
#endif
{
const Uint64 max_delay = 0xffffffffLL * SDL_NS_PER_MS;
if (ns > max_delay) {
ns = max_delay;
}
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER <= 180030723)
static HANDLE mutex = 0;
if (!mutex) {
mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS);
}
WaitForSingleObjectEx(mutex, (DWORD)SDL_NS_TO_MS(ns), FALSE);
#else
Sleep((DWORD)SDL_NS_TO_MS(ns));
#endif
const Uint64 max_delay = 0xffffffffLL * SDL_NS_PER_MS;
if (ns > max_delay) {
ns = max_delay;
}
const DWORD delay = (DWORD)SDL_NS_TO_MS(ns);
HANDLE event = SDL_GetWaitableEvent();
if (event) {
WaitForSingleObjectEx(event, delay, FALSE);
return;
}
Sleep(delay);
}
#endif // SDL_TIMER_WINDOWS
+11 -2
View File
@@ -1064,7 +1064,7 @@ static bool RLEAlphaSurface(SDL_Surface *surface)
return false;
}
// save the destination format so we can undo the encoding later
*(SDL_PixelFormat *)rlebuf = df->format;
*(SDL_PixelFormat *)rlebuf = dest->format;
dst = rlebuf + sizeof(SDL_PixelFormat);
// Do the actual encoding
@@ -1232,6 +1232,7 @@ static const getpix_func getpixes[4] = {
static bool RLEColorkeySurface(SDL_Surface *surface)
{
SDL_Surface *dest;
Uint8 *rlebuf, *dst;
int maxn;
int y;
@@ -1242,6 +1243,11 @@ static bool RLEColorkeySurface(SDL_Surface *surface)
Uint32 ckey, rgbmask;
int w, h;
dest = surface->map.info.dst_surface;
if (!dest) {
return false;
}
// calculate the worst case size for the compressed surface
switch (bpp) {
case 1:
@@ -1263,15 +1269,18 @@ static bool RLEColorkeySurface(SDL_Surface *surface)
return false;
}
maxsize += sizeof(SDL_PixelFormat);
rlebuf = (Uint8 *)SDL_malloc(maxsize);
if (!rlebuf) {
return false;
}
// save the destination format so we can undo the encoding later
*(SDL_PixelFormat *)rlebuf = dest->format;
// Set up the conversion
srcbuf = (Uint8 *)surface->pixels;
maxn = bpp == 4 ? 65535 : 255;
dst = rlebuf;
dst = rlebuf + sizeof(SDL_PixelFormat);
rgbmask = ~surface->fmt->Amask;
ckey = surface->map.info.colorkey & rgbmask;
lastline = dst;
+36 -10
View File
@@ -610,6 +610,15 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface);
#else
#define USE_DUFFS_LOOP
#endif
#define DUFFS_LOOP1(pixel_copy_increment, width) \
{ \
int n; \
for (n = width; n > 0; --n) { \
pixel_copy_increment; \
} \
}
#ifdef USE_DUFFS_LOOP
// 8-times unrolled loop
@@ -666,8 +675,26 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface);
} \
}
// Use the 8-times version of the loop by default
// 2-times unrolled loop
#define DUFFS_LOOP2(pixel_copy_increment, width) \
{ \
int n = (width + 1) / 2; \
switch (width & 1) { \
case 0: \
do { \
pixel_copy_increment; \
SDL_FALLTHROUGH; \
case 1: \
pixel_copy_increment; \
} while (--n > 0); \
} \
}
// Use the 4-times version of the loop by default
#define DUFFS_LOOP(pixel_copy_increment, width) \
DUFFS_LOOP4(pixel_copy_increment, width)
// Use the 8-times version of the loop for simple routines
#define DUFFS_LOOP_TRIVIAL(pixel_copy_increment, width) \
DUFFS_LOOP8(pixel_copy_increment, width)
// Special version of Duff's device for even more optimization
@@ -701,20 +728,19 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface);
// Don't use Duff's device to unroll loops
#define DUFFS_LOOP(pixel_copy_increment, width) \
{ \
int n; \
for (n = width; n > 0; --n) { \
pixel_copy_increment; \
} \
}
DUFFS_LOOP1(pixel_copy_increment, width)
#define DUFFS_LOOP_TRIVIAL(pixel_copy_increment, width) \
DUFFS_LOOP1(pixel_copy_increment, width)
#define DUFFS_LOOP8(pixel_copy_increment, width) \
DUFFS_LOOP(pixel_copy_increment, width)
DUFFS_LOOP1(pixel_copy_increment, width)
#define DUFFS_LOOP4(pixel_copy_increment, width) \
DUFFS_LOOP(pixel_copy_increment, width)
DUFFS_LOOP1(pixel_copy_increment, width)
#define DUFFS_LOOP2(pixel_copy_increment, width) \
DUFFS_LOOP1(pixel_copy_increment, width)
#define DUFFS_LOOP_124(pixel_copy_increment1, \
pixel_copy_increment2, \
pixel_copy_increment4, width) \
DUFFS_LOOP(pixel_copy_increment1, width)
DUFFS_LOOP1(pixel_copy_increment1, width)
#endif // USE_DUFFS_LOOP
+20 -48
View File
@@ -604,11 +604,8 @@ SDL_FORCE_INLINE void BlitBto4Key(SDL_BlitInfo *info, const Uint32 srcbpp)
}
}
SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp)
static void BlitBtoNAlpha(SDL_BlitInfo *info)
{
const Uint32 mask = (1 << srcbpp) - 1;
const Uint32 align = (8 / srcbpp) - 1;
int width = info->dst_w;
int height = info->dst_h;
Uint8 *src = info->src;
@@ -616,15 +613,17 @@ SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp)
int srcskip = info->src_skip;
int dstskip = info->dst_skip;
const SDL_Color *srcpal = info->src_pal->colors;
const SDL_PixelFormatDetails *srcfmt = info->src_fmt;
const SDL_PixelFormatDetails *dstfmt = info->dst_fmt;
int dstbpp;
int srcbpp, dstbpp;
int c;
Uint32 pixel;
Uint32 pixel, mask, align;
unsigned sR, sG, sB;
unsigned dR, dG, dB, dA;
const unsigned A = info->a;
// Set up some basic variables
srcbpp = srcfmt->bytes_per_pixel;
dstbpp = dstfmt->bytes_per_pixel;
if (srcbpp == 4)
srcskip += width - (width + 1) / 2;
@@ -632,6 +631,8 @@ SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp)
srcskip += width - (width + 3) / 4;
else if (srcbpp == 1)
srcskip += width - (width + 7) / 8;
mask = (1 << srcbpp) - 1;
align = (8 / srcbpp) - 1;
if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) {
while (height--) {
@@ -680,28 +681,27 @@ SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp)
}
}
SDL_FORCE_INLINE void BlitBtoNAlphaKey(SDL_BlitInfo *info, const Uint32 srcbpp)
static void BlitBtoNAlphaKey(SDL_BlitInfo *info)
{
const Uint32 mask = (1 << srcbpp) - 1;
const Uint32 align = (8 / srcbpp) - 1;
int width = info->dst_w;
int height = info->dst_h;
Uint8 *src = info->src;
Uint8 *dst = info->dst;
int srcskip = info->src_skip;
int dstskip = info->dst_skip;
const SDL_PixelFormatDetails *srcfmt = info->src_fmt;
const SDL_PixelFormatDetails *dstfmt = info->dst_fmt;
const SDL_Color *srcpal = info->src_pal->colors;
int dstbpp;
int srcbpp, dstbpp;
int c;
Uint32 pixel;
Uint32 pixel, mask, align;
unsigned sR, sG, sB;
unsigned dR, dG, dB, dA;
const unsigned A = info->a;
Uint32 ckey = info->colorkey;
// Set up some basic variables
srcbpp = srcfmt->bytes_per_pixel;
dstbpp = dstfmt->bytes_per_pixel;
if (srcbpp == 4)
srcskip += width - (width + 1) / 2;
@@ -709,6 +709,8 @@ SDL_FORCE_INLINE void BlitBtoNAlphaKey(SDL_BlitInfo *info, const Uint32 srcbpp)
srcskip += width - (width + 3) / 4;
else if (srcbpp == 1)
srcskip += width - (width + 7) / 8;
mask = (1 << srcbpp) - 1;
align = (8 / srcbpp) - 1;
if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) {
while (height--) {
@@ -799,16 +801,6 @@ static const SDL_BlitFunc colorkey_blit_1b[] = {
(SDL_BlitFunc)NULL, Blit1bto1Key, Blit1bto2Key, Blit1bto3Key, Blit1bto4Key
};
static void Blit1btoNAlpha(SDL_BlitInfo *info)
{
BlitBtoNAlpha(info, 1);
}
static void Blit1btoNAlphaKey(SDL_BlitInfo *info)
{
BlitBtoNAlphaKey(info, 1);
}
static void Blit2bto1(SDL_BlitInfo *info) {
@@ -851,16 +843,6 @@ static const SDL_BlitFunc colorkey_blit_2b[] = {
(SDL_BlitFunc)NULL, Blit2bto1Key, Blit2bto2Key, Blit2bto3Key, Blit2bto4Key
};
static void Blit2btoNAlpha(SDL_BlitInfo *info)
{
BlitBtoNAlpha(info, 2);
}
static void Blit2btoNAlphaKey(SDL_BlitInfo *info)
{
BlitBtoNAlphaKey(info, 2);
}
static void Blit4bto1(SDL_BlitInfo *info) {
@@ -903,16 +885,6 @@ static const SDL_BlitFunc colorkey_blit_4b[] = {
(SDL_BlitFunc)NULL, Blit4bto1Key, Blit4bto2Key, Blit4bto3Key, Blit4bto4Key
};
static void Blit4btoNAlpha(SDL_BlitInfo *info)
{
BlitBtoNAlpha(info, 4);
}
static void Blit4btoNAlphaKey(SDL_BlitInfo *info)
{
BlitBtoNAlphaKey(info, 4);
}
SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface)
@@ -940,10 +912,10 @@ SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface)
break;
case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
return which >= 2 ? Blit1btoNAlpha : (SDL_BlitFunc)NULL;
return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL;
case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
return which >= 2 ? Blit1btoNAlphaKey : (SDL_BlitFunc)NULL;
return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL;
}
return NULL;
}
@@ -963,10 +935,10 @@ SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface)
break;
case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
return which >= 2 ? Blit2btoNAlpha : (SDL_BlitFunc)NULL;
return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL;
case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
return which >= 2 ? Blit2btoNAlphaKey : (SDL_BlitFunc)NULL;
return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL;
}
return NULL;
}
@@ -986,10 +958,10 @@ SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface)
break;
case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
return which >= 2 ? Blit4btoNAlpha : (SDL_BlitFunc)NULL;
return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL;
case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
return which >= 2 ? Blit4btoNAlphaKey : (SDL_BlitFunc)NULL;
return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL;
}
return NULL;
}
+8 -8
View File
@@ -48,7 +48,7 @@ static void Blit1to1(SDL_BlitInfo *info)
while (height--) {
#ifdef USE_DUFFS_LOOP
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
*dst = map[*src];
}
@@ -100,7 +100,7 @@ static void Blit1to2(SDL_BlitInfo *info)
#ifdef USE_DUFFS_LOOP
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
*(Uint16 *)dst = map[*src++];
dst += 2;
@@ -256,7 +256,7 @@ static void Blit1to4(SDL_BlitInfo *info)
while (height--) {
#ifdef USE_DUFFS_LOOP
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
*dst++ = map[*src++];
, width);
/* *INDENT-ON* */ // clang-format on
@@ -297,7 +297,7 @@ static void Blit1to1Key(SDL_BlitInfo *info)
if (palmap) {
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
if ( *src != ckey ) {
*dst = palmap[*src];
@@ -313,7 +313,7 @@ static void Blit1to1Key(SDL_BlitInfo *info)
} else {
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
if ( *src != ckey ) {
*dst = *src;
@@ -345,7 +345,7 @@ static void Blit1to2Key(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
if ( *src != ckey ) {
*dstp=palmap[*src];
@@ -408,7 +408,7 @@ static void Blit1to4Key(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
if ( *src != ckey ) {
*dstp = palmap[*src];
@@ -444,7 +444,7 @@ static void Blit1toNAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4(
DUFFS_LOOP(
{
sR = srcpal[*src].r;
sG = srcpal[*src].g;
+11 -11
View File
@@ -46,7 +46,7 @@ static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4(
DUFFS_LOOP(
{
DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
dR = dstpal[*dst].r;
@@ -91,7 +91,7 @@ static void BlitNto1PixelAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4(
DUFFS_LOOP(
{
DISEMBLE_RGBA(src,srcbpp,srcfmt,Pixel,sR,sG,sB,sA);
dR = dstpal[*dst].r;
@@ -253,7 +253,7 @@ static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4({
DUFFS_LOOP({
Uint32 s = *srcp++;
Uint32 d = *dstp;
*dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
@@ -283,7 +283,7 @@ static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4({
DUFFS_LOOP({
s = *srcp;
d = *dstp;
@@ -705,7 +705,7 @@ static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4({
DUFFS_LOOP({
Uint32 s = *srcp++;
Uint32 d = *dstp;
/*
@@ -743,7 +743,7 @@ static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4({
DUFFS_LOOP({
Uint32 s = *srcp++;
Uint32 d = *dstp;
/*
@@ -776,7 +776,7 @@ static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4({
DUFFS_LOOP({
Uint32 s = *srcp;
unsigned alpha = s >> 27; // downscale alpha to 5 bits
/* Here we special-case opaque alpha since the
@@ -819,7 +819,7 @@ static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4({
DUFFS_LOOP({
unsigned alpha;
Uint32 s = *srcp;
alpha = s >> 27; // downscale alpha to 5 bits
@@ -872,7 +872,7 @@ static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info)
if (sA) {
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4(
DUFFS_LOOP(
{
DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA);
@@ -910,7 +910,7 @@ static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP4(
DUFFS_LOOP(
{
RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
if (sA && Pixel != ckey) {
@@ -1302,7 +1302,7 @@ static void BlitNtoNPixelAlpha(SDL_BlitInfo *info)
dstbpp = dstfmt->bytes_per_pixel;
while (height--) {
DUFFS_LOOP4(
DUFFS_LOOP(
{
DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
if (sA) {
+8 -47
View File
@@ -40,7 +40,6 @@
#define BLIT_FEATURE_HAS_MMX 0x01
#define BLIT_FEATURE_HAS_ALTIVEC 0x02
#define BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH 0x04
#define BLIT_FEATURE_HAS_ARM_SIMD 0x08
#ifdef SDL_ALTIVEC_BLITTERS
#ifdef SDL_PLATFORM_MACOS
@@ -891,37 +890,7 @@ static Uint32 GetBlitFeatures(void)
#endif
#else
// Feature 1 is has-MMX
#define GetBlitFeatures() ((SDL_HasMMX() ? BLIT_FEATURE_HAS_MMX : 0) | (SDL_HasARMSIMD() ? BLIT_FEATURE_HAS_ARM_SIMD : 0))
#endif
#ifdef SDL_ARM_SIMD_BLITTERS
void Blit_XBGR8888_XRGB8888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride);
static void Blit_XBGR8888_XRGB8888ARMSIMD(SDL_BlitInfo *info)
{
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint32_t *dstp = (uint32_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 2);
uint32_t *srcp = (uint32_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 2);
Blit_XBGR8888_XRGB8888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
}
void Blit_RGB444_XRGB8888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint16_t *src, int32_t src_stride);
static void Blit_RGB444_XRGB8888ARMSIMD(SDL_BlitInfo *info)
{
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint32_t *dstp = (uint32_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 2);
uint16_t *srcp = (uint16_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 1);
Blit_RGB444_XRGB8888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
}
#define GetBlitFeatures() ((SDL_HasMMX() ? BLIT_FEATURE_HAS_MMX : 0))
#endif
// This is now endian dependent
@@ -1831,7 +1800,7 @@ static void Blit_RGB555_ARGB1555(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
*dst = *src | mask;
++dst;
@@ -1862,7 +1831,7 @@ static void Blit4to4MaskAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
*dst = *src | mask;
++dst;
@@ -1879,7 +1848,7 @@ static void Blit4to4MaskAlpha(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
*dst = *src & mask;
++dst;
@@ -2173,7 +2142,7 @@ static void Blit2to2Key(SDL_BlitInfo *info)
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
if ( (*srcp & rgbmask) != ckey ) {
*dstp = *srcp;
@@ -2219,7 +2188,7 @@ static void BlitNtoNKey(SDL_BlitInfo *info)
Uint32 mask = ((Uint32)info->a) << dstfmt->Ashift;
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
if ((*src32 & rgbmask) != ckey) {
*dst32 = *src32 | mask;
@@ -2237,7 +2206,7 @@ static void BlitNtoNKey(SDL_BlitInfo *info)
Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
if ((*src32 & rgbmask) != ckey) {
*dst32 = *src32 & mask;
@@ -2494,7 +2463,7 @@ static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info)
Uint32 *dst32 = (Uint32 *)dst;
while (height--) {
/* *INDENT-OFF* */ // clang-format off
DUFFS_LOOP(
DUFFS_LOOP_TRIVIAL(
{
if ((*src32 & rgbmask) != ckey) {
*dst32 = *src32;
@@ -2825,10 +2794,6 @@ static const struct blit_table normal_blit_2[] = {
{ 0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA },
#endif
#ifdef SDL_ARM_SIMD_BLITTERS
{ 0x00000F00, 0x000000F0, 0x0000000F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
BLIT_FEATURE_HAS_ARM_SIMD, Blit_RGB444_XRGB8888ARMSIMD, NO_ALPHA | COPY_ALPHA },
#endif
#if SDL_HAVE_BLIT_N_RGB565
{ 0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
0, Blit_RGB565_ARGB8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA },
@@ -2895,10 +2860,6 @@ static const struct blit_table normal_blit_4[] = {
// has-altivec
{ 0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F,
BLIT_FEATURE_HAS_ALTIVEC, Blit_XRGB8888_RGB565Altivec, NO_ALPHA },
#endif
#ifdef SDL_ARM_SIMD_BLITTERS
{ 0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
BLIT_FEATURE_HAS_ARM_SIMD, Blit_XBGR8888_XRGB8888ARMSIMD, NO_ALPHA | COPY_ALPHA },
#endif
// 4->3 with same rgb triplet
{ 0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x000000FF, 0x0000FF00, 0x00FF0000,
+57 -52
View File
@@ -589,7 +589,11 @@ done:
SDL_Surface *SDL_LoadBMP(const char *file)
{
return SDL_LoadBMP_IO(SDL_IOFromFile(file, "rb"), 1);
SDL_IOStream *stream = SDL_IOFromFile(file, "rb");
if (!stream) {
return NULL;
}
return SDL_LoadBMP_IO(stream, true);
}
bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
@@ -597,7 +601,7 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
bool was_error = true;
Sint64 fp_offset, new_offset;
int i, pad;
SDL_Surface *intermediate_surface;
SDL_Surface *intermediate_surface = NULL;
Uint8 *bits;
bool save32bit = false;
bool saveLegacyBMP = false;
@@ -634,63 +638,60 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
Uint32 bV4GammaBlue = 0;
// Make sure we have somewhere to save
intermediate_surface = NULL;
if (dst) {
if (!SDL_SurfaceValid(surface)) {
SDL_InvalidParamError("surface");
goto done;
}
if (!SDL_SurfaceValid(surface)) {
SDL_InvalidParamError("surface");
goto done;
}
if (!dst) {
SDL_InvalidParamError("dst");
goto done;
}
#ifdef SAVE_32BIT_BMP
// We can save alpha information in a 32-bit BMP
if (SDL_BITSPERPIXEL(surface->format) >= 8 &&
(SDL_ISPIXELFORMAT_ALPHA(surface->format) ||
surface->map.info.flags & SDL_COPY_COLORKEY)) {
save32bit = true;
}
// We can save alpha information in a 32-bit BMP
if (SDL_BITSPERPIXEL(surface->format) >= 8 &&
(SDL_ISPIXELFORMAT_ALPHA(surface->format) ||
surface->map.info.flags & SDL_COPY_COLORKEY)) {
save32bit = true;
}
#endif // SAVE_32BIT_BMP
if (surface->palette && !save32bit) {
if (SDL_BITSPERPIXEL(surface->format) == 8) {
intermediate_surface = surface;
} else {
SDL_SetError("%u bpp BMP files not supported",
SDL_BITSPERPIXEL(surface->format));
goto done;
}
} else if ((SDL_BITSPERPIXEL(surface->format) == 24) && !save32bit &&
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
(surface->fmt->Rmask == 0x00FF0000) &&
(surface->fmt->Gmask == 0x0000FF00) &&
(surface->fmt->Bmask == 0x000000FF)
#else
(surface->fmt->Rmask == 0x000000FF) &&
(surface->fmt->Gmask == 0x0000FF00) &&
(surface->fmt->Bmask == 0x00FF0000)
#endif
) {
if (surface->palette && !save32bit) {
if (SDL_BITSPERPIXEL(surface->format) == 8) {
intermediate_surface = surface;
} else {
SDL_PixelFormat pixel_format;
/* If the surface has a colorkey or alpha channel we'll save a
32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
if (save32bit) {
pixel_format = SDL_PIXELFORMAT_BGRA32;
} else {
pixel_format = SDL_PIXELFORMAT_BGR24;
}
intermediate_surface = SDL_ConvertSurface(surface, pixel_format);
if (!intermediate_surface) {
SDL_SetError("Couldn't convert image to %d bpp",
(int)SDL_BITSPERPIXEL(pixel_format));
goto done;
}
SDL_SetError("%u bpp BMP files not supported",
SDL_BITSPERPIXEL(surface->format));
goto done;
}
} else if ((SDL_BITSPERPIXEL(surface->format) == 24) && !save32bit &&
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
(surface->fmt->Rmask == 0x00FF0000) &&
(surface->fmt->Gmask == 0x0000FF00) &&
(surface->fmt->Bmask == 0x000000FF)
#else
(surface->fmt->Rmask == 0x000000FF) &&
(surface->fmt->Gmask == 0x0000FF00) &&
(surface->fmt->Bmask == 0x00FF0000)
#endif
) {
intermediate_surface = surface;
} else {
/* Set no error here because it may overwrite a more useful message from
SDL_IOFromFile() if SDL_SaveBMP_IO() is called from SDL_SaveBMP(). */
goto done;
SDL_PixelFormat pixel_format;
/* If the surface has a colorkey or alpha channel we'll save a
32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
if (save32bit) {
pixel_format = SDL_PIXELFORMAT_BGRA32;
} else {
pixel_format = SDL_PIXELFORMAT_BGR24;
}
intermediate_surface = SDL_ConvertSurface(surface, pixel_format);
if (!intermediate_surface) {
SDL_SetError("Couldn't convert image to %d bpp",
(int)SDL_BITSPERPIXEL(pixel_format));
goto done;
}
}
if (save32bit) {
@@ -873,5 +874,9 @@ done:
bool SDL_SaveBMP(SDL_Surface *surface, const char *file)
{
return SDL_SaveBMP_IO(surface, SDL_IOFromFile(file, "wb"), true);
SDL_IOStream *stream = SDL_IOFromFile(file, "wb");
if (!stream) {
return false;
}
return SDL_SaveBMP_IO(surface, stream, true);
}
+7 -3
View File
@@ -196,9 +196,13 @@ void *SDL_GetClipboardData(const char *mime_type, size_t *size)
return _this->GetClipboardData(_this, mime_type, size);
} else if (_this->GetClipboardText && SDL_IsTextMimeType(mime_type)) {
char *text = _this->GetClipboardText(_this);
if (text && *text == '\0') {
SDL_free(text);
text = NULL;
if (text) {
if (*text == '\0') {
SDL_free(text);
text = NULL;
} else {
*size = SDL_strlen(text);
}
}
return text;
} else {
+2 -3
View File
@@ -300,7 +300,9 @@ void SDL_EGL_UnloadLibrary(SDL_VideoDevice *_this)
static bool SDL_EGL_LoadLibraryInternal(SDL_VideoDevice *_this, const char *egl_path)
{
SDL_SharedObject *egl_dll_handle = NULL;
#if !defined(SDL_VIDEO_STATIC_ANGLE) && !defined(SDL_VIDEO_DRIVER_VITA)
SDL_SharedObject *opengl_dll_handle = NULL;
#endif
const char *path = NULL;
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
const char *d3dcompiler;
@@ -426,9 +428,6 @@ static bool SDL_EGL_LoadLibraryInternal(SDL_VideoDevice *_this, const char *egl_
#endif
_this->egl_data->egl_dll_handle = egl_dll_handle;
#ifdef SDL_VIDEO_DRIVER_VITA
_this->egl_data->opengl_dll_handle = opengl_dll_handle;
#endif
// Load new function pointers
LOAD_FUNC(PFNEGLGETDISPLAYPROC, eglGetDisplay);
+6 -6
View File
@@ -772,9 +772,9 @@ static const float mat_BT601_Limited_8bit[] = {
static const float mat_BT601_Full_8bit[] = {
0.0f, -0.501960814f, -0.501960814f, 0.0f, // offset
1.0000f, 0.0000f, 1.4020f, 0.0f, // Rcoeff
1.0000f, -0.3441f, -0.7141f, 0.0f, // Gcoeff
1.0000f, 1.7720f, 0.0000f, 0.0f, // Bcoeff
1.0000f, 0.0000f, 1.4075f, 0.0f, // Rcoeff
1.0000f, -0.3455f, -0.7169f, 0.0f, // Gcoeff
1.0000f, 1.7790f, 0.0000f, 0.0f, // Bcoeff
};
static const float mat_BT709_Limited_8bit[] = {
@@ -786,9 +786,9 @@ static const float mat_BT709_Limited_8bit[] = {
static const float mat_BT709_Full_8bit[] = {
0.0f, -0.501960814f, -0.501960814f, 0.0f, // offset
1.0000f, 0.0000f, 1.5748f, 0.0f, // Rcoeff
1.0000f, -0.1873f, -0.4681f, 0.0f, // Gcoeff
1.0000f, 1.8556f, 0.0000f, 0.0f, // Bcoeff
1.0000f, 0.0000f, 1.5810f, 0.0f, // Rcoeff
1.0000f, -0.1881f, -0.4700f, 0.0f, // Gcoeff
1.0000f, 1.8629f, 0.0000f, 0.0f, // Bcoeff
};
static const float mat_BT2020_Limited_10bit[] = {
+2 -2
View File
@@ -297,12 +297,12 @@ static int COMPUTEOUTCODE(const RECTTYPE *rect, SCALARTYPE x, SCALARTYPE y)
int code = 0;
if (y < rect->y) {
code |= CODE_TOP;
} else if (y >= rect->y + rect->h) {
} else if (y > (rect->y + rect->h - ENCLOSEPOINTS_EPSILON)) {
code |= CODE_BOTTOM;
}
if (x < rect->x) {
code |= CODE_LEFT;
} else if (x >= rect->x + rect->w) {
} else if (x > (rect->x + rect->w - ENCLOSEPOINTS_EPSILON)) {
code |= CODE_RIGHT;
}
return code;
+6
View File
@@ -1786,6 +1786,9 @@ static bool SDL_FlipSurfaceHorizontal(SDL_Surface *surface)
bpp = SDL_BYTESPERPIXEL(surface->format);
row = (Uint8 *)surface->pixels;
tmp = SDL_small_alloc(Uint8, surface->pitch, &isstack);
if (!tmp) {
return false;
}
for (i = surface->h; i--; ) {
a = row;
b = a + (surface->w - 1) * bpp;
@@ -1815,6 +1818,9 @@ static bool SDL_FlipSurfaceVertical(SDL_Surface *surface)
a = (Uint8 *)surface->pixels;
b = a + (surface->h - 1) * surface->pitch;
tmp = SDL_small_alloc(Uint8, surface->pitch, &isstack);
if (!tmp) {
return false;
}
for (i = surface->h / 2; i--; ) {
SDL_memcpy(tmp, a, surface->pitch);
SDL_memcpy(a, b, surface->pitch);
+1
View File
@@ -498,6 +498,7 @@ typedef struct VideoBootStrap
} VideoBootStrap;
// Not all of these are available in a given build. Use #ifdefs, etc.
extern VideoBootStrap PRIVATE_bootstrap;
extern VideoBootStrap COCOA_bootstrap;
extern VideoBootStrap X11_bootstrap;
extern VideoBootStrap WINDOWS_bootstrap;
+25 -1
View File
@@ -59,6 +59,10 @@
#include <emscripten.h>
#endif
#ifdef SDL_PLATFORM_3DS
#include <3ds.h>
#endif
#ifdef SDL_PLATFORM_LINUX
#include <sys/types.h>
#include <sys/stat.h>
@@ -67,6 +71,9 @@
// Available video drivers
static VideoBootStrap *bootstrap[] = {
#ifdef SDL_VIDEO_DRIVER_PRIVATE
&PRIVATE_bootstrap,
#endif
#ifdef SDL_VIDEO_DRIVER_COCOA
&COCOA_bootstrap,
#endif
@@ -258,7 +265,7 @@ typedef struct
static Uint32 SDL_DefaultGraphicsBackends(SDL_VideoDevice *_this)
{
#if (defined(SDL_VIDEO_OPENGL) && defined(SDL_PLATFORM_MACOS)) || (defined(SDL_PLATFORM_IOS) && !TARGET_OS_MACCATALYST) || defined(SDL_PLATFORM_ANDROID)
#if (defined(SDL_VIDEO_OPENGL) && defined(SDL_PLATFORM_MACOS)) || (defined(SDL_PLATFORM_IOS) && !TARGET_OS_MACCATALYST)
if (_this->GL_CreateContext) {
return SDL_WINDOW_OPENGL;
}
@@ -5518,6 +5525,23 @@ bool SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags flags, const char *title, cons
},
title, message);
return true;
#elif defined(SDL_PLATFORM_3DS)
errorConf errCnf;
bool hasGpuRight;
// If the video subsystem has not been initialised, set up graphics temporarily
hasGpuRight = gspHasGpuRight();
if (!hasGpuRight)
gfxInitDefault();
errorInit(&errCnf, ERROR_TEXT_WORD_WRAP, CFG_LANGUAGE_EN);
errorText(&errCnf, message);
errorDisp(&errCnf);
if (!hasGpuRight)
gfxExit();
return true;
#else
SDL_MessageBoxData data;
SDL_MessageBoxButtonData button;
+20 -11
View File
@@ -171,8 +171,10 @@ static bool GetYUVConversionType(SDL_Colorspace colorspace, YCbCrType *yuv_type)
if (SDL_ISCOLORSPACE_MATRIX_BT709(colorspace)) {
if (SDL_ISCOLORSPACE_LIMITED_RANGE(colorspace)) {
*yuv_type = YCBCR_709_LIMITED;
return true;
} else {
*yuv_type = YCBCR_709_FULL;
}
return true;
}
if (SDL_ISCOLORSPACE_MATRIX_BT2020_NCL(colorspace)) {
@@ -691,6 +693,13 @@ static struct RGB2YUVFactors RGB2YUVFactorTables[] = {
{ -0.1482f, -0.2910f, 0.4392f },
{ 0.4392f, -0.3678f, -0.0714f },
},
// ITU-R BT.709-6 full range
{
0,
{ 0.2126f, 0.7152f, 0.0722f },
{ -0.1141f, -0.3839f, 0.498f },
{ 0.498f, -0.4524f, -0.0457f },
},
// ITU-R BT.709-6
{
16,
@@ -707,7 +716,7 @@ static struct RGB2YUVFactors RGB2YUVFactorTables[] = {
},
};
static bool SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, SDL_PixelFormat dst_format, void *dst, int dst_pitch, YCbCrType yuv_type)
static bool SDL_ConvertPixels_XRGB8888_to_YUV(int width, int height, const void *src, int src_pitch, SDL_PixelFormat dst_format, void *dst, int dst_pitch, YCbCrType yuv_type)
{
const int src_pitch_x_2 = src_pitch * 2;
const int height_half = height / 2;
@@ -718,9 +727,9 @@ static bool SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void
const struct RGB2YUVFactors *cvt = &RGB2YUVFactorTables[yuv_type];
#define MAKE_Y(r, g, b) (Uint8)((int)(cvt->y[0] * (r) + cvt->y[1] * (g) + cvt->y[2] * (b) + 0.5f) + cvt->y_offset)
#define MAKE_U(r, g, b) (Uint8)((int)(cvt->u[0] * (r) + cvt->u[1] * (g) + cvt->u[2] * (b) + 0.5f) + 128)
#define MAKE_V(r, g, b) (Uint8)((int)(cvt->v[0] * (r) + cvt->v[1] * (g) + cvt->v[2] * (b) + 0.5f) + 128)
#define MAKE_Y(r, g, b) (Uint8)SDL_clamp(((int)(cvt->y[0] * (r) + cvt->y[1] * (g) + cvt->y[2] * (b) + 0.5f) + cvt->y_offset), 0, 255)
#define MAKE_U(r, g, b) (Uint8)SDL_clamp(((int)(cvt->u[0] * (r) + cvt->u[1] * (g) + cvt->u[2] * (b) + 0.5f) + 128), 0, 255)
#define MAKE_V(r, g, b) (Uint8)SDL_clamp(((int)(cvt->v[0] * (r) + cvt->v[1] * (g) + cvt->v[2] * (b) + 0.5f) + 128), 0, 255)
#define READ_2x2_PIXELS \
const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
@@ -1149,9 +1158,9 @@ bool SDL_ConvertPixels_RGB_to_YUV(int width, int height,
#endif
// ARGB8888 to FOURCC
if (src_format == SDL_PIXELFORMAT_ARGB8888 &&
if ((src_format == SDL_PIXELFORMAT_ARGB8888 || src_format == SDL_PIXELFORMAT_XRGB8888) &&
SDL_COLORSPACEPRIMARIES(src_colorspace) == SDL_COLORSPACEPRIMARIES(dst_colorspace)) {
return SDL_ConvertPixels_ARGB8888_to_YUV(width, height, src, src_pitch, dst_format, dst, dst_pitch, yuv_type);
return SDL_ConvertPixels_XRGB8888_to_YUV(width, height, src, src_pitch, dst_format, dst, dst_pitch, yuv_type);
}
if (dst_format == SDL_PIXELFORMAT_P010) {
@@ -1194,15 +1203,15 @@ bool SDL_ConvertPixels_RGB_to_YUV(int width, int height,
return false;
}
// convert src/src_format to tmp/ARGB8888
result = SDL_ConvertPixelsAndColorspace(width, height, src_format, src_colorspace, src_properties, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, dst_colorspace, dst_properties, tmp, tmp_pitch);
// convert src/src_format to tmp/XRGB8888
result = SDL_ConvertPixelsAndColorspace(width, height, src_format, src_colorspace, src_properties, src, src_pitch, SDL_PIXELFORMAT_XRGB8888, SDL_COLORSPACE_SRGB, 0, tmp, tmp_pitch);
if (!result) {
SDL_free(tmp);
return false;
}
// convert tmp/ARGB8888 to dst/FOURCC
result = SDL_ConvertPixels_ARGB8888_to_YUV(width, height, tmp, tmp_pitch, dst_format, dst, dst_pitch, yuv_type);
// convert tmp/XRGB8888 to dst/FOURCC
result = SDL_ConvertPixels_XRGB8888_to_YUV(width, height, tmp, tmp_pitch, dst_format, dst, dst_pitch, yuv_type);
SDL_free(tmp);
return result;
}
+1 -1
View File
@@ -286,7 +286,7 @@ SDL_GLContext Cocoa_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
_this->GL_SwapWindow = Cocoa_GLES_SwapWindow;
_this->GL_DestroyContext = Cocoa_GLES_DestroyContext;
if (Cocoa_GLES_LoadLibrary(_this, NULL) != 0) {
if (!Cocoa_GLES_LoadLibrary(_this, NULL)) {
return NULL;
}
return Cocoa_GLES_CreateContext(_this, window);
+5 -5
View File
@@ -199,7 +199,7 @@
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
". [SDL] In performDragOperation, draggingSourceOperationMask %lx, "
"expected Generic %lx, others Copy %lx, Link %lx, Private %lx, Move %lx, Delete %lx\n",
(unsigned long)[sender draggingSourceOperationMask],
@@ -210,7 +210,7 @@
(unsigned long)NSDragOperationMove,
(unsigned long)NSDragOperationDelete);
if ([sender draggingPasteboard]) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
". [SDL] In performDragOperation, valid draggingPasteboard, "
"name [%s] '%s', changeCount %ld\n",
[[[[sender draggingPasteboard] name] className] UTF8String],
@@ -229,7 +229,7 @@
for (NSString *supportedType in [pasteboard types]) {
NSString *typeString = [pasteboard stringForType:supportedType];
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
". [SDL] In performDragOperation, Pasteboard type '%s', stringForType (%lu) '%s'\n",
[[supportedType description] UTF8String],
(unsigned long)[[typeString description] length],
@@ -281,7 +281,7 @@
}
}
}
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
". [SDL] In performDragOperation, desiredType '%s', "
"Submitting DropFile as (%lu) '%s'\n",
[[desiredType description] UTF8String],
@@ -296,7 +296,7 @@
char *saveptr = NULL;
char *token = SDL_strtok_r(buffer, "\r\n", &saveptr);
while (token) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
". [SDL] In performDragOperation, desiredType '%s', "
"Submitting DropText as (%lu) '%s'\n",
[[desiredType description] UTF8String],

Some files were not shown because too many files have changed in this diff Show More