From f07d6d1f43a040b611fffe3acec308c5402ada65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 23 Sep 2020 17:07:37 +0200 Subject: [PATCH] kms/crtc: Keep track of ACTIVE property value When atomic modesetting isn't enabled, this property may not exist, so emulate by assuming ACTIVE is set to true if a mode is set. Part-of: --- src/backends/native/meta-kms-crtc-private.h | 7 +- src/backends/native/meta-kms-crtc.c | 110 +++++++++++++++++--- src/backends/native/meta-kms-crtc.h | 4 + src/backends/native/meta-kms-impl-device.c | 22 +++- 4 files changed, 123 insertions(+), 20 deletions(-) diff --git a/src/backends/native/meta-kms-crtc-private.h b/src/backends/native/meta-kms-crtc-private.h index 9e2937a3b..60c5fd309 100644 --- a/src/backends/native/meta-kms-crtc-private.h +++ b/src/backends/native/meta-kms-crtc-private.h @@ -32,9 +32,10 @@ typedef enum _MetaKmsCrtcProp META_KMS_CRTC_N_PROPS } MetaKmsCrtcProp; -MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device, - drmModeCrtc *drm_crtc, - int idx); +MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc, + int idx, + GError **error); void meta_kms_crtc_update_state (MetaKmsCrtc *crtc); diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c index 38fb06fab..4e4bd4319 100644 --- a/src/backends/native/meta-kms-crtc.c +++ b/src/backends/native/meta-kms-crtc.c @@ -86,6 +86,12 @@ meta_kms_crtc_get_prop_name (MetaKmsCrtc *crtc, return crtc->prop_table.props[prop].name; } +gboolean +meta_kms_crtc_is_active (MetaKmsCrtc *crtc) +{ + return crtc->current_state.is_active; +} + static void read_gamma_state (MetaKmsCrtc *crtc, MetaKmsImplDevice *impl_device, @@ -116,11 +122,33 @@ read_gamma_state (MetaKmsCrtc *crtc, current_state->gamma.blue); } -static void -meta_kms_crtc_read_state (MetaKmsCrtc *crtc, - MetaKmsImplDevice *impl_device, - drmModeCrtc *drm_crtc) +static int +find_prop_idx (MetaKmsProp *prop, + uint32_t *drm_props, + int n_drm_props) { + int i; + + g_return_val_if_fail (prop->prop_id > 0, -1); + + for (i = 0; i < n_drm_props; i++) + { + if (drm_props[i] == prop->prop_id) + return i; + } + + return -1; +} + +static void +meta_kms_crtc_read_state (MetaKmsCrtc *crtc, + MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc, + drmModeObjectProperties *drm_props) +{ + MetaKmsProp *active_prop; + int active_idx; + crtc->current_state.rect = (MetaRectangle) { .x = drm_crtc->x, .y = drm_crtc->y, @@ -131,6 +159,19 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc, crtc->current_state.is_drm_mode_valid = drm_crtc->mode_valid; crtc->current_state.drm_mode = drm_crtc->mode; + active_prop = &crtc->prop_table.props[META_KMS_CRTC_PROP_ACTIVE]; + if (active_prop->prop_id) + { + active_idx = find_prop_idx (active_prop, + drm_props->props, + drm_props->count_props); + crtc->current_state.is_active = !!drm_props->prop_values[active_idx]; + } + else + { + crtc->current_state.is_active = drm_crtc->mode_valid; + } + read_gamma_state (crtc, impl_device, drm_crtc); } @@ -138,20 +179,29 @@ void meta_kms_crtc_update_state (MetaKmsCrtc *crtc) { MetaKmsImplDevice *impl_device; + int fd; drmModeCrtc *drm_crtc; + drmModeObjectProperties *drm_props; impl_device = meta_kms_device_get_impl_device (crtc->device); - drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device), - crtc->id); - if (!drm_crtc) + fd = meta_kms_impl_device_get_fd (impl_device); + + drm_crtc = drmModeGetCrtc (fd, crtc->id); + drm_props = drmModeObjectGetProperties (fd, crtc->id, DRM_MODE_OBJECT_CRTC); + + if (!drm_crtc || !drm_props) { + crtc->current_state.is_active = FALSE; crtc->current_state.rect = (MetaRectangle) { }; crtc->current_state.is_drm_mode_valid = FALSE; - return; + goto out; } - meta_kms_crtc_read_state (crtc, impl_device, drm_crtc); - drmModeFreeCrtc (drm_crtc); + meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props); + +out: + g_clear_pointer (&drm_props, drmModeFreeObjectProperties); + g_clear_pointer (&drm_crtc, drmModeFreeCrtc); } static void @@ -188,6 +238,7 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc, meta_kms_update_get_primary_plane_assignment (update, crtc); drm_mode = meta_kms_mode_get_drm_mode (mode_set->mode); + crtc->current_state.is_active = TRUE; crtc->current_state.rect = meta_fixed_16_rectangle_to_rectangle (plane_assignment->src_rect); crtc->current_state.is_drm_mode_valid = TRUE; @@ -195,6 +246,7 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc, } else { + crtc->current_state.is_active = FALSE; crtc->current_state.rect = (MetaRectangle) { 0 }; crtc->current_state.is_drm_mode_valid = FALSE; crtc->current_state.drm_mode = (drmModeModeInfo) { 0 }; @@ -224,6 +276,18 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc, } } +static void +parse_active (MetaKmsImplDevice *impl_device, + MetaKmsProp *prop, + drmModePropertyPtr drm_prop, + uint64_t drm_prop_value, + gpointer user_data) +{ + MetaKmsCrtc *crtc = user_data; + + crtc->current_state.is_active = !!drm_prop_value; +} + static void init_proporties (MetaKmsCrtc *crtc, MetaKmsImplDevice *impl_device, @@ -244,6 +308,7 @@ init_proporties (MetaKmsCrtc *crtc, { .name = "ACTIVE", .type = DRM_MODE_PROP_RANGE, + .parse = parse_active, }, [META_KMS_CRTC_PROP_GAMMA_LUT] = { @@ -264,18 +329,31 @@ init_proporties (MetaKmsCrtc *crtc, drm_props->count_props, crtc->prop_table.props, META_KMS_CRTC_N_PROPS, - NULL); + crtc); drmModeFreeObjectProperties (drm_props); } MetaKmsCrtc * -meta_kms_crtc_new (MetaKmsImplDevice *impl_device, - drmModeCrtc *drm_crtc, - int idx) +meta_kms_crtc_new (MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc, + int idx, + GError **error) { + int fd; + drmModeObjectProperties *drm_props; MetaKmsCrtc *crtc; + fd = meta_kms_impl_device_get_fd (impl_device); + drm_props = drmModeObjectGetProperties (fd, drm_crtc->crtc_id, + DRM_MODE_OBJECT_CRTC); + if (!drm_props) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), + "drmModeObjectGetProperties: %s", g_strerror (errno)); + return NULL; + } + crtc = g_object_new (META_TYPE_KMS_CRTC, NULL); crtc->device = meta_kms_impl_device_get_device (impl_device); crtc->id = drm_crtc->crtc_id; @@ -283,7 +361,9 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device, init_proporties (crtc, impl_device, drm_crtc); - meta_kms_crtc_read_state (crtc, impl_device, drm_crtc); + meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props); + + drmModeFreeObjectProperties (drm_props); return crtc; } diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h index 824b5eec4..1d9b79156 100644 --- a/src/backends/native/meta-kms-crtc.h +++ b/src/backends/native/meta-kms-crtc.h @@ -29,6 +29,8 @@ typedef struct _MetaKmsCrtcState { + gboolean is_active; + MetaRectangle rect; gboolean is_drm_mode_valid; drmModeModeInfo drm_mode; @@ -55,4 +57,6 @@ uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc); int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc); +gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc); + #endif /* META_KMS_CRTC_H */ diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index 321fc0167..1385e0676 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -304,13 +304,31 @@ init_crtcs (MetaKmsImplDevice *impl_device, for (idx = 0; idx < drm_resources->count_crtcs; idx++) { + uint32_t crtc_id; drmModeCrtc *drm_crtc; MetaKmsCrtc *crtc; + g_autoptr (GError) error = NULL; + + crtc_id = drm_resources->crtcs[idx]; + drm_crtc = drmModeGetCrtc (priv->fd, crtc_id); + if (!drm_crtc) + { + g_warning ("Failed to get CRTC %u info on '%s': %s", + crtc_id, priv->path, error->message); + continue; + } + + crtc = meta_kms_crtc_new (impl_device, drm_crtc, idx, &error); - drm_crtc = drmModeGetCrtc (priv->fd, drm_resources->crtcs[idx]); - crtc = meta_kms_crtc_new (impl_device, drm_crtc, idx); drmModeFreeCrtc (drm_crtc); + if (!crtc) + { + g_warning ("Failed to create CRTC for %u on '%s': %s", + crtc_id, priv->path, error->message); + continue; + } + priv->crtcs = g_list_prepend (priv->crtcs, crtc); } priv->crtcs = g_list_reverse (priv->crtcs);