Mir

Merge lp:~afrantzis/mir/vt-switching-1 into lp:~mir-team/mir/trunk

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Alexandros Frantzis
Approved revision: no longer in the source branch.
Merged at revision: 585
Proposed branch: lp:~afrantzis/mir/vt-switching-1
Merge into: lp:~mir-team/mir/trunk
Diff against target: 1824 lines (+935/-65)
33 files modified
include/server/mir/graphics/display.h (+11/-0)
include/test/mir_test_doubles/mock_display.h (+5/-0)
include/test/mir_test_doubles/null_display.h (+7/-0)
include/test/mir_test_doubles/null_virtual_terminal.h (+47/-0)
src/server/display_server.cpp (+12/-0)
src/server/graphics/android/android_display.cpp (+15/-0)
src/server/graphics/android/android_display.h (+8/-0)
src/server/graphics/gbm/CMakeLists.txt (+1/-0)
src/server/graphics/gbm/gbm_display.cpp (+31/-3)
src/server/graphics/gbm/gbm_display.h (+12/-2)
src/server/graphics/gbm/gbm_display_buffer.cpp (+17/-2)
src/server/graphics/gbm/gbm_display_buffer.h (+4/-0)
src/server/graphics/gbm/gbm_display_helpers.cpp (+40/-0)
src/server/graphics/gbm/gbm_display_helpers.h (+3/-0)
src/server/graphics/gbm/gbm_platform.cpp (+9/-4)
src/server/graphics/gbm/gbm_platform.h (+7/-2)
src/server/graphics/gbm/linux_virtual_terminal.cpp (+180/-0)
src/server/graphics/gbm/linux_virtual_terminal.h (+67/-0)
src/server/graphics/gbm/virtual_terminal.h (+55/-0)
tests/behavior-tests/session_management_context.cpp (+9/-0)
tests/integration-tests/test_display_server_main_loop_events.cpp (+178/-0)
tests/integration-tests/test_surfaceloop.cpp (+7/-0)
tests/mir_test_framework/testing_server_options.cpp (+7/-0)
tests/unit-tests/compositor/test_multi_threaded_compositor.cpp (+7/-0)
tests/unit-tests/graphics/gbm/mock_drm.cpp (+10/-0)
tests/unit-tests/graphics/gbm/mock_drm.h (+3/-0)
tests/unit-tests/graphics/gbm/test_gbm_buffer.cpp (+4/-1)
tests/unit-tests/graphics/gbm/test_gbm_buffer_allocator.cpp (+3/-1)
tests/unit-tests/graphics/gbm/test_gbm_display.cpp (+117/-31)
tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp (+13/-6)
tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp (+12/-5)
tests/unit-tests/graphics/gbm/test_gbm_platform.cpp (+18/-5)
tests/unit-tests/graphics/test_graphics_platform.cpp (+16/-3)
To merge this branch: bzr merge lp:~afrantzis/mir/vt-switching-1
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Abstain
Robert Carr (community) Approve
Kevin DuBois (community) Approve
Robert Ancell Pending
Review via email: mp+158327@code.launchpad.net

This proposal supersedes a proposal from 2013-04-10.

Commit message

server,gbm: Support VT switching

Since VT switching is a desktop specific concept at the moment, this branch
introduces it in more generic terms, as pause/resume in the high level
interfaces. Note that the mechanisms that implement pausing/resuming are
not tied to VT switching in particular. We can reuse them to pause/resume
arbitrarily.

In order for VT switching (pause/resume) to work properly, mir needs to be
run with root privileges, since this is required for drm{Drop,Set}Master().
However, if no VT switch (pause/resume) is performed, mir can be happily
run without root priveleges (as before, assuming appropriate device
permissions).

Description of the change

server,gbm: Support VT switching

Since VT switching is a desktop specific concept, this branch introduces it in more generic terms, as pause/resume in the high level interfaces. Note that the mechanisms that implement pausing/resuming are not tied to VT switching in particular. We can reuse them to pause/resume arbitrarily.

In order for VT switching (pause/resume) to work properly, mir needs to be run with root privileges, since this is required for drm{Drop,Set}Master(). However, if no VT switch (pause/resume) is performed, mir can be happily run without root priveleges (as before, assuming appropriate device permissions).

There is a bit of code churn in this branch because of the interface changes in mg::Display and mg::Platform, that caused a barrage of amendments to related stub and mock classes.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

Around + display->pause();

Do we need to pause input?

review: Needs Information
Revision history for this message
Alexandros Frantzis (afrantzis) wrote : Posted in a previous version of this proposal

> Around + display->pause();
>
> Do we need to pause input?

Good question, we probably do, but I am not familiar with input details and how moving to another VT affects input. I guess from the perspective of pause/resume, it makes sense to stop processing/sending input events anyway when paused.

In any case, I'd rather leave it out of this MP (and let you implement it in an upcoming MP as needed ;))

Revision history for this message
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal

The concepts of pause/resume (although not coded to do anything in android) are useful for what we'll want to do when the display is turned off on android, so I like the general idea

I kept thinking the pause/resume for the platform and the display could be consilidated, however I think its ok as it is

Revision history for this message
Alexandros Frantzis (afrantzis) wrote : Posted in a previous version of this proposal

> I kept thinking the pause/resume for the platform and the display could be
> consilidated, however I think its ok as it is

This is doable, although less explicit, but on second thought I prefer it this way too.
We can also move register_pause_resume_handlers() to mg::Display too, thus leaving the mg::Platform interface unchanged.

Revision history for this message
Robert Ancell (robert-ancell) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Text conflict in include/server/mir/graphics/platform.h
Text conflict in src/server/graphics/android/android_platform.h
Text conflict in src/server/graphics/gbm/gbm_platform.cpp
Text conflict in src/server/graphics/gbm/gbm_platform.h
Text conflict in tests/integration-tests/graphics/gbm/test_buffer_integration.cpp
Text conflict in tests/integration-tests/test_display_info.cpp
Text conflict in tests/integration-tests/test_drm_auth_magic.cpp
Text conflict in tests/integration-tests/test_surfaceloop.cpp
Text conflict in tests/mir_test_framework/testing_server_options.cpp
Text conflict in tests/unit-tests/frontend/test_session_mediator.cpp
Text conflict in tests/unit-tests/frontend/test_session_mediator_android.cpp
Text conflict in tests/unit-tests/frontend/test_session_mediator_gbm.cpp
Text conflict in tests/unit-tests/graphics/gbm/mock_drm.cpp
Text conflict in tests/unit-tests/graphics/gbm/mock_drm.h
14 conflicts encountered.

review: Needs Fixing
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> I kept thinking the pause/resume for the platform and the display could be consilidated

Fixed.

> Text conflict in include/server/mir/graphics/platform.h
...

Fixed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

okay, with the consolidated pause/resume, this looks good to me

review: Approve
Revision history for this message
Robert Carr (robertcarr) wrote :

I like the changes to consolidate pause/resume on display...was going to ask about this :)

I think it lgtm to me as it stands!

I wonder if LinuxVirtualTerminal should use some interface for the ioctls so it can be unit tested for interaction.

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

I can't test this any more. Blocked by bug 1167828 for now.

review: Abstain
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> I like the changes to consolidate pause/resume on display...was going to ask
> about this :)
>
> I think it lgtm to me as it stands!
>
> I wonder if LinuxVirtualTerminal should use some interface for the ioctls so
> it can be unit tested for interaction.

Yes, ideally it should. I considered adding an, e.g., FileOperations dependency on LinuxVirtualTerminal, but decided against it for this MP to keep it small. In retrospect, I should have proposed this differently: use a DummyVirtualTerminal for this MP, and add the real VT implementation in a different one. Anyway, I will fix this in an upcoming MP.

Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/server/mir/graphics/display.h'
--- include/server/mir/graphics/display.h 2013-03-13 04:54:15 +0000
+++ include/server/mir/graphics/display.h 2013-04-11 11:00:30 +0000
@@ -26,6 +26,9 @@
2626
27namespace mir27namespace mir
28{28{
29
30class MainLoop;
31
29namespace graphics32namespace graphics
30{33{
3134
@@ -40,6 +43,14 @@
4043
41 virtual std::shared_ptr<DisplayConfiguration> configuration() = 0;44 virtual std::shared_ptr<DisplayConfiguration> configuration() = 0;
4245
46 virtual void register_pause_resume_handlers(
47 MainLoop& main_loop,
48 std::function<void()> const& pause_handler,
49 std::function<void()> const& resume_handler) = 0;
50
51 virtual void pause() = 0;
52 virtual void resume() = 0;
53
43protected:54protected:
44 Display() = default;55 Display() = default;
45 ~Display() = default;56 ~Display() = default;
4657
=== modified file 'include/test/mir_test_doubles/mock_display.h'
--- include/test/mir_test_doubles/mock_display.h 2013-03-13 04:54:15 +0000
+++ include/test/mir_test_doubles/mock_display.h 2013-04-11 11:00:30 +0000
@@ -35,6 +35,11 @@
35 MOCK_CONST_METHOD0(view_area, geometry::Rectangle ());35 MOCK_CONST_METHOD0(view_area, geometry::Rectangle ());
36 MOCK_METHOD1(for_each_display_buffer, void (std::function<void(graphics::DisplayBuffer&)> const&));36 MOCK_METHOD1(for_each_display_buffer, void (std::function<void(graphics::DisplayBuffer&)> const&));
37 MOCK_METHOD0(configuration, std::shared_ptr<graphics::DisplayConfiguration>());37 MOCK_METHOD0(configuration, std::shared_ptr<graphics::DisplayConfiguration>());
38 MOCK_METHOD3(register_pause_resume_handlers, void(MainLoop&,
39 std::function<void()> const&,
40 std::function<void()> const&));
41 MOCK_METHOD0(pause, void());
42 MOCK_METHOD0(resume, void());
38};43};
3944
40}45}
4146
=== modified file 'include/test/mir_test_doubles/null_display.h'
--- include/test/mir_test_doubles/null_display.h 2013-03-13 04:54:15 +0000
+++ include/test/mir_test_doubles/null_display.h 2013-04-11 11:00:30 +0000
@@ -42,6 +42,13 @@
42 {42 {
43 return std::shared_ptr<graphics::DisplayConfiguration>();43 return std::shared_ptr<graphics::DisplayConfiguration>();
44 }44 }
45 void register_pause_resume_handlers(MainLoop&,
46 std::function<void()> const&,
47 std::function<void()> const&)
48 {
49 }
50 void pause() {}
51 void resume() {}
45};52};
4653
47}54}
4855
=== added file 'include/test/mir_test_doubles/null_virtual_terminal.h'
--- include/test/mir_test_doubles/null_virtual_terminal.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/null_virtual_terminal.h 2013-04-11 11:00:30 +0000
@@ -0,0 +1,47 @@
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 Lesser 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 Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#ifndef MIR_TEST_DOUBLES_NULL_VIRTUAL_TERMINAL_H_
20#define MIR_TEST_DOUBLES_NULL_VIRTUAL_TERMINAL_H_
21
22#include "src/server/graphics/gbm/virtual_terminal.h"
23
24namespace mir
25{
26namespace test
27{
28namespace doubles
29{
30
31class NullVirtualTerminal : public graphics::gbm::VirtualTerminal
32{
33public:
34 void set_graphics_mode() {}
35
36 void register_switch_handlers(MainLoop&,
37 std::function<void()> const&,
38 std::function<void()> const&)
39 {
40 }
41};
42
43}
44}
45}
46
47#endif /* MIR_TEST_DOUBLES_NULL_VIRTUAL_TERMINAL_H_ */
048
=== modified file 'src/server/display_server.cpp'
--- src/server/display_server.cpp 2013-04-10 16:23:54 +0000
+++ src/server/display_server.cpp 2013-04-11 11:00:30 +0000
@@ -44,6 +44,18 @@
44 input_manager{config.the_input_manager()},44 input_manager{config.the_input_manager()},
45 main_loop{config.the_main_loop()}45 main_loop{config.the_main_loop()}
46 {46 {
47 display->register_pause_resume_handlers(
48 *main_loop,
49 [this]
50 {
51 compositor->stop();
52 display->pause();
53 },
54 [this]
55 {
56 display->resume();
57 compositor->start();
58 });
47 }59 }
4860
49 std::shared_ptr<mg::Display> display;61 std::shared_ptr<mg::Display> display;
5062
=== modified file 'src/server/graphics/android/android_display.cpp'
--- src/server/graphics/android/android_display.cpp 2013-03-21 03:32:59 +0000
+++ src/server/graphics/android/android_display.cpp 2013-04-11 11:00:30 +0000
@@ -142,6 +142,21 @@
142 return std::make_shared<NullDisplayConfiguration>();142 return std::make_shared<NullDisplayConfiguration>();
143}143}
144144
145void mga::AndroidDisplay::register_pause_resume_handlers(
146 MainLoop& /*main_loop*/,
147 std::function<void()> const& /*pause_handler*/,
148 std::function<void()> const& /*resume_handler*/)
149{
150}
151
152void mga::AndroidDisplay::pause()
153{
154}
155
156void mga::AndroidDisplay::resume()
157{
158}
159
145void mga::AndroidDisplay::make_current()160void mga::AndroidDisplay::make_current()
146{161{
147 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)162 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
148163
=== modified file 'src/server/graphics/android/android_display.h'
--- src/server/graphics/android/android_display.h 2013-03-22 18:33:51 +0000
+++ src/server/graphics/android/android_display.h 2013-04-11 11:00:30 +0000
@@ -50,6 +50,14 @@
5050
51 std::shared_ptr<DisplayConfiguration> configuration();51 std::shared_ptr<DisplayConfiguration> configuration();
5252
53 void register_pause_resume_handlers(
54 MainLoop& main_loop,
55 std::function<void()> const& pause_handler,
56 std::function<void()> const& resume_handler);
57
58 void pause();
59 void resume();
60
53 void make_current();61 void make_current();
54private:62private:
55 std::shared_ptr<AndroidFramebufferWindowQuery> native_window;63 std::shared_ptr<AndroidFramebufferWindowQuery> native_window;
5664
=== modified file 'src/server/graphics/gbm/CMakeLists.txt'
--- src/server/graphics/gbm/CMakeLists.txt 2013-03-13 04:54:15 +0000
+++ src/server/graphics/gbm/CMakeLists.txt 2013-04-11 11:00:30 +0000
@@ -24,6 +24,7 @@
24 kms_output.cpp24 kms_output.cpp
25 kms_output_container.cpp25 kms_output_container.cpp
26 kms_page_flipper.cpp26 kms_page_flipper.cpp
27 linux_virtual_terminal.cpp
27)28)
2829
29target_link_libraries(30target_link_libraries(
3031
=== modified file 'src/server/graphics/gbm/gbm_display.cpp'
--- src/server/graphics/gbm/gbm_display.cpp 2013-03-13 04:54:15 +0000
+++ src/server/graphics/gbm/gbm_display.cpp 2013-04-11 11:00:30 +0000
@@ -22,6 +22,7 @@
22#include "kms_display_configuration.h"22#include "kms_display_configuration.h"
23#include "kms_output.h"23#include "kms_output.h"
24#include "kms_page_flipper.h"24#include "kms_page_flipper.h"
25#include "virtual_terminal.h"
2526
26#include "mir/geometry/rectangle.h"27#include "mir/geometry/rectangle.h"
2728
@@ -36,6 +37,8 @@
36 output_container{platform->drm.fd,37 output_container{platform->drm.fd,
37 std::make_shared<KMSPageFlipper>(platform->drm.fd)}38 std::make_shared<KMSPageFlipper>(platform->drm.fd)}
38{39{
40 platform->vt->set_graphics_mode();
41
39 shared_egl.setup(platform->gbm);42 shared_egl.setup(platform->gbm);
4043
41 configure(configuration());44 configure(configuration());
@@ -43,6 +46,10 @@
43 shared_egl.make_current();46 shared_egl.make_current();
44}47}
4548
49mgg::GBMDisplay::~GBMDisplay()
50{
51}
52
46geom::Rectangle mgg::GBMDisplay::view_area() const53geom::Rectangle mgg::GBMDisplay::view_area() const
47{54{
48 return display_buffers[0]->view_area();55 return display_buffers[0]->view_area();
@@ -92,8 +99,29 @@
92 max_size.height.as_uint32_t());99 max_size.height.as_uint32_t());
93100
94 /* Create a single DisplayBuffer that displays the surface on all the outputs */101 /* Create a single DisplayBuffer that displays the surface on all the outputs */
95 std::unique_ptr<DisplayBuffer> db{new GBMDisplayBuffer{platform, listener, enabled_outputs,102 std::unique_ptr<GBMDisplayBuffer> db{new GBMDisplayBuffer{platform, listener, enabled_outputs,
96 std::move(surface), max_size,103 std::move(surface), max_size,
97 shared_egl.context()}};104 shared_egl.context()}};
98 display_buffers.push_back(std::move(db));105 display_buffers.push_back(std::move(db));
99}106}
107
108void mgg::GBMDisplay::register_pause_resume_handlers(
109 MainLoop& main_loop,
110 std::function<void()> const& pause_handler,
111 std::function<void()> const& resume_handler)
112{
113 platform->vt->register_switch_handlers(main_loop, pause_handler, resume_handler);
114}
115
116void mgg::GBMDisplay::pause()
117{
118 platform->drm.drop_master();
119}
120
121void mgg::GBMDisplay::resume()
122{
123 platform->drm.set_master();
124
125 for (auto& db_ptr : display_buffers)
126 db_ptr->schedule_set_crtc();
127}
100128
=== modified file 'src/server/graphics/gbm/gbm_display.h'
--- src/server/graphics/gbm/gbm_display.h 2013-03-21 03:32:59 +0000
+++ src/server/graphics/gbm/gbm_display.h 2013-04-11 11:00:30 +0000
@@ -20,7 +20,6 @@
20#define MIR_GRAPHICS_GBM_GBM_DISPLAY_H_20#define MIR_GRAPHICS_GBM_GBM_DISPLAY_H_
2121
22#include "mir/graphics/display.h"22#include "mir/graphics/display.h"
23#include "mir/graphics/display_buffer.h"
24#include "kms_output_container.h"23#include "kms_output_container.h"
25#include "gbm_display_helpers.h"24#include "gbm_display_helpers.h"
2625
@@ -36,31 +35,42 @@
36{35{
3736
38class DisplayReport;37class DisplayReport;
38class DisplayBuffer;
3939
40namespace gbm40namespace gbm
41{41{
4242
43class GBMPlatform;43class GBMPlatform;
44class KMSOutput;44class KMSOutput;
45class GBMDisplayBuffer;
4546
46class GBMDisplay : public Display47class GBMDisplay : public Display
47{48{
48public:49public:
49 GBMDisplay(std::shared_ptr<GBMPlatform> const& platform,50 GBMDisplay(std::shared_ptr<GBMPlatform> const& platform,
50 std::shared_ptr<DisplayReport> const& listener);51 std::shared_ptr<DisplayReport> const& listener);
52 ~GBMDisplay();
5153
52 geometry::Rectangle view_area() const;54 geometry::Rectangle view_area() const;
53 void for_each_display_buffer(std::function<void(DisplayBuffer&)> const& f);55 void for_each_display_buffer(std::function<void(DisplayBuffer&)> const& f);
5456
55 std::shared_ptr<DisplayConfiguration> configuration();57 std::shared_ptr<DisplayConfiguration> configuration();
5658
59 void register_pause_resume_handlers(
60 MainLoop& main_loop,
61 std::function<void()> const& pause_handler,
62 std::function<void()> const& resume_handler);
63
64 void pause();
65 void resume();
66
57private:67private:
58 void configure(std::shared_ptr<DisplayConfiguration> const& conf);68 void configure(std::shared_ptr<DisplayConfiguration> const& conf);
5969
60 std::shared_ptr<GBMPlatform> const platform;70 std::shared_ptr<GBMPlatform> const platform;
61 std::shared_ptr<DisplayReport> const listener;71 std::shared_ptr<DisplayReport> const listener;
62 helpers::EGLHelper shared_egl;72 helpers::EGLHelper shared_egl;
63 std::vector<std::unique_ptr<DisplayBuffer>> display_buffers;73 std::vector<std::unique_ptr<GBMDisplayBuffer>> display_buffers;
64 KMSOutputContainer output_container;74 KMSOutputContainer output_container;
65};75};
6676
6777
=== modified file 'src/server/graphics/gbm/gbm_display_buffer.cpp'
--- src/server/graphics/gbm/gbm_display_buffer.cpp 2013-03-21 03:32:59 +0000
+++ src/server/graphics/gbm/gbm_display_buffer.cpp 2013-04-11 11:00:30 +0000
@@ -105,7 +105,8 @@
105 drm(platform->drm),105 drm(platform->drm),
106 outputs(outputs),106 outputs(outputs),
107 surface_gbm{std::move(surface_gbm_param)},107 surface_gbm{std::move(surface_gbm_param)},
108 size(size)108 size(size),
109 needs_set_crtc{false}
109{110{
110 egl.setup(platform->gbm, surface_gbm.get(), shared_context);111 egl.setup(platform->gbm, surface_gbm.get(), shared_context);
111112
@@ -180,11 +181,20 @@
180 * If the flip fails, release the buffer object to make it available181 * If the flip fails, release the buffer object to make it available
181 * for future rendering.182 * for future rendering.
182 */183 */
183 if (!schedule_and_wait_for_page_flip(bufobj))184 if (!needs_set_crtc && !schedule_and_wait_for_page_flip(bufobj))
184 {185 {
185 bufobj->release();186 bufobj->release();
186 return false;187 return false;
187 }188 }
189 else if (needs_set_crtc)
190 {
191 for (auto& output : outputs)
192 {
193 if (!output->set_crtc(bufobj->get_drm_fb_id()))
194 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to set DRM crtc"));
195 }
196 needs_set_crtc = false;
197 }
188198
189 /*199 /*
190 * Release the last flipped buffer object (which is not displayed anymore)200 * Release the last flipped buffer object (which is not displayed anymore)
@@ -265,3 +275,8 @@
265 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to make EGL surface current"));275 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to make EGL surface current"));
266 }276 }
267}277}
278
279void mgg::GBMDisplayBuffer::schedule_set_crtc()
280{
281 needs_set_crtc = true;
282}
268283
=== modified file 'src/server/graphics/gbm/gbm_display_buffer.h'
--- src/server/graphics/gbm/gbm_display_buffer.h 2013-03-13 04:54:15 +0000
+++ src/server/graphics/gbm/gbm_display_buffer.h 2013-04-11 11:00:30 +0000
@@ -24,6 +24,7 @@
2424
25#include <vector>25#include <vector>
26#include <memory>26#include <memory>
27#include <atomic>
2728
28namespace mir29namespace mir
29{30{
@@ -55,6 +56,8 @@
55 void clear();56 void clear();
56 bool post_update();57 bool post_update();
5758
59 void schedule_set_crtc();
60
58private:61private:
59 BufferObject* get_front_buffer_object();62 BufferObject* get_front_buffer_object();
60 bool schedule_and_wait_for_page_flip(BufferObject* bufobj);63 bool schedule_and_wait_for_page_flip(BufferObject* bufobj);
@@ -68,6 +71,7 @@
68 GBMSurfaceUPtr surface_gbm;71 GBMSurfaceUPtr surface_gbm;
69 helpers::EGLHelper egl;72 helpers::EGLHelper egl;
70 geometry::Size size;73 geometry::Size size;
74 std::atomic<bool> needs_set_crtc;
71};75};
7276
73}77}
7478
=== modified file 'src/server/graphics/gbm/gbm_display_helpers.cpp'
--- src/server/graphics/gbm/gbm_display_helpers.cpp 2013-03-13 04:54:15 +0000
+++ src/server/graphics/gbm/gbm_display_helpers.cpp 2013-04-11 11:00:30 +0000
@@ -96,6 +96,46 @@
96 }96 }
97}97}
9898
99void mggh::DRMHelper::drop_master() const
100{
101 /* We must have our own device fd first, so that it has become the DRM master */
102 if (fd < 0)
103 {
104 BOOST_THROW_EXCEPTION(
105 std::runtime_error("Tried to drop DRM master without a DRM device"));
106 }
107
108 int ret = drmDropMaster(fd);
109
110 if (ret < 0)
111 {
112 BOOST_THROW_EXCEPTION(
113 boost::enable_error_info(
114 std::runtime_error("Failed to drop DRM master"))
115 << boost::errinfo_errno(ret));
116 }
117}
118
119void mggh::DRMHelper::set_master() const
120{
121 /* We must have our own device fd first, so that it has become the DRM master */
122 if (fd < 0)
123 {
124 BOOST_THROW_EXCEPTION(
125 std::runtime_error("Tried to set DRM master without a DRM device"));
126 }
127
128 int ret = drmSetMaster(fd);
129
130 if (ret < 0)
131 {
132 BOOST_THROW_EXCEPTION(
133 boost::enable_error_info(
134 std::runtime_error("Failed to set DRM master"))
135 << boost::errinfo_errno(ret));
136 }
137}
138
99int mggh::DRMHelper::open_drm_device()139int mggh::DRMHelper::open_drm_device()
100{140{
101 static const char *drivers[] = {141 static const char *drivers[] = {
102142
=== modified file 'src/server/graphics/gbm/gbm_display_helpers.h'
--- src/server/graphics/gbm/gbm_display_helpers.h 2013-03-21 03:32:59 +0000
+++ src/server/graphics/gbm/gbm_display_helpers.h 2013-04-11 11:00:30 +0000
@@ -57,6 +57,9 @@
57 int get_authenticated_fd();57 int get_authenticated_fd();
58 void auth_magic(drm_magic_t magic) const;58 void auth_magic(drm_magic_t magic) const;
5959
60 void drop_master() const;
61 void set_master() const;
62
60 int fd;63 int fd;
6164
62private:65private:
6366
=== modified file 'src/server/graphics/gbm/gbm_platform.cpp'
--- src/server/graphics/gbm/gbm_platform.cpp 2013-04-09 18:00:48 +0000
+++ src/server/graphics/gbm/gbm_platform.cpp 2013-04-11 11:00:30 +0000
@@ -21,6 +21,7 @@
21#include <boost/throw_exception.hpp>21#include <boost/throw_exception.hpp>
22#include "gbm_buffer_allocator.h"22#include "gbm_buffer_allocator.h"
23#include "gbm_display.h"23#include "gbm_display.h"
24#include "linux_virtual_terminal.h"
24#include "mir/graphics/platform_ipc_package.h"25#include "mir/graphics/platform_ipc_package.h"
25#include "mir/graphics/egl/mesa_native_display.h"26#include "mir/graphics/egl/mesa_native_display.h"
26#include "mir/logging/logger.h"27#include "mir/logging/logger.h"
@@ -54,9 +55,11 @@
5455
55}56}
5657
57mgg::GBMPlatform::GBMPlatform(std::shared_ptr<DisplayReport> const& listener) :58mgg::GBMPlatform::GBMPlatform(std::shared_ptr<DisplayReport> const& listener,
58 listener(listener),59 std::shared_ptr<VirtualTerminal> const& vt)
59 native_display(0)60 : listener(listener),
61 vt{vt},
62 native_display(0)
60{63{
61 drm.setup();64 drm.setup();
62 gbm.setup(drm);65 gbm.setup(drm);
@@ -97,5 +100,7 @@
97100
98std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<DisplayReport> const& report)101std::shared_ptr<mg::Platform> mg::create_platform(std::shared_ptr<DisplayReport> const& report)
99{102{
100 return std::make_shared<mgg::GBMPlatform>(report);103 return std::make_shared<mgg::GBMPlatform>(
104 report,
105 std::make_shared<mgg::LinuxVirtualTerminal>());
101}106}
102107
=== modified file 'src/server/graphics/gbm/gbm_platform.h'
--- src/server/graphics/gbm/gbm_platform.h 2013-04-09 18:00:48 +0000
+++ src/server/graphics/gbm/gbm_platform.h 2013-04-11 11:00:30 +0000
@@ -32,12 +32,15 @@
32namespace gbm32namespace gbm
33{33{
3434
35class VirtualTerminal;
36
35class GBMPlatform : public Platform,37class GBMPlatform : public Platform,
36 public DRMAuthenticator,38 public DRMAuthenticator,
37 public std::enable_shared_from_this<GBMPlatform>39 public std::enable_shared_from_this<GBMPlatform>
38{40{
39public:41public:
40 explicit GBMPlatform(std::shared_ptr<DisplayReport> const& reporter);42 explicit GBMPlatform(std::shared_ptr<DisplayReport> const& reporter,
43 std::shared_ptr<VirtualTerminal> const& vt);
4144
42 /* From Platform */45 /* From Platform */
43 std::shared_ptr<compositor::GraphicBufferAllocator> create_buffer_allocator(46 std::shared_ptr<compositor::GraphicBufferAllocator> create_buffer_allocator(
@@ -53,7 +56,9 @@
53 helpers::DRMHelper drm;56 helpers::DRMHelper drm;
54 helpers::GBMHelper gbm;57 helpers::GBMHelper gbm;
5558
56 std::shared_ptr<DisplayReport> listener;59 std::shared_ptr<DisplayReport> const listener;
60 std::shared_ptr<VirtualTerminal> const vt;
61
57private:62private:
58 std::shared_ptr<MirMesaEGLNativeDisplay> native_display;63 std::shared_ptr<MirMesaEGLNativeDisplay> native_display;
59};64};
6065
=== added file 'src/server/graphics/gbm/linux_virtual_terminal.cpp'
--- src/server/graphics/gbm/linux_virtual_terminal.cpp 1970-01-01 00:00:00 +0000
+++ src/server/graphics/gbm/linux_virtual_terminal.cpp 2013-04-11 11:00:30 +0000
@@ -0,0 +1,180 @@
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 Lesser 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 Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#include "linux_virtual_terminal.h"
20#include "mir/main_loop.h"
21
22#include <boost/throw_exception.hpp>
23#include <boost/exception/errinfo_errno.hpp>
24#include <boost/exception/errinfo_file_name.hpp>
25
26#include <vector>
27#include <string>
28#include <sstream>
29#include <stdexcept>
30#include <csignal>
31
32#include <fcntl.h>
33#include <linux/vt.h>
34#include <linux/kd.h>
35#include <sys/ioctl.h>
36
37namespace mgg = mir::graphics::gbm;
38
39namespace
40{
41
42int find_active_vt_number()
43{
44 static std::vector<std::string> const paths{"/dev/tty", "/dev/tty0"};
45 int active_vt{-1};
46
47 for (auto& p : paths)
48 {
49 auto fd = open(p.c_str(), O_RDONLY, 0);
50 if (fd < 0)
51 fd = open(p.c_str(), O_WRONLY, 0);
52
53 if (fd >= 0)
54 {
55 struct vt_stat vts;
56 auto status = ioctl(fd, VT_GETSTATE, &vts);
57 close(fd);
58
59 if (status >= 0)
60 {
61 active_vt = vts.v_active;
62 break;
63 }
64 }
65 }
66
67 if (active_vt < 0)
68 {
69 BOOST_THROW_EXCEPTION(
70 std::runtime_error("Failed to find the current VT"));
71 }
72
73 return active_vt;
74}
75
76int open_vt(int vt_number)
77{
78 std::stringstream vt_path_stream;
79 vt_path_stream << "/dev/tty" << vt_number;
80
81 std::string const active_vt_path{vt_path_stream.str()};
82
83 auto vt_fd = open(active_vt_path.c_str(), O_RDONLY | O_NDELAY, 0);
84
85 if (vt_fd < 0)
86 {
87 BOOST_THROW_EXCEPTION(
88 boost::enable_error_info(
89 std::runtime_error("Failed to open current VT"))
90 << boost::errinfo_file_name(active_vt_path)
91 << boost::errinfo_errno(errno));
92 }
93
94 return vt_fd;
95}
96
97}
98
99mgg::LinuxVirtualTerminal::LinuxVirtualTerminal()
100 : vt_fd{open_vt(find_active_vt_number())},
101 prev_kd_mode{0},
102 prev_vt_mode(),
103 active{true}
104{
105 if (ioctl(vt_fd.fd(), KDGETMODE, &prev_kd_mode) < 0)
106 {
107 BOOST_THROW_EXCEPTION(
108 boost::enable_error_info(
109 std::runtime_error("Failed to get current VT mode"))
110 << boost::errinfo_errno(errno));
111 }
112
113 if (ioctl(vt_fd.fd(), VT_GETMODE, &prev_vt_mode) < 0)
114 {
115 BOOST_THROW_EXCEPTION(
116 boost::enable_error_info(
117 std::runtime_error("Failed to get the current VT")) << boost::errinfo_errno(errno));
118 }
119}
120
121mgg::LinuxVirtualTerminal::~LinuxVirtualTerminal() noexcept(true)
122{
123 if (vt_fd.fd() > 0)
124 {
125 ioctl(vt_fd.fd(), KDSETMODE, prev_kd_mode);
126 ioctl(vt_fd.fd(), VT_SETMODE, &prev_vt_mode);
127 }
128}
129
130void mgg::LinuxVirtualTerminal::set_graphics_mode()
131{
132 if (ioctl(vt_fd.fd(), KDSETMODE, KD_GRAPHICS) < 0)
133 {
134 BOOST_THROW_EXCEPTION(
135 boost::enable_error_info(
136 std::runtime_error("Failed to set VT to graphics mode"))
137 << boost::errinfo_errno(errno));
138 }
139}
140
141void mgg::LinuxVirtualTerminal::register_switch_handlers(
142 MainLoop& main_loop,
143 std::function<void()> const& switch_away,
144 std::function<void()> const& switch_back)
145{
146 main_loop.register_signal_handler(
147 {SIGUSR1},
148 [this, switch_away, switch_back](int)
149 {
150 active = !active;
151 if (active)
152 {
153 static int const allow_switch{2};
154 switch_back();
155 ioctl(vt_fd.fd(), VT_RELDISP, allow_switch);
156 }
157 else
158 {
159 switch_away();
160 ioctl(vt_fd.fd(), VT_RELDISP, VT_ACKACQ);
161 }
162 });
163
164 struct vt_mode vtm
165 {
166 VT_PROCESS,
167 0,
168 SIGUSR1,
169 SIGUSR1,
170 0
171 };
172
173 if (ioctl(vt_fd.fd(), VT_SETMODE, &vtm) < 0)
174 {
175 BOOST_THROW_EXCEPTION(
176 boost::enable_error_info(
177 std::runtime_error("Failed to set the current VT mode"))
178 << boost::errinfo_errno(errno));
179 }
180}
0181
=== added file 'src/server/graphics/gbm/linux_virtual_terminal.h'
--- src/server/graphics/gbm/linux_virtual_terminal.h 1970-01-01 00:00:00 +0000
+++ src/server/graphics/gbm/linux_virtual_terminal.h 2013-04-11 11:00:30 +0000
@@ -0,0 +1,67 @@
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 Lesser 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 Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#ifndef MIR_GRAPHICS_GBM_LINUX_VIRTUAL_TERMINAL_H_
20#define MIR_GRAPHICS_GBM_LINUX_VIRTUAL_TERMINAL_H_
21
22#include "virtual_terminal.h"
23
24#include <linux/vt.h>
25#include <unistd.h>
26
27namespace mir
28{
29namespace graphics
30{
31namespace gbm
32{
33
34class LinuxVirtualTerminal : public VirtualTerminal
35{
36public:
37 LinuxVirtualTerminal();
38 ~LinuxVirtualTerminal() noexcept(true);
39
40 void set_graphics_mode();
41 void register_switch_handlers(
42 MainLoop& main_loop,
43 std::function<void()> const& switch_away,
44 std::function<void()> const& switch_back);
45
46private:
47 class FDWrapper
48 {
49 public:
50 FDWrapper(int fd) : fd_{fd} {}
51 ~FDWrapper() { if (fd_ >= 0) close(fd_); }
52 int fd() const { return fd_; }
53 private:
54 int const fd_;
55 };
56
57 FDWrapper const vt_fd;
58 int prev_kd_mode;
59 struct vt_mode prev_vt_mode;
60 bool active;
61};
62
63}
64}
65}
66
67#endif /* MIR_GRAPHICS_GBM_LINUX_VIRTUAL_TERMINAL_H_ */
068
=== added file 'src/server/graphics/gbm/virtual_terminal.h'
--- src/server/graphics/gbm/virtual_terminal.h 1970-01-01 00:00:00 +0000
+++ src/server/graphics/gbm/virtual_terminal.h 2013-04-11 11:00:30 +0000
@@ -0,0 +1,55 @@
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 Lesser 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 Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#ifndef MIR_GRAPHICS_GBM_VIRTUAL_TERMINAL_H_
20#define MIR_GRAPHICS_GBM_VIRTUAL_TERMINAL_H_
21
22#include <functional>
23
24namespace mir
25{
26
27class MainLoop;
28
29namespace graphics
30{
31namespace gbm
32{
33
34class VirtualTerminal
35{
36public:
37 virtual ~VirtualTerminal() = default;
38
39 virtual void set_graphics_mode() = 0;
40 virtual void register_switch_handlers(
41 MainLoop& main_loop,
42 std::function<void()> const& switch_away,
43 std::function<void()> const& switch_back) = 0;
44
45protected:
46 VirtualTerminal() = default;
47 VirtualTerminal(VirtualTerminal const&) = delete;
48 VirtualTerminal& operator=(VirtualTerminal const&) = delete;
49};
50
51}
52}
53}
54
55#endif /* MIR_GRAPHICS_GBM_VIRTUAL_TERMINAL_H_ */
056
=== modified file 'tests/behavior-tests/session_management_context.cpp'
--- tests/behavior-tests/session_management_context.cpp 2013-04-01 16:11:03 +0000
+++ tests/behavior-tests/session_management_context.cpp 2013-04-11 11:00:30 +0000
@@ -105,6 +105,15 @@
105 return std::shared_ptr<mg::DisplayConfiguration>();105 return std::shared_ptr<mg::DisplayConfiguration>();
106 }106 }
107107
108 void register_pause_resume_handlers(MainLoop&,
109 std::function<void()> const&,
110 std::function<void()> const&)
111 {
112 }
113
114 void pause() {}
115 void resume() {}
116
108 geom::Rectangle area;117 geom::Rectangle area;
109};118};
110119
111120
=== modified file 'tests/integration-tests/test_display_server_main_loop_events.cpp'
--- tests/integration-tests/test_display_server_main_loop_events.cpp 2013-04-08 16:20:33 +0000
+++ tests/integration-tests/test_display_server_main_loop_events.cpp 2013-04-11 11:00:30 +0000
@@ -17,6 +17,8 @@
17 */17 */
1818
19#include "mir/compositor/compositor.h"19#include "mir/compositor/compositor.h"
20#include "mir/graphics/display.h"
21#include "mir/main_loop.h"
2022
21#include "mir_test_framework/testing_server_configuration.h"23#include "mir_test_framework/testing_server_configuration.h"
22#include "mir_test_doubles/mock_input_manager.h"24#include "mir_test_doubles/mock_input_manager.h"
@@ -30,6 +32,7 @@
3032
31namespace mi = mir::input;33namespace mi = mir::input;
32namespace mc = mir::compositor;34namespace mc = mir::compositor;
35namespace mg = mir::graphics;
33namespace mtd = mir::test::doubles;36namespace mtd = mir::test::doubles;
34namespace mtf = mir_test_framework;37namespace mtf = mir_test_framework;
3538
@@ -43,6 +46,54 @@
43 MOCK_METHOD0(stop, void());46 MOCK_METHOD0(stop, void());
44};47};
4548
49class MockDisplay : public mg::Display
50{
51public:
52 MockDisplay(std::shared_ptr<mg::Display> const& display,
53 int pause_signal, int resume_signal)
54 : display{display},
55 pause_signal{pause_signal},
56 resume_signal{resume_signal}
57 {
58 }
59
60 mir::geometry::Rectangle view_area() const
61 {
62 return display->view_area();
63 }
64
65 void for_each_display_buffer(std::function<void(mg::DisplayBuffer&)> const& f)
66 {
67 display->for_each_display_buffer(f);
68 }
69
70 std::shared_ptr<mg::DisplayConfiguration> configuration()
71 {
72 return display->configuration();
73 }
74
75 void register_pause_resume_handlers(
76 mir::MainLoop& main_loop,
77 std::function<void()> const& pause_handler,
78 std::function<void()> const& resume_handler)
79 {
80 main_loop.register_signal_handler(
81 {pause_signal},
82 [pause_handler](int) { pause_handler(); });
83 main_loop.register_signal_handler(
84 {resume_signal},
85 [resume_handler](int) { resume_handler(); });
86 }
87
88 MOCK_METHOD0(pause, void());
89 MOCK_METHOD0(resume, void());
90
91private:
92 std::shared_ptr<mg::Display> const display;
93 int const pause_signal;
94 int const resume_signal;
95};
96
46class ServerConfig : public mtf::TestingServerConfiguration97class ServerConfig : public mtf::TestingServerConfiguration
47{98{
48public:99public:
@@ -77,6 +128,66 @@
77 std::shared_ptr<MockCompositor> mock_compositor;128 std::shared_ptr<MockCompositor> mock_compositor;
78};129};
79130
131
132class PauseResumeServerConfig : public mtf::TestingServerConfiguration
133{
134public:
135 PauseResumeServerConfig()
136 : pause_signal{SIGUSR1}, resume_signal{SIGUSR2}
137 {
138 }
139
140 std::shared_ptr<mg::Display> the_display() override
141 {
142 if (!mock_display)
143 {
144 auto display = mtf::TestingServerConfiguration::the_display();
145 mock_display = std::make_shared<MockDisplay>(display,
146 pause_signal,
147 resume_signal);
148 }
149
150 return mock_display;
151 }
152
153 std::shared_ptr<mc::Compositor> the_compositor() override
154 {
155 if (!mock_compositor)
156 mock_compositor = std::make_shared<MockCompositor>();
157
158 return mock_compositor;
159 }
160
161 std::shared_ptr<MockDisplay> the_mock_display()
162 {
163 the_display();
164 return mock_display;
165 }
166
167 std::shared_ptr<MockCompositor> the_mock_compositor()
168 {
169 the_compositor();
170 return mock_compositor;
171 }
172
173 void emit_pause_event()
174 {
175 kill(getpid(), pause_signal);
176 }
177
178 void emit_resume_event()
179 {
180 kill(getpid(), resume_signal);
181 }
182
183private:
184 std::shared_ptr<MockCompositor> mock_compositor;
185 std::shared_ptr<MockDisplay> mock_display;
186
187 int const pause_signal;
188 int const resume_signal;
189};
190
80}191}
81192
82TEST(DisplayServerMainLoopEvents, display_server_shuts_down_properly_on_sigint)193TEST(DisplayServerMainLoopEvents, display_server_shuts_down_properly_on_sigint)
@@ -100,3 +211,70 @@
100 kill(getpid(), SIGTERM);211 kill(getpid(), SIGTERM);
101 });212 });
102}213}
214
215TEST(DisplayServerMainLoopEvents, display_server_components_pause_and_resume)
216{
217 using namespace testing;
218
219 PauseResumeServerConfig server_config;
220
221 auto mock_compositor = server_config.the_mock_compositor();
222 auto mock_display = server_config.the_mock_display();
223
224 {
225 InSequence s;
226
227 /* Start */
228 EXPECT_CALL(*mock_compositor, start()).Times(1);
229
230 /* Pause */
231 EXPECT_CALL(*mock_compositor, stop()).Times(1);
232 EXPECT_CALL(*mock_display, pause()).Times(1);
233
234 /* Resume */
235 EXPECT_CALL(*mock_display, resume()).Times(1);
236 EXPECT_CALL(*mock_compositor, start()).Times(1);
237
238 /* Stop */
239 EXPECT_CALL(*mock_compositor, stop()).Times(1);
240 }
241
242 mir::run_mir(server_config,
243 [&server_config](mir::DisplayServer&)
244 {
245 server_config.emit_pause_event();
246 server_config.emit_resume_event();
247 kill(getpid(), SIGTERM);
248 });
249}
250
251TEST(DisplayServerMainLoopEvents, display_server_quits_when_paused)
252{
253 using namespace testing;
254
255 PauseResumeServerConfig server_config;
256
257 auto mock_compositor = server_config.the_mock_compositor();
258 auto mock_display = server_config.the_mock_display();
259
260 {
261 InSequence s;
262
263 /* Start */
264 EXPECT_CALL(*mock_compositor, start()).Times(1);
265
266 /* Pause */
267 EXPECT_CALL(*mock_compositor, stop()).Times(1);
268 EXPECT_CALL(*mock_display, pause()).Times(1);
269
270 /* Stop */
271 EXPECT_CALL(*mock_compositor, stop()).Times(1);
272 }
273
274 mir::run_mir(server_config,
275 [&server_config](mir::DisplayServer&)
276 {
277 server_config.emit_pause_event();
278 kill(getpid(), SIGTERM);
279 });
280}
103281
=== modified file 'tests/integration-tests/test_surfaceloop.cpp'
--- tests/integration-tests/test_surfaceloop.cpp 2013-04-10 16:40:04 +0000
+++ tests/integration-tests/test_surfaceloop.cpp 2013-04-11 11:00:30 +0000
@@ -133,6 +133,13 @@
133 auto null_configuration = std::shared_ptr<mg::DisplayConfiguration>();133 auto null_configuration = std::shared_ptr<mg::DisplayConfiguration>();
134 return null_configuration;134 return null_configuration;
135 }135 }
136 void register_pause_resume_handlers(mir::MainLoop&,
137 std::function<void()> const&,
138 std::function<void()> const&)
139 {
140 }
141 void pause() {}
142 void resume() {}
136};143};
137144
138struct SurfaceSync145struct SurfaceSync
139146
=== modified file 'tests/mir_test_framework/testing_server_options.cpp'
--- tests/mir_test_framework/testing_server_options.cpp 2013-04-09 18:00:48 +0000
+++ tests/mir_test_framework/testing_server_options.cpp 2013-04-11 11:00:30 +0000
@@ -86,6 +86,13 @@
86 auto null_configuration = std::shared_ptr<mg::DisplayConfiguration>();86 auto null_configuration = std::shared_ptr<mg::DisplayConfiguration>();
87 return null_configuration;87 return null_configuration;
88 }88 }
89 void register_pause_resume_handlers(mir::MainLoop&,
90 std::function<void()> const&,
91 std::function<void()> const&)
92 {
93 }
94 void pause() {}
95 void resume() {}
89};96};
9097
91class StubGraphicPlatform : public mg::Platform98class StubGraphicPlatform : public mg::Platform
9299
=== modified file 'tests/unit-tests/compositor/test_multi_threaded_compositor.cpp'
--- tests/unit-tests/compositor/test_multi_threaded_compositor.cpp 2013-03-27 15:12:09 +0000
+++ tests/unit-tests/compositor/test_multi_threaded_compositor.cpp 2013-04-11 11:00:30 +0000
@@ -53,6 +53,13 @@
53 {53 {
54 return std::shared_ptr<mg::DisplayConfiguration>();54 return std::shared_ptr<mg::DisplayConfiguration>();
55 }55 }
56 void register_pause_resume_handlers(mir::MainLoop&,
57 std::function<void()> const&,
58 std::function<void()> const&)
59 {
60 }
61 void pause() {}
62 void resume() {}
5663
57private:64private:
58 std::vector<mtd::NullDisplayBuffer> buffers;65 std::vector<mtd::NullDisplayBuffer> buffers;
5966
=== modified file 'tests/unit-tests/graphics/gbm/mock_drm.cpp'
--- tests/unit-tests/graphics/gbm/mock_drm.cpp 2013-03-07 06:00:18 +0000
+++ tests/unit-tests/graphics/gbm/mock_drm.cpp 2013-04-11 11:00:30 +0000
@@ -351,3 +351,13 @@
351{351{
352 return global_mock->drmPrimeFDToHandle(fd, prime_fd, handle);352 return global_mock->drmPrimeFDToHandle(fd, prime_fd, handle);
353}353}
354
355int drmSetMaster(int fd)
356{
357 return global_mock->drmSetMaster(fd);
358}
359
360int drmDropMaster(int fd)
361{
362 return global_mock->drmDropMaster(fd);
363}
354364
=== modified file 'tests/unit-tests/graphics/gbm/mock_drm.h'
--- tests/unit-tests/graphics/gbm/mock_drm.h 2013-03-07 06:00:18 +0000
+++ tests/unit-tests/graphics/gbm/mock_drm.h 2013-04-11 11:00:30 +0000
@@ -117,6 +117,9 @@
117 MOCK_METHOD4(drmPrimeHandleToFD, int(int fd, uint32_t handle, uint32_t flags, int *prime_fd));117 MOCK_METHOD4(drmPrimeHandleToFD, int(int fd, uint32_t handle, uint32_t flags, int *prime_fd));
118 MOCK_METHOD3(drmPrimeFDToHandle, int(int fd, int prime_fd, uint32_t *handle));118 MOCK_METHOD3(drmPrimeFDToHandle, int(int fd, int prime_fd, uint32_t *handle));
119119
120 MOCK_METHOD1(drmSetMaster, int(int fd));
121 MOCK_METHOD1(drmDropMaster, int(int fd));
122
120 FakeDRMResources fake_drm;123 FakeDRMResources fake_drm;
121};124};
122125
123126
=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_buffer.cpp'
--- tests/unit-tests/graphics/gbm/test_gbm_buffer.cpp 2013-03-27 04:39:27 +0000
+++ tests/unit-tests/graphics/gbm/test_gbm_buffer.cpp 2013-04-11 11:00:30 +0000
@@ -27,6 +27,7 @@
27#include "mir/graphics/buffer_initializer.h"27#include "mir/graphics/buffer_initializer.h"
28#include "mir/compositor/buffer_ipc_package.h"28#include "mir/compositor/buffer_ipc_package.h"
29#include "mir/compositor/buffer_properties.h"29#include "mir/compositor/buffer_properties.h"
30#include "mir_test_doubles/null_virtual_terminal.h"
3031
31#include "mir/graphics/null_display_report.h"32#include "mir/graphics/null_display_report.h"
3233
@@ -42,6 +43,7 @@
42namespace mg=mir::graphics;43namespace mg=mir::graphics;
43namespace mgg=mir::graphics::gbm;44namespace mgg=mir::graphics::gbm;
44namespace geom=mir::geometry;45namespace geom=mir::geometry;
46namespace mtd=mir::test::doubles;
4547
46class GBMGraphicBufferBasic : public ::testing::Test48class GBMGraphicBufferBasic : public ::testing::Test
47{49{
@@ -77,7 +79,8 @@
77 ON_CALL(mock_egl, eglGetProcAddress(StrEq("glEGLImageTargetTexture2DOES")))79 ON_CALL(mock_egl, eglGetProcAddress(StrEq("glEGLImageTargetTexture2DOES")))
78 .WillByDefault(Return(reinterpret_cast<func_ptr_t>(glEGLImageTargetTexture2DOES)));80 .WillByDefault(Return(reinterpret_cast<func_ptr_t>(glEGLImageTargetTexture2DOES)));
7981
80 platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());82 platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>(),
83 std::make_shared<mtd::NullVirtualTerminal>());
81 null_init = std::make_shared<mg::NullBufferInitializer>();84 null_init = std::make_shared<mg::NullBufferInitializer>();
82 allocator.reset(new mgg::GBMBufferAllocator(platform, null_init));85 allocator.reset(new mgg::GBMBufferAllocator(platform, null_init));
83 }86 }
8487
=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_buffer_allocator.cpp'
--- tests/unit-tests/graphics/gbm/test_gbm_buffer_allocator.cpp 2013-03-13 08:09:52 +0000
+++ tests/unit-tests/graphics/gbm/test_gbm_buffer_allocator.cpp 2013-04-11 11:00:30 +0000
@@ -27,6 +27,7 @@
27#include "mir_test/egl_mock.h"27#include "mir_test/egl_mock.h"
28#include "mir_test/gl_mock.h"28#include "mir_test/gl_mock.h"
29#include "mir_test_doubles/mock_buffer_initializer.h"29#include "mir_test_doubles/mock_buffer_initializer.h"
30#include "mir_test_doubles/null_virtual_terminal.h"
30#include "mir/graphics/null_display_report.h"31#include "mir/graphics/null_display_report.h"
3132
32#include <memory>33#include <memory>
@@ -67,7 +68,8 @@
67 ON_CALL(mock_egl, eglGetProcAddress(StrEq("glEGLImageTargetTexture2DOES")))68 ON_CALL(mock_egl, eglGetProcAddress(StrEq("glEGLImageTargetTexture2DOES")))
68 .WillByDefault(Return(reinterpret_cast<func_ptr_t>(glEGLImageTargetTexture2DOES)));69 .WillByDefault(Return(reinterpret_cast<func_ptr_t>(glEGLImageTargetTexture2DOES)));
6970
70 platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());71 platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>(),
72 std::make_shared<mtd::NullVirtualTerminal>());
71 mock_buffer_initializer = std::make_shared<testing::NiceMock<mtd::MockBufferInitializer>>();73 mock_buffer_initializer = std::make_shared<testing::NiceMock<mtd::MockBufferInitializer>>();
72 allocator.reset(new mgg::GBMBufferAllocator(platform, mock_buffer_initializer));74 allocator.reset(new mgg::GBMBufferAllocator(platform, mock_buffer_initializer));
73 }75 }
7476
=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display.cpp'
--- tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-03-22 11:37:34 +0000
+++ tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-04-11 11:00:30 +0000
@@ -18,13 +18,17 @@
18#include <boost/throw_exception.hpp>18#include <boost/throw_exception.hpp>
19#include "src/server/graphics/gbm/gbm_platform.h"19#include "src/server/graphics/gbm/gbm_platform.h"
20#include "src/server/graphics/gbm/gbm_display.h"20#include "src/server/graphics/gbm/gbm_display.h"
21#include "src/server/graphics/gbm/virtual_terminal.h"
21#include "mir/logging/display_report.h"22#include "mir/logging/display_report.h"
22#include "mir/logging/logger.h"23#include "mir/logging/logger.h"
24#include "mir/graphics/display_buffer.h"
25#include "mir/main_loop.h"
2326
24#include "mir_test/egl_mock.h"27#include "mir_test/egl_mock.h"
25#include "mir_test/gl_mock.h"28#include "mir_test/gl_mock.h"
26#include "mir/graphics/null_display_report.h"29#include "mir/graphics/null_display_report.h"
27#include "mir_test_doubles/mock_display_report.h"30#include "mir_test_doubles/mock_display_report.h"
31#include "mir_test_doubles/null_virtual_terminal.h"
2832
29#include "mock_drm.h"33#include "mock_drm.h"
30#include "mock_gbm.h"34#include "mock_gbm.h"
@@ -48,11 +52,24 @@
48 ~MockLogger() noexcept(true) {}52 ~MockLogger() noexcept(true) {}
49};53};
5054
55class MockVirtualTerminal : public mgg::VirtualTerminal
56{
57public:
58 ~MockVirtualTerminal() noexcept(true) {}
59
60 MOCK_METHOD0(set_graphics_mode, void());
61 MOCK_METHOD3(register_switch_handlers,
62 void(mir::MainLoop&,
63 std::function<void()> const&,
64 std::function<void()> const&));
65};
66
51class GBMDisplayTest : public ::testing::Test67class GBMDisplayTest : public ::testing::Test
52{68{
53public:69public:
54 GBMDisplayTest() :70 GBMDisplayTest() :
55 mock_report(new ::testing::NiceMock<mtd::MockDisplayReport>())71 mock_report{std::make_shared<testing::NiceMock<mtd::MockDisplayReport>>()},
72 null_report{std::make_shared<mg::NullDisplayReport>()}
56 {73 {
57 using namespace testing;74 using namespace testing;
58 ON_CALL(mock_egl, eglChooseConfig(_,_,_,1,_))75 ON_CALL(mock_egl, eglChooseConfig(_,_,_,1,_))
@@ -78,6 +95,12 @@
78 .Times(AtLeast(0));95 .Times(AtLeast(0));
79 }96 }
8097
98 std::shared_ptr<mgg::GBMPlatform> create_platform()
99 {
100 return std::make_shared<mgg::GBMPlatform>(
101 null_report,
102 std::make_shared<mtd::NullVirtualTerminal>());
103 }
81104
82 void setup_post_update_expectations()105 void setup_post_update_expectations()
83 {106 {
@@ -167,7 +190,8 @@
167 ::testing::NiceMock<mir::GLMock> mock_gl;190 ::testing::NiceMock<mir::GLMock> mock_gl;
168 ::testing::NiceMock<mgg::MockDRM> mock_drm;191 ::testing::NiceMock<mgg::MockDRM> mock_drm;
169 ::testing::NiceMock<mgg::MockGBM> mock_gbm;192 ::testing::NiceMock<mgg::MockGBM> mock_gbm;
170 std::shared_ptr<testing::NiceMock<mtd::MockDisplayReport>> mock_report;193 std::shared_ptr<testing::NiceMock<mtd::MockDisplayReport>> const mock_report;
194 std::shared_ptr<mg::DisplayReport> const null_report;
171};195};
172196
173}197}
@@ -232,8 +256,8 @@
232256
233 EXPECT_NO_THROW(257 EXPECT_NO_THROW(
234 {258 {
235 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());259 auto platform = create_platform();
236 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);260 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
237 });261 });
238}262}
239263
@@ -273,8 +297,8 @@
273297
274 EXPECT_NO_THROW(298 EXPECT_NO_THROW(
275 {299 {
276 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());300 auto platform = create_platform();
277 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);301 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
278 });302 });
279}303}
280304
@@ -291,8 +315,8 @@
291315
292 EXPECT_THROW(316 EXPECT_THROW(
293 {317 {
294 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());318 auto platform = create_platform();
295 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);319 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
296 }, std::runtime_error);320 }, std::runtime_error);
297}321}
298322
@@ -310,10 +334,10 @@
310 EXPECT_CALL(mock_drm, drmClose(_))334 EXPECT_CALL(mock_drm, drmClose(_))
311 .Times(Exactly(1));335 .Times(Exactly(1));
312336
313 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());337 auto platform = create_platform();
314338
315 EXPECT_THROW({339 EXPECT_THROW({
316 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);340 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
317 }, std::runtime_error) << "Expected that c'tor of GBMDisplay throws";341 }, std::runtime_error) << "Expected that c'tor of GBMDisplay throws";
318}342}
319343
@@ -332,8 +356,8 @@
332 .Times(Exactly(1));356 .Times(Exactly(1));
333357
334 EXPECT_THROW({358 EXPECT_THROW({
335 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());359 auto platform = create_platform();
336 }, std::runtime_error) << "Expected c'tor of GBMDisplay to throw an exception";360 }, std::runtime_error) << "Expected c'tor of GBMPlatform to throw an exception";
337}361}
338362
339namespace363namespace
@@ -394,8 +418,8 @@
394418
395 EXPECT_NO_THROW(419 EXPECT_NO_THROW(
396 {420 {
397 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());421 auto platform = create_platform();
398 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);422 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
399423
400 display->for_each_display_buffer([](mg::DisplayBuffer& db)424 display->for_each_display_buffer([](mg::DisplayBuffer& db)
401 {425 {
@@ -434,8 +458,8 @@
434458
435 EXPECT_NO_THROW(459 EXPECT_NO_THROW(
436 {460 {
437 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());461 auto platform = create_platform();
438 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);462 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
439463
440 display->for_each_display_buffer([](mg::DisplayBuffer& db)464 display->for_each_display_buffer([](mg::DisplayBuffer& db)
441 {465 {
@@ -469,7 +493,7 @@
469493
470 EXPECT_NO_THROW(494 EXPECT_NO_THROW(
471 {495 {
472 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());496 auto platform = create_platform();
473 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);497 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);
474 });498 });
475}499}
@@ -478,11 +502,11 @@
478{502{
479 using namespace ::testing;503 using namespace ::testing;
480504
481 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());505 auto platform = create_platform();
482 auto logger = std::make_shared<MockLogger>();506 auto logger = std::make_shared<MockLogger>();
483507
484 auto reporter = std::make_shared<ml::DisplayReport>(logger);508 auto reporter = std::make_shared<ml::DisplayReport>(logger);
485 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);509 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
486510
487 EXPECT_CALL(511 EXPECT_CALL(
488 *logger,512 *logger,
@@ -497,11 +521,11 @@
497{521{
498 using namespace ::testing;522 using namespace ::testing;
499523
500 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());524 auto platform = create_platform();
501 auto logger = std::make_shared<MockLogger>();525 auto logger = std::make_shared<MockLogger>();
502526
503 auto reporter = std::make_shared<ml::DisplayReport>(logger);527 auto reporter = std::make_shared<ml::DisplayReport>(logger);
504 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);528 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
505529
506 EXPECT_CALL(530 EXPECT_CALL(
507 *logger,531 *logger,
@@ -516,11 +540,11 @@
516{540{
517 using namespace ::testing;541 using namespace ::testing;
518542
519 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());543 auto platform = create_platform();
520 auto logger = std::make_shared<MockLogger>();544 auto logger = std::make_shared<MockLogger>();
521545
522 auto reporter = std::make_shared<ml::DisplayReport>(logger);546 auto reporter = std::make_shared<ml::DisplayReport>(logger);
523 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);547 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
524548
525 EXPECT_CALL(549 EXPECT_CALL(
526 *logger,550 *logger,
@@ -535,11 +559,11 @@
535{559{
536 using namespace ::testing;560 using namespace ::testing;
537561
538 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());562 auto platform = create_platform();
539 auto logger = std::make_shared<MockLogger>();563 auto logger = std::make_shared<MockLogger>();
540564
541 auto reporter = std::make_shared<ml::DisplayReport>(logger);565 auto reporter = std::make_shared<ml::DisplayReport>(logger);
542 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);566 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
543567
544 EXPECT_CALL(568 EXPECT_CALL(
545 *logger,569 *logger,
@@ -561,8 +585,8 @@
561585
562 EXPECT_THROW(586 EXPECT_THROW(
563 {587 {
564 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());588 auto platform = create_platform();
565 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);589 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
566 }, std::runtime_error);590 }, std::runtime_error);
567}591}
568592
@@ -577,8 +601,8 @@
577601
578 EXPECT_THROW(602 EXPECT_THROW(
579 {603 {
580 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());604 auto platform = create_platform();
581 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);605 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
582 }, std::runtime_error);606 }, std::runtime_error);
583}607}
584608
@@ -586,8 +610,8 @@
586{610{
587 using namespace ::testing;611 using namespace ::testing;
588612
589 auto platform = std::make_shared<mgg::GBMPlatform>(std::make_shared<mg::NullDisplayReport>());613 auto platform = create_platform();
590 auto display = std::make_shared<mgg::GBMDisplay>(platform, mock_report);614 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
591615
592 int callback_count{0};616 int callback_count{0};
593617
@@ -598,3 +622,65 @@
598622
599 EXPECT_NE(0, callback_count);623 EXPECT_NE(0, callback_count);
600}624}
625
626TEST_F(GBMDisplayTest, constructor_sets_vt_graphics_mode)
627{
628 using namespace testing;
629
630 auto mock_vt = std::make_shared<MockVirtualTerminal>();
631
632 EXPECT_CALL(*mock_vt, set_graphics_mode())
633 .Times(1);
634
635 auto platform = std::make_shared<mgg::GBMPlatform>(null_report, mock_vt);
636
637 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
638}
639
640TEST_F(GBMDisplayTest, pause_drops_drm_master)
641{
642 using namespace testing;
643
644 EXPECT_CALL(mock_drm, drmDropMaster(mock_drm.fake_drm.fd()))
645 .Times(1);
646
647 auto platform = create_platform();
648 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
649
650 display->pause();
651}
652
653TEST_F(GBMDisplayTest, resume_sets_drm_master)
654{
655 using namespace testing;
656
657 EXPECT_CALL(mock_drm, drmSetMaster(mock_drm.fake_drm.fd()))
658 .Times(1);
659
660 auto platform = create_platform();
661 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
662
663 display->resume();
664}
665
666TEST_F(GBMDisplayTest, set_or_drop_drm_master_failure_throws)
667{
668 using namespace testing;
669
670 EXPECT_CALL(mock_drm, drmDropMaster(_))
671 .WillOnce(Return(-1));
672
673 EXPECT_CALL(mock_drm, drmSetMaster(_))
674 .WillOnce(Return(-1));
675
676 auto platform = create_platform();
677 auto display = std::make_shared<mgg::GBMDisplay>(platform, null_report);
678
679 EXPECT_THROW({
680 display->pause();
681 }, std::runtime_error);
682
683 EXPECT_THROW({
684 display->resume();
685 }, std::runtime_error);
686}
601687
=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp'
--- tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp 2013-03-13 08:09:52 +0000
+++ tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp 2013-04-11 11:00:30 +0000
@@ -25,6 +25,7 @@
25#include "mir_test/egl_mock.h"25#include "mir_test/egl_mock.h"
26#include "mir_test/gl_mock.h"26#include "mir_test/gl_mock.h"
27#include "mir/graphics/null_display_report.h"27#include "mir/graphics/null_display_report.h"
28#include "mir_test_doubles/null_virtual_terminal.h"
2829
29#include "mock_drm.h"30#include "mock_drm.h"
30#include "mock_gbm.h"31#include "mock_gbm.h"
@@ -37,6 +38,7 @@
37namespace mg = mir::graphics;38namespace mg = mir::graphics;
38namespace mgg = mir::graphics::gbm;39namespace mgg = mir::graphics::gbm;
39namespace geom = mir::geometry;40namespace geom = mir::geometry;
41namespace mtd = mir::test::doubles;
4042
41namespace43namespace
42{44{
@@ -59,8 +61,7 @@
59class GBMDisplayConfigurationTest : public ::testing::Test61class GBMDisplayConfigurationTest : public ::testing::Test
60{62{
61public:63public:
62 GBMDisplayConfigurationTest() :64 GBMDisplayConfigurationTest()
63 null_listener{std::make_shared<mg::NullDisplayReport>()}
64 {65 {
65 using namespace testing;66 using namespace testing;
6667
@@ -81,6 +82,13 @@
81 setup_sample_modes();82 setup_sample_modes();
82 }83 }
8384
85 std::shared_ptr<mgg::GBMPlatform> create_platform()
86 {
87 return std::make_shared<mgg::GBMPlatform>(
88 std::make_shared<mg::NullDisplayReport>(),
89 std::make_shared<mtd::NullVirtualTerminal>());
90 }
91
84 void setup_sample_modes()92 void setup_sample_modes()
85 {93 {
86 /* Add DRM modes */94 /* Add DRM modes */
@@ -98,7 +106,6 @@
98 ::testing::NiceMock<mir::GLMock> mock_gl;106 ::testing::NiceMock<mir::GLMock> mock_gl;
99 ::testing::NiceMock<mgg::MockDRM> mock_drm;107 ::testing::NiceMock<mgg::MockDRM> mock_drm;
100 ::testing::NiceMock<mgg::MockGBM> mock_gbm;108 ::testing::NiceMock<mgg::MockGBM> mock_gbm;
101 std::shared_ptr<mg::DisplayReport> const null_listener;
102109
103 std::vector<drmModeModeInfo> modes0;110 std::vector<drmModeModeInfo> modes0;
104 std::vector<mg::DisplayConfigurationMode> conf_modes0;111 std::vector<mg::DisplayConfigurationMode> conf_modes0;
@@ -176,7 +183,7 @@
176 };183 };
177184
178 /* Test body */185 /* Test body */
179 auto platform = std::make_shared<mgg::GBMPlatform>(null_listener);186 auto platform = create_platform();
180 auto display = platform->create_display();187 auto display = platform->create_display();
181188
182 auto conf = display->configuration();189 auto conf = display->configuration();
@@ -214,7 +221,7 @@
214 resources.prepare();221 resources.prepare();
215222
216 /* Test body */223 /* Test body */
217 auto platform = std::make_shared<mgg::GBMPlatform>(null_listener);224 auto platform = create_platform();
218 auto display = platform->create_display();225 auto display = platform->create_display();
219226
220 auto conf = display->configuration();227 auto conf = display->configuration();
@@ -253,7 +260,7 @@
253 resources.prepare();260 resources.prepare();
254261
255 /* Test body */262 /* Test body */
256 auto platform = std::make_shared<mgg::GBMPlatform>(null_listener);263 auto platform = create_platform();
257 auto display = platform->create_display();264 auto display = platform->create_display();
258265
259 auto conf = display->configuration();266 auto conf = display->configuration();
260267
=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp'
--- tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp 2013-03-13 08:09:52 +0000
+++ tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp 2013-04-11 11:00:30 +0000
@@ -23,6 +23,7 @@
23#include "mir_test/egl_mock.h"23#include "mir_test/egl_mock.h"
24#include "mir_test/gl_mock.h"24#include "mir_test/gl_mock.h"
25#include "mir/graphics/null_display_report.h"25#include "mir/graphics/null_display_report.h"
26#include "mir_test_doubles/null_virtual_terminal.h"
2627
27#include "mock_drm.h"28#include "mock_drm.h"
28#include "mock_gbm.h"29#include "mock_gbm.h"
@@ -33,6 +34,7 @@
33namespace mg = mir::graphics;34namespace mg = mir::graphics;
34namespace mgg = mir::graphics::gbm;35namespace mgg = mir::graphics::gbm;
35namespace geom = mir::geometry;36namespace geom = mir::geometry;
37namespace mtd = mir::test::doubles;
3638
37namespace39namespace
38{40{
@@ -41,7 +43,6 @@
41{43{
42public:44public:
43 GBMDisplayMultiMonitorTest()45 GBMDisplayMultiMonitorTest()
44 : null_listener{std::make_shared<mg::NullDisplayReport>()}
45 {46 {
46 using namespace testing;47 using namespace testing;
4748
@@ -69,6 +70,13 @@
69 .Times(AtLeast(0));70 .Times(AtLeast(0));
70 }71 }
7172
73 std::shared_ptr<mgg::GBMPlatform> create_platform()
74 {
75 return std::make_shared<mgg::GBMPlatform>(
76 std::make_shared<mg::NullDisplayReport>(),
77 std::make_shared<mtd::NullVirtualTerminal>());
78 }
79
72 void setup_outputs(int n)80 void setup_outputs(int n)
73 {81 {
74 mgg::FakeDRMResources& resources(mock_drm.fake_drm);82 mgg::FakeDRMResources& resources(mock_drm.fake_drm);
@@ -117,7 +125,6 @@
117 testing::NiceMock<mir::GLMock> mock_gl;125 testing::NiceMock<mir::GLMock> mock_gl;
118 testing::NiceMock<mgg::MockDRM> mock_drm;126 testing::NiceMock<mgg::MockDRM> mock_drm;
119 testing::NiceMock<mgg::MockGBM> mock_gbm;127 testing::NiceMock<mgg::MockGBM> mock_gbm;
120 std::shared_ptr<mg::DisplayReport> const null_listener;
121128
122 std::vector<drmModeModeInfo> modes0;129 std::vector<drmModeModeInfo> modes0;
123 std::vector<drmModeModeInfo> modes_empty;130 std::vector<drmModeModeInfo> modes_empty;
@@ -168,7 +175,7 @@
168 .After(crtc_setups);175 .After(crtc_setups);
169 }176 }
170177
171 auto platform = std::make_shared<mgg::GBMPlatform>(null_listener);178 auto platform = create_platform();
172 auto display = platform->create_display();179 auto display = platform->create_display();
173}180}
174181
@@ -201,7 +208,7 @@
201 .Times(1);208 .Times(1);
202 }209 }
203210
204 auto platform = std::make_shared<mgg::GBMPlatform>(null_listener);211 auto platform = create_platform();
205 auto display = platform->create_display();212 auto display = platform->create_display();
206}213}
207214
@@ -254,7 +261,7 @@
254 .WillOnce(DoAll(InvokePageFlipHandler(&user_data[1]), Return(0)))261 .WillOnce(DoAll(InvokePageFlipHandler(&user_data[1]), Return(0)))
255 .WillOnce(DoAll(InvokePageFlipHandler(&user_data[2]), Return(0)));262 .WillOnce(DoAll(InvokePageFlipHandler(&user_data[2]), Return(0)));
256263
257 auto platform = std::make_shared<mgg::GBMPlatform>(null_listener);264 auto platform = create_platform();
258 auto display = platform->create_display();265 auto display = platform->create_display();
259266
260 display->for_each_display_buffer([](mg::DisplayBuffer& buffer)267 display->for_each_display_buffer([](mg::DisplayBuffer& buffer)
261268
=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_platform.cpp'
--- tests/unit-tests/graphics/gbm/test_gbm_platform.cpp 2013-03-13 04:54:15 +0000
+++ tests/unit-tests/graphics/gbm/test_gbm_platform.cpp 2013-04-11 11:00:30 +0000
@@ -16,9 +16,10 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#include "mir/graphics/platform.h"
20#include "mir/graphics/platform_ipc_package.h"19#include "mir/graphics/platform_ipc_package.h"
21#include "mir/graphics/drm_authenticator.h"20#include "mir/graphics/drm_authenticator.h"
21#include "src/server/graphics/gbm/gbm_platform.h"
22#include "mir_test_doubles/null_virtual_terminal.h"
2223
23#include "mir/graphics/null_display_report.h"24#include "mir/graphics/null_display_report.h"
2425
@@ -28,13 +29,17 @@
28#include "mock_gbm.h"29#include "mock_gbm.h"
2930
30#include <gtest/gtest.h>31#include <gtest/gtest.h>
32#include <gmock/gmock.h>
3133
32#include <stdexcept>34#include <stdexcept>
3335
34namespace mg = mir::graphics;36namespace mg = mir::graphics;
37namespace mgg = mir::graphics::gbm;
38namespace mtd = mir::test::doubles;
3539
36namespace40namespace
37{41{
42
38class GBMGraphicsPlatform : public ::testing::Test43class GBMGraphicsPlatform : public ::testing::Test
39{44{
40public:45public:
@@ -43,6 +48,14 @@
43 ::testing::Mock::VerifyAndClearExpectations(&mock_drm);48 ::testing::Mock::VerifyAndClearExpectations(&mock_drm);
44 ::testing::Mock::VerifyAndClearExpectations(&mock_gbm);49 ::testing::Mock::VerifyAndClearExpectations(&mock_gbm);
45 }50 }
51
52 std::shared_ptr<mg::Platform> create_platform()
53 {
54 return std::make_shared<mgg::GBMPlatform>(
55 std::make_shared<mg::NullDisplayReport>(),
56 std::make_shared<mtd::NullVirtualTerminal>());
57 }
58
46 ::testing::NiceMock<mg::gbm::MockDRM> mock_drm;59 ::testing::NiceMock<mg::gbm::MockDRM> mock_drm;
47 ::testing::NiceMock<mg::gbm::MockGBM> mock_gbm;60 ::testing::NiceMock<mg::gbm::MockGBM> mock_gbm;
48};61};
@@ -69,7 +82,7 @@
69 EXPECT_CALL(mock_drm, drmClose(auth_fd));82 EXPECT_CALL(mock_drm, drmClose(auth_fd));
7083
71 EXPECT_NO_THROW (84 EXPECT_NO_THROW (
72 auto platform = mg::create_platform(std::make_shared<mg::NullDisplayReport>());85 auto platform = create_platform();
73 auto pkg = platform->get_ipc_package();86 auto pkg = platform->get_ipc_package();
7487
75 ASSERT_TRUE(pkg.get());88 ASSERT_TRUE(pkg.get());
@@ -87,7 +100,7 @@
87100
88 try101 try
89 {102 {
90 auto platform = mg::create_platform(std::make_shared<mg::NullDisplayReport>());103 auto platform = create_platform();
91 } catch(...)104 } catch(...)
92 {105 {
93 return;106 return;
@@ -105,7 +118,7 @@
105 EXPECT_CALL(mock_drm, drmAuthMagic(mock_drm.fake_drm.fd(),magic))118 EXPECT_CALL(mock_drm, drmAuthMagic(mock_drm.fake_drm.fd(),magic))
106 .WillOnce(Return(0));119 .WillOnce(Return(0));
107120
108 auto platform = mg::create_platform(std::make_shared<mg::NullDisplayReport>());121 auto platform = create_platform();
109 auto authenticator = std::dynamic_pointer_cast<mg::DRMAuthenticator>(platform);122 auto authenticator = std::dynamic_pointer_cast<mg::DRMAuthenticator>(platform);
110 authenticator->drm_auth_magic(magic);123 authenticator->drm_auth_magic(magic);
111}124}
@@ -119,7 +132,7 @@
119 EXPECT_CALL(mock_drm, drmAuthMagic(mock_drm.fake_drm.fd(),magic))132 EXPECT_CALL(mock_drm, drmAuthMagic(mock_drm.fake_drm.fd(),magic))
120 .WillOnce(Return(-1));133 .WillOnce(Return(-1));
121134
122 auto platform = mg::create_platform(std::make_shared<mg::NullDisplayReport>());135 auto platform = create_platform();
123 auto authenticator = std::dynamic_pointer_cast<mg::DRMAuthenticator>(platform);136 auto authenticator = std::dynamic_pointer_cast<mg::DRMAuthenticator>(platform);
124137
125 EXPECT_THROW({138 EXPECT_THROW({
126139
=== modified file 'tests/unit-tests/graphics/test_graphics_platform.cpp'
--- tests/unit-tests/graphics/test_graphics_platform.cpp 2013-03-22 17:08:01 +0000
+++ tests/unit-tests/graphics/test_graphics_platform.cpp 2013-04-11 11:00:30 +0000
@@ -25,6 +25,8 @@
25#ifndef ANDROID25#ifndef ANDROID
26#include "gbm/mock_drm.h"26#include "gbm/mock_drm.h"
27#include "gbm/mock_gbm.h"27#include "gbm/mock_gbm.h"
28#include "mir_test_doubles/null_virtual_terminal.h"
29#include "src/server/graphics/gbm/gbm_platform.h"
28#else30#else
29#include "mir_test/hw_mock.h"31#include "mir_test/hw_mock.h"
30#endif32#endif
@@ -69,6 +71,17 @@
69#endif71#endif
70 }72 }
7173
74 std::shared_ptr<mg::Platform> create_platform()
75 {
76#ifdef ANDROID
77 return mg::create_platform(std::make_shared<mg::NullDisplayReport>());
78#else
79 return std::make_shared<mg::gbm::GBMPlatform>(
80 std::make_shared<mg::NullDisplayReport>(),
81 std::make_shared<mir::test::doubles::NullVirtualTerminal>());
82#endif
83 }
84
72 std::shared_ptr<ml::Logger> logger;85 std::shared_ptr<ml::Logger> logger;
73 std::shared_ptr<mg::BufferInitializer> buffer_initializer;86 std::shared_ptr<mg::BufferInitializer> buffer_initializer;
7487
@@ -87,7 +100,7 @@
87 using namespace testing;100 using namespace testing;
88101
89 EXPECT_NO_THROW (102 EXPECT_NO_THROW (
90 auto platform = mg::create_platform(std::make_shared<mg::NullDisplayReport>());103 auto platform = create_platform();
91 auto allocator = platform->create_buffer_allocator(buffer_initializer);104 auto allocator = platform->create_buffer_allocator(buffer_initializer);
92105
93 EXPECT_TRUE(allocator.get());106 EXPECT_TRUE(allocator.get());
@@ -97,7 +110,7 @@
97110
98TEST_F(GraphicsPlatform, buffer_creation)111TEST_F(GraphicsPlatform, buffer_creation)
99{112{
100 auto platform = mg::create_platform(std::make_shared<mg::NullDisplayReport>());113 auto platform = create_platform();
101 auto allocator = platform->create_buffer_allocator(buffer_initializer);114 auto allocator = platform->create_buffer_allocator(buffer_initializer);
102 auto supported_pixel_formats = allocator->supported_pixel_formats();115 auto supported_pixel_formats = allocator->supported_pixel_formats();
103116
@@ -119,7 +132,7 @@
119132
120TEST_F(GraphicsPlatform, get_ipc_package)133TEST_F(GraphicsPlatform, get_ipc_package)
121{134{
122 auto platform = mg::create_platform(std::make_shared<mg::NullDisplayReport>());135 auto platform = create_platform();
123 auto pkg = platform->get_ipc_package();136 auto pkg = platform->get_ipc_package();
124137
125 ASSERT_TRUE(pkg.get() != NULL);138 ASSERT_TRUE(pkg.get() != NULL);

Subscribers

People subscribed via source and target branches