diff --git a/src/backends/native/meta-kms-device-private.h b/src/backends/native/meta-kms-device-private.h index 1660b9707..f40e9e979 100644 --- a/src/backends/native/meta-kms-device-private.h +++ b/src/backends/native/meta-kms-device-private.h @@ -23,6 +23,7 @@ #include "backends/native/meta-kms-types.h" #include "backends/native/meta-kms-update-private.h" +META_EXPORT_TEST MetaKmsImplDevice * meta_kms_device_get_impl_device (MetaKmsDevice *device); MetaKmsResourceChanges meta_kms_device_update_states_in_impl (MetaKmsDevice *device, diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c index 9948dd160..afc264dfe 100644 --- a/src/backends/native/meta-kms-device.c +++ b/src/backends/native/meta-kms-device.c @@ -371,17 +371,51 @@ meta_create_kms_impl_device (MetaKmsDevice *device, { meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl)); - if (flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING) + const char *env_kms_mode; + enum { + KMS_MODE_AUTO, + KMS_MODE_ATOMIC, + KMS_MODE_SIMPLE, + KMS_MODE_HEADLESS, + } kms_mode; + + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl)); + + env_kms_mode = g_getenv ("MUTTER_DEBUG_FORCE_KMS_MODE"); + if (env_kms_mode) { - return g_initable_new (META_TYPE_KMS_IMPL_DEVICE_DUMMY, - NULL, error, - "device", device, - "impl", impl, - "path", path, - "flags", flags, - NULL); + if (g_strcmp0 (env_kms_mode, "auto") == 0) + { + kms_mode = KMS_MODE_AUTO; + } + else if (g_strcmp0 (env_kms_mode, "atomic") == 0) + { + kms_mode = KMS_MODE_ATOMIC; + } + else if (g_strcmp0 (env_kms_mode, "simple") == 0) + { + kms_mode = KMS_MODE_SIMPLE; + } + else if (g_strcmp0 (env_kms_mode, "headless") == 0) + { + kms_mode = KMS_MODE_HEADLESS; + } + else + { + g_warning ("Attempted to force invalid mode setting mode '%s", + env_kms_mode); + kms_mode = KMS_MODE_AUTO; + } } else + { + if (flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING) + kms_mode = KMS_MODE_HEADLESS; + else + kms_mode = KMS_MODE_AUTO; + } + + if (kms_mode == KMS_MODE_AUTO) { GType impl_device_types[] = { META_TYPE_KMS_IMPL_DEVICE_ATOMIC, @@ -417,6 +451,32 @@ meta_create_kms_impl_device (MetaKmsDevice *device, return NULL; } + else + { + GType type; + + switch (kms_mode) + { + case KMS_MODE_ATOMIC: + type = META_TYPE_KMS_IMPL_DEVICE_ATOMIC; + break; + case KMS_MODE_SIMPLE: + type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE; + break; + case KMS_MODE_HEADLESS: + type = META_TYPE_KMS_IMPL_DEVICE_DUMMY; + break; + default: + g_assert_not_reached (); + }; + + return g_initable_new (type, NULL, error, + "device", device, + "impl", impl, + "path", path, + "flags", flags, + NULL); + } } static gpointer diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c index 36cf6c39d..b1925f984 100644 --- a/src/backends/native/meta-kms-impl-device-atomic.c +++ b/src/backends/native/meta-kms-impl-device-atomic.c @@ -1212,15 +1212,6 @@ meta_kms_impl_device_atomic_initable_init (GInitable *initable, GError **error) { MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable); - const char *atomic_kms_enable_env; - - atomic_kms_enable_env = getenv ("MUTTER_DEBUG_ENABLE_ATOMIC_KMS"); - if (atomic_kms_enable_env && g_strcmp0 (atomic_kms_enable_env, "1") != 0) - { - g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_USER_INHIBITED, - "Atomic mode setting disable via env var"); - return FALSE; - } if (!initable_parent_iface->init (initable, cancellable, error)) return FALSE; diff --git a/src/backends/native/meta-kms-impl-device-atomic.h b/src/backends/native/meta-kms-impl-device-atomic.h index 74658797c..99aa066db 100644 --- a/src/backends/native/meta-kms-impl-device-atomic.h +++ b/src/backends/native/meta-kms-impl-device-atomic.h @@ -23,6 +23,7 @@ #include "backends/native/meta-kms-impl-device.h" #define META_TYPE_KMS_IMPL_DEVICE_ATOMIC (meta_kms_impl_device_atomic_get_type ()) +META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaKmsImplDeviceAtomic, meta_kms_impl_device_atomic, META, KMS_IMPL_DEVICE_ATOMIC, MetaKmsImplDevice) diff --git a/src/backends/native/meta-kms-impl-device-simple.h b/src/backends/native/meta-kms-impl-device-simple.h index 7be5f0a83..aeea434fd 100644 --- a/src/backends/native/meta-kms-impl-device-simple.h +++ b/src/backends/native/meta-kms-impl-device-simple.h @@ -23,6 +23,7 @@ #include "backends/native/meta-kms-impl-device.h" #define META_TYPE_KMS_IMPL_DEVICE_SIMPLE (meta_kms_impl_device_simple_get_type ()) +META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaKmsImplDeviceSimple, meta_kms_impl_device_simple, META, KMS_IMPL_DEVICE_SIMPLE, MetaKmsImplDevice) diff --git a/src/tests/kvm/meson.build b/src/tests/kvm/meson.build index bdd74ff54..17aaff1f5 100644 --- a/src/tests/kvm/meson.build +++ b/src/tests/kvm/meson.build @@ -27,20 +27,20 @@ endif virtme_run = find_program('virtme-run.sh') -vm_env_entries = [] -foreach name, value: test_env_variables - vm_env_entries += ['@0@=@1@'.format(name, value)] -endforeach -vm_env = ' '.join(vm_env_entries) - foreach test_case: privileged_tests + vm_env_entries = [] + foreach name, value: test_case['variables'] + vm_env_entries += ['@0@=@1@'.format(name, value)] + endforeach + vm_env = ' '.join(vm_env_entries) + test('kvm-' + test_case['name'], virtme_run, suite: ['core', 'mutter/kvm', 'mutter/kvm/' + test_case['suite']], depends: [ kernel_image_target, ], workdir: mutter_srcdir, - env: test_env, + env: test_case['env'], args: [ kernel_image_path, meta_dbus_runner.full_path(), diff --git a/src/tests/kvm/virtme-run.sh b/src/tests/kvm/virtme-run.sh index 006209387..7d2929bb1 100755 --- a/src/tests/kvm/virtme-run.sh +++ b/src/tests/kvm/virtme-run.sh @@ -20,6 +20,10 @@ XDG_DATA_DIRS=$XDG_DATA_DIRS \ $VM_ENV \ " +if [ ! -v $MUTTER_DEBUG_FORCE_KMS_MODE ]; then + VIRTME_ENV="$VIRTME_ENV MUTTER_DEBUG_FORCE_KMS_MODE=$MUTTER_DEBUG_FORCE_KMS_MODE" +fi + if [[ "$(stat -c '%t:%T' -L /proc/$$/fd/0)" == "0:0" ]]; then mkfifo $XDG_RUNTIME_DIR/fake-stdin.$$ exec 0<> $XDG_RUNTIME_DIR/fake-stdin.$$ diff --git a/src/tests/meson.build b/src/tests/meson.build index 6d2105332..33f413dbb 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -263,8 +263,40 @@ if have_native_tests }, ] - # Privileged tests - privileged_test_cases += [ + # KMS tests + kms_test_variants = [] + kms_atomic_variables = {'MUTTER_DEBUG_FORCE_KMS_MODE': 'atomic'} + kms_simple_variables = {'MUTTER_DEBUG_FORCE_KMS_MODE': 'simple'} + kms_variants = [ + ['atomic', kms_atomic_variables], + ['simple', kms_simple_variables], + ] + foreach variant: kms_variants + name = variant[0] + variables = variant[1] + suffix = '-@0@'.format(name) + + kms_test_env_variables = test_env_variables + variables + kms_test_variants += [[suffix, kms_test_env_variables]] + endforeach + + kms_test_cases = [ + { + 'name': 'kms-force-atomic-sanity', + 'suite': 'backends/native/kms', + 'sources': [ + 'native-kms-force-atomic-sanity.c', + ], + 'variants': [['', test_env_variables + kms_atomic_variables]], + }, + { + 'name': 'kms-force-simple-sanity', + 'suite': 'backends/native/kms', + 'sources': [ + 'native-kms-force-simple-sanity.c', + ], + 'variants': [['', test_env_variables + kms_simple_variables]], + }, { 'name': 'kms-render', 'suite': 'backends/native/kms', @@ -272,6 +304,7 @@ if have_native_tests 'native-kms-render.c', wayland_test_utils, ], + 'variants': kms_test_variants, }, { 'name': 'kms-device', @@ -281,6 +314,7 @@ if have_native_tests 'meta-kms-test-utils.h', 'native-kms-device.c', ], + 'variants': kms_test_variants, }, { 'name': 'kms-update', @@ -290,9 +324,12 @@ if have_native_tests 'meta-kms-test-utils.h', 'native-kms-updates.c', ], + 'variants': kms_test_variants, }, ] + privileged_test_cases += kms_test_cases + # Wayland tests test_cases += [ { @@ -379,6 +416,12 @@ endforeach if have_kvm_tests or have_tty_tests privileged_tests = [] foreach test_case: privileged_test_cases + if test_case.has_key('variants') + variants = test_case['variants'] + else + variants = [['', test_env_variables, []]] + endif + test_executable = executable('mutter-' + test_case['name'], sources: test_case['sources'], include_directories: tests_includes, @@ -390,13 +433,22 @@ if have_kvm_tests or have_tty_tests install: have_installed_tests, install_dir: mutter_installed_tests_libexecdir, ) - privileged_tests += [ - { - 'name': test_case['name'], - 'suite': test_case['suite'], - 'executable': test_executable, - }, - ] + + foreach variant: variants + variant_env = environment() + foreach name, value: variant[1] + variant_env.set(name, value) + endforeach + privileged_tests += [ + { + 'name': '@0@@1@'.format(test_case['name'], variant[0]), + 'suite': test_case['suite'], + 'executable': test_executable, + 'variables': variant[1], + 'env': variant_env, + }, + ] + endforeach endforeach if have_kvm_tests @@ -407,7 +459,7 @@ if have_kvm_tests or have_tty_tests foreach test_case: privileged_tests test('tty-' + test_case['name'], test_case['executable'], suite: ['core', 'mutter/tty', 'mutter/tty/' + test_case['suite']], - env: test_env, + env: test_case['env'], is_parallel: false, timeout: 60, ) diff --git a/src/tests/native-kms-force-atomic-sanity.c b/src/tests/native-kms-force-atomic-sanity.c new file mode 100644 index 000000000..fe8d3dbfb --- /dev/null +++ b/src/tests/native-kms-force-atomic-sanity.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 Red Hat Inc. + * + * 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. + * + */ + +#include "config.h" + +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-kms.h" +#include "backends/native/meta-kms-device.h" +#include "backends/native/meta-kms-device-private.h" +#include "backends/native/meta-kms-impl-device-atomic.h" +#include "meta-test/meta-context-test.h" + +static MetaContext *test_context; + +static void +meta_test_kms_force_atomic_sanity (void) +{ + MetaBackend *backend = meta_context_get_backend (test_context); + MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend)); + GList *l; + + g_assert_nonnull (meta_kms_get_devices (kms)); + + for (l = meta_kms_get_devices (kms); l; l = l->next) + { + MetaKmsDevice *device = META_KMS_DEVICE (l->data); + MetaKmsImplDevice *impl_device; + + impl_device = meta_kms_device_get_impl_device (device); + g_assert_true (META_IS_KMS_IMPL_DEVICE_ATOMIC (impl_device)); + } +} + +static void +init_tests (void) +{ + g_test_add_func ("/backends/native/kms/force-atomic-sanity", + meta_test_kms_force_atomic_sanity); +} + +int +main (int argc, + char **argv) +{ + g_autoptr (MetaContext) context = NULL; + g_autoptr (GError) error = NULL; + + context = meta_create_test_context (META_CONTEXT_TEST_TYPE_VKMS, + META_CONTEXT_TEST_FLAG_NO_X11); + g_assert (meta_context_configure (context, &argc, &argv, NULL)); + + test_context = context; + + init_tests (); + + return meta_context_test_run_tests (META_CONTEXT_TEST (context), + META_TEST_RUN_FLAG_CAN_SKIP); +} diff --git a/src/tests/native-kms-force-simple-sanity.c b/src/tests/native-kms-force-simple-sanity.c new file mode 100644 index 000000000..e1f6a69b0 --- /dev/null +++ b/src/tests/native-kms-force-simple-sanity.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 Red Hat Inc. + * + * 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. + * + */ + +#include "config.h" + +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-kms.h" +#include "backends/native/meta-kms-device.h" +#include "backends/native/meta-kms-device-private.h" +#include "backends/native/meta-kms-impl-device-simple.h" +#include "meta-test/meta-context-test.h" + +static MetaContext *test_context; + +static void +meta_test_kms_force_simple_sanity (void) +{ + MetaBackend *backend = meta_context_get_backend (test_context); + MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend)); + GList *l; + + g_assert_nonnull (meta_kms_get_devices (kms)); + + for (l = meta_kms_get_devices (kms); l; l = l->next) + { + MetaKmsDevice *device = META_KMS_DEVICE (l->data); + MetaKmsImplDevice *impl_device; + + impl_device = meta_kms_device_get_impl_device (device); + g_assert_true (META_IS_KMS_IMPL_DEVICE_SIMPLE (impl_device)); + } +} + +static void +init_tests (void) +{ + g_test_add_func ("/backends/native/kms/force-simple-sanity", + meta_test_kms_force_simple_sanity); +} + +int +main (int argc, + char **argv) +{ + g_autoptr (MetaContext) context = NULL; + g_autoptr (GError) error = NULL; + + context = meta_create_test_context (META_CONTEXT_TEST_TYPE_VKMS, + META_CONTEXT_TEST_FLAG_NO_X11); + g_assert (meta_context_configure (context, &argc, &argv, NULL)); + + test_context = context; + + init_tests (); + + return meta_context_test_run_tests (META_CONTEXT_TEST (context), + META_TEST_RUN_FLAG_CAN_SKIP); +}