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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
Jonas Ådahl 2020-09-23 17:07:37 +02:00 committed by Marge Bot
parent 28facbfa3a
commit f07d6d1f43
4 changed files with 123 additions and 20 deletions

View File

@ -32,9 +32,10 @@ typedef enum _MetaKmsCrtcProp
META_KMS_CRTC_N_PROPS META_KMS_CRTC_N_PROPS
} MetaKmsCrtcProp; } MetaKmsCrtcProp;
MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device, MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
drmModeCrtc *drm_crtc, drmModeCrtc *drm_crtc,
int idx); int idx,
GError **error);
void meta_kms_crtc_update_state (MetaKmsCrtc *crtc); void meta_kms_crtc_update_state (MetaKmsCrtc *crtc);

View File

@ -86,6 +86,12 @@ meta_kms_crtc_get_prop_name (MetaKmsCrtc *crtc,
return crtc->prop_table.props[prop].name; return crtc->prop_table.props[prop].name;
} }
gboolean
meta_kms_crtc_is_active (MetaKmsCrtc *crtc)
{
return crtc->current_state.is_active;
}
static void static void
read_gamma_state (MetaKmsCrtc *crtc, read_gamma_state (MetaKmsCrtc *crtc,
MetaKmsImplDevice *impl_device, MetaKmsImplDevice *impl_device,
@ -116,11 +122,33 @@ read_gamma_state (MetaKmsCrtc *crtc,
current_state->gamma.blue); current_state->gamma.blue);
} }
static void static int
meta_kms_crtc_read_state (MetaKmsCrtc *crtc, find_prop_idx (MetaKmsProp *prop,
MetaKmsImplDevice *impl_device, uint32_t *drm_props,
drmModeCrtc *drm_crtc) 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) { crtc->current_state.rect = (MetaRectangle) {
.x = drm_crtc->x, .x = drm_crtc->x,
.y = drm_crtc->y, .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.is_drm_mode_valid = drm_crtc->mode_valid;
crtc->current_state.drm_mode = drm_crtc->mode; 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); read_gamma_state (crtc, impl_device, drm_crtc);
} }
@ -138,20 +179,29 @@ void
meta_kms_crtc_update_state (MetaKmsCrtc *crtc) meta_kms_crtc_update_state (MetaKmsCrtc *crtc)
{ {
MetaKmsImplDevice *impl_device; MetaKmsImplDevice *impl_device;
int fd;
drmModeCrtc *drm_crtc; drmModeCrtc *drm_crtc;
drmModeObjectProperties *drm_props;
impl_device = meta_kms_device_get_impl_device (crtc->device); impl_device = meta_kms_device_get_impl_device (crtc->device);
drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device), fd = meta_kms_impl_device_get_fd (impl_device);
crtc->id);
if (!drm_crtc) 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.rect = (MetaRectangle) { };
crtc->current_state.is_drm_mode_valid = FALSE; crtc->current_state.is_drm_mode_valid = FALSE;
return; goto out;
} }
meta_kms_crtc_read_state (crtc, impl_device, drm_crtc); meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props);
drmModeFreeCrtc (drm_crtc);
out:
g_clear_pointer (&drm_props, drmModeFreeObjectProperties);
g_clear_pointer (&drm_crtc, drmModeFreeCrtc);
} }
static void static void
@ -188,6 +238,7 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
meta_kms_update_get_primary_plane_assignment (update, crtc); meta_kms_update_get_primary_plane_assignment (update, crtc);
drm_mode = meta_kms_mode_get_drm_mode (mode_set->mode); drm_mode = meta_kms_mode_get_drm_mode (mode_set->mode);
crtc->current_state.is_active = TRUE;
crtc->current_state.rect = crtc->current_state.rect =
meta_fixed_16_rectangle_to_rectangle (plane_assignment->src_rect); meta_fixed_16_rectangle_to_rectangle (plane_assignment->src_rect);
crtc->current_state.is_drm_mode_valid = TRUE; crtc->current_state.is_drm_mode_valid = TRUE;
@ -195,6 +246,7 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
} }
else else
{ {
crtc->current_state.is_active = FALSE;
crtc->current_state.rect = (MetaRectangle) { 0 }; crtc->current_state.rect = (MetaRectangle) { 0 };
crtc->current_state.is_drm_mode_valid = FALSE; crtc->current_state.is_drm_mode_valid = FALSE;
crtc->current_state.drm_mode = (drmModeModeInfo) { 0 }; 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 static void
init_proporties (MetaKmsCrtc *crtc, init_proporties (MetaKmsCrtc *crtc,
MetaKmsImplDevice *impl_device, MetaKmsImplDevice *impl_device,
@ -244,6 +308,7 @@ init_proporties (MetaKmsCrtc *crtc,
{ {
.name = "ACTIVE", .name = "ACTIVE",
.type = DRM_MODE_PROP_RANGE, .type = DRM_MODE_PROP_RANGE,
.parse = parse_active,
}, },
[META_KMS_CRTC_PROP_GAMMA_LUT] = [META_KMS_CRTC_PROP_GAMMA_LUT] =
{ {
@ -264,18 +329,31 @@ init_proporties (MetaKmsCrtc *crtc,
drm_props->count_props, drm_props->count_props,
crtc->prop_table.props, crtc->prop_table.props,
META_KMS_CRTC_N_PROPS, META_KMS_CRTC_N_PROPS,
NULL); crtc);
drmModeFreeObjectProperties (drm_props); drmModeFreeObjectProperties (drm_props);
} }
MetaKmsCrtc * MetaKmsCrtc *
meta_kms_crtc_new (MetaKmsImplDevice *impl_device, meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
drmModeCrtc *drm_crtc, drmModeCrtc *drm_crtc,
int idx) int idx,
GError **error)
{ {
int fd;
drmModeObjectProperties *drm_props;
MetaKmsCrtc *crtc; 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 = g_object_new (META_TYPE_KMS_CRTC, NULL);
crtc->device = meta_kms_impl_device_get_device (impl_device); crtc->device = meta_kms_impl_device_get_device (impl_device);
crtc->id = drm_crtc->crtc_id; crtc->id = drm_crtc->crtc_id;
@ -283,7 +361,9 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
init_proporties (crtc, impl_device, drm_crtc); 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; return crtc;
} }

View File

@ -29,6 +29,8 @@
typedef struct _MetaKmsCrtcState typedef struct _MetaKmsCrtcState
{ {
gboolean is_active;
MetaRectangle rect; MetaRectangle rect;
gboolean is_drm_mode_valid; gboolean is_drm_mode_valid;
drmModeModeInfo drm_mode; drmModeModeInfo drm_mode;
@ -55,4 +57,6 @@ uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc);
int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc); int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc);
#endif /* META_KMS_CRTC_H */ #endif /* META_KMS_CRTC_H */

View File

@ -304,13 +304,31 @@ init_crtcs (MetaKmsImplDevice *impl_device,
for (idx = 0; idx < drm_resources->count_crtcs; idx++) for (idx = 0; idx < drm_resources->count_crtcs; idx++)
{ {
uint32_t crtc_id;
drmModeCrtc *drm_crtc; drmModeCrtc *drm_crtc;
MetaKmsCrtc *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); 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_prepend (priv->crtcs, crtc);
} }
priv->crtcs = g_list_reverse (priv->crtcs); priv->crtcs = g_list_reverse (priv->crtcs);