Mir

Merge lp:~kdub/mir/fix-1270245 into lp:mir

Proposed by Kevin DuBois
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 3150
Proposed branch: lp:~kdub/mir/fix-1270245
Merge into: lp:mir
Diff against target: 328 lines (+165/-12)
7 files modified
src/platforms/android/server/device_quirks.cpp (+19/-6)
src/platforms/android/server/device_quirks.h (+2/-0)
src/platforms/android/server/display.cpp (+2/-1)
src/platforms/android/server/server_render_window.cpp (+11/-3)
src/platforms/android/server/server_render_window.h (+4/-1)
tests/unit-tests/graphics/android/test_device_detection.cpp (+76/-0)
tests/unit-tests/graphics/android/test_server_interpreter.cpp (+51/-1)
To merge this branch: bzr merge lp:~kdub/mir/fix-1270245
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Andreas Pokorny (community) Approve
Alan Griffiths Abstain
Alexandros Frantzis (community) Approve
Review via email: mp+278489@code.launchpad.net

Commit message

android: explicitly wait for the synchronization fence before the framebuffer EGL context is posted in hwc::set() for some mali-based devices.

fixes: lp: #1270245

Description of the change

android: explicitly wait for the synchronization fence before the framebuffer EGL context is posted in hwc::set() for some mali-based devices.

note: this branch, in tandem with https://code.launchpad.net/~kdub/mir/egl-sync-fences/+merge/278181 should fix the software corruption on the mali devices. Running this should fix the egltriangle skipping back, but you could still see corruption from lp: #1517205 with this branch.

fixes: lp: #1270245

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
Alexandros Frantzis (afrantzis) wrote :

I am not able to reproduce the original bug locally to check if the fix works properly, but the code looks sensible.

+ if (clear_fence)
+ mga::SyncFence(std::make_shared<RealSyncFileOps>(), mir::Fd(fence_fd)).wait();

Since RealSyncFileOps is a stateless object we could instantiate it once as a member variable and reuse it to avoid unnecessary memory allocation on every frame. Of course there is still mir::Fd and probably many other objects we are allocating dynamically on every frame, but let's cut where we can.

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

why mx4? Shouldnt that be nexus10? Or is that problem not related to the gpu but the display controller itself?

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

+ return device_name == std::string{"krillin"} || device_name == std::string{"mx4"};

I know there's existing code in this style, but it seem unnecessary to construct temporary string objects for these constants. As std::string has an operator==(std::string const&, const CharT*) the same test can be written more efficiently:

    return device_name == "krillin" || device_name == "mx4";

review: Abstain
Revision history for this message
Kevin DuBois (kdub) wrote :

@N10, This device isn't supported anymore by mir, and I haven't verified that this fix works for the device. It might be better to detect the device class eventually (eg, mali) and autodetect the workaround based on that.

Other issues fixed.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Confused - I tried your branch ..

1) without a || device_name == "manta" :
 corruption in mir_demo_client_flicker
 strange inconsistent updates in fingerpaint .. always somwehere on the right side of the buffer
 no jumps or flickering in egltriangle
2) with an additional || device_name "manta"
 no corruption in mir_demo_client_flicker
 no update problems in fingerpaint!
 no jumps or flickering in egltriangle

It seems to fix lp:1517205

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> @N10, This device isn't supported anymore by mir, and I haven't verified that
> this fix works for the device. It might be better to detect the device class
> eventually (eg, mali) and autodetect the workaround based on that.
>
> Other issues fixed.

can we add manta here? But the problem is not limited to mali since mx4 has the quirk?

Revision history for this message
Kevin DuBois (kdub) wrote :

@Andreas, thanks for verifying, will add the n10 as well

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

thx!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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
1=== modified file 'src/platforms/android/server/device_quirks.cpp'
2--- src/platforms/android/server/device_quirks.cpp 2015-11-25 12:59:13 +0000
3+++ src/platforms/android/server/device_quirks.cpp 2015-11-30 18:34:59 +0000
4@@ -49,7 +49,7 @@
5
6 unsigned int num_framebuffers_for(std::string const& device_name, bool quirk_enabled)
7 {
8- if (quirk_enabled && device_name == std::string{"mx3"})
9+ if (quirk_enabled && device_name == "mx3")
10 return 3;
11 else
12 return 2;
13@@ -57,15 +57,22 @@
14
15 bool gralloc_cannot_be_closed_safely_for(std::string const& device_name, bool quirk_enabled)
16 {
17- return quirk_enabled && device_name == std::string{"krillin"};
18-}
19+ return quirk_enabled && device_name == "krillin";
20+}
21+
22+bool clear_fb_context_fence_for(std::string const& device_name)
23+{
24+ return device_name == "krillin" || device_name == "mx4" || device_name == "manta";
25+}
26+
27 }
28
29 mga::DeviceQuirks::DeviceQuirks(PropertiesWrapper const& properties)
30 : device_name(determine_device_name(properties)),
31 num_framebuffers_(num_framebuffers_for(device_name, true)),
32 gralloc_cannot_be_closed_safely_(gralloc_cannot_be_closed_safely_for(device_name, true)),
33- enable_width_alignment_quirk{true}
34+ enable_width_alignment_quirk{true},
35+ clear_fb_context_fence_{clear_fb_context_fence_for(device_name)}
36 {
37 }
38
39@@ -73,7 +80,8 @@
40 : device_name(determine_device_name(properties)),
41 num_framebuffers_(num_framebuffers_for(device_name, options.get(num_framebuffers_opt, true))),
42 gralloc_cannot_be_closed_safely_(gralloc_cannot_be_closed_safely_for(device_name, options.get(gralloc_cannot_be_closed_safely_opt, true))),
43- enable_width_alignment_quirk(options.get(width_alignment_opt, true))
44+ enable_width_alignment_quirk(options.get(width_alignment_opt, true)),
45+ clear_fb_context_fence_{clear_fb_context_fence_for(device_name)}
46 {
47 }
48
49@@ -89,11 +97,16 @@
50
51 int mga::DeviceQuirks::aligned_width(int width) const
52 {
53- if (enable_width_alignment_quirk && width == 720 && device_name == std::string{"vegetahd"})
54+ if (enable_width_alignment_quirk && width == 720 && device_name == "vegetahd")
55 return 736;
56 return width;
57 }
58
59+bool mga::DeviceQuirks::clear_fb_context_fence() const
60+{
61+ return clear_fb_context_fence_;
62+}
63+
64 void mga::DeviceQuirks::add_options(boost::program_options::options_description& config)
65 {
66 config.add_options()
67
68=== modified file 'src/platforms/android/server/device_quirks.h'
69--- src/platforms/android/server/device_quirks.h 2015-11-25 12:59:13 +0000
70+++ src/platforms/android/server/device_quirks.h 2015-11-30 18:34:59 +0000
71@@ -63,6 +63,7 @@
72 unsigned int num_framebuffers() const;
73 bool gralloc_cannot_be_closed_safely() const;
74 int aligned_width(int width) const;
75+ bool clear_fb_context_fence() const;
76
77 static void add_options(boost::program_options::options_description& config);
78
79@@ -73,6 +74,7 @@
80 unsigned int const num_framebuffers_;
81 bool const gralloc_cannot_be_closed_safely_;
82 bool const enable_width_alignment_quirk;
83+ bool const clear_fb_context_fence_;
84 };
85 }
86 }
87
88=== modified file 'src/platforms/android/server/display.cpp'
89--- src/platforms/android/server/display.cpp 2015-11-16 10:52:06 +0000
90+++ src/platforms/android/server/display.cpp 2015-11-30 18:34:59 +0000
91@@ -119,7 +119,8 @@
92 {
93 std::shared_ptr<mga::FramebufferBundle> fbs{display_buffer_builder.create_framebuffers(config)};
94 auto cache = std::make_shared<mga::InterpreterCache>();
95- auto interpreter = std::make_shared<mga::ServerRenderWindow>(fbs, config.current_format, cache);
96+ mga::DeviceQuirks quirks(mga::PropertiesOps{});
97+ auto interpreter = std::make_shared<mga::ServerRenderWindow>(fbs, config.current_format, cache, quirks);
98 auto native_window = std::make_shared<mga::MirNativeWindow>(interpreter);
99 return std::unique_ptr<mga::ConfigurableDisplayBuffer>(new mga::DisplayBuffer(
100 name,
101
102=== modified file 'src/platforms/android/server/server_render_window.cpp'
103--- src/platforms/android/server/server_render_window.cpp 2015-09-04 02:42:45 +0000
104+++ src/platforms/android/server/server_render_window.cpp 2015-11-30 18:34:59 +0000
105@@ -37,10 +37,12 @@
106 mga::ServerRenderWindow::ServerRenderWindow(
107 std::shared_ptr<mga::FramebufferBundle> const& fb_bundle,
108 MirPixelFormat format,
109- std::shared_ptr<InterpreterResourceCache> const& cache)
110+ std::shared_ptr<InterpreterResourceCache> const& cache,
111+ DeviceQuirks& quirks)
112 : fb_bundle(fb_bundle),
113 resource_cache(cache),
114- format(mga::to_android_format(format))
115+ format(mga::to_android_format(format)),
116+ clear_fence(quirks.clear_fb_context_fence())
117 {
118 }
119
120@@ -54,7 +56,13 @@
121
122 void mga::ServerRenderWindow::driver_returns_buffer(ANativeWindowBuffer* buffer, int fence_fd)
123 {
124- resource_cache->update_native_fence(buffer, fence_fd);
125+ //depending on the quirk, some mali drivers won't synchronize the fb context fence before posting.
126+ //if this bug is present, we synchronize here to avoid tearing or other artifacts.
127+ if (clear_fence)
128+ mga::SyncFence(std::make_shared<RealSyncFileOps>(), mir::Fd(fence_fd)).wait();
129+ else
130+ resource_cache->update_native_fence(buffer, fence_fd);
131+
132 resource_cache->retrieve_buffer(buffer);
133 }
134
135
136=== modified file 'src/platforms/android/server/server_render_window.h'
137--- src/platforms/android/server/server_render_window.h 2015-06-17 05:20:42 +0000
138+++ src/platforms/android/server/server_render_window.h 2015-11-30 18:34:59 +0000
139@@ -21,6 +21,7 @@
140 #define MIR_GRAPHICS_ANDROID_SERVER_RENDER_WINDOW_H_
141
142 #include "mir/graphics/android/android_driver_interpreter.h"
143+#include "device_quirks.h"
144 #include "mir_toolkit/common.h"
145
146 #include <memory>
147@@ -39,7 +40,8 @@
148 public:
149 ServerRenderWindow(std::shared_ptr<FramebufferBundle> const& fb_bundle,
150 MirPixelFormat format,
151- std::shared_ptr<InterpreterResourceCache> const&);
152+ std::shared_ptr<InterpreterResourceCache> const&,
153+ DeviceQuirks& quirks);
154
155 graphics::NativeBuffer* driver_requests_buffer() override;
156 void driver_returns_buffer(ANativeWindowBuffer*, int fence_fd) override;
157@@ -52,6 +54,7 @@
158 std::shared_ptr<FramebufferBundle> const fb_bundle;
159 std::shared_ptr<InterpreterResourceCache> const resource_cache;
160 int format;
161+ bool const clear_fence;
162 };
163
164 }
165
166=== modified file 'tests/unit-tests/graphics/android/test_device_detection.cpp'
167--- tests/unit-tests/graphics/android/test_device_detection.cpp 2015-11-25 12:59:13 +0000
168+++ tests/unit-tests/graphics/android/test_device_detection.cpp 2015-11-30 18:34:59 +0000
169@@ -132,6 +132,82 @@
170 EXPECT_THAT(quirks.aligned_width(720), Eq(736));
171 }
172
173+TEST(DeviceDetection, clears_gl_context_fence_on_manta)
174+{
175+ using namespace testing;
176+ char const default_str[] = "";
177+ char const mx4_name_str[] = "manta";
178+
179+ MockOps mock_ops;
180+ EXPECT_CALL(mock_ops, property_get(StrEq("ro.product.device"), _, StrEq(default_str)))
181+ .Times(1)
182+ .WillOnce(Invoke([&](char const*, char* value, char const*)
183+ {
184+ strncpy(value, mx4_name_str, PROP_VALUE_MAX);
185+ return 0;
186+ }));
187+
188+ mga::DeviceQuirks quirks(mock_ops);
189+ EXPECT_TRUE(quirks.clear_fb_context_fence());
190+}
191+
192+TEST(DeviceDetection, clears_gl_context_fence_on_mx4)
193+{
194+ using namespace testing;
195+ char const default_str[] = "";
196+ char const mx4_name_str[] = "mx4";
197+
198+ MockOps mock_ops;
199+ EXPECT_CALL(mock_ops, property_get(StrEq("ro.product.device"), _, StrEq(default_str)))
200+ .Times(1)
201+ .WillOnce(Invoke([&](char const*, char* value, char const*)
202+ {
203+ strncpy(value, mx4_name_str, PROP_VALUE_MAX);
204+ return 0;
205+ }));
206+
207+ mga::DeviceQuirks quirks(mock_ops);
208+ EXPECT_TRUE(quirks.clear_fb_context_fence());
209+}
210+
211+TEST(DeviceDetection, clears_gl_context_fence_on_krillin)
212+{
213+ using namespace testing;
214+ char const default_str[] = "";
215+ char const krillin_name_str[] = "krillin";
216+
217+ MockOps mock_ops;
218+ EXPECT_CALL(mock_ops, property_get(StrEq("ro.product.device"), _, StrEq(default_str)))
219+ .Times(1)
220+ .WillOnce(Invoke([&](char const*, char* value, char const*)
221+ {
222+ strncpy(value, krillin_name_str, PROP_VALUE_MAX);
223+ return 0;
224+ }));
225+
226+ mga::DeviceQuirks quirks(mock_ops);
227+ EXPECT_TRUE(quirks.clear_fb_context_fence());
228+}
229+
230+TEST(DeviceDetection, does_not_clear_gl_context_fence_on_others)
231+{
232+ using namespace testing;
233+ char const default_str[] = "";
234+ char const mx4_name_str[] = "others";
235+
236+ MockOps mock_ops;
237+ EXPECT_CALL(mock_ops, property_get(StrEq("ro.product.device"), _, StrEq(default_str)))
238+ .Times(1)
239+ .WillOnce(Invoke([&](char const*, char* value, char const*)
240+ {
241+ strncpy(value, mx4_name_str, PROP_VALUE_MAX);
242+ return 0;
243+ }));
244+
245+ mga::DeviceQuirks quirks(mock_ops);
246+ EXPECT_FALSE(quirks.clear_fb_context_fence());
247+}
248+
249 struct DeviceQuirks : testing::Test
250 {
251 void SetUp()
252
253=== modified file 'tests/unit-tests/graphics/android/test_server_interpreter.cpp'
254--- tests/unit-tests/graphics/android/test_server_interpreter.cpp 2015-09-04 02:42:45 +0000
255+++ tests/unit-tests/graphics/android/test_server_interpreter.cpp 2015-11-30 18:34:59 +0000
256@@ -39,6 +39,26 @@
257
258 namespace
259 {
260+//krillin and mx4 need to clear their fences before hwc commit.
261+struct StubPropertiesWrapper : mga::PropertiesWrapper
262+{
263+ StubPropertiesWrapper(bool should_clear_fence) :
264+ name(should_clear_fence ? "mx4" : "otherdevice")
265+ {
266+ }
267+
268+ int property_get(char const* key, char* value, char const* default_value) const override
269+ {
270+ if (strncmp(key, "ro.product.device", PROP_VALUE_MAX) == 0)
271+ strncpy(value, name.c_str(), name.size());
272+ else
273+ strncpy(value, default_value, PROP_VALUE_MAX);
274+ return 0;
275+ }
276+
277+ std::string name;
278+};
279+
280 struct ServerRenderWindow : public ::testing::Test
281 {
282 std::shared_ptr<mtd::MockBuffer> mock_buffer{std::make_shared<testing::NiceMock<mtd::MockBuffer>>()};
283@@ -47,7 +67,9 @@
284 std::shared_ptr<mtd::MockFBBundle> mock_fb_bundle{
285 std::make_shared<testing::NiceMock<mtd::MockFBBundle>>()};
286 MirPixelFormat format{mir_pixel_format_abgr_8888};
287- mga::ServerRenderWindow render_window{mock_fb_bundle, format, mock_cache};
288+ StubPropertiesWrapper wrapper{false};
289+ mga::DeviceQuirks quirks{wrapper};
290+ mga::ServerRenderWindow render_window{mock_fb_bundle, format, mock_cache, quirks};
291 };
292 }
293
294@@ -92,6 +114,34 @@
295 Mock::VerifyAndClearExpectations(mock_fb_bundle.get());
296 }
297
298+TEST_F(ServerRenderWindow, clears_fence_when_quirk_present)
299+{
300+ using namespace testing;
301+ StubPropertiesWrapper wrapper{true};
302+ mga::DeviceQuirks quirks{wrapper};
303+ mga::ServerRenderWindow render_window{mock_fb_bundle, format, mock_cache, quirks};
304+
305+ int fake_fence = 488;
306+ auto stub_buffer = std::make_shared<mtd::StubAndroidNativeBuffer>();
307+
308+ EXPECT_CALL(*mock_fb_bundle, buffer_for_render())
309+ .WillOnce(Return(mock_buffer));
310+ EXPECT_CALL(*mock_buffer, native_buffer_handle())
311+ .WillOnce(Return(stub_buffer));
312+
313+ render_window.driver_requests_buffer();
314+ Mock::VerifyAndClearExpectations(mock_fb_bundle.get());
315+
316+ std::shared_ptr<mg::Buffer> buf1 = mock_buffer;
317+ EXPECT_CALL(*mock_cache, update_native_fence(stub_buffer->anwb(), fake_fence))
318+ .Times(0);
319+ EXPECT_CALL(*mock_cache, retrieve_buffer(stub_buffer->anwb()))
320+ .WillOnce(Return(mock_buffer));
321+
322+ render_window.driver_returns_buffer(stub_buffer->anwb(), fake_fence);
323+ Mock::VerifyAndClearExpectations(mock_fb_bundle.get());
324+}
325+
326 TEST_F(ServerRenderWindow, returns_format)
327 {
328 EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, render_window.driver_requests_info(NATIVE_WINDOW_FORMAT));

Subscribers

People subscribed via source and target branches