Mir

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

Proposed by Kevin DuBois
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 1837
Proposed branch: lp:~kdub/mir/fix-1352883
Merge into: lp:mir
Diff against target: 256 lines (+210/-3)
3 files modified
src/platform/graphics/android/hwc_device.cpp (+19/-3)
src/platform/graphics/android/hwc_device.h (+1/-0)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+190/-0)
To merge this branch: bzr merge lp:~kdub/mir/fix-1352883
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Daniel van Vugt Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+229804@code.launchpad.net

Commit message

android: fix intermittent problem that happens during certain list rearrangements. Scan the list of onscreen buffers in HwcDevice instead of trying to have the list helper classes figure out the onscreen buffers.
(LP: #1352883)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Tested on N4, seems to work. I'm not familiar with the affected Android code though.

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

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platform/graphics/android/hwc_device.cpp'
2--- src/platform/graphics/android/hwc_device.cpp 2014-08-01 09:14:20 +0000
3+++ src/platform/graphics/android/hwc_device.cpp 2014-08-06 14:48:05 +0000
4@@ -26,6 +26,7 @@
5 #include "buffer.h"
6 #include "hwc_fallback_gl_renderer.h"
7 #include <limits>
8+#include <algorithm>
9
10 namespace mg = mir::graphics;
11 namespace mga=mir::graphics::android;
12@@ -74,6 +75,19 @@
13 {
14 }
15
16+bool mga::HwcDevice::buffer_is_onscreen(mg::Buffer const& buffer) const
17+{
18+ /* check the handles, as the buffer ptrs might change between sets */
19+ auto const handle = buffer.native_buffer_handle().get();
20+ auto it = std::find_if(
21+ onscreen_overlay_buffers.begin(), onscreen_overlay_buffers.end(),
22+ [&handle](std::shared_ptr<mg::Buffer> const& b)
23+ {
24+ return (handle == b->native_buffer_handle().get());
25+ });
26+ return it != onscreen_overlay_buffers.end();
27+}
28+
29 void mga::HwcDevice::post_gl(SwappingGLContext const& context)
30 {
31 auto lg = lock_unblanked();
32@@ -142,9 +156,11 @@
33 }
34 else
35 {
36- if (it->needs_commit)
37- it->layer.set_acquirefence_from(*renderable->buffer());
38- next_onscreen_overlay_buffers.push_back(renderable->buffer());
39+ auto buffer = renderable->buffer();
40+ if (!buffer_is_onscreen(*buffer))
41+ it->layer.set_acquirefence_from(*buffer);
42+
43+ next_onscreen_overlay_buffers.push_back(buffer);
44 }
45 it++;
46 }
47
48=== modified file 'src/platform/graphics/android/hwc_device.h'
49--- src/platform/graphics/android/hwc_device.h 2014-08-01 09:14:20 +0000
50+++ src/platform/graphics/android/hwc_device.h 2014-08-06 14:48:05 +0000
51@@ -52,6 +52,7 @@
52 RenderableListCompositor const& list_compositor);
53
54 private:
55+ bool buffer_is_onscreen(Buffer const&) const;
56 void turned_screen_off() override;
57 LayerList hwc_list;
58 std::vector<std::shared_ptr<Buffer>> onscreen_overlay_buffers;
59
60=== modified file 'tests/unit-tests/graphics/android/test_hwc_device.cpp'
61--- tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-08-01 09:14:20 +0000
62+++ tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-08-06 14:48:05 +0000
63@@ -583,3 +583,193 @@
64 device.mode(MirPowerMode::mir_power_mode_off);
65 EXPECT_THAT(stub_buffer1.use_count(), Eq(use_count_before));
66 }
67+
68+TEST_F(HwcDevice, tracks_hwc_owned_fences_even_across_list_changes)
69+{
70+ using namespace testing;
71+ hwc_layer_1_t layer3;
72+ fill_hwc_layer(layer2, &comp_rect, position1, *stub_buffer1, HWC_FRAMEBUFFER, 0);
73+ fill_hwc_layer(layer3, &comp2_rect, position2, *stub_buffer2, HWC_FRAMEBUFFER, 0);
74+
75+ int acquire_fence1 = 39303;
76+ int acquire_fence2 = 393044;
77+ int release_fence1 = 39304;
78+ int release_fence2 = 123;
79+ int release_fence3 = 136;
80+ mg::RenderableList renderlist1{
81+ stub_renderable1
82+ };
83+ mg::RenderableList renderlist2{
84+ stub_renderable1,
85+ stub_renderable2
86+ };
87+
88+ layer.acquireFenceFd = acquire_fence1;
89+ layer.compositionType = HWC_OVERLAY;
90+ std::list<hwc_layer_1_t*> expected_list1
91+ {
92+ &layer,
93+ &target_layer
94+ };
95+ auto set_fences = [&](hwc_display_contents_1_t& contents)
96+ {
97+ ASSERT_EQ(contents.numHwLayers, 2);
98+ contents.hwLayers[0].releaseFenceFd = release_fence1;
99+ contents.retireFenceFd = -1;
100+ };
101+ auto set_fences2 = [&](hwc_display_contents_1_t& contents)
102+ {
103+ ASSERT_EQ(contents.numHwLayers, 3);
104+ contents.hwLayers[0].releaseFenceFd = release_fence2;
105+ contents.hwLayers[1].releaseFenceFd = release_fence3;
106+ contents.retireFenceFd = -1;
107+ };
108+
109+ layer2.acquireFenceFd = -1;
110+ layer2.compositionType = HWC_OVERLAY;
111+ layer3.acquireFenceFd = acquire_fence2;
112+ layer3.compositionType = HWC_OVERLAY;
113+ std::list<hwc_layer_1_t*> expected_list2
114+ {
115+ &layer2,
116+ &layer3,
117+ &target_layer
118+ };
119+
120+ Sequence seq;
121+ // first post
122+ EXPECT_CALL(*mock_device, prepare(_))
123+ .InSequence(seq)
124+ .WillOnce(Invoke(set_all_layers_to_overlay));
125+ EXPECT_CALL(*mock_native_buffer1, copy_fence())
126+ .InSequence(seq)
127+ .WillOnce(Return(acquire_fence1));
128+ EXPECT_CALL(*mock_device, set(MatchesList(expected_list1)))
129+ .InSequence(seq)
130+ .WillOnce(Invoke(set_fences));
131+ EXPECT_CALL(*mock_native_buffer1, update_usage(release_fence1, mga::BufferAccess::read))
132+ .InSequence(seq);
133+
134+ //end first post, second post
135+ EXPECT_CALL(*mock_device, prepare(_))
136+ .InSequence(seq)
137+ .WillOnce(Invoke(set_all_layers_to_overlay));
138+ //note that only the 2nd buffer should have its fence copied
139+ EXPECT_CALL(*mock_native_buffer2, copy_fence())
140+ .InSequence(seq)
141+ .WillOnce(Return(acquire_fence2));
142+ EXPECT_CALL(*mock_device, set(MatchesList(expected_list2)))
143+ .InSequence(seq)
144+ .WillOnce(Invoke(set_fences2));
145+ EXPECT_CALL(*mock_native_buffer1, update_usage(release_fence2, mga::BufferAccess::read))
146+ .InSequence(seq);
147+ EXPECT_CALL(*mock_native_buffer2, update_usage(release_fence3, mga::BufferAccess::read))
148+ .InSequence(seq);
149+ //end second post
150+
151+ mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
152+ EXPECT_TRUE(device.post_overlays(stub_context, renderlist1, stub_compositor));
153+
154+ EXPECT_TRUE(device.post_overlays(stub_context, renderlist2, stub_compositor));
155+}
156+
157+TEST_F(HwcDevice, tracks_hwc_owned_fences_across_list_rearrange)
158+{
159+ using namespace testing;
160+ hwc_layer_1_t layer3;
161+ hwc_layer_1_t layer4;
162+ fill_hwc_layer(layer3, &comp2_rect, position2, *stub_buffer2, HWC_FRAMEBUFFER, 0);
163+ fill_hwc_layer(layer4, &comp_rect, position1, *stub_buffer1, HWC_FRAMEBUFFER, 0);
164+
165+ int acquire_fence1 = 39303;
166+ int acquire_fence2 = 393044;
167+ int release_fence1 = 39304;
168+ int release_fence2 = 123;
169+ int release_fence3 = 136;
170+ int release_fence4 = 1344;
171+ mg::RenderableList renderlist{
172+ stub_renderable1,
173+ stub_renderable2
174+ };
175+
176+ //the renderable ptr or the buffer ptr could change, while still referencing the same buffer_handle_t
177+ mg::RenderableList renderlist2{
178+ std::make_shared<mtd::StubRenderable>(
179+ std::make_shared<mtd::StubBuffer>(mock_native_buffer2, size2), position2),
180+ std::make_shared<mtd::StubRenderable>(
181+ std::make_shared<mtd::StubBuffer>(mock_native_buffer1, size1), position1),
182+ };
183+
184+ layer.acquireFenceFd = acquire_fence1;
185+ layer.compositionType = HWC_OVERLAY;
186+ layer2.acquireFenceFd = acquire_fence2;
187+ layer2.compositionType = HWC_OVERLAY;
188+ std::list<hwc_layer_1_t*> expected_list1
189+ {
190+ &layer,
191+ &layer2,
192+ &target_layer
193+ };
194+ auto set_fences = [&](hwc_display_contents_1_t& contents)
195+ {
196+ ASSERT_EQ(contents.numHwLayers, 3);
197+ contents.hwLayers[0].releaseFenceFd = release_fence1;
198+ contents.hwLayers[1].releaseFenceFd = release_fence2;
199+ contents.retireFenceFd = -1;
200+ };
201+ auto set_fences2 = [&](hwc_display_contents_1_t& contents)
202+ {
203+ ASSERT_EQ(contents.numHwLayers, 3);
204+ contents.hwLayers[0].releaseFenceFd = release_fence3;
205+ contents.hwLayers[1].releaseFenceFd = release_fence4;
206+ contents.retireFenceFd = -1;
207+ };
208+
209+ layer3.acquireFenceFd = -1;
210+ layer3.compositionType = HWC_OVERLAY;
211+ layer4.acquireFenceFd = -1;
212+ layer4.compositionType = HWC_OVERLAY;
213+ std::list<hwc_layer_1_t*> expected_list2
214+ {
215+ &layer3,
216+ &layer4,
217+ &target_layer
218+ };
219+
220+ Sequence seq;
221+ // first post
222+ EXPECT_CALL(*mock_device, prepare(_))
223+ .InSequence(seq)
224+ .WillOnce(Invoke(set_all_layers_to_overlay));
225+ EXPECT_CALL(*mock_native_buffer1, copy_fence())
226+ .InSequence(seq)
227+ .WillOnce(Return(acquire_fence1));
228+ EXPECT_CALL(*mock_native_buffer2, copy_fence())
229+ .InSequence(seq)
230+ .WillOnce(Return(acquire_fence2));
231+ EXPECT_CALL(*mock_device, set(MatchesList(expected_list1)))
232+ .InSequence(seq)
233+ .WillOnce(Invoke(set_fences));
234+ EXPECT_CALL(*mock_native_buffer1, update_usage(release_fence1, mga::BufferAccess::read))
235+ .InSequence(seq);
236+ EXPECT_CALL(*mock_native_buffer2, update_usage(release_fence2, mga::BufferAccess::read))
237+ .InSequence(seq);
238+
239+ //end first post, second post
240+ EXPECT_CALL(*mock_device, prepare(_))
241+ .InSequence(seq)
242+ .WillOnce(Invoke(set_all_layers_to_overlay));
243+ //note that the buffers just flipped position, no acquire fence copying.
244+ EXPECT_CALL(*mock_device, set(MatchesList(expected_list2)))
245+ .InSequence(seq)
246+ .WillOnce(Invoke(set_fences2));
247+ EXPECT_CALL(*mock_native_buffer2, update_usage(release_fence3, mga::BufferAccess::read))
248+ .InSequence(seq);
249+ EXPECT_CALL(*mock_native_buffer1, update_usage(release_fence4, mga::BufferAccess::read))
250+ .InSequence(seq);
251+ //end second post
252+
253+ mga::HwcDevice device(mock_device, mock_vsync, mock_file_ops);
254+ EXPECT_TRUE(device.post_overlays(stub_context, renderlist, stub_compositor));
255+ EXPECT_TRUE(device.post_overlays(stub_context, renderlist2, stub_compositor));
256+}

Subscribers

People subscribed via source and target branches