Re-added WinRT support until we're sure that it's no longer being used

This commit is contained in:
Sam Lantinga
2022-11-23 10:41:43 -08:00
parent d5572559a5
commit a635a485bc
92 changed files with 8410 additions and 164 deletions

View File

@@ -46,27 +46,13 @@
#endif
/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */
static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32,{ 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483,{ 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } };
static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0,{ 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } };
/* handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency). */
static HMODULE libavrt = NULL;
typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD);
typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
static void
WASAPI_DetectDevices(void)
{
SDL_IMMDevice_EnumerateEndpoints(SDL_FALSE);
}
int
WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
{
return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture);
WASAPI_EnumerateEndpoints();
}
static SDL_INLINE SDL_bool
@@ -140,7 +126,7 @@ UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
return 0;
}
static int ActivateWasapiDevice(_THIS, SDL_bool isrecovery);
static void ReleaseWasapiDevice(_THIS);
static SDL_bool
@@ -157,7 +143,7 @@ RecoverWasapiDevice(_THIS)
devices try to reinitialize whatever the new default is, so it's more
likely to carry on here, but this handles a non-default device that
simply had its format changed in the Windows Control Panel. */
if (ActivateWasapiDevice(this, SDL_TRUE) == -1) {
if (WASAPI_ActivateDevice(this, SDL_TRUE) == -1) {
SDL_OpenedAudioDeviceDisconnected(this);
return SDL_FALSE;
}
@@ -363,6 +349,11 @@ ReleaseWasapiDevice(_THIS)
this->hidden->capturestream = NULL;
}
if (this->hidden->activation_handler) {
WASAPI_PlatformDeleteActivationHandler(this->hidden->activation_handler);
this->hidden->activation_handler = NULL;
}
if (this->hidden->event) {
CloseHandle(this->hidden->event);
this->hidden->event = NULL;
@@ -371,6 +362,18 @@ ReleaseWasapiDevice(_THIS)
static void
WASAPI_CloseDevice(_THIS)
{
WASAPI_UnrefDevice(this);
}
void
WASAPI_RefDevice(_THIS)
{
SDL_AtomicIncRef(&this->hidden->refcount);
}
void
WASAPI_UnrefDevice(_THIS)
{
if (!SDL_AtomicDecRef(&this->hidden->refcount)) {
return;
@@ -387,7 +390,7 @@ WASAPI_CloseDevice(_THIS)
}
/* This is called once a device is activated, possibly asynchronously. */
static int
int
WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
{
/* !!! FIXME: we could request an exclusive mode stream, which is lower latency;
@@ -416,7 +419,7 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
SDL_assert(client != NULL);
#if defined(__GDK__) /* CreateEventEx() arrived in Vista, so we need an #ifdef for XP. */
#if defined(__WINRT__) || defined(__GDK__) /* CreateEventEx() arrived in Vista, so we need an #ifdef for XP. */
this->hidden->event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
#else
this->hidden->event = CreateEventW(NULL, 0, 0, NULL);
@@ -538,34 +541,6 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
return 0; /* good to go. */
}
static int
ActivateWasapiDevice(_THIS, const SDL_bool isrecovery)
{
IMMDevice *device = NULL;
HRESULT ret;
if (SDL_IMMDevice_Get(this->hidden->devid, &device, this->iscapture) < 0) {
this->hidden->client = NULL;
return -1; /* This is already set by SDL_IMMDevice_Get */
}
/* this is not async in standard win32, yay! */
ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **) &this->hidden->client);
IMMDevice_Release(device);
if (FAILED(ret)) {
SDL_assert(this->hidden->client == NULL);
return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
}
SDL_assert(this->hidden->client != NULL);
if (WASAPI_PrepDevice(this, isrecovery) == -1) { /* not async, fire it right away. */
return -1;
}
return 0; /* good to go. */
}
static int
WASAPI_OpenDevice(_THIS, const char *devname)
@@ -580,7 +555,7 @@ WASAPI_OpenDevice(_THIS, const char *devname)
}
SDL_zerop(this->hidden);
SDL_AtomicIncRef(&this->hidden->refcount); /* so CloseDevice() will unref to zero. */
WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */
if (!devid) { /* is default device? */
this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration);
@@ -591,7 +566,7 @@ WASAPI_OpenDevice(_THIS, const char *devname)
}
}
if (ActivateWasapiDevice(this, SDL_FALSE) == -1) {
if (WASAPI_ActivateDevice(this, SDL_FALSE) == -1) {
return -1; /* already set error. */
}
@@ -609,58 +584,26 @@ WASAPI_OpenDevice(_THIS, const char *devname)
static void
WASAPI_ThreadInit(_THIS)
{
/* this thread uses COM. */
if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */
this->hidden->coinitialized = SDL_TRUE;
}
/* Set this thread to very high "Pro Audio" priority. */
if (pAvSetMmThreadCharacteristicsW) {
DWORD idx = 0;
this->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx);
}
WASAPI_PlatformThreadInit(this);
}
static void
WASAPI_ThreadDeinit(_THIS)
{
/* Set this thread back to normal priority. */
if (this->hidden->task && pAvRevertMmThreadCharacteristics) {
pAvRevertMmThreadCharacteristics(this->hidden->task);
this->hidden->task = NULL;
}
if (this->hidden->coinitialized) {
WIN_CoUninitialize();
this->hidden->coinitialized = SDL_FALSE;
}
WASAPI_PlatformThreadDeinit(this);
}
static void
WASAPI_Deinitialize(void)
{
if (libavrt) {
FreeLibrary(libavrt);
libavrt = NULL;
}
pAvSetMmThreadCharacteristicsW = NULL;
pAvRevertMmThreadCharacteristics = NULL;
SDL_IMMDevice_Quit();
WASAPI_PlatformDeinit();
}
static SDL_bool
WASAPI_Init(SDL_AudioDriverImpl * impl)
{
if (SDL_IMMDevice_Init() < 0) {
return SDL_FALSE; /* Error is set by SDL_IMMDevice_Init */
}
libavrt = LoadLibrary(TEXT("avrt.dll")); /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */
if (libavrt) {
pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW) GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW");
pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics) GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics");
if (WASAPI_PlatformInit() == -1) {
return SDL_FALSE;
}
/* Set the function pointers */