[mutter] crtc/kms: Outsource CRTC state fetching to MetaKmsCrtc



commit 596376c40841e6b9702aab17df5dc3822fb29001
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Mar 8 19:19:18 2019 +0100

    crtc/kms: Outsource CRTC state fetching to MetaKmsCrtc
    
    Move reading state into a struct for MetaCrtcKms to use instead of
    querying KMS itself. The state is fetched in the impl context, but
    consists of only simple data types, so is made accessible publicly. As
    of this, MetaCrtcKms construction does not involve any manual KMS
    interaction outside of the MetaKms abstraction.
    
    https://gitlab.gnome.org/GNOME/mutter/issues/548
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/525

 src/backends/native/meta-crtc-kms.c            | 18 ++++-----
 src/backends/native/meta-crtc-kms.h            |  5 +--
 src/backends/native/meta-gpu-kms.c             | 13 ++-----
 src/backends/native/meta-kms-crtc-private.h    |  2 +
 src/backends/native/meta-kms-crtc.c            | 39 +++++++++++++++++++
 src/backends/native/meta-kms-crtc.h            | 14 +++++++
 src/backends/native/meta-kms-device-private.h  | 27 +++++++++++++
 src/backends/native/meta-kms-device.c          |  7 ++++
 src/backends/native/meta-kms-impl-device.c     |  9 +++++
 src/backends/native/meta-kms-impl-device.h     |  2 +
 src/backends/native/meta-kms.c                 | 54 ++++++++++++++++++++++++++
 src/backends/native/meta-monitor-manager-kms.c |  3 +-
 src/meson.build                                |  1 +
 13 files changed, 170 insertions(+), 24 deletions(-)
---
diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c
index 1877903c4..8ac7fb969 100644
--- a/src/backends/native/meta-crtc-kms.c
+++ b/src/backends/native/meta-crtc-kms.c
@@ -494,27 +494,25 @@ meta_crtc_destroy_notify (MetaCrtc *crtc)
 }
 
 MetaCrtc *
-meta_create_kms_crtc (MetaGpuKms   *gpu_kms,
-                      MetaKmsCrtc  *kms_crtc,
-                      drmModeCrtc  *drm_crtc)
+meta_create_kms_crtc (MetaGpuKms  *gpu_kms,
+                      MetaKmsCrtc *kms_crtc)
 {
   MetaGpu *gpu = META_GPU (gpu_kms);
   MetaCrtc *crtc;
   MetaCrtcKms *crtc_kms;
+  const MetaKmsCrtcState *crtc_state;
 
-  crtc = g_object_new (META_TYPE_CRTC, NULL);
+  crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
 
+  crtc = g_object_new (META_TYPE_CRTC, NULL);
   crtc->gpu = gpu;
   crtc->crtc_id = meta_kms_crtc_get_id (kms_crtc);
-  crtc->rect.x = drm_crtc->x;
-  crtc->rect.y = drm_crtc->y;
-  crtc->rect.width = drm_crtc->width;
-  crtc->rect.height = drm_crtc->height;
+  crtc->rect = crtc_state->rect;
   crtc->is_dirty = FALSE;
   crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
   crtc->all_transforms = ALL_TRANSFORMS_MASK;
 
-  if (drm_crtc->mode_valid)
+  if (crtc_state->is_drm_mode_valid)
     {
       GList *l;
 
@@ -522,7 +520,7 @@ meta_create_kms_crtc (MetaGpuKms   *gpu_kms,
         {
           MetaCrtcMode *mode = l->data;
 
-          if (meta_drm_mode_equal (&drm_crtc->mode, mode->driver_private))
+          if (meta_drm_mode_equal (&crtc_state->drm_mode, mode->driver_private))
             {
               crtc->current_mode = mode;
               break;
diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h
index 8e09614c9..3be1d5db8 100644
--- a/src/backends/native/meta-crtc-kms.h
+++ b/src/backends/native/meta-crtc-kms.h
@@ -55,8 +55,7 @@ gboolean
 meta_crtc_kms_supports_format (MetaCrtc *crtc,
                                uint32_t  drm_format);
 
-MetaCrtc * meta_create_kms_crtc (MetaGpuKms   *gpu_kms,
-                                 MetaKmsCrtc  *kms_crtc,
-                                 drmModeCrtc  *drm_crtc);
+MetaCrtc * meta_create_kms_crtc (MetaGpuKms  *gpu_kms,
+                                 MetaKmsCrtc *kms_crtc);
 
 #endif /* META_CRTC_KMS_H */
diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
index 7b186de80..09b1c87d7 100644
--- a/src/backends/native/meta-gpu-kms.c
+++ b/src/backends/native/meta-gpu-kms.c
@@ -703,8 +703,7 @@ init_modes (MetaGpuKms *gpu_kms,
 }
 
 static void
-init_crtcs (MetaGpuKms       *gpu_kms,
-            MetaKmsResources *resources)
+init_crtcs (MetaGpuKms *gpu_kms)
 {
   MetaGpu *gpu = META_GPU (gpu_kms);
   MetaKmsDevice *kms_device = gpu_kms->kms_device;
@@ -716,15 +715,9 @@ init_crtcs (MetaGpuKms       *gpu_kms,
   for (l = meta_kms_device_get_crtcs (kms_device); l; l = l->next)
     {
       MetaKmsCrtc *kms_crtc = l->data;
-      int crtc_idx;
-      drmModeCrtc *drm_crtc;
       MetaCrtc *crtc;
 
-      crtc_idx = meta_kms_crtc_get_idx (kms_crtc);
-      drm_crtc = drmModeGetCrtc (gpu_kms->fd,
-                                 resources->resources->crtcs[crtc_idx]);
-      crtc = meta_create_kms_crtc (gpu_kms, kms_crtc, drm_crtc);
-      drmModeFreeCrtc (drm_crtc);
+      crtc = meta_create_kms_crtc (gpu_kms, kms_crtc);
 
       crtcs = g_list_append (crtcs, crtc);
     }
@@ -868,7 +861,7 @@ meta_gpu_kms_read_current (MetaGpu  *gpu,
 
   init_connectors (gpu_kms, resources.resources);
   init_modes (gpu_kms, resources.resources);
-  init_crtcs (gpu_kms, &resources);
+  init_crtcs (gpu_kms);
   init_outputs (gpu_kms, &resources);
   init_frame_clock (gpu_kms);
 
diff --git a/src/backends/native/meta-kms-crtc-private.h b/src/backends/native/meta-kms-crtc-private.h
index ad4492bf1..41db399e6 100644
--- a/src/backends/native/meta-kms-crtc-private.h
+++ b/src/backends/native/meta-kms-crtc-private.h
@@ -28,4 +28,6 @@ MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
                                  drmModeCrtc       *drm_crtc,
                                  int                idx);
 
+void meta_kms_crtc_update_state (MetaKmsCrtc *crtc);
+
 #endif /* META_KMS_CRTC_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 73ae8ab9c..910a5a84a 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -22,6 +22,7 @@
 #include "backends/native/meta-kms-crtc.h"
 #include "backends/native/meta-kms-crtc-private.h"
 
+#include "backends/native/meta-kms-device-private.h"
 #include "backends/native/meta-kms-impl-device.h"
 
 struct _MetaKmsCrtc
@@ -32,6 +33,8 @@ struct _MetaKmsCrtc
 
   uint32_t id;
   int idx;
+
+  MetaKmsCrtcState current_state;
 };
 
 G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT)
@@ -42,6 +45,12 @@ meta_kms_crtc_get_device (MetaKmsCrtc *crtc)
   return crtc->device;
 }
 
+const MetaKmsCrtcState *
+meta_kms_crtc_get_current_state (MetaKmsCrtc *crtc)
+{
+  return &crtc->current_state;
+}
+
 uint32_t
 meta_kms_crtc_get_id (MetaKmsCrtc *crtc)
 {
@@ -54,6 +63,36 @@ meta_kms_crtc_get_idx (MetaKmsCrtc *crtc)
   return crtc->idx;
 }
 
+static void
+meta_kms_crtc_read_state (MetaKmsCrtc       *crtc,
+                          MetaKmsImplDevice *impl_device,
+                          drmModeCrtc       *drm_crtc)
+{
+  crtc->current_state = (MetaKmsCrtcState) {
+    .rect = {
+      .x = drm_crtc->x,
+      .y = drm_crtc->y,
+      .width = drm_crtc->width,
+      .height = drm_crtc->height,
+    },
+    .is_drm_mode_valid = drm_crtc->mode_valid,
+    .drm_mode = drm_crtc->mode,
+  };
+}
+
+void
+meta_kms_crtc_update_state (MetaKmsCrtc *crtc)
+{
+  MetaKmsImplDevice *impl_device;
+  drmModeCrtc *drm_crtc;
+
+  impl_device = meta_kms_device_get_impl_device (crtc->device);
+  drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device),
+                             crtc->id);
+  meta_kms_crtc_read_state (crtc, impl_device, drm_crtc);
+  drmModeFreeCrtc (drm_crtc);
+}
+
 MetaKmsCrtc *
 meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
                    drmModeCrtc       *drm_crtc,
diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h
index 12eda39f2..9d0ceadd9 100644
--- a/src/backends/native/meta-kms-crtc.h
+++ b/src/backends/native/meta-kms-crtc.h
@@ -25,6 +25,18 @@
 #include <xf86drmMode.h>
 
 #include "backends/native/meta-kms-types.h"
+#include "meta/boxes.h"
+
+typedef struct _MetaKmsCrtcState
+{
+  MetaRectangle rect;
+  gboolean is_drm_mode_valid;
+  drmModeModeInfo drm_mode;
+
+  uint32_t common_possible_crtcs;
+  uint32_t common_possible_clones;
+  uint32_t encoder_device_idxs;
+} MetaKmsCrtcState;
 
 #define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ())
 G_DECLARE_FINAL_TYPE (MetaKmsCrtc, meta_kms_crtc,
@@ -33,6 +45,8 @@ G_DECLARE_FINAL_TYPE (MetaKmsCrtc, meta_kms_crtc,
 
 MetaKmsDevice * meta_kms_crtc_get_device (MetaKmsCrtc *crtc);
 
+const MetaKmsCrtcState * meta_kms_crtc_get_current_state (MetaKmsCrtc *crtc);
+
 uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc);
 
 int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
diff --git a/src/backends/native/meta-kms-device-private.h b/src/backends/native/meta-kms-device-private.h
new file mode 100644
index 000000000..0d4f4e341
--- /dev/null
+++ b/src/backends/native/meta-kms-device-private.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_KMS_DEVICE_PRIVATE_H
+#define META_KMS_DEVICE_PRIVATE_H
+
+#include "backends/native/meta-kms-types.h"
+
+MetaKmsImplDevice * meta_kms_device_get_impl_device (MetaKmsDevice *device);
+
+#endif /* META_KMS_DEVICE_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c
index c168bad80..6f5caf02d 100644
--- a/src/backends/native/meta-kms-device.c
+++ b/src/backends/native/meta-kms-device.c
@@ -19,6 +19,7 @@
 
 #include "config.h"
 
+#include "backends/native/meta-kms-device-private.h"
 #include "backends/native/meta-kms-device.h"
 
 #include "backends/native/meta-backend-native.h"
@@ -44,6 +45,12 @@ struct _MetaKmsDevice
 
 G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT);
 
+MetaKmsImplDevice *
+meta_kms_device_get_impl_device (MetaKmsDevice *device)
+{
+  return device->impl_device;
+}
+
 int
 meta_kms_device_leak_fd (MetaKmsDevice *device)
 {
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
index d35f2300b..b849a138d 100644
--- a/src/backends/native/meta-kms-impl-device.c
+++ b/src/backends/native/meta-kms-impl-device.c
@@ -216,6 +216,15 @@ init_planes (MetaKmsImplDevice *impl_device)
   impl_device->planes = g_list_reverse (impl_device->planes);
 }
 
+void
+meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
+{
+  meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl_device->impl));
+
+  g_list_foreach (impl_device->crtcs, (GFunc) meta_kms_crtc_update_state,
+                  NULL);
+}
+
 MetaKmsImplDevice *
 meta_kms_impl_device_new (MetaKmsDevice *device,
                           MetaKmsImpl   *impl,
diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h
index 26d946760..974915c3d 100644
--- a/src/backends/native/meta-kms-impl-device.h
+++ b/src/backends/native/meta-kms-impl-device.h
@@ -49,6 +49,8 @@ int meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device);
 
 int meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device);
 
+void meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device);
+
 int meta_kms_impl_device_close (MetaKmsImplDevice *impl_device);
 
 MetaKmsImplDevice * meta_kms_impl_device_new (MetaKmsDevice *device,
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index 40ce2e8ea..4fd9c5ee4 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -21,8 +21,11 @@
 
 #include "backends/native/meta-kms-private.h"
 
+#include "backends/native/meta-backend-native.h"
+#include "backends/native/meta-kms-device-private.h"
 #include "backends/native/meta-kms-impl.h"
 #include "backends/native/meta-kms-impl-simple.h"
+#include "backends/native/meta-udev.h"
 
 struct _MetaKms
 {
@@ -30,6 +33,8 @@ struct _MetaKms
 
   MetaBackend *backend;
 
+  guint hotplug_handler_id;
+
   MetaKmsImpl *impl;
   gboolean in_impl_task;
 
@@ -59,6 +64,45 @@ meta_kms_in_impl_task (MetaKms *kms)
   return kms->in_impl_task;
 }
 
+static gboolean
+update_states_in_impl (MetaKmsImpl  *impl,
+                       gpointer      user_data,
+                       GError      **error)
+{
+  MetaKms *kms = user_data;
+  GList *l;
+
+  for (l = kms->devices; l; l = l->next)
+    {
+      MetaKmsDevice *device = l->data;
+      MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
+
+      meta_kms_impl_device_update_states (impl_device);
+    }
+
+  return TRUE;
+}
+
+static gboolean
+meta_kms_update_states_sync (MetaKms  *kms,
+                             GError  **error)
+{
+  return meta_kms_run_impl_task_sync (kms,
+                                      update_states_in_impl,
+                                      kms,
+                                      error);
+}
+
+static void
+on_udev_hotplug (MetaUdev *udev,
+                 MetaKms  *kms)
+{
+  g_autoptr (GError) error = NULL;
+
+  if (!meta_kms_update_states_sync (kms, &error))
+    g_warning ("Updating KMS state failed: %s", error->message);
+}
+
 MetaBackend *
 meta_kms_get_backend (MetaKms *kms)
 {
@@ -86,6 +130,8 @@ MetaKms *
 meta_kms_new (MetaBackend  *backend,
               GError      **error)
 {
+  MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
+  MetaUdev *udev = meta_backend_native_get_udev (backend_native);
   MetaKms *kms;
 
   kms = g_object_new (META_TYPE_KMS, NULL);
@@ -97,6 +143,9 @@ meta_kms_new (MetaBackend  *backend,
       return NULL;
     }
 
+  kms->hotplug_handler_id =
+    g_signal_connect (udev, "hotplug", G_CALLBACK (on_udev_hotplug), kms);
+
   return kms;
 }
 
@@ -104,9 +153,14 @@ static void
 meta_kms_finalize (GObject *object)
 {
   MetaKms *kms = META_KMS (object);
+  MetaBackendNative *backend_native = META_BACKEND_NATIVE (kms->backend);
+  MetaUdev *udev = meta_backend_native_get_udev (backend_native);
 
   g_list_free_full (kms->devices, g_object_unref);
 
+  if (kms->hotplug_handler_id)
+    g_signal_handler_disconnect (udev, kms->hotplug_handler_id);
+
   G_OBJECT_CLASS (meta_kms_parent_class)->finalize (object);
 }
 
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 3c118e736..6fa230020 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -412,7 +412,8 @@ meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager
   MetaUdev *udev = meta_backend_native_get_udev (META_BACKEND_NATIVE (backend));
 
   manager_kms->hotplug_handler_id =
-    g_signal_connect (udev, "hotplug", G_CALLBACK (on_udev_hotplug), manager);
+    g_signal_connect_after (udev, "hotplug",
+                            G_CALLBACK (on_udev_hotplug), manager);
 }
 
 static void
diff --git a/src/meson.build b/src/meson.build
index 0bdd4583e..6e13c7c2f 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -601,6 +601,7 @@ if have_native_backend
     'backends/native/meta-kms-crtc-private.h',
     'backends/native/meta-kms-crtc.c',
     'backends/native/meta-kms-crtc.h',
+    'backends/native/meta-kms-device-private.h',
     'backends/native/meta-kms-device.c',
     'backends/native/meta-kms-device.h',
     'backends/native/meta-kms-impl-device.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]