From 37db905ff97cb118b5f48ad46172de53345acbe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 20 Oct 2022 21:34:25 +0200 Subject: [PATCH] kms/update: Support merging updates with mode sets Will be helpful to allow constructing each initial mode set update per CRTC, merging them later on-demand. Part-of: --- src/backends/native/meta-kms-update.c | 52 ++++++++++++++++++++++++++- src/tests/native-kms-updates.c | 17 ++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index c6b090d94..09e42d3c7 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -671,6 +671,56 @@ meta_kms_custom_page_flip_free (MetaKmsCustomPageFlip *custom_page_flip) g_free (custom_page_flip); } +static GList * +find_mode_set_link_for (MetaKmsUpdate *update, + MetaKmsCrtc *crtc) +{ + GList *l; + + for (l = update->mode_sets; l; l = l->next) + { + MetaKmsModeSet *mode_set = l->data; + + if (mode_set->crtc == crtc) + return l; + } + + return NULL; +} + +static void +merge_mode_sets (MetaKmsUpdate *update, + MetaKmsUpdate *other_update) +{ + while (other_update->mode_sets) + { + GList *l = other_update->mode_sets; + MetaKmsModeSet *other_mode_set = l->data; + MetaKmsCrtc *crtc = other_mode_set->crtc; + GList *el; + + other_update->mode_sets = + g_list_remove_link (other_update->mode_sets, l); + + el = find_mode_set_link_for (update, crtc); + if (el) + { + meta_kms_mode_set_free (el->data); + update->mode_sets = + g_list_insert_before_link (update->mode_sets, el, l); + update->mode_sets = + g_list_delete_link (update->mode_sets, el); + } + else + { + update->mode_sets = + g_list_insert_before_link (update->mode_sets, + update->mode_sets, + l); + } + } +} + static GList * find_plane_assignment_link_for (MetaKmsUpdate *update, MetaKmsPlane *plane) @@ -808,10 +858,10 @@ meta_kms_update_merge_from (MetaKmsUpdate *update, MetaKmsUpdate *other_update) { g_return_if_fail (update->device == other_update->device); - g_return_if_fail (!update->mode_sets && !other_update->mode_sets); g_return_if_fail (!update->connector_updates && !other_update->connector_updates); + merge_mode_sets (update, other_update); merge_plane_assignments_from (update, other_update); merge_crtc_color_updates_from (update, other_update); merge_custom_page_flip_from (update, other_update); diff --git a/src/tests/native-kms-updates.c b/src/tests/native-kms-updates.c index 231a253d1..f253093dc 100644 --- a/src/tests/native-kms-updates.c +++ b/src/tests/native-kms-updates.c @@ -408,6 +408,8 @@ meta_test_kms_update_merge (void) MetaKmsUpdate *update2; g_autoptr (MetaGammaLut) lut = NULL; g_autoptr (MetaDrmBuffer) cursor_buffer2 = NULL; + GList *mode_sets; + MetaKmsModeSet *mode_set; GList *plane_assignments; MetaKmsPlaneAssignment *plane_assignment; GList *crtc_color_updates; @@ -456,12 +458,17 @@ meta_test_kms_update_merge (void) 10, 11); /* - * Create an update2 with with cursor buffer 2 + * Create an update2 with a mode set and a cursor buffer 2 * on the cursor plane at at (32, 56), and a new CRTC gamma. */ update2 = meta_kms_update_new (device); + meta_kms_update_mode_set (update2, + crtc, + g_list_append (NULL, connector), + mode); + lut = meta_gamma_lut_new (3, (uint16_t[]) { 1, 2, 3 }, (uint16_t[]) { 4, 5, 6 }, @@ -488,6 +495,14 @@ meta_test_kms_update_merge (void) meta_kms_update_merge_from (update1, update2); meta_kms_update_free (update2); + mode_sets = meta_kms_update_get_mode_sets (update1); + g_assert_cmpuint (g_list_length (mode_sets), ==, 1); + mode_set = mode_sets->data; + g_assert (mode_set->crtc == crtc); + g_assert (mode_set->mode == mode); + g_assert_cmpuint (g_list_length (mode_set->connectors), ==, 1); + g_assert (mode_set->connectors->data == connector); + plane_assignments = meta_kms_update_get_plane_assignments (update1); g_assert_cmpuint (g_list_length (plane_assignments), ==, 2); plane_assignment = meta_kms_update_get_primary_plane_assignment (update1,