Mir

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

Proposed by Andreas Pokorny
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 Needs Fixing
Daniel van Vugt Pending
Alexandros Frantzis 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.
Revision history for this message
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
Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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
Revision history for this message
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.

Revision history for this message
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
Revision history for this message
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.

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

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

Revision history for this message
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
Revision history for this message
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

formating issues fixed

1288. By Andreas Pokorny

code style and formating improved

1289. By Andreas Pokorny

Moving Translucent option out of demo shell

1290. By Andreas Pokorny

Adding Basic Server Copy which always selects a transucent outpu

Currently named greeter - but does not greet reasonable yet.

1291. By Andreas Pokorny

Override and variable nameing missing

1292. By Andreas Pokorny

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

merging cross compile fixes

Revision history for this message
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

WIP rework of render_surfaces demo - dropped greeter

1294. By Andreas Pokorny

Merging surfacesless branch with latest improvement

1295. By Andreas Pokorny

Reworked the example - integrated it into render surfaces

1296. By Andreas Pokorny

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

uninitialized member variable

1298. By Andreas Pokorny

duplicated parameter removed, const added to SelectPixelFormat

1299. By Andreas Pokorny

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

Unmerged revisions

1299. By Andreas Pokorny

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

1298. By Andreas Pokorny

duplicated parameter removed, const added to SelectPixelFormat

1297. By Andreas Pokorny

uninitialized member variable

1296. By Andreas Pokorny

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

Reworked the example - integrated it into render surfaces

1294. By Andreas Pokorny

Merging surfacesless branch with latest improvement

1293. By Andreas Pokorny

WIP rework of render_surfaces demo - dropped greeter

1292. By Andreas Pokorny

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

merging cross compile fixes

1291. By Andreas Pokorny

Override and variable nameing missing

1290. By Andreas Pokorny

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
=== modified file 'examples/CMakeLists.txt'
--- examples/CMakeLists.txt 2013-12-18 02:19:19 +0000
+++ examples/CMakeLists.txt 2013-12-20 13:46:31 +0000
@@ -109,6 +109,7 @@
109 buffer_render_target.cpp109 buffer_render_target.cpp
110 image_renderer.cpp110 image_renderer.cpp
111 server_configuration.cpp111 server_configuration.cpp
112 select_pixel_format.cpp
112)113)
113add_executable(mir_demo_standalone_render_surfaces ${RENDER_SURFACES_SOURCES})114add_executable(mir_demo_standalone_render_surfaces ${RENDER_SURFACES_SOURCES})
114target_link_libraries(mir_demo_standalone_render_surfaces115target_link_libraries(mir_demo_standalone_render_surfaces
@@ -157,4 +158,3 @@
157install(TARGETS mir_demo_server_basic158install(TARGETS mir_demo_server_basic
158 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}159 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
159)160)
160
161161
=== modified file 'examples/basic_server.cpp'
--- examples/basic_server.cpp 2013-09-25 11:56:15 +0000
+++ examples/basic_server.cpp 2013-12-20 13:46:31 +0000
@@ -52,8 +52,6 @@
52 (void)ignore;52 (void)ignore;
53 }53 }
54 }54 }
55
56 using mir::examples::ServerConfiguration::the_options;
57};55};
58}56}
5957
6058
=== modified file 'examples/demo-shell/window_manager.cpp'
--- examples/demo-shell/window_manager.cpp 2013-12-18 02:19:19 +0000
+++ examples/demo-shell/window_manager.cpp 2013-12-20 13:46:31 +0000
@@ -153,6 +153,7 @@
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_index,
156 power_mode);157 power_mode);
157 });158 });
158 display_off = !display_off;159 display_off = !display_off;
159160
=== modified file 'examples/render_surfaces.cpp'
--- examples/render_surfaces.cpp 2013-12-18 02:19:19 +0000
+++ examples/render_surfaces.cpp 2013-12-20 13:46:31 +0000
@@ -24,6 +24,7 @@
24#include "mir/geometry/size.h"24#include "mir/geometry/size.h"
25#include "mir/geometry/rectangles.h"25#include "mir/geometry/rectangles.h"
26#include "mir/graphics/buffer_initializer.h"26#include "mir/graphics/buffer_initializer.h"
27#include "mir/graphics/pixel_format_utils.h"
27#include "mir/graphics/cursor.h"28#include "mir/graphics/cursor.h"
28#include "mir/graphics/display.h"29#include "mir/graphics/display.h"
29#include "mir/graphics/display_buffer.h"30#include "mir/graphics/display_buffer.h"
@@ -36,13 +37,15 @@
36#include "buffer_render_target.h"37#include "buffer_render_target.h"
37#include "image_renderer.h"38#include "image_renderer.h"
38#include "server_configuration.h"39#include "server_configuration.h"
40#include "select_pixel_format.h"
3941
40#include <thread>42#include <algorithm>
41#include <atomic>43#include <atomic>
42#include <chrono>44#include <chrono>
43#include <csignal>45#include <csignal>
44#include <iostream>46#include <iostream>
45#include <sstream>47#include <sstream>
48#include <thread>
46#include <vector>49#include <vector>
4750
48#include <glm/gtc/matrix_transform.hpp>51#include <glm/gtc/matrix_transform.hpp>
@@ -136,6 +139,7 @@
136139
137char const* const surfaces_to_render = "surfaces-to-render";140char const* const surfaces_to_render = "surfaces-to-render";
138char const* const display_cursor = "display-cursor";141char const* const display_cursor = "display-cursor";
142char const* const translucent = "translucent";
139143
140///\internal [StopWatch_tag]144///\internal [StopWatch_tag]
141// tracks elapsed time - for animation.145// tracks elapsed time - for animation.
@@ -260,6 +264,10 @@
260 add_options()264 add_options()
261 (surfaces_to_render, po::value<int>(), "Number of surfaces to render"265 (surfaces_to_render, po::value<int>(), "Number of surfaces to render"
262 " [int:default=5]")266 " [int:default=5]")
267 (surfaces_to_render, po::value<int>(), "Number of surfaces to render"
268 " [int:default=5]")
269 (translucent, po::bool_switch()->default_value(false),
270 "Enable translucent frame buffer")
263 (display_cursor, po::value<bool>(), "Display test cursor. (If input is "271 (display_cursor, po::value<bool>(), "Display test cursor. (If input is "
264 "disabled it gets animated.) "272 "disabled it gets animated.) "
265 "[bool:default=false]");273 "[bool:default=false]");
@@ -306,6 +314,18 @@
306 return std::make_shared<RenderResourcesBufferInitializer>();314 return std::make_shared<RenderResourcesBufferInitializer>();
307 }315 }
308 ///\internal [RenderResourcesBufferInitializer_tag]316 ///\internal [RenderResourcesBufferInitializer_tag]
317
318 std::shared_ptr<mg::DisplayConfigurationPolicy> the_display_configuration_policy() override
319 {
320 return display_configuration_policy(
321 [this]() -> std::shared_ptr<mg::DisplayConfigurationPolicy>
322 {
323 return std::make_shared<me::SelectPixelFormat>(
324 me::ServerConfiguration::the_display_configuration_policy(),
325 the_options()->get(translucent,false));
326 }
327 );
328 }
309329
310 ///\internal [RenderSurfacesDisplayBufferCompositor_tag]330 ///\internal [RenderSurfacesDisplayBufferCompositor_tag]
311 // Decorate the DefaultDisplayBufferCompositor in order to move surfaces.331 // Decorate the DefaultDisplayBufferCompositor in order to move surfaces.
@@ -334,7 +354,7 @@
334 stop_watch.restart();354 stop_watch.restart();
335 }355 }
336356
337 glClearColor(0.0, 1.0, 0.0, 1.0);357 glClearColor(0.0, 1.0, 0.0, 0.0);
338 db_compositor->composite();358 db_compositor->composite();
339359
340 for (auto& m : moveables)360 for (auto& m : moveables)
341361
=== added file 'examples/select_pixel_format.cpp'
--- examples/select_pixel_format.cpp 1970-01-01 00:00:00 +0000
+++ examples/select_pixel_format.cpp 2013-12-20 13:46:31 +0000
@@ -0,0 +1,69 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */
18
19#include "select_pixel_format.h"
20
21#include "mir/graphics/display_configuration.h"
22#include "mir/graphics/pixel_format_utils.h"
23
24#include <stdexcept>
25#include <algorithm>
26
27
28namespace mir
29{
30namespace examples
31{
32
33SelectPixelFormat::SelectPixelFormat(std::shared_ptr<DisplayConfigurationPolicy> const& base_policy,
34 bool with_alpha)
35 : base_policy(base_policy),
36 with_alpha(with_alpha)
37{}
38
39void SelectPixelFormat::apply_to(graphics::DisplayConfiguration & conf)
40{
41 base_policy->apply_to(conf);
42 conf.for_each_output(
43 [&](graphics::DisplayConfigurationOutput const& conf_output)
44 {
45 if (!conf_output.connected || !conf_output.used) return;
46
47 auto const& pos = find_if(conf_output.pixel_formats.begin(),
48 conf_output.pixel_formats.end(),
49 [&](MirPixelFormat format) -> bool
50 {
51 return graphics::contains_alpha(format) == with_alpha;
52 }
53 );
54
55 // keep the default setings if nothing was found
56 if (pos == conf_output.pixel_formats.end())
57 return;
58
59 conf.configure_output(conf_output.id, true, conf_output.top_left,
60 conf_output.current_mode_index,
61 std::distance(conf_output.pixel_formats.begin(), pos),
62 conf_output.power_mode
63 );
64 });
65}
66
67}
68}
69
070
=== added file 'examples/select_pixel_format.h'
--- examples/select_pixel_format.h 1970-01-01 00:00:00 +0000
+++ examples/select_pixel_format.h 2013-12-20 13:46:31 +0000
@@ -0,0 +1,52 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */
18
19
20#ifndef MIR_EXAMPLES_SELECT_PIXEL_FORMAT_H
21#define MIR_EXAMPLES_SELECT_PIXEL_FORMAT_H
22
23#include "mir/graphics/display_configuration_policy.h"
24
25#include <boost/shared_ptr.hpp>
26
27
28namespace mir
29{
30namespace examples
31{
32
33/**
34 * \brief Example of a DisplayConfigurationPolicy that tries to find
35 * an opaque or transparent pixel format, or falls back to the default
36 * if not found.
37 */
38class SelectPixelFormat : public graphics::DisplayConfigurationPolicy
39{
40public:
41 SelectPixelFormat(std::shared_ptr<graphics::DisplayConfigurationPolicy> const& base_policy,
42 bool with_alpha);
43 virtual void apply_to(graphics::DisplayConfiguration& conf);
44private:
45 std::shared_ptr<graphics::DisplayConfigurationPolicy> const base_policy;
46 bool with_alpha;
47};
48
49}
50}
51
52#endif
053
=== modified file 'examples/server_configuration.cpp'
--- examples/server_configuration.cpp 2013-10-21 10:40:19 +0000
+++ examples/server_configuration.cpp 2013-12-20 13:46:31 +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_index,
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_index,
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_index,
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_index,
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 2013-12-20 13:46:31 +0000
@@ -135,8 +135,8 @@
135 virtual void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const = 0;135 virtual void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const = 0;
136136
137 /** Configures an output. */137 /** Configures an output. */
138 virtual void configure_output(DisplayConfigurationOutputId id, bool used,138 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;139 size_t mode_index, size_t format_index, MirPowerMode power_mode) = 0;
140140
141protected:141protected:
142 DisplayConfiguration() = default;142 DisplayConfiguration() = default;
143143
=== modified file 'include/platform/mir/graphics/platform.h'
--- include/platform/mir/graphics/platform.h 2013-12-18 02:19:19 +0000
+++ include/platform/mir/graphics/platform.h 2013-12-20 13:46:31 +0000
@@ -81,7 +81,7 @@
81 * Creates the display subsystem.81 * Creates the display subsystem.
82 */82 */
83 virtual std::shared_ptr<Display> create_display(83 virtual std::shared_ptr<Display> create_display(
84 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) = 0;84 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy) = 0;
8585
86 /**86 /**
87 * Gets the IPC package for the platform.87 * Gets the IPC package for the platform.
8888
=== added file 'include/server/mir/graphics/pixel_format_utils.h'
--- include/server/mir/graphics/pixel_format_utils.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/graphics/pixel_format_utils.h 2013-12-20 13:46:31 +0000
@@ -0,0 +1,46 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */
18
19#include "mir_toolkit/common.h"
20
21#include <cstdint>
22
23namespace mir
24{
25namespace graphics
26{
27
28/*!
29 * \name MirPixelFormat utility functions
30 *
31 * A set of functions to query details of MirPixelFormat
32 * TODO improve this through https://bugs.launchpad.net/mir/+bug/1236254
33 * \{
34 */
35bool contains_alpha(MirPixelFormat format);
36int32_t red_channel_depth(MirPixelFormat format);
37int32_t blue_channel_depth(MirPixelFormat format);
38int32_t green_channel_depth(MirPixelFormat format);
39int32_t alpha_channel_depth(MirPixelFormat format);
40/*!
41 * \}
42 */
43
44
45}
46}
047
=== 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 2013-12-20 13:46:31 +0000
@@ -35,7 +35,7 @@
35 void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)>) const35 void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)>) const
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, size_t, 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 2013-12-20 13:46:31 +0000
@@ -136,7 +136,7 @@
136 }136 }
137 }137 }
138138
139 void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode)139 void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t, size_t, MirPowerMode)
140 {140 {
141 }141 }
142142
143143
=== 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 2013-12-20 13:46:31 +0000
@@ -62,7 +62,7 @@
62 f(configuration);62 f(configuration);
63}63}
6464
65void mga::AndroidDisplayConfiguration::configure_output(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPowerMode power_mode)65void mga::AndroidDisplayConfiguration::configure_output(mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, size_t, MirPowerMode power_mode)
66{66{
67 configuration.power_mode = power_mode;67 configuration.power_mode = power_mode;
68}68}
6969
=== 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 2013-12-20 13:46:31 +0000
@@ -37,7 +37,7 @@
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;
39 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;39 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;
40 void configure_output(DisplayConfigurationOutputId, bool, geometry::Point, size_t, MirPowerMode power_mode);40 void configure_output(DisplayConfigurationOutputId, bool, geometry::Point, size_t, size_t, MirPowerMode power_mode);
4141
42private:42private:
43 DisplayConfigurationOutput configuration;43 DisplayConfigurationOutput configuration;
4444
=== 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 2013-12-20 13:46:31 +0000
@@ -109,7 +109,7 @@
109void mgm::RealKMSDisplayConfiguration::configure_output(109void mgm::RealKMSDisplayConfiguration::configure_output(
110 DisplayConfigurationOutputId id, bool used,110 DisplayConfigurationOutputId id, bool used,
111 geometry::Point top_left, size_t mode_index,111 geometry::Point top_left, size_t mode_index,
112 MirPowerMode power_mode)112 size_t format_index, MirPowerMode power_mode)
113{113{
114 auto iter = find_output_with_id(id);114 auto iter = find_output_with_id(id);
115115
@@ -120,9 +120,13 @@
120 if (used && mode_index >= output.modes.size())120 if (used && mode_index >= output.modes.size())
121 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));121 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));
122122
123 if (used && format_index >= output.pixel_formats.size())
124 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid format_index for used output"));
125
123 output.used = used;126 output.used = used;
124 output.top_left = top_left;127 output.top_left = top_left;
125 output.current_mode_index = mode_index;128 output.current_mode_index = mode_index;
129 output.current_format_index = format_index;
126 output.power_mode = power_mode;130 output.power_mode = power_mode;
127 }131 }
128 else132 else
129133
=== 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 2013-12-20 13:46:31 +0000
@@ -39,8 +39,8 @@
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;
41 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;41 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const;
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, size_t foramt_index, MirPowerMode power_mode);
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/session_mediator.cpp'
--- src/server/frontend/session_mediator.cpp 2013-12-18 02:19:19 +0000
+++ src/server/frontend/session_mediator.cpp 2013-12-20 13:46:31 +0000
@@ -321,7 +321,8 @@
321 mg::DisplayConfigurationOutputId output_id{static_cast<int>(output.output_id())};321 mg::DisplayConfigurationOutputId output_id{static_cast<int>(output.output_id())};
322 config->configure_output(output_id, output.used(),322 config->configure_output(output_id, output.used(),
323 geom::Point{output.position_x(), output.position_y()},323 geom::Point{output.position_x(), output.position_y()},
324 output.current_mode(), static_cast<MirPowerMode>(output.power_mode()));324 output.current_mode(), output.current_format(),
325 static_cast<MirPowerMode>(output.power_mode()));
325 }326 }
326327
327 display_changer->configure(session, config);328 display_changer->configure(session, config);
328329
=== modified file 'src/server/graphics/CMakeLists.txt'
--- src/server/graphics/CMakeLists.txt 2013-12-20 05:06:28 +0000
+++ src/server/graphics/CMakeLists.txt 2013-12-20 13:46:31 +0000
@@ -5,6 +5,7 @@
55
6 default_configuration.cpp6 default_configuration.cpp
7 default_display_configuration_policy.cpp7 default_display_configuration_policy.cpp
8 pixel_format_utils.cpp
8 gl_extensions_base.cpp9 gl_extensions_base.cpp
9 surfaceless_egl_context.cpp10 surfaceless_egl_context.cpp
10)11)
1112
=== 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 2013-12-20 13:46:31 +0000
@@ -45,15 +45,16 @@
45 if (preferred_mode_index > conf_output.modes.size())45 if (preferred_mode_index > conf_output.modes.size())
46 preferred_mode_index = 0;46 preferred_mode_index = 0;
4747
48 conf.configure_output(conf_output.id, true, geom::Point(),48 conf.configure_output(conf_output.id, true, geom::Point(), preferred_mode_index,
49 preferred_mode_index, default_power_state);49 conf_output.current_format_index, default_power_state);
5050
51 --available_outputs_for_card[conf_output.card_id];51 --available_outputs_for_card[conf_output.card_id];
52 }52 }
53 else53 else
54 {54 {
55 conf.configure_output(conf_output.id, false, conf_output.top_left,55 conf.configure_output(conf_output.id, false, conf_output.top_left,
56 conf_output.current_mode_index, default_power_state);56 conf_output.current_mode_index, conf_output.current_format_index,
57 default_power_state);
57 }58 }
58 });59 });
59}60}
6061
=== 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 2013-12-20 13:46:31 +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};
@@ -100,7 +65,7 @@
100 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to fetch EGL display."));65 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to fetch EGL display."));
101}66}
10267
103void mgn::detail::EGLDisplayHandle::initialize()68void mgn::detail::EGLDisplayHandle::initialize(MirPixelFormat format)
104{69{
105 int major;70 int major;
106 int minor;71 int minor;
@@ -110,17 +75,28 @@
110 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to initialize EGL."));75 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to initialize EGL."));
111 }76 }
11277
113 egl_context_ = eglCreateContext(egl_display, choose_config(detail::nested_egl_config_attribs), EGL_NO_CONTEXT, detail::nested_egl_context_attribs);78 egl_context_ = eglCreateContext(egl_display, choose_windowed_es_config(format), EGL_NO_CONTEXT, detail::nested_egl_context_attribs);
79
114 if (egl_context_ == EGL_NO_CONTEXT)80 if (egl_context_ == EGL_NO_CONTEXT)
115 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create shared EGL context"));81 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create shared EGL context"));
116}82}
11783
118EGLConfig mgn::detail::EGLDisplayHandle::choose_config(const EGLint attrib_list[]) const84EGLConfig mgn::detail::EGLDisplayHandle::choose_windowed_es_config(MirPixelFormat format) const
119{85{
86 EGLint const nested_egl_config_attribs[] =
87 {
88 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
89 EGL_RED_SIZE, mg::red_channel_depth(format),
90 EGL_GREEN_SIZE, mg::green_channel_depth(format),
91 EGL_BLUE_SIZE, mg::blue_channel_depth(format),
92 EGL_ALPHA_SIZE, mg::alpha_channel_depth(format),
93 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
94 EGL_NONE
95 };
120 EGLConfig result;96 EGLConfig result;
121 int n;97 int n;
12298
123 int res = eglChooseConfig(egl_display, attrib_list, &result, 1, &n);99 int res = eglChooseConfig(egl_display, nested_egl_config_attribs, &result, 1, &n);
124 if ((res != EGL_TRUE) || (n != 1))100 if ((res != EGL_TRUE) || (n != 1))
125 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to choose EGL configuration."));101 BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir Display Error: Failed to choose EGL configuration."));
126102
@@ -149,17 +125,18 @@
149mgn::NestedDisplay::NestedDisplay(125mgn::NestedDisplay::NestedDisplay(
150 std::shared_ptr<HostConnection> const& connection,126 std::shared_ptr<HostConnection> const& connection,
151 std::shared_ptr<input::EventFilter> const& event_handler,127 std::shared_ptr<input::EventFilter> const& event_handler,
152 std::shared_ptr<mg::DisplayReport> const& display_report) :128 std::shared_ptr<mg::DisplayReport> const& display_report,
129 std::shared_ptr<mg::DisplayConfigurationPolicy> const& initial_conf_policy) :
153 connection{connection},130 connection{connection},
154 event_handler{event_handler},131 event_handler{event_handler},
155 display_report{display_report},132 display_report{display_report},
156 egl_display{*connection},133 egl_display{*connection},
157 egl_pixel_format{find_opaque_surface_format(*connection)},
158 outputs{}134 outputs{}
159{135{
160 egl_display.initialize();136
161 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_display.egl_context());137 std::shared_ptr<DisplayConfiguration> conf(configuration());
162 configure(*configuration());138 initial_conf_policy->apply_to(*conf);
139 configure(*conf);
163}140}
164141
165mgn::NestedDisplay::~NestedDisplay() noexcept142mgn::NestedDisplay::~NestedDisplay() noexcept
@@ -178,6 +155,14 @@
178 return std::make_shared<NestedDisplayConfiguration>(mir_connection_create_display_config(*connection));155 return std::make_shared<NestedDisplayConfiguration>(mir_connection_create_display_config(*connection));
179}156}
180157
158void mgn::NestedDisplay::complete_display_initialization(MirPixelFormat format)
159{
160 if (egl_display.egl_context() != EGL_NO_CONTEXT) return;
161
162 egl_display.initialize(format);
163 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_display.egl_context());
164}
165
181void mgn::NestedDisplay::configure(mg::DisplayConfiguration const& configuration)166void mgn::NestedDisplay::configure(mg::DisplayConfiguration const& configuration)
182{167{
183 decltype(outputs) result;168 decltype(outputs) result;
@@ -193,13 +178,16 @@
193 geometry::Rectangle const area{output.top_left, output.modes[output.current_mode_index].size};178 geometry::Rectangle const area{output.top_left, output.modes[output.current_mode_index].size};
194179
195 auto const& egl_display_mode = output.modes[output.current_mode_index];180 auto const& egl_display_mode = output.modes[output.current_mode_index];
181 auto const& egl_config_format = output.pixel_formats[output.current_format_index];
182
183 complete_display_initialization(egl_config_format);
196184
197 MirSurfaceParameters const request_params =185 MirSurfaceParameters const request_params =
198 {186 {
199 "Mir nested display",187 "Mir nested display",
200 egl_display_mode.size.width.as_int(),188 egl_display_mode.size.width.as_int(),
201 egl_display_mode.size.height.as_int(),189 egl_display_mode.size.height.as_int(),
202 egl_pixel_format,190 egl_config_format,
203 mir_buffer_usage_hardware,191 mir_buffer_usage_hardware,
204 static_cast<uint32_t>(output.id.as_value())192 static_cast<uint32_t>(output.id.as_value())
205 };193 };
@@ -213,7 +201,8 @@
213 egl_display,201 egl_display,
214 mir_surface,202 mir_surface,
215 area,203 area,
216 event_handler);204 event_handler,
205 output.pixel_formats[output.current_format_index]);
217 }206 }
218 });207 });
219208
@@ -274,13 +263,7 @@
274 return std::weak_ptr<Cursor>();263 return std::weak_ptr<Cursor>();
275}264}
276265
277namespace
278{
279}
280
281std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context()266std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context()
282{267{
283 return std::unique_ptr<mg::GLContext>{new SurfacelessEGLContext(egl_display,268 return std::unique_ptr<mg::GLContext>{new SurfacelessEGLContext(egl_display, EGL_NO_CONTEXT)};
284 detail::nested_egl_config_attribs,
285 EGL_NO_CONTEXT)};
286}269}
287270
=== 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 2013-12-20 13:46:31 +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 2013-12-20 13:46:31 +0000
@@ -86,7 +86,7 @@
86}86}
8787
88void mgn::NestedDisplayConfiguration::configure_output(DisplayConfigurationOutputId id, bool used,88void mgn::NestedDisplayConfiguration::configure_output(DisplayConfigurationOutputId id, bool used,
89 geometry::Point top_left, size_t mode_index, MirPowerMode power_mode)89 geometry::Point top_left, size_t mode_index, size_t format_index, MirPowerMode power_mode)
90{90{
91 for (auto mir_output = display_config->outputs;91 for (auto mir_output = display_config->outputs;
92 mir_output != display_config->outputs+display_config->num_outputs;92 mir_output != display_config->outputs+display_config->num_outputs;
@@ -97,10 +97,14 @@
97 if (used && mode_index >= mir_output->num_modes)97 if (used && mode_index >= mir_output->num_modes)
98 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));98 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid mode_index for used output"));
9999
100 if (used && format_index >= mir_output->num_output_formats)
101 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid format_index for used output"));
102
100 mir_output->used = used;103 mir_output->used = used;
101 mir_output->position_x = top_left.x.as_uint32_t();104 mir_output->position_x = top_left.x.as_uint32_t();
102 mir_output->position_y = top_left.y.as_uint32_t();105 mir_output->position_y = top_left.y.as_uint32_t();
103 mir_output->current_mode = mode_index;106 mir_output->current_mode = mode_index;
107 mir_output->current_output_format = format_index;
104 mir_output->power_mode = static_cast<MirPowerMode>(power_mode);108 mir_output->power_mode = static_cast<MirPowerMode>(power_mode);
105 return;109 return;
106 }110 }
107111
=== 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 2013-12-20 13:46:31 +0000
@@ -38,7 +38,7 @@
38 void for_each_output(std::function<void(DisplayConfigurationOutput const&)>) const;38 void for_each_output(std::function<void(DisplayConfigurationOutput const&)>) const;
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 size_t format_index, MirPowerMode power_mode);
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 2013-12-20 13:46:31 +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 2013-12-20 13:46:31 +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 2013-12-20 13:46:31 +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 2013-12-20 13:46:31 +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 2013-12-20 13:46:31 +0000
@@ -67,6 +67,6 @@
67}67}
6868
69void mgo::DisplayConfiguration::configure_output(69void mgo::DisplayConfiguration::configure_output(
70 mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, MirPowerMode)70 mg::DisplayConfigurationOutputId, bool, geom::Point, size_t, size_t, MirPowerMode)
71{71{
72}72}
7373
=== 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 2013-12-20 13:46:31 +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, size_t format_index, MirPowerMode power_mode) override;
4040
41private:41private:
42 DisplayConfigurationOutput output;42 DisplayConfigurationOutput output;
4343
=== added file 'src/server/graphics/pixel_format_utils.cpp'
--- src/server/graphics/pixel_format_utils.cpp 1970-01-01 00:00:00 +0000
+++ src/server/graphics/pixel_format_utils.cpp 2013-12-20 13:46:31 +0000
@@ -0,0 +1,65 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */
18
19#include "mir/graphics/pixel_format_utils.h"
20
21namespace mir
22{
23namespace graphics
24{
25
26bool contains_alpha(MirPixelFormat format)
27{
28 return (format == mir_pixel_format_abgr_8888 ||
29 format == mir_pixel_format_argb_8888);
30}
31
32int32_t red_channel_depth(MirPixelFormat format)
33{
34 if (mir_pixel_format_invalid < format &&
35 format < mir_pixel_formats)
36 return 8;
37 return 0;
38}
39
40int32_t blue_channel_depth(MirPixelFormat format)
41{
42 if (mir_pixel_format_invalid < format &&
43 format < mir_pixel_formats)
44 return 8;
45 return 0;
46}
47
48int32_t green_channel_depth( MirPixelFormat format )
49{
50 if (mir_pixel_format_invalid < format &&
51 format < mir_pixel_formats)
52 return 8;
53 return 0;
54}
55
56int32_t alpha_channel_depth( MirPixelFormat format )
57{
58 if (format == mir_pixel_format_abgr_8888 ||
59 format == mir_pixel_format_argb_8888)
60 return 8;
61 return 0;
62}
63
64}
65}
066
=== 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 2013-12-20 13:46:31 +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_index,
139 mir_power_mode_on);140 mir_power_mode_on);
140 }141 }
141 });142 });
142143
=== 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 2013-12-20 13:46:31 +0000
@@ -175,7 +175,7 @@
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, size_t, MirPowerMode)
179 {179 {
180 }180 }
181181
182182
=== 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 2013-12-20 13:46:31 +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, size_t, MirPowerMode));
87};87};
8888
89}89}
@@ -555,6 +555,7 @@
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 size_t format_index0 = 2, format_index1 = 0;
558 mg::DisplayConfigurationOutputId id0{6}, id1{3};559 mg::DisplayConfigurationOutputId id0{6}, id1{3};
559560
560 NiceMock<MockConfig> mock_display_config;561 NiceMock<MockConfig> mock_display_config;
@@ -568,9 +569,9 @@
568 EXPECT_CALL(*mock_display_selector, active_configuration())569 EXPECT_CALL(*mock_display_selector, active_configuration())
569 .InSequence(seq)570 .InSequence(seq)
570 .WillOnce(Return(mt::fake_shared(mock_display_config)));571 .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))572 EXPECT_CALL(mock_display_config, configure_output(id0, used0, pt0, mode_index0, format_index0, mir_power_mode_on))
572 .InSequence(seq);573 .InSequence(seq);
573 EXPECT_CALL(mock_display_config, configure_output(id1, used1, pt1, mode_index1, mir_power_mode_off))574 EXPECT_CALL(mock_display_config, configure_output(id1, used1, pt1, mode_index1, format_index1, mir_power_mode_off))
574 .InSequence(seq);575 .InSequence(seq);
575 EXPECT_CALL(*mock_display_selector, configure(_,_))576 EXPECT_CALL(*mock_display_selector, configure(_,_))
576 .InSequence(seq);577 .InSequence(seq);
@@ -593,6 +594,7 @@
593 disp0->set_position_x(pt0.x.as_uint32_t());594 disp0->set_position_x(pt0.x.as_uint32_t());
594 disp0->set_position_y(pt0.y.as_uint32_t());595 disp0->set_position_y(pt0.y.as_uint32_t());
595 disp0->set_current_mode(mode_index0);596 disp0->set_current_mode(mode_index0);
597 disp0->set_current_format(format_index0);
596 disp0->set_power_mode(static_cast<uint32_t>(mir_power_mode_on));598 disp0->set_power_mode(static_cast<uint32_t>(mir_power_mode_on));
597599
598 auto disp1 = configuration.add_display_output();600 auto disp1 = configuration.add_display_output();
@@ -601,6 +603,7 @@
601 disp1->set_position_x(pt1.x.as_uint32_t());603 disp1->set_position_x(pt1.x.as_uint32_t());
602 disp1->set_position_y(pt1.y.as_uint32_t());604 disp1->set_position_y(pt1.y.as_uint32_t());
603 disp1->set_current_mode(mode_index1);605 disp1->set_current_mode(mode_index1);
606 disp1->set_current_format(format_index1);
604 disp1->set_power_mode(static_cast<uint32_t>(mir_power_mode_off));607 disp1->set_power_mode(static_cast<uint32_t>(mir_power_mode_off));
605608
606 session_mediator.configure_display(nullptr, &configuration,609 session_mediator.configure_display(nullptr, &configuration,
607610
=== modified file 'tests/unit-tests/graphics/CMakeLists.txt'
--- tests/unit-tests/graphics/CMakeLists.txt 2013-12-20 05:06:28 +0000
+++ tests/unit-tests/graphics/CMakeLists.txt 2013-12-20 13:46:31 +0000
@@ -6,6 +6,7 @@
6 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_configuration_policy.cpp6 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_configuration_policy.cpp
7 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_id.cpp7 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_id.cpp
8 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_properties.cpp8 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_properties.cpp
9 ${CMAKE_CURRENT_SOURCE_DIR}/test_pixel_format_utils.cpp
9 ${CMAKE_CURRENT_SOURCE_DIR}/test_surfaceless_egl_context.cpp10 ${CMAKE_CURRENT_SOURCE_DIR}/test_surfaceless_egl_context.cpp
10)11)
1112
1213
=== 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 2013-12-20 13:46:31 +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_index, 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_index, 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_index, 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_index, 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 2013-12-20 13:46:31 +0000
@@ -141,7 +141,7 @@
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, size_t, MirPowerMode)
145 {145 {
146 }146 }
147147
148148
=== 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 2013-12-20 13:46:31 +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_index,
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_index,
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_index,
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_index,
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, 0,
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, 0,
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 2013-12-20 13:46:31 +0000
@@ -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, size_t, MirPowerMode)
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 2013-12-20 13:46:31 +0000
@@ -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(0, output.current_format_index);
271 });272 });
272}273}
273274
@@ -278,11 +279,26 @@
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 size_t const too_big_format_index = 1;
294 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
295
296 EXPECT_THROW(
297 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, default_current_mode, -1, mir_power_mode_on);},
298 std::runtime_error);
299
300 EXPECT_THROW(
301 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id), true, top_left, default_current_mode, too_big_format_index, mir_power_mode_on);},
286 std::runtime_error);302 std::runtime_error);
287}303}
288304
@@ -292,11 +308,11 @@
292 mgn::NestedDisplayConfiguration config(build_trivial_configuration());308 mgn::NestedDisplayConfiguration config(build_trivial_configuration());
293309
294 EXPECT_THROW(310 EXPECT_THROW(
295 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id+1), true, top_left, default_current_mode, mir_power_mode_on);},311 {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);312 std::runtime_error);
297313
298 EXPECT_THROW(314 EXPECT_THROW(
299 {config.configure_output(mg::DisplayConfigurationOutputId(default_output_id-1), true, top_left, default_current_mode, mir_power_mode_on);},315 {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);316 std::runtime_error);
301}317}
302318
@@ -326,7 +342,7 @@
326 geom::Point const top_left{100,200};342 geom::Point const top_left{100,200};
327 mgn::NestedDisplayConfiguration config(build_non_trivial_configuration());343 mgn::NestedDisplayConfiguration config(build_non_trivial_configuration());
328344
329 config.configure_output(id, true, top_left, 1, mir_power_mode_on);345 config.configure_output(id, true, top_left, 1, 2, mir_power_mode_on);
330346
331 MockOutputVisitor ov;347 MockOutputVisitor ov;
332 EXPECT_CALL(ov, f(_)).Times(Exactly(3));348 EXPECT_CALL(ov, f(_)).Times(Exactly(3));
@@ -338,6 +354,7 @@
338 EXPECT_EQ(true, output.used);354 EXPECT_EQ(true, output.used);
339 EXPECT_EQ(top_left, output.top_left);355 EXPECT_EQ(top_left, output.top_left);
340 EXPECT_EQ(1, output.current_mode_index);356 EXPECT_EQ(1, output.current_mode_index);
357 EXPECT_EQ(2, output.current_format_index);
341 }358 }
342 });359 });
343}360}
344361
=== 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 2013-12-20 13:46:31 +0000
@@ -135,8 +135,8 @@
135 f(output);135 f(output);
136 }136 }
137137
138 MOCK_METHOD5(configure_output, void(mg::DisplayConfigurationOutputId, bool,138 MOCK_METHOD6(configure_output, void(mg::DisplayConfigurationOutputId, bool,
139 geom::Point, size_t, MirPowerMode));139 geom::Point, size_t, size_t, MirPowerMode));
140140
141private:141private:
142 static const size_t max_simultaneous_outputs_all{std::numeric_limits<size_t>::max()};142 static const size_t max_simultaneous_outputs_all{std::numeric_limits<size_t>::max()};
@@ -159,12 +159,14 @@
159 if (output.connected && output.modes.size() > 0)159 if (output.connected && output.modes.size() > 0)
160 {160 {
161 EXPECT_CALL(conf, configure_output(output.id, true, geom::Point(),161 EXPECT_CALL(conf, configure_output(output.id, true, geom::Point(),
162 output.preferred_mode_index, _));162 output.preferred_mode_index,
163 output.current_format_index, _));
163 }164 }
164 else165 else
165 {166 {
166 EXPECT_CALL(conf, configure_output(output.id, false, output.top_left,167 EXPECT_CALL(conf, configure_output(output.id, false, output.top_left,
167 output.current_mode_index, _));168 output.current_mode_index,
169 output.current_format_index, _));
168 }170 }
169 });171 });
170172
@@ -180,7 +182,7 @@
180182
181 conf.for_each_output([&conf](mg::DisplayConfigurationOutput const& output)183 conf.for_each_output([&conf](mg::DisplayConfigurationOutput const& output)
182 {184 {
183 EXPECT_CALL(conf, configure_output(output.id, _, _, _, mir_power_mode_on));185 EXPECT_CALL(conf, configure_output(output.id, _, _, _, _, mir_power_mode_on));
184 });186 });
185187
186 policy.apply_to(conf);188 policy.apply_to(conf);
@@ -200,10 +202,10 @@
200 ++output_count;202 ++output_count;
201 });203 });
202204
203 EXPECT_CALL(conf, configure_output(_, true, _, _, _))205 EXPECT_CALL(conf, configure_output(_, true, _, _, _, _))
204 .Times(AtMost(max_simultaneous_outputs));206 .Times(AtMost(max_simultaneous_outputs));
205207
206 EXPECT_CALL(conf, configure_output(_, false, _, _, _))208 EXPECT_CALL(conf, configure_output(_, false, _, _, _, _))
207 .Times(AtLeast(output_count - max_simultaneous_outputs));209 .Times(AtLeast(output_count - max_simultaneous_outputs));
208210
209 policy.apply_to(conf);211 policy.apply_to(conf);
210212
=== added file 'tests/unit-tests/graphics/test_pixel_format_utils.cpp'
--- tests/unit-tests/graphics/test_pixel_format_utils.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/graphics/test_pixel_format_utils.cpp 2013-12-20 13:46:31 +0000
@@ -0,0 +1,79 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
17 */
18
19#include "mir_toolkit/common.h"
20#include "mir/graphics/pixel_format_utils.h"
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
23
24namespace mg = mir::graphics;
25TEST(MirPixelformat,contains_alpha)
26{
27 EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_xbgr_8888));
28 EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_bgr_888));
29 EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_xrgb_8888));
30 EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_xbgr_8888));
31 EXPECT_TRUE(mg::contains_alpha(mir_pixel_format_argb_8888));
32 EXPECT_TRUE(mg::contains_alpha(mir_pixel_format_abgr_8888));
33 EXPECT_FALSE(mg::contains_alpha(mir_pixel_format_invalid));
34}
35
36TEST(MirPixelformat,red_channel_depths)
37{
38 EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_xbgr_8888));
39 EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_bgr_888));
40 EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_xrgb_8888));
41 EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_xbgr_8888));
42 EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_argb_8888));
43 EXPECT_EQ(8, mg::red_channel_depth(mir_pixel_format_abgr_8888));
44 EXPECT_EQ(0, mg::red_channel_depth(mir_pixel_format_invalid));
45}
46
47TEST(MirPixelformat,blue_channel_depths)
48{
49 EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_xbgr_8888));
50 EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_bgr_888));
51 EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_xrgb_8888));
52 EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_xbgr_8888));
53 EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_argb_8888));
54 EXPECT_EQ(8, mg::blue_channel_depth(mir_pixel_format_abgr_8888));
55 EXPECT_EQ(0, mg::red_channel_depth(mir_pixel_format_invalid));
56}
57
58TEST(MirPixelformat,green_channel_depths)
59{
60 EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_xbgr_8888));
61 EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_bgr_888));
62 EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_xrgb_8888));
63 EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_xbgr_8888));
64 EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_argb_8888));
65 EXPECT_EQ(8, mg::green_channel_depth(mir_pixel_format_abgr_8888));
66 EXPECT_EQ(0, mg::red_channel_depth(mir_pixel_format_invalid));
67}
68
69
70TEST(MirPixelformat,alpha_channel_depths)
71{
72 EXPECT_EQ(0, mg::alpha_channel_depth(mir_pixel_format_xbgr_8888));
73 EXPECT_EQ(0, mg::alpha_channel_depth(mir_pixel_format_bgr_888));
74 EXPECT_EQ(0, mg::alpha_channel_depth(mir_pixel_format_xrgb_8888));
75 EXPECT_EQ(0, mg::alpha_channel_depth(mir_pixel_format_xbgr_8888));
76 EXPECT_EQ(8, mg::alpha_channel_depth(mir_pixel_format_argb_8888));
77 EXPECT_EQ(8, mg::alpha_channel_depth(mir_pixel_format_abgr_8888));
78 EXPECT_EQ(0, mg::red_channel_depth(mir_pixel_format_invalid));
79}

Subscribers

People subscribed via source and target branches