Mir

Merge lp:~vanvugt/mir/set-subpixel into lp:mir

Proposed by Daniel van Vugt
Status: Work in progress
Proposed branch: lp:~vanvugt/mir/set-subpixel
Merge into: lp:mir
Diff against target: 195 lines (+115/-1)
6 files modified
include/client/mir_toolkit/mir_display_configuration.h (+12/-0)
src/client/display_configuration_api.cpp (+6/-0)
src/client/symbols.map (+1/-0)
src/server/frontend/session_mediator.cpp (+2/-1)
src/utils/out.c (+38/-0)
tests/acceptance-tests/test_new_display_configuration.cpp (+56/-0)
To merge this branch: bzr merge lp:~vanvugt/mir/set-subpixel
Reviewer Review Type Date Requested Status
Chris Halse Rogers Disapprove
Mir CI Bot continuous-integration Approve
Review via email: mp+317590@code.launchpad.net

Commit message

Add support for setting the subpixel arrangement.

Because many people like myself will find that the system doesn't
know how to automatically detect it.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4047
https://mir-jenkins.ubuntu.com/job/mir-ci/3011/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4021
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4108
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4098
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4098
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4098
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4048
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4048/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4048
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4048/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4048
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4048/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4048
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4048/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4048
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4048/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4048
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4048/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3011/rebuild

review: Approve (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

I'm a mild -1 on this. This is not a configuration property, and should not be a part of the configuration interface.

The shell has all the pieces it needs to implement overrides; that's an appropriate place for this functionality. I'd also fully support this being implemented in a Mir server configuration file - there is a broad need for some quirking infrastructure, and Mir could usefully provide that.

It's inappropriate for client configuration.

review: Disapprove
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

The common case this branch aims to deal with is when the detected order is "unknown" and the user must choose one (and usually HRGB will be a good guess).

We will need this branch only if the shell chooses to store the display config as a blob, so this setter would be required. If the shell goes to the trouble of translating the display config to its own storage format (with potential overrides) then yes this branch would not be required.

But there's another lesser use case of this branch, which is for shells (demo servers) that don't remember their configurations. For our demo servers, having a setter like this is the only way to avoid forcing the override and custom configuration logic into the toolkits (which is then an O(N) problem as opposed to an O(1) problem with this branch).

So to me this branch is useful right now. I understand it may prove to not be useful to Unity8, but it also doesn't hurt anyone to have this flexibility.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

And I just realised Chris is wrong. We do need this branch more than I thought...

If configuration tools don't have the ability to ever set the correct subpixel order, then clients who query the subpixel order from the display config of their current output will never be able to get the right value. And text in apps will have incorrect appearance.

Chris is assuming all monitor configuration tooling will be built into the shells, in all cases. That needlessly blocks the ability to have third-party configuration tools like mirout, and blocks our ability to do correct subpixel rendering in USC on the login screen for example. We really do need this setter.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

BTW, "Mir server configuration files" are a bad idea, as I've highlighted before. It's a bad idea because that commits all Mir servers/shells to accessing some fixed format/path for one thing which is a different format/path to all of its other configuration settings.

Mir can certainly provide some serialization helper functions, but should never imply a complete file format or location.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Yeah, “Mir server configuration file” is unclear. I meant “file that Mir loads for quirks”, something that we already do on Android. That does not make sense to be shell-specific, because it's hardware-specific rather than user configuration.

I continue to think that the functionality this branch introduces should not be implemented.

Systems are simpler when there are fewer things that can change, and fewer places where those things are changeable. Sometimes added complexity is required, but in this case toolkits already have settings to override the hardware reported values (and, indeed, I'm not sure if GTK uses the hardware reported value *at all*).

This is unnecessary complexity, and should be avoided.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

"toolkits already have settings to override the hardware reported values"

Therein lays the flaw in your suggestion. Even if every toolkit supported overrides, the user would need to learn each toolkit's override hack and apply them all. That's not very user friendly.

More user friendly is for Mir to store the override the user chose in some graphical configuration dialog, and export that to all Mir clients.

Certainly that already works if you assume all monitor configuration tooling run insides the shell process, but that's not a great assumption, and is already proven false by sufficient prior art. If the monitor configuration tool is separate to the shell process (ie. is a Mir client rather than a shell-specific client), and you want a single GUI to configure your subpixel override that all toolkits will honour, then we need this branch.

lp:~vanvugt/mir/set-subpixel updated
4048. By Daniel van Vugt

Merge latest trunk

4049. By Daniel van Vugt

Merge latest trunk

4050. By Daniel van Vugt

Merge latest trunk

Unmerged revisions

4050. By Daniel van Vugt

Merge latest trunk

4049. By Daniel van Vugt

Merge latest trunk

4048. By Daniel van Vugt

Merge latest trunk

4047. By Daniel van Vugt

Uncomment the fix. Test now passes.

4046. By Daniel van Vugt

Add a regression test (failing)

4045. By Daniel van Vugt

Correct mirout syntax help

4044. By Daniel van Vugt

Implement a fix, but commented out for now.

4043. By Daniel van Vugt

Add a subcommand to mirout

4042. By Daniel van Vugt

Prototype

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/client/mir_toolkit/mir_display_configuration.h'
--- include/client/mir_toolkit/mir_display_configuration.h 2017-02-17 08:46:05 +0000
+++ include/client/mir_toolkit/mir_display_configuration.h 2017-04-12 09:45:14 +0000
@@ -501,6 +501,18 @@
501MirSubpixelArrangement mir_output_get_subpixel_arrangement(MirOutput const* output);501MirSubpixelArrangement mir_output_get_subpixel_arrangement(MirOutput const* output);
502502
503/**503/**
504 * Set the subpixel arrangement of a display.
505 *
506 * Often it's not possible to automatically detect the subpixel arrangement
507 * of a display so one may wish to set it explicitly.
508 *
509 * \param [in] output The MirOutput to modify
510 * \param [in] sub The subpixel arrangement to set
511 */
512void mir_output_set_subpixel_arrangement(MirOutput* output,
513 MirSubpixelArrangement sub);
514
515/**
504 * Get the form-factor of a connected output.516 * Get the form-factor of a connected output.
505 *517 *
506 * This call succeeds even if the output is not connected, but may return nonsense values.518 * This call succeeds even if the output is not connected, but may return nonsense values.
507519
=== modified file 'src/client/display_configuration_api.cpp'
--- src/client/display_configuration_api.cpp 2017-02-17 08:46:05 +0000
+++ src/client/display_configuration_api.cpp 2017-04-12 09:45:14 +0000
@@ -310,6 +310,12 @@
310 return static_cast<MirSubpixelArrangement>(output->subpixel_arrangement());310 return static_cast<MirSubpixelArrangement>(output->subpixel_arrangement());
311}311}
312312
313void mir_output_set_subpixel_arrangement(MirOutput* output,
314 MirSubpixelArrangement sub)
315{
316 output->set_subpixel_arrangement(sub);
317}
318
313uint32_t mir_output_get_gamma_size(MirOutput const* output)319uint32_t mir_output_get_gamma_size(MirOutput const* output)
314{320{
315 return (output->gamma_red().size() / (sizeof(uint16_t) / sizeof(char)));321 return (output->gamma_red().size() / (sizeof(uint16_t) / sizeof(char)));
316322
=== modified file 'src/client/symbols.map'
--- src/client/symbols.map 2017-03-29 11:53:31 +0000
+++ src/client/symbols.map 2017-04-12 09:45:14 +0000
@@ -581,6 +581,7 @@
581581
582MIR_CLIENT_0.27 { # New functions in Mir 0.27 or 1.0582MIR_CLIENT_0.27 { # New functions in Mir 0.27 or 1.0
583 global:583 global:
584 mir_output_set_subpixel_arrangement;
584 mir_connection_apply_session_input_config;585 mir_connection_apply_session_input_config;
585 mir_connection_set_base_input_config;586 mir_connection_set_base_input_config;
586 mir_create_freestyle_window_spec;587 mir_create_freestyle_window_spec;
587588
=== modified file 'src/server/frontend/session_mediator.cpp'
--- src/server/frontend/session_mediator.cpp 2017-04-07 00:48:39 +0000
+++ src/server/frontend/session_mediator.cpp 2017-04-12 09:45:14 +0000
@@ -1269,7 +1269,8 @@
1269 dest.power_mode = static_cast<MirPowerMode>(src.power_mode());1269 dest.power_mode = static_cast<MirPowerMode>(src.power_mode());
1270 dest.orientation = static_cast<MirOrientation>(src.orientation());1270 dest.orientation = static_cast<MirOrientation>(src.orientation());
1271 dest.scale = src.scale_factor();1271 dest.scale = src.scale_factor();
12721272 dest.subpixel_arrangement =
1273 static_cast<MirSubpixelArrangement>(src.subpixel_arrangement());
1273 dest.gamma = {convert_string_to_gamma_curve(src.gamma_red()),1274 dest.gamma = {convert_string_to_gamma_curve(src.gamma_red()),
1274 convert_string_to_gamma_curve(src.gamma_green()),1275 convert_string_to_gamma_curve(src.gamma_green()),
1275 convert_string_to_gamma_curve(src.gamma_blue())};1276 convert_string_to_gamma_curve(src.gamma_blue())};
12761277
=== modified file 'src/utils/out.c'
--- src/utils/out.c 2017-03-28 03:49:44 +0000
+++ src/utils/out.c 2017-04-12 09:45:14 +0000
@@ -70,6 +70,7 @@
70 "HBGR",70 "HBGR",
71 "VRGB",71 "VRGB",
72 "VBGR",72 "VBGR",
73 "none",
73 };74 };
74 return ((unsigned)s < sizeof(name)/sizeof(name[0])) ? name[s]75 return ((unsigned)s < sizeof(name)/sizeof(name[0])) ? name[s]
75 : "out-of-range";76 : "out-of-range";
@@ -288,6 +289,42 @@
288 mir_output_set_orientation(target[t], orientation[i]);289 mir_output_set_orientation(target[t], orientation[i]);
289 }290 }
290 }291 }
292 else if (!strcmp(*action, "subpixel"))
293 {
294 if (++action >= action_end)
295 {
296 fprintf(stderr, "Missing parameter after `%s'\n", action[-1]);
297 return false;
298 }
299 char const* arg = *action;
300 enum {arrangements = 6};
301 static const MirSubpixelArrangement arrangement[arrangements] =
302 {
303 mir_subpixel_arrangement_unknown,
304 mir_subpixel_arrangement_horizontal_rgb,
305 mir_subpixel_arrangement_horizontal_bgr,
306 mir_subpixel_arrangement_vertical_rgb,
307 mir_subpixel_arrangement_vertical_bgr,
308 mir_subpixel_arrangement_none
309 };
310
311 int i;
312 for (i = 0; i < arrangements; ++i)
313 if (!strcmp(arg, subpixel_name(arrangement[i])))
314 break;
315
316 if (i >= arrangements)
317 {
318 fprintf(stderr, "Unknown arrangement `%s'\n", arg);
319 return false;
320 }
321 else
322 {
323 for (int t = 0; t < targets; ++t)
324 mir_output_set_subpixel_arrangement(target[t],
325 arrangement[i]);
326 }
327 }
291 else if (!strcmp(*action, "place"))328 else if (!strcmp(*action, "place"))
292 {329 {
293 int x, y;330 int x, y;
@@ -469,6 +506,7 @@
469 " place +X+Y\n"506 " place +X+Y\n"
470 " mode (WIDTHxHEIGHT | preferred) [rate HZ]\n"507 " mode (WIDTHxHEIGHT | preferred) [rate HZ]\n"
471 " rate HZ\n"508 " rate HZ\n"
509 " subpixel (unknown | HRGB | HBGR | VRGB | VBGR | none)\n"
472 , argv[0]);510 , argv[0]);
473 return 0;511 return 0;
474 }512 }
475513
=== modified file 'tests/acceptance-tests/test_new_display_configuration.cpp'
--- tests/acceptance-tests/test_new_display_configuration.cpp 2017-04-11 14:13:20 +0000
+++ tests/acceptance-tests/test_new_display_configuration.cpp 2017-04-12 09:45:14 +0000
@@ -977,6 +977,62 @@
977 client.disconnect();977 client.disconnect();
978}978}
979979
980TEST_F(DisplayConfigurationTest, client_can_set_subpixel_arrangement)
981{
982 DisplayClient client{new_connection()};
983
984 client.connect();
985
986 auto client_config = client.get_base_config();
987 int const test_arrangements = 2;
988 MirSubpixelArrangement const test_arrangement[test_arrangements] =
989 {
990 mir_subpixel_arrangement_horizontal_rgb,
991 mir_subpixel_arrangement_vertical_bgr
992 };
993
994 int const n = mir_display_config_get_num_outputs(client_config.get());
995 for (int i = 0; i < n; ++i)
996 {
997 auto output =
998 mir_display_config_get_mutable_output(client_config.get(), i);
999
1000 mir_output_set_subpixel_arrangement(output,
1001 test_arrangement[i % test_arrangements]);
1002 }
1003
1004 DisplayConfigMatchingContext context;
1005 context.matcher = [c = client_config.get()](MirDisplayConfig* conf)
1006 {
1007 EXPECT_THAT(conf, mt::DisplayConfigMatches(c));
1008 };
1009
1010 mir_connection_set_display_config_change_callback(
1011 client.connection,
1012 &new_display_config_matches,
1013 &context);
1014
1015 mir_connection_preview_base_display_configuration(client.connection,
1016 client_config.get(), 10);
1017 EXPECT_TRUE(context.done.wait_for(std::chrono::seconds(10)));
1018 mir_connection_confirm_base_display_configuration(client.connection,
1019 client_config.get());
1020
1021 std::shared_ptr<mg::DisplayConfiguration> current_config =
1022 server.the_display()->configuration();
1023
1024 current_config->for_each_output(
1025 [test_arrangement, test_arrangements, i = 0]
1026 (mg::UserDisplayConfigurationOutput& output) mutable
1027 {
1028 EXPECT_EQ(test_arrangement[i % test_arrangements],
1029 output.subpixel_arrangement);
1030 ++i;
1031 });
1032
1033 client.disconnect();
1034}
1035
980TEST_F(DisplayConfigurationTest, client_sees_server_set_gamma)1036TEST_F(DisplayConfigurationTest, client_sees_server_set_gamma)
981{1037{
982 uint32_t const size = 4;1038 uint32_t const size = 4;

Subscribers

People subscribed via source and target branches