Mir

Merge lp:~robertcarr/mir/nested-internal-egl-on-mesa-without-caveat into lp:mir

Proposed by Robert Carr
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 1471
Proposed branch: lp:~robertcarr/mir/nested-internal-egl-on-mesa-without-caveat
Merge into: lp:mir
Diff against target: 139 lines (+65/-3)
3 files modified
src/platform/graphics/mesa/native_platform.cpp (+46/-1)
src/platform/graphics/mesa/native_platform.h (+10/-0)
src/platform/graphics/mesa/platform.cpp (+9/-2)
To merge this branch: bzr merge lp:~robertcarr/mir/nested-internal-egl-on-mesa-without-caveat
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Approve
Daniel van Vugt Approve
Kevin DuBois Pending
Review via email: mp+210514@code.launchpad.net

This proposal supersedes a proposal from 2014-01-02.

Commit message

Implement internal clients on nested Mesa platform (LP: #1279092)

This is to unblock the Unity8 on desktop preview.

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

Most of this diff is not yours :)

Please resubmit with the appropriate prerequisite defined:
lp:~raof/mir/check-for-surfaceless

review: Needs Resubmitting
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

> Most of this diff is not yours :)
>
> Please resubmit with the appropriate prerequisite defined:
> lp:~raof/mir/check-for-surfaceless

++

review: Needs Resubmitting
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

The prereq branch interfering with this diff has now landed. Please merge development-branch and resubmit.

review: Needs Resubmitting
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

(1) Could the freeze in swap buffers be related to bug 1236256...?

(2) printf is sometimes slower than rendering, and should at least not be done on every frame:
22 + printf("Swapped\n");
Are you sure you want to keep that?

(3) There are logic changes in src/ without any changes in tests/. Are these changes already covered by existing tests?

Mostly Needs Information, but (2) needs fixing.

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

1. It could be. My first impression is that perhaps its related to some reentrancy in mesa EGL...the deadlock definitely seems to be on EGL internal mutexes (At the API level, not the driver/platform level). Of course I haven't completely ruled out a mir deadlock causing this.

2. Whoops! Of course not. Put this in for debugging for holidays...thanks!

3. Mm :(. The internal client itself is already covered by tests. I couldn't really find a test to write here that I thought was meaningful.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal

The use of static to share this information between platforms strikes me as strange.

also
8 +#include <stdio.h>
9 +

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

(4) We're not crippling non-nested multi-monitor with this, are we?
69 +// TODO: Currently this will not work in multimonitor scenarios!. Use of an internal client inside a nested Mir on Mesa will end in
70 +// a deadlock inside the Mesa-EGL layer between the multiple compositor threads. ~racarr

review: Needs Information
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Setting to Work in progress again. Racarr's clearly too busy to discuss this right now.

Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

Old comments addressed. It doesn't affect non nested multi-monitor. The bug seems to be in the client code:

https://bugs.launchpad.net/mir/+bug/1285500

Referenced the bug in the comment

Revision history for this message
Daniel van Vugt (vanvugt) : Posted in a previous version of this proposal
review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

82 + static bool internal_display_clients_present;
83 + static std::shared_ptr<InternalNativeDisplay> internal_native_display;

Public mutable data is a race condition waiting to happen.

These should probably be file scope and either atomic or protected by a mutex. (A static member function can server the needs of mir_server_mesa_egl_native_display_is_valid()).

Also, I see no value in having both variables.

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

Good call. Pushed a cleanup.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

Nit: nullptr is the new 0

~~~~

132 return ((mgm::Platform::internal_display_clients_present) &&
133 - (display == mgm::Platform::internal_native_display.get()));
134 + (display == mgm::Platform::internal_native_display.get())) ||
135 + (mgm::NativePlatform::internal_native_display_in_use() && (display == mgm::NativePlatform::internal_native_display().get()));

This looks like poor encapsulation (and poor formatting). Maybe the two primary sub expressions could be separated out?

And names like "NativePlatform::internal_native_display()" vs "Platform::internal_native_display" don't clearly distinguish the intent.

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

How about like this?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

(1) I suspect your description and code comments are now out of date, following a couple of recent nesting/multimonitor fixes in Mir 0.1.6 and 0.1.7. Please check...

(2) This looks like it should return a MirBool:
int mir_server_mesa_egl_native_display_is_valid
however we'd have to move the definition of MirBool from client_types.h into common.h, which is probably fine.

(3) Needs Fixing: The methods of mgm::NativePlatform:: look racy and not thread safe. They have internal locking but the caller gets a shared_ptr to the same objects, and the caller is not locked. If you can't safely move the locking up and out of NativePlatform then perhaps try returning copies of objects so you're never returning the locked instance.

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

> (1) I suspect your description and code comments are now out of date,
> following a couple of recent nesting/multimonitor fixes in Mir 0.1.6 and
> 0.1.7. Please check...

I suspect that too.

> (3) Needs Fixing: The methods of mgm::NativePlatform:: look racy and not
> thread safe. They have internal locking but the caller gets a shared_ptr to
> the same objects, and the caller is not locked. If you can't safely move the
> locking up and out of NativePlatform then perhaps try returning copies of
> objects so you're never returning the locked instance.

I disagree: the mutex is needed to protect native_display not the object referenced by it (nor the reference count).

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:1298
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~robertcarr/mir/nested-internal-egl-on-mesa-without-caveat/+merge/210514/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-ci/1042/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-trusty-i386-build/1201
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-trusty-amd64-build/1199
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-trusty-touch/783
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-amd64-ci/774
        deb: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-amd64-ci/774/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-armhf-ci/779
        deb: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-armhf-ci/779/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-trusty-armhf/784
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-trusty-armhf/784/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-mako/735
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/4695

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-team-mir-development-branch-ci/1042/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Now that you mention it, I can't be sure that is a thread safety issue. Although to be properly sure we really should be returning shared_ptrs to const objects instead of mutable ones.

review: Approve
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 :

131 + bool nested_internal_display_in_use = mgm::NativePlatform::internal_native_display_in_use();
132 + bool host_internal_display_in_use = mgm::Platform::internal_display_clients_present;
133 +
134 + if (host_internal_display_in_use)
135 + return (display == mgm::Platform::internal_native_display.get());
136 + else if (nested_internal_display_in_use)
137 + return (display == mgm::NativePlatform::internal_native_display().get());

By making calls to (for example) mgm::NativePlatform::internal_native_display_in_use() and mgm::Platform::internal_native_display.get()) without any locking there is a risk of state changing. But I doubt we have a real problem.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Land the thing! After 3 months I think we're out of reasons not to.

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/platform/graphics/mesa/native_platform.cpp'
2--- src/platform/graphics/mesa/native_platform.cpp 2014-03-06 06:05:17 +0000
3+++ src/platform/graphics/mesa/native_platform.cpp 2014-03-12 02:47:17 +0000
4@@ -25,8 +25,13 @@
5 #include "mir/graphics/platform_ipc_package.h"
6 #include "mir/graphics/nested_context.h"
7
8+#include "internal_client.h"
9+#include "internal_native_display.h"
10+
11 #include <boost/exception/errinfo_errno.hpp>
12 #include <boost/throw_exception.hpp>
13+
14+#include <mutex>
15 #include <stdexcept>
16
17 namespace mg = mir::graphics;
18@@ -42,6 +47,11 @@
19 nested_context->drm_set_gbm_device(gbm.device);
20 }
21
22+mgm::NativePlatform::~NativePlatform()
23+{
24+ finish_internal_native_display();
25+}
26+
27 std::shared_ptr<mg::GraphicBufferAllocator> mgm::NativePlatform::create_buffer_allocator(
28 std::shared_ptr<mg::BufferInitializer> const& buffer_initializer)
29 {
30@@ -82,7 +92,8 @@
31
32 std::shared_ptr<mg::InternalClient> mgm::NativePlatform::create_internal_client()
33 {
34- BOOST_THROW_EXCEPTION(std::runtime_error("MesaNativePlatform::create_internal_client is not implemented yet!"));
35+ auto nd = ensure_internal_native_display(get_ipc_package());
36+ return std::make_shared<mgm::InternalClient>(nd);
37 }
38
39 void mgm::NativePlatform::fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const
40@@ -106,3 +117,37 @@
41 {
42 return std::make_shared<mgm::NativePlatform>();
43 }
44+
45+namespace
46+{
47+std::shared_ptr<mgm::InternalNativeDisplay> native_display = nullptr;
48+std::mutex native_display_guard;
49+}
50+
51+bool mgm::NativePlatform::internal_native_display_in_use()
52+{
53+ std::unique_lock<std::mutex> lg(native_display_guard);
54+ return native_display != nullptr;
55+}
56+
57+std::shared_ptr<mgm::InternalNativeDisplay> mgm::NativePlatform::internal_native_display()
58+{
59+ std::unique_lock<std::mutex> lg(native_display_guard);
60+ return native_display;
61+}
62+
63+std::shared_ptr<mgm::InternalNativeDisplay> mgm::NativePlatform::ensure_internal_native_display(
64+ std::shared_ptr<mg::PlatformIPCPackage> const& package)
65+{
66+ std::unique_lock<std::mutex> lg(native_display_guard);
67+ if (!native_display)
68+ native_display = std::make_shared<mgm::InternalNativeDisplay>(package);
69+ return native_display;
70+}
71+
72+void mgm::NativePlatform::finish_internal_native_display()
73+{
74+ std::unique_lock<std::mutex> lg(native_display_guard);
75+ native_display.reset();
76+}
77+
78
79=== modified file 'src/platform/graphics/mesa/native_platform.h'
80--- src/platform/graphics/mesa/native_platform.h 2014-03-06 06:05:17 +0000
81+++ src/platform/graphics/mesa/native_platform.h 2014-03-12 02:47:17 +0000
82@@ -30,20 +30,30 @@
83 {
84 namespace mesa
85 {
86+class InternalNativeDisplay;
87+
88 class NativePlatform : public graphics::NativePlatform
89 {
90 public:
91+ virtual ~NativePlatform();
92+
93 void initialize(std::shared_ptr<NestedContext> const& nested_context);
94 std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(
95 std::shared_ptr<BufferInitializer> const& buffer_initializer) override;
96 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;
97 std::shared_ptr<InternalClient> create_internal_client() override;
98 void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const override;
99+
100+ static std::shared_ptr<InternalNativeDisplay> internal_native_display();
101+ static bool internal_native_display_in_use();
102
103 private:
104 int drm_fd;
105 std::shared_ptr<NestedContext> nested_context;
106 helpers::GBMHelper gbm;
107+
108+ static std::shared_ptr<InternalNativeDisplay> ensure_internal_native_display(std::shared_ptr<PlatformIPCPackage> const& package);
109+ static void finish_internal_native_display();
110 };
111 }
112 }
113
114=== modified file 'src/platform/graphics/mesa/platform.cpp'
115--- src/platform/graphics/mesa/platform.cpp 2014-03-06 06:05:17 +0000
116+++ src/platform/graphics/mesa/platform.cpp 2014-03-12 02:47:17 +0000
117@@ -17,6 +17,7 @@
118 */
119
120 #include "platform.h"
121+#include "native_platform.h"
122 #include "buffer_allocator.h"
123 #include "display.h"
124 #include "internal_client.h"
125@@ -179,6 +180,12 @@
126
127 extern "C" int mir_server_mesa_egl_native_display_is_valid(MirMesaEGLNativeDisplay* display)
128 {
129- return ((mgm::Platform::internal_display_clients_present) &&
130- (display == mgm::Platform::internal_native_display.get()));
131+ bool nested_internal_display_in_use = mgm::NativePlatform::internal_native_display_in_use();
132+ bool host_internal_display_in_use = mgm::Platform::internal_display_clients_present;
133+
134+ if (host_internal_display_in_use)
135+ return (display == mgm::Platform::internal_native_display.get());
136+ else if (nested_internal_display_in_use)
137+ return (display == mgm::NativePlatform::internal_native_display().get());
138+ return 0;
139 }

Subscribers

People subscribed via source and target branches