Mir

Merge lp:~andreas-pokorny/mir/add-pixel-format-to-display-configuration into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Andreas Pokorny
Approved revision: no longer in the source branch.
Merged at revision: 1328
Proposed branch: lp:~andreas-pokorny/mir/add-pixel-format-to-display-configuration
Merge into: lp:mir
Prerequisite: lp:~andreas-pokorny/mir/pixel-format-utils
Diff against target: 1838 lines (+481/-326)
40 files modified
debian/control (+2/-2)
debian/libmirclient5.install (+1/-1)
examples/demo-shell/window_manager.cpp (+2/-1)
examples/server_configuration.cpp (+8/-4)
include/platform/mir/graphics/display_configuration.h (+5/-4)
include/shared/mir_toolkit/client_types.h (+1/-1)
include/test/mir_test_doubles/null_display_configuration.h (+7/-7)
include/test/mir_test_doubles/stub_display_configuration.h (+6/-5)
src/client/CMakeLists.txt (+1/-1)
src/client/display_configuration.cpp (+1/-1)
src/platform/graphics/android/android_display_configuration.cpp (+9/-3)
src/platform/graphics/android/android_display_configuration.h (+4/-3)
src/platform/graphics/mesa/real_kms_display_configuration.cpp (+21/-5)
src/platform/graphics/mesa/real_kms_display_configuration.h (+4/-4)
src/server/frontend/protobuf_buffer_packer.cpp (+1/-1)
src/server/frontend/session_mediator.cpp (+4/-1)
src/server/graphics/default_display_configuration_policy.cpp (+53/-14)
src/server/graphics/nested/nested_display.cpp (+42/-57)
src/server/graphics/nested/nested_display.h (+6/-5)
src/server/graphics/nested/nested_display_configuration.cpp (+24/-5)
src/server/graphics/nested/nested_display_configuration.h (+3/-3)
src/server/graphics/nested/nested_output.cpp (+3/-2)
src/server/graphics/nested/nested_output.h (+2/-1)
src/server/graphics/nested/nested_platform.cpp (+2/-2)
src/server/graphics/nested/nested_platform.h (+5/-5)
src/server/graphics/offscreen/display_configuration.cpp (+4/-2)
src/server/graphics/offscreen/display_configuration.h (+4/-4)
src/server/scene/mediating_display_changer.cpp (+1/-0)
tests/acceptance-tests/test_client_library.cpp (+1/-1)
tests/mir_test/display_config_matchers.cpp (+5/-5)
tests/mir_test_framework/stubbed_server_configuration.cpp (+1/-1)
tests/unit-tests/frontend/test_session_mediator.cpp (+7/-3)
tests/unit-tests/graphics/android/test_android_fb.cpp (+22/-22)
tests/unit-tests/graphics/mesa/test_cursor.cpp (+7/-7)
tests/unit-tests/graphics/mesa/test_display_configuration.cpp (+7/-7)
tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp (+16/-6)
tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp (+2/-2)
tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp (+27/-11)
tests/unit-tests/graphics/test_default_display_configuration_policy.cpp (+159/-116)
tests/unit-tests/graphics/test_display_configuration.cpp (+1/-1)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/add-pixel-format-to-display-configuration
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Approve
Alan Griffiths Abstain
Robert Carr (community) Approve
Review via email: mp+200294@code.launchpad.net

This proposal supersedes a proposal from 2014-01-02.

Commit message

Adds a mir pixel format parameter to DisplayConfiguration::configure_output

So within DisplayConfigurationPolicy the format can be specified for each output.
The pixel format parameter is still ignored by android and also mesa to some degree,
which only validates it. It is supported by nested display. The default configuration
policy implementation tries to select an opaque format though.

Description of the change

Adds a mir pixel format parameter to DisplayConfiguration::configure_output

So within DisplayConfigurationPolicy the format can be specified for each output.
The pixel format parameter is still ignored by android and also mesa to some degree,
which only validates it. It is supported by nested display. The default configuration
policy implementation tries to select an opaque format though.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

LGTM. A few small comments:

1. It's a shame that all these updates to configure_output are making the diff noisy. It's not entirely clear to me why the PixelFormat needs to go through the configure_output call besides the deficiencies of the interface (no other way from frontend to the nested surfaces). Conceptually it doesn't seem to match. You aren't creating that here though.

2.
"+using namespace mir::graphics;"
253 +namespace mesa
etc...

Unless there has been a recent change Mir style is not to do this and use the aliases. Maybe we should be open to changing this. I'm not fond of using namespace, but could be happy to enclose implementations in namespace scopes in C++ files.

3. This is another thing that you aren't causing, as there seems to be a lot of inconsistency in this area of the code anyway...there are some indentation "errors" though

+ virtual void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
+ size_t mode_index, MirPixelFormat format, MirPowerMode power_mode) = 0;

Typically mir style is instead:
+ virtual void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
+ size_t mode_index, MirPixelFormat format, MirPowerMode power_mode) = 0;

That is to say just follow the 4 space indentation rather than align. Obviously this code isn't respecting that to start though, and I have a feeling it might be my fault so no blocking there ;)

I'll approve but can someone else comment on the namespacing before we top approve?

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

1) My first attempt introduced a separate interface that would only serve the purpose of configuring the pixel format iirc. That one got reject in favour of adding a parameter to configure_output

2) wrt: +using mir::graphics it was mg = mir::graphics initially and duflu indicated that we should avoid that style, and suggested "using". In the other file that I touched after that review I changed it to namespace mir { namespace ... { } } as a better compromise. We should discuss that topic.

3) I am still playing around with getting my vim cinoptions into the right shape. I thought I saw that alignment of the second line parameters in the mir style guide. http://unity.ubuntu.com/mir/cppguide/index.html?showone=Function_Declarations_and_Definitions#Function_Declarations_and_Definitions
But then again I was also told that those examples are wrong :)

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

Re:
    namespace mg=mir::graphics;
    mg::Something
Namespace aliases are cryptic in the least. We should aim to do better. I suggest a good alternative/compromise is:
    using namespace mir;
    graphics::Something
Although if it's the only "Something" used by the source file then it's even better to reduce syntactic coupling by:
    using mir::graphics::Something;
    Something
I also accept "using namespace mir::graphics" :)

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

(1) I agree in real display systems (non-nested) the pixel format is not something you choose. What you choose is a colour depth (which may or may not fully dictate the pixel format), and from that you can query what the physical pixel format is. That's if you even need it at all. In the case of OpenGL for example, you never need to know the physical display pixel format. I'm wondering if should make it more obvious that the MirPixelFormat parameter is only meaningful to nested displays?

My key concern is that although two graphics systems might look similar, one may only support RGB and the next might only support BGR. And a third might only support 16-bit colour (like i8xx GPUs). So specifying a desired pixel format is very dangerous to portability _if_ you require that the format be honored. It's not yet clear to me if we are using it in an unsafe way though.

(2) Namespaces: See previous comment

review: Needs Information
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> (1) I agree in real display systems (non-nested) the pixel format is not
> something you choose. What you choose is a colour depth (which may or may not
> fully dictate the pixel format), and from that you can query what the physical
> pixel format is. That's if you even need it at all. In the case of OpenGL for
> example, you never need to know the physical display pixel format. I'm
> wondering if should make it more obvious that the MirPixelFormat parameter is
> only meaningful to nested displays?
>
> My key concern is that although two graphics systems might look similar, one
> may only support RGB and the next might only support BGR. And a third might
> only support 16-bit colour (like i8xx GPUs). So specifying a desired pixel
> format is very dangerous to portability _if_ you require that the format be
> honored. It's not yet clear to me if we are using it in an unsafe way though.

I think neither for nested nor for the real display outputs specifying a pixel format makes
sense. What is shown on the display changes dynamically based on the content provided.
So if there is content provided by a client that can be scanned out directly the
"current pixel format" at the output as an up-front configuration makes no sense.
If we can somehow leverage more hardware composting support, we might have opaque and
 non opaque RGB buffers and YUV buffers at the same time - and no notion of "current pixel format"
on an output.

As soon as we do that (=hwc) for real displays we will also do that for the nested case.
Then we should also rework NestedDisplay and NestedOutput. Those classes should only create
buffers when the nested shell request buffers for rendering.

But right now the graphical structure (as i understand them) is:
 * there is a mir server that creates a frame buffer
 * the frame buffer contains the rendering result of the shell that draws all its visible clients
and that recursively for all levels of nested servers. Bypass is just an exception through the system.

With the hwc support we discussed in December it may become:
 * there is a mir server
 * the shell decides which set of buffers define the rendering result of the server
and that recursively for all levels of nested servers. Bypass does not exist as a special case.

At that point the "current pixel format" should no longer be part of the Output Configuration.

> (2) Namespaces: See previous comment

What is bad about to opening namespace scope inside source files of the class to be implemented?

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

(1) OK I don't care to argue about pixel format passing any more. If nesting needs it right now, then leave it. But I'd like to think we will eventually revisit it for a nicer solution.

(2) Nothing is bad about "using namespace" in most cpp files. In fact, it's very good to reduce the syntactic coupling and improve readability. There are some cases where it could be dangerous, but they're relatively rare.

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

(1) I know I said I would drop the issue, but now I notice this, my original concerns seem justified. We all know that EGL won't and can't honour the exact format. But passing it as a parameter could give easily the reader a false impression that we expect the given pixel format to be honoured.
680 +EGLConfig mgn::detail::EGLDisplayHandle::choose_windowed_es_config(MirPixelFormat format) const
681 {
682 + EGLint const nested_egl_config_attribs[] =
683 + {
684 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
685 + EGL_RED_SIZE, mg::red_channel_depth(format),
686 + EGL_GREEN_SIZE, mg::green_channel_depth(format),
687 + EGL_BLUE_SIZE, mg::blue_channel_depth(format),
688 + EGL_ALPHA_SIZE, mg::alpha_channel_depth(format),
689 + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
690 + EGL_NONE
691 + };

(2) Back on the subject of namespaces... Although I do endorse "using namespace", introducing it in existing source files can and does inflate the diff unnecessarily (like in real_kms_display_configuration.cpp). I'm not saying change it back, but just beware in future.

(4) The comment doesn't match the code:
63 /** The index in the 'pixel_format' vector of the current output pixel format. */
64 - size_t current_format_index;
65 + MirPixelFormat current_format;

(5) Unnecessary change in indentation:
88 - std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) = 0;
89 + std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) = 0;

(6) This is a client ABI break, so we need to bump MIRCLIENT_ABI and debian/* info:
101 - uint32_t current_output_format;
102 + MirPixelFormat current_output_format;

(7) Don't you mean "mode_index >= modes.size()" ?
521 + if (mode_index > modes.size())
522 + return 0;

(8) Please avoid the keyword "inline". The compiler is a better judge of that. Inlining unnecessarily just leads to binary bloat.

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

As this seems to be the MP for an argument about namespaces I'll state my reason for a (mild) preference for introducing short aliases as done by the majority of existing code:

Assume we have a header containing "namespace example { <declaration> }"

Then in an implementation we want to provide a definition.

We can do this many ways:

1. "namespace example { <definition> }"
2. "example::<definition>"
3. "namespace eg = example; eg::<definition>"

What we can't do (as it defines a different entity in global namespace) is:

4. "using namespace example; <definition>"

In the past I've seen projects trip over the "definition is an implicit declaration" trap due to mismatched names in header and implementation. (The trap is that there is no compile-time error as nothing tells the compiler that the declaration and definition are intended to reference the same thing.)

In order to get an early (compile-time) error I prefer style 2 or 3 in these cases. That approach is largely followed in the Mir codebase.

I am aware that we often have a definition in the header (typically a class def) and the equivalent of 4 works for defining member functions. My preference is for a consistent approach over a more complex rule depending upon whether the header has a definition or a declaration or whether we are defining member functions or functions.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> (1) I know I said I would drop the issue, but now I notice this, my original
> concerns seem justified. We all know that EGL won't and can't honour the exact
> format. But passing it as a parameter could give easily the reader a false
> impression that we expect the given pixel format to be honoured.
> 680 +EGLConfig
> mgn::detail::EGLDisplayHandle::choose_windowed_es_config(MirPixelFormat
> format) const
> 681 {
> 682 + EGLint const nested_egl_config_attribs[] =
> 683 + {
> 684 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
> 685 + EGL_RED_SIZE, mg::red_channel_depth(format),
> 686 + EGL_GREEN_SIZE, mg::green_channel_depth(format),
> 687 + EGL_BLUE_SIZE, mg::blue_channel_depth(format),
> 688 + EGL_ALPHA_SIZE, mg::alpha_channel_depth(format),
> 689 + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
> 690 + EGL_NONE
> 691 + };

What is your suggestion here? Make a cosmetic change and split the pixel format into four components somewhere higher in the call hierarchy? Rework the frame buffer allocation responsibility entirely? But still at some point someone requests a certain format and EGL tried to find one or more that match. The relevant piece here is that EGL_ALPHA_SIZE is zero in the right cases and non-zero in the other cases.

>
> (2) Back on the subject of namespaces... Although I do endorse "using
> namespace", introducing it in existing source files can and does inflate the
> diff unnecessarily (like in real_kms_display_configuration.cpp). I'm not
> saying change it back, but just beware in future.

That was my reaction to your complaint on mg = mir::graphics; + excessive Boy Scouting. I cannot second using using :) in most cases, but I had the impression that we should abandon the acronym-alias style - hence removed it from a file I touched afterwards.

> (4)-(8)

aye - thanks for paying so much attention!

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

(1) I don't have a suggestion for something better right now, so won't block on it. Just a concern.

(2) Now you're aware of our varying views, use your own judgement. Namespace style won't usually be a blocker, so long as you're sensible (which you are).

(4)-(8) Need fixing.

(9) You have a prerequisite on a branch which is not up for review ("Work in progress"). This means some of the diff is hidden and not visible on this page. Please ensure prerequisite branches are up for review first.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

466 +MirPixelFormat select_format(MirPixelFormat format, std::vector<MirPixelFormat> const& formats)
467 +{
468 + if (formats.empty())
469 + return mir_pixel_format_invalid;
470 +
471 + if (!mg::contains_alpha(format))
472 + return format;
473 +
474 + auto opaque_pos = std::find_if_not(formats.begin(), formats.end(), mg::contains_alpha);
475 +
476 + if (opaque_pos == formats.end())
477 + return format;
478 +
479 + return *opaque_pos;
480 +}

From the prototype I would expect that select_format() would return a format that exists in formats (or possibly fail).

What is the intent of this function? The logic seems weird - is it right?

Is failure indicated by returning 468 mir_pixel_format_invalid as in ll468-9? (If failure is an option I'd expect an exception, if not a "sensible" default.)

If format doesn't contain an alpha component it will return format regardless of whether format is in formats (unless formats is empty per check on l468).

If format does contain alpha as then it it actually uses the contents of formats to decide which format to return: It either returns an entry in formats (as I initially expected - although it doesn't prioritize what I read as the requested format) or it returns format where I expected a failure.

So the return is one of mir_pixel_format_invalid, format, or the first alpha format from formats.

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> 466 +MirPixelFormat select_format(MirPixelFormat format,
> std::vector<MirPixelFormat> const& formats)
> 467 +{
> 468 + if (formats.empty())
> 469 + return mir_pixel_format_invalid;
> 470 +
> 471 + if (!mg::contains_alpha(format))
> 472 + return format;
> 473 +
> 474 + auto opaque_pos = std::find_if_not(formats.begin(), formats.end(),
> mg::contains_alpha);
> 475 +
> 476 + if (opaque_pos == formats.end())
> 477 + return format;
> 478 +
> 479 + return *opaque_pos;
> 480 +}
>
> From the prototype I would expect that select_format() would return a format
> that exists in formats (or possibly fail).
>
> What is the intent of this function? The logic seems weird - is it right?

The idea was that default display configuration policy should try to select an opaque format where possible.
There might be multiple opaque formats, and one might be already configured - so the default policy does not
touch it.
The idea was that a decorated policy selected certain opaque format on purpose.

> Is failure indicated by returning 468 mir_pixel_format_invalid as in ll468-9?
> (If failure is an option I'd expect an exception, if not a "sensible"
> default.)

Yes, that is failure and in some graphics platforms that yields an exception (mesa, nested).
Here I was not sure how the class should behave, since all but nested ignore the value of the
configured output format.

> If format doesn't contain an alpha component it will return format regardless
> of whether format is in formats (unless formats is empty per check on l468).

Yes thats an error case that I did not handle. (It is handled in nested and mesa platform though - with an exception)

> If format does contain alpha as then it it actually uses the contents of
> formats to decide which format to return: It either returns an entry in
> formats (as I initially expected - although it doesn't prioritize what I read
> as the requested format) or it returns format where I expected a failure.

Hm if there is no opaque format in the vector it takes the preconfigured one - blindly assuming that it is part of the vector. Which would then be a format with alpha channel.

> So the return is one of mir_pixel_format_invalid, format, or the first alpha
> format from formats.

no the first non-alpha format - it uses find_if_not

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

(6) There's a real danger of external projects compiling successfully with this change, and then crashing with out-of-bounds array accesses:
127 - uint32_t current_output_format;
128 + MirPixelFormat current_output_format;
because we kept the same name and both are int-compatible but have different meanings. To remove the risk of such regressions, I suggest renaming fields; something like "current_format".

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> The idea was that default display configuration policy should try to select an
> opaque format where possible.
...
> Hm if there is no opaque format in the vector it takes the preconfigured one -
> blindly assuming that it is part of the vector. Which would then be a format
> with alpha channel.
>
> > So the return is one of mir_pixel_format_invalid, format, or the first alpha
> > format from formats.
>
> no the first non-alpha format - it uses find_if_not

I'd find it easier to follow like this:

MirPixelFormat select_opaque_format(MirPixelFormat format, std::vector<MirPixelFormat> const& formats)
{
    auto const format_in_formats = formats.end() != std::find(formats.begin(), formats.end(), format);

    if (!mg::contains_alpha(format) && format_in_formats)
        return format;

    // format is either unavailable or transparent
    auto const first_opaque = std::find_if_not(formats.begin(), formats.end(), mg::contains_alpha);

    if (first_opaque != formats.end())
        return *first_opaque;

    // only tranparent options - allow choice if available
    if (format_in_formats)
        return format;

    if (formats.size())
        return formats.at(0);

    return mir_pixel_format_invalid;
}

review: Abstain
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

yes a lot better.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) :
review: Abstain
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(9) Duplicate alias definition:
799 +namespace mgn = mg::nested;
800 namespace mgn = mir::graphics::nested;
But not important.

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
=== modified file 'debian/control'
--- debian/control 2014-01-10 05:07:43 +0000
+++ debian/control 2014-01-10 10:21:28 +0000
@@ -128,7 +128,7 @@
128 .128 .
129 Contains header files required to build Mir servers.129 Contains header files required to build Mir servers.
130130
131Package: libmirclient4131Package: libmirclient5
132Section: libs132Section: libs
133Architecture: i386 amd64 armhf arm64133Architecture: i386 amd64 armhf arm64
134Multi-Arch: same134Multi-Arch: same
@@ -146,7 +146,7 @@
146Architecture: i386 amd64 armhf arm64146Architecture: i386 amd64 armhf arm64
147Multi-Arch: same147Multi-Arch: same
148Pre-Depends: ${misc:Pre-Depends}148Pre-Depends: ${misc:Pre-Depends}
149Depends: libmirclient4 (= ${binary:Version}),149Depends: libmirclient5 (= ${binary:Version}),
150 libmirprotobuf-dev (= ${binary:Version}),150 libmirprotobuf-dev (= ${binary:Version}),
151 mircommon-dev (= ${binary:Version}),151 mircommon-dev (= ${binary:Version}),
152 ${misc:Depends},152 ${misc:Depends},
153153
=== renamed file 'debian/libmirclient4.install' => 'debian/libmirclient5.install'
--- debian/libmirclient4.install 2013-10-21 17:49:01 +0000
+++ debian/libmirclient5.install 2014-01-10 10:21:28 +0000
@@ -1,1 +1,1 @@
1usr/lib/*/libmirclient.so.41usr/lib/*/libmirclient.so.5
22
=== modified file 'examples/demo-shell/window_manager.cpp'
--- examples/demo-shell/window_manager.cpp 2014-01-10 03:23:02 +0000
+++ examples/demo-shell/window_manager.cpp 2014-01-10 10:21:28 +0000
@@ -151,8 +151,9 @@
151 power_mode = mir_power_mode_off;151 power_mode = mir_power_mode_off;
152152
153 conf->configure_output(output.id, output.used,153 conf->configure_output(output.id, output.used,
154 output.top_left, 154 output.top_left,
155 output.current_mode_index,155 output.current_mode_index,
156 output.current_format,
156 power_mode);157 power_mode);
157 });158 });
158 display_off = !display_off;159 display_off = !display_off;
159160
=== modified file 'examples/server_configuration.cpp'
--- examples/server_configuration.cpp 2013-10-21 10:40:19 +0000
+++ examples/server_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -61,14 +61,16 @@
61 available_outputs_for_card[conf_output.card_id] > 0)61 available_outputs_for_card[conf_output.card_id] > 0)
62 {62 {
63 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},
64 preferred_mode_index, mir_power_mode_on);64 preferred_mode_index, conf_output.current_format,
65 mir_power_mode_on);
65 max_x += conf_output.modes[preferred_mode_index].size.width.as_int();66 max_x += conf_output.modes[preferred_mode_index].size.width.as_int();
66 --available_outputs_for_card[conf_output.card_id];67 --available_outputs_for_card[conf_output.card_id];
67 }68 }
68 else69 else
69 {70 {
70 conf.configure_output(conf_output.id, false, conf_output.top_left,71 conf.configure_output(conf_output.id, false, conf_output.top_left,
71 conf_output.current_mode_index, mir_power_mode_on);72 conf_output.current_mode_index, conf_output.current_format,
73 mir_power_mode_on);
72 }74 }
73 });75 });
74 }76 }
@@ -88,13 +90,15 @@
88 if (!done && conf_output.connected && conf_output.modes.size() > 0)90 if (!done && conf_output.connected && conf_output.modes.size() > 0)
89 {91 {
90 conf.configure_output(conf_output.id, true, geom::Point{0, 0},92 conf.configure_output(conf_output.id, true, geom::Point{0, 0},
91 preferred_mode_index, mir_power_mode_on);93 preferred_mode_index, conf_output.current_format,
94 mir_power_mode_on);
92 done = true;95 done = true;
93 }96 }
94 else97 else
95 {98 {
96 conf.configure_output(conf_output.id, false, conf_output.top_left,99 conf.configure_output(conf_output.id, false, conf_output.top_left,
97 conf_output.current_mode_index, mir_power_mode_on);100 conf_output.current_mode_index, conf_output.current_format,
101 mir_power_mode_on);
98 }102 }
99 });103 });
100 }104 }
101105
=== modified file 'include/platform/mir/graphics/display_configuration.h'
--- include/platform/mir/graphics/display_configuration.h 2013-12-18 02:19:19 +0000
+++ include/platform/mir/graphics/display_configuration.h 2014-01-10 10:21:28 +0000
@@ -22,6 +22,7 @@
22#include "mir/int_wrapper.h"22#include "mir/int_wrapper.h"
23#include "mir/geometry/size.h"23#include "mir/geometry/size.h"
24#include "mir/geometry/point.h"24#include "mir/geometry/point.h"
25#include "mir/graphics/pixel_format_utils.h"
25#include "mir_toolkit/common.h"26#include "mir_toolkit/common.h"
2627
27#include <functional>28#include <functional>
@@ -103,8 +104,8 @@
103 geometry::Point top_left;104 geometry::Point top_left;
104 /** The index in the 'modes' vector of the current output mode. */105 /** The index in the 'modes' vector of the current output mode. */
105 size_t current_mode_index;106 size_t current_mode_index;
106 /** The index in the 'pixel_format' vector of the current output pixel format. */107 /** The current output pixel format. A matching entry should be found in the 'pixel_formats' vector*/
107 size_t current_format_index;108 MirPixelFormat current_format;
108 /** Current power mode **/109 /** Current power mode **/
109 MirPowerMode power_mode;110 MirPowerMode power_mode;
110};111};
@@ -135,8 +136,8 @@
135 virtual void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const = 0;136 virtual void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const = 0;
136137
137 /** Configures an output. */138 /** Configures an output. */
138 virtual void configure_output(DisplayConfigurationOutputId id, bool used,139 virtual void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
139 geometry::Point top_left, size_t mode_index, MirPowerMode power_mode) = 0;140 size_t mode_index, MirPixelFormat format, MirPowerMode power_mode) = 0;
140141
141protected:142protected:
142 DisplayConfiguration() = default;143 DisplayConfiguration() = default;
143144
=== modified file 'include/shared/mir_toolkit/client_types.h'
--- include/shared/mir_toolkit/client_types.h 2013-12-18 02:19:19 +0000
+++ include/shared/mir_toolkit/client_types.h 2014-01-10 10:21:28 +0000
@@ -230,7 +230,7 @@
230230
231 uint32_t num_output_formats;231 uint32_t num_output_formats;
232 MirPixelFormat* output_formats;232 MirPixelFormat* output_formats;
233 uint32_t current_output_format;233 MirPixelFormat current_format;
234234
235 uint32_t card_id;235 uint32_t card_id;
236 uint32_t output_id;236 uint32_t output_id;
237237
=== modified file 'include/test/mir_test_doubles/null_display_configuration.h'
--- include/test/mir_test_doubles/null_display_configuration.h 2013-09-12 21:36:55 +0000
+++ include/test/mir_test_doubles/null_display_configuration.h 2014-01-10 10:21:28 +0000
@@ -29,13 +29,13 @@
29{29{
30class NullDisplayConfiguration : public graphics::DisplayConfiguration30class NullDisplayConfiguration : public graphics::DisplayConfiguration
31{31{
32 void for_each_card(std::function<void(graphics::DisplayConfigurationCard const&)>) const32 void for_each_card(std::function<void(graphics::DisplayConfigurationCard const&)>) const override
33 {33 {
34 }34 }
35 void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)>) const35 void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)>) const override
36 {36 {
37 }37 }
38 void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode) override38 void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPixelFormat, MirPowerMode) override
39 {39 {
40 }40 }
41};41};
4242
=== modified file 'include/test/mir_test_doubles/stub_display_configuration.h'
--- include/test/mir_test_doubles/stub_display_configuration.h 2013-12-18 02:19:19 +0000
+++ include/test/mir_test_doubles/stub_display_configuration.h 2014-01-10 10:21:28 +0000
@@ -79,7 +79,7 @@
79 ((i % 2) == 0),79 ((i % 2) == 0),
80 ((i % 2) == 1),80 ((i % 2) == 1),
81 top_left,81 top_left,
82 mode_index, 1u,82 mode_index, pfs[0],
83 mir_power_mode_off83 mir_power_mode_off
84 };84 };
8585
@@ -107,7 +107,8 @@
107 graphics::DisplayConfigurationOutputType::vga,107 graphics::DisplayConfigurationOutputType::vga,
108 std::vector<MirPixelFormat>{mir_pixel_format_abgr_8888},108 std::vector<MirPixelFormat>{mir_pixel_format_abgr_8888},
109 {{rect.size, 60.0}},109 {{rect.size, 60.0}},
110 0, geometry::Size{}, true, true, rect.top_left, 0, 0, mir_power_mode_on110 0, geometry::Size{}, true, true, rect.top_left, 0,
111 mir_pixel_format_abgr_8888, mir_power_mode_on
111 };112 };
112113
113 outputs.push_back(output);114 outputs.push_back(output);
@@ -122,13 +123,13 @@
122 cards.push_back(card);123 cards.push_back(card);
123 }124 }
124125
125 void for_each_card(std::function<void(graphics::DisplayConfigurationCard const&)> f) const126 void for_each_card(std::function<void(graphics::DisplayConfigurationCard const&)> f) const override
126 {127 {
127 for (auto const& card : cards)128 for (auto const& card : cards)
128 f(card);129 f(card);
129 }130 }
130131
131 void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)> f) const132 void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)> f) const override
132 {133 {
133 for (auto& disp : outputs)134 for (auto& disp : outputs)
134 {135 {
@@ -136,7 +137,7 @@
136 }137 }
137 }138 }
138139
139 void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode)140 void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPixelFormat, MirPowerMode) override
140 {141 {
141 }142 }
142143
143144
=== modified file 'src/client/CMakeLists.txt'
--- src/client/CMakeLists.txt 2013-12-20 18:08:18 +0000
+++ src/client/CMakeLists.txt 2014-01-10 10:21:28 +0000
@@ -69,7 +69,7 @@
69 ${CLIENT_SOURCES}69 ${CLIENT_SOURCES}
70)70)
7171
72set(MIRCLIENT_ABI 4)72set(MIRCLIENT_ABI 5)
7373
74set_target_properties(74set_target_properties(
75 mirclient75 mirclient
7676
=== modified file 'src/client/display_configuration.cpp'
--- src/client/display_configuration.cpp 2013-12-18 02:19:19 +0000
+++ src/client/display_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -88,7 +88,7 @@
88 {88 {
89 output.output_formats[i] = static_cast<MirPixelFormat>(msg.pixel_format(i));89 output.output_formats[i] = static_cast<MirPixelFormat>(msg.pixel_format(i));
90 }90 }
91 output.current_output_format = msg.current_format();91 output.current_format = static_cast<MirPixelFormat>(msg.current_format());
9292
93 output.position_x = msg.position_x();93 output.position_x = msg.position_x();
94 output.position_y = msg.position_y();94 output.position_y = msg.position_y();
9595
=== modified file 'src/platform/graphics/android/android_display_configuration.cpp'
--- src/platform/graphics/android/android_display_configuration.cpp 2013-12-18 02:19:19 +0000
+++ src/platform/graphics/android/android_display_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -24,14 +24,20 @@
24 : configuration{mg::DisplayConfigurationOutputId{1},24 : configuration{mg::DisplayConfigurationOutputId{1},
25 mg::DisplayConfigurationCardId{0},25 mg::DisplayConfigurationCardId{0},
26 mg::DisplayConfigurationOutputType::lvds,26 mg::DisplayConfigurationOutputType::lvds,
27 {mir_pixel_format_abgr_8888},27 {
28 mir_pixel_format_abgr_8888,
29 mir_pixel_format_bgr_888,
30 mir_pixel_format_xbgr_8888
31 },
28 {mg::DisplayConfigurationMode{display_size,0.0f}},32 {mg::DisplayConfigurationMode{display_size,0.0f}},
29 0,33 0,
30 geom::Size{0,0},34 geom::Size{0,0},
31 true,35 true,
32 true,36 true,
33 geom::Point{0,0},37 geom::Point{0,0},
34 0, 0, mir_power_mode_on},38 0,
39 mir_pixel_format_abgr_8888,
40 mir_power_mode_on},
35 card{mg::DisplayConfigurationCardId{0}, 1}41 card{mg::DisplayConfigurationCardId{0}, 1}
36{42{
37}43}
@@ -62,7 +68,7 @@
62 f(configuration);68 f(configuration);
63}69}
6470
65void mga::AndroidDisplayConfiguration::configure_output(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPowerMode power_mode)71void mga::AndroidDisplayConfiguration::configure_output(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPixelFormat, MirPowerMode power_mode)
66{72{
67 configuration.power_mode = power_mode;73 configuration.power_mode = power_mode;
68}74}
6975
=== modified file 'src/platform/graphics/android/android_display_configuration.h'
--- src/platform/graphics/android/android_display_configuration.h 2013-12-18 02:19:19 +0000
+++ src/platform/graphics/android/android_display_configuration.h 2014-01-10 10:21:28 +0000
@@ -35,9 +35,10 @@
3535
36 virtual ~AndroidDisplayConfiguration() = default;36 virtual ~AndroidDisplayConfiguration() = default;
3737
38 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const;38 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;
39 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;39 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;
40 void configure_output(DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode power_mode);40 void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
41 size_t mode_index, MirPixelFormat format, MirPowerMode power_mode) override;
4142
42private:43private:
43 DisplayConfigurationOutput configuration;44 DisplayConfigurationOutput configuration;
4445
=== modified file 'src/platform/graphics/mesa/real_kms_display_configuration.cpp'
--- src/platform/graphics/mesa/real_kms_display_configuration.cpp 2013-12-18 02:19:19 +0000
+++ src/platform/graphics/mesa/real_kms_display_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -18,6 +18,7 @@
1818
19#include "real_kms_display_configuration.h"19#include "real_kms_display_configuration.h"
20#include "drm_mode_resources.h"20#include "drm_mode_resources.h"
21#include "mir/graphics/pixel_format_utils.h"
2122
22#include <cmath>23#include <cmath>
23#include <limits>24#include <limits>
@@ -65,6 +66,11 @@
65 return static_cast<mg::DisplayConfigurationOutputType>(connector_type);66 return static_cast<mg::DisplayConfigurationOutputType>(connector_type);
66}67}
6768
69bool format_available_in_pixel_formats(MirPixelFormat format, mg::DisplayConfigurationOutput const& output)
70{
71 return output.pixel_formats.end() != find(output.pixel_formats.begin(), output.pixel_formats.end(), format);
72}
73
68}74}
6975
70mgm::RealKMSDisplayConfiguration::RealKMSDisplayConfiguration(int drm_fd)76mgm::RealKMSDisplayConfiguration::RealKMSDisplayConfiguration(int drm_fd)
@@ -109,7 +115,7 @@
109void mgm::RealKMSDisplayConfiguration::configure_output(115void mgm::RealKMSDisplayConfiguration::configure_output(
110 DisplayConfigurationOutputId id, bool used,116 DisplayConfigurationOutputId id, bool used,
111 geometry::Point top_left, size_t mode_index,117 geometry::Point top_left, size_t mode_index,
112 MirPowerMode power_mode)118 MirPixelFormat format, MirPowerMode power_mode)
113{119{
114 auto iter = find_output_with_id(id);120 auto iter = find_output_with_id(id);
115121
@@ -120,9 +126,16 @@
120 if (used && mode_index >= output.modes.size())126 if (used && mode_index >= output.modes.size())
121 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));127 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));
122128
129 if (used && !valid_pixel_format(format))
130 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid format for used output"));
131
132 if (used && !format_available_in_pixel_formats(format, output))
133 BOOST_THROW_EXCEPTION(std::runtime_error("Format not available for used output"));
134
123 output.used = used;135 output.used = used;
124 output.top_left = top_left;136 output.top_left = top_left;
125 output.current_mode_index = mode_index;137 output.current_mode_index = mode_index;
138 output.current_format = format;
126 output.power_mode = power_mode;139 output.power_mode = power_mode;
127 }140 }
128 else141 else
@@ -164,7 +177,7 @@
164 DRMModeResources resources{drm_fd};177 DRMModeResources resources{drm_fd};
165178
166 size_t max_outputs = std::min(resources.num_crtcs(), resources.num_connectors());179 size_t max_outputs = std::min(resources.num_crtcs(), resources.num_connectors());
167 card = {mg::DisplayConfigurationCardId{0}, max_outputs};180 card = {DisplayConfigurationCardId{0}, max_outputs};
168181
169 resources.for_each_connector([&](DRMModeConnectorUPtr connector)182 resources.for_each_connector([&](DRMModeConnectorUPtr connector)
170 {183 {
@@ -224,7 +237,8 @@
224 {237 {
225 outputs.push_back({id, card_id, type, formats, modes, preferred_mode_index,238 outputs.push_back({id, card_id, type, formats, modes, preferred_mode_index,
226 physical_size, connected, false, geom::Point(),239 physical_size, connected, false, geom::Point(),
227 current_mode_index, 0u, mir_power_mode_on});240 current_mode_index, mir_pixel_format_xrgb_8888,
241 mir_power_mode_on});
228 }242 }
229 else243 else
230 {244 {
@@ -235,11 +249,12 @@
235 output.physical_size_mm = physical_size;249 output.physical_size_mm = physical_size;
236 output.connected = connected;250 output.connected = connected;
237 output.current_mode_index = current_mode_index;251 output.current_mode_index = current_mode_index;
252 output.current_format = mir_pixel_format_xrgb_8888;
238 }253 }
239}254}
240255
241std::vector<mg::DisplayConfigurationOutput>::iterator256std::vector<mg::DisplayConfigurationOutput>::iterator
242mgm::RealKMSDisplayConfiguration::find_output_with_id(DisplayConfigurationOutputId id)257mgm::RealKMSDisplayConfiguration::find_output_with_id(mg::DisplayConfigurationOutputId id)
243{258{
244 return std::find_if(outputs.begin(), outputs.end(),259 return std::find_if(outputs.begin(), outputs.end(),
245 [id](DisplayConfigurationOutput const& output)260 [id](DisplayConfigurationOutput const& output)
@@ -249,7 +264,7 @@
249}264}
250265
251std::vector<mg::DisplayConfigurationOutput>::const_iterator266std::vector<mg::DisplayConfigurationOutput>::const_iterator
252mgm::RealKMSDisplayConfiguration::find_output_with_id(DisplayConfigurationOutputId id) const267mgm::RealKMSDisplayConfiguration::find_output_with_id(mg::DisplayConfigurationOutputId id) const
253{268{
254 return std::find_if(outputs.begin(), outputs.end(),269 return std::find_if(outputs.begin(), outputs.end(),
255 [id](DisplayConfigurationOutput const& output)270 [id](DisplayConfigurationOutput const& output)
@@ -257,3 +272,4 @@
257 return output.id == id;272 return output.id == id;
258 });273 });
259}274}
275
260276
=== modified file 'src/platform/graphics/mesa/real_kms_display_configuration.h'
--- src/platform/graphics/mesa/real_kms_display_configuration.h 2013-12-18 02:19:19 +0000
+++ src/platform/graphics/mesa/real_kms_display_configuration.h 2014-01-10 10:21:28 +0000
@@ -37,10 +37,10 @@
37 RealKMSDisplayConfiguration(RealKMSDisplayConfiguration const& conf);37 RealKMSDisplayConfiguration(RealKMSDisplayConfiguration const& conf);
38 RealKMSDisplayConfiguration& operator=(RealKMSDisplayConfiguration const& conf);38 RealKMSDisplayConfiguration& operator=(RealKMSDisplayConfiguration const& conf);
3939
40 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const;40 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;
41 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;41 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;
42 void configure_output(DisplayConfigurationOutputId id, bool used,42 void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
43 geometry::Point top_left, size_t mode_index, MirPowerMode power_mode);43 size_t mode_index, MirPixelFormat format, MirPowerMode power_mode) override;
4444
45 uint32_t get_kms_connector_id(DisplayConfigurationOutputId id) const;45 uint32_t get_kms_connector_id(DisplayConfigurationOutputId id) const;
46 size_t get_kms_mode_index(DisplayConfigurationOutputId id, size_t conf_mode_index) const;46 size_t get_kms_mode_index(DisplayConfigurationOutputId id, size_t conf_mode_index) const;
4747
=== modified file 'src/server/frontend/protobuf_buffer_packer.cpp'
--- src/server/frontend/protobuf_buffer_packer.cpp 2013-12-18 02:19:19 +0000
+++ src/server/frontend/protobuf_buffer_packer.cpp 2014-01-10 10:21:28 +0000
@@ -64,7 +64,7 @@
64 protobuf_output.set_position_x(display_output.top_left.x.as_uint32_t());64 protobuf_output.set_position_x(display_output.top_left.x.as_uint32_t());
65 protobuf_output.set_position_y(display_output.top_left.y.as_uint32_t());65 protobuf_output.set_position_y(display_output.top_left.y.as_uint32_t());
66 protobuf_output.set_current_mode(display_output.current_mode_index);66 protobuf_output.set_current_mode(display_output.current_mode_index);
67 protobuf_output.set_current_format(display_output.current_format_index);67 protobuf_output.set_current_format(static_cast<uint32_t>(display_output.current_format));
68 protobuf_output.set_power_mode(static_cast<uint32_t>(display_output.power_mode));68 protobuf_output.set_power_mode(static_cast<uint32_t>(display_output.power_mode));
69}69}
7070
7171
=== modified file 'src/server/frontend/session_mediator.cpp'
--- src/server/frontend/session_mediator.cpp 2013-12-18 02:19:19 +0000
+++ src/server/frontend/session_mediator.cpp 2014-01-10 10:21:28 +0000
@@ -34,6 +34,7 @@
34#include "mir/graphics/platform.h"34#include "mir/graphics/platform.h"
35#include "mir/frontend/display_changer.h"35#include "mir/frontend/display_changer.h"
36#include "mir/graphics/display_configuration.h"36#include "mir/graphics/display_configuration.h"
37#include "mir/graphics/pixel_format_utils.h"
37#include "mir/graphics/platform_ipc_package.h"38#include "mir/graphics/platform_ipc_package.h"
38#include "mir/frontend/client_constants.h"39#include "mir/frontend/client_constants.h"
39#include "mir/frontend/event_sink.h"40#include "mir/frontend/event_sink.h"
@@ -321,7 +322,9 @@
321 mg::DisplayConfigurationOutputId output_id{static_cast<int>(output.output_id())};322 mg::DisplayConfigurationOutputId output_id{static_cast<int>(output.output_id())};
322 config->configure_output(output_id, output.used(),323 config->configure_output(output_id, output.used(),
323 geom::Point{output.position_x(), output.position_y()},324 geom::Point{output.position_x(), output.position_y()},
324 output.current_mode(), static_cast<MirPowerMode>(output.power_mode()));325 output.current_mode(),
326 static_cast<MirPixelFormat>(output.current_format()),
327 static_cast<MirPowerMode>(output.power_mode()));
325 }328 }
326329
327 display_changer->configure(session, config);330 display_changer->configure(session, config);
328331
=== modified file 'src/server/graphics/default_display_configuration_policy.cpp'
--- src/server/graphics/default_display_configuration_policy.cpp 2013-12-18 02:19:19 +0000
+++ src/server/graphics/default_display_configuration_policy.cpp 2014-01-10 10:21:28 +0000
@@ -18,12 +18,52 @@
1818
19#include "default_display_configuration_policy.h"19#include "default_display_configuration_policy.h"
20#include "mir/graphics/display_configuration.h"20#include "mir/graphics/display_configuration.h"
21#include "mir/graphics/pixel_format_utils.h"
2122
22#include <unordered_map>23#include <unordered_map>
24#include <algorithm>
2325
24namespace mg = mir::graphics;26namespace mg = mir::graphics;
25namespace geom = mir::geometry;27namespace geom = mir::geometry;
2628
29namespace
30{
31size_t select_mode_index(size_t mode_index, std::vector<mg::DisplayConfigurationMode> const & modes)
32{
33 if (modes.empty())
34 return std::numeric_limits<size_t>::max();
35
36 if (mode_index >= modes.size())
37 return 0;
38
39 return mode_index;
40}
41
42MirPixelFormat select_opaque_format(MirPixelFormat format, std::vector<MirPixelFormat> const& formats)
43{
44 auto const format_in_formats = formats.end() != std::find(formats.begin(), formats.end(), format);
45
46 if (!mg::contains_alpha(format) && format_in_formats)
47 return format;
48
49 // format is either unavailable or transparent
50 auto const first_opaque = std::find_if_not(formats.begin(), formats.end(), mg::contains_alpha);
51
52 if (first_opaque != formats.end())
53 return *first_opaque;
54
55 // only tranparent options - allow choice if available
56 if (format_in_formats)
57 return format;
58
59 if (formats.size())
60 return formats.at(0);
61
62 return mir_pixel_format_invalid;
63}
64
65}
66
27void mg::DefaultDisplayConfigurationPolicy::apply_to(DisplayConfiguration& conf)67void mg::DefaultDisplayConfigurationPolicy::apply_to(DisplayConfiguration& conf)
28{68{
29 static MirPowerMode const default_power_state = mir_power_mode_on;69 static MirPowerMode const default_power_state = mir_power_mode_on;
@@ -38,23 +78,22 @@
38 conf.for_each_output(78 conf.for_each_output(
39 [&](DisplayConfigurationOutput const& conf_output)79 [&](DisplayConfigurationOutput const& conf_output)
40 {80 {
41 if (conf_output.connected && conf_output.modes.size() > 0 &&81 if (!conf_output.connected || conf_output.modes.empty() ||
42 available_outputs_for_card[conf_output.card_id] > 0)82 available_outputs_for_card[conf_output.card_id] == 0)
43 {
44 size_t preferred_mode_index{conf_output.preferred_mode_index};
45 if (preferred_mode_index > conf_output.modes.size())
46 preferred_mode_index = 0;
47
48 conf.configure_output(conf_output.id, true, geom::Point(),
49 preferred_mode_index, default_power_state);
50
51 --available_outputs_for_card[conf_output.card_id];
52 }
53 else
54 {83 {
55 conf.configure_output(conf_output.id, false, conf_output.top_left,84 conf.configure_output(conf_output.id, false, conf_output.top_left,
56 conf_output.current_mode_index, default_power_state);85 conf_output.current_mode_index, conf_output.current_format,
86 default_power_state);
87 return;
57 }88 }
89
90 size_t preferred_mode_index{select_mode_index(conf_output.preferred_mode_index, conf_output.modes)};
91 MirPixelFormat format{select_opaque_format(conf_output.current_format, conf_output.pixel_formats)};
92
93 conf.configure_output(conf_output.id, true, geom::Point(), preferred_mode_index,
94 format, default_power_state);
95
96 --available_outputs_for_card[conf_output.card_id];
58 });97 });
59}98}
6099
61100
=== modified file 'src/server/graphics/nested/nested_display.cpp'
--- src/server/graphics/nested/nested_display.cpp 2013-12-20 05:06:28 +0000
+++ src/server/graphics/nested/nested_display.cpp 2014-01-10 10:21:28 +0000
@@ -22,8 +22,10 @@
22#include "mir_api_wrappers.h"22#include "mir_api_wrappers.h"
2323
24#include "mir/geometry/rectangle.h"24#include "mir/geometry/rectangle.h"
25#include "mir/graphics/pixel_format_utils.h"
25#include "mir/graphics/gl_context.h"26#include "mir/graphics/gl_context.h"
26#include "mir/graphics/surfaceless_egl_context.h"27#include "mir/graphics/surfaceless_egl_context.h"
28#include "mir/graphics/display_configuration_policy.h"
27#include "host_connection.h"29#include "host_connection.h"
2830
29#include <boost/throw_exception.hpp>31#include <boost/throw_exception.hpp>
@@ -34,45 +36,8 @@
34namespace mgnw = mir::graphics::nested::mir_api_wrappers;36namespace mgnw = mir::graphics::nested::mir_api_wrappers;
35namespace geom = mir::geometry;37namespace geom = mir::geometry;
3638
37namespace39EGLint const mgn::detail::nested_egl_context_attribs[] =
38{40{
39
40MirPixelFormat find_opaque_surface_format(MirConnection* connection)
41{
42 static unsigned const max_formats = 32;
43 MirPixelFormat formats[max_formats];
44 unsigned int valid_formats;
45
46 mir_connection_get_available_surface_formats(connection, formats,
47 max_formats, &valid_formats);
48
49 // Find an opaque surface format
50 for (auto f = formats; f != formats+valid_formats; ++f)
51 {
52 if (*f == mir_pixel_format_xbgr_8888 ||
53 *f == mir_pixel_format_xrgb_8888)
54 {
55 return *f;
56 }
57 }
58
59 BOOST_THROW_EXCEPTION(
60 std::runtime_error("Nested Mir failed to find an opaque surface format"));
61}
62
63}
64
65EGLint const mgn::detail::nested_egl_config_attribs[] = {
66 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
67 EGL_RED_SIZE, 8,
68 EGL_GREEN_SIZE, 8,
69 EGL_BLUE_SIZE, 8,
70 EGL_ALPHA_SIZE, 0,
71 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
72 EGL_NONE
73};
74
75EGLint const mgn::detail::nested_egl_context_attribs[] = {
76 EGL_CONTEXT_CLIENT_VERSION, 2,41 EGL_CONTEXT_CLIENT_VERSION, 2,
77 EGL_NONE42 EGL_NONE
78};43};
@@ -93,6 +58,8 @@
93}58}
9459
95mgn::detail::EGLDisplayHandle::EGLDisplayHandle(MirConnection* connection)60mgn::detail::EGLDisplayHandle::EGLDisplayHandle(MirConnection* connection)
61 : egl_display(EGL_NO_DISPLAY),
62 egl_context_(EGL_NO_CONTEXT)
96{63{
97 auto const native_display = (EGLNativeDisplayType) mir_connection_get_egl_native_display(connection);64 auto const native_display = (EGLNativeDisplayType) mir_connection_get_egl_native_display(connection);
98 egl_display = eglGetDisplay(native_display);65 egl_display = eglGetDisplay(native_display);
@@ -100,7 +67,7 @@
100 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to fetch EGL display."));67 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to fetch EGL display."));
101}68}
10269
103void mgn::detail::EGLDisplayHandle::initialize()70void mgn::detail::EGLDisplayHandle::initialize(MirPixelFormat format)
104{71{
105 int major;72 int major;
106 int minor;73 int minor;
@@ -110,17 +77,28 @@
110 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to initialize EGL."));77 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to initialize EGL."));
111 }78 }
11279
113 egl_context_ = eglCreateContext(egl_display, choose_config(detail::nested_egl_config_attribs), EGL_NO_CONTEXT, detail::nested_egl_context_attribs);80 egl_context_ = eglCreateContext(egl_display, choose_windowed_es_config(format), EGL_NO_CONTEXT, detail::nested_egl_context_attribs);
81
114 if (egl_context_ == EGL_NO_CONTEXT)82 if (egl_context_ == EGL_NO_CONTEXT)
115 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create shared EGL context"));83 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create shared EGL context"));
116}84}
11785
118EGLConfig mgn::detail::EGLDisplayHandle::choose_config(const EGLint attrib_list[]) const86EGLConfig mgn::detail::EGLDisplayHandle::choose_windowed_es_config(MirPixelFormat format) const
119{87{
88 EGLint const nested_egl_config_attribs[] =
89 {
90 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
91 EGL_RED_SIZE, mg::red_channel_depth(format),
92 EGL_GREEN_SIZE, mg::green_channel_depth(format),
93 EGL_BLUE_SIZE, mg::blue_channel_depth(format),
94 EGL_ALPHA_SIZE, mg::alpha_channel_depth(format),
95 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
96 EGL_NONE
97 };
120 EGLConfig result;98 EGLConfig result;
121 int n;99 int n;
122100
123 int res = eglChooseConfig(egl_display, attrib_list, &result, 1, &n);101 int res = eglChooseConfig(egl_display, nested_egl_config_attribs, &result, 1, &n);
124 if ((res != EGL_TRUE) || (n != 1))102 if ((res != EGL_TRUE) || (n != 1))
125 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to choose EGL configuration."));103 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to choose EGL configuration."));
126104
@@ -149,17 +127,18 @@
149mgn::NestedDisplay::NestedDisplay(127mgn::NestedDisplay::NestedDisplay(
150 std::shared_ptr<HostConnection> const& connection,128 std::shared_ptr<HostConnection> const& connection,
151 std::shared_ptr<input::EventFilter> const& event_handler,129 std::shared_ptr<input::EventFilter> const& event_handler,
152 std::shared_ptr<mg::DisplayReport> const& display_report) :130 std::shared_ptr<mg::DisplayReport> const& display_report,
131 std::shared_ptr<mg::DisplayConfigurationPolicy> const& initial_conf_policy) :
153 connection{connection},132 connection{connection},
154 event_handler{event_handler},133 event_handler{event_handler},
155 display_report{display_report},134 display_report{display_report},
156 egl_display{*connection},135 egl_display{*connection},
157 egl_pixel_format{find_opaque_surface_format(*connection)},
158 outputs{}136 outputs{}
159{137{
160 egl_display.initialize();138
161 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_display.egl_context());139 std::shared_ptr<DisplayConfiguration> conf(configuration());
162 configure(*configuration());140 initial_conf_policy->apply_to(*conf);
141 configure(*conf);
163}142}
164143
165mgn::NestedDisplay::~NestedDisplay() noexcept144mgn::NestedDisplay::~NestedDisplay() noexcept
@@ -178,6 +157,14 @@
178 return std::make_shared<NestedDisplayConfiguration>(mir_connection_create_display_config(*connection));157 return std::make_shared<NestedDisplayConfiguration>(mir_connection_create_display_config(*connection));
179}158}
180159
160void mgn::NestedDisplay::complete_display_initialization(MirPixelFormat format)
161{
162 if (egl_display.egl_context() != EGL_NO_CONTEXT) return;
163
164 egl_display.initialize(format);
165 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_display.egl_context());
166}
167
181void mgn::NestedDisplay::configure(mg::DisplayConfiguration const& configuration)168void mgn::NestedDisplay::configure(mg::DisplayConfiguration const& configuration)
182{169{
183 decltype(outputs) result;170 decltype(outputs) result;
@@ -193,13 +180,16 @@
193 geometry::Rectangle const area{output.top_left, output.modes[output.current_mode_index].size};180 geometry::Rectangle const area{output.top_left, output.modes[output.current_mode_index].size};
194181
195 auto const& egl_display_mode = output.modes[output.current_mode_index];182 auto const& egl_display_mode = output.modes[output.current_mode_index];
183 auto const& egl_config_format = output.current_format;
184
185 complete_display_initialization(egl_config_format);
196186
197 MirSurfaceParameters const request_params =187 MirSurfaceParameters const request_params =
198 {188 {
199 "Mir nested display",189 "Mir nested display",
200 egl_display_mode.size.width.as_int(),190 egl_display_mode.size.width.as_int(),
201 egl_display_mode.size.height.as_int(),191 egl_display_mode.size.height.as_int(),
202 egl_pixel_format,192 egl_config_format,
203 mir_buffer_usage_hardware,193 mir_buffer_usage_hardware,
204 static_cast<uint32_t>(output.id.as_value())194 static_cast<uint32_t>(output.id.as_value())
205 };195 };
@@ -213,7 +203,8 @@
213 egl_display,203 egl_display,
214 mir_surface,204 mir_surface,
215 area,205 area,
216 event_handler);206 event_handler,
207 output.current_format);
217 }208 }
218 });209 });
219210
@@ -274,13 +265,7 @@
274 return std::weak_ptr<Cursor>();265 return std::weak_ptr<Cursor>();
275}266}
276267
277namespace
278{
279}
280
281std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context()268std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context()
282{269{
283 return std::unique_ptr<mg::GLContext>{new SurfacelessEGLContext(egl_display,270 return std::unique_ptr<mg::GLContext>{new SurfacelessEGLContext(egl_display, EGL_NO_CONTEXT)};
284 detail::nested_egl_config_attribs,
285 EGL_NO_CONTEXT)};
286}271}
287272
=== modified file 'src/server/graphics/nested/nested_display.h'
--- src/server/graphics/nested/nested_display.h 2013-12-18 02:19:19 +0000
+++ src/server/graphics/nested/nested_display.h 2014-01-10 10:21:28 +0000
@@ -42,6 +42,7 @@
42{42{
43class DisplayReport;43class DisplayReport;
44class DisplayBuffer;44class DisplayBuffer;
45class DisplayConfigurationPolicy;
4546
46namespace nested47namespace nested
47{48{
@@ -67,8 +68,8 @@
67 explicit EGLDisplayHandle(MirConnection* connection);68 explicit EGLDisplayHandle(MirConnection* connection);
68 ~EGLDisplayHandle() noexcept;69 ~EGLDisplayHandle() noexcept;
6970
70 void initialize();71 void initialize(MirPixelFormat format);
71 EGLConfig choose_config(const EGLint attrib_list[]) const;72 EGLConfig choose_windowed_es_config(MirPixelFormat format) const;
72 EGLNativeWindowType native_window(EGLConfig egl_config, MirSurface* mir_surface) const;73 EGLNativeWindowType native_window(EGLConfig egl_config, MirSurface* mir_surface) const;
73 EGLContext egl_context() const;74 EGLContext egl_context() const;
74 operator EGLDisplay() const { return egl_display; }75 operator EGLDisplay() const { return egl_display; }
@@ -83,7 +84,6 @@
8384
84class NestedOutput;85class NestedOutput;
8586
86extern EGLint const nested_egl_config_attribs[];
87extern EGLint const nested_egl_context_attribs[];87extern EGLint const nested_egl_context_attribs[];
88}88}
8989
@@ -95,7 +95,8 @@
95 NestedDisplay(95 NestedDisplay(
96 std::shared_ptr<HostConnection> const& connection,96 std::shared_ptr<HostConnection> const& connection,
97 std::shared_ptr<input::EventFilter> const& event_handler,97 std::shared_ptr<input::EventFilter> const& event_handler,
98 std::shared_ptr<DisplayReport> const& display_report);98 std::shared_ptr<DisplayReport> const& display_report,
99 std::shared_ptr<DisplayConfigurationPolicy> const& conf_policy);
99100
100 ~NestedDisplay() noexcept;101 ~NestedDisplay() noexcept;
101102
@@ -124,11 +125,11 @@
124 std::shared_ptr<input::EventFilter> const event_handler;125 std::shared_ptr<input::EventFilter> const event_handler;
125 std::shared_ptr<DisplayReport> const display_report;126 std::shared_ptr<DisplayReport> const display_report;
126 detail::EGLDisplayHandle egl_display;127 detail::EGLDisplayHandle egl_display;
127 MirPixelFormat const egl_pixel_format;
128128
129 std::mutex outputs_mutex;129 std::mutex outputs_mutex;
130 std::unordered_map<DisplayConfigurationOutputId, std::shared_ptr<detail::NestedOutput>> outputs;130 std::unordered_map<DisplayConfigurationOutputId, std::shared_ptr<detail::NestedOutput>> outputs;
131 DisplayConfigurationChangeHandler my_conf_change_handler;131 DisplayConfigurationChangeHandler my_conf_change_handler;
132 void complete_display_initialization(MirPixelFormat format);
132};133};
133134
134}135}
135136
=== modified file 'src/server/graphics/nested/nested_display_configuration.cpp'
--- src/server/graphics/nested/nested_display_configuration.cpp 2013-12-18 02:19:19 +0000
+++ src/server/graphics/nested/nested_display_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -18,15 +18,26 @@
1818
19#include "nested_display_configuration.h"19#include "nested_display_configuration.h"
2020
21namespace mg = mir::graphics;21#include "mir/graphics/pixel_format_utils.h"
22namespace mgn = mg::nested;
2322
24#include <boost/throw_exception.hpp>23#include <boost/throw_exception.hpp>
2524
26#include <stdexcept>25#include <stdexcept>
27#include <algorithm>26#include <algorithm>
2827
29namespace mgn = mir::graphics::nested;28
29namespace mg = mir::graphics;
30namespace mgn = mg::nested;
31
32namespace
33{
34bool format_valid_for_output(MirDisplayOutput const& output, MirPixelFormat format)
35{
36 MirPixelFormat * end = output.output_formats + output.num_output_formats;
37 return end != std::find(output.output_formats, end, format);
38}
39
40}
3041
31mgn::NestedDisplayConfiguration::NestedDisplayConfiguration(MirDisplayConfiguration* connection) :42mgn::NestedDisplayConfiguration::NestedDisplayConfiguration(MirDisplayConfiguration* connection) :
32display_config{connection}43display_config{connection}
@@ -77,7 +88,7 @@
77 !!mir_output.used,88 !!mir_output.used,
78 geometry::Point{mir_output.position_x, mir_output.position_y},89 geometry::Point{mir_output.position_x, mir_output.position_y},
79 mir_output.current_mode,90 mir_output.current_mode,
80 mir_output.current_output_format,91 mir_output.current_format,
81 mir_output.power_mode92 mir_output.power_mode
82 };93 };
8394
@@ -86,7 +97,7 @@
86}97}
8798
88void mgn::NestedDisplayConfiguration::configure_output(DisplayConfigurationOutputId id, bool used,99void mgn::NestedDisplayConfiguration::configure_output(DisplayConfigurationOutputId id, bool used,
89 geometry::Point top_left, size_t mode_index, MirPowerMode power_mode)100 geometry::Point top_left, size_t mode_index, MirPixelFormat format, MirPowerMode power_mode)
90{101{
91 for (auto mir_output = display_config->outputs;102 for (auto mir_output = display_config->outputs;
92 mir_output != display_config->outputs+display_config->num_outputs;103 mir_output != display_config->outputs+display_config->num_outputs;
@@ -97,13 +108,21 @@
97 if (used && mode_index >= mir_output->num_modes)108 if (used && mode_index >= mir_output->num_modes)
98 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));109 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));
99110
111 if (used && !mg::valid_pixel_format(format))
112 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid format for used output"));
113
114 if (used && !format_valid_for_output(*mir_output, format))
115 BOOST_THROW_EXCEPTION(std::runtime_error("Format not available for used output"));
116
100 mir_output->used = used;117 mir_output->used = used;
101 mir_output->position_x = top_left.x.as_uint32_t();118 mir_output->position_x = top_left.x.as_uint32_t();
102 mir_output->position_y = top_left.y.as_uint32_t();119 mir_output->position_y = top_left.y.as_uint32_t();
103 mir_output->current_mode = mode_index;120 mir_output->current_mode = mode_index;
121 mir_output->current_format = format;
104 mir_output->power_mode = static_cast<MirPowerMode>(power_mode);122 mir_output->power_mode = static_cast<MirPowerMode>(power_mode);
105 return;123 return;
106 }124 }
107 }125 }
108 BOOST_THROW_EXCEPTION(std::runtime_error("Trying to configure invalid output"));126 BOOST_THROW_EXCEPTION(std::runtime_error("Trying to configure invalid output"));
109}127}
128
110129
=== modified file 'src/server/graphics/nested/nested_display_configuration.h'
--- src/server/graphics/nested/nested_display_configuration.h 2013-09-12 21:36:55 +0000
+++ src/server/graphics/nested/nested_display_configuration.h 2014-01-10 10:21:28 +0000
@@ -34,11 +34,11 @@
34 explicit NestedDisplayConfiguration(MirDisplayConfiguration* display_config);34 explicit NestedDisplayConfiguration(MirDisplayConfiguration* display_config);
35 virtual ~NestedDisplayConfiguration() noexcept;35 virtual ~NestedDisplayConfiguration() noexcept;
3636
37 void for_each_card(std::function<void(DisplayConfigurationCard const&)>) const;37 void for_each_card(std::function<void(DisplayConfigurationCard const&)>) const override;
38 void for_each_output(std::function<void(DisplayConfigurationOutput const&)>) const;38 void for_each_output(std::function<void(DisplayConfigurationOutput const&)>) const override;
3939
40 void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left, size_t mode_index,40 void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left, size_t mode_index,
41 MirPowerMode power_mode);41 MirPixelFormat format, MirPowerMode power_mode) override;
4242
43 operator MirDisplayConfiguration*() const { return display_config; }43 operator MirDisplayConfiguration*() const { return display_config; }
44private:44private:
4545
=== modified file 'src/server/graphics/nested/nested_output.cpp'
--- src/server/graphics/nested/nested_output.cpp 2013-09-23 13:37:44 +0000
+++ src/server/graphics/nested/nested_output.cpp 2014-01-10 10:21:28 +0000
@@ -41,10 +41,11 @@
41 EGLDisplayHandle const& egl_display,41 EGLDisplayHandle const& egl_display,
42 MirSurface* mir_surface,42 MirSurface* mir_surface,
43 geometry::Rectangle const& area,43 geometry::Rectangle const& area,
44 std::shared_ptr<input::EventFilter> const& event_handler) :44 std::shared_ptr<input::EventFilter> const& event_handler,
45 MirPixelFormat preferred_format) :
45 egl_display(egl_display),46 egl_display(egl_display),
46 mir_surface{mir_surface},47 mir_surface{mir_surface},
47 egl_config{egl_display.choose_config(nested_egl_config_attribs)},48 egl_config{egl_display.choose_windowed_es_config(preferred_format)},
48 egl_context{egl_display, eglCreateContext(egl_display, egl_config, egl_display.egl_context(), nested_egl_context_attribs)},49 egl_context{egl_display, eglCreateContext(egl_display, egl_config, egl_display.egl_context(), nested_egl_context_attribs)},
49 area{area.top_left, area.size},50 area{area.top_left, area.size},
50 event_handler{event_handler},51 event_handler{event_handler},
5152
=== modified file 'src/server/graphics/nested/nested_output.h'
--- src/server/graphics/nested/nested_output.h 2013-09-23 13:37:44 +0000
+++ src/server/graphics/nested/nested_output.h 2014-01-10 10:21:28 +0000
@@ -54,7 +54,8 @@
54 EGLDisplayHandle const& egl_display,54 EGLDisplayHandle const& egl_display,
55 MirSurface* mir_surface,55 MirSurface* mir_surface,
56 geometry::Rectangle const& area,56 geometry::Rectangle const& area,
57 std::shared_ptr<input::EventFilter> const& event_handler);57 std::shared_ptr<input::EventFilter> const& event_handler,
58 MirPixelFormat preferred_format);
5859
59 ~NestedOutput() noexcept;60 ~NestedOutput() noexcept;
6061
6162
=== modified file 'src/server/graphics/nested/nested_platform.cpp'
--- src/server/graphics/nested/nested_platform.cpp 2013-12-18 02:19:19 +0000
+++ src/server/graphics/nested/nested_platform.cpp 2014-01-10 10:21:28 +0000
@@ -113,9 +113,9 @@
113 return native_platform->create_buffer_allocator(buffer_initializer);113 return native_platform->create_buffer_allocator(buffer_initializer);
114}114}
115115
116std::shared_ptr<mg::Display> mgn::NestedPlatform::create_display(std::shared_ptr<mg::DisplayConfigurationPolicy> const& /*initial_conf_policy*/)116std::shared_ptr<mg::Display> mgn::NestedPlatform::create_display(std::shared_ptr<mg::DisplayConfigurationPolicy> const& conf_policy)
117{117{
118 return std::make_shared<mgn::NestedDisplay>(connection, event_handler, display_report);118 return std::make_shared<mgn::NestedDisplay>(connection, event_handler, display_report, conf_policy);
119}119}
120120
121std::shared_ptr<mg::PlatformIPCPackage> mgn::NestedPlatform::get_ipc_package()121std::shared_ptr<mg::PlatformIPCPackage> mgn::NestedPlatform::get_ipc_package()
122122
=== modified file 'src/server/graphics/nested/nested_platform.h'
--- src/server/graphics/nested/nested_platform.h 2013-12-18 02:19:19 +0000
+++ src/server/graphics/nested/nested_platform.h 2014-01-10 10:21:28 +0000
@@ -42,12 +42,12 @@
4242
43 ~NestedPlatform() noexcept;43 ~NestedPlatform() noexcept;
44 std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(44 std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(
45 std::shared_ptr<BufferInitializer> const& buffer_initializer);45 std::shared_ptr<BufferInitializer> const& buffer_initializer) override;
46 std::shared_ptr<Display> create_display(46 std::shared_ptr<Display> create_display(
47 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy);47 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) override;
48 std::shared_ptr<PlatformIPCPackage> get_ipc_package();48 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;
49 std::shared_ptr<InternalClient> create_internal_client();49 std::shared_ptr<InternalClient> create_internal_client() override;
50 void fill_ipc_package(BufferIPCPacker* packer, Buffer const* Buffer) const;50 void fill_ipc_package(BufferIPCPacker* packer, Buffer const* Buffer) const override;
51 EGLNativeDisplayType egl_native_display() const;51 EGLNativeDisplayType egl_native_display() const;
5252
53private:53private:
5454
=== modified file 'src/server/graphics/offscreen/display_configuration.cpp'
--- src/server/graphics/offscreen/display_configuration.cpp 2013-12-18 02:19:19 +0000
+++ src/server/graphics/offscreen/display_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -31,7 +31,9 @@
31 true,31 true,
32 true,32 true,
33 geom::Point{0,0},33 geom::Point{0,0},
34 0, 0, mir_power_mode_on},34 0,
35 mir_pixel_format_xrgb_8888,
36 mir_power_mode_on},
35 card{mg::DisplayConfigurationCardId{0}, 1}37 card{mg::DisplayConfigurationCardId{0}, 1}
36{38{
37}39}
@@ -67,6 +69,6 @@
67}69}
6870
69void mgo::DisplayConfiguration::configure_output(71void mgo::DisplayConfiguration::configure_output(
70 mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPowerMode)72 mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPixelFormat, MirPowerMode)
71{73{
72}74}
7375
=== modified file 'src/server/graphics/offscreen/display_configuration.h'
--- src/server/graphics/offscreen/display_configuration.h 2013-11-12 17:23:53 +0000
+++ src/server/graphics/offscreen/display_configuration.h 2014-01-10 10:21:28 +0000
@@ -33,10 +33,10 @@
33 DisplayConfiguration(DisplayConfiguration const& other);33 DisplayConfiguration(DisplayConfiguration const& other);
34 DisplayConfiguration& operator=(DisplayConfiguration const& other);34 DisplayConfiguration& operator=(DisplayConfiguration const& other);
3535
36 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const;36 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;
37 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;37 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;
38 void configure_output(DisplayConfigurationOutputId, bool, geometry::Point,38 virtual void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
39 size_t, MirPowerMode power_mode);39 size_t mode_index, MirPixelFormat format, MirPowerMode power_mode) override;
4040
41private:41private:
42 DisplayConfigurationOutput output;42 DisplayConfigurationOutput output;
4343
=== modified file 'src/server/scene/mediating_display_changer.cpp'
--- src/server/scene/mediating_display_changer.cpp 2013-12-18 02:19:19 +0000
+++ src/server/scene/mediating_display_changer.cpp 2014-01-10 10:21:28 +0000
@@ -136,6 +136,7 @@
136 conf->configure_output(output.id, output.used,136 conf->configure_output(output.id, output.used,
137 output.top_left,137 output.top_left,
138 output.current_mode_index,138 output.current_mode_index,
139 output.current_format,
139 mir_power_mode_on);140 mir_power_mode_on);
140 }141 }
141 });142 });
142143
=== modified file 'tests/acceptance-tests/test_client_library.cpp'
--- tests/acceptance-tests/test_client_library.cpp 2013-12-18 02:19:19 +0000
+++ tests/acceptance-tests/test_client_library.cpp 2014-01-10 10:21:28 +0000
@@ -885,7 +885,7 @@
885 MirDisplayOutput* disp = &configuration->outputs[i];885 MirDisplayOutput* disp = &configuration->outputs[i];
886 ASSERT_NE(nullptr, disp);886 ASSERT_NE(nullptr, disp);
887 EXPECT_GE(disp->num_modes, disp->current_mode);887 EXPECT_GE(disp->num_modes, disp->current_mode);
888 EXPECT_GE(disp->num_output_formats, disp->current_output_format);888 EXPECT_GE(disp->num_output_formats, disp->current_format);
889 }889 }
890890
891 mir_display_config_destroy(configuration);891 mir_display_config_destroy(configuration);
892892
=== modified file 'tests/mir_test/display_config_matchers.cpp'
--- tests/mir_test/display_config_matchers.cpp 2013-12-18 02:19:19 +0000
+++ tests/mir_test/display_config_matchers.cpp 2014-01-10 10:21:28 +0000
@@ -67,7 +67,7 @@
67 geom::Point{protobuf_output.position_x(),67 geom::Point{protobuf_output.position_x(),
68 protobuf_output.position_y()},68 protobuf_output.position_y()},
69 protobuf_output.current_mode(),69 protobuf_output.current_mode(),
70 protobuf_output.current_format(),70 static_cast<MirPixelFormat>(protobuf_output.current_format()),
71 static_cast<MirPowerMode>(protobuf_output.power_mode())71 static_cast<MirPowerMode>(protobuf_output.power_mode())
72 };72 };
7373
@@ -132,7 +132,7 @@
132 geom::Point{client_output.position_x,132 geom::Point{client_output.position_x,
133 client_output.position_y},133 client_output.position_y},
134 client_output.current_mode,134 client_output.current_mode,
135 client_output.current_output_format,135 client_output.current_format,
136 static_cast<MirPowerMode>(client_output.power_mode)136 static_cast<MirPowerMode>(client_output.power_mode)
137 };137 };
138138
@@ -162,20 +162,20 @@
162 }162 }
163 }163 }
164164
165 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const165 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const override
166 {166 {
167 for (auto const& card : cards)167 for (auto const& card : cards)
168 f(card);168 f(card);
169 }169 }
170170
171 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const171 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const override
172 {172 {
173 for (auto const& output : outputs)173 for (auto const& output : outputs)
174 f(output);174 f(output);
175 }175 }
176176
177 void configure_output(mg::DisplayConfigurationOutputId, bool,177 void configure_output(mg::DisplayConfigurationOutputId, bool,
178 geom::Point, size_t, MirPowerMode)178 geom::Point, size_t, MirPixelFormat, MirPowerMode) override
179 {179 {
180 }180 }
181181
182182
=== modified file 'tests/mir_test_framework/stubbed_server_configuration.cpp'
--- tests/mir_test_framework/stubbed_server_configuration.cpp 2014-01-07 03:30:47 +0000
+++ tests/mir_test_framework/stubbed_server_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -132,7 +132,7 @@
132 mg::DisplayConfigurationCardId{0},132 mg::DisplayConfigurationCardId{0},
133 mg::DisplayConfigurationOutputType::vga,133 mg::DisplayConfigurationOutputType::vga,
134 std::vector<MirPixelFormat>{mir_pixel_format_abgr_8888},134 std::vector<MirPixelFormat>{mir_pixel_format_abgr_8888},
135 modes, 0, geom::Size{}, true, true, geom::Point{0,0}, 0, 0, mir_power_mode_on};135 modes, 0, geom::Size{}, true, true, geom::Point{0,0}, 0, mir_pixel_format_abgr_8888, mir_power_mode_on};
136136
137 f(dummy_output_config);137 f(dummy_output_config);
138 }138 }
139139
=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
--- tests/unit-tests/frontend/test_session_mediator.cpp 2013-12-18 02:19:19 +0000
+++ tests/unit-tests/frontend/test_session_mediator.cpp 2014-01-10 10:21:28 +0000
@@ -83,7 +83,7 @@
83{83{
84 MOCK_CONST_METHOD1(for_each_card, void(std::function<void(mg::DisplayConfigurationCard const&)>));84 MOCK_CONST_METHOD1(for_each_card, void(std::function<void(mg::DisplayConfigurationCard const&)>));
85 MOCK_CONST_METHOD1(for_each_output, void(std::function<void(mg::DisplayConfigurationOutput const&)>));85 MOCK_CONST_METHOD1(for_each_output, void(std::function<void(mg::DisplayConfigurationOutput const&)>));
86 MOCK_METHOD5(configure_output, void(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPowerMode));86 MOCK_METHOD6(configure_output, void(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPixelFormat, MirPowerMode));
87};87};
8888
89}89}
@@ -555,6 +555,8 @@
555 bool used0 = false, used1 = true;555 bool used0 = false, used1 = true;
556 geom::Point pt0{44,22}, pt1{3,2};556 geom::Point pt0{44,22}, pt1{3,2};
557 size_t mode_index0 = 1, mode_index1 = 3;557 size_t mode_index0 = 1, mode_index1 = 3;
558 MirPixelFormat format0{mir_pixel_format_invalid};
559 MirPixelFormat format1{mir_pixel_format_argb_8888};
558 mg::DisplayConfigurationOutputId id0{6}, id1{3};560 mg::DisplayConfigurationOutputId id0{6}, id1{3};
559561
560 NiceMock<MockConfig> mock_display_config;562 NiceMock<MockConfig> mock_display_config;
@@ -568,9 +570,9 @@
568 EXPECT_CALL(*mock_display_selector, active_configuration())570 EXPECT_CALL(*mock_display_selector, active_configuration())
569 .InSequence(seq)571 .InSequence(seq)
570 .WillOnce(Return(mt::fake_shared(mock_display_config)));572 .WillOnce(Return(mt::fake_shared(mock_display_config)));
571 EXPECT_CALL(mock_display_config, configure_output(id0, used0, pt0, mode_index0, mir_power_mode_on))573 EXPECT_CALL(mock_display_config, configure_output(id0, used0, pt0, mode_index0, format0, mir_power_mode_on))
572 .InSequence(seq);574 .InSequence(seq);
573 EXPECT_CALL(mock_display_config, configure_output(id1, used1, pt1, mode_index1, mir_power_mode_off))575 EXPECT_CALL(mock_display_config, configure_output(id1, used1, pt1, mode_index1, format1, mir_power_mode_off))
574 .InSequence(seq);576 .InSequence(seq);
575 EXPECT_CALL(*mock_display_selector, configure(_,_))577 EXPECT_CALL(*mock_display_selector, configure(_,_))
576 .InSequence(seq);578 .InSequence(seq);
@@ -593,6 +595,7 @@
593 disp0->set_position_x(pt0.x.as_uint32_t());595 disp0->set_position_x(pt0.x.as_uint32_t());
594 disp0->set_position_y(pt0.y.as_uint32_t());596 disp0->set_position_y(pt0.y.as_uint32_t());
595 disp0->set_current_mode(mode_index0);597 disp0->set_current_mode(mode_index0);
598 disp0->set_current_format(format0);
596 disp0->set_power_mode(static_cast<uint32_t>(mir_power_mode_on));599 disp0->set_power_mode(static_cast<uint32_t>(mir_power_mode_on));
597600
598 auto disp1 = configuration.add_display_output();601 auto disp1 = configuration.add_display_output();
@@ -601,6 +604,7 @@
601 disp1->set_position_x(pt1.x.as_uint32_t());604 disp1->set_position_x(pt1.x.as_uint32_t());
602 disp1->set_position_y(pt1.y.as_uint32_t());605 disp1->set_position_y(pt1.y.as_uint32_t());
603 disp1->set_current_mode(mode_index1);606 disp1->set_current_mode(mode_index1);
607 disp1->set_current_format(format1);
604 disp1->set_power_mode(static_cast<uint32_t>(mir_power_mode_off));608 disp1->set_power_mode(static_cast<uint32_t>(mir_power_mode_off));
605609
606 session_mediator.configure_display(nullptr, &configuration,610 session_mediator.configure_display(nullptr, &configuration,
607611
=== modified file 'tests/unit-tests/graphics/android/test_android_fb.cpp'
--- tests/unit-tests/graphics/android/test_android_fb.cpp 2013-12-18 02:19:19 +0000
+++ tests/unit-tests/graphics/android/test_android_fb.cpp 2014-01-10 10:21:28 +0000
@@ -256,28 +256,28 @@
256 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)256 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
257 {257 {
258 configuration->configure_output(258 configuration->configure_output(
259 output.id, output.used, output.top_left, output.current_mode_index, mir_power_mode_on);259 output.id, output.used, output.top_left, output.current_mode_index, output.current_format, mir_power_mode_on);
260 });260 });
261 display.configure(*configuration);261 display.configure(*configuration);
262262
263 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)263 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
264 {264 {
265 configuration->configure_output(265 configuration->configure_output(
266 output.id, output.used, output.top_left, output.current_mode_index, mir_power_mode_standby);266 output.id, output.used, output.top_left, output.current_mode_index, output.current_format, mir_power_mode_standby);
267 });267 });
268 display.configure(*configuration);268 display.configure(*configuration);
269269
270 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)270 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
271 {271 {
272 configuration->configure_output(272 configuration->configure_output(
273 output.id, output.used, output.top_left, output.current_mode_index, mir_power_mode_off);273 output.id, output.used, output.top_left, output.current_mode_index, output.current_format, mir_power_mode_off);
274 });274 });
275 display.configure(*configuration);275 display.configure(*configuration);
276276
277 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)277 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
278 {278 {
279 configuration->configure_output(279 configuration->configure_output(
280 output.id, output.used, output.top_left, output.current_mode_index, mir_power_mode_suspend);280 output.id, output.used, output.top_left, output.current_mode_index, output.current_format, mir_power_mode_suspend);
281 });281 });
282 display.configure(*configuration);282 display.configure(*configuration);
283}283}
284284
=== modified file 'tests/unit-tests/graphics/mesa/test_cursor.cpp'
--- tests/unit-tests/graphics/mesa/test_cursor.cpp 2013-12-18 02:19:19 +0000
+++ tests/unit-tests/graphics/mesa/test_cursor.cpp 2014-01-10 10:21:28 +0000
@@ -105,7 +105,7 @@
105 true,105 true,
106 geom::Point{0, 0},106 geom::Point{0, 0},
107 1,107 1,
108 0,108 mir_pixel_format_invalid,
109 mir_power_mode_on109 mir_power_mode_on
110 });110 });
111 outputs.push_back(111 outputs.push_back(
@@ -124,33 +124,33 @@
124 true,124 true,
125 geom::Point{100, 50},125 geom::Point{100, 50},
126 0,126 0,
127 0,127 mir_pixel_format_invalid,
128 mir_power_mode_on128 mir_power_mode_on
129 });129 });
130 }130 }
131131
132 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const132 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const override
133 {133 {
134 f({card_id, outputs.size()});134 f({card_id, outputs.size()});
135 }135 }
136136
137 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const137 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const override
138 {138 {
139 for (auto const& output : outputs)139 for (auto const& output : outputs)
140 f(output);140 f(output);
141 }141 }
142142
143 void configure_output(mg::DisplayConfigurationOutputId, bool,143 void configure_output(mg::DisplayConfigurationOutputId, bool,
144 geom::Point, size_t, MirPowerMode)144 geom::Point, size_t, MirPixelFormat, MirPowerMode) override
145 {145 {
146 }146 }
147147
148 uint32_t get_kms_connector_id(mg::DisplayConfigurationOutputId id) const148 uint32_t get_kms_connector_id(mg::DisplayConfigurationOutputId id) const override
149 {149 {
150 return id.as_value();150 return id.as_value();
151 }151 }
152152
153 size_t get_kms_mode_index(mg::DisplayConfigurationOutputId, size_t conf_mode_index) const153 size_t get_kms_mode_index(mg::DisplayConfigurationOutputId, size_t conf_mode_index) const override
154 {154 {
155 return conf_mode_index;155 return conf_mode_index;
156 }156 }
157157
=== modified file 'tests/unit-tests/graphics/mesa/test_display_configuration.cpp'
--- tests/unit-tests/graphics/mesa/test_display_configuration.cpp 2013-12-18 02:19:19 +0000
+++ tests/unit-tests/graphics/mesa/test_display_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -197,7 +197,7 @@
197 true,197 true,
198 geom::Point(),198 geom::Point(),
199 1,199 1,
200 0,200 mir_pixel_format_invalid,
201 mir_power_mode_on201 mir_power_mode_on
202 },202 },
203 {203 {
@@ -212,7 +212,7 @@
212 false,212 false,
213 geom::Point(),213 geom::Point(),
214 std::numeric_limits<size_t>::max(),214 std::numeric_limits<size_t>::max(),
215 std::numeric_limits<size_t>::max(),215 mir_pixel_format_invalid,
216 mir_power_mode_on216 mir_power_mode_on
217 },217 },
218 {218 {
@@ -227,7 +227,7 @@
227 false,227 false,
228 geom::Point(),228 geom::Point(),
229 std::numeric_limits<size_t>::max(),229 std::numeric_limits<size_t>::max(),
230 std::numeric_limits<size_t>::max(),230 mir_pixel_format_invalid,
231 mir_power_mode_on231 mir_power_mode_on
232 }232 }
233 };233 };
@@ -381,7 +381,7 @@
381 true,381 true,
382 geom::Point(),382 geom::Point(),
383 1,383 1,
384 0,384 mir_pixel_format_invalid,
385 mir_power_mode_on385 mir_power_mode_on
386 },386 },
387 {387 {
@@ -396,7 +396,7 @@
396 false,396 false,
397 geom::Point(),397 geom::Point(),
398 std::numeric_limits<size_t>::max(),398 std::numeric_limits<size_t>::max(),
399 std::numeric_limits<size_t>::max(),399 mir_pixel_format_invalid,
400 mir_power_mode_on400 mir_power_mode_on
401 },401 },
402 };402 };
@@ -415,7 +415,7 @@
415 true,415 true,
416 geom::Point(),416 geom::Point(),
417 std::numeric_limits<size_t>::max(),417 std::numeric_limits<size_t>::max(),
418 std::numeric_limits<size_t>::max(),418 mir_pixel_format_invalid,
419 mir_power_mode_on419 mir_power_mode_on
420 },420 },
421 {421 {
@@ -430,7 +430,7 @@
430 false,430 false,
431 geom::Point(),431 geom::Point(),
432 1,432 1,
433 0,433 mir_pixel_format_invalid,
434 mir_power_mode_on434 mir_power_mode_on
435 },435 },
436 };436 };
437437
=== modified file 'tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp'
--- tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp 2013-12-18 02:19:19 +0000
+++ tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp 2014-01-10 10:21:28 +0000
@@ -57,12 +57,16 @@
57 if (conf_output.connected && conf_output.modes.size() > 0)57 if (conf_output.connected && conf_output.modes.size() > 0)
58 {58 {
59 conf.configure_output(conf_output.id, true, geom::Point{0, 0},59 conf.configure_output(conf_output.id, true, geom::Point{0, 0},
60 conf_output.preferred_mode_index, mir_power_mode_on);60 conf_output.preferred_mode_index,
61 conf_output.current_format,
62 mir_power_mode_on);
61 }63 }
62 else64 else
63 {65 {
64 conf.configure_output(conf_output.id, false, conf_output.top_left,66 conf.configure_output(conf_output.id, false, conf_output.top_left,
65 conf_output.current_mode_index, mir_power_mode_on);67 conf_output.current_mode_index,
68 conf_output.current_format,
69 mir_power_mode_on);
66 }70 }
67 });71 });
68 }72 }
@@ -81,13 +85,17 @@
81 if (conf_output.connected && conf_output.modes.size() > 0)85 if (conf_output.connected && conf_output.modes.size() > 0)
82 {86 {
83 conf.configure_output(conf_output.id, true, geom::Point{max_x, 0},87 conf.configure_output(conf_output.id, true, geom::Point{max_x, 0},
84 conf_output.preferred_mode_index, mir_power_mode_on);88 conf_output.preferred_mode_index,
89 conf_output.current_format,
90 mir_power_mode_on);
85 max_x += conf_output.modes[conf_output.preferred_mode_index].size.width.as_int();91 max_x += conf_output.modes[conf_output.preferred_mode_index].size.width.as_int();
86 }92 }
87 else93 else
88 {94 {
89 conf.configure_output(conf_output.id, false, conf_output.top_left,95 conf.configure_output(conf_output.id, false, conf_output.top_left,
90 conf_output.current_mode_index, mir_power_mode_on);96 conf_output.current_mode_index,
97 conf_output.current_format,
98 mir_power_mode_on);
91 }99 }
92 });100 });
93 }101 }
@@ -472,7 +480,8 @@
472 [&](mg::DisplayConfigurationOutput const& conf_output)480 [&](mg::DisplayConfigurationOutput const& conf_output)
473 {481 {
474 conf->configure_output(conf_output.id, false, conf_output.top_left,482 conf->configure_output(conf_output.id, false, conf_output.top_left,
475 conf_output.preferred_mode_index, mir_power_mode_on);483 conf_output.preferred_mode_index, mir_pixel_format_xrgb_8888,
484 mir_power_mode_on);
476 });485 });
477486
478 display->configure(*conf);487 display->configure(*conf);
@@ -508,7 +517,8 @@
508 [&](mg::DisplayConfigurationOutput const& conf_output)517 [&](mg::DisplayConfigurationOutput const& conf_output)
509 {518 {
510 conf->configure_output(conf_output.id, false, conf_output.top_left,519 conf->configure_output(conf_output.id, false, conf_output.top_left,
511 conf_output.preferred_mode_index, mir_power_mode_on);520 conf_output.preferred_mode_index, mir_pixel_format_xrgb_8888,
521 mir_power_mode_on);
512 });522 });
513523
514 display->configure(*conf);524 display->configure(*conf);
515525
=== modified file 'tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp'
--- tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp 2013-12-18 02:19:19 +0000
+++ tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp 2014-01-10 10:21:28 +0000
@@ -79,7 +79,7 @@
79 used,79 used,
80 rect.top_left,80 rect.top_left,
81 i - 1,81 i - 1,
82 0,82 mir_pixel_format_invalid,
83 mir_power_mode_on83 mir_power_mode_on
84 };84 };
8585
@@ -89,7 +89,7 @@
89 }89 }
9090
91 void configure_output(mg::DisplayConfigurationOutputId, bool,91 void configure_output(mg::DisplayConfigurationOutputId, bool,
92 geom::Point, size_t, MirPowerMode)92 geom::Point, size_t, MirPixelFormat, MirPowerMode) override
93 {93 {
94 }94 }
9595
9696
=== modified file 'tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp'
--- tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp 2013-09-12 21:36:55 +0000
+++ tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -36,7 +36,7 @@
36uint32_t const default_current_mode = 0;36uint32_t const default_current_mode = 0;
37uint32_t const default_num_output_formats = 0;37uint32_t const default_num_output_formats = 0;
38MirPixelFormat* const default_output_formats = nullptr;38MirPixelFormat* const default_output_formats = nullptr;
39uint32_t const default_current_output_format = 0;39MirPixelFormat const default_current_output_format = mir_pixel_format_abgr_8888;
40uint32_t const default_card_id = 1;40uint32_t const default_card_id = 1;
41uint32_t const second_card_id = 2;41uint32_t const second_card_id = 2;
42uint32_t const default_output_id = 0;42uint32_t const default_output_id = 0;
@@ -84,7 +84,7 @@
84 output->current_mode = 0;84 output->current_mode = 0;
85 output->num_output_formats = NoOfFormats;85 output->num_output_formats = NoOfFormats;
86 output->output_formats = format_tmp;86 output->output_formats = format_tmp;
87 output->current_output_format = 0;87 output->current_format = NoOfFormats > 0 ? formats[0] : mir_pixel_format_invalid;
88 }88 }
8989
90 template<int NoOfOutputs, int NoOfModes, int NoOfFormats>90 template<int NoOfOutputs, int NoOfModes, int NoOfFormats>
@@ -257,7 +257,7 @@
257 mgn::NestedDisplayConfiguration config(build_trivial_configuration());257 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
258258
259 config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true,259 config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true,
260 top_left, default_current_mode, mir_power_mode_on);260 top_left, default_current_mode, default_current_output_format, mir_power_mode_on);
261261
262 MockOutputVisitor ov;262 MockOutputVisitor ov;
263 EXPECT_CALL(ov, f(_)).Times(Exactly(1));263 EXPECT_CALL(ov, f(_)).Times(Exactly(1));
@@ -268,6 +268,7 @@
268 EXPECT_EQ(true, output.used);268 EXPECT_EQ(true, output.used);
269 EXPECT_EQ(top_left, output.top_left);269 EXPECT_EQ(top_left, output.top_left);
270 EXPECT_EQ(0, output.current_mode_index);270 EXPECT_EQ(0, output.current_mode_index);
271 EXPECT_EQ(default_current_output_format, output.current_format);
271 });272 });
272}273}
273274
@@ -278,11 +279,25 @@
278 mgn::NestedDisplayConfiguration config(build_trivial_configuration());279 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
279280
280 EXPECT_THROW(281 EXPECT_THROW(
281 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, -1, mir_power_mode_on);},282 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, -1, default_current_output_format, mir_power_mode_on);},
282 std::runtime_error);283 std::runtime_error);
283284
284 EXPECT_THROW(285 EXPECT_THROW(
285 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, too_big_mode_index, mir_power_mode_on);},286 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, too_big_mode_index, default_current_output_format, mir_power_mode_on);},
287 std::runtime_error);
288}
289
290TEST_F(NestedDisplayConfiguration, configure_output_rejects_invalid_format)
291{
292 geom::Point const top_left{10,20};
293 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
294
295 EXPECT_THROW(
296 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, default_current_mode, mir_pixel_format_invalid, mir_power_mode_on);},
297 std::runtime_error);
298
299 EXPECT_THROW(
300 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, default_current_mode, mir_pixel_formats, mir_power_mode_on);},
286 std::runtime_error);301 std::runtime_error);
287}302}
288303
@@ -292,11 +307,11 @@
292 mgn::NestedDisplayConfiguration config(build_trivial_configuration());307 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
293308
294 EXPECT_THROW(309 EXPECT_THROW(
295 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id+1), true, top_left, default_current_mode, mir_power_mode_on);},310 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id+1), true, top_left, default_current_mode, default_current_output_format, mir_power_mode_on);},
296 std::runtime_error);311 std::runtime_error);
297312
298 EXPECT_THROW(313 EXPECT_THROW(
299 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id-1), true, top_left, default_current_mode, mir_power_mode_on);},314 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id-1), true, top_left, default_current_mode, default_current_output_format, mir_power_mode_on);},
300 std::runtime_error);315 std::runtime_error);
301}316}
302317
@@ -326,7 +341,7 @@
326 geom::Point const top_left{100,200};341 geom::Point const top_left{100,200};
327 mgn::NestedDisplayConfiguration config(build_non_trivial_configuration());342 mgn::NestedDisplayConfiguration config(build_non_trivial_configuration());
328343
329 config.configure_output(id, true, top_left, 1, mir_power_mode_on);344 config.configure_output(id, true, top_left, 1, mir_pixel_format_argb_8888, mir_power_mode_on);
330345
331 MockOutputVisitor ov;346 MockOutputVisitor ov;
332 EXPECT_CALL(ov, f(_)).Times(Exactly(3));347 EXPECT_CALL(ov, f(_)).Times(Exactly(3));
@@ -338,6 +353,7 @@
338 EXPECT_EQ(true, output.used);353 EXPECT_EQ(true, output.used);
339 EXPECT_EQ(top_left, output.top_left);354 EXPECT_EQ(top_left, output.top_left);
340 EXPECT_EQ(1, output.current_mode_index);355 EXPECT_EQ(1, output.current_mode_index);
356 EXPECT_EQ(mir_pixel_format_argb_8888, output.current_format);
341 }357 }
342 });358 });
343}359}
344360
=== modified file 'tests/unit-tests/graphics/test_default_display_configuration_policy.cpp'
--- tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-12-18 02:19:19 +0000
+++ tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2014-01-10 10:21:28 +0000
@@ -22,149 +22,158 @@
22#include <gtest/gtest.h>22#include <gtest/gtest.h>
23#include <gmock/gmock.h>23#include <gmock/gmock.h>
2424
25namespace mg = mir::graphics;25using namespace mir::graphics;
26namespace geom = mir::geometry;26using namespace mir::geometry;
2727
28namespace28namespace
29{29{
3030
31class MockDisplayConfiguration : public mg::DisplayConfiguration31class MockDisplayConfiguration : public DisplayConfiguration
32{32{
33public:33public:
34 MockDisplayConfiguration(size_t max_simultaneous_outputs)34 MockDisplayConfiguration(MockDisplayConfiguration && m)
35 : card_id{1}, max_simultaneous_outputs{max_simultaneous_outputs}35 : max_simultaneous_outputs{m.max_simultaneous_outputs},
36 outputs{std::move(m.outputs)}
36 {37 {
37 /* Connected with modes */38 }
38 outputs.push_back(
39 {
40 mg::DisplayConfigurationOutputId{10},
41 card_id,
42 mg::DisplayConfigurationOutputType::vga,
43 {
44 mir_pixel_format_abgr_8888
45 },
46 {
47 {geom::Size{123, 111}, 59.9},
48 {geom::Size{123, 111}, 59.9},
49 {geom::Size{123, 111}, 59.9}
50 },
51 2,
52 geom::Size{324, 642},
53 true,
54 false,
55 geom::Point{geom::X{123}, geom::Y{343}},
56 1,
57 0,
58 mir_power_mode_on
59 });
60 /* Connected without modes */
61 outputs.push_back(
62 {
63 mg::DisplayConfigurationOutputId{11},
64 card_id,
65 mg::DisplayConfigurationOutputType::vga,
66 {},
67 {},
68 std::numeric_limits<size_t>::max(),
69 geom::Size{566, 111},
70 true,
71 false,
72 geom::Point(),
73 std::numeric_limits<size_t>::max(),
74 std::numeric_limits<size_t>::max(),
75 mir_power_mode_on
76 });
77 /* Connected with a single mode */
78 outputs.push_back(
79 {
80 mg::DisplayConfigurationOutputId{12},
81 card_id,
82 mg::DisplayConfigurationOutputType::vga,
83 {
84 mir_pixel_format_abgr_8888
85 },
86 {
87 {geom::Size{523, 555}, 60.0},
88 },
89 0,
90 geom::Size{324, 642},
91 true,
92 false,
93 geom::Point(),
94 0,
95 0,
96 mir_power_mode_on
97 });
98 /* Not connected */
99 outputs.push_back(
100 {
101 mg::DisplayConfigurationOutputId{13},
102 card_id,
103 mg::DisplayConfigurationOutputType::vga,
104 {
105 mir_pixel_format_abgr_8888
106 },
107 {},
108 0,
109 geom::Size{324, 642},
110 false,
111 false,
112 geom::Point(),
113 1,
114 0,
115 mir_power_mode_on
116 });
11739
40 MockDisplayConfiguration(size_t max_simultaneous_outputs, std::vector<DisplayConfigurationOutput> && config)
41 : max_simultaneous_outputs{max_simultaneous_outputs},
42 outputs{config}
43 {
118 if (max_simultaneous_outputs == max_simultaneous_outputs_all)44 if (max_simultaneous_outputs == max_simultaneous_outputs_all)
119 max_simultaneous_outputs = outputs.size();45 max_simultaneous_outputs = outputs.size();
120 }46 }
12147
122 MockDisplayConfiguration()48 MockDisplayConfiguration(std::vector<DisplayConfigurationOutput> && config)
123 : MockDisplayConfiguration{max_simultaneous_outputs_all}49 : MockDisplayConfiguration(max_simultaneous_outputs_all, std::move(config))
124 {50 {
125 }51 }
12652
127 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const53 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const
128 {54 {
129 f({card_id, max_simultaneous_outputs});55 f({DisplayConfigurationCardId{1}, max_simultaneous_outputs});
130 }56 }
13157
132 void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const58 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const
133 {59 {
134 for (auto const& output : outputs)60 for (auto const& output : outputs)
135 f(output);61 f(output);
136 }62 }
13763
138 MOCK_METHOD5(configure_output, void(mg::DisplayConfigurationOutputId, bool,64 MOCK_METHOD6(configure_output, void(DisplayConfigurationOutputId, bool,
139 geom::Point, size_t, MirPowerMode));65 Point, size_t, MirPixelFormat, MirPowerMode));
14066
67 static const size_t max_simultaneous_outputs_all{std::numeric_limits<size_t>::max()};
141private:68private:
142 static const size_t max_simultaneous_outputs_all{std::numeric_limits<size_t>::max()};
143 mg::DisplayConfigurationCardId const card_id;
144 size_t max_simultaneous_outputs;69 size_t max_simultaneous_outputs;
145 std::vector<mg::DisplayConfigurationOutput> outputs;70 std::vector<DisplayConfigurationOutput> outputs;
146};71};
14772
148}73}
14974
75DisplayConfigurationOutput default_output(DisplayConfigurationOutputId id)
76{
77 return { id, DisplayConfigurationCardId{1},
78 DisplayConfigurationOutputType::vga,
79 {mir_pixel_format_abgr_8888},
80 { {Size{523, 555}, 60.0} },
81 0,
82 Size{324, 642},
83 true,
84 false,
85 Point{X{123}, Y{343}},
86 0,
87 mir_pixel_format_abgr_8888,
88 mir_power_mode_on
89 };
90}
91
92DisplayConfigurationOutput connected_with_modes()
93{
94 DisplayConfigurationOutput output = default_output(DisplayConfigurationOutputId{10}) ;
95 output.modes =
96 {
97 {Size{123, 111}, 59.9},
98 {Size{123, 111}, 59.9},
99 {Size{123, 111}, 59.9}
100 };
101 output.preferred_mode_index = 2;
102 output.current_mode_index = 1;
103 return output;
104}
105DisplayConfigurationOutput connected_without_modes()
106{
107 DisplayConfigurationOutput output = default_output(DisplayConfigurationOutputId{11});
108 output.pixel_formats = {};
109 output.modes = {};
110 output.current_format = mir_pixel_format_invalid;
111 output.current_mode_index = std::numeric_limits<size_t>::max();
112 return output;
113}
114
115DisplayConfigurationOutput connected_with_single_mode()
116{
117 return default_output(DisplayConfigurationOutputId{12});
118}
119
120DisplayConfigurationOutput not_connected()
121{
122 DisplayConfigurationOutput output = default_output(DisplayConfigurationOutputId{13});
123 output.connected = false;
124 output.current_mode_index = 1;
125 return output;
126}
127
128DisplayConfigurationOutput connected_with_rgba_and_xrgb()
129{
130 DisplayConfigurationOutput output = default_output(DisplayConfigurationOutputId{14});
131 output.pixel_formats = {mir_pixel_format_argb_8888, mir_pixel_format_xrgb_8888};
132 return output;
133}
134
135DisplayConfigurationOutput connected_with_xrgb_bgr()
136{
137 DisplayConfigurationOutput output = default_output(DisplayConfigurationOutputId{15});
138 output.pixel_formats = {mir_pixel_format_xrgb_8888, mir_pixel_format_bgr_888};
139 output.current_format = mir_pixel_format_bgr_888;
140 return output;
141}
142
143MockDisplayConfiguration create_default_configuration(size_t max_outputs = MockDisplayConfiguration::max_simultaneous_outputs_all)
144{
145 return MockDisplayConfiguration
146 {
147 max_outputs,
148 {
149 connected_with_modes(),
150 connected_without_modes(),
151 connected_with_single_mode(),
152 not_connected(),
153 }
154 };
155}
156
150TEST(DefaultDisplayConfigurationPolicyTest, uses_all_connected_valid_outputs)157TEST(DefaultDisplayConfigurationPolicyTest, uses_all_connected_valid_outputs)
151{158{
152 using namespace ::testing;159 using namespace ::testing;
153160
154 mg::DefaultDisplayConfigurationPolicy policy;161 DefaultDisplayConfigurationPolicy policy;
155 MockDisplayConfiguration conf;162 MockDisplayConfiguration conf{create_default_configuration()};
156163
157 conf.for_each_output([&conf](mg::DisplayConfigurationOutput const& output)164 conf.for_each_output([&conf](DisplayConfigurationOutput const& output)
158 {165 {
159 if (output.connected && output.modes.size() > 0)166 if (output.connected && output.modes.size() > 0)
160 {167 {
161 EXPECT_CALL(conf, configure_output(output.id, true, geom::Point(),168 EXPECT_CALL(conf, configure_output(output.id, true, Point(),
162 output.preferred_mode_index, _));169 output.preferred_mode_index,
170 _, _));
163 }171 }
164 else172 else
165 {173 {
166 EXPECT_CALL(conf, configure_output(output.id, false, output.top_left,174 EXPECT_CALL(conf, configure_output(output.id, false, output.top_left,
167 output.current_mode_index, _));175 output.current_mode_index,
176 _, _));
168 }177 }
169 });178 });
170179
@@ -175,12 +184,12 @@
175{184{
176 using namespace ::testing;185 using namespace ::testing;
177186
178 mg::DefaultDisplayConfigurationPolicy policy;187 DefaultDisplayConfigurationPolicy policy;
179 MockDisplayConfiguration conf;188 MockDisplayConfiguration conf{create_default_configuration()};
180189
181 conf.for_each_output([&conf](mg::DisplayConfigurationOutput const& output)190 conf.for_each_output([&conf](DisplayConfigurationOutput const& output)
182 {191 {
183 EXPECT_CALL(conf, configure_output(output.id, _, _, _, mir_power_mode_on));192 EXPECT_CALL(conf, configure_output(output.id, _, _, _, _, mir_power_mode_on));
184 });193 });
185194
186 policy.apply_to(conf);195 policy.apply_to(conf);
@@ -191,20 +200,54 @@
191 using namespace ::testing;200 using namespace ::testing;
192201
193 size_t const max_simultaneous_outputs{1};202 size_t const max_simultaneous_outputs{1};
194 mg::DefaultDisplayConfigurationPolicy policy;203 DefaultDisplayConfigurationPolicy policy;
195 MockDisplayConfiguration conf{max_simultaneous_outputs};204 MockDisplayConfiguration conf{create_default_configuration(max_simultaneous_outputs)};
196205
197 size_t output_count{0};206 size_t output_count{0};
198 conf.for_each_output([&output_count](mg::DisplayConfigurationOutput const&)207 conf.for_each_output([&output_count](DisplayConfigurationOutput const&)
199 {208 {
200 ++output_count;209 ++output_count;
201 });210 });
202211
203 EXPECT_CALL(conf, configure_output(_, true, _, _, _))212 EXPECT_CALL(conf, configure_output(_, true, _, _, _, _))
204 .Times(AtMost(max_simultaneous_outputs));213 .Times(AtMost(max_simultaneous_outputs));
205214
206 EXPECT_CALL(conf, configure_output(_, false, _, _, _))215 EXPECT_CALL(conf, configure_output(_, false, _, _, _, _))
207 .Times(AtLeast(output_count - max_simultaneous_outputs));216 .Times(AtLeast(output_count - max_simultaneous_outputs));
208217
209 policy.apply_to(conf);218 policy.apply_to(conf);
210}219}
220
221TEST(DefaultDisplayConfigurationPolicyTest, prefer_opaque_over_alpha)
222{
223 using namespace ::testing;
224
225 DefaultDisplayConfigurationPolicy policy;
226 MockDisplayConfiguration pick_xrgb{ { connected_with_rgba_and_xrgb() } };
227
228 EXPECT_CALL(pick_xrgb, configure_output(_, true, _, _, mir_pixel_format_xrgb_8888, _));
229 policy.apply_to(pick_xrgb);
230}
231
232TEST(DefaultDisplayConfigurationPolicyTest, preserve_opaque_selection)
233{
234 using namespace ::testing;
235
236 DefaultDisplayConfigurationPolicy policy;
237 MockDisplayConfiguration keep_bgr{ { connected_with_xrgb_bgr() } };
238
239 EXPECT_CALL(keep_bgr, configure_output(_, true, _, _, mir_pixel_format_bgr_888, _));
240 policy.apply_to(keep_bgr);
241}
242
243TEST(DefaultDisplayConfigurationPolicyTest, accept_transparency_when_only_option)
244{
245 using namespace ::testing;
246
247 DefaultDisplayConfigurationPolicy policy;
248 MockDisplayConfiguration pick_rgba{ { default_output(DisplayConfigurationOutputId{15}) } };
249
250 EXPECT_CALL(pick_rgba, configure_output(_, true, _, _, mir_pixel_format_abgr_8888, _));
251 policy.apply_to(pick_rgba);
252}
253
211254
=== modified file 'tests/unit-tests/graphics/test_display_configuration.cpp'
--- tests/unit-tests/graphics/test_display_configuration.cpp 2013-12-18 02:19:19 +0000
+++ tests/unit-tests/graphics/test_display_configuration.cpp 2014-01-10 10:21:28 +0000
@@ -45,7 +45,7 @@
45 true,45 true,
46 geom::Point(),46 geom::Point(),
47 2,47 2,
48 0,48 mir_pixel_format_abgr_8888,
49 mir_power_mode_on49 mir_power_mode_on
50};50};
5151

Subscribers

People subscribed via source and target branches