Mir

Merge lp:~afrantzis/mir/fix-1217877 into lp:mir

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Robert Carr
Approved revision: no longer in the source branch.
Merged at revision: 1152
Proposed branch: lp:~afrantzis/mir/fix-1217877
Merge into: lp:mir
Diff against target: 296 lines (+133/-9)
4 files modified
examples/demo_client_display_config.c (+73/-3)
examples/server_configuration.cpp (+11/-1)
src/platform/graphics/default_display_configuration_policy.cpp (+14/-2)
tests/unit-tests/graphics/test_default_display_configuration_policy.cpp (+35/-3)
To merge this branch: bzr merge lp:~afrantzis/mir/fix-1217877
Reviewer Review Type Date Requested Status
Robert Carr (community) Approve
Kevin DuBois (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Approve
Review via email: mp+191962@code.launchpad.net

Commit message

graphics,examples: Don't enable more outputs than supported when changing the display configuration

Description of the change

graphics,examples: Don't enable more outputs than supported when changing the display configuration

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

LGTM

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

looks okay to me too

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

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/demo_client_display_config.c'
2--- examples/demo_client_display_config.c 2013-09-25 07:51:36 +0000
3+++ examples/demo_client_display_config.c 2013-10-21 10:42:37 +0000
4@@ -29,6 +29,7 @@
5 #include <signal.h>
6 #include <string.h>
7 #include <time.h>
8+#include <stdlib.h>
9
10 typedef enum
11 {
12@@ -48,6 +49,52 @@
13 volatile sig_atomic_t reconfigure;
14 };
15
16+struct Card
17+{
18+ uint32_t card_id;
19+ uint32_t available_outputs;
20+};
21+
22+struct Cards
23+{
24+ size_t num_cards;
25+ struct Card *cards;
26+};
27+
28+static struct Cards *cards_create(struct MirDisplayConfiguration *conf)
29+{
30+ struct Cards *cards = (struct Cards*) calloc(1, sizeof(struct Cards));
31+ cards->num_cards = conf->num_cards;
32+ cards->cards = (struct Card*) calloc(cards->num_cards, sizeof(struct Card));
33+
34+ for (size_t i = 0; i < cards->num_cards; i++)
35+ {
36+ cards->cards[i].card_id = conf->cards[i].card_id;
37+ cards->cards[i].available_outputs =
38+ conf->cards[i].max_simultaneous_outputs;
39+ }
40+
41+ return cards;
42+}
43+
44+static void cards_free(struct Cards *cards)
45+{
46+ free(cards->cards);
47+ free(cards);
48+}
49+
50+static struct Card *cards_find_card(struct Cards *cards, uint32_t card_id)
51+{
52+ for (size_t i = 0; i < cards->num_cards; i++)
53+ {
54+ if (cards->cards[i].card_id == card_id)
55+ return &cards->cards[i];
56+ }
57+
58+ fprintf(stderr, "Error: Couldn't find card with id: %u\n", card_id);
59+ abort();
60+}
61+
62 static void print_current_configuration(MirConnection *connection)
63 {
64 MirDisplayConfiguration *conf = mir_connection_create_display_config(connection);
65@@ -101,52 +148,75 @@
66
67 static void configure_display_clone(struct MirDisplayConfiguration *conf)
68 {
69+ struct Cards *cards = cards_create(conf);
70+
71 for (uint32_t i = 0; i < conf->num_outputs; i++)
72 {
73 MirDisplayOutput *output = &conf->outputs[i];
74- if (output->connected && output->num_modes > 0)
75+ struct Card *card = cards_find_card(cards, output->card_id);
76+
77+ if (output->connected && output->num_modes > 0 &&
78+ card->available_outputs > 0)
79 {
80 output->used = 1;
81 output->current_mode = 0;
82 output->position_x = 0;
83 output->position_y = 0;
84+ --card->available_outputs;
85 }
86 }
87+
88+ cards_free(cards);
89 }
90
91 static void configure_display_horizontal(struct MirDisplayConfiguration *conf)
92 {
93+ struct Cards *cards = cards_create(conf);
94+
95 uint32_t max_x = 0;
96 for (uint32_t i = 0; i < conf->num_outputs; i++)
97 {
98 MirDisplayOutput *output = &conf->outputs[i];
99- if (output->connected && output->num_modes > 0)
100+ struct Card *card = cards_find_card(cards, output->card_id);
101+
102+ if (output->connected && output->num_modes > 0 &&
103+ card->available_outputs > 0)
104 {
105 output->used = 1;
106 output->current_mode = 0;
107 output->position_x = max_x;
108 output->position_y = 0;
109 max_x += output->modes[0].horizontal_resolution;
110+ --card->available_outputs;
111 }
112 }
113
114+ cards_free(cards);
115 }
116
117 static void configure_display_vertical(struct MirDisplayConfiguration *conf)
118 {
119+ struct Cards *cards = cards_create(conf);
120+
121 uint32_t max_y = 0;
122 for (uint32_t i = 0; i < conf->num_outputs; i++)
123 {
124 MirDisplayOutput *output = &conf->outputs[i];
125- if (output->connected && output->num_modes > 0)
126+ struct Card *card = cards_find_card(cards, output->card_id);
127+
128+ if (output->connected && output->num_modes > 0 &&
129+ card->available_outputs > 0)
130 {
131 output->used = 1;
132 output->current_mode = 0;
133 output->position_x = 0;
134 output->position_y = max_y;
135 max_y += output->modes[0].vertical_resolution;
136+ --card->available_outputs;
137 }
138 }
139+
140+ cards_free(cards);
141 }
142
143 static void configure_display_single(struct MirDisplayConfiguration *conf, int output_num)
144
145=== modified file 'examples/server_configuration.cpp'
146--- examples/server_configuration.cpp 2013-09-12 21:36:55 +0000
147+++ examples/server_configuration.cpp 2013-10-21 10:42:37 +0000
148@@ -25,6 +25,7 @@
149 #include <string>
150
151 #include <linux/input.h>
152+#include <unordered_map>
153
154 namespace me = mir::examples;
155 namespace mg = mir::graphics;
156@@ -45,15 +46,24 @@
157 {
158 size_t const preferred_mode_index{0};
159 int max_x = 0;
160+ std::unordered_map<mg::DisplayConfigurationCardId, size_t> available_outputs_for_card;
161+
162+ conf.for_each_card(
163+ [&](mg::DisplayConfigurationCard const& card)
164+ {
165+ available_outputs_for_card[card.id] = card.max_simultaneous_outputs;
166+ });
167
168 conf.for_each_output(
169 [&](mg::DisplayConfigurationOutput const& conf_output)
170 {
171- if (conf_output.connected && conf_output.modes.size() > 0)
172+ if (conf_output.connected && conf_output.modes.size() > 0 &&
173+ available_outputs_for_card[conf_output.card_id] > 0)
174 {
175 conf.configure_output(conf_output.id, true, geom::Point{max_x, 0},
176 preferred_mode_index, mir_power_mode_on);
177 max_x += conf_output.modes[preferred_mode_index].size.width.as_int();
178+ --available_outputs_for_card[conf_output.card_id];
179 }
180 else
181 {
182
183=== modified file 'src/platform/graphics/default_display_configuration_policy.cpp'
184--- src/platform/graphics/default_display_configuration_policy.cpp 2013-09-12 21:36:55 +0000
185+++ src/platform/graphics/default_display_configuration_policy.cpp 2013-10-21 10:42:37 +0000
186@@ -19,17 +19,27 @@
187 #include "mir/graphics/default_display_configuration_policy.h"
188 #include "mir/graphics/display_configuration.h"
189
190+#include <unordered_map>
191+
192 namespace mg = mir::graphics;
193 namespace geom = mir::geometry;
194
195 void mg::DefaultDisplayConfigurationPolicy::apply_to(DisplayConfiguration& conf)
196 {
197 static MirPowerMode const default_power_state = mir_power_mode_on;
198+ std::unordered_map<DisplayConfigurationCardId, size_t> available_outputs_for_card;
199+
200+ conf.for_each_card(
201+ [&](DisplayConfigurationCard const& card)
202+ {
203+ available_outputs_for_card[card.id] = card.max_simultaneous_outputs;
204+ });
205
206 conf.for_each_output(
207- [&conf](DisplayConfigurationOutput const& conf_output)
208+ [&](DisplayConfigurationOutput const& conf_output)
209 {
210- if (conf_output.connected && conf_output.modes.size() > 0)
211+ if (conf_output.connected && conf_output.modes.size() > 0 &&
212+ available_outputs_for_card[conf_output.card_id] > 0)
213 {
214 size_t preferred_mode_index{conf_output.preferred_mode_index};
215 if (preferred_mode_index > conf_output.modes.size())
216@@ -37,6 +47,8 @@
217
218 conf.configure_output(conf_output.id, true, geom::Point(),
219 preferred_mode_index, default_power_state);
220+
221+ --available_outputs_for_card[conf_output.card_id];
222 }
223 else
224 {
225
226=== modified file 'tests/unit-tests/graphics/test_default_display_configuration_policy.cpp'
227--- tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-09-12 21:36:55 +0000
228+++ tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-10-21 10:42:37 +0000
229@@ -31,8 +31,8 @@
230 class MockDisplayConfiguration : public mg::DisplayConfiguration
231 {
232 public:
233- MockDisplayConfiguration()
234- : card_id{1}
235+ MockDisplayConfiguration(size_t max_simultaneous_outputs)
236+ : card_id{1}, max_simultaneous_outputs{max_simultaneous_outputs}
237 {
238 /* Connected with modes */
239 outputs.push_back(
240@@ -114,11 +114,19 @@
241 0,
242 mir_power_mode_on
243 });
244+
245+ if (max_simultaneous_outputs == max_simultaneous_outputs_all)
246+ max_simultaneous_outputs = outputs.size();
247+ }
248+
249+ MockDisplayConfiguration()
250+ : MockDisplayConfiguration{max_simultaneous_outputs_all}
251+ {
252 }
253
254 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const
255 {
256- f({card_id, outputs.size()});
257+ f({card_id, max_simultaneous_outputs});
258 }
259
260 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const
261@@ -131,7 +139,9 @@
262 geom::Point, size_t, MirPowerMode));
263
264 private:
265+ static const size_t max_simultaneous_outputs_all{std::numeric_limits<size_t>::max()};
266 mg::DisplayConfigurationCardId const card_id;
267+ size_t max_simultaneous_outputs;
268 std::vector<mg::DisplayConfigurationOutput> outputs;
269 };
270
271@@ -176,3 +186,25 @@
272 policy.apply_to(conf);
273 }
274
275+TEST(DefaultDisplayConfigurationPolicyTest, does_not_enable_more_outputs_than_supported)
276+{
277+ using namespace ::testing;
278+
279+ size_t const max_simultaneous_outputs{1};
280+ mg::DefaultDisplayConfigurationPolicy policy;
281+ MockDisplayConfiguration conf{max_simultaneous_outputs};
282+
283+ size_t output_count{0};
284+ conf.for_each_output([&output_count](mg::DisplayConfigurationOutput const&)
285+ {
286+ ++output_count;
287+ });
288+
289+ EXPECT_CALL(conf, configure_output(_, true, _, _, _))
290+ .Times(AtMost(max_simultaneous_outputs));
291+
292+ EXPECT_CALL(conf, configure_output(_, false, _, _, _))
293+ .Times(AtLeast(output_count - max_simultaneous_outputs));
294+
295+ policy.apply_to(conf);
296+}

Subscribers

People subscribed via source and target branches