[mutter] tests/kms: Check predicted state is correctly predicted



commit 2e774e8e145541fa0a903aa8e05d4da55b03dace
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Jun 28 09:20:10 2021 +0200

    tests/kms: Check predicted state is correctly predicted
    
    When we're predicting state, i.e. when having posted an update while
    avoiding reading KMS state, copy the predicted state, update the actual
    state, and check that the predicted state matches the newly updated one.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2159>

 src/backends/native/meta-kms-mode-private.h |   4 +
 src/backends/native/meta-kms-mode.c         |  11 ++
 src/backends/native/meta-kms-mode.h         |   1 +
 src/backends/native/meta-kms-private.h      |   6 +
 src/backends/native/meta-kms-update.h       |   1 +
 src/backends/native/meta-kms.c              |   2 +-
 src/tests/native-kms-device.c               | 205 ++++++++++++++++++++++++++--
 7 files changed, 218 insertions(+), 12 deletions(-)
---
diff --git a/src/backends/native/meta-kms-mode-private.h b/src/backends/native/meta-kms-mode-private.h
index ded03c52ef..4969c824eb 100644
--- a/src/backends/native/meta-kms-mode-private.h
+++ b/src/backends/native/meta-kms-mode-private.h
@@ -25,6 +25,10 @@
 uint32_t meta_kms_mode_create_blob_id (MetaKmsMode  *mode,
                                        GError      **error);
 
+META_EXPORT_TEST
+MetaKmsMode * meta_kms_mode_clone (MetaKmsMode *mode);
+
+META_EXPORT_TEST
 void meta_kms_mode_free (MetaKmsMode *mode);
 
 MetaKmsMode * meta_kms_mode_new (MetaKmsImplDevice     *impl_device,
diff --git a/src/backends/native/meta-kms-mode.c b/src/backends/native/meta-kms-mode.c
index 88da86a857..bedc7b5821 100644
--- a/src/backends/native/meta-kms-mode.c
+++ b/src/backends/native/meta-kms-mode.c
@@ -133,6 +133,17 @@ meta_kms_mode_hash (MetaKmsMode *mode)
   return hash;
 }
 
+MetaKmsMode *
+meta_kms_mode_clone (MetaKmsMode *mode)
+{
+  MetaKmsMode *new_mode;
+
+  new_mode = g_new0 (MetaKmsMode, 1);
+  *new_mode = *mode;
+
+  return new_mode;
+}
+
 void
 meta_kms_mode_free (MetaKmsMode *mode)
 {
diff --git a/src/backends/native/meta-kms-mode.h b/src/backends/native/meta-kms-mode.h
index d3a81aeafd..63650834e5 100644
--- a/src/backends/native/meta-kms-mode.h
+++ b/src/backends/native/meta-kms-mode.h
@@ -40,6 +40,7 @@ int meta_kms_mode_get_width (MetaKmsMode *mode);
 META_EXPORT_TEST
 int meta_kms_mode_get_height (MetaKmsMode *mode);
 
+META_EXPORT_TEST
 const char * meta_kms_mode_get_name (MetaKmsMode *mode);
 
 MetaKmsModeFlag meta_kms_mode_get_flags (MetaKmsMode *mode);
diff --git a/src/backends/native/meta-kms-private.h b/src/backends/native/meta-kms-private.h
index 8d0954c72a..3661abe29e 100644
--- a/src/backends/native/meta-kms-private.h
+++ b/src/backends/native/meta-kms-private.h
@@ -22,6 +22,8 @@
 
 #include "backends/native/meta-kms.h"
 
+#include <gudev/gudev.h>
+
 #include "backends/native/meta-kms-types.h"
 
 typedef void (* MetaKmsCallback) (MetaKms  *kms,
@@ -51,6 +53,10 @@ GSource * meta_kms_register_fd_in_impl (MetaKms             *kms,
                                         MetaKmsImplTaskFunc  dispatch,
                                         gpointer             user_data);
 
+META_EXPORT_TEST
+MetaKmsUpdateChanges meta_kms_update_states_sync (MetaKms     *kms,
+                                                  GUdevDevice *udev_device);
+
 gboolean meta_kms_in_impl_task (MetaKms *kms);
 
 gboolean meta_kms_is_waiting_for_impl_task (MetaKms *kms);
diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h
index 08abf4cf90..f31e36aad3 100644
--- a/src/backends/native/meta-kms-update.h
+++ b/src/backends/native/meta-kms-update.h
@@ -107,6 +107,7 @@ void meta_kms_update_set_privacy_screen (MetaKmsUpdate    *update,
                                          MetaKmsConnector *connector,
                                          gboolean          enabled);
 
+META_EXPORT_TEST
 void meta_kms_update_set_power_save (MetaKmsUpdate *update);
 
 META_EXPORT_TEST
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index a8905fcc01..2688a23c68 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -618,7 +618,7 @@ update_states_in_impl (MetaKmsImpl  *impl,
   return GUINT_TO_POINTER (meta_kms_update_states_in_impl (kms, data));
 }
 
-static MetaKmsUpdateChanges
+MetaKmsUpdateChanges
 meta_kms_update_states_sync (MetaKms     *kms,
                              GUdevDevice *udev_device)
 {
diff --git a/src/tests/native-kms-device.c b/src/tests/native-kms-device.c
index ef14e530c2..cafe4dffef 100644
--- a/src/tests/native-kms-device.c
+++ b/src/tests/native-kms-device.c
@@ -24,9 +24,10 @@
 #include "backends/native/meta-kms-connector.h"
 #include "backends/native/meta-kms-crtc.h"
 #include "backends/native/meta-kms-device.h"
+#include "backends/native/meta-kms-mode-private.h"
 #include "backends/native/meta-kms-plane.h"
+#include "backends/native/meta-kms-private.h"
 #include "backends/native/meta-kms-update.h"
-#include "backends/native/meta-kms.h"
 #include "meta-test/meta-context-test.h"
 #include "tests/meta-kms-test-utils.h"
 
@@ -88,6 +89,178 @@ meta_test_kms_device_sanity (void)
                    META_KMS_PLANE_TYPE_CURSOR);
 }
 
+static void
+assert_crtc_state_equals (const MetaKmsCrtcState *crtc_state1,
+                          const MetaKmsCrtcState *crtc_state2)
+{
+  g_assert_cmpint (crtc_state1->is_active, ==, crtc_state2->is_active);
+  g_assert (meta_rectangle_equal (&crtc_state1->rect, &crtc_state2->rect));
+  g_assert_cmpint (crtc_state1->is_drm_mode_valid,
+                   ==,
+                   crtc_state2->is_drm_mode_valid);
+  if (crtc_state1->is_drm_mode_valid)
+    {
+      g_assert_cmpstr (crtc_state1->drm_mode.name,
+                       ==,
+                       crtc_state2->drm_mode.name);
+    }
+
+  g_assert_cmpint (crtc_state1->gamma.size, ==, crtc_state1->gamma.size);
+  g_assert_cmpmem (crtc_state1->gamma.red,
+                   crtc_state1->gamma.size * sizeof (uint16_t),
+                   crtc_state2->gamma.red,
+                   crtc_state2->gamma.size * sizeof (uint16_t));
+  g_assert_cmpmem (crtc_state1->gamma.green,
+                   crtc_state1->gamma.size * sizeof (uint16_t),
+                   crtc_state2->gamma.green,
+                   crtc_state2->gamma.size * sizeof (uint16_t));
+  g_assert_cmpmem (crtc_state1->gamma.blue,
+                   crtc_state1->gamma.size * sizeof (uint16_t),
+                   crtc_state2->gamma.blue,
+                   crtc_state2->gamma.size * sizeof (uint16_t));
+}
+
+static int
+compare_modes (gconstpointer a,
+               gconstpointer b)
+{
+  MetaKmsMode *mode_a = (MetaKmsMode *) a;
+  MetaKmsMode *mode_b = (MetaKmsMode *) b;
+
+  return g_strcmp0 (meta_kms_mode_get_name (mode_a),
+                    meta_kms_mode_get_name (mode_b));
+}
+
+static void
+assert_list_equals_unsorted (GList        *list1,
+                             GList        *list2,
+                             GCompareFunc  compare)
+{
+  list1 = g_list_copy (list1);
+  list2 = g_list_copy (list2);
+
+  while (list1)
+    {
+      GList *l;
+
+      l = g_list_find_custom (list2, list1->data, compare);
+      g_assert_nonnull (l);
+      list2 = g_list_delete_link (list2, l);
+      list1 = g_list_delete_link (list1, list1);
+    }
+
+  g_assert_null (list2);
+}
+
+static void
+assert_connector_state_equals (const MetaKmsConnectorState *connector_state1,
+                               const MetaKmsConnectorState *connector_state2)
+{
+  g_assert_cmpuint (connector_state1->current_crtc_id,
+                    ==,
+                    connector_state2->current_crtc_id);
+  g_assert_cmpuint (connector_state1->common_possible_crtcs,
+                    ==,
+                    connector_state2->common_possible_crtcs);
+  g_assert_cmpuint (connector_state1->common_possible_clones,
+                    ==,
+                    connector_state2->common_possible_clones);
+  g_assert_cmpuint (connector_state1->encoder_device_idxs,
+                    ==,
+                    connector_state2->encoder_device_idxs);
+  g_assert_cmpuint (g_list_length (connector_state1->modes),
+                    ==,
+                    g_list_length (connector_state2->modes));
+
+  assert_list_equals_unsorted (connector_state1->modes,
+                               connector_state2->modes,
+                               compare_modes);
+
+  if (connector_state1->edid_data || connector_state2->edid_data)
+    {
+      g_assert_cmpint (g_bytes_compare (connector_state1->edid_data,
+                                        connector_state2->edid_data),
+                       ==,
+                       0);
+    }
+
+  g_assert_cmpint (connector_state1->has_scaling,
+                   ==,
+                   connector_state2->has_scaling);
+  g_assert_cmpint (connector_state1->non_desktop,
+                   ==,
+                   connector_state2->non_desktop);
+
+  g_assert_cmpint (connector_state1->subpixel_order,
+                   ==,
+                   connector_state2->subpixel_order);
+  g_assert_cmpint (connector_state1->suggested_x,
+                   ==,
+                   connector_state2->suggested_x);
+  g_assert_cmpint (connector_state1->hotplug_mode_update,
+                   ==,
+                   connector_state2->hotplug_mode_update);
+  g_assert_cmpint (connector_state1->panel_orientation_transform,
+                   ==,
+                   connector_state2->panel_orientation_transform);
+}
+
+static MetaKmsCrtcState
+copy_crtc_state (const MetaKmsCrtcState *crtc_state)
+{
+  MetaKmsCrtcState new_state;
+
+  g_assert_nonnull (crtc_state);
+
+  new_state = *crtc_state;
+  new_state.gamma.red = g_memdup2 (new_state.gamma.red,
+                                   new_state.gamma.size * sizeof (uint16_t));
+  new_state.gamma.green = g_memdup2 (new_state.gamma.green,
+                                     new_state.gamma.size * sizeof (uint16_t));
+  new_state.gamma.blue = g_memdup2 (new_state.gamma.blue,
+                                    new_state.gamma.size * sizeof (uint16_t));
+
+  return new_state;
+}
+
+static MetaKmsConnectorState
+copy_connector_state (const MetaKmsConnectorState *connector_state)
+{
+  MetaKmsConnectorState new_state;
+
+  g_assert_nonnull (connector_state);
+
+  new_state = *connector_state;
+  new_state.modes = g_list_copy_deep (new_state.modes,
+                                      (GCopyFunc) meta_kms_mode_clone,
+                                      NULL);
+  if (new_state.edid_data)
+    {
+      new_state.edid_data =
+        g_bytes_new_from_bytes (new_state.edid_data,
+                                0,
+                                g_bytes_get_size (new_state.edid_data));
+    }
+
+  return new_state;
+}
+
+static void
+release_crtc_state (const MetaKmsCrtcState *crtc_state)
+{
+  g_free (crtc_state->gamma.red);
+  g_free (crtc_state->gamma.green);
+  g_free (crtc_state->gamma.blue);
+}
+
+static void
+release_connector_state (const MetaKmsConnectorState *connector_state)
+{
+  g_list_free_full (connector_state->modes,
+                    (GDestroyNotify) meta_kms_mode_free);
+  g_bytes_unref (connector_state->edid_data);
+}
+
 static void
 meta_test_kms_device_mode_set (void)
 {
@@ -98,8 +271,8 @@ meta_test_kms_device_mode_set (void)
   MetaKmsMode *mode;
   MetaKmsPlane *primary_plane;
   g_autoptr (MetaDrmBuffer) primary_buffer = NULL;
-  const MetaKmsCrtcState *crtc_state;
-  const MetaKmsConnectorState *connector_state;
+  MetaKmsCrtcState crtc_state;
+  MetaKmsConnectorState connector_state;
   MetaRectangle mode_rect;
 
   device = meta_get_test_kms_device (test_context);
@@ -127,18 +300,28 @@ meta_test_kms_device_mode_set (void)
                                        META_KMS_UPDATE_FLAG_NONE);
   meta_kms_update_free (update);
 
-  crtc_state = meta_kms_crtc_get_current_state (crtc);
-  g_assert_nonnull (crtc_state);
-  g_assert_true (crtc_state->is_active);
-  g_assert_true (crtc_state->is_drm_mode_valid);
+  g_assert_nonnull (meta_kms_crtc_get_current_state (crtc));
+  crtc_state = copy_crtc_state (meta_kms_crtc_get_current_state (crtc));
+  g_assert_true (crtc_state.is_active);
+  g_assert_true (crtc_state.is_drm_mode_valid);
   mode_rect = meta_get_mode_rect (mode);
-  g_assert (meta_rectangle_equal (&crtc_state->rect, &mode_rect));
+  g_assert (meta_rectangle_equal (&crtc_state.rect, &mode_rect));
 
-  connector_state = meta_kms_connector_get_current_state (connector);
-  g_assert_nonnull (connector_state);
-  g_assert_cmpuint (connector_state->current_crtc_id,
+  g_assert_nonnull (meta_kms_connector_get_current_state (connector));
+  connector_state =
+    copy_connector_state (meta_kms_connector_get_current_state (connector));
+  g_assert_cmpuint (connector_state.current_crtc_id,
                     ==,
                     meta_kms_crtc_get_id (crtc));
+
+  meta_kms_update_states_sync (meta_kms_device_get_kms (device), NULL);
+  assert_crtc_state_equals (&crtc_state,
+                            meta_kms_crtc_get_current_state (crtc));
+  assert_connector_state_equals (&connector_state,
+                                 meta_kms_connector_get_current_state (connector));
+
+  release_crtc_state (&crtc_state);
+  release_connector_state (&connector_state);
 }
 
 static void


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