From 12ef1a5e4b260cd62cb37e2b5314a312842b9caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 11 May 2016 16:26:34 +0800 Subject: [PATCH] backends/native: Let the monitor manager manage KMS modes Let MetaMonitorManagerKms manage KMS modes. This lets us pass less state to MetaRendererNative. Instead let MetaMonitorManager tell the monitor manager when it should set the mode and with what framebuffer. https://bugzilla.gnome.org/show_bug.cgi?id=768976 --- .../native/meta-monitor-manager-kms.c | 90 ++++++++++++++----- .../native/meta-monitor-manager-kms.h | 3 + src/backends/native/meta-renderer-native.c | 26 ++---- src/backends/native/meta-renderer-native.h | 5 +- 4 files changed, 82 insertions(+), 42 deletions(-) diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index 51aed365c..bb3d1c380 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -1008,7 +1008,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, static void crtc_free (CoglKmsCrtc *crtc) { - g_free (crtc->connectors); g_slice_free (CoglKmsCrtc, crtc); } @@ -1087,12 +1086,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, if (crtc_info->mode == NULL) { cogl_crtc->id = crtc->crtc_id; - cogl_crtc->x = 0; - cogl_crtc->y = 0; - cogl_crtc->count = 0; - memset (&cogl_crtc->mode, 0, sizeof (drmModeModeInfo)); - cogl_crtc->connectors = NULL; - cogl_crtc->count = 0; crtc->rect.x = 0; crtc->rect.y = 0; @@ -1109,11 +1102,11 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, mode = crtc_info->mode; + n_connectors = crtc_info->outputs->len; + connectors = g_new (uint32_t, n_connectors); + cogl_crtc->id = crtc->crtc_id; - cogl_crtc->x = crtc_info->x; - cogl_crtc->y = crtc_info->y; - cogl_crtc->count = n_connectors = crtc_info->outputs->len; - cogl_crtc->connectors = connectors = g_new (uint32_t, n_connectors); + cogl_crtc->connected = n_connectors > 0; for (j = 0; j < n_connectors; j++) { @@ -1125,9 +1118,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, output->crtc = crtc; } - memcpy (&cogl_crtc->mode, crtc_info->mode->driver_private, - sizeof (drmModeModeInfo)); - if (meta_monitor_transform_is_rotated (crtc_info->transform)) { width = mode->height; @@ -1177,12 +1167,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager, g_ptr_array_add (cogl_crtcs, cogl_crtc); cogl_crtc->id = crtc->crtc_id; - cogl_crtc->x = 0; - cogl_crtc->y = 0; - cogl_crtc->count = 0; - memset (&cogl_crtc->mode, 0, sizeof (drmModeModeInfo)); - cogl_crtc->connectors = NULL; - cogl_crtc->count = 0; crtc->rect.x = 0; crtc->rect.y = 0; @@ -1314,6 +1298,72 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms) manager_kms->desktop_settings = g_settings_new ("org.gnome.desktop.interface"); } +static void +get_crtc_connectors (MetaMonitorManager *manager, + MetaCRTC *crtc, + uint32_t **connectors, + unsigned int *n_connectors) +{ + GArray *connectors_array = NULL; + unsigned int i; + + for (i = 0; i < manager->n_outputs; i++) + { + MetaOutput *output = &manager->outputs[i]; + + if (output->crtc == crtc) + { + if (!connectors_array) + connectors_array = g_array_new (FALSE, FALSE, sizeof (uint32_t)); + g_array_append_val (connectors_array, output->winsys_id); + } + } + + if (connectors_array) + { + *connectors = (uint32_t *) connectors_array->data; + *n_connectors = connectors_array->len; + } + else + { + *connectors = NULL; + *n_connectors = 0; + } +} + +void +meta_monitor_manager_kms_apply_crtc_modes (MetaMonitorManagerKms *manager_kms, + uint32_t fb_id) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); + unsigned int i; + + for (i = 0; i < manager->n_crtcs; i++) + { + MetaCRTC *crtc = &manager->crtcs[i]; + uint32_t *connectors; + unsigned int n_connectors; + drmModeModeInfo *mode; + + get_crtc_connectors (manager, crtc, &connectors, &n_connectors); + + if (connectors) + mode = crtc->current_mode->driver_private; + else + mode = NULL; + + if (drmModeSetCrtc (manager_kms->fd, + crtc->crtc_id, + fb_id, + crtc->rect.x, crtc->rect.y, + connectors, n_connectors, + mode) != 0) + g_warning ("Failed to set CRTC mode %s: %m", crtc->current_mode->name); + + g_free (connectors); + } +} + static void meta_monitor_manager_kms_dispose (GObject *object) { diff --git a/src/backends/native/meta-monitor-manager-kms.h b/src/backends/native/meta-monitor-manager-kms.h index 294fb4f44..a9c0c9543 100644 --- a/src/backends/native/meta-monitor-manager-kms.h +++ b/src/backends/native/meta-monitor-manager-kms.h @@ -37,4 +37,7 @@ typedef struct _MetaMonitorManagerKms MetaMonitorManagerKms; GType meta_monitor_manager_kms_get_type (void); +void meta_monitor_manager_kms_apply_crtc_modes (MetaMonitorManagerKms *manager_kms, + uint32_t fb_id); + #endif /* META_MONITOR_MANAGER_KMS_H */ diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 58cc14885..4404a42fb 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -47,6 +47,7 @@ #include #include "backends/meta-backend-private.h" +#include "backends/native/meta-monitor-manager-kms.h" #include "backends/native/meta-renderer-native.h" #include "cogl/cogl.h" @@ -332,22 +333,13 @@ fail: static void setup_crtc_modes (CoglDisplay *display, int fb_id) { - CoglRendererEGL *egl_renderer = display->renderer->winsys; - MetaRendererNative *renderer_native = egl_renderer->platform; - GList *l; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); - for (l = renderer_native->crtcs; l; l = l->next) - { - CoglKmsCrtc *crtc = l->data; - - int ret = drmModeSetCrtc (renderer_native->kms_fd, - crtc->id, - fb_id, crtc->x, crtc->y, - crtc->connectors, crtc->count, - crtc->count ? &crtc->mode : NULL); - if (ret) - g_warning ("Failed to set crtc mode %s: %m", crtc->mode.name); - } + meta_monitor_manager_kms_apply_crtc_modes (monitor_manager_kms, fb_id); } static void @@ -363,7 +355,7 @@ flip_all_crtcs (CoglDisplay *display, CoglFlipKMS *flip, int fb_id) CoglKmsCrtc *crtc = l->data; int ret = 0; - if (crtc->count == 0 || crtc->ignore) + if (!crtc->connected || crtc->ignore) continue; needs_flip = TRUE; @@ -392,7 +384,6 @@ flip_all_crtcs (CoglDisplay *display, CoglFlipKMS *flip, int fb_id) static void crtc_free (CoglKmsCrtc *crtc) { - g_free (crtc->connectors); g_slice_free (CoglKmsCrtc, crtc); } @@ -404,7 +395,6 @@ crtc_copy (CoglKmsCrtc *from) new = g_slice_new (CoglKmsCrtc); *new = *from; - new->connectors = g_memdup (from->connectors, from->count * sizeof(uint32_t)); return new; } diff --git a/src/backends/native/meta-renderer-native.h b/src/backends/native/meta-renderer-native.h index 37a5acd5c..9e01301f9 100644 --- a/src/backends/native/meta-renderer-native.h +++ b/src/backends/native/meta-renderer-native.h @@ -32,11 +32,8 @@ typedef struct { uint32_t id; - uint32_t x, y; - drmModeModeInfo mode; - uint32_t *connectors; - uint32_t count; + gboolean connected; CoglBool ignore; } CoglKmsCrtc;