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
=== modified file 'src/platform/graphics/mesa/native_platform.cpp'
--- src/platform/graphics/mesa/native_platform.cpp 2014-03-06 06:05:17 +0000
+++ src/platform/graphics/mesa/native_platform.cpp 2014-03-12 02:47:17 +0000
@@ -25,8 +25,13 @@
25#include "mir/graphics/platform_ipc_package.h"25#include "mir/graphics/platform_ipc_package.h"
26#include "mir/graphics/nested_context.h"26#include "mir/graphics/nested_context.h"
2727
28#include "internal_client.h"
29#include "internal_native_display.h"
30
28#include <boost/exception/errinfo_errno.hpp>31#include <boost/exception/errinfo_errno.hpp>
29#include <boost/throw_exception.hpp>32#include <boost/throw_exception.hpp>
33
34#include <mutex>
30#include <stdexcept>35#include <stdexcept>
3136
32namespace mg = mir::graphics;37namespace mg = mir::graphics;
@@ -42,6 +47,11 @@
42 nested_context->drm_set_gbm_device(gbm.device);47 nested_context->drm_set_gbm_device(gbm.device);
43}48}
4449
50mgm::NativePlatform::~NativePlatform()
51{
52 finish_internal_native_display();
53}
54
45std::shared_ptr<mg::GraphicBufferAllocator> mgm::NativePlatform::create_buffer_allocator(55std::shared_ptr<mg::GraphicBufferAllocator> mgm::NativePlatform::create_buffer_allocator(
46 std::shared_ptr<mg::BufferInitializer> const& buffer_initializer)56 std::shared_ptr<mg::BufferInitializer> const& buffer_initializer)
47{57{
@@ -82,7 +92,8 @@
8292
83std::shared_ptr<mg::InternalClient> mgm::NativePlatform::create_internal_client()93std::shared_ptr<mg::InternalClient> mgm::NativePlatform::create_internal_client()
84{94{
85 BOOST_THROW_EXCEPTION(std::runtime_error("MesaNativePlatform::create_internal_client is not implemented yet!"));95 auto nd = ensure_internal_native_display(get_ipc_package());
96 return std::make_shared<mgm::InternalClient>(nd);
86}97}
8798
88void mgm::NativePlatform::fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const99void mgm::NativePlatform::fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const
@@ -106,3 +117,37 @@
106{117{
107 return std::make_shared<mgm::NativePlatform>();118 return std::make_shared<mgm::NativePlatform>();
108}119}
120
121namespace
122{
123std::shared_ptr<mgm::InternalNativeDisplay> native_display = nullptr;
124std::mutex native_display_guard;
125}
126
127bool mgm::NativePlatform::internal_native_display_in_use()
128{
129 std::unique_lock<std::mutex> lg(native_display_guard);
130 return native_display != nullptr;
131}
132
133std::shared_ptr<mgm::InternalNativeDisplay> mgm::NativePlatform::internal_native_display()
134{
135 std::unique_lock<std::mutex> lg(native_display_guard);
136 return native_display;
137}
138
139std::shared_ptr<mgm::InternalNativeDisplay> mgm::NativePlatform::ensure_internal_native_display(
140 std::shared_ptr<mg::PlatformIPCPackage> const& package)
141{
142 std::unique_lock<std::mutex> lg(native_display_guard);
143 if (!native_display)
144 native_display = std::make_shared<mgm::InternalNativeDisplay>(package);
145 return native_display;
146}
147
148void mgm::NativePlatform::finish_internal_native_display()
149{
150 std::unique_lock<std::mutex> lg(native_display_guard);
151 native_display.reset();
152}
153
109154
=== modified file 'src/platform/graphics/mesa/native_platform.h'
--- src/platform/graphics/mesa/native_platform.h 2014-03-06 06:05:17 +0000
+++ src/platform/graphics/mesa/native_platform.h 2014-03-12 02:47:17 +0000
@@ -30,20 +30,30 @@
30{30{
31namespace mesa31namespace mesa
32{32{
33class InternalNativeDisplay;
34
33class NativePlatform : public graphics::NativePlatform35class NativePlatform : public graphics::NativePlatform
34{36{
35public:37public:
38 virtual ~NativePlatform();
39
36 void initialize(std::shared_ptr<NestedContext> const& nested_context);40 void initialize(std::shared_ptr<NestedContext> const& nested_context);
37 std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(41 std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(
38 std::shared_ptr<BufferInitializer> const& buffer_initializer) override;42 std::shared_ptr<BufferInitializer> const& buffer_initializer) override;
39 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;43 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;
40 std::shared_ptr<InternalClient> create_internal_client() override;44 std::shared_ptr<InternalClient> create_internal_client() override;
41 void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const override;45 void fill_ipc_package(BufferIPCPacker* packer, Buffer const* buffer) const override;
46
47 static std::shared_ptr<InternalNativeDisplay> internal_native_display();
48 static bool internal_native_display_in_use();
4249
43private:50private:
44 int drm_fd;51 int drm_fd;
45 std::shared_ptr<NestedContext> nested_context;52 std::shared_ptr<NestedContext> nested_context;
46 helpers::GBMHelper gbm;53 helpers::GBMHelper gbm;
54
55 static std::shared_ptr<InternalNativeDisplay> ensure_internal_native_display(std::shared_ptr<PlatformIPCPackage> const& package);
56 static void finish_internal_native_display();
47};57};
48}58}
49}59}
5060
=== modified file 'src/platform/graphics/mesa/platform.cpp'
--- src/platform/graphics/mesa/platform.cpp 2014-03-06 06:05:17 +0000
+++ src/platform/graphics/mesa/platform.cpp 2014-03-12 02:47:17 +0000
@@ -17,6 +17,7 @@
17 */17 */
1818
19#include "platform.h"19#include "platform.h"
20#include "native_platform.h"
20#include "buffer_allocator.h"21#include "buffer_allocator.h"
21#include "display.h"22#include "display.h"
22#include "internal_client.h"23#include "internal_client.h"
@@ -179,6 +180,12 @@
179180
180extern "C" int mir_server_mesa_egl_native_display_is_valid(MirMesaEGLNativeDisplay* display)181extern "C" int mir_server_mesa_egl_native_display_is_valid(MirMesaEGLNativeDisplay* display)
181{182{
182 return ((mgm::Platform::internal_display_clients_present) &&183 bool nested_internal_display_in_use = mgm::NativePlatform::internal_native_display_in_use();
183 (display == mgm::Platform::internal_native_display.get()));184 bool host_internal_display_in_use = mgm::Platform::internal_display_clients_present;
185
186 if (host_internal_display_in_use)
187 return (display == mgm::Platform::internal_native_display.get());
188 else if (nested_internal_display_in_use)
189 return (display == mgm::NativePlatform::internal_native_display().get());
190 return 0;
184}191}

Subscribers

People subscribed via source and target branches