mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-23 10:53:27 +08:00
Fixed memory leaks if OpenVR initialization fails
This commit is contained in:
parent
7b492553c4
commit
d199586683
@ -271,22 +271,20 @@ static bool OPENVR_VideoInit(SDL_VideoDevice *_this)
|
|||||||
{
|
{
|
||||||
SDL_VideoData *data = (SDL_VideoData *)_this->internal;
|
SDL_VideoData *data = (SDL_VideoData *)_this->internal;
|
||||||
|
|
||||||
{
|
const char * hintWidth = SDL_GetHint("SDL_DEFAULT_WIDTH");
|
||||||
const char * hintWidth = SDL_GetHint("SDL_DEFAULT_WIDTH");
|
const char * hintHeight = SDL_GetHint("SDL_DEFAULT_HEIGHT");
|
||||||
const char * hintHeight = SDL_GetHint("SDL_DEFAULT_HEIGHT");
|
const char * hintFPS = SDL_GetHint("SDL_DEFAULT_FPS");
|
||||||
const char * hintFPS = SDL_GetHint("SDL_DEFAULT_FPS");
|
int width = hintWidth?atoi(hintWidth):0;
|
||||||
int width = hintWidth?atoi(hintWidth):0;
|
int height = hintHeight?atoi(hintHeight):0;
|
||||||
int height = hintHeight?atoi(hintHeight):0;
|
if (height > 0 && width > 0) {
|
||||||
if (height > 0 && width > 0) {
|
openvr_vd_default.desktop_mode.w = width;
|
||||||
openvr_vd_default.desktop_mode.w = width;
|
openvr_vd_default.desktop_mode.h = height;
|
||||||
openvr_vd_default.desktop_mode.h = height;
|
}
|
||||||
}
|
int fps = hintFPS?atoi(hintFPS):0;
|
||||||
int fps = hintFPS?atoi(hintFPS):0;
|
if (fps) {
|
||||||
if (fps) {
|
openvr_vd_default.desktop_mode.refresh_rate = fps;
|
||||||
openvr_vd_default.desktop_mode.refresh_rate = fps;
|
} else {
|
||||||
} else {
|
openvr_vd_default.desktop_mode.refresh_rate = data->oSystem->GetFloatTrackedDeviceProperty(k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty_Prop_DisplayFrequency_Float, 0);
|
||||||
openvr_vd_default.desktop_mode.refresh_rate = data->oSystem->GetFloatTrackedDeviceProperty(k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty_Prop_DisplayFrequency_Float, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openvr_vd_default.internal = (SDL_DisplayData *)data;
|
openvr_vd_default.internal = (SDL_DisplayData *)data;
|
||||||
@ -306,7 +304,19 @@ static void OPENVR_VideoQuit(SDL_VideoDevice *_this)
|
|||||||
|
|
||||||
static void OPENVR_Destroy(SDL_VideoDevice *device)
|
static void OPENVR_Destroy(SDL_VideoDevice *device)
|
||||||
{
|
{
|
||||||
// Don't need to destroy and free internal, since it is already done in SDL_VideoQuit
|
SDL_VideoData *data = device->internal;
|
||||||
|
|
||||||
|
#ifdef SDL_PLATFORM_WINDOWS
|
||||||
|
SDL_UnregisterApp();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
if (data->openVRLIB) {
|
||||||
|
SDL_UnloadObject(data->openVRLIB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_free(device->internal);
|
||||||
|
SDL_free(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t *ImageSDLToOpenVRGL(SDL_Surface * surf, bool bFlipY)
|
static uint32_t *ImageSDLToOpenVRGL(SDL_Surface * surf, bool bFlipY)
|
||||||
@ -1552,10 +1562,13 @@ static SDL_VideoDevice *OPENVR_CreateDevice(void)
|
|||||||
data = NULL;
|
data = NULL;
|
||||||
}
|
}
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
#ifdef SDL_PLATFORM_WINDOWS
|
||||||
|
SDL_UnregisterApp();
|
||||||
|
#endif
|
||||||
SDL_free(device);
|
SDL_free(device);
|
||||||
SDL_OutOfMemory();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
device->internal = data;
|
||||||
|
|
||||||
{
|
{
|
||||||
const char * hint = SDL_GetHint(SDL_HINT_OPENVR_LIBRARY);
|
const char * hint = SDL_GetHint(SDL_HINT_OPENVR_LIBRARY);
|
||||||
@ -1570,82 +1583,75 @@ static SDL_VideoDevice *OPENVR_CreateDevice(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->openVRLIB) {
|
if (!data->openVRLIB) {
|
||||||
data->FN_VR_InitInternal = (intptr_t(*)(EVRInitError * peError, EVRApplicationType eType))SDL_LoadFunction(data->openVRLIB, "VR_InitInternal");
|
|
||||||
data->FN_VR_GetVRInitErrorAsEnglishDescription = (const char *(*)(EVRInitError error))SDL_LoadFunction(data->openVRLIB, "VR_GetVRInitErrorAsEnglishDescription");
|
|
||||||
data->FN_VR_GetGenericInterface = (intptr_t (*)(const char *pchInterfaceVersion, EVRInitError * peError))SDL_LoadFunction(data->openVRLIB, "VR_GetGenericInterface");
|
|
||||||
} else {
|
|
||||||
SDL_SetError("Could not open OpenVR API Library");
|
SDL_SetError("Could not open OpenVR API Library");
|
||||||
return NULL;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->FN_VR_InitInternal) {
|
data->FN_VR_InitInternal = (intptr_t(*)(EVRInitError * peError, EVRApplicationType eType))SDL_LoadFunction(data->openVRLIB, "VR_InitInternal");
|
||||||
char fnname[128];
|
data->FN_VR_GetVRInitErrorAsEnglishDescription = (const char *(*)(EVRInitError error))SDL_LoadFunction(data->openVRLIB, "VR_GetVRInitErrorAsEnglishDescription");
|
||||||
EVRInitError e;
|
data->FN_VR_GetGenericInterface = (intptr_t (*)(const char *pchInterfaceVersion, EVRInitError * peError))SDL_LoadFunction(data->openVRLIB, "VR_GetGenericInterface");
|
||||||
data->vrtoken = data->FN_VR_InitInternal(&e, EVRApplicationType_VRApplication_Overlay);
|
if (!data->FN_VR_InitInternal || !data->FN_VR_GetVRInitErrorAsEnglishDescription || !data->FN_VR_GetGenericInterface) {
|
||||||
if (!data->vrtoken) {
|
goto error;
|
||||||
const char *err = "Can't get english description";
|
|
||||||
if (data->FN_VR_GetVRInitErrorAsEnglishDescription != NULL)
|
|
||||||
err = data->FN_VR_GetVRInitErrorAsEnglishDescription(e);
|
|
||||||
SDL_SetError("Could not generate OpenVR Context (%s)", err);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_snprintf(fnname, 127, "FnTable:%s", IVRSystem_Version);
|
|
||||||
data->oSystem = (struct VR_IVRSystem_FnTable *)data->FN_VR_GetGenericInterface(fnname, &e);
|
|
||||||
SDL_snprintf(fnname, 127, "FnTable:%s", IVROverlay_Version);
|
|
||||||
data->oOverlay = (struct VR_IVROverlay_FnTable *)data->FN_VR_GetGenericInterface(fnname, &e);
|
|
||||||
SDL_snprintf(fnname, 127, "FnTable:%s", IVRInput_Version);
|
|
||||||
data->oInput = (struct VR_IVRInput_FnTable *)data->FN_VR_GetGenericInterface(fnname, &e);
|
|
||||||
|
|
||||||
if (!data->oOverlay || !data->oSystem) {
|
|
||||||
SDL_SetError("Could not get interfaces for the OpenVR System (%s), Overlay (%s) and Input (%s) versions", IVRSystem_Version, IVROverlay_Version, IVRInput_Version);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
char fnname[128];
|
||||||
const char * hint = SDL_GetHint("SDL_OPENVR_INPUT_PROFILE");
|
EVRInitError e;
|
||||||
char * loadpath = 0;
|
data->vrtoken = data->FN_VR_InitInternal(&e, EVRApplicationType_VRApplication_Overlay);
|
||||||
EVRInputError err;
|
if (!data->vrtoken) {
|
||||||
|
const char *err = "Can't get english description";
|
||||||
|
if (data->FN_VR_GetVRInitErrorAsEnglishDescription != NULL)
|
||||||
|
err = data->FN_VR_GetVRInitErrorAsEnglishDescription(e);
|
||||||
|
SDL_SetError("Could not generate OpenVR Context (%s)", err);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_snprintf(fnname, 127, "FnTable:%s", IVRSystem_Version);
|
||||||
|
data->oSystem = (struct VR_IVRSystem_FnTable *)data->FN_VR_GetGenericInterface(fnname, &e);
|
||||||
|
SDL_snprintf(fnname, 127, "FnTable:%s", IVROverlay_Version);
|
||||||
|
data->oOverlay = (struct VR_IVROverlay_FnTable *)data->FN_VR_GetGenericInterface(fnname, &e);
|
||||||
|
SDL_snprintf(fnname, 127, "FnTable:%s", IVRInput_Version);
|
||||||
|
data->oInput = (struct VR_IVRInput_FnTable *)data->FN_VR_GetGenericInterface(fnname, &e);
|
||||||
|
|
||||||
|
if (!data->oOverlay || !data->oSystem || !data->oInput) {
|
||||||
|
SDL_SetError("Could not get interfaces for the OpenVR System (%s), Overlay (%s) and Input (%s) versions", IVRSystem_Version, IVROverlay_Version, IVRInput_Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *hint = SDL_GetHint("SDL_OPENVR_INPUT_PROFILE");
|
||||||
|
char *loadpath = 0;
|
||||||
|
EVRInputError err;
|
||||||
|
|
||||||
|
if (hint) {
|
||||||
|
SDL_asprintf(&loadpath, "%s", hint);
|
||||||
|
} else {
|
||||||
|
const char *basepath = SDL_GetBasePath();
|
||||||
|
SDL_asprintf(&loadpath, "%ssdloverlay_actions.json", basepath);
|
||||||
|
}
|
||||||
|
if (!loadpath) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = data->oInput->SetActionManifestPath(loadpath);
|
||||||
|
#ifdef DEBUG_OPENVR
|
||||||
|
SDL_Log("Loaded action manifest at %s (%d)", loadpath, err);
|
||||||
|
#endif
|
||||||
|
SDL_free(loadpath);
|
||||||
|
if (err != EVRInputError_VRInputError_None) {
|
||||||
|
// I know we don't normally log, but this _really_ should be percolated
|
||||||
|
// up as far as we can.
|
||||||
|
SDL_Log("Could not load action manifest path");
|
||||||
|
// If we didn't have a hint, this is a soft fail.
|
||||||
|
// If we did have the hint, then it's a hard fail.
|
||||||
if (hint) {
|
if (hint) {
|
||||||
SDL_asprintf(&loadpath, "%s", hint);
|
goto error;
|
||||||
} else {
|
|
||||||
const char *basepath = SDL_GetBasePath();
|
|
||||||
SDL_asprintf(&loadpath, "%ssdloverlay_actions.json", basepath);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (!loadpath) {
|
int e = OPENVR_SetupJoystckBasedOnLoadedActionManifest(data);
|
||||||
return NULL;
|
if(e) {
|
||||||
}
|
goto error;
|
||||||
|
|
||||||
err = data->oInput->SetActionManifestPath(loadpath);
|
|
||||||
#ifdef DEBUG_OPENVR
|
|
||||||
SDL_Log("Loaded action manifest at %s (%d)", loadpath, err);
|
|
||||||
#endif
|
|
||||||
SDL_free(loadpath);
|
|
||||||
if (err != EVRInputError_VRInputError_None) {
|
|
||||||
// I know we don't normally log, but this _really_ should be percolated
|
|
||||||
// up as far as we can.
|
|
||||||
SDL_Log("Could not load action manifest path");
|
|
||||||
// If we didn't have a hint, this is a soft fail.
|
|
||||||
// If we did have the hint, then it's a hard fail.
|
|
||||||
if (hint) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int e = OPENVR_SetupJoystckBasedOnLoadedActionManifest(data);
|
|
||||||
if(e) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device->internal = data;
|
|
||||||
device->wakeup_lock = SDL_CreateMutex();
|
|
||||||
|
|
||||||
// Setup amount of available displays
|
// Setup amount of available displays
|
||||||
device->num_displays = 0;
|
device->num_displays = 0;
|
||||||
|
|
||||||
@ -1722,6 +1728,10 @@ static SDL_VideoDevice *OPENVR_CreateDevice(void)
|
|||||||
device->SetWindowIcon = OPENVR_SetWindowIcon;
|
device->SetWindowIcon = OPENVR_SetWindowIcon;
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
|
|
||||||
|
error:
|
||||||
|
OPENVR_Destroy(device);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoBootStrap OPENVR_bootstrap = {
|
VideoBootStrap OPENVR_bootstrap = {
|
||||||
|
Loading…
Reference in New Issue
Block a user