Commit e3ea9b5b7c15da16940dc77b9082552c8ddd5570

antonino 2022-08-23T00:37:43

restore vrr state on exit

diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
index 2f6eb26..328ddf5 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -625,6 +625,40 @@ KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, SDL_bool enabled)
                              vrr_prop_id,
                              enabled);
 }
+
+static SDL_bool 
+KMSDRM_CrtcGetVrr(uint32_t drm_fd, uint32_t crtc_id)
+{
+    uint32_t vrr_prop_id;
+    drmModeObjectPropertiesPtr props;
+    int i;
+
+    if (!KMSDRM_VrrPropId(drm_fd, crtc_id, &vrr_prop_id)) 
+        return SDL_FALSE;
+
+
+    props = KMSDRM_drmModeObjectGetProperties(drm_fd,
+                                       crtc_id,
+                                       DRM_MODE_OBJECT_CRTC);
+
+    if(!props)
+        return SDL_FALSE;
+
+    for (i = 0; i < props->count_props; ++i) {
+        drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
+
+        if (!drm_prop)
+            continue;
+
+        if(drm_prop->prop_id == vrr_prop_id) {
+            return props->prop_values[i] ? SDL_TRUE: SDL_FALSE;
+        }
+
+        KMSDRM_drmModeFreeProperty(drm_prop);
+    }
+    return SDL_FALSE;
+}
+
 /* Gets a DRM connector, builds an SDL_Display with it, and adds it to the
    list of SDL Displays in _this->displays[]  */
 static void
@@ -766,6 +800,14 @@ KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
     dispdata->connector = connector;
     dispdata->crtc = crtc;
 
+    /* save previous vrr state */
+    dispdata->saved_vrr = KMSDRM_CrtcGetVrr(viddata->drm_fd, crtc->crtc_id);
+    /* try to enable vrr */
+    if(KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id, "VRR_CAPABLE")) {
+        SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR");
+        KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, SDL_TRUE);
+    }
+
     /*****************************************/
     /* Part 2: setup the SDL_Display itself. */
     /*****************************************/
@@ -792,12 +834,6 @@ KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
     /* Add the display to the list of SDL displays. */
     SDL_AddVideoDisplay(&display, SDL_FALSE);
 
-    /* try to enable vrr */
-    if(KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id, "VRR_CAPABLE")) {
-        SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR");
-        KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, SDL_TRUE);
-    }
-
 cleanup:
     if (encoder)
         KMSDRM_drmModeFreeEncoder(encoder);
@@ -1275,6 +1311,9 @@ KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
         return;
     }
 
+    /* restore vrr state */
+    KMSDRM_CrtcSetVrr(windata->viddata->drm_fd, dispdata->crtc->crtc_id, dispdata->saved_vrr);
+
     viddata = windata->viddata;
 
     if ( !is_vulkan && viddata->gbm_init) {
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h
index ebc863f..b3e719c 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.h
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h
@@ -71,6 +71,7 @@ typedef struct SDL_DisplayData
     drmModeModeInfo fullscreen_mode;
 
     drmModeCrtc *saved_crtc;    /* CRTC to restore on quit */
+    SDL_bool saved_vrr;
 
     /* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct,
        because setting/unsetting up these is done on window creation/destruction,