Mir

Merge lp:~vanvugt/mir/fix-1308941 into lp:mir

Proposed by Daniel van Vugt
Status: Merged
Approved by: Alberto Aguirre
Approved revision: no longer in the source branch.
Merged at revision: 1573
Proposed branch: lp:~vanvugt/mir/fix-1308941
Merge into: lp:mir
Diff against target: 181 lines (+127/-4)
2 files modified
src/platform/graphics/mesa/real_kms_display_configuration.cpp (+19/-3)
tests/unit-tests/graphics/mesa/test_display_configuration.cpp (+108/-1)
To merge this branch: bzr merge lp:~vanvugt/mir/fix-1308941
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Approve
Alberto Aguirre (community) Approve
Alexandros Frantzis (community) Approve
Review via email: mp+217021@code.launchpad.net

Commit message

Ensure Mir remembers the current display mode even when the display is off.
So it's easy to toggle a monitor's power mode and it will stay in the
same mode. (LP: #1308941)

The one exception where current_mode_index is not restored is when the
definition of that display mode index has changed (e.g. new monitor plugged
in). When that happens, fall back to the preferred mode.

To post a comment you must log in.
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

32 + output.current_mode_index = preferred_mode_index;

We are essentially misinforming the users about the current state of their displays. That being said, we are only doing so when a display is not used or is not in the mir_power_mode_on state (the only cases were there is no current mode set), so I don't think this will cause problems. It will a bit strange when we print out display information, though (e.g. with mirout).

I can't think of a another way to provide easy power on/off, or a particular failure scenario for this approach, so OK, but we should keep an eye out for unintended consequences.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

LGTM

review: Approve
Revision history for this message
Robert Carr (robertcarr) wrote :

Hai! So desu. Arigato!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platform/graphics/mesa/real_kms_display_configuration.cpp'
2--- src/platform/graphics/mesa/real_kms_display_configuration.cpp 2014-03-26 05:48:59 +0000
3+++ src/platform/graphics/mesa/real_kms_display_configuration.cpp 2014-04-24 10:44:16 +0000
4@@ -168,8 +168,9 @@
5 kms_connector_type_to_output_type(connector.connector_type)};
6 geom::Size physical_size{connector.mmWidth, connector.mmHeight};
7 bool connected{connector.connection == DRM_MODE_CONNECTED};
8- size_t current_mode_index{std::numeric_limits<size_t>::max()};
9- size_t preferred_mode_index{std::numeric_limits<size_t>::max()};
10+ size_t const invalid_mode_index = std::numeric_limits<size_t>::max();
11+ size_t current_mode_index{invalid_mode_index};
12+ size_t preferred_mode_index{invalid_mode_index};
13 std::vector<DisplayConfigurationMode> modes;
14 std::vector<MirPixelFormat> formats {mir_pixel_format_argb_8888,
15 mir_pixel_format_xrgb_8888};
16@@ -217,11 +218,26 @@
17 {
18 auto& output = *iter;
19
20+ if (current_mode_index != invalid_mode_index)
21+ {
22+ output.current_mode_index = current_mode_index;
23+ }
24+ else if (!modes.empty() && // If empty retain old current_mode_index!
25+ ( output.current_mode_index >= modes.size() ||
26+ output.modes[output.current_mode_index] !=
27+ modes[output.current_mode_index]))
28+ {
29+ // current_mode_index is invalid and the definition of the old
30+ // current mode has also changed (different display plugged in)
31+ // so fall back to the preferred mode...
32+ output.current_mode_index = preferred_mode_index;
33+ }
34+ // else output.current_mode_index is correct and unchanged.
35+
36 output.modes = modes;
37 output.preferred_mode_index = preferred_mode_index;
38 output.physical_size_mm = physical_size;
39 output.connected = connected;
40- output.current_mode_index = current_mode_index;
41 output.current_format = mir_pixel_format_xrgb_8888;
42 }
43 }
44
45=== modified file 'tests/unit-tests/graphics/mesa/test_display_configuration.cpp'
46--- tests/unit-tests/graphics/mesa/test_display_configuration.cpp 2014-03-27 09:46:09 +0000
47+++ tests/unit-tests/graphics/mesa/test_display_configuration.cpp 2014-04-24 10:44:16 +0000
48@@ -118,6 +118,13 @@
49 /* Add the DisplayConfiguration modes corresponding to the DRM modes */
50 for (auto const& mode : modes0)
51 conf_modes0.push_back(conf_mode_from_drm_mode(mode));
52+
53+ modes1.push_back(fake::create_mode(123, 456, 138500, 2080, 1111, fake::NormalMode));
54+ modes1.push_back(fake::create_mode(789, 1011, 148500, 2200, 1125, fake::NormalMode));
55+ modes1.push_back(fake::create_mode(1213, 1415, 119000, 1840, 1080, fake::PreferredMode));
56+
57+ for (auto const& mode : modes1)
58+ conf_modes1.push_back(conf_mode_from_drm_mode(mode));
59 }
60
61 ::testing::NiceMock<mtd::MockEGL> mock_egl;
62@@ -127,6 +134,8 @@
63
64 std::vector<drmModeModeInfo> modes0;
65 std::vector<mg::DisplayConfigurationMode> conf_modes0;
66+ std::vector<drmModeModeInfo> modes1;
67+ std::vector<mg::DisplayConfigurationMode> conf_modes1;
68 std::vector<drmModeModeInfo> modes_empty;
69
70 mtf::UdevEnvironment fake_devices;
71@@ -422,7 +431,7 @@
72 false,
73 true,
74 geom::Point(),
75- std::numeric_limits<size_t>::max(),
76+ 1, // Ensure current_mode_index is remembered even still
77 mir_pixel_format_invalid,
78 mir_power_mode_on,
79 mir_orientation_normal
80@@ -531,3 +540,101 @@
81
82 EXPECT_EQ(expected_outputs_after.size(), output_count);
83 }
84+
85+TEST_F(MesaDisplayConfigurationTest, new_monitor_defaults_to_preferred_mode)
86+{
87+ using namespace ::testing;
88+
89+ uint32_t const crtc_ids[1] = {10};
90+ uint32_t const encoder_ids[2] = {20, 21};
91+ uint32_t const connector_ids[1] = {30};
92+ geom::Size const connector_physical_sizes_mm_before{480, 270};
93+ geom::Size const connector_physical_sizes_mm_after{512, 642};
94+ std::vector<uint32_t> possible_encoder_ids_empty;
95+ uint32_t const possible_crtcs_mask_empty{0};
96+ int const noutputs = 1;
97+
98+ mg::DisplayConfigurationOutput const expected_outputs_before[noutputs] =
99+ {
100+ {
101+ mg::DisplayConfigurationOutputId(connector_ids[0]),
102+ mg::DisplayConfigurationCardId{0},
103+ mg::DisplayConfigurationOutputType::composite,
104+ {},
105+ conf_modes0,
106+ 1,
107+ connector_physical_sizes_mm_before,
108+ true,
109+ true,
110+ geom::Point(),
111+ 1,
112+ mir_pixel_format_invalid,
113+ mir_power_mode_on,
114+ mir_orientation_normal
115+ },
116+ };
117+
118+ mg::DisplayConfigurationOutput const expected_outputs_after[noutputs] =
119+ {
120+ {
121+ mg::DisplayConfigurationOutputId(connector_ids[0]),
122+ mg::DisplayConfigurationCardId{0},
123+ mg::DisplayConfigurationOutputType::composite,
124+ {},
125+ conf_modes1,
126+ 2,
127+ connector_physical_sizes_mm_after,
128+ true,
129+ true,
130+ geom::Point(),
131+ 2, // current_mode_index changed to preferred as the list of
132+ // available modes has also changed
133+ mir_pixel_format_invalid,
134+ mir_power_mode_on,
135+ mir_orientation_normal
136+ },
137+ };
138+
139+ mtd::FakeDRMResources& resources(mock_drm.fake_drm);
140+
141+ resources.reset();
142+ resources.add_crtc(crtc_ids[0], modes0[1]);
143+ resources.add_encoder(encoder_ids[0], crtc_ids[0], possible_crtcs_mask_empty);
144+ resources.add_connector(connector_ids[0], DRM_MODE_CONNECTOR_Composite,
145+ DRM_MODE_CONNECTED, encoder_ids[0],
146+ modes0, possible_encoder_ids_empty,
147+ connector_physical_sizes_mm_before);
148+ resources.prepare();
149+
150+ auto display = create_display(create_platform());
151+ auto conf = display->configuration();
152+ int output_count = 0;
153+ conf->for_each_output([&](mg::DisplayConfigurationOutput const& output)
154+ {
155+ ASSERT_LT(output_count, noutputs);
156+ EXPECT_EQ(expected_outputs_before[output_count], output) << "output_count: " << output_count;
157+ ++output_count;
158+ });
159+ EXPECT_EQ(noutputs, output_count);
160+
161+ // Now simulate a change of monitor with different capabilities where the
162+ // old current_mode does not exist. Mir should choose the preferred mode.
163+ resources.reset();
164+ resources.add_crtc(crtc_ids[0], modes1[1]);
165+ resources.add_encoder(encoder_ids[0], crtc_ids[0], possible_crtcs_mask_empty);
166+ resources.add_connector(connector_ids[0], DRM_MODE_CONNECTOR_Composite,
167+ DRM_MODE_CONNECTED, encoder_ids[1],
168+ modes1, possible_encoder_ids_empty,
169+ connector_physical_sizes_mm_after);
170+ resources.prepare();
171+
172+ conf = display->configuration();
173+ output_count = 0;
174+ conf->for_each_output([&](mg::DisplayConfigurationOutput const& output)
175+ {
176+ ASSERT_LT(output_count, noutputs);
177+ EXPECT_EQ(expected_outputs_after[output_count], output) << "output_count: " << output_count;
178+ ++output_count;
179+ });
180+ EXPECT_EQ(noutputs, output_count);
181+}

Subscribers

People subscribed via source and target branches