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
=== modified file 'examples/demo_client_display_config.c'
--- examples/demo_client_display_config.c 2013-09-25 07:51:36 +0000
+++ examples/demo_client_display_config.c 2013-10-21 10:42:37 +0000
@@ -29,6 +29,7 @@
29#include <signal.h>29#include <signal.h>
30#include <string.h>30#include <string.h>
31#include <time.h>31#include <time.h>
32#include <stdlib.h>
3233
33typedef enum34typedef enum
34{35{
@@ -48,6 +49,52 @@
48 volatile sig_atomic_t reconfigure;49 volatile sig_atomic_t reconfigure;
49};50};
5051
52struct Card
53{
54 uint32_t card_id;
55 uint32_t available_outputs;
56};
57
58struct Cards
59{
60 size_t num_cards;
61 struct Card *cards;
62};
63
64static struct Cards *cards_create(struct MirDisplayConfiguration *conf)
65{
66 struct Cards *cards = (struct Cards*) calloc(1, sizeof(struct Cards));
67 cards->num_cards = conf->num_cards;
68 cards->cards = (struct Card*) calloc(cards->num_cards, sizeof(struct Card));
69
70 for (size_t i = 0; i < cards->num_cards; i++)
71 {
72 cards->cards[i].card_id = conf->cards[i].card_id;
73 cards->cards[i].available_outputs =
74 conf->cards[i].max_simultaneous_outputs;
75 }
76
77 return cards;
78}
79
80static void cards_free(struct Cards *cards)
81{
82 free(cards->cards);
83 free(cards);
84}
85
86static struct Card *cards_find_card(struct Cards *cards, uint32_t card_id)
87{
88 for (size_t i = 0; i < cards->num_cards; i++)
89 {
90 if (cards->cards[i].card_id == card_id)
91 return &cards->cards[i];
92 }
93
94 fprintf(stderr, "Error: Couldn't find card with id: %u\n", card_id);
95 abort();
96}
97
51static void print_current_configuration(MirConnection *connection)98static void print_current_configuration(MirConnection *connection)
52{99{
53 MirDisplayConfiguration *conf = mir_connection_create_display_config(connection);100 MirDisplayConfiguration *conf = mir_connection_create_display_config(connection);
@@ -101,52 +148,75 @@
101148
102static void configure_display_clone(struct MirDisplayConfiguration *conf)149static void configure_display_clone(struct MirDisplayConfiguration *conf)
103{150{
151 struct Cards *cards = cards_create(conf);
152
104 for (uint32_t i = 0; i < conf->num_outputs; i++)153 for (uint32_t i = 0; i < conf->num_outputs; i++)
105 {154 {
106 MirDisplayOutput *output = &conf->outputs[i];155 MirDisplayOutput *output = &conf->outputs[i];
107 if (output->connected && output->num_modes > 0)156 struct Card *card = cards_find_card(cards, output->card_id);
157
158 if (output->connected && output->num_modes > 0 &&
159 card->available_outputs > 0)
108 {160 {
109 output->used = 1;161 output->used = 1;
110 output->current_mode = 0;162 output->current_mode = 0;
111 output->position_x = 0;163 output->position_x = 0;
112 output->position_y = 0;164 output->position_y = 0;
165 --card->available_outputs;
113 }166 }
114 }167 }
168
169 cards_free(cards);
115}170}
116171
117static void configure_display_horizontal(struct MirDisplayConfiguration *conf)172static void configure_display_horizontal(struct MirDisplayConfiguration *conf)
118{173{
174 struct Cards *cards = cards_create(conf);
175
119 uint32_t max_x = 0;176 uint32_t max_x = 0;
120 for (uint32_t i = 0; i < conf->num_outputs; i++)177 for (uint32_t i = 0; i < conf->num_outputs; i++)
121 {178 {
122 MirDisplayOutput *output = &conf->outputs[i];179 MirDisplayOutput *output = &conf->outputs[i];
123 if (output->connected && output->num_modes > 0)180 struct Card *card = cards_find_card(cards, output->card_id);
181
182 if (output->connected && output->num_modes > 0 &&
183 card->available_outputs > 0)
124 {184 {
125 output->used = 1;185 output->used = 1;
126 output->current_mode = 0;186 output->current_mode = 0;
127 output->position_x = max_x;187 output->position_x = max_x;
128 output->position_y = 0;188 output->position_y = 0;
129 max_x += output->modes[0].horizontal_resolution;189 max_x += output->modes[0].horizontal_resolution;
190 --card->available_outputs;
130 }191 }
131 }192 }
132193
194 cards_free(cards);
133}195}
134196
135static void configure_display_vertical(struct MirDisplayConfiguration *conf)197static void configure_display_vertical(struct MirDisplayConfiguration *conf)
136{198{
199 struct Cards *cards = cards_create(conf);
200
137 uint32_t max_y = 0;201 uint32_t max_y = 0;
138 for (uint32_t i = 0; i < conf->num_outputs; i++)202 for (uint32_t i = 0; i < conf->num_outputs; i++)
139 {203 {
140 MirDisplayOutput *output = &conf->outputs[i];204 MirDisplayOutput *output = &conf->outputs[i];
141 if (output->connected && output->num_modes > 0)205 struct Card *card = cards_find_card(cards, output->card_id);
206
207 if (output->connected && output->num_modes > 0 &&
208 card->available_outputs > 0)
142 {209 {
143 output->used = 1;210 output->used = 1;
144 output->current_mode = 0;211 output->current_mode = 0;
145 output->position_x = 0;212 output->position_x = 0;
146 output->position_y = max_y;213 output->position_y = max_y;
147 max_y += output->modes[0].vertical_resolution;214 max_y += output->modes[0].vertical_resolution;
215 --card->available_outputs;
148 }216 }
149 }217 }
218
219 cards_free(cards);
150}220}
151221
152static void configure_display_single(struct MirDisplayConfiguration *conf, int output_num)222static void configure_display_single(struct MirDisplayConfiguration *conf, int output_num)
153223
=== modified file 'examples/server_configuration.cpp'
--- examples/server_configuration.cpp 2013-09-12 21:36:55 +0000
+++ examples/server_configuration.cpp 2013-10-21 10:42:37 +0000
@@ -25,6 +25,7 @@
25#include <string>25#include <string>
2626
27#include <linux/input.h>27#include <linux/input.h>
28#include <unordered_map>
2829
29namespace me = mir::examples;30namespace me = mir::examples;
30namespace mg = mir::graphics;31namespace mg = mir::graphics;
@@ -45,15 +46,24 @@
45 {46 {
46 size_t const preferred_mode_index{0};47 size_t const preferred_mode_index{0};
47 int max_x = 0;48 int max_x = 0;
49 std::unordered_map<mg::DisplayConfigurationCardId, size_t> available_outputs_for_card;
50
51 conf.for_each_card(
52 [&](mg::DisplayConfigurationCard const& card)
53 {
54 available_outputs_for_card[card.id] = card.max_simultaneous_outputs;
55 });
4856
49 conf.for_each_output(57 conf.for_each_output(
50 [&](mg::DisplayConfigurationOutput const& conf_output)58 [&](mg::DisplayConfigurationOutput const& conf_output)
51 {59 {
52 if (conf_output.connected && conf_output.modes.size() > 0)60 if (conf_output.connected && conf_output.modes.size() > 0 &&
61 available_outputs_for_card[conf_output.card_id] > 0)
53 {62 {
54 conf.configure_output(conf_output.id, true, geom::Point{max_x, 0},63 conf.configure_output(conf_output.id, true, geom::Point{max_x, 0},
55 preferred_mode_index, mir_power_mode_on);64 preferred_mode_index, mir_power_mode_on);
56 max_x += conf_output.modes[preferred_mode_index].size.width.as_int();65 max_x += conf_output.modes[preferred_mode_index].size.width.as_int();
66 --available_outputs_for_card[conf_output.card_id];
57 }67 }
58 else68 else
59 {69 {
6070
=== modified file 'src/platform/graphics/default_display_configuration_policy.cpp'
--- src/platform/graphics/default_display_configuration_policy.cpp 2013-09-12 21:36:55 +0000
+++ src/platform/graphics/default_display_configuration_policy.cpp 2013-10-21 10:42:37 +0000
@@ -19,17 +19,27 @@
19#include "mir/graphics/default_display_configuration_policy.h"19#include "mir/graphics/default_display_configuration_policy.h"
20#include "mir/graphics/display_configuration.h"20#include "mir/graphics/display_configuration.h"
2121
22#include <unordered_map>
23
22namespace mg = mir::graphics;24namespace mg = mir::graphics;
23namespace geom = mir::geometry;25namespace geom = mir::geometry;
2426
25void mg::DefaultDisplayConfigurationPolicy::apply_to(DisplayConfiguration& conf)27void mg::DefaultDisplayConfigurationPolicy::apply_to(DisplayConfiguration& conf)
26{28{
27 static MirPowerMode const default_power_state = mir_power_mode_on;29 static MirPowerMode const default_power_state = mir_power_mode_on;
30 std::unordered_map<DisplayConfigurationCardId, size_t> available_outputs_for_card;
31
32 conf.for_each_card(
33 [&](DisplayConfigurationCard const& card)
34 {
35 available_outputs_for_card[card.id] = card.max_simultaneous_outputs;
36 });
2837
29 conf.for_each_output(38 conf.for_each_output(
30 [&conf](DisplayConfigurationOutput const& conf_output)39 [&](DisplayConfigurationOutput const& conf_output)
31 {40 {
32 if (conf_output.connected && conf_output.modes.size() > 0)41 if (conf_output.connected && conf_output.modes.size() > 0 &&
42 available_outputs_for_card[conf_output.card_id] > 0)
33 {43 {
34 size_t preferred_mode_index{conf_output.preferred_mode_index};44 size_t preferred_mode_index{conf_output.preferred_mode_index};
35 if (preferred_mode_index > conf_output.modes.size())45 if (preferred_mode_index > conf_output.modes.size())
@@ -37,6 +47,8 @@
3747
38 conf.configure_output(conf_output.id, true, geom::Point(),48 conf.configure_output(conf_output.id, true, geom::Point(),
39 preferred_mode_index, default_power_state);49 preferred_mode_index, default_power_state);
50
51 --available_outputs_for_card[conf_output.card_id];
40 }52 }
41 else53 else
42 {54 {
4355
=== modified file 'tests/unit-tests/graphics/test_default_display_configuration_policy.cpp'
--- tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-09-12 21:36:55 +0000
+++ tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-10-21 10:42:37 +0000
@@ -31,8 +31,8 @@
31class MockDisplayConfiguration : public mg::DisplayConfiguration31class MockDisplayConfiguration : public mg::DisplayConfiguration
32{32{
33public:33public:
34 MockDisplayConfiguration()34 MockDisplayConfiguration(size_t max_simultaneous_outputs)
35 : card_id{1}35 : card_id{1}, max_simultaneous_outputs{max_simultaneous_outputs}
36 {36 {
37 /* Connected with modes */37 /* Connected with modes */
38 outputs.push_back(38 outputs.push_back(
@@ -114,11 +114,19 @@
114 0,114 0,
115 mir_power_mode_on115 mir_power_mode_on
116 });116 });
117
118 if (max_simultaneous_outputs == max_simultaneous_outputs_all)
119 max_simultaneous_outputs = outputs.size();
120 }
121
122 MockDisplayConfiguration()
123 : MockDisplayConfiguration{max_simultaneous_outputs_all}
124 {
117 }125 }
118126
119 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const127 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const
120 {128 {
121 f({card_id, outputs.size()});129 f({card_id, max_simultaneous_outputs});
122 }130 }
123131
124 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const132 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const
@@ -131,7 +139,9 @@
131 geom::Point, size_t, MirPowerMode));139 geom::Point, size_t, MirPowerMode));
132140
133private:141private:
142 static const size_t max_simultaneous_outputs_all{std::numeric_limits<size_t>::max()};
134 mg::DisplayConfigurationCardId const card_id;143 mg::DisplayConfigurationCardId const card_id;
144 size_t max_simultaneous_outputs;
135 std::vector<mg::DisplayConfigurationOutput> outputs;145 std::vector<mg::DisplayConfigurationOutput> outputs;
136};146};
137147
@@ -176,3 +186,25 @@
176 policy.apply_to(conf);186 policy.apply_to(conf);
177}187}
178188
189TEST(DefaultDisplayConfigurationPolicyTest, does_not_enable_more_outputs_than_supported)
190{
191 using namespace ::testing;
192
193 size_t const max_simultaneous_outputs{1};
194 mg::DefaultDisplayConfigurationPolicy policy;
195 MockDisplayConfiguration conf{max_simultaneous_outputs};
196
197 size_t output_count{0};
198 conf.for_each_output([&output_count](mg::DisplayConfigurationOutput const&)
199 {
200 ++output_count;
201 });
202
203 EXPECT_CALL(conf, configure_output(_, true, _, _, _))
204 .Times(AtMost(max_simultaneous_outputs));
205
206 EXPECT_CALL(conf, configure_output(_, false, _, _, _))
207 .Times(AtLeast(output_count - max_simultaneous_outputs));
208
209 policy.apply_to(conf);
210}

Subscribers

People subscribed via source and target branches