LIBS: updated sdl2

master
Martin Gerhardy 2022-03-09 18:44:06 +01:00
parent 99bfd08f9a
commit 106e6d7295
34 changed files with 513 additions and 321 deletions

View File

@ -174,7 +174,7 @@ macro(CheckPulseAudio)
set(SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC "\"${PULSE_SIMPLE_LIB_SONAME}\"")
set(HAVE_PULSEAUDIO_SHARED TRUE)
else()
list(APPEND EXTRA_LDFLAGS ${PKG_sPULSEAUDIO_LDFLAGS})
list(APPEND EXTRA_LDFLAGS ${PKG_PULSEAUDIO_LDFLAGS})
endif()
set(HAVE_SDL_AUDIO TRUE)
endif()
@ -467,6 +467,8 @@ macro(CheckX11)
else()
list(APPEND EXTRA_LIBS ${X11_LIB} ${XEXT_LIB})
endif()
else()
list(APPEND EXTRA_LIBS ${X11_LIB} ${XEXT_LIB})
endif()
set(CMAKE_REQUIRED_LIBRARIES ${X11_LIB} ${X11_LIB})

View File

@ -869,8 +869,9 @@ extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecon
* calling it with 0 intensity stops any rumbling.
*
* Note that this is rumbling of the _triggers_ and not the game controller as
* a whole. The first controller to offer this feature was the PlayStation 5's
* DualShock 5.
* a whole. This is currently only supported on Xbox One controllers. If you
* want the (more common) whole-controller rumble, use
* SDL_GameControllerRumble() instead.
*
* \param gamecontroller The controller to vibrate
* \param left_rumble The intensity of the left trigger rumble motor, from 0

View File

@ -625,6 +625,21 @@ extern "C" {
*/
#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE "SDL_JOYSTICK_HIDAPI_GAMECUBE"
/**
* \brief A variable controlling whether "low_frequency_rumble" and "high_frequency_rumble" is used to implement
* the GameCube controller's 3 rumble modes, Stop(0), Rumble(1), and StopHard(2)
* this is useful for applications that need full compatibility for things like ADSR envelopes.
* Stop is implemented by setting "low_frequency_rumble" to "0" and "high_frequency_rumble" ">0"
* Rumble is both at any arbitrary value,
* StopHard is implemented by setting both "low_frequency_rumble" and "high_frequency_rumble" to "0"
*
* This variable can be set to the following values:
* "0" - Normal rumble behavior is behavior is used (default)
* "1" - Proper GameCube controller rumble behavior is used
*
*/
#define SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE "SDL_JOYSTICK_GAMECUBE_RUMBLE_BRAKE"
/**
* \brief A variable controlling whether Switch Joy-Cons should be treated the same as Switch Pro Controllers when using the HIDAPI driver.
*

View File

@ -829,9 +829,9 @@ extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 lo
* Each call to this function cancels any previous trigger rumble effect, and
* calling it with 0 intensity stops any rumbling.
*
* Note that this function is for _trigger_ rumble; the first joystick to
* support this was the PlayStation 5's DualShock 5 controller. If you want
* the (more common) whole-controller rumble, use SDL_JoystickRumble()
* Note that this is rumbling of the _triggers_ and not the game controller as
* a whole. This is currently only supported on Xbox One controllers. If you
* want the (more common) whole-controller rumble, use SDL_JoystickRumble()
* instead.
*
* \param joystick The joystick to vibrate

View File

@ -271,6 +271,10 @@ extern DECLSPEC void SDLCALL SDL_StopTextInput(void);
/**
* Set the rectangle used to type Unicode text inputs.
*
* Note: If you want use system native IME window, try to set hint
* **SDL_HINT_IME_SHOW_UI** to **1**, otherwise this function won't give you
* any feedback.
*
* \param rect the SDL_Rect structure representing the rectangle to receive
* text (ignored if NULL)
*

View File

@ -407,6 +407,7 @@ openslES_CreatePCMPlayer(_THIS)
{
struct SDL_PrivateAudioData *audiodata = this->hidden;
SLDataFormat_PCM format_pcm;
SLAndroidDataFormat_PCM_EX format_pcm_ex;
SLresult result;
int i;
@ -414,30 +415,30 @@ openslES_CreatePCMPlayer(_THIS)
it can be done as described here:
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
*/
#if 1
/* Just go with signed 16-bit audio as it's the most compatible */
this->spec.format = AUDIO_S16SYS;
#else
SDL_AudioFormat test_format;
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
if (SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format)) {
break;
if(SDL_GetAndroidSDKVersion() >= 21) {
SDL_AudioFormat test_format;
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
if (SDL_AUDIO_ISSIGNED(test_format)) {
break;
}
}
}
if (!test_format) {
/* Didn't find a compatible format : */
LOGI( "No compatible audio format, using signed 16-bit audio" );
test_format = AUDIO_S16SYS;
if (!test_format) {
/* Didn't find a compatible format : */
LOGI( "No compatible audio format, using signed 16-bit audio" );
test_format = AUDIO_S16SYS;
}
this->spec.format = test_format;
} else {
/* Just go with signed 16-bit audio as it's the most compatible */
this->spec.format = AUDIO_S16SYS;
}
this->spec.format = test_format;
#endif
/* Update the fragment size as size in bytes */
SDL_CalculateAudioSpec(&this->spec);
LOGI("Try to open %u hz %u bit chan %u %s samples %u",
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
LOGI("Try to open %u hz %s %u bit chan %u %s samples %u",
this->spec.freq, SDL_AUDIO_ISFLOAT(this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(this->spec.format),
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
/* configure audio source */
@ -488,7 +489,19 @@ openslES_CreatePCMPlayer(_THIS)
break;
}
SLDataSource audioSrc = { &loc_bufq, &format_pcm };
if(SDL_AUDIO_ISFLOAT(this->spec.format)) {
/* Copy all setup into PCM EX structure */
format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
format_pcm_ex.endianness = format_pcm.endianness;
format_pcm_ex.channelMask = format_pcm.channelMask;
format_pcm_ex.numChannels = format_pcm.numChannels;
format_pcm_ex.sampleRate = format_pcm.samplesPerSec;
format_pcm_ex.bitsPerSample = format_pcm.bitsPerSample;
format_pcm_ex.containerSize = format_pcm.containerSize;
format_pcm_ex.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
}
SLDataSource audioSrc = { &loc_bufq, SDL_AUDIO_ISFLOAT(this->spec.format) ? (void*)&format_pcm_ex : (void*)&format_pcm };
/* configure audio sink */
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };

View File

@ -394,6 +394,7 @@ typedef struct {
unsigned int text_len;
keysym_t composebuffer[2];
unsigned char composelen;
int type;
} SDL_WSCONS_input_data;
static SDL_WSCONS_input_data* inputs[4] = {NULL, NULL, NULL, NULL};
@ -432,6 +433,7 @@ static SDL_WSCONS_input_data* SDL_WSCONS_Init_Keyboard(const char* dev)
RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETLEDS, &input->ledstate));
input->origledstate = input->ledstate;
RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETENCODING, &input->encoding));
RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GTYPE, &input->type));
#ifdef WSKBDIO_SETVERSION
RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_SETVERSION, &version));
#endif
@ -725,7 +727,12 @@ static void updateKeyboard(SDL_WSCONS_input_data* input)
}
break;
}
Translate_to_keycode(input, type, events[i].value);
if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7)
SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value);
else
Translate_to_keycode(input, type, events[i].value);
if (type == WSCONS_EVENT_KEY_UP) continue;
if (IS_ALTGR_MODE && !IS_CONTROL_HELD)

View File

@ -206,11 +206,28 @@ SDL_LogEvent(const SDL_Event *event)
SDL_EVENT_CASE(SDL_APP_DIDENTERBACKGROUND) break;
SDL_EVENT_CASE(SDL_APP_WILLENTERFOREGROUND) break;
SDL_EVENT_CASE(SDL_APP_DIDENTERFOREGROUND) break;
SDL_EVENT_CASE(SDL_LOCALECHANGED) break;
SDL_EVENT_CASE(SDL_KEYMAPCHANGED) break;
SDL_EVENT_CASE(SDL_CLIPBOARDUPDATE) break;
SDL_EVENT_CASE(SDL_RENDER_TARGETS_RESET) break;
SDL_EVENT_CASE(SDL_RENDER_DEVICE_RESET) break;
SDL_EVENT_CASE(SDL_DISPLAYEVENT) {
char name2[64];
switch (event->display.event) {
case SDL_DISPLAYEVENT_NONE: SDL_strlcpy(name2, "SDL_DISPLAYEVENT_NONE (THIS IS PROBABLY A BUG!)", sizeof(name2)); break;
#define SDL_DISPLAYEVENT_CASE(x) case x: SDL_strlcpy(name2, #x, sizeof (name2)); break
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_ORIENTATION);
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_CONNECTED);
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_DISCONNECTED);
#undef SDL_DISPLAYEVENT_CASE
default: SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof(name2)); break;
}
SDL_snprintf(details, sizeof (details), " (timestamp=%u display=%u event=%s data1=%d)",
(uint) event->display.timestamp, (uint) event->display.display, name2, (int) event->display.data1);
break;
}
SDL_EVENT_CASE(SDL_WINDOWEVENT) {
char name2[64];
switch(event->window.event) {
@ -232,6 +249,8 @@ SDL_LogEvent(const SDL_Event *event)
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_CLOSE);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_TAKE_FOCUS);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIT_TEST);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ICCPROF_CHANGED);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_DISPLAY_CHANGED);
#undef SDL_WINDOWEVENT_CASE
default: SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof (name2)); break;
}
@ -660,7 +679,7 @@ static int
SDL_PeepEventsInternal(SDL_Event * events, int numevents, SDL_eventaction action,
Uint32 minType, Uint32 maxType, SDL_bool include_sentinel)
{
int i, used;
int i, used, sentinels_expected = 0;
/* Don't look after we've quit */
if (!SDL_AtomicGet(&SDL_EventQ.active)) {
@ -723,8 +742,15 @@ SDL_PeepEventsInternal(SDL_Event * events, int numevents, SDL_eventaction action
}
if (type == SDL_POLLSENTINEL) {
/* Special handling for the sentinel event */
if (!include_sentinel || SDL_AtomicGet(&SDL_sentinel_pending) > 0) {
/* Skip it, we don't want to include it or there's another one pending */
if (!include_sentinel) {
/* Skip it, we don't want to include it */
continue;
}
if (!events || action != SDL_GETEVENT) {
++sentinels_expected;
}
if (SDL_AtomicGet(&SDL_sentinel_pending) > sentinels_expected) {
/* Skip it, there's another one pending */
continue;
}
}
@ -991,6 +1017,7 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
SDL_Window *wakeup_window;
Uint32 start, expiration;
SDL_bool include_sentinel = (timeout == 0) ? SDL_TRUE : SDL_FALSE;
int result;
/* If there isn't a poll sentinel event pending, pump events and add one */
if (SDL_AtomicGet(&SDL_sentinel_pending) == 0) {
@ -998,33 +1025,34 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
}
/* First check for existing events */
switch (SDL_PeepEventsInternal(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, include_sentinel)) {
case -1:
result = SDL_PeepEventsInternal(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, include_sentinel);
if (result < 0) {
return 0;
case 0:
}
if (include_sentinel) {
if (event) {
if (event->type == SDL_POLLSENTINEL) {
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
} else {
/* Need to peek the next event to check for sentinel */
SDL_Event dummy;
if (SDL_PeepEventsInternal(&dummy, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, SDL_TRUE) &&
dummy.type == SDL_POLLSENTINEL) {
SDL_PeepEventsInternal(&dummy, 1, SDL_GETEVENT, SDL_POLLSENTINEL, SDL_POLLSENTINEL, SDL_TRUE);
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
}
}
if (result == 0) {
if (timeout == 0) {
/* No events available, and not willing to wait */
return 0;
}
break;
default:
if (include_sentinel) {
if (event) {
if (event->type == SDL_POLLSENTINEL) {
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
} else {
/* Need to peek the next event to check for sentinel */
SDL_Event dummy;
if (SDL_PeepEventsInternal(&dummy, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, SDL_TRUE) &&
dummy.type == SDL_POLLSENTINEL) {
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
}
}
} else {
/* Has existing events */
return 1;
}

View File

@ -867,10 +867,14 @@ SDL_SendKeyboardText(const char *text)
posted = 0;
if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) {
SDL_Event event;
size_t i = 0, length = SDL_strlen(text);
event.text.type = SDL_TEXTINPUT;
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
SDL_utf8strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
posted = (SDL_PushEvent(&event) > 0);
while (i < length) {
i += SDL_utf8strlcpy(event.text.text, text + i, SDL_arraysize(event.text.text));
posted |= (SDL_PushEvent(&event) > 0);
}
}
return (posted);
}

View File

@ -259,7 +259,7 @@ static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t
buf[0] = 0;
if (str) {
if (str && CFGetTypeID(str) == CFStringGetTypeID()) {
len --;
CFIndex str_len = CFStringGetLength(str);
@ -298,7 +298,7 @@ static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, cha
buf[0] = 0;
if (str) {
if (str && CFGetTypeID(str) == CFStringGetTypeID()) {
len--;
CFIndex str_len = CFStringGetLength(str);
@ -326,10 +326,7 @@ static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, cha
static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len)
{
// This crashes on M1 Macs, tracked by radar bug 79667729
//return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len);
buf[0] = 0;
return 0;
return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len);
}
static int get_manufacturer_string(IOHIDDeviceRef device, wchar_t *buf, size_t len)
@ -557,6 +554,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
continue;
}
#if 0 // Prefer direct HID support as that has extended functionality
#if defined(SDL_JOYSTICK_MFI)
// We want to prefer Game Controller support where available,
// as Apple will likely be requiring that for supported devices.
@ -564,6 +562,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
if (IOS_SupportedHIDDevice(dev)) {
continue;
}
#endif
#endif
dev_vid = get_vendor_id(dev);

View File

@ -1882,7 +1882,7 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc
0x12ab, /* Unknown */
0x1430, /* RedOctane */
0x146b, /* BigBen */
0x1532, /* Razer Sabertooth */
0x1532, /* Razer */
0x15e4, /* Numark */
0x162e, /* Joytech */
0x1689, /* Razer Onza */
@ -1911,7 +1911,7 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc
0x0738, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1532, /* Razer Wildcat */
0x1532, /* Razer */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
0x2e24, /* Hyperkin */
@ -1944,6 +1944,9 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc
} else if (vendor == 0x0001 && product == 0x0001) {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
} else if (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER) {
type = SDL_CONTROLLER_TYPE_XBOXONE;
} else if ((vendor == USB_VENDOR_AMAZON && product == USB_PRODUCT_AMAZON_LUNA_CONTROLLER) ||
(vendor == BLUETOOTH_VENDOR_AMAZON && product == BLUETOOTH_PRODUCT_LUNA_CONTROLLER)) {
type = SDL_CONTROLLER_TYPE_AMAZON_LUNA;
@ -2443,6 +2446,8 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x04d9, 0xa292), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x04d9, 0xa293), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x1532, 0x0266), /* Razer Huntman V2 Analog, non-functional DInput device */
MAKE_VIDPID(0x1532, 0x0282), /* Razer Huntman Mini Analog, non-functional DInput device */
MAKE_VIDPID(0x26ce, 0x01a2), /* ASRock LED Controller */
};

View File

@ -53,6 +53,7 @@ typedef struct {
/* Without this variable, hid_write starts to lag a TON */
SDL_bool rumbleUpdate;
SDL_bool m_bUseButtonLabels;
SDL_bool useRumbleBrake;
} SDL_DriverGameCube_Context;
static SDL_bool
@ -92,6 +93,14 @@ static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata,
ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE);
}
static void SDLCALL SDL_JoystickGameCubeRumbleBrakeHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
if (hint) {
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)userdata;
ctx->useRumbleBrake = SDL_GetStringBoolean(hint, SDL_FALSE);
}
}
static Uint8 RemapButton(SDL_DriverGameCube_Context *ctx, Uint8 button)
{
if (!ctx->m_bUseButtonLabels) {
@ -142,6 +151,7 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
ctx->joysticks[2] = -1;
ctx->joysticks[3] = -1;
ctx->rumble[0] = rumbleMagic;
ctx->useRumbleBrake = SDL_FALSE;
if (device->vendor_id != USB_VENDOR_NINTENDO) {
ctx->pc_mode = SDL_TRUE;
@ -195,6 +205,8 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
}
}
SDL_AddHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE,
SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx);
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
@ -439,12 +451,22 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
if (joystick->instance_id == ctx->joysticks[i]) {
if (ctx->wireless[i]) {
return SDL_SetError("Ninteno GameCube WaveBird controllers do not support rumble");
return SDL_SetError("Nintendo GameCube WaveBird controllers do not support rumble");
}
if (!ctx->rumbleAllowed[i]) {
return SDL_SetError("Second USB cable for WUP-028 not connected");
}
val = (low_frequency_rumble > 0 || high_frequency_rumble > 0);
if (ctx->useRumbleBrake) {
if (low_frequency_rumble == 0 && high_frequency_rumble > 0) {
val = 0; /* if only low is 0 we want to do a regular stop*/
} else if (low_frequency_rumble == 0 && high_frequency_rumble == 0) {
val = 2; /* if both frequencies are 0 we want to do a hard stop */
} else {
val = 1; /* normal rumble */
}
} else {
val = (low_frequency_rumble > 0 || high_frequency_rumble > 0);
}
if (val != ctx->rumble[i + 1]) {
ctx->rumble[i + 1] = val;
ctx->rumbleUpdate = SDL_TRUE;
@ -522,6 +544,8 @@ HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device)
SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
SDL_DelHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE,
SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx);
SDL_LockMutex(device->dev_lock);
{

View File

@ -69,6 +69,9 @@ static NSString *GCInputXboxShareButton = @"Button Share";
#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 130000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1500000))
@property(nonatomic, readonly) NSString *productCategory;
#endif
#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 140500) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140500) || (__MAC_OS_X_VERSION_MAX_ALLOWED >= 110300))
@property(class, nonatomic, readwrite) BOOL shouldMonitorBackgroundEvents;
#endif
@end
@interface GCExtendedGamepad (SDL)
#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 121000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 121000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1401000))
@ -572,6 +575,10 @@ IOS_JoystickInit(void)
return 0;
}
if (@available(macOS 11.3, iOS 14.5, tvOS 14.5, *)) {
GCController.shouldMonitorBackgroundEvents = YES;
}
/* For whatever reason, this always returns an empty array on
macOS 11.0.1 */
for (GCController *controller in [GCController controllers]) {

View File

@ -1147,7 +1147,8 @@ SDL_DINPUT_JoystickQuit(void)
}
if (coinitialized) {
WIN_CoUninitialize();
/* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */
/*WIN_CoUninitialize();*/
coinitialized = SDL_FALSE;
}
}

View File

@ -657,7 +657,8 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
wgi_state.gamepad_statics = NULL;
}
WIN_CoUninitialize();
/* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */
/*WIN_CoUninitialize();*/
wgi_state.initialized = SDL_FALSE;
}
}
@ -921,9 +922,12 @@ RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, co
return SDL_TRUE;
}
/* The Xbox 360 wireless controller shows up as product 0 in WGI */
/* The Xbox 360 wireless controller shows up as product 0 in WGI.
Try to match it to a Raw Input device via name or known product ID. */
if (vendor_id == device->vendor_id && product_id == 0 &&
name && SDL_strstr(device->name, name) != NULL) {
((name && SDL_strstr(device->name, name) != NULL) ||
(device->vendor_id == USB_VENDOR_MICROSOFT &&
device->product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER))) {
return SDL_TRUE;
}

View File

@ -256,7 +256,8 @@ SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance);
if (data->coinitialized == S_OK) {
WIN_CoUninitialize();
/* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */
/*WIN_CoUninitialize();*/
}
}

View File

@ -71,7 +71,9 @@ typedef struct
IDirect3DSurface9 *defaultRenderTarget;
IDirect3DSurface9 *currentRenderTarget;
void* d3dxDLL;
#if SDL_HAVE_YUV
LPDIRECT3DPIXELSHADER9 shaders[NUM_SHADERS];
#endif
LPDIRECT3DVERTEXBUFFER9 vertexBuffers[8];
size_t vertexBufferSize[8];
int currentVertexBuffer;
@ -95,6 +97,7 @@ typedef struct
D3D_TextureRep texture;
D3DTEXTUREFILTERTYPE scaleMode;
#if SDL_HAVE_YUV
/* YV12 texture support */
SDL_bool yuv;
D3D_TextureRep utexture;
@ -102,6 +105,7 @@ typedef struct
Uint8 *pixels;
int pitch;
SDL_Rect locked_rect;
#endif
} D3D_TextureData;
typedef struct
@ -534,7 +538,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (D3D_CreateTextureRep(data->device, &texturedata->texture, usage, texture->format, PixelFormatToD3DFMT(texture->format), texture->w, texture->h) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texture->format == SDL_PIXELFORMAT_YV12 ||
texture->format == SDL_PIXELFORMAT_IYUV) {
texturedata->yuv = SDL_TRUE;
@ -547,6 +551,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return -1;
}
}
#endif
return 0;
}
@ -563,7 +568,7 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (D3D_RecreateTextureRep(data->device, &texturedata->texture) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texturedata->yuv) {
if (D3D_RecreateTextureRep(data->device, &texturedata->utexture) < 0) {
return -1;
@ -573,6 +578,7 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return -1;
}
}
#endif
return 0;
}
@ -590,7 +596,7 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, pixels, pitch) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texturedata->yuv) {
/* Skip to the correct offset into the next texture */
pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
@ -605,6 +611,7 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
return -1;
}
}
#endif
return 0;
}
@ -647,7 +654,7 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
if (!texturedata) {
return SDL_SetError("Texture is not currently available");
}
#if SDL_HAVE_YUV
texturedata->locked_rect = *rect;
if (texturedata->yuv) {
@ -663,7 +670,9 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
(void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
*pitch = texturedata->pitch;
} else {
} else
#endif
{
RECT d3drect;
D3DLOCKED_RECT locked;
HRESULT result;
@ -696,14 +705,17 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (!texturedata) {
return;
}
#if SDL_HAVE_YUV
if (texturedata->yuv) {
const SDL_Rect *rect = &texturedata->locked_rect;
void *pixels =
(void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
D3D_UpdateTexture(renderer, texture, rect, pixels, texturedata->pitch);
} else {
}
else
#endif
{
IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0);
texturedata->texture.dirty = SDL_TRUE;
if (data->drawstate.texture == texture) {
@ -711,10 +723,6 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
data->drawstate.shader = NULL;
IDirect3DDevice9_SetPixelShader(data->device, NULL);
IDirect3DDevice9_SetTexture(data->device, 0, NULL);
if (texturedata->yuv) {
IDirect3DDevice9_SetTexture(data->device, 1, NULL);
IDirect3DDevice9_SetTexture(data->device, 2, NULL);
}
}
}
}
@ -946,7 +954,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
if (BindTextureRep(data->device, &texturedata->texture, 0) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texturedata->yuv) {
switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
case SDL_YUV_CONVERSION_JPEG:
@ -972,6 +980,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
return -1;
}
}
#endif
return 0;
}
@ -982,18 +991,22 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
const SDL_BlendMode blend = cmd->data.draw.blend;
if (texture != data->drawstate.texture) {
#if SDL_HAVE_YUV
D3D_TextureData *oldtexturedata = data->drawstate.texture ? (D3D_TextureData *) data->drawstate.texture->driverdata : NULL;
D3D_TextureData *newtexturedata = texture ? (D3D_TextureData *) texture->driverdata : NULL;
#endif
LPDIRECT3DPIXELSHADER9 shader = NULL;
/* disable any enabled textures we aren't going to use, let SetupTextureState() do the rest. */
if (texture == NULL) {
IDirect3DDevice9_SetTexture(data->device, 0, NULL);
}
#if SDL_HAVE_YUV
if ((!newtexturedata || !newtexturedata->yuv) && (oldtexturedata && oldtexturedata->yuv)) {
IDirect3DDevice9_SetTexture(data->device, 1, NULL);
IDirect3DDevice9_SetTexture(data->device, 2, NULL);
}
#endif
if (texture && SetupTextureState(data, texture, &shader) < 0) {
return -1;
}
@ -1010,10 +1023,12 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
} else if (texture) {
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
UpdateDirtyTexture(data->device, &texturedata->texture);
#if SDL_HAVE_YUV
if (texturedata->yuv) {
UpdateDirtyTexture(data->device, &texturedata->utexture);
UpdateDirtyTexture(data->device, &texturedata->vtexture);
}
#endif
}
if (blend != data->drawstate.blend) {
@ -1353,10 +1368,12 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
renderdata->drawstate.shader = NULL;
IDirect3DDevice9_SetPixelShader(renderdata->device, NULL);
IDirect3DDevice9_SetTexture(renderdata->device, 0, NULL);
#if SDL_HAVE_YUV
if (data->yuv) {
IDirect3DDevice9_SetTexture(renderdata->device, 1, NULL);
IDirect3DDevice9_SetTexture(renderdata->device, 2, NULL);
}
#endif
}
if (!data) {
@ -1364,9 +1381,11 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
}
D3D_DestroyTextureRep(&data->texture);
#if SDL_HAVE_YUV
D3D_DestroyTextureRep(&data->utexture);
D3D_DestroyTextureRep(&data->vtexture);
SDL_free(data->pixels);
#endif
SDL_free(data);
texture->driverdata = NULL;
}
@ -1388,12 +1407,14 @@ D3D_DestroyRenderer(SDL_Renderer * renderer)
IDirect3DSurface9_Release(data->currentRenderTarget);
data->currentRenderTarget = NULL;
}
#if SDL_HAVE_YUV
for (i = 0; i < SDL_arraysize(data->shaders); ++i) {
if (data->shaders[i]) {
IDirect3DPixelShader9_Release(data->shaders[i]);
data->shaders[i] = NULL;
}
}
#endif
/* Release all vertex buffers */
for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) {
if (data->vertexBuffers[i]) {
@ -1666,7 +1687,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
/* Set up parameters for rendering */
D3D_InitRenderState(data);
#if SDL_HAVE_YUV
if (caps.MaxSimultaneousTextures >= 3) {
int i;
for (i = 0; i < SDL_arraysize(data->shaders); ++i) {
@ -1680,7 +1701,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
}
}
#endif
data->drawstate.blend = SDL_BLENDMODE_INVALID;
return renderer;

View File

@ -91,7 +91,7 @@ typedef struct
int lockedTexturePositionX;
int lockedTexturePositionY;
D3D11_FILTER scaleMode;
#if SDL_HAVE_YUV
/* YV12 texture support */
SDL_bool yuv;
ID3D11Texture2D *mainTextureU;
@ -107,6 +107,7 @@ typedef struct
Uint8 *pixels;
int pitch;
SDL_Rect locked_rect;
#endif
} D3D11_TextureData;
/* Blend mode data */
@ -1116,7 +1117,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
}
#if SDL_HAVE_YUV
if (texture->format == SDL_PIXELFORMAT_YV12 ||
texture->format == SDL_PIXELFORMAT_IYUV) {
textureData->yuv = SDL_TRUE;
@ -1165,7 +1166,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
}
}
#endif /* SDL_HAVE_YUV */
resourceViewDesc.Format = textureDesc.Format;
resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
resourceViewDesc.Texture2D.MostDetailedMip = 0;
@ -1179,7 +1180,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
}
#if SDL_HAVE_YUV
if (textureData->yuv) {
result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
(ID3D11Resource *)textureData->mainTextureU,
@ -1232,7 +1233,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result);
}
}
#endif /* SDL_HAVE_YUV */
return 0;
}
@ -1250,6 +1251,7 @@ D3D11_DestroyTexture(SDL_Renderer * renderer,
SAFE_RELEASE(data->mainTextureResourceView);
SAFE_RELEASE(data->mainTextureRenderTargetView);
SAFE_RELEASE(data->stagingTexture);
#if SDL_HAVE_YUV
SAFE_RELEASE(data->mainTextureU);
SAFE_RELEASE(data->mainTextureResourceViewU);
SAFE_RELEASE(data->mainTextureV);
@ -1257,6 +1259,7 @@ D3D11_DestroyTexture(SDL_Renderer * renderer,
SAFE_RELEASE(data->mainTextureNV);
SAFE_RELEASE(data->mainTextureResourceViewNV);
SDL_free(data->pixels);
#endif
SDL_free(data);
texture->driverdata = NULL;
}
@ -1357,7 +1360,7 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (textureData->yuv) {
/* Skip to the correct offset into the next texture */
srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch);
@ -1381,6 +1384,7 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
return -1;
}
}
#endif /* SDL_HAVE_YUV */
return 0;
}
@ -1448,7 +1452,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
if (!textureData) {
return SDL_SetError("Texture is not currently available");
}
#if SDL_HAVE_YUV
if (textureData->yuv || textureData->nv12) {
/* It's more efficient to upload directly... */
if (!textureData->pixels) {
@ -1465,7 +1469,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
*pitch = textureData->pitch;
return 0;
}
#endif
if (textureData->stagingTexture) {
return SDL_SetError("texture is already locked");
}
@ -1529,7 +1533,7 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (!textureData) {
return;
}
#if SDL_HAVE_YUV
if (textureData->yuv || textureData->nv12) {
const SDL_Rect *rect = &textureData->locked_rect;
void *pixels =
@ -1538,7 +1542,7 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
return;
}
#endif
/* Commit the pixel buffer's changes back to the staging texture: */
ID3D11DeviceContext_Unmap(rendererData->d3dContext,
(ID3D11Resource *)textureData->stagingTexture,
@ -1981,7 +1985,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const
default:
return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode);
}
#if SDL_HAVE_YUV
if (textureData->yuv) {
ID3D11ShaderResourceView *shaderResources[] = {
textureData->mainTextureResourceView,
@ -2032,7 +2036,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const
SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix);
}
#endif /* SDL_HAVE_YUV */
return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_RGB],
1, &textureData->mainTextureResourceView, textureSampler, matrix);
}
@ -2341,6 +2345,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
if (!data) {
SDL_free(renderer);
SDL_OutOfMemory();
return NULL;
}

View File

@ -1886,9 +1886,10 @@ static struct
{
const void *shader_data;
SIZE_T shader_size;
} D3D11_shaders[] = {
} D3D11_shaders[NUM_SHADERS] = {
{ D3D11_PixelShader_Colors, sizeof(D3D11_PixelShader_Colors) },
{ D3D11_PixelShader_Textures, sizeof(D3D11_PixelShader_Textures) },
#if SDL_HAVE_YUV
{ D3D11_PixelShader_YUV_JPEG, sizeof(D3D11_PixelShader_YUV_JPEG) },
{ D3D11_PixelShader_YUV_BT601, sizeof(D3D11_PixelShader_YUV_BT601) },
{ D3D11_PixelShader_YUV_BT709, sizeof(D3D11_PixelShader_YUV_BT709) },
@ -1898,6 +1899,7 @@ static struct
{ D3D11_PixelShader_NV21_JPEG, sizeof(D3D11_PixelShader_NV21_JPEG) },
{ D3D11_PixelShader_NV21_BT601, sizeof(D3D11_PixelShader_NV21_BT601) },
{ D3D11_PixelShader_NV21_BT709, sizeof(D3D11_PixelShader_NV21_BT709) },
#endif
};
int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vertexShader, ID3D11InputLayout **inputLayout)

View File

@ -25,6 +25,7 @@
typedef enum {
SHADER_SOLID,
SHADER_RGB,
#if SDL_HAVE_YUV
SHADER_YUV_JPEG,
SHADER_YUV_BT601,
SHADER_YUV_BT709,
@ -34,6 +35,7 @@ typedef enum {
SHADER_NV21_JPEG,
SHADER_NV21_BT601,
SHADER_NV21_BT709,
#endif
NUM_SHADERS
} D3D11_Shader;

View File

@ -167,11 +167,12 @@ typedef struct METAL_ShaderPipelines
@property (nonatomic, retain) id<MTLTexture> mtltexture_uv;
@property (nonatomic, retain) id<MTLSamplerState> mtlsampler;
@property (nonatomic, assign) SDL_MetalFragmentFunction fragmentFunction;
#if SDL_HAVE_YUV
@property (nonatomic, assign) BOOL yuv;
@property (nonatomic, assign) BOOL nv12;
@property (nonatomic, assign) size_t conversionBufferOffset;
#endif
@property (nonatomic, assign) BOOL hasdata;
@property (nonatomic, retain) id<MTLBuffer> lockedbuffer;
@property (nonatomic, assign) SDL_Rect lockedrect;
@end
@ -605,14 +606,14 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
mtltexdesc.usage = MTLTextureUsageShaderRead;
}
}
id<MTLTexture> mtltexture = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
if (mtltexture == nil) {
return SDL_SetError("Texture allocation failed");
}
id<MTLTexture> mtltexture_uv = nil;
#if SDL_HAVE_YUV
BOOL yuv = (texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12);
BOOL nv12 = (texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21);
@ -637,7 +638,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return SDL_SetError("Texture allocation failed");
}
}
#endif /* SDL_HAVE_YUV */
METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
if (texture->scaleMode == SDL_ScaleModeNearest) {
texturedata.mtlsampler = data.mtlsamplernearest;
@ -646,7 +647,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
}
texturedata.mtltexture = mtltexture;
texturedata.mtltexture_uv = mtltexture_uv;
#if SDL_HAVE_YUV
texturedata.yuv = yuv;
texturedata.nv12 = nv12;
@ -656,10 +657,12 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV12;
} else if (texture->format == SDL_PIXELFORMAT_NV21) {
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV21;
} else {
} else
#endif
{
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_COPY;
}
#if SDL_HAVE_YUV
if (yuv || nv12) {
size_t offset = 0;
SDL_YUV_CONVERSION_MODE mode = SDL_GetYUVConversionModeForResolution(texture->w, texture->h);
@ -671,7 +674,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
}
texturedata.conversionBufferOffset = offset;
}
#endif
texture->driverdata = (void*)CFBridgingRetain(texturedata);
#if !__has_feature(objc_arc)
@ -785,7 +788,7 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture, *rect, 0, pixels, pitch) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texturedata.yuv) {
int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0;
int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1;
@ -815,7 +818,7 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
return -1;
}
}
#endif
texturedata.hasdata = YES;
return 0;
@ -896,10 +899,12 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
}
*pitch = SDL_BYTESPERPIXEL(texture->format) * rect->w;
#if SDL_HAVE_YUV
if (texturedata.yuv || texturedata.nv12) {
buffersize = ((*pitch) * rect->h) + (2 * (*pitch + 1) / 2) * ((rect->h + 1) / 2);
} else {
} else
#endif
{
buffersize = (*pitch) * rect->h;
}
@ -953,7 +958,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(rect.x, rect.y, 0)];
#if SDL_HAVE_YUV
if (texturedata.yuv) {
int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0;
int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1;
@ -993,7 +998,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
destinationLevel:0
destinationOrigin:MTLOriginMake(UVrect.x, UVrect.y, 0)];
}
#endif
[blitcmd endEncoding];
[data.mtlcmdbuffer commit];
@ -1313,10 +1318,12 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t
}
[data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0];
#if SDL_HAVE_YUV
if (texturedata.yuv || texturedata.nv12) {
[data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture_uv atIndex:1];
[data.mtlcmdencoder setFragmentBuffer:data.mtlbufconstants offset:texturedata.conversionBufferOffset atIndex:1];
}
#endif
statecache->texture = texture;
}
return SDL_TRUE;

View File

@ -1690,6 +1690,32 @@ GL_SetVSync(SDL_Renderer * renderer, const int vsync)
return retval;
}
static SDL_bool
GL_IsProbablyAccelerated(const GL_RenderData *data)
{
/*const char *vendor = (const char *) data->glGetString(GL_VENDOR);*/
const char *renderer = (const char *) data->glGetString(GL_RENDERER);
#ifdef __WINDOWS__
if (SDL_strcmp(renderer, "GDI Generic") == 0) {
return SDL_FALSE; /* Microsoft's fallback software renderer. Fix your system! */
}
#endif
#ifdef __APPLE__
if (SDL_strcmp(renderer, "Apple Software Renderer") == 0) {
return SDL_FALSE; /* (a probably very old) Apple software-based OpenGL. */
}
#endif
if (SDL_strcmp(renderer, "Software Rasterizer") == 0) {
return SDL_FALSE; /* (a probably very old) Software Mesa, or some other generic thing. */
}
/* !!! FIXME: swrast? llvmpipe? softpipe? */
return SDL_TRUE;
}
static SDL_Renderer *
GL_CreateRenderer(SDL_Window * window, Uint32 flags)
@ -1700,6 +1726,8 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
Uint32 window_flags;
int profile_mask = 0, major = 0, minor = 0;
SDL_bool changed_window = SDL_FALSE;
const char *hint;
SDL_bool non_power_of_two_supported = SDL_FALSE;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask);
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
@ -1758,7 +1786,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->GL_BindTexture = GL_BindTexture;
renderer->GL_UnbindTexture = GL_UnbindTexture;
renderer->info = GL_RenderDriver.info;
renderer->info.flags = SDL_RENDERER_ACCELERATED;
renderer->info.flags = 0; /* will set some flags below. */
renderer->driverdata = data;
renderer->window = window;
@ -1782,6 +1810,10 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
goto error;
}
if (GL_IsProbablyAccelerated(data)) {
renderer->info.flags |= SDL_RENDERER_ACCELERATED;
}
#ifdef __MACOSX__
/* Enable multi-threaded rendering */
/* Disabled until Ryan finishes his VBO/PBO code...
@ -1815,15 +1847,37 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
}
hint = SDL_getenv("GL_ARB_texture_non_power_of_two");
if (!hint || *hint != '0') {
SDL_bool isGL2 = SDL_FALSE;
const char *verstr = (const char *)data->glGetString(GL_VERSION);
if (verstr) {
char verbuf[16];
char *ptr;
SDL_strlcpy(verbuf, verstr, sizeof (verbuf));
ptr = SDL_strchr(verbuf, '.');
if (ptr) {
*ptr = '\0';
if (SDL_atoi(verbuf) >= 2) {
isGL2 = SDL_TRUE;
}
}
}
if (isGL2 || SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
non_power_of_two_supported = SDL_TRUE;
}
}
data->textype = GL_TEXTURE_2D;
if (SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
if (non_power_of_two_supported) {
data->GL_ARB_texture_non_power_of_two_supported = SDL_TRUE;
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
renderer->info.max_texture_width = value;
renderer->info.max_texture_height = value;
} else if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
data->textype = GL_TEXTURE_RECTANGLE_ARB;
}
if (data->GL_ARB_texture_rectangle_supported) {
data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value);
renderer->info.max_texture_width = value;
renderer->info.max_texture_height = value;
@ -1848,7 +1902,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
}
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
data->shaders ? "ENABLED" : "DISABLED");
#if SDL_HAVE_YUV
/* We support YV12 textures using 3 textures and a shader */
if (data->shaders && data->num_texture_units >= 3) {
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
@ -1856,7 +1910,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
}
#endif
#ifdef __MACOSX__
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_UYVY;
#endif

View File

@ -284,7 +284,7 @@ static const char *shader_source[NUM_SHADERS][2] =
" gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n"
"}"
},
#if SDL_HAVE_YUV
/* SHADER_YUV_JPEG */
{
/* vertex shader */
@ -384,6 +384,7 @@ static const char *shader_source[NUM_SHADERS][2] =
BT709_SHADER_CONSTANTS
NV21_SHADER_BODY
},
#endif /* SDL_HAVE_YUV */
};
static SDL_bool

View File

@ -32,6 +32,7 @@ typedef enum {
SHADER_SOLID,
SHADER_RGB,
SHADER_RGBA,
#if SDL_HAVE_YUV
SHADER_YUV_JPEG,
SHADER_YUV_BT601,
SHADER_YUV_BT709,
@ -43,6 +44,7 @@ typedef enum {
SHADER_NV21_JPEG,
SHADER_NV21_BT601,
SHADER_NV21_BT709,
#endif
NUM_SHADERS
} GL_Shader;

View File

@ -561,6 +561,7 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
case GLES2_IMAGESOURCE_TEXTURE_BGR:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR;
break;
#if SDL_HAVE_YUV
case GLES2_IMAGESOURCE_TEXTURE_YUV:
switch (SDL_GetYUVConversionModeForResolution(w, h)) {
case SDL_YUV_CONVERSION_JPEG:
@ -617,6 +618,7 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
goto fault;
}
break;
#endif /* SDL_HAVE_YUV */
case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES;
break;
@ -1018,6 +1020,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
break;
}
break;
#if SDL_HAVE_YUV
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_YV12:
sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
@ -1028,6 +1031,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
case SDL_PIXELFORMAT_NV21:
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
break;
#endif
case SDL_PIXELFORMAT_EXTERNAL_OES:
sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
break;
@ -1051,6 +1055,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
case SDL_PIXELFORMAT_BGR888:
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
break;
#if SDL_HAVE_YUV
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_YV12:
sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
@ -1061,6 +1066,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
case SDL_PIXELFORMAT_NV21:
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
break;
#endif
case SDL_PIXELFORMAT_EXTERNAL_OES:
sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
break;
@ -1364,6 +1370,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
break;
#if SDL_HAVE_YUV
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_NV12:
@ -1371,6 +1378,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
format = GL_LUMINANCE;
type = GL_UNSIGNED_BYTE;
break;
#endif
#ifdef GL_TEXTURE_EXTERNAL_OES
case SDL_PIXELFORMAT_EXTERNAL_OES:
format = GL_NONE;
@ -2129,11 +2137,12 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->SetVSync = GLES2_SetVSync;
renderer->GL_BindTexture = GLES2_BindTexture;
renderer->GL_UnbindTexture = GLES2_UnbindTexture;
#if SDL_HAVE_YUV
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
#endif
#ifdef GL_TEXTURE_EXTERNAL_OES
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_EXTERNAL_OES;
#endif

View File

@ -121,6 +121,8 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
} \
";
#if SDL_HAVE_YUV
#define JPEG_SHADER_CONSTANTS \
"// YUV offset \n" \
"const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \
@ -299,6 +301,7 @@ static const Uint8 GLES2_Fragment_TextureNV21BT709[] = \
BT709_SHADER_CONSTANTS \
NV21_SHADER_BODY \
;
#endif
/* Custom Android video format texture */
static const Uint8 GLES2_Fragment_TextureExternalOES[] = " \
@ -335,6 +338,7 @@ const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
return GLES2_Fragment_TextureRGB;
case GLES2_SHADER_FRAGMENT_TEXTURE_BGR:
return GLES2_Fragment_TextureBGR;
#if SDL_HAVE_YUV
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG:
return GLES2_Fragment_TextureYUVJPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601:
@ -357,6 +361,7 @@ const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
return GLES2_Fragment_TextureNV21BT601;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709:
return GLES2_Fragment_TextureNV21BT709;
#endif
case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES:
return GLES2_Fragment_TextureExternalOES;
default:

View File

@ -34,6 +34,7 @@ typedef enum
GLES2_SHADER_FRAGMENT_TEXTURE_ARGB,
GLES2_SHADER_FRAGMENT_TEXTURE_BGR,
GLES2_SHADER_FRAGMENT_TEXTURE_RGB,
#if SDL_HAVE_YUV
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709,
@ -45,6 +46,7 @@ typedef enum
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709,
#endif
GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES,
GLES2_SHADER_COUNT
} GLES2_ShaderType;

View File

@ -139,11 +139,11 @@ SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FP
rotate(0.5, height - 0.5, sinangle, cosangle, center, &x2, &y2);
rotate(width - 0.5, height - 0.5, sinangle, cosangle, center, &x3, &y3);
minx = SDL_floor( SDL_min( SDL_min(x0, x1), SDL_min(x2, x3) ) );
maxx = SDL_ceil( SDL_max( SDL_max(x0, x1), SDL_max(x2, x3) ) );
minx = (int)SDL_floor( SDL_min( SDL_min(x0, x1), SDL_min(x2, x3) ) );
maxx = (int)SDL_ceil( SDL_max( SDL_max(x0, x1), SDL_max(x2, x3) ) );
miny = SDL_floor( SDL_min( SDL_min(y0, y1), SDL_min(y2, y3) ) );
maxy = SDL_ceil( SDL_max( SDL_max(y0, y1), SDL_max(y2, y3) ) );
miny = (int)SDL_floor( SDL_min( SDL_min(y0, y1), SDL_min(y2, y3) ) );
maxy = (int)SDL_ceil( SDL_max( SDL_max(y0, y1), SDL_max(y2, y3) ) );
rect_dest->w = maxx - minx;
rect_dest->h = maxy - miny;
@ -249,6 +249,7 @@ Assumes dst surface was allocated with the correct dimensions.
\param flipx Flag indicating horizontal mirroring should be applied.
\param flipy Flag indicating vertical mirroring should be applied.
\param smooth Flag indicating anti-aliasing should be used.
\param dst_rect destination coordinates
\param center true center.
*/
static void
@ -283,8 +284,8 @@ transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int isin, int icos,
int x;
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
double src_y = (rect_dest->y + y + 0.5 - center->y);
int sdx = (icos * src_x - isin * src_y) + cx - fp_half;
int sdy = (isin * src_x + icos * src_y) + cy - fp_half;
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
for (x = 0; x < dst->w; x++) {
int dx = (sdx >> 16);
int dy = (sdy >> 16);
@ -339,8 +340,8 @@ transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int isin, int icos,
int x;
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
double src_y = (rect_dest->y + y + 0.5 - center->y);
int sdx = (icos * src_x - isin * src_y) + cx - fp_half;
int sdy = (isin * src_x + icos * src_y) + cy - fp_half;
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
for (x = 0; x < dst->w; x++) {
int dx = (sdx >> 16);
int dy = (sdy >> 16);
@ -369,29 +370,35 @@ Assumes dst surface was allocated with the correct dimensions.
\param src Source surface.
\param dst Destination surface.
\param cx Horizontal center coordinate.
\param cy Vertical center coordinate.
\param isin Integer version of sine of angle.
\param icos Integer version of cosine of angle.
\param flipx Flag indicating horizontal mirroring should be applied.
\param flipy Flag indicating vertical mirroring should be applied.
\param dst_rect destination coordinates
\param center true center.
*/
static void
transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int isin, int icos, int flipx, int flipy,
const SDL_Rect *rect_dest,
const SDL_FPoint *center)
{
int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay;
int sw, sh;
int cx, cy;
tColorY *pc;
int gap;
const int fp_half = (1<<15);
int y;
/*
* Variable setup
*/
xd = ((src->w - dst->w) << 15);
yd = ((src->h - dst->h) << 15);
ax = (cx << 16) - (icos * cx);
ay = (cy << 16) - (isin * cx);
sw = src->w - 1;
sh = src->h - 1;
pc = (tColorY*) dst->pixels;
gap = dst->pitch - dst->w;
cx = (int)(center->x * 65536.0);
cy = (int)(center->y * 65536.0);
/*
* Clear surface to colorkey
*/
@ -400,15 +407,17 @@ transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin
* Iterate through destination surface
*/
for (y = 0; y < dst->h; y++) {
dy = cy - y;
sdx = (ax + (isin * dy)) + xd;
sdy = (ay - (icos * dy)) + yd;
int x;
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
double src_y = (rect_dest->y + y + 0.5 - center->y);
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
for (x = 0; x < dst->w; x++) {
dx = (sdx >> 16);
dy = (sdy >> 16);
int dx = (sdx >> 16);
int dy = (sdy >> 16);
if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
if (flipx) dx = (src->w-1)-dx;
if (flipy) dy = (src->h-1)-dy;
if (flipx) dx = sw - dx;
if (flipy) dy = sh- dy;
*pc = *((tColorY *)src->pixels + src->pitch * dy + dx);
}
sdx += icos;
@ -424,7 +433,7 @@ transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin
\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing.
Rotates a 32-bit or 8-bit 'src' surface to newly created 'dst' surface.
'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set
'angle' is the rotation in degrees, 'center' the rotation center. If 'smooth' is set
then the destination 32-bit surface is anti-aliased. 8-bit surfaces must have a colorkey. 32-bit
surfaces must have a 8888 layout with red, green, blue and alpha masks (any ordering goes).
The blend mode of the 'src' surface has some effects on generation of the 'dst' surface: The NONE
@ -467,7 +476,6 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int
colorKeyAvailable = SDL_TRUE;
}
}
/* This function requires a 32-bit surface or 8-bit surface with a colorkey */
is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable;
if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask)))
@ -481,12 +489,14 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int
rz_dst = NULL;
if (is8bit) {
/* Target surface is 8 bit */
rz_dst = SDL_CreateRGBSurface(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 8, 0, 0, 0, 0);
rz_dst = SDL_CreateRGBSurfaceWithFormat(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 8, src->format->format);
if (rz_dst != NULL) {
for (i = 0; i < src->format->palette->ncolors; i++) {
rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
if (src->format->palette) {
for (i = 0; i < src->format->palette->ncolors; i++) {
rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
}
rz_dst->format->palette->ncolors = src->format->palette->ncolors;
}
rz_dst->format->palette->ncolors = src->format->palette->ncolors;
}
} else {
/* Target surface is 32 bit with source RGBA ordering */
@ -547,8 +557,8 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int
if(angle90 >= 0) {
transformSurfaceY90(src, rz_dst, angle90, flipx, flipy);
} else {
transformSurfaceY(src, rz_dst, rect_dest->w/2, rect_dest->h/2, (int)sangleinv, (int)cangleinv,
flipx, flipy);
transformSurfaceY(src, rz_dst, (int)sangleinv, (int)cangleinv,
flipx, flipy, rect_dest, center);
}
} else {
/* Call the 32-bit transformation routine to do the rotation */

View File

@ -217,7 +217,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
data = (VITA_GXM_RenderData *) SDL_calloc(1, sizeof(VITA_GXM_RenderData));
if (!data) {
VITA_GXM_DestroyRenderer(renderer);
SDL_free(renderer);
SDL_OutOfMemory();
return NULL;
}
@ -226,7 +226,9 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->SupportsBlendMode = VITA_GXM_SupportsBlendMode;
renderer->CreateTexture = VITA_GXM_CreateTexture;
renderer->UpdateTexture = VITA_GXM_UpdateTexture;
#if SDL_HAVE_YUV
renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
#endif
renderer->LockTexture = VITA_GXM_LockTexture;
renderer->UnlockTexture = VITA_GXM_UnlockTexture;
renderer->SetTextureScaleMode = VITA_GXM_SetTextureScaleMode;

View File

@ -641,19 +641,16 @@ SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_
size_t bytes = SDL_min(src_bytes, dst_bytes - 1);
size_t i = 0;
unsigned char trailing_bytes = 0;
if (bytes)
{
if (bytes) {
unsigned char c = (unsigned char)src[bytes - 1];
if (UTF8_IsLeadByte(c))
if (UTF8_IsLeadByte(c)) {
--bytes;
else if (UTF8_IsTrailingByte(c))
{
for (i = bytes - 1; i != 0; --i)
{
} else if (UTF8_IsTrailingByte(c)) {
for (i = bytes - 1; i != 0; --i) {
c = (unsigned char)src[i];
trailing_bytes = UTF8_TrailingBytes(c);
if (trailing_bytes)
{
if (trailing_bytes) {
if (bytes - i != trailing_bytes + 1)
bytes = i;
@ -664,6 +661,7 @@ SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_
SDL_memcpy(dst, src, bytes);
}
dst[bytes] = '\0';
return bytes;
}

View File

@ -128,8 +128,6 @@ static VideoBootStrap *bootstrap[] = {
NULL
};
static SDL_VideoDevice *_this = NULL;
#define CHECK_WINDOW_MAGIC(window, retval) \
if (!_this) { \
SDL_UninitializedVideo(); \
@ -172,129 +170,58 @@ typedef struct {
int bytes_per_pixel;
} SDL_WindowTextureData;
static SDL_bool
ShouldUseTextureFramebuffer()
{
const char *hint;
/* If there's no native framebuffer support then there's no option */
if (!_this->CreateWindowFramebuffer) {
return SDL_TRUE;
}
/* If this is the dummy driver there is no texture support */
if (_this->is_dummy) {
return SDL_FALSE;
}
/* See if the user or application wants a specific behavior */
hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
if (hint) {
if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) {
return SDL_FALSE;
} else {
return SDL_TRUE;
}
}
/* Each platform has different performance characteristics */
#if defined(__WIN32__)
/* GDI BitBlt() is way faster than Direct3D dynamic textures right now.
*/
return SDL_FALSE;
#elif defined(__MACOSX__)
/* Mac OS X uses OpenGL as the native fast path (for cocoa and X11) */
return SDL_TRUE;
#elif defined(__LINUX__)
/* Properly configured OpenGL drivers are faster than MIT-SHM */
#if SDL_VIDEO_OPENGL
/* Ugh, find a way to cache this value! */
{
SDL_Window *window;
SDL_GLContext context;
SDL_bool hasAcceleratedOpenGL = SDL_FALSE;
window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN);
if (window) {
context = SDL_GL_CreateContext(window);
if (context) {
const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
const char *vendor = NULL;
glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
if (glGetStringFunc) {
vendor = (const char *) glGetStringFunc(GL_VENDOR);
}
/* Add more vendors here at will... */
if (vendor &&
(SDL_strstr(vendor, "ATI Technologies") ||
SDL_strstr(vendor, "NVIDIA"))) {
hasAcceleratedOpenGL = SDL_TRUE;
}
SDL_GL_DeleteContext(context);
}
SDL_DestroyWindow(window);
}
return hasAcceleratedOpenGL;
}
#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
/* Let's be optimistic about this! */
return SDL_TRUE;
#else
return SDL_FALSE;
#endif
#else
/* Play it safe, assume that if there is a framebuffer driver that it's
optimized for the current platform.
*/
return SDL_FALSE;
#endif
}
static int
SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
{
SDL_WindowTextureData *data;
SDL_RendererInfo info;
SDL_WindowTextureData *data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
int i;
data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
if (!data) {
SDL_Renderer *renderer = NULL;
int i;
const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
/* Check to see if there's a specific driver requested */
if (hint && *hint != '0' && *hint != '1' &&
const SDL_bool specific_accelerated_renderer = (
hint && *hint != '0' && *hint != '1' &&
SDL_strcasecmp(hint, "true") != 0 &&
SDL_strcasecmp(hint, "false") != 0 &&
SDL_strcasecmp(hint, "software") != 0) {
SDL_strcasecmp(hint, "software") != 0
);
/* Check to see if there's a specific driver requested */
if (specific_accelerated_renderer) {
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
SDL_RendererInfo info;
SDL_GetRenderDriverInfo(i, &info);
if (SDL_strcasecmp(info.name, hint) == 0) {
renderer = SDL_CreateRenderer(window, i, 0);
break;
}
}
}
if (!renderer) {
if (!renderer || (SDL_GetRendererInfo(renderer, &info) == -1)) {
if (renderer) { SDL_DestroyRenderer(renderer); }
return SDL_SetError("Requested renderer for " SDL_HINT_FRAMEBUFFER_ACCELERATION " is not available");
}
/* if it was specifically requested, even if SDL_RENDERER_ACCELERATED isn't set, we'll accept this renderer. */
} else {
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
SDL_RendererInfo info;
SDL_GetRenderDriverInfo(i, &info);
if (SDL_strcmp(info.name, "software") != 0) {
renderer = SDL_CreateRenderer(window, i, 0);
if (renderer) {
break;
if (renderer && (SDL_GetRendererInfo(renderer, &info) == 0) && (info.flags & SDL_RENDERER_ACCELERATED)) {
break; /* this will work. */
}
if (renderer) { /* wasn't accelerated, etc, skip it. */
SDL_DestroyRenderer(renderer);
renderer = NULL;
}
}
}
if (!renderer) {
return SDL_SetError("No hardware accelerated renderers available");
}
}
if (!renderer) {
return SDL_SetError("No hardware accelerated renderers available");
}
SDL_assert(renderer != NULL); /* should have explicitly checked this above. */
/* Create the data after we successfully create the renderer (bug #1116) */
data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data));
@ -305,6 +232,10 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f
SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, data);
data->renderer = renderer;
} else {
if (SDL_GetRendererInfo(data->renderer, &info) == -1) {
return -1;
}
}
/* Free any old texture and pixel data */
@ -315,23 +246,14 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f
SDL_free(data->pixels);
data->pixels = NULL;
{
SDL_RendererInfo info;
Uint32 i;
/* Find the first format without an alpha channel */
*format = info.texture_formats[0];
if (SDL_GetRendererInfo(data->renderer, &info) < 0) {
return -1;
}
/* Find the first format without an alpha channel */
*format = info.texture_formats[0];
for (i = 0; i < info.num_texture_formats; ++i) {
if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) &&
!SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) {
*format = info.texture_formats[i];
break;
}
for (i = 0; i < (int) info.num_texture_formats; ++i) {
if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) &&
!SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) {
*format = info.texture_formats[i];
break;
}
}
@ -364,6 +286,8 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f
return 0;
}
static SDL_VideoDevice *_this = NULL;
static int
SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, const SDL_Rect * rects, int numrects)
{
@ -413,28 +337,6 @@ SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window * window)
SDL_free(data);
}
/* This will switch the video backend from using a software surface to
using a GPU texture through the 2D render API, if we think this would
be more efficient. This only checks once, on demand. */
static void
PrepareWindowFramebuffer()
{
/* Add the renderer framebuffer emulation if desired */
if (_this->checked_texture_framebuffer) {
return;
}
_this->checked_texture_framebuffer = SDL_TRUE;
if (ShouldUseTextureFramebuffer()) {
_this->CreateWindowFramebuffer = SDL_CreateWindowTexture;
_this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture;
_this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture;
}
}
static int
cmpmodes(const void *A, const void *B)
{
@ -2549,20 +2451,58 @@ SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags)
static SDL_Surface *
SDL_CreateWindowFramebuffer(SDL_Window * window)
{
Uint32 format;
void *pixels;
int pitch;
Uint32 format = 0;
void *pixels = NULL;
int pitch = 0;
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
SDL_bool created_framebuffer = SDL_FALSE;
PrepareWindowFramebuffer();
/* This will switch the video backend from using a software surface to
using a GPU texture through the 2D render API, if we think this would
be more efficient. This only checks once, on demand. */
if (!_this->checked_texture_framebuffer) {
SDL_bool attempt_texture_framebuffer = SDL_TRUE;
if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) {
return NULL;
if (_this->is_dummy) { /* dummy driver never has GPU support, of course. */
attempt_texture_framebuffer = SDL_FALSE;
}
#if defined(__WIN32__) /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. (!!! FIXME: is this still true?) */
else if ((_this->CreateWindowFramebuffer != NULL) && (SDL_strcmp(_this->name, "windows") == 0)) {
attempt_texture_framebuffer = SDL_FALSE;
}
#endif
if (attempt_texture_framebuffer) {
if (SDL_CreateWindowTexture(_this, window, &format, &pixels, &pitch) == -1) {
/* !!! FIXME: if this failed halfway (made renderer, failed to make texture, etc),
!!! FIXME: we probably need to clean this up so it doesn't interfere with
!!! FIXME: a software fallback at the system level (can we blit to an
!!! FIXME: OpenGL window? etc). */
} else {
/* future attempts will just try to use a texture framebuffer. */
/* !!! FIXME: maybe we shouldn't override these but check if we used a texture
!!! FIXME: framebuffer at the right places; is it feasible we could have an
!!! FIXME: accelerated OpenGL window and a second ends up in software? */
_this->CreateWindowFramebuffer = SDL_CreateWindowTexture;
_this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture;
_this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture;
created_framebuffer = SDL_TRUE;
}
}
_this->checked_texture_framebuffer = SDL_TRUE; /* don't check this again. */
}
if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) {
return NULL;
if (!created_framebuffer) {
if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) {
return NULL;
}
if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) {
return NULL;
}
}
if (window->surface) {

View File

@ -43,6 +43,7 @@ static int Emscripten_VideoInit(_THIS);
static int Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
static void Emscripten_VideoQuit(_THIS);
static int Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
static int Emscripten_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
static int Emscripten_CreateWindow(_THIS, SDL_Window * window);
static void Emscripten_SetWindowSize(_THIS, SDL_Window * window);
@ -82,6 +83,7 @@ Emscripten_CreateDevice(int devindex)
device->VideoInit = Emscripten_VideoInit;
device->VideoQuit = Emscripten_VideoQuit;
device->GetDisplayUsableBounds = Emscripten_GetDisplayUsableBounds;
device->GetDisplayDPI = Emscripten_GetDisplayDPI;
device->SetDisplayMode = Emscripten_SetDisplayMode;
@ -182,6 +184,27 @@ Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect *
return 0;
}
static int
Emscripten_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi_out, float * hdpi_out, float * vdpi_out)
{
const float dpi_reference = 96.0f;
float dpi;
dpi = (float)emscripten_get_device_pixel_ratio() * dpi_reference;
if (ddpi_out) {
*ddpi_out = dpi;
}
if (hdpi_out) {
*hdpi_out = dpi;
}
if (vdpi_out) {
*vdpi_out = dpi;
}
return 0;
}
static void
Emscripten_PumpEvents(_THIS)
{

View File

@ -67,7 +67,6 @@ RISCOS_PollKeyboard(_THIS)
/* Check for key presses */
while (key < 0xff) {
SDL_bool already_pressed = SDL_FALSE;
key = _kernel_osbyte(121, key + 1, 0) & 0xff;
switch (key) {
case 255:
@ -83,22 +82,16 @@ RISCOS_PollKeyboard(_THIS)
break;
default:
/* Do we already know of this key? */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_RISCOS_translate_keycode(key));
/* Record the press so we can detect release later. */
for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {
if (driverdata->key_pressed[i] == key) {
already_pressed = SDL_TRUE;
break;
}
}
if (!already_pressed) {
SDL_SendKeyboardKey(SDL_PRESSED, SDL_RISCOS_translate_keycode(key));
/* Record the press so we can detect release later. */
for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {
if (driverdata->key_pressed[i] == 255) {
driverdata->key_pressed[i] = key;
break;
}
if (driverdata->key_pressed[i] == 255) {
driverdata->key_pressed[i] = key;
break;
}
}
}

View File

@ -51,16 +51,17 @@ static const TCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatche
static const TCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
static ATOM SDL_HelperWindowClass = 0;
/* For borderless Windows, still want the following flags:
/* For borderless Windows, still want the following flag:
- WS_MINIMIZEBOX: window will respond to Windows minimize commands sent to all windows, such as windows key + m, shaking title bar, etc.
Additionally, non-fullscreen windows can add:
- WS_CAPTION: this seems to enable the Windows minimize animation
- WS_SYSMENU: enables system context menu on task bar
- WS_MINIMIZEBOX: window will respond to Windows minimize commands sent to all windows, such as windows key + m, shaking title bar, etc.
This will also cause the task bar to overlap the window and other windowed behaviors, so only use this for windows that shouldn't appear to be fullscreen
*/
#define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
#define STYLE_FULLSCREEN (WS_POPUP)
#define STYLE_BORDERLESS (WS_POPUP)
#define STYLE_FULLSCREEN (WS_POPUP | WS_MINIMIZEBOX)
#define STYLE_BORDERLESS (WS_POPUP | WS_MINIMIZEBOX)
#define STYLE_BORDERLESS_WINDOWED (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
#define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
#define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)