Mir

Merge lp:~andreas-pokorny/mir/allow-transparent-server-buffers into lp:mir

Proposed by Andreas Pokorny on 2013-12-18
Status: Superseded
Proposed branch: lp:~andreas-pokorny/mir/allow-transparent-server-buffers
Merge into: lp:mir
Prerequisite: lp:~raof/mir/check-for-surfaceless
Diff against target: 1416 lines (+517/-152)
41 files modified
examples/CMakeLists.txt (+1/-1)
examples/basic_server.cpp (+0/-2)
examples/demo-shell/window_manager.cpp (+1/-0)
examples/render_surfaces.cpp (+22/-2)
examples/select_pixel_format.cpp (+69/-0)
examples/select_pixel_format.h (+52/-0)
examples/server_configuration.cpp (+8/-4)
include/platform/mir/graphics/display_configuration.h (+2/-2)
include/platform/mir/graphics/platform.h (+1/-1)
include/server/mir/graphics/pixel_format_utils.h (+46/-0)
include/test/mir_test_doubles/null_display_configuration.h (+1/-1)
include/test/mir_test_doubles/stub_display_configuration.h (+1/-1)
src/platform/graphics/android/android_display_configuration.cpp (+1/-1)
src/platform/graphics/android/android_display_configuration.h (+1/-1)
src/platform/graphics/mesa/real_kms_display_configuration.cpp (+5/-1)
src/platform/graphics/mesa/real_kms_display_configuration.h (+2/-2)
src/server/frontend/session_mediator.cpp (+2/-1)
src/server/graphics/CMakeLists.txt (+1/-0)
src/server/graphics/default_display_configuration_policy.cpp (+4/-3)
src/server/graphics/nested/nested_display.cpp (+40/-57)
src/server/graphics/nested/nested_display.h (+6/-5)
src/server/graphics/nested/nested_display_configuration.cpp (+5/-1)
src/server/graphics/nested/nested_display_configuration.h (+1/-1)
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 (+1/-1)
src/server/graphics/offscreen/display_configuration.h (+4/-4)
src/server/graphics/pixel_format_utils.cpp (+65/-0)
src/server/scene/mediating_display_changer.cpp (+1/-0)
tests/mir_test/display_config_matchers.cpp (+1/-1)
tests/unit-tests/frontend/test_session_mediator.cpp (+6/-3)
tests/unit-tests/graphics/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/test_android_fb.cpp (+22/-22)
tests/unit-tests/graphics/mesa/test_cursor.cpp (+1/-1)
tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp (+16/-6)
tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp (+1/-1)
tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp (+26/-9)
tests/unit-tests/graphics/test_default_display_configuration_policy.cpp (+9/-7)
tests/unit-tests/graphics/test_pixel_format_utils.cpp (+79/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/allow-transparent-server-buffers
Reviewer Review Type Date Requested Status
Alan Griffiths 2013-12-18 Needs Fixing on 2013-12-19
Alexandros Frantzis 2013-12-18 Pending
Daniel van Vugt 2013-12-18 Pending
Review via email: mp+199405@code.launchpad.net

This proposal supersedes a proposal from 2013-12-13.

Description of the change

Adds an interface in ServerConfiguration to select the MirPixelFormat of the buffers(s) the server allocates.
So far this is only limited to nested servers.

I think I should also put that into the offscreen platform, which currently defaults to RGBA.
Not sure for mesa and android.

And of course I would like to have hints on the interface ..

To post a comment you must log in.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

5 add_executable(mir_demo_server_shell
6 demo_shell.cpp
7 + fullscreen_placement_strategy.h
8 fullscreen_placement_strategy.cpp
9 + translucent_outputs.h
10 + translucent_outputs.cpp
11 + window_manager.h
12 window_manager.cpp
13 + ../server_configuration.h
14 ../server_configuration.cpp
15 )

Don't add header files to the sources.

~~~~

86 +MirPixelFormat TranslucentOutputs::get_pixel_format(pixel_format_array const& availableFormats)

Naming convention: availableFormats => available_formats

~~~~

196 + typedef std::vector<MirPixelFormat> pixel_format_array;

Naming convention: pixel_format_array => PixelFormatArray (PixelFormats is probably better)

~~~~

88 + for(auto const& f : availableFormats )

Whitespace. Vis:
    for (auto const& f : availableFormats)

~~~~

It seems odd to be adding OutputConfiguration as a parameter to create_display() when it is only relevant to NestedPlatform. Why not make it a dependency of NestedPlatform and supply it to the constructor?

~~~~

198 + virtual MirPixelFormat get_pixel_format(pixel_format_array const& availableFormats) = 0;

"get_" lacks semantic content. Perhaps "choose_"?

review: Needs Fixing
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

Seeing OutputConfiguration passed around next to DisplayConfigurationPolicy makes me wonder if there is a missing abstraction that covers both.

Andreas Pokorny (andreas-pokorny) wrote : Posted in a previous version of this proposal

I think my curly braces placement is wrong too? In:

88 + for (auto const& f : availableFormats )
89 + {
90 + if (f == mir_pixel_format_abgr_8888 ||
91 + f == mir_pixel_format_argb_8888)
92 + {

Yes didnt like that passing around either, but I thought a pixel format configuration would also be reasonable to some degree for non nested platforms. We could turn that into a list of DisplayConfigurationPolicies (for convenience) and extend the DisplayConfiguration interface to be able to also affect the preferred PixelFormat on the Output?

I added those header files there since IDEs that support cmake see those header files that are part of the project, and shows them, and cmake can separate between things to compile and other stuff.

Alexandros Frantzis (afrantzis) wrote : Posted in a previous version of this proposal

Choosing the pixel format of each output's framebuffer is part of the display (re)configuration process, so I think that it conceptually belongs in DisplayConfigurationPolicy. However, I don't think that any changes to the policy interface are actually needed. We only need to allow the policy to set the format, by extending DisplayConfiguration::configure_output() to accept a 'format_index' parameter (note that DisplayConfigurationOutput already contains a 'pixel_formats' and 'current_format_index' fields).

review: Needs Fixing
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

pixel_format_utils.cpp could eventually be replaced by the proposal in bug 1236254. But they're not conflicting ideas so that's OK.

I haven't followed this through yet, but please read the existing discussion --> bug 1256702
The important point is to ensure that translucency is optional, _never_ used on a real shell, and only used in temporary things like greeters.

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

1. Wrapping: Please wrap lines earlier, ideally before column 80. The human brain loses track of the next line to read otherwise...
49 +CascadedDisplayConfigurationPolicy::CascadedDisplayConfigurationPolicy(std::shared_ptr<graphics::DisplayConfigurationPolicy> const& l,
50 + std::shared_ptr<graphics::DisplayConfigurationPolicy> const& r)
Although the class name seems excessively long too. Not sure what to do about that.

2. I think guard macros are meant to follow the namespace?.. So:
   MIR_DEMO_SHELL_CASCADED_DISPLAY_CONFIGURATION_POLICY_H
becomes:
   MIR_EXAMPLES_CASCADED_DISPLAY_CONFIGURATION_POLICY_H_

3. It's possibly too easy to enable translucency. That's an unusual problem, but it's absolutely critical to performance that no shell implementer accidentally uses translucency. It should be clearly marked as "for greeter use only", somehow.

4. Per #3, please remove ALL translucency support from demo-shell. We don't want people copying demo-shell thinking it's a good idea to use translucency on shells when it will cripple performance. Perhaps create a "demo-greeter" based on examples/basic_server.cpp instead?

5. "if(" should have a space; "if ("

6. Please remove spaces: "mg::red_channel_depth( format )"

7. Half of this diff is not yours. It seems to have come from raof's "surfaceless" branch. Please resubmit this branch listing that one as the prerequisite. Then his work won't appear in your MP diff, and it will be half the size to review.

8. Tests for your new logic (other than pixel format utils); is it just
 tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp
?

This isn't an exhaustive review, but I've written enough for now :)

review: Needs Fixing
Andreas Pokorny (andreas-pokorny) wrote :

1. ok.. just that coding guideline state 120 and there was already lots of code in that length

4. Should it have any specific functionality other than picking a different pixel format?

8. Behavior change so far is only working inside nested - the other platforms ignore the policies more or less. Mesa needs fixing if now somebody tries to create a non nesting shell with alpha channel it will not get a buffer.

Daniel van Vugt (vanvugt) wrote :

Lines 49/50 are 134 characters wide, so still too long ;)

Alan Griffiths (alan-griffiths) wrote :

Do we actually need CascadedDisplayConfigurationPolicy? Or could TranslucentOutputs simply decorate the default policy?

~~~~

49 +CascadedDisplayConfigurationPolicy::CascadedDisplayConfigurationPolicy(std::shared_ptr<graphics::DisplayConfigurationPolicy> const& l,
50 + std::shared_ptr<graphics::DisplayConfigurationPolicy> const& r)

vs

102 + CascadedDisplayConfigurationPolicy(std::shared_ptr<graphics::DisplayConfigurationPolicy> const& left,
103 + std::shared_ptr<graphics::DisplayConfigurationPolicy> const& right);

The naming should be consistent between declaration and definition.
http://unity.ubuntu.com/mir/cppguide/index.html?showone=Function_Declarations_and_Definitions#Function_Declarations_and_Definitions

Also, I don't understand the significance of left/right (or the alternative l/r) - are these names meaningful? What I can see in the code is better represented as "first/second".

~~~~

106 + std::shared_ptr<DisplayConfigurationPolicy> left, right;

These dependencies should be const.

Also, while it isn't in the style guide, we have evolved a strong tendency towards single declarations in a statement. Vis:

std::shared_ptr<DisplayConfigurationPolicy> const left;
std::shared_ptr<DisplayConfigurationPolicy> const right;

~~~~

438 - void configure_output(DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode power_mode);
439 + void configure_output(DisplayConfigurationOutputId, bool, geometry::Point, size_t, size_t, MirPowerMode power_mode);

OK, not introduced by this MP, but the declaration doesn't:

1. Name the parameters
2. mention "virtual" or "override"

review: Needs Fixing
Andreas Pokorny (andreas-pokorny) wrote :

wrt: l vs left r vs right - I am still prone to my previous style guide and compiler setup which included -Wshadow.
Despite the fact I prefer mirs, I constantly fall back in old patterns.

1287. By Andreas Pokorny on 2013-12-18

formating issues fixed

1288. By Andreas Pokorny on 2013-12-19

code style and formating improved

1289. By Andreas Pokorny on 2013-12-19

Moving Translucent option out of demo shell

1290. By Andreas Pokorny on 2013-12-19

Adding Basic Server Copy which always selects a transucent outpu

Currently named greeter - but does not greet reasonable yet.

1291. By Andreas Pokorny on 2013-12-19

Override and variable nameing missing

1292. By Andreas Pokorny on 2013-12-19

* Preparing for release 0.1.3
* No-change rebuild for ust.

merging cross compile fixes

Alan Griffiths (alan-griffiths) wrote :

286 + std::shared_ptr<graphics::DisplayConfigurationPolicy> base_policy;

Should be const.

~~~~

344 +#include <cstdint>
345 +#include "mir_toolkit/common.h"

http://unity.ubuntu.com/mir/cppguide/index.html?showone=Names_and_Order_of_Includes#Names_and_Order_of_Includes

~~~~

93 +
94 + using mir::examples::ServerConfiguration::the_options;

Not used

~~~~

82 + void launch_client()
83 + {
84 + if (the_options()->is_set(launch_child_opt))
85 + {
86 + char buffer[128] = {0};
87 + sprintf(buffer, "fd://%d", the_connector()->client_socket_fd());
88 + setenv("MIR_SOCKET", buffer, 1);
89 + auto ignore = system((the_options()->get(launch_child_opt, "") + "&").c_str());
90 + (void)ignore;
91 + }

This code looks familiar - maybe it should be in a common base class? (mir::examples::ServerConfiguration?)

I'm not sure how useful the "greeter" is as an example server. Certainly, if it exists, there ought to be more documentation on how to get it to do anything interesting.

review: Needs Fixing
1293. By Andreas Pokorny on 2013-12-19

WIP rework of render_surfaces demo - dropped greeter

1294. By Andreas Pokorny on 2013-12-20

Merging surfacesless branch with latest improvement

1295. By Andreas Pokorny on 2013-12-20

Reworked the example - integrated it into render surfaces

1296. By Andreas Pokorny on 2013-12-20

Merge from devel to make auto merge from CI conflict free

+ cleanups in the MP, dropping unnecessary bits and whitespace noise

1297. By Andreas Pokorny on 2013-12-20

uninitialized member variable

1298. By Andreas Pokorny on 2013-12-20

duplicated parameter removed, const added to SelectPixelFormat

1299. By Andreas Pokorny on 2013-12-25

Ensure that opaque pixel formats are preferred over translucent in the default policy

Unmerged revisions

1299. By Andreas Pokorny on 2013-12-25

Ensure that opaque pixel formats are preferred over translucent in the default policy

1298. By Andreas Pokorny on 2013-12-20

duplicated parameter removed, const added to SelectPixelFormat

1297. By Andreas Pokorny on 2013-12-20

uninitialized member variable

1296. By Andreas Pokorny on 2013-12-20

Merge from devel to make auto merge from CI conflict free

+ cleanups in the MP, dropping unnecessary bits and whitespace noise

1295. By Andreas Pokorny on 2013-12-20

Reworked the example - integrated it into render surfaces

1294. By Andreas Pokorny on 2013-12-20

Merging surfacesless branch with latest improvement

1293. By Andreas Pokorny on 2013-12-19

WIP rework of render_surfaces demo - dropped greeter

1292. By Andreas Pokorny on 2013-12-19

* Preparing for release 0.1.3
* No-change rebuild for ust.

merging cross compile fixes

1291. By Andreas Pokorny on 2013-12-19

Override and variable nameing missing

1290. By Andreas Pokorny on 2013-12-19

Adding Basic Server Copy which always selects a transucent outpu

Currently named greeter - but does not greet reasonable yet.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/CMakeLists.txt'
2--- examples/CMakeLists.txt 2013-12-18 02:19:19 +0000
3+++ examples/CMakeLists.txt 2013-12-20 13:46:31 +0000
4@@ -109,6 +109,7 @@
5 buffer_render_target.cpp
6 image_renderer.cpp
7 server_configuration.cpp
8+ select_pixel_format.cpp
9 )
10 add_executable(mir_demo_standalone_render_surfaces ${RENDER_SURFACES_SOURCES})
11 target_link_libraries(mir_demo_standalone_render_surfaces
12@@ -157,4 +158,3 @@
13 install(TARGETS mir_demo_server_basic
14 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
15 )
16-
17
18=== modified file 'examples/basic_server.cpp'
19--- examples/basic_server.cpp 2013-09-25 11:56:15 +0000
20+++ examples/basic_server.cpp 2013-12-20 13:46:31 +0000
21@@ -52,8 +52,6 @@
22 (void)ignore;
23 }
24 }
25-
26- using mir::examples::ServerConfiguration::the_options;
27 };
28 }
29
30
31=== modified file 'examples/demo-shell/window_manager.cpp'
32--- examples/demo-shell/window_manager.cpp 2013-12-18 02:19:19 +0000
33+++ examples/demo-shell/window_manager.cpp 2013-12-20 13:46:31 +0000
34@@ -153,6 +153,7 @@
35 conf->configure_output(output.id, output.used,
36 output.top_left,
37 output.current_mode_index,
38+ output.current_format_index,
39 power_mode);
40 });
41 display_off = !display_off;
42
43=== modified file 'examples/render_surfaces.cpp'
44--- examples/render_surfaces.cpp 2013-12-18 02:19:19 +0000
45+++ examples/render_surfaces.cpp 2013-12-20 13:46:31 +0000
46@@ -24,6 +24,7 @@
47 #include "mir/geometry/size.h"
48 #include "mir/geometry/rectangles.h"
49 #include "mir/graphics/buffer_initializer.h"
50+#include "mir/graphics/pixel_format_utils.h"
51 #include "mir/graphics/cursor.h"
52 #include "mir/graphics/display.h"
53 #include "mir/graphics/display_buffer.h"
54@@ -36,13 +37,15 @@
55 #include "buffer_render_target.h"
56 #include "image_renderer.h"
57 #include "server_configuration.h"
58+#include "select_pixel_format.h"
59
60-#include <thread>
61+#include <algorithm>
62 #include <atomic>
63 #include <chrono>
64 #include <csignal>
65 #include <iostream>
66 #include <sstream>
67+#include <thread>
68 #include <vector>
69
70 #include <glm/gtc/matrix_transform.hpp>
71@@ -136,6 +139,7 @@
72
73 char const* const surfaces_to_render = "surfaces-to-render";
74 char const* const display_cursor = "display-cursor";
75+char const* const translucent = "translucent";
76
77 ///\internal [StopWatch_tag]
78 // tracks elapsed time - for animation.
79@@ -260,6 +264,10 @@
80 add_options()
81 (surfaces_to_render, po::value<int>(), "Number of surfaces to render"
82 " [int:default=5]")
83+ (surfaces_to_render, po::value<int>(), "Number of surfaces to render"
84+ " [int:default=5]")
85+ (translucent, po::bool_switch()->default_value(false),
86+ "Enable translucent frame buffer")
87 (display_cursor, po::value<bool>(), "Display test cursor. (If input is "
88 "disabled it gets animated.) "
89 "[bool:default=false]");
90@@ -306,6 +314,18 @@
91 return std::make_shared<RenderResourcesBufferInitializer>();
92 }
93 ///\internal [RenderResourcesBufferInitializer_tag]
94+
95+ std::shared_ptr<mg::DisplayConfigurationPolicy> the_display_configuration_policy() override
96+ {
97+ return display_configuration_policy(
98+ [this]() -> std::shared_ptr<mg::DisplayConfigurationPolicy>
99+ {
100+ return std::make_shared<me::SelectPixelFormat>(
101+ me::ServerConfiguration::the_display_configuration_policy(),
102+ the_options()->get(translucent,false));
103+ }
104+ );
105+ }
106
107 ///\internal [RenderSurfacesDisplayBufferCompositor_tag]
108 // Decorate the DefaultDisplayBufferCompositor in order to move surfaces.
109@@ -334,7 +354,7 @@
110 stop_watch.restart();
111 }
112
113- glClearColor(0.0, 1.0, 0.0, 1.0);
114+ glClearColor(0.0, 1.0, 0.0, 0.0);
115 db_compositor->composite();
116
117 for (auto& m : moveables)
118
119=== added file 'examples/select_pixel_format.cpp'
120--- examples/select_pixel_format.cpp 1970-01-01 00:00:00 +0000
121+++ examples/select_pixel_format.cpp 2013-12-20 13:46:31 +0000
122@@ -0,0 +1,69 @@
123+/*
124+ * Copyright © 2013 Canonical Ltd.
125+ *
126+ * This program is free software: you can redistribute it and/or modify
127+ * it under the terms of the GNU General Public License version 3 as
128+ * published by the Free Software Foundation.
129+ *
130+ * This program is distributed in the hope that it will be useful,
131+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
132+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
133+ * GNU General Public License for more details.
134+ *
135+ * You should have received a copy of the GNU General Public License
136+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
137+ *
138+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
139+ */
140+
141+#include "select_pixel_format.h"
142+
143+#include "mir/graphics/display_configuration.h"
144+#include "mir/graphics/pixel_format_utils.h"
145+
146+#include <stdexcept>
147+#include <algorithm>
148+
149+
150+namespace mir
151+{
152+namespace examples
153+{
154+
155+SelectPixelFormat::SelectPixelFormat(std::shared_ptr<DisplayConfigurationPolicy> const& base_policy,
156+ bool with_alpha)
157+ : base_policy(base_policy),
158+ with_alpha(with_alpha)
159+{}
160+
161+void SelectPixelFormat::apply_to(graphics::DisplayConfiguration & conf)
162+{
163+ base_policy->apply_to(conf);
164+ conf.for_each_output(
165+ [&](graphics::DisplayConfigurationOutput const& conf_output)
166+ {
167+ if (!conf_output.connected || !conf_output.used) return;
168+
169+ auto const& pos = find_if(conf_output.pixel_formats.begin(),
170+ conf_output.pixel_formats.end(),
171+ [&](MirPixelFormat format) -> bool
172+ {
173+ return graphics::contains_alpha(format) == with_alpha;
174+ }
175+ );
176+
177+ // keep the default setings if nothing was found
178+ if (pos == conf_output.pixel_formats.end())
179+ return;
180+
181+ conf.configure_output(conf_output.id, true, conf_output.top_left,
182+ conf_output.current_mode_index,
183+ std::distance(conf_output.pixel_formats.begin(), pos),
184+ conf_output.power_mode
185+ );
186+ });
187+}
188+
189+}
190+}
191+
192
193=== added file 'examples/select_pixel_format.h'
194--- examples/select_pixel_format.h 1970-01-01 00:00:00 +0000
195+++ examples/select_pixel_format.h 2013-12-20 13:46:31 +0000
196@@ -0,0 +1,52 @@
197+/*
198+ * Copyright © 2013 Canonical Ltd.
199+ *
200+ * This program is free software: you can redistribute it and/or modify
201+ * it under the terms of the GNU General Public License version 3 as
202+ * published by the Free Software Foundation.
203+ *
204+ * This program is distributed in the hope that it will be useful,
205+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
206+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
207+ * GNU General Public License for more details.
208+ *
209+ * You should have received a copy of the GNU General Public License
210+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
211+ *
212+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
213+ */
214+
215+
216+#ifndef MIR_EXAMPLES_SELECT_PIXEL_FORMAT_H
217+#define MIR_EXAMPLES_SELECT_PIXEL_FORMAT_H
218+
219+#include "mir/graphics/display_configuration_policy.h"
220+
221+#include <boost/shared_ptr.hpp>
222+
223+
224+namespace mir
225+{
226+namespace examples
227+{
228+
229+/**
230+ * \brief Example of a DisplayConfigurationPolicy that tries to find
231+ * an opaque or transparent pixel format, or falls back to the default
232+ * if not found.
233+ */
234+class SelectPixelFormat : public graphics::DisplayConfigurationPolicy
235+{
236+public:
237+ SelectPixelFormat(std::shared_ptr<graphics::DisplayConfigurationPolicy> const& base_policy,
238+ bool with_alpha);
239+ virtual void apply_to(graphics::DisplayConfiguration& conf);
240+private:
241+ std::shared_ptr<graphics::DisplayConfigurationPolicy> const base_policy;
242+ bool with_alpha;
243+};
244+
245+}
246+}
247+
248+#endif
249
250=== modified file 'examples/server_configuration.cpp'
251--- examples/server_configuration.cpp 2013-10-21 10:40:19 +0000
252+++ examples/server_configuration.cpp 2013-12-20 13:46:31 +0000
253@@ -61,14 +61,16 @@
254 available_outputs_for_card[conf_output.card_id] > 0)
255 {
256 conf.configure_output(conf_output.id, true, geom::Point{max_x, 0},
257- preferred_mode_index, mir_power_mode_on);
258+ preferred_mode_index, conf_output.current_format_index,
259+ mir_power_mode_on);
260 max_x += conf_output.modes[preferred_mode_index].size.width.as_int();
261 --available_outputs_for_card[conf_output.card_id];
262 }
263 else
264 {
265 conf.configure_output(conf_output.id, false, conf_output.top_left,
266- conf_output.current_mode_index, mir_power_mode_on);
267+ conf_output.current_mode_index, conf_output.current_format_index,
268+ mir_power_mode_on);
269 }
270 });
271 }
272@@ -88,13 +90,15 @@
273 if (!done && conf_output.connected && conf_output.modes.size() > 0)
274 {
275 conf.configure_output(conf_output.id, true, geom::Point{0, 0},
276- preferred_mode_index, mir_power_mode_on);
277+ preferred_mode_index, conf_output.current_format_index,
278+ mir_power_mode_on);
279 done = true;
280 }
281 else
282 {
283 conf.configure_output(conf_output.id, false, conf_output.top_left,
284- conf_output.current_mode_index, mir_power_mode_on);
285+ conf_output.current_mode_index, conf_output.current_format_index,
286+ mir_power_mode_on);
287 }
288 });
289 }
290
291=== modified file 'include/platform/mir/graphics/display_configuration.h'
292--- include/platform/mir/graphics/display_configuration.h 2013-12-18 02:19:19 +0000
293+++ include/platform/mir/graphics/display_configuration.h 2013-12-20 13:46:31 +0000
294@@ -135,8 +135,8 @@
295 virtual void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const = 0;
296
297 /** Configures an output. */
298- virtual void configure_output(DisplayConfigurationOutputId id, bool used,
299- geometry::Point top_left, size_t mode_index, MirPowerMode power_mode) = 0;
300+ virtual void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
301+ size_t mode_index, size_t format_index, MirPowerMode power_mode) = 0;
302
303 protected:
304 DisplayConfiguration() = default;
305
306=== modified file 'include/platform/mir/graphics/platform.h'
307--- include/platform/mir/graphics/platform.h 2013-12-18 02:19:19 +0000
308+++ include/platform/mir/graphics/platform.h 2013-12-20 13:46:31 +0000
309@@ -81,7 +81,7 @@
310 * Creates the display subsystem.
311 */
312 virtual std::shared_ptr<Display> create_display(
313- std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) = 0;
314+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) = 0;
315
316 /**
317 * Gets the IPC package for the platform.
318
319=== added file 'include/server/mir/graphics/pixel_format_utils.h'
320--- include/server/mir/graphics/pixel_format_utils.h 1970-01-01 00:00:00 +0000
321+++ include/server/mir/graphics/pixel_format_utils.h 2013-12-20 13:46:31 +0000
322@@ -0,0 +1,46 @@
323+/*
324+ * Copyright © 2013 Canonical Ltd.
325+ *
326+ * This program is free software: you can redistribute it and/or modify it
327+ * under the terms of the GNU General Public License version 3,
328+ * as published by the Free Software Foundation.
329+ *
330+ * This program is distributed in the hope that it will be useful,
331+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
332+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
333+ * GNU General Public License for more details.
334+ *
335+ * You should have received a copy of the GNU General Public License
336+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
337+ *
338+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
339+ */
340+
341+#include "mir_toolkit/common.h"
342+
343+#include <cstdint>
344+
345+namespace mir
346+{
347+namespace graphics
348+{
349+
350+/*!
351+ * \name MirPixelFormat utility functions
352+ *
353+ * A set of functions to query details of MirPixelFormat
354+ * TODO improve this through https://bugs.launchpad.net/mir/+bug/1236254
355+ * \{
356+ */
357+bool contains_alpha(MirPixelFormat format);
358+int32_t red_channel_depth(MirPixelFormat format);
359+int32_t blue_channel_depth(MirPixelFormat format);
360+int32_t green_channel_depth(MirPixelFormat format);
361+int32_t alpha_channel_depth(MirPixelFormat format);
362+/*!
363+ * \}
364+ */
365+
366+
367+}
368+}
369
370=== modified file 'include/test/mir_test_doubles/null_display_configuration.h'
371--- include/test/mir_test_doubles/null_display_configuration.h 2013-09-12 21:36:55 +0000
372+++ include/test/mir_test_doubles/null_display_configuration.h 2013-12-20 13:46:31 +0000
373@@ -35,7 +35,7 @@
374 void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)>) const
375 {
376 }
377- void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode) override
378+ void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, size_t, MirPowerMode) override
379 {
380 }
381 };
382
383=== modified file 'include/test/mir_test_doubles/stub_display_configuration.h'
384--- include/test/mir_test_doubles/stub_display_configuration.h 2013-12-18 02:19:19 +0000
385+++ include/test/mir_test_doubles/stub_display_configuration.h 2013-12-20 13:46:31 +0000
386@@ -136,7 +136,7 @@
387 }
388 }
389
390- void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode)
391+ void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, size_t, MirPowerMode)
392 {
393 }
394
395
396=== modified file 'src/platform/graphics/android/android_display_configuration.cpp'
397--- src/platform/graphics/android/android_display_configuration.cpp 2013-12-18 02:19:19 +0000
398+++ src/platform/graphics/android/android_display_configuration.cpp 2013-12-20 13:46:31 +0000
399@@ -62,7 +62,7 @@
400 f(configuration);
401 }
402
403-void mga::AndroidDisplayConfiguration::configure_output(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPowerMode power_mode)
404+void mga::AndroidDisplayConfiguration::configure_output(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, size_t, MirPowerMode power_mode)
405 {
406 configuration.power_mode = power_mode;
407 }
408
409=== modified file 'src/platform/graphics/android/android_display_configuration.h'
410--- src/platform/graphics/android/android_display_configuration.h 2013-12-18 02:19:19 +0000
411+++ src/platform/graphics/android/android_display_configuration.h 2013-12-20 13:46:31 +0000
412@@ -37,7 +37,7 @@
413
414 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const;
415 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;
416- void configure_output(DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode power_mode);
417+ void configure_output(DisplayConfigurationOutputId, bool, geometry::Point, size_t, size_t, MirPowerMode power_mode);
418
419 private:
420 DisplayConfigurationOutput configuration;
421
422=== modified file 'src/platform/graphics/mesa/real_kms_display_configuration.cpp'
423--- src/platform/graphics/mesa/real_kms_display_configuration.cpp 2013-12-18 02:19:19 +0000
424+++ src/platform/graphics/mesa/real_kms_display_configuration.cpp 2013-12-20 13:46:31 +0000
425@@ -109,7 +109,7 @@
426 void mgm::RealKMSDisplayConfiguration::configure_output(
427 DisplayConfigurationOutputId id, bool used,
428 geometry::Point top_left, size_t mode_index,
429- MirPowerMode power_mode)
430+ size_t format_index, MirPowerMode power_mode)
431 {
432 auto iter = find_output_with_id(id);
433
434@@ -120,9 +120,13 @@
435 if (used && mode_index >= output.modes.size())
436 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));
437
438+ if (used && format_index >= output.pixel_formats.size())
439+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid format_index for used output"));
440+
441 output.used = used;
442 output.top_left = top_left;
443 output.current_mode_index = mode_index;
444+ output.current_format_index = format_index;
445 output.power_mode = power_mode;
446 }
447 else
448
449=== modified file 'src/platform/graphics/mesa/real_kms_display_configuration.h'
450--- src/platform/graphics/mesa/real_kms_display_configuration.h 2013-12-18 02:19:19 +0000
451+++ src/platform/graphics/mesa/real_kms_display_configuration.h 2013-12-20 13:46:31 +0000
452@@ -39,8 +39,8 @@
453
454 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const;
455 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;
456- void configure_output(DisplayConfigurationOutputId id, bool used,
457- geometry::Point top_left, size_t mode_index, MirPowerMode power_mode);
458+ void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
459+ size_t mode_index, size_t foramt_index, MirPowerMode power_mode);
460
461 uint32_t get_kms_connector_id(DisplayConfigurationOutputId id) const;
462 size_t get_kms_mode_index(DisplayConfigurationOutputId id, size_t conf_mode_index) const;
463
464=== modified file 'src/server/frontend/session_mediator.cpp'
465--- src/server/frontend/session_mediator.cpp 2013-12-18 02:19:19 +0000
466+++ src/server/frontend/session_mediator.cpp 2013-12-20 13:46:31 +0000
467@@ -321,7 +321,8 @@
468 mg::DisplayConfigurationOutputId output_id{static_cast<int>(output.output_id())};
469 config->configure_output(output_id, output.used(),
470 geom::Point{output.position_x(), output.position_y()},
471- output.current_mode(), static_cast<MirPowerMode>(output.power_mode()));
472+ output.current_mode(), output.current_format(),
473+ static_cast<MirPowerMode>(output.power_mode()));
474 }
475
476 display_changer->configure(session, config);
477
478=== modified file 'src/server/graphics/CMakeLists.txt'
479--- src/server/graphics/CMakeLists.txt 2013-12-20 05:06:28 +0000
480+++ src/server/graphics/CMakeLists.txt 2013-12-20 13:46:31 +0000
481@@ -5,6 +5,7 @@
482
483 default_configuration.cpp
484 default_display_configuration_policy.cpp
485+ pixel_format_utils.cpp
486 gl_extensions_base.cpp
487 surfaceless_egl_context.cpp
488 )
489
490=== modified file 'src/server/graphics/default_display_configuration_policy.cpp'
491--- src/server/graphics/default_display_configuration_policy.cpp 2013-12-18 02:19:19 +0000
492+++ src/server/graphics/default_display_configuration_policy.cpp 2013-12-20 13:46:31 +0000
493@@ -45,15 +45,16 @@
494 if (preferred_mode_index > conf_output.modes.size())
495 preferred_mode_index = 0;
496
497- conf.configure_output(conf_output.id, true, geom::Point(),
498- preferred_mode_index, default_power_state);
499+ conf.configure_output(conf_output.id, true, geom::Point(), preferred_mode_index,
500+ conf_output.current_format_index, default_power_state);
501
502 --available_outputs_for_card[conf_output.card_id];
503 }
504 else
505 {
506 conf.configure_output(conf_output.id, false, conf_output.top_left,
507- conf_output.current_mode_index, default_power_state);
508+ conf_output.current_mode_index, conf_output.current_format_index,
509+ default_power_state);
510 }
511 });
512 }
513
514=== modified file 'src/server/graphics/nested/nested_display.cpp'
515--- src/server/graphics/nested/nested_display.cpp 2013-12-20 05:06:28 +0000
516+++ src/server/graphics/nested/nested_display.cpp 2013-12-20 13:46:31 +0000
517@@ -22,8 +22,10 @@
518 #include "mir_api_wrappers.h"
519
520 #include "mir/geometry/rectangle.h"
521+#include "mir/graphics/pixel_format_utils.h"
522 #include "mir/graphics/gl_context.h"
523 #include "mir/graphics/surfaceless_egl_context.h"
524+#include "mir/graphics/display_configuration_policy.h"
525 #include "host_connection.h"
526
527 #include <boost/throw_exception.hpp>
528@@ -34,45 +36,8 @@
529 namespace mgnw = mir::graphics::nested::mir_api_wrappers;
530 namespace geom = mir::geometry;
531
532-namespace
533-{
534-
535-MirPixelFormat find_opaque_surface_format(MirConnection* connection)
536-{
537- static unsigned const max_formats = 32;
538- MirPixelFormat formats[max_formats];
539- unsigned int valid_formats;
540-
541- mir_connection_get_available_surface_formats(connection, formats,
542- max_formats, &valid_formats);
543-
544- // Find an opaque surface format
545- for (auto f = formats; f != formats+valid_formats; ++f)
546- {
547- if (*f == mir_pixel_format_xbgr_8888 ||
548- *f == mir_pixel_format_xrgb_8888)
549- {
550- return *f;
551- }
552- }
553-
554- BOOST_THROW_EXCEPTION(
555- std::runtime_error("Nested Mir failed to find an opaque surface format"));
556-}
557-
558-}
559-
560-EGLint const mgn::detail::nested_egl_config_attribs[] = {
561- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
562- EGL_RED_SIZE, 8,
563- EGL_GREEN_SIZE, 8,
564- EGL_BLUE_SIZE, 8,
565- EGL_ALPHA_SIZE, 0,
566- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
567- EGL_NONE
568-};
569-
570-EGLint const mgn::detail::nested_egl_context_attribs[] = {
571+EGLint const mgn::detail::nested_egl_context_attribs[] =
572+{
573 EGL_CONTEXT_CLIENT_VERSION, 2,
574 EGL_NONE
575 };
576@@ -100,7 +65,7 @@
577 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to fetch EGL display."));
578 }
579
580-void mgn::detail::EGLDisplayHandle::initialize()
581+void mgn::detail::EGLDisplayHandle::initialize(MirPixelFormat format)
582 {
583 int major;
584 int minor;
585@@ -110,17 +75,28 @@
586 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to initialize EGL."));
587 }
588
589- egl_context_ = eglCreateContext(egl_display, choose_config(detail::nested_egl_config_attribs), EGL_NO_CONTEXT, detail::nested_egl_context_attribs);
590+ egl_context_ = eglCreateContext(egl_display, choose_windowed_es_config(format), EGL_NO_CONTEXT, detail::nested_egl_context_attribs);
591+
592 if (egl_context_ == EGL_NO_CONTEXT)
593 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create shared EGL context"));
594 }
595
596-EGLConfig mgn::detail::EGLDisplayHandle::choose_config(const EGLint attrib_list[]) const
597+EGLConfig mgn::detail::EGLDisplayHandle::choose_windowed_es_config(MirPixelFormat format) const
598 {
599+ EGLint const nested_egl_config_attribs[] =
600+ {
601+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
602+ EGL_RED_SIZE, mg::red_channel_depth(format),
603+ EGL_GREEN_SIZE, mg::green_channel_depth(format),
604+ EGL_BLUE_SIZE, mg::blue_channel_depth(format),
605+ EGL_ALPHA_SIZE, mg::alpha_channel_depth(format),
606+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
607+ EGL_NONE
608+ };
609 EGLConfig result;
610 int n;
611
612- int res = eglChooseConfig(egl_display, attrib_list, &result, 1, &n);
613+ int res = eglChooseConfig(egl_display, nested_egl_config_attribs, &result, 1, &n);
614 if ((res != EGL_TRUE) || (n != 1))
615 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to choose EGL configuration."));
616
617@@ -149,17 +125,18 @@
618 mgn::NestedDisplay::NestedDisplay(
619 std::shared_ptr<HostConnection> const& connection,
620 std::shared_ptr<input::EventFilter> const& event_handler,
621- std::shared_ptr<mg::DisplayReport> const& display_report) :
622+ std::shared_ptr<mg::DisplayReport> const& display_report,
623+ std::shared_ptr<mg::DisplayConfigurationPolicy> const& initial_conf_policy) :
624 connection{connection},
625 event_handler{event_handler},
626 display_report{display_report},
627 egl_display{*connection},
628- egl_pixel_format{find_opaque_surface_format(*connection)},
629 outputs{}
630 {
631- egl_display.initialize();
632- eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_display.egl_context());
633- configure(*configuration());
634+
635+ std::shared_ptr<DisplayConfiguration> conf(configuration());
636+ initial_conf_policy->apply_to(*conf);
637+ configure(*conf);
638 }
639
640 mgn::NestedDisplay::~NestedDisplay() noexcept
641@@ -178,6 +155,14 @@
642 return std::make_shared<NestedDisplayConfiguration>(mir_connection_create_display_config(*connection));
643 }
644
645+void mgn::NestedDisplay::complete_display_initialization(MirPixelFormat format)
646+{
647+ if (egl_display.egl_context() != EGL_NO_CONTEXT) return;
648+
649+ egl_display.initialize(format);
650+ eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_display.egl_context());
651+}
652+
653 void mgn::NestedDisplay::configure(mg::DisplayConfiguration const& configuration)
654 {
655 decltype(outputs) result;
656@@ -193,13 +178,16 @@
657 geometry::Rectangle const area{output.top_left, output.modes[output.current_mode_index].size};
658
659 auto const& egl_display_mode = output.modes[output.current_mode_index];
660+ auto const& egl_config_format = output.pixel_formats[output.current_format_index];
661+
662+ complete_display_initialization(egl_config_format);
663
664 MirSurfaceParameters const request_params =
665 {
666 "Mir nested display",
667 egl_display_mode.size.width.as_int(),
668 egl_display_mode.size.height.as_int(),
669- egl_pixel_format,
670+ egl_config_format,
671 mir_buffer_usage_hardware,
672 static_cast<uint32_t>(output.id.as_value())
673 };
674@@ -213,7 +201,8 @@
675 egl_display,
676 mir_surface,
677 area,
678- event_handler);
679+ event_handler,
680+ output.pixel_formats[output.current_format_index]);
681 }
682 });
683
684@@ -274,13 +263,7 @@
685 return std::weak_ptr<Cursor>();
686 }
687
688-namespace
689-{
690-}
691-
692 std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context()
693 {
694- return std::unique_ptr<mg::GLContext>{new SurfacelessEGLContext(egl_display,
695- detail::nested_egl_config_attribs,
696- EGL_NO_CONTEXT)};
697+ return std::unique_ptr<mg::GLContext>{new SurfacelessEGLContext(egl_display, EGL_NO_CONTEXT)};
698 }
699
700=== modified file 'src/server/graphics/nested/nested_display.h'
701--- src/server/graphics/nested/nested_display.h 2013-12-18 02:19:19 +0000
702+++ src/server/graphics/nested/nested_display.h 2013-12-20 13:46:31 +0000
703@@ -42,6 +42,7 @@
704 {
705 class DisplayReport;
706 class DisplayBuffer;
707+class DisplayConfigurationPolicy;
708
709 namespace nested
710 {
711@@ -67,8 +68,8 @@
712 explicit EGLDisplayHandle(MirConnection* connection);
713 ~EGLDisplayHandle() noexcept;
714
715- void initialize();
716- EGLConfig choose_config(const EGLint attrib_list[]) const;
717+ void initialize(MirPixelFormat format);
718+ EGLConfig choose_windowed_es_config (MirPixelFormat format) const;
719 EGLNativeWindowType native_window(EGLConfig egl_config, MirSurface* mir_surface) const;
720 EGLContext egl_context() const;
721 operator EGLDisplay() const { return egl_display; }
722@@ -83,7 +84,6 @@
723
724 class NestedOutput;
725
726-extern EGLint const nested_egl_config_attribs[];
727 extern EGLint const nested_egl_context_attribs[];
728 }
729
730@@ -95,7 +95,8 @@
731 NestedDisplay(
732 std::shared_ptr<HostConnection> const& connection,
733 std::shared_ptr<input::EventFilter> const& event_handler,
734- std::shared_ptr<DisplayReport> const& display_report);
735+ std::shared_ptr<DisplayReport> const& display_report,
736+ std::shared_ptr<DisplayConfigurationPolicy> const& conf_policy);
737
738 ~NestedDisplay() noexcept;
739
740@@ -124,11 +125,11 @@
741 std::shared_ptr<input::EventFilter> const event_handler;
742 std::shared_ptr<DisplayReport> const display_report;
743 detail::EGLDisplayHandle egl_display;
744- MirPixelFormat const egl_pixel_format;
745
746 std::mutex outputs_mutex;
747 std::unordered_map<DisplayConfigurationOutputId, std::shared_ptr<detail::NestedOutput>> outputs;
748 DisplayConfigurationChangeHandler my_conf_change_handler;
749+ void complete_display_initialization( MirPixelFormat format );
750 };
751
752 }
753
754=== modified file 'src/server/graphics/nested/nested_display_configuration.cpp'
755--- src/server/graphics/nested/nested_display_configuration.cpp 2013-12-18 02:19:19 +0000
756+++ src/server/graphics/nested/nested_display_configuration.cpp 2013-12-20 13:46:31 +0000
757@@ -86,7 +86,7 @@
758 }
759
760 void mgn::NestedDisplayConfiguration::configure_output(DisplayConfigurationOutputId id, bool used,
761- geometry::Point top_left, size_t mode_index, MirPowerMode power_mode)
762+ geometry::Point top_left, size_t mode_index, size_t format_index, MirPowerMode power_mode)
763 {
764 for (auto mir_output = display_config->outputs;
765 mir_output != display_config->outputs+display_config->num_outputs;
766@@ -97,10 +97,14 @@
767 if (used && mode_index >= mir_output->num_modes)
768 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));
769
770+ if (used && format_index >= mir_output->num_output_formats)
771+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid format_index for used output"));
772+
773 mir_output->used = used;
774 mir_output->position_x = top_left.x.as_uint32_t();
775 mir_output->position_y = top_left.y.as_uint32_t();
776 mir_output->current_mode = mode_index;
777+ mir_output->current_output_format = format_index;
778 mir_output->power_mode = static_cast<MirPowerMode>(power_mode);
779 return;
780 }
781
782=== modified file 'src/server/graphics/nested/nested_display_configuration.h'
783--- src/server/graphics/nested/nested_display_configuration.h 2013-09-12 21:36:55 +0000
784+++ src/server/graphics/nested/nested_display_configuration.h 2013-12-20 13:46:31 +0000
785@@ -38,7 +38,7 @@
786 void for_each_output(std::function<void(DisplayConfigurationOutput const&)>) const;
787
788 void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left, size_t mode_index,
789- MirPowerMode power_mode);
790+ size_t format_index, MirPowerMode power_mode);
791
792 operator MirDisplayConfiguration*() const { return display_config; }
793 private:
794
795=== modified file 'src/server/graphics/nested/nested_output.cpp'
796--- src/server/graphics/nested/nested_output.cpp 2013-09-23 13:37:44 +0000
797+++ src/server/graphics/nested/nested_output.cpp 2013-12-20 13:46:31 +0000
798@@ -41,10 +41,11 @@
799 EGLDisplayHandle const& egl_display,
800 MirSurface* mir_surface,
801 geometry::Rectangle const& area,
802- std::shared_ptr<input::EventFilter> const& event_handler) :
803+ std::shared_ptr<input::EventFilter> const& event_handler,
804+ MirPixelFormat preferred_format) :
805 egl_display(egl_display),
806 mir_surface{mir_surface},
807- egl_config{egl_display.choose_config(nested_egl_config_attribs)},
808+ egl_config{egl_display.choose_windowed_es_config(preferred_format)},
809 egl_context{egl_display, eglCreateContext(egl_display, egl_config, egl_display.egl_context(), nested_egl_context_attribs)},
810 area{area.top_left, area.size},
811 event_handler{event_handler},
812
813=== modified file 'src/server/graphics/nested/nested_output.h'
814--- src/server/graphics/nested/nested_output.h 2013-09-23 13:37:44 +0000
815+++ src/server/graphics/nested/nested_output.h 2013-12-20 13:46:31 +0000
816@@ -54,7 +54,8 @@
817 EGLDisplayHandle const& egl_display,
818 MirSurface* mir_surface,
819 geometry::Rectangle const& area,
820- std::shared_ptr<input::EventFilter> const& event_handler);
821+ std::shared_ptr<input::EventFilter> const& event_handler,
822+ MirPixelFormat preferred_format);
823
824 ~NestedOutput() noexcept;
825
826
827=== modified file 'src/server/graphics/nested/nested_platform.cpp'
828--- src/server/graphics/nested/nested_platform.cpp 2013-12-18 02:19:19 +0000
829+++ src/server/graphics/nested/nested_platform.cpp 2013-12-20 13:46:31 +0000
830@@ -113,9 +113,9 @@
831 return native_platform->create_buffer_allocator(buffer_initializer);
832 }
833
834-std::shared_ptr<mg::Display> mgn::NestedPlatform::create_display(std::shared_ptr<mg::DisplayConfigurationPolicy> const& /*initial_conf_policy*/)
835+std::shared_ptr<mg::Display> mgn::NestedPlatform::create_display(std::shared_ptr<mg::DisplayConfigurationPolicy> const& conf_policy)
836 {
837- return std::make_shared<mgn::NestedDisplay>(connection, event_handler, display_report);
838+ return std::make_shared<mgn::NestedDisplay>(connection, event_handler, display_report, conf_policy);
839 }
840
841 std::shared_ptr<mg::PlatformIPCPackage> mgn::NestedPlatform::get_ipc_package()
842
843=== modified file 'src/server/graphics/nested/nested_platform.h'
844--- src/server/graphics/nested/nested_platform.h 2013-12-18 02:19:19 +0000
845+++ src/server/graphics/nested/nested_platform.h 2013-12-20 13:46:31 +0000
846@@ -42,12 +42,12 @@
847
848 ~NestedPlatform() noexcept;
849 std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(
850- std::shared_ptr<BufferInitializer> const& buffer_initializer);
851+ std::shared_ptr<BufferInitializer> const& buffer_initializer) override;
852 std::shared_ptr<Display> create_display(
853- std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy);
854- std::shared_ptr<PlatformIPCPackage> get_ipc_package();
855- std::shared_ptr<InternalClient> create_internal_client();
856- void fill_ipc_package(BufferIPCPacker* packer, Buffer const* Buffer) const;
857+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) override;
858+ std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;
859+ std::shared_ptr<InternalClient> create_internal_client() override;
860+ void fill_ipc_package(BufferIPCPacker* packer, Buffer const* Buffer) const override;
861 EGLNativeDisplayType egl_native_display() const;
862
863 private:
864
865=== modified file 'src/server/graphics/offscreen/display_configuration.cpp'
866--- src/server/graphics/offscreen/display_configuration.cpp 2013-12-18 02:19:19 +0000
867+++ src/server/graphics/offscreen/display_configuration.cpp 2013-12-20 13:46:31 +0000
868@@ -67,6 +67,6 @@
869 }
870
871 void mgo::DisplayConfiguration::configure_output(
872- mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPowerMode)
873+ mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, size_t, MirPowerMode)
874 {
875 }
876
877=== modified file 'src/server/graphics/offscreen/display_configuration.h'
878--- src/server/graphics/offscreen/display_configuration.h 2013-11-12 17:23:53 +0000
879+++ src/server/graphics/offscreen/display_configuration.h 2013-12-20 13:46:31 +0000
880@@ -33,10 +33,10 @@
881 DisplayConfiguration(DisplayConfiguration const& other);
882 DisplayConfiguration& operator=(DisplayConfiguration const& other);
883
884- void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const;
885- void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;
886- void configure_output(DisplayConfigurationOutputId, bool, geometry::Point,
887- size_t, MirPowerMode power_mode);
888+ void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;
889+ void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;
890+ virtual void configure_output(DisplayConfigurationOutputId id, bool used, geometry::Point top_left,
891+ size_t mode_index, size_t format_index, MirPowerMode power_mode) override;
892
893 private:
894 DisplayConfigurationOutput output;
895
896=== added file 'src/server/graphics/pixel_format_utils.cpp'
897--- src/server/graphics/pixel_format_utils.cpp 1970-01-01 00:00:00 +0000
898+++ src/server/graphics/pixel_format_utils.cpp 2013-12-20 13:46:31 +0000
899@@ -0,0 +1,65 @@
900+/*
901+ * Copyright © 2013 Canonical Ltd.
902+ *
903+ * This program is free software: you can redistribute it and/or modify it
904+ * under the terms of the GNU General Public License version 3,
905+ * as published by the Free Software Foundation.
906+ *
907+ * This program is distributed in the hope that it will be useful,
908+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
909+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
910+ * GNU General Public License for more details.
911+ *
912+ * You should have received a copy of the GNU General Public License
913+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
914+ *
915+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
916+ */
917+
918+#include "mir/graphics/pixel_format_utils.h"
919+
920+namespace mir
921+{
922+namespace graphics
923+{
924+
925+bool contains_alpha(MirPixelFormat format)
926+{
927+ return (format == mir_pixel_format_abgr_8888 ||
928+ format == mir_pixel_format_argb_8888);
929+}
930+
931+int32_t red_channel_depth(MirPixelFormat format)
932+{
933+ if (mir_pixel_format_invalid < format &&
934+ format < mir_pixel_formats)
935+ return 8;
936+ return 0;
937+}
938+
939+int32_t blue_channel_depth(MirPixelFormat format)
940+{
941+ if (mir_pixel_format_invalid < format &&
942+ format < mir_pixel_formats)
943+ return 8;
944+ return 0;
945+}
946+
947+int32_t green_channel_depth( MirPixelFormat format )
948+{
949+ if (mir_pixel_format_invalid < format &&
950+ format < mir_pixel_formats)
951+ return 8;
952+ return 0;
953+}
954+
955+int32_t alpha_channel_depth( MirPixelFormat format )
956+{
957+ if (format == mir_pixel_format_abgr_8888 ||
958+ format == mir_pixel_format_argb_8888)
959+ return 8;
960+ return 0;
961+}
962+
963+}
964+}
965
966=== modified file 'src/server/scene/mediating_display_changer.cpp'
967--- src/server/scene/mediating_display_changer.cpp 2013-12-18 02:19:19 +0000
968+++ src/server/scene/mediating_display_changer.cpp 2013-12-20 13:46:31 +0000
969@@ -136,6 +136,7 @@
970 conf->configure_output(output.id, output.used,
971 output.top_left,
972 output.current_mode_index,
973+ output.current_format_index,
974 mir_power_mode_on);
975 }
976 });
977
978=== modified file 'tests/mir_test/display_config_matchers.cpp'
979--- tests/mir_test/display_config_matchers.cpp 2013-12-18 02:19:19 +0000
980+++ tests/mir_test/display_config_matchers.cpp 2013-12-20 13:46:31 +0000
981@@ -175,7 +175,7 @@
982 }
983
984 void configure_output(mg::DisplayConfigurationOutputId, bool,
985- geom::Point, size_t, MirPowerMode)
986+ geom::Point, size_t, size_t, MirPowerMode)
987 {
988 }
989
990
991=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
992--- tests/unit-tests/frontend/test_session_mediator.cpp 2013-12-18 02:19:19 +0000
993+++ tests/unit-tests/frontend/test_session_mediator.cpp 2013-12-20 13:46:31 +0000
994@@ -83,7 +83,7 @@
995 {
996 MOCK_CONST_METHOD1(for_each_card, void(std::function<void(mg::DisplayConfigurationCard const&)>));
997 MOCK_CONST_METHOD1(for_each_output, void(std::function<void(mg::DisplayConfigurationOutput const&)>));
998- MOCK_METHOD5(configure_output, void(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPowerMode));
999+ MOCK_METHOD6(configure_output, void(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, size_t, MirPowerMode));
1000 };
1001
1002 }
1003@@ -555,6 +555,7 @@
1004 bool used0 = false, used1 = true;
1005 geom::Point pt0{44,22}, pt1{3,2};
1006 size_t mode_index0 = 1, mode_index1 = 3;
1007+ size_t format_index0 = 2, format_index1 = 0;
1008 mg::DisplayConfigurationOutputId id0{6}, id1{3};
1009
1010 NiceMock<MockConfig> mock_display_config;
1011@@ -568,9 +569,9 @@
1012 EXPECT_CALL(*mock_display_selector, active_configuration())
1013 .InSequence(seq)
1014 .WillOnce(Return(mt::fake_shared(mock_display_config)));
1015- EXPECT_CALL(mock_display_config, configure_output(id0, used0, pt0, mode_index0, mir_power_mode_on))
1016+ EXPECT_CALL(mock_display_config, configure_output(id0, used0, pt0, mode_index0, format_index0, mir_power_mode_on))
1017 .InSequence(seq);
1018- EXPECT_CALL(mock_display_config, configure_output(id1, used1, pt1, mode_index1, mir_power_mode_off))
1019+ EXPECT_CALL(mock_display_config, configure_output(id1, used1, pt1, mode_index1, format_index1, mir_power_mode_off))
1020 .InSequence(seq);
1021 EXPECT_CALL(*mock_display_selector, configure(_,_))
1022 .InSequence(seq);
1023@@ -593,6 +594,7 @@
1024 disp0->set_position_x(pt0.x.as_uint32_t());
1025 disp0->set_position_y(pt0.y.as_uint32_t());
1026 disp0->set_current_mode(mode_index0);
1027+ disp0->set_current_format(format_index0);
1028 disp0->set_power_mode(static_cast<uint32_t>(mir_power_mode_on));
1029
1030 auto disp1 = configuration.add_display_output();
1031@@ -601,6 +603,7 @@
1032 disp1->set_position_x(pt1.x.as_uint32_t());
1033 disp1->set_position_y(pt1.y.as_uint32_t());
1034 disp1->set_current_mode(mode_index1);
1035+ disp1->set_current_format(format_index1);
1036 disp1->set_power_mode(static_cast<uint32_t>(mir_power_mode_off));
1037
1038 session_mediator.configure_display(nullptr, &configuration,
1039
1040=== modified file 'tests/unit-tests/graphics/CMakeLists.txt'
1041--- tests/unit-tests/graphics/CMakeLists.txt 2013-12-20 05:06:28 +0000
1042+++ tests/unit-tests/graphics/CMakeLists.txt 2013-12-20 13:46:31 +0000
1043@@ -6,6 +6,7 @@
1044 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_configuration_policy.cpp
1045 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_id.cpp
1046 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_properties.cpp
1047+ ${CMAKE_CURRENT_SOURCE_DIR}/test_pixel_format_utils.cpp
1048 ${CMAKE_CURRENT_SOURCE_DIR}/test_surfaceless_egl_context.cpp
1049 )
1050
1051
1052=== modified file 'tests/unit-tests/graphics/android/test_android_fb.cpp'
1053--- tests/unit-tests/graphics/android/test_android_fb.cpp 2013-12-18 02:19:19 +0000
1054+++ tests/unit-tests/graphics/android/test_android_fb.cpp 2013-12-20 13:46:31 +0000
1055@@ -256,28 +256,28 @@
1056 configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
1057 {
1058 configuration->configure_output(
1059- output.id, output.used, output.top_left, output.current_mode_index, mir_power_mode_on);
1060- });
1061- display.configure(*configuration);
1062-
1063- configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
1064- {
1065- configuration->configure_output(
1066- output.id, output.used, output.top_left, output.current_mode_index, mir_power_mode_standby);
1067- });
1068- display.configure(*configuration);
1069-
1070- configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
1071- {
1072- configuration->configure_output(
1073- output.id, output.used, output.top_left, output.current_mode_index, mir_power_mode_off);
1074- });
1075- display.configure(*configuration);
1076-
1077- configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
1078- {
1079- configuration->configure_output(
1080- output.id, output.used, output.top_left, output.current_mode_index, mir_power_mode_suspend);
1081+ output.id, output.used, output.top_left, output.current_mode_index, output.current_format_index, mir_power_mode_on);
1082+ });
1083+ display.configure(*configuration);
1084+
1085+ configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
1086+ {
1087+ configuration->configure_output(
1088+ output.id, output.used, output.top_left, output.current_mode_index, output.current_format_index, mir_power_mode_standby);
1089+ });
1090+ display.configure(*configuration);
1091+
1092+ configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
1093+ {
1094+ configuration->configure_output(
1095+ output.id, output.used, output.top_left, output.current_mode_index, output.current_format_index, mir_power_mode_off);
1096+ });
1097+ display.configure(*configuration);
1098+
1099+ configuration->for_each_output([&](mg::DisplayConfigurationOutput const& output)
1100+ {
1101+ configuration->configure_output(
1102+ output.id, output.used, output.top_left, output.current_mode_index, output.current_format_index, mir_power_mode_suspend);
1103 });
1104 display.configure(*configuration);
1105 }
1106
1107=== modified file 'tests/unit-tests/graphics/mesa/test_cursor.cpp'
1108--- tests/unit-tests/graphics/mesa/test_cursor.cpp 2013-12-18 02:19:19 +0000
1109+++ tests/unit-tests/graphics/mesa/test_cursor.cpp 2013-12-20 13:46:31 +0000
1110@@ -141,7 +141,7 @@
1111 }
1112
1113 void configure_output(mg::DisplayConfigurationOutputId, bool,
1114- geom::Point, size_t, MirPowerMode)
1115+ geom::Point, size_t, size_t, MirPowerMode)
1116 {
1117 }
1118
1119
1120=== modified file 'tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp'
1121--- tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp 2013-12-18 02:19:19 +0000
1122+++ tests/unit-tests/graphics/mesa/test_display_multi_monitor.cpp 2013-12-20 13:46:31 +0000
1123@@ -57,12 +57,16 @@
1124 if (conf_output.connected && conf_output.modes.size() > 0)
1125 {
1126 conf.configure_output(conf_output.id, true, geom::Point{0, 0},
1127- conf_output.preferred_mode_index, mir_power_mode_on);
1128+ conf_output.preferred_mode_index,
1129+ conf_output.current_format_index,
1130+ mir_power_mode_on);
1131 }
1132 else
1133 {
1134 conf.configure_output(conf_output.id, false, conf_output.top_left,
1135- conf_output.current_mode_index, mir_power_mode_on);
1136+ conf_output.current_mode_index,
1137+ conf_output.current_format_index,
1138+ mir_power_mode_on);
1139 }
1140 });
1141 }
1142@@ -81,13 +85,17 @@
1143 if (conf_output.connected && conf_output.modes.size() > 0)
1144 {
1145 conf.configure_output(conf_output.id, true, geom::Point{max_x, 0},
1146- conf_output.preferred_mode_index, mir_power_mode_on);
1147+ conf_output.preferred_mode_index,
1148+ conf_output.current_format_index,
1149+ mir_power_mode_on);
1150 max_x += conf_output.modes[conf_output.preferred_mode_index].size.width.as_int();
1151 }
1152 else
1153 {
1154 conf.configure_output(conf_output.id, false, conf_output.top_left,
1155- conf_output.current_mode_index, mir_power_mode_on);
1156+ conf_output.current_mode_index,
1157+ conf_output.current_format_index,
1158+ mir_power_mode_on);
1159 }
1160 });
1161 }
1162@@ -472,7 +480,8 @@
1163 [&](mg::DisplayConfigurationOutput const& conf_output)
1164 {
1165 conf->configure_output(conf_output.id, false, conf_output.top_left,
1166- conf_output.preferred_mode_index, mir_power_mode_on);
1167+ conf_output.preferred_mode_index, 0,
1168+ mir_power_mode_on);
1169 });
1170
1171 display->configure(*conf);
1172@@ -508,7 +517,8 @@
1173 [&](mg::DisplayConfigurationOutput const& conf_output)
1174 {
1175 conf->configure_output(conf_output.id, false, conf_output.top_left,
1176- conf_output.preferred_mode_index, mir_power_mode_on);
1177+ conf_output.preferred_mode_index, 0,
1178+ mir_power_mode_on);
1179 });
1180
1181 display->configure(*conf);
1182
1183=== modified file 'tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp'
1184--- tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp 2013-12-18 02:19:19 +0000
1185+++ tests/unit-tests/graphics/mesa/test_overlapping_output_grouping.cpp 2013-12-20 13:46:31 +0000
1186@@ -89,7 +89,7 @@
1187 }
1188
1189 void configure_output(mg::DisplayConfigurationOutputId, bool,
1190- geom::Point, size_t, MirPowerMode)
1191+ geom::Point, size_t, size_t, MirPowerMode)
1192 {
1193 }
1194
1195
1196=== modified file 'tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp'
1197--- tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp 2013-09-12 21:36:55 +0000
1198+++ tests/unit-tests/graphics/nested/test_nested_display_configuration.cpp 2013-12-20 13:46:31 +0000
1199@@ -257,7 +257,7 @@
1200 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
1201
1202 config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true,
1203- top_left, default_current_mode, mir_power_mode_on);
1204+ top_left, default_current_mode, default_current_output_format, mir_power_mode_on);
1205
1206 MockOutputVisitor ov;
1207 EXPECT_CALL(ov, f(_)).Times(Exactly(1));
1208@@ -268,6 +268,7 @@
1209 EXPECT_EQ(true, output.used);
1210 EXPECT_EQ(top_left, output.top_left);
1211 EXPECT_EQ(0, output.current_mode_index);
1212+ EXPECT_EQ(0, output.current_format_index);
1213 });
1214 }
1215
1216@@ -278,11 +279,26 @@
1217 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
1218
1219 EXPECT_THROW(
1220- {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, -1, mir_power_mode_on);},
1221- std::runtime_error);
1222-
1223- EXPECT_THROW(
1224- {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, too_big_mode_index, mir_power_mode_on);},
1225+ {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, -1, default_current_output_format, mir_power_mode_on);},
1226+ std::runtime_error);
1227+
1228+ EXPECT_THROW(
1229+ {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, too_big_mode_index, default_current_output_format, mir_power_mode_on);},
1230+ std::runtime_error);
1231+}
1232+
1233+TEST_F(NestedDisplayConfiguration, configure_output_rejects_invalid_format)
1234+{
1235+ geom::Point const top_left{10,20};
1236+ size_t const too_big_format_index = 1;
1237+ mgn::NestedDisplayConfiguration config(build_trivial_configuration());
1238+
1239+ EXPECT_THROW(
1240+ {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, default_current_mode, -1, mir_power_mode_on);},
1241+ std::runtime_error);
1242+
1243+ EXPECT_THROW(
1244+ {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, default_current_mode, too_big_format_index, mir_power_mode_on);},
1245 std::runtime_error);
1246 }
1247
1248@@ -292,11 +308,11 @@
1249 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
1250
1251 EXPECT_THROW(
1252- {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id+1), true, top_left, default_current_mode, mir_power_mode_on);},
1253+ {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id+1), true, top_left, default_current_mode, default_current_output_format, mir_power_mode_on);},
1254 std::runtime_error);
1255
1256 EXPECT_THROW(
1257- {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id-1), true, top_left, default_current_mode, mir_power_mode_on);},
1258+ {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id-1), true, top_left, default_current_mode, default_current_output_format, mir_power_mode_on);},
1259 std::runtime_error);
1260 }
1261
1262@@ -326,7 +342,7 @@
1263 geom::Point const top_left{100,200};
1264 mgn::NestedDisplayConfiguration config(build_non_trivial_configuration());
1265
1266- config.configure_output(id, true, top_left, 1, mir_power_mode_on);
1267+ config.configure_output(id, true, top_left, 1, 2, mir_power_mode_on);
1268
1269 MockOutputVisitor ov;
1270 EXPECT_CALL(ov, f(_)).Times(Exactly(3));
1271@@ -338,6 +354,7 @@
1272 EXPECT_EQ(true, output.used);
1273 EXPECT_EQ(top_left, output.top_left);
1274 EXPECT_EQ(1, output.current_mode_index);
1275+ EXPECT_EQ(2, output.current_format_index);
1276 }
1277 });
1278 }
1279
1280=== modified file 'tests/unit-tests/graphics/test_default_display_configuration_policy.cpp'
1281--- tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-12-18 02:19:19 +0000
1282+++ tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-12-20 13:46:31 +0000
1283@@ -135,8 +135,8 @@
1284 f(output);
1285 }
1286
1287- MOCK_METHOD5(configure_output, void(mg::DisplayConfigurationOutputId, bool,
1288- geom::Point, size_t, MirPowerMode));
1289+ MOCK_METHOD6(configure_output, void(mg::DisplayConfigurationOutputId, bool,
1290+ geom::Point, size_t, size_t, MirPowerMode));
1291
1292 private:
1293 static const size_t max_simultaneous_outputs_all{std::numeric_limits<size_t>::max()};
1294@@ -159,12 +159,14 @@
1295 if (output.connected && output.modes.size() > 0)
1296 {
1297 EXPECT_CALL(conf, configure_output(output.id, true, geom::Point(),
1298- output.preferred_mode_index, _));
1299+ output.preferred_mode_index,
1300+ output.current_format_index, _));
1301 }
1302 else
1303 {
1304 EXPECT_CALL(conf, configure_output(output.id, false, output.top_left,
1305- output.current_mode_index, _));
1306+ output.current_mode_index,
1307+ output.current_format_index, _));
1308 }
1309 });
1310
1311@@ -180,7 +182,7 @@
1312
1313 conf.for_each_output([&conf](mg::DisplayConfigurationOutput const& output)
1314 {
1315- EXPECT_CALL(conf, configure_output(output.id, _, _, _, mir_power_mode_on));
1316+ EXPECT_CALL(conf, configure_output(output.id, _, _, _, _, mir_power_mode_on));
1317 });
1318
1319 policy.apply_to(conf);
1320@@ -200,10 +202,10 @@
1321 ++output_count;
1322 });
1323
1324- EXPECT_CALL(conf, configure_output(_, true, _, _, _))
1325+ EXPECT_CALL(conf, configure_output(_, true, _, _, _, _))
1326 .Times(AtMost(max_simultaneous_outputs));
1327
1328- EXPECT_CALL(conf, configure_output(_, false, _, _, _))
1329+ EXPECT_CALL(conf, configure_output(_, false, _, _, _, _))
1330 .Times(AtLeast(output_count - max_simultaneous_outputs));
1331
1332 policy.apply_to(conf);
1333
1334=== added file 'tests/unit-tests/graphics/test_pixel_format_utils.cpp'
1335--- tests/unit-tests/graphics/test_pixel_format_utils.cpp 1970-01-01 00:00:00 +0000
1336+++ tests/unit-tests/graphics/test_pixel_format_utils.cpp 2013-12-20 13:46:31 +0000
1337@@ -0,0 +1,79 @@
1338+/*
1339+ * Copyright © 2013 Canonical Ltd.
1340+ *
1341+ * This program is free software: you can redistribute it and/or modify it
1342+ * under the terms of the GNU General Public License version 3,
1343+ * as published by the Free Software Foundation.
1344+ *
1345+ * This program is distributed in the hope that it will be useful,
1346+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1347+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1348+ * GNU General Public License for more details.
1349+ *
1350+ * You should have received a copy of the GNU General Public License
1351+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1352+ *
1353+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
1354+ */
1355+
1356+#include "mir_toolkit/common.h"
1357+#include "mir/graphics/pixel_format_utils.h"
1358+#include <gmock/gmock.h>
1359+#include <gtest/gtest.h>
1360+
1361+namespace mg = mir::graphics;
1362+TEST(MirPixelformat,contains_alpha)
1363+{
1364+ EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_xbgr_8888));
1365+ EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_bgr_888));
1366+ EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_xrgb_8888));
1367+ EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_xbgr_8888));
1368+ EXPECT_TRUE(mg::contains_alpha(mir_pixel_format_argb_8888));
1369+ EXPECT_TRUE(mg::contains_alpha(mir_pixel_format_abgr_8888));
1370+ EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_invalid));
1371+}
1372+
1373+TEST(MirPixelformat,red_channel_depths)
1374+{
1375+ EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_xbgr_8888));
1376+ EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_bgr_888));
1377+ EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_xrgb_8888));
1378+ EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_xbgr_8888));
1379+ EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_argb_8888));
1380+ EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_abgr_8888));
1381+ EXPECT_EQ(0, mg::red_channel_depth(mir_pixel_format_invalid));
1382+}
1383+
1384+TEST(MirPixelformat,blue_channel_depths)
1385+{
1386+ EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_xbgr_8888));
1387+ EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_bgr_888));
1388+ EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_xrgb_8888));
1389+ EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_xbgr_8888));
1390+ EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_argb_8888));
1391+ EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_abgr_8888));
1392+ EXPECT_EQ(0, mg::red_channel_depth(mir_pixel_format_invalid));
1393+}
1394+
1395+TEST(MirPixelformat,green_channel_depths)
1396+{
1397+ EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_xbgr_8888));
1398+ EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_bgr_888));
1399+ EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_xrgb_8888));
1400+ EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_xbgr_8888));
1401+ EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_argb_8888));
1402+ EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_abgr_8888));
1403+ EXPECT_EQ(0, mg::red_channel_depth(mir_pixel_format_invalid));
1404+}
1405+
1406+
1407+TEST(MirPixelformat,alpha_channel_depths)
1408+{
1409+ EXPECT_EQ(0, mg::alpha_channel_depth(mir_pixel_format_xbgr_8888));
1410+ EXPECT_EQ(0, mg::alpha_channel_depth(mir_pixel_format_bgr_888));
1411+ EXPECT_EQ(0, mg::alpha_channel_depth(mir_pixel_format_xrgb_8888));
1412+ EXPECT_EQ(0, mg::alpha_channel_depth(mir_pixel_format_xbgr_8888));
1413+ EXPECT_EQ(8, mg::alpha_channel_depth(mir_pixel_format_argb_8888));
1414+ EXPECT_EQ(8, mg::alpha_channel_depth(mir_pixel_format_abgr_8888));
1415+ EXPECT_EQ(0, mg::red_channel_depth(mir_pixel_format_invalid));
1416+}

Subscribers

People subscribed via source and target branches