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>
This commit is contained in:
Jonas Ådahl 2021-06-28 09:20:10 +02:00 committed by Marge Bot
parent 2478000c73
commit 2e774e8e14
7 changed files with 218 additions and 12 deletions

View File

@ -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,

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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)
{

View File

@ -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