Mir

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

Proposed by Kevin DuBois
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 2302
Proposed branch: lp:~kdub/mir/fix-1413211
Merge into: lp:mir
Diff against target: 88 lines (+29/-21)
3 files modified
src/server/graphics/software_cursor.cpp (+8/-20)
src/server/graphics/software_cursor.h (+1/-1)
tests/unit-tests/graphics/test_software_cursor.cpp (+20/-0)
To merge this branch: bzr merge lp:~kdub/mir/fix-1413211
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Daniel van Vugt Abstain
Alexandros Frantzis (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+248560@code.launchpad.net

Commit message

Ensure that mg::Buffer::write won't block when writing the SoftwareCursor by allocating a fresh buffer each time an update is needed.

fixes: LP: #1413211

Description of the change

Ensure that mg::Buffer::write won't block when writing the SoftwareCursor by allocating a fresh buffer each time an update is needed.

fixes: LP: #1413211

This seemed like the least obtrusive fix for this problem. Basically, the mg::Buffer::write() to update pixel contents was blocking because the cursor was always onscreen, and there wasn't an opportunity to write to the buffer.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

The same bugs exist for touchspots and other overlays. Shouldn't we be fixing this in some common code?

The bug description is certainly generalised, so if we do just fix it for software cursor, then this is not a fix for the attached bug. Call it a partial workaround and keep the bug open?

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

The compositor jerkiness when touchspots are on (lp: #1373692) and this bug (lp: #1413211) are two different root causes. This one is a lockup because another part of the system tries to write to a buffer that is onscreen, and the android code disallows this to avoid tearing on the cursor image. The other bug's root cause is more that certain android devices don't have any fences or waits that stop the composition threads from spiking if we're trying to post the exact same thing twice in a row.

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

Looks good.

Also tested on Mesa/intel.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) :
review: Abstain
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Maybe I'm just not attuned to this bit of the code but this doesn't feel elegant.

But I don't have another idea ready.

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/software_cursor.cpp'
2--- src/server/graphics/software_cursor.cpp 2015-01-21 09:03:53 +0000
3+++ src/server/graphics/software_cursor.cpp 2015-02-04 14:35:56 +0000
4@@ -127,8 +127,11 @@
5 // Do a lock dance to make this function threadsafe,
6 // while avoiding calling scene methods under lock
7 {
8+ geom::Point position{0,0};
9 std::lock_guard<std::mutex> lg{guard};
10- new_renderable = create_renderable_for(cursor_image);
11+ if (renderable)
12+ position = renderable->screen_position().top_left;
13+ new_renderable = create_renderable_for(cursor_image, position);
14 }
15
16 // Add the new renderable first, then remove the old one to avoid
17@@ -148,26 +151,11 @@
18 }
19
20 std::shared_ptr<mg::detail::CursorRenderable>
21-mg::SoftwareCursor::create_renderable_for(CursorImage const& cursor_image)
22+mg::SoftwareCursor::create_renderable_for(CursorImage const& cursor_image, geom::Point position)
23 {
24- std::shared_ptr<detail::CursorRenderable> new_renderable;
25-
26- // Reuse buffer if possible, to minimize buffer reallocations
27- if (renderable && renderable->buffer()->size() == cursor_image.size())
28- {
29- new_renderable = std::make_shared<detail::CursorRenderable>(
30- renderable->buffer(),
31- renderable->screen_position().top_left + hotspot -
32- cursor_image.hotspot());
33- }
34- else
35- {
36- auto const buffer = allocator->alloc_buffer(
37- {cursor_image.size(), format, mg::BufferUsage::software});
38- new_renderable = std::make_shared<detail::CursorRenderable>(
39- buffer,
40- geom::Point{0,0} - cursor_image.hotspot());
41- }
42+ auto new_renderable = std::make_shared<detail::CursorRenderable>(
43+ allocator->alloc_buffer({cursor_image.size(), format, mg::BufferUsage::software}),
44+ position + hotspot - cursor_image.hotspot());
45
46 size_t const pixels_size =
47 cursor_image.size().width.as_uint32_t() *
48
49=== modified file 'src/server/graphics/software_cursor.h'
50--- src/server/graphics/software_cursor.h 2015-01-13 13:23:21 +0000
51+++ src/server/graphics/software_cursor.h 2015-02-04 14:35:56 +0000
52@@ -51,7 +51,7 @@
53
54 private:
55 std::shared_ptr<detail::CursorRenderable> create_renderable_for(
56- CursorImage const& cursor_image);
57+ CursorImage const& cursor_image, geometry::Point position);
58
59 std::shared_ptr<GraphicBufferAllocator> const allocator;
60 std::shared_ptr<input::Scene> const scene;
61
62=== modified file 'tests/unit-tests/graphics/test_software_cursor.cpp'
63--- tests/unit-tests/graphics/test_software_cursor.cpp 2015-01-13 13:23:21 +0000
64+++ tests/unit-tests/graphics/test_software_cursor.cpp 2015-02-04 14:35:56 +0000
65@@ -274,3 +274,23 @@
66
67 cursor.show(another_stub_cursor_image);
68 }
69+
70+//lp: #1413211
71+TEST_F(SoftwareCursor, new_buffer_on_each_show)
72+{
73+ struct MockBufferAllocator : public mg::GraphicBufferAllocator
74+ {
75+ MOCK_METHOD1(alloc_buffer, std::shared_ptr<mg::Buffer>(mg::BufferProperties const&));
76+ std::vector<MirPixelFormat> supported_pixel_formats() { return {mir_pixel_format_abgr_8888}; }
77+ } mock_allocator;
78+
79+ EXPECT_CALL(mock_allocator, alloc_buffer(testing::_))
80+ .Times(3)
81+ .WillRepeatedly(testing::Return(std::make_shared<mtd::StubBuffer>()));;
82+ mg::SoftwareCursor cursor{
83+ mt::fake_shared(mock_allocator),
84+ mt::fake_shared(mock_input_scene)};
85+ cursor.show(another_stub_cursor_image);
86+ cursor.show(another_stub_cursor_image);
87+ cursor.show(stub_cursor_image);
88+}

Subscribers

People subscribed via source and target branches