Fixed memory leaks in KMSDRM property handling

Also cleaned up the code for consistency so it's easy to see memory leaks here.
This commit is contained in:
Sam Lantinga 2025-06-22 16:26:21 -07:00
parent 603118c340
commit 9ed83e71f6
1 changed files with 73 additions and 162 deletions

View File

@ -588,88 +588,51 @@ static void KMSDRM_DeinitDisplays(SDL_VideoDevice *_this)
} }
} }
static uint32_t KMSDRM_CrtcGetPropId(uint32_t drm_fd, static bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd, uint32_t output_id)
drmModeObjectPropertiesPtr props,
char const *name)
{ {
uint32_t i, prop_id = 0;
for (i = 0; !prop_id && i < props->count_props; ++i) {
drmModePropertyPtr drm_prop =
KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (!drm_prop) {
continue;
}
if (SDL_strcmp(drm_prop->name, name) == 0) {
prop_id = drm_prop->prop_id;
}
KMSDRM_drmModeFreeProperty(drm_prop);
}
return prop_id;
}
static bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id)
{
drmModeObjectPropertiesPtr drm_props;
drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
crtc_id,
DRM_MODE_OBJECT_CRTC);
if (!drm_props) {
return false;
}
*vrr_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
drm_props,
"VRR_ENABLED");
KMSDRM_drmModeFreeObjectProperties(drm_props);
return true;
}
static bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd,
uint32_t output_id,
char const *name)
{
uint32_t i;
bool found = false; bool found = false;
uint64_t prop_value = 0; uint64_t prop_value = 0;
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, output_id, DRM_MODE_OBJECT_CONNECTOR);
output_id, if (props) {
DRM_MODE_OBJECT_CONNECTOR); for (uint32_t i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (!props) { if (prop) {
return false; if (SDL_strcasecmp(prop->name, "VRR_CAPABLE") == 0) {
} prop_value = props->prop_values[i];
found = true;
for (i = 0; !found && i < props->count_props; ++i) { }
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]); KMSDRM_drmModeFreeProperty(prop);
}
if (!drm_prop) {
continue;
} }
KMSDRM_drmModeFreeObjectProperties(props);
if (SDL_strcasecmp(drm_prop->name, name) == 0) {
prop_value = props->prop_values[i];
found = true;
}
KMSDRM_drmModeFreeProperty(drm_prop);
} }
if (found) { if (found) {
return prop_value ? true : false; return prop_value ? true : false;
} }
return false; return false;
} }
static bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id)
{
bool found = false;
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
if (props) {
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (prop) {
if (SDL_strcmp(prop->name, "VRR_ENABLED") == 0) {
*vrr_prop_id = prop->prop_id;
found = true;
}
KMSDRM_drmModeFreeProperty(prop);
}
}
KMSDRM_drmModeFreeObjectProperties(props);
}
return found;
}
static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled) static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled)
{ {
uint32_t vrr_prop_id; uint32_t vrr_prop_id;
@ -677,119 +640,67 @@ static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled)
return; return;
} }
KMSDRM_drmModeObjectSetProperty(drm_fd, KMSDRM_drmModeObjectSetProperty(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC, vrr_prop_id, enabled);
crtc_id,
DRM_MODE_OBJECT_CRTC,
vrr_prop_id,
enabled);
} }
static bool KMSDRM_CrtcGetVrr(uint32_t drm_fd, uint32_t crtc_id) static bool KMSDRM_CrtcGetVrr(uint32_t drm_fd, uint32_t crtc_id)
{ {
uint32_t object_prop_id, vrr_prop_id; uint32_t vrr_prop_id = 0;
drmModeObjectPropertiesPtr props; bool found = false;
bool object_prop_value; uint64_t prop_value = 0;
int i;
if (!KMSDRM_VrrPropId(drm_fd, crtc_id, &vrr_prop_id)) { if (!KMSDRM_VrrPropId(drm_fd, crtc_id, &vrr_prop_id)) {
return false; return false;
} }
props = KMSDRM_drmModeObjectGetProperties(drm_fd, drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
crtc_id, if (props) {
DRM_MODE_OBJECT_CRTC); for (uint32_t i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (!props) { if (prop) {
return false; if (prop->prop_id == vrr_prop_id) {
prop_value = props->prop_values[i];
found = true;
}
KMSDRM_drmModeFreeProperty(prop);
}
}
KMSDRM_drmModeFreeObjectProperties(props);
} }
if (found) {
for (i = 0; i < props->count_props; ++i) { return prop_value ? true : false;
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
if (!drm_prop) {
continue;
}
object_prop_id = drm_prop->prop_id;
object_prop_value = props->prop_values[i] ? true : false;
KMSDRM_drmModeFreeProperty(drm_prop);
if (object_prop_id == vrr_prop_id) {
return object_prop_value;
}
} }
return false; return false;
} }
static bool KMSDRM_OrientationPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *orientation_prop_id)
{
drmModeObjectPropertiesPtr drm_props;
drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
crtc_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!drm_props) {
return false;
}
*orientation_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
drm_props,
"panel orientation");
KMSDRM_drmModeFreeObjectProperties(drm_props);
return true;
}
static int KMSDRM_CrtcGetOrientation(uint32_t drm_fd, uint32_t crtc_id) static int KMSDRM_CrtcGetOrientation(uint32_t drm_fd, uint32_t crtc_id)
{ {
uint32_t orientation_prop_id; bool found = false;
drmModeObjectPropertiesPtr props;
int i;
bool done = false;
int orientation = 0; int orientation = 0;
if (!KMSDRM_OrientationPropId(drm_fd, crtc_id, &orientation_prop_id)) { drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CONNECTOR);
return orientation; if (props) {
} for (uint32_t i = 0; !found && i < props->count_props; ++i) {
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
props = KMSDRM_drmModeObjectGetProperties(drm_fd, if (prop) {
crtc_id, if (SDL_strcasecmp(prop->name, "panel orientation") == 0 && (prop->flags & DRM_MODE_PROP_ENUM)) {
DRM_MODE_OBJECT_CONNECTOR); if (prop->count_enums) {
// "Normal" is the default of no rotation (0 degrees)
if (!props) { if (SDL_strcmp(prop->enums[0].name, "Left Side Up") == 0) {
return orientation; orientation = 90;
} } else if (SDL_strcmp(prop->enums[0].name, "Upside Down") == 0) {
orientation = 180;
for (i = 0; i < props->count_props && !done; ++i) { } else if (SDL_strcmp(prop->enums[0].name, "Right Side Up") == 0) {
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]); orientation = 270;
}
if (!drm_prop) { }
continue; found = true;
}
if (drm_prop->prop_id == orientation_prop_id && (drm_prop->flags & DRM_MODE_PROP_ENUM)) {
if (drm_prop->count_enums) {
// "Normal" is the default of no rotation (0 degrees)
if (SDL_strcmp(drm_prop->enums[0].name, "Left Side Up") == 0) {
orientation = 90;
} else if (SDL_strcmp(drm_prop->enums[0].name, "Upside Down") == 0) {
orientation = 180;
} else if (SDL_strcmp(drm_prop->enums[0].name, "Right Side Up") == 0) {
orientation = 270;
} }
KMSDRM_drmModeFreeProperty(prop);
} }
done = true;
} }
KMSDRM_drmModeFreeObjectProperties(props);
KMSDRM_drmModeFreeProperty(drm_prop);
} }
KMSDRM_drmModeFreeObjectProperties(props);
return orientation; return orientation;
} }
@ -964,7 +875,7 @@ static void KMSDRM_AddDisplay(SDL_VideoDevice *_this, drmModeConnector *connecto
// save previous vrr state // save previous vrr state
dispdata->saved_vrr = KMSDRM_CrtcGetVrr(viddata->drm_fd, crtc->crtc_id); dispdata->saved_vrr = KMSDRM_CrtcGetVrr(viddata->drm_fd, crtc->crtc_id);
// try to enable vrr // try to enable vrr
if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id, "VRR_CAPABLE")) { if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id)) {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR"); SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR");
KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, true); KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, true);
} }