Mir

Merge lp:~albaguirre/mir/minimize-1498550 into lp:mir

Proposed by Alberto Aguirre
Status: Merged
Approved by: Alberto Aguirre
Approved revision: no longer in the source branch.
Merged at revision: 2971
Proposed branch: lp:~albaguirre/mir/minimize-1498550
Merge into: lp:mir
Diff against target: 220 lines (+64/-27)
7 files modified
src/platforms/android/server/display.cpp (+0/-1)
src/platforms/android/server/display_disconnected_exception.h (+41/-0)
src/platforms/android/server/display_group.cpp (+4/-13)
src/platforms/android/server/display_group.h (+0/-2)
src/platforms/android/server/real_hwc_wrapper.cpp (+14/-1)
src/platforms/android/server/real_hwc_wrapper.h (+2/-0)
tests/unit-tests/graphics/android/test_display_group.cpp (+3/-10)
To merge this branch: bzr merge lp:~albaguirre/mir/minimize-1498550
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+272167@code.launchpad.net

Commit message

Query HWC for display connection if hwc->set fails.

Avoid using hotplug events to ignore commit errors; instead have the wrapper query the external display connection status and issue a DisplayDisconnectedException in such cases. The DisplayGroup can then choose to ignore that specific exception.

This only minimizes the occurences of lp:1498550, as there are still situations in which hwc->set fails due to unplugging the external display but hwc still reports the display as connected. The only recovery in this situation seems to be to tear down the compositor thread and recreate it as it happens when a display configuration occurs.

Description of the change

This only minimizes the occurences of lp:1498550, as there are still situations in which hwc->set fails due to unplugging the external display but hwc still reports the display as connected. The only recovery in this situation seems to be to tear down the compositor thread and recreate it as it happens when a display configuration occurs.

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

^--
"/usr/include/EGL/eglplatform.h:100:35: fatal error: android/native_window.h: No such file or directory"

Ummm.

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 :

Seems reasonable. (But not "obviously correct".)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platforms/android/server/display.cpp'
2--- src/platforms/android/server/display.cpp 2015-08-17 06:42:51 +0000
3+++ src/platforms/android/server/display.cpp 2015-09-25 14:17:02 +0000
4@@ -279,7 +279,6 @@
5 {
6 std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
7 configuration_dirty = true;
8- displays.hotplug_occurred();
9 display_change_pipe->notify_change();
10 }
11
12
13=== added file 'src/platforms/android/server/display_disconnected_exception.h'
14--- src/platforms/android/server/display_disconnected_exception.h 1970-01-01 00:00:00 +0000
15+++ src/platforms/android/server/display_disconnected_exception.h 2015-09-25 14:17:02 +0000
16@@ -0,0 +1,41 @@
17+/*
18+ * Copyright © 2015 Canonical Ltd.
19+ *
20+ * This program is free software: you can redistribute it and/or modify it
21+ * under the terms of the GNU Lesser General Public License version 3,
22+ * as published by the Free Software Foundation.
23+ *
24+ * This program is distributed in the hope that it will be useful,
25+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27+ * GNU Lesser General Public License for more details.
28+ *
29+ * You should have received a copy of the GNU Lesser General Public License
30+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31+ *
32+ * Authored by: Alberto Aguirre <alberto.aguirre@canonical.com>
33+ */
34+
35+#ifndef MIR_GRAPHICS_ANDROID_DISPLAY_DISCONNECTED_EXCEPTION_H_
36+#define MIR_GRAPHICS_ANDROID_DISPLAY_DISCONNECTED_EXCEPTION_H_
37+
38+#include <stdexcept>
39+
40+namespace mir
41+{
42+namespace graphics
43+{
44+namespace android
45+{
46+
47+class DisplayDisconnectedException : public std::runtime_error
48+{
49+public:
50+ DisplayDisconnectedException() : std::runtime_error("display disconnected") {}
51+};
52+
53+}
54+}
55+}
56+
57+#endif /* MIR_GRAPHICS_ANDROID_DISPLAY_DISCONNECTED_EXCEPTION_H_ */
58
59=== modified file 'src/platforms/android/server/display_group.cpp'
60--- src/platforms/android/server/display_group.cpp 2015-07-22 02:54:31 +0000
61+++ src/platforms/android/server/display_group.cpp 2015-09-25 14:17:02 +0000
62@@ -18,6 +18,7 @@
63
64 #include "display_group.h"
65 #include "configurable_display_buffer.h"
66+#include "display_disconnected_exception.h"
67 #include <boost/throw_exception.hpp>
68 #include <stdexcept>
69
70@@ -28,8 +29,7 @@
71 mga::DisplayGroup::DisplayGroup(
72 std::shared_ptr<mga::DisplayDevice> const& device,
73 std::unique_ptr<mga::ConfigurableDisplayBuffer> primary_buffer) :
74- device(device),
75- hotplugging(false)
76+ device(device)
77 {
78 dbs.emplace(std::make_pair(mga::DisplayName::primary, std::move(primary_buffer)));
79 }
80@@ -81,18 +81,15 @@
81 std::unique_lock<decltype(guard)> lk(guard);
82 for(auto const& db : dbs)
83 contents.emplace_back(db.second->contents());
84- hotplugging = false;
85 }
86
87 try
88 {
89 device->commit(contents);
90 }
91- catch (std::runtime_error& e)
92+ catch (mga::DisplayDisconnectedException& e)
93 {
94- std::unique_lock<decltype(guard)> lk(guard);
95- if (!hotplugging)
96- throw e;
97+ //Ignore disconnect errors as they are not fatal
98 }
99 }
100
101@@ -100,9 +97,3 @@
102 {
103 return device->recommended_sleep();
104 }
105-
106-void mga::DisplayGroup::hotplug_occurred()
107-{
108- std::unique_lock<decltype(guard)> lk(guard);
109- hotplugging = true;
110-}
111
112=== modified file 'src/platforms/android/server/display_group.h'
113--- src/platforms/android/server/display_group.h 2015-07-22 02:54:31 +0000
114+++ src/platforms/android/server/display_group.h 2015-09-25 14:17:02 +0000
115@@ -50,13 +50,11 @@
116 void remove(DisplayName name);
117 void configure(DisplayName name, MirPowerMode, MirOrientation, geometry::Displacement);
118 bool display_present(DisplayName name) const;
119- void hotplug_occurred();
120
121 private:
122 std::mutex mutable guard;
123 std::shared_ptr<DisplayDevice> const device;
124 std::map<DisplayName, std::unique_ptr<ConfigurableDisplayBuffer>> dbs;
125- bool hotplugging;
126 };
127
128 }
129
130=== modified file 'src/platforms/android/server/real_hwc_wrapper.cpp'
131--- src/platforms/android/server/real_hwc_wrapper.cpp 2015-07-22 02:54:31 +0000
132+++ src/platforms/android/server/real_hwc_wrapper.cpp 2015-09-25 14:17:02 +0000
133@@ -18,6 +18,7 @@
134
135 #include "real_hwc_wrapper.h"
136 #include "hwc_report.h"
137+#include "display_disconnected_exception.h"
138 #include <boost/throw_exception.hpp>
139 #include <stdexcept>
140 #include <sstream>
141@@ -115,9 +116,15 @@
142 std::array<hwc_display_contents_1_t*, HWC_NUM_DISPLAY_TYPES> const& displays) const
143 {
144 report->report_set_list(displays);
145- if (auto rc = hwc_device->set(hwc_device.get(), num_displays(displays),
146+ auto const num_displays = ::num_displays(displays);
147+ if (auto rc = hwc_device->set(hwc_device.get(), num_displays,
148 const_cast<hwc_display_contents_1**>(displays.data())))
149 {
150+ if (num_displays > 1 && !display_connected(DisplayName::external))
151+ {
152+ BOOST_THROW_EXCEPTION(mga::DisplayDisconnectedException());
153+ }
154+
155 std::stringstream ss;
156 ss << "error during hwc set(). rc = " << std::hex << rc;
157 BOOST_THROW_EXCEPTION(std::runtime_error(ss.str()));
158@@ -290,3 +297,9 @@
159 if (rc < 0)
160 BOOST_THROW_EXCEPTION(std::system_error(rc, std::system_category(), "unable to set active display config"));
161 }
162+
163+bool mga::RealHwcWrapper::display_connected(DisplayName display_name) const
164+{
165+ size_t num_configs = 0;
166+ return hwc_device->getDisplayConfigs(hwc_device.get(), display_name, nullptr, &num_configs) == 0;
167+}
168
169=== modified file 'src/platforms/android/server/real_hwc_wrapper.h'
170--- src/platforms/android/server/real_hwc_wrapper.h 2015-06-17 05:20:42 +0000
171+++ src/platforms/android/server/real_hwc_wrapper.h 2015-09-25 14:17:02 +0000
172@@ -73,6 +73,8 @@
173 void vsync(DisplayName, std::chrono::nanoseconds) noexcept;
174 void hotplug(DisplayName, bool) noexcept;
175 void invalidate() noexcept;
176+
177+ bool display_connected(DisplayName) const;
178 private:
179 std::shared_ptr<hwc_composer_device_1> const hwc_device;
180 std::shared_ptr<HwcReport> const report;
181
182=== modified file 'tests/unit-tests/graphics/android/test_display_group.cpp'
183--- tests/unit-tests/graphics/android/test_display_group.cpp 2015-07-22 02:54:31 +0000
184+++ tests/unit-tests/graphics/android/test_display_group.cpp 2015-09-25 14:17:02 +0000
185@@ -18,6 +18,7 @@
186
187 #include "src/platforms/android/server/configurable_display_buffer.h"
188 #include "src/platforms/android/server/display_group.h"
189+#include "src/platforms/android/server/display_disconnected_exception.h"
190 #include "mir/test/doubles/mock_display_device.h"
191 #include "mir/test/doubles/stub_renderable_list_compositor.h"
192 #include "mir/test/doubles/stub_swapping_gl_context.h"
193@@ -84,7 +85,7 @@
194 group.post();
195 }
196
197-//lp: 1474891: If the driver is processing the external display in set,
198+//lp: 1474891, 1498550: If the driver is processing the external display in set,
199 //and it gets a hotplug event removing the external display, set() will throw, which we should ignore
200 TEST(DisplayGroup, group_ignores_throws_during_hotplug)
201 {
202@@ -92,17 +93,9 @@
203 NiceMock<mtd::MockDisplayDevice> mock_device;
204 mga::DisplayGroup group(mt::fake_shared(mock_device), std::make_unique<StubConfigurableDB>());
205 EXPECT_CALL(mock_device, commit(_))
206- .WillOnce(Throw(std::runtime_error("")))
207- .WillOnce(InvokeWithoutArgs([&]{
208- group.hotplug_occurred();
209- throw std::runtime_error("");
210- }))
211+ .WillOnce(Throw(mga::DisplayDisconnectedException()))
212 .WillOnce(Throw(std::runtime_error("")));
213
214- EXPECT_THROW({
215- group.post();
216- }, std::runtime_error);
217-
218 EXPECT_NO_THROW({group.post();});
219
220 EXPECT_THROW({

Subscribers

People subscribed via source and target branches