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
=== modified file 'src/platforms/android/server/device_quirks.cpp'
--- src/platforms/android/server/device_quirks.cpp 2015-11-25 12:59:13 +0000
+++ src/platforms/android/server/device_quirks.cpp 2015-11-30 18:34:59 +0000
@@ -49,7 +49,7 @@
4949
50unsigned int num_framebuffers_for(std::string const& device_name, bool quirk_enabled)50unsigned int num_framebuffers_for(std::string const& device_name, bool quirk_enabled)
51{51{
52 if (quirk_enabled && device_name == std::string{"mx3"})52 if (quirk_enabled && device_name == "mx3")
53 return 3;53 return 3;
54 else54 else
55 return 2;55 return 2;
@@ -57,15 +57,22 @@
5757
58bool gralloc_cannot_be_closed_safely_for(std::string const& device_name, bool quirk_enabled)58bool gralloc_cannot_be_closed_safely_for(std::string const& device_name, bool quirk_enabled)
59{59{
60 return quirk_enabled && device_name == std::string{"krillin"};60 return quirk_enabled && device_name == "krillin";
61}61}
62
63bool clear_fb_context_fence_for(std::string const& device_name)
64{
65 return device_name == "krillin" || device_name == "mx4" || device_name == "manta";
66}
67
62}68}
6369
64mga::DeviceQuirks::DeviceQuirks(PropertiesWrapper const& properties)70mga::DeviceQuirks::DeviceQuirks(PropertiesWrapper const& properties)
65 : device_name(determine_device_name(properties)),71 : device_name(determine_device_name(properties)),
66 num_framebuffers_(num_framebuffers_for(device_name, true)),72 num_framebuffers_(num_framebuffers_for(device_name, true)),
67 gralloc_cannot_be_closed_safely_(gralloc_cannot_be_closed_safely_for(device_name, true)),73 gralloc_cannot_be_closed_safely_(gralloc_cannot_be_closed_safely_for(device_name, true)),
68 enable_width_alignment_quirk{true}74 enable_width_alignment_quirk{true},
75 clear_fb_context_fence_{clear_fb_context_fence_for(device_name)}
69{76{
70}77}
7178
@@ -73,7 +80,8 @@
73 : device_name(determine_device_name(properties)),80 : device_name(determine_device_name(properties)),
74 num_framebuffers_(num_framebuffers_for(device_name, options.get(num_framebuffers_opt, true))),81 num_framebuffers_(num_framebuffers_for(device_name, options.get(num_framebuffers_opt, true))),
75 gralloc_cannot_be_closed_safely_(gralloc_cannot_be_closed_safely_for(device_name, options.get(gralloc_cannot_be_closed_safely_opt, true))),82 gralloc_cannot_be_closed_safely_(gralloc_cannot_be_closed_safely_for(device_name, options.get(gralloc_cannot_be_closed_safely_opt, true))),
76 enable_width_alignment_quirk(options.get(width_alignment_opt, true))83 enable_width_alignment_quirk(options.get(width_alignment_opt, true)),
84 clear_fb_context_fence_{clear_fb_context_fence_for(device_name)}
77{85{
78}86}
7987
@@ -89,11 +97,16 @@
8997
90int mga::DeviceQuirks::aligned_width(int width) const98int mga::DeviceQuirks::aligned_width(int width) const
91{99{
92 if (enable_width_alignment_quirk && width == 720 && device_name == std::string{"vegetahd"})100 if (enable_width_alignment_quirk && width == 720 && device_name == "vegetahd")
93 return 736;101 return 736;
94 return width;102 return width;
95}103}
96104
105bool mga::DeviceQuirks::clear_fb_context_fence() const
106{
107 return clear_fb_context_fence_;
108}
109
97void mga::DeviceQuirks::add_options(boost::program_options::options_description& config)110void mga::DeviceQuirks::add_options(boost::program_options::options_description& config)
98{111{
99 config.add_options()112 config.add_options()
100113
=== modified file 'src/platforms/android/server/device_quirks.h'
--- src/platforms/android/server/device_quirks.h 2015-11-25 12:59:13 +0000
+++ src/platforms/android/server/device_quirks.h 2015-11-30 18:34:59 +0000
@@ -63,6 +63,7 @@
63 unsigned int num_framebuffers() const;63 unsigned int num_framebuffers() const;
64 bool gralloc_cannot_be_closed_safely() const;64 bool gralloc_cannot_be_closed_safely() const;
65 int aligned_width(int width) const;65 int aligned_width(int width) const;
66 bool clear_fb_context_fence() const;
6667
67 static void add_options(boost::program_options::options_description& config);68 static void add_options(boost::program_options::options_description& config);
6869
@@ -73,6 +74,7 @@
73 unsigned int const num_framebuffers_;74 unsigned int const num_framebuffers_;
74 bool const gralloc_cannot_be_closed_safely_;75 bool const gralloc_cannot_be_closed_safely_;
75 bool const enable_width_alignment_quirk;76 bool const enable_width_alignment_quirk;
77 bool const clear_fb_context_fence_;
76};78};
77}79}
78}80}
7981
=== modified file 'src/platforms/android/server/display.cpp'
--- src/platforms/android/server/display.cpp 2015-11-16 10:52:06 +0000
+++ src/platforms/android/server/display.cpp 2015-11-30 18:34:59 +0000
@@ -119,7 +119,8 @@
119{119{
120 std::shared_ptr<mga::FramebufferBundle> fbs{display_buffer_builder.create_framebuffers(config)};120 std::shared_ptr<mga::FramebufferBundle> fbs{display_buffer_builder.create_framebuffers(config)};
121 auto cache = std::make_shared<mga::InterpreterCache>();121 auto cache = std::make_shared<mga::InterpreterCache>();
122 auto interpreter = std::make_shared<mga::ServerRenderWindow>(fbs, config.current_format, cache);122 mga::DeviceQuirks quirks(mga::PropertiesOps{});
123 auto interpreter = std::make_shared<mga::ServerRenderWindow>(fbs, config.current_format, cache, quirks);
123 auto native_window = std::make_shared<mga::MirNativeWindow>(interpreter);124 auto native_window = std::make_shared<mga::MirNativeWindow>(interpreter);
124 return std::unique_ptr<mga::ConfigurableDisplayBuffer>(new mga::DisplayBuffer(125 return std::unique_ptr<mga::ConfigurableDisplayBuffer>(new mga::DisplayBuffer(
125 name,126 name,
126127
=== modified file 'src/platforms/android/server/server_render_window.cpp'
--- src/platforms/android/server/server_render_window.cpp 2015-09-04 02:42:45 +0000
+++ src/platforms/android/server/server_render_window.cpp 2015-11-30 18:34:59 +0000
@@ -37,10 +37,12 @@
37mga::ServerRenderWindow::ServerRenderWindow(37mga::ServerRenderWindow::ServerRenderWindow(
38 std::shared_ptr<mga::FramebufferBundle> const& fb_bundle,38 std::shared_ptr<mga::FramebufferBundle> const& fb_bundle,
39 MirPixelFormat format,39 MirPixelFormat format,
40 std::shared_ptr<InterpreterResourceCache> const& cache)40 std::shared_ptr<InterpreterResourceCache> const& cache,
41 DeviceQuirks& quirks)
41 : fb_bundle(fb_bundle),42 : fb_bundle(fb_bundle),
42 resource_cache(cache),43 resource_cache(cache),
43 format(mga::to_android_format(format))44 format(mga::to_android_format(format)),
45 clear_fence(quirks.clear_fb_context_fence())
44{46{
45}47}
4648
@@ -54,7 +56,13 @@
5456
55void mga::ServerRenderWindow::driver_returns_buffer(ANativeWindowBuffer* buffer, int fence_fd)57void mga::ServerRenderWindow::driver_returns_buffer(ANativeWindowBuffer* buffer, int fence_fd)
56{58{
57 resource_cache->update_native_fence(buffer, fence_fd);59 //depending on the quirk, some mali drivers won't synchronize the fb context fence before posting.
60 //if this bug is present, we synchronize here to avoid tearing or other artifacts.
61 if (clear_fence)
62 mga::SyncFence(std::make_shared<RealSyncFileOps>(), mir::Fd(fence_fd)).wait();
63 else
64 resource_cache->update_native_fence(buffer, fence_fd);
65
58 resource_cache->retrieve_buffer(buffer);66 resource_cache->retrieve_buffer(buffer);
59}67}
6068
6169
=== modified file 'src/platforms/android/server/server_render_window.h'
--- src/platforms/android/server/server_render_window.h 2015-06-17 05:20:42 +0000
+++ src/platforms/android/server/server_render_window.h 2015-11-30 18:34:59 +0000
@@ -21,6 +21,7 @@
21#define MIR_GRAPHICS_ANDROID_SERVER_RENDER_WINDOW_H_21#define MIR_GRAPHICS_ANDROID_SERVER_RENDER_WINDOW_H_
2222
23#include "mir/graphics/android/android_driver_interpreter.h"23#include "mir/graphics/android/android_driver_interpreter.h"
24#include "device_quirks.h"
24#include "mir_toolkit/common.h"25#include "mir_toolkit/common.h"
2526
26#include <memory>27#include <memory>
@@ -39,7 +40,8 @@
39public:40public:
40 ServerRenderWindow(std::shared_ptr<FramebufferBundle> const& fb_bundle,41 ServerRenderWindow(std::shared_ptr<FramebufferBundle> const& fb_bundle,
41 MirPixelFormat format,42 MirPixelFormat format,
42 std::shared_ptr<InterpreterResourceCache> const&);43 std::shared_ptr<InterpreterResourceCache> const&,
44 DeviceQuirks& quirks);
4345
44 graphics::NativeBuffer* driver_requests_buffer() override;46 graphics::NativeBuffer* driver_requests_buffer() override;
45 void driver_returns_buffer(ANativeWindowBuffer*, int fence_fd) override;47 void driver_returns_buffer(ANativeWindowBuffer*, int fence_fd) override;
@@ -52,6 +54,7 @@
52 std::shared_ptr<FramebufferBundle> const fb_bundle;54 std::shared_ptr<FramebufferBundle> const fb_bundle;
53 std::shared_ptr<InterpreterResourceCache> const resource_cache;55 std::shared_ptr<InterpreterResourceCache> const resource_cache;
54 int format;56 int format;
57 bool const clear_fence;
55};58};
5659
57}60}
5861
=== modified file 'tests/unit-tests/graphics/android/test_device_detection.cpp'
--- tests/unit-tests/graphics/android/test_device_detection.cpp 2015-11-25 12:59:13 +0000
+++ tests/unit-tests/graphics/android/test_device_detection.cpp 2015-11-30 18:34:59 +0000
@@ -132,6 +132,82 @@
132 EXPECT_THAT(quirks.aligned_width(720), Eq(736));132 EXPECT_THAT(quirks.aligned_width(720), Eq(736));
133}133}
134134
135TEST(DeviceDetection, clears_gl_context_fence_on_manta)
136{
137 using namespace testing;
138 char const default_str[] = "";
139 char const mx4_name_str[] = "manta";
140
141 MockOps mock_ops;
142 EXPECT_CALL(mock_ops, property_get(StrEq("ro.product.device"), _, StrEq(default_str)))
143 .Times(1)
144 .WillOnce(Invoke([&](char const*, char* value, char const*)
145 {
146 strncpy(value, mx4_name_str, PROP_VALUE_MAX);
147 return 0;
148 }));
149
150 mga::DeviceQuirks quirks(mock_ops);
151 EXPECT_TRUE(quirks.clear_fb_context_fence());
152}
153
154TEST(DeviceDetection, clears_gl_context_fence_on_mx4)
155{
156 using namespace testing;
157 char const default_str[] = "";
158 char const mx4_name_str[] = "mx4";
159
160 MockOps mock_ops;
161 EXPECT_CALL(mock_ops, property_get(StrEq("ro.product.device"), _, StrEq(default_str)))
162 .Times(1)
163 .WillOnce(Invoke([&](char const*, char* value, char const*)
164 {
165 strncpy(value, mx4_name_str, PROP_VALUE_MAX);
166 return 0;
167 }));
168
169 mga::DeviceQuirks quirks(mock_ops);
170 EXPECT_TRUE(quirks.clear_fb_context_fence());
171}
172
173TEST(DeviceDetection, clears_gl_context_fence_on_krillin)
174{
175 using namespace testing;
176 char const default_str[] = "";
177 char const krillin_name_str[] = "krillin";
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, krillin_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
192TEST(DeviceDetection, does_not_clear_gl_context_fence_on_others)
193{
194 using namespace testing;
195 char const default_str[] = "";
196 char const mx4_name_str[] = "others";
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_FALSE(quirks.clear_fb_context_fence());
209}
210
135struct DeviceQuirks : testing::Test211struct DeviceQuirks : testing::Test
136{212{
137 void SetUp()213 void SetUp()
138214
=== modified file 'tests/unit-tests/graphics/android/test_server_interpreter.cpp'
--- tests/unit-tests/graphics/android/test_server_interpreter.cpp 2015-09-04 02:42:45 +0000
+++ tests/unit-tests/graphics/android/test_server_interpreter.cpp 2015-11-30 18:34:59 +0000
@@ -39,6 +39,26 @@
3939
40namespace40namespace
41{41{
42//krillin and mx4 need to clear their fences before hwc commit.
43struct StubPropertiesWrapper : mga::PropertiesWrapper
44{
45 StubPropertiesWrapper(bool should_clear_fence) :
46 name(should_clear_fence ? "mx4" : "otherdevice")
47 {
48 }
49
50 int property_get(char const* key, char* value, char const* default_value) const override
51 {
52 if (strncmp(key, "ro.product.device", PROP_VALUE_MAX) == 0)
53 strncpy(value, name.c_str(), name.size());
54 else
55 strncpy(value, default_value, PROP_VALUE_MAX);
56 return 0;
57 }
58
59 std::string name;
60};
61
42struct ServerRenderWindow : public ::testing::Test62struct ServerRenderWindow : public ::testing::Test
43{63{
44 std::shared_ptr<mtd::MockBuffer> mock_buffer{std::make_shared<testing::NiceMock<mtd::MockBuffer>>()};64 std::shared_ptr<mtd::MockBuffer> mock_buffer{std::make_shared<testing::NiceMock<mtd::MockBuffer>>()};
@@ -47,7 +67,9 @@
47 std::shared_ptr<mtd::MockFBBundle> mock_fb_bundle{67 std::shared_ptr<mtd::MockFBBundle> mock_fb_bundle{
48 std::make_shared<testing::NiceMock<mtd::MockFBBundle>>()};68 std::make_shared<testing::NiceMock<mtd::MockFBBundle>>()};
49 MirPixelFormat format{mir_pixel_format_abgr_8888};69 MirPixelFormat format{mir_pixel_format_abgr_8888};
50 mga::ServerRenderWindow render_window{mock_fb_bundle, format, mock_cache};70 StubPropertiesWrapper wrapper{false};
71 mga::DeviceQuirks quirks{wrapper};
72 mga::ServerRenderWindow render_window{mock_fb_bundle, format, mock_cache, quirks};
51};73};
52}74}
5375
@@ -92,6 +114,34 @@
92 Mock::VerifyAndClearExpectations(mock_fb_bundle.get());114 Mock::VerifyAndClearExpectations(mock_fb_bundle.get());
93}115}
94116
117TEST_F(ServerRenderWindow, clears_fence_when_quirk_present)
118{
119 using namespace testing;
120 StubPropertiesWrapper wrapper{true};
121 mga::DeviceQuirks quirks{wrapper};
122 mga::ServerRenderWindow render_window{mock_fb_bundle, format, mock_cache, quirks};
123
124 int fake_fence = 488;
125 auto stub_buffer = std::make_shared<mtd::StubAndroidNativeBuffer>();
126
127 EXPECT_CALL(*mock_fb_bundle, buffer_for_render())
128 .WillOnce(Return(mock_buffer));
129 EXPECT_CALL(*mock_buffer, native_buffer_handle())
130 .WillOnce(Return(stub_buffer));
131
132 render_window.driver_requests_buffer();
133 Mock::VerifyAndClearExpectations(mock_fb_bundle.get());
134
135 std::shared_ptr<mg::Buffer> buf1 = mock_buffer;
136 EXPECT_CALL(*mock_cache, update_native_fence(stub_buffer->anwb(), fake_fence))
137 .Times(0);
138 EXPECT_CALL(*mock_cache, retrieve_buffer(stub_buffer->anwb()))
139 .WillOnce(Return(mock_buffer));
140
141 render_window.driver_returns_buffer(stub_buffer->anwb(), fake_fence);
142 Mock::VerifyAndClearExpectations(mock_fb_bundle.get());
143}
144
95TEST_F(ServerRenderWindow, returns_format)145TEST_F(ServerRenderWindow, returns_format)
96{146{
97 EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, render_window.driver_requests_info(NATIVE_WINDOW_FORMAT));147 EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, render_window.driver_requests_info(NATIVE_WINDOW_FORMAT));

Subscribers

People subscribed via source and target branches