You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
X11: Fix memory leak in screen_get_refresh_rate
This commit is contained in:
@@ -1800,59 +1800,57 @@ Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const {
|
|||||||
float DisplayServerX11::screen_get_refresh_rate(int p_screen) const {
|
float DisplayServerX11::screen_get_refresh_rate(int p_screen) const {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V_MSG(!xrandr_ext_ok || !xrr_get_monitors, SCREEN_REFRESH_RATE_FALLBACK, "XRandR extension is not available.");
|
||||||
|
|
||||||
p_screen = _get_screen_index(p_screen);
|
p_screen = _get_screen_index(p_screen);
|
||||||
int screen_count = get_screen_count();
|
int screen_count = get_screen_count();
|
||||||
ERR_FAIL_INDEX_V(p_screen, screen_count, SCREEN_REFRESH_RATE_FALLBACK);
|
ERR_FAIL_INDEX_V(p_screen, screen_count, SCREEN_REFRESH_RATE_FALLBACK);
|
||||||
|
|
||||||
//Use xrandr to get screen refresh rate.
|
int target_x;
|
||||||
if (xrandr_ext_ok) {
|
int target_y;
|
||||||
XRRScreenResources *screen_info = XRRGetScreenResourcesCurrent(x11_display, windows[MAIN_WINDOW_ID].x11_window);
|
{
|
||||||
if (screen_info) {
|
int count = 0;
|
||||||
RRMode current_mode = 0;
|
xrr_monitor_info *monitors = xrr_get_monitors(x11_display, windows[MAIN_WINDOW_ID].x11_window, true, &count);
|
||||||
xrr_monitor_info *monitors = nullptr;
|
ERR_FAIL_NULL_V(monitors, SCREEN_REFRESH_RATE_FALLBACK);
|
||||||
|
if (count <= p_screen) {
|
||||||
if (xrr_get_monitors) {
|
xrr_free_monitors(monitors);
|
||||||
int count = 0;
|
ERR_FAIL_V_MSG(SCREEN_REFRESH_RATE_FALLBACK, vformat("Invalid screen index: %d (count: %d).", p_screen, count));
|
||||||
monitors = xrr_get_monitors(x11_display, windows[MAIN_WINDOW_ID].x11_window, true, &count);
|
|
||||||
ERR_FAIL_INDEX_V(p_screen, count, SCREEN_REFRESH_RATE_FALLBACK);
|
|
||||||
} else {
|
|
||||||
ERR_PRINT("An error occurred while trying to get the screen refresh rate.");
|
|
||||||
return SCREEN_REFRESH_RATE_FALLBACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found_active_mode = false;
|
|
||||||
for (int crtc = 0; crtc < screen_info->ncrtc; crtc++) { // Loop through outputs to find which one is currently outputting.
|
|
||||||
XRRCrtcInfo *monitor_info = XRRGetCrtcInfo(x11_display, screen_info, screen_info->crtcs[crtc]);
|
|
||||||
if (monitor_info->x != monitors[p_screen].x || monitor_info->y != monitors[p_screen].y) { // If X and Y aren't the same as the monitor we're looking for, this isn't the right monitor. Continue.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (monitor_info->mode != None) {
|
|
||||||
current_mode = monitor_info->mode;
|
|
||||||
found_active_mode = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_active_mode) {
|
|
||||||
for (int mode = 0; mode < screen_info->nmode; mode++) {
|
|
||||||
XRRModeInfo m_info = screen_info->modes[mode];
|
|
||||||
if (m_info.id == current_mode) {
|
|
||||||
// Snap to nearest 0.01 to stay consistent with other platforms.
|
|
||||||
return Math::snapped((float)m_info.dotClock / ((float)m_info.hTotal * (float)m_info.vTotal), 0.01);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_PRINT("An error occurred while trying to get the screen refresh rate."); // We should have returned the refresh rate by now. An error must have occurred.
|
|
||||||
return SCREEN_REFRESH_RATE_FALLBACK;
|
|
||||||
} else {
|
|
||||||
ERR_PRINT("An error occurred while trying to get the screen refresh rate.");
|
|
||||||
return SCREEN_REFRESH_RATE_FALLBACK;
|
|
||||||
}
|
}
|
||||||
|
target_x = monitors[p_screen].x;
|
||||||
|
target_y = monitors[p_screen].y;
|
||||||
|
xrr_free_monitors(monitors);
|
||||||
}
|
}
|
||||||
ERR_PRINT("An error occurred while trying to get the screen refresh rate.");
|
|
||||||
return SCREEN_REFRESH_RATE_FALLBACK;
|
XRRScreenResources *screen_res = XRRGetScreenResourcesCurrent(x11_display, windows[MAIN_WINDOW_ID].x11_window);
|
||||||
|
ERR_FAIL_NULL_V(screen_res, SCREEN_REFRESH_RATE_FALLBACK);
|
||||||
|
|
||||||
|
XRRModeInfo *mode_info = nullptr;
|
||||||
|
for (int crtc = 0; crtc < screen_res->ncrtc; crtc++) { // Loop through outputs to find which one is currently outputting.
|
||||||
|
XRRCrtcInfo *monitor_info = XRRGetCrtcInfo(x11_display, screen_res, screen_res->crtcs[crtc]);
|
||||||
|
if (monitor_info->x != target_x || monitor_info->y != target_y || monitor_info->mode == None) {
|
||||||
|
XRRFreeCrtcInfo(monitor_info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int mode = 0; mode < screen_res->nmode; mode++) {
|
||||||
|
if (screen_res->modes[mode].id == monitor_info->mode) {
|
||||||
|
mode_info = &screen_res->modes[mode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XRRFreeCrtcInfo(monitor_info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float result;
|
||||||
|
if (mode_info) {
|
||||||
|
// Snap to nearest 0.01 to stay consistent with other platforms.
|
||||||
|
result = Math::snapped((float)mode_info->dotClock / ((float)mode_info->hTotal * (float)mode_info->vTotal), 0.01);
|
||||||
|
} else {
|
||||||
|
ERR_PRINT("An error occurred while trying to get the screen refresh rate.");
|
||||||
|
result = SCREEN_REFRESH_RATE_FALLBACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeScreenResources(screen_res);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DBUS_ENABLED
|
#ifdef DBUS_ENABLED
|
||||||
|
|||||||
Reference in New Issue
Block a user