diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 681f210f0..21db6ca21 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -131,6 +131,7 @@ MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend, MetaIdleManager * meta_backend_get_idle_manager (MetaBackend *backend); +META_EXPORT_TEST MetaColorManager * meta_backend_get_color_manager (MetaBackend *backend); META_EXPORT_TEST diff --git a/src/backends/meta-color-manager-private.h b/src/backends/meta-color-manager-private.h index aa0904533..ae33ae1ca 100644 --- a/src/backends/meta-color-manager-private.h +++ b/src/backends/meta-color-manager-private.h @@ -32,4 +32,7 @@ CdClient * meta_color_manager_get_cd_client (MetaColorManager *color_manager); META_EXPORT_TEST gboolean meta_color_manager_is_ready (MetaColorManager *color_manager); +META_EXPORT_TEST +int meta_color_manager_get_num_color_devices (MetaColorManager *color_manager); + #endif /* META_COLOR_MANAGER_PRIVATE_H */ diff --git a/src/backends/meta-color-manager.c b/src/backends/meta-color-manager.c index 3bc31644e..696c2b337 100644 --- a/src/backends/meta-color-manager.c +++ b/src/backends/meta-color-manager.c @@ -380,3 +380,12 @@ meta_color_manager_is_ready (MetaColorManager *color_manager) return priv->is_ready; } + +int +meta_color_manager_get_num_color_devices (MetaColorManager *color_manager) +{ + MetaColorManagerPrivate *priv = + meta_color_manager_get_instance_private (color_manager); + + return g_hash_table_size (priv->devices); +} diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h index 0e19064a4..3e81c7a09 100644 --- a/src/backends/meta-monitor.h +++ b/src/backends/meta-monitor.h @@ -160,6 +160,7 @@ const char * meta_monitor_get_serial (MetaMonitor *monitor); META_EXPORT_TEST const MetaEdidInfo * meta_monitor_get_edid_info (MetaMonitor *monitor); +META_EXPORT_TEST const char * meta_monitor_get_edid_checksum_md5 (MetaMonitor *monitor); META_EXPORT_TEST diff --git a/src/tests/color-management-tests.c b/src/tests/color-management-tests.c new file mode 100644 index 000000000..15072d1bc --- /dev/null +++ b/src/tests/color-management-tests.c @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2021 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. + * + */ + +#include "config.h" + +#include "backends/meta-color-device.h" +#include "backends/meta-color-manager-private.h" +#include "meta-test/meta-context-test.h" +#include "tests/meta-monitor-test-utils.h" + +static MetaContext *test_context; + +static MonitorTestCaseSetup base_monitor_setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = 1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 +}; + +/* Extracted from a 'California Institute of Technology, 0x1403' monitor. */ +#define CALTECH_MONITOR_EDID (\ + (MetaEdidInfo) { \ + .gamma = 2.200000, \ + .red_x = 0.683594, \ + .red_y = 0.312500, \ + .green_x = 0.255859, \ + .green_y = 0.685547, \ + .blue_x = 0.139648, \ + .blue_y = 0.056641, \ + .white_x = 0.313477, \ + .white_y = 0.326172, \ + }) + +/* Extracted from a 'Ancor Communications Inc, VX239, ECLMRS004144' monitor. */ +#define ANCOR_VX239_EDID (\ + (MetaEdidInfo) { \ + .gamma = 2.200000, \ + .red_x = 0.651367, \ + .red_y = 0.335938, \ + .green_x = 0.321289, \ + .green_y = 0.614258, \ + .blue_x = 0.154297, \ + .blue_y = 0.063477, \ + .white_x = 0.313477, \ + .white_y = 0.329102, \ + }) + +static void +meta_test_color_management_device_basic (void) +{ + MetaBackend *backend = meta_context_get_backend (test_context); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + MetaColorManager *color_manager = + meta_backend_get_color_manager (backend); + MonitorTestCaseSetup test_case_setup = base_monitor_setup; + MetaMonitorTestSetup *test_setup; + GList *monitors; + GList *l; + int i; + + test_case_setup.outputs[0].edid_info = CALTECH_MONITOR_EDID; + test_case_setup.outputs[0].has_edid_info = TRUE; + test_case_setup.outputs[1].edid_info = ANCOR_VX239_EDID; + test_case_setup.outputs[1].has_edid_info = TRUE; + + test_case_setup.n_outputs = 0; + test_setup = meta_create_monitor_test_setup (backend, &test_case_setup, + MONITOR_TEST_FLAG_NO_STORED); + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); + + test_case_setup.n_outputs = 2; + test_setup = meta_create_monitor_test_setup (backend, &test_case_setup, + MONITOR_TEST_FLAG_NO_STORED); + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); + + i = 0; + monitors = meta_monitor_manager_get_monitors (monitor_manager); + g_assert_cmpuint (g_list_length (monitors), ==, 2); + g_assert_cmpuint (g_list_length (monitors), + ==, + meta_color_manager_get_num_color_devices (color_manager)); + + test_case_setup.n_outputs = 1; + test_setup = meta_create_monitor_test_setup (backend, &test_case_setup, + MONITOR_TEST_FLAG_NO_STORED); + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + g_assert_cmpuint (g_list_length (monitors), ==, 1); + g_assert_cmpuint (g_list_length (monitors), + ==, + meta_color_manager_get_num_color_devices (color_manager)); + + test_case_setup.n_outputs = 2; + test_setup = meta_create_monitor_test_setup (backend, &test_case_setup, + MONITOR_TEST_FLAG_NO_STORED); + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + g_assert_cmpuint (g_list_length (monitors), ==, 2); + g_assert_cmpuint (g_list_length (monitors), + ==, + meta_color_manager_get_num_color_devices (color_manager)); + + for (l = monitors, i = 0; l; l = l->next, i++) + { + MetaMonitor *monitor = META_MONITOR (l->data); + const MetaEdidInfo *expected_edid_info = + &test_case_setup.outputs[i].edid_info; + const MetaEdidInfo *monitor_edid_info; + MetaColorDevice *color_device; + + g_assert_nonnull (meta_monitor_get_edid_checksum_md5 (monitor)); + monitor_edid_info = meta_monitor_get_edid_info (monitor); + + g_assert_cmpfloat_with_epsilon (expected_edid_info->gamma, + monitor_edid_info->gamma, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (expected_edid_info->red_x, + monitor_edid_info->red_x, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (expected_edid_info->red_y, + monitor_edid_info->red_y, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (expected_edid_info->green_x, + monitor_edid_info->green_x, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (expected_edid_info->green_y, + monitor_edid_info->green_y, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (expected_edid_info->blue_x, + monitor_edid_info->blue_x, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (expected_edid_info->blue_y, + monitor_edid_info->blue_y, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (expected_edid_info->white_x, + monitor_edid_info->white_x, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (expected_edid_info->white_y, + monitor_edid_info->white_y, + FLT_EPSILON); + + color_device = meta_color_manager_get_color_device (color_manager, + monitor); + g_assert_nonnull (color_device); + + g_assert (meta_color_device_get_monitor (color_device) == monitor); + } +} + +static MetaMonitorTestSetup * +create_stage_view_test_setup (MetaBackend *backend) +{ + return meta_create_monitor_test_setup (backend, &base_monitor_setup, + MONITOR_TEST_FLAG_NO_STORED); +} + +static void +on_before_tests (MetaContext *context) +{ + MetaBackend *backend = meta_context_get_backend (test_context); + MetaColorManager *color_manager = + meta_backend_get_color_manager (backend); + + while (!meta_color_manager_is_ready (color_manager)) + g_main_context_iteration (NULL, TRUE); +} + +static void +init_tests (void) +{ + meta_init_monitor_test_setup (create_stage_view_test_setup); + + g_test_add_func ("/color-management/device/basic", + meta_test_color_management_device_basic); +} + +int +main (int argc, char **argv) +{ + g_autoptr (MetaContext) context = NULL; + + context = meta_create_test_context (META_CONTEXT_TEST_TYPE_NESTED, + META_CONTEXT_TEST_FLAG_NONE); + + g_assert (meta_context_configure (context, &argc, &argv, NULL)); + + test_context = context; + + init_tests (); + + g_signal_connect (context, "before-tests", + G_CALLBACK (on_before_tests), NULL); + + return meta_context_test_run_tests (META_CONTEXT_TEST (context), + META_TEST_RUN_FLAG_NONE); +} diff --git a/src/tests/meson.build b/src/tests/meson.build index c076eef91..1787a9c19 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -222,6 +222,11 @@ test_cases += [ 'suite': 'unit', 'sources': [ 'edid-tests.c', ], }, + { + 'name': 'color-management', + 'suite': 'unit', + 'sources': [ 'color-management-tests.c', ], + }, ] if have_native_tests diff --git a/src/tests/meta-monitor-test-utils.c b/src/tests/meta-monitor-test-utils.c index 1344f1ca4..bd30d3188 100644 --- a/src/tests/meta-monitor-test-utils.c +++ b/src/tests/meta-monitor-test-utils.c @@ -768,6 +768,15 @@ meta_create_monitor_test_setup (MetaBackend *backend, output_info->tile_info = setup->outputs[i].tile_info; output_info->panel_orientation_transform = setup->outputs[i].panel_orientation_transform; + if (setup->outputs[i].has_edid_info) + { + output_info->edid_info = g_memdup2 (&setup->outputs[i].edid_info, + sizeof (setup->outputs[i].edid_info)); + output_info->edid_checksum_md5 = + g_compute_checksum_for_data (G_CHECKSUM_MD5, + (uint8_t *) &setup->outputs[i].edid_info, + sizeof (setup->outputs[i].edid_info)); + } output = g_object_new (META_TYPE_OUTPUT_TEST, "id", (uint64_t) i, diff --git a/src/tests/meta-monitor-test-utils.h b/src/tests/meta-monitor-test-utils.h index ceae9d52a..c27c64d38 100644 --- a/src/tests/meta-monitor-test-utils.h +++ b/src/tests/meta-monitor-test-utils.h @@ -112,6 +112,8 @@ typedef struct _MonitorTestCaseOutput gboolean hotplug_mode; int suggested_x; int suggested_y; + gboolean has_edid_info; + MetaEdidInfo edid_info; } MonitorTestCaseOutput; typedef struct _MonitorTestCaseCrtc