Mir

Merge lp:~robert-ancell/mir/gbm-check-connections into lp:~mir-team/mir/trunk

Proposed by Robert Ancell
Status: Merged
Approved by: Robert Ancell
Approved revision: no longer in the source branch.
Merged at revision: 833
Proposed branch: lp:~robert-ancell/mir/gbm-check-connections
Merge into: lp:~mir-team/mir/trunk
Diff against target: 163 lines (+58/-12)
5 files modified
src/server/graphics/gbm/gbm_display_helpers.cpp (+20/-2)
src/server/graphics/gbm/gbm_display_helpers.h (+2/-0)
tests/unit-tests/graphics/gbm/test_gbm_display.cpp (+4/-2)
tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp (+16/-8)
tests/unit-tests/graphics/gbm/test_gbm_platform.cpp (+16/-0)
To merge this branch: bzr merge lp:~robert-ancell/mir/gbm-check-connections
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Abstain
Review via email: mp+172982@code.launchpad.net

Commit message

Only use a DRM device if it has connections

Description of the change

Pick the first DRM device that has connections.

I'm least sure about the testing changes, but I discussed then with Alexandros on a hangout and I think they match what he expected.

To post a comment you must log in.
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

8 +int mggh::DRMHelper::count_connections(int fd)

In drm_mode_resources.h we have a class DRMModeResources for dealing with resources in a more elegant and safe way. We should use it here. See kms_display_configuration.cpp for an example of how to use it.

72 - EXPECT_CALL(mock_drm, drmModeFreeResources(_))
73 - .Times(Exactly(0));
74 -
75 - EXPECT_CALL(mock_drm, drmClose(_))
76 - .Times(Exactly(1));

We should keep these. They check that we handle failure gracefully (i.e., that we don't try to free null resources, and that we shut down drm properly).

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Robert Ancell (robert-ancell) wrote :

> 72 - EXPECT_CALL(mock_drm, drmModeFreeResources(_))
> 73 - .Times(Exactly(0));
> 74 -
> 75 - EXPECT_CALL(mock_drm, drmClose(_))
> 76 - .Times(Exactly(1));
>
> We should keep these. They check that we handle failure gracefully (i.e., that
> we don't try to free null resources, and that we shut down drm properly).

drmClose isn't called, because the DRM device is open()ed and close()d directly.

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

> drmClose isn't called, because the DRM device is open()ed and close()d directly.

We are still using drmClose:

$ grep -R drmClose src/
src/server/graphics/gbm/drm_close_threadsafe.cpp: return drmClose(fd);

$ grep -R drm_close_threadsafe\( src/
src/server/graphics/gbm/gbm_platform.cpp: mgg::drm_close_threadsafe(ipc_fds[0]);
src/server/graphics/gbm/drm_close_threadsafe.cpp:int mgg::drm_close_threadsafe(int fd)
src/server/graphics/gbm/drm_close_threadsafe.h:int drm_close_threadsafe(int fd);
src/server/graphics/gbm/gbm_display_helpers.cpp: mgg::drm_close_threadsafe(fd);

Revision history for this message
Robert Ancell (robert-ancell) wrote :

> > drmClose isn't called, because the DRM device is open()ed and close()d
> directly.
>
> We are still using drmClose:

Yes, drmClose is the codebase but *in this particular case* drmClose is not called because the new code bails out earlier than before. I've updated the test to make this clearer.

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

135 - resources.add_connector(id, DRM_MODE_DISCONNECTED, invalid_id,
136 - modes_empty, possible_encoder_ids_empty,
137 + resources.add_connector(id, DRM_MODE_CONNECTED, encoder0_id,

This looks suspiciously like changing one test scenario to an other, where adding the new scenario would be better.

But as Alexandros is more familiar with this logic I'll let him decide.

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

> > drmClose isn't called, because the DRM device is open()ed and close()d
> directly.
>
> We are still using drmClose:

OK, in that case the test is no longer a GBMDisplay test, but a GBMPlatform test, and an adaptation of it should be placed in test_gbm_platform.cpp. For this test I propose the following changes:

TEST_F(GBMDisplayTest, create_display_kms_failure)
{
    using namespace testing;

    auto platform = create_platform();

    Mock::VerifyAndClearExpectations(&mock_drm);

    EXPECT_CALL(mock_drm, drmModeGetResources(_))
        .Times(Exactly(1))
        .WillOnce(Return(reinterpret_cast<drmModeRes*>(0)));

    EXPECT_CALL(mock_drm, drmModeFreeResources(_))
        .Times(Exactly(0));

    EXPECT_CALL(mock_drm, drmClose(_))
        .Times(Exactly(1));

    EXPECT_THROW({
        auto display = create_display(platform);
    }, std::runtime_error) << "Expected that c'tor of GBMDisplay throws";
}

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

> 135 - resources.add_connector(id, DRM_MODE_DISCONNECTED, invalid_id,
> 136 - modes_empty, possible_encoder_ids_empty,
> 137 + resources.add_connector(id, DRM_MODE_CONNECTED, encoder0_id,
>
> This looks suspiciously like changing one test scenario to an other, where
> adding the new scenario would be better.
>
> But as Alexandros is more familiar with this logic I'll let him decide.

These particular tests aren't affected by these changes; they don't care about the connection status of the connectors, so we can safely change them.

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

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/server/graphics/gbm/gbm_display_helpers.cpp'
2--- src/server/graphics/gbm/gbm_display_helpers.cpp 2013-07-04 07:20:35 +0000
3+++ src/server/graphics/gbm/gbm_display_helpers.cpp 2013-07-10 01:52:27 +0000
4@@ -194,6 +194,20 @@
5 return ENOMEDIUM;
6 }
7
8+int mggh::DRMHelper::count_connections(int fd)
9+{
10+ DRMModeResources resources{fd};
11+
12+ int n_connected = 0;
13+ resources.for_each_connector([&](DRMModeConnectorUPtr connector)
14+ {
15+ if (connector->connection == DRM_MODE_CONNECTED)
16+ n_connected++;
17+ });
18+
19+ return n_connected;
20+}
21+
22 int mggh::DRMHelper::open_drm_device(UdevHelper const& udev)
23 {
24 int tmp_fd = -1;
25@@ -254,8 +268,12 @@
26 continue;
27 }
28
29- // We currently only handle one DRM device
30- break;
31+ // Stop if this device has connections to display on
32+ if (count_connections(tmp_fd) > 0)
33+ break;
34+
35+ close(tmp_fd);
36+ tmp_fd = -1;
37 }
38 udev_enumerate_unref(enumerator);
39
40
41=== modified file 'src/server/graphics/gbm/gbm_display_helpers.h'
42--- src/server/graphics/gbm/gbm_display_helpers.h 2013-06-25 06:39:50 +0000
43+++ src/server/graphics/gbm/gbm_display_helpers.h 2013-07-10 01:52:27 +0000
44@@ -84,6 +84,8 @@
45 // handling >1 DRM device.
46 int is_appropriate_device(UdevHelper const& udev, udev_device* dev);
47
48+ int count_connections(int fd);
49+
50 int open_drm_device(UdevHelper const& udev);
51 };
52
53
54=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display.cpp'
55--- tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-07-03 17:48:30 +0000
56+++ tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-07-10 01:52:27 +0000
57@@ -347,6 +347,10 @@
58 {
59 using namespace testing;
60
61+ auto platform = create_platform();
62+
63+ Mock::VerifyAndClearExpectations(&mock_drm);
64+
65 EXPECT_CALL(mock_drm, drmModeGetResources(_))
66 .Times(Exactly(1))
67 .WillOnce(Return(reinterpret_cast<drmModeRes*>(0)));
68@@ -357,8 +361,6 @@
69 EXPECT_CALL(mock_drm, drmClose(_))
70 .Times(Exactly(1));
71
72- auto platform = create_platform();
73-
74 EXPECT_THROW({
75 auto display = create_display(platform);
76 }, std::runtime_error) << "Expected that c'tor of GBMDisplay throws";
77
78=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp'
79--- tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp 2013-07-01 06:53:02 +0000
80+++ tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp 2013-07-10 01:52:27 +0000
81@@ -209,19 +209,23 @@
82
83 TEST_F(GBMDisplayConfigurationTest, get_kms_connector_id_returns_correct_id)
84 {
85- uint32_t const invalid_id{0};
86+ uint32_t const crtc0_id{10};
87+ uint32_t const encoder0_id{20};
88+ uint32_t const possible_crtcs_mask_empty{0};
89 std::vector<uint32_t> const connector_ids{30, 31};
90- std::vector<uint32_t> possible_encoder_ids_empty;
91+ std::vector<uint32_t> encoder_ids{20};
92
93 /* Set up DRM resources */
94 mtd::FakeDRMResources& resources(mock_drm.fake_drm);
95
96 resources.reset();
97
98+ resources.add_crtc(crtc0_id, modes0[1]);
99+ resources.add_encoder(encoder0_id, crtc0_id, possible_crtcs_mask_empty);
100 for (auto id : connector_ids)
101 {
102- resources.add_connector(id, DRM_MODE_DISCONNECTED, invalid_id,
103- modes_empty, possible_encoder_ids_empty,
104+ resources.add_connector(id, DRM_MODE_CONNECTED, encoder0_id,
105+ modes0, encoder_ids,
106 geom::Size());
107 }
108
109@@ -248,19 +252,23 @@
110
111 TEST_F(GBMDisplayConfigurationTest, get_kms_connector_id_throws_on_invalid_id)
112 {
113- uint32_t const invalid_id{0};
114+ uint32_t const crtc0_id{10};
115+ uint32_t const encoder0_id{20};
116+ uint32_t const possible_crtcs_mask_empty{0};
117 std::vector<uint32_t> const connector_ids{30, 31};
118- std::vector<uint32_t> possible_encoder_ids_empty;
119+ std::vector<uint32_t> encoder_ids{20};
120
121 /* Set up DRM resources */
122 mtd::FakeDRMResources& resources(mock_drm.fake_drm);
123
124 resources.reset();
125
126+ resources.add_crtc(crtc0_id, modes0[1]);
127+ resources.add_encoder(encoder0_id, crtc0_id, possible_crtcs_mask_empty);
128 for (auto id : connector_ids)
129 {
130- resources.add_connector(id, DRM_MODE_DISCONNECTED, invalid_id,
131- modes_empty, possible_encoder_ids_empty,
132+ resources.add_connector(id, DRM_MODE_CONNECTED, encoder0_id,
133+ modes0, encoder_ids,
134 geom::Size());
135 }
136
137
138=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_platform.cpp'
139--- tests/unit-tests/graphics/gbm/test_gbm_platform.cpp 2013-07-08 16:02:07 +0000
140+++ tests/unit-tests/graphics/gbm/test_gbm_platform.cpp 2013-07-10 01:52:27 +0000
141@@ -120,6 +120,22 @@
142 FAIL() << "Expected an exception to be thrown.";
143 }
144
145+TEST_F(GBMGraphicsPlatform, fails_if_no_resources)
146+{
147+ using namespace ::testing;
148+
149+ EXPECT_CALL(mock_drm, drmModeGetResources(_))
150+ .Times(Exactly(1))
151+ .WillOnce(Return(reinterpret_cast<drmModeRes*>(0)));
152+
153+ EXPECT_CALL(mock_drm, drmModeFreeResources(_))
154+ .Times(Exactly(0));
155+
156+ EXPECT_THROW({
157+ auto platform = create_platform();
158+ }, std::runtime_error) << "Expected that c'tor of GBMPlatform throws";
159+}
160+
161 /* ipc packaging tests */
162 TEST_F(GBMGraphicsPlatform, test_ipc_data_packed_correctly)
163 {

Subscribers

People subscribed via source and target branches